diff --git a/resources/2char.png b/resources/2char.png new file mode 100644 index 0000000..56196af Binary files /dev/null and b/resources/2char.png differ diff --git a/resources/META-INF/MANIFEST.MF b/resources/META-INF/MANIFEST.MF new file mode 100644 index 0000000..58630c0 --- /dev/null +++ b/resources/META-INF/MANIFEST.MF @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 + diff --git a/resources/armor/chain.png b/resources/armor/chain.png new file mode 100644 index 0000000..5c26ea8 Binary files /dev/null and b/resources/armor/chain.png differ diff --git a/resources/armor/plate.png b/resources/armor/plate.png new file mode 100644 index 0000000..5350f3f Binary files /dev/null and b/resources/armor/plate.png differ diff --git a/resources/char.png b/resources/char.png new file mode 100644 index 0000000..7cfa08a Binary files /dev/null and b/resources/char.png differ diff --git a/resources/clouds.png b/resources/clouds.png new file mode 100644 index 0000000..b6c9e13 Binary files /dev/null and b/resources/clouds.png differ diff --git a/resources/default.gif b/resources/default.gif new file mode 100644 index 0000000..15e0fc2 Binary files /dev/null and b/resources/default.gif differ diff --git a/resources/default.png b/resources/default.png new file mode 100644 index 0000000..13a42f1 Binary files /dev/null and b/resources/default.png differ diff --git a/resources/dirt.png b/resources/dirt.png new file mode 100644 index 0000000..b29e009 Binary files /dev/null and b/resources/dirt.png differ diff --git a/resources/glsl/core.glsl b/resources/glsl/core.glsl new file mode 100644 index 0000000..0c88351 --- /dev/null +++ b/resources/glsl/core.glsl @@ -0,0 +1,144 @@ + +// eaglercraft opengl 1.3 emulation +// copyright (c) 2020 calder young +// creative commons BY-NC 4.0 + +#line 7 + +precision highp int; +precision highp sampler2D; +precision highp float; + +uniform mat4 matrix_m; +uniform mat4 matrix_p; +uniform mat4 matrix_t; + +#ifdef CC_VERT + +in vec3 a_position; +#ifdef CC_a_texture0 +in vec2 a_texture0; +#endif +#ifdef CC_a_color +in vec4 a_color; +#endif +#ifdef CC_a_normal +in vec4 a_normal; +#endif + +#ifdef CC_fog +out vec4 v_position; +#endif +#ifdef CC_a_color +out vec4 v_color; +#endif +#ifdef CC_a_normal +out vec4 v_normal; +#endif +#ifdef CC_a_texture0 +out vec2 v_texture0; +#endif + +void main(){ + vec4 pos = matrix_m * vec4(a_position, 1.0); +#ifdef CC_fog + v_position = pos; +#endif +#ifdef CC_a_color + v_color = a_color; +#endif +#ifdef CC_a_normal + v_normal = a_normal; +#endif +#ifdef CC_a_texture0 + v_texture0 = a_texture0; +#endif + gl_Position = matrix_p * pos; +} + +#endif + +#ifdef CC_FRAG + +#ifdef CC_unit0 +uniform sampler2D tex0; +#ifndef CC_a_texture0 +uniform vec2 texCoordV0; +#endif +#endif +#ifdef CC_lighting +uniform vec3 light0Pos; +uniform vec3 light1Pos; +uniform vec3 normalUniform; +#endif +#ifdef CC_fog +uniform vec4 fogColor; +uniform int fogMode; +uniform float fogStart; +uniform float fogEnd; +uniform float fogDensity; +uniform float fogPremultiply; +#endif +uniform vec4 colorUniform; +#ifdef CC_alphatest +uniform float alphaTestF; +#endif + +#ifdef CC_fog +in vec4 v_position; +#endif +#ifdef CC_a_color +in vec4 v_color; +#endif +#ifdef CC_a_normal +in vec4 v_normal; +#endif +#ifdef CC_a_texture0 +in vec2 v_texture0; +#endif + +out vec4 fragColor; + +void main(){ +#ifdef CC_a_color + vec4 color = colorUniform * v_color; +#else + vec4 color = colorUniform; +#endif + +#ifdef CC_unit0 +#ifdef CC_a_texture0 + color *= texture(tex0, (matrix_t * vec4(v_texture0, 0.0, 1.0)).xy).rgba; +#else + color *= texture(tex0, (matrix_t * vec4(texCoordV0, 0.0, 1.0)).xy).rgba; +#endif +#endif + +#ifdef CC_alphatest + if(color.a < alphaTestF){ + discard; + } +#endif + +#ifdef CC_lighting +#ifdef CC_a_normal + vec3 normal = ((v_normal.xyz - 0.5) * 2.0); +#else + vec3 normal = normalUniform; +#endif + normal = normalize(mat3(matrix_m) * normal); + float ins = max(dot(normal, -light0Pos), 0.0) + max(dot(normal, -light1Pos), 0.0); + color.rgb *= min((0.4 + ins * 0.6), 1.0); +#endif + +#ifdef CC_fog + float dist = sqrt(dot(v_position, v_position)); + float i = (fogMode == 1) ? clamp((dist - fogStart) / (fogEnd - fogStart), 0.0, 1.0) : clamp(1.0 - pow(2.718, -(fogDensity * dist)), 0.0, 1.0); + color.rgb = mix(color.rgb, fogColor.xyz, i * fogColor.a); +#endif + + fragColor = color; +} + +#endif + diff --git a/resources/glsl/fxaa.glsl b/resources/glsl/fxaa.glsl new file mode 100644 index 0000000..8cd01a3 --- /dev/null +++ b/resources/glsl/fxaa.glsl @@ -0,0 +1,255 @@ +#line 0 + +precision lowp int; +precision lowp sampler2D; +precision lowp float; + +in vec2 pos; + +out vec4 fragColor; + +#define FXAA_PC 1 +#define FXAA_GLSL_130 1 +#define FXAA_FAST_PIXEL_OFFSET 0 +#define FXAA_GATHER4_ALPHA 0 + +#ifndef FXAA_GREEN_AS_LUMA + // For those using non-linear color, + // and either not able to get luma in alpha, or not wanting to, + // this enables FXAA to run using green as a proxy for luma. + // So with this enabled, no need to pack luma in alpha. + // + // This will turn off AA on anything which lacks some amount of green. + // Pure red and blue or combination of only R and B, will get no AA. + // + // Might want to lower the settings for both, + // fxaaConsoleEdgeThresholdMin + // fxaaQualityEdgeThresholdMin + // In order to insure AA does not get turned off on colors + // which contain a minor amount of green. + // + // 1 = On. + // 0 = Off. + // + #define FXAA_GREEN_AS_LUMA 1 +#endif + +#ifndef FXAA_DISCARD + // 1 = Use discard on pixels which don't need AA. + // 0 = Return unchanged color on pixels which don't need AA. + #define FXAA_DISCARD 0 +#endif + +/*============================================================================ + API PORTING +============================================================================*/ + #define FxaaBool bool + #define FxaaDiscard discard + #define FxaaFloat float + #define FxaaFloat2 vec2 + #define FxaaFloat3 vec3 + #define FxaaFloat4 vec4 + #define FxaaHalf float + #define FxaaHalf2 vec2 + #define FxaaHalf3 vec3 + #define FxaaHalf4 vec4 + #define FxaaInt2 ivec2 + #define FxaaSat(x) clamp(x, 0.0, 1.0) + #define FxaaTex sampler2D +/*--------------------------------------------------------------------------*/ + + #define FxaaTexTop(t, p) texture(t, p) + +/*============================================================================ + GREEN AS LUMA OPTION SUPPORT FUNCTION +============================================================================*/ +#if (FXAA_GREEN_AS_LUMA == 0) + // TODO Luma + FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return dot(rgba.xyz, vec3(0.299, 0.587, 0.114)); } +#else + FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; } +#endif + +/*============================================================================ + FXAA3 CONSOLE - PC VERSION +============================================================================*/ +/*--------------------------------------------------------------------------*/ +FxaaFloat4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + // + // Use noperspective interpolation here (turn off perspective interpolation). + // {xy} = center of pixel + FxaaFloat2 pos, + // + // Used only for FXAA Console, and not used on the 360 version. + // Use noperspective interpolation here (turn off perspective interpolation). + // {xy__} = upper left of pixel + // {__zw} = lower right of pixel + FxaaFloat4 fxaaConsolePosPos, + // + // Input color texture. + // {rgb_} = color in linear or perceptual color space + // if (FXAA_GREEN_AS_LUMA == 0) + // {___a} = luma in perceptual color space (not linear) + FxaaTex tex, + // + // Only used on FXAA Console. + // This must be from a constant/uniform. + // This effects sub-pixel AA quality and inversely sharpness. + // Where N ranges between, + // N = 0.50 (default) + // N = 0.33 (sharper) + // {x___} = -N/screenWidthInPixels + // {_y__} = -N/screenHeightInPixels + // {__z_} = N/screenWidthInPixels + // {___w} = N/screenHeightInPixels + FxaaFloat4 fxaaConsoleRcpFrameOpt, + // + // Only used on FXAA Console. + // Not used on 360, but used on PS3 and PC. + // This must be from a constant/uniform. + // {x___} = -2.0/screenWidthInPixels + // {_y__} = -2.0/screenHeightInPixels + // {__z_} = 2.0/screenWidthInPixels + // {___w} = 2.0/screenHeightInPixels + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_SHARPNESS define. + // It is here now to allow easier tuning. + // This does not effect PS3, as this needs to be compiled in. + // Use FXAA_CONSOLE__PS3_EDGE_SHARPNESS for PS3. + // Due to the PS3 being ALU bound, + // there are only three safe values here: 2 and 4 and 8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // For all other platforms can be a non-power of two. + // 8.0 is sharper (default!!!) + // 4.0 is softer + // 2.0 is really soft (good only for vector graphics inputs) + FxaaFloat fxaaConsoleEdgeSharpness, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD define. + // It is here now to allow easier tuning. + // This does not effect PS3, as this needs to be compiled in. + // Use FXAA_CONSOLE__PS3_EDGE_THRESHOLD for PS3. + // Due to the PS3 being ALU bound, + // there are only two safe values here: 1/4 and 1/8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // The console setting has a different mapping than the quality setting. + // Other platforms can use other values. + // 0.125 leaves less aliasing, but is softer (default!!!) + // 0.25 leaves more aliasing, and is sharper + FxaaFloat fxaaConsoleEdgeThreshold, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD_MIN define. + // It is here now to allow easier tuning. + // Trims the algorithm from processing darks. + // The console setting has a different mapping than the quality setting. + // This does not apply to PS3, + // PS3 was simplified to avoid more shader instructions. + // 0.06 - faster but more aliasing in darks + // 0.05 - default + // 0.04 - slower and less aliasing in darks + // Special notes when using FXAA_GREEN_AS_LUMA, + // Likely want to set this to zero. + // As colors that are mostly not-green + // will appear very dark in the green channel! + // Tune by looking at mostly non-green content, + // then start at zero and increase until aliasing is a problem. + FxaaFloat fxaaConsoleEdgeThresholdMin +) { +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xy)); + FxaaFloat lumaSw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xw)); + FxaaFloat lumaNe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zy)); + FxaaFloat lumaSe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zw)); +/*--------------------------------------------------------------------------*/ + FxaaFloat4 rgbyM = FxaaTexTop(tex, pos.xy); + #if (FXAA_GREEN_AS_LUMA == 0) + // TODO Luma + FxaaFloat lumaM = FxaaLuma(rgbyM); + #else + FxaaFloat lumaM = rgbyM.y; + #endif +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMaxNwSw = max(lumaNw, lumaSw); + lumaNe += 1.0/384.0; + FxaaFloat lumaMinNwSw = min(lumaNw, lumaSw); +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMaxNeSe = max(lumaNe, lumaSe); + FxaaFloat lumaMinNeSe = min(lumaNe, lumaSe); +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMax = max(lumaMaxNeSe, lumaMaxNwSw); + FxaaFloat lumaMin = min(lumaMinNeSe, lumaMinNwSw); +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMaxScaled = lumaMax * fxaaConsoleEdgeThreshold; +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMinM = min(lumaMin, lumaM); + FxaaFloat lumaMaxScaledClamped = max(fxaaConsoleEdgeThresholdMin, lumaMaxScaled); + FxaaFloat lumaMaxM = max(lumaMax, lumaM); + FxaaFloat dirSwMinusNe = lumaSw - lumaNe; + FxaaFloat lumaMaxSubMinM = lumaMaxM - lumaMinM; + FxaaFloat dirSeMinusNw = lumaSe - lumaNw; + if(lumaMaxSubMinM < lumaMaxScaledClamped) + { + #if (FXAA_DISCARD == 1) + FxaaDiscard; + #else + return rgbyM; + #endif + } +/*--------------------------------------------------------------------------*/ + FxaaFloat2 dir; + dir.x = dirSwMinusNe + dirSeMinusNw; + dir.y = dirSwMinusNe - dirSeMinusNw; +/*--------------------------------------------------------------------------*/ + FxaaFloat2 dir1 = normalize(dir.xy); + FxaaFloat4 rgbyN1 = FxaaTexTop(tex, pos.xy - dir1 * fxaaConsoleRcpFrameOpt.zw); + FxaaFloat4 rgbyP1 = FxaaTexTop(tex, pos.xy + dir1 * fxaaConsoleRcpFrameOpt.zw); +/*--------------------------------------------------------------------------*/ + FxaaFloat dirAbsMinTimesC = min(abs(dir1.x), abs(dir1.y)) * fxaaConsoleEdgeSharpness; + FxaaFloat2 dir2 = clamp(dir1.xy / dirAbsMinTimesC, -2.0, 2.0); +/*--------------------------------------------------------------------------*/ + FxaaFloat2 dir2x = dir2 * fxaaConsoleRcpFrameOpt2.zw; + FxaaFloat4 rgbyN2 = FxaaTexTop(tex, pos.xy - dir2x); + FxaaFloat4 rgbyP2 = FxaaTexTop(tex, pos.xy + dir2x); +/*--------------------------------------------------------------------------*/ + FxaaFloat4 rgbyA = rgbyN1 + rgbyP1; + FxaaFloat4 rgbyB = ((rgbyN2 + rgbyP2) * 0.25) + (rgbyA * 0.25); +/*--------------------------------------------------------------------------*/ + #if (FXAA_GREEN_AS_LUMA == 0) + // TODO Luma + float lumaB = FxaaLuma(rgbyB); + #else + float lumaB = rgbyB.y; + #endif + if((lumaB < lumaMin) || (lumaB > lumaMax)) + rgbyB.xyz = rgbyA.xyz * 0.5; + // + return rgbyB; +} +/*==========================================================================*/ + +uniform sampler2D f_color; + +uniform vec2 screenSize; + +#define edgeSharpness 7.0 +#define edgeThreshold 0.1 +#define edgeThresholdMin 0.005 + +void main(){ + vec4 posPos; + posPos.xy = pos - (0.6 / screenSize); + posPos.zw = pos + (0.6 / screenSize); + vec4 rcpFrameOpt; + rcpFrameOpt.xy = vec2(-0.50, -0.50) / screenSize; + rcpFrameOpt.zw = vec2( 0.50, 0.50) / screenSize; + vec4 rcpFrameOpt2; + rcpFrameOpt2.xy = vec2(-2.0, -2.0) / screenSize; + rcpFrameOpt2.zw = vec2( 2.0, 2.0) / screenSize; + + fragColor = vec4(FxaaPixelShader(pos, posPos, f_color, rcpFrameOpt, rcpFrameOpt2, edgeSharpness, edgeThreshold, edgeThresholdMin).rgb, 1.0); +} diff --git a/resources/glsl/occl.glsl b/resources/glsl/occl.glsl new file mode 100644 index 0000000..df74763 --- /dev/null +++ b/resources/glsl/occl.glsl @@ -0,0 +1,25 @@ +#line 2 + +precision highp int; +precision highp sampler2D; +precision highp float; + +#ifdef CC_VERT +uniform mat4 matrix_m; +uniform mat4 matrix_p; + +in vec3 a_vert; + +void main(){ + gl_Position = (matrix_p * (matrix_m * vec4(a_vert, 1.0))); +} +#endif + +#ifdef CC_FRAG + +out vec4 fragColor; + +void main(){ + fragColor = vec4(1.0); +} +#endif diff --git a/resources/glsl/pvert.glsl b/resources/glsl/pvert.glsl new file mode 100644 index 0000000..ce17a2c --- /dev/null +++ b/resources/glsl/pvert.glsl @@ -0,0 +1,13 @@ +#line 0 + +precision lowp int; +precision lowp sampler2D; +precision lowp float; + +in vec2 a_pos; + +out vec2 pos; + +void main(){ + gl_Position = vec4((pos = a_pos) * 2.0 - 1.0, 0.0, 1.0); +} diff --git a/resources/grass.png b/resources/grass.png new file mode 100644 index 0000000..fd7a724 Binary files /dev/null and b/resources/grass.png differ diff --git a/resources/gui/gui.png b/resources/gui/gui.png new file mode 100644 index 0000000..81af329 Binary files /dev/null and b/resources/gui/gui.png differ diff --git a/resources/gui/icons.png b/resources/gui/icons.png new file mode 100644 index 0000000..93e95aa Binary files /dev/null and b/resources/gui/icons.png differ diff --git a/resources/item/arrows.png b/resources/item/arrows.png new file mode 100644 index 0000000..75c5828 Binary files /dev/null and b/resources/item/arrows.png differ diff --git a/resources/item/sign.png b/resources/item/sign.png new file mode 100644 index 0000000..e829472 Binary files /dev/null and b/resources/item/sign.png differ diff --git a/resources/mob/creeper.png b/resources/mob/creeper.png new file mode 100644 index 0000000..e0a5e0a Binary files /dev/null and b/resources/mob/creeper.png differ diff --git a/resources/mob/pig.png b/resources/mob/pig.png new file mode 100644 index 0000000..5c1efc2 Binary files /dev/null and b/resources/mob/pig.png differ diff --git a/resources/mob/sheep.png b/resources/mob/sheep.png new file mode 100644 index 0000000..98cfa9a Binary files /dev/null and b/resources/mob/sheep.png differ diff --git a/resources/mob/sheep_fur.png b/resources/mob/sheep_fur.png new file mode 100644 index 0000000..f1291a5 Binary files /dev/null and b/resources/mob/sheep_fur.png differ diff --git a/resources/mob/skeleton.png b/resources/mob/skeleton.png new file mode 100644 index 0000000..9d22339 Binary files /dev/null and b/resources/mob/skeleton.png differ diff --git a/resources/mob/spider.png b/resources/mob/spider.png new file mode 100644 index 0000000..08344a8 Binary files /dev/null and b/resources/mob/spider.png differ diff --git a/resources/mob/zombie.png b/resources/mob/zombie.png new file mode 100644 index 0000000..0ab7089 Binary files /dev/null and b/resources/mob/zombie.png differ diff --git a/resources/null b/resources/null new file mode 100644 index 0000000..e69de29 diff --git a/resources/particles.png b/resources/particles.png new file mode 100644 index 0000000..3077c2d Binary files /dev/null and b/resources/particles.png differ diff --git a/resources/rain.png b/resources/rain.png new file mode 100644 index 0000000..e9dc16c Binary files /dev/null and b/resources/rain.png differ diff --git a/resources/terrain.png b/resources/terrain.png new file mode 100644 index 0000000..cbf4e3c Binary files /dev/null and b/resources/terrain.png differ diff --git a/resources/water.png b/resources/water.png new file mode 100644 index 0000000..8b92f9b Binary files /dev/null and b/resources/water.png differ diff --git a/src/main/java/com/mojang/minecraft/ChatLine.java b/src/main/java/com/mojang/minecraft/ChatLine.java new file mode 100644 index 0000000..05ebffe --- /dev/null +++ b/src/main/java/com/mojang/minecraft/ChatLine.java @@ -0,0 +1,13 @@ +package com.mojang.minecraft; + +public class ChatLine +{ + public ChatLine(String message) + { + this.message = message; + this.time = 0; + } + + public String message; + public int time; +} diff --git a/src/main/java/com/mojang/minecraft/Entity.java b/src/main/java/com/mojang/minecraft/Entity.java new file mode 100644 index 0000000..595cd6d --- /dev/null +++ b/src/main/java/com/mojang/minecraft/Entity.java @@ -0,0 +1,477 @@ +package com.mojang.minecraft; + +import com.mojang.minecraft.level.BlockMap; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.level.liquid.LiquidType; +import com.mojang.minecraft.level.tile.Block; +import com.mojang.minecraft.level.tile.Tile$SoundType; +import com.mojang.minecraft.model.Vec3D; +import com.mojang.minecraft.net.PositionUpdate; +import com.mojang.minecraft.phys.AABB; +import com.mojang.minecraft.render.TextureManager; +import com.mojang.util.MathHelper; +import java.io.Serializable; +import java.util.ArrayList; + +public abstract class Entity implements Serializable { + + public static final long serialVersionUID = 0L; + public Level level; + public float xo; + public float yo; + public float zo; + public float x; + public float y; + public float z; + public float xd; + public float yd; + public float zd; + public float yRot; + public float xRot; + public float yRotO; + public float xRotO; + public AABB bb; + public boolean onGround = false; + public boolean horizontalCollision = false; + public boolean collision = false; + public boolean slide = true; + public boolean removed = false; + public float heightOffset = 0.0F; + public float bbWidth = 0.6F; + public float bbHeight = 1.8F; + public float walkDistO = 0.0F; + public float walkDist = 0.0F; + public boolean makeStepSound = true; + public float fallDistance = 0.0F; + private int nextStep = 1; + public BlockMap blockMap; + public float xOld; + public float yOld; + public float zOld; + public int textureId = 0; + public float ySlideOffset = 0.0F; + public float footSize = 0.0F; + public boolean noPhysics = false; + public float pushthrough = 0.0F; + public boolean hovered = false; + + + public Entity(Level var1) { + this.level = var1; + this.setPos(0.0F, 0.0F, 0.0F); + } + + public void resetPos() { + if(this.level != null) { + float var1 = (float)this.level.xSpawn + 0.5F; + float var2 = (float)this.level.ySpawn; + + for(float var3 = (float)this.level.zSpawn + 0.5F; var2 > 0.0F; ++var2) { + this.setPos(var1, var2, var3); + if(this.level.getCubes(this.bb).size() == 0) { + break; + } + } + + this.xd = this.yd = this.zd = 0.0F; + this.yRot = this.level.rotSpawn; + this.xRot = 0.0F; + } + } + + public void remove() { + this.removed = true; + } + + public void setSize(float var1, float var2) { + this.bbWidth = var1; + this.bbHeight = var2; + } + + public void setPos(PositionUpdate var1) { + if(var1.position) { + this.setPos(var1.x, var1.y, var1.z); + } else { + this.setPos(this.x, this.y, this.z); + } + + if(var1.rotation) { + this.setRot(var1.yaw, var1.pitch); + } else { + this.setRot(this.yRot, this.xRot); + } + } + + protected void setRot(float var1, float var2) { + this.yRot = var1; + this.xRot = var2; + } + + public void setPos(float var1, float var2, float var3) { + this.x = var1; + this.y = var2; + this.z = var3; + float var4 = this.bbWidth / 2.0F; + float var5 = this.bbHeight / 2.0F; + this.bb = new AABB(var1 - var4, var2 - var5, var3 - var4, var1 + var4, var2 + var5, var3 + var4); + } + + public void turn(float var1, float var2) { + float var3 = this.xRot; + float var4 = this.yRot; + this.yRot = (float)((double)this.yRot + (double)var1 * 0.15D); + this.xRot = (float)((double)this.xRot - (double)var2 * 0.15D); + if(this.xRot < -90.0F) { + this.xRot = -90.0F; + } + + if(this.xRot > 90.0F) { + this.xRot = 90.0F; + } + + this.xRotO += this.xRot - var3; + this.yRotO += this.yRot - var4; + } + + public void interpolateTurn(float var1, float var2) { + this.yRot = (float)((double)this.yRot + (double)var1 * 0.15D); + this.xRot = (float)((double)this.xRot - (double)var2 * 0.15D); + if(this.xRot < -90.0F) { + this.xRot = -90.0F; + } + + if(this.xRot > 90.0F) { + this.xRot = 90.0F; + } + + } + + public void tick() { + this.walkDistO = this.walkDist; + this.xo = this.x; + this.yo = this.y; + this.zo = this.z; + this.xRotO = this.xRot; + this.yRotO = this.yRot; + } + + public boolean isFree(float var1, float var2, float var3, float var4) { + AABB var5 = this.bb.grow(var4, var4, var4).cloneMove(var1, var2, var3); + return this.level.getCubes(var5).size() > 0?false:!this.level.containsAnyLiquid(var5); + } + + public boolean isFree(float var1, float var2, float var3) { + AABB var4 = this.bb.cloneMove(var1, var2, var3); + return this.level.getCubes(var4).size() > 0?false:!this.level.containsAnyLiquid(var4); + } + + public void move(float var1, float var2, float var3) { + if(this.noPhysics) { + this.bb.move(var1, var2, var3); + this.x = (this.bb.x0 + this.bb.x1) / 2.0F; + this.y = this.bb.y0 + this.heightOffset - this.ySlideOffset; + this.z = (this.bb.z0 + this.bb.z1) / 2.0F; + } else { + float var4 = this.x; + float var5 = this.z; + float var6 = var1; + float var7 = var2; + float var8 = var3; + AABB var9 = this.bb.copy(); + ArrayList var10 = this.level.getCubes(this.bb.expand(var1, var2, var3)); + + for(int var11 = 0; var11 < var10.size(); ++var11) { + var2 = ((AABB)var10.get(var11)).clipYCollide(this.bb, var2); + } + + this.bb.move(0.0F, var2, 0.0F); + if(!this.slide && var7 != var2) { + var3 = 0.0F; + var2 = 0.0F; + var1 = 0.0F; + } + + boolean var16 = this.onGround || var7 != var2 && var7 < 0.0F; + + int var12; + for(var12 = 0; var12 < var10.size(); ++var12) { + var1 = ((AABB)var10.get(var12)).clipXCollide(this.bb, var1); + } + + this.bb.move(var1, 0.0F, 0.0F); + if(!this.slide && var6 != var1) { + var3 = 0.0F; + var2 = 0.0F; + var1 = 0.0F; + } + + for(var12 = 0; var12 < var10.size(); ++var12) { + var3 = ((AABB)var10.get(var12)).clipZCollide(this.bb, var3); + } + + this.bb.move(0.0F, 0.0F, var3); + if(!this.slide && var8 != var3) { + var3 = 0.0F; + var2 = 0.0F; + var1 = 0.0F; + } + + float var17; + float var18; + if(this.footSize > 0.0F && var16 && this.ySlideOffset < 0.05F && (var6 != var1 || var8 != var3)) { + var18 = var1; + var17 = var2; + float var13 = var3; + var1 = var6; + var2 = this.footSize; + var3 = var8; + AABB var14 = this.bb.copy(); + this.bb = var9.copy(); + var10 = this.level.getCubes(this.bb.expand(var6, var2, var8)); + + int var15; + for(var15 = 0; var15 < var10.size(); ++var15) { + var2 = ((AABB)var10.get(var15)).clipYCollide(this.bb, var2); + } + + this.bb.move(0.0F, var2, 0.0F); + if(!this.slide && var7 != var2) { + var3 = 0.0F; + var2 = 0.0F; + var1 = 0.0F; + } + + for(var15 = 0; var15 < var10.size(); ++var15) { + var1 = ((AABB)var10.get(var15)).clipXCollide(this.bb, var1); + } + + this.bb.move(var1, 0.0F, 0.0F); + if(!this.slide && var6 != var1) { + var3 = 0.0F; + var2 = 0.0F; + var1 = 0.0F; + } + + for(var15 = 0; var15 < var10.size(); ++var15) { + var3 = ((AABB)var10.get(var15)).clipZCollide(this.bb, var3); + } + + this.bb.move(0.0F, 0.0F, var3); + if(!this.slide && var8 != var3) { + var3 = 0.0F; + var2 = 0.0F; + var1 = 0.0F; + } + + if(var18 * var18 + var13 * var13 >= var1 * var1 + var3 * var3) { + var1 = var18; + var2 = var17; + var3 = var13; + this.bb = var14.copy(); + } else { + this.ySlideOffset = (float)((double)this.ySlideOffset + 0.5D); + } + } + + this.horizontalCollision = var6 != var1 || var8 != var3; + this.onGround = var7 != var2 && var7 < 0.0F; + this.collision = this.horizontalCollision || var7 != var2; + if(this.onGround) { + if(this.fallDistance > 0.0F) { + this.causeFallDamage(this.fallDistance); + this.fallDistance = 0.0F; + } + } else if(var2 < 0.0F) { + this.fallDistance -= var2; + } + + if(var6 != var1) { + this.xd = 0.0F; + } + + if(var7 != var2) { + this.yd = 0.0F; + } + + if(var8 != var3) { + this.zd = 0.0F; + } + + this.x = (this.bb.x0 + this.bb.x1) / 2.0F; + this.y = this.bb.y0 + this.heightOffset - this.ySlideOffset; + this.z = (this.bb.z0 + this.bb.z1) / 2.0F; + var18 = this.x - var4; + var17 = this.z - var5; + this.walkDist = (float)((double)this.walkDist + (double)MathHelper.sqrt(var18 * var18 + var17 * var17) * 0.6D); + if(this.makeStepSound) { + int var19 = this.level.getTile((int)this.x, (int)(this.y - 0.2F - this.heightOffset), (int)this.z); + if(this.walkDist > (float)this.nextStep && var19 > 0) { + ++this.nextStep; + Tile$SoundType var20; + if((var20 = Block.blocks[var19].stepsound) != Tile$SoundType.none) { + this.playSound("step." + var20.name, var20.getVolume() * 0.75F, var20.getPitch()); + } + } + } + + this.ySlideOffset *= 0.4F; + } + } + + protected void causeFallDamage(float var1) {} + + public boolean isInWater() { + return this.level.containsLiquid(this.bb.grow(0.0F, -0.4F, 0.0F), LiquidType.WATER); + } + + public boolean isUnderWater() { + int var1; + return (var1 = this.level.getTile((int)this.x, (int)(this.y + 0.12F), (int)this.z)) != 0?Block.blocks[var1].getLiquidType().equals(LiquidType.WATER):false; + } + + public boolean isInLava() { + return this.level.containsLiquid(this.bb.grow(0.0F, -0.4F, 0.0F), LiquidType.LAVA); + } + + public void moveRelative(float var1, float var2, float var3) { + float var4; + if((var4 = MathHelper.sqrt(var1 * var1 + var2 * var2)) >= 0.01F) { + if(var4 < 1.0F) { + var4 = 1.0F; + } + + var4 = var3 / var4; + var1 *= var4; + var2 *= var4; + var3 = MathHelper.sin(this.yRot * 3.1415927F / 180.0F); + var4 = MathHelper.cos(this.yRot * 3.1415927F / 180.0F); + this.xd += var1 * var4 - var2 * var3; + this.zd += var2 * var4 + var1 * var3; + } + } + + public boolean isLit() { + int var1 = (int)this.x; + int var2 = (int)this.y; + int var3 = (int)this.z; + return this.level.isLit(var1, var2, var3); + } + + public float getBrightness(float var1) { + int var4 = (int)this.x; + int var2 = (int)(this.y + this.heightOffset / 2.0F - 0.5F); + int var3 = (int)this.z; + return this.level.getBrightness(var4, var2, var3); + } + + public void render(TextureManager var1, float var2) {} + + public void setLevel(Level var1) { + this.level = var1; + } + + public void playSound(String var1, float var2, float var3) { + this.level.playSound(var1, this, var2, var3); + } + + public void moveTo(float var1, float var2, float var3, float var4, float var5) { + this.xo = this.x = var1; + this.yo = this.y = var2; + this.zo = this.z = var3; + this.yRot = var4; + this.xRot = var5; + this.setPos(var1, var2, var3); + } + + public float distanceTo(Entity var1) { + float var2 = this.x - var1.x; + float var3 = this.y - var1.y; + float var4 = this.z - var1.z; + return MathHelper.sqrt(var2 * var2 + var3 * var3 + var4 * var4); + } + + public float distanceTo(float var1, float var2, float var3) { + var1 = this.x - var1; + var2 = this.y - var2; + float var4 = this.z - var3; + return MathHelper.sqrt(var1 * var1 + var2 * var2 + var4 * var4); + } + + public float distanceToSqr(Entity var1) { + float var2 = this.x - var1.x; + float var3 = this.y - var1.y; + float var4 = this.z - var1.z; + return var2 * var2 + var3 * var3 + var4 * var4; + } + + public void playerTouch(Entity var1) {} + + public void push(Entity var1) { + float var2 = var1.x - this.x; + float var3 = var1.z - this.z; + float var4; + if((var4 = var2 * var2 + var3 * var3) >= 0.01F) { + var4 = MathHelper.sqrt(var4); + var2 /= var4; + var3 /= var4; + var2 /= var4; + var3 /= var4; + var2 *= 0.05F; + var3 *= 0.05F; + var2 *= 1.0F - this.pushthrough; + var3 *= 1.0F - this.pushthrough; + this.push(-var2, 0.0F, -var3); + var1.push(var2, 0.0F, var3); + } + + } + + protected void push(float var1, float var2, float var3) { + this.xd += var1; + this.yd += var2; + this.zd += var3; + } + + public void hurt(Entity var1, int var2) {} + + public boolean intersects(float var1, float var2, float var3, float var4, float var5, float var6) { + return this.bb.intersects(var1, var2, var3, var4, var5, var6); + } + + public boolean isPickable() { + return false; + } + + public boolean isPushable() { + return false; + } + + public boolean isShootable() { + return false; + } + + public void awardKillScore(Entity var1, int var2) {} + + public boolean shouldRender(Vec3D var1) { + float var2 = this.x - var1.x; + float var3 = this.y - var1.y; + float var4 = this.z - var1.z; + var4 = var2 * var2 + var3 * var3 + var4 * var4; + return this.shouldRenderAtSqrDistance(var4); + } + + public boolean shouldRenderAtSqrDistance(float var1) { + float var2 = this.bb.getSize() * 64.0F; + return var1 < var2 * var2; + } + + public int getTexture() { + return this.textureId; + } + + public boolean isCreativeModeAllowed() { + return false; + } + + public void renderHover(TextureManager var1, float var2) {} +} diff --git a/src/main/java/com/mojang/minecraft/GameSettings.java b/src/main/java/com/mojang/minecraft/GameSettings.java new file mode 100644 index 0000000..06f11af --- /dev/null +++ b/src/main/java/com/mojang/minecraft/GameSettings.java @@ -0,0 +1,287 @@ +package com.mojang.minecraft; + +import com.mojang.minecraft.render.TextureManager; +import java.awt.image.BufferedImage; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Iterator; +import javax.imageio.ImageIO; +import org.lwjgl.input.Keyboard; + +import com.mojang.minecraft.gamemode.*; +import com.mojang.minecraft.player.Inventory; + +public final class GameSettings +{ + public GameSettings(Minecraft minecraft, File minecraftFolder) + { + bindings = new KeyBinding[] {forwardKey, leftKey, backKey, rightKey, jumpKey, buildKey, chatKey, toggleFogKey, saveLocationKey, loadLocationKey}; + + settingCount = 8; + + this.minecraft = minecraft; + + settingsFile = new File(minecraftFolder, "options.txt"); + + load(); + } + + private static final String[] renderDistances = new String[]{"FAR", "NORMAL", "SHORT", "TINY"}; + public boolean music = true; + public boolean sound = true; + public boolean invertMouse = false; + public boolean showFrameRate = false; + public int viewDistance = 0; + public boolean viewBobbing = true; + public boolean anaglyph = false; + public boolean limitFramerate = false; + public boolean ofBetterGrass = false; + public boolean ofFastMath = true; + public boolean ofSmoothFPS = false; + public boolean gamemode = false; + public boolean randomDrops = false; + public KeyBinding forwardKey = new KeyBinding("Forward", 17); + public KeyBinding leftKey = new KeyBinding("Left", 30); + public KeyBinding backKey = new KeyBinding("Back", 31); + public KeyBinding rightKey = new KeyBinding("Right", 32); + public KeyBinding jumpKey = new KeyBinding("Jump", 57); + public KeyBinding buildKey = new KeyBinding("Build", 48); + public KeyBinding chatKey = new KeyBinding("Chat", 20); + public KeyBinding toggleFogKey = new KeyBinding("Toggle fog", 33); + public KeyBinding saveLocationKey = new KeyBinding("Save location", 28); + public KeyBinding loadLocationKey = new KeyBinding("Load location", 19); + public KeyBinding[] bindings; + private Minecraft minecraft; + private File settingsFile; + public int settingCount; + + public String getBinding(int key) + { + return bindings[key].name + ": " + Keyboard.getKeyName(bindings[key].key); + } + + public void setBinding(int key, int keyID) + { + bindings[key].key = keyID; + + save(); + } + + public void toggleSetting(int setting, int fogValue) + { + if(setting == 0) + { + music = !music; + } + + if(setting == 1) + { + sound = !sound; + } + + if(setting == 2) + { + invertMouse = !invertMouse; + } + + if(setting == 3) + { + showFrameRate = !showFrameRate; + } + + if(setting == 4) + { + viewDistance = viewDistance + fogValue & 3; + } + + if(setting == 5) + { + viewBobbing = !viewBobbing; + } + + if(setting == 6) + { + minecraft.levelRenderer.refresh(); + anaglyph = !anaglyph; + minecraft.levelRenderer.refresh(); + } + + if(setting == 7) + { + limitFramerate = !limitFramerate; + } + + if(setting == 8) { + ofBetterGrass = !ofBetterGrass; + minecraft.levelRenderer.refresh(); + } + + if(setting == 9) { + ofFastMath = !ofFastMath; + minecraft.levelRenderer.refresh(); + } + + if(setting == 11) { + if(gamemode) { + GameMode game = new SurvivalGameMode(minecraft); + game.apply(minecraft.level); + game.apply(minecraft.player); + minecraft.gamemode = game; + } else { + GameMode game = new CreativeGameMode(minecraft); + game.apply(minecraft.level); + game.apply(minecraft.player); + minecraft.gamemode = game; + } + gamemode = !gamemode; + } + + if(setting == 12) { + randomDrops = !randomDrops; + } + + save(); + } + + public String getSetting(int id) + { + return id == 0 ? "Music: " + (music ? "ON" : "OFF") + : (id == 1 ? "Sound: " + (sound ? "ON" : "OFF") + : (id == 2 ? "Invert mouse: " + (invertMouse ? "ON" : "OFF") + : (id == 3 ? "Show FPS: " + (showFrameRate ? "ON" : "OFF") + : (id == 4 ? "Render distance: " + renderDistances[viewDistance] + : (id == 5 ? "View bobbing: " + (viewBobbing ? "ON" : "OFF") + : (id == 6 ? "3d anaglyph: " + (anaglyph ? "ON" : "OFF") + : (id == 7 ? "Limit framerate: " + (limitFramerate ? "ON" : "OFF") + : (id == 8 ? "Better Grass: " + (ofBetterGrass ? "ON" : "OFF") + : (id == 9 ? "Fast Math: " + (ofFastMath ? "ON" : "OFF") + : (id == 10 ? "Smooth FPS: " + (ofSmoothFPS ? "ON" : "OFF") + : (id == 11 ? "GameMode: " + (gamemode ? "Creative" : "Survival") + : (id == 12 ? "Random Drops: " + (randomDrops ? "ON": "OFF") + : "")))))))))))); + } + + private void load() + { + try + { + if(settingsFile.exists()) + { + FileReader fileReader = new FileReader(settingsFile); + BufferedReader reader = new BufferedReader(fileReader); + + String line = null; + + while((line = reader.readLine()) != null) + { + String[] setting = line.split(":"); + + if(setting[0].equals("music")) + { + music = setting[1].equals("true"); + } + + if(setting[0].equals("sound")) + { + sound = setting[1].equals("true"); + } + + if(setting[0].equals("invertYMouse")) + { + invertMouse = setting[1].equals("true"); + } + + if(setting[0].equals("showFrameRate")) + { + showFrameRate = setting[1].equals("true"); + } + + if(setting[0].equals("viewDistance")) + { + viewDistance = Integer.parseInt(setting[1]); + } + + if(setting[0].equals("bobView")) + { + viewBobbing = setting[1].equals("true"); + } + + if(setting[0].equals("anaglyph3d")) + { + anaglyph = setting[1].equals("true"); + } + + if(setting[0].equals("limitFramerate")) + { + limitFramerate = setting[1].equals("true"); + } + + if(setting[0].equals("ofBetterGrass")) + { + ofBetterGrass = setting[1].equals("true"); + } + + if(setting[0].equals("ofFastMath")) + { + ofFastMath = setting[1].equals("true"); + } + + if(setting[0].equals("ofSmoothFPS")) + { + ofSmoothFPS = setting[1].equals("true"); + } + + for(int index = 0; index < this.bindings.length; index++) + { + if(setting[0].equals("key_" + bindings[index].name)) + { + bindings[index].key = Integer.parseInt(setting[1]); + } + } + } + + reader.close(); + } + } catch (Exception e) { + System.out.println("Failed to load options"); + + e.printStackTrace(); + } + } + + private void save() + { + try { + FileWriter fileWriter = new FileWriter(this.settingsFile); + PrintWriter writer = new PrintWriter(fileWriter); + + writer.println("music:" + music); + writer.println("sound:" + sound); + writer.println("invertYMouse:" + invertMouse); + writer.println("showFrameRate:" + showFrameRate); + writer.println("viewDistance:" + viewDistance); + writer.println("bobView:" + viewBobbing); + writer.println("anaglyph3d:" + anaglyph); + writer.println("limitFramerate:" + limitFramerate); + writer.println("ofBetterGrass:" + ofBetterGrass); + writer.println("ofFastMath:" + ofFastMath); + writer.println("ofSmoothFPS:" + ofSmoothFPS); + + for(int binding = 0; binding < bindings.length; binding++) + { + writer.println("key_" + bindings[binding].name + ":" + bindings[binding].key); + } + + writer.close(); + } catch (Exception e) { + System.out.println("Failed to save options"); + + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/com/mojang/minecraft/KeyBinding.java b/src/main/java/com/mojang/minecraft/KeyBinding.java new file mode 100644 index 0000000..b97a0d1 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/KeyBinding.java @@ -0,0 +1,13 @@ +package com.mojang.minecraft; + +public class KeyBinding +{ + public KeyBinding(String name, int key) + { + this.name = name; + this.key = key; + } + + public String name; + public int key; +} diff --git a/src/main/java/com/mojang/minecraft/Minecraft$OS.java b/src/main/java/com/mojang/minecraft/Minecraft$OS.java new file mode 100644 index 0000000..53e2455 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/Minecraft$OS.java @@ -0,0 +1,16 @@ +package com.mojang.minecraft; + +public enum Minecraft$OS +{ + linux("linux", 0), + solaris("solaris", 1), + windows("windows", 2), + macos("macos", 3), + unknown("unknown", 4); + + private static final Minecraft$OS[] values = new Minecraft$OS[] {linux, solaris, windows, macos, unknown}; + + private Minecraft$OS(String name, int id) + { + } +} diff --git a/src/main/java/com/mojang/minecraft/Minecraft.java b/src/main/java/com/mojang/minecraft/Minecraft.java new file mode 100644 index 0000000..6c8dc75 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/Minecraft.java @@ -0,0 +1,1804 @@ +package com.mojang.minecraft; + +import com.mojang.minecraft.gamemode.CreativeGameMode; +import com.mojang.minecraft.gamemode.GameMode; +import com.mojang.minecraft.gamemode.SurvivalGameMode; +import com.mojang.minecraft.gui.*; +import com.mojang.minecraft.item.Arrow; +import com.mojang.minecraft.item.Item; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.level.LevelIO; +import com.mojang.minecraft.level.generator.LevelGenerator; +import com.mojang.minecraft.level.liquid.LiquidType; +import com.mojang.minecraft.level.tile.Block; +import com.mojang.minecraft.mob.Mob; +import com.mojang.minecraft.model.HumanoidModel; +import com.mojang.minecraft.model.ModelManager; +import com.mojang.minecraft.model.ModelPart; +import com.mojang.minecraft.model.Vec3D; +import com.mojang.minecraft.net.NetworkManager; +import com.mojang.minecraft.net.NetworkPlayer; +import com.mojang.minecraft.net.PacketType; +import com.mojang.minecraft.particle.Particle; +import com.mojang.minecraft.particle.ParticleManager; +import com.mojang.minecraft.particle.WaterDropParticle; +import com.mojang.minecraft.phys.AABB; +import com.mojang.minecraft.player.InputHandlerImpl; +import com.mojang.minecraft.player.Player; +import com.mojang.minecraft.render.*; +import com.mojang.minecraft.render.Renderer; +import com.mojang.minecraft.render.texture.TextureFX; +import com.mojang.minecraft.render.texture.TextureLavaFX; +import com.mojang.minecraft.render.texture.TextureWaterFX; +import com.mojang.minecraft.sound.SoundManager; +import com.mojang.minecraft.sound.SoundPlayer; +import com.mojang.net.NetworkHandler; +import com.mojang.util.MathHelper; +import org.lwjgl.BufferUtils; +import org.lwjgl.LWJGLException; +import org.lwjgl.input.Controllers; +import org.lwjgl.input.Cursor; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.Display; +import org.lwjgl.opengl.DisplayMode; +import org.lwjgl.opengl.GL11; +import org.lwjgl.util.glu.GLU; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioSystem; +import javax.swing.*; +import java.awt.*; +import java.io.*; +import java.nio.IntBuffer; +import java.util.Collections; +import java.util.List; + +public final class Minecraft implements Runnable { + + public GameMode gamemode = new SurvivalGameMode(this); + private boolean fullscreen = false; + public int width; + public int height; + private Timer timer = new Timer(20.0F); + public Level level; + public LevelRenderer levelRenderer; + public Player player; + public ParticleManager particleManager; + public SessionData session = null; + public String host; + public Canvas canvas; + public boolean levelLoaded = false; + public volatile boolean waiting = false; + private Cursor cursor; + public TextureManager textureManager; + public FontRenderer fontRenderer; + public GuiScreen currentScreen = null; + public ProgressBarDisplay progressBar = new ProgressBarDisplay(this); + public Renderer renderer = new Renderer(this); + public LevelIO levelIo; + public SoundManager sound; + private ResourceDownloadThread resourceThread; + private int ticks; + private int blockHitTime; + public String levelName; + public int levelId; + public Robot robot; + public HUDScreen hud; + public boolean online; + public NetworkManager networkManager; + public SoundPlayer soundPlayer; + public MovingObjectPosition selected; + public static GameSettings settings; + private MinecraftApplet applet; + String server; + int port; + volatile boolean running; + public String debug; + public boolean hasMouse; + private int lastClick; + public boolean raining; + + + public Minecraft(Canvas var1, MinecraftApplet var2, int var3, int var4, boolean var5) { + this.levelIo = new LevelIO(this.progressBar); + this.sound = new SoundManager(); + this.ticks = 0; + this.blockHitTime = 0; + this.levelName = null; + this.levelId = 0; + this.online = false; + new HumanoidModel(0.0F); + this.selected = null; + this.server = null; + this.port = 0; + this.running = false; + this.debug = ""; + this.hasMouse = false; + this.lastClick = 0; + this.raining = false; + + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (Exception var7) { + var7.printStackTrace(); + } + + this.applet = var2; + new SleepForeverThread(this); + this.canvas = var1; + this.width = var3; + this.height = var4; + this.fullscreen = var5; + if(var1 != null) { + try { + this.robot = new Robot(); + return; + } catch (AWTException var8) { + var8.printStackTrace(); + } + } + + } + + public final void setCurrentScreen(GuiScreen var1) { + if(!(this.currentScreen instanceof ErrorScreen)) { + if(this.currentScreen != null) { + this.currentScreen.onClose(); + } + + if(var1 == null && this.player.health <= 0) { + var1 = new GameOverScreen(); + } + + this.currentScreen = (GuiScreen)var1; + if(var1 != null) { + if(this.hasMouse) { + this.player.releaseAllKeys(); + this.hasMouse = false; + if(this.levelLoaded) { + try { + Mouse.setNativeCursor((Cursor)null); + } catch (LWJGLException var4) { + var4.printStackTrace(); + } + } else { + Mouse.setGrabbed(false); + } + } + + int var2 = this.width * 240 / this.height; + int var3 = this.height * 240 / this.height; + ((GuiScreen)var1).open(this, var2, var3); + this.online = false; + } else { + this.grabMouse(); + } + } + } + + private static void checkGLError(String var0) { + int var1; + if((var1 = GL11.glGetError()) != 0) { + String var2 = GLU.gluErrorString(var1); + System.out.println("########## GL ERROR ##########"); + System.out.println("@ " + var0); + System.out.println(var1 + ": " + var2); + System.exit(0); + } + + } + + public final void shutdown() { + try { + if(this.soundPlayer != null) { + SoundPlayer var1 = this.soundPlayer; + this.soundPlayer.running = false; + } + + if(this.resourceThread != null) { + ResourceDownloadThread var4 = this.resourceThread; + this.resourceThread.running = true; + } + } catch (Exception var3) { + ; + } + + Minecraft var5 = this; + if(!this.levelLoaded) { + try { + LevelIO.save(var5.level, (OutputStream)(new FileOutputStream(new File("level.dat")))); + } catch (Exception var2) { + var2.printStackTrace(); + } + } + + Mouse.destroy(); + Keyboard.destroy(); + Display.destroy(); + } + + public final void run() { + this.running = true; + + try { + Minecraft var1 = this; + if(this.canvas != null) { + Display.setParent(this.canvas); + } else if(this.fullscreen) { + Display.setFullscreen(true); + this.width = Display.getDisplayMode().getWidth(); + this.height = Display.getDisplayMode().getHeight(); + } else { + Display.setDisplayMode(new DisplayMode(this.width, this.height)); + } + + Display.setTitle("Minecraft 0.30"); + + try { + Display.create(); + } catch (LWJGLException var57) { + var57.printStackTrace(); + + try { + Thread.sleep(1000L); + } catch (InterruptedException var56) { + ; + } + + Display.create(); + } + + Keyboard.create(); + Mouse.create(); + + try { + Controllers.create(); + } catch (Exception var55) { + var55.printStackTrace(); + } + + checkGLError("Pre startup"); + GL11.glEnable(3553); + GL11.glShadeModel(7425); + GL11.glClearDepth(1.0D); + GL11.glEnable(2929); + GL11.glDepthFunc(515); + GL11.glEnable(3008); + GL11.glAlphaFunc(516, 0.0F); + GL11.glCullFace(1029); + GL11.glMatrixMode(5889); + GL11.glLoadIdentity(); + GL11.glMatrixMode(5888); + checkGLError("Startup"); + String var3 = "minecraftclassicforever"; + String var5 = System.getProperty("user.home", "."); + String var6; + File var7; + switch(OperatingSystemLookup.lookup[((var6 = System.getProperty("os.name").toLowerCase()).contains("win")?Minecraft$OS.windows:(var6.contains("mac")?Minecraft$OS.macos:(var6.contains("solaris")?Minecraft$OS.solaris:(var6.contains("sunos")?Minecraft$OS.solaris:(var6.contains("linux")?Minecraft$OS.linux:(var6.contains("unix")?Minecraft$OS.linux:Minecraft$OS.unknown)))))).ordinal()]) { + case 1: + case 2: + var7 = new File(var5, '.' + var3 + '/'); + break; + case 3: + String var8; + if((var8 = System.getenv("APPDATA")) != null) { + var7 = new File(var8, "." + var3 + '/'); + } else { + var7 = new File(var5, '.' + var3 + '/'); + } + break; + case 4: + var7 = new File(var5, "Library/Application Support/" + var3); + break; + default: + var7 = new File(var5, var3 + '/'); + } + + if(!var7.exists() && !var7.mkdirs()) { + throw new RuntimeException("The working directory could not be created: " + var7); + } + + File var2 = var7; + this.settings = new GameSettings(this, var7); + this.textureManager = new TextureManager(this.settings); + this.textureManager.registerAnimation(new TextureLavaFX()); + this.textureManager.registerAnimation(new TextureWaterFX()); + this.fontRenderer = new FontRenderer(this.settings, "/default.png", this.textureManager); + IntBuffer var9; + (var9 = BufferUtils.createIntBuffer(256)).clear().limit(256); + this.levelRenderer = new LevelRenderer(this, this.textureManager); + Item.initModels(); + Mob.modelCache = new ModelManager(); + GL11.glViewport(0, 0, this.width, this.height); + if(this.server != null && this.session != null) { + Level var85; + (var85 = new Level()).setData(8, 8, 8, new byte[512]); + this.setLevel(var85); + } else { + boolean var10 = false; + + try { + if(var1.levelName != null) { + var1.loadOnlineLevel(var1.levelName, var1.levelId); + } else if(!var1.levelLoaded) { + Level var11 = null; + if((var11 = var1.levelIo.load((InputStream)(new FileInputStream(new File("level.dat"))))) != null) { + var1.setLevel(var11); + } + } + } catch (Exception var54) { + var54.printStackTrace(); + } + + if(this.level == null) { + this.generateLevel(1); + } + } + + this.particleManager = new ParticleManager(this.level, this.textureManager); + if(this.levelLoaded) { + try { + var1.cursor = new Cursor(16, 16, 0, 0, 1, var9, (IntBuffer)null); + } catch (LWJGLException var53) { + var53.printStackTrace(); + } + } + + try { + var1.soundPlayer = new SoundPlayer(var1.settings); + SoundPlayer var4 = var1.soundPlayer; + + try { + AudioFormat var67 = new AudioFormat(44100.0F, 16, 2, true, true); + var4.dataLine = AudioSystem.getSourceDataLine(var67); + var4.dataLine.open(var67, 4410); + var4.dataLine.start(); + var4.running = true; + Thread var72; + (var72 = new Thread(var4)).setDaemon(true); + var72.setPriority(10); + var72.start(); + } catch (Exception var51) { + var51.printStackTrace(); + var4.running = false; + } + + var1.resourceThread = new ResourceDownloadThread(var2, var1); + var1.resourceThread.start(); + } catch (Exception var52) { + ; + } + + checkGLError("Post startup"); + this.hud = new HUDScreen(this, this.width, this.height); + (new SkinDownloadThread(this)).start(); + if(this.server != null && this.session != null) { + this.networkManager = new NetworkManager(this, this.server, this.port, this.session.username, this.session.mppass); + } + } catch (Exception var62) { + var62.printStackTrace(); + JOptionPane.showMessageDialog((Component)null, var62.toString(), "Failed to start Minecraft", 0); + return; + } + + long var13 = System.currentTimeMillis(); + int var15 = 0; + + try { + while(this.running) { + if(this.waiting) { + Thread.sleep(100L); + } else { + if(this.canvas == null && Display.isCloseRequested()) { + this.running = false; + } + + try { + Timer var63 = this.timer; + long var16; + long var18 = (var16 = System.currentTimeMillis()) - var63.lastSysClock; + long var20 = System.nanoTime() / 1000000L; + double var24; + if(var18 > 1000L) { + long var22 = var20 - var63.lastHRClock; + var24 = (double)var18 / (double)var22; + var63.adjustment += (var24 - var63.adjustment) * 0.20000000298023224D; + var63.lastSysClock = var16; + var63.lastHRClock = var20; + } + + if(var18 < 0L) { + var63.lastSysClock = var16; + var63.lastHRClock = var20; + } + + double var95; + var24 = ((var95 = (double)var20 / 1000.0D) - var63.lastHR) * var63.adjustment; + var63.lastHR = var95; + if(var24 < 0.0D) { + var24 = 0.0D; + } + + if(var24 > 1.0D) { + var24 = 1.0D; + } + + var63.elapsedDelta = (float)((double)var63.elapsedDelta + var24 * (double)var63.speed * (double)var63.tps); + var63.elapsedTicks = (int)var63.elapsedDelta; + if(var63.elapsedTicks > 100) { + var63.elapsedTicks = 100; + } + + var63.elapsedDelta -= (float)var63.elapsedTicks; + var63.delta = var63.elapsedDelta; + + for(int var64 = 0; var64 < this.timer.elapsedTicks; ++var64) { + ++this.ticks; + this.tick(); + } + + checkGLError("Pre render"); + GL11.glEnable(3553); + if(!this.online) { + this.gamemode.applyCracks(this.timer.delta); + float var65 = this.timer.delta; + Renderer var66 = this.renderer; + if(this.renderer.displayActive && !Display.isActive()) { + var66.minecraft.pause(); + } + + var66.displayActive = Display.isActive(); + int var68; + int var70; + int var86; + int var81; + if(var66.minecraft.hasMouse) { + var81 = 0; + var86 = 0; + if(var66.minecraft.levelLoaded) { + if(var66.minecraft.canvas != null) { + Point var90; + var70 = (var90 = var66.minecraft.canvas.getLocationOnScreen()).x + var66.minecraft.width / 2; + var68 = var90.y + var66.minecraft.height / 2; + Point var75; + var81 = (var75 = MouseInfo.getPointerInfo().getLocation()).x - var70; + var86 = -(var75.y - var68); + var66.minecraft.robot.mouseMove(var70, var68); + } else { + Mouse.setCursorPosition(var66.minecraft.width / 2, var66.minecraft.height / 2); + } + } else { + var81 = Mouse.getDX(); + var86 = Mouse.getDY(); + } + + byte var91 = 1; + if(var66.minecraft.settings.invertMouse) { + var91 = -1; + } + + var66.minecraft.player.turn((float)var81, (float)(var86 * var91)); + } + + if(!var66.minecraft.online) { + var81 = var66.minecraft.width * 240 / var66.minecraft.height; + var86 = var66.minecraft.height * 240 / var66.minecraft.height; + int var94 = Mouse.getX() * var81 / var66.minecraft.width; + var70 = var86 - Mouse.getY() * var86 / var66.minecraft.height - 1; + if(var66.minecraft.level != null) { + float var80 = var65; + Renderer var82 = var66; + Renderer var27 = var66; + Player var28; + float var29 = (var28 = var66.minecraft.player).xRotO + (var28.xRot - var28.xRotO) * var65; + float var30 = var28.yRotO + (var28.yRot - var28.yRotO) * var65; + Vec3D var31 = var66.getPlayerVector(var65); + float var32 = MathHelper.cos(-var30 * 0.017453292F - 3.1415927F); + float var69 = MathHelper.sin(-var30 * 0.017453292F - 3.1415927F); + float var74 = MathHelper.cos(-var29 * 0.017453292F); + float var33 = MathHelper.sin(-var29 * 0.017453292F); + float var34 = var69 * var74; + float var87 = var32 * var74; + float var36 = var66.minecraft.gamemode.getReachDistance(); + Vec3D var71 = var31.add(var34 * var36, var33 * var36, var87 * var36); + var66.minecraft.selected = var66.minecraft.level.clip(var31, var71); + var74 = var36; + if(var66.minecraft.selected != null) { + var74 = var66.minecraft.selected.vec.distance(var66.getPlayerVector(var65)); + } + + var31 = var66.getPlayerVector(var65); + if(var66.minecraft.gamemode instanceof CreativeGameMode) { + var36 = 32.0F; + } else { + var36 = var74; + } + + var71 = var31.add(var34 * var36, var33 * var36, var87 * var36); + var66.entity = null; + List var37 = var66.minecraft.level.blockMap.getEntities(var28, var28.bb.expand(var34 * var36, var33 * var36, var87 * var36)); + float var35 = 0.0F; + + for(var81 = 0; var81 < var37.size(); ++var81) { + Entity var88; + if((var88 = (Entity)var37.get(var81)).isPickable()) { + var74 = 0.1F; + MovingObjectPosition var78; + if((var78 = var88.bb.grow(var74, var74, var74).clip(var31, var71)) != null && ((var74 = var31.distance(var78.vec)) < var35 || var35 == 0.0F)) { + var27.entity = var88; + var35 = var74; + } + } + } + + if(var27.entity != null && !(var27.minecraft.gamemode instanceof CreativeGameMode)) { + var27.minecraft.selected = new MovingObjectPosition(var27.entity); + } + + int var77 = 0; + + while(true) { + if(var77 >= 2) { + GL11.glColorMask(true, true, true, false); + break; + } + + if(var82.minecraft.settings.anaglyph) { + if(var77 == 0) { + GL11.glColorMask(false, true, true, false); + } else { + GL11.glColorMask(true, false, false, false); + } + } + + Player var126 = var82.minecraft.player; + Level var119 = var82.minecraft.level; + LevelRenderer var89 = var82.minecraft.levelRenderer; + ParticleManager var93 = var82.minecraft.particleManager; + GL11.glViewport(0, 0, var82.minecraft.width, var82.minecraft.height); + Level var26 = var82.minecraft.level; + var28 = var82.minecraft.player; + var29 = 1.0F / (float)(4 - var82.minecraft.settings.viewDistance); + var29 = 1.0F - (float)Math.pow((double)var29, 0.25D); + var30 = (float)(var26.skyColor >> 16 & 255) / 255.0F; + float var117 = (float)(var26.skyColor >> 8 & 255) / 255.0F; + var32 = (float)(var26.skyColor & 255) / 255.0F; + var82.fogRed = (float)(var26.fogColor >> 16 & 255) / 255.0F; + var82.fogBlue = (float)(var26.fogColor >> 8 & 255) / 255.0F; + var82.fogGreen = (float)(var26.fogColor & 255) / 255.0F; + var82.fogRed += (var30 - var82.fogRed) * var29; + var82.fogBlue += (var117 - var82.fogBlue) * var29; + var82.fogGreen += (var32 - var82.fogGreen) * var29; + var82.fogRed *= var82.fogColorMultiplier; + var82.fogBlue *= var82.fogColorMultiplier; + var82.fogGreen *= var82.fogColorMultiplier; + Block var73; + if((var73 = Block.blocks[var26.getTile((int)var28.x, (int)(var28.y + 0.12F), (int)var28.z)]) != null && var73.getLiquidType() != LiquidType.NOT_LIQUID) { + LiquidType var79; + if((var79 = var73.getLiquidType()) == LiquidType.WATER) { + var82.fogRed = 0.02F; + var82.fogBlue = 0.02F; + var82.fogGreen = 0.2F; + } else if(var79 == LiquidType.LAVA) { + var82.fogRed = 0.6F; + var82.fogBlue = 0.1F; + var82.fogGreen = 0.0F; + } + } + + if(var82.minecraft.settings.anaglyph) { + var74 = (var82.fogRed * 30.0F + var82.fogBlue * 59.0F + var82.fogGreen * 11.0F) / 100.0F; + var33 = (var82.fogRed * 30.0F + var82.fogBlue * 70.0F) / 100.0F; + var34 = (var82.fogRed * 30.0F + var82.fogGreen * 70.0F) / 100.0F; + var82.fogRed = var74; + var82.fogBlue = var33; + var82.fogGreen = var34; + } + + GL11.glClearColor(var82.fogRed, var82.fogBlue, var82.fogGreen, 0.0F); + GL11.glClear(16640); + var82.fogColorMultiplier = 1.0F; + GL11.glEnable(2884); + var82.fogEnd = (float)(512 >> (var82.minecraft.settings.viewDistance << 1)); + GL11.glMatrixMode(5889); + GL11.glLoadIdentity(); + var29 = 0.07F; + if(var82.minecraft.settings.anaglyph) { + GL11.glTranslatef((float)(-((var77 << 1) - 1)) * var29, 0.0F, 0.0F); + } + + Player var116 = var82.minecraft.player; + var69 = 70.0F; + if(var116.health <= 0) { + var74 = (float)var116.deathTime + var80; + var69 /= (1.0F - 500.0F / (var74 + 500.0F)) * 2.0F + 1.0F; + } + + GLU.gluPerspective(var69, (float)var82.minecraft.width / (float)var82.minecraft.height, 0.05F, var82.fogEnd); + GL11.glMatrixMode(5888); + GL11.glLoadIdentity(); + if(var82.minecraft.settings.anaglyph) { + GL11.glTranslatef((float)((var77 << 1) - 1) * 0.1F, 0.0F, 0.0F); + } + + var82.hurtEffect(var80); + if(var82.minecraft.settings.viewBobbing) { + var82.applyBobbing(var80); + } + + var116 = var82.minecraft.player; + GL11.glTranslatef(0.0F, 0.0F, -0.1F); + GL11.glRotatef(var116.xRotO + (var116.xRot - var116.xRotO) * var80, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(var116.yRotO + (var116.yRot - var116.yRotO) * var80, 0.0F, 1.0F, 0.0F); + var69 = var116.xo + (var116.x - var116.xo) * var80; + var74 = var116.yo + (var116.y - var116.yo) * var80; + var33 = var116.zo + (var116.z - var116.zo) * var80; + GL11.glTranslatef(-var69, -var74, -var33); + Frustrum var76 = FrustrumImpl.update(); + Frustrum var100 = var76; + LevelRenderer var101 = var82.minecraft.levelRenderer; + + int var98; + for(var98 = 0; var98 < var101.chunkCache.length; ++var98) { + var101.chunkCache[var98].clip(var100); + } + + var101 = var82.minecraft.levelRenderer; + Collections.sort(var82.minecraft.levelRenderer.chunks, new ChunkDirtyDistanceComparator(var126)); + var98 = var101.chunks.size() - 1; + int var105; + if((var105 = var101.chunks.size()) > 3) { + var105 = 3; + } + + int var104; + for(var104 = 0; var104 < var105; ++var104) { + Chunk var118; + (var118 = (Chunk)var101.chunks.remove(var98 - var104)).update(); + var118.loaded = false; + } + + var82.updateFog(); + GL11.glEnable(2912); + var89.sortChunks(var126, 0); + int var83; + int var110; + ShapeRenderer var115; + int var114; + int var125; + int var122; + int var120; + if(var119.isSolid(var126.x, var126.y, var126.z, 0.1F)) { + var120 = (int)var126.x; + var83 = (int)var126.y; + var110 = (int)var126.z; + + for(var122 = var120 - 1; var122 <= var120 + 1; ++var122) { + for(var125 = var83 - 1; var125 <= var83 + 1; ++var125) { + for(int var38 = var110 - 1; var38 <= var110 + 1; ++var38) { + var105 = var38; + var98 = var125; + int var99 = var122; + if((var104 = var89.level.getTile(var122, var125, var38)) != 0 && Block.blocks[var104].isSolid()) { + GL11.glColor4f(0.2F, 0.2F, 0.2F, 1.0F); + GL11.glDepthFunc(513); + var115 = ShapeRenderer.instance; + ShapeRenderer.instance.begin(); + + for(var114 = 0; var114 < 6; ++var114) { + Block.blocks[var104].renderInside(var115, var99, var98, var105, var114); + } + + var115.end(); + GL11.glCullFace(1028); + var115.begin(); + + for(var114 = 0; var114 < 6; ++var114) { + Block.blocks[var104].renderInside(var115, var99, var98, var105, var114); + } + + var115.end(); + GL11.glCullFace(1029); + GL11.glDepthFunc(515); + } + } + } + } + } + + var82.setLighting(true); + Vec3D var103 = var82.getPlayerVector(var80); + var89.level.blockMap.render(var103, var76, var89.textureManager, var80); + var82.setLighting(false); + var82.updateFog(); + float var107 = var80; + ParticleManager var96 = var93; + var29 = -MathHelper.cos(var126.yRot * 3.1415927F / 180.0F); + var117 = -(var30 = -MathHelper.sin(var126.yRot * 3.1415927F / 180.0F)) * MathHelper.sin(var126.xRot * 3.1415927F / 180.0F); + var32 = var29 * MathHelper.sin(var126.xRot * 3.1415927F / 180.0F); + var69 = MathHelper.cos(var126.xRot * 3.1415927F / 180.0F); + + for(var83 = 0; var83 < 2; ++var83) { + if(var96.particles[var83].size() != 0) { + var110 = 0; + if(var83 == 0) { + var110 = var96.textureManager.load("/particles.png"); + } + + if(var83 == 1) { + var110 = var96.textureManager.load("/terrain.png"); + } + + GL11.glBindTexture(3553, var110); + ShapeRenderer var121 = ShapeRenderer.instance; + ShapeRenderer.instance.begin(); + + for(var120 = 0; var120 < var96.particles[var83].size(); ++var120) { + ((Particle)var96.particles[var83].get(var120)).render(var121, var107, var29, var69, var30, var117, var32); + } + + var121.end(); + } + } + + GL11.glBindTexture(3553, var89.textureManager.load("/rock.png")); + GL11.glEnable(3553); + GL11.glCallList(var89.listId); + var82.updateFog(); + var101 = var89; + GL11.glBindTexture(3553, var89.textureManager.load("/clouds.png")); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + var107 = (float)(var89.level.cloudColor >> 16 & 255) / 255.0F; + var29 = (float)(var89.level.cloudColor >> 8 & 255) / 255.0F; + var30 = (float)(var89.level.cloudColor & 255) / 255.0F; + if(var89.minecraft.settings.anaglyph) { + var117 = (var107 * 30.0F + var29 * 59.0F + var30 * 11.0F) / 100.0F; + var32 = (var107 * 30.0F + var29 * 70.0F) / 100.0F; + var69 = (var107 * 30.0F + var30 * 70.0F) / 100.0F; + var107 = var117; + var29 = var32; + var30 = var69; + } + + var115 = ShapeRenderer.instance; + var74 = 0.0F; + var33 = 4.8828125E-4F; + var74 = (float)(var89.level.depth + 2); + var34 = ((float)var89.ticks + var80) * var33 * 0.03F; + var35 = 0.0F; + var115.begin(); + var115.color(var107, var29, var30); + + for(var86 = -2048; var86 < var101.level.width + 2048; var86 += 512) { + for(var125 = -2048; var125 < var101.level.height + 2048; var125 += 512) { + var115.vertexUV((float)var86, var74, (float)(var125 + 512), (float)var86 * var33 + var34, (float)(var125 + 512) * var33); + var115.vertexUV((float)(var86 + 512), var74, (float)(var125 + 512), (float)(var86 + 512) * var33 + var34, (float)(var125 + 512) * var33); + var115.vertexUV((float)(var86 + 512), var74, (float)var125, (float)(var86 + 512) * var33 + var34, (float)var125 * var33); + var115.vertexUV((float)var86, var74, (float)var125, (float)var86 * var33 + var34, (float)var125 * var33); + var115.vertexUV((float)var86, var74, (float)var125, (float)var86 * var33 + var34, (float)var125 * var33); + var115.vertexUV((float)(var86 + 512), var74, (float)var125, (float)(var86 + 512) * var33 + var34, (float)var125 * var33); + var115.vertexUV((float)(var86 + 512), var74, (float)(var125 + 512), (float)(var86 + 512) * var33 + var34, (float)(var125 + 512) * var33); + var115.vertexUV((float)var86, var74, (float)(var125 + 512), (float)var86 * var33 + var34, (float)(var125 + 512) * var33); + } + } + + var115.end(); + GL11.glDisable(3553); + var115.begin(); + var34 = (float)(var101.level.skyColor >> 16 & 255) / 255.0F; + var35 = (float)(var101.level.skyColor >> 8 & 255) / 255.0F; + var87 = (float)(var101.level.skyColor & 255) / 255.0F; + if(var101.minecraft.settings.anaglyph) { + var36 = (var34 * 30.0F + var35 * 59.0F + var87 * 11.0F) / 100.0F; + var69 = (var34 * 30.0F + var35 * 70.0F) / 100.0F; + var74 = (var34 * 30.0F + var87 * 70.0F) / 100.0F; + var34 = var36; + var35 = var69; + var87 = var74; + } + + var115.color(var34, var35, var87); + var74 = (float)(var101.level.depth + 10); + + for(var125 = -2048; var125 < var101.level.width + 2048; var125 += 512) { + for(var68 = -2048; var68 < var101.level.height + 2048; var68 += 512) { + var115.vertex((float)var125, var74, (float)var68); + var115.vertex((float)(var125 + 512), var74, (float)var68); + var115.vertex((float)(var125 + 512), var74, (float)(var68 + 512)); + var115.vertex((float)var125, var74, (float)(var68 + 512)); + } + } + + var115.end(); + GL11.glEnable(3553); + var82.updateFog(); + int var108; + if(var82.minecraft.selected != null) { + GL11.glDisable(3008); + MovingObjectPosition var10001 = var82.minecraft.selected; + var105 = var126.inventory.getSelected(); + boolean var106 = false; + MovingObjectPosition var102 = var10001; + var101 = var89; + ShapeRenderer var113 = ShapeRenderer.instance; + GL11.glEnable(3042); + GL11.glEnable(3008); + GL11.glBlendFunc(770, 1); + GL11.glColor4f(1.0F, 1.0F, 1.0F, (MathHelper.sin((float)System.currentTimeMillis() / 100.0F) * 0.2F + 0.4F) * 0.5F); + if(var89.cracks > 0.0F) { + GL11.glBlendFunc(774, 768); + var108 = var89.textureManager.load("/terrain.png"); + GL11.glBindTexture(3553, var108); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.5F); + GL11.glPushMatrix(); + Block var10000 = (var114 = var89.level.getTile(var102.x, var102.y, var102.z)) > 0?Block.blocks[var114]:null; + var73 = var10000; + var74 = (var10000.x1 + var73.x2) / 2.0F; + var33 = (var73.y1 + var73.y2) / 2.0F; + var34 = (var73.z1 + var73.z2) / 2.0F; + GL11.glTranslatef((float)var102.x + var74, (float)var102.y + var33, (float)var102.z + var34); + var35 = 1.01F; + GL11.glScalef(1.01F, var35, var35); + GL11.glTranslatef(-((float)var102.x + var74), -((float)var102.y + var33), -((float)var102.z + var34)); + var113.begin(); + var113.noColor(); + GL11.glDepthMask(false); + if(var73 == null) { + var73 = Block.STONE; + } + + for(var86 = 0; var86 < 6; ++var86) { + var73.renderSide(var113, var102.x, var102.y, var102.z, var86, 240 + (int)(var101.cracks * 10.0F)); + } + + var113.end(); + GL11.glDepthMask(true); + GL11.glPopMatrix(); + } + + GL11.glDisable(3042); + GL11.glDisable(3008); + var10001 = var82.minecraft.selected; + var126.inventory.getSelected(); + var106 = false; + var102 = var10001; + GL11.glEnable(3042); + GL11.glBlendFunc(770, 771); + GL11.glColor4f(0.0F, 0.0F, 0.0F, 0.4F); + GL11.glLineWidth(2.0F); + GL11.glDisable(3553); + GL11.glDepthMask(false); + var29 = 0.002F; + if((var104 = var89.level.getTile(var102.x, var102.y, var102.z)) > 0) { + AABB var111 = Block.blocks[var104].getSelectionBox(var102.x, var102.y, var102.z).grow(var29, var29, var29); + GL11.glBegin(3); + GL11.glVertex3f(var111.x0, var111.y0, var111.z0); + GL11.glVertex3f(var111.x1, var111.y0, var111.z0); + GL11.glVertex3f(var111.x1, var111.y0, var111.z1); + GL11.glVertex3f(var111.x0, var111.y0, var111.z1); + GL11.glVertex3f(var111.x0, var111.y0, var111.z0); + GL11.glEnd(); + GL11.glBegin(3); + GL11.glVertex3f(var111.x0, var111.y1, var111.z0); + GL11.glVertex3f(var111.x1, var111.y1, var111.z0); + GL11.glVertex3f(var111.x1, var111.y1, var111.z1); + GL11.glVertex3f(var111.x0, var111.y1, var111.z1); + GL11.glVertex3f(var111.x0, var111.y1, var111.z0); + GL11.glEnd(); + GL11.glBegin(1); + GL11.glVertex3f(var111.x0, var111.y0, var111.z0); + GL11.glVertex3f(var111.x0, var111.y1, var111.z0); + GL11.glVertex3f(var111.x1, var111.y0, var111.z0); + GL11.glVertex3f(var111.x1, var111.y1, var111.z0); + GL11.glVertex3f(var111.x1, var111.y0, var111.z1); + GL11.glVertex3f(var111.x1, var111.y1, var111.z1); + GL11.glVertex3f(var111.x0, var111.y0, var111.z1); + GL11.glVertex3f(var111.x0, var111.y1, var111.z1); + GL11.glEnd(); + } + + GL11.glDepthMask(true); + GL11.glEnable(3553); + GL11.glDisable(3042); + GL11.glEnable(3008); + } + + GL11.glBlendFunc(770, 771); + var82.updateFog(); + GL11.glEnable(3553); + GL11.glEnable(3042); + GL11.glBindTexture(3553, var89.textureManager.load("/water.png")); + GL11.glCallList(var89.listId + 1); + GL11.glDisable(3042); + GL11.glEnable(3042); + GL11.glColorMask(false, false, false, false); + var120 = var89.sortChunks(var126, 1); + GL11.glColorMask(true, true, true, true); + if(var82.minecraft.settings.anaglyph) { + if(var77 == 0) { + GL11.glColorMask(false, true, true, false); + } else { + GL11.glColorMask(true, false, false, false); + } + } + + if(var120 > 0) { + GL11.glBindTexture(3553, var89.textureManager.load("/terrain.png")); + if(settings.ofFastMath) { + GL11.glCallLists(var89.buffer_fast); + } else { + GL11.glCallLists(var89.buffer); + } + } + + GL11.glDepthMask(true); + GL11.glDisable(3042); + GL11.glDisable(2912); + if(var82.minecraft.raining) { + float var97 = var80; + var27 = var82; + var28 = var82.minecraft.player; + Level var109 = var82.minecraft.level; + var104 = (int)var28.x; + var108 = (int)var28.y; + var114 = (int)var28.z; + ShapeRenderer var84 = ShapeRenderer.instance; + GL11.glDisable(2884); + GL11.glNormal3f(0.0F, 1.0F, 0.0F); + GL11.glEnable(3042); + GL11.glBlendFunc(770, 771); + //GL11.glBindTexture(3553, var82.minecraft.textureManager.load("/rain.png")); + + for(var110 = var104 - 5; var110 <= var104 + 5; ++var110) { + for(var122 = var114 - 5; var122 <= var114 + 5; ++var122) { + var120 = var109.getHighestTile(var110, var122); + var86 = var108 - 5; + var125 = var108 + 5; + if(var86 < var120) { + var86 = var120; + } + + if(var125 < var120) { + var125 = var120; + } + + if(var86 != var125) { + var74 = ((float)((var27.levelTicks + var110 * 3121 + var122 * 418711) % 32) + var97) / 32.0F; + float var124 = (float)var110 + 0.5F - var28.x; + var35 = (float)var122 + 0.5F - var28.z; + float var92 = MathHelper.sqrt(var124 * var124 + var35 * var35) / (float)5; + GL11.glColor4f(1.0F, 1.0F, 1.0F, (1.0F - var92 * var92) * 0.7F); + var84.begin(); + var84.vertexUV((float)var110, (float)var86, (float)var122, 0.0F, (float)var86 * 2.0F / 8.0F + var74 * 2.0F); + var84.vertexUV((float)(var110 + 1), (float)var86, (float)(var122 + 1), 2.0F, (float)var86 * 2.0F / 8.0F + var74 * 2.0F); + var84.vertexUV((float)(var110 + 1), (float)var125, (float)(var122 + 1), 2.0F, (float)var125 * 2.0F / 8.0F + var74 * 2.0F); + var84.vertexUV((float)var110, (float)var125, (float)var122, 0.0F, (float)var125 * 2.0F / 8.0F + var74 * 2.0F); + var84.vertexUV((float)var110, (float)var86, (float)(var122 + 1), 0.0F, (float)var86 * 2.0F / 8.0F + var74 * 2.0F); + var84.vertexUV((float)(var110 + 1), (float)var86, (float)var122, 2.0F, (float)var86 * 2.0F / 8.0F + var74 * 2.0F); + var84.vertexUV((float)(var110 + 1), (float)var125, (float)var122, 2.0F, (float)var125 * 2.0F / 8.0F + var74 * 2.0F); + var84.vertexUV((float)var110, (float)var125, (float)(var122 + 1), 0.0F, (float)var125 * 2.0F / 8.0F + var74 * 2.0F); + var84.end(); + } + } + } + + GL11.glEnable(2884); + GL11.glDisable(3042); + } + + if(var82.entity != null) { + var82.entity.renderHover(var82.minecraft.textureManager, var80); + } + + GL11.glClear(256); + GL11.glLoadIdentity(); + if(var82.minecraft.settings.anaglyph) { + GL11.glTranslatef((float)((var77 << 1) - 1) * 0.1F, 0.0F, 0.0F); + } + + var82.hurtEffect(var80); + if(var82.minecraft.settings.viewBobbing) { + var82.applyBobbing(var80); + } + + HeldBlock var112 = var82.heldBlock; + var117 = var82.heldBlock.lastPos + (var112.pos - var112.lastPos) * var80; + var116 = var112.minecraft.player; + GL11.glPushMatrix(); + GL11.glRotatef(var116.xRotO + (var116.xRot - var116.xRotO) * var80, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(var116.yRotO + (var116.yRot - var116.yRotO) * var80, 0.0F, 1.0F, 0.0F); + var112.minecraft.renderer.setLighting(true); + GL11.glPopMatrix(); + GL11.glPushMatrix(); + var69 = 0.8F; + if(var112.moving) { + var33 = MathHelper.sin((var74 = ((float)var112.offset + var80) / 7.0F) * 3.1415927F); + GL11.glTranslatef(-MathHelper.sin(MathHelper.sqrt(var74) * 3.1415927F) * 0.4F, MathHelper.sin(MathHelper.sqrt(var74) * 3.1415927F * 2.0F) * 0.2F, -var33 * 0.2F); + } + + GL11.glTranslatef(0.7F * var69, -0.65F * var69 - (1.0F - var117) * 0.6F, -0.9F * var69); + GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F); + GL11.glEnable(2977); + if(var112.moving) { + var33 = MathHelper.sin((var74 = ((float)var112.offset + var80) / 7.0F) * var74 * 3.1415927F); + GL11.glRotatef(MathHelper.sin(MathHelper.sqrt(var74) * 3.1415927F) * 80.0F, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(-var33 * 20.0F, 1.0F, 0.0F, 0.0F); + } + + GL11.glColor4f(var74 = var112.minecraft.level.getBrightness((int)var116.x, (int)var116.y, (int)var116.z), var74, var74, 1.0F); + ShapeRenderer var123 = ShapeRenderer.instance; + if(var112.block != null) { + var34 = 0.4F; + GL11.glScalef(0.4F, var34, var34); + GL11.glTranslatef(-0.5F, -0.5F, -0.5F); + GL11.glBindTexture(3553, var112.minecraft.textureManager.load("/terrain.png")); + var112.block.renderPreview(var123); + } else { + var116.bindTexture(var112.minecraft.textureManager); + GL11.glScalef(1.0F, -1.0F, -1.0F); + GL11.glTranslatef(0.0F, 0.2F, 0.0F); + GL11.glRotatef(-120.0F, 0.0F, 0.0F, 1.0F); + GL11.glScalef(1.0F, 1.0F, 1.0F); + var34 = 0.0625F; + ModelPart var127; + if(!(var127 = var112.minecraft.player.getModel().leftArm).hasList) { + var127.generateList(var34); + } + + GL11.glCallList(var127.list); + } + + GL11.glDisable(2977); + GL11.glPopMatrix(); + var112.minecraft.renderer.setLighting(false); + if(!var82.minecraft.settings.anaglyph) { + break; + } + + ++var77; + } + + var66.minecraft.hud.render(var65, var66.minecraft.currentScreen != null, var94, var70); + } else { + GL11.glViewport(0, 0, var66.minecraft.width, var66.minecraft.height); + GL11.glClearColor(0.0F, 0.0F, 0.0F, 0.0F); + GL11.glClear(16640); + GL11.glMatrixMode(5889); + GL11.glLoadIdentity(); + GL11.glMatrixMode(5888); + GL11.glLoadIdentity(); + var66.enableGuiMode(); + } + + if(var66.minecraft.currentScreen != null) { + var66.minecraft.currentScreen.render(var94, var70); + } + + Thread.yield(); + Display.update(); + } + } + + if(this.settings.limitFramerate) { + Thread.sleep(5L); + } + + checkGLError("Post render"); + ++var15; + } catch (Exception var58) { + this.setCurrentScreen(new ErrorScreen("Client error", "The game broke! [" + var58 + "]")); + var58.printStackTrace(); + } + + while(System.currentTimeMillis() >= var13 + 1000L) { + this.debug = var15 + " fps, " + Chunk.chunkUpdates + " chunk updates"; + Chunk.chunkUpdates = 0; + var13 += 1000L; + var15 = 0; + } + } + } + + return; + } catch (StopGameException var59) { + ; + } catch (Exception var60) { + var60.printStackTrace(); + return; + } finally { + this.shutdown(); + } + + } + + public final void grabMouse() { + if(!this.hasMouse) { + this.hasMouse = true; + if(this.levelLoaded) { + try { + Mouse.setNativeCursor(this.cursor); + Mouse.setCursorPosition(this.width / 2, this.height / 2); + } catch (LWJGLException var2) { + var2.printStackTrace(); + } + + if(this.canvas == null) { + this.canvas.requestFocus(); + } + } else { + Mouse.setGrabbed(true); + } + + this.setCurrentScreen((GuiScreen)null); + this.lastClick = this.ticks + 10000; + } + } + + public final void pause() { + if(this.currentScreen == null) { + this.setCurrentScreen(new PauseScreen()); + } + } + + private void onMouseClick(int var1) { + if(var1 != 0 || this.blockHitTime <= 0) { + HeldBlock var2; + if(var1 == 0) { + var2 = this.renderer.heldBlock; + this.renderer.heldBlock.offset = -1; + var2.moving = true; + } + + int var3; + if(var1 == 1 && (var3 = this.player.inventory.getSelected()) > 0 && this.gamemode.useItem(this.player, var3)) { + var2 = this.renderer.heldBlock; + this.renderer.heldBlock.pos = 0.0F; + } else if(this.selected == null) { + if(var1 == 0 && !(this.gamemode instanceof CreativeGameMode)) { + this.blockHitTime = 10; + } + + } else { + if(this.selected.entityPos == 1) { + if(var1 == 0) { + this.selected.entity.hurt(this.player, 4); + return; + } + } else if(this.selected.entityPos == 0) { + var3 = this.selected.x; + int var4 = this.selected.y; + int var5 = this.selected.z; + if(var1 != 0) { + if(this.selected.face == 0) { + --var4; + } + + if(this.selected.face == 1) { + ++var4; + } + + if(this.selected.face == 2) { + --var5; + } + + if(this.selected.face == 3) { + ++var5; + } + + if(this.selected.face == 4) { + --var3; + } + + if(this.selected.face == 5) { + ++var3; + } + } + + Block var6 = Block.blocks[this.level.getTile(var3, var4, var5)]; + if(var1 == 0) { + if(var6 != Block.BEDROCK || this.player.userType >= 100) { + this.gamemode.hitBlock(var3, var4, var5); + return; + } + } else { + int var10; + if((var10 = this.player.inventory.getSelected()) <= 0) { + return; + } + + Block var8; + AABB var9; + if(((var8 = Block.blocks[this.level.getTile(var3, var4, var5)]) == null || var8 == Block.WATER || var8 == Block.STATIONARY_WATER || var8 == Block.LAVA || var8 == Block.STATIONARY_LAVA) && ((var9 = Block.blocks[var10].getCollisionBox(var3, var4, var5)) == null || (this.player.bb.intersects(var9)?false:this.level.isFree(var9)))) { + if(!this.gamemode.canPlace(var10)) { + return; + } + + if(this.isOnline()) { + this.networkManager.sendBlockChange(var3, var4, var5, var1, var10); + } + + this.level.netSetTile(var3, var4, var5, var10); + var2 = this.renderer.heldBlock; + this.renderer.heldBlock.pos = 0.0F; + Block.blocks[var10].onPlace(this.level, var3, var4, var5); + } + } + } + + } + } + } + + private void tick() { + if(this.soundPlayer != null) { + SoundPlayer var1 = this.soundPlayer; + SoundManager var2 = this.sound; + if(System.currentTimeMillis() > var2.lastMusic && var2.playMusic(var1, "calm")) { + var2.lastMusic = System.currentTimeMillis() + (long)var2.random.nextInt(900000) + 300000L; + } + } + + this.gamemode.spawnMob(); + HUDScreen var17 = this.hud; + ++this.hud.ticks; + + int var16; + for(var16 = 0; var16 < var17.chat.size(); ++var16) { + ++((ChatLine)var17.chat.get(var16)).time; + } + + GL11.glBindTexture(3553, this.textureManager.load("/terrain.png")); + TextureManager var19 = this.textureManager; + + for(var16 = 0; var16 < var19.animations.size(); ++var16) { + TextureFX var3; + (var3 = (TextureFX)var19.animations.get(var16)).anaglyph = var19.settings.anaglyph; + var3.animate(); + var19.textureBuffer.clear(); + var19.textureBuffer.put(var3.textureData); + var19.textureBuffer.position(0).limit(var3.textureData.length); + GL11.glTexSubImage2D(3553, 0, var3.textureId % 16 << 4, var3.textureId / 16 << 4, 16, 16, 6408, 5121, var19.textureBuffer); + } + + int var4; + int var8; + int var40; + int var46; + int var45; + if(this.networkManager != null && !(this.currentScreen instanceof ErrorScreen)) { + if(!this.networkManager.isConnected()) { + this.progressBar.setTitle("Connecting.."); + this.progressBar.setProgress(0); + } else { + NetworkManager var20 = this.networkManager; + if(this.networkManager.successful) { + NetworkHandler var18 = var20.netHandler; + if(var20.netHandler.connected) { + try { + NetworkHandler var22 = var20.netHandler; + var20.netHandler.channel.read(var22.in); + var4 = 0; + + while(var22.in.position() > 0 && var4++ != 100) { + var22.in.flip(); + byte var5 = var22.in.get(0); + PacketType var6; + if((var6 = PacketType.packets[var5]) == null) { + throw new IOException("Bad command: " + var5); + } + + if(var22.in.remaining() < var6.length + 1) { + var22.in.compact(); + break; + } + + var22.in.get(); + Object[] var7 = new Object[var6.params.length]; + + for(var8 = 0; var8 < var7.length; ++var8) { + var7[var8] = var22.readObject(var6.params[var8]); + } + + NetworkManager var42 = var22.netManager; + if(var22.netManager.successful) { + if(var6 == PacketType.IDENTIFICATION) { + var42.minecraft.progressBar.setTitle(var7[1].toString()); + var42.minecraft.progressBar.setText(var7[2].toString()); + var42.minecraft.player.userType = ((Byte)var7[3]).byteValue(); + } else if(var6 == PacketType.LEVEL_INIT) { + var42.minecraft.setLevel((Level)null); + var42.levelData = new ByteArrayOutputStream(); + } else if(var6 == PacketType.LEVEL_DATA) { + short var11 = ((Short)var7[0]).shortValue(); + byte[] var12 = (byte[])((byte[])var7[1]); + byte var13 = ((Byte)var7[2]).byteValue(); + var42.minecraft.progressBar.setProgress(var13); + var42.levelData.write(var12, 0, var11); + } else if(var6 == PacketType.LEVEL_FINALIZE) { + try { + var42.levelData.close(); + } catch (IOException var14) { + var14.printStackTrace(); + } + + byte[] var51 = LevelIO.decompress(new ByteArrayInputStream(var42.levelData.toByteArray())); + var42.levelData = null; + short var55 = ((Short)var7[0]).shortValue(); + short var63 = ((Short)var7[1]).shortValue(); + short var21 = ((Short)var7[2]).shortValue(); + Level var30; + (var30 = new Level()).setNetworkMode(true); + var30.setData(var55, var63, var21, var51); + var42.minecraft.setLevel(var30); + var42.minecraft.online = false; + var42.levelLoaded = true; + } else if(var6 == PacketType.BLOCK_CHANGE) { + if(var42.minecraft.level != null) { + var42.minecraft.level.netSetTile(((Short)var7[0]).shortValue(), ((Short)var7[1]).shortValue(), ((Short)var7[2]).shortValue(), ((Byte)var7[3]).byteValue()); + } + } else { + byte var9; + String var34; + NetworkPlayer var33; + short var36; + short var10004; + byte var10001; + short var47; + short var10003; + if(var6 == PacketType.SPAWN_PLAYER) { + var10001 = ((Byte)var7[0]).byteValue(); + String var10002 = (String)var7[1]; + var10003 = ((Short)var7[2]).shortValue(); + var10004 = ((Short)var7[3]).shortValue(); + short var10005 = ((Short)var7[4]).shortValue(); + byte var10006 = ((Byte)var7[5]).byteValue(); + byte var58 = ((Byte)var7[6]).byteValue(); + var9 = var10006; + short var10 = var10005; + var47 = var10004; + var36 = var10003; + var34 = var10002; + var5 = var10001; + if(var5 >= 0) { + var9 = (byte)(var9 + 128); + var47 = (short)(var47 - 22); + var33 = new NetworkPlayer(var42.minecraft, var5, var34, var36, var47, var10, (float)(var9 * 360) / 256.0F, (float)(var58 * 360) / 256.0F); + var42.players.put(Byte.valueOf(var5), var33); + var42.minecraft.level.addEntity(var33); + } else { + var42.minecraft.level.setSpawnPos(var36 / 32, var47 / 32, var10 / 32, (float)(var9 * 320 / 256)); + var42.minecraft.player.moveTo((float)var36 / 32.0F, (float)var47 / 32.0F, (float)var10 / 32.0F, (float)(var9 * 360) / 256.0F, (float)(var58 * 360) / 256.0F); + } + } else { + byte var53; + NetworkPlayer var61; + byte var69; + if(var6 == PacketType.POSITION_ROTATION) { + var10001 = ((Byte)var7[0]).byteValue(); + short var66 = ((Short)var7[1]).shortValue(); + var10003 = ((Short)var7[2]).shortValue(); + var10004 = ((Short)var7[3]).shortValue(); + var69 = ((Byte)var7[4]).byteValue(); + var9 = ((Byte)var7[5]).byteValue(); + var53 = var69; + var47 = var10004; + var36 = var10003; + short var38 = var66; + var5 = var10001; + if(var5 < 0) { + var42.minecraft.player.moveTo((float)var38 / 32.0F, (float)var36 / 32.0F, (float)var47 / 32.0F, (float)(var53 * 360) / 256.0F, (float)(var9 * 360) / 256.0F); + } else { + var53 = (byte)(var53 + 128); + var36 = (short)(var36 - 22); + if((var61 = (NetworkPlayer)var42.players.get(Byte.valueOf(var5))) != null) { + var61.teleport(var38, var36, var47, (float)(var53 * 360) / 256.0F, (float)(var9 * 360) / 256.0F); + } + } + } else { + byte var37; + byte var44; + byte var49; + byte var65; + byte var67; + if(var6 == PacketType.POSITION_ROTATION_UPDATE) { + var10001 = ((Byte)var7[0]).byteValue(); + var67 = ((Byte)var7[1]).byteValue(); + var65 = ((Byte)var7[2]).byteValue(); + byte var64 = ((Byte)var7[3]).byteValue(); + var69 = ((Byte)var7[4]).byteValue(); + var9 = ((Byte)var7[5]).byteValue(); + var53 = var69; + var49 = var64; + var44 = var65; + var37 = var67; + var5 = var10001; + if(var5 >= 0) { + var53 = (byte)(var53 + 128); + if((var61 = (NetworkPlayer)var42.players.get(Byte.valueOf(var5))) != null) { + var61.queue(var37, var44, var49, (float)(var53 * 360) / 256.0F, (float)(var9 * 360) / 256.0F); + } + } + } else if(var6 == PacketType.ROTATION_UPDATE) { + var10001 = ((Byte)var7[0]).byteValue(); + var67 = ((Byte)var7[1]).byteValue(); + var44 = ((Byte)var7[2]).byteValue(); + var37 = var67; + var5 = var10001; + if(var5 >= 0) { + var37 = (byte)(var37 + 128); + NetworkPlayer var54; + if((var54 = (NetworkPlayer)var42.players.get(Byte.valueOf(var5))) != null) { + var54.queue((float)(var37 * 360) / 256.0F, (float)(var44 * 360) / 256.0F); + } + } + } else if(var6 == PacketType.POSITION_UPDATE) { + var10001 = ((Byte)var7[0]).byteValue(); + var67 = ((Byte)var7[1]).byteValue(); + var65 = ((Byte)var7[2]).byteValue(); + var49 = ((Byte)var7[3]).byteValue(); + var44 = var65; + var37 = var67; + var5 = var10001; + NetworkPlayer var59; + if(var5 >= 0 && (var59 = (NetworkPlayer)var42.players.get(Byte.valueOf(var5))) != null) { + var59.queue(var37, var44, var49); + } + } else if(var6 == PacketType.DESPAWN_PLAYER) { + var5 = ((Byte)var7[0]).byteValue(); + if(var5 >= 0 && (var33 = (NetworkPlayer)var42.players.remove(Byte.valueOf(var5))) != null) { + var33.clear(); + var42.minecraft.level.removeEntity(var33); + } + } else if(var6 == PacketType.CHAT_MESSAGE) { + var10001 = ((Byte)var7[0]).byteValue(); + var34 = (String)var7[1]; + var5 = var10001; + if(var5 < 0) { + var42.minecraft.hud.addChat("&e" + var34); + } else { + var42.players.get(Byte.valueOf(var5)); + var42.minecraft.hud.addChat(var34); + } + } else if(var6 == PacketType.DISCONNECT) { + var42.netHandler.close(); + var42.minecraft.setCurrentScreen(new ErrorScreen("Connection lost", (String)var7[0])); + } else if(var6 == PacketType.UPDATE_PLAYER_TYPE) { + var42.minecraft.player.userType = ((Byte)var7[0]).byteValue(); + } + } + } + } + } + + if(!var22.connected) { + break; + } + + var22.in.compact(); + } + + if(var22.out.position() > 0) { + var22.out.flip(); + var22.channel.write(var22.out); + var22.out.compact(); + } + } catch (Exception var15) { + var20.minecraft.setCurrentScreen(new ErrorScreen("Disconnected!", "You\'ve lost connection to the server")); + var20.minecraft.online = false; + var15.printStackTrace(); + var20.netHandler.close(); + var20.minecraft.networkManager = null; + } + } + } + + Player var28 = this.player; + var20 = this.networkManager; + if(this.networkManager.levelLoaded) { + int var24 = (int)(var28.x * 32.0F); + var4 = (int)(var28.y * 32.0F); + var40 = (int)(var28.z * 32.0F); + var46 = (int)(var28.yRot * 256.0F / 360.0F) & 255; + var45 = (int)(var28.xRot * 256.0F / 360.0F) & 255; + var20.netHandler.send(PacketType.POSITION_ROTATION, new Object[]{Integer.valueOf(-1), Integer.valueOf(var24), Integer.valueOf(var4), Integer.valueOf(var40), Integer.valueOf(var46), Integer.valueOf(var45)}); + } + } + } + + if(this.currentScreen == null && this.player != null && this.player.health <= 0) { + this.setCurrentScreen((GuiScreen)null); + } + + if(this.currentScreen == null || this.currentScreen.grabsMouse) { + int var25; + while(Mouse.next()) { + if((var25 = Mouse.getEventDWheel()) != 0) { + this.player.inventory.swapPaint(var25); + } + + if(this.currentScreen == null) { + if(!this.hasMouse && Mouse.getEventButtonState()) { + this.grabMouse(); + } else { + if(Mouse.getEventButton() == 0 && Mouse.getEventButtonState()) { + this.onMouseClick(0); + this.lastClick = this.ticks; + } + + if(Mouse.getEventButton() == 1 && Mouse.getEventButtonState()) { + this.onMouseClick(1); + this.lastClick = this.ticks; + } + + if(Mouse.getEventButton() == 2 && Mouse.getEventButtonState() && this.selected != null) { + if((var16 = this.level.getTile(this.selected.x, this.selected.y, this.selected.z)) == Block.GRASS.id) { + var16 = Block.DIRT.id; + } + + if(var16 == Block.DOUBLE_SLAB.id) { + var16 = Block.SLAB.id; + } + + if(var16 == Block.BEDROCK.id) { + var16 = Block.STONE.id; + } + + this.player.inventory.grabTexture(var16, this.gamemode instanceof CreativeGameMode); + } + } + } + + if(this.currentScreen != null) { + this.currentScreen.mouseEvent(); + } + } + + if(this.blockHitTime > 0) { + --this.blockHitTime; + } + + while(Keyboard.next()) { + this.player.setKey(Keyboard.getEventKey(), Keyboard.getEventKeyState()); + if(Keyboard.getEventKeyState()) { + if(this.currentScreen != null) { + this.currentScreen.keyboardEvent(); + } + + if(this.currentScreen == null) { + if(Keyboard.getEventKey() == 1) { + this.pause(); + } + + if(this.gamemode instanceof CreativeGameMode) { + if(Keyboard.getEventKey() == this.settings.loadLocationKey.key) { + this.player.resetPos(); + } + + if(Keyboard.getEventKey() == this.settings.saveLocationKey.key) { + this.level.setSpawnPos((int)this.player.x, (int)this.player.y, (int)this.player.z, this.player.yRot); + this.player.resetPos(); + } + } + + Keyboard.getEventKey(); + if(Keyboard.getEventKey() == 63) { + this.raining = !this.raining; + } + + if(Keyboard.getEventKey() == 15 && this.gamemode instanceof SurvivalGameMode && this.player.arrows > 0) { + this.level.addEntity(new Arrow(this.level, this.player, this.player.x, this.player.y, this.player.z, this.player.yRot, this.player.xRot, 1.2F)); + --this.player.arrows; + } + + if(Keyboard.getEventKey() == this.settings.buildKey.key) { + this.gamemode.openInventory(); + } + + if(Keyboard.getEventKey() == this.settings.chatKey.key && this.networkManager != null && this.networkManager.isConnected()) { + this.player.releaseAllKeys(); + this.setCurrentScreen(new ChatInputScreen()); + } + } + + for(var25 = 0; var25 < 9; ++var25) { + if(Keyboard.getEventKey() == var25 + 2) { + this.player.inventory.selected = var25; + } + } + + if(Keyboard.getEventKey() == this.settings.toggleFogKey.key) { + this.settings.toggleSetting(4, !Keyboard.isKeyDown(42) && !Keyboard.isKeyDown(54)?1:-1); + } + } + } + + if(this.currentScreen == null) { + if(Mouse.isButtonDown(0) && (float)(this.ticks - this.lastClick) >= this.timer.tps / 4.0F && this.hasMouse) { + this.onMouseClick(0); + this.lastClick = this.ticks; + } + + if(Mouse.isButtonDown(1) && (float)(this.ticks - this.lastClick) >= this.timer.tps / 4.0F && this.hasMouse) { + this.onMouseClick(1); + this.lastClick = this.ticks; + } + } + + boolean var26 = this.currentScreen == null && Mouse.isButtonDown(0) && this.hasMouse; + boolean var35 = false; + if(!this.gamemode.instantBreak && this.blockHitTime <= 0) { + if(var26 && this.selected != null && this.selected.entityPos == 0) { + var4 = this.selected.x; + var40 = this.selected.y; + var46 = this.selected.z; + this.gamemode.hitBlock(var4, var40, var46, this.selected.face); + } else { + this.gamemode.resetHits(); + } + } + } + + if(this.currentScreen != null) { + this.lastClick = this.ticks + 10000; + } + + if(this.currentScreen != null) { + this.currentScreen.doInput(); + if(this.currentScreen != null) { + this.currentScreen.tick(); + } + } + + if(this.level != null) { + Renderer var29 = this.renderer; + ++this.renderer.levelTicks; + HeldBlock var41 = var29.heldBlock; + var29.heldBlock.lastPos = var41.pos; + if(var41.moving) { + ++var41.offset; + if(var41.offset == 7) { + var41.offset = 0; + var41.moving = false; + } + } + + Player var27 = var41.minecraft.player; + var4 = var41.minecraft.player.inventory.getSelected(); + Block var43 = null; + if(var4 > 0) { + var43 = Block.blocks[var4]; + } + + float var48 = 0.4F; + float var50; + if((var50 = (var43 == var41.block?1.0F:0.0F) - var41.pos) < -var48) { + var50 = -var48; + } + + if(var50 > var48) { + var50 = var48; + } + + var41.pos += var50; + if(var41.pos < 0.1F) { + var41.block = var43; + } + + if(var29.minecraft.raining) { + Renderer var39 = var29; + var27 = var29.minecraft.player; + Level var32 = var29.minecraft.level; + var40 = (int)var27.x; + var46 = (int)var27.y; + var45 = (int)var27.z; + + for(var8 = 0; var8 < 50; ++var8) { + int var60 = var40 + var39.random.nextInt(9) - 4; + int var52 = var45 + var39.random.nextInt(9) - 4; + int var57; + if((var57 = var32.getHighestTile(var60, var52)) <= var46 + 4 && var57 >= var46 - 4) { + float var56 = var39.random.nextFloat(); + float var62 = var39.random.nextFloat(); + var39.minecraft.particleManager.spawnParticle(new WaterDropParticle(var32, (float)var60 + var56, (float)var57 + 0.1F, (float)var52 + var62)); + } + } + } + + LevelRenderer var31 = this.levelRenderer; + ++this.levelRenderer.ticks; + this.level.tickEntities(); + if(!this.isOnline()) { + this.level.tick(); + } + + this.particleManager.tick(); + } + + } + + public final boolean isOnline() { + return this.networkManager != null; + } + + public final void generateLevel(int var1) { + String var2 = this.session != null?this.session.username:"anonymous"; + Level var4 = (new LevelGenerator(this.progressBar)).generate(var2, 128 << var1, 128 << var1, 64); + this.gamemode.prepareLevel(var4); + this.setLevel(var4); + } + + public final boolean loadOnlineLevel(String var1, int var2) { + Level var3; + if((var3 = this.levelIo.loadOnline(this.host, var1, var2)) == null) { + return false; + } else { + this.setLevel(var3); + return true; + } + } + + public final void setLevel(Level var1) { + if(this.applet == null || !this.applet.getDocumentBase().getHost().equalsIgnoreCase("minecraft.net") && !this.applet.getDocumentBase().getHost().equalsIgnoreCase("www.minecraft.net") || !this.applet.getCodeBase().getHost().equalsIgnoreCase("minecraft.net") && !this.applet.getCodeBase().getHost().equalsIgnoreCase("www.minecraft.net")) { + var1 = null; + } + + this.level = var1; + if(var1 != null) { + var1.initTransient(); + this.gamemode.apply(var1); + var1.font = this.fontRenderer; + var1.rendererContext$5cd64a7f = this; + if(!this.isOnline()) { + this.player = (Player)var1.findSubclassOf(Player.class); + } else if(this.player != null) { + this.player.resetPos(); + this.gamemode.preparePlayer(this.player); + if(var1 != null) { + var1.player = this.player; + var1.addEntity(this.player); + } + } + } + + if(this.player == null) { + this.player = new Player(var1); + this.player.resetPos(); + this.gamemode.preparePlayer(this.player); + if(var1 != null) { + var1.player = this.player; + } + } + + if(this.player != null) { + this.player.input = new InputHandlerImpl(this.settings); + this.gamemode.apply(this.player); + } + + if(this.levelRenderer != null) { + LevelRenderer var3 = this.levelRenderer; + if(this.levelRenderer.level != null) { + var3.level.removeListener(var3); + } + + var3.level = var1; + if(var1 != null) { + var1.addListener(var3); + var3.refresh(); + } + } + + if(this.particleManager != null) { + ParticleManager var5 = this.particleManager; + if(var1 != null) { + var1.particleEngine = var5; + } + + for(int var4 = 0; var4 < 2; ++var4) { + var5.particles[var4].clear(); + } + } + + System.gc(); + } +} diff --git a/src/main/java/com/mojang/minecraft/MinecraftApplet$1.java b/src/main/java/com/mojang/minecraft/MinecraftApplet$1.java new file mode 100644 index 0000000..d2ed969 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/MinecraftApplet$1.java @@ -0,0 +1,32 @@ +package com.mojang.minecraft; + +import java.awt.Canvas; + +// MinecraftCanvas +public class MinecraftApplet$1 extends Canvas +{ + public MinecraftApplet$1(MinecraftApplet minecraftApplet) + { + this.applet = minecraftApplet; + } + + @Override + public synchronized void addNotify() + { + super.addNotify(); + + applet.startGameThread(); + } + + @Override + public synchronized void removeNotify() + { + applet.stopGameThread(); + + super.removeNotify(); + } + + private static final long serialVersionUID = 1L; + + private MinecraftApplet applet; +} diff --git a/src/main/java/com/mojang/minecraft/MinecraftApplet.java b/src/main/java/com/mojang/minecraft/MinecraftApplet.java new file mode 100644 index 0000000..a835106 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/MinecraftApplet.java @@ -0,0 +1,115 @@ +package com.mojang.minecraft; + +import java.applet.Applet; +import java.awt.BorderLayout; +import java.awt.Canvas; + +public class MinecraftApplet extends Applet +{ + private static final long serialVersionUID = 1L; + + private Canvas canvas; + private Minecraft minecraft; + + private Thread thread = null; + + public void init() + { + canvas = new MinecraftApplet$1(this); + + boolean fullscreen = false; + + if(getParameter("fullscreen") != null) + { + fullscreen = getParameter("fullscreen").equalsIgnoreCase("true"); + } + + minecraft = new Minecraft(canvas, this, getWidth(), getHeight(), fullscreen); + + minecraft.host = getDocumentBase().getHost(); + + if(getDocumentBase().getPort() > 0) + { + minecraft.host = minecraft.host + ":" + getDocumentBase().getPort(); + } + + if(getParameter("username") != null && getParameter("sessionid") != null) + { + minecraft.session = new SessionData(getParameter("username"), getParameter("sessionid")); + + if(getParameter("mppass") != null) + { + minecraft.session.mppass = getParameter("mppass"); + } + + // TODO: Not tested. + minecraft.session.haspaid = getParameter("haspaid").equalsIgnoreCase("true"); + } + + if(getParameter("loadmap_user") != null && getParameter("loadmap_id") != null) + { + minecraft.levelName = getParameter("loadmap_user"); + minecraft.levelId = Integer.parseInt(getParameter("loadmap_id")); + } else if(getParameter("server") != null && getParameter("port") != null) { + String server = getParameter("server"); + int port = Integer.parseInt(getParameter("port")); + + minecraft.server = server; + minecraft.port = port; + } + + minecraft.levelLoaded = true; + + setLayout(new BorderLayout()); + + add(canvas, "Center"); + + canvas.setFocusable(true); + + validate(); + } + + public void startGameThread() + { + if(thread == null) + { + thread = new Thread(minecraft); + + thread.start(); + } + } + + @Override + public void start() + { + minecraft.waiting = false; + } + + @Override + public void stop() + { + minecraft.waiting = true; + } + + @Override + public void destroy() + { + stopGameThread(); + } + + public void stopGameThread() + { + if(thread != null) + { + minecraft.running = false; + + try { + thread.join(1000L); + } catch (InterruptedException var3) { + minecraft.shutdown(); + } + + thread = null; + } + } +} diff --git a/src/main/java/com/mojang/minecraft/MovingObjectPosition.java b/src/main/java/com/mojang/minecraft/MovingObjectPosition.java new file mode 100644 index 0000000..07a3980 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/MovingObjectPosition.java @@ -0,0 +1,37 @@ +package com.mojang.minecraft; + +import com.mojang.minecraft.model.Vec3D; + +public class MovingObjectPosition +{ + public MovingObjectPosition(int x, int y, int z, int side, Vec3D blockPos) + { + entityPos = 0; + + this.x = x; + this.y = y; + this.z = z; + + this.face = side; + + vec = new Vec3D(blockPos.x, blockPos.y, blockPos.z); + } + + public MovingObjectPosition(Entity entity) + { + entityPos = 1; + this.entity = entity; + } + + public int entityPos; + + public int x; + public int y; + public int z; + + public int face; + + public Vec3D vec; + + public Entity entity; +} diff --git a/src/main/java/com/mojang/minecraft/OperatingSystemLookup.java b/src/main/java/com/mojang/minecraft/OperatingSystemLookup.java new file mode 100644 index 0000000..fb9071c --- /dev/null +++ b/src/main/java/com/mojang/minecraft/OperatingSystemLookup.java @@ -0,0 +1,37 @@ +package com.mojang.minecraft; + +import com.mojang.minecraft.Minecraft$OS; + +// $FF: synthetic class +final class OperatingSystemLookup { + + // $FF: synthetic field + static final int[] lookup = new int[Minecraft$OS.values().length]; + + + static { + try { + lookup[Minecraft$OS.linux.ordinal()] = 1; + } catch (NoSuchFieldError var3) { + ; + } + + try { + lookup[Minecraft$OS.solaris.ordinal()] = 2; + } catch (NoSuchFieldError var2) { + ; + } + + try { + lookup[Minecraft$OS.windows.ordinal()] = 3; + } catch (NoSuchFieldError var1) { + ; + } + + try { + lookup[Minecraft$OS.macos.ordinal()] = 4; + } catch (NoSuchFieldError var0) { + ; + } + } +} diff --git a/src/main/java/com/mojang/minecraft/ProgressBarDisplay.java b/src/main/java/com/mojang/minecraft/ProgressBarDisplay.java new file mode 100644 index 0000000..0d1ca21 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/ProgressBarDisplay.java @@ -0,0 +1,99 @@ +package com.mojang.minecraft; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.StopGameException; +import com.mojang.minecraft.render.ShapeRenderer; +import org.lwjgl.opengl.Display; +import org.lwjgl.opengl.GL11; + +public final class ProgressBarDisplay { + + private String text = ""; + private Minecraft minecraft; + private String title = ""; + private long start = System.currentTimeMillis(); + + + public ProgressBarDisplay(Minecraft var1) { + this.minecraft = var1; + } + + public final void setTitle(String var1) { + if(!this.minecraft.running) { + throw new StopGameException(); + } else { + this.title = var1; + int var3 = this.minecraft.width * 240 / this.minecraft.height; + int var2 = this.minecraft.height * 240 / this.minecraft.height; + GL11.glClear(256); + GL11.glMatrixMode(5889); + GL11.glLoadIdentity(); + GL11.glOrtho(0.0D, (double)var3, (double)var2, 0.0D, 100.0D, 300.0D); + GL11.glMatrixMode(5888); + GL11.glLoadIdentity(); + GL11.glTranslatef(0.0F, 0.0F, -200.0F); + } + } + + public final void setText(String var1) { + if(!this.minecraft.running) { + throw new StopGameException(); + } else { + this.text = var1; + this.setProgress(-1); + } + } + + public final void setProgress(int var1) { + if(!this.minecraft.running) { + throw new StopGameException(); + } else { + long var2; + if((var2 = System.currentTimeMillis()) - this.start < 0L || var2 - this.start >= 20L) { + this.start = var2; + int var4 = this.minecraft.width * 240 / this.minecraft.height; + int var5 = this.minecraft.height * 240 / this.minecraft.height; + GL11.glClear(16640); + ShapeRenderer var6 = ShapeRenderer.instance; + int var7 = this.minecraft.textureManager.load("/dirt.png"); + GL11.glBindTexture(3553, var7); + float var10 = 32.0F; + var6.begin(); + var6.color(4210752); + var6.vertexUV(0.0F, (float)var5, 0.0F, 0.0F, (float)var5 / var10); + var6.vertexUV((float)var4, (float)var5, 0.0F, (float)var4 / var10, (float)var5 / var10); + var6.vertexUV((float)var4, 0.0F, 0.0F, (float)var4 / var10, 0.0F); + var6.vertexUV(0.0F, 0.0F, 0.0F, 0.0F, 0.0F); + var6.end(); + if(var1 >= 0) { + var7 = var4 / 2 - 50; + int var8 = var5 / 2 + 16; + GL11.glDisable(3553); + var6.begin(); + var6.color(8421504); + var6.vertex((float)var7, (float)var8, 0.0F); + var6.vertex((float)var7, (float)(var8 + 2), 0.0F); + var6.vertex((float)(var7 + 100), (float)(var8 + 2), 0.0F); + var6.vertex((float)(var7 + 100), (float)var8, 0.0F); + var6.color(8454016); + var6.vertex((float)var7, (float)var8, 0.0F); + var6.vertex((float)var7, (float)(var8 + 2), 0.0F); + var6.vertex((float)(var7 + var1), (float)(var8 + 2), 0.0F); + var6.vertex((float)(var7 + var1), (float)var8, 0.0F); + var6.end(); + GL11.glEnable(3553); + } + + this.minecraft.fontRenderer.render(this.title, (var4 - this.minecraft.fontRenderer.getWidth(this.title)) / 2, var5 / 2 - 4 - 16, 16777215); + this.minecraft.fontRenderer.render(this.text, (var4 - this.minecraft.fontRenderer.getWidth(this.text)) / 2, var5 / 2 - 4 + 8, 16777215); + Display.update(); + + try { + Thread.yield(); + } catch (Exception var9) { + ; + } + } + } + } +} diff --git a/src/main/java/com/mojang/minecraft/ResourceDownloadThread.java b/src/main/java/com/mojang/minecraft/ResourceDownloadThread.java new file mode 100644 index 0000000..f9f18c2 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/ResourceDownloadThread.java @@ -0,0 +1,244 @@ +package com.mojang.minecraft; + +import java.io.*; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; + +public class ResourceDownloadThread extends Thread +{ + public ResourceDownloadThread(File minecraftFolder, Minecraft minecraft) + { + this.minecraft = minecraft; + + this.setName("Resource download thread"); + this.setDaemon(true); + + dir = new File(minecraftFolder, "resources/"); + + if(!dir.exists() && !dir.mkdirs()) + { + throw new RuntimeException("The working directory could not be created: " + dir); + } + } + + @Override + public void run() + { + BufferedReader reader = null; + + try { + ArrayList list = new ArrayList(); + + URL base = new URL("http://dl.dropbox.com/u/40737374/minecraft_resources/"); + URL url = new URL(base, "resources/"); + + URLConnection con = url.openConnection(); + + con.setConnectTimeout(20000); + + reader = new BufferedReader(new InputStreamReader(con.getInputStream())); + + String line = null; + + while((line = reader.readLine()) != null) + { + list.add(line); + } + + reader.close(); + + /*for(String s : list) + { + try { + String split[] = s.split(","); + int size = Integer.parseInt(split[1]); + File file = new File(dir, split[0]); + + if(!file.exists() || file.length() != size) + { + try { + file.getParentFile().mkdirs(); + } catch(SecurityException e) { + e.printStackTrace(); + } + + URL url1 = new URL(base, split[0].replaceAll(" ", "%20")); + + download(url1, file, size); + } else { + int index = split[0].indexOf("/"); + + if(split[0].substring(0, index).equalsIgnoreCase("sound")) + { + minecraft.sound.registerSound(file, split[0].substring(index + 1, split[0].length() - 4).replaceAll("[1-9]", "").replaceAll("/", ".")); + //this.mc.audio.registerSound(split[0].substring(index + 1, split[0].length() - 4).replaceAll("[1-9]", "").replaceAll("/", "."), file.toURI().toURL(), true); + } else if (split[0].substring(0, index).equalsIgnoreCase("music")) { + if(split[0].contains("sweden")) + { + //this.mc.audio.registerMusic("menu", file.toURI().toURL(), true); + } + + //this.mc.audio.registerMusic("bg", file.toURI().toURL(), true); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + + if (!this.running) return; + }*/ + + for(String s : list) + { + String split[] = s.split(","); + int size = Integer.parseInt(split[1]); + File file = new File(dir, split[0]); + + File musicFolder = new File(dir, "music"); + + if(!file.exists() || file.length() != size) + { + try { + file.getParentFile().mkdirs(); + } catch(SecurityException e) { + e.printStackTrace(); + } + + URL url1 = new URL(base, split[0].replaceAll(" ", "%20")); + + if(file.getPath().contains("music")) + { + if(file.getName().equals("minecraft.ogg") && !new File(musicFolder, "calm1.ogg").exists()) + { + download(url1, file, size); + } else if(file.getName().equals("clark.ogg") && !new File(musicFolder, "calm2.ogg").exists()) { + download(url1, file, size); + } else if(file.getName().equals("sweden.ogg") && !new File(musicFolder, "calm3.ogg").exists()) { + download(url1, file, size); + } + } else { + download(url1, file, size); + } + } + + File minecraftOGG = new File(musicFolder, "minecraft.ogg"); + File clarkOGG = new File(musicFolder, "clark.ogg"); + File swedenOGG = new File(musicFolder, "sweden.ogg"); + + minecraftOGG.renameTo(new File(musicFolder, "calm1.ogg")); + clarkOGG.renameTo(new File(musicFolder, "calm2.ogg")); + swedenOGG.renameTo(new File(musicFolder, "calm3.ogg")); + } + + File soundsFolder = new File(dir, "sound"); + File stepsFolder = new File(soundsFolder, "step"); + + for(int i = 1; i <= 4; i++) + { + minecraft.sound.registerSound(new File(stepsFolder, "grass" + i + ".ogg"), "step/grass" + i + ".ogg"); + minecraft.sound.registerSound(new File(stepsFolder, "gravel" + i + ".ogg"), "step/gravel" + i + ".ogg"); + minecraft.sound.registerSound(new File(stepsFolder, "stone" + i + ".ogg"), "step/stone" + i + ".ogg"); + minecraft.sound.registerSound(new File(stepsFolder, "wood" + i + ".ogg"), "step/wood" + i + ".ogg"); + } + + File musicFolder = new File(dir, "music"); + + for(int i = 1; i <= 3; i++) + { + minecraft.sound.registerMusic("calm" + i + ".ogg", new File(musicFolder, "calm" + i + ".ogg")); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (reader != null) + reader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + this.finished = true; + } + + private File dir; + private Minecraft minecraft; + boolean running = false; + + private boolean finished = false; + private int progress = 0; + + private void download(URL url, File file, int size) + { + System.out.println("Downloading: " + file.getName() + "..."); + + //minecraft.progressBar.setText(file.getName()); + + DataInputStream in = null; + DataOutputStream out = null; + + try + { + byte[] data = new byte[4096]; + + in = new DataInputStream(url.openStream()); + FileOutputStream fos = new FileOutputStream(file); + out = new DataOutputStream(fos); + + int done = 0; + + do + { + int length = in.read(data); + + if(length < 0) + { + in.close(); + out.close(); + + return; + } + + out.write(data, 0, length); + + done += length; + progress = (int)(((double)done / (double)size) * 100); + } while(!running); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try + { + if(in != null) + { + in.close(); + } + + if(out != null) + { + out.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + //minecraft.progressBar.setText(""); + progress = 0; + + System.out.println("Downloaded: " + file.getName()); + } + + public boolean isFinished() + { + return finished; + } + + public int getProgress() + { + return progress; + } +} diff --git a/src/main/java/com/mojang/minecraft/SessionData.java b/src/main/java/com/mojang/minecraft/SessionData.java new file mode 100644 index 0000000..fa354c2 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/SessionData.java @@ -0,0 +1,66 @@ +package com.mojang.minecraft; + +import com.mojang.minecraft.level.tile.Block; +import java.util.ArrayList; +import java.util.List; + +public final class SessionData { + + public static List allowedBlocks; + public String username; + public String sessionId; + public String mppass; + public boolean haspaid; + + + public SessionData(String var1, String var2) { + this.username = var1; + this.sessionId = var2; + } + + static { + (allowedBlocks = new ArrayList()).add(Block.STONE); + allowedBlocks.add(Block.COBBLESTONE); + allowedBlocks.add(Block.BRICK); + allowedBlocks.add(Block.DIRT); + allowedBlocks.add(Block.WOOD); + allowedBlocks.add(Block.LOG); + allowedBlocks.add(Block.LEAVES); + allowedBlocks.add(Block.GLASS); + allowedBlocks.add(Block.SLAB); + allowedBlocks.add(Block.MOSSY_COBBLESTONE); + allowedBlocks.add(Block.SAPLING); + allowedBlocks.add(Block.DANDELION); + allowedBlocks.add(Block.ROSE); + allowedBlocks.add(Block.BROWN_MUSHROOM); + allowedBlocks.add(Block.RED_MUSHROOM); + allowedBlocks.add(Block.SAND); + allowedBlocks.add(Block.GRAVEL); + allowedBlocks.add(Block.SPONGE); + allowedBlocks.add(Block.RED_WOOL); + allowedBlocks.add(Block.ORANGE_WOOL); + allowedBlocks.add(Block.YELLOW_WOOL); + allowedBlocks.add(Block.LIME_WOOL); + allowedBlocks.add(Block.GREEN_WOOL); + allowedBlocks.add(Block.AQUA_GREEN_WOOL); + allowedBlocks.add(Block.CYAN_WOOL); + allowedBlocks.add(Block.BLUE_WOOL); + allowedBlocks.add(Block.PURPLE_WOOL); + allowedBlocks.add(Block.INDIGO_WOOL); + allowedBlocks.add(Block.VIOLET_WOOL); + allowedBlocks.add(Block.MAGENTA_WOOL); + allowedBlocks.add(Block.PINK_WOOL); + allowedBlocks.add(Block.BLACK_WOOL); + allowedBlocks.add(Block.GRAY_WOOL); + allowedBlocks.add(Block.WHITE_WOOL); + allowedBlocks.add(Block.COAL_ORE); + allowedBlocks.add(Block.IRON_ORE); + allowedBlocks.add(Block.GOLD_ORE); + allowedBlocks.add(Block.IRON_BLOCK); + allowedBlocks.add(Block.GOLD_BLOCK); + allowedBlocks.add(Block.BOOKSHELF); + allowedBlocks.add(Block.TNT); + allowedBlocks.add(Block.OBSIDIAN); + allowedBlocks.add(Block.BEDROCK); + } +} diff --git a/src/main/java/com/mojang/minecraft/SkinDownloadThread.java b/src/main/java/com/mojang/minecraft/SkinDownloadThread.java new file mode 100644 index 0000000..5e85d64 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/SkinDownloadThread.java @@ -0,0 +1,51 @@ +package com.mojang.minecraft; + +import com.mojang.minecraft.player.Player; +import java.net.HttpURLConnection; +import java.net.URL; +import javax.imageio.ImageIO; + +public class SkinDownloadThread extends Thread +{ + public SkinDownloadThread(Minecraft minecraft) + { + super(); + + this.minecraft = minecraft; + } + + @Override + public void run() + { + if(minecraft.session != null) + { + HttpURLConnection connection = null; + + try { + connection = (HttpURLConnection)new URL("http://www.minecraft.net/skin/" + minecraft.session.username + ".png").openConnection(); + + connection.setDoInput(true); + connection.setDoOutput(false); + + connection.connect(); + + if(connection.getResponseCode() != 404) + { + Player.newTexture = ImageIO.read(connection.getInputStream()); + + return; + } + } catch (Exception var4) { + var4.printStackTrace(); + } finally { + if(connection != null) + { + connection.disconnect(); + } + } + + } + } + + private Minecraft minecraft; +} diff --git a/src/main/java/com/mojang/minecraft/SleepForeverThread.java b/src/main/java/com/mojang/minecraft/SleepForeverThread.java new file mode 100644 index 0000000..d64606b --- /dev/null +++ b/src/main/java/com/mojang/minecraft/SleepForeverThread.java @@ -0,0 +1,27 @@ +package com.mojang.minecraft; + +public class SleepForeverThread extends Thread +{ + public SleepForeverThread(Minecraft minecraft) + { + setDaemon(true); + + start(); + } + + @Override + public void run() + { + while(true) + { + try { + while(true) + { + Thread.sleep(2147483647L); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } +} diff --git a/src/main/java/com/mojang/minecraft/StopGameException.java b/src/main/java/com/mojang/minecraft/StopGameException.java new file mode 100644 index 0000000..19f8a52 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/StopGameException.java @@ -0,0 +1,6 @@ +package com.mojang.minecraft; + +public class StopGameException extends Error +{ + private static final long serialVersionUID = 1L; +} diff --git a/src/main/java/com/mojang/minecraft/Timer.java b/src/main/java/com/mojang/minecraft/Timer.java new file mode 100644 index 0000000..ab2bbe5 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/Timer.java @@ -0,0 +1,21 @@ +package com.mojang.minecraft; + +public class Timer +{ + public Timer(float tps) + { + this.tps = tps; + lastSysClock = System.currentTimeMillis(); + lastHRClock = System.nanoTime() / 1000000L; + } + + float tps; + double lastHR; + public int elapsedTicks; + public float delta; + public float speed = 1.0F; + public float elapsedDelta = 0.0F; + long lastSysClock; + long lastHRClock; + double adjustment = 1.0D; +} diff --git a/src/main/java/com/mojang/minecraft/gamemode/CreativeGameMode.java b/src/main/java/com/mojang/minecraft/gamemode/CreativeGameMode.java new file mode 100644 index 0000000..33361bd --- /dev/null +++ b/src/main/java/com/mojang/minecraft/gamemode/CreativeGameMode.java @@ -0,0 +1,58 @@ +package com.mojang.minecraft.gamemode; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.SessionData; +import com.mojang.minecraft.gui.BlockSelectScreen; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.level.tile.Block; +import com.mojang.minecraft.player.Player; + +public class CreativeGameMode extends GameMode +{ + public CreativeGameMode(Minecraft minecraft) + { + super(minecraft); + + instantBreak = true; + } + + @Override + public void apply(Level level) + { + super.apply(level); + + level.removeAllNonCreativeModeEntities(); + + level.creativeMode = true; + level.growTrees = false; + } + + @Override + public void openInventory() + { + BlockSelectScreen blockSelectScreen = new BlockSelectScreen(); + + minecraft.setCurrentScreen(blockSelectScreen); + } + + @Override + public boolean isSurvival() + { + return false; + } + + @Override + public void apply(Player player) + { + for(int slot = 0; slot < 9; slot++) + { + player.inventory.count[slot] = 1; + + if(player.inventory.slots[slot] <= 0) + { + player.inventory.slots[slot] = ((Block)SessionData.allowedBlocks.get(slot)).id; + } + } + + } +} diff --git a/src/main/java/com/mojang/minecraft/gamemode/GameMode.java b/src/main/java/com/mojang/minecraft/gamemode/GameMode.java new file mode 100644 index 0000000..c823ca4 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/gamemode/GameMode.java @@ -0,0 +1,108 @@ +package com.mojang.minecraft.gamemode; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.level.tile.Block; +import com.mojang.minecraft.level.tile.Tile$SoundType; +import com.mojang.minecraft.player.Player; + +public class GameMode +{ + public GameMode(Minecraft minecraft) + { + this.minecraft = minecraft; + + instantBreak = false; + } + + public Minecraft minecraft; + + public boolean instantBreak; + + public void apply(Level level) + { + level.creativeMode = false; + level.growTrees = true; + } + + public void openInventory() + { + } + + public void hitBlock(int x, int y, int z) + { + this.breakBlock(x, y, z); + } + + public boolean canPlace(int block) + { + return true; + } + + public void breakBlock(int x, int y, int z) + { + Level level = minecraft.level; + Block block = Block.blocks[level.getTile(x, y, z)]; + + boolean success = level.netSetTile(x, y, z, 0); + + if(block != null && success) + { + if(minecraft.isOnline()) + { + minecraft.networkManager.sendBlockChange(x, y, z, 0, minecraft.player.inventory.getSelected()); + } + + if(block.stepsound != Tile$SoundType.none) + { + level.playSound("step." + block.stepsound.name, (float)x, (float)y, (float)z, (block.stepsound.getVolume() + 1.0F) / 2.0F, block.stepsound.getPitch() * 0.8F); + } + + block.spawnBreakParticles(level, x, y, z, minecraft.particleManager); + } + + } + + public void hitBlock(int x, int y, int z, int side) + { + } + + public void resetHits() + { + } + + public void applyCracks(float time) + { + } + + public float getReachDistance() + { + return 5.0F; + } + + public boolean useItem(Player player, int type) + { + return false; + } + + public void preparePlayer(Player player) + { + } + + public void spawnMob() + { + } + + public void prepareLevel(Level level) + { + } + + public boolean isSurvival() + { + return true; + } + + public void apply(Player player) + { + } +} diff --git a/src/main/java/com/mojang/minecraft/gamemode/SurvivalGameMode.java b/src/main/java/com/mojang/minecraft/gamemode/SurvivalGameMode.java new file mode 100644 index 0000000..6c055f0 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/gamemode/SurvivalGameMode.java @@ -0,0 +1,174 @@ +package com.mojang.minecraft.gamemode; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.level.MobSpawner; +import com.mojang.minecraft.level.tile.Block; +import com.mojang.minecraft.mob.Mob; +import com.mojang.minecraft.player.Player; + +public final class SurvivalGameMode extends GameMode +{ + public SurvivalGameMode(Minecraft minecraft) + { + super(minecraft); + } + + private int hitX; + private int hitY; + private int hitZ; + private int hits; + private int hardness; + private int hitDelay; + private MobSpawner spawner; + + @Override + public void apply(Level level) + { + super.apply(level); + + spawner = new MobSpawner(level); + } + + @Override + public void hitBlock(int x, int y, int z, int side) + { + if(hitDelay > 0) + { + hitDelay--; + } else if(x == hitX && y == hitY && z == hitZ) { + int type = minecraft.level.getTile(x, y, z); + + if(type != 0) + { + Block block = Block.blocks[type]; + + hardness = block.getHardness(); + + block.spawnBlockParticles(minecraft.level, x, y, z, side, minecraft.particleManager); + + hits++; + + if(hits == hardness + 1) + { + breakBlock(x, y, z); + + hits = 0; + hitDelay = 5; + } + + } + } else { + // TODO: I think if I don't set hits to 0 you can continue breaking from where you left off. + + hits = 0; + hitX = x; + hitY = y; + hitZ = z; + } + } + + @Override + public boolean canPlace(int block) + { + return minecraft.player.inventory.removeResource(block); + } + + @Override + public void breakBlock(int x, int y, int z) + { + int block = minecraft.level.getTile(x, y, z); + Block.blocks[block].onBreak(minecraft.level, x, y, z); + + super.breakBlock(x, y, z); + } + + @Override + public void hitBlock(int x, int y, int z) + { + int block = this.minecraft.level.getTile(x, y, z); + + if(block > 0 && Block.blocks[block].getHardness() == 0) + { + breakBlock(x, y, z); + } + } + + @Override + public void resetHits() + { + this.hits = 0; + this.hitDelay = 0; + } + + @Override + public void applyCracks(float time) + { + if(hits <= 0) + { + minecraft.levelRenderer.cracks = 0.0F; + } else { + minecraft.levelRenderer.cracks = ((float)hits + time - 1.0F) / (float)hardness; + } + } + + @Override + public float getReachDistance() + { + return 4.0F; + } + + @Override + public boolean useItem(Player player, int type) + { + Block block = Block.blocks[type]; + if(block == Block.RED_MUSHROOM && minecraft.player.inventory.removeResource(type)) + { + player.hurt(null, 3); + + return true; + } else if(block == Block.BROWN_MUSHROOM && minecraft.player.inventory.removeResource(type)) { + player.heal(5); + + return true; + } else { + return false; + } + } + + @Override + public void preparePlayer(Player player) + { + player.inventory.slots[8] = Block.TNT.id; + player.inventory.count[8] = (int) 1e+5; + } + + @Override + public void spawnMob() + { + int area = spawner.level.width * spawner.level.height * spawner.level.depth / 64 / 64 / 64; + + if(spawner.level.random.nextInt(100) < area && spawner.level.countInstanceOf(Mob.class) < area * 20) + { + spawner.spawn(area, spawner.level.player, null); + } + + } + + @Override + public void prepareLevel(Level level) + { + spawner = new MobSpawner(level); + + minecraft.progressBar.setText("Spawning.."); + + int area = level.width * level.height * level.depth / 800; + + spawner.spawn(area, null, minecraft.progressBar); + } + + @Override + public void apply(Player player) { + + } +} diff --git a/src/main/java/com/mojang/minecraft/gui/BlockSelectScreen.java b/src/main/java/com/mojang/minecraft/gui/BlockSelectScreen.java new file mode 100644 index 0000000..34fa93d --- /dev/null +++ b/src/main/java/com/mojang/minecraft/gui/BlockSelectScreen.java @@ -0,0 +1,74 @@ +package com.mojang.minecraft.gui; + +import com.mojang.minecraft.SessionData; +import com.mojang.minecraft.gui.GuiScreen; +import com.mojang.minecraft.level.tile.Block; +import com.mojang.minecraft.render.ShapeRenderer; +import com.mojang.minecraft.render.TextureManager; +import org.lwjgl.opengl.GL11; + +public final class BlockSelectScreen extends GuiScreen { + + public BlockSelectScreen() { + this.grabsMouse = true; + } + + private int getBlockOnScreen(int var1, int var2) { + for(int var3 = 0; var3 < SessionData.allowedBlocks.size(); ++var3) { + int var4 = this.width / 2 + var3 % 9 * 24 + -108 - 3; + int var5 = this.height / 2 + var3 / 9 * 24 + -60 + 3; + if(var1 >= var4 && var1 <= var4 + 24 && var2 >= var5 - 12 && var2 <= var5 + 12) { + return var3; + } + } + + return -1; + } + + public final void render(int var1, int var2) { + var1 = this.getBlockOnScreen(var1, var2); + drawFadingBox(this.width / 2 - 120, 30, this.width / 2 + 120, 180, -1878719232, -1070583712); + if(var1 >= 0) { + var2 = this.width / 2 + var1 % 9 * 24 + -108; + int var3 = this.height / 2 + var1 / 9 * 24 + -60; + drawFadingBox(var2 - 3, var3 - 8, var2 + 23, var3 + 24 - 6, -1862270977, -1056964609); + } + + drawCenteredString(this.fontRenderer, "Select block", this.width / 2, 40, 16777215); + TextureManager var7 = this.minecraft.textureManager; + ShapeRenderer var8 = ShapeRenderer.instance; + var2 = var7.load("/terrain.png"); + GL11.glBindTexture(3553, var2); + + for(var2 = 0; var2 < SessionData.allowedBlocks.size(); ++var2) { + Block var4 = (Block)SessionData.allowedBlocks.get(var2); + GL11.glPushMatrix(); + int var5 = this.width / 2 + var2 % 9 * 24 + -108; + int var6 = this.height / 2 + var2 / 9 * 24 + -60; + GL11.glTranslatef((float)var5, (float)var6, 0.0F); + GL11.glScalef(10.0F, 10.0F, 10.0F); + GL11.glTranslatef(1.0F, 0.5F, 8.0F); + GL11.glRotatef(-30.0F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F); + if(var1 == var2) { + GL11.glScalef(1.6F, 1.6F, 1.6F); + } + + GL11.glTranslatef(-1.5F, 0.5F, 0.5F); + GL11.glScalef(-1.0F, -1.0F, -1.0F); + var8.begin(); + var4.renderFullbright(var8); + var8.end(); + GL11.glPopMatrix(); + } + + } + + protected final void onMouseClick(int var1, int var2, int var3) { + if(var3 == 0) { + this.minecraft.player.inventory.replaceSlot(this.getBlockOnScreen(var1, var2)); + this.minecraft.setCurrentScreen((GuiScreen)null); + } + + } +} diff --git a/src/main/java/com/mojang/minecraft/gui/Button.java b/src/main/java/com/mojang/minecraft/gui/Button.java new file mode 100644 index 0000000..5488333 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/gui/Button.java @@ -0,0 +1,33 @@ +package com.mojang.minecraft.gui; + +import com.mojang.minecraft.gui.Screen; + +public class Button extends Screen { + + int width; + int height; + public int x; + public int y; + public String text; + public int id; + public boolean active; + public boolean visible; + + + public Button(int var1, int var2, int var3, String var4) { + this(var1, var2, var3, 200, 20, var4); + } + + protected Button(int var1, int var2, int var3, int var4, int var5, String var6) { + this.width = 200; + this.height = 20; + this.active = true; + this.visible = true; + this.id = var1; + this.x = var2; + this.y = var3; + this.width = var4; + this.height = 20; + this.text = var6; + } +} diff --git a/src/main/java/com/mojang/minecraft/gui/ChatInputScreen.java b/src/main/java/com/mojang/minecraft/gui/ChatInputScreen.java new file mode 100644 index 0000000..b16eeb1 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/gui/ChatInputScreen.java @@ -0,0 +1,69 @@ +package com.mojang.minecraft.gui; + +import com.mojang.minecraft.gui.GuiScreen; +import com.mojang.minecraft.net.NetworkManager; +import com.mojang.minecraft.net.PacketType; +import org.lwjgl.input.Keyboard; + +public final class ChatInputScreen extends GuiScreen { + + private String message = ""; + private int counter = 0; + + + public final void onOpen() { + Keyboard.enableRepeatEvents(true); + } + + public final void onClose() { + Keyboard.enableRepeatEvents(false); + } + + public final void tick() { + ++this.counter; + } + + protected final void onKeyPress(char var1, int var2) { + if(var2 == 1) { + this.minecraft.setCurrentScreen((GuiScreen)null); + } else if(var2 == 28) { + NetworkManager var10000 = this.minecraft.networkManager; + String var4 = this.message.trim(); + NetworkManager var3 = var10000; + if((var4 = var4.trim()).length() > 0) { + var3.netHandler.send(PacketType.CHAT_MESSAGE, new Object[]{Integer.valueOf(-1), var4}); + } + + this.minecraft.setCurrentScreen((GuiScreen)null); + } else { + if(var2 == 14 && this.message.length() > 0) { + this.message = this.message.substring(0, this.message.length() - 1); + } + + if("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ,.:-_\'*!\\\"#%/()=+?[]{}<>@|$;".indexOf(var1) >= 0 && this.message.length() < 64 - (this.minecraft.session.username.length() + 2)) { + this.message = this.message + var1; + } + + } + } + + public final void render(int var1, int var2) { + drawBox(2, this.height - 14, this.width - 2, this.height - 2, Integer.MIN_VALUE); + drawString(this.fontRenderer, "> " + this.message + (this.counter / 6 % 2 == 0?"_":""), 4, this.height - 12, 14737632); + } + + protected final void onMouseClick(int var1, int var2, int var3) { + if(var3 == 0 && this.minecraft.hud.hoveredPlayer != null) { + if(this.message.length() > 0 && !this.message.endsWith(" ")) { + this.message = this.message + " "; + } + + this.message = this.message + this.minecraft.hud.hoveredPlayer; + var1 = 64 - (this.minecraft.session.username.length() + 2); + if(this.message.length() > var1) { + this.message = this.message.substring(0, var1); + } + } + + } +} diff --git a/src/main/java/com/mojang/minecraft/gui/ControlsScreen.java b/src/main/java/com/mojang/minecraft/gui/ControlsScreen.java new file mode 100644 index 0000000..bf7052a --- /dev/null +++ b/src/main/java/com/mojang/minecraft/gui/ControlsScreen.java @@ -0,0 +1,57 @@ +package com.mojang.minecraft.gui; + +import com.mojang.minecraft.GameSettings; +import com.mojang.minecraft.gui.Button; +import com.mojang.minecraft.gui.GuiScreen; +import com.mojang.minecraft.gui.OptionButton; + +public final class ControlsScreen extends GuiScreen { + + private GuiScreen parent; + private String title = "Controls"; + private GameSettings settings; + private int selected = -1; + + + public ControlsScreen(GuiScreen var1, GameSettings var2) { + this.parent = var1; + this.settings = var2; + } + + public final void onOpen() { + for(int var1 = 0; var1 < this.settings.bindings.length; ++var1) { + this.buttons.add(new OptionButton(var1, this.width / 2 - 155 + var1 % 2 * 160, this.height / 6 + 24 * (var1 >> 1), this.settings.getBinding(var1))); + } + + this.buttons.add(new Button(200, this.width / 2 - 100, this.height / 6 + 168, "Done")); + } + + protected final void onButtonClick(Button var1) { + for(int var2 = 0; var2 < this.settings.bindings.length; ++var2) { + ((Button)this.buttons.get(var2)).text = this.settings.getBinding(var2); + } + + if(var1.id == 200) { + this.minecraft.setCurrentScreen(this.parent); + } else { + this.selected = var1.id; + var1.text = "> " + this.settings.getBinding(var1.id) + " <"; + } + } + + protected final void onKeyPress(char var1, int var2) { + if(this.selected >= 0) { + this.settings.setBinding(this.selected, var2); + ((Button)this.buttons.get(this.selected)).text = this.settings.getBinding(this.selected); + this.selected = -1; + } else { + super.onKeyPress(var1, var2); + } + } + + public final void render(int var1, int var2) { + drawFadingBox(0, 0, this.width, this.height, 1610941696, -1607454624); + drawCenteredString(this.fontRenderer, this.title, this.width / 2, 20, 16777215); + super.render(var1, var2); + } +} diff --git a/src/main/java/com/mojang/minecraft/gui/ErrorScreen.java b/src/main/java/com/mojang/minecraft/gui/ErrorScreen.java new file mode 100644 index 0000000..6fe51d1 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/gui/ErrorScreen.java @@ -0,0 +1,26 @@ +package com.mojang.minecraft.gui; + +import com.mojang.minecraft.gui.GuiScreen; + +public final class ErrorScreen extends GuiScreen { + + private String title; + private String text; + + + public ErrorScreen(String var1, String var2) { + this.title = var1; + this.text = var2; + } + + public final void onOpen() {} + + public final void render(int var1, int var2) { + drawFadingBox(0, 0, this.width, this.height, -12574688, -11530224); + drawCenteredString(this.fontRenderer, this.title, this.width / 2, 90, 16777215); + drawCenteredString(this.fontRenderer, this.text, this.width / 2, 110, 16777215); + super.render(var1, var2); + } + + protected final void onKeyPress(char var1, int var2) {} +} diff --git a/src/main/java/com/mojang/minecraft/gui/FontRenderer.java b/src/main/java/com/mojang/minecraft/gui/FontRenderer.java new file mode 100644 index 0000000..d14cc79 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/gui/FontRenderer.java @@ -0,0 +1,158 @@ +package com.mojang.minecraft.gui; + +import com.mojang.minecraft.GameSettings; +import com.mojang.minecraft.render.ShapeRenderer; +import com.mojang.minecraft.render.TextureManager; +import java.awt.image.BufferedImage; +import java.io.IOException; +import javax.imageio.ImageIO; +import org.lwjgl.opengl.GL11; + +public final class FontRenderer { + + private int[] widthmap = new int[256]; + private int fontTexture = 0; + private GameSettings settings; + + + public FontRenderer(GameSettings var1, String var2, TextureManager var3) { + this.settings = var1; + + BufferedImage var14; + try { + var14 = ImageIO.read(TextureManager.class.getResourceAsStream(var2)); + } catch (IOException var13) { + throw new RuntimeException(var13); + } + + int var4 = var14.getWidth(); + int var5 = var14.getHeight(); + int[] var6 = new int[var4 * var5]; + var14.getRGB(0, 0, var4, var5, var6, 0, var4); + + for(int var15 = 0; var15 < 128; ++var15) { + var5 = var15 % 16; + int var7 = var15 / 16; + int var8 = 0; + + for(boolean var9 = false; var8 < 8 && !var9; ++var8) { + int var10 = (var5 << 3) + var8; + var9 = true; + + for(int var11 = 0; var11 < 8 && var9; ++var11) { + int var12 = ((var7 << 3) + var11) * var4; + if((var6[var10 + var12] & 255) > 128) { + var9 = false; + } + } + } + + if(var15 == 32) { + var8 = 4; + } + + this.widthmap[var15] = var8; + } + + this.fontTexture = var3.load(var2); + } + + public final void render(String var1, int var2, int var3, int var4) { + this.render(var1, var2 + 1, var3 + 1, var4, true); + this.renderNoShadow(var1, var2, var3, var4); + } + + public final void renderNoShadow(String var1, int var2, int var3, int var4) { + this.render(var1, var2, var3, var4, false); + } + + private void render(String var1, int var2, int var3, int var4, boolean var5) { + if(var1 != null) { + char[] var12 = var1.toCharArray(); + if(var5) { + var4 = (var4 & 16579836) >> 2; + } + + GL11.glBindTexture(3553, this.fontTexture); + ShapeRenderer var6 = ShapeRenderer.instance; + ShapeRenderer.instance.begin(); + var6.color(var4); + int var7 = 0; + + for(int var8 = 0; var8 < var12.length; ++var8) { + int var9; + if(var12[var8] == 38 && var12.length > var8 + 1) { + if((var4 = "0123456789abcdef".indexOf(var12[var8 + 1])) < 0) { + var4 = 15; + } + + var9 = (var4 & 8) << 3; + int var10 = (var4 & 1) * 191 + var9; + int var11 = ((var4 & 2) >> 1) * 191 + var9; + var4 = ((var4 & 4) >> 2) * 191 + var9; + if(this.settings.anaglyph) { + var9 = (var4 * 30 + var11 * 59 + var10 * 11) / 100; + var11 = (var4 * 30 + var11 * 70) / 100; + var10 = (var4 * 30 + var10 * 70) / 100; + var4 = var9; + var11 = var11; + var10 = var10; + } + + var4 = var4 << 16 | var11 << 8 | var10; + var8 += 2; + if(var5) { + var4 = (var4 & 16579836) >> 2; + } + + var6.color(var4); + } + + var4 = var12[var8] % 16 << 3; + var9 = var12[var8] / 16 << 3; + float var13 = 7.99F; + var6.vertexUV((float)(var2 + var7), (float)var3 + var13, 0.0F, (float)var4 / 128.0F, ((float)var9 + var13) / 128.0F); + var6.vertexUV((float)(var2 + var7) + var13, (float)var3 + var13, 0.0F, ((float)var4 + var13) / 128.0F, ((float)var9 + var13) / 128.0F); + var6.vertexUV((float)(var2 + var7) + var13, (float)var3, 0.0F, ((float)var4 + var13) / 128.0F, (float)var9 / 128.0F); + var6.vertexUV((float)(var2 + var7), (float)var3, 0.0F, (float)var4 / 128.0F, (float)var9 / 128.0F); + var7 += this.widthmap[var12[var8]]; + } + + var6.end(); + } + } + + public final int getWidth(String var1) { + if(var1 == null) { + return 0; + } else { + char[] var4 = var1.toCharArray(); + int var2 = 0; + + for(int var3 = 0; var3 < var4.length; ++var3) { + if(var4[var3] == 38) { + ++var3; + } else { + var2 += this.widthmap[var4[var3]]; + } + } + + return var2; + } + } + + public static String stripColor(String var0) { + char[] var3 = var0.toCharArray(); + String var1 = ""; + + for(int var2 = 0; var2 < var3.length; ++var2) { + if(var3[var2] == 38) { + ++var2; + } else { + var1 = var1 + var3[var2]; + } + } + + return var1; + } +} diff --git a/src/main/java/com/mojang/minecraft/gui/GameOverScreen.java b/src/main/java/com/mojang/minecraft/gui/GameOverScreen.java new file mode 100644 index 0000000..09a7546 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/gui/GameOverScreen.java @@ -0,0 +1,46 @@ +package com.mojang.minecraft.gui; + +import com.mojang.minecraft.gui.Button; +import com.mojang.minecraft.gui.GenerateLevelScreen; +import com.mojang.minecraft.gui.GuiScreen; +import com.mojang.minecraft.gui.LoadLevelScreen; +import com.mojang.minecraft.gui.OptionsScreen; +import org.lwjgl.opengl.GL11; + +public final class GameOverScreen extends GuiScreen { + + public final void onOpen() { + this.buttons.clear(); + this.buttons.add(new Button(1, this.width / 2 - 100, this.height / 4 + 72, "Generate new level...")); + this.buttons.add(new Button(2, this.width / 2 - 100, this.height / 4 + 96, "Load level..")); + if(this.minecraft.session == null) { + ((Button)this.buttons.get(1)).active = false; + } + + } + + protected final void onButtonClick(Button var1) { + if(var1.id == 0) { + this.minecraft.setCurrentScreen(new OptionsScreen(this, this.minecraft.settings)); + } + + if(var1.id == 1) { + this.minecraft.setCurrentScreen(new GenerateLevelScreen(this)); + } + + if(this.minecraft.session != null && var1.id == 2) { + this.minecraft.setCurrentScreen(new LoadLevelScreen(this)); + } + + } + + public final void render(int var1, int var2) { + drawFadingBox(0, 0, this.width, this.height, 1615855616, -1602211792); + GL11.glPushMatrix(); + GL11.glScalef(2.0F, 2.0F, 2.0F); + drawCenteredString(this.fontRenderer, "Game over!", this.width / 2 / 2, 30, 16777215); + GL11.glPopMatrix(); + drawCenteredString(this.fontRenderer, "Score: &e" + this.minecraft.player.getScore(), this.width / 2, 100, 16777215); + super.render(var1, var2); + } +} diff --git a/src/main/java/com/mojang/minecraft/gui/GenerateLevelScreen.java b/src/main/java/com/mojang/minecraft/gui/GenerateLevelScreen.java new file mode 100644 index 0000000..2e1b2fe --- /dev/null +++ b/src/main/java/com/mojang/minecraft/gui/GenerateLevelScreen.java @@ -0,0 +1,38 @@ +package com.mojang.minecraft.gui; + +import com.mojang.minecraft.gui.Button; +import com.mojang.minecraft.gui.GuiScreen; + +public final class GenerateLevelScreen extends GuiScreen { + + private GuiScreen parent; + + + public GenerateLevelScreen(GuiScreen var1) { + this.parent = var1; + } + + public final void onOpen() { + this.buttons.clear(); + this.buttons.add(new Button(0, this.width / 2 - 100, this.height / 4, "Small")); + this.buttons.add(new Button(1, this.width / 2 - 100, this.height / 4 + 24, "Normal")); + this.buttons.add(new Button(2, this.width / 2 - 100, this.height / 4 + 48, "Huge")); + this.buttons.add(new Button(3, this.width / 2 - 100, this.height / 4 + 120, "Cancel")); + } + + protected final void onButtonClick(Button var1) { + if(var1.id == 3) { + this.minecraft.setCurrentScreen(this.parent); + } else { + this.minecraft.generateLevel(var1.id); + this.minecraft.setCurrentScreen((GuiScreen)null); + this.minecraft.grabMouse(); + } + } + + public final void render(int var1, int var2) { + drawFadingBox(0, 0, this.width, this.height, 1610941696, -1607454624); + drawCenteredString(this.fontRenderer, "Generate new level", this.width / 2, 40, 16777215); + super.render(var1, var2); + } +} diff --git a/src/main/java/com/mojang/minecraft/gui/GuiMods.java b/src/main/java/com/mojang/minecraft/gui/GuiMods.java new file mode 100644 index 0000000..85292ea --- /dev/null +++ b/src/main/java/com/mojang/minecraft/gui/GuiMods.java @@ -0,0 +1,40 @@ +package com.mojang.minecraft.gui; + +import com.mojang.minecraft.Minecraft; + +public class GuiMods extends GuiScreen { + GuiScreen parent = null; + String title = "Optifine"; + + public GuiMods(GuiScreen parent) { + this.parent = parent; + } + + public final void onOpen() { + this.buttons.add(new OptionButton(1, this.width / 2 - 155 + 0 % 2 * 160, this.height / 6 + 24 * (0 >> 1), minecraft.settings.getSetting(11))); + this.buttons.add(new OptionButton(2, this.width / 2 - 155 + 1 % 2 * 160, this.height / 6 + 24 * (1 >> 1), minecraft.settings.getSetting(12))); + this.buttons.add(new Button(200, this.width / 2 - 100, this.height / 6 + 168 + 12, "Done")); + } + + public final void onButtonClick(Button var1) { + if(var1.id == 1) { + minecraft.settings.toggleSetting(11, 0); + var1.text = minecraft.settings.getSetting(11); + } + + if(var1.id == 2) { + minecraft.settings.toggleSetting(12, 0); + var1.text = minecraft.settings.getSetting(12); + } + + if(var1.id == 200) { + minecraft.setCurrentScreen(parent); + } + } + + public final void render(int var1, int var2) { + drawFadingBox(0, 0, this.width, this.height, 1610941696, -1607454624); + drawCenteredString(this.fontRenderer, this.title, this.width / 2, 20, 16777215); + super.render(var1, var2); + } +} diff --git a/src/main/java/com/mojang/minecraft/gui/GuiMore.java b/src/main/java/com/mojang/minecraft/gui/GuiMore.java new file mode 100644 index 0000000..f216795 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/gui/GuiMore.java @@ -0,0 +1,40 @@ +package com.mojang.minecraft.gui; + +import com.mojang.minecraft.Minecraft; + +public class GuiMore extends GuiScreen { + GuiScreen parent = null; + String title; + + public GuiMore(GuiScreen parent) { + this.parent = parent; + this.title = "More Options..."; + } + + public final void onOpen() { + this.buttons.add(new Button(50, this.width / 2 - 100, this.height / 6 + 0 + 12, "Mods")); + this.buttons.add(new Button(100, this.width / 2 - 100, this.height / 6 + 25 + 12, "Optifine")); + this.buttons.add(new Button(200, this.width / 2 - 100, this.height / 6 + 168 + 12, "Done")); + } + + public final void onButtonClick(Button var1) { + + if(var1.id == 50) { + minecraft.setCurrentScreen(new GuiMods(this)); + } + + if(var1.id == 100) { + minecraft.setCurrentScreen(new GuiOptifine(this)); + } + + if(var1.id == 200) { + minecraft.setCurrentScreen(parent); + } + } + + public final void render(int var1, int var2) { + drawFadingBox(0, 0, this.width, this.height, 1610941696, -1607454624); + drawCenteredString(this.fontRenderer, this.title, this.width / 2, 20, 16777215); + super.render(var1, var2); + } +} diff --git a/src/main/java/com/mojang/minecraft/gui/GuiOptifine.java b/src/main/java/com/mojang/minecraft/gui/GuiOptifine.java new file mode 100644 index 0000000..05bdcff --- /dev/null +++ b/src/main/java/com/mojang/minecraft/gui/GuiOptifine.java @@ -0,0 +1,40 @@ +package com.mojang.minecraft.gui; + +import com.mojang.minecraft.Minecraft; + +public class GuiOptifine extends GuiScreen { + GuiScreen parent = null; + String title = "Optifine"; + + public GuiOptifine(GuiScreen parent) { + this.parent = parent; + } + + public final void onOpen() { + this.buttons.add(new OptionButton(1, this.width / 2 - 155 + 0 % 2 * 160, this.height / 6 + 24 * (0 >> 1), minecraft.settings.getSetting(8))); + this.buttons.add(new OptionButton(2, this.width / 2 - 155 + 1 % 2 * 160, this.height / 6 + 24 * (1 >> 1), minecraft.settings.getSetting(9))); + this.buttons.add(new Button(200, this.width / 2 - 100, this.height / 6 + 168 + 12, "Done")); + } + + public final void onButtonClick(Button var1) { + if(var1.id == 1) { + minecraft.settings.toggleSetting(8, 0); + var1.text = minecraft.settings.getSetting(8); + } + + if(var1.id == 2) { + minecraft.settings.toggleSetting(9, 0); + var1.text = minecraft.settings.getSetting(9); + } + + if(var1.id == 200) { + minecraft.setCurrentScreen(parent); + } + } + + public final void render(int var1, int var2) { + drawFadingBox(0, 0, this.width, this.height, 1610941696, -1607454624); + drawCenteredString(this.fontRenderer, this.title, this.width / 2, 20, 16777215); + super.render(var1, var2); + } +} diff --git a/src/main/java/com/mojang/minecraft/gui/GuiScreen.java b/src/main/java/com/mojang/minecraft/gui/GuiScreen.java new file mode 100644 index 0000000..b62aa2f --- /dev/null +++ b/src/main/java/com/mojang/minecraft/gui/GuiScreen.java @@ -0,0 +1,117 @@ +package com.mojang.minecraft.gui; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.gui.Button; +import com.mojang.minecraft.gui.FontRenderer; +import com.mojang.minecraft.gui.Screen; +import java.util.ArrayList; +import java.util.List; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; + +public class GuiScreen extends Screen { + + protected Minecraft minecraft; + protected int width; + protected int height; + protected List buttons = new ArrayList(); + public boolean grabsMouse = false; + protected FontRenderer fontRenderer; + + + public void render(int var1, int var2) { + for(int var3 = 0; var3 < this.buttons.size(); ++var3) { + Button var10000 = (Button)this.buttons.get(var3); + Minecraft var7 = this.minecraft; + Button var4 = var10000; + if(var10000.visible) { + FontRenderer var8 = var7.fontRenderer; + GL11.glBindTexture(3553, var7.textureManager.load("/gui/gui.png")); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + byte var9 = 1; + boolean var6 = var1 >= var4.x && var2 >= var4.y && var1 < var4.x + var4.width && var2 < var4.y + var4.height; + if(!var4.active) { + var9 = 0; + } else if(var6) { + var9 = 2; + } + + var4.drawImage(var4.x, var4.y, 0, 46 + var9 * 20, var4.width / 2, var4.height); + var4.drawImage(var4.x + var4.width / 2, var4.y, 200 - var4.width / 2, 46 + var9 * 20, var4.width / 2, var4.height); + if(!var4.active) { + Button.drawCenteredString(var8, var4.text, var4.x + var4.width / 2, var4.y + (var4.height - 8) / 2, -6250336); + } else if(var6) { + Button.drawCenteredString(var8, var4.text, var4.x + var4.width / 2, var4.y + (var4.height - 8) / 2, 16777120); + } else { + Button.drawCenteredString(var8, var4.text, var4.x + var4.width / 2, var4.y + (var4.height - 8) / 2, 14737632); + } + } + } + + } + + protected void onKeyPress(char var1, int var2) { + if(var2 == 1) { + this.minecraft.setCurrentScreen((GuiScreen)null); + this.minecraft.grabMouse(); + } + + } + + protected void onMouseClick(int var1, int var2, int var3) { + if(var3 == 0) { + for(var3 = 0; var3 < this.buttons.size(); ++var3) { + Button var4; + Button var7; + if((var7 = var4 = (Button)this.buttons.get(var3)).active && var1 >= var7.x && var2 >= var7.y && var1 < var7.x + var7.width && var2 < var7.y + var7.height) { + this.onButtonClick(var4); + } + } + } + + } + + protected void onButtonClick(Button var1) {} + + public final void open(Minecraft var1, int var2, int var3) { + this.minecraft = var1; + this.fontRenderer = var1.fontRenderer; + this.width = var2; + this.height = var3; + this.onOpen(); + } + + public void onOpen() {} + + public final void doInput() { + while(Mouse.next()) { + this.mouseEvent(); + } + + while(Keyboard.next()) { + this.keyboardEvent(); + } + + } + + public final void mouseEvent() { + if(Mouse.getEventButtonState()) { + int var1 = Mouse.getEventX() * this.width / this.minecraft.width; + int var2 = this.height - Mouse.getEventY() * this.height / this.minecraft.height - 1; + this.onMouseClick(var1, var2, Mouse.getEventButton()); + } + + } + + public final void keyboardEvent() { + if(Keyboard.getEventKeyState()) { + this.onKeyPress(Keyboard.getEventCharacter(), Keyboard.getEventKey()); + } + + } + + public void tick() {} + + public void onClose() {} +} diff --git a/src/main/java/com/mojang/minecraft/gui/HUDScreen.java b/src/main/java/com/mojang/minecraft/gui/HUDScreen.java new file mode 100644 index 0000000..4558ba2 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/gui/HUDScreen.java @@ -0,0 +1,215 @@ +package com.mojang.minecraft.gui; + +import com.mojang.minecraft.ChatLine; +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.gamemode.SurvivalGameMode; +import com.mojang.minecraft.gui.ChatInputScreen; +import com.mojang.minecraft.gui.FontRenderer; +import com.mojang.minecraft.gui.Screen; +import com.mojang.minecraft.level.tile.Block; +import com.mojang.minecraft.player.Inventory; +import com.mojang.minecraft.render.ShapeRenderer; +import com.mojang.minecraft.render.TextureManager; +import com.mojang.util.MathHelper; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import org.lwjgl.input.Keyboard; +import org.lwjgl.opengl.GL11; + +public final class HUDScreen extends Screen { + + public List chat = new ArrayList(); + private Random random = new Random(); + private Minecraft mc; + private int width; + private int height; + public String hoveredPlayer = null; + public int ticks = 0; + + + public HUDScreen(Minecraft var1, int var2, int var3) { + this.mc = var1; + this.width = var2 * 240 / var3; + this.height = var3 * 240 / var3; + } + + public final void render(float var1, boolean var2, int var3, int var4) { + FontRenderer var5 = this.mc.fontRenderer; + this.mc.renderer.enableGuiMode(); + TextureManager var6 = this.mc.textureManager; + GL11.glBindTexture(3553, this.mc.textureManager.load("/gui/gui.png")); + ShapeRenderer var7 = ShapeRenderer.instance; + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glEnable(3042); + Inventory var8 = this.mc.player.inventory; + this.imgZ = -90.0F; + this.drawImage(this.width / 2 - 91, this.height - 22, 0, 0, 182, 22); + this.drawImage(this.width / 2 - 91 - 1 + var8.selected * 20, this.height - 22 - 1, 0, 22, 24, 22); + GL11.glBindTexture(3553, this.mc.textureManager.load("/gui/icons.png")); + this.drawImage(this.width / 2 - 7, this.height / 2 - 7, 0, 0, 16, 16); + boolean var9 = this.mc.player.invulnerableTime / 3 % 2 == 1; + if(this.mc.player.invulnerableTime < 10) { + var9 = false; + } + + int var10 = this.mc.player.health; + int var11 = this.mc.player.lastHealth; + this.random.setSeed((long)(this.ticks * 312871)); + int var12; + int var14; + int var15; + int var26; + if(this.mc.gamemode.isSurvival()) { + for(var12 = 0; var12 < 10; ++var12) { + byte var13 = 0; + if(var9) { + var13 = 1; + } + + var14 = this.width / 2 - 91 + (var12 << 3); + var15 = this.height - 32; + if(var10 <= 4) { + var15 += this.random.nextInt(2); + } + + this.drawImage(var14, var15, 16 + var13 * 9, 0, 9, 9); + if(var9) { + if((var12 << 1) + 1 < var11) { + this.drawImage(var14, var15, 70, 0, 9, 9); + } + + if((var12 << 1) + 1 == var11) { + this.drawImage(var14, var15, 79, 0, 9, 9); + } + } + + if((var12 << 1) + 1 < var10) { + this.drawImage(var14, var15, 52, 0, 9, 9); + } + + if((var12 << 1) + 1 == var10) { + this.drawImage(var14, var15, 61, 0, 9, 9); + } + } + + if(this.mc.player.isUnderWater()) { + var12 = (int)Math.ceil((double)(this.mc.player.airSupply - 2) * 10.0D / 300.0D); + var26 = (int)Math.ceil((double)this.mc.player.airSupply * 10.0D / 300.0D) - var12; + + for(var14 = 0; var14 < var12 + var26; ++var14) { + if(var14 < var12) { + this.drawImage(this.width / 2 - 91 + (var14 << 3), this.height - 32 - 9, 16, 18, 9, 9); + } else { + this.drawImage(this.width / 2 - 91 + (var14 << 3), this.height - 32 - 9, 25, 18, 9, 9); + } + } + } + } + + GL11.glDisable(3042); + + String var23; + for(var12 = 0; var12 < var8.slots.length; ++var12) { + var26 = this.width / 2 - 90 + var12 * 20; + var14 = this.height - 16; + if((var15 = var8.slots[var12]) > 0) { + GL11.glPushMatrix(); + GL11.glTranslatef((float)var26, (float)var14, -50.0F); + if(var8.popTime[var12] > 0) { + float var18; + float var21 = -MathHelper.sin((var18 = ((float)var8.popTime[var12] - var1) / 5.0F) * var18 * 3.1415927F) * 8.0F; + float var19 = MathHelper.sin(var18 * var18 * 3.1415927F) + 1.0F; + float var16 = MathHelper.sin(var18 * 3.1415927F) + 1.0F; + GL11.glTranslatef(10.0F, var21 + 10.0F, 0.0F); + GL11.glScalef(var19, var16, 1.0F); + GL11.glTranslatef(-10.0F, -10.0F, 0.0F); + } + + GL11.glScalef(10.0F, 10.0F, 10.0F); + GL11.glTranslatef(1.0F, 0.5F, 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); + int var20 = var6.load("/terrain.png"); + GL11.glBindTexture(3553, var20); + var7.begin(); + Block.blocks[var15].renderFullbright(var7); + var7.end(); + GL11.glPopMatrix(); + if(var8.count[var12] > 1) { + var23 = "" + var8.count[var12]; + var5.render(var23, var26 + 19 - var5.getWidth(var23), var14 + 6, 16777215); + } + } + } + + var5.render("0.30", 2, 2, 16777215); + if(this.mc.settings.showFrameRate) { + var5.render(this.mc.debug, 2, 12, 16777215); + } + + if(this.mc.gamemode instanceof SurvivalGameMode) { + String var24 = "Score: &e" + this.mc.player.getScore(); + var5.render(var24, this.width - var5.getWidth(var24) - 2, 2, 16777215); + var5.render("Arrows: " + this.mc.player.arrows, this.width / 2 + 8, this.height - 33, 16777215); + } + + byte var25 = 10; + boolean var27 = false; + if(this.mc.currentScreen instanceof ChatInputScreen) { + var25 = 20; + var27 = true; + } + + for(var14 = 0; var14 < this.chat.size() && var14 < var25; ++var14) { + if(((ChatLine)this.chat.get(var14)).time < 200 || var27) { + var5.render(((ChatLine)this.chat.get(var14)).message, 2, this.height - 8 - var14 * 9 - 20, 16777215); + } + } + + var14 = this.width / 2; + var15 = this.height / 2; + this.hoveredPlayer = null; + if(Keyboard.isKeyDown(15) && this.mc.networkManager != null && this.mc.networkManager.isConnected()) { + List var22 = this.mc.networkManager.getPlayers(); + GL11.glEnable(3042); + GL11.glDisable(3553); + GL11.glBlendFunc(770, 771); + GL11.glBegin(7); + GL11.glColor4f(0.0F, 0.0F, 0.0F, 0.7F); + GL11.glVertex2f((float)(var14 + 128), (float)(var15 - 68 - 12)); + GL11.glVertex2f((float)(var14 - 128), (float)(var15 - 68 - 12)); + GL11.glColor4f(0.2F, 0.2F, 0.2F, 0.8F); + GL11.glVertex2f((float)(var14 - 128), (float)(var15 + 68)); + GL11.glVertex2f((float)(var14 + 128), (float)(var15 + 68)); + GL11.glEnd(); + GL11.glDisable(3042); + GL11.glEnable(3553); + var23 = "Connected players:"; + var5.render(var23, var14 - var5.getWidth(var23) / 2, var15 - 64 - 12, 16777215); + + for(var11 = 0; var11 < var22.size(); ++var11) { + int var28 = var14 + var11 % 2 * 120 - 120; + int var17 = var15 - 64 + (var11 / 2 << 3); + if(var2 && var3 >= var28 && var4 >= var17 && var3 < var28 + 120 && var4 < var17 + 8) { + this.hoveredPlayer = (String)var22.get(var11); + var5.renderNoShadow((String)var22.get(var11), var28 + 2, var17, 16777215); + } else { + var5.renderNoShadow((String)var22.get(var11), var28, var17, 15658734); + } + } + } + + } + + public final void addChat(String var1) { + this.chat.add(0, new ChatLine(var1)); + + while(this.chat.size() > 50) { + this.chat.remove(this.chat.size() - 1); + } + + } +} diff --git a/src/main/java/com/mojang/minecraft/gui/LevelDialog.java b/src/main/java/com/mojang/minecraft/gui/LevelDialog.java new file mode 100644 index 0000000..30d1250 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/gui/LevelDialog.java @@ -0,0 +1,52 @@ +package com.mojang.minecraft.gui; + +import com.mojang.minecraft.gui.LoadLevelScreen; +import javax.swing.JFileChooser; +import javax.swing.filechooser.FileNameExtensionFilter; + +final class LevelDialog extends Thread { + + // $FF: synthetic field + private LoadLevelScreen screen; + + + LevelDialog(LoadLevelScreen var1) { + super(); + this.screen = var1; + } + + public final void run() { + JFileChooser var1; + LoadLevelScreen var2; + try { + LoadLevelScreen var10000 = this.screen; + var1 = new JFileChooser(); + var10000.chooser = var1; + FileNameExtensionFilter var3 = new FileNameExtensionFilter("Minecraft levels", new String[]{"mine"}); + var2 = this.screen; + this.screen.chooser.setFileFilter(var3); + var2 = this.screen; + this.screen.chooser.setMultiSelectionEnabled(false); + int var7; + if(this.screen.saving) { + var2 = this.screen; + var7 = this.screen.chooser.showSaveDialog(this.screen.minecraft.canvas); + } else { + var2 = this.screen; + var7 = this.screen.chooser.showOpenDialog(this.screen.minecraft.canvas); + } + + if(var7 == 0) { + (var2 = this.screen).selectedFile = this.screen.chooser.getSelectedFile(); + } + } finally { + boolean var6 = false; + var2 = this.screen; + this.screen.frozen = false; + var1 = null; + var2 = this.screen; + this.screen.chooser = var1; + } + + } +} diff --git a/src/main/java/com/mojang/minecraft/gui/LevelNameScreen.java b/src/main/java/com/mojang/minecraft/gui/LevelNameScreen.java new file mode 100644 index 0000000..3c7ee76 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/gui/LevelNameScreen.java @@ -0,0 +1,85 @@ +package com.mojang.minecraft.gui; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.gui.Button; +import com.mojang.minecraft.gui.GuiScreen; +import org.lwjgl.input.Keyboard; + +public final class LevelNameScreen extends GuiScreen { + + private GuiScreen parent; + private String title = "Enter level name:"; + private int id; + private String name; + private int counter = 0; + + + public LevelNameScreen(GuiScreen var1, String var2, int var3) { + this.parent = var1; + this.id = var3; + this.name = var2; + if(this.name.equals("-")) { + this.name = ""; + } + + } + + public final void onOpen() { + this.buttons.clear(); + Keyboard.enableRepeatEvents(true); + this.buttons.add(new Button(0, this.width / 2 - 100, this.height / 4 + 120, "Save")); + this.buttons.add(new Button(1, this.width / 2 - 100, this.height / 4 + 144, "Cancel")); + ((Button)this.buttons.get(0)).active = this.name.trim().length() > 1; + } + + public final void onClose() { + Keyboard.enableRepeatEvents(false); + } + + public final void tick() { + ++this.counter; + } + + protected final void onButtonClick(Button var1) { + if(var1.active) { + if(var1.id == 0 && this.name.trim().length() > 1) { + Minecraft var10000 = this.minecraft; + int var10001 = this.id; + String var2 = this.name.trim(); + int var3 = var10001; + Minecraft var4 = var10000; + var10000.levelIo.saveOnline(var4.level, var4.host, var4.session.username, var4.session.sessionId, var2, var3); + this.minecraft.setCurrentScreen((GuiScreen)null); + this.minecraft.grabMouse(); + } + + if(var1.id == 1) { + this.minecraft.setCurrentScreen(this.parent); + } + + } + } + + protected final void onKeyPress(char var1, int var2) { + if(var2 == 14 && this.name.length() > 0) { + this.name = this.name.substring(0, this.name.length() - 1); + } + + if("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ,.:-_\'*!\"#%/()=+?[]{}<>".indexOf(var1) >= 0 && this.name.length() < 64) { + this.name = this.name + var1; + } + + ((Button)this.buttons.get(0)).active = this.name.trim().length() > 1; + } + + public final void render(int var1, int var2) { + drawFadingBox(0, 0, this.width, this.height, 1610941696, -1607454624); + drawCenteredString(this.fontRenderer, this.title, this.width / 2, 40, 16777215); + int var3 = this.width / 2 - 100; + int var4 = this.height / 2 - 10; + drawBox(var3 - 1, var4 - 1, var3 + 200 + 1, var4 + 20 + 1, -6250336); + drawBox(var3, var4, var3 + 200, var4 + 20, -16777216); + drawString(this.fontRenderer, this.name + (this.counter / 6 % 2 == 0?"_":""), var3 + 4, var4 + 6, 14737632); + super.render(var1, var2); + } +} diff --git a/src/main/java/com/mojang/minecraft/gui/LoadLevelScreen.java b/src/main/java/com/mojang/minecraft/gui/LoadLevelScreen.java new file mode 100644 index 0000000..468f2e0 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/gui/LoadLevelScreen.java @@ -0,0 +1,164 @@ +package com.mojang.minecraft.gui; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.gui.Button; +import com.mojang.minecraft.gui.GuiScreen; +import com.mojang.minecraft.gui.LevelDialog; +import com.mojang.minecraft.level.Level; +import java.io.BufferedReader; +import java.io.File; +import java.io.InputStreamReader; +import java.net.URL; +import javax.swing.JFileChooser; +import javax.swing.SwingUtilities; + +public class LoadLevelScreen extends GuiScreen implements Runnable { + + protected GuiScreen parent; + private boolean finished = false; + private boolean loaded = false; + private String[] levels = null; + private String status = ""; + protected String title = "Load level"; + boolean frozen = false; + JFileChooser chooser; + protected boolean saving = false; + protected File selectedFile; + + + public LoadLevelScreen(GuiScreen var1) { + this.parent = var1; + } + + public void run() { + try { + if(this.frozen) { + try { + Thread.sleep(100L); + } catch (InterruptedException var2) { + var2.printStackTrace(); + } + } + + this.status = "Getting level list.."; + URL var1 = new URL("http://" + this.minecraft.host + "/listmaps.jsp?user=" + this.minecraft.session.username); + BufferedReader var4 = new BufferedReader(new InputStreamReader(var1.openConnection().getInputStream())); + this.levels = var4.readLine().split(";"); + if(this.levels.length >= 5) { + this.setLevels(this.levels); + this.loaded = true; + return; + } + + this.status = this.levels[0]; + this.finished = true; + } catch (Exception var3) { + var3.printStackTrace(); + this.status = "Failed to load levels"; + this.finished = true; + } + + } + + protected void setLevels(String[] var1) { + for(int var2 = 0; var2 < 5; ++var2) { + ((Button)this.buttons.get(var2)).active = !var1[var2].equals("-"); + ((Button)this.buttons.get(var2)).text = var1[var2]; + ((Button)this.buttons.get(var2)).visible = true; + } + + } + + public void onOpen() { + (new Thread(this)).start(); + + for(int var1 = 0; var1 < 5; ++var1) { + this.buttons.add(new Button(var1, this.width / 2 - 100, this.height / 6 + var1 * 24, "---")); + ((Button)this.buttons.get(var1)).visible = false; + ((Button)this.buttons.get(var1)).active = false; + } + + this.buttons.add(new Button(5, this.width / 2 - 100, this.height / 6 + 120 + 12, "Load file...")); + this.buttons.add(new Button(6, this.width / 2 - 100, this.height / 6 + 168, "Cancel")); + } + + protected final void onButtonClick(Button var1) { + if(!this.frozen) { + if(var1.active) { + if(this.loaded && var1.id < 5) { + this.openLevel(var1.id); + } + + if(this.finished || this.loaded && var1.id == 5) { + this.frozen = true; + LevelDialog var2; + (var2 = new LevelDialog(this)).setDaemon(true); + SwingUtilities.invokeLater(var2); + } + + if(this.finished || this.loaded && var1.id == 6) { + this.minecraft.setCurrentScreen(this.parent); + } + + } + } + } + + protected void openLevel(File var1) { + File var2 = var1; + Minecraft var4 = this.minecraft; + Level var5; + boolean var10000; + if((var5 = this.minecraft.levelIo.load(var2)) == null) { + var10000 = false; + } else { + var4.setLevel(var5); + var10000 = true; + } + + this.minecraft.setCurrentScreen(this.parent); + } + + protected void openLevel(int var1) { + this.minecraft.loadOnlineLevel(this.minecraft.session.username, var1); + this.minecraft.setCurrentScreen((GuiScreen)null); + this.minecraft.grabMouse(); + } + + public void render(int var1, int var2) { + drawFadingBox(0, 0, this.width, this.height, 1610941696, -1607454624); + drawCenteredString(this.fontRenderer, this.title, this.width / 2, 20, 16777215); + if(this.frozen) { + drawCenteredString(this.fontRenderer, "Selecting file..", this.width / 2, this.height / 2 - 4, 16777215); + + try { + Thread.sleep(20L); + } catch (InterruptedException var3) { + var3.printStackTrace(); + } + } else { + if(!this.loaded) { + drawCenteredString(this.fontRenderer, this.status, this.width / 2, this.height / 2 - 4, 16777215); + } + + super.render(var1, var2); + } + } + + public final void onClose() { + super.onClose(); + if(this.chooser != null) { + this.chooser.cancelSelection(); + } + + } + + public final void tick() { + super.tick(); + if(this.selectedFile != null) { + this.openLevel(this.selectedFile); + this.selectedFile = null; + } + + } +} diff --git a/src/main/java/com/mojang/minecraft/gui/OptionButton.java b/src/main/java/com/mojang/minecraft/gui/OptionButton.java new file mode 100644 index 0000000..494f155 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/gui/OptionButton.java @@ -0,0 +1,10 @@ +package com.mojang.minecraft.gui; + +import com.mojang.minecraft.gui.Button; + +public final class OptionButton extends Button { + + public OptionButton(int var1, int var2, int var3, String var4) { + super(var1, var2, var3, 150, 20, var4); + } +} diff --git a/src/main/java/com/mojang/minecraft/gui/OptionsScreen.java b/src/main/java/com/mojang/minecraft/gui/OptionsScreen.java new file mode 100644 index 0000000..391eda6 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/gui/OptionsScreen.java @@ -0,0 +1,58 @@ +package com.mojang.minecraft.gui; + +import com.mojang.minecraft.GameSettings; +import com.mojang.minecraft.gui.Button; +import com.mojang.minecraft.gui.ControlsScreen; +import com.mojang.minecraft.gui.GuiScreen; +import com.mojang.minecraft.gui.OptionButton; + +public final class OptionsScreen extends GuiScreen { + + private GuiScreen parent; + private String title = "Options"; + private GameSettings settings; + + + public OptionsScreen(GuiScreen var1, GameSettings var2) { + this.parent = var1; + this.settings = var2; + } + + public final void onOpen() { + for(int var1 = 0; var1 < this.settings.settingCount; ++var1) { + this.buttons.add(new OptionButton(var1, this.width / 2 - 155 + var1 % 2 * 160, this.height / 6 + 24 * (var1 >> 1), this.settings.getSetting(var1))); + } + + this.buttons.add(new Button(50, this.width / 2 - 100, this.height / 6 + 95 + 12, "More...")); + this.buttons.add(new Button(100, this.width / 2 - 100, this.height / 6 + 120 + 12, "Controls...")); + this.buttons.add(new Button(200, this.width / 2 - 100, this.height / 6 + 168, "Done")); + } + + protected final void onButtonClick(Button var1) { + if(var1.active) { + if(var1.id < 100) { + this.settings.toggleSetting(var1.id, 1); + var1.text = this.settings.getSetting(var1.id); + } + + if(var1.id == 50) { + this.minecraft.setCurrentScreen(new GuiMore(this)); + } + + if(var1.id == 100) { + this.minecraft.setCurrentScreen(new ControlsScreen(this, this.settings)); + } + + if(var1.id == 200) { + this.minecraft.setCurrentScreen(this.parent); + } + + } + } + + public final void render(int var1, int var2) { + drawFadingBox(0, 0, this.width, this.height, 1610941696, -1607454624); + drawCenteredString(this.fontRenderer, this.title, this.width / 2, 20, 16777215); + super.render(var1, var2); + } +} diff --git a/src/main/java/com/mojang/minecraft/gui/PauseScreen.java b/src/main/java/com/mojang/minecraft/gui/PauseScreen.java new file mode 100644 index 0000000..63894d2 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/gui/PauseScreen.java @@ -0,0 +1,63 @@ +package com.mojang.minecraft.gui; + +import com.mojang.minecraft.gui.Button; +import com.mojang.minecraft.gui.GenerateLevelScreen; +import com.mojang.minecraft.gui.GuiScreen; +import com.mojang.minecraft.gui.LoadLevelScreen; +import com.mojang.minecraft.gui.OptionsScreen; +import com.mojang.minecraft.gui.SaveLevelScreen; + +public final class PauseScreen extends GuiScreen { + + public final void onOpen() { + this.buttons.clear(); + this.buttons.add(new Button(0, this.width / 2 - 100, this.height / 4, "Options...")); + this.buttons.add(new Button(1, this.width / 2 - 100, this.height / 4 + 24, "Generate new level...")); + this.buttons.add(new Button(2, this.width / 2 - 100, this.height / 4 + 48, "Save level..")); + this.buttons.add(new Button(3, this.width / 2 - 100, this.height / 4 + 72, "Load level..")); + this.buttons.add(new Button(4, this.width / 2 - 100, this.height / 4 + 120, "Back to game")); + if(this.minecraft.session == null) { + ((Button)this.buttons.get(2)).active = false; + ((Button)this.buttons.get(3)).active = false; + } + + if(this.minecraft.networkManager != null) { + ((Button)this.buttons.get(1)).active = false; + ((Button)this.buttons.get(2)).active = false; + ((Button)this.buttons.get(3)).active = false; + } + + } + + protected final void onButtonClick(Button var1) { + if(var1.id == 0) { + this.minecraft.setCurrentScreen(new OptionsScreen(this, this.minecraft.settings)); + } + + if(var1.id == 1) { + this.minecraft.setCurrentScreen(new GenerateLevelScreen(this)); + } + + if(this.minecraft.session != null) { + if(var1.id == 2) { + this.minecraft.setCurrentScreen(new SaveLevelScreen(this)); + } + + if(var1.id == 3) { + this.minecraft.setCurrentScreen(new LoadLevelScreen(this)); + } + } + + if(var1.id == 4) { + this.minecraft.setCurrentScreen((GuiScreen)null); + this.minecraft.grabMouse(); + } + + } + + public final void render(int var1, int var2) { + drawFadingBox(0, 0, this.width, this.height, 1610941696, -1607454624); + drawCenteredString(this.fontRenderer, "Game menu", this.width / 2, 40, 16777215); + super.render(var1, var2); + } +} diff --git a/src/main/java/com/mojang/minecraft/gui/SaveLevelScreen.java b/src/main/java/com/mojang/minecraft/gui/SaveLevelScreen.java new file mode 100644 index 0000000..6ad7917 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/gui/SaveLevelScreen.java @@ -0,0 +1,56 @@ +package com.mojang.minecraft.gui; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.gui.Button; +import com.mojang.minecraft.gui.GuiScreen; +import com.mojang.minecraft.gui.LevelNameScreen; +import com.mojang.minecraft.gui.LoadLevelScreen; +import java.io.File; + +public final class SaveLevelScreen extends LoadLevelScreen { + + public SaveLevelScreen(GuiScreen var1) { + super(var1); + this.title = "Save level"; + this.saving = true; + } + + public final void onOpen() { + super.onOpen(); + ((Button)this.buttons.get(5)).text = "Save file..."; + } + + protected final void setLevels(String[] var1) { + for(int var2 = 0; var2 < 5; ++var2) { + ((Button)this.buttons.get(var2)).text = var1[var2]; + ((Button)this.buttons.get(var2)).visible = true; + ((Button)this.buttons.get(var2)).active = this.minecraft.session.haspaid; + } + + } + + public final void render(int var1, int var2) { + super.render(var1, var2); + if(!this.minecraft.session.haspaid) { + drawFadingBox(this.width / 2 - 80, 72, this.width / 2 + 80, 120, -536870912, -536870912); + drawCenteredString(this.fontRenderer, "Premium only!", this.width / 2, 80, 16748688); + drawCenteredString(this.fontRenderer, "Purchase the game to be able", this.width / 2, 96, 14712960); + drawCenteredString(this.fontRenderer, "to save your levels online.", this.width / 2, 104, 14712960); + } + } + + protected final void openLevel(File var1) { + if(!var1.getName().endsWith(".mine")) { + var1 = new File(var1.getParentFile(), var1.getName() + ".mine"); + } + + File var2 = var1; + Minecraft var3 = this.minecraft; + this.minecraft.levelIo.save(var3.level, var2); + this.minecraft.setCurrentScreen(this.parent); + } + + protected final void openLevel(int var1) { + this.minecraft.setCurrentScreen(new LevelNameScreen(this, ((Button)this.buttons.get(var1)).text, var1)); + } +} diff --git a/src/main/java/com/mojang/minecraft/gui/Screen.java b/src/main/java/com/mojang/minecraft/gui/Screen.java new file mode 100644 index 0000000..c44cdae --- /dev/null +++ b/src/main/java/com/mojang/minecraft/gui/Screen.java @@ -0,0 +1,75 @@ +package com.mojang.minecraft.gui; + +import com.mojang.minecraft.gui.FontRenderer; +import com.mojang.minecraft.render.ShapeRenderer; +import org.lwjgl.opengl.GL11; + +public class Screen { + + protected float imgZ = 0.0F; + + + protected static void drawBox(int var0, int var1, int var2, int var3, int var4) { + float var5 = (float)(var4 >>> 24) / 255.0F; + float var6 = (float)(var4 >> 16 & 255) / 255.0F; + float var7 = (float)(var4 >> 8 & 255) / 255.0F; + float var9 = (float)(var4 & 255) / 255.0F; + ShapeRenderer var8 = ShapeRenderer.instance; + GL11.glEnable(3042); + GL11.glDisable(3553); + GL11.glBlendFunc(770, 771); + GL11.glColor4f(var6, var7, var9, var5); + var8.begin(); + var8.vertex((float)var0, (float)var3, 0.0F); + var8.vertex((float)var2, (float)var3, 0.0F); + var8.vertex((float)var2, (float)var1, 0.0F); + var8.vertex((float)var0, (float)var1, 0.0F); + var8.end(); + GL11.glEnable(3553); + GL11.glDisable(3042); + } + + protected static void drawFadingBox(int var0, int var1, int var2, int var3, int var4, int var5) { + float var6 = (float)(var4 >>> 24) / 255.0F; + float var7 = (float)(var4 >> 16 & 255) / 255.0F; + float var8 = (float)(var4 >> 8 & 255) / 255.0F; + float var12 = (float)(var4 & 255) / 255.0F; + float var9 = (float)(var5 >>> 24) / 255.0F; + float var10 = (float)(var5 >> 16 & 255) / 255.0F; + float var11 = (float)(var5 >> 8 & 255) / 255.0F; + float var13 = (float)(var5 & 255) / 255.0F; + GL11.glDisable(3553); + GL11.glEnable(3042); + GL11.glBlendFunc(770, 771); + GL11.glBegin(7); + GL11.glColor4f(var7, var8, var12, var6); + GL11.glVertex2f((float)var2, (float)var1); + GL11.glVertex2f((float)var0, (float)var1); + GL11.glColor4f(var10, var11, var13, var9); + GL11.glVertex2f((float)var0, (float)var3); + GL11.glVertex2f((float)var2, (float)var3); + GL11.glEnd(); + GL11.glDisable(3042); + GL11.glEnable(3553); + } + + public static void drawCenteredString(FontRenderer var0, String var1, int var2, int var3, int var4) { + var0.render(var1, var2 - var0.getWidth(var1) / 2, var3, var4); + } + + public static void drawString(FontRenderer var0, String var1, int var2, int var3, int var4) { + var0.render(var1, var2, var3, var4); + } + + public final void drawImage(int var1, int var2, int var3, int var4, int var5, int var6) { + float var7 = 0.00390625F; + float var8 = 0.00390625F; + ShapeRenderer var9 = ShapeRenderer.instance; + ShapeRenderer.instance.begin(); + var9.vertexUV((float)var1, (float)(var2 + var6), this.imgZ, (float)var3 * var7, (float)(var4 + var6) * var8); + var9.vertexUV((float)(var1 + var5), (float)(var2 + var6), this.imgZ, (float)(var3 + var5) * var7, (float)(var4 + var6) * var8); + var9.vertexUV((float)(var1 + var5), (float)var2, this.imgZ, (float)(var3 + var5) * var7, (float)var4 * var8); + var9.vertexUV((float)var1, (float)var2, this.imgZ, (float)var3 * var7, (float)var4 * var8); + var9.end(); + } +} diff --git a/src/main/java/com/mojang/minecraft/item/Arrow.java b/src/main/java/com/mojang/minecraft/item/Arrow.java new file mode 100644 index 0000000..641ab27 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/item/Arrow.java @@ -0,0 +1,294 @@ +package com.mojang.minecraft.item; + +import com.mojang.minecraft.Entity; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.phys.AABB; +import com.mojang.minecraft.player.Player; +import com.mojang.minecraft.render.ShapeRenderer; +import com.mojang.minecraft.render.TextureManager; +import com.mojang.util.MathHelper; +import java.util.List; +import org.lwjgl.opengl.GL11; + +public class Arrow extends Entity +{ + public Arrow(Level level1, Entity owner, float x, float y, float z, float unknown0, float unknown1, float unknown2) + { + super(level1); + + this.owner = owner; + + setSize(0.3F, 0.5F); + + heightOffset = bbHeight / 2.0F; + damage = 3; + + if(!(owner instanceof Player)) + { + type = 1; + } else { + damage = 7; + } + + heightOffset = 0.25F; + + float unknown3 = MathHelper.cos(-unknown0 * 0.017453292F - 3.1415927F); + float unknown4 = MathHelper.sin(-unknown0 * 0.017453292F - 3.1415927F); + + unknown0 = MathHelper.cos(-unknown1 * 0.017453292F); + unknown1 = MathHelper.sin(-unknown1 * 0.017453292F); + + slide = false; + + gravity = 1.0F / unknown2; + + xo -= unknown3 * 0.2F; + zo += unknown4 * 0.2F; + + x -= unknown3 * 0.2F; + z += unknown4 * 0.2F; + + xd = unknown4 * unknown0 * unknown2; + yd = unknown1 * unknown2; + zd = unknown3 * unknown0 * unknown2; + + setPos(x, y, z); + + unknown3 = MathHelper.sqrt(xd * xd + zd * zd); + + yRotO = yRot = (float)(Math.atan2((double)xd, (double)zd) * 180.0D / 3.1415927410125732D); + xRotO = xRot = (float)(Math.atan2((double)yd, (double)unknown3) * 180.0D / 3.1415927410125732D); + + makeStepSound = false; + } + + @Override + public void tick() + { + time++; + + xRotO = xRot; + yRotO = yRot; + + xo = x; + yo = y; + zo = z; + + if(hasHit) + { + stickTime++; + + if(type == 0) + { + if(stickTime >= 300 && Math.random() < 0.009999999776482582D) + { + remove(); + } + } else if(type == 1 && stickTime >= 20) { + remove(); + } + } else { + xd *= 0.998F; + yd *= 0.998F; + zd *= 0.998F; + + yd -= 0.02F * gravity; + + int unknown0 = (int)(MathHelper.sqrt(xd * xd + yd * yd + zd * zd) / 0.2F + 1.0F); + + float x0 = xd / (float)unknown0; + float y0 = yd / (float)unknown0; + float z0 = zd / (float)unknown0; + + for(int unknown4 = 0; unknown4 < unknown0 && !collision; unknown4++) + { + AABB unknown5 = bb.expand(x0, y0, z0); + + if(level.getCubes(unknown5).size() > 0) + { + collision = true; + } + + List blockMapEntitiesList = level.blockMap.getEntities(this, unknown5); + + for(int currentEntity = 0; currentEntity < blockMapEntitiesList.size(); currentEntity++) + { + Entity entity = (Entity)blockMapEntitiesList.get(currentEntity); + + if((entity).isShootable() && (entity != owner || time > 5)) + { + entity.hurt(this, damage); + + collision = true; + + remove(); + + return; + } + } + + if(!collision) + { + bb.move(x0, y0, z0); + + x += x0; + y += y0; + z += z0; + + blockMap.moved(this); + } + } + + if(collision) + { + hasHit = true; + + xd = yd = zd = 0.0F; + } + + if(!hasHit) + { + float unknown6 = MathHelper.sqrt(xd * xd + zd * zd); + + yRot = (float)(Math.atan2((double)xd, (double)zd) * 180.0D / 3.1415927410125732D); + + for(xRot = (float)(Math.atan2((double)yd, (double)unknown6) * 180.0D / 3.1415927410125732D); xRot - xRotO < -180.0F; xRotO -= 360.0F) + { + // TODO: ?. + } + + while(xRot - xRotO >= 180.0F) + { + xRotO += 360.0F; + } + + while(yRot - yRotO < -180.0F) + { + yRotO -= 360.0F; + } + + while(yRot - yRotO >= 180.0F) + { + yRotO += 360.0F; + } + } + } + } + + @Override + public void render(TextureManager textureManager, float unknown0) + { + textureId = textureManager.load("/item/arrows.png"); + + GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureId); + + float brightness = level.getBrightness((int)x, (int)y, (int)z); + + GL11.glPushMatrix(); + GL11.glColor4f(brightness, brightness, brightness, 1.0F); + GL11.glTranslatef(xo + (x - xo) * unknown0, this.yo + (this.y - this.yo) * unknown0 - this.heightOffset / 2.0F, this.zo + (this.z - this.zo) * unknown0); + GL11.glRotatef(yRotO + (yRot - yRotO) * unknown0 - 90.0F, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(xRotO + (xRot - xRotO) * unknown0, 0.0F, 0.0F, 1.0F); + GL11.glRotatef(45.0F, 1.0F, 0.0F, 0.0F); + + ShapeRenderer shapeRenderer = ShapeRenderer.instance; + + unknown0 = 0.5F; + + float unknown1 = (float)(0 + type * 10) / 32.0F; + float unknown2 = (float)(5 + type * 10) / 32.0F; + float unknown3 = 0.15625F; + + float unknown4 = (float)(5 + type * 10) / 32.0F; + float unknown5 = (float)(10 + type * 10) / 32.0F; + float unknown6 = 0.05625F; + + GL11.glScalef(0.05625F, unknown6, unknown6); + + GL11.glNormal3f(unknown6, 0.0F, 0.0F); + + shapeRenderer.begin(); + shapeRenderer.vertexUV(-7.0F, -2.0F, -2.0F, 0.0F, unknown4); + shapeRenderer.vertexUV(-7.0F, -2.0F, 2.0F, unknown3, unknown4); + shapeRenderer.vertexUV(-7.0F, 2.0F, 2.0F, unknown3, unknown5); + shapeRenderer.vertexUV(-7.0F, 2.0F, -2.0F, 0.0F, unknown5); + shapeRenderer.end(); + + GL11.glNormal3f(-unknown6, 0.0F, 0.0F); + + shapeRenderer.begin(); + shapeRenderer.vertexUV(-7.0F, 2.0F, -2.0F, 0.0F, unknown4); + shapeRenderer.vertexUV(-7.0F, 2.0F, 2.0F, unknown3, unknown4); + shapeRenderer.vertexUV(-7.0F, -2.0F, 2.0F, unknown3, unknown5); + shapeRenderer.vertexUV(-7.0F, -2.0F, -2.0F, 0.0F, unknown5); + shapeRenderer.end(); + + for(int unknown7 = 0; unknown7 < 4; unknown7++) + { + GL11.glRotatef(90.0F, 1.0F, 0.0F, 0.0F); + + GL11.glNormal3f(0.0F, -unknown6, 0.0F); + + shapeRenderer.vertexUV(-8.0F, -2.0F, 0.0F, 0.0F, unknown1); + shapeRenderer.vertexUV(8.0F, -2.0F, 0.0F, unknown0, unknown1); + shapeRenderer.vertexUV(8.0F, 2.0F, 0.0F, unknown0, unknown2); + shapeRenderer.vertexUV(-8.0F, 2.0F, 0.0F, 0.0F, unknown2); + shapeRenderer.end(); + } + + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glPopMatrix(); + } + + @Override + public void playerTouch(Entity entity) + { + Player player = (Player)entity; + + if(hasHit && owner == player && player.arrows < 99) + { + TakeEntityAnim takeEntityAnim = new TakeEntityAnim(level, this, player); + + level.addEntity(takeEntityAnim); + + player.arrows++; + + remove(); + } + } + + @Override + public void awardKillScore(Entity entity, int score) + { + owner.awardKillScore(entity, score); + } + + public static final long serialVersionUID = 0L; + + private float xd; + private float yd; + private float zd; + + private float yRot; + private float xRot; + private float yRotO; + private float xRotO; + + private boolean hasHit = false; + + private int stickTime = 0; + + private Entity owner; + + private int time = 0; + private int type = 0; + + private float gravity = 0.0F; + + private int damage; + + public Entity getOwner() + { + return owner; + } +} diff --git a/src/main/java/com/mojang/minecraft/item/Item.java b/src/main/java/com/mojang/minecraft/item/Item.java new file mode 100644 index 0000000..650cb9f --- /dev/null +++ b/src/main/java/com/mojang/minecraft/item/Item.java @@ -0,0 +1,149 @@ +package com.mojang.minecraft.item; + +import com.mojang.minecraft.Entity; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.level.tile.Block; +import com.mojang.minecraft.player.Player; +import com.mojang.minecraft.render.TextureManager; +import com.mojang.util.MathHelper; +import org.lwjgl.opengl.GL11; + +public class Item extends Entity +{ + public Item(Level level1, float x, float y, float z, int block) + { + super(level1); + + setSize(0.25F, 0.25F); + + heightOffset = bbHeight / 2.0F; + + setPos(x, y, z); + + resource = block; + + rot = (float)(Math.random() * 360.0D); + + xd = (float)(Math.random() * 0.20000000298023224D - 0.10000000149011612D); + yd = 0.2F; + zd = (float)(Math.random() * 0.20000000298023224D - 0.10000000149011612D); + + makeStepSound = false; + } + + @Override + public void tick() + { + xo = x; + yo = y; + zo = z; + + yd -= 0.04F; + + move(xd, yd, zd); + + xd *= 0.98F; + yd *= 0.98F; + zd *= 0.98F; + + if(onGround) + { + xd *= 0.7F; + zd *= 0.7F; + yd *= -0.5F; + } + + tickCount++; + + age++; + + if(age >= 6000) + { + remove(); + } + } + + @Override + public void render(TextureManager textureManager, float unknown0) + { + textureId = textureManager.load("/terrain.png"); + + GL11.glBindTexture(3553, this.textureId); + + float brightness = level.getBrightness((int)x, (int)y, (int)z); + float unknown1 = rot + ((float)tickCount + unknown0) * 3.0F; + + GL11.glPushMatrix(); + GL11.glColor4f(brightness, brightness, brightness, 1.0F); + + float unknown2 = (brightness = MathHelper.sin(unknown1 / 10.0F)) * 0.1F + 0.1F; + + GL11.glTranslatef(xo + (x - xo) * unknown0, yo + (y - yo) * unknown0 + unknown2, zo + (z - zo) * unknown0); + GL11.glRotatef(unknown1, 0.0F, 1.0F, 0.0F); + + models[resource].generateList(); + + brightness = (brightness = (brightness = brightness * 0.5F + 0.5F) * brightness) * brightness; + + GL11.glColor4f(1.0F, 1.0F, 1.0F, brightness * 0.4F); + GL11.glDisable(3553); + GL11.glEnable(3042); + GL11.glBlendFunc(770, 1); + GL11.glDisable(3008); + + models[resource].generateList(); + + GL11.glEnable(3008); + GL11.glDisable(3042); + GL11.glBlendFunc(770, 771); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glPopMatrix(); + GL11.glEnable(3553); + } + + @Override + public void playerTouch(Entity entity) + { + Player player = (Player)entity; + + if(player.addResource(resource)) + { + TakeEntityAnim takeEntityAnim = new TakeEntityAnim(level, this, player); + + level.addEntity(takeEntityAnim); + + remove(); + } + + } + + public static final long serialVersionUID = 0L; + + private static ItemModel[] models = new ItemModel[256]; + + private float xd; + private float yd; + private float zd; + + private float rot; + + private int resource; + + private int tickCount; + + private int age = 0; + + public static void initModels() + { + for(int unknown0 = 0; unknown0 < 256; unknown0++) + { + Block var1 = Block.blocks[unknown0]; + + if(var1 != null) + { + models[unknown0] = new ItemModel(var1.textureId); + } + } + + } +} diff --git a/src/main/java/com/mojang/minecraft/item/ItemModel.java b/src/main/java/com/mojang/minecraft/item/ItemModel.java new file mode 100644 index 0000000..d9a3693 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/item/ItemModel.java @@ -0,0 +1,62 @@ +package com.mojang.minecraft.item; + +import com.mojang.minecraft.model.ModelPart; +import com.mojang.minecraft.model.TexturedQuad; +import com.mojang.minecraft.model.Vertex; + +public class ItemModel +{ + public ItemModel(int tex) + { + float var3 = -2.0F; + float var4 = -2.0F; + float var15 = -2.0F; + + model.vertices = new Vertex[8]; + model.quads = new TexturedQuad[6]; + + Vertex vertex1 = new Vertex(var15, var4, var3, 0.0F, 0.0F); + Vertex vertex2 = new Vertex(2.0F, var4, var3, 0.0F, 8.0F); + Vertex vertex3 = new Vertex(2.0F, 2.0F, var3, 8.0F, 8.0F); + Vertex vertex4 = new Vertex(var15, 2.0F, var3, 8.0F, 0.0F); + Vertex vertex5 = new Vertex(var15, var4, 2.0F, 0.0F, 0.0F); + Vertex vertex6 = new Vertex(2.0F, var4, 2.0F, 0.0F, 8.0F); + Vertex vertex7 = new Vertex(2.0F, 2.0F, 2.0F, 8.0F, 8.0F); + Vertex vertex8 = new Vertex(var15, 2.0F, 2.0F, 8.0F, 0.0F); + + model.vertices[0] = vertex1; + model.vertices[1] = vertex2; + model.vertices[2] = vertex3; + model.vertices[3] = vertex4; + model.vertices[4] = vertex5; + model.vertices[5] = vertex6; + model.vertices[6] = vertex7; + model.vertices[7] = vertex8; + + float u1 = ((float)(tex % 16) + (1.0F - 0.25F)) / 16.0F; + float v1 = ((float)(tex / 16) + (1.0F - 0.25F)) / 16.0F; + float u2 = ((float)(tex % 16) + 0.25F) / 16.0F; + float v2 = ((float)(tex / 16) + 0.25F) / 16.0F; + + Vertex[] vertexes1 = new Vertex[] {vertex6, vertex2, vertex3, vertex7}; + Vertex[] vertexes2 = new Vertex[] {vertex1, vertex5, vertex8, vertex4}; + Vertex[] vertexes3 = new Vertex[] {vertex6, vertex5, vertex1, vertex2}; + Vertex[] vertexes4 = new Vertex[] {vertex3, vertex4, vertex8, vertex7}; + Vertex[] vertexes5 = new Vertex[] {vertex2, vertex1, vertex4, vertex3}; + Vertex[] vertexes6 = new Vertex[] {vertex5, vertex6, vertex7, vertex8}; + + model.quads[0] = new TexturedQuad(vertexes1, u1, v1, u2, v2); + model.quads[1] = new TexturedQuad(vertexes2, u1, v1, u2, v2); + model.quads[2] = new TexturedQuad(vertexes3, u1, v1, u2, v2); + model.quads[3] = new TexturedQuad(vertexes4, u1, v1, u2, v2); + model.quads[4] = new TexturedQuad(vertexes5, u1, v1, u2, v2); + model.quads[5] = new TexturedQuad(vertexes6, u1, v1, u2, v2); + } + + private ModelPart model = new ModelPart(0, 0); + + public void generateList() + { + model.render(0.0625F); + } +} diff --git a/src/main/java/com/mojang/minecraft/item/PrimedTnt.java b/src/main/java/com/mojang/minecraft/item/PrimedTnt.java new file mode 100644 index 0000000..814d511 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/item/PrimedTnt.java @@ -0,0 +1,192 @@ +package com.mojang.minecraft.item; + +import com.mojang.minecraft.Entity; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.level.tile.Block; +import com.mojang.minecraft.particle.SmokeParticle; +import com.mojang.minecraft.particle.TerrainParticle; +import com.mojang.minecraft.player.Player; +import com.mojang.minecraft.render.ShapeRenderer; +import com.mojang.minecraft.render.TextureManager; +import com.mojang.util.MathHelper; +import java.util.Random; +import org.lwjgl.opengl.GL11; + +public class PrimedTnt extends Entity +{ + public PrimedTnt(Level level1, float x, float y, float z) + { + super(level1); + + setSize(0.98F, 0.98F); + + heightOffset = bbHeight / 2.0F; + + setPos(x, y, z); + + float unknown0 = (float)(Math.random() * 3.1415927410125732D * 2.0D); + + xd = -MathHelper.sin(unknown0 * 3.1415927F / 180.0F) * 0.02F; + yd = 0.2F; + zd = -MathHelper.cos(unknown0 * 3.1415927F / 180.0F) * 0.02F; + + makeStepSound = false; + + life = 40; + + xo = x; + yo = y; + zo = z; + } + + @Override + public void tick() + { + xo = x; + yo = y; + zo = z; + + yd -= 0.04F; + + move(xd, yd, zd); + + xd *= 0.98F; + yd *= 0.98F; + zd *= 0.98F; + + if(onGround) + { + xd *= 0.7F; + zd *= 0.7F; + yd *= -0.5F; + } + + if(!defused) + { + if(life-- > 0) + { + SmokeParticle smokeParticle = new SmokeParticle(level, x, y + 0.6F, z); + + level.particleEngine.spawnParticle(smokeParticle); + } else { + remove(); + + Random random = new Random(); + float radius = 4.0F; + + level.explode(null, x, y, z, radius); + + for(int i = 0; i < 100; i++) + { + float unknown0 = (float)random.nextGaussian() * radius / 4.0F; + float unknown1 = (float)random.nextGaussian() * radius / 4.0F; + float unknown2 = (float)random.nextGaussian() * radius / 4.0F; + float unknown3 = MathHelper.sqrt(unknown0 * unknown0 + unknown1 * unknown1 + unknown2 * unknown2); + float unknown4 = unknown0 / unknown3 / unknown3; + float unknown5 = unknown1 / unknown3 / unknown3; + + unknown3 = unknown2 / unknown3 / unknown3; + + TerrainParticle terrainParticle = new TerrainParticle(level, x + unknown0, y + unknown1, z + unknown2, unknown4, unknown5, unknown3, Block.TNT); + + level.particleEngine.spawnParticle(terrainParticle); + } + + } + } + } + + @Override + public void render(TextureManager textureManager, float unknown0) + { + int textureID = textureManager.load("/terrain.png"); + + GL11.glBindTexture(3553, textureID); + + float brightness = level.getBrightness((int)x, (int)y, (int)z); + + GL11.glPushMatrix(); + GL11.glColor4f(brightness, brightness, brightness, 1.0F); + GL11.glTranslatef(xo + (x - xo) * unknown0 - 0.5F, yo + (y - yo) * unknown0 - 0.5F, zo + (z - zo) * unknown0 - 0.5F); + GL11.glPushMatrix(); + + ShapeRenderer shapeRenderer = ShapeRenderer.instance; + + Block.TNT.renderPreview(shapeRenderer); + + GL11.glDisable(3553); + GL11.glDisable(2896); + GL11.glColor4f(1.0F, 1.0F, 1.0F, (float)((life / 4 + 1) % 2) * 0.4F); + + if(life <= 16) + { + GL11.glColor4f(1.0F, 1.0F, 1.0F, (float)((life + 1) % 2) * 0.6F); + } + + if(life <= 2) + { + GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.9F); + } + + GL11.glEnable(3042); + GL11.glBlendFunc(770, 1); + + Block.TNT.renderPreview(shapeRenderer); + + GL11.glDisable(3042); + GL11.glEnable(3553); + GL11.glEnable(2896); + GL11.glPopMatrix(); + GL11.glPopMatrix(); + } + + @Override + public void playerTouch(Entity entity) + { + if(defused) + { + Player player = (Player)entity; + + if(player.addResource(Block.TNT.id)) + { + TakeEntityAnim takeEntityAnim = new TakeEntityAnim(this.level, this, player); + + level.addEntity(takeEntityAnim); + + remove(); + } + + } + } + + @Override + public void hurt(Entity entity, int damage) + { + if(!removed) + { + super.hurt(entity, damage); + + if(entity instanceof Player) + { + remove(); + + Item item = new Item(level, x, y, z, Block.TNT.id); + + level.addEntity(item); + } + + } + } + + @Override + public boolean isPickable() { + return !this.removed; + } + + public static final long serialVersionUID = 0L; + private float xd; + private float yd; + private float zd; + public int life = 0; + private boolean defused; +} diff --git a/src/main/java/com/mojang/minecraft/item/TakeEntityAnim.java b/src/main/java/com/mojang/minecraft/item/TakeEntityAnim.java new file mode 100644 index 0000000..335cb13 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/item/TakeEntityAnim.java @@ -0,0 +1,63 @@ +package com.mojang.minecraft.item; + +import com.mojang.minecraft.Entity; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.render.TextureManager; + +public class TakeEntityAnim extends Entity +{ + public TakeEntityAnim(Level level1, Entity item, Entity player) + { + super(level1); + + this.item = item; + this.player = player; + + setSize(1.0F, 1.0F); + + xorg = item.x; + yorg = item.y; + zorg = item.z; + } + + @Override + public void tick() + { + time++; + + if(time >= 3) + { + remove(); + } + + // TODO: Is this right? + float distance = (distance = (float)time / 3.0F) * distance; + + xo = item.xo = item.x; + yo = item.yo = item.y; + zo = item.zo = item.z; + + x = item.x = xorg + (player.x - xorg) * distance; + y = item.y = yorg + (player.y - 1.0F - yorg) * distance; + z = item.z = zorg + (player.z - zorg) * distance; + + setPos(x, y, z); + } + + @Override + public void render(TextureManager textureManager, float unknown0) + { + item.render(textureManager, unknown0); + } + + private static final long serialVersionUID = 1L; + + private int time = 0; + + private Entity item; + private Entity player; + + private float xorg; + private float yorg; + private float zorg; +} diff --git a/src/main/java/com/mojang/minecraft/level/BlockMap$Slot.java b/src/main/java/com/mojang/minecraft/level/BlockMap$Slot.java new file mode 100644 index 0000000..2267ecc --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/BlockMap$Slot.java @@ -0,0 +1,86 @@ +package com.mojang.minecraft.level; + +import com.mojang.minecraft.Entity; +import com.mojang.minecraft.level.BlockMap; +import com.mojang.minecraft.level.SyntheticClass; +import java.io.Serializable; + +class BlockMap$Slot implements Serializable { + + public static final long serialVersionUID = 0L; + private int xSlot; + private int ySlot; + private int zSlot; + // $FF: synthetic field + final BlockMap blockMap; + + + private BlockMap$Slot(BlockMap var1) { + this.blockMap = var1; + } + + public BlockMap$Slot init(float var1, float var2, float var3) { + this.xSlot = (int)(var1 / 16.0F); + this.ySlot = (int)(var2 / 16.0F); + this.zSlot = (int)(var3 / 16.0F); + if(this.xSlot < 0) { + this.xSlot = 0; + } + + if(this.ySlot < 0) { + this.ySlot = 0; + } + + if(this.zSlot < 0) { + this.zSlot = 0; + } + + if(this.xSlot >= BlockMap.getWidth(this.blockMap)) { + this.xSlot = BlockMap.getWidth(this.blockMap) - 1; + } + + if(this.ySlot >= BlockMap.getDepth(this.blockMap)) { + this.ySlot = BlockMap.getDepth(this.blockMap) - 1; + } + + if(this.zSlot >= BlockMap.getHeight(this.blockMap)) { + this.zSlot = BlockMap.getHeight(this.blockMap) - 1; + } + + return this; + } + + public void add(Entity var1) { + if(this.xSlot >= 0 && this.ySlot >= 0 && this.zSlot >= 0) { + this.blockMap.entityGrid[(this.zSlot * BlockMap.getDepth(this.blockMap) + this.ySlot) * BlockMap.getWidth(this.blockMap) + this.xSlot].add(var1); + } + + } + + public void remove(Entity var1) { + if(this.xSlot >= 0 && this.ySlot >= 0 && this.zSlot >= 0) { + this.blockMap.entityGrid[(this.zSlot * BlockMap.getDepth(this.blockMap) + this.ySlot) * BlockMap.getWidth(this.blockMap) + this.xSlot].remove(var1); + } + + } + + // $FF: synthetic method + BlockMap$Slot(BlockMap var1, SyntheticClass var2) { + this(var1); + } + + // $FF: synthetic method + static int getXSlot(BlockMap$Slot var0) { + return var0.xSlot; + } + + // $FF: synthetic method + static int getYSlot(BlockMap$Slot var0) { + return var0.ySlot; + } + + // $FF: synthetic method + static int getZSlot(BlockMap$Slot var0) { + return var0.zSlot; + } +} diff --git a/src/main/java/com/mojang/minecraft/level/BlockMap.java b/src/main/java/com/mojang/minecraft/level/BlockMap.java new file mode 100644 index 0000000..9d9f2ca --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/BlockMap.java @@ -0,0 +1,280 @@ +package com.mojang.minecraft.level; + +import com.mojang.minecraft.Entity; +import com.mojang.minecraft.level.BlockMap$Slot; +import com.mojang.minecraft.level.SyntheticClass; +import com.mojang.minecraft.model.Vec3D; +import com.mojang.minecraft.phys.AABB; +import com.mojang.minecraft.render.Frustrum; +import com.mojang.minecraft.render.TextureManager; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +public class BlockMap implements Serializable { + + public static final long serialVersionUID = 0L; + private int width; + private int depth; + private int height; + private BlockMap$Slot slot = new BlockMap$Slot(this, (SyntheticClass)null); + private BlockMap$Slot slot2 = new BlockMap$Slot(this, (SyntheticClass)null); + public List[] entityGrid; + public List all = new ArrayList(); + private List tmp = new ArrayList(); + + + public BlockMap(int var1, int var2, int var3) { + this.width = var1 / 16; + this.depth = var2 / 16; + this.height = var3 / 16; + if(this.width == 0) { + this.width = 1; + } + + if(this.depth == 0) { + this.depth = 1; + } + + if(this.height == 0) { + this.height = 1; + } + + this.entityGrid = new ArrayList[this.width * this.depth * this.height]; + + for(var1 = 0; var1 < this.width; ++var1) { + for(var2 = 0; var2 < this.depth; ++var2) { + for(var3 = 0; var3 < this.height; ++var3) { + this.entityGrid[(var3 * this.depth + var2) * this.width + var1] = new ArrayList(); + } + } + } + + } + + public void insert(Entity var1) { + this.all.add(var1); + this.slot.init(var1.x, var1.y, var1.z).add(var1); + var1.xOld = var1.x; + var1.yOld = var1.y; + var1.zOld = var1.z; + var1.blockMap = this; + } + + public void remove(Entity var1) { + this.slot.init(var1.xOld, var1.yOld, var1.zOld).remove(var1); + this.all.remove(var1); + } + + public void moved(Entity var1) { + BlockMap$Slot var2 = this.slot.init(var1.xOld, var1.yOld, var1.zOld); + BlockMap$Slot var3 = this.slot2.init(var1.x, var1.y, var1.z); + if(!var2.equals(var3)) { + var2.remove(var1); + var3.add(var1); + var1.xOld = var1.x; + var1.yOld = var1.y; + var1.zOld = var1.z; + } + } + + public List getEntities(Entity var1, float var2, float var3, float var4, float var5, float var6, float var7) { + this.tmp.clear(); + return this.getEntities(var1, var2, var3, var4, var5, var6, var7, this.tmp); + } + + public List getEntities(Entity var1, float var2, float var3, float var4, float var5, float var6, float var7, List var8) { + BlockMap$Slot var9 = this.slot.init(var2, var3, var4); + BlockMap$Slot var10 = this.slot2.init(var5, var6, var7); + + for(int var11 = BlockMap$Slot.getXSlot(var9) - 1; var11 <= BlockMap$Slot.getXSlot(var10) + 1; ++var11) { + for(int var12 = BlockMap$Slot.getYSlot(var9) - 1; var12 <= BlockMap$Slot.getYSlot(var10) + 1; ++var12) { + for(int var13 = BlockMap$Slot.getZSlot(var9) - 1; var13 <= BlockMap$Slot.getZSlot(var10) + 1; ++var13) { + if(var11 >= 0 && var12 >= 0 && var13 >= 0 && var11 < this.width && var12 < this.depth && var13 < this.height) { + List var14 = this.entityGrid[(var13 * this.depth + var12) * this.width + var11]; + + for(int var15 = 0; var15 < var14.size(); ++var15) { + Entity var16; + if((var16 = (Entity)var14.get(var15)) != var1 && var16.intersects(var2, var3, var4, var5, var6, var7)) { + var8.add(var16); + } + } + } + } + } + } + + return var8; + } + + public void removeAllNonCreativeModeEntities() { + for(int var1 = 0; var1 < this.width; ++var1) { + for(int var2 = 0; var2 < this.depth; ++var2) { + for(int var3 = 0; var3 < this.height; ++var3) { + List var4 = this.entityGrid[(var3 * this.depth + var2) * this.width + var1]; + + for(int var5 = 0; var5 < var4.size(); ++var5) { + if(!((Entity)var4.get(var5)).isCreativeModeAllowed()) { + var4.remove(var5--); + } + } + } + } + } + + } + + public void clear() { + for(int var1 = 0; var1 < this.width; ++var1) { + for(int var2 = 0; var2 < this.depth; ++var2) { + for(int var3 = 0; var3 < this.height; ++var3) { + this.entityGrid[(var3 * this.depth + var2) * this.width + var1].clear(); + } + } + } + + } + + public List getEntities(Entity var1, AABB var2) { + this.tmp.clear(); + return this.getEntities(var1, var2.x0, var2.y0, var2.z0, var2.x1, var2.y1, var2.z1, this.tmp); + } + + public List getEntities(Entity var1, AABB var2, List var3) { + return this.getEntities(var1, var2.x0, var2.y0, var2.z0, var2.x1, var2.y1, var2.z1, var3); + } + + public void tickAll() { + for(int var1 = 0; var1 < this.all.size(); ++var1) { + Entity var2; + (var2 = (Entity)this.all.get(var1)).tick(); + if(var2.removed) { + this.all.remove(var1--); + this.slot.init(var2.xOld, var2.yOld, var2.zOld).remove(var2); + } else { + int var3 = (int)(var2.xOld / 16.0F); + int var4 = (int)(var2.yOld / 16.0F); + int var5 = (int)(var2.zOld / 16.0F); + int var6 = (int)(var2.x / 16.0F); + int var7 = (int)(var2.y / 16.0F); + int var8 = (int)(var2.z / 16.0F); + if(var3 != var6 || var4 != var7 || var5 != var8) { + this.moved(var2); + } + } + } + + } + + public void render(Vec3D var1, Frustrum var2, TextureManager var3, float var4) { + for(int var5 = 0; var5 < this.width; ++var5) { + float var6 = (float)((var5 << 4) - 2); + float var7 = (float)((var5 + 1 << 4) + 2); + + for(int var8 = 0; var8 < this.depth; ++var8) { + float var9 = (float)((var8 << 4) - 2); + float var10 = (float)((var8 + 1 << 4) + 2); + + for(int var11 = 0; var11 < this.height; ++var11) { + List var12; + if((var12 = this.entityGrid[(var11 * this.depth + var8) * this.width + var5]).size() != 0) { + float var13 = (float)((var11 << 4) - 2); + float var14 = (float)((var11 + 1 << 4) + 2); + if(var2.isBoxInFrustrum(var6, var9, var13, var7, var10, var14)) { + float var16 = var14; + float var17 = var10; + float var15 = var7; + var14 = var13; + var13 = var9; + float var18 = var6; + Frustrum var19 = var2; + int var20 = 0; + + boolean var10000; + while(true) { + if(var20 >= 6) { + var10000 = true; + break; + } + + if(var19.frustrum[var20][0] * var18 + var19.frustrum[var20][1] * var13 + var19.frustrum[var20][2] * var14 + var19.frustrum[var20][3] <= 0.0F) { + var10000 = false; + break; + } + + if(var19.frustrum[var20][0] * var15 + var19.frustrum[var20][1] * var13 + var19.frustrum[var20][2] * var14 + var19.frustrum[var20][3] <= 0.0F) { + var10000 = false; + break; + } + + if(var19.frustrum[var20][0] * var18 + var19.frustrum[var20][1] * var17 + var19.frustrum[var20][2] * var14 + var19.frustrum[var20][3] <= 0.0F) { + var10000 = false; + break; + } + + if(var19.frustrum[var20][0] * var15 + var19.frustrum[var20][1] * var17 + var19.frustrum[var20][2] * var14 + var19.frustrum[var20][3] <= 0.0F) { + var10000 = false; + break; + } + + if(var19.frustrum[var20][0] * var18 + var19.frustrum[var20][1] * var13 + var19.frustrum[var20][2] * var16 + var19.frustrum[var20][3] <= 0.0F) { + var10000 = false; + break; + } + + if(var19.frustrum[var20][0] * var15 + var19.frustrum[var20][1] * var13 + var19.frustrum[var20][2] * var16 + var19.frustrum[var20][3] <= 0.0F) { + var10000 = false; + break; + } + + if(var19.frustrum[var20][0] * var18 + var19.frustrum[var20][1] * var17 + var19.frustrum[var20][2] * var16 + var19.frustrum[var20][3] <= 0.0F) { + var10000 = false; + break; + } + + if(var19.frustrum[var20][0] * var15 + var19.frustrum[var20][1] * var17 + var19.frustrum[var20][2] * var16 + var19.frustrum[var20][3] <= 0.0F) { + var10000 = false; + break; + } + + ++var20; + } + + boolean var21 = var10000; + + for(int var23 = 0; var23 < var12.size(); ++var23) { + Entity var22; + if((var22 = (Entity)var12.get(var23)).shouldRender(var1)) { + if(!var21) { + AABB var24 = var22.bb; + if(!var2.isBoxInFrustrum(var24.x0, var24.y0, var24.z0, var24.x1, var24.y1, var24.z1)) { + continue; + } + } + + var22.render(var3, var4); + } + } + } + } + } + } + } + + } + + // $FF: synthetic method + static int getWidth(BlockMap var0) { + return var0.width; + } + + // $FF: synthetic method + static int getDepth(BlockMap var0) { + return var0.depth; + } + + // $FF: synthetic method + static int getHeight(BlockMap var0) { + return var0.height; + } +} diff --git a/src/main/java/com/mojang/minecraft/level/Level.java b/src/main/java/com/mojang/minecraft/level/Level.java new file mode 100644 index 0000000..52e96cd --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/Level.java @@ -0,0 +1,1013 @@ +package com.mojang.minecraft.level; + +import com.mojang.minecraft.Entity; +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.MovingObjectPosition; +import com.mojang.minecraft.level.BlockMap; +import com.mojang.minecraft.level.NextTickListEntry; +import com.mojang.minecraft.level.liquid.LiquidType; +import com.mojang.minecraft.level.tile.Block; +import com.mojang.minecraft.model.Vec3D; +import com.mojang.minecraft.particle.ParticleManager; +import com.mojang.minecraft.phys.AABB; +import com.mojang.minecraft.render.LevelRenderer; +import com.mojang.minecraft.sound.AudioInfo; +import com.mojang.minecraft.sound.EntitySoundPos; +import com.mojang.minecraft.sound.LevelSoundPos; +import com.mojang.util.MathHelper; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Random; + +public class Level implements Serializable { + + public static final long serialVersionUID = 0L; + public int width; + public int height; + public int depth; + public byte[] blocks; + public String name; + public String creator; + public long createTime; + public int xSpawn; + public int ySpawn; + public int zSpawn; + public float rotSpawn; + private transient ArrayList listeners = new ArrayList(); + private transient int[] blockers; + public transient Random random = new Random(); + private transient int randId; + private transient ArrayList tickList; + public BlockMap blockMap; + private boolean networkMode; + public transient Minecraft rendererContext$5cd64a7f; + public boolean creativeMode; + public int waterLevel; + public int skyColor; + public int fogColor; + public int cloudColor; + int unprocessed; + private int tickCount; + public Entity player; + public transient ParticleManager particleEngine; + public transient Object font; + public boolean growTrees; + + + public Level() { + this.randId = this.random.nextInt(); + this.tickList = new ArrayList(); + this.networkMode = false; + this.unprocessed = 0; + this.tickCount = 0; + this.growTrees = false; + } + + public void initTransient() { + if(this.blocks == null) { + throw new RuntimeException("The level is corrupt!"); + } else { + this.listeners = new ArrayList(); + this.blockers = new int[this.width * this.height]; + Arrays.fill(this.blockers, this.depth); + this.calcLightDepths(0, 0, this.width, this.height); + this.random = new Random(); + this.randId = this.random.nextInt(); + this.tickList = new ArrayList(); + if(this.waterLevel == 0) { + this.waterLevel = this.depth / 2; + } + + if(this.skyColor == 0) { + this.skyColor = 10079487; + } + + if(this.fogColor == 0) { + this.fogColor = 16777215; + } + + if(this.cloudColor == 0) { + this.cloudColor = 16777215; + } + + if(this.xSpawn == 0 && this.ySpawn == 0 && this.zSpawn == 0) { + this.findSpawn(); + } + + if(this.blockMap == null) { + this.blockMap = new BlockMap(this.width, this.depth, this.height); + } + + } + } + + public void setData(int var1, int var2, int var3, byte[] var4) { + this.width = var1; + this.height = var3; + this.depth = var2; + this.blocks = var4; + this.blockers = new int[var1 * var3]; + Arrays.fill(this.blockers, this.depth); + this.calcLightDepths(0, 0, var1, var3); + + for(var1 = 0; var1 < this.listeners.size(); ++var1) { + ((LevelRenderer)this.listeners.get(var1)).refresh(); + } + + this.tickList.clear(); + this.findSpawn(); + this.initTransient(); + System.gc(); + } + + public void findSpawn() { + Random var1 = new Random(); + int var2 = 0; + + int var3; + int var4; + int var5; + do { + ++var2; + var3 = var1.nextInt(this.width / 2) + this.width / 4; + var4 = var1.nextInt(this.height / 2) + this.height / 4; + var5 = this.getHighestTile(var3, var4) + 1; + if(var2 == 10000) { + this.xSpawn = var3; + this.ySpawn = -100; + this.zSpawn = var4; + return; + } + } while((float)var5 <= this.getWaterLevel()); + + this.xSpawn = var3; + this.ySpawn = var5; + this.zSpawn = var4; + } + + public void calcLightDepths(int var1, int var2, int var3, int var4) { + for(int var5 = var1; var5 < var1 + var3; ++var5) { + for(int var6 = var2; var6 < var2 + var4; ++var6) { + int var7 = this.blockers[var5 + var6 * this.width]; + + int var8; + for(var8 = this.depth - 1; var8 > 0 && !this.isLightBlocker(var5, var8, var6); --var8) { + ; + } + + this.blockers[var5 + var6 * this.width] = var8; + if(var7 != var8) { + int var9 = var7 < var8?var7:var8; + var7 = var7 > var8?var7:var8; + + for(var8 = 0; var8 < this.listeners.size(); ++var8) { + ((LevelRenderer)this.listeners.get(var8)).queueChunks(var5 - 1, var9 - 1, var6 - 1, var5 + 1, var7 + 1, var6 + 1); + } + } + } + } + + } + + public void addListener(LevelRenderer var1) { + this.listeners.add(var1); + } + + public void finalize() {} + + public void removeListener(LevelRenderer var1) { + this.listeners.remove(var1); + } + + public boolean isLightBlocker(int var1, int var2, int var3) { + Block var4; + return (var4 = Block.blocks[this.getTile(var1, var2, var3)]) == null?false:var4.isOpaque(); + } + + public ArrayList getCubes(AABB var1) { + ArrayList var2 = new ArrayList(); + int var3 = (int)var1.x0; + int var4 = (int)var1.x1 + 1; + int var5 = (int)var1.y0; + int var6 = (int)var1.y1 + 1; + int var7 = (int)var1.z0; + int var8 = (int)var1.z1 + 1; + if(var1.x0 < 0.0F) { + --var3; + } + + if(var1.y0 < 0.0F) { + --var5; + } + + if(var1.z0 < 0.0F) { + --var7; + } + + for(var3 = var3; var3 < var4; ++var3) { + for(int var9 = var5; var9 < var6; ++var9) { + for(int var10 = var7; var10 < var8; ++var10) { + AABB var11; + if(var3 >= 0 && var9 >= 0 && var10 >= 0 && var3 < this.width && var9 < this.depth && var10 < this.height) { + Block var12; + if((var12 = Block.blocks[this.getTile(var3, var9, var10)]) != null && (var11 = var12.getCollisionBox(var3, var9, var10)) != null && var1.intersectsInner(var11)) { + var2.add(var11); + } + } else if((var3 < 0 || var9 < 0 || var10 < 0 || var3 >= this.width || var10 >= this.height) && (var11 = Block.BEDROCK.getCollisionBox(var3, var9, var10)) != null && var1.intersectsInner(var11)) { + var2.add(var11); + } + } + } + } + + return var2; + } + + public void swap(int var1, int var2, int var3, int var4, int var5, int var6) { + if(!this.networkMode) { + int var7 = this.getTile(var1, var2, var3); + int var8 = this.getTile(var4, var5, var6); + this.setTileNoNeighborChange(var1, var2, var3, var8); + this.setTileNoNeighborChange(var4, var5, var6, var7); + this.updateNeighborsAt(var1, var2, var3, var8); + this.updateNeighborsAt(var4, var5, var6, var7); + } + } + + public boolean setTileNoNeighborChange(int var1, int var2, int var3, int var4) { + return this.networkMode?false:this.netSetTileNoNeighborChange(var1, var2, var3, var4); + } + + public boolean netSetTileNoNeighborChange(int var1, int var2, int var3, int var4) { + if(var1 >= 0 && var2 >= 0 && var3 >= 0 && var1 < this.width && var2 < this.depth && var3 < this.height) { + if(var4 == this.blocks[(var2 * this.height + var3) * this.width + var1]) { + return false; + } else { + if(var4 == 0 && (var1 == 0 || var3 == 0 || var1 == this.width - 1 || var3 == this.height - 1) && (float)var2 >= this.getGroundLevel() && (float)var2 < this.getWaterLevel()) { + var4 = Block.WATER.id; + } + + byte var5 = this.blocks[(var2 * this.height + var3) * this.width + var1]; + this.blocks[(var2 * this.height + var3) * this.width + var1] = (byte)var4; + if(var5 != 0) { + Block.blocks[var5].onRemoved(this, var1, var2, var3); + } + + if(var4 != 0) { + Block.blocks[var4].onAdded(this, var1, var2, var3); + } + + this.calcLightDepths(var1, var3, 1, 1); + + for(var4 = 0; var4 < this.listeners.size(); ++var4) { + ((LevelRenderer)this.listeners.get(var4)).queueChunks(var1 - 1, var2 - 1, var3 - 1, var1 + 1, var2 + 1, var3 + 1); + } + + return true; + } + } else { + return false; + } + } + + public boolean setTile(int var1, int var2, int var3, int var4) { + if(this.networkMode) { + return false; + } else if(this.setTileNoNeighborChange(var1, var2, var3, var4)) { + this.updateNeighborsAt(var1, var2, var3, var4); + return true; + } else { + return false; + } + } + + public boolean netSetTile(int var1, int var2, int var3, int var4) { + if(this.netSetTileNoNeighborChange(var1, var2, var3, var4)) { + this.updateNeighborsAt(var1, var2, var3, var4); + return true; + } else { + return false; + } + } + + public void updateNeighborsAt(int var1, int var2, int var3, int var4) { + this.updateTile(var1 - 1, var2, var3, var4); + this.updateTile(var1 + 1, var2, var3, var4); + this.updateTile(var1, var2 - 1, var3, var4); + this.updateTile(var1, var2 + 1, var3, var4); + this.updateTile(var1, var2, var3 - 1, var4); + this.updateTile(var1, var2, var3 + 1, var4); + } + + public boolean setTileNoUpdate(int var1, int var2, int var3, int var4) { + if(var1 >= 0 && var2 >= 0 && var3 >= 0 && var1 < this.width && var2 < this.depth && var3 < this.height) { + if(var4 == this.blocks[(var2 * this.height + var3) * this.width + var1]) { + return false; + } else { + this.blocks[(var2 * this.height + var3) * this.width + var1] = (byte)var4; + return true; + } + } else { + return false; + } + } + + private void updateTile(int var1, int var2, int var3, int var4) { + if(var1 >= 0 && var2 >= 0 && var3 >= 0 && var1 < this.width && var2 < this.depth && var3 < this.height) { + Block var5; + if((var5 = Block.blocks[this.blocks[(var2 * this.height + var3) * this.width + var1]]) != null) { + var5.onNeighborChange(this, var1, var2, var3, var4); + } + + } + } + + public boolean isLit(int var1, int var2, int var3) { + return var1 >= 0 && var2 >= 0 && var3 >= 0 && var1 < this.width && var2 < this.depth && var3 < this.height?var2 >= this.blockers[var1 + var3 * this.width]:true; + } + + public int getTile(int var1, int var2, int var3) { + return var1 >= 0 && var2 >= 0 && var3 >= 0 && var1 < this.width && var2 < this.depth && var3 < this.height?this.blocks[(var2 * this.height + var3) * this.width + var1] & 255:0; + } + + public boolean isSolidTile(int var1, int var2, int var3) { + Block var4; + return (var4 = Block.blocks[this.getTile(var1, var2, var3)]) == null?false:var4.isSolid(); + } + + public void tickEntities() { + this.blockMap.tickAll(); + } + + public void tick() { + ++this.tickCount; + int var1 = 1; + + int var2; + for(var2 = 1; 1 << var1 < this.width; ++var1) { + ; + } + + while(1 << var2 < this.height) { + ++var2; + } + + int var3 = this.height - 1; + int var4 = this.width - 1; + int var5 = this.depth - 1; + int var6; + int var7; + if(this.tickCount % 5 == 0) { + var6 = this.tickList.size(); + + for(var7 = 0; var7 < var6; ++var7) { + NextTickListEntry var8; + if((var8 = (NextTickListEntry)this.tickList.remove(0)).ticks > 0) { + --var8.ticks; + this.tickList.add(var8); + } else { + byte var9; + if(this.isInBounds(var8.x, var8.y, var8.z) && (var9 = this.blocks[(var8.y * this.height + var8.z) * this.width + var8.x]) == var8.block && var9 > 0) { + Block.blocks[var9].update(this, var8.x, var8.y, var8.z, this.random); + } + } + } + } + + this.unprocessed += this.width * this.height * this.depth; + var6 = this.unprocessed / 200; + this.unprocessed -= var6 * 200; + + for(var7 = 0; var7 < var6; ++var7) { + this.randId = this.randId * 3 + 1013904223; + int var12; + int var13 = (var12 = this.randId >> 2) & var4; + int var10 = var12 >> var1 & var3; + var12 = var12 >> var1 + var2 & var5; + byte var11 = this.blocks[(var12 * this.height + var10) * this.width + var13]; + if(Block.physics[var11]) { + Block.blocks[var11].update(this, var13, var12, var10, this.random); + } + } + + } + + public int countInstanceOf(Class var1) { + int var2 = 0; + + for(int var3 = 0; var3 < this.blockMap.all.size(); ++var3) { + Entity var4 = (Entity)this.blockMap.all.get(var3); + if(var1.isAssignableFrom(var4.getClass())) { + ++var2; + } + } + + return var2; + } + + private boolean isInBounds(int var1, int var2, int var3) { + return var1 >= 0 && var2 >= 0 && var3 >= 0 && var1 < this.width && var2 < this.depth && var3 < this.height; + } + + public float getGroundLevel() { + return this.getWaterLevel() - 2.0F; + } + + public float getWaterLevel() { + return (float)this.waterLevel; + } + + public boolean containsAnyLiquid(AABB var1) { + int var2 = (int)var1.x0; + int var3 = (int)var1.x1 + 1; + int var4 = (int)var1.y0; + int var5 = (int)var1.y1 + 1; + int var6 = (int)var1.z0; + int var7 = (int)var1.z1 + 1; + if(var1.x0 < 0.0F) { + --var2; + } + + if(var1.y0 < 0.0F) { + --var4; + } + + if(var1.z0 < 0.0F) { + --var6; + } + + if(var2 < 0) { + var2 = 0; + } + + if(var4 < 0) { + var4 = 0; + } + + if(var6 < 0) { + var6 = 0; + } + + if(var3 > this.width) { + var3 = this.width; + } + + if(var5 > this.depth) { + var5 = this.depth; + } + + if(var7 > this.height) { + var7 = this.height; + } + + for(int var10 = var2; var10 < var3; ++var10) { + for(var2 = var4; var2 < var5; ++var2) { + for(int var8 = var6; var8 < var7; ++var8) { + Block var9; + if((var9 = Block.blocks[this.getTile(var10, var2, var8)]) != null && var9.getLiquidType() != LiquidType.NOT_LIQUID) { + return true; + } + } + } + } + + return false; + } + + public boolean containsLiquid(AABB var1, LiquidType var2) { + int var3 = (int)var1.x0; + int var4 = (int)var1.x1 + 1; + int var5 = (int)var1.y0; + int var6 = (int)var1.y1 + 1; + int var7 = (int)var1.z0; + int var8 = (int)var1.z1 + 1; + if(var1.x0 < 0.0F) { + --var3; + } + + if(var1.y0 < 0.0F) { + --var5; + } + + if(var1.z0 < 0.0F) { + --var7; + } + + if(var3 < 0) { + var3 = 0; + } + + if(var5 < 0) { + var5 = 0; + } + + if(var7 < 0) { + var7 = 0; + } + + if(var4 > this.width) { + var4 = this.width; + } + + if(var6 > this.depth) { + var6 = this.depth; + } + + if(var8 > this.height) { + var8 = this.height; + } + + for(int var11 = var3; var11 < var4; ++var11) { + for(var3 = var5; var3 < var6; ++var3) { + for(int var9 = var7; var9 < var8; ++var9) { + Block var10; + if((var10 = Block.blocks[this.getTile(var11, var3, var9)]) != null && var10.getLiquidType() == var2) { + return true; + } + } + } + } + + return false; + } + + public void addToTickNextTick(int var1, int var2, int var3, int var4) { + if(!this.networkMode) { + NextTickListEntry var5 = new NextTickListEntry(var1, var2, var3, var4); + if(var4 > 0) { + var3 = Block.blocks[var4].getTickDelay(); + var5.ticks = var3; + } + + this.tickList.add(var5); + } + } + + public boolean isFree(AABB var1) { + return this.blockMap.getEntities((Entity)null, var1).size() == 0; + } + + public List findEntities(Entity var1, AABB var2) { + return this.blockMap.getEntities(var1, var2); + } + + public boolean isSolid(float var1, float var2, float var3, float var4) { + return this.isSolid(var1 - var4, var2 - var4, var3 - var4)?true:(this.isSolid(var1 - var4, var2 - var4, var3 + var4)?true:(this.isSolid(var1 - var4, var2 + var4, var3 - var4)?true:(this.isSolid(var1 - var4, var2 + var4, var3 + var4)?true:(this.isSolid(var1 + var4, var2 - var4, var3 - var4)?true:(this.isSolid(var1 + var4, var2 - var4, var3 + var4)?true:(this.isSolid(var1 + var4, var2 + var4, var3 - var4)?true:this.isSolid(var1 + var4, var2 + var4, var3 + var4))))))); + } + + private boolean isSolid(float var1, float var2, float var3) { + int var4; + return (var4 = this.getTile((int)var1, (int)var2, (int)var3)) > 0 && Block.blocks[var4].isSolid(); + } + + public int getHighestTile(int var1, int var2) { + int var3; + for(var3 = this.depth; (this.getTile(var1, var3 - 1, var2) == 0 || Block.blocks[this.getTile(var1, var3 - 1, var2)].getLiquidType() != LiquidType.NOT_LIQUID) && var3 > 0; --var3) { + ; + } + + return var3; + } + + public void setSpawnPos(int var1, int var2, int var3, float var4) { + this.xSpawn = var1; + this.ySpawn = var2; + this.zSpawn = var3; + this.rotSpawn = var4; + } + + public float getBrightness(int var1, int var2, int var3) { + return this.isLit(var1, var2, var3)?1.0F:0.6F; + } + + public float getCaveness(float var1, float var2, float var3, float var4) { + int var5 = (int)var1; + int var14 = (int)var2; + int var6 = (int)var3; + float var7 = 0.0F; + float var8 = 0.0F; + + for(int var9 = var5 - 6; var9 <= var5 + 6; ++var9) { + for(int var10 = var6 - 6; var10 <= var6 + 6; ++var10) { + if(this.isInBounds(var9, var14, var10) && !this.isSolidTile(var9, var14, var10)) { + float var11 = (float)var9 + 0.5F - var1; + + float var12; + float var13; + for(var13 = (float)(Math.atan2((double)(var12 = (float)var10 + 0.5F - var3), (double)var11) - (double)(var4 * 3.1415927F / 180.0F) + 1.5707963705062866D); var13 < -3.1415927F; var13 += 6.2831855F) { + ; + } + + while(var13 >= 3.1415927F) { + var13 -= 6.2831855F; + } + + if(var13 < 0.0F) { + var13 = -var13; + } + + var11 = MathHelper.sqrt(var11 * var11 + 4.0F + var12 * var12); + var11 = 1.0F / var11; + if(var13 > 1.0F) { + var11 = 0.0F; + } + + if(var11 < 0.0F) { + var11 = 0.0F; + } + + var8 += var11; + if(this.isLit(var9, var14, var10)) { + var7 += var11; + } + } + } + } + + if(var8 == 0.0F) { + return 0.0F; + } else { + return var7 / var8; + } + } + + public float getCaveness(Entity var1) { + float var2 = MathHelper.cos(-var1.yRot * 0.017453292F + 3.1415927F); + float var3 = MathHelper.sin(-var1.yRot * 0.017453292F + 3.1415927F); + float var4 = MathHelper.cos(-var1.xRot * 0.017453292F); + float var5 = MathHelper.sin(-var1.xRot * 0.017453292F); + float var6 = var1.x; + float var7 = var1.y; + float var21 = var1.z; + float var8 = 1.6F; + float var9 = 0.0F; + float var10 = 0.0F; + + for(int var11 = 0; var11 <= 200; ++var11) { + float var12 = ((float)var11 / (float)200 - 0.5F) * 2.0F; + int var13 = 0; + + while(var13 <= 200) { + float var14 = ((float)var13 / (float)200 - 0.5F) * var8; + float var16 = var4 * var14 + var5; + var14 = var4 - var5 * var14; + float var17 = var2 * var12 + var3 * var14; + var16 = var16; + var14 = var2 * var14 - var3 * var12; + int var15 = 0; + + while(true) { + if(var15 < 10) { + float var18 = var6 + var17 * (float)var15 * 0.8F; + float var19 = var7 + var16 * (float)var15 * 0.8F; + float var20 = var21 + var14 * (float)var15 * 0.8F; + if(!this.isSolid(var18, var19, var20)) { + ++var9; + if(this.isLit((int)var18, (int)var19, (int)var20)) { + ++var10; + } + + ++var15; + continue; + } + } + + ++var13; + break; + } + } + } + + if(var9 == 0.0F) { + return 0.0F; + } else { + float var22; + if((var22 = var10 / var9 / 0.1F) > 1.0F) { + var22 = 1.0F; + } + + var22 = 1.0F - var22; + return 1.0F - var22 * var22 * var22; + } + } + + public byte[] copyBlocks() { + return Arrays.copyOf(this.blocks, this.blocks.length); + } + + public LiquidType getLiquid(int var1, int var2, int var3) { + int var4; + return (var4 = this.getTile(var1, var2, var3)) == 0?LiquidType.NOT_LIQUID:Block.blocks[var4].getLiquidType(); + } + + public boolean isWater(int var1, int var2, int var3) { + int var4; + return (var4 = this.getTile(var1, var2, var3)) > 0 && Block.blocks[var4].getLiquidType() == LiquidType.WATER; + } + + public void setNetworkMode(boolean var1) { + this.networkMode = var1; + } + + public MovingObjectPosition clip(Vec3D var1, Vec3D var2) { + if(!Float.isNaN(var1.x) && !Float.isNaN(var1.y) && !Float.isNaN(var1.z)) { + if(!Float.isNaN(var2.x) && !Float.isNaN(var2.y) && !Float.isNaN(var2.z)) { + int var3 = (int)Math.floor((double)var2.x); + int var4 = (int)Math.floor((double)var2.y); + int var5 = (int)Math.floor((double)var2.z); + int var6 = (int)Math.floor((double)var1.x); + int var7 = (int)Math.floor((double)var1.y); + int var8 = (int)Math.floor((double)var1.z); + int var9 = 20; + + while(var9-- >= 0) { + if(Float.isNaN(var1.x) || Float.isNaN(var1.y) || Float.isNaN(var1.z)) { + return null; + } + + if(var6 == var3 && var7 == var4 && var8 == var5) { + return null; + } + + float var10 = 999.0F; + float var11 = 999.0F; + float var12 = 999.0F; + if(var3 > var6) { + var10 = (float)var6 + 1.0F; + } + + if(var3 < var6) { + var10 = (float)var6; + } + + if(var4 > var7) { + var11 = (float)var7 + 1.0F; + } + + if(var4 < var7) { + var11 = (float)var7; + } + + if(var5 > var8) { + var12 = (float)var8 + 1.0F; + } + + if(var5 < var8) { + var12 = (float)var8; + } + + float var13 = 999.0F; + float var14 = 999.0F; + float var15 = 999.0F; + float var16 = var2.x - var1.x; + float var17 = var2.y - var1.y; + float var18 = var2.z - var1.z; + if(var10 != 999.0F) { + var13 = (var10 - var1.x) / var16; + } + + if(var11 != 999.0F) { + var14 = (var11 - var1.y) / var17; + } + + if(var12 != 999.0F) { + var15 = (var12 - var1.z) / var18; + } + + boolean var19 = false; + byte var24; + if(var13 < var14 && var13 < var15) { + if(var3 > var6) { + var24 = 4; + } else { + var24 = 5; + } + + var1.x = var10; + var1.y += var17 * var13; + var1.z += var18 * var13; + } else if(var14 < var15) { + if(var4 > var7) { + var24 = 0; + } else { + var24 = 1; + } + + var1.x += var16 * var14; + var1.y = var11; + var1.z += var18 * var14; + } else { + if(var5 > var8) { + var24 = 2; + } else { + var24 = 3; + } + + var1.x += var16 * var15; + var1.y += var17 * var15; + var1.z = var12; + } + + Vec3D var20; + var6 = (int)((var20 = new Vec3D(var1.x, var1.y, var1.z)).x = (float)Math.floor((double)var1.x)); + if(var24 == 5) { + --var6; + ++var20.x; + } + + var7 = (int)(var20.y = (float)Math.floor((double)var1.y)); + if(var24 == 1) { + --var7; + ++var20.y; + } + + var8 = (int)(var20.z = (float)Math.floor((double)var1.z)); + if(var24 == 3) { + --var8; + ++var20.z; + } + + int var22 = this.getTile(var6, var7, var8); + Block var21 = Block.blocks[var22]; + if(var22 > 0 && var21.getLiquidType() == LiquidType.NOT_LIQUID) { + MovingObjectPosition var23; + if(var21.isCube()) { + if((var23 = var21.clip(var6, var7, var8, var1, var2)) != null) { + return var23; + } + } else if((var23 = var21.clip(var6, var7, var8, var1, var2)) != null) { + return var23; + } + } + } + + return null; + } else { + return null; + } + } else { + return null; + } + } + + public void playSound(String var1, Entity var2, float var3, float var4) { + if(this.rendererContext$5cd64a7f != null) { + Minecraft var5; + if((var5 = this.rendererContext$5cd64a7f).soundPlayer == null || !var5.settings.sound) { + return; + } + + AudioInfo var6; + if(var2.distanceToSqr(var5.player) < 1024.0F && (var6 = var5.sound.getAudioInfo(var1, var3, var4)) != null) { + var5.soundPlayer.play(var6, new EntitySoundPos(var2, var5.player)); + } + } + + } + + public void playSound(String var1, float var2, float var3, float var4, float var5, float var6) { + if(this.rendererContext$5cd64a7f != null) { + Minecraft var7; + if((var7 = this.rendererContext$5cd64a7f).soundPlayer == null || !var7.settings.sound) { + return; + } + + AudioInfo var8; + if((var8 = var7.sound.getAudioInfo(var1, var5, var6)) != null) { + var7.soundPlayer.play(var8, new LevelSoundPos(var2, var3, var4, var7.player)); + } + } + + } + + public boolean maybeGrowTree(int var1, int var2, int var3) { + int var4 = this.random.nextInt(3) + 4; + boolean var5 = true; + + int var6; + int var8; + int var9; + for(var6 = var2; var6 <= var2 + 1 + var4; ++var6) { + byte var7 = 1; + if(var6 == var2) { + var7 = 0; + } + + if(var6 >= var2 + 1 + var4 - 2) { + var7 = 2; + } + + for(var8 = var1 - var7; var8 <= var1 + var7 && var5; ++var8) { + for(var9 = var3 - var7; var9 <= var3 + var7 && var5; ++var9) { + if(var8 >= 0 && var6 >= 0 && var9 >= 0 && var8 < this.width && var6 < this.depth && var9 < this.height) { + if((this.blocks[(var6 * this.height + var9) * this.width + var8] & 255) != 0) { + var5 = false; + } + } else { + var5 = false; + } + } + } + } + + if(!var5) { + return false; + } else if((this.blocks[((var2 - 1) * this.height + var3) * this.width + var1] & 255) == Block.GRASS.id && var2 < this.depth - var4 - 1) { + this.setTile(var1, var2 - 1, var3, Block.DIRT.id); + + int var13; + for(var13 = var2 - 3 + var4; var13 <= var2 + var4; ++var13) { + var8 = var13 - (var2 + var4); + var9 = 1 - var8 / 2; + + for(int var10 = var1 - var9; var10 <= var1 + var9; ++var10) { + int var12 = var10 - var1; + + for(var6 = var3 - var9; var6 <= var3 + var9; ++var6) { + int var11 = var6 - var3; + if(Math.abs(var12) != var9 || Math.abs(var11) != var9 || this.random.nextInt(2) != 0 && var8 != 0) { + this.setTile(var10, var13, var6, Block.LEAVES.id); + } + } + } + } + + for(var13 = 0; var13 < var4; ++var13) { + this.setTile(var1, var2 + var13, var3, Block.LOG.id); + } + + return true; + } else { + return false; + } + } + + public Entity getPlayer() { + return this.player; + } + + public void addEntity(Entity var1) { + this.blockMap.insert(var1); + var1.setLevel(this); + } + + public void removeEntity(Entity var1) { + this.blockMap.remove(var1); + } + + public void explode(Entity var1, float var2, float var3, float var4, float var5) { + int var6 = (int)(var2 - var5 - 1.0F); + int var7 = (int)(var2 + var5 + 1.0F); + int var8 = (int)(var3 - var5 - 1.0F); + int var9 = (int)(var3 + var5 + 1.0F); + int var10 = (int)(var4 - var5 - 1.0F); + int var11 = (int)(var4 + var5 + 1.0F); + + int var13; + float var15; + float var16; + for(int var12 = var6; var12 < var7; ++var12) { + for(var13 = var9 - 1; var13 >= var8; --var13) { + for(int var14 = var10; var14 < var11; ++var14) { + var15 = (float)var12 + 0.5F - var2; + var16 = (float)var13 + 0.5F - var3; + float var17 = (float)var14 + 0.5F - var4; + int var19; + if(var12 >= 0 && var13 >= 0 && var14 >= 0 && var12 < this.width && var13 < this.depth && var14 < this.height && var15 * var15 + var16 * var16 + var17 * var17 < var5 * var5 && (var19 = this.getTile(var12, var13, var14)) > 0 && Block.blocks[var19].canExplode()) { + Block.blocks[var19].dropItems(this, var12, var13, var14, 0.3F); + this.setTile(var12, var13, var14, 0); + Block.blocks[var19].explode(this, var12, var13, var14); + } + } + } + } + + List var18 = this.blockMap.getEntities(var1, (float)var6, (float)var8, (float)var10, (float)var7, (float)var9, (float)var11); + + for(var13 = 0; var13 < var18.size(); ++var13) { + Entity var20; + if((var15 = (var20 = (Entity)var18.get(var13)).distanceTo(var2, var3, var4) / var5) <= 1.0F) { + var16 = 1.0F - var15; + var20.hurt(var1, (int)(var16 * 15.0F + 1.0F)); + } + } + + } + + public Entity findSubclassOf(Class var1) { + for(int var2 = 0; var2 < this.blockMap.all.size(); ++var2) { + Entity var3 = (Entity)this.blockMap.all.get(var2); + if(var1.isAssignableFrom(var3.getClass())) { + return var3; + } + } + + return null; + } + + public void removeAllNonCreativeModeEntities() { + this.blockMap.removeAllNonCreativeModeEntities(); + } +} diff --git a/src/main/java/com/mojang/minecraft/level/LevelIO.java b/src/main/java/com/mojang/minecraft/level/LevelIO.java new file mode 100644 index 0000000..ba10a5e --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/LevelIO.java @@ -0,0 +1,258 @@ +package com.mojang.minecraft.level; + +import com.mojang.minecraft.ProgressBarDisplay; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.level.LevelObjectInputStream; +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +public final class LevelIO { + + private ProgressBarDisplay progressBar; + + + public LevelIO(ProgressBarDisplay var1) { + this.progressBar = var1; + } + + public final boolean save(Level var1, File var2) { + try { + FileOutputStream var5 = new FileOutputStream(var2); + save(var1, (OutputStream)var5); + var5.close(); + return true; + } catch (Exception var4) { + var4.printStackTrace(); + if(this.progressBar != null) { + this.progressBar.setText("Failed!"); + } + + try { + Thread.sleep(1000L); + } catch (InterruptedException var3) { + ; + } + + return false; + } + } + + public final Level load(File var1) { + try { + FileInputStream var5 = new FileInputStream(var1); + Level var2 = this.load((InputStream)var5); + var5.close(); + return var2; + } catch (Exception var4) { + var4.printStackTrace(); + if(this.progressBar != null) { + this.progressBar.setText("Failed!"); + } + + try { + Thread.sleep(1000L); + } catch (InterruptedException var3) { + ; + } + + return null; + } + } + + public final boolean saveOnline(Level var1, String var2, String var3, String var4, String var5, int var6) { + if(var4 == null) { + var4 = ""; + } + + if(this.progressBar != null && this.progressBar != null) { + this.progressBar.setTitle("Saving level"); + } + + try { + if(this.progressBar != null && this.progressBar != null) { + this.progressBar.setText("Compressing.."); + } + + ByteArrayOutputStream var7 = new ByteArrayOutputStream(); + save(var1, (OutputStream)var7); + var7.close(); + byte[] var10 = var7.toByteArray(); + if(this.progressBar != null && this.progressBar != null) { + this.progressBar.setText("Connecting.."); + } + + HttpURLConnection var12; + (var12 = (HttpURLConnection)(new URL("http://" + var2 + "/level/save.html")).openConnection()).setDoInput(true); + var12.setDoOutput(true); + var12.setRequestMethod("POST"); + DataOutputStream var13; + (var13 = new DataOutputStream(var12.getOutputStream())).writeUTF(var3); + var13.writeUTF(var4); + var13.writeUTF(var5); + var13.writeByte(var6); + var13.writeInt(var10.length); + if(this.progressBar != null) { + this.progressBar.setText("Saving.."); + } + + var13.write(var10); + var13.close(); + BufferedReader var11; + if(!(var11 = new BufferedReader(new InputStreamReader(var12.getInputStream()))).readLine().equalsIgnoreCase("ok")) { + if(this.progressBar != null) { + this.progressBar.setText("Failed: " + var11.readLine()); + } + + var11.close(); + Thread.sleep(1000L); + return false; + } else { + var11.close(); + return true; + } + } catch (Exception var9) { + var9.printStackTrace(); + if(this.progressBar != null) { + this.progressBar.setText("Failed!"); + } + + try { + Thread.sleep(1000L); + } catch (InterruptedException var8) { + ; + } + + return false; + } + } + + public final Level loadOnline(String var1, String var2, int var3) { + if(this.progressBar != null) { + this.progressBar.setTitle("Loading level"); + } + + try { + if(this.progressBar != null) { + this.progressBar.setText("Connecting.."); + } + + HttpURLConnection var6; + (var6 = (HttpURLConnection)(new URL("http://" + var1 + "/level/load.html?id=" + var3 + "&user=" + var2)).openConnection()).setDoInput(true); + if(this.progressBar != null) { + this.progressBar.setText("Loading.."); + } + + DataInputStream var7; + if((var7 = new DataInputStream(var6.getInputStream())).readUTF().equalsIgnoreCase("ok")) { + return this.load((InputStream)var7); + } else { + if(this.progressBar != null) { + this.progressBar.setText("Failed: " + var7.readUTF()); + } + + var7.close(); + Thread.sleep(1000L); + return null; + } + } catch (Exception var5) { + var5.printStackTrace(); + if(this.progressBar != null) { + this.progressBar.setText("Failed!"); + } + + try { + Thread.sleep(3000L); + } catch (InterruptedException var4) { + ; + } + + return null; + } + } + + public final Level load(InputStream var1) { + if(this.progressBar != null) { + this.progressBar.setTitle("Loading level"); + } + + if(this.progressBar != null) { + this.progressBar.setText("Reading.."); + } + + try { + DataInputStream var10; + if((var10 = new DataInputStream(new GZIPInputStream(var1))).readInt() != 656127880) { + return null; + } else { + byte var12; + if((var12 = var10.readByte()) > 2) { + return null; + } else if(var12 <= 1) { + String var14 = var10.readUTF(); + String var15 = var10.readUTF(); + long var3 = var10.readLong(); + short var5 = var10.readShort(); + short var6 = var10.readShort(); + short var7 = var10.readShort(); + byte[] var8 = new byte[var5 * var6 * var7]; + var10.readFully(var8); + var10.close(); + Level var11; + (var11 = new Level()).setData(var5, var7, var6, var8); + var11.name = var14; + var11.creator = var15; + var11.createTime = var3; + return var11; + } else { + Level var2; + LevelObjectInputStream var13; + (var2 = (Level)(var13 = new LevelObjectInputStream(var10)).readObject()).initTransient(); + var13.close(); + return var2; + } + } + } catch (Exception var9) { + var9.printStackTrace(); + System.out.println("Failed to load level: " + var9.toString()); + return null; + } + } + + public static void save(Level var0, OutputStream var1) { + try { + DataOutputStream var3; + (var3 = new DataOutputStream(new GZIPOutputStream(var1))).writeInt(656127880); + var3.writeByte(2); + ObjectOutputStream var4; + (var4 = new ObjectOutputStream(var3)).writeObject(var0); + var4.close(); + } catch (Exception var2) { + var2.printStackTrace(); + } + } + + public static byte[] decompress(InputStream var0) { + try { + DataInputStream var3; + byte[] var1 = new byte[(var3 = new DataInputStream(new GZIPInputStream(var0))).readInt()]; + var3.readFully(var1); + var3.close(); + return var1; + } catch (Exception var2) { + throw new RuntimeException(var2); + } + } +} diff --git a/src/main/java/com/mojang/minecraft/level/LevelObjectInputStream.java b/src/main/java/com/mojang/minecraft/level/LevelObjectInputStream.java new file mode 100644 index 0000000..85be8d1 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/LevelObjectInputStream.java @@ -0,0 +1,35 @@ +package com.mojang.minecraft.level; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectStreamClass; +import java.util.HashSet; +import java.util.Set; + +public final class LevelObjectInputStream extends ObjectInputStream { + + private Set classes = new HashSet(); + + + public LevelObjectInputStream(InputStream var1) throws IOException { + super(var1); + this.classes.add("com.mojang.minecraft.player.Player$1"); + this.classes.add("com.mojang.minecraft.mob.Creeper$1"); + this.classes.add("com.mojang.minecraft.mob.Skeleton$1"); + } + + protected final ObjectStreamClass readClassDescriptor() { + try + { + ObjectStreamClass var1 = super.readClassDescriptor(); + return this.classes.contains(var1.getName())?ObjectStreamClass.lookup(Class.forName(var1.getName())):var1; + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + return null; + } +} diff --git a/src/main/java/com/mojang/minecraft/level/MobSpawner.java b/src/main/java/com/mojang/minecraft/level/MobSpawner.java new file mode 100644 index 0000000..dc3cf14 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/MobSpawner.java @@ -0,0 +1,106 @@ +package com.mojang.minecraft.level; + +import com.mojang.minecraft.Entity; +import com.mojang.minecraft.ProgressBarDisplay; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.level.liquid.LiquidType; +import com.mojang.minecraft.mob.Creeper; +import com.mojang.minecraft.mob.Mob; +import com.mojang.minecraft.mob.Pig; +import com.mojang.minecraft.mob.Sheep; +import com.mojang.minecraft.mob.Skeleton; +import com.mojang.minecraft.mob.Spider; +import com.mojang.minecraft.mob.Zombie; + +public final class MobSpawner { + + public Level level; + + + public MobSpawner(Level var1) { + this.level = var1; + } + + public final int spawn(int var1, Entity var2, ProgressBarDisplay var3) { + int var4 = 0; + + for(int var5 = 0; var5 < var1; ++var5) { + if(var3 != null) { + var3.setProgress(var5 * 100 / (var1 - 1)); + } + + int var6 = this.level.random.nextInt(6); + int var7 = this.level.random.nextInt(this.level.width); + int var8 = (int)(Math.min(this.level.random.nextFloat(), this.level.random.nextFloat()) * (float)this.level.depth); + int var9 = this.level.random.nextInt(this.level.height); + if(!this.level.isSolidTile(var7, var8, var9) && this.level.getLiquid(var7, var8, var9) == LiquidType.NOT_LIQUID && (!this.level.isLit(var7, var8, var9) || this.level.random.nextInt(5) == 0)) { + for(int var10 = 0; var10 < 3; ++var10) { + int var11 = var7; + int var12 = var8; + int var13 = var9; + + for(int var14 = 0; var14 < 3; ++var14) { + var11 += this.level.random.nextInt(6) - this.level.random.nextInt(6); + var12 += this.level.random.nextInt(1) - this.level.random.nextInt(1); + var13 += this.level.random.nextInt(6) - this.level.random.nextInt(6); + if(var11 >= 0 && var13 >= 1 && var12 >= 0 && var12 < this.level.depth - 2 && var11 < this.level.width && var13 < this.level.height && this.level.isSolidTile(var11, var12 - 1, var13) && !this.level.isSolidTile(var11, var12, var13) && !this.level.isSolidTile(var11, var12 + 1, var13)) { + float var15 = (float)var11 + 0.5F; + float var16 = (float)var12 + 1.0F; + float var17 = (float)var13 + 0.5F; + float var19; + float var18; + float var20; + if(var2 != null) { + var18 = var15 - var2.x; + var19 = var16 - var2.y; + var20 = var17 - var2.z; + if(var18 * var18 + var19 * var19 + var20 * var20 < 256.0F) { + continue; + } + } else { + var18 = var15 - (float)this.level.xSpawn; + var19 = var16 - (float)this.level.ySpawn; + var20 = var17 - (float)this.level.zSpawn; + if(var18 * var18 + var19 * var19 + var20 * var20 < 256.0F) { + continue; + } + } + + Object var21 = null; + if(var6 == 0) { + var21 = new Zombie(this.level, var15, var16, var17); + } + + if(var6 == 1) { + var21 = new Skeleton(this.level, var15, var16, var17); + } + + if(var6 == 2) { + var21 = new Pig(this.level, var15, var16, var17); + } + + if(var6 == 3) { + var21 = new Creeper(this.level, var15, var16, var17); + } + + if(var6 == 4) { + var21 = new Spider(this.level, var15, var16, var17); + } + + if(var6 == 5) { + var21 = new Sheep(this.level, var15, var16, var17); + } + + if(this.level.isFree(((Mob)var21).bb)) { + ++var4; + this.level.addEntity((Entity)var21); + } + } + } + } + } + } + + return var4; + } +} diff --git a/src/main/java/com/mojang/minecraft/level/NextTickListEntry.java b/src/main/java/com/mojang/minecraft/level/NextTickListEntry.java new file mode 100644 index 0000000..1bb039b --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/NextTickListEntry.java @@ -0,0 +1,19 @@ +package com.mojang.minecraft.level; + + +public final class NextTickListEntry { + + public int x; + public int y; + public int z; + public int block; + public int ticks; + + + public NextTickListEntry(int var1, int var2, int var3, int var4) { + this.x = var1; + this.y = var2; + this.z = var3; + this.block = var4; + } +} diff --git a/src/main/java/com/mojang/minecraft/level/SyntheticClass.java b/src/main/java/com/mojang/minecraft/level/SyntheticClass.java new file mode 100644 index 0000000..fffeda8 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/SyntheticClass.java @@ -0,0 +1,6 @@ +package com.mojang.minecraft.level; + + +// $FF: synthetic class +final class SyntheticClass { +} diff --git a/src/main/java/com/mojang/minecraft/level/generator/LevelGenerator.java b/src/main/java/com/mojang/minecraft/level/generator/LevelGenerator.java new file mode 100644 index 0000000..3727a02 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/generator/LevelGenerator.java @@ -0,0 +1,544 @@ +package com.mojang.minecraft.level.generator; + +import com.mojang.minecraft.ProgressBarDisplay; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.level.generator.noise.CombinedNoise; +import com.mojang.minecraft.level.generator.noise.OctaveNoise; +import com.mojang.minecraft.level.tile.Block; +import com.mojang.util.MathHelper; +import java.util.ArrayList; +import java.util.Random; + +public final class LevelGenerator { + + private ProgressBarDisplay progressBar; + private int width; + private int depth; + private int height; + private Random random = new Random(); + private byte[] blocks; + private int waterLevel; + private int[] h = new int[1048576]; + + + public LevelGenerator(ProgressBarDisplay var1) { + this.progressBar = var1; + } + + public final Level generate(String var1, int var2, int var3, int var4) { + this.progressBar.setTitle("Generating level"); + this.width = var2; + this.depth = var3; + this.height = 64; + this.waterLevel = 32; + this.blocks = new byte[var2 * var3 << 6]; + this.progressBar.setText("Raising.."); + LevelGenerator var5 = this; + CombinedNoise var6 = new CombinedNoise(new OctaveNoise(this.random, 8), new OctaveNoise(this.random, 8)); + CombinedNoise var7 = new CombinedNoise(new OctaveNoise(this.random, 8), new OctaveNoise(this.random, 8)); + OctaveNoise var8 = new OctaveNoise(this.random, 6); + int[] var9 = new int[this.width * this.depth]; + float var10 = 1.3F; + + int var11; + int var12; + for(var11 = 0; var11 < var5.width; ++var11) { + var5.setProgress(var11 * 100 / (var5.width - 1)); + + for(var12 = 0; var12 < var5.depth; ++var12) { + double var13 = var6.compute((double)((float)var11 * var10), (double)((float)var12 * var10)) / 6.0D + (double)-4; + double var15 = var7.compute((double)((float)var11 * var10), (double)((float)var12 * var10)) / 5.0D + 10.0D + (double)-4; + if(var8.compute((double)var11, (double)var12) / 8.0D > 0.0D) { + var15 = var13; + } + + double var19; + if((var19 = Math.max(var13, var15) / 2.0D) < 0.0D) { + var19 *= 0.8D; + } + + var9[var11 + var12 * var5.width] = (int)var19; + } + } + + this.progressBar.setText("Eroding.."); + int[] var42 = var9; + var5 = this; + var7 = new CombinedNoise(new OctaveNoise(this.random, 8), new OctaveNoise(this.random, 8)); + CombinedNoise var49 = new CombinedNoise(new OctaveNoise(this.random, 8), new OctaveNoise(this.random, 8)); + + int var23; + int var51; + int var54; + for(var51 = 0; var51 < var5.width; ++var51) { + var5.setProgress(var51 * 100 / (var5.width - 1)); + + for(var54 = 0; var54 < var5.depth; ++var54) { + double var21 = var7.compute((double)(var51 << 1), (double)(var54 << 1)) / 8.0D; + var12 = var49.compute((double)(var51 << 1), (double)(var54 << 1)) > 0.0D?1:0; + if(var21 > 2.0D) { + var23 = ((var42[var51 + var54 * var5.width] - var12) / 2 << 1) + var12; + var42[var51 + var54 * var5.width] = var23; + } + } + } + + this.progressBar.setText("Soiling.."); + var42 = var9; + var5 = this; + int var46 = this.width; + int var48 = this.depth; + var51 = this.height; + OctaveNoise var53 = new OctaveNoise(this.random, 8); + + int var25; + int var24; + int var27; + int var26; + int var28; + for(var24 = 0; var24 < var46; ++var24) { + var5.setProgress(var24 * 100 / (var5.width - 1)); + + for(var11 = 0; var11 < var48; ++var11) { + var12 = (int)(var53.compute((double)var24, (double)var11) / 24.0D) - 4; + var25 = (var23 = var42[var24 + var11 * var46] + var5.waterLevel) + var12; + var42[var24 + var11 * var46] = Math.max(var23, var25); + if(var42[var24 + var11 * var46] > var51 - 2) { + var42[var24 + var11 * var46] = var51 - 2; + } + + if(var42[var24 + var11 * var46] < 1) { + var42[var24 + var11 * var46] = 1; + } + + for(var26 = 0; var26 < var51; ++var26) { + var27 = (var26 * var5.depth + var11) * var5.width + var24; + var28 = 0; + if(var26 <= var23) { + var28 = Block.DIRT.id; + } + + if(var26 <= var25) { + var28 = Block.STONE.id; + } + + if(var26 == 0) { + var28 = Block.LAVA.id; + } + + var5.blocks[var27] = (byte)var28; + } + } + } + + this.progressBar.setText("Carving.."); + boolean var45 = true; + boolean var44 = false; + var5 = this; + var48 = this.width; + var51 = this.depth; + var54 = this.height; + var24 = var48 * var51 * var54 / 256 / 64 << 1; + + for(var11 = 0; var11 < var24; ++var11) { + var5.setProgress(var11 * 100 / (var24 - 1) / 4); + float var55 = var5.random.nextFloat() * (float)var48; + float var59 = var5.random.nextFloat() * (float)var54; + float var56 = var5.random.nextFloat() * (float)var51; + var26 = (int)((var5.random.nextFloat() + var5.random.nextFloat()) * 200.0F); + float var61 = var5.random.nextFloat() * 3.1415927F * 2.0F; + float var64 = 0.0F; + float var29 = var5.random.nextFloat() * 3.1415927F * 2.0F; + float var30 = 0.0F; + float var31 = var5.random.nextFloat() * var5.random.nextFloat(); + + for(int var32 = 0; var32 < var26; ++var32) { + var55 += MathHelper.sin(var61) * MathHelper.cos(var29); + var56 += MathHelper.cos(var61) * MathHelper.cos(var29); + var59 += MathHelper.sin(var29); + var61 += var64 * 0.2F; + var64 = (var64 *= 0.9F) + (var5.random.nextFloat() - var5.random.nextFloat()); + var29 = (var29 + var30 * 0.5F) * 0.5F; + var30 = (var30 *= 0.75F) + (var5.random.nextFloat() - var5.random.nextFloat()); + if(var5.random.nextFloat() >= 0.25F) { + float var43 = var55 + (var5.random.nextFloat() * 4.0F - 2.0F) * 0.2F; + float var50 = var59 + (var5.random.nextFloat() * 4.0F - 2.0F) * 0.2F; + float var33 = var56 + (var5.random.nextFloat() * 4.0F - 2.0F) * 0.2F; + float var34 = ((float)var5.height - var50) / (float)var5.height; + var34 = 1.2F + (var34 * 3.5F + 1.0F) * var31; + var34 = MathHelper.sin((float)var32 * 3.1415927F / (float)var26) * var34; + + for(int var35 = (int)(var43 - var34); var35 <= (int)(var43 + var34); ++var35) { + for(int var36 = (int)(var50 - var34); var36 <= (int)(var50 + var34); ++var36) { + for(int var37 = (int)(var33 - var34); var37 <= (int)(var33 + var34); ++var37) { + float var38 = (float)var35 - var43; + float var39 = (float)var36 - var50; + float var40 = (float)var37 - var33; + if(var38 * var38 + var39 * var39 * 2.0F + var40 * var40 < var34 * var34 && var35 >= 1 && var36 >= 1 && var37 >= 1 && var35 < var5.width - 1 && var36 < var5.height - 1 && var37 < var5.depth - 1) { + int var66 = (var36 * var5.depth + var37) * var5.width + var35; + if(var5.blocks[var66] == Block.STONE.id) { + var5.blocks[var66] = 0; + } + } + } + } + } + } + } + } + + this.populateOre(Block.COAL_ORE.id, 90, 1, 4); + this.populateOre(Block.IRON_ORE.id, 70, 2, 4); + this.populateOre(Block.GOLD_ORE.id, 50, 3, 4); + this.progressBar.setText("Watering.."); + var5 = this; + var51 = Block.STATIONARY_WATER.id; + this.setProgress(0); + + for(var54 = 0; var54 < var5.width; ++var54) { + var5.flood(var54, var5.height / 2 - 1, 0, 0, var51); + var5.flood(var54, var5.height / 2 - 1, var5.depth - 1, 0, var51); + } + + for(var54 = 0; var54 < var5.depth; ++var54) { + var5.flood(0, var5.height / 2 - 1, var54, 0, var51); + var5.flood(var5.width - 1, var5.height / 2 - 1, var54, 0, var51); + } + + var54 = var5.width * var5.depth / 8000; + + for(var24 = 0; var24 < var54; ++var24) { + if(var24 % 100 == 0) { + var5.setProgress(var24 * 100 / (var54 - 1)); + } + + var11 = var5.random.nextInt(var5.width); + var12 = var5.waterLevel - 1 - var5.random.nextInt(2); + var23 = var5.random.nextInt(var5.depth); + if(var5.blocks[(var12 * var5.depth + var23) * var5.width + var11] == 0) { + var5.flood(var11, var12, var23, 0, var51); + } + } + + var5.setProgress(100); + this.progressBar.setText("Melting.."); + var5 = this; + var46 = this.width * this.depth * this.height / 20000; + + for(var48 = 0; var48 < var46; ++var48) { + if(var48 % 100 == 0) { + var5.setProgress(var48 * 100 / (var46 - 1)); + } + + var51 = var5.random.nextInt(var5.width); + var54 = (int)(var5.random.nextFloat() * var5.random.nextFloat() * (float)(var5.waterLevel - 3)); + var24 = var5.random.nextInt(var5.depth); + if(var5.blocks[(var54 * var5.depth + var24) * var5.width + var51] == 0) { + var5.flood(var51, var54, var24, 0, Block.STATIONARY_LAVA.id); + } + } + + var5.setProgress(100); + this.progressBar.setText("Growing.."); + var42 = var9; + var5 = this; + var46 = this.width; + var48 = this.depth; + var51 = this.height; + var53 = new OctaveNoise(this.random, 8); + OctaveNoise var58 = new OctaveNoise(this.random, 8); + + int var63; + for(var11 = 0; var11 < var46; ++var11) { + var5.setProgress(var11 * 100 / (var5.width - 1)); + + for(var12 = 0; var12 < var48; ++var12) { + boolean var60 = var53.compute((double)var11, (double)var12) > 8.0D; + boolean var57 = var58.compute((double)var11, (double)var12) > 12.0D; + var27 = ((var26 = var42[var11 + var12 * var46]) * var5.depth + var12) * var5.width + var11; + if(((var28 = var5.blocks[((var26 + 1) * var5.depth + var12) * var5.width + var11] & 255) == Block.WATER.id || var28 == Block.STATIONARY_WATER.id) && var26 <= var51 / 2 - 1 && var57) { + var5.blocks[var27] = (byte)Block.GRAVEL.id; + } + + if(var28 == 0) { + var63 = Block.GRASS.id; + if(var26 <= var51 / 2 - 1 && var60) { + var63 = Block.SAND.id; + } + + var5.blocks[var27] = (byte)var63; + } + } + } + + this.progressBar.setText("Planting.."); + var42 = var9; + var5 = this; + var46 = this.width; + var48 = this.width * this.depth / 3000; + + for(var51 = 0; var51 < var48; ++var51) { + var54 = var5.random.nextInt(2); + var5.setProgress(var51 * 50 / (var48 - 1)); + var24 = var5.random.nextInt(var5.width); + var11 = var5.random.nextInt(var5.depth); + + for(var12 = 0; var12 < 10; ++var12) { + var23 = var24; + var25 = var11; + + for(var26 = 0; var26 < 5; ++var26) { + var23 += var5.random.nextInt(6) - var5.random.nextInt(6); + var25 += var5.random.nextInt(6) - var5.random.nextInt(6); + if((var54 < 2 || var5.random.nextInt(4) == 0) && var23 >= 0 && var25 >= 0 && var23 < var5.width && var25 < var5.depth) { + var27 = var42[var23 + var25 * var46] + 1; + if((var5.blocks[(var27 * var5.depth + var25) * var5.width + var23] & 255) == 0) { + var63 = (var27 * var5.depth + var25) * var5.width + var23; + if((var5.blocks[((var27 - 1) * var5.depth + var25) * var5.width + var23] & 255) == Block.GRASS.id) { + if(var54 == 0) { + var5.blocks[var63] = (byte)Block.DANDELION.id; + } else if(var54 == 1) { + var5.blocks[var63] = (byte)Block.ROSE.id; + } + } + } + } + } + } + } + + var42 = var9; + var5 = this; + var46 = this.width; + var51 = this.width * this.depth * this.height / 2000; + + for(var54 = 0; var54 < var51; ++var54) { + var24 = var5.random.nextInt(2); + var5.setProgress(var54 * 50 / (var51 - 1) + 50); + var11 = var5.random.nextInt(var5.width); + var12 = var5.random.nextInt(var5.height); + var23 = var5.random.nextInt(var5.depth); + + for(var25 = 0; var25 < 20; ++var25) { + var26 = var11; + var27 = var12; + var28 = var23; + + for(var63 = 0; var63 < 5; ++var63) { + var26 += var5.random.nextInt(6) - var5.random.nextInt(6); + var27 += var5.random.nextInt(2) - var5.random.nextInt(2); + var28 += var5.random.nextInt(6) - var5.random.nextInt(6); + if((var24 < 2 || var5.random.nextInt(4) == 0) && var26 >= 0 && var28 >= 0 && var27 >= 1 && var26 < var5.width && var28 < var5.depth && var27 < var42[var26 + var28 * var46] - 1 && (var5.blocks[(var27 * var5.depth + var28) * var5.width + var26] & 255) == 0) { + int var62 = (var27 * var5.depth + var28) * var5.width + var26; + if((var5.blocks[((var27 - 1) * var5.depth + var28) * var5.width + var26] & 255) == Block.STONE.id) { + if(var24 == 0) { + var5.blocks[var62] = (byte)Block.BROWN_MUSHROOM.id; + } else if(var24 == 1) { + var5.blocks[var62] = (byte)Block.RED_MUSHROOM.id; + } + } + } + } + } + } + + Level var65; + (var65 = new Level()).waterLevel = this.waterLevel; + var65.setData(var2, 64, var3, this.blocks); + var65.createTime = System.currentTimeMillis(); + var65.creator = var1; + var65.name = "A Nice World"; + int[] var52 = var9; + Level var47 = var65; + var5 = this; + var48 = this.width; + var51 = this.width * this.depth / 4000; + + for(var54 = 0; var54 < var51; ++var54) { + var5.setProgress(var54 * 50 / (var51 - 1) + 50); + var24 = var5.random.nextInt(var5.width); + var11 = var5.random.nextInt(var5.depth); + + for(var12 = 0; var12 < 20; ++var12) { + var23 = var24; + var25 = var11; + + for(var26 = 0; var26 < 20; ++var26) { + var23 += var5.random.nextInt(6) - var5.random.nextInt(6); + var25 += var5.random.nextInt(6) - var5.random.nextInt(6); + if(var23 >= 0 && var25 >= 0 && var23 < var5.width && var25 < var5.depth) { + var27 = var52[var23 + var25 * var48] + 1; + if(var5.random.nextInt(4) == 0) { + var47.maybeGrowTree(var23, var27, var25); + } + } + } + } + } + + return var65; + } + + private void populateOre(int var1, int var2, int var3, int var4) { + byte var25 = (byte)var1; + var4 = this.width; + int var5 = this.depth; + int var6 = this.height; + int var7 = var4 * var5 * var6 / 256 / 64 * var2 / 100; + + for(int var8 = 0; var8 < var7; ++var8) { + this.setProgress(var8 * 100 / (var7 - 1) / 4 + var3 * 100 / 4); + float var9 = this.random.nextFloat() * (float)var4; + float var10 = this.random.nextFloat() * (float)var6; + float var11 = this.random.nextFloat() * (float)var5; + int var12 = (int)((this.random.nextFloat() + this.random.nextFloat()) * 75.0F * (float)var2 / 100.0F); + float var13 = this.random.nextFloat() * 3.1415927F * 2.0F; + float var14 = 0.0F; + float var15 = this.random.nextFloat() * 3.1415927F * 2.0F; + float var16 = 0.0F; + + for(int var17 = 0; var17 < var12; ++var17) { + var9 += MathHelper.sin(var13) * MathHelper.cos(var15); + var11 += MathHelper.cos(var13) * MathHelper.cos(var15); + var10 += MathHelper.sin(var15); + var13 += var14 * 0.2F; + var14 = (var14 *= 0.9F) + (this.random.nextFloat() - this.random.nextFloat()); + var15 = (var15 + var16 * 0.5F) * 0.5F; + var16 = (var16 *= 0.9F) + (this.random.nextFloat() - this.random.nextFloat()); + float var18 = MathHelper.sin((float)var17 * 3.1415927F / (float)var12) * (float)var2 / 100.0F + 1.0F; + + for(int var19 = (int)(var9 - var18); var19 <= (int)(var9 + var18); ++var19) { + for(int var20 = (int)(var10 - var18); var20 <= (int)(var10 + var18); ++var20) { + for(int var21 = (int)(var11 - var18); var21 <= (int)(var11 + var18); ++var21) { + float var22 = (float)var19 - var9; + float var23 = (float)var20 - var10; + float var24 = (float)var21 - var11; + if(var22 * var22 + var23 * var23 * 2.0F + var24 * var24 < var18 * var18 && var19 >= 1 && var20 >= 1 && var21 >= 1 && var19 < this.width - 1 && var20 < this.height - 1 && var21 < this.depth - 1) { + int var26 = (var20 * this.depth + var21) * this.width + var19; + if(this.blocks[var26] == Block.STONE.id) { + this.blocks[var26] = var25; + } + } + } + } + } + } + } + + } + + private void setProgress(int var1) { + this.progressBar.setProgress(var1); + } + + private long flood(int var1, int var2, int var3, int var4, int var5) { + byte var20 = (byte)var5; + ArrayList var21 = new ArrayList(); + byte var6 = 0; + int var7 = 1; + + int var8; + for(var8 = 1; 1 << var7 < this.width; ++var7) { + ; + } + + while(1 << var8 < this.depth) { + ++var8; + } + + int var9 = this.depth - 1; + int var10 = this.width - 1; + int var22 = var6 + 1; + this.h[0] = ((var2 << var8) + var3 << var7) + var1; + long var11 = 0L; + var1 = this.width * this.depth; + + while(var22 > 0) { + --var22; + var2 = this.h[var22]; + if(var22 == 0 && var21.size() > 0) { + this.h = (int[])var21.remove(var21.size() - 1); + var22 = this.h.length; + } + + var3 = var2 >> var7 & var9; + int var13 = var2 >> var7 + var8; + + int var14; + int var15; + for(var15 = var14 = var2 & var10; var14 > 0 && this.blocks[var2 - 1] == 0; --var2) { + --var14; + } + + while(var15 < this.width && this.blocks[var2 + var15 - var14] == 0) { + ++var15; + } + + int var16 = var2 >> var7 & var9; + int var17 = var2 >> var7 + var8; + if(var16 != var3 || var17 != var13) { + System.out.println("Diagonal flood!?"); + } + + boolean var23 = false; + boolean var24 = false; + boolean var18 = false; + var11 += (long)(var15 - var14); + + for(var14 = var14; var14 < var15; ++var14) { + this.blocks[var2] = var20; + boolean var19; + if(var3 > 0) { + if((var19 = this.blocks[var2 - this.width] == 0) && !var23) { + if(var22 == this.h.length) { + var21.add(this.h); + this.h = new int[1048576]; + var22 = 0; + } + + this.h[var22++] = var2 - this.width; + } + + var23 = var19; + } + + if(var3 < this.depth - 1) { + if((var19 = this.blocks[var2 + this.width] == 0) && !var24) { + if(var22 == this.h.length) { + var21.add(this.h); + this.h = new int[1048576]; + var22 = 0; + } + + this.h[var22++] = var2 + this.width; + } + + var24 = var19; + } + + if(var13 > 0) { + byte var25 = this.blocks[var2 - var1]; + if((var20 == Block.LAVA.id || var20 == Block.STATIONARY_LAVA.id) && (var25 == Block.WATER.id || var25 == Block.STATIONARY_WATER.id)) { + this.blocks[var2 - var1] = (byte)Block.STONE.id; + } + + if((var19 = var25 == 0) && !var18) { + if(var22 == this.h.length) { + var21.add(this.h); + this.h = new int[1048576]; + var22 = 0; + } + + this.h[var22++] = var2 - var1; + } + + var18 = var19; + } + + ++var2; + } + } + + return var11; + } +} diff --git a/src/main/java/com/mojang/minecraft/level/generator/noise/CombinedNoise.java b/src/main/java/com/mojang/minecraft/level/generator/noise/CombinedNoise.java new file mode 100644 index 0000000..d9fe5f7 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/generator/noise/CombinedNoise.java @@ -0,0 +1,19 @@ +package com.mojang.minecraft.level.generator.noise; + +public final class CombinedNoise extends Noise +{ + public CombinedNoise(Noise noise1, Noise noise2) + { + this.noise1 = noise1; + this.noise2 = noise2; + } + + @Override + public double compute(double x, double z) + { + return noise1.compute(x + noise2.compute(x, z), z); + } + + private Noise noise1; + private Noise noise2; +} diff --git a/src/main/java/com/mojang/minecraft/level/generator/noise/Noise.java b/src/main/java/com/mojang/minecraft/level/generator/noise/Noise.java new file mode 100644 index 0000000..a4adfe1 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/generator/noise/Noise.java @@ -0,0 +1,7 @@ +package com.mojang.minecraft.level.generator.noise; + + +public abstract class Noise +{ + public abstract double compute(double x, double z); +} diff --git a/src/main/java/com/mojang/minecraft/level/generator/noise/OctaveNoise.java b/src/main/java/com/mojang/minecraft/level/generator/noise/OctaveNoise.java new file mode 100644 index 0000000..4e2b0fd --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/generator/noise/OctaveNoise.java @@ -0,0 +1,37 @@ +package com.mojang.minecraft.level.generator.noise; + +import java.util.Random; + +public class OctaveNoise extends Noise +{ + public OctaveNoise(Random random, int octaves) + { + this.octaves = octaves; + perlin = new PerlinNoise[octaves]; + + for(int count = 0; count < octaves; count++) + { + perlin[count] = new PerlinNoise(random); + } + + } + + @Override + public double compute(double x, double z) + { + double result = 0.0D; + double unknown0 = 1.0D; + + for(int count = 0; count < octaves; count++) + { + result += perlin[count].compute(x / unknown0, z / unknown0) * unknown0; + + unknown0 *= 2.0D; + } + + return result; + } + + private PerlinNoise[] perlin; + private int octaves; +} diff --git a/src/main/java/com/mojang/minecraft/level/generator/noise/PerlinNoise.java b/src/main/java/com/mojang/minecraft/level/generator/noise/PerlinNoise.java new file mode 100644 index 0000000..8f8d953 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/generator/noise/PerlinNoise.java @@ -0,0 +1,135 @@ +package com.mojang.minecraft.level.generator.noise; + +import java.util.Random; + +public class PerlinNoise extends Noise +{ + public PerlinNoise() + { + this(new Random()); + } + + public PerlinNoise(Random random) + { + noise = new int[512]; + + for(int count = 0; count < 256; noise[count] = count++) + { + } + + for(int count = 0; count < 256; count++) + { + int unknown0 = random.nextInt(256 - count) + count; + int unknown1 = noise[count]; + + noise[count] = noise[unknown0]; + noise[unknown0] = unknown1; + noise[count + 256] = noise[count]; + } + + } + + @Override + public double compute(double x, double z) + { + double unknown0 = 0.0D; + double unknown1 = z; + double unknown2 = x; + + int unknown3 = (int)Math.floor(x) & 255; + int unknown4 = (int)Math.floor(z) & 255; + int unknown5 = (int)Math.floor(0.0D) & 255; + + unknown2 -= Math.floor(unknown2); + unknown1 -= Math.floor(unknown1); + unknown0 = 0.0D - Math.floor(0.0D); + + double unknown6 = a(unknown2); + double unknown7 = a(unknown1); + double unknown8 = a(unknown0); + + int unknown9 = noise[unknown3] + unknown4; + int unknown10 = noise[unknown9] + unknown5; + + unknown9 = noise[unknown9 + 1] + unknown5; + unknown3 = noise[unknown3 + 1] + unknown4; + unknown4 = noise[unknown3] + unknown5; + unknown3 = noise[unknown3 + 1] + unknown5; + + // TODO: Maybe organize better. + return lerp( + unknown8, + lerp( + unknown7, + lerp( + unknown6, + grad( + noise[unknown10], + unknown2, + unknown1, + unknown0), + grad( + noise[unknown4], + unknown2 - 1.0D, + unknown1, + unknown0)), + lerp( + unknown6, + grad( + noise[unknown9], + unknown2, + unknown1 - 1.0D, + unknown0), + grad( + noise[unknown3], + unknown2 - 1.0D, + unknown1 - 1.0D, + unknown0))), + lerp( + unknown7, + lerp( + unknown6, + grad( + noise[unknown10 + 1], + unknown2, + unknown1, + unknown0 - 1.0D), + grad( + noise[unknown4 + 1], + unknown2 - 1.0D, + unknown1, + unknown0 - 1.0D)), + lerp( + unknown6, + grad( + noise[unknown9 + 1], + unknown2, + unknown1 - 1.0D, + unknown0 - 1.0D), + grad( + noise[unknown3 + 1], + unknown2 - 1.0D, + unknown1 - 1.0D, + unknown0 - 1.0D)))); + } + + private int[] noise; + + private static double a(double unknown0) + { + return unknown0 * unknown0 * unknown0 * (unknown0 * (unknown0 * 6.0D - 15.0D) + 10.0D); + } + + private static double lerp(double unknown0, double unknown1, double unknown2) + { + return unknown1 + unknown0 * (unknown2 - unknown1); + } + + private static double grad(int unknown0, double unknown1, double unknown2, double unknown3) + { + double unknown4 = (unknown0 &= 15) < 8 ? unknown1 : unknown2; + double unknown5 = unknown0 < 4 ? unknown2 : (unknown0 != 12 && unknown0 != 14 ? unknown3 : unknown1); + + return ((unknown0 & 1) == 0 ? unknown4 : -unknown4) + ((unknown0 & 2) == 0 ? unknown5 : -unknown5); + } +} diff --git a/src/main/java/com/mojang/minecraft/level/liquid/LiquidType.java b/src/main/java/com/mojang/minecraft/level/liquid/LiquidType.java new file mode 100644 index 0000000..b830b4c --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/liquid/LiquidType.java @@ -0,0 +1,17 @@ +package com.mojang.minecraft.level.liquid; + +public class LiquidType +{ + private LiquidType(int type) + { + values = new LiquidType[4]; + + values[type] = this; + } + + private LiquidType[] values; + + public static final LiquidType NOT_LIQUID = new LiquidType(0); + public static final LiquidType WATER = new LiquidType(1); + public static final LiquidType LAVA = new LiquidType(2); +} diff --git a/src/main/java/com/mojang/minecraft/level/tile/Block.java b/src/main/java/com/mojang/minecraft/level/tile/Block.java new file mode 100644 index 0000000..e3219b0 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/tile/Block.java @@ -0,0 +1,742 @@ +package com.mojang.minecraft.level.tile; + +import com.mojang.minecraft.MovingObjectPosition; +import com.mojang.minecraft.item.Item; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.level.liquid.LiquidType; +import com.mojang.minecraft.model.Vec3D; +import com.mojang.minecraft.particle.ParticleManager; +import com.mojang.minecraft.particle.TerrainParticle; +import com.mojang.minecraft.phys.AABB; +import com.mojang.minecraft.render.ShapeRenderer; +import java.util.Random; + +public class Block +{ + protected Block(int id) + { + explodes = true; + blocks[id] = this; + this.id = id; + + setBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + + opaque[id] = isSolid(); + cube[id] = isCube(); + liquid[id] = false; + } + + protected Block(int id, int textureID) + { + this(id); + + textureId = textureID; + } + + protected static Random random = new Random(); + public static final Block[] blocks = new Block[256]; + public static final boolean[] physics = new boolean[256]; + private static boolean[] opaque = new boolean[256]; + private static boolean[] cube = new boolean[256]; + public static final boolean[] liquid = new boolean[256]; + private static int[] tickDelay = new int[256]; + public static final Block STONE; + public static final Block GRASS; + public static final Block DIRT; + public static final Block COBBLESTONE; + public static final Block WOOD; + public static final Block SAPLING; + public static final Block BEDROCK; + public static final Block WATER; + public static final Block STATIONARY_WATER; + public static final Block LAVA; + public static final Block STATIONARY_LAVA; + public static final Block SAND; + public static final Block GRAVEL; + public static final Block GOLD_ORE; + public static final Block IRON_ORE; + public static final Block COAL_ORE; + public static final Block LOG; + public static final Block LEAVES; + public static final Block SPONGE; + public static final Block GLASS; + public static final Block RED_WOOL; + public static final Block ORANGE_WOOL; + public static final Block YELLOW_WOOL; + public static final Block LIME_WOOL; + public static final Block GREEN_WOOL; + public static final Block AQUA_GREEN_WOOL; + public static final Block CYAN_WOOL; + public static final Block BLUE_WOOL; + public static final Block PURPLE_WOOL; + public static final Block INDIGO_WOOL; + public static final Block VIOLET_WOOL; + public static final Block MAGENTA_WOOL; + public static final Block PINK_WOOL; + public static final Block BLACK_WOOL; + public static final Block GRAY_WOOL; + public static final Block WHITE_WOOL; + public static final Block DANDELION; + public static final Block ROSE; + public static final Block BROWN_MUSHROOM; + public static final Block RED_MUSHROOM; + public static final Block GOLD_BLOCK; + public static final Block IRON_BLOCK; + public static final Block DOUBLE_SLAB; + public static final Block SLAB; + public static final Block BRICK; + public static final Block TNT; + public static final Block BOOKSHELF; + public static final Block MOSSY_COBBLESTONE; + public static final Block OBSIDIAN; + public int textureId; + public final int id; + public Tile$SoundType stepsound; + private int hardness; + private boolean explodes; + public float x1; + public float y1; + public float z1; + public float x2; + public float y2; + public float z2; + public float particleGravity; + + public boolean isCube() + { + return true; + } + + protected Block setData(Tile$SoundType soundType, float var2, float particleGravity, float hardness) + { + this.particleGravity = particleGravity; + this.stepsound = soundType; + this.hardness = (int)(hardness * 20.0F); + + return this; + } + + protected void setPhysics(boolean physics) + { + this.physics[id] = physics; + } + + protected void setBounds(float x1, float y1, float z1, float x2, float y2, float z2) + { + this.x1 = x1; + this.y1 = y1; + this.z1 = z1; + this.x2 = x2; + this.y2 = y2; + this.z2 = z2; + } + + public void setTickDelay(int tickDelay) + { + this.tickDelay[id] = tickDelay; + } + + public void renderFullbright(ShapeRenderer shapeRenderer) + { + float red = 0.5F; + float green = 0.8F; + float blue = 0.6F; + + shapeRenderer.color(red, red, red); + renderInside(shapeRenderer, -2, 0, 0, 0); + + shapeRenderer.color(1.0F, 1.0F, 1.0F); + renderInside(shapeRenderer, -2, 0, 0, 1); + + shapeRenderer.color(green, green, green); + renderInside(shapeRenderer, -2, 0, 0, 2); + + shapeRenderer.color(green, green, green); + renderInside(shapeRenderer, -2, 0, 0, 3); + + shapeRenderer.color(blue, blue, blue); + renderInside(shapeRenderer, -2, 0, 0, 4); + + shapeRenderer.color(blue, blue, blue); + renderInside(shapeRenderer, -2, 0, 0, 5); + } + + protected float getBrightness(Level level, int x, int y, int z) + { + return level.getBrightness(x, y, z); + } + + public boolean canRenderSide(Level level, int x, int y, int z, int side) + { + return !level.isSolidTile(x, y, z); + } + + protected int getTextureId(int texture) + { + return textureId; + } + + public void renderInside(ShapeRenderer shapeRenderer, int x, int y, int z, int side) + { + int textureID1 = getTextureId(side); + + renderSide(shapeRenderer, x, y, z, side, textureID1); + } + + // TODO. + public void renderSide(ShapeRenderer shapeRenderer, int x, int y, int z, int side, int textureID) + { + int var7 = textureID % 16 << 4; + int var8 = textureID / 16 << 4; + float var9 = (float)var7 / 256.0F; + float var17 = ((float)var7 + 15.99F) / 256.0F; + float var10 = (float)var8 / 256.0F; + float var11 = ((float)var8 + 15.99F) / 256.0F; + if(side >= 2 && textureID < 240) { + if(this.y1 >= 0.0F && this.y2 <= 1.0F) { + var10 = ((float)var8 + this.y1 * 15.99F) / 256.0F; + var11 = ((float)var8 + this.y2 * 15.99F) / 256.0F; + } else { + var10 = (float)var8 / 256.0F; + var11 = ((float)var8 + 15.99F) / 256.0F; + } + } + + float var16 = (float)x + this.x1; + float var14 = (float)x + this.x2; + float var18 = (float)y + this.y1; + float var15 = (float)y + this.y2; + float var12 = (float)z + this.z1; + float var13 = (float)z + this.z2; + if(side == 0) { + shapeRenderer.vertexUV(var16, var18, var13, var9, var11); + shapeRenderer.vertexUV(var16, var18, var12, var9, var10); + shapeRenderer.vertexUV(var14, var18, var12, var17, var10); + shapeRenderer.vertexUV(var14, var18, var13, var17, var11); + } else if(side == 1) { + shapeRenderer.vertexUV(var14, var15, var13, var17, var11); + shapeRenderer.vertexUV(var14, var15, var12, var17, var10); + shapeRenderer.vertexUV(var16, var15, var12, var9, var10); + shapeRenderer.vertexUV(var16, var15, var13, var9, var11); + } else if(side == 2) { + shapeRenderer.vertexUV(var16, var15, var12, var17, var10); + shapeRenderer.vertexUV(var14, var15, var12, var9, var10); + shapeRenderer.vertexUV(var14, var18, var12, var9, var11); + shapeRenderer.vertexUV(var16, var18, var12, var17, var11); + } else if(side == 3) { + shapeRenderer.vertexUV(var16, var15, var13, var9, var10); + shapeRenderer.vertexUV(var16, var18, var13, var9, var11); + shapeRenderer.vertexUV(var14, var18, var13, var17, var11); + shapeRenderer.vertexUV(var14, var15, var13, var17, var10); + } else if(side == 4) { + shapeRenderer.vertexUV(var16, var15, var13, var17, var10); + shapeRenderer.vertexUV(var16, var15, var12, var9, var10); + shapeRenderer.vertexUV(var16, var18, var12, var9, var11); + shapeRenderer.vertexUV(var16, var18, var13, var17, var11); + } else if(side == 5) { + shapeRenderer.vertexUV(var14, var18, var13, var9, var11); + shapeRenderer.vertexUV(var14, var18, var12, var17, var11); + shapeRenderer.vertexUV(var14, var15, var12, var17, var10); + shapeRenderer.vertexUV(var14, var15, var13, var9, var10); + } + } + + // TODO. + public final void renderSide(ShapeRenderer var1, int var2, int var3, int var4, int var5) { + int var6; + float var7; + float var8 = (var7 = (float)((var6 = this.getTextureId(var5)) % 16) / 16.0F) + 0.0624375F; + float var16; + float var9 = (var16 = (float)(var6 / 16) / 16.0F) + 0.0624375F; + float var10 = (float)var2 + this.x1; + float var14 = (float)var2 + this.x2; + float var11 = (float)var3 + this.y1; + float var15 = (float)var3 + this.y2; + float var12 = (float)var4 + this.z1; + float var13 = (float)var4 + this.z2; + if(var5 == 0) { + var1.vertexUV(var14, var11, var13, var8, var9); + var1.vertexUV(var14, var11, var12, var8, var16); + var1.vertexUV(var10, var11, var12, var7, var16); + var1.vertexUV(var10, var11, var13, var7, var9); + } + + if(var5 == 1) { + var1.vertexUV(var10, var15, var13, var7, var9); + var1.vertexUV(var10, var15, var12, var7, var16); + var1.vertexUV(var14, var15, var12, var8, var16); + var1.vertexUV(var14, var15, var13, var8, var9); + } + + if(var5 == 2) { + var1.vertexUV(var10, var11, var12, var8, var9); + var1.vertexUV(var14, var11, var12, var7, var9); + var1.vertexUV(var14, var15, var12, var7, var16); + var1.vertexUV(var10, var15, var12, var8, var16); + } + + if(var5 == 3) { + var1.vertexUV(var14, var15, var13, var8, var16); + var1.vertexUV(var14, var11, var13, var8, var9); + var1.vertexUV(var10, var11, var13, var7, var9); + var1.vertexUV(var10, var15, var13, var7, var16); + } + + if(var5 == 4) { + var1.vertexUV(var10, var11, var13, var8, var9); + var1.vertexUV(var10, var11, var12, var7, var9); + var1.vertexUV(var10, var15, var12, var7, var16); + var1.vertexUV(var10, var15, var13, var8, var16); + } + + if(var5 == 5) { + var1.vertexUV(var14, var15, var13, var7, var16); + var1.vertexUV(var14, var15, var12, var8, var16); + var1.vertexUV(var14, var11, var12, var8, var9); + var1.vertexUV(var14, var11, var13, var7, var9); + } + + } + + public AABB getSelectionBox(int x, int y, int z) + { + AABB aabb = new AABB((float)x + x1, (float)y + y1, (float)z + z1, (float)x + x2, (float)y + y2, (float)z + z2);; + + return aabb; + } + + public AABB getCollisionBox(int x, int y, int z) + { + AABB aabb = new AABB((float)x + x1, (float)y + y1, (float)z + z1, (float)x + x2, (float)y + y2, (float)z + z2);; + + return aabb; + } + + public boolean isOpaque() + { + return true; + } + + public boolean isSolid() + { + return true; + } + + public void update(Level level, int x, int y, int z, Random rand) + { + } + + // TODO. + public void spawnBreakParticles(Level level, int x, int y, int z, ParticleManager particleManager) + { + for(int var6 = 0; var6 < 4; ++var6) + { + for(int var7 = 0; var7 < 4; ++var7) + { + for(int var8 = 0; var8 < 4; ++var8) + { + float var9 = (float)x + ((float)var6 + 0.5F) / (float)4; + float var10 = (float)y + ((float)var7 + 0.5F) / (float)4; + float var11 = (float)z + ((float)var8 + 0.5F) / (float)4; + + particleManager.spawnParticle(new TerrainParticle(level, var9, var10, var11, var9 - (float) x - 0.5F, var10 - (float) y - 0.5F, var11 - (float) z - 0.5F, this)); + } + } + } + + } + + // TODO. + public final void spawnBlockParticles(Level var1, int var2, int var3, int var4, int var5, ParticleManager var6) { + float var7 = 0.1F; + float var8 = (float)var2 + random.nextFloat() * (this.x2 - this.x1 - var7 * 2.0F) + var7 + this.x1; + float var9 = (float)var3 + random.nextFloat() * (this.y2 - this.y1 - var7 * 2.0F) + var7 + this.y1; + float var10 = (float)var4 + random.nextFloat() * (this.z2 - this.z1 - var7 * 2.0F) + var7 + this.z1; + if(var5 == 0) { + var9 = (float)var3 + this.y1 - var7; + } + + if(var5 == 1) { + var9 = (float)var3 + this.y2 + var7; + } + + if(var5 == 2) { + var10 = (float)var4 + this.z1 - var7; + } + + if(var5 == 3) { + var10 = (float)var4 + this.z2 + var7; + } + + if(var5 == 4) { + var8 = (float)var2 + this.x1 - var7; + } + + if(var5 == 5) { + var8 = (float)var2 + this.x2 + var7; + } + + var6.spawnParticle((new TerrainParticle(var1, var8, var9, var10, 0.0F, 0.0F, 0.0F, this)).setPower(0.2F).scale(0.6F)); + } + + public LiquidType getLiquidType() + { + return LiquidType.NOT_LIQUID; + } + + // TODO. + public void onNeighborChange(Level var1, int var2, int var3, int var4, int var5) + { + } + + public void onPlace(Level level, int x, int y, int z) + { + } + + public int getTickDelay() + { + return 0; + } + + public void onAdded(Level level, int x, int y, int z) + { + } + + // TODO past here. + + public void onRemoved(Level var1, int var2, int var3, int var4) {} + + public int getDropCount() { + return 1; + } + + public int getDrop() { + return this.id; + } + + public final int getHardness() { + return this.hardness; + } + + public void onBreak(Level var1, int var2, int var3, int var4) { + this.dropItems(var1, var2, var3, var4, 1.0F); + } + + public void dropItems(Level var1, int var2, int var3, int var4, float var5) { + if(!var1.creativeMode) { + int var6 = this.getDropCount(); + + for(int var7 = 0; var7 < var6; ++var7) { + if(random.nextFloat() <= var5) { + float var8 = 0.7F; + float var9 = random.nextFloat() * var8 + (1.0F - var8) * 0.5F; + float var10 = random.nextFloat() * var8 + (1.0F - var8) * 0.5F; + var8 = random.nextFloat() * var8 + (1.0F - var8) * 0.5F; + var1.addEntity(new Item(var1, (float)var2 + var9, (float)var3 + var10, (float)var4 + var8, this.getDrop())); + } + } + + } + } + + public void renderPreview(ShapeRenderer var1) { + var1.begin(); + + for(int var2 = 0; var2 < 6; ++var2) { + if(var2 == 0) { + var1.normal(0.0F, 1.0F, 0.0F); + } + + if(var2 == 1) { + var1.normal(0.0F, -1.0F, 0.0F); + } + + if(var2 == 2) { + var1.normal(0.0F, 0.0F, 1.0F); + } + + if(var2 == 3) { + var1.normal(0.0F, 0.0F, -1.0F); + } + + if(var2 == 4) { + var1.normal(1.0F, 0.0F, 0.0F); + } + + if(var2 == 5) { + var1.normal(-1.0F, 0.0F, 0.0F); + } + + this.renderInside(var1, 0, 0, 0, var2); + } + + var1.end(); + } + + public final boolean canExplode() { + return this.explodes; + } + + public final MovingObjectPosition clip(int var1, int var2, int var3, Vec3D var4, Vec3D var5) { + var4 = var4.add((float)(-var1), (float)(-var2), (float)(-var3)); + var5 = var5.add((float)(-var1), (float)(-var2), (float)(-var3)); + Vec3D var6 = var4.getXIntersection(var5, this.x1); + Vec3D var7 = var4.getXIntersection(var5, this.x2); + Vec3D var8 = var4.getYIntersection(var5, this.y1); + Vec3D var9 = var4.getYIntersection(var5, this.y2); + Vec3D var10 = var4.getZIntersection(var5, this.z1); + var5 = var4.getZIntersection(var5, this.z2); + if(!this.xIntersects(var6)) { + var6 = null; + } + + if(!this.xIntersects(var7)) { + var7 = null; + } + + if(!this.yIntersects(var8)) { + var8 = null; + } + + if(!this.yIntersects(var9)) { + var9 = null; + } + + if(!this.zIntersects(var10)) { + var10 = null; + } + + if(!this.zIntersects(var5)) { + var5 = null; + } + + Vec3D var11 = null; + if(var6 != null) { + var11 = var6; + } + + if(var7 != null && (var11 == null || var4.distance(var7) < var4.distance(var11))) { + var11 = var7; + } + + if(var8 != null && (var11 == null || var4.distance(var8) < var4.distance(var11))) { + var11 = var8; + } + + if(var9 != null && (var11 == null || var4.distance(var9) < var4.distance(var11))) { + var11 = var9; + } + + if(var10 != null && (var11 == null || var4.distance(var10) < var4.distance(var11))) { + var11 = var10; + } + + if(var5 != null && (var11 == null || var4.distance(var5) < var4.distance(var11))) { + var11 = var5; + } + + if(var11 == null) { + return null; + } else { + byte var12 = -1; + if(var11 == var6) { + var12 = 4; + } + + if(var11 == var7) { + var12 = 5; + } + + if(var11 == var8) { + var12 = 0; + } + + if(var11 == var9) { + var12 = 1; + } + + if(var11 == var10) { + var12 = 2; + } + + if(var11 == var5) { + var12 = 3; + } + + return new MovingObjectPosition(var1, var2, var3, var12, var11.add((float)var1, (float)var2, (float)var3)); + } + } + + private boolean xIntersects(Vec3D var1) { + return var1 == null?false:var1.y >= this.y1 && var1.y <= this.y2 && var1.z >= this.z1 && var1.z <= this.z2; + } + + private boolean yIntersects(Vec3D var1) { + return var1 == null?false:var1.x >= this.x1 && var1.x <= this.x2 && var1.z >= this.z1 && var1.z <= this.z2; + } + + private boolean zIntersects(Vec3D var1) { + return var1 == null?false:var1.x >= this.x1 && var1.x <= this.x2 && var1.y >= this.y1 && var1.y <= this.y2; + } + + public void explode(Level var1, int var2, int var3, int var4) {} + + public boolean render(Level var1, int var2, int var3, int var4, ShapeRenderer var5) { + boolean var6 = false; + float var7 = 0.5F; + float var8 = 0.8F; + float var9 = 0.6F; + float var10; + if(this.canRenderSide(var1, var2, var3 - 1, var4, 0)) { + var10 = this.getBrightness(var1, var2, var3 - 1, var4); + var5.color(var7 * var10, var7 * var10, var7 * var10); + this.renderInside(var5, var2, var3, var4, 0); + var6 = true; + } + + if(this.canRenderSide(var1, var2, var3 + 1, var4, 1)) { + var10 = this.getBrightness(var1, var2, var3 + 1, var4); + var5.color(var10 * 1.0F, var10 * 1.0F, var10 * 1.0F); + this.renderInside(var5, var2, var3, var4, 1); + var6 = true; + } + + if(this.canRenderSide(var1, var2, var3, var4 - 1, 2)) { + var10 = this.getBrightness(var1, var2, var3, var4 - 1); + var5.color(var8 * var10, var8 * var10, var8 * var10); + this.renderInside(var5, var2, var3, var4, 2); + var6 = true; + } + + if(this.canRenderSide(var1, var2, var3, var4 + 1, 3)) { + var10 = this.getBrightness(var1, var2, var3, var4 + 1); + var5.color(var8 * var10, var8 * var10, var8 * var10); + this.renderInside(var5, var2, var3, var4, 3); + var6 = true; + } + + if(this.canRenderSide(var1, var2 - 1, var3, var4, 4)) { + var10 = this.getBrightness(var1, var2 - 1, var3, var4); + var5.color(var9 * var10, var9 * var10, var9 * var10); + this.renderInside(var5, var2, var3, var4, 4); + var6 = true; + } + + if(this.canRenderSide(var1, var2 + 1, var3, var4, 5)) { + var10 = this.getBrightness(var1, var2 + 1, var3, var4); + var5.color(var9 * var10, var9 * var10, var9 * var10); + this.renderInside(var5, var2, var3, var4, 5); + var6 = true; + } + + return var6; + } + + public int getRenderPass() { + return 0; + } + + static { + Block var10000 = (new StoneBlock(1, 1)).setData(Tile$SoundType.stone, 1.0F, 1.0F, 1.0F); + boolean var0 = false; + Block var1 = var10000; + var10000.explodes = false; + STONE = var1; + GRASS = (new GrassBlock(2)).setData(Tile$SoundType.grass, 0.9F, 1.0F, 0.6F); + DIRT = (new DirtBlock(3, 2)).setData(Tile$SoundType.grass, 0.8F, 1.0F, 0.5F); + var10000 = (new Block(4, 16)).setData(Tile$SoundType.stone, 1.0F, 1.0F, 1.5F); + var0 = false; + var1 = var10000; + var10000.explodes = false; + COBBLESTONE = var1; + WOOD = (new Block(5, 4)).setData(Tile$SoundType.wood, 1.0F, 1.0F, 1.5F); + SAPLING = (new SaplingBlock(6, 15)).setData(Tile$SoundType.none, 0.7F, 1.0F, 0.0F); + var10000 = (new Block(7, 17)).setData(Tile$SoundType.stone, 1.0F, 1.0F, 999.0F); + var0 = false; + var1 = var10000; + var10000.explodes = false; + BEDROCK = var1; + WATER = (new LiquidBlock(8, LiquidType.WATER)).setData(Tile$SoundType.none, 1.0F, 1.0F, 100.0F); + STATIONARY_WATER = (new StillLiquidBlock(9, LiquidType.WATER)).setData(Tile$SoundType.none, 1.0F, 1.0F, 100.0F); + LAVA = (new LiquidBlock(10, LiquidType.LAVA)).setData(Tile$SoundType.none, 1.0F, 1.0F, 100.0F); + STATIONARY_LAVA = (new StillLiquidBlock(11, LiquidType.LAVA)).setData(Tile$SoundType.none, 1.0F, 1.0F, 100.0F); + SAND = (new SandBlock(12, 18)).setData(Tile$SoundType.gravel, 0.8F, 1.0F, 0.5F); + GRAVEL = (new SandBlock(13, 19)).setData(Tile$SoundType.gravel, 0.8F, 1.0F, 0.6F); + var10000 = (new OreBlock(14, 32)).setData(Tile$SoundType.stone, 1.0F, 1.0F, 3.0F); + var0 = false; + var1 = var10000; + var10000.explodes = false; + GOLD_ORE = var1; + var10000 = (new OreBlock(15, 33)).setData(Tile$SoundType.stone, 1.0F, 1.0F, 3.0F); + var0 = false; + var1 = var10000; + var10000.explodes = false; + IRON_ORE = var1; + var10000 = (new OreBlock(16, 34)).setData(Tile$SoundType.stone, 1.0F, 1.0F, 3.0F); + var0 = false; + var1 = var10000; + var10000.explodes = false; + COAL_ORE = var1; + LOG = (new WoodBlock(17)).setData(Tile$SoundType.wood, 1.0F, 1.0F, 2.5F); + LEAVES = (new LeavesBlock(18, 22)).setData(Tile$SoundType.grass, 1.0F, 0.4F, 0.2F); + SPONGE = (new SpongeBlock(19)).setData(Tile$SoundType.cloth, 1.0F, 0.9F, 0.6F); + GLASS = (new GlassBlock(20, 49, false)).setData(Tile$SoundType.metal, 1.0F, 1.0F, 0.3F); + RED_WOOL = (new Block(21, 64)).setData(Tile$SoundType.cloth, 1.0F, 1.0F, 0.8F); + ORANGE_WOOL = (new Block(22, 65)).setData(Tile$SoundType.cloth, 1.0F, 1.0F, 0.8F); + YELLOW_WOOL = (new Block(23, 66)).setData(Tile$SoundType.cloth, 1.0F, 1.0F, 0.8F); + LIME_WOOL = (new Block(24, 67)).setData(Tile$SoundType.cloth, 1.0F, 1.0F, 0.8F); + GREEN_WOOL = (new Block(25, 68)).setData(Tile$SoundType.cloth, 1.0F, 1.0F, 0.8F); + AQUA_GREEN_WOOL = (new Block(26, 69)).setData(Tile$SoundType.cloth, 1.0F, 1.0F, 0.8F); + CYAN_WOOL = (new Block(27, 70)).setData(Tile$SoundType.cloth, 1.0F, 1.0F, 0.8F); + BLUE_WOOL = (new Block(28, 71)).setData(Tile$SoundType.cloth, 1.0F, 1.0F, 0.8F); + PURPLE_WOOL = (new Block(29, 72)).setData(Tile$SoundType.cloth, 1.0F, 1.0F, 0.8F); + INDIGO_WOOL = (new Block(30, 73)).setData(Tile$SoundType.cloth, 1.0F, 1.0F, 0.8F); + VIOLET_WOOL = (new Block(31, 74)).setData(Tile$SoundType.cloth, 1.0F, 1.0F, 0.8F); + MAGENTA_WOOL = (new Block(32, 75)).setData(Tile$SoundType.cloth, 1.0F, 1.0F, 0.8F); + PINK_WOOL = (new Block(33, 76)).setData(Tile$SoundType.cloth, 1.0F, 1.0F, 0.8F); + BLACK_WOOL = (new Block(34, 77)).setData(Tile$SoundType.cloth, 1.0F, 1.0F, 0.8F); + GRAY_WOOL = (new Block(35, 78)).setData(Tile$SoundType.cloth, 1.0F, 1.0F, 0.8F); + WHITE_WOOL = (new Block(36, 79)).setData(Tile$SoundType.cloth, 1.0F, 1.0F, 0.8F); + DANDELION = (new FlowerBlock(37, 13)).setData(Tile$SoundType.none, 0.7F, 1.0F, 0.0F); + ROSE = (new FlowerBlock(38, 12)).setData(Tile$SoundType.none, 0.7F, 1.0F, 0.0F); + BROWN_MUSHROOM = (new MushroomBlock(39, 29)).setData(Tile$SoundType.none, 0.7F, 1.0F, 0.0F); + RED_MUSHROOM = (new MushroomBlock(40, 28)).setData(Tile$SoundType.none, 0.7F, 1.0F, 0.0F); + var10000 = (new MetalBlock(41, 40)).setData(Tile$SoundType.metal, 0.7F, 1.0F, 3.0F); + var0 = false; + var1 = var10000; + var10000.explodes = false; + GOLD_BLOCK = var1; + var10000 = (new MetalBlock(42, 39)).setData(Tile$SoundType.metal, 0.7F, 1.0F, 5.0F); + var0 = false; + var1 = var10000; + var10000.explodes = false; + IRON_BLOCK = var1; + var10000 = (new SlabBlock(43, true)).setData(Tile$SoundType.stone, 1.0F, 1.0F, 2.0F); + var0 = false; + var1 = var10000; + var10000.explodes = false; + DOUBLE_SLAB = var1; + var10000 = (new SlabBlock(44, false)).setData(Tile$SoundType.stone, 1.0F, 1.0F, 2.0F); + var0 = false; + var1 = var10000; + var10000.explodes = false; + SLAB = var1; + var10000 = (new Block(45, 7)).setData(Tile$SoundType.stone, 1.0F, 1.0F, 2.0F); + var0 = false; + var1 = var10000; + var10000.explodes = false; + BRICK = var1; + TNT = (new TNTBlock(46, 8)).setData(Tile$SoundType.cloth, 1.0F, 1.0F, 0.0F); + BOOKSHELF = (new BookshelfBlock(47, 35)).setData(Tile$SoundType.wood, 1.0F, 1.0F, 1.5F); + var10000 = (new Block(48, 36)).setData(Tile$SoundType.stone, 1.0F, 1.0F, 1.0F); + var0 = false; + var1 = var10000; + var10000.explodes = false; + MOSSY_COBBLESTONE = var1; + var10000 = (new StoneBlock(49, 37)).setData(Tile$SoundType.stone, 1.0F, 1.0F, 10.0F); + var0 = false; + var1 = var10000; + var10000.explodes = false; + OBSIDIAN = var1; + } +} diff --git a/src/main/java/com/mojang/minecraft/level/tile/BookshelfBlock.java b/src/main/java/com/mojang/minecraft/level/tile/BookshelfBlock.java new file mode 100644 index 0000000..e9a90ee --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/tile/BookshelfBlock.java @@ -0,0 +1,28 @@ +package com.mojang.minecraft.level.tile; + +import java.util.Random; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.level.tile.Block; + +public final class BookshelfBlock extends Block { + + public BookshelfBlock(int var1, int var2) { + super(47, 35); + } + + protected final int getTextureId(int texture) { + return texture <= 1?4:this.textureId; + } + + public final int getDrop() { + if(Minecraft.settings.randomDrops) { + return new Random().nextInt(49 - 1 + 1) + 1; + } + return Block.BOOKSHELF.id; + } + + public final int getDropCount() { + return 0; + } +} diff --git a/src/main/java/com/mojang/minecraft/level/tile/DirtBlock.java b/src/main/java/com/mojang/minecraft/level/tile/DirtBlock.java new file mode 100644 index 0000000..fa0b366 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/tile/DirtBlock.java @@ -0,0 +1,20 @@ +package com.mojang.minecraft.level.tile; + +import java.util.Random; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.level.tile.Block; + +public final class DirtBlock extends Block { + + protected DirtBlock(int var1, int var2) { + super(3, 2); + } + + public final int getDrop() { + if(Minecraft.settings.randomDrops) { + return new Random().nextInt(49 - 1 + 1) + 1; + } + return Block.DIRT.id; + } +} diff --git a/src/main/java/com/mojang/minecraft/level/tile/FlowerBlock.java b/src/main/java/com/mojang/minecraft/level/tile/FlowerBlock.java new file mode 100644 index 0000000..f09d98b --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/tile/FlowerBlock.java @@ -0,0 +1,103 @@ +package com.mojang.minecraft.level.tile; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.phys.AABB; +import com.mojang.minecraft.render.ShapeRenderer; +import com.mojang.util.MathHelper; + +import java.util.Random; + +public class FlowerBlock extends Block { + + protected FlowerBlock(int var1, int var2) { + super(var1); + this.textureId = var2; + this.setPhysics(true); + float var3 = 0.2F; + this.setBounds(0.5F - var3, 0.0F, 0.5F - var3, var3 + 0.5F, var3 * 3.0F, var3 + 0.5F); + } + + public void update(Level level, int x, int y, int z, Random rand) { + if(!level.growTrees) { + int var6 = level.getTile(x, y - 1, z); + if(!level.isLit(x, y, z) || var6 != Block.DIRT.id && var6 != Block.GRASS.id) { + level.setTile(x, y, z, 0); + } + + } + } + + private void render(ShapeRenderer var1, float var2, float var3, float var4) { + int var15; + int var5 = (var15 = this.getTextureId(15)) % 16 << 4; + int var6 = var15 / 16 << 4; + float var16 = (float)var5 / 256.0F; + float var17 = ((float)var5 + 15.99F) / 256.0F; + float var7 = (float)var6 / 256.0F; + float var18 = ((float)var6 + 15.99F) / 256.0F; + + for(int var8 = 0; var8 < 2; ++var8) { + float var9 = (float)((double)MathHelper.sin((float)var8 * 3.1415927F / 2.0F + 0.7853982F) * 0.5D); + float var10 = (float)((double)MathHelper.cos((float)var8 * 3.1415927F / 2.0F + 0.7853982F) * 0.5D); + float var11 = var2 + 0.5F - var9; + var9 += var2 + 0.5F; + float var13 = var3 + 1.0F; + float var14 = var4 + 0.5F - var10; + var10 += var4 + 0.5F; + var1.vertexUV(var11, var13, var14, var17, var7); + var1.vertexUV(var9, var13, var10, var16, var7); + var1.vertexUV(var9, var3, var10, var16, var18); + var1.vertexUV(var11, var3, var14, var17, var18); + var1.vertexUV(var9, var13, var10, var17, var7); + var1.vertexUV(var11, var13, var14, var16, var7); + var1.vertexUV(var11, var3, var14, var16, var18); + var1.vertexUV(var9, var3, var10, var17, var18); + } + + } + + public final boolean isOpaque() { + return false; + } + + public final boolean isSolid() { + return false; + } + + public final void renderPreview(ShapeRenderer var1) { + var1.normal(0.0F, 1.0F, 0.0F); + var1.begin(); + this.render(var1, 0.0F, 0.4F, -0.3F); + var1.end(); + } + + public final boolean isCube() { + return false; + } + + public final boolean render(Level var1, int var2, int var3, int var4, ShapeRenderer var5) { + float var6 = var1.getBrightness(var2, var3, var4); + var5.color(var6, var6, var6); + this.render(var5, (float)var2, (float)var3, (float)var4); + return true; + } + + public final void renderFullbright(ShapeRenderer shapeRenderer) { + shapeRenderer.color(1.0F, 1.0F, 1.0F); + this.render(shapeRenderer, (float)-2, 0.0F, 0.0F); + } + + @Override + public AABB getCollisionBox(int x, int y, int z) + { + return null; + } + + public int getDrop() { + if(Minecraft.settings.randomDrops) { + return new Random().nextInt(49 - 1 + 1) + 1; + } + return this == Block.ROSE ? Block.ROSE.id : Block.DANDELION.id; + } +} diff --git a/src/main/java/com/mojang/minecraft/level/tile/GlassBlock.java b/src/main/java/com/mojang/minecraft/level/tile/GlassBlock.java new file mode 100644 index 0000000..8ebbc25 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/tile/GlassBlock.java @@ -0,0 +1,29 @@ +package com.mojang.minecraft.level.tile; + +import java.util.Random; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.level.Level; + +public final class GlassBlock extends Block { + + private boolean showNeighborSides = false; + + + protected GlassBlock(int var1, int var2, boolean var3) { + super(20, 49); + } + + public final boolean isSolid() { + return false; + } + + public final boolean canRenderSide(Level level, int x, int y, int z, int side) { + int var6 = level.getTile(x, y, z); + return !this.showNeighborSides && var6 == this.id?false:super.canRenderSide(level, x, y, z, side); + } + + public final boolean isOpaque() { + return false; + } +} diff --git a/src/main/java/com/mojang/minecraft/level/tile/GrassBlock.java b/src/main/java/com/mojang/minecraft/level/tile/GrassBlock.java new file mode 100644 index 0000000..8599528 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/tile/GrassBlock.java @@ -0,0 +1,44 @@ +package com.mojang.minecraft.level.tile; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.level.tile.Block; +import java.util.Random; + +public final class GrassBlock extends Block { + + protected GrassBlock(int var1) { + super(2); + this.textureId = 3; + this.setPhysics(true); + } + + protected final int getTextureId(int texture) { + return texture == 1 ? 0 : (texture == 0 ? 2 : Minecraft.settings.ofBetterGrass ? 0 : 3); + } + + public final void update(Level level, int x, int y, int z, Random rand) { + if(rand.nextInt(4) == 0) { + if(!level.isLit(x, y, z)) { + level.setTile(x, y, z, Block.DIRT.id); + } else { + for(int var9 = 0; var9 < 4; ++var9) { + int var6 = x + rand.nextInt(3) - 1; + int var7 = y + rand.nextInt(5) - 3; + int var8 = z + rand.nextInt(3) - 1; + if(level.getTile(var6, var7, var8) == Block.DIRT.id && level.isLit(var6, var7, var8)) { + level.setTile(var6, var7, var8, Block.GRASS.id); + } + } + + } + } + } + + public final int getDrop() { + if(Minecraft.settings.randomDrops) { + return new Random().nextInt(49 - 1 + 1) + 1; + } + return Block.DIRT.getDrop(); + } +} diff --git a/src/main/java/com/mojang/minecraft/level/tile/LeavesBaseBlock.java b/src/main/java/com/mojang/minecraft/level/tile/LeavesBaseBlock.java new file mode 100644 index 0000000..20a9ff6 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/tile/LeavesBaseBlock.java @@ -0,0 +1,26 @@ +package com.mojang.minecraft.level.tile; + +import com.mojang.minecraft.level.Level; + +public class LeavesBaseBlock extends Block { + + private boolean showNeighborSides = true; + + + protected LeavesBaseBlock(int var1, int var2, boolean var3) { + super(var1, var2); + } + + public final boolean isSolid() { + return false; + } + + public final boolean canRenderSide(Level level, int x, int y, int z, int side) { + int var6 = level.getTile(x, y, z); + return !this.showNeighborSides && var6 == this.id?false:super.canRenderSide(level, x, y, z, side); + } + + public final boolean isOpaque() { + return false; + } +} diff --git a/src/main/java/com/mojang/minecraft/level/tile/LeavesBlock.java b/src/main/java/com/mojang/minecraft/level/tile/LeavesBlock.java new file mode 100644 index 0000000..0730acb --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/tile/LeavesBlock.java @@ -0,0 +1,19 @@ +package com.mojang.minecraft.level.tile; + +import com.mojang.minecraft.level.tile.Block; +import com.mojang.minecraft.level.tile.LeavesBaseBlock; + +public final class LeavesBlock extends LeavesBaseBlock { + + protected LeavesBlock(int var1, int var2) { + super(18, 22, true); + } + + public final int getDropCount() { + return random.nextInt(10) == 0?1:0; + } + + public final int getDrop() { + return Block.SAPLING.id; + } +} diff --git a/src/main/java/com/mojang/minecraft/level/tile/LiquidBlock.java b/src/main/java/com/mojang/minecraft/level/tile/LiquidBlock.java new file mode 100644 index 0000000..de06907 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/tile/LiquidBlock.java @@ -0,0 +1,168 @@ +package com.mojang.minecraft.level.tile; + +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.level.liquid.LiquidType; +import com.mojang.minecraft.phys.AABB; +import com.mojang.minecraft.render.ShapeRenderer; + +import java.util.Random; + +public class LiquidBlock extends Block { + + protected LiquidType type; + protected int stillId; + protected int movingId; + + + protected LiquidBlock(int var1, LiquidType var2) { + super(var1); + this.type = var2; + this.textureId = 14; + if(var2 == LiquidType.LAVA) { + this.textureId = 30; + } + + Block.liquid[var1] = true; + this.movingId = var1; + this.stillId = var1 + 1; + float var4 = 0.01F; + float var3 = 0.1F; + this.setBounds(var4 + 0.0F, 0.0F - var3 + var4, var4 + 0.0F, var4 + 1.0F, 1.0F - var3 + var4, var4 + 1.0F); + this.setPhysics(true); + if(var2 == LiquidType.LAVA) { + this.setTickDelay(16); + } + + } + + public final boolean isCube() { + return false; + } + + public final void onPlace(Level level, int x, int y, int z) { + level.addToTickNextTick(x, y, z, this.movingId); + } + + public void update(Level level, int x, int y, int z, Random rand) { + boolean var7 = false; + z = z; + y = y; + x = x; + level = level; + boolean var8 = false; + + boolean var6; + do { + --y; + if(level.getTile(x, y, z) != 0 || !this.canFlow(level, x, y, z)) { + break; + } + + if(var6 = level.setTile(x, y, z, this.movingId)) { + var8 = true; + } + } while(var6 && this.type != LiquidType.LAVA); + + ++y; + if(this.type == LiquidType.WATER || !var8) { + var8 = var8 | this.flow(level, x - 1, y, z) | this.flow(level, x + 1, y, z) | this.flow(level, x, y, z - 1) | this.flow(level, x, y, z + 1); + } + + if(!var8) { + level.setTileNoUpdate(x, y, z, this.stillId); + } else { + level.addToTickNextTick(x, y, z, this.movingId); + } + + } + + private boolean canFlow(Level var1, int var2, int var3, int var4) { + if(this.type == LiquidType.WATER) { + for(int var7 = var2 - 2; var7 <= var2 + 2; ++var7) { + for(int var5 = var3 - 2; var5 <= var3 + 2; ++var5) { + for(int var6 = var4 - 2; var6 <= var4 + 2; ++var6) { + if(var1.getTile(var7, var5, var6) == Block.SPONGE.id) { + return false; + } + } + } + } + } + + return true; + } + + private boolean flow(Level var1, int var2, int var3, int var4) { + if(var1.getTile(var2, var3, var4) == 0) { + if(!this.canFlow(var1, var2, var3, var4)) { + return false; + } + + if(var1.setTile(var2, var3, var4, this.movingId)) { + var1.addToTickNextTick(var2, var3, var4, this.movingId); + } + } + + return false; + } + + protected final float getBrightness(Level level, int x, int y, int z) { + return this.type == LiquidType.LAVA?100.0F: level.getBrightness(x, y, z); + } + + public final boolean canRenderSide(Level level, int x, int y, int z, int side) { + int var6; + return x >= 0 && y >= 0 && z >= 0 && x < level.width && z < level.height?((var6 = level.getTile(x, y, z)) != this.movingId && var6 != this.stillId?(side == 1 && (level.getTile(x - 1, y, z) == 0 || level.getTile(x + 1, y, z) == 0 || level.getTile(x, y, z - 1) == 0 || level.getTile(x, y, z + 1) == 0)?true:super.canRenderSide(level, x, y, z, side)):false):false; + } + + public final void renderInside(ShapeRenderer shapeRenderer, int x, int y, int z, int side) { + super.renderInside(shapeRenderer, x, y, z, side); + super.renderSide(shapeRenderer, x, y, z, side); + } + + public final boolean isOpaque() { + return true; + } + + public final boolean isSolid() { + return false; + } + + public final LiquidType getLiquidType() { + return this.type; + } + + public void onNeighborChange(Level var1, int var2, int var3, int var4, int var5) { + if(var5 != 0) { + LiquidType var6 = Block.blocks[var5].getLiquidType(); + if(this.type == LiquidType.WATER && var6 == LiquidType.LAVA || var6 == LiquidType.WATER && this.type == LiquidType.LAVA) { + var1.setTile(var2, var3, var4, Block.STONE.id); + return; + } + } + + var1.addToTickNextTick(var2, var3, var4, var5); + } + + public final int getTickDelay() { + return this.type == LiquidType.LAVA?5:0; + } + + public final void dropItems(Level var1, int var2, int var3, int var4, float var5) {} + + public final void onBreak(Level var1, int var2, int var3, int var4) {} + + public final int getDropCount() { + return 0; + } + + public final int getRenderPass() { + return this.type == LiquidType.WATER?1:0; + } + + @Override + public AABB getCollisionBox(int x, int y, int z) + { + return null; + } +} diff --git a/src/main/java/com/mojang/minecraft/level/tile/MetalBlock.java b/src/main/java/com/mojang/minecraft/level/tile/MetalBlock.java new file mode 100644 index 0000000..e439f89 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/tile/MetalBlock.java @@ -0,0 +1,25 @@ +package com.mojang.minecraft.level.tile; + +import java.util.Random; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.level.tile.Block; + +public final class MetalBlock extends Block { + + public MetalBlock(int var1, int var2) { + super(var1); + this.textureId = var2; + } + + protected final int getTextureId(int texture) { + return texture == 1?this.textureId - 16:(texture == 0?this.textureId + 16:this.textureId); + } + + public final int getDrop() { + if(Minecraft.settings.randomDrops) { + return new Random().nextInt(49 - 1 + 1) + 1; + } + return this == Block.GOLD_BLOCK ? Block.GOLD_BLOCK.id : Block.IRON_BLOCK.id; + } +} diff --git a/src/main/java/com/mojang/minecraft/level/tile/MushroomBlock.java b/src/main/java/com/mojang/minecraft/level/tile/MushroomBlock.java new file mode 100644 index 0000000..f63b611 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/tile/MushroomBlock.java @@ -0,0 +1,32 @@ +package com.mojang.minecraft.level.tile; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.level.tile.Block; +import com.mojang.minecraft.level.tile.FlowerBlock; +import java.util.Random; + +public final class MushroomBlock extends FlowerBlock { + + protected MushroomBlock(int var1, int var2) { + super(var1, var2); + float var3 = 0.2F; + this.setBounds(0.5F - var3, 0.0F, 0.5F - var3, var3 + 0.5F, var3 * 2.0F, var3 + 0.5F); + } + + public final void update(Level level, int x, int y, int z, Random rand) { + int var6 = level.getTile(x, y - 1, z); + if(level.isLit(x, y, z) || var6 != Block.STONE.id && var6 != Block.GRAVEL.id && var6 != Block.COBBLESTONE.id) { + level.setTile(x, y, z, 0); + } + + } + + @Override + public final int getDrop() { + if(Minecraft.settings.randomDrops) { + return new Random().nextInt(49 - 1 + 1) + 1; + } + return this == Block.RED_MUSHROOM ? Block.RED_MUSHROOM.id : Block.BROWN_MUSHROOM.id; + } +} diff --git a/src/main/java/com/mojang/minecraft/level/tile/OreBlock.java b/src/main/java/com/mojang/minecraft/level/tile/OreBlock.java new file mode 100644 index 0000000..d1e5c02 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/tile/OreBlock.java @@ -0,0 +1,24 @@ +package com.mojang.minecraft.level.tile; + +import java.util.Random; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.level.tile.Block; + +public final class OreBlock extends Block { + + public OreBlock(int var1, int var2) { + super(var1, var2); + } + + public final int getDrop() { + if(Minecraft.settings.randomDrops) { + return new Random().nextInt(49 - 1 + 1) + 1; + } + return this == Block.COAL_ORE?Block.SLAB.id:(this == Block.GOLD_ORE?Block.GOLD_BLOCK.id:(this == Block.IRON_ORE?Block.IRON_BLOCK.id:this.id)); + } + + public final int getDropCount() { + return random.nextInt(3) + 1; + } +} diff --git a/src/main/java/com/mojang/minecraft/level/tile/SandBlock.java b/src/main/java/com/mojang/minecraft/level/tile/SandBlock.java new file mode 100644 index 0000000..793db28 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/tile/SandBlock.java @@ -0,0 +1,55 @@ +package com.mojang.minecraft.level.tile; + +import java.util.Random; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.level.liquid.LiquidType; +import com.mojang.minecraft.level.tile.Block; + +public final class SandBlock extends Block { + + public SandBlock(int var1, int var2) { + super(var1, var2); + } + + public final void onPlace(Level level, int x, int y, int z) { + this.fall(level, x, y, z); + } + + public final void onNeighborChange(Level var1, int var2, int var3, int var4, int var5) { + this.fall(var1, var2, var3, var4); + } + + private void fall(Level var1, int var2, int var3, int var4) { + int var11 = var2; + int var5 = var3; + int var6 = var4; + + while(true) { + int var8 = var5 - 1; + int var10; + LiquidType var12; + if(!((var10 = var1.getTile(var11, var8, var6)) == 0?true:((var12 = Block.blocks[var10].getLiquidType()) == LiquidType.WATER?true:var12 == LiquidType.LAVA)) || var5 <= 0) { + if(var5 != var3) { + if((var10 = var1.getTile(var11, var5, var6)) > 0 && Block.blocks[var10].getLiquidType() != LiquidType.NOT_LIQUID) { + var1.setTileNoUpdate(var11, var5, var6, 0); + } + + var1.swap(var2, var3, var4, var11, var5, var6); + } + + return; + } + + --var5; + } + } + + public final int getDrop() { + if(Minecraft.settings.randomDrops) { + return new Random().nextInt(49 - 1 + 1) + 1; + } + return Block.SAND.id; + } +} diff --git a/src/main/java/com/mojang/minecraft/level/tile/SaplingBlock.java b/src/main/java/com/mojang/minecraft/level/tile/SaplingBlock.java new file mode 100644 index 0000000..48cc55a --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/tile/SaplingBlock.java @@ -0,0 +1,38 @@ +package com.mojang.minecraft.level.tile; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.level.tile.Block; +import com.mojang.minecraft.level.tile.FlowerBlock; +import java.util.Random; + +public final class SaplingBlock extends FlowerBlock { + + protected SaplingBlock(int var1, int var2) { + super(6, 15); + float var3 = 0.4F; + this.setBounds(0.5F - var3, 0.0F, 0.5F - var3, var3 + 0.5F, var3 * 2.0F, var3 + 0.5F); + } + + public final void update(Level level, int x, int y, int z, Random rand) { + int var6 = level.getTile(x, y - 1, z); + if(level.isLit(x, y, z) && (var6 == Block.DIRT.id || var6 == Block.GRASS.id)) { + if(rand.nextInt(5) == 0) { + level.setTileNoUpdate(x, y, z, 0); + if(!level.maybeGrowTree(x, y, z)) { + level.setTileNoUpdate(x, y, z, this.id); + } + } + + } else { + level.setTile(x, y, z, 0); + } + } + + public final int getDrop() { + if(Minecraft.settings.randomDrops) { + return new Random().nextInt(49 - 1 + 1) + 1; + } + return Block.SAPLING.id; + } +} diff --git a/src/main/java/com/mojang/minecraft/level/tile/SlabBlock.java b/src/main/java/com/mojang/minecraft/level/tile/SlabBlock.java new file mode 100644 index 0000000..1a155e0 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/tile/SlabBlock.java @@ -0,0 +1,67 @@ +package com.mojang.minecraft.level.tile; + +import java.util.Random; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.level.tile.Block; + +public final class SlabBlock extends Block { + + private boolean doubleSlab; + + + public SlabBlock(int var1, boolean var2) { + super(var1, 6); + this.doubleSlab = var2; + if(!var2) { + this.setBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F); + } + + } + + protected final int getTextureId(int texture) { + return texture <= 1?6:5; + } + + public final boolean isSolid() { + return this.doubleSlab; + } + + public final void onNeighborChange(Level var1, int var2, int var3, int var4, int var5) { + if(this == Block.SLAB) { + ; + } + } + + public final void onAdded(Level level, int x, int y, int z) { + if(this != Block.SLAB) { + super.onAdded(level, x, y, z); + } + + if(level.getTile(x, y - 1, z) == SLAB.id) { + level.setTile(x, y, z, 0); + level.setTile(x, y - 1, z, Block.DOUBLE_SLAB.id); + } + + } + + public final int getDrop() { + if(Minecraft.settings.randomDrops) { + return new Random().nextInt(49 - 1 + 1) + 1; + } + return Block.SLAB.id; + } + + public final boolean isCube() { + return this.doubleSlab; + } + + public final boolean canRenderSide(Level level, int x, int y, int z, int side) { + if(this != Block.SLAB) { + super.canRenderSide(level, x, y, z, side); + } + + return side == 1?true:(!super.canRenderSide(level, x, y, z, side)?false:(side == 0?true: level.getTile(x, y, z) != this.id)); + } +} diff --git a/src/main/java/com/mojang/minecraft/level/tile/SpongeBlock.java b/src/main/java/com/mojang/minecraft/level/tile/SpongeBlock.java new file mode 100644 index 0000000..6e13069 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/tile/SpongeBlock.java @@ -0,0 +1,46 @@ +package com.mojang.minecraft.level.tile; + +import java.util.Random; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.level.tile.Block; + +public final class SpongeBlock extends Block { + + protected SpongeBlock(int var1) { + super(19); + this.textureId = 48; + } + + public final void onAdded(Level level, int x, int y, int z) { + for(int var7 = x - 2; var7 <= x + 2; ++var7) { + for(int var5 = y - 2; var5 <= y + 2; ++var5) { + for(int var6 = z - 2; var6 <= z + 2; ++var6) { + if(level.isWater(var7, var5, var6)) { + level.setTileNoNeighborChange(var7, var5, var6, 0); + } + } + } + } + + } + + public final void onRemoved(Level var1, int var2, int var3, int var4) { + for(int var7 = var2 - 2; var7 <= var2 + 2; ++var7) { + for(int var5 = var3 - 2; var5 <= var3 + 2; ++var5) { + for(int var6 = var4 - 2; var6 <= var4 + 2; ++var6) { + var1.updateNeighborsAt(var7, var5, var6, var1.getTile(var7, var5, var6)); + } + } + } + + } + + public final int getDrop() { + if(Minecraft.settings.randomDrops) { + return new Random().nextInt(49 - 1 + 1) + 1; + } + return Block.SPONGE.id; + } +} diff --git a/src/main/java/com/mojang/minecraft/level/tile/StillLiquidBlock.java b/src/main/java/com/mojang/minecraft/level/tile/StillLiquidBlock.java new file mode 100644 index 0000000..0709be0 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/tile/StillLiquidBlock.java @@ -0,0 +1,57 @@ +package com.mojang.minecraft.level.tile; + +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.level.liquid.LiquidType; + +import java.util.Random; + +public final class StillLiquidBlock extends LiquidBlock { + + protected StillLiquidBlock(int var1, LiquidType var2) { + super(var1, var2); + this.movingId = var1 - 1; + this.stillId = var1; + this.setPhysics(false); + } + + public final void update(Level level, int x, int y, int z, Random rand) {} + + public final void onNeighborChange(Level var1, int var2, int var3, int var4, int var5) { + boolean var6 = false; + if(var1.getTile(var2 - 1, var3, var4) == 0) { + var6 = true; + } + + if(var1.getTile(var2 + 1, var3, var4) == 0) { + var6 = true; + } + + if(var1.getTile(var2, var3, var4 - 1) == 0) { + var6 = true; + } + + if(var1.getTile(var2, var3, var4 + 1) == 0) { + var6 = true; + } + + if(var1.getTile(var2, var3 - 1, var4) == 0) { + var6 = true; + } + + if(var5 != 0) { + LiquidType var7 = Block.blocks[var5].getLiquidType(); + if(this.type == LiquidType.WATER && var7 == LiquidType.LAVA || var7 == LiquidType.WATER && this.type == LiquidType.LAVA) { + var1.setTile(var2, var3, var4, Block.STONE.id); + return; + } + } + + if(var6) { + var1.setTileNoUpdate(var2, var3, var4, this.movingId); + var1.addToTickNextTick(var2, var3, var4, this.movingId); + } + + } + + +} diff --git a/src/main/java/com/mojang/minecraft/level/tile/StoneBlock.java b/src/main/java/com/mojang/minecraft/level/tile/StoneBlock.java new file mode 100644 index 0000000..9518e37 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/tile/StoneBlock.java @@ -0,0 +1,20 @@ +package com.mojang.minecraft.level.tile; + +import java.util.Random; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.level.tile.Block; + +public final class StoneBlock extends Block { + + public StoneBlock(int var1, int var2) { + super(var1, var2); + } + + public final int getDrop() { + if(Minecraft.settings.randomDrops) { + return new Random().nextInt(49 - 1 + 1) + 1; + } + return Block.COBBLESTONE.id; + } +} diff --git a/src/main/java/com/mojang/minecraft/level/tile/TNTBlock.java b/src/main/java/com/mojang/minecraft/level/tile/TNTBlock.java new file mode 100644 index 0000000..7db3915 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/tile/TNTBlock.java @@ -0,0 +1,48 @@ +package com.mojang.minecraft.level.tile; + +import java.util.Random; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.item.PrimedTnt; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.level.tile.Block; +import com.mojang.minecraft.particle.ParticleManager; + +public final class TNTBlock extends Block { + + public TNTBlock(int var1, int var2) { + super(46, 8); + } + + protected final int getTextureId(int texture) { + return texture == 0?this.textureId + 2:(texture == 1?this.textureId + 1:this.textureId); + } + + public final int getDropCount() { + return 0; + } + + public final void explode(Level var1, int var2, int var3, int var4) { + if(!var1.creativeMode) { + PrimedTnt var5; + (var5 = new PrimedTnt(var1, (float)var2 + 0.5F, (float)var3 + 0.5F, (float)var4 + 0.5F)).life = random.nextInt(var5.life / 4) + var5.life / 8; + var1.addEntity(var5); + } + + } + + public final void spawnBreakParticles(Level level, int x, int y, int z, ParticleManager particleManager) { + if(!level.creativeMode) { + level.addEntity(new PrimedTnt(level, (float) x + 0.5F, (float) y + 0.5F, (float) z + 0.5F)); + } else { + super.spawnBreakParticles(level, x, y, z, particleManager); + } + } + + public final int getDrop() { + if(Minecraft.settings.randomDrops) { + return new Random().nextInt(49 - 1 + 1) + 1; + } + return Block.TNT.id; + } +} diff --git a/src/main/java/com/mojang/minecraft/level/tile/Tile$SoundType.java b/src/main/java/com/mojang/minecraft/level/tile/Tile$SoundType.java new file mode 100644 index 0000000..84fff91 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/tile/Tile$SoundType.java @@ -0,0 +1,35 @@ +package com.mojang.minecraft.level.tile; + +import com.mojang.minecraft.level.tile.Block; + +public enum Tile$SoundType { + + none("none", 0, "-", 0.0F, 0.0F), + grass("grass", 1, "grass", 0.6F, 1.0F), + cloth("cloth", 2, "grass", 0.7F, 1.2F), + gravel("gravel", 3, "gravel", 1.0F, 1.0F), + stone("stone", 4, "stone", 1.0F, 1.0F), + metal("metal", 5, "stone", 1.0F, 2.0F), + wood("wood", 6, "wood", 1.0F, 1.0F); + public final String name; + private final float volume; + private final float pitch; + // $FF: synthetic field + private static final Tile$SoundType[] values = new Tile$SoundType[]{none, grass, cloth, gravel, stone, metal, wood}; + + + private Tile$SoundType(String var1, int var2, String var3, float var4, float var5) { + this.name = var3; + this.volume = var4; + this.pitch = var5; + } + + public final float getVolume() { + return this.volume / (Block.random.nextFloat() * 0.4F + 1.0F) * 0.5F; + } + + public final float getPitch() { + return this.pitch / (Block.random.nextFloat() * 0.2F + 0.9F); + } + +} diff --git a/src/main/java/com/mojang/minecraft/level/tile/WoodBlock.java b/src/main/java/com/mojang/minecraft/level/tile/WoodBlock.java new file mode 100644 index 0000000..1805f72 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/level/tile/WoodBlock.java @@ -0,0 +1,29 @@ +package com.mojang.minecraft.level.tile; + +import java.util.Random; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.level.tile.Block; + +public final class WoodBlock extends Block { + + protected WoodBlock(int var1) { + super(17); + this.textureId = 20; + } + + public final int getDropCount() { + return random.nextInt(3) + 3; + } + + public final int getDrop() { + if(Minecraft.settings.randomDrops) { + return new Random().nextInt(49 - 1 + 1) + 1; + } + return Block.WOOD.id; + } + + protected final int getTextureId(int texture) { + return texture == 1?21:(texture == 0?21:20); + } +} diff --git a/src/main/java/com/mojang/minecraft/mob/Creeper$1.java b/src/main/java/com/mojang/minecraft/mob/Creeper$1.java new file mode 100644 index 0000000..2663cee --- /dev/null +++ b/src/main/java/com/mojang/minecraft/mob/Creeper$1.java @@ -0,0 +1,46 @@ +package com.mojang.minecraft.mob; + +import com.mojang.minecraft.Entity; +import com.mojang.minecraft.level.tile.Block; +import com.mojang.minecraft.mob.Creeper; +import com.mojang.minecraft.mob.ai.BasicAttackAI; +import com.mojang.minecraft.particle.TerrainParticle; +import com.mojang.util.MathHelper; + +final class Creeper$1 extends BasicAttackAI { + + public static final long serialVersionUID = 0L; + // $FF: synthetic field + final Creeper creeper; + + + Creeper$1(Creeper var1) { + this.creeper = var1; + } + + public final boolean attack(Entity var1) { + if(!super.attack(var1)) { + return false; + } else { + this.mob.hurt(var1, 6); + return true; + } + } + + public final void beforeRemove() { + float var1 = 4.0F; + this.level.explode(this.mob, this.mob.x, this.mob.y, this.mob.z, var1); + + for(int var2 = 0; var2 < 500; ++var2) { + float var3 = (float)this.random.nextGaussian() * var1 / 4.0F; + float var4 = (float)this.random.nextGaussian() * var1 / 4.0F; + float var5 = (float)this.random.nextGaussian() * var1 / 4.0F; + float var6 = MathHelper.sqrt(var3 * var3 + var4 * var4 + var5 * var5); + float var7 = var3 / var6 / var6; + float var8 = var4 / var6 / var6; + var6 = var5 / var6 / var6; + this.level.particleEngine.spawnParticle(new TerrainParticle(this.level, this.mob.x + var3, this.mob.y + var4, this.mob.z + var5, var7, var8, var6, Block.LEAVES)); + } + + } +} diff --git a/src/main/java/com/mojang/minecraft/mob/Creeper.java b/src/main/java/com/mojang/minecraft/mob/Creeper.java new file mode 100644 index 0000000..e27ce57 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/mob/Creeper.java @@ -0,0 +1,28 @@ +package com.mojang.minecraft.mob; + +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.mob.Creeper$1; +import com.mojang.minecraft.mob.Mob; +import com.mojang.util.MathHelper; + +public class Creeper extends Mob { + + public static final long serialVersionUID = 0L; + + + public Creeper(Level var1, float var2, float var3, float var4) { + super(var1); + this.heightOffset = 1.62F; + this.modelName = "creeper"; + this.textureName = "/mob/creeper.png"; + this.ai = new Creeper$1(this); + this.ai.defaultLookAngle = 45; + this.deathScore = 200; + this.setPos(var2, var3, var4); + } + + public float getBrightness(float var1) { + float var2 = (float)(20 - this.health) / 20.0F; + return ((MathHelper.sin((float)this.tickCount + var1) * 0.5F + 0.5F) * var2 * 0.5F + 0.25F + var2 * 0.25F) * super.getBrightness(var1); + } +} diff --git a/src/main/java/com/mojang/minecraft/mob/HumanoidMob.java b/src/main/java/com/mojang/minecraft/mob/HumanoidMob.java new file mode 100644 index 0000000..bf4175a --- /dev/null +++ b/src/main/java/com/mojang/minecraft/mob/HumanoidMob.java @@ -0,0 +1,70 @@ +package com.mojang.minecraft.mob; + +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.mob.Mob; +import com.mojang.minecraft.model.HumanoidModel; +import com.mojang.minecraft.model.Model; +import com.mojang.minecraft.render.TextureManager; +import org.lwjgl.opengl.GL11; + +public class HumanoidMob extends Mob { + + public static final long serialVersionUID = 0L; + public boolean helmet = Math.random() < 0.20000000298023224D; + public boolean armor = Math.random() < 0.20000000298023224D; + + + public HumanoidMob(Level var1, float var2, float var3, float var4) { + super(var1); + this.modelName = "humanoid"; + this.setPos(var2, var3, var4); + } + + public void renderModel(TextureManager var1, float var2, float var3, float var4, float var5, float var6, float var7) { + super.renderModel(var1, var2, var3, var4, var5, var6, var7); + Model var9 = modelCache.getModel(this.modelName); + GL11.glEnable(3008); + if(this.allowAlpha) { + GL11.glEnable(2884); + } + + if(this.hasHair) { + GL11.glDisable(2884); + HumanoidModel var10 = null; + (var10 = (HumanoidModel)var9).headwear.yaw = var10.head.yaw; + var10.headwear.pitch = var10.head.pitch; + var10.headwear.render(var7); + GL11.glEnable(2884); + } + + if(this.armor || this.helmet) { + GL11.glBindTexture(3553, var1.load("/armor/plate.png")); + GL11.glDisable(2884); + HumanoidModel var8; + (var8 = (HumanoidModel)modelCache.getModel("humanoid.armor")).head.render = this.helmet; + var8.body.render = this.armor; + var8.rightArm.render = this.armor; + var8.leftArm.render = this.armor; + var8.rightLeg.render = false; + var8.leftLeg.render = false; + HumanoidModel var11 = (HumanoidModel)var9; + var8.head.yaw = var11.head.yaw; + var8.head.pitch = var11.head.pitch; + var8.rightArm.pitch = var11.rightArm.pitch; + var8.rightArm.roll = var11.rightArm.roll; + var8.leftArm.pitch = var11.leftArm.pitch; + var8.leftArm.roll = var11.leftArm.roll; + var8.rightLeg.pitch = var11.rightLeg.pitch; + var8.leftLeg.pitch = var11.leftLeg.pitch; + var8.head.render(var7); + var8.body.render(var7); + var8.rightArm.render(var7); + var8.leftArm.render(var7); + var8.rightLeg.render(var7); + var8.leftLeg.render(var7); + GL11.glEnable(2884); + } + + GL11.glDisable(3008); + } +} diff --git a/src/main/java/com/mojang/minecraft/mob/Mob.java b/src/main/java/com/mojang/minecraft/mob/Mob.java new file mode 100644 index 0000000..36a3e29 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/mob/Mob.java @@ -0,0 +1,443 @@ +package com.mojang.minecraft.mob; + +import com.mojang.minecraft.Entity; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.mob.ai.AI; +import com.mojang.minecraft.mob.ai.BasicAI; +import com.mojang.minecraft.model.ModelManager; +import com.mojang.minecraft.render.TextureManager; +import com.mojang.util.MathHelper; +import org.lwjgl.opengl.GL11; + +public class Mob extends Entity { + + public static final long serialVersionUID = 0L; + public static final int ATTACK_DURATION = 5; + public static final int TOTAL_AIR_SUPPLY = 300; + public static ModelManager modelCache; + public int invulnerableDuration = 20; + public float rot; + public float timeOffs; + public float speed; + public float rotA = (float)(Math.random() + 1.0D) * 0.01F; + protected float yBodyRot = 0.0F; + protected float yBodyRotO = 0.0F; + protected float oRun; + protected float run; + protected float animStep; + protected float animStepO; + protected int tickCount = 0; + public boolean hasHair = true; + protected String textureName = "/char.png"; + public boolean allowAlpha = true; + public float rotOffs = 0.0F; + public String modelName = null; + protected float bobStrength = 1.0F; + protected int deathScore = 0; + public float renderOffset = 0.0F; + public int health = 20; + public int lastHealth; + public int invulnerableTime = 0; + public int airSupply = 300; + public int hurtTime; + public int hurtDuration; + public float hurtDir = 0.0F; + public int deathTime = 0; + public int attackTime = 0; + public float oTilt; + public float tilt; + protected boolean dead = false; + public AI ai; + + + public Mob(Level var1) { + super(var1); + this.setPos(this.x, this.y, this.z); + this.timeOffs = (float)Math.random() * 12398.0F; + this.rot = (float)(Math.random() * 3.1415927410125732D * 2.0D); + this.speed = 1.0F; + this.ai = new BasicAI(); + this.footSize = 0.5F; + } + + public boolean isPickable() { + return !this.removed; + } + + public boolean isPushable() { + return !this.removed; + } + + public final void tick() { + super.tick(); + this.oTilt = this.tilt; + if(this.attackTime > 0) { + --this.attackTime; + } + + if(this.hurtTime > 0) { + --this.hurtTime; + } + + if(this.invulnerableTime > 0) { + --this.invulnerableTime; + } + + if(this.health <= 0) { + ++this.deathTime; + if(this.deathTime > 20) { + if(this.ai != null) { + this.ai.beforeRemove(); + } + + this.remove(); + } + } + + if(this.isUnderWater()) { + if(this.airSupply > 0) { + --this.airSupply; + } else { + this.hurt((Entity)null, 2); + } + } else { + this.airSupply = 300; + } + + if(this.isInWater()) { + this.fallDistance = 0.0F; + } + + if(this.isInLava()) { + this.hurt((Entity)null, 10); + } + + this.animStepO = this.animStep; + this.yBodyRotO = this.yBodyRot; + this.yRotO = this.yRot; + this.xRotO = this.xRot; + ++this.tickCount; + this.aiStep(); + float var1 = this.x - this.xo; + float var2 = this.z - this.zo; + float var3 = MathHelper.sqrt(var1 * var1 + var2 * var2); + float var4 = this.yBodyRot; + float var5 = 0.0F; + this.oRun = this.run; + float var6 = 0.0F; + if(var3 > 0.05F) { + var6 = 1.0F; + var5 = var3 * 3.0F; + var4 = (float)Math.atan2((double)var2, (double)var1) * 180.0F / 3.1415927F - 90.0F; + } + + if(!this.onGround) { + var6 = 0.0F; + } + + this.run += (var6 - this.run) * 0.3F; + + for(var1 = var4 - this.yBodyRot; var1 < -180.0F; var1 += 360.0F) { + ; + } + + while(var1 >= 180.0F) { + var1 -= 360.0F; + } + + this.yBodyRot += var1 * 0.1F; + + for(var1 = this.yRot - this.yBodyRot; var1 < -180.0F; var1 += 360.0F) { + ; + } + + while(var1 >= 180.0F) { + var1 -= 360.0F; + } + + boolean var7 = var1 < -90.0F || var1 >= 90.0F; + if(var1 < -75.0F) { + var1 = -75.0F; + } + + if(var1 >= 75.0F) { + var1 = 75.0F; + } + + this.yBodyRot = this.yRot - var1; + this.yBodyRot += var1 * 0.1F; + if(var7) { + var5 = -var5; + } + + while(this.yRot - this.yRotO < -180.0F) { + this.yRotO -= 360.0F; + } + + while(this.yRot - this.yRotO >= 180.0F) { + this.yRotO += 360.0F; + } + + while(this.yBodyRot - this.yBodyRotO < -180.0F) { + this.yBodyRotO -= 360.0F; + } + + while(this.yBodyRot - this.yBodyRotO >= 180.0F) { + this.yBodyRotO += 360.0F; + } + + while(this.xRot - this.xRotO < -180.0F) { + this.xRotO -= 360.0F; + } + + while(this.xRot - this.xRotO >= 180.0F) { + this.xRotO += 360.0F; + } + + this.animStep += var5; + } + + public void aiStep() { + if(this.ai != null) { + this.ai.tick(this.level, this); + } + + } + + protected void bindTexture(TextureManager var1) { + this.textureId = var1.load(this.textureName); + GL11.glBindTexture(3553, this.textureId); + } + + public void render(TextureManager var1, float var2) { + if(this.modelName != null) { + float var3; + if((var3 = (float)this.attackTime - var2) < 0.0F) { + var3 = 0.0F; + } + + while(this.yBodyRotO - this.yBodyRot < -180.0F) { + this.yBodyRotO += 360.0F; + } + + while(this.yBodyRotO - this.yBodyRot >= 180.0F) { + this.yBodyRotO -= 360.0F; + } + + while(this.xRotO - this.xRot < -180.0F) { + this.xRotO += 360.0F; + } + + while(this.xRotO - this.xRot >= 180.0F) { + this.xRotO -= 360.0F; + } + + while(this.yRotO - this.yRot < -180.0F) { + this.yRotO += 360.0F; + } + + while(this.yRotO - this.yRot >= 180.0F) { + this.yRotO -= 360.0F; + } + + float var4 = this.yBodyRotO + (this.yBodyRot - this.yBodyRotO) * var2; + float var5 = this.oRun + (this.run - this.oRun) * var2; + float var6 = this.yRotO + (this.yRot - this.yRotO) * var2; + float var7 = this.xRotO + (this.xRot - this.xRotO) * var2; + var6 -= var4; + GL11.glPushMatrix(); + float var8 = this.animStepO + (this.animStep - this.animStepO) * var2; + float var9; + GL11.glColor3f(var9 = this.getBrightness(var2), var9, var9); + var9 = 0.0625F; + float var10 = -Math.abs(MathHelper.cos(var8 * 0.6662F)) * 5.0F * var5 * this.bobStrength - 23.0F; + GL11.glTranslatef(this.xo + (this.x - this.xo) * var2, this.yo + (this.y - this.yo) * var2 - 1.62F + this.renderOffset, this.zo + (this.z - this.zo) * var2); + float var11; + if((var11 = (float)this.hurtTime - var2) > 0.0F || this.health <= 0) { + if(var11 < 0.0F) { + var11 = 0.0F; + } else { + var11 = MathHelper.sin((var11 /= (float)this.hurtDuration) * var11 * var11 * var11 * 3.1415927F) * 14.0F; + } + + float var12 = 0.0F; + if(this.health <= 0) { + var12 = ((float)this.deathTime + var2) / 20.0F; + if((var11 += var12 * var12 * 800.0F) > 90.0F) { + var11 = 90.0F; + } + } + + var12 = this.hurtDir; + GL11.glRotatef(180.0F - var4 + this.rotOffs, 0.0F, 1.0F, 0.0F); + GL11.glScalef(1.0F, 1.0F, 1.0F); + GL11.glRotatef(-var12, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(-var11, 0.0F, 0.0F, 1.0F); + GL11.glRotatef(var12, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(-(180.0F - var4 + this.rotOffs), 0.0F, 1.0F, 0.0F); + } + + GL11.glTranslatef(0.0F, -var10 * var9, 0.0F); + GL11.glScalef(1.0F, -1.0F, 1.0F); + GL11.glRotatef(180.0F - var4 + this.rotOffs, 0.0F, 1.0F, 0.0F); + if(!this.allowAlpha) { + GL11.glDisable(3008); + } else { + GL11.glDisable(2884); + } + + GL11.glScalef(-1.0F, 1.0F, 1.0F); + modelCache.getModel(this.modelName).attackOffset = var3 / 5.0F; + this.bindTexture(var1); + this.renderModel(var1, var8, var2, var5, var6, var7, var9); + if(this.invulnerableTime > this.invulnerableDuration - 10) { + GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.75F); + GL11.glEnable(3042); + GL11.glBlendFunc(770, 1); + this.bindTexture(var1); + this.renderModel(var1, var8, var2, var5, var6, var7, var9); + GL11.glDisable(3042); + GL11.glBlendFunc(770, 771); + } + + GL11.glEnable(3008); + if(this.allowAlpha) { + GL11.glEnable(2884); + } + + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glPopMatrix(); + } + } + + public void renderModel(TextureManager var1, float var2, float var3, float var4, float var5, float var6, float var7) { + modelCache.getModel(this.modelName).render(var2, var4, (float)this.tickCount + var3, var5, var6, var7); + } + + public void heal(int var1) { + if(this.health > 0) { + this.health += var1; + if(this.health > 20) { + this.health = 20; + } + + this.invulnerableTime = this.invulnerableDuration / 2; + } + } + + public void hurt(Entity var1, int var2) { + if(!this.level.creativeMode) { + if(this.health > 0) { + this.ai.hurt(var1, var2); + if((float)this.invulnerableTime > (float)this.invulnerableDuration / 2.0F) { + if(this.lastHealth - var2 >= this.health) { + return; + } + + this.health = this.lastHealth - var2; + } else { + this.lastHealth = this.health; + this.invulnerableTime = this.invulnerableDuration; + this.health -= var2; + this.hurtTime = this.hurtDuration = 10; + } + + this.hurtDir = 0.0F; + if(var1 != null) { + float var3 = var1.x - this.x; + float var4 = var1.z - this.z; + this.hurtDir = (float)(Math.atan2((double)var4, (double)var3) * 180.0D / 3.1415927410125732D) - this.yRot; + this.knockback(var1, var2, var3, var4); + } else { + this.hurtDir = (float)((int)(Math.random() * 2.0D) * 180); + } + + if(this.health <= 0) { + this.die(var1); + } + + } + } + } + + public void knockback(Entity var1, int var2, float var3, float var4) { + float var5 = MathHelper.sqrt(var3 * var3 + var4 * var4); + float var6 = 0.4F; + this.xd /= 2.0F; + this.yd /= 2.0F; + this.zd /= 2.0F; + this.xd -= var3 / var5 * var6; + this.yd += 0.4F; + this.zd -= var4 / var5 * var6; + if(this.yd > 0.4F) { + this.yd = 0.4F; + } + + } + + public void die(Entity var1) { + if(!this.level.creativeMode) { + if(this.deathScore > 0 && var1 != null) { + var1.awardKillScore(this, this.deathScore); + } + + this.dead = true; + } + } + + protected void causeFallDamage(float var1) { + if(!this.level.creativeMode) { + int var2; + if((var2 = (int)Math.ceil((double)(var1 - 3.0F))) > 0) { + this.hurt((Entity)null, var2); + } + + } + } + + public void travel(float var1, float var2) { + float var3; + if(this.isInWater()) { + var3 = this.y; + this.moveRelative(var1, var2, 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 + var3, this.zd)) { + this.yd = 0.3F; + } + + } else if(this.isInLava()) { + var3 = this.y; + this.moveRelative(var1, var2, 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 + var3, this.zd)) { + this.yd = 0.3F; + } + + } else { + this.moveRelative(var1, var2, 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) { + var3 = 0.6F; + this.xd *= var3; + this.zd *= var3; + } + + } + } + + public boolean isShootable() { + return true; + } +} diff --git a/src/main/java/com/mojang/minecraft/mob/Pig.java b/src/main/java/com/mojang/minecraft/mob/Pig.java new file mode 100644 index 0000000..fb6f286 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/mob/Pig.java @@ -0,0 +1,34 @@ +package com.mojang.minecraft.mob; + +import com.mojang.minecraft.Entity; +import com.mojang.minecraft.item.Item; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.level.tile.Block; +import com.mojang.minecraft.mob.QuadrupedMob; + +public class Pig extends QuadrupedMob { + + public static final long serialVersionUID = 0L; + + + public Pig(Level var1, float var2, float var3, float var4) { + super(var1, var2, var3, var4); + this.heightOffset = 1.72F; + this.modelName = "pig"; + this.textureName = "/mob/pig.png"; + } + + public void die(Entity var1) { + if(var1 != null) { + var1.awardKillScore(this, 10); + } + + int var2 = (int)(Math.random() + Math.random() + 1.0D); + + for(int var3 = 0; var3 < var2; ++var3) { + this.level.addEntity(new Item(this.level, this.x, this.y, this.z, Block.BROWN_MUSHROOM.id)); + } + + super.die(var1); + } +} diff --git a/src/main/java/com/mojang/minecraft/mob/QuadrupedMob.java b/src/main/java/com/mojang/minecraft/mob/QuadrupedMob.java new file mode 100644 index 0000000..385461d --- /dev/null +++ b/src/main/java/com/mojang/minecraft/mob/QuadrupedMob.java @@ -0,0 +1,17 @@ +package com.mojang.minecraft.mob; + +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.mob.Mob; + +public class QuadrupedMob extends Mob { + + public static final long serialVersionUID = 0L; + + + public QuadrupedMob(Level var1, float var2, float var3, float var4) { + super(var1); + this.setSize(1.4F, 1.2F); + this.setPos(var2, var3, var4); + this.modelName = "pig"; + } +} diff --git a/src/main/java/com/mojang/minecraft/mob/Sheep$1.java b/src/main/java/com/mojang/minecraft/mob/Sheep$1.java new file mode 100644 index 0000000..25c205e --- /dev/null +++ b/src/main/java/com/mojang/minecraft/mob/Sheep$1.java @@ -0,0 +1,51 @@ +package com.mojang.minecraft.mob; + +import com.mojang.minecraft.level.tile.Block; +import com.mojang.minecraft.mob.Sheep; +import com.mojang.minecraft.mob.ai.BasicAI; +import com.mojang.util.MathHelper; + +final class Sheep$1 extends BasicAI { + + private static final long serialVersionUID = 1L; + // $FF: synthetic field + final Sheep sheep; + + + Sheep$1(Sheep var1) { + this.sheep = var1; + } + + protected final void update() { + float var1 = MathHelper.sin(this.sheep.yRot * 3.1415927F / 180.0F); + float var2 = MathHelper.cos(this.sheep.yRot * 3.1415927F / 180.0F); + var1 = -0.7F * var1; + var2 = 0.7F * var2; + int var4 = (int)(this.mob.x + var1); + int var3 = (int)(this.mob.y - 2.0F); + int var5 = (int)(this.mob.z + var2); + if(this.sheep.grazing) { + if(this.level.getTile(var4, var3, var5) != Block.GRASS.id) { + this.sheep.grazing = false; + } else { + if(++this.sheep.grazingTime == 60) { + this.level.setTile(var4, var3, var5, Block.DIRT.id); + if(this.random.nextInt(5) == 0) { + this.sheep.hasFur = true; + } + } + + this.xxa = 0.0F; + this.yya = 0.0F; + this.mob.xRot = (float)(40 + this.sheep.grazingTime / 2 % 2 * 10); + } + } else { + if(this.level.getTile(var4, var3, var5) == Block.GRASS.id) { + this.sheep.grazing = true; + this.sheep.grazingTime = 0; + } + + super.update(); + } + } +} diff --git a/src/main/java/com/mojang/minecraft/mob/Sheep.java b/src/main/java/com/mojang/minecraft/mob/Sheep.java new file mode 100644 index 0000000..9eb126b --- /dev/null +++ b/src/main/java/com/mojang/minecraft/mob/Sheep.java @@ -0,0 +1,113 @@ +package com.mojang.minecraft.mob; + +import com.mojang.minecraft.Entity; +import com.mojang.minecraft.item.Item; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.level.tile.Block; +import com.mojang.minecraft.mob.QuadrupedMob; +import com.mojang.minecraft.mob.Sheep$1; +import com.mojang.minecraft.model.AnimalModel; +import com.mojang.minecraft.player.Player; +import com.mojang.minecraft.render.TextureManager; +import org.lwjgl.opengl.GL11; + +public class Sheep extends QuadrupedMob { + + public static final long serialVersionUID = 0L; + public boolean hasFur = true; + public boolean grazing = false; + public int grazingTime = 0; + public float graze; + public float grazeO; + + + public Sheep(Level var1, float var2, float var3, float var4) { + super(var1, var2, var3, var4); + this.setSize(1.4F, 1.72F); + this.setPos(var2, var3, var4); + this.heightOffset = 1.72F; + this.modelName = "sheep"; + this.textureName = "/mob/sheep.png"; + this.ai = new Sheep$1(this); + } + + public void aiStep() { + super.aiStep(); + this.grazeO = this.graze; + if(this.grazing) { + this.graze += 0.2F; + } else { + this.graze -= 0.2F; + } + + if(this.graze < 0.0F) { + this.graze = 0.0F; + } + + if(this.graze > 1.0F) { + this.graze = 1.0F; + } + + } + + public void die(Entity var1) { + if(var1 != null) { + var1.awardKillScore(this, 10); + } + + int var2 = (int)(Math.random() + Math.random() + 1.0D); + + for(int var3 = 0; var3 < var2; ++var3) { + this.level.addEntity(new Item(this.level, this.x, this.y, this.z, Block.BROWN_MUSHROOM.id)); + } + + super.die(var1); + } + + public void hurt(Entity var1, int var2) { + if(this.hasFur && var1 instanceof Player) { + this.hasFur = false; + int var3 = (int)(Math.random() * 3.0D + 1.0D); + + for(var2 = 0; var2 < var3; ++var2) { + this.level.addEntity(new Item(this.level, this.x, this.y, this.z, Block.WHITE_WOOL.id)); + } + + } else { + super.hurt(var1, var2); + } + } + + public void renderModel(TextureManager var1, float var2, float var3, float var4, float var5, float var6, float var7) { + AnimalModel var8; + float var9 = (var8 = (AnimalModel)modelCache.getModel(this.modelName)).head.y; + float var10 = var8.head.z; + var8.head.y += (this.grazeO + (this.graze - this.grazeO) * var3) * 8.0F; + var8.head.z -= this.grazeO + (this.graze - this.grazeO) * var3; + super.renderModel(var1, var2, var3, var4, var5, var6, var7); + if(this.hasFur) { + GL11.glBindTexture(3553, var1.load("/mob/sheep_fur.png")); + GL11.glDisable(2884); + AnimalModel var11; + (var11 = (AnimalModel)modelCache.getModel("sheep.fur")).head.yaw = var8.head.yaw; + var11.head.pitch = var8.head.pitch; + var11.head.y = var8.head.y; + var11.head.x = var8.head.x; + var11.body.yaw = var8.body.yaw; + var11.body.pitch = var8.body.pitch; + var11.leg1.pitch = var8.leg1.pitch; + var11.leg2.pitch = var8.leg2.pitch; + var11.leg3.pitch = var8.leg3.pitch; + var11.leg4.pitch = var8.leg4.pitch; + var11.head.render(var7); + var11.body.render(var7); + var11.leg1.render(var7); + var11.leg2.render(var7); + var11.leg3.render(var7); + var11.leg4.render(var7); + } + + var8.head.y = var9; + var8.head.z = var10; + } +} diff --git a/src/main/java/com/mojang/minecraft/mob/Skeleton$1.java b/src/main/java/com/mojang/minecraft/mob/Skeleton$1.java new file mode 100644 index 0000000..3ae510b --- /dev/null +++ b/src/main/java/com/mojang/minecraft/mob/Skeleton$1.java @@ -0,0 +1,30 @@ +package com.mojang.minecraft.mob; + +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.mob.Mob; +import com.mojang.minecraft.mob.Skeleton; +import com.mojang.minecraft.mob.ai.BasicAttackAI; + +final class Skeleton$1 extends BasicAttackAI { + + public static final long serialVersionUID = 0L; + // $FF: synthetic field + final Skeleton parent; + + + Skeleton$1(Skeleton var1) { + this.parent = var1; + } + + public final void tick(Level var1, Mob var2) { + super.tick(var1, var2); + if(var2.health > 0 && this.random.nextInt(30) == 0 && this.attackTarget != null) { + this.parent.shootArrow(var1); + } + + } + + public final void beforeRemove() { + Skeleton.shootRandomArrow(this.parent); + } +} diff --git a/src/main/java/com/mojang/minecraft/mob/Skeleton.java b/src/main/java/com/mojang/minecraft/mob/Skeleton.java new file mode 100644 index 0000000..aa2f050 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/mob/Skeleton.java @@ -0,0 +1,38 @@ +package com.mojang.minecraft.mob; + +import com.mojang.minecraft.item.Arrow; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.mob.Skeleton$1; +import com.mojang.minecraft.mob.Zombie; + +public class Skeleton extends Zombie { + + public static final long serialVersionUID = 0L; + + + public Skeleton(Level var1, float var2, float var3, float var4) { + super(var1, var2, var3, var4); + this.modelName = "skeleton"; + this.textureName = "/mob/skeleton.png"; + Skeleton$1 var5 = new Skeleton$1(this); + this.deathScore = 120; + var5.runSpeed = 0.3F; + var5.damage = 8; + this.ai = var5; + } + + public void shootArrow(Level var1) { + var1.addEntity(new Arrow(var1, this, this.x, this.y, this.z, this.yRot + 180.0F + (float)(Math.random() * 45.0D - 22.5D), this.xRot - (float)(Math.random() * 45.0D - 10.0D), 1.0F)); + } + + // $FF: synthetic method + static void shootRandomArrow(Skeleton var0) { + var0 = var0; + int var1 = (int)((Math.random() + Math.random()) * 3.0D + 4.0D); + + for(int var2 = 0; var2 < var1; ++var2) { + var0.level.addEntity(new Arrow(var0.level, var0.level.getPlayer(), var0.x, var0.y - 0.2F, var0.z, (float)Math.random() * 360.0F, -((float)Math.random()) * 60.0F, 0.4F)); + } + + } +} diff --git a/src/main/java/com/mojang/minecraft/mob/Spider.java b/src/main/java/com/mojang/minecraft/mob/Spider.java new file mode 100644 index 0000000..c3104a0 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/mob/Spider.java @@ -0,0 +1,23 @@ +package com.mojang.minecraft.mob; + +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.mob.QuadrupedMob; +import com.mojang.minecraft.mob.ai.JumpAttackAI; + +public class Spider extends QuadrupedMob { + + public static final long serialVersionUID = 0L; + + + public Spider(Level var1, float var2, float var3, float var4) { + super(var1, var2, var3, var4); + this.heightOffset = 0.72F; + this.modelName = "spider"; + this.textureName = "/mob/spider.png"; + this.setSize(1.4F, 0.9F); + this.setPos(var2, var3, var4); + this.deathScore = 105; + this.bobStrength = 0.0F; + this.ai = new JumpAttackAI(); + } +} diff --git a/src/main/java/com/mojang/minecraft/mob/Zombie.java b/src/main/java/com/mojang/minecraft/mob/Zombie.java new file mode 100644 index 0000000..5c6c8aa --- /dev/null +++ b/src/main/java/com/mojang/minecraft/mob/Zombie.java @@ -0,0 +1,23 @@ +package com.mojang.minecraft.mob; + +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.mob.HumanoidMob; +import com.mojang.minecraft.mob.ai.BasicAttackAI; + +public class Zombie extends HumanoidMob { + + public static final long serialVersionUID = 0L; + + + public Zombie(Level var1, float var2, float var3, float var4) { + super(var1, var2, var3, var4); + this.modelName = "zombie"; + this.textureName = "/mob/zombie.png"; + this.heightOffset = 1.62F; + BasicAttackAI var5 = new BasicAttackAI(); + this.deathScore = 80; + var5.defaultLookAngle = 30; + var5.runSpeed = 1.0F; + this.ai = var5; + } +} diff --git a/src/main/java/com/mojang/minecraft/mob/ai/AI.java b/src/main/java/com/mojang/minecraft/mob/ai/AI.java new file mode 100644 index 0000000..8be0556 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/mob/ai/AI.java @@ -0,0 +1,19 @@ +package com.mojang.minecraft.mob.ai; + +import com.mojang.minecraft.Entity; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.mob.Mob; +import java.io.Serializable; + +public abstract class AI implements Serializable { + + public static final long serialVersionUID = 0L; + public int defaultLookAngle = 0; + + + public void tick(Level var1, Mob var2) {} + + public void beforeRemove() {} + + public void hurt(Entity var1, int var2) {} +} diff --git a/src/main/java/com/mojang/minecraft/mob/ai/BasicAI.java b/src/main/java/com/mojang/minecraft/mob/ai/BasicAI.java new file mode 100644 index 0000000..3714b28 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/mob/ai/BasicAI.java @@ -0,0 +1,119 @@ +package com.mojang.minecraft.mob.ai; + +import com.mojang.minecraft.Entity; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.mob.Mob; +import com.mojang.minecraft.mob.ai.AI; +import java.util.List; +import java.util.Random; + +public class BasicAI extends AI { + + public static final long serialVersionUID = 0L; + public Random random = new Random(); + public float xxa; + public float yya; + protected float yRotA; + public Level level; + public Mob mob; + public boolean jumping = false; + protected int attackDelay = 0; + public float runSpeed = 0.7F; + protected int noActionTime = 0; + public Entity attackTarget = null; + + + public void tick(Level var1, Mob var2) { + ++this.noActionTime; + Entity var3; + if(this.noActionTime > 600 && this.random.nextInt(800) == 0 && (var3 = var1.getPlayer()) != null) { + float var4 = var3.x - var2.x; + float var5 = var3.y - var2.y; + float var6 = var3.z - var2.z; + if(var4 * var4 + var5 * var5 + var6 * var6 < 1024.0F) { + this.noActionTime = 0; + } else { + var2.remove(); + } + } + + this.level = var1; + this.mob = var2; + if(this.attackDelay > 0) { + --this.attackDelay; + } + + if(var2.health <= 0) { + this.jumping = false; + this.xxa = 0.0F; + this.yya = 0.0F; + this.yRotA = 0.0F; + } else { + this.update(); + } + + boolean var7 = var2.isInWater(); + boolean var9 = var2.isInLava(); + if(this.jumping) { + if(var7) { + var2.yd += 0.04F; + } else if(var9) { + var2.yd += 0.04F; + } else if(var2.onGround) { + this.jumpFromGround(); + } + } + + this.xxa *= 0.98F; + this.yya *= 0.98F; + this.yRotA *= 0.9F; + var2.travel(this.xxa, this.yya); + List var11; + if((var11 = var1.findEntities(var2, var2.bb.grow(0.2F, 0.0F, 0.2F))) != null && var11.size() > 0) { + for(int var8 = 0; var8 < var11.size(); ++var8) { + Entity var10; + if((var10 = (Entity)var11.get(var8)).isPushable()) { + var10.push(var2); + } + } + } + + } + + protected void jumpFromGround() { + this.mob.yd = 0.42F; + } + + protected void update() { + if(this.random.nextFloat() < 0.07F) { + this.xxa = (this.random.nextFloat() - 0.5F) * this.runSpeed; + this.yya = this.random.nextFloat() * this.runSpeed; + } + + this.jumping = this.random.nextFloat() < 0.01F; + if(this.random.nextFloat() < 0.04F) { + this.yRotA = (this.random.nextFloat() - 0.5F) * 60.0F; + } + + this.mob.yRot += this.yRotA; + this.mob.xRot = (float)this.defaultLookAngle; + if(this.attackTarget != null) { + this.yya = this.runSpeed; + this.jumping = this.random.nextFloat() < 0.04F; + } + + boolean var1 = this.mob.isInWater(); + boolean var2 = this.mob.isInLava(); + if(var1 || var2) { + this.jumping = this.random.nextFloat() < 0.8F; + } + + } + + public void beforeRemove() {} + + public void hurt(Entity var1, int var2) { + super.hurt(var1, var2); + this.noActionTime = 0; + } +} diff --git a/src/main/java/com/mojang/minecraft/mob/ai/BasicAttackAI.java b/src/main/java/com/mojang/minecraft/mob/ai/BasicAttackAI.java new file mode 100644 index 0000000..a1eefb9 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/mob/ai/BasicAttackAI.java @@ -0,0 +1,87 @@ +package com.mojang.minecraft.mob.ai; + +import com.mojang.minecraft.Entity; +import com.mojang.minecraft.item.Arrow; +import com.mojang.minecraft.mob.ai.BasicAI; +import com.mojang.minecraft.model.Vec3D; +import com.mojang.util.MathHelper; + +public class BasicAttackAI extends BasicAI { + + public static final long serialVersionUID = 0L; + public int damage = 6; + + + protected void update() { + super.update(); + if(this.mob.health > 0) { + this.doAttack(); + } + + } + + protected void doAttack() { + Entity var1 = this.level.getPlayer(); + float var2 = 16.0F; + if(this.attackTarget != null && this.attackTarget.removed) { + this.attackTarget = null; + } + + float var3; + float var4; + float var5; + if(var1 != null && this.attackTarget == null) { + var3 = var1.x - this.mob.x; + var4 = var1.y - this.mob.y; + var5 = var1.z - this.mob.z; + if(var3 * var3 + var4 * var4 + var5 * var5 < var2 * var2) { + this.attackTarget = var1; + } + } + + if(this.attackTarget != null) { + var3 = this.attackTarget.x - this.mob.x; + var4 = this.attackTarget.y - this.mob.y; + var5 = this.attackTarget.z - this.mob.z; + float var6; + if((var6 = var3 * var3 + var4 * var4 + var5 * var5) > var2 * var2 * 2.0F * 2.0F && this.random.nextInt(100) == 0) { + this.attackTarget = null; + } + + if(this.attackTarget != null) { + var6 = MathHelper.sqrt(var6); + this.mob.yRot = (float)(Math.atan2((double)var5, (double)var3) * 180.0D / 3.1415927410125732D) - 90.0F; + this.mob.xRot = -((float)(Math.atan2((double)var4, (double)var6) * 180.0D / 3.1415927410125732D)); + if(MathHelper.sqrt(var3 * var3 + var4 * var4 + var5 * var5) < 2.0F && this.attackDelay == 0) { + this.attack(this.attackTarget); + } + } + + } + } + + public boolean attack(Entity var1) { + if(this.level.clip(new Vec3D(this.mob.x, this.mob.y, this.mob.z), new Vec3D(var1.x, var1.y, var1.z)) != null) { + return false; + } else { + this.mob.attackTime = 5; + this.attackDelay = this.random.nextInt(20) + 10; + int var2 = (int)((this.random.nextFloat() + this.random.nextFloat()) / 2.0F * (float)this.damage + 1.0F); + var1.hurt(this.mob, var2); + this.noActionTime = 0; + return true; + } + } + + public void hurt(Entity var1, int var2) { + super.hurt(var1, var2); + if(var1 instanceof Arrow) { + var1 = ((Arrow)var1).getOwner(); + } + + if(var1 != null && !var1.getClass().equals(this.mob.getClass())) { + this.attackTarget = var1; + } + + } +} diff --git a/src/main/java/com/mojang/minecraft/mob/ai/JumpAttackAI.java b/src/main/java/com/mojang/minecraft/mob/ai/JumpAttackAI.java new file mode 100644 index 0000000..6eff10b --- /dev/null +++ b/src/main/java/com/mojang/minecraft/mob/ai/JumpAttackAI.java @@ -0,0 +1,24 @@ +package com.mojang.minecraft.mob.ai; + +import com.mojang.minecraft.mob.ai.BasicAttackAI; + +public class JumpAttackAI extends BasicAttackAI { + + public static final long serialVersionUID = 0L; + + + public JumpAttackAI() { + this.runSpeed *= 0.8F; + } + + protected void jumpFromGround() { + if(this.attackTarget == null) { + super.jumpFromGround(); + } else { + this.mob.xd = 0.0F; + this.mob.zd = 0.0F; + this.mob.moveRelative(0.0F, 1.0F, 0.6F); + this.mob.yd = 0.5F; + } + } +} diff --git a/src/main/java/com/mojang/minecraft/model/AnimalModel.java b/src/main/java/com/mojang/minecraft/model/AnimalModel.java new file mode 100644 index 0000000..d5094e8 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/model/AnimalModel.java @@ -0,0 +1,52 @@ +package com.mojang.minecraft.model; + +import com.mojang.minecraft.model.Model; +import com.mojang.minecraft.model.ModelPart; +import com.mojang.util.MathHelper; + +public class AnimalModel extends Model { + + public ModelPart head = new ModelPart(0, 0); + public ModelPart body; + public ModelPart leg1; + public ModelPart leg2; + public ModelPart leg3; + public ModelPart leg4; + + + public AnimalModel(int var1, float var2) { + this.head.setBounds(-4.0F, -4.0F, -8.0F, 8, 8, 8, 0.0F); + this.head.setPosition(0.0F, (float)(18 - var1), -6.0F); + this.body = new ModelPart(28, 8); + this.body.setBounds(-5.0F, -10.0F, -7.0F, 10, 16, 8, 0.0F); + this.body.setPosition(0.0F, (float)(17 - var1), 2.0F); + this.leg1 = new ModelPart(0, 16); + this.leg1.setBounds(-2.0F, 0.0F, -2.0F, 4, var1, 4, 0.0F); + this.leg1.setPosition(-3.0F, (float)(24 - var1), 7.0F); + this.leg2 = new ModelPart(0, 16); + this.leg2.setBounds(-2.0F, 0.0F, -2.0F, 4, var1, 4, 0.0F); + this.leg2.setPosition(3.0F, (float)(24 - var1), 7.0F); + this.leg3 = new ModelPart(0, 16); + this.leg3.setBounds(-2.0F, 0.0F, -2.0F, 4, var1, 4, 0.0F); + this.leg3.setPosition(-3.0F, (float)(24 - var1), -5.0F); + this.leg4 = new ModelPart(0, 16); + this.leg4.setBounds(-2.0F, 0.0F, -2.0F, 4, var1, 4, 0.0F); + this.leg4.setPosition(3.0F, (float)(24 - var1), -5.0F); + } + + public final void render(float var1, float var2, float var3, float var4, float var5, float var6) { + this.head.yaw = var4 / 57.295776F; + this.head.pitch = var5 / 57.295776F; + this.body.pitch = 1.5707964F; + this.leg1.pitch = MathHelper.cos(var1 * 0.6662F) * 1.4F * var2; + this.leg2.pitch = MathHelper.cos(var1 * 0.6662F + 3.1415927F) * 1.4F * var2; + this.leg3.pitch = MathHelper.cos(var1 * 0.6662F + 3.1415927F) * 1.4F * var2; + this.leg4.pitch = MathHelper.cos(var1 * 0.6662F) * 1.4F * var2; + this.head.render(var6); + this.body.render(var6); + this.leg1.render(var6); + this.leg2.render(var6); + this.leg3.render(var6); + this.leg4.render(var6); + } +} diff --git a/src/main/java/com/mojang/minecraft/model/CreeperModel.java b/src/main/java/com/mojang/minecraft/model/CreeperModel.java new file mode 100644 index 0000000..73c1478 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/model/CreeperModel.java @@ -0,0 +1,52 @@ +package com.mojang.minecraft.model; + +import com.mojang.minecraft.model.Model; +import com.mojang.minecraft.model.ModelPart; +import com.mojang.util.MathHelper; + +public final class CreeperModel extends Model { + + private ModelPart head = new ModelPart(0, 0); + private ModelPart unused; + private ModelPart body; + private ModelPart leg1; + private ModelPart leg2; + private ModelPart leg3; + private ModelPart leg4; + + + public CreeperModel() { + this.head.setBounds(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.0F); + this.unused = new ModelPart(32, 0); + this.unused.setBounds(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.0F + 0.5F); + this.body = new ModelPart(16, 16); + this.body.setBounds(-4.0F, 0.0F, -2.0F, 8, 12, 4, 0.0F); + this.leg1 = new ModelPart(0, 16); + this.leg1.setBounds(-2.0F, 0.0F, -2.0F, 4, 6, 4, 0.0F); + this.leg1.setPosition(-2.0F, 12.0F, 4.0F); + this.leg2 = new ModelPart(0, 16); + this.leg2.setBounds(-2.0F, 0.0F, -2.0F, 4, 6, 4, 0.0F); + this.leg2.setPosition(2.0F, 12.0F, 4.0F); + this.leg3 = new ModelPart(0, 16); + this.leg3.setBounds(-2.0F, 0.0F, -2.0F, 4, 6, 4, 0.0F); + this.leg3.setPosition(-2.0F, 12.0F, -4.0F); + this.leg4 = new ModelPart(0, 16); + this.leg4.setBounds(-2.0F, 0.0F, -2.0F, 4, 6, 4, 0.0F); + this.leg4.setPosition(2.0F, 12.0F, -4.0F); + } + + public final void render(float var1, float var2, float var3, float var4, float var5, float var6) { + this.head.yaw = var4 / 57.295776F; + this.head.pitch = var5 / 57.295776F; + this.leg1.pitch = MathHelper.cos(var1 * 0.6662F) * 1.4F * var2; + this.leg2.pitch = MathHelper.cos(var1 * 0.6662F + 3.1415927F) * 1.4F * var2; + this.leg3.pitch = MathHelper.cos(var1 * 0.6662F + 3.1415927F) * 1.4F * var2; + this.leg4.pitch = MathHelper.cos(var1 * 0.6662F) * 1.4F * var2; + this.head.render(var6); + this.body.render(var6); + this.leg1.render(var6); + this.leg2.render(var6); + this.leg3.render(var6); + this.leg4.render(var6); + } +} diff --git a/src/main/java/com/mojang/minecraft/model/HumanoidModel.java b/src/main/java/com/mojang/minecraft/model/HumanoidModel.java new file mode 100644 index 0000000..dc2bd24 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/model/HumanoidModel.java @@ -0,0 +1,69 @@ +package com.mojang.minecraft.model; + +import com.mojang.minecraft.model.Model; +import com.mojang.minecraft.model.ModelPart; +import com.mojang.util.MathHelper; + +public class HumanoidModel extends Model { + + public ModelPart head; + public ModelPart headwear; + public ModelPart body; + public ModelPart rightArm; + public ModelPart leftArm; + public ModelPart rightLeg; + public ModelPart leftLeg; + + + public HumanoidModel() { + this(0.0F); + } + + public HumanoidModel(float var1) { + this.head = new ModelPart(0, 0); + this.head.setBounds(-4.0F, -8.0F, -4.0F, 8, 8, 8, var1); + this.headwear = new ModelPart(32, 0); + this.headwear.setBounds(-4.0F, -8.0F, -4.0F, 8, 8, 8, var1 + 0.5F); + this.body = new ModelPart(16, 16); + this.body.setBounds(-4.0F, 0.0F, -2.0F, 8, 12, 4, var1); + this.rightArm = new ModelPart(40, 16); + this.rightArm.setBounds(-3.0F, -2.0F, -2.0F, 4, 12, 4, var1); + this.rightArm.setPosition(-5.0F, 2.0F, 0.0F); + this.leftArm = new ModelPart(40, 16); + this.leftArm.mirror = true; + this.leftArm.setBounds(-1.0F, -2.0F, -2.0F, 4, 12, 4, var1); + this.leftArm.setPosition(5.0F, 2.0F, 0.0F); + this.rightLeg = new ModelPart(0, 16); + this.rightLeg.setBounds(-2.0F, 0.0F, -2.0F, 4, 12, 4, var1); + this.rightLeg.setPosition(-2.0F, 12.0F, 0.0F); + this.leftLeg = new ModelPart(0, 16); + this.leftLeg.mirror = true; + this.leftLeg.setBounds(-2.0F, 0.0F, -2.0F, 4, 12, 4, var1); + this.leftLeg.setPosition(2.0F, 12.0F, 0.0F); + } + + public final void render(float var1, float var2, float var3, float var4, float var5, float var6) { + this.setRotationAngles(var1, var2, var3, var4, var5, var6); + this.head.render(var6); + this.body.render(var6); + this.rightArm.render(var6); + this.leftArm.render(var6); + this.rightLeg.render(var6); + this.leftLeg.render(var6); + } + + public void setRotationAngles(float var1, float var2, float var3, float var4, float var5, float var6) { + this.head.yaw = var4 / 57.295776F; + this.head.pitch = var5 / 57.295776F; + this.rightArm.pitch = MathHelper.cos(var1 * 0.6662F + 3.1415927F) * 2.0F * var2; + this.rightArm.roll = (MathHelper.cos(var1 * 0.2312F) + 1.0F) * var2; + this.leftArm.pitch = MathHelper.cos(var1 * 0.6662F) * 2.0F * var2; + this.leftArm.roll = (MathHelper.cos(var1 * 0.2812F) - 1.0F) * var2; + this.rightLeg.pitch = MathHelper.cos(var1 * 0.6662F) * 1.4F * var2; + this.leftLeg.pitch = MathHelper.cos(var1 * 0.6662F + 3.1415927F) * 1.4F * var2; + this.rightArm.roll += MathHelper.cos(var3 * 0.09F) * 0.05F + 0.05F; + this.leftArm.roll -= MathHelper.cos(var3 * 0.09F) * 0.05F + 0.05F; + this.rightArm.pitch += MathHelper.sin(var3 * 0.067F) * 0.05F; + this.leftArm.pitch -= MathHelper.sin(var3 * 0.067F) * 0.05F; + } +} diff --git a/src/main/java/com/mojang/minecraft/model/Model.java b/src/main/java/com/mojang/minecraft/model/Model.java new file mode 100644 index 0000000..1585634 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/model/Model.java @@ -0,0 +1,10 @@ +package com.mojang.minecraft.model; + + +public abstract class Model { + + public float attackOffset; + + + public void render(float var1, float var2, float var3, float var4, float var5, float var6) {} +} diff --git a/src/main/java/com/mojang/minecraft/model/ModelManager.java b/src/main/java/com/mojang/minecraft/model/ModelManager.java new file mode 100644 index 0000000..790839c --- /dev/null +++ b/src/main/java/com/mojang/minecraft/model/ModelManager.java @@ -0,0 +1,30 @@ +package com.mojang.minecraft.model; + +import com.mojang.minecraft.model.AnimalModel; +import com.mojang.minecraft.model.CreeperModel; +import com.mojang.minecraft.model.HumanoidModel; +import com.mojang.minecraft.model.Model; +import com.mojang.minecraft.model.PigModel; +import com.mojang.minecraft.model.SheepFurModel; +import com.mojang.minecraft.model.SheepModel; +import com.mojang.minecraft.model.SkeletonModel; +import com.mojang.minecraft.model.SpiderModel; +import com.mojang.minecraft.model.ZombieModel; + +public final class ModelManager { + + private HumanoidModel human = new HumanoidModel(0.0F); + private HumanoidModel armoredHuman = new HumanoidModel(1.0F); + private CreeperModel creeper = new CreeperModel(); + private SkeletonModel skeleton = new SkeletonModel(); + private ZombieModel zombie = new ZombieModel(); + private AnimalModel pig = new PigModel(); + private AnimalModel sheep = new SheepModel(); + private SpiderModel spider = new SpiderModel(); + private SheepFurModel sheepFur = new SheepFurModel(); + + + public final Model getModel(String var1) { + return (Model)(var1.equals("humanoid")?this.human:(var1.equals("humanoid.armor")?this.armoredHuman:(var1.equals("creeper")?this.creeper:(var1.equals("skeleton")?this.skeleton:(var1.equals("zombie")?this.zombie:(var1.equals("pig")?this.pig:(var1.equals("sheep")?this.sheep:(var1.equals("spider")?this.spider:(var1.equals("sheep.fur")?this.sheepFur:null))))))))); + } +} diff --git a/src/main/java/com/mojang/minecraft/model/ModelPart.java b/src/main/java/com/mojang/minecraft/model/ModelPart.java new file mode 100644 index 0000000..2f61d76 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/model/ModelPart.java @@ -0,0 +1,152 @@ +package com.mojang.minecraft.model; + +import com.mojang.minecraft.model.TexturedQuad; +import com.mojang.minecraft.model.Vec3D; +import com.mojang.minecraft.model.Vertex; +import org.lwjgl.opengl.GL11; + +public final class ModelPart { + + public Vertex[] vertices; + public TexturedQuad[] quads; + private int u; + private int v; + public float x; + public float y; + public float z; + public float pitch; + public float yaw; + public float roll; + public boolean hasList = false; + public int list = 0; + public boolean mirror = false; + public boolean render = true; + private boolean unused = false; + + + public ModelPart(int var1, int var2) { + this.u = var1; + this.v = var2; + } + + public final void setBounds(float var1, float var2, float var3, int var4, int var5, int var6, float var7) { + this.vertices = new Vertex[8]; + this.quads = new TexturedQuad[6]; + float var8 = var1 + (float)var4; + float var9 = var2 + (float)var5; + float var10 = var3 + (float)var6; + var1 -= var7; + var2 -= var7; + var3 -= var7; + var8 += var7; + var9 += var7; + var10 += var7; + if(this.mirror) { + var7 = var8; + var8 = var1; + var1 = var7; + } + + Vertex var20 = new Vertex(var1, var2, var3, 0.0F, 0.0F); + Vertex var11 = new Vertex(var8, var2, var3, 0.0F, 8.0F); + Vertex var12 = new Vertex(var8, var9, var3, 8.0F, 8.0F); + Vertex var18 = new Vertex(var1, var9, var3, 8.0F, 0.0F); + Vertex var13 = new Vertex(var1, var2, var10, 0.0F, 0.0F); + Vertex var15 = new Vertex(var8, var2, var10, 0.0F, 8.0F); + Vertex var21 = new Vertex(var8, var9, var10, 8.0F, 8.0F); + Vertex var14 = new Vertex(var1, var9, var10, 8.0F, 0.0F); + this.vertices[0] = var20; + this.vertices[1] = var11; + this.vertices[2] = var12; + this.vertices[3] = var18; + this.vertices[4] = var13; + this.vertices[5] = var15; + this.vertices[6] = var21; + this.vertices[7] = var14; + this.quads[0] = new TexturedQuad(new Vertex[]{var15, var11, var12, var21}, this.u + var6 + var4, this.v + var6, this.u + var6 + var4 + var6, this.v + var6 + var5); + this.quads[1] = new TexturedQuad(new Vertex[]{var20, var13, var14, var18}, this.u, this.v + var6, this.u + var6, this.v + var6 + var5); + this.quads[2] = new TexturedQuad(new Vertex[]{var15, var13, var20, var11}, this.u + var6, this.v, this.u + var6 + var4, this.v + var6); + this.quads[3] = new TexturedQuad(new Vertex[]{var12, var18, var14, var21}, this.u + var6 + var4, this.v, this.u + var6 + var4 + var4, this.v + var6); + this.quads[4] = new TexturedQuad(new Vertex[]{var11, var20, var18, var12}, this.u + var6, this.v + var6, this.u + var6 + var4, this.v + var6 + var5); + this.quads[5] = new TexturedQuad(new Vertex[]{var13, var15, var21, var14}, this.u + var6 + var4 + var6, this.v + var6, this.u + var6 + var4 + var6 + var4, this.v + var6 + var5); + if(this.mirror) { + for(int var16 = 0; var16 < this.quads.length; ++var16) { + TexturedQuad var17; + Vertex[] var19 = new Vertex[(var17 = this.quads[var16]).vertices.length]; + + for(var4 = 0; var4 < var17.vertices.length; ++var4) { + var19[var4] = var17.vertices[var17.vertices.length - var4 - 1]; + } + + var17.vertices = var19; + } + } + + } + + public final void setPosition(float var1, float var2, float var3) { + this.x = var1; + this.y = var2; + this.z = var3; + } + + public final void render(float var1) { + if(this.render) { + if(!this.hasList) { + this.generateList(var1); + } + + if(this.pitch == 0.0F && this.yaw == 0.0F && this.roll == 0.0F) { + if(this.x == 0.0F && this.y == 0.0F && this.z == 0.0F) { + GL11.glCallList(this.list); + } else { + GL11.glTranslatef(this.x * var1, this.y * var1, this.z * var1); + GL11.glCallList(this.list); + GL11.glTranslatef(-this.x * var1, -this.y * var1, -this.z * var1); + } + } else { + GL11.glPushMatrix(); + GL11.glTranslatef(this.x * var1, this.y * var1, this.z * var1); + if(this.roll != 0.0F) { + GL11.glRotatef(this.roll * 57.295776F, 0.0F, 0.0F, 1.0F); + } + + if(this.yaw != 0.0F) { + GL11.glRotatef(this.yaw * 57.295776F, 0.0F, 1.0F, 0.0F); + } + + if(this.pitch != 0.0F) { + GL11.glRotatef(this.pitch * 57.295776F, 1.0F, 0.0F, 0.0F); + } + + GL11.glCallList(this.list); + GL11.glPopMatrix(); + } + } + } + + public void generateList(float var1) { + this.list = GL11.glGenLists(1); + GL11.glNewList(this.list, 4864); + GL11.glBegin(7); + + for(int var2 = 0; var2 < this.quads.length; ++var2) { + TexturedQuad var10000 = this.quads[var2]; + float var3 = var1; + TexturedQuad var4 = var10000; + Vec3D var5 = var10000.vertices[1].vector.subtract(var4.vertices[0].vector).normalize(); + Vec3D var6 = var4.vertices[1].vector.subtract(var4.vertices[2].vector).normalize(); + GL11.glNormal3f((var5 = (new Vec3D(var5.y * var6.z - var5.z * var6.y, var5.z * var6.x - var5.x * var6.z, var5.x * var6.y - var5.y * var6.x)).normalize()).x, var5.y, var5.z); + + for(int var7 = 0; var7 < 4; ++var7) { + Vertex var8; + GL11.glTexCoord2f((var8 = var4.vertices[var7]).u, var8.v); + GL11.glVertex3f(var8.vector.x * var3, var8.vector.y * var3, var8.vector.z * var3); + } + } + + GL11.glEnd(); + GL11.glEndList(); + this.hasList = true; + } +} diff --git a/src/main/java/com/mojang/minecraft/model/PigModel.java b/src/main/java/com/mojang/minecraft/model/PigModel.java new file mode 100644 index 0000000..64fe27c --- /dev/null +++ b/src/main/java/com/mojang/minecraft/model/PigModel.java @@ -0,0 +1,10 @@ +package com.mojang.minecraft.model; + +import com.mojang.minecraft.model.AnimalModel; + +public final class PigModel extends AnimalModel { + + public PigModel() { + super(6, 0.0F); + } +} diff --git a/src/main/java/com/mojang/minecraft/model/SheepFurModel.java b/src/main/java/com/mojang/minecraft/model/SheepFurModel.java new file mode 100644 index 0000000..9eab032 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/model/SheepFurModel.java @@ -0,0 +1,30 @@ +package com.mojang.minecraft.model; + +import com.mojang.minecraft.model.AnimalModel; +import com.mojang.minecraft.model.ModelPart; + +public final class SheepFurModel extends AnimalModel { + + public SheepFurModel() { + super(12, 0.0F); + this.head = new ModelPart(0, 0); + this.head.setBounds(-3.0F, -4.0F, -4.0F, 6, 6, 6, 0.6F); + this.head.setPosition(0.0F, 6.0F, -8.0F); + this.body = new ModelPart(28, 8); + this.body.setBounds(-4.0F, -10.0F, -7.0F, 8, 16, 6, 1.75F); + this.body.setPosition(0.0F, 5.0F, 2.0F); + float var1 = 0.5F; + this.leg1 = new ModelPart(0, 16); + this.leg1.setBounds(-2.0F, 0.0F, -2.0F, 4, 6, 4, var1); + this.leg1.setPosition(-3.0F, 12.0F, 7.0F); + this.leg2 = new ModelPart(0, 16); + this.leg2.setBounds(-2.0F, 0.0F, -2.0F, 4, 6, 4, var1); + this.leg2.setPosition(3.0F, 12.0F, 7.0F); + this.leg3 = new ModelPart(0, 16); + this.leg3.setBounds(-2.0F, 0.0F, -2.0F, 4, 6, 4, var1); + this.leg3.setPosition(-3.0F, 12.0F, -5.0F); + this.leg4 = new ModelPart(0, 16); + this.leg4.setBounds(-2.0F, 0.0F, -2.0F, 4, 6, 4, var1); + this.leg4.setPosition(3.0F, 12.0F, -5.0F); + } +} diff --git a/src/main/java/com/mojang/minecraft/model/SheepModel.java b/src/main/java/com/mojang/minecraft/model/SheepModel.java new file mode 100644 index 0000000..2b3fcba --- /dev/null +++ b/src/main/java/com/mojang/minecraft/model/SheepModel.java @@ -0,0 +1,17 @@ +package com.mojang.minecraft.model; + +import com.mojang.minecraft.model.AnimalModel; +import com.mojang.minecraft.model.ModelPart; + +public final class SheepModel extends AnimalModel { + + public SheepModel() { + super(12, 0.0F); + this.head = new ModelPart(0, 0); + this.head.setBounds(-3.0F, -4.0F, -6.0F, 6, 6, 8, 0.0F); + this.head.setPosition(0.0F, 6.0F, -8.0F); + this.body = new ModelPart(28, 8); + this.body.setBounds(-4.0F, -10.0F, -7.0F, 8, 16, 6, 0.0F); + this.body.setPosition(0.0F, 5.0F, 2.0F); + } +} diff --git a/src/main/java/com/mojang/minecraft/model/SkeletonModel.java b/src/main/java/com/mojang/minecraft/model/SkeletonModel.java new file mode 100644 index 0000000..c084563 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/model/SkeletonModel.java @@ -0,0 +1,24 @@ +package com.mojang.minecraft.model; + +import com.mojang.minecraft.model.ModelPart; +import com.mojang.minecraft.model.ZombieModel; + +public final class SkeletonModel extends ZombieModel { + + public SkeletonModel() { + this.rightArm = new ModelPart(40, 16); + this.rightArm.setBounds(-1.0F, -2.0F, -1.0F, 2, 12, 2, 0.0F); + this.rightArm.setPosition(-5.0F, 2.0F, 0.0F); + this.leftArm = new ModelPart(40, 16); + this.leftArm.mirror = true; + this.leftArm.setBounds(-1.0F, -2.0F, -1.0F, 2, 12, 2, 0.0F); + this.leftArm.setPosition(5.0F, 2.0F, 0.0F); + this.rightLeg = new ModelPart(0, 16); + this.rightLeg.setBounds(-1.0F, 0.0F, -1.0F, 2, 12, 2, 0.0F); + this.rightLeg.setPosition(-2.0F, 12.0F, 0.0F); + this.leftLeg = new ModelPart(0, 16); + this.leftLeg.mirror = true; + this.leftLeg.setBounds(-1.0F, 0.0F, -1.0F, 2, 12, 2, 0.0F); + this.leftLeg.setPosition(2.0F, 12.0F, 0.0F); + } +} diff --git a/src/main/java/com/mojang/minecraft/model/SpiderModel.java b/src/main/java/com/mojang/minecraft/model/SpiderModel.java new file mode 100644 index 0000000..0c065b0 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/model/SpiderModel.java @@ -0,0 +1,113 @@ +package com.mojang.minecraft.model; + +import com.mojang.minecraft.model.Model; +import com.mojang.minecraft.model.ModelPart; +import com.mojang.util.MathHelper; + +public final class SpiderModel extends Model { + + private ModelPart head = new ModelPart(32, 4); + private ModelPart neck; + private ModelPart body; + private ModelPart leg1; + private ModelPart leg2; + private ModelPart leg3; + private ModelPart leg4; + private ModelPart leg5; + private ModelPart leg6; + private ModelPart leg7; + private ModelPart leg8; + + + public SpiderModel() { + this.head.setBounds(-4.0F, -4.0F, -8.0F, 8, 8, 8, 0.0F); + this.head.setPosition(0.0F, 0.0F, -3.0F); + this.neck = new ModelPart(0, 0); + this.neck.setBounds(-3.0F, -3.0F, -3.0F, 6, 6, 6, 0.0F); + this.body = new ModelPart(0, 12); + this.body.setBounds(-5.0F, -4.0F, -6.0F, 10, 8, 12, 0.0F); + this.body.setPosition(0.0F, 0.0F, 9.0F); + this.leg1 = new ModelPart(18, 0); + this.leg1.setBounds(-15.0F, -1.0F, -1.0F, 16, 2, 2, 0.0F); + this.leg1.setPosition(-4.0F, 0.0F, 2.0F); + this.leg2 = new ModelPart(18, 0); + this.leg2.setBounds(-1.0F, -1.0F, -1.0F, 16, 2, 2, 0.0F); + this.leg2.setPosition(4.0F, 0.0F, 2.0F); + this.leg3 = new ModelPart(18, 0); + this.leg3.setBounds(-15.0F, -1.0F, -1.0F, 16, 2, 2, 0.0F); + this.leg3.setPosition(-4.0F, 0.0F, 1.0F); + this.leg4 = new ModelPart(18, 0); + this.leg4.setBounds(-1.0F, -1.0F, -1.0F, 16, 2, 2, 0.0F); + this.leg4.setPosition(4.0F, 0.0F, 1.0F); + this.leg5 = new ModelPart(18, 0); + this.leg5.setBounds(-15.0F, -1.0F, -1.0F, 16, 2, 2, 0.0F); + this.leg5.setPosition(-4.0F, 0.0F, 0.0F); + this.leg6 = new ModelPart(18, 0); + this.leg6.setBounds(-1.0F, -1.0F, -1.0F, 16, 2, 2, 0.0F); + this.leg6.setPosition(4.0F, 0.0F, 0.0F); + this.leg7 = new ModelPart(18, 0); + this.leg7.setBounds(-15.0F, -1.0F, -1.0F, 16, 2, 2, 0.0F); + this.leg7.setPosition(-4.0F, 0.0F, -1.0F); + this.leg8 = new ModelPart(18, 0); + this.leg8.setBounds(-1.0F, -1.0F, -1.0F, 16, 2, 2, 0.0F); + this.leg8.setPosition(4.0F, 0.0F, -1.0F); + } + + public final void render(float var1, float var2, float var3, float var4, float var5, float var6) { + this.head.yaw = var4 / 57.295776F; + this.head.pitch = var5 / 57.295776F; + var4 = 0.7853982F; + this.leg1.roll = -var4; + this.leg2.roll = var4; + this.leg3.roll = -var4 * 0.74F; + this.leg4.roll = var4 * 0.74F; + this.leg5.roll = -var4 * 0.74F; + this.leg6.roll = var4 * 0.74F; + this.leg7.roll = -var4; + this.leg8.roll = var4; + var4 = 0.3926991F; + this.leg1.yaw = var4 * 2.0F; + this.leg2.yaw = -var4 * 2.0F; + this.leg3.yaw = var4; + this.leg4.yaw = -var4; + this.leg5.yaw = -var4; + this.leg6.yaw = var4; + this.leg7.yaw = -var4 * 2.0F; + this.leg8.yaw = var4 * 2.0F; + var4 = -(MathHelper.cos(var1 * 0.6662F * 2.0F) * 0.4F) * var2; + var5 = -(MathHelper.cos(var1 * 0.6662F * 2.0F + 3.1415927F) * 0.4F) * var2; + float var7 = -(MathHelper.cos(var1 * 0.6662F * 2.0F + 1.5707964F) * 0.4F) * var2; + float var8 = -(MathHelper.cos(var1 * 0.6662F * 2.0F + 4.712389F) * 0.4F) * var2; + float var9 = Math.abs(MathHelper.sin(var1 * 0.6662F) * 0.4F) * var2; + float var10 = Math.abs(MathHelper.sin(var1 * 0.6662F + 3.1415927F) * 0.4F) * var2; + float var11 = Math.abs(MathHelper.sin(var1 * 0.6662F + 1.5707964F) * 0.4F) * var2; + var2 = Math.abs(MathHelper.sin(var1 * 0.6662F + 4.712389F) * 0.4F) * var2; + this.leg1.yaw += var4; + this.leg2.yaw -= var4; + this.leg3.yaw += var5; + this.leg4.yaw -= var5; + this.leg5.yaw += var7; + this.leg6.yaw -= var7; + this.leg7.yaw += var8; + this.leg8.yaw -= var8; + this.leg1.roll += var9; + this.leg2.roll -= var9; + this.leg3.roll += var10; + this.leg4.roll -= var10; + this.leg5.roll += var11; + this.leg6.roll -= var11; + this.leg7.roll += var2; + this.leg8.roll -= var2; + this.head.render(var6); + this.neck.render(var6); + this.body.render(var6); + this.leg1.render(var6); + this.leg2.render(var6); + this.leg3.render(var6); + this.leg4.render(var6); + this.leg5.render(var6); + this.leg6.render(var6); + this.leg7.render(var6); + this.leg8.render(var6); + } +} diff --git a/src/main/java/com/mojang/minecraft/model/TexturedQuad.java b/src/main/java/com/mojang/minecraft/model/TexturedQuad.java new file mode 100644 index 0000000..3a680a7 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/model/TexturedQuad.java @@ -0,0 +1,31 @@ +package com.mojang.minecraft.model; + +import com.mojang.minecraft.model.Vertex; + +public final class TexturedQuad { + + public Vertex[] vertices; + + + private TexturedQuad(Vertex[] var1) { + this.vertices = var1; + } + + public TexturedQuad(Vertex[] var1, int var2, int var3, int var4, int var5) { + this(var1); + float var7 = 0.0015625F; + float var6 = 0.003125F; + var1[0] = var1[0].create((float)var4 / 64.0F - var7, (float)var3 / 32.0F + var6); + var1[1] = var1[1].create((float)var2 / 64.0F + var7, (float)var3 / 32.0F + var6); + var1[2] = var1[2].create((float)var2 / 64.0F + var7, (float)var5 / 32.0F - var6); + var1[3] = var1[3].create((float)var4 / 64.0F - var7, (float)var5 / 32.0F - var6); + } + + public TexturedQuad(Vertex[] var1, float var2, float var3, float var4, float var5) { + this(var1); + var1[0] = var1[0].create(var4, var3); + var1[1] = var1[1].create(var2, var3); + var1[2] = var1[2].create(var2, var5); + var1[3] = var1[3].create(var4, var5); + } +} diff --git a/src/main/java/com/mojang/minecraft/model/Vec3D.java b/src/main/java/com/mojang/minecraft/model/Vec3D.java new file mode 100644 index 0000000..cff068c --- /dev/null +++ b/src/main/java/com/mojang/minecraft/model/Vec3D.java @@ -0,0 +1,69 @@ +package com.mojang.minecraft.model; + +import com.mojang.util.MathHelper; + +public final class Vec3D { + + public float x; + public float y; + public float z; + + + public Vec3D(float var1, float var2, float var3) { + this.x = var1; + this.y = var2; + this.z = var3; + } + + public final Vec3D subtract(Vec3D var1) { + return new Vec3D(this.x - var1.x, this.y - var1.y, this.z - var1.z); + } + + public final Vec3D normalize() { + float var1 = MathHelper.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); + return new Vec3D(this.x / var1, this.y / var1, this.z / var1); + } + + public final Vec3D add(float var1, float var2, float var3) { + return new Vec3D(this.x + var1, this.y + var2, this.z + var3); + } + + public final float distance(Vec3D var1) { + float var2 = var1.x - this.x; + float var3 = var1.y - this.y; + float var4 = var1.z - this.z; + return MathHelper.sqrt(var2 * var2 + var3 * var3 + var4 * var4); + } + + public final float distanceSquared(Vec3D var1) { + float var2 = var1.x - this.x; + float var3 = var1.y - this.y; + float var4 = var1.z - this.z; + return var2 * var2 + var3 * var3 + var4 * var4; + } + + public final Vec3D getXIntersection(Vec3D var1, float var2) { + float var3 = var1.x - this.x; + float var4 = var1.y - this.y; + float var5 = var1.z - this.z; + return var3 * var3 < 1.0E-7F?null:((var2 = (var2 - this.x) / var3) >= 0.0F && var2 <= 1.0F?new Vec3D(this.x + var3 * var2, this.y + var4 * var2, this.z + var5 * var2):null); + } + + public final Vec3D getYIntersection(Vec3D var1, float var2) { + float var3 = var1.x - this.x; + float var4 = var1.y - this.y; + float var5 = var1.z - this.z; + return var4 * var4 < 1.0E-7F?null:((var2 = (var2 - this.y) / var4) >= 0.0F && var2 <= 1.0F?new Vec3D(this.x + var3 * var2, this.y + var4 * var2, this.z + var5 * var2):null); + } + + public final Vec3D getZIntersection(Vec3D var1, float var2) { + float var3 = var1.x - this.x; + float var4 = var1.y - this.y; + float var5; + return (var5 = var1.z - this.z) * var5 < 1.0E-7F?null:((var2 = (var2 - this.z) / var5) >= 0.0F && var2 <= 1.0F?new Vec3D(this.x + var3 * var2, this.y + var4 * var2, this.z + var5 * var2):null); + } + + public final String toString() { + return "(" + this.x + ", " + this.y + ", " + this.z + ")"; + } +} diff --git a/src/main/java/com/mojang/minecraft/model/Vertex.java b/src/main/java/com/mojang/minecraft/model/Vertex.java new file mode 100644 index 0000000..1e62351 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/model/Vertex.java @@ -0,0 +1,31 @@ +package com.mojang.minecraft.model; + +import com.mojang.minecraft.model.Vec3D; + +public final class Vertex { + + public Vec3D vector; + public float u; + public float v; + + + public Vertex(float var1, float var2, float var3, float var4, float var5) { + this(new Vec3D(var1, var2, var3), var4, var5); + } + + public final Vertex create(float var1, float var2) { + return new Vertex(this, var1, var2); + } + + private Vertex(Vertex var1, float var2, float var3) { + this.vector = var1.vector; + this.u = var2; + this.v = var3; + } + + private Vertex(Vec3D var1, float var2, float var3) { + this.vector = var1; + this.u = var2; + this.v = var3; + } +} diff --git a/src/main/java/com/mojang/minecraft/model/ZombieModel.java b/src/main/java/com/mojang/minecraft/model/ZombieModel.java new file mode 100644 index 0000000..c5e6f23 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/model/ZombieModel.java @@ -0,0 +1,25 @@ +package com.mojang.minecraft.model; + +import com.mojang.minecraft.model.HumanoidModel; +import com.mojang.util.MathHelper; + +public class ZombieModel extends HumanoidModel { + + public final void setRotationAngles(float var1, float var2, float var3, float var4, float var5, float var6) { + super.setRotationAngles(var1, var2, var3, var4, var5, var6); + var1 = MathHelper.sin(this.attackOffset * 3.1415927F); + var2 = MathHelper.sin((1.0F - (1.0F - this.attackOffset) * (1.0F - this.attackOffset)) * 3.1415927F); + this.rightArm.roll = 0.0F; + this.leftArm.roll = 0.0F; + this.rightArm.yaw = -(0.1F - var1 * 0.6F); + this.leftArm.yaw = 0.1F - var1 * 0.6F; + this.rightArm.pitch = -1.5707964F; + this.leftArm.pitch = -1.5707964F; + this.rightArm.pitch -= var1 * 1.2F - var2 * 0.4F; + this.leftArm.pitch -= var1 * 1.2F - var2 * 0.4F; + this.rightArm.roll += MathHelper.cos(var3 * 0.09F) * 0.05F + 0.05F; + this.leftArm.roll -= MathHelper.cos(var3 * 0.09F) * 0.05F + 0.05F; + this.rightArm.pitch += MathHelper.sin(var3 * 0.067F) * 0.05F; + this.leftArm.pitch -= MathHelper.sin(var3 * 0.067F) * 0.05F; + } +} diff --git a/src/main/java/com/mojang/minecraft/net/NetworkManager.java b/src/main/java/com/mojang/minecraft/net/NetworkManager.java new file mode 100644 index 0000000..866878b --- /dev/null +++ b/src/main/java/com/mojang/minecraft/net/NetworkManager.java @@ -0,0 +1,74 @@ +package com.mojang.minecraft.net; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.gui.ErrorScreen; +import com.mojang.net.NetworkHandler; +import java.io.ByteArrayOutputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; + +public class NetworkManager +{ + public NetworkManager(Minecraft minecraft, String server, int port, String username, String key) + { + minecraft.online = true; + + this.minecraft = minecraft; + + players = new HashMap(); + + new ServerConnectThread(this, server, port, username, key, minecraft).start(); + } + + public ByteArrayOutputStream levelData; + + public NetworkHandler netHandler; + + public Minecraft minecraft; + + public boolean successful = false; + public boolean levelLoaded = false; + + public HashMap players; + + public void sendBlockChange(int x, int y, int z, int mode, int block) + { + netHandler.send(PacketType.PLAYER_SET_BLOCK, new Object[] {x, y, z, mode, block}); + } + + public void error(Exception e) + { + netHandler.close(); + + ErrorScreen errorScreen = new ErrorScreen("Disconnected!", e.getMessage()); + + minecraft.setCurrentScreen(errorScreen); + + e.printStackTrace(); + } + + public boolean isConnected() + { + return netHandler != null && netHandler.connected; + } + + public List getPlayers() + { + ArrayList list = new ArrayList(); + + list.add(minecraft.session.username); + + Iterator playerIterator = this.players.values().iterator(); + + while(playerIterator.hasNext()) + { + NetworkPlayer networkPlayer = (NetworkPlayer)playerIterator.next(); + + list.add(networkPlayer.name); + } + + return list; + } +} diff --git a/src/main/java/com/mojang/minecraft/net/NetworkPlayer.java b/src/main/java/com/mojang/minecraft/net/NetworkPlayer.java new file mode 100644 index 0000000..b8c0045 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/net/NetworkPlayer.java @@ -0,0 +1,235 @@ +package com.mojang.minecraft.net; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.gui.FontRenderer; +import com.mojang.minecraft.mob.HumanoidMob; +import com.mojang.minecraft.net.PositionUpdate; +import com.mojang.minecraft.net.SkinDownloadThread; +import com.mojang.minecraft.render.TextureManager; +import java.awt.image.BufferedImage; +import java.util.LinkedList; +import java.util.List; +import org.lwjgl.opengl.GL11; + +public class NetworkPlayer extends HumanoidMob { + + public static final long serialVersionUID = 77479605454997290L; + private List moveQueue = new LinkedList(); + private Minecraft minecraft; + private int xp; + private int yp; + private int zp; + private transient int a = -1; + public transient BufferedImage newTexture = null; + public String name; + public String displayName; + int tickCount = 0; + private TextureManager textures; + + + public NetworkPlayer(Minecraft var1, int var2, String var3, int var4, int var5, int var6, float var7, float var8) { + super(var1.level, (float)var4, (float)var5, (float)var6); + this.minecraft = var1; + this.displayName = var3; + var3 = FontRenderer.stripColor(var3); + this.name = var3; + this.xp = var4; + this.yp = var5; + this.zp = var6; + this.heightOffset = 0.0F; + this.pushthrough = 0.8F; + this.setPos((float)var4 / 32.0F, (float)var5 / 32.0F, (float)var6 / 32.0F); + this.xRot = var8; + this.yRot = var7; + this.armor = this.helmet = false; + this.renderOffset = 0.6875F; + (new SkinDownloadThread(this)).start(); + this.allowAlpha = false; + } + + public void aiStep() { + int var1 = 5; + + do { + if(this.moveQueue.size() > 0) { + this.setPos((PositionUpdate)this.moveQueue.remove(0)); + } + } while(var1-- > 0 && this.moveQueue.size() > 10); + + this.onGround = true; + } + + public void bindTexture(TextureManager var1) { + this.textures = var1; + if(this.newTexture != null) { + BufferedImage var2 = this.newTexture; + int[] var3 = new int[512]; + var2.getRGB(32, 0, 32, 16, var3, 0, 32); + int var5 = 0; + + boolean var10001; + while(true) { + if(var5 >= var3.length) { + var10001 = false; + break; + } + + if(var3[var5] >>> 24 < 128) { + var10001 = true; + break; + } + + ++var5; + } + + this.hasHair = var10001; + this.a = var1.load(this.newTexture); + this.newTexture = null; + } + + if(this.a < 0) { + GL11.glBindTexture(3553, var1.load("/char.png")); + } else { + GL11.glBindTexture(3553, this.a); + } + } + + public void renderHover(TextureManager var1, float var2) { + FontRenderer var3 = this.minecraft.fontRenderer; + GL11.glPushMatrix(); + GL11.glTranslatef(this.xo + (this.x - this.xo) * var2, this.yo + (this.y - this.yo) * var2 + 0.8F + this.renderOffset, this.zo + (this.z - this.zo) * var2); + GL11.glRotatef(-this.minecraft.player.yRot, 0.0F, 1.0F, 0.0F); + var2 = 0.05F; + GL11.glScalef(0.05F, -var2, var2); + GL11.glTranslatef((float)(-var3.getWidth(this.displayName)) / 2.0F, 0.0F, 0.0F); + GL11.glNormal3f(1.0F, -1.0F, 1.0F); + GL11.glDisable(2896); + GL11.glDisable(16384); + if(this.name.equalsIgnoreCase("Notch")) { + var3.renderNoShadow(this.displayName, 0, 0, 16776960); + } else { + var3.renderNoShadow(this.displayName, 0, 0, 16777215); + } + + GL11.glDepthFunc(516); + GL11.glDepthMask(false); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.8F); + GL11.glEnable(3042); + GL11.glBlendFunc(770, 771); + var3.renderNoShadow(this.displayName, 0, 0, 16777215); + GL11.glDisable(3042); + GL11.glDepthMask(true); + GL11.glDepthFunc(515); + GL11.glTranslatef(1.0F, 1.0F, -0.05F); + var3.renderNoShadow(this.name, 0, 0, 5263440); + GL11.glEnable(16384); + GL11.glEnable(2896); + GL11.glPopMatrix(); + } + + public void queue(byte var1, byte var2, byte var3, float var4, float var5) { + float var6 = var4 - this.yRot; + + float var7; + for(var7 = var5 - this.xRot; var6 >= 180.0F; var6 -= 360.0F) { + ; + } + + while(var6 < -180.0F) { + var6 += 360.0F; + } + + while(var7 >= 180.0F) { + var7 -= 360.0F; + } + + while(var7 < -180.0F) { + var7 += 360.0F; + } + + var6 = this.yRot + var6 * 0.5F; + var7 = this.xRot + var7 * 0.5F; + this.moveQueue.add(new PositionUpdate(((float)this.xp + (float)var1 / 2.0F) / 32.0F, ((float)this.yp + (float)var2 / 2.0F) / 32.0F, ((float)this.zp + (float)var3 / 2.0F) / 32.0F, var6, var7)); + this.xp += var1; + this.yp += var2; + this.zp += var3; + this.moveQueue.add(new PositionUpdate((float)this.xp / 32.0F, (float)this.yp / 32.0F, (float)this.zp / 32.0F, var4, var5)); + } + + public void teleport(short var1, short var2, short var3, float var4, float var5) { + float var6 = var4 - this.yRot; + + float var7; + for(var7 = var5 - this.xRot; var6 >= 180.0F; var6 -= 360.0F) { + ; + } + + while(var6 < -180.0F) { + var6 += 360.0F; + } + + while(var7 >= 180.0F) { + var7 -= 360.0F; + } + + while(var7 < -180.0F) { + var7 += 360.0F; + } + + var6 = this.yRot + var6 * 0.5F; + var7 = this.xRot + var7 * 0.5F; + this.moveQueue.add(new PositionUpdate((float)(this.xp + var1) / 64.0F, (float)(this.yp + var2) / 64.0F, (float)(this.zp + var3) / 64.0F, var6, var7)); + this.xp = var1; + this.yp = var2; + this.zp = var3; + this.moveQueue.add(new PositionUpdate((float)this.xp / 32.0F, (float)this.yp / 32.0F, (float)this.zp / 32.0F, var4, var5)); + } + + public void queue(byte var1, byte var2, byte var3) { + this.moveQueue.add(new PositionUpdate(((float)this.xp + (float)var1 / 2.0F) / 32.0F, ((float)this.yp + (float)var2 / 2.0F) / 32.0F, ((float)this.zp + (float)var3 / 2.0F) / 32.0F)); + this.xp += var1; + this.yp += var2; + this.zp += var3; + this.moveQueue.add(new PositionUpdate((float)this.xp / 32.0F, (float)this.yp / 32.0F, (float)this.zp / 32.0F)); + } + + public void queue(float var1, float var2) { + float var3 = var1 - this.yRot; + + float var4; + for(var4 = var2 - this.xRot; var3 >= 180.0F; var3 -= 360.0F) { + ; + } + + while(var3 < -180.0F) { + var3 += 360.0F; + } + + while(var4 >= 180.0F) { + var4 -= 360.0F; + } + + while(var4 < -180.0F) { + var4 += 360.0F; + } + + var3 = this.yRot + var3 * 0.5F; + var4 = this.xRot + var4 * 0.5F; + this.moveQueue.add(new PositionUpdate(var3, var4)); + this.moveQueue.add(new PositionUpdate(var1, var2)); + } + + public void clear() { + if(this.a >= 0 && this.textures != null) { + TextureManager var10000 = this.textures; + int var1 = this.a; + TextureManager var2 = this.textures; + var10000.textureImages.remove(Integer.valueOf(var1)); + var2.idBuffer.clear(); + var2.idBuffer.put(var1); + var2.idBuffer.flip(); + GL11.glDeleteTextures(var2.idBuffer.get()); + } + + } +} diff --git a/src/main/java/com/mojang/minecraft/net/PacketType.java b/src/main/java/com/mojang/minecraft/net/PacketType.java new file mode 100644 index 0000000..9d3ca6f --- /dev/null +++ b/src/main/java/com/mojang/minecraft/net/PacketType.java @@ -0,0 +1,86 @@ +package com.mojang.minecraft.net; + +public class PacketType +{ + private PacketType(Class ... classes) + { + opcode = (byte)(nextOpcode++); + packets[opcode] = this; + params = new Class[classes.length]; + + int length = 0; + + for(int classNumber = 0; classNumber < classes.length; classNumber++) + { + Class class_ = classes[classNumber]; + + params[classNumber] = class_; + + if(class_ == Long.TYPE) + { + length += 8; + } else if(class_ == Integer.TYPE) { + length += 4; + } else if(class_ == Short.TYPE) { + length += 2; + } else if(class_ == Byte.TYPE) { + ++length; + } else if(class_ == Float.TYPE) { + length += 4; + } else if(class_ == Double.TYPE) { + length += 8; + } else if(class_ == byte[].class) { + length += 1024; + } else if(class_ == String.class) { + length += 64; + } + } + + this.length = length; + } + + public static final PacketType[] packets = new PacketType[256]; + + public static final PacketType IDENTIFICATION = new PacketType(new Class[] {Byte.TYPE, String.class, String.class, Byte.TYPE}); + public static final PacketType LEVEL_INIT; + public static final PacketType LEVEL_DATA; + public static final PacketType LEVEL_FINALIZE; + public static final PacketType PLAYER_SET_BLOCK; + public static final PacketType BLOCK_CHANGE; + public static final PacketType SPAWN_PLAYER; + public static final PacketType POSITION_ROTATION; + public static final PacketType POSITION_ROTATION_UPDATE; + public static final PacketType POSITION_UPDATE; + public static final PacketType ROTATION_UPDATE; + public static final PacketType DESPAWN_PLAYER; + public static final PacketType CHAT_MESSAGE; + public static final PacketType DISCONNECT; + public static final PacketType UPDATE_PLAYER_TYPE; + + public int length; + private static int nextOpcode; + public byte opcode; + public Class[] params; + + static + { + new PacketType(new Class[0]); + + LEVEL_INIT = new PacketType(new Class[0]); + LEVEL_DATA = new PacketType(new Class[] {Short.TYPE, byte[].class, Byte.TYPE}); + LEVEL_FINALIZE = new PacketType(new Class[] {Short.TYPE, Short.TYPE, Short.TYPE}); + PLAYER_SET_BLOCK = new PacketType(new Class[] {Short.TYPE, Short.TYPE, Short.TYPE, Byte.TYPE, Byte.TYPE}); + BLOCK_CHANGE = new PacketType(new Class[] {Short.TYPE, Short.TYPE, Short.TYPE, Byte.TYPE}); + SPAWN_PLAYER = new PacketType(new Class[] {Byte.TYPE, String.class, Short.TYPE, Short.TYPE, Short.TYPE, Byte.TYPE, Byte.TYPE}); + POSITION_ROTATION = new PacketType(new Class[] {Byte.TYPE, Short.TYPE, Short.TYPE, Short.TYPE, Byte.TYPE, Byte.TYPE}); + POSITION_ROTATION_UPDATE = new PacketType(new Class[] {Byte.TYPE, Byte.TYPE, Byte.TYPE, Byte.TYPE, Byte.TYPE, Byte.TYPE}); + POSITION_UPDATE = new PacketType(new Class[] {Byte.TYPE, Byte.TYPE, Byte.TYPE, Byte.TYPE}); + ROTATION_UPDATE = new PacketType(new Class[] {Byte.TYPE, Byte.TYPE, Byte.TYPE}); + DESPAWN_PLAYER = new PacketType(new Class[] {Byte.TYPE}); + CHAT_MESSAGE = new PacketType(new Class[] {Byte.TYPE, String.class}); + DISCONNECT = new PacketType(new Class[] {String.class}); + UPDATE_PLAYER_TYPE = new PacketType(new Class[] {Byte.TYPE}); + + nextOpcode = 0; + } +} diff --git a/src/main/java/com/mojang/minecraft/net/PositionUpdate.java b/src/main/java/com/mojang/minecraft/net/PositionUpdate.java new file mode 100644 index 0000000..f6dd543 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/net/PositionUpdate.java @@ -0,0 +1,45 @@ +package com.mojang.minecraft.net; + +public class PositionUpdate +{ + public PositionUpdate(float x, float y, float z, float yaw, float pitch) + { + this.x = x; + this.y = y; + this.z = z; + this.yaw = yaw; + this.pitch = pitch; + + rotation = true; + position = true; + } + + public PositionUpdate(float x, float y, float z) + { + this.x = x; + this.y = y; + this.z = z; + + position = true; + rotation = false; + } + + public PositionUpdate(float yaw, float pitch) + { + this.yaw = yaw; + this.pitch = pitch; + + rotation = true; + position = false; + } + + public float x; + public float y; + public float z; + + public float yaw; + public float pitch; + + public boolean rotation = false; + public boolean position = false; +} diff --git a/src/main/java/com/mojang/minecraft/net/ServerConnectThread.java b/src/main/java/com/mojang/minecraft/net/ServerConnectThread.java new file mode 100644 index 0000000..e102efb --- /dev/null +++ b/src/main/java/com/mojang/minecraft/net/ServerConnectThread.java @@ -0,0 +1,53 @@ +package com.mojang.minecraft.net; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.gui.ErrorScreen; +import com.mojang.net.NetworkHandler; + +public class ServerConnectThread extends Thread +{ + public ServerConnectThread(NetworkManager networkManager, String server, int port, String username, String key, Minecraft minecraft) { + super(); + + netManager = networkManager; + + this.server = server; + this.port = port; + + this.username = username; + this.key = key; + + this.minecraft = minecraft; + } + + @Override + public void run() + { + try { + netManager.netHandler = new NetworkHandler(server, port); + netManager.netHandler.netManager = netManager; + + netManager.netHandler.send(PacketType.IDENTIFICATION, new Object[]{Byte.valueOf((byte)7), this.username, this.key, Integer.valueOf(0)}); + + netManager.successful = true; + } catch (Exception var3) { + minecraft.online = false; + + minecraft.networkManager = null; + + minecraft.setCurrentScreen(new ErrorScreen("Failed to connect", "You failed to connect to the server. It\'s probably down!")); + + netManager.successful = false; + } + } + + private String server; + private int port; + + private String username; + private String key; + + private Minecraft minecraft; + + private NetworkManager netManager; +} diff --git a/src/main/java/com/mojang/minecraft/net/SkinDownloadThread.java b/src/main/java/com/mojang/minecraft/net/SkinDownloadThread.java new file mode 100644 index 0000000..e8a4098 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/net/SkinDownloadThread.java @@ -0,0 +1,46 @@ +package com.mojang.minecraft.net; + +import java.net.HttpURLConnection; +import java.net.URL; +import javax.imageio.ImageIO; + +public class SkinDownloadThread extends Thread +{ + public SkinDownloadThread(NetworkPlayer networkPlayer) + { + super(); + + this.player = networkPlayer; + } + + @Override + public void run() + { + HttpURLConnection connection = null; + + try { + connection = (HttpURLConnection)new URL("http://www.minecraft.net/skin/" + player.name + ".png").openConnection(); + + connection.setDoInput(true); + connection.setDoOutput(false); + + connection.connect(); + + if(connection.getResponseCode() == 404) + { + return; + } + + player.newTexture = ImageIO.read(connection.getInputStream()); + } catch(Exception e) { + e.printStackTrace(); + } finally { + if(connection != null) + { + connection.disconnect(); + } + } + } + + private NetworkPlayer player; +} diff --git a/src/main/java/com/mojang/minecraft/particle/Particle.java b/src/main/java/com/mojang/minecraft/particle/Particle.java new file mode 100644 index 0000000..d24916c --- /dev/null +++ b/src/main/java/com/mojang/minecraft/particle/Particle.java @@ -0,0 +1,101 @@ +package com.mojang.minecraft.particle; + +import com.mojang.minecraft.Entity; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.render.ShapeRenderer; +import com.mojang.util.MathHelper; + +public class Particle extends Entity { + + private static final long serialVersionUID = 1L; + protected float xd; + protected float yd; + protected float zd; + protected int tex; + protected float uo; + protected float vo; + protected int age = 0; + protected int lifetime = 0; + protected float size; + protected float gravity; + protected float rCol; + protected float gCol; + protected float bCol; + + + public Particle(Level var1, float var2, float var3, float var4, float var5, float var6, float var7) { + super(var1); + this.setSize(0.2F, 0.2F); + this.heightOffset = this.bbHeight / 2.0F; + this.setPos(var2, var3, var4); + this.rCol = this.gCol = this.bCol = 1.0F; + this.xd = var5 + (float)(Math.random() * 2.0D - 1.0D) * 0.4F; + this.yd = var6 + (float)(Math.random() * 2.0D - 1.0D) * 0.4F; + this.zd = var7 + (float)(Math.random() * 2.0D - 1.0D) * 0.4F; + float var8 = (float)(Math.random() + Math.random() + 1.0D) * 0.15F; + var2 = MathHelper.sqrt(this.xd * this.xd + this.yd * this.yd + this.zd * this.zd); + this.xd = this.xd / var2 * var8 * 0.4F; + this.yd = this.yd / var2 * var8 * 0.4F + 0.1F; + this.zd = this.zd / var2 * var8 * 0.4F; + this.uo = (float)Math.random() * 3.0F; + this.vo = (float)Math.random() * 3.0F; + this.size = (float)(Math.random() * 0.5D + 0.5D); + this.lifetime = (int)(4.0D / (Math.random() * 0.9D + 0.1D)); + this.age = 0; + this.makeStepSound = false; + } + + public Particle setPower(float var1) { + this.xd *= var1; + this.yd = (this.yd - 0.1F) * var1 + 0.1F; + this.zd *= var1; + return this; + } + + public Particle scale(float var1) { + this.setSize(0.2F * var1, 0.2F * var1); + this.size *= var1; + return this; + } + + public void tick() { + this.xo = this.x; + this.yo = this.y; + this.zo = this.z; + if(this.age++ >= this.lifetime) { + this.remove(); + } + + this.yd = (float)((double)this.yd - 0.04D * (double)this.gravity); + this.move(this.xd, this.yd, this.zd); + this.xd *= 0.98F; + this.yd *= 0.98F; + this.zd *= 0.98F; + if(this.onGround) { + this.xd *= 0.7F; + this.zd *= 0.7F; + } + + } + + public void render(ShapeRenderer var1, float var2, float var3, float var4, float var5, float var6, float var7) { + float var8; + float var9 = (var8 = (float)(this.tex % 16) / 16.0F) + 0.0624375F; + float var10; + float var11 = (var10 = (float)(this.tex / 16) / 16.0F) + 0.0624375F; + float var12 = 0.1F * this.size; + float var13 = this.xo + (this.x - this.xo) * var2; + float var14 = this.yo + (this.y - this.yo) * var2; + float var15 = this.zo + (this.z - this.zo) * var2; + var2 = this.getBrightness(var2); + var1.color(this.rCol * var2, this.gCol * var2, this.bCol * var2); + var1.vertexUV(var13 - var3 * var12 - var6 * var12, var14 - var4 * var12, var15 - var5 * var12 - var7 * var12, var8, var11); + var1.vertexUV(var13 - var3 * var12 + var6 * var12, var14 + var4 * var12, var15 - var5 * var12 + var7 * var12, var8, var10); + var1.vertexUV(var13 + var3 * var12 + var6 * var12, var14 + var4 * var12, var15 + var5 * var12 + var7 * var12, var9, var10); + var1.vertexUV(var13 + var3 * var12 - var6 * var12, var14 - var4 * var12, var15 + var5 * var12 - var7 * var12, var9, var11); + } + + public int getParticleTexture() { + return 0; + } +} diff --git a/src/main/java/com/mojang/minecraft/particle/ParticleManager.java b/src/main/java/com/mojang/minecraft/particle/ParticleManager.java new file mode 100644 index 0000000..8dbeef6 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/particle/ParticleManager.java @@ -0,0 +1,47 @@ +package com.mojang.minecraft.particle; + +import com.mojang.minecraft.Entity; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.particle.Particle; +import com.mojang.minecraft.render.TextureManager; +import java.util.ArrayList; +import java.util.List; + +public final class ParticleManager { + + public List[] particles = new List[2]; + public TextureManager textureManager; + + + public ParticleManager(Level var1, TextureManager var2) { + if(var1 != null) { + var1.particleEngine = this; + } + + this.textureManager = var2; + + for(int var3 = 0; var3 < 2; ++var3) { + this.particles[var3] = new ArrayList(); + } + + } + + public final void spawnParticle(Entity var1) { + Particle var3; + int var2 = (var3 = (Particle)var1).getParticleTexture(); + this.particles[var2].add(var3); + } + + public final void tick() { + for(int var1 = 0; var1 < 2; ++var1) { + for(int var2 = 0; var2 < this.particles[var1].size(); ++var2) { + Particle var3; + (var3 = (Particle)this.particles[var1].get(var2)).tick(); + if(var3.removed) { + this.particles[var1].remove(var2--); + } + } + } + + } +} diff --git a/src/main/java/com/mojang/minecraft/particle/SmokeParticle.java b/src/main/java/com/mojang/minecraft/particle/SmokeParticle.java new file mode 100644 index 0000000..b2ced7c --- /dev/null +++ b/src/main/java/com/mojang/minecraft/particle/SmokeParticle.java @@ -0,0 +1,46 @@ +package com.mojang.minecraft.particle; + +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.particle.Particle; +import com.mojang.minecraft.render.ShapeRenderer; + +public class SmokeParticle extends Particle { + + private static final long serialVersionUID = 1L; + + + public SmokeParticle(Level var1, float var2, float var3, float var4) { + super(var1, var2, var3, var4, 0.0F, 0.0F, 0.0F); + this.xd *= 0.1F; + this.yd *= 0.1F; + this.zd *= 0.1F; + this.rCol = this.gCol = this.bCol = (float)(Math.random() * 0.30000001192092896D); + this.lifetime = (int)(8.0D / (Math.random() * 0.8D + 0.2D)); + this.noPhysics = true; + } + + public void render(ShapeRenderer var1, float var2, float var3, float var4, float var5, float var6, float var7) { + super.render(var1, var2, var3, var4, var5, var6, var7); + } + + public void tick() { + this.xo = this.x; + this.yo = this.y; + this.zo = this.z; + if(this.age++ >= this.lifetime) { + this.remove(); + } + + this.tex = 7 - (this.age << 3) / this.lifetime; + this.yd = (float)((double)this.yd + 0.004D); + this.move(this.xd, this.yd, this.zd); + this.xd *= 0.96F; + this.yd *= 0.96F; + this.zd *= 0.96F; + if(this.onGround) { + this.xd *= 0.7F; + this.zd *= 0.7F; + } + + } +} diff --git a/src/main/java/com/mojang/minecraft/particle/TerrainParticle.java b/src/main/java/com/mojang/minecraft/particle/TerrainParticle.java new file mode 100644 index 0000000..22f8617 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/particle/TerrainParticle.java @@ -0,0 +1,40 @@ +package com.mojang.minecraft.particle; + +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.level.tile.Block; +import com.mojang.minecraft.particle.Particle; +import com.mojang.minecraft.render.ShapeRenderer; + +public class TerrainParticle extends Particle { + + private static final long serialVersionUID = 1L; + + + public TerrainParticle(Level var1, float var2, float var3, float var4, float var5, float var6, float var7, Block var8) { + super(var1, var2, var3, var4, var5, var6, var7); + this.tex = var8.textureId; + this.gravity = var8.particleGravity; + this.rCol = this.gCol = this.bCol = 0.6F; + } + + public int getParticleTexture() { + return 1; + } + + public void render(ShapeRenderer var1, float var2, float var3, float var4, float var5, float var6, float var7) { + float var8; + float var9 = (var8 = ((float)(this.tex % 16) + this.uo / 4.0F) / 16.0F) + 0.015609375F; + float var10; + float var11 = (var10 = ((float)(this.tex / 16) + this.vo / 4.0F) / 16.0F) + 0.015609375F; + float var12 = 0.1F * this.size; + float var13 = this.xo + (this.x - this.xo) * var2; + float var14 = this.yo + (this.y - this.yo) * var2; + float var15 = this.zo + (this.z - this.zo) * var2; + var2 = this.getBrightness(var2); + var1.color(var2 * this.rCol, var2 * this.gCol, var2 * this.bCol); + var1.vertexUV(var13 - var3 * var12 - var6 * var12, var14 - var4 * var12, var15 - var5 * var12 - var7 * var12, var8, var11); + var1.vertexUV(var13 - var3 * var12 + var6 * var12, var14 + var4 * var12, var15 - var5 * var12 + var7 * var12, var8, var10); + var1.vertexUV(var13 + var3 * var12 + var6 * var12, var14 + var4 * var12, var15 + var5 * var12 + var7 * var12, var9, var10); + var1.vertexUV(var13 + var3 * var12 - var6 * var12, var14 - var4 * var12, var15 + var5 * var12 - var7 * var12, var9, var11); + } +} diff --git a/src/main/java/com/mojang/minecraft/particle/WaterDropParticle.java b/src/main/java/com/mojang/minecraft/particle/WaterDropParticle.java new file mode 100644 index 0000000..0479a50 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/particle/WaterDropParticle.java @@ -0,0 +1,52 @@ +package com.mojang.minecraft.particle; + +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.particle.Particle; +import com.mojang.minecraft.render.ShapeRenderer; + +public class WaterDropParticle extends Particle { + + private static final long serialVersionUID = 1L; + + + public WaterDropParticle(Level var1, float var2, float var3, float var4) { + super(var1, var2, var3, var4, 0.0F, 0.0F, 0.0F); + this.xd *= 0.3F; + this.yd = (float)Math.random() * 0.2F + 0.1F; + this.zd *= 0.3F; + this.rCol = 1.0F; + this.gCol = 1.0F; + this.bCol = 1.0F; + this.tex = 16; + this.setSize(0.01F, 0.01F); + this.lifetime = (int)(8.0D / (Math.random() * 0.8D + 0.2D)); + } + + public void render(ShapeRenderer var1, float var2, float var3, float var4, float var5, float var6, float var7) { + super.render(var1, var2, var3, var4, var5, var6, var7); + } + + public void tick() { + this.xo = this.x; + this.yo = this.y; + this.zo = this.z; + this.yd = (float)((double)this.yd - 0.06D); + this.move(this.xd, this.yd, this.zd); + this.xd *= 0.98F; + this.yd *= 0.98F; + this.zd *= 0.98F; + if(this.lifetime-- <= 0) { + this.remove(); + } + + if(this.onGround) { + if(Math.random() < 0.5D) { + this.remove(); + } + + this.xd *= 0.7F; + this.zd *= 0.7F; + } + + } +} diff --git a/src/main/java/com/mojang/minecraft/phys/AABB.java b/src/main/java/com/mojang/minecraft/phys/AABB.java new file mode 100644 index 0000000..6c6ffdf --- /dev/null +++ b/src/main/java/com/mojang/minecraft/phys/AABB.java @@ -0,0 +1,308 @@ +package com.mojang.minecraft.phys; + +import com.mojang.minecraft.MovingObjectPosition; +import com.mojang.minecraft.model.Vec3D; +import java.io.Serializable; + +public class AABB implements Serializable { + + public static final long serialVersionUID = 0L; + private float epsilon = 0.0F; + public float x0; + public float y0; + public float z0; + public float x1; + public float y1; + public float z1; + + + public AABB(float var1, float var2, float var3, float var4, float var5, float var6) { + this.x0 = var1; + this.y0 = var2; + this.z0 = var3; + this.x1 = var4; + this.y1 = var5; + this.z1 = var6; + } + + public AABB expand(float var1, float var2, float var3) { + float var4 = this.x0; + float var5 = this.y0; + float var6 = this.z0; + float var7 = this.x1; + float var8 = this.y1; + float var9 = this.z1; + if(var1 < 0.0F) { + var4 += var1; + } + + if(var1 > 0.0F) { + var7 += var1; + } + + if(var2 < 0.0F) { + var5 += var2; + } + + if(var2 > 0.0F) { + var8 += var2; + } + + if(var3 < 0.0F) { + var6 += var3; + } + + if(var3 > 0.0F) { + var9 += var3; + } + + return new AABB(var4, var5, var6, var7, var8, var9); + } + + public AABB grow(float var1, float var2, float var3) { + float var4 = this.x0 - var1; + float var5 = this.y0 - var2; + float var6 = this.z0 - var3; + var1 += this.x1; + var2 += this.y1; + float var7 = this.z1 + var3; + return new AABB(var4, var5, var6, var1, var2, var7); + } + + public AABB cloneMove(float var1, float var2, float var3) { + return new AABB(this.x0 + var3, this.y0 + var2, this.z0 + var3, this.x1 + var1, this.y1 + var2, this.z1 + var3); + } + + public float clipXCollide(AABB var1, float var2) { + if(var1.y1 > this.y0 && var1.y0 < this.y1) { + if(var1.z1 > this.z0 && var1.z0 < this.z1) { + float var3; + if(var2 > 0.0F && var1.x1 <= this.x0 && (var3 = this.x0 - var1.x1 - this.epsilon) < var2) { + var2 = var3; + } + + if(var2 < 0.0F && var1.x0 >= this.x1 && (var3 = this.x1 - var1.x0 + this.epsilon) > var2) { + var2 = var3; + } + + return var2; + } else { + return var2; + } + } else { + return var2; + } + } + + public float clipYCollide(AABB var1, float var2) { + if(var1.x1 > this.x0 && var1.x0 < this.x1) { + if(var1.z1 > this.z0 && var1.z0 < this.z1) { + float var3; + if(var2 > 0.0F && var1.y1 <= this.y0 && (var3 = this.y0 - var1.y1 - this.epsilon) < var2) { + var2 = var3; + } + + if(var2 < 0.0F && var1.y0 >= this.y1 && (var3 = this.y1 - var1.y0 + this.epsilon) > var2) { + var2 = var3; + } + + return var2; + } else { + return var2; + } + } else { + return var2; + } + } + + public float clipZCollide(AABB var1, float var2) { + if(var1.x1 > this.x0 && var1.x0 < this.x1) { + if(var1.y1 > this.y0 && var1.y0 < this.y1) { + float var3; + if(var2 > 0.0F && var1.z1 <= this.z0 && (var3 = this.z0 - var1.z1 - this.epsilon) < var2) { + var2 = var3; + } + + if(var2 < 0.0F && var1.z0 >= this.z1 && (var3 = this.z1 - var1.z0 + this.epsilon) > var2) { + var2 = var3; + } + + return var2; + } else { + return var2; + } + } else { + return var2; + } + } + + public boolean intersects(AABB var1) { + return var1.x1 > this.x0 && var1.x0 < this.x1?(var1.y1 > this.y0 && var1.y0 < this.y1?var1.z1 > this.z0 && var1.z0 < this.z1:false):false; + } + + public boolean intersectsInner(AABB var1) { + return var1.x1 >= this.x0 && var1.x0 <= this.x1?(var1.y1 >= this.y0 && var1.y0 <= this.y1?var1.z1 >= this.z0 && var1.z0 <= this.z1:false):false; + } + + public void move(float var1, float var2, float var3) { + this.x0 += var1; + this.y0 += var2; + this.z0 += var3; + this.x1 += var1; + this.y1 += var2; + this.z1 += var3; + } + + public boolean intersects(float var1, float var2, float var3, float var4, float var5, float var6) { + return var4 > this.x0 && var1 < this.x1?(var5 > this.y0 && var2 < this.y1?var6 > this.z0 && var3 < this.z1:false):false; + } + + public boolean contains(Vec3D var1) { + return var1.x > this.x0 && var1.x < this.x1?(var1.y > this.y0 && var1.y < this.y1?var1.z > this.z0 && var1.z < this.z1:false):false; + } + + public float getSize() { + float var1 = this.x1 - this.x0; + float var2 = this.y1 - this.y0; + float var3 = this.z1 - this.z0; + return (var1 + var2 + var3) / 3.0F; + } + + public AABB shrink(float var1, float var2, float var3) { + float var4 = this.x0; + float var5 = this.y0; + float var6 = this.z0; + float var7 = this.x1; + float var8 = this.y1; + float var9 = this.z1; + if(var1 < 0.0F) { + var4 -= var1; + } + + if(var1 > 0.0F) { + var7 -= var1; + } + + if(var2 < 0.0F) { + var5 -= var2; + } + + if(var2 > 0.0F) { + var8 -= var2; + } + + if(var3 < 0.0F) { + var6 -= var3; + } + + if(var3 > 0.0F) { + var9 -= var3; + } + + return new AABB(var4, var5, var6, var7, var8, var9); + } + + public AABB copy() { + return new AABB(this.x0, this.y0, this.z0, this.x1, this.y1, this.z1); + } + + public MovingObjectPosition clip(Vec3D var1, Vec3D var2) { + Vec3D var3 = var1.getXIntersection(var2, this.x0); + Vec3D var4 = var1.getXIntersection(var2, this.x1); + Vec3D var5 = var1.getYIntersection(var2, this.y0); + Vec3D var6 = var1.getYIntersection(var2, this.y1); + Vec3D var7 = var1.getZIntersection(var2, this.z0); + var2 = var1.getZIntersection(var2, this.z1); + if(!this.xIntersects(var3)) { + var3 = null; + } + + if(!this.xIntersects(var4)) { + var4 = null; + } + + if(!this.yIntersects(var5)) { + var5 = null; + } + + if(!this.yIntersects(var6)) { + var6 = null; + } + + if(!this.zIntersects(var7)) { + var7 = null; + } + + if(!this.zIntersects(var2)) { + var2 = null; + } + + Vec3D var8 = null; + if(var3 != null) { + var8 = var3; + } + + if(var4 != null && (var8 == null || var1.distanceSquared(var4) < var1.distanceSquared(var8))) { + var8 = var4; + } + + if(var5 != null && (var8 == null || var1.distanceSquared(var5) < var1.distanceSquared(var8))) { + var8 = var5; + } + + if(var6 != null && (var8 == null || var1.distanceSquared(var6) < var1.distanceSquared(var8))) { + var8 = var6; + } + + if(var7 != null && (var8 == null || var1.distanceSquared(var7) < var1.distanceSquared(var8))) { + var8 = var7; + } + + if(var2 != null && (var8 == null || var1.distanceSquared(var2) < var1.distanceSquared(var8))) { + var8 = var2; + } + + if(var8 == null) { + return null; + } else { + byte var9 = -1; + if(var8 == var3) { + var9 = 4; + } + + if(var8 == var4) { + var9 = 5; + } + + if(var8 == var5) { + var9 = 0; + } + + if(var8 == var6) { + var9 = 1; + } + + if(var8 == var7) { + var9 = 2; + } + + if(var8 == var2) { + var9 = 3; + } + + return new MovingObjectPosition(0, 0, 0, var9, var8); + } + } + + private boolean xIntersects(Vec3D var1) { + return var1 == null?false:var1.y >= this.y0 && var1.y <= this.y1 && var1.z >= this.z0 && var1.z <= this.z1; + } + + private boolean yIntersects(Vec3D var1) { + return var1 == null?false:var1.x >= this.x0 && var1.x <= this.x1 && var1.z >= this.z0 && var1.z <= this.z1; + } + + private boolean zIntersects(Vec3D var1) { + return var1 == null?false:var1.x >= this.x0 && var1.x <= this.x1 && var1.y >= this.y0 && var1.y <= this.y1; + } +} diff --git a/src/main/java/com/mojang/minecraft/player/InputHandler.java b/src/main/java/com/mojang/minecraft/player/InputHandler.java new file mode 100644 index 0000000..53827bb --- /dev/null +++ b/src/main/java/com/mojang/minecraft/player/InputHandler.java @@ -0,0 +1,20 @@ +package com.mojang.minecraft.player; + +public class InputHandler +{ + public float xxa = 0.0F; + public float jumping = 0.0F; + public boolean yya = false; + + public void updateMovement() + { + } + + public void resetKeys() + { + } + + public void setKeyState(int key, boolean state) + { + } +} diff --git a/src/main/java/com/mojang/minecraft/player/InputHandlerImpl.java b/src/main/java/com/mojang/minecraft/player/InputHandlerImpl.java new file mode 100644 index 0000000..267697c --- /dev/null +++ b/src/main/java/com/mojang/minecraft/player/InputHandlerImpl.java @@ -0,0 +1,90 @@ +package com.mojang.minecraft.player; + +import com.mojang.minecraft.GameSettings; + +public class InputHandlerImpl extends InputHandler +{ + public InputHandlerImpl(GameSettings gameSettings) + { + settings = gameSettings; + } + + @Override + public void updateMovement() + { + xxa = 0.0F; + jumping = 0.0F; + + if(keyStates[0]) + { + jumping--; + } + + if(keyStates[1]) + { + jumping++; + } + + if(keyStates[2]) + { + xxa--; + } + + if(keyStates[3]) + { + xxa++; + } + + yya = keyStates[4]; + } + + @Override + public void resetKeys() + { + for(int i = 0; i < keyStates.length; ++i) + { + keyStates[i] = false; + } + + } + + @Override + public void setKeyState(int key, boolean state) + { + byte index = -1; + + if(key == settings.forwardKey.key) + { + index = 0; + } + + if(key == settings.backKey.key) + { + index = 1; + } + + if(key == settings.leftKey.key) + { + index = 2; + } + + if(key == settings.rightKey.key) + { + index = 3; + } + + if(key == settings.jumpKey.key) + { + index = 4; + } + + if(index >= 0) + { + keyStates[index] = state; + } + + } + + private boolean[] keyStates = new boolean[10]; + private GameSettings settings; +} diff --git a/src/main/java/com/mojang/minecraft/player/Inventory.java b/src/main/java/com/mojang/minecraft/player/Inventory.java new file mode 100644 index 0000000..ad4da94 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/player/Inventory.java @@ -0,0 +1,127 @@ +package com.mojang.minecraft.player; + +import com.mojang.minecraft.SessionData; +import com.mojang.minecraft.level.tile.Block; +import java.io.Serializable; + +public class Inventory implements Serializable { + + public static final long serialVersionUID = 0L; + public static final int POP_TIME_DURATION = 5; + public int[] slots = new int[9]; + public int[] count = new int[9]; + public int[] popTime = new int[9]; + public int selected = 0; + + + public Inventory() { + for(int var1 = 0; var1 < 9; ++var1) { + this.slots[var1] = -1; + this.count[var1] = 0; + } + + } + + public int getSelected() { + return this.slots[this.selected]; + } + + private int getSlot(int var1) { + for(int var2 = 0; var2 < this.slots.length; ++var2) { + if(var1 == this.slots[var2]) { + return var2; + } + } + + return -1; + } + + public void grabTexture(int var1, boolean var2) { + int var3; + if((var3 = this.getSlot(var1)) >= 0) { + this.selected = var3; + } else { + if(var2 && var1 > 0 && SessionData.allowedBlocks.contains(Block.blocks[var1])) { + this.replaceSlot(Block.blocks[var1]); + } + + } + } + + public void swapPaint(int var1) { + if(var1 > 0) { + var1 = 1; + } + + if(var1 < 0) { + var1 = -1; + } + + for(this.selected -= var1; this.selected < 0; this.selected += this.slots.length) { + ; + } + + while(this.selected >= this.slots.length) { + this.selected -= this.slots.length; + } + + } + + public void replaceSlot(int var1) { + if(var1 >= 0) { + this.replaceSlot((Block)SessionData.allowedBlocks.get(var1)); + } + + } + + public void replaceSlot(Block var1) { + if(var1 != null) { + int var2; + if((var2 = this.getSlot(var1.id)) >= 0) { + this.slots[var2] = this.slots[this.selected]; + } + + this.slots[this.selected] = var1.id; + } + + } + + public boolean addResource(int var1) { + int var2; + if((var2 = this.getSlot(var1)) < 0) { + var2 = this.getSlot(-1); + } + + if(var2 < 0) { + return false; + } else if(this.count[var2] >= 99) { + return false; + } else { + this.slots[var2] = var1; + ++this.count[var2]; + this.popTime[var2] = 5; + return true; + } + } + + public void tick() { + for(int var1 = 0; var1 < this.popTime.length; ++var1) { + if(this.popTime[var1] > 0) { + --this.popTime[var1]; + } + } + + } + + public boolean removeResource(int var1) { + if((var1 = this.getSlot(var1)) < 0) { + return false; + } else { + if(--this.count[var1] <= 0) { + this.slots[var1] = -1; + } + + return true; + } + } +} diff --git a/src/main/java/com/mojang/minecraft/player/Player$1.java b/src/main/java/com/mojang/minecraft/player/Player$1.java new file mode 100644 index 0000000..e755802 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/player/Player$1.java @@ -0,0 +1,26 @@ +package com.mojang.minecraft.player; + +import com.mojang.minecraft.mob.ai.BasicAI; +import com.mojang.minecraft.player.Player; + +// PlayerAI +public class Player$1 extends BasicAI +{ + public Player$1(Player player) + { + this.player = player; + } + + @Override + protected void update() + { + this.jumping = player.input.yya; + + this.xxa = player.input.xxa; + this.yya = player.input.jumping; + } + + public static final long serialVersionUID = 0L; + + private Player player; +} diff --git a/src/main/java/com/mojang/minecraft/player/Player.java b/src/main/java/com/mojang/minecraft/player/Player.java new file mode 100644 index 0000000..8009833 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/player/Player.java @@ -0,0 +1,162 @@ +package com.mojang.minecraft.player; + +import com.mojang.minecraft.Entity; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.mob.Mob; +import com.mojang.minecraft.model.HumanoidModel; +import com.mojang.minecraft.player.InputHandler; +import com.mojang.minecraft.player.Inventory; +import com.mojang.minecraft.player.Player$1; +import com.mojang.minecraft.render.TextureManager; +import com.mojang.util.MathHelper; +import java.awt.image.BufferedImage; +import java.util.List; +import org.lwjgl.opengl.GL11; + +public class Player extends Mob { + + public static final long serialVersionUID = 0L; + public static final int MAX_HEALTH = 20; + public static final int MAX_ARROWS = 99; + public transient InputHandler input; + public Inventory inventory = new Inventory(); + public byte userType = 0; + public float oBob; + public float bob; + public int score = 0; + public int arrows = 20; + private static int newTextureId = -1; + public static BufferedImage newTexture; + + + public Player(Level var1) { + super(var1); + if(var1 != null) { + var1.player = this; + var1.removeEntity(this); + var1.addEntity(this); + } + + this.heightOffset = 1.62F; + this.health = 20; + this.modelName = "humanoid"; + this.rotOffs = 180.0F; + this.ai = new Player$1(this); + } + + public void resetPos() { + this.heightOffset = 1.62F; + this.setSize(0.6F, 1.8F); + super.resetPos(); + if(this.level != null) { + this.level.player = this; + } + + this.health = 20; + this.deathTime = 0; + } + + public void aiStep() { + this.inventory.tick(); + this.oBob = this.bob; + this.input.updateMovement(); + super.aiStep(); + float var1 = MathHelper.sqrt(this.xd * this.xd + this.zd * this.zd); + float var2 = (float)Math.atan((double)(-this.yd * 0.2F)) * 15.0F; + if(var1 > 0.1F) { + var1 = 0.1F; + } + + if(!this.onGround || this.health <= 0) { + var1 = 0.0F; + } + + if(this.onGround || this.health <= 0) { + var2 = 0.0F; + } + + this.bob += (var1 - this.bob) * 0.4F; + this.tilt += (var2 - this.tilt) * 0.8F; + List var3; + if(this.health > 0 && (var3 = this.level.findEntities(this, this.bb.grow(1.0F, 0.0F, 1.0F))) != null) { + for(int var4 = 0; var4 < var3.size(); ++var4) { + ((Entity)var3.get(var4)).playerTouch(this); + } + } + + } + + public void render(TextureManager var1, float var2) {} + + public void releaseAllKeys() { + this.input.resetKeys(); + } + + public void setKey(int var1, boolean var2) { + this.input.setKeyState(var1, var2); + } + + public boolean addResource(int var1) { + return this.inventory.addResource(var1); + } + + public int getScore() { + return this.score; + } + + public HumanoidModel getModel() { + return (HumanoidModel)modelCache.getModel(this.modelName); + } + + public void die(Entity var1) { + this.setSize(0.2F, 0.2F); + this.setPos(this.x, this.y, this.z); + this.yd = 0.1F; + if(var1 != null) { + this.xd = -MathHelper.cos((this.hurtDir + this.yRot) * 3.1415927F / 180.0F) * 0.1F; + this.zd = -MathHelper.sin((this.hurtDir + this.yRot) * 3.1415927F / 180.0F) * 0.1F; + } else { + this.xd = this.zd = 0.0F; + } + + this.heightOffset = 0.1F; + } + + public void remove() {} + + public void awardKillScore(Entity var1, int var2) { + this.score += var2; + } + + public boolean isShootable() { + return true; + } + + public void bindTexture(TextureManager var1) { + if(newTexture != null) { + newTextureId = var1.load(newTexture); + newTexture = null; + } + + int var2; + if(newTextureId < 0) { + var2 = var1.load("/char.png"); + GL11.glBindTexture(3553, var2); + } else { + var2 = newTextureId; + GL11.glBindTexture(3553, var2); + } + } + + public void hurt(Entity var1, int var2) { + if(!this.level.creativeMode) { + super.hurt(var1, var2); + } + + } + + public boolean isCreativeModeAllowed() { + return true; + } + +} diff --git a/src/main/java/com/mojang/minecraft/render/Chunk.java b/src/main/java/com/mojang/minecraft/render/Chunk.java new file mode 100644 index 0000000..10d95cd --- /dev/null +++ b/src/main/java/com/mojang/minecraft/render/Chunk.java @@ -0,0 +1,123 @@ +package com.mojang.minecraft.render; + +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.level.tile.Block; +import com.mojang.minecraft.player.Player; +import com.mojang.minecraft.render.Frustrum; +import com.mojang.minecraft.render.ShapeRenderer; +import com.mojang.util.MathHelper; +import org.lwjgl.opengl.GL11; + +public final class Chunk { + + private Level level; + private int baseListId = -1; + private static ShapeRenderer renderer = ShapeRenderer.instance; + public static int chunkUpdates = 0; + private int x; + private int y; + private int z; + private int width; + private int height; + private int depth; + public boolean visible = false; + private boolean[] dirty = new boolean[2]; + public boolean loaded; + + + public Chunk(Level var1, int var2, int var3, int var4, int var5, int var6) { + this.level = var1; + this.x = var2; + this.y = var3; + this.z = var4; + this.width = this.height = this.depth = 16; + MathHelper.sqrt((float)(this.width * this.width + this.height * this.height + this.depth * this.depth)); + this.baseListId = var6; + this.setAllDirty(); + } + + public final void update() { + ++chunkUpdates; + int var1 = this.x; + int var2 = this.y; + int var3 = this.z; + int var4 = this.x + this.width; + int var5 = this.y + this.height; + int var6 = this.z + this.depth; + + int var7; + for(var7 = 0; var7 < 2; ++var7) { + this.dirty[var7] = true; + } + + for(var7 = 0; var7 < 2; ++var7) { + boolean var8 = false; + boolean var9 = false; + GL11.glNewList(this.baseListId + var7, 4864); + renderer.begin(); + + for(int var10 = var1; var10 < var4; ++var10) { + for(int var11 = var2; var11 < var5; ++var11) { + for(int var12 = var3; var12 < var6; ++var12) { + int var13; + if((var13 = this.level.getTile(var10, var11, var12)) > 0) { + Block var14; + if((var14 = Block.blocks[var13]).getRenderPass() != var7) { + var8 = true; + } else { + var9 |= var14.render(this.level, var10, var11, var12, renderer); + } + } + } + } + } + + renderer.end(); + GL11.glEndList(); + if(var9) { + this.dirty[var7] = false; + } + + if(!var8) { + break; + } + } + + } + + public final float distanceSquared(Player var1) { + float var2 = var1.x - (float)this.x; + float var3 = var1.y - (float)this.y; + float var4 = var1.z - (float)this.z; + return var2 * var2 + var3 * var3 + var4 * var4; + } + + private void setAllDirty() { + for(int var1 = 0; var1 < 2; ++var1) { + this.dirty[var1] = true; + } + + } + + public final void dispose() { + this.setAllDirty(); + this.level = null; + } + + public final int appendLists(int[] var1, int var2, int var3) { + if(!this.visible) { + return var2; + } else { + if(!this.dirty[var3]) { + var1[var2++] = this.baseListId + var3; + } + + return var2; + } + } + + public final void clip(Frustrum var1) { + this.visible = var1.isBoxInFrustrum((float)this.x, (float)this.y, (float)this.z, (float)(this.x + this.width), (float)(this.y + this.height), (float)(this.z + this.depth)); + } + +} diff --git a/src/main/java/com/mojang/minecraft/render/ChunkDirtyDistanceComparator.java b/src/main/java/com/mojang/minecraft/render/ChunkDirtyDistanceComparator.java new file mode 100644 index 0000000..9454f0b --- /dev/null +++ b/src/main/java/com/mojang/minecraft/render/ChunkDirtyDistanceComparator.java @@ -0,0 +1,43 @@ +package com.mojang.minecraft.render; + +import com.mojang.minecraft.player.Player; +import java.util.Comparator; + +public class ChunkDirtyDistanceComparator implements Comparator +{ + public ChunkDirtyDistanceComparator(Player player) + { + this.player = player; + } + + @Override + public int compare(Object o1, Object o2) + { + Chunk chunk = (Chunk)o1; + Chunk other = (Chunk)o2; + + if(chunk.visible || !other.visible) + { + if(other.visible) + { + float sqDist = chunk.distanceSquared(player); + float otherSqDist = other.distanceSquared(player); + + if(sqDist == otherSqDist) + { + return 0; + } else if(sqDist > otherSqDist) { + return -1; + } else { + return 1; + } + } else { + return 1; + } + } else { + return -1; + } + } + + private Player player; +} diff --git a/src/main/java/com/mojang/minecraft/render/ChunkDistanceComparator.java b/src/main/java/com/mojang/minecraft/render/ChunkDistanceComparator.java new file mode 100644 index 0000000..99cd287 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/render/ChunkDistanceComparator.java @@ -0,0 +1,33 @@ +package com.mojang.minecraft.render; + +import com.mojang.minecraft.player.Player; +import java.util.Comparator; + +public class ChunkDistanceComparator implements Comparator +{ + public ChunkDistanceComparator(Player player) + { + this.player = player; + } + + @Override + public int compare(Object o1, Object o2) + { + Chunk chunk = (Chunk)o1; + Chunk other = (Chunk)o2; + + float sqDist = chunk.distanceSquared(player); + float otherSqDist = other.distanceSquared(player); + + if(sqDist == otherSqDist) + { + return 0; + } else if(sqDist > otherSqDist) { + return -1; + } else { + return 1; + } + } + + private Player player; +} diff --git a/src/main/java/com/mojang/minecraft/render/Frustrum.java b/src/main/java/com/mojang/minecraft/render/Frustrum.java new file mode 100644 index 0000000..a3823d4 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/render/Frustrum.java @@ -0,0 +1,21 @@ +package com.mojang.minecraft.render; + + +public class Frustrum { + + public float[][] frustrum = new float[16][16]; + public float[] projection = new float[16]; + public float[] modelview = new float[16]; + public float[] clipping = new float[16]; + + + public final boolean isBoxInFrustrum(float var1, float var2, float var3, float var4, float var5, float var6) { + for(int var7 = 0; var7 < 6; ++var7) { + if(this.frustrum[var7][0] * var1 + this.frustrum[var7][1] * var2 + this.frustrum[var7][2] * var3 + this.frustrum[var7][3] <= 0.0F && this.frustrum[var7][0] * var4 + this.frustrum[var7][1] * var2 + this.frustrum[var7][2] * var3 + this.frustrum[var7][3] <= 0.0F && this.frustrum[var7][0] * var1 + this.frustrum[var7][1] * var5 + this.frustrum[var7][2] * var3 + this.frustrum[var7][3] <= 0.0F && this.frustrum[var7][0] * var4 + this.frustrum[var7][1] * var5 + this.frustrum[var7][2] * var3 + this.frustrum[var7][3] <= 0.0F && this.frustrum[var7][0] * var1 + this.frustrum[var7][1] * var2 + this.frustrum[var7][2] * var6 + this.frustrum[var7][3] <= 0.0F && this.frustrum[var7][0] * var4 + this.frustrum[var7][1] * var2 + this.frustrum[var7][2] * var6 + this.frustrum[var7][3] <= 0.0F && this.frustrum[var7][0] * var1 + this.frustrum[var7][1] * var5 + this.frustrum[var7][2] * var6 + this.frustrum[var7][3] <= 0.0F && this.frustrum[var7][0] * var4 + this.frustrum[var7][1] * var5 + this.frustrum[var7][2] * var6 + this.frustrum[var7][3] <= 0.0F) { + return false; + } + } + + return true; + } +} diff --git a/src/main/java/com/mojang/minecraft/render/FrustrumImpl.java b/src/main/java/com/mojang/minecraft/render/FrustrumImpl.java new file mode 100644 index 0000000..05d18e9 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/render/FrustrumImpl.java @@ -0,0 +1,85 @@ +package com.mojang.minecraft.render; + +import com.mojang.minecraft.render.Frustrum; +import com.mojang.util.MathHelper; +import java.nio.FloatBuffer; +import org.lwjgl.BufferUtils; +import org.lwjgl.opengl.GL11; + +public final class FrustrumImpl extends Frustrum { + + private static FrustrumImpl instance = new FrustrumImpl(); + private FloatBuffer projectionBuff = BufferUtils.createFloatBuffer(16); + private FloatBuffer modelviewBuff = BufferUtils.createFloatBuffer(16); + private FloatBuffer unused = BufferUtils.createFloatBuffer(16); + + + public static Frustrum update() { + FrustrumImpl var0 = instance; + instance.projectionBuff.clear(); + var0.modelviewBuff.clear(); + var0.unused.clear(); + GL11.glGetFloat(2983, var0.projectionBuff); + GL11.glGetFloat(2982, var0.modelviewBuff); + var0.projectionBuff.flip().limit(16); + var0.projectionBuff.get(var0.projection); + var0.modelviewBuff.flip().limit(16); + var0.modelviewBuff.get(var0.modelview); + var0.clipping[0] = var0.modelview[0] * var0.projection[0] + var0.modelview[1] * var0.projection[4] + var0.modelview[2] * var0.projection[8] + var0.modelview[3] * var0.projection[12]; + var0.clipping[1] = var0.modelview[0] * var0.projection[1] + var0.modelview[1] * var0.projection[5] + var0.modelview[2] * var0.projection[9] + var0.modelview[3] * var0.projection[13]; + var0.clipping[2] = var0.modelview[0] * var0.projection[2] + var0.modelview[1] * var0.projection[6] + var0.modelview[2] * var0.projection[10] + var0.modelview[3] * var0.projection[14]; + var0.clipping[3] = var0.modelview[0] * var0.projection[3] + var0.modelview[1] * var0.projection[7] + var0.modelview[2] * var0.projection[11] + var0.modelview[3] * var0.projection[15]; + var0.clipping[4] = var0.modelview[4] * var0.projection[0] + var0.modelview[5] * var0.projection[4] + var0.modelview[6] * var0.projection[8] + var0.modelview[7] * var0.projection[12]; + var0.clipping[5] = var0.modelview[4] * var0.projection[1] + var0.modelview[5] * var0.projection[5] + var0.modelview[6] * var0.projection[9] + var0.modelview[7] * var0.projection[13]; + var0.clipping[6] = var0.modelview[4] * var0.projection[2] + var0.modelview[5] * var0.projection[6] + var0.modelview[6] * var0.projection[10] + var0.modelview[7] * var0.projection[14]; + var0.clipping[7] = var0.modelview[4] * var0.projection[3] + var0.modelview[5] * var0.projection[7] + var0.modelview[6] * var0.projection[11] + var0.modelview[7] * var0.projection[15]; + var0.clipping[8] = var0.modelview[8] * var0.projection[0] + var0.modelview[9] * var0.projection[4] + var0.modelview[10] * var0.projection[8] + var0.modelview[11] * var0.projection[12]; + var0.clipping[9] = var0.modelview[8] * var0.projection[1] + var0.modelview[9] * var0.projection[5] + var0.modelview[10] * var0.projection[9] + var0.modelview[11] * var0.projection[13]; + var0.clipping[10] = var0.modelview[8] * var0.projection[2] + var0.modelview[9] * var0.projection[6] + var0.modelview[10] * var0.projection[10] + var0.modelview[11] * var0.projection[14]; + var0.clipping[11] = var0.modelview[8] * var0.projection[3] + var0.modelview[9] * var0.projection[7] + var0.modelview[10] * var0.projection[11] + var0.modelview[11] * var0.projection[15]; + var0.clipping[12] = var0.modelview[12] * var0.projection[0] + var0.modelview[13] * var0.projection[4] + var0.modelview[14] * var0.projection[8] + var0.modelview[15] * var0.projection[12]; + var0.clipping[13] = var0.modelview[12] * var0.projection[1] + var0.modelview[13] * var0.projection[5] + var0.modelview[14] * var0.projection[9] + var0.modelview[15] * var0.projection[13]; + var0.clipping[14] = var0.modelview[12] * var0.projection[2] + var0.modelview[13] * var0.projection[6] + var0.modelview[14] * var0.projection[10] + var0.modelview[15] * var0.projection[14]; + var0.clipping[15] = var0.modelview[12] * var0.projection[3] + var0.modelview[13] * var0.projection[7] + var0.modelview[14] * var0.projection[11] + var0.modelview[15] * var0.projection[15]; + var0.frustrum[0][0] = var0.clipping[3] - var0.clipping[0]; + var0.frustrum[0][1] = var0.clipping[7] - var0.clipping[4]; + var0.frustrum[0][2] = var0.clipping[11] - var0.clipping[8]; + var0.frustrum[0][3] = var0.clipping[15] - var0.clipping[12]; + normalize(var0.frustrum, 0); + var0.frustrum[1][0] = var0.clipping[3] + var0.clipping[0]; + var0.frustrum[1][1] = var0.clipping[7] + var0.clipping[4]; + var0.frustrum[1][2] = var0.clipping[11] + var0.clipping[8]; + var0.frustrum[1][3] = var0.clipping[15] + var0.clipping[12]; + normalize(var0.frustrum, 1); + var0.frustrum[2][0] = var0.clipping[3] + var0.clipping[1]; + var0.frustrum[2][1] = var0.clipping[7] + var0.clipping[5]; + var0.frustrum[2][2] = var0.clipping[11] + var0.clipping[9]; + var0.frustrum[2][3] = var0.clipping[15] + var0.clipping[13]; + normalize(var0.frustrum, 2); + var0.frustrum[3][0] = var0.clipping[3] - var0.clipping[1]; + var0.frustrum[3][1] = var0.clipping[7] - var0.clipping[5]; + var0.frustrum[3][2] = var0.clipping[11] - var0.clipping[9]; + var0.frustrum[3][3] = var0.clipping[15] - var0.clipping[13]; + normalize(var0.frustrum, 3); + var0.frustrum[4][0] = var0.clipping[3] - var0.clipping[2]; + var0.frustrum[4][1] = var0.clipping[7] - var0.clipping[6]; + var0.frustrum[4][2] = var0.clipping[11] - var0.clipping[10]; + var0.frustrum[4][3] = var0.clipping[15] - var0.clipping[14]; + normalize(var0.frustrum, 4); + var0.frustrum[5][0] = var0.clipping[3] + var0.clipping[2]; + var0.frustrum[5][1] = var0.clipping[7] + var0.clipping[6]; + var0.frustrum[5][2] = var0.clipping[11] + var0.clipping[10]; + var0.frustrum[5][3] = var0.clipping[15] + var0.clipping[14]; + normalize(var0.frustrum, 5); + return instance; + } + + private static void normalize(float[][] var0, int var1) { + float var2 = MathHelper.sqrt(var0[var1][0] * var0[var1][0] + var0[var1][1] * var0[var1][1] + var0[var1][2] * var0[var1][2]); + var0[var1][0] /= var2; + var0[var1][1] /= var2; + var0[var1][2] /= var2; + var0[var1][3] /= var2; + } + +} diff --git a/src/main/java/com/mojang/minecraft/render/HeldBlock.java b/src/main/java/com/mojang/minecraft/render/HeldBlock.java new file mode 100644 index 0000000..541cd46 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/render/HeldBlock.java @@ -0,0 +1,23 @@ +package com.mojang.minecraft.render; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.level.tile.Block; + +public class HeldBlock +{ + public HeldBlock(Minecraft minecraft) + { + this.minecraft = minecraft; + } + + public Minecraft minecraft; + + public Block block = null; + + public float pos = 0.0F; + public float lastPos = 0.0F; + + public int offset = 0; + + public boolean moving = false; +} diff --git a/src/main/java/com/mojang/minecraft/render/LevelRenderer.java b/src/main/java/com/mojang/minecraft/render/LevelRenderer.java new file mode 100644 index 0000000..cd62d11 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/render/LevelRenderer.java @@ -0,0 +1,266 @@ +package com.mojang.minecraft.render; + +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.player.Player; +import com.mojang.minecraft.render.Chunk; +import com.mojang.minecraft.render.ChunkDistanceComparator; +import com.mojang.minecraft.render.ShapeRenderer; +import com.mojang.minecraft.render.TextureManager; +import java.nio.IntBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.lwjgl.BufferUtils; +import org.lwjgl.opengl.GL11; + +public final class LevelRenderer { + + public Level level; + public TextureManager textureManager; + public int listId; + public IntBuffer buffer = BufferUtils.createIntBuffer(65536); + public IntBuffer buffer_fast = BufferUtils.createIntBuffer(4096); + public List chunks = new ArrayList(); + private Chunk[] loadQueue; + public Chunk[] chunkCache; + private int xChunks; + private int yChunks; + private int zChunks; + private int baseListId; + public Minecraft minecraft; + private int[] chunkDataCache = new int['\uc350']; + public int ticks = 0; + private float lastLoadX = -9999.0F; + private float lastLoadY = -9999.0F; + private float lastLoadZ = -9999.0F; + public float cracks; + + + public LevelRenderer(Minecraft var1, TextureManager var2) { + this.minecraft = var1; + this.textureManager = var2; + this.listId = GL11.glGenLists(2); + this.baseListId = GL11.glGenLists(4096 << 6 << 1); + } + + public final void refresh() { + int var1; + if(this.chunkCache != null) { + for(var1 = 0; var1 < this.chunkCache.length; ++var1) { + this.chunkCache[var1].dispose(); + } + } + + this.xChunks = this.level.width / 16; + this.yChunks = this.level.depth / 16; + this.zChunks = this.level.height / 16; + this.chunkCache = new Chunk[this.xChunks * this.yChunks * this.zChunks]; + this.loadQueue = new Chunk[this.xChunks * this.yChunks * this.zChunks]; + var1 = 0; + + int var2; + int var4; + for(var2 = 0; var2 < this.xChunks; ++var2) { + for(int var3 = 0; var3 < this.yChunks; ++var3) { + for(var4 = 0; var4 < this.zChunks; ++var4) { + this.chunkCache[(var4 * this.yChunks + var3) * this.xChunks + var2] = new Chunk(this.level, var2 << 4, var3 << 4, var4 << 4, 16, this.baseListId + var1); + this.loadQueue[(var4 * this.yChunks + var3) * this.xChunks + var2] = this.chunkCache[(var4 * this.yChunks + var3) * this.xChunks + var2]; + var1 += 2; + } + } + } + + for(var2 = 0; var2 < this.chunks.size(); ++var2) { + ((Chunk)this.chunks.get(var2)).loaded = false; + } + + this.chunks.clear(); + GL11.glNewList(this.listId, 4864); + LevelRenderer var9 = this; + float var10 = 0.5F; + GL11.glColor4f(0.5F, var10, var10, 1.0F); + ShapeRenderer var11 = ShapeRenderer.instance; + float var12 = this.level.getGroundLevel(); + int var5 = 128; + if(128 > this.level.width) { + var5 = this.level.width; + } + + if(var5 > this.level.height) { + var5 = this.level.height; + } + + int var6 = 2048 / var5; + var11.begin(); + + int var7; + for(var7 = -var5 * var6; var7 < var9.level.width + var5 * var6; var7 += var5) { + for(int var8 = -var5 * var6; var8 < var9.level.height + var5 * var6; var8 += var5) { + var10 = var12; + if(var7 >= 0 && var8 >= 0 && var7 < var9.level.width && var8 < var9.level.height) { + var10 = 0.0F; + } + + var11.vertexUV((float)var7, var10, (float)(var8 + var5), 0.0F, (float)var5); + var11.vertexUV((float)(var7 + var5), var10, (float)(var8 + var5), (float)var5, (float)var5); + var11.vertexUV((float)(var7 + var5), var10, (float)var8, (float)var5, 0.0F); + var11.vertexUV((float)var7, var10, (float)var8, 0.0F, 0.0F); + } + } + + var11.end(); + GL11.glColor3f(0.8F, 0.8F, 0.8F); + var11.begin(); + + for(var7 = 0; var7 < var9.level.width; var7 += var5) { + var11.vertexUV((float)var7, 0.0F, 0.0F, 0.0F, 0.0F); + var11.vertexUV((float)(var7 + var5), 0.0F, 0.0F, (float)var5, 0.0F); + var11.vertexUV((float)(var7 + var5), var12, 0.0F, (float)var5, var12); + var11.vertexUV((float)var7, var12, 0.0F, 0.0F, var12); + var11.vertexUV((float)var7, var12, (float)var9.level.height, 0.0F, var12); + var11.vertexUV((float)(var7 + var5), var12, (float)var9.level.height, (float)var5, var12); + var11.vertexUV((float)(var7 + var5), 0.0F, (float)var9.level.height, (float)var5, 0.0F); + var11.vertexUV((float)var7, 0.0F, (float)var9.level.height, 0.0F, 0.0F); + } + + GL11.glColor3f(0.6F, 0.6F, 0.6F); + + for(var7 = 0; var7 < var9.level.height; var7 += var5) { + var11.vertexUV(0.0F, var12, (float)var7, 0.0F, 0.0F); + var11.vertexUV(0.0F, var12, (float)(var7 + var5), (float)var5, 0.0F); + var11.vertexUV(0.0F, 0.0F, (float)(var7 + var5), (float)var5, var12); + var11.vertexUV(0.0F, 0.0F, (float)var7, 0.0F, var12); + var11.vertexUV((float)var9.level.width, 0.0F, (float)var7, 0.0F, var12); + var11.vertexUV((float)var9.level.width, 0.0F, (float)(var7 + var5), (float)var5, var12); + var11.vertexUV((float)var9.level.width, var12, (float)(var7 + var5), (float)var5, 0.0F); + var11.vertexUV((float)var9.level.width, var12, (float)var7, 0.0F, 0.0F); + } + + var11.end(); + GL11.glEndList(); + GL11.glNewList(this.listId + 1, 4864); + var9 = this; + GL11.glColor3f(1.0F, 1.0F, 1.0F); + var10 = this.level.getWaterLevel(); + GL11.glBlendFunc(770, 771); + var11 = ShapeRenderer.instance; + var4 = 128; + if(128 > this.level.width) { + var4 = this.level.width; + } + + if(var4 > this.level.height) { + var4 = this.level.height; + } + + var5 = 2048 / var4; + var11.begin(); + + for(var6 = -var4 * var5; var6 < var9.level.width + var4 * var5; var6 += var4) { + for(var7 = -var4 * var5; var7 < var9.level.height + var4 * var5; var7 += var4) { + float var13 = var10 - 0.1F; + if(var6 < 0 || var7 < 0 || var6 >= var9.level.width || var7 >= var9.level.height) { + var11.vertexUV((float)var6, var13, (float)(var7 + var4), 0.0F, (float)var4); + var11.vertexUV((float)(var6 + var4), var13, (float)(var7 + var4), (float)var4, (float)var4); + var11.vertexUV((float)(var6 + var4), var13, (float)var7, (float)var4, 0.0F); + var11.vertexUV((float)var6, var13, (float)var7, 0.0F, 0.0F); + var11.vertexUV((float)var6, var13, (float)var7, 0.0F, 0.0F); + var11.vertexUV((float)(var6 + var4), var13, (float)var7, (float)var4, 0.0F); + var11.vertexUV((float)(var6 + var4), var13, (float)(var7 + var4), (float)var4, (float)var4); + var11.vertexUV((float)var6, var13, (float)(var7 + var4), 0.0F, (float)var4); + } + } + } + + var11.end(); + GL11.glDisable(3042); + GL11.glEndList(); + this.queueChunks(0, 0, 0, this.level.width, this.level.depth, this.level.height); + } + + public final int sortChunks(Player var1, int var2) { + float var3 = var1.x - this.lastLoadX; + float var4 = var1.y - this.lastLoadY; + float var5 = var1.z - this.lastLoadZ; + if(var3 * var3 + var4 * var4 + var5 * var5 > 64.0F) { + this.lastLoadX = var1.x; + this.lastLoadY = var1.y; + this.lastLoadZ = var1.z; + Arrays.sort(this.loadQueue, new ChunkDistanceComparator(var1)); + } + + int var6 = 0; + + for(int var7 = 0; var7 < this.loadQueue.length; ++var7) { + var6 = this.loadQueue[var7].appendLists(this.chunkDataCache, var6, var2); + } + + if(!Minecraft.settings.ofFastMath) { + this.buffer.clear(); + this.buffer.put(this.chunkDataCache, 0, var6); + this.buffer.flip(); + if(this.buffer.remaining() > 0) { + GL11.glBindTexture(3553, this.textureManager.load("/terrain.png")); + GL11.glCallLists(this.buffer); + } + + return this.buffer.remaining(); + } else { + this.buffer_fast.clear(); + this.buffer_fast.put(this.chunkDataCache, 0, var6); + this.buffer_fast.flip(); + if(this.buffer_fast.remaining() > 0) { + GL11.glBindTexture(3553, this.textureManager.load("/terrain.png")); + GL11.glCallLists(this.buffer_fast); + } + + return this.buffer_fast.remaining(); + } + } + + public final void queueChunks(int var1, int var2, int var3, int var4, int var5, int var6) { + var1 /= 16; + var2 /= 16; + var3 /= 16; + var4 /= 16; + var5 /= 16; + var6 /= 16; + if(var1 < 0) { + var1 = 0; + } + + if(var2 < 0) { + var2 = 0; + } + + if(var3 < 0) { + var3 = 0; + } + + if(var4 > this.xChunks - 1) { + var4 = this.xChunks - 1; + } + + if(var5 > this.yChunks - 1) { + var5 = this.yChunks - 1; + } + + if(var6 > this.zChunks - 1) { + var6 = this.zChunks - 1; + } + + for(var1 = var1; var1 <= var4; ++var1) { + for(int var7 = var2; var7 <= var5; ++var7) { + for(int var8 = var3; var8 <= var6; ++var8) { + Chunk var9; + if(!(var9 = this.chunkCache[(var8 * this.yChunks + var7) * this.xChunks + var1]).loaded) { + var9.loaded = true; + this.chunks.add(this.chunkCache[(var8 * this.yChunks + var7) * this.xChunks + var1]); + } + } + } + } + + } +} diff --git a/src/main/java/com/mojang/minecraft/render/Renderer.java b/src/main/java/com/mojang/minecraft/render/Renderer.java new file mode 100644 index 0000000..023070a --- /dev/null +++ b/src/main/java/com/mojang/minecraft/render/Renderer.java @@ -0,0 +1,170 @@ +package com.mojang.minecraft.render; + +import com.mojang.minecraft.Entity; +import com.mojang.minecraft.Minecraft; +import com.mojang.minecraft.level.Level; +import com.mojang.minecraft.level.liquid.LiquidType; +import com.mojang.minecraft.level.tile.Block; +import com.mojang.minecraft.model.Vec3D; +import com.mojang.minecraft.player.Player; +import com.mojang.minecraft.render.HeldBlock; +import com.mojang.util.MathHelper; +import java.nio.FloatBuffer; +import java.util.Random; +import org.lwjgl.BufferUtils; +import org.lwjgl.opengl.GL11; + +public final class Renderer { + + public Minecraft minecraft; + public float fogColorMultiplier = 1.0F; + public boolean displayActive = false; + public float fogEnd = 0.0F; + public HeldBlock heldBlock; + public int levelTicks; + public Entity entity = null; + public Random random = new Random(); + private volatile int unused1 = 0; + private volatile int unused2 = 0; + private FloatBuffer buffer = BufferUtils.createFloatBuffer(16); + public float fogRed; + public float fogBlue; + public float fogGreen; + + + public Renderer(Minecraft var1) { + this.minecraft = var1; + this.heldBlock = new HeldBlock(var1); + } + + public Vec3D getPlayerVector(float var1) { + Player var4; + float var2 = (var4 = this.minecraft.player).xo + (var4.x - var4.xo) * var1; + float var3 = var4.yo + (var4.y - var4.yo) * var1; + float var5 = var4.zo + (var4.z - var4.zo) * var1; + return new Vec3D(var2, var3, var5); + } + + public void hurtEffect(float var1) { + Player var3; + float var2 = (float)(var3 = this.minecraft.player).hurtTime - var1; + if(var3.health <= 0) { + var1 += (float)var3.deathTime; + GL11.glRotatef(40.0F - 8000.0F / (var1 + 200.0F), 0.0F, 0.0F, 1.0F); + } + + if(var2 >= 0.0F) { + var2 = MathHelper.sin((var2 /= (float)var3.hurtDuration) * var2 * var2 * var2 * 3.1415927F); + var1 = var3.hurtDir; + GL11.glRotatef(-var3.hurtDir, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(-var2 * 14.0F, 0.0F, 0.0F, 1.0F); + GL11.glRotatef(var1, 0.0F, 1.0F, 0.0F); + } + } + + public void applyBobbing(float var1) { + Player var4; + float var2 = (var4 = this.minecraft.player).walkDist - var4.walkDistO; + var2 = var4.walkDist + var2 * var1; + float var3 = var4.oBob + (var4.bob - var4.oBob) * var1; + float var5 = var4.oTilt + (var4.tilt - var4.oTilt) * var1; + GL11.glTranslatef(MathHelper.sin(var2 * 3.1415927F) * var3 * 0.5F, -Math.abs(MathHelper.cos(var2 * 3.1415927F) * var3), 0.0F); + GL11.glRotatef(MathHelper.sin(var2 * 3.1415927F) * var3 * 3.0F, 0.0F, 0.0F, 1.0F); + GL11.glRotatef(Math.abs(MathHelper.cos(var2 * 3.1415927F + 0.2F) * var3) * 5.0F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(var5, 1.0F, 0.0F, 0.0F); + } + + public final void setLighting(boolean var1) { + if(!var1) { + GL11.glDisable(2896); + GL11.glDisable(16384); + } else { + GL11.glEnable(2896); + GL11.glEnable(16384); + GL11.glEnable(2903); + GL11.glColorMaterial(1032, 5634); + float var4 = 0.7F; + float var2 = 0.3F; + Vec3D var3 = (new Vec3D(0.0F, -1.0F, 0.5F)).normalize(); + GL11.glLight(16384, 4611, this.createBuffer(var3.x, var3.y, var3.z, 0.0F)); + GL11.glLight(16384, 4609, this.createBuffer(var2, var2, var2, 1.0F)); + GL11.glLight(16384, 4608, this.createBuffer(0.0F, 0.0F, 0.0F, 1.0F)); + GL11.glLightModel(2899, this.createBuffer(var4, var4, var4, 1.0F)); + } + } + + public final void enableGuiMode() { + int var1 = this.minecraft.width * 240 / this.minecraft.height; + int var2 = this.minecraft.height * 240 / this.minecraft.height; + GL11.glClear(256); + GL11.glMatrixMode(5889); + GL11.glLoadIdentity(); + GL11.glOrtho(0.0D, (double)var1, (double)var2, 0.0D, 100.0D, 300.0D); + GL11.glMatrixMode(5888); + GL11.glLoadIdentity(); + GL11.glTranslatef(0.0F, 0.0F, -200.0F); + } + + public void updateFog() { + Level var1 = this.minecraft.level; + Player var2 = this.minecraft.player; + GL11.glFog(2918, this.createBuffer(this.fogRed, this.fogBlue, this.fogGreen, 1.0F)); + GL11.glNormal3f(0.0F, -1.0F, 0.0F); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + Block var5; + if((var5 = Block.blocks[var1.getTile((int)var2.x, (int)(var2.y + 0.12F), (int)var2.z)]) != null && var5.getLiquidType() != LiquidType.NOT_LIQUID) { + LiquidType var6 = var5.getLiquidType(); + GL11.glFogi(2917, 2048); + float var3; + float var4; + float var7; + float var8; + if(var6 == LiquidType.WATER) { + GL11.glFogf(2914, 0.1F); + var7 = 0.4F; + var8 = 0.4F; + var3 = 0.9F; + if(this.minecraft.settings.anaglyph) { + var4 = (var7 * 30.0F + var8 * 59.0F + var3 * 11.0F) / 100.0F; + var8 = (var7 * 30.0F + var8 * 70.0F) / 100.0F; + var3 = (var7 * 30.0F + var3 * 70.0F) / 100.0F; + var7 = var4; + var8 = var8; + var3 = var3; + } + + GL11.glLightModel(2899, this.createBuffer(var7, var8, var3, 1.0F)); + } else if(var6 == LiquidType.LAVA) { + GL11.glFogf(2914, 2.0F); + var7 = 0.4F; + var8 = 0.3F; + var3 = 0.3F; + if(this.minecraft.settings.anaglyph) { + var4 = (var7 * 30.0F + var8 * 59.0F + var3 * 11.0F) / 100.0F; + var8 = (var7 * 30.0F + var8 * 70.0F) / 100.0F; + var3 = (var7 * 30.0F + var3 * 70.0F) / 100.0F; + var7 = var4; + var8 = var8; + var3 = var3; + } + + GL11.glLightModel(2899, this.createBuffer(var7, var8, var3, 1.0F)); + } + } else { + GL11.glFogi(2917, 9729); + GL11.glFogf(2915, 0.0F); + GL11.glFogf(2916, this.fogEnd); + GL11.glLightModel(2899, this.createBuffer(1.0F, 1.0F, 1.0F, 1.0F)); + } + + GL11.glEnable(2903); + GL11.glColorMaterial(1028, 4608); + } + + private FloatBuffer createBuffer(float var1, float var2, float var3, float var4) { + this.buffer.clear(); + this.buffer.put(var1).put(var2).put(var3).put(var4); + this.buffer.flip(); + return this.buffer; + } +} diff --git a/src/main/java/com/mojang/minecraft/render/ShapeRenderer.java b/src/main/java/com/mojang/minecraft/render/ShapeRenderer.java new file mode 100644 index 0000000..1a484dc --- /dev/null +++ b/src/main/java/com/mojang/minecraft/render/ShapeRenderer.java @@ -0,0 +1,157 @@ +package com.mojang.minecraft.render; + +import java.nio.FloatBuffer; +import org.lwjgl.BufferUtils; +import org.lwjgl.opengl.GL11; + +public final class ShapeRenderer { + + private FloatBuffer buffer = BufferUtils.createFloatBuffer(524288); + private float[] data = new float[524288]; + private int vertices = 0; + private float u; + private float v; + private float r; + private float g; + private float b; + private boolean color = false; + private boolean texture = false; + private int vertexLength = 3; + private int length = 0; + private boolean noColor = false; + public static ShapeRenderer instance = new ShapeRenderer(); + + + public final void end() { + if(this.vertices > 0) { + this.buffer.clear(); + this.buffer.put(this.data, 0, this.length); + this.buffer.flip(); + if(this.texture && this.color) { + GL11.glInterleavedArrays(10794, 0, this.buffer); + } else if(this.texture) { + GL11.glInterleavedArrays(10791, 0, this.buffer); + } else if(this.color) { + GL11.glInterleavedArrays(10788, 0, this.buffer); + } else { + GL11.glInterleavedArrays(10785, 0, this.buffer); + } + + GL11.glEnableClientState('\u8074'); + if(this.texture) { + GL11.glEnableClientState('\u8078'); + } + + if(this.color) { + GL11.glEnableClientState('\u8076'); + } + + GL11.glDrawArrays(7, 0, this.vertices); + GL11.glDisableClientState('\u8074'); + if(this.texture) { + GL11.glDisableClientState('\u8078'); + } + + if(this.color) { + GL11.glDisableClientState('\u8076'); + } + } + + this.clear(); + } + + private void clear() { + this.vertices = 0; + this.buffer.clear(); + this.length = 0; + } + + public final void begin() { + this.clear(); + this.color = false; + this.texture = false; + this.noColor = false; + } + + public final void color(float var1, float var2, float var3) { + if(!this.noColor) { + if(!this.color) { + this.vertexLength += 3; + } + + this.color = true; + this.r = var1; + this.g = var2; + this.b = var3; + } + } + + public final void vertexUV(float var1, float var2, float var3, float var4, float var5) { + if(!this.texture) { + this.vertexLength += 2; + } + + this.texture = true; + this.u = var4; + this.v = var5; + this.vertex(var1, var2, var3); + } + + public final void vertex(float var1, float var2, float var3) { + if(this.texture) { + this.data[this.length++] = this.u; + this.data[this.length++] = this.v; + } + + if(this.color) { + this.data[this.length++] = this.r; + this.data[this.length++] = this.g; + this.data[this.length++] = this.b; + } + + this.data[this.length++] = var1; + this.data[this.length++] = var2; + this.data[this.length++] = var3; + ++this.vertices; + if(this.vertices % 4 == 0 && this.length >= 524288 - (this.vertexLength << 2)) { + this.end(); + } + + } + + public final void color(int var1) { + int var2 = var1 >> 16 & 255; + int var3 = var1 >> 8 & 255; + var1 &= 255; + int var10001 = var2; + int var10002 = var3; + var3 = var1; + var2 = var10002; + var1 = var10001; + byte var7 = (byte)var1; + byte var4 = (byte)var2; + byte var8 = (byte)var3; + byte var6 = var4; + byte var5 = var7; + if(!this.noColor) { + if(!this.color) { + this.vertexLength += 3; + } + + this.color = true; + this.r = (float)(var5 & 255) / 255.0F; + this.g = (float)(var6 & 255) / 255.0F; + this.b = (float)(var8 & 255) / 255.0F; + } + + } + + public final void noColor() { + this.noColor = true; + } + + public final void normal(float var1, float var2, float var3) { + GL11.glNormal3f(var1, var2, var3); + } + +} diff --git a/src/main/java/com/mojang/minecraft/render/TextureManager.java b/src/main/java/com/mojang/minecraft/render/TextureManager.java new file mode 100644 index 0000000..f53e204 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/render/TextureManager.java @@ -0,0 +1,99 @@ +package com.mojang.minecraft.render; + +import com.mojang.minecraft.GameSettings; +import com.mojang.minecraft.render.texture.TextureFX; +import java.awt.Graphics; +import java.awt.image.BufferedImage; +import java.awt.image.ImageObserver; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.IntBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import javax.imageio.ImageIO; +import org.lwjgl.BufferUtils; +import org.lwjgl.opengl.GL11; + +public class TextureManager { + + public HashMap textures = new HashMap(); + public HashMap textureImages = new HashMap(); + public IntBuffer idBuffer = BufferUtils.createIntBuffer(1); + public ByteBuffer textureBuffer = BufferUtils.createByteBuffer(262144); + public List animations = new ArrayList(); + public GameSettings settings; + + + public TextureManager(GameSettings var1) { + this.settings = var1; + } + + public final int load(String var1) { + Integer var2; + if((var2 = (Integer)this.textures.get(var1)) != null) { + return var2.intValue(); + } else { + try { + this.idBuffer.clear(); + GL11.glGenTextures(this.idBuffer); + int var4 = this.idBuffer.get(0); + this.load(ImageIO.read(TextureManager.class.getResourceAsStream(var1)), var4); + this.textures.put(var1, Integer.valueOf(var4)); + return var4; + } catch (IOException var3) { + throw new RuntimeException("!!"); + } + } + } + + public final int load(BufferedImage var1) { + this.idBuffer.clear(); + GL11.glGenTextures(this.idBuffer); + int var2 = this.idBuffer.get(0); + this.load(var1, var2); + this.textureImages.put(Integer.valueOf(var2), var1); + return var2; + } + + public void load(BufferedImage var1, int var2) { + GL11.glBindTexture(3553, var2); + GL11.glTexParameteri(3553, 10241, 9728); + GL11.glTexParameteri(3553, 10240, 9728); + var2 = var1.getWidth(); + int var3 = var1.getHeight(); + int[] var4 = new int[var2 * var3]; + byte[] var5 = new byte[var2 * var3 << 2]; + var1.getRGB(0, 0, var2, var3, var4, 0, var2); + + for(int var11 = 0; var11 < var4.length; ++var11) { + int var6 = var4[var11] >>> 24; + int var7 = var4[var11] >> 16 & 255; + int var8 = var4[var11] >> 8 & 255; + int var9 = var4[var11] & 255; + if(this.settings.anaglyph) { + int var10 = (var7 * 30 + var8 * 59 + var9 * 11) / 100; + var8 = (var7 * 30 + var8 * 70) / 100; + var9 = (var7 * 30 + var9 * 70) / 100; + var7 = var10; + var8 = var8; + var9 = var9; + } + + var5[var11 << 2] = (byte)var7; + var5[(var11 << 2) + 1] = (byte)var8; + var5[(var11 << 2) + 2] = (byte)var9; + var5[(var11 << 2) + 3] = (byte)var6; + } + + this.textureBuffer.clear(); + this.textureBuffer.put(var5); + this.textureBuffer.position(0).limit(var5.length); + GL11.glTexImage2D(3553, 0, 6408, var2, var3, 0, 6408, 5121, this.textureBuffer); + } + + public final void registerAnimation(TextureFX var1) { + this.animations.add(var1); + var1.animate(); + } +} diff --git a/src/main/java/com/mojang/minecraft/render/texture/TextureFX.java b/src/main/java/com/mojang/minecraft/render/texture/TextureFX.java new file mode 100644 index 0000000..f9179bc --- /dev/null +++ b/src/main/java/com/mojang/minecraft/render/texture/TextureFX.java @@ -0,0 +1,17 @@ +package com.mojang.minecraft.render.texture; + +public class TextureFX +{ + public TextureFX(int textureID) + { + this.textureId = textureID; + } + + public byte[] textureData = new byte[1024]; + public int textureId; + public boolean anaglyph = false; + + public void animate() + { + } +} diff --git a/src/main/java/com/mojang/minecraft/render/texture/TextureLavaFX.java b/src/main/java/com/mojang/minecraft/render/texture/TextureLavaFX.java new file mode 100644 index 0000000..8ba098f --- /dev/null +++ b/src/main/java/com/mojang/minecraft/render/texture/TextureLavaFX.java @@ -0,0 +1,87 @@ +package com.mojang.minecraft.render.texture; + +import com.mojang.minecraft.level.tile.Block; +import com.mojang.minecraft.render.texture.TextureFX; +import com.mojang.util.MathHelper; + +public final class TextureLavaFX extends TextureFX { + + private float[] red = new float[256]; + private float[] green = new float[256]; + private float[] blue = new float[256]; + private float[] alpha = new float[256]; + + + public TextureLavaFX() { + super(Block.LAVA.textureId); + } + + public final void animate() { + int var1; + int var2; + float var3; + int var5; + int var6; + int var7; + int var8; + int var9; + for(var1 = 0; var1 < 16; ++var1) { + for(var2 = 0; var2 < 16; ++var2) { + var3 = 0.0F; + int var4 = (int)(MathHelper.sin((float)var2 * 3.1415927F * 2.0F / 16.0F) * 1.2F); + var5 = (int)(MathHelper.sin((float)var1 * 3.1415927F * 2.0F / 16.0F) * 1.2F); + + for(var6 = var1 - 1; var6 <= var1 + 1; ++var6) { + for(var7 = var2 - 1; var7 <= var2 + 1; ++var7) { + var8 = var6 + var4 & 15; + var9 = var7 + var5 & 15; + var3 += this.red[var8 + (var9 << 4)]; + } + } + + this.green[var1 + (var2 << 4)] = var3 / 10.0F + (this.blue[(var1 & 15) + ((var2 & 15) << 4)] + this.blue[(var1 + 1 & 15) + ((var2 & 15) << 4)] + this.blue[(var1 + 1 & 15) + ((var2 + 1 & 15) << 4)] + this.blue[(var1 & 15) + ((var2 + 1 & 15) << 4)]) / 4.0F * 0.8F; + this.blue[var1 + (var2 << 4)] += this.alpha[var1 + (var2 << 4)] * 0.01F; + if(this.blue[var1 + (var2 << 4)] < 0.0F) { + this.blue[var1 + (var2 << 4)] = 0.0F; + } + + this.alpha[var1 + (var2 << 4)] -= 0.06F; + if(Math.random() < 0.005D) { + this.alpha[var1 + (var2 << 4)] = 1.5F; + } + } + } + + float[] var10 = this.green; + this.green = this.red; + this.red = var10; + + for(var2 = 0; var2 < 256; ++var2) { + if((var3 = this.red[var2] * 2.0F) > 1.0F) { + var3 = 1.0F; + } + + if(var3 < 0.0F) { + var3 = 0.0F; + } + + var5 = (int)(var3 * 100.0F + 155.0F); + var6 = (int)(var3 * var3 * 255.0F); + var7 = (int)(var3 * var3 * var3 * var3 * 128.0F); + if(this.anaglyph) { + var8 = (var5 * 30 + var6 * 59 + var7 * 11) / 100; + var9 = (var5 * 30 + var6 * 70) / 100; + var1 = (var5 * 30 + var7 * 70) / 100; + var5 = var8; + var6 = var9; + var7 = var1; + } + + this.textureData[var2 << 2] = (byte)var5; + this.textureData[(var2 << 2) + 1] = (byte)var6; + this.textureData[(var2 << 2) + 2] = (byte)var7; + this.textureData[(var2 << 2) + 3] = -1; + } + + } +} diff --git a/src/main/java/com/mojang/minecraft/render/texture/TextureWaterFX.java b/src/main/java/com/mojang/minecraft/render/texture/TextureWaterFX.java new file mode 100644 index 0000000..777cd82 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/render/texture/TextureWaterFX.java @@ -0,0 +1,90 @@ +package com.mojang.minecraft.render.texture; + +import com.mojang.minecraft.level.tile.Block; +import com.mojang.minecraft.render.texture.TextureFX; + +public final class TextureWaterFX extends TextureFX { + + private float[] red = new float[256]; + private float[] blue = new float[256]; + private float[] green = new float[256]; + private float[] alpha = new float[256]; + private int updates = 0; + + + public TextureWaterFX() { + super(Block.WATER.textureId); + } + + public final void animate() { + ++this.updates; + + int var1; + int var2; + float var3; + int var4; + int var5; + int var6; + for(var1 = 0; var1 < 16; ++var1) { + for(var2 = 0; var2 < 16; ++var2) { + var3 = 0.0F; + + for(var4 = var1 - 1; var4 <= var1 + 1; ++var4) { + var5 = var4 & 15; + var6 = var2 & 15; + var3 += this.red[var5 + (var6 << 4)]; + } + + this.blue[var1 + (var2 << 4)] = var3 / 3.3F + this.green[var1 + (var2 << 4)] * 0.8F; + } + } + + for(var1 = 0; var1 < 16; ++var1) { + for(var2 = 0; var2 < 16; ++var2) { + this.green[var1 + (var2 << 4)] += this.alpha[var1 + (var2 << 4)] * 0.05F; + if(this.green[var1 + (var2 << 4)] < 0.0F) { + this.green[var1 + (var2 << 4)] = 0.0F; + } + + this.alpha[var1 + (var2 << 4)] -= 0.1F; + if(Math.random() < 0.05D) { + this.alpha[var1 + (var2 << 4)] = 0.5F; + } + } + } + + float[] var8 = this.blue; + this.blue = this.red; + this.red = var8; + + for(var2 = 0; var2 < 256; ++var2) { + if((var3 = this.red[var2]) > 1.0F) { + var3 = 1.0F; + } + + if(var3 < 0.0F) { + var3 = 0.0F; + } + + float var9 = var3 * var3; + var5 = (int)(32.0F + var9 * 32.0F); + var6 = (int)(50.0F + var9 * 64.0F); + var1 = 255; + int var10 = (int)(146.0F + var9 * 50.0F); + if(this.anaglyph) { + var1 = (var5 * 30 + var6 * 59 + 2805) / 100; + var4 = (var5 * 30 + var6 * 70) / 100; + int var7 = (var5 * 30 + 17850) / 100; + var5 = var1; + var6 = var4; + var1 = var7; + } + + this.textureData[var2 << 2] = (byte)var5; + this.textureData[(var2 << 2) + 1] = (byte)var6; + this.textureData[(var2 << 2) + 2] = (byte)var1; + this.textureData[(var2 << 2) + 3] = (byte)var10; + } + + } +} diff --git a/src/main/java/com/mojang/minecraft/sound/Audio.java b/src/main/java/com/mojang/minecraft/sound/Audio.java new file mode 100644 index 0000000..dcd4e50 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/sound/Audio.java @@ -0,0 +1,6 @@ +package com.mojang.minecraft.sound; + +public interface Audio +{ + boolean play(int[] var1, int[] var2, int var3); +} diff --git a/src/main/java/com/mojang/minecraft/sound/AudioInfo.java b/src/main/java/com/mojang/minecraft/sound/AudioInfo.java new file mode 100644 index 0000000..a827f21 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/sound/AudioInfo.java @@ -0,0 +1,11 @@ +package com.mojang.minecraft.sound; + +public class AudioInfo +{ + public float volume = 1.0F; + + public int update(short[] var1, int var2) + { + return 0; + } +} diff --git a/src/main/java/com/mojang/minecraft/sound/BaseSoundPos.java b/src/main/java/com/mojang/minecraft/sound/BaseSoundPos.java new file mode 100644 index 0000000..eb16cd9 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/sound/BaseSoundPos.java @@ -0,0 +1,50 @@ +package com.mojang.minecraft.sound; + +import com.mojang.minecraft.Entity; +import com.mojang.util.MathHelper; + +public abstract class BaseSoundPos implements SoundPos +{ + public BaseSoundPos(Entity listener) + { + this.listener = listener; + } + + private Entity listener; + + public float getRotationDiff(float x, float y) + { + x -= listener.x; + y -= listener.z; + + float var3 = MathHelper.sqrt(x * x + y * y); + + x /= var3; + y /= var3; + + if((var3 /= 2.0F) > 1.0F) + { + var3 = 1.0F; + } + + float var4 = MathHelper.cos(-listener.yRot * 0.017453292F + 3.1415927F); + + return (MathHelper.sin(-listener.yRot * 0.017453292F + 3.1415927F) * y - var4 * x) * var3; + } + + public float getDistanceSq(float x, float y, float z) + { + x -= listener.x; + y -= listener.y; + float var4 = z - listener.z; + + var4 = MathHelper.sqrt(x * x + y * y + var4 * var4); + + if((var4 = 1.0F - var4 / 32.0F) < 0.0F) + { + var4 = 0.0F; + } + + return var4; + } +} diff --git a/src/main/java/com/mojang/minecraft/sound/EntitySoundPos.java b/src/main/java/com/mojang/minecraft/sound/EntitySoundPos.java new file mode 100644 index 0000000..56a2767 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/sound/EntitySoundPos.java @@ -0,0 +1,27 @@ +package com.mojang.minecraft.sound; + +import com.mojang.minecraft.Entity; + +public class EntitySoundPos extends BaseSoundPos +{ + public EntitySoundPos(Entity source, Entity listener) + { + super(listener); + + this.source = source; + } + + @Override + public float getRotationDiff() + { + return super.getRotationDiff(source.x, source.z); + } + + @Override + public float getDistanceSq() + { + return super.getDistanceSq(source.x, source.y, source.z); + } + + private Entity source; +} diff --git a/src/main/java/com/mojang/minecraft/sound/LevelSoundPos.java b/src/main/java/com/mojang/minecraft/sound/LevelSoundPos.java new file mode 100644 index 0000000..4afa5bc --- /dev/null +++ b/src/main/java/com/mojang/minecraft/sound/LevelSoundPos.java @@ -0,0 +1,31 @@ +package com.mojang.minecraft.sound; + +import com.mojang.minecraft.Entity; + +public final class LevelSoundPos extends BaseSoundPos +{ + public LevelSoundPos(float x, float y, float z, Entity listener) + { + super(listener); + + this.x = x; + this.y = y; + this.z = z; + } + + @Override + public float getRotationDiff() + { + return super.getRotationDiff(x, z); + } + + @Override + public float getDistanceSq() + { + return super.getDistanceSq(x, y, z); + } + + private float x; + private float y; + private float z; +} diff --git a/src/main/java/com/mojang/minecraft/sound/Music.java b/src/main/java/com/mojang/minecraft/sound/Music.java new file mode 100644 index 0000000..a6bb799 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/sound/Music.java @@ -0,0 +1,80 @@ +package com.mojang.minecraft.sound; + +import de.jarnbjo.ogg.LogicalOggStreamImpl; +import de.jarnbjo.ogg.OggFormatException; +import de.jarnbjo.ogg.OnDemandUrlStream; +import de.jarnbjo.vorbis.VorbisFormatException; +import de.jarnbjo.vorbis.VorbisStream; + +import java.io.IOException; +import java.net.URL; +import java.nio.ByteBuffer; + +// TODO. +public final class Music implements Audio { + + ByteBuffer playing = ByteBuffer.allocate(176400); + ByteBuffer current = ByteBuffer.allocate(176400); + private ByteBuffer processing = null; + ByteBuffer previous = null; + VorbisStream stream; + SoundPlayer player; + boolean finished = false; + boolean stopped = false; + + + public Music(SoundPlayer var1, URL var2) { + this.player = var1; + try + { + LogicalOggStreamImpl var3 = (LogicalOggStreamImpl)(new OnDemandUrlStream(var2)).getLogicalStreams().iterator().next(); + this.stream = new VorbisStream(var3); + } catch (VorbisFormatException e) { + e.printStackTrace(); + } catch (OggFormatException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + (new MusicPlayThread(this)).start(); + } + + public final boolean play(int[] var1, int[] var2, int var3) { + if(!this.player.settings.music) { + this.stopped = true; + return false; + } else { + var3 = var3; + int var4 = 0; + + while(var3 > 0 && (this.processing != null || this.previous != null)) { + if(this.processing == null && this.previous != null) { + this.processing = this.previous; + this.previous = null; + } + + if(this.processing != null && this.processing.remaining() > 0) { + int var5; + if((var5 = this.processing.remaining() / 4) > var3) { + var5 = var3; + } + + for(int var6 = 0; var6 < var5; ++var6) { + var1[var4 + var6] += this.processing.getShort(); + var2[var4 + var6] += this.processing.getShort(); + } + + var4 += var5; + var3 -= var5; + } + + if(this.current == null && this.processing != null && this.processing.remaining() == 0) { + this.current = this.processing; + this.processing = null; + } + } + + return this.processing != null || this.previous != null || !this.finished; + } + } +} diff --git a/src/main/java/com/mojang/minecraft/sound/MusicPlayThread.java b/src/main/java/com/mojang/minecraft/sound/MusicPlayThread.java new file mode 100644 index 0000000..e187931 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/sound/MusicPlayThread.java @@ -0,0 +1,101 @@ +package com.mojang.minecraft.sound; + +import de.jarnbjo.vorbis.VorbisStream; + +import java.nio.ByteBuffer; + +// TODO. +final class MusicPlayThread extends Thread { + + // $FF: synthetic field + private Music music; + + + public MusicPlayThread(Music var1) { + super(); + this.music = var1; + this.setPriority(10); + this.setDaemon(true); + } + + public final void run() { + try { + do { + if(this.music.stopped) { + return; + } + + Music var1 = this.music; + ByteBuffer var2; + Music var10001; + if(this.music.playing == null) { + var1 = this.music; + if(this.music.current != null) { + var1 = this.music; + var2 = this.music.current; + var10001 = this.music; + this.music.playing = var2; + var2 = null; + var1 = this.music; + this.music.current = null; + var1 = this.music; + this.music.playing.clear(); + } + } + + var1 = this.music; + if(this.music.playing != null) { + var1 = this.music; + if(this.music.playing.remaining() != 0) { + while(true) { + var1 = this.music; + if(this.music.playing.remaining() == 0) { + break; + } + + var1 = this.music; + var1 = this.music; + var2 = this.music.playing; + VorbisStream var9 = this.music.stream; + int var10 = this.music.stream.readPcm(var2.array(), var2.position(), var2.remaining()); + var2.position(var2.position() + var10); + boolean var11; + if(var11 = var10 <= 0) { + this.music.finished = true; + this.music.stopped = true; + break; + } + } + } + } + + var1 = this.music; + if(this.music.playing != null) { + var1 = this.music; + if(this.music.previous == null) { + var1 = this.music; + this.music.playing.flip(); + var1 = this.music; + var2 = this.music.playing; + var10001 = this.music; + this.music.previous = var2; + var2 = null; + var1 = this.music; + this.music.playing = var2; + } + } + + Thread.sleep(10L); + var1 = this.music; + } while(this.music.player.running); + + return; + } catch (Exception var7) { + var7.printStackTrace(); + return; + } finally { + this.music.finished = true; + } + + } +} diff --git a/src/main/java/com/mojang/minecraft/sound/Sound.java b/src/main/java/com/mojang/minecraft/sound/Sound.java new file mode 100644 index 0000000..43a9433 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/sound/Sound.java @@ -0,0 +1,62 @@ +package com.mojang.minecraft.sound; + +// TODO. +public final class Sound implements Audio { + + private AudioInfo info; + private SoundPos pos; + private float pitch = 0.0F; + private float volume = 1.0F; + private static short[] data = new short[1]; + + + public Sound(AudioInfo var1, SoundPos var2) { + this.info = var1; + this.pos = var2; + this.pitch = var2.getRotationDiff(); + this.volume = var2.getDistanceSq() * var1.volume; + } + + public final boolean play(int[] var1, int[] var2, int var3) { + if(data.length < var3) { + data = new short[var3]; + } + + int var4; + boolean var5 = (var4 = this.info.update(data, var3)) > 0; + float var6 = this.pos.getRotationDiff(); + float var7 = this.pos.getDistanceSq() * this.info.volume; + int var8 = (int)((this.pitch > 0.0F?1.0F - this.pitch:1.0F) * this.volume * 65536.0F); + int var9 = (int)((this.pitch < 0.0F?1.0F + this.pitch:1.0F) * this.volume * 65536.0F); + int var10 = (int)((var6 > 0.0F?1.0F - var6:1.0F) * var7 * 65536.0F); + int var11 = (int)((var6 < 0.0F?var6 + 1.0F:1.0F) * var7 * 65536.0F); + var10 -= var8; + var11 -= var9; + int var12; + int var13; + int var14; + if(var10 == 0 && var11 == 0) { + if(var8 >= 0 || var9 != 0) { + var12 = var8; + var13 = var9; + + for(var14 = 0; var14 < var4; ++var14) { + var1[var14] += data[var14] * var12 >> 16; + var2[var14] += data[var14] * var13 >> 16; + } + } + } else { + for(var12 = 0; var12 < var4; ++var12) { + var13 = var8 + var10 * var12 / var3; + var14 = var9 + var11 * var12 / var3; + var1[var12] += data[var12] * var13 >> 16; + var2[var12] += data[var12] * var14 >> 16; + } + } + + this.pitch = var6; + this.volume = var7; + return var5; + } + +} diff --git a/src/main/java/com/mojang/minecraft/sound/SoundData.java b/src/main/java/com/mojang/minecraft/sound/SoundData.java new file mode 100644 index 0000000..700b960 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/sound/SoundData.java @@ -0,0 +1,13 @@ +package com.mojang.minecraft.sound; + +public class SoundData +{ + public SoundData(short[] data, float length) + { + this.data = data; + this.length = length; + } + + public short[] data; + public float length; +} diff --git a/src/main/java/com/mojang/minecraft/sound/SoundInfo.java b/src/main/java/com/mojang/minecraft/sound/SoundInfo.java new file mode 100644 index 0000000..e98720f --- /dev/null +++ b/src/main/java/com/mojang/minecraft/sound/SoundInfo.java @@ -0,0 +1,35 @@ +package com.mojang.minecraft.sound; + +// TODO. +public final class SoundInfo extends AudioInfo { + + private SoundData data; + private float seek = 0.0F; + private float pitch; + + + public SoundInfo(SoundData var1, float var2, float var3) { + this.data = var1; + this.pitch = var2 * 44100.0F / var1.length; + this.volume = var3; + } + + public final int update(short[] var1, int var2) { + if(this.seek >= (float)this.data.data.length) { + return 0; + } else { + for(int var3 = 0; var3 < var2; ++var3) { + int var4 = (int)this.seek; + short var5 = this.data.data[var4]; + short var6 = var4 < this.data.data.length - 1?this.data.data[var4 + 1]:0; + var1[var3] = (short)((int)((float)var5 + (float)(var6 - var5) * (this.seek - (float)var4))); + this.seek += this.pitch; + if(this.seek >= (float)this.data.data.length) { + return var3; + } + } + + return var2; + } + } +} diff --git a/src/main/java/com/mojang/minecraft/sound/SoundManager.java b/src/main/java/com/mojang/minecraft/sound/SoundManager.java new file mode 100644 index 0000000..f794e8f --- /dev/null +++ b/src/main/java/com/mojang/minecraft/sound/SoundManager.java @@ -0,0 +1,96 @@ +package com.mojang.minecraft.sound; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.util.*; + +// TODO. +public final class SoundManager { + + private SoundReader reader = new SoundReader(); + public Map sounds = new HashMap(); + private Map music = new HashMap(); + public Random random = new Random(); + public long lastMusic = System.currentTimeMillis() + 60000L; + + + public final AudioInfo getAudioInfo(String var1, float var2, float var3) { + List var4 = null; + Map var5 = this.sounds; + synchronized(this.sounds) { + var4 = (List)this.sounds.get(var1); + } + + if(var4 == null) { + return null; + } else { + SoundData var7 = (SoundData)var4.get(this.random.nextInt(var4.size())); + return new SoundInfo(var7, var3, var2); + } + } + + public void registerSound(File var1, String var2) { + try { + for(var2 = var2.substring(0, var2.length() - 4).replaceAll("/", "."); Character.isDigit(var2.charAt(var2.length() - 1)); var2 = var2.substring(0, var2.length() - 1)) { + ; + } + + SoundData var7 = SoundReader.read(var1.toURI().toURL()); + Map var3 = this.sounds; + synchronized(this.sounds) { + Object var4; + if((var4 = (List)this.sounds.get(var2)) == null) { + var4 = new ArrayList(); + this.sounds.put(var2, var4); + } + + ((List)var4).add(var7); + } + } catch (Exception var6) { + var6.printStackTrace(); + } + + } + + public final void registerMusic(String var1, File var2) { + Map var3 = this.music; + synchronized(this.music) { + for(var1 = var1.substring(0, var1.length() - 4).replaceAll("/", "."); Character.isDigit(var1.charAt(var1.length() - 1)); var1 = var1.substring(0, var1.length() - 1)) { + ; + } + + Object var4; + if((var4 = (List)this.music.get(var1)) == null) { + var4 = new ArrayList(); + this.music.put(var1, var4); + } + + ((List)var4).add(var2); + } + } + + public boolean playMusic(SoundPlayer var1, String var2) { + List var3 = null; + Map var4 = this.music; + synchronized(this.music) { + var3 = (List)this.music.get(var2); + } + + if(var3 == null) { + return false; + } else { + File var8 = (File)var3.get(this.random.nextInt(var3.size())); + + try { + var1.play(new Music(var1, var8.toURI().toURL())); + } catch (MalformedURLException var5) { + var5.printStackTrace(); + } catch (IOException var6) { + var6.printStackTrace(); + } + + return true; + } + } +} diff --git a/src/main/java/com/mojang/minecraft/sound/SoundPlayer.java b/src/main/java/com/mojang/minecraft/sound/SoundPlayer.java new file mode 100644 index 0000000..7a73138 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/sound/SoundPlayer.java @@ -0,0 +1,107 @@ +package com.mojang.minecraft.sound; + +import com.mojang.minecraft.GameSettings; + +import javax.sound.sampled.SourceDataLine; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +// TODO. +public final class SoundPlayer implements Runnable { + + public boolean running = false; + public SourceDataLine dataLine; + private List audioQueue = new ArrayList(); + public GameSettings settings; + + + public SoundPlayer(GameSettings var1) { + this.settings = var1; + } + + public final void play(Audio var1) { + if(this.running) { + List var2 = this.audioQueue; + synchronized(this.audioQueue) { + this.audioQueue.add(var1); + } + } + } + + public final void play(AudioInfo var1, SoundPos var2) { + this.play(new Sound(var1, var2)); + } + + public final void run() { + int[] var1 = new int[4410]; + int[] var2 = new int[4410]; + + for(byte[] var3 = new byte[17640]; this.running; this.dataLine.write(var3, 0, 17640)) { + try { + Thread.sleep(1L); + } catch (InterruptedException var10) { + var10.printStackTrace(); + } + + Arrays.fill(var1, 0, 4410, 0); + Arrays.fill(var2, 0, 4410, 0); + boolean var4 = true; + int[] var5 = var2; + int[] var6 = var1; + List var12 = this.audioQueue; + List var7 = this.audioQueue; + synchronized(this.audioQueue) { + int var8 = 0; + + while(true) { + if(var8 >= var12.size()) { + break; + } + + if(!((Audio)var12.get(var8)).play(var6, var5, 4410)) { + var12.remove(var8--); + } + + ++var8; + } + } + + int var13; + if(!this.settings.music && !this.settings.sound) { + for(var13 = 0; var13 < 4410; ++var13) { + var3[var13 << 2] = 0; + var3[(var13 << 2) + 1] = 0; + var3[(var13 << 2) + 2] = 0; + var3[(var13 << 2) + 3] = 0; + } + } else { + for(var13 = 0; var13 < 4410; ++var13) { + int var15 = var1[var13]; + int var14 = var2[var13]; + if(var15 < -32000) { + var15 = -32000; + } + + if(var14 < -32000) { + var14 = -32000; + } + + if(var15 >= 32000) { + var15 = 32000; + } + + if(var14 >= 32000) { + var14 = 32000; + } + + var3[var13 << 2] = (byte)(var15 >> 8); + var3[(var13 << 2) + 1] = (byte)var15; + var3[(var13 << 2) + 2] = (byte)(var14 >> 8); + var3[(var13 << 2) + 3] = (byte)var14; + } + } + } + + } +} diff --git a/src/main/java/com/mojang/minecraft/sound/SoundPos.java b/src/main/java/com/mojang/minecraft/sound/SoundPos.java new file mode 100644 index 0000000..f425b88 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/sound/SoundPos.java @@ -0,0 +1,8 @@ +package com.mojang.minecraft.sound; + +public interface SoundPos +{ + float getRotationDiff(); + + float getDistanceSq(); +} diff --git a/src/main/java/com/mojang/minecraft/sound/SoundReader.java b/src/main/java/com/mojang/minecraft/sound/SoundReader.java new file mode 100644 index 0000000..ec57429 --- /dev/null +++ b/src/main/java/com/mojang/minecraft/sound/SoundReader.java @@ -0,0 +1,89 @@ +package com.mojang.minecraft.sound; + +import de.jarnbjo.ogg.LogicalOggStreamImpl; +import de.jarnbjo.ogg.OggFormatException; +import de.jarnbjo.ogg.OnDemandUrlStream; +import de.jarnbjo.vorbis.IdentificationHeader; +import de.jarnbjo.vorbis.VorbisFormatException; +import de.jarnbjo.vorbis.VorbisStream; + +import java.io.IOException; +import java.net.URL; + +// TODO. +public final class SoundReader { + + public static SoundData read(URL var0) { + VorbisStream var12 = null; + try + { + LogicalOggStreamImpl var11 = (LogicalOggStreamImpl)(new OnDemandUrlStream(var0)).getLogicalStreams().iterator().next(); + var12 = new VorbisStream(var11); + } catch (VorbisFormatException e) { + e.printStackTrace(); + } catch (OggFormatException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + byte[] var2 = new byte[4096]; + int var3 = 0; + boolean var1 = false; + IdentificationHeader var14 = var12.getIdentificationHeader(); + int var4 = var12.getIdentificationHeader().getChannels(); + short[] var5 = new short[4096]; + int var6 = 0; + + label51: + while(var3 >= 0) { + int var15 = 0; + + while(true) { + try { + if(var15 < var2.length && (var3 = var12.readPcm(var2, var15, var2.length - var15)) > 0) { + var15 += var3; + continue; + } + } catch (Exception var10) { + var3 = -1; + } + + if(var15 <= 0) { + break; + } + + boolean var7 = false; + int var16 = 0; + + while(true) { + if(var16 >= var15) { + continue label51; + } + + int var8 = 0; + + for(int var9 = 0; var9 < var4; ++var9) { + var8 += var2[var16++] << 8 | var2[var16++] & 255; + } + + if(var6 == var5.length) { + short[] var18 = var5; + var5 = new short[var5.length << 1]; + System.arraycopy(var18, 0, var5, 0, var6); + } + + var5[var6++] = (short)(var8 / var4); + } + } + } + + if(var6 != var5.length) { + short[] var17 = var5; + var5 = new short[var6]; + System.arraycopy(var17, 0, var5, 0, var6); + } + + IdentificationHeader var13; + return new SoundData(var5, (float)(var13 = var12.getIdentificationHeader()).getSampleRate()); + } +} diff --git a/src/main/java/com/mojang/net/NetworkHandler.java b/src/main/java/com/mojang/net/NetworkHandler.java new file mode 100644 index 0000000..cb6a88b --- /dev/null +++ b/src/main/java/com/mojang/net/NetworkHandler.java @@ -0,0 +1,164 @@ +package com.mojang.net; + +import com.mojang.minecraft.net.NetworkManager; +import com.mojang.minecraft.net.PacketType; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketException; +import java.nio.ByteBuffer; +import java.nio.channels.SocketChannel; +import java.util.Arrays; + +public final class NetworkHandler { + + public volatile boolean connected; + public SocketChannel channel; + public ByteBuffer in = ByteBuffer.allocate(1048576); + public ByteBuffer out = ByteBuffer.allocate(1048576); + public NetworkManager netManager; + private Socket sock; + private boolean unused = false; + private byte[] stringBytes = new byte[64]; + + + public NetworkHandler(String var1, int var2) { + try + { + channel = SocketChannel.open(); + this.channel.connect(new InetSocketAddress(var1, var2)); + this.channel.configureBlocking(false); + System.currentTimeMillis(); + this.sock = this.channel.socket(); + this.connected = true; + this.in.clear(); + this.out.clear(); + this.sock.setTcpNoDelay(true); + this.sock.setTrafficClass(24); + this.sock.setKeepAlive(false); + this.sock.setReuseAddress(false); + this.sock.setSoTimeout(100); + this.sock.getInetAddress().toString(); + } catch (SocketException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public final void close() { + try { + if(this.out.position() > 0) { + this.out.flip(); + this.channel.write(this.out); + this.out.compact(); + } + } catch (Exception var2) { + ; + } + + this.connected = false; + + try { + this.channel.close(); + } catch (Exception var1) { + ; + } + + this.sock = null; + this.channel = null; + } + + public final void send(PacketType var1, Object ... var2) { + if(this.connected) { + this.out.put(var1.opcode); + + for(int var3 = 0; var3 < var2.length; ++var3) { + Class var10001 = var1.params[var3]; + Object var4 = var2[var3]; + Class var5 = var10001; + NetworkHandler var6 = this; + if(this.connected) { + try { + if(var5 == Long.TYPE) { + var6.out.putLong(((Long)var4).longValue()); + } else if(var5 == Integer.TYPE) { + var6.out.putInt(((Number)var4).intValue()); + } else if(var5 == Short.TYPE) { + var6.out.putShort(((Number)var4).shortValue()); + } else if(var5 == Byte.TYPE) { + var6.out.put(((Number)var4).byteValue()); + } else if(var5 == Double.TYPE) { + var6.out.putDouble(((Double)var4).doubleValue()); + } else if(var5 == Float.TYPE) { + var6.out.putFloat(((Float)var4).floatValue()); + } else { + byte[] var9; + if(var5 != String.class) { + if(var5 == byte[].class) { + if((var9 = (byte[])((byte[])var4)).length < 1024) { + var9 = Arrays.copyOf(var9, 1024); + } + + var6.out.put(var9); + } + } else { + var9 = ((String)var4).getBytes("UTF-8"); + Arrays.fill(var6.stringBytes, (byte)32); + + int var8; + for(var8 = 0; var8 < 64 && var8 < var9.length; ++var8) { + var6.stringBytes[var8] = var9[var8]; + } + + for(var8 = var9.length; var8 < 64; ++var8) { + var6.stringBytes[var8] = 32; + } + + var6.out.put(var6.stringBytes); + } + } + } catch (Exception var7) { + this.netManager.error(var7); + } + } + } + + } + } + + public Object readObject(Class var1) { + if(!this.connected) { + return null; + } else { + try { + if(var1 == Long.TYPE) { + return Long.valueOf(this.in.getLong()); + } else if(var1 == Integer.TYPE) { + return Integer.valueOf(this.in.getInt()); + } else if(var1 == Short.TYPE) { + return Short.valueOf(this.in.getShort()); + } else if(var1 == Byte.TYPE) { + return Byte.valueOf(this.in.get()); + } else if(var1 == Double.TYPE) { + return Double.valueOf(this.in.getDouble()); + } else if(var1 == Float.TYPE) { + return Float.valueOf(this.in.getFloat()); + } else if(var1 == String.class) { + this.in.get(this.stringBytes); + return (new String(this.stringBytes, "UTF-8")).trim(); + } else if(var1 == byte[].class) { + byte[] var3 = new byte[1024]; + this.in.get(var3); + return var3; + } else { + return null; + } + } catch (Exception var2) { + this.netManager.error(var2); + return null; + } + } + } +} diff --git a/src/main/java/com/mojang/util/MathHelper.java b/src/main/java/com/mojang/util/MathHelper.java new file mode 100644 index 0000000..ede92ea --- /dev/null +++ b/src/main/java/com/mojang/util/MathHelper.java @@ -0,0 +1,43 @@ +package com.mojang.util; + +import com.mojang.minecraft.Minecraft; + +public final class MathHelper { + + private static float[] SIN_TABLE = new float[65536]; + private static float[] SIN_TABLE_FAST = new float[4096]; + + public static final float sin(float var0) { + if(Minecraft.settings.ofFastMath) { + return SIN_TABLE_FAST[(int)(var0 * 651.8986F) & 4095]; + } else { + return SIN_TABLE[(int)(var0 * 10430.378F) & '\uffff']; + } + } + + public static final float cos(float var0) { + if(Minecraft.settings.ofFastMath) { + return SIN_TABLE_FAST[(int)((var0 + ((float)Math.PI / 2F)) * 651.8986F) & 4095]; + } else { + return SIN_TABLE[(int)(var0 * 10430.378F + 16384.0F) & '\uffff']; + } + } + + public static final float sqrt(float var0) { + return (float)Math.sqrt((double)var0); + } + + static { + for(int var0 = 0; var0 < 65536; ++var0) { + SIN_TABLE[var0] = (float)Math.sin((double)var0 * 3.141592653589793D * 2.0D / 65536.0D); + } + + for (int j = 0; j < 4096; ++j) { + SIN_TABLE_FAST[j] = (float)Math.sin((double)(((float)j + 0.5F) / 4096.0F * ((float)Math.PI * 2F))); + } + + for (int l = 0; l < 360; l += 90) { + SIN_TABLE_FAST[(int)((float)l * 11.377778F) & 4095] = (float)Math.sin((double)((float)l * 0.017453292F)); + } + } +} diff --git a/src/main/java/de/jarnbjo/ogg/BasicStream.java b/src/main/java/de/jarnbjo/ogg/BasicStream.java new file mode 100644 index 0000000..8f35e15 --- /dev/null +++ b/src/main/java/de/jarnbjo/ogg/BasicStream.java @@ -0,0 +1,107 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: BasicStream.java,v 1.1 2003/08/08 19:48:22 jarnbjo Exp $ + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: BasicStream.java,v $ + * + */ + +package de.jarnbjo.ogg; + +import java.io.*; +import java.net.*; +import java.util.*; + +/** + * Implementation of the PhysicalOggStream interface for reading + * an Ogg stream from a URL. This class performs + * no internal caching, and will not read data from the network before + * requested to do so. It is intended to be used in non-realtime applications + * like file download managers or similar. + */ + +public class BasicStream implements PhysicalOggStream { + + private boolean closed=false; + private InputStream sourceStream; + private Object drainLock=new Object(); + private LinkedList pageCache=new LinkedList(); + private long numberOfSamples=-1; + private int position=0; + + private HashMap logicalStreams=new HashMap(); + private OggPage firstPage; + + public BasicStream(InputStream sourceStream) throws OggFormatException, IOException { + firstPage=OggPage.create(sourceStream); + position+=firstPage.getTotalLength(); + LogicalOggStreamImpl los=new LogicalOggStreamImpl(this, firstPage.getStreamSerialNumber()); + logicalStreams.put(new Integer(firstPage.getStreamSerialNumber()), los); + los.checkFormat(firstPage); + } + + public Collection getLogicalStreams() { + return logicalStreams.values(); + } + + public boolean isOpen() { + return !closed; + } + + public void close() throws IOException { + closed=true; + sourceStream.close(); + } + + public int getContentLength() { + return -1; + } + + public int getPosition() { + return position; + } + + int pageNumber=2; + + public OggPage getOggPage(int index) throws IOException { + if(firstPage!=null) { + OggPage tmp=firstPage; + firstPage=null; + return tmp; + } + else { + OggPage page=OggPage.create(sourceStream); + position+=page.getTotalLength(); + return page; + } + } + + private LogicalOggStream getLogicalStream(int serialNumber) { + return (LogicalOggStream)logicalStreams.get(new Integer(serialNumber)); + } + + public void setTime(long granulePosition) throws IOException { + throw new UnsupportedOperationException("Method not supported by this class"); + } + + /** + * @return always false + */ + + public boolean isSeekable() { + return false; + } + +} \ No newline at end of file diff --git a/src/main/java/de/jarnbjo/ogg/CachedUrlStream.java b/src/main/java/de/jarnbjo/ogg/CachedUrlStream.java new file mode 100644 index 0000000..db126bd --- /dev/null +++ b/src/main/java/de/jarnbjo/ogg/CachedUrlStream.java @@ -0,0 +1,246 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: CachedUrlStream.java,v 1.1 2003/04/10 19:48:22 jarnbjo Exp $ + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: CachedUrlStream.java,v $ + * Revision 1.1 2003/04/10 19:48:22 jarnbjo + * no message + * + * + */ + +package de.jarnbjo.ogg; + +import java.io.*; +import java.net.*; +import java.util.*; + +/** + * Implementation of the PhysicalOggStream interface for reading + * and caching an Ogg stream from a URL. This class reads the data as fast as + * possible from the URL, caches it locally either in memory or on disk, and + * supports seeking within the available data. + */ + +public class CachedUrlStream implements PhysicalOggStream { + + private boolean closed=false; + private URLConnection source; + private InputStream sourceStream; + private Object drainLock=new Object(); + private RandomAccessFile drain; + private byte[] memoryCache; + private ArrayList pageOffsets=new ArrayList(); + private ArrayList pageLengths=new ArrayList(); + private long numberOfSamples=-1; + private long cacheLength; + + private HashMap logicalStreams=new HashMap(); + + private LoaderThread loaderThread; + + /** + * Creates an instance of this class, using a memory cache. + */ + + public CachedUrlStream(URL source) throws OggFormatException, IOException { + this(source, null); + } + + /** + * Creates an instance of this class, using the specified file as cache. The + * file is not automatically deleted when this class is disposed. + */ + + public CachedUrlStream(URL source, RandomAccessFile drain) throws OggFormatException, IOException { + + this.source=source.openConnection(); + + if(drain==null) { + int contentLength=this.source.getContentLength(); + if(contentLength==-1) { + throw new IOException("The URLConncetion's content length must be set when operating with a in-memory cache."); + } + memoryCache=new byte[contentLength]; + } + + this.drain=drain; + this.sourceStream=this.source.getInputStream(); + + loaderThread=new LoaderThread(sourceStream, drain, memoryCache); + new Thread(loaderThread).start(); + + while(!loaderThread.isBosDone() || pageOffsets.size()<20) { + System.out.print("pageOffsets.size(): "+pageOffsets.size()+"\r"); + try { + Thread.sleep(200); + } + catch (InterruptedException ex) { + } + } + System.out.println(); + System.out.println("caching "+pageOffsets.size()+"/20 pages\r"); + } + + public Collection getLogicalStreams() { + return logicalStreams.values(); + } + + public boolean isOpen() { + return !closed; + } + + public void close() throws IOException { + closed=true; + sourceStream.close(); + } + + public long getCacheLength() { + return cacheLength; + } + + /* + private OggPage getNextPage() throws EndOfOggStreamException, IOException, OggFormatException { + return getNextPage(false); + } + + private OggPage getNextPage(boolean skipData) throws EndOfOggStreamException, IOException, OggFormatException { + return OggPage.create(sourceStream, skipData); + } + */ + + public OggPage getOggPage(int index) throws IOException { + synchronized(drainLock) { + Long offset=(Long)pageOffsets.get(index); + Long length=(Long)pageLengths.get(index); + if(offset!=null) { + if(drain!=null) { + drain.seek(offset.longValue()); + return OggPage.create(drain); + } + else { + byte[] tmpArray=new byte[length.intValue()]; + System.arraycopy(memoryCache, offset.intValue(), tmpArray, 0, length.intValue()); + return OggPage.create(tmpArray); + } + } + else { + return null; + } + } + } + + private LogicalOggStream getLogicalStream(int serialNumber) { + return (LogicalOggStream)logicalStreams.get(new Integer(serialNumber)); + } + + public void setTime(long granulePosition) throws IOException { + for(Iterator iter=logicalStreams.values().iterator(); iter.hasNext(); ) { + LogicalOggStream los=(LogicalOggStream)iter.next(); + los.setTime(granulePosition); + } + } + + public class LoaderThread implements Runnable { + + private InputStream source; + private RandomAccessFile drain; + private byte[] memoryCache; + + private boolean bosDone=false; + + private int pageNumber; + + public LoaderThread(InputStream source, RandomAccessFile drain, byte[] memoryCache) { + this.source=source; + this.drain=drain; + this.memoryCache=memoryCache; + } + + public void run() { + try { + boolean eos=false; + byte[] buffer=new byte[8192]; + while(!eos) { + OggPage op=OggPage.create(source); + synchronized (drainLock) { + int listSize=pageOffsets.size(); + + long pos= + listSize>0? + ((Long)pageOffsets.get(listSize-1)).longValue()+ + ((Long)pageLengths.get(listSize-1)).longValue(): + 0; + + byte[] arr1=op.getHeader(); + byte[] arr2=op.getSegmentTable(); + byte[] arr3=op.getData(); + + if(drain!=null) { + drain.seek(pos); + drain.write(arr1); + drain.write(arr2); + drain.write(arr3); + } + else { + System.arraycopy(arr1, 0, memoryCache, (int)pos, arr1.length); + System.arraycopy(arr2, 0, memoryCache, (int)pos+arr1.length, arr2.length); + System.arraycopy(arr3, 0, memoryCache, (int)pos+arr1.length+arr2.length, arr3.length); + } + + pageOffsets.add(new Long(pos)); + pageLengths.add(new Long(arr1.length+arr2.length+arr3.length)); + } + + if(!op.isBos()) { + bosDone=true; + //System.out.println("bosDone=true;"); + } + if(op.isEos()) { + eos=true; + } + + LogicalOggStreamImpl los=(LogicalOggStreamImpl)getLogicalStream(op.getStreamSerialNumber()); + if(los==null) { + los=new LogicalOggStreamImpl(CachedUrlStream.this, op.getStreamSerialNumber()); + logicalStreams.put(new Integer(op.getStreamSerialNumber()), los); + los.checkFormat(op); + } + + los.addPageNumberMapping(pageNumber); + los.addGranulePosition(op.getAbsoluteGranulePosition()); + + pageNumber++; + cacheLength=op.getAbsoluteGranulePosition(); + //System.out.println("read page: "+pageNumber); + } + } + catch(EndOfOggStreamException e) { + // ok + } + catch(IOException e) { + e.printStackTrace(); + } + } + + public boolean isBosDone() { + return bosDone; + } + } + + public boolean isSeekable() { + return true; + } +} \ No newline at end of file diff --git a/src/main/java/de/jarnbjo/ogg/EndOfOggStreamException.java b/src/main/java/de/jarnbjo/ogg/EndOfOggStreamException.java new file mode 100644 index 0000000..19e67de --- /dev/null +++ b/src/main/java/de/jarnbjo/ogg/EndOfOggStreamException.java @@ -0,0 +1,35 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: EndOfOggStreamException.java,v 1.1 2003/03/03 21:02:20 jarnbjo Exp $ + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: EndOfOggStreamException.java,v $ + * Revision 1.1 2003/03/03 21:02:20 jarnbjo + * no message + * + */ + + package de.jarnbjo.ogg; + +import java.io.IOException; + +/** + * Exception thrown when reaching the end of an Ogg stream + */ + +public class EndOfOggStreamException extends IOException { + + public EndOfOggStreamException() { + } +} \ No newline at end of file diff --git a/src/main/java/de/jarnbjo/ogg/FileStream.java b/src/main/java/de/jarnbjo/ogg/FileStream.java new file mode 100644 index 0000000..7d21c1e --- /dev/null +++ b/src/main/java/de/jarnbjo/ogg/FileStream.java @@ -0,0 +1,148 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: FileStream.java,v 1.1 2003/04/10 19:48:22 jarnbjo Exp $ + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: FileStream.java,v $ + * Revision 1.1 2003/04/10 19:48:22 jarnbjo + * no message + * + * + */ + +package de.jarnbjo.ogg; + +import java.io.*; +import java.util.*; + +/** + * Implementation of the PhysicalOggStream interface for accessing + * normal disk files. + */ + +public class FileStream implements PhysicalOggStream { + + private boolean closed=false; + private RandomAccessFile source; + private long[] pageOffsets; + private long numberOfSamples=-1; + + private HashMap logicalStreams=new HashMap(); + + /** + * Creates access to the specified file through the PhysicalOggStream interface. + * The specified source file must have been opened for reading. + * + * @param source the file to read from + * + * @throws OggFormatException if the stream format is incorrect + * @throws IOException if some other IO error occurs when reading the file + */ + + public FileStream(RandomAccessFile source) throws OggFormatException, IOException { + this.source=source; + + ArrayList po=new ArrayList(); + int pageNumber=0; + try { + while(true) { + po.add(new Long(this.source.getFilePointer())); + + // skip data if pageNumber>0 + OggPage op=getNextPage(pageNumber>0); + if(op==null) { + break; + } + + LogicalOggStreamImpl los=(LogicalOggStreamImpl)getLogicalStream(op.getStreamSerialNumber()); + if(los==null) { + los=new LogicalOggStreamImpl(this, op.getStreamSerialNumber()); + logicalStreams.put(new Integer(op.getStreamSerialNumber()), los); + } + + if(pageNumber==0) { + los.checkFormat(op); + } + + los.addPageNumberMapping(pageNumber); + los.addGranulePosition(op.getAbsoluteGranulePosition()); + + if(pageNumber>0) { + this.source.seek(this.source.getFilePointer()+op.getTotalLength()); + } + + pageNumber++; + } + } + catch(EndOfOggStreamException e) { + // ok + } + catch(IOException e) { + throw e; + } + //System.out.println("pageNumber: "+pageNumber); + this.source.seek(0L); + pageOffsets=new long[po.size()]; + int i=0; + Iterator iter=po.iterator(); + while(iter.hasNext()) { + pageOffsets[i++]=((Long)iter.next()).longValue(); + } + } + + public Collection getLogicalStreams() { + return logicalStreams.values(); + } + + public boolean isOpen() { + return !closed; + } + + public void close() throws IOException { + closed=true; + source.close(); + } + + private OggPage getNextPage() throws EndOfOggStreamException, IOException, OggFormatException { + return getNextPage(false); + } + + private OggPage getNextPage(boolean skipData) throws EndOfOggStreamException, IOException, OggFormatException { + return OggPage.create(source, skipData); + } + + public OggPage getOggPage(int index) throws IOException { + source.seek(pageOffsets[index]); + return OggPage.create(source); + } + + private LogicalOggStream getLogicalStream(int serialNumber) { + return (LogicalOggStream)logicalStreams.get(new Integer(serialNumber)); + } + + public void setTime(long granulePosition) throws IOException { + for(Iterator iter=logicalStreams.values().iterator(); iter.hasNext(); ) { + LogicalOggStream los=(LogicalOggStream)iter.next(); + los.setTime(granulePosition); + } + } + + /** + * @return always true + */ + + public boolean isSeekable() { + return true; + } +} \ No newline at end of file diff --git a/src/main/java/de/jarnbjo/ogg/LogicalOggStream.java b/src/main/java/de/jarnbjo/ogg/LogicalOggStream.java new file mode 100644 index 0000000..98f1f6d --- /dev/null +++ b/src/main/java/de/jarnbjo/ogg/LogicalOggStream.java @@ -0,0 +1,145 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: LogicalOggStream.java,v 1.2 2003/04/10 19:48:22 jarnbjo Exp $ + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: LogicalOggStream.java,v $ + * Revision 1.2 2003/04/10 19:48:22 jarnbjo + * no message + * + * Revision 1.1 2003/03/03 21:02:20 jarnbjo + * no message + * + */ + +package de.jarnbjo.ogg; + +import java.io.IOException; + +/** + * Interface providing access to a logical Ogg stream as part of a + * physical Ogg stream. + */ + + +public interface LogicalOggStream { + + public static final String FORMAT_UNKNOWN = "application/octet-stream"; + + public static final String FORMAT_VORBIS = "audio/x-vorbis"; + public static final String FORMAT_FLAC = "audio/x-flac"; + public static final String FORMAT_THEORA = "video/x-theora"; + + /** + * Note: To read from the stream, you must use either + * this method or the method getNextOggPacket. + * Mixing calls to the two methods will cause data corruption. + * + * @return the next Ogg page + * + * @see #getNextOggPacket() + * + * @throws OggFormatException if the ogg stream is corrupted + * @throws IOException if some other IO error occurs + */ + + public OggPage getNextOggPage() throws OggFormatException, IOException; + + /** + * Note: To read from the stream, you must use either + * this method or the method getNextOggPage. + * Mixing calls to the two methods will cause data corruption. + * + * @return the next packet as a byte array + * + * @see #getNextOggPage() + * + * @throws OggFormatException if the ogg stream is corrupted + * @throws IOException if some other IO error occurs + */ + + public byte[] getNextOggPacket() throws OggFormatException, IOException; + + /** + * Checks if this stream is open for reading. + * + * @return true if this stream is open for reading, + * false otherwise + */ + + public boolean isOpen(); + + /** + * Closes this stream. After invoking this method, no further access + * to the streams data is possible. + * + * @throws IOException if an IO error occurs + */ + + public void close() throws IOException; + + /** + * Sets the stream's position to the beginning of the stream. + * This method does not work if the physical Ogg stream is not + * seekable. + * + * @throws OggFormatException if the ogg stream is corrupted + * @throws IOException if some other IO error occurs + */ + + public void reset() throws OggFormatException, IOException; + + /** + * This method does not work if the physical Ogg stream is not + * seekable. + * + * @return the granule position of the last page within + * this stream + */ + + public long getMaximumGranulePosition(); + + /** + * This method is invoked on all logical streams when + * calling the same method on the physical stream. The + * same restrictions as mentioned there apply. + * This method does not work if the physical Ogg stream is not + * seekable. + * + * @param granulePosition + * + * @see PhysicalOggStream#setTime(long) + * + * @throws IOException if an IO error occurs + */ + + public void setTime(long granulePosition) throws IOException; + + /** + * @return the last parsed granule position of this stream + */ + + public long getTime(); + + /** + * @return the content type of this stream + * + * @see #FORMAT_UNKNOWN + * @see #FORMAT_VORBIS + * @see #FORMAT_FLAC + * @see #FORMAT_THEORA + */ + + public String getFormat(); +} \ No newline at end of file diff --git a/src/main/java/de/jarnbjo/ogg/LogicalOggStreamImpl.java b/src/main/java/de/jarnbjo/ogg/LogicalOggStreamImpl.java new file mode 100644 index 0000000..f898f48 --- /dev/null +++ b/src/main/java/de/jarnbjo/ogg/LogicalOggStreamImpl.java @@ -0,0 +1,207 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: LogicalOggStreamImpl.java,v 1.3 2003/03/31 00:23:04 jarnbjo Exp $ + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: LogicalOggStreamImpl.java,v $ + * Revision 1.3 2003/03/31 00:23:04 jarnbjo + * no message + * + * Revision 1.2 2003/03/16 01:11:26 jarnbjo + * no message + * + * Revision 1.1 2003/03/03 21:02:20 jarnbjo + * no message + * + */ + +package de.jarnbjo.ogg; + +import java.io.*; +import java.util.*; + +public class LogicalOggStreamImpl implements LogicalOggStream { + + private PhysicalOggStream source; + private int serialNumber; + + private ArrayList pageNumberMapping=new ArrayList(); + private ArrayList granulePositions=new ArrayList(); + + private int pageIndex=0; + private OggPage currentPage; + private int currentSegmentIndex; + + private boolean open=true; + + private String format=FORMAT_UNKNOWN; + + public LogicalOggStreamImpl(PhysicalOggStream source, int serialNumber) { + this.source=source; + this.serialNumber=serialNumber; + } + + public void addPageNumberMapping(int physicalPageNumber) { + pageNumberMapping.add(new Integer(physicalPageNumber)); + } + + public void addGranulePosition(long granulePosition) { + granulePositions.add(new Long(granulePosition)); + } + + public synchronized void reset() throws OggFormatException, IOException { + currentPage=null; + currentSegmentIndex=0; + pageIndex=0; + } + + public synchronized OggPage getNextOggPage() throws EndOfOggStreamException, OggFormatException, IOException { + if(source.isSeekable()) { + currentPage=source.getOggPage(((Integer)pageNumberMapping.get(pageIndex++)).intValue()); + } + else { + currentPage=source.getOggPage(-1); + } + return currentPage; + } + + public synchronized byte[] getNextOggPacket() throws EndOfOggStreamException, OggFormatException, IOException { + ByteArrayOutputStream res=new ByteArrayOutputStream(); + int segmentLength=0; + + if(currentPage==null) { + currentPage=getNextOggPage(); + } + + do { + if(currentSegmentIndex>=currentPage.getSegmentOffsets().length) { + currentSegmentIndex=0; + + if(!currentPage.isEos()) { + if(source.isSeekable() && pageNumberMapping.size()<=pageIndex) { + while(pageNumberMapping.size()<=pageIndex+10) { + try { + Thread.sleep(1000); + } + catch (InterruptedException ex) { + } + } + } + currentPage=getNextOggPage(); + + if(res.size()==0 && currentPage.isContinued()) { + boolean done=false; + while(!done) { + if(currentPage.getSegmentLengths()[currentSegmentIndex++]!=255) { + done=true; + } + if(currentSegmentIndex>currentPage.getSegmentTable().length) { + currentPage=source.getOggPage(((Integer)pageNumberMapping.get(pageIndex++)).intValue()); + } + } + } + } + else { + throw new EndOfOggStreamException(); + } + } + segmentLength=currentPage.getSegmentLengths()[currentSegmentIndex]; + res.write(currentPage.getData(), currentPage.getSegmentOffsets()[currentSegmentIndex], segmentLength); + currentSegmentIndex++; + } while(segmentLength==255); + + return res.toByteArray(); + } + + public boolean isOpen() { + return open; + } + + public void close() throws IOException { + open=false; + } + + public long getMaximumGranulePosition() { + Long mgp=(Long)granulePositions.get(granulePositions.size()-1); + return mgp.longValue(); + } + + public synchronized long getTime() { + return currentPage!=null?currentPage.getAbsoluteGranulePosition():-1; + } + + public synchronized void setTime(long granulePosition) throws IOException { + + int page=0; + for(page=0; pagegranulePosition) { + break; + } + } + + pageIndex=page; + currentPage=source.getOggPage(((Integer)pageNumberMapping.get(pageIndex++)).intValue()); + currentSegmentIndex=0; + int segmentLength=0; + do { + if(currentSegmentIndex>=currentPage.getSegmentOffsets().length) { + currentSegmentIndex=0; + if(pageIndex>=pageNumberMapping.size()) { + throw new EndOfOggStreamException(); + } + currentPage=source.getOggPage(((Integer)pageNumberMapping.get(pageIndex++)).intValue()); + } + segmentLength=currentPage.getSegmentLengths()[currentSegmentIndex]; + currentSegmentIndex++; + } while(segmentLength==255); + } + + public void checkFormat(OggPage page) { + byte[] data=page.getData(); + + if(data.length>=7 && + data[1]==0x76 && + data[2]==0x6f && + data[3]==0x72 && + data[4]==0x62 && + data[5]==0x69 && + data[6]==0x73) { + + format=FORMAT_VORBIS; + } + else if(data.length>=7 && + data[1]==0x74 && + data[2]==0x68 && + data[3]==0x65 && + data[4]==0x6f && + data[5]==0x72 && + data[6]==0x61) { + + format=FORMAT_THEORA; + } + else if (data.length==4 && + data[0]==0x66 && + data[1]==0x4c && + data[2]==0x61 && + data[3]==0x43) { + + format=FORMAT_FLAC; + } + } + + public String getFormat() { + return format; + } +} \ No newline at end of file diff --git a/src/main/java/de/jarnbjo/ogg/OggFormatException.java b/src/main/java/de/jarnbjo/ogg/OggFormatException.java new file mode 100644 index 0000000..055f146 --- /dev/null +++ b/src/main/java/de/jarnbjo/ogg/OggFormatException.java @@ -0,0 +1,40 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: OggFormatException.java,v 1.1 2003/03/03 21:02:20 jarnbjo Exp $ + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: OggFormatException.java,v $ + * Revision 1.1 2003/03/03 21:02:20 jarnbjo + * no message + * + */ + +package de.jarnbjo.ogg; + +import java.io.IOException; + +/** + * Exception thrown when trying to read a corrupted Ogg stream. + */ + +public class OggFormatException extends IOException { + + public OggFormatException() { + super(); + } + + public OggFormatException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/src/main/java/de/jarnbjo/ogg/OggPage.java b/src/main/java/de/jarnbjo/ogg/OggPage.java new file mode 100644 index 0000000..af9a32f --- /dev/null +++ b/src/main/java/de/jarnbjo/ogg/OggPage.java @@ -0,0 +1,425 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: OggPage.java,v 1.3 2003/04/10 19:48:22 jarnbjo Exp $ + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: OggPage.java,v $ + * Revision 1.3 2003/04/10 19:48:22 jarnbjo + * no message + * + * Revision 1.2 2003/03/31 00:23:04 jarnbjo + * no message + * + * Revision 1.1 2003/03/03 21:02:20 jarnbjo + * no message + * + */ + +package de.jarnbjo.ogg; + +import java.io.*; + +import de.jarnbjo.util.io.*; + +/** + *

An instance of this class represents an ogg page read from an ogg file + * or network stream. It has no public constructor, but instances can be + * created by the create methods, supplying a JMF stream or + * a RandomAccessFile + * which is positioned at the beginning of an Ogg page.

+ * + *

Furtheron, the class provides methods for accessing the raw page data, + * as well as data attributes like segmenting information, sequence number, + * stream serial number, chechsum and wether this page is the beginning or + * end of a logical bitstream (BOS, EOS) and if the page data starts with a + * continued packet or a fresh data packet.

+ */ + +public class OggPage { + + private int version; + private boolean continued, bos, eos; + private long absoluteGranulePosition; + private int streamSerialNumber, pageSequenceNumber, pageCheckSum; + private int[] segmentOffsets; + private int[] segmentLengths; + private int totalLength; + private byte[] header, segmentTable, data; + + protected OggPage() { + } + + private OggPage( + int version, + boolean continued, + boolean bos, + boolean eos, + long absoluteGranulePosition, + int streamSerialNumber, + int pageSequenceNumber, + int pageCheckSum, + int[] segmentOffsets, + int[] segmentLengths, + int totalLength, + byte[] header, + byte[] segmentTable, + byte[] data) { + + this.version=version; + this.continued=continued; + this.bos=bos; + this.eos=eos; + this.absoluteGranulePosition=absoluteGranulePosition; + this.streamSerialNumber=streamSerialNumber; + this.pageSequenceNumber=pageSequenceNumber; + this.pageCheckSum=pageCheckSum; + this.segmentOffsets=segmentOffsets; + this.segmentLengths=segmentLengths; + this.totalLength=totalLength; + this.header=header; + this.segmentTable=segmentTable; + this.data=data; + } + + /** + * this method equals to create(RandomAccessFile source, false) + * + * @see #create(RandomAccessFile, boolean) + */ + + public static OggPage create(RandomAccessFile source) throws IOException, EndOfOggStreamException, OggFormatException { + return create(source, false); + } + + /** + * This method is called to read data from the current position in the + * specified RandomAccessFile and create a new OggPage instance based on the data + * read. If the parameter skipData is set to true, + * the actual page segments (page data) is skipped and not read into + * memory. This mode is useful when scanning through an ogg file to build + * a seek table. + * + * @param source the source from which the ogg page is generated + * @param skipData if set to true, the actual page data is not read into memory + * @return an ogg page created by reading data from the specified source, starting at the current position + * @throws FormatException if the data read from the specified source is not matching the specification for an ogg page + * @throws EndOfStreamException if it is not possible to read an entire ogg page from the specified source + * @throws IOException if some other I/O error is detected when reading from the source + * + * @see #create(RandomAccessFile) + */ + + public static OggPage create(RandomAccessFile source, boolean skipData) throws IOException, EndOfOggStreamException, OggFormatException { + return create((Object)source, skipData); + } + + /** + * this method equals to create(InputStream source, false) + * + * @see #create(InputStream, boolean) + */ + + public static OggPage create(InputStream source) throws IOException, EndOfOggStreamException, OggFormatException { + return create(source, false); + } + + /** + * This method is called to read data from the current position in the + * specified InpuStream and create a new OggPage instance based on the data + * read. If the parameter skipData is set to true, + * the actual page segments (page data) is skipped and not read into + * memory. This mode is useful when scanning through an ogg file to build + * a seek table. + * + * @param source the source from which the ogg page is generated + * @param skipData if set to true, the actual page data is not read into memory + * @return an ogg page created by reading data from the specified source, starting at the current position + * @throws FormatException if the data read from the specified source is not matching the specification for an ogg page + * @throws EndOfStreamException if it is not possible to read an entire ogg page from the specified source + * @throws IOException if some other I/O error is detected when reading from the source + * + * @see #create(InputStream) + */ + + public static OggPage create(InputStream source, boolean skipData) throws IOException, EndOfOggStreamException, OggFormatException { + return create((Object)source, skipData); + } + + /** + * this method equals to create(byte[] source, false) + * + * @see #create(byte[], boolean) + */ + + public static OggPage create(byte[] source) throws IOException, EndOfOggStreamException, OggFormatException { + return create(source, false); + } + + /** + * This method is called to + * create a new OggPage instance based on the specified byte array. + * + * @param source the source from which the ogg page is generated + * @param skipData if set to true, the actual page data is not read into memory + * @return an ogg page created by reading data from the specified source, starting at the current position + * @throws FormatException if the data read from the specified source is not matching the specification for an ogg page + * @throws EndOfStreamException if it is not possible to read an entire ogg page from the specified source + * @throws IOException if some other I/O error is detected when reading from the source + * + * @see #create(byte[]) + */ + + public static OggPage create(byte[] source, boolean skipData) throws IOException, EndOfOggStreamException, OggFormatException { + return create((Object)source, skipData); + } + + private static OggPage create(Object source, boolean skipData) throws IOException, EndOfOggStreamException, OggFormatException { + + try { + int sourceOffset=27; + + byte[] header=new byte[27]; + if(source instanceof RandomAccessFile) { + RandomAccessFile raf=(RandomAccessFile)source; + if(raf.getFilePointer()==raf.length()) { + return null; + } + raf.readFully(header); + } + else if(source instanceof InputStream) { + readFully((InputStream)source, header); + } + else if(source instanceof byte[]) { + System.arraycopy((byte[])source, 0, header, 0, 27); + } + + BitInputStream bdSource=new ByteArrayBitInputStream(header); + + int capture=bdSource.getInt(32); + + if(capture!=0x5367674f) { + //throw new FormatException("Ogg page does not start with 'OggS' (0x4f676753)"); + + /* + ** This condition is IMHO an error, but older Ogg files often contain + ** pages with a different capture than OggS. I am not sure how to + ** manage these pages, but the decoder seems to work properly, if + ** the incorrect capture is simply ignored. + */ + + String cs=Integer.toHexString(capture); + while(cs.length()<8) { + cs="0"+cs; + } + cs=cs.substring(6, 8)+cs.substring(4, 6)+cs.substring(2, 4)+cs.substring(0, 2); + char c1=(char)(Integer.valueOf(cs.substring(0, 2), 16).intValue()); + char c2=(char)(Integer.valueOf(cs.substring(2, 4), 16).intValue()); + char c3=(char)(Integer.valueOf(cs.substring(4, 6), 16).intValue()); + char c4=(char)(Integer.valueOf(cs.substring(6, 8), 16).intValue()); + System.out.println("Ogg packet header is 0x"+cs+" ("+c1+c2+c3+c4+"), should be 0x4f676753 (OggS)"); + } + + int version=bdSource.getInt(8); + byte tmp=(byte)bdSource.getInt(8); + boolean bf1=(tmp&1)!=0; + boolean bos=(tmp&2)!=0; + boolean eos=(tmp&4)!=0; + long absoluteGranulePosition=bdSource.getLong(64); + int streamSerialNumber=bdSource.getInt(32); + int pageSequenceNumber=bdSource.getInt(32); + int pageCheckSum=bdSource.getInt(32); + int pageSegments=bdSource.getInt(8); + + //System.out.println("OggPage: "+streamSerialNumber+" / "+absoluteGranulePosition+" / "+pageSequenceNumber); + + int[] segmentOffsets=new int[pageSegments]; + int[] segmentLengths=new int[pageSegments]; + int totalLength=0; + + byte[] segmentTable=new byte[pageSegments]; + byte[] tmpBuf=new byte[1]; + + for(int i=0; itrue if this page begins with a continued packet + */ + + public boolean isContinued() { + return continued; + } + + /** + * @return true if this page begins with a fresh packet + */ + + public boolean isFresh() { + return !continued; + } + + /** + * @return true if this page is the beginning of a logical stream + */ + + public boolean isBos() { + return bos; + } + + /** + * @return true if this page is the end of a logical stream + */ + + public boolean isEos() { + return eos; + } + +} \ No newline at end of file diff --git a/src/main/java/de/jarnbjo/ogg/OnDemandUrlStream.java b/src/main/java/de/jarnbjo/ogg/OnDemandUrlStream.java new file mode 100644 index 0000000..c57ddf2 --- /dev/null +++ b/src/main/java/de/jarnbjo/ogg/OnDemandUrlStream.java @@ -0,0 +1,121 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: OnDemandUrlStream.java,v 1.1 2003/04/10 19:48:22 jarnbjo Exp $ + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: OnDemandUrlStream.java,v $ + * Revision 1.1 2003/04/10 19:48:22 jarnbjo + * no message + * + * Revision 1.1 2003/03/31 00:23:04 jarnbjo + * no message + * + */ + +package de.jarnbjo.ogg; + +import java.io.*; +import java.net.*; +import java.util.*; + +/** + * Implementation of the PhysicalOggStream interface for reading + * an Ogg stream from a URL. This class performs + * no internal caching, and will not read data from the network before + * requested to do so. It is intended to be used in non-realtime applications + * like file download managers or similar. + */ + +public class OnDemandUrlStream implements PhysicalOggStream { + + private boolean closed=false; + private URLConnection source; + private InputStream sourceStream; + private Object drainLock=new Object(); + private LinkedList pageCache=new LinkedList(); + private long numberOfSamples=-1; + private int contentLength=0; + private int position=0; + + private HashMap logicalStreams=new HashMap(); + private OggPage firstPage; + + private static final int PAGECACHE_SIZE = 20; + + public OnDemandUrlStream(URL source) throws OggFormatException, IOException { + this.source=source.openConnection(); + this.sourceStream=this.source.getInputStream(); + + contentLength=this.source.getContentLength(); + + firstPage=OggPage.create(sourceStream); + position+=firstPage.getTotalLength(); + LogicalOggStreamImpl los=new LogicalOggStreamImpl(this, firstPage.getStreamSerialNumber()); + logicalStreams.put(new Integer(firstPage.getStreamSerialNumber()), los); + los.checkFormat(firstPage); + } + + public Collection getLogicalStreams() { + return logicalStreams.values(); + } + + public boolean isOpen() { + return !closed; + } + + public void close() throws IOException { + closed=true; + sourceStream.close(); + } + + public int getContentLength() { + return contentLength; + } + + public int getPosition() { + return position; + } + + int pageNumber=2; + + public OggPage getOggPage(int index) throws IOException { + if(firstPage!=null) { + OggPage tmp=firstPage; + firstPage=null; + return tmp; + } + else { + OggPage page=OggPage.create(sourceStream); + position+=page.getTotalLength(); + return page; + } + } + + private LogicalOggStream getLogicalStream(int serialNumber) { + return (LogicalOggStream)logicalStreams.get(new Integer(serialNumber)); + } + + public void setTime(long granulePosition) throws IOException { + throw new UnsupportedOperationException("Method not supported by this class"); + } + + /** + * @return always false + */ + + public boolean isSeekable() { + return false; + } + +} \ No newline at end of file diff --git a/src/main/java/de/jarnbjo/ogg/PhysicalOggStream.java b/src/main/java/de/jarnbjo/ogg/PhysicalOggStream.java new file mode 100644 index 0000000..698d09a --- /dev/null +++ b/src/main/java/de/jarnbjo/ogg/PhysicalOggStream.java @@ -0,0 +1,118 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: PhysicalOggStream.java,v 1.3 2003/04/10 19:48:22 jarnbjo Exp $ + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: PhysicalOggStream.java,v $ + * Revision 1.3 2003/04/10 19:48:22 jarnbjo + * no message + * + * Revision 1.2 2003/03/31 00:23:04 jarnbjo + * no message + * + * Revision 1.1 2003/03/03 21:02:20 jarnbjo + * no message + * + */ + +package de.jarnbjo.ogg; + +import java.io.IOException; +import java.util.Collection; + +/** + * Interface providing access to a physical Ogg stream. Typically this is + * a file. + */ + +public interface PhysicalOggStream { + + /** + * Returns a collection of objects implementing LogicalOggStream + * for accessing the separate logical streams within this physical Ogg stream. + * + * @return a collection of objects implementing LogicalOggStream + * which are representing the logical streams contained within this + * physical stream + * + * @see LogicalOggStream + */ + + public Collection getLogicalStreams(); + + /** + * Return the Ogg page with the absolute index index, + * independent from the logical structure of this stream or if the + * index parameter is -1, the next Ogg page is returned. + * This method should only be used by implementations of LogicalOggStream + * to access the raw pages. + * + * @param index the absolute index starting from 0 at the beginning of + * the file or stream or -1 to get the next page in a non-seekable + * stream + * + * @return the Ogg page with the physical absolute index index + * + * @throws OggFormatException if the ogg stream is corrupted + * @throws IOException if some other IO error occurs + */ + + public OggPage getOggPage(int index) throws OggFormatException, IOException; + + /** + * Checks if this stream is open for reading. + * + * @return true if this stream is open for reading, + * false otherwise + */ + + public boolean isOpen(); + + /** + * Closes this stream. After invoking this method, no further access + * to the streams data is possible. + * + * @throws IOException + */ + + public void close() throws IOException; + + /** + * Sets this stream's (and its logical stream's) position to the granule + * position. The next packet read from any logical stream will be the + * first packet beginning on the first page with a granule position higher + * than the argument.

+ * + * At the moment, this method only works correctly for Ogg files with + * a single logical Vorbis stream, and due to the different interpretations + * of the granule position, depending on mixed content, this method will + * never be able to work for mixed streams. Chained and interleaved streams are + * also not yet supported. Actually, this method is only a hack to support + * seeking from JMF, but may of course be abused otherwise too :) + * + * @param granulePosition + * + * @throws OggFormatException if the ogg stream is corrupted + * @throws IOException if some other IO error occurs + */ + + public void setTime(long granulePosition) throws OggFormatException, IOException; + + /** + * @return true if the stream is seekable, false + * otherwise + */ + + public boolean isSeekable(); +} \ No newline at end of file diff --git a/src/main/java/de/jarnbjo/ogg/UncachedUrlStream.java b/src/main/java/de/jarnbjo/ogg/UncachedUrlStream.java new file mode 100644 index 0000000..6ecffa6 --- /dev/null +++ b/src/main/java/de/jarnbjo/ogg/UncachedUrlStream.java @@ -0,0 +1,201 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: UncachedUrlStream.java,v 1.1 2003/04/10 19:48:22 jarnbjo Exp $ + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: UncachedUrlStream.java,v $ + * Revision 1.1 2003/04/10 19:48:22 jarnbjo + * no message + * + */ + +package de.jarnbjo.ogg; + +import java.io.*; +import java.net.*; +import java.util.*; + +/** + * Implementation of the PhysicalOggStream interface for reading + * an Ogg stream from a URL. This class performs only the necessary caching + * to provide continous playback. Seeking within the stream is not supported. + */ + +public class UncachedUrlStream implements PhysicalOggStream { + + private boolean closed=false; + private URLConnection source; + private InputStream sourceStream; + private Object drainLock=new Object(); + private LinkedList pageCache=new LinkedList(); + private long numberOfSamples=-1; + + private HashMap logicalStreams=new HashMap(); + + private LoaderThread loaderThread; + + private static final int PAGECACHE_SIZE = 10; + + /** Creates an instance of the PhysicalOggStream interface + * suitable for reading an Ogg stream from a URL. + */ + + public UncachedUrlStream(URL source) throws OggFormatException, IOException { + + this.source=source.openConnection(); + this.sourceStream=this.source.getInputStream(); + + loaderThread=new LoaderThread(sourceStream, pageCache); + new Thread(loaderThread).start(); + + while(!loaderThread.isBosDone() || pageCache.size()PAGECACHE_SIZE) { + try { + Thread.sleep(200); + } + catch (InterruptedException ex) { + } + } + } + } + catch(EndOfOggStreamException e) { + // ok + } + catch(IOException e) { + e.printStackTrace(); + } + } + + public boolean isBosDone() { + return bosDone; + } + } + + /** + * @return always false + */ + + public boolean isSeekable() { + return false; + } + +} \ No newline at end of file diff --git a/src/main/java/de/jarnbjo/util/audio/FadeableAudioInputStream.java b/src/main/java/de/jarnbjo/util/audio/FadeableAudioInputStream.java new file mode 100644 index 0000000..4916102 --- /dev/null +++ b/src/main/java/de/jarnbjo/util/audio/FadeableAudioInputStream.java @@ -0,0 +1,62 @@ +package de.jarnbjo.util.audio; + +import java.io.*; +import javax.sound.sampled.*; + +public class FadeableAudioInputStream extends AudioInputStream { + + private AudioInputStream stream; + private boolean fading=false; + private double phi=0.0; + + public FadeableAudioInputStream(AudioInputStream stream) throws IOException { + super(stream, stream.getFormat(), -1L); + } + + public void fadeOut() { + fading=true; + phi=0.0; + } + + public int read(byte[] b) throws IOException { + return read(b, 0, b.length); + } + + public int read(byte[] b, int offset, int length) throws IOException { + int read=super.read(b, offset, length); + + //System.out.println("read "+read); + + if(fading) { + int j=0, l=0, r=0; + double gain=0.0; + + for(int i=offset; i>8)&0xff); + b[j++]=(byte)(r&0xff); + b[j++]=(byte)((r>>8)&0xff); + } + } + + return read; + } + +} \ No newline at end of file diff --git a/src/main/java/de/jarnbjo/util/io/BitInputStream.java b/src/main/java/de/jarnbjo/util/io/BitInputStream.java new file mode 100644 index 0000000..1f31092 --- /dev/null +++ b/src/main/java/de/jarnbjo/util/io/BitInputStream.java @@ -0,0 +1,179 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: BitInputStream.java,v 1.5 2003/04/10 19:48:31 jarnbjo Exp $ + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: BitInputStream.java,v $ + * Revision 1.5 2003/04/10 19:48:31 jarnbjo + * no message + * + * Revision 1.4 2003/03/16 20:57:06 jarnbjo + * no message + * + * Revision 1.3 2003/03/16 20:56:56 jarnbjo + * no message + * + * Revision 1.2 2003/03/16 01:11:39 jarnbjo + * no message + * + * Revision 1.1 2003/03/03 21:02:20 jarnbjo + * no message + * + */ + +package de.jarnbjo.util.io; + +import java.io.IOException; + +/** + * An interface with methods allowing bit-wise reading from + * an input stream. All methods in this interface are optional + * and an implementation not support a method or a specific state + * (e.g. endian) will throw an UnspportedOperationException if + * such a method is being called. This should be speicified in + * the implementation documentation. + */ + +public interface BitInputStream { + + /** + * constant for setting this stream's mode to little endian + * + * @see #setEndian(int) + */ + + public static final int LITTLE_ENDIAN = 0; + + /** + * constant for setting this stream's mode to big endian + * + * @see #setEndian(int) + */ + + public static final int BIG_ENDIAN = 1; + + /** + * reads one bit (as a boolean) from the input stream + * + * @return true if the next bit is 1, + * false otherwise + * + * @throws IOException if an I/O error occurs + * @throws UnsupportedOperationException if the method is not supported by the implementation + */ + + public boolean getBit() throws IOException; + + /** + * reads bits number of bits from the input + * stream + * + * @return the unsigned integer value read from the stream + * + * @throws IOException if an I/O error occurs + * @throws UnsupportedOperationException if the method is not supported by the implementation + */ + + public int getInt(int bits) throws IOException; + + /** + * reads bits number of bits from the input + * stream + * + * @return the signed integer value read from the stream + * + * @throws IOException if an I/O error occurs + * @throws UnsupportedOperationException if the method is not supported by the implementation + */ + + public int getSignedInt(int bits) throws IOException; + + /** + * reads a huffman codeword based on the root + * parameter and returns the decoded value + * + * @param root the root of the Huffman tree used to decode the codeword + * @return the decoded unsigned integer value read from the stream + * + * @throws IOException if an I/O error occurs + * @throws UnsupportedOperationException if the method is not supported by the implementation + */ + + public int getInt(HuffmanNode root) throws IOException; + + /** + * reads an integer encoded as "signed rice" as described in + * the FLAC audio format specification + * + * @param order + * @return the decoded integer value read from the stream + * + * @throws IOException if an I/O error occurs + * @throws UnsupportedOperationException if the method is not supported by the implementation + */ + + public int readSignedRice(int order) throws IOException; + + /** + * fills the array from offset with len + * integers encoded as "signed rice" as described in + * the FLAC audio format specification + * + * @param order + * @param buffer + * @param offset + * @param len + * @return the decoded integer value read from the stream + * + * @throws IOException if an I/O error occurs + * @throws UnsupportedOperationException if the method is not supported by the implementation + */ + + public void readSignedRice(int order, int[] buffer, int offset, int len) throws IOException; + + /** + * reads bits number of bits from the input + * stream + * + * @return the unsigned long value read from the stream + * + * @throws IOException if an I/O error occurs + * @throws UnsupportedOperationException if the method is not supported by the implementation + */ + + public long getLong(int bits) throws IOException; + + /** + * causes the read pointer to be moved to the beginning + * of the next byte, remaining bits in the current byte + * are discarded + * + * @throws UnsupportedOperationException if the method is not supported by the implementation + */ + + public void align(); + + /** + * changes the endian mode used when reading bit-wise from + * the stream, changing the mode mid-stream will cause the + * read cursor to move to the beginning of the next byte + * (as if calling the allign method + * + * @see #align() + * + * @throws UnsupportedOperationException if the method is not supported by the implementation + */ + + public void setEndian(int endian); +} \ No newline at end of file diff --git a/src/main/java/de/jarnbjo/util/io/ByteArrayBitInputStream.java b/src/main/java/de/jarnbjo/util/io/ByteArrayBitInputStream.java new file mode 100644 index 0000000..c62483f --- /dev/null +++ b/src/main/java/de/jarnbjo/util/io/ByteArrayBitInputStream.java @@ -0,0 +1,346 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: ByteArrayBitInputStream.java,v 1.3 2003/04/10 19:48:31 jarnbjo Exp $ + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: ByteArrayBitInputStream.java,v $ + * Revision 1.3 2003/04/10 19:48:31 jarnbjo + * no message + * + * Revision 1.2 2003/03/16 01:11:39 jarnbjo + * no message + * + * Revision 1.1 2003/03/03 21:02:20 jarnbjo + * no message + * + */ + +package de.jarnbjo.util.io; + +import java.io.IOException; + +/** + * Implementation of the BitInputStream interface, + * using a byte array as data source. +*/ + +public class ByteArrayBitInputStream implements BitInputStream { + + private byte[] source; + private byte currentByte; + + private int endian; + + private int byteIndex=0; + private int bitIndex=0; + + public ByteArrayBitInputStream(byte[] source) { + this(source, LITTLE_ENDIAN); + } + + public ByteArrayBitInputStream(byte[] source, int endian) { + this.endian=endian; + this.source=source; + currentByte=source[0]; + bitIndex=(endian==LITTLE_ENDIAN)?0:7; + } + + public boolean getBit() throws IOException { + if(endian==LITTLE_ENDIAN) { + if(bitIndex>7) { + bitIndex=0; + currentByte=source[++byteIndex]; + } + return (currentByte&(1<<(bitIndex++)))!=0; + } + else { + if(bitIndex<0) { + bitIndex=7; + currentByte=source[++byteIndex]; + } + return (currentByte&(1<<(bitIndex--)))!=0; + } + } + + public int getInt(int bits) throws IOException { + if(bits>32) { + throw new IllegalArgumentException("Argument \"bits\" must be <= 32"); + } + int res=0; + if(endian==LITTLE_ENDIAN) { + for(int i=0; i>offset; + bitIndex-=bits; + } + else { + res=(((int)currentByte)&0xff&((1<<(bitIndex+1))-1))<<(bits-bitIndex-1); + bits-=bitIndex+1; + currentByte=source[++byteIndex]; + while(bits>=8) { + bits-=8; + res|=(((int)source[byteIndex])&0xff)<0) { + int ci=((int)source[byteIndex])&0xff; + res|=(ci>>(8-bits))&((1<=1<<(bits-1)) { + raw-=1<7) { + bitIndex=0; + currentByte=source[++byteIndex]; + } + root=(currentByte&(1<<(bitIndex++)))!=0?root.o1:root.o0; + } + return root.value.intValue(); + } + + public long getLong(int bits) throws IOException { + if(bits>64) { + throw new IllegalArgumentException("Argument \"bits\" must be <= 64"); + } + long res=0; + if(endian==LITTLE_ENDIAN) { + for(int i=0; i=0; i--) { + if(getBit()) { + res|=(1L<reads an integer encoded as "signed rice" as described in + * the FLAC audio format specification

+ * + *

not supported for little endian

+ * + * @param order + * @return the decoded integer value read from the stream + * + * @throws IOException if an I/O error occurs + * @throws UnsupportedOperationException if the method is not supported by the implementation + */ + + public int readSignedRice(int order) throws IOException { + + int msbs=-1, lsbs=0, res=0; + + if(endian==LITTLE_ENDIAN) { + // little endian + throw new UnsupportedOperationException("ByteArrayBitInputStream.readSignedRice() is only supported in big endian mode"); + } + else { + // big endian + + byte cb=source[byteIndex]; + do { + msbs++; + if(bitIndex<0) { + bitIndex=7; + byteIndex++; + cb=source[byteIndex]; + } + } while((cb&(1<>offset; + bitIndex-=bits; + } + else { + lsbs=(((int)source[byteIndex])&0xff&((1<<(bitIndex+1))-1))<<(bits-bitIndex-1); + bits-=bitIndex+1; + byteIndex++; + while(bits>=8) { + bits-=8; + lsbs|=(((int)source[byteIndex])&0xff)<0) { + int ci=((int)source[byteIndex])&0xff; + lsbs|=(ci>>(8-bits))&((1<>1)-1:(res>>1); + } + + /** + *

fills the array from offset with len + * integers encoded as "signed rice" as described in + * the FLAC audio format specification

+ * + *

not supported for little endian

+ * + * @param order + * @param buffer + * @param offset + * @param len + * @return the decoded integer value read from the stream + * + * @throws IOException if an I/O error occurs + * @throws UnsupportedOperationException if the method is not supported by the implementation + */ + + public void readSignedRice(int order, int[] buffer, int off, int len) throws IOException { + + if(endian==LITTLE_ENDIAN) { + // little endian + throw new UnsupportedOperationException("ByteArrayBitInputStream.readSignedRice() is only supported in big endian mode"); + } + else { + // big endian + for(int i=off; i>offset; + bitIndex-=bits; + } + else { + lsbs=(((int)source[byteIndex])&0xff&((1<<(bitIndex+1))-1))<<(bits-bitIndex-1); + bits-=bitIndex+1; + byteIndex++; + while(bits>=8) { + bits-=8; + lsbs|=(((int)source[byteIndex])&0xff)<0) { + int ci=((int)source[byteIndex])&0xff; + lsbs|=(ci>>(8-bits))&((1<>1)-1:(res>>1); + } + } + } + + public void align() { + if(endian==BIG_ENDIAN && bitIndex>=0) { + bitIndex=7; + byteIndex++; + } + else if(endian==LITTLE_ENDIAN && bitIndex<=7) { + bitIndex=0; + byteIndex++; + } + } + + public void setEndian(int endian) { + if(this.endian==BIG_ENDIAN && endian==LITTLE_ENDIAN) { + bitIndex=0; + byteIndex++; + } + else if(this.endian==LITTLE_ENDIAN && endian==BIG_ENDIAN) { + bitIndex=7; + byteIndex++; + } + this.endian=endian; + } + + /** + * @return the byte array used as a source for this instance + */ + + public byte[] getSource() { + return source; + } +} \ No newline at end of file diff --git a/src/main/java/de/jarnbjo/util/io/HuffmanNode.java b/src/main/java/de/jarnbjo/util/io/HuffmanNode.java new file mode 100644 index 0000000..9528a62 --- /dev/null +++ b/src/main/java/de/jarnbjo/util/io/HuffmanNode.java @@ -0,0 +1,138 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: HuffmanNode.java,v 1.2 2003/04/10 19:48:31 jarnbjo Exp $ + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: HuffmanNode.java,v $ + * Revision 1.2 2003/04/10 19:48:31 jarnbjo + * no message + * + */ + +package de.jarnbjo.util.io; + +import java.io.IOException; +import de.jarnbjo.util.io.BitInputStream; + +/** + * Representation of a node in a Huffman tree, used to read + * Huffman compressed codewords from e.g. a Vorbis stream. + */ + +final public class HuffmanNode { + + private HuffmanNode parent; + private int depth=0; + protected HuffmanNode o0, o1; + protected Integer value; + private boolean full=false; + + /** + * creates a new Huffman tree root node + */ + + public HuffmanNode() { + this(null); + } + + protected HuffmanNode(HuffmanNode parent) { + this.parent=parent; + if(parent!=null) { + depth=parent.getDepth()+1; + } + } + + protected HuffmanNode(HuffmanNode parent, int value) { + this(parent); + this.value=new Integer(value); + full=true; + } + + protected int read(BitInputStream bis) throws IOException { + HuffmanNode iter=this; + while(iter.value==null) { + iter=bis.getBit()?iter.o1:iter.o0; + } + return iter.value.intValue(); + } + + protected HuffmanNode get0() { + return o0==null?set0(new HuffmanNode(this)):o0; + } + + protected HuffmanNode get1() { + return o1==null?set1(new HuffmanNode(this)):o1; + } + + protected Integer getValue() { + return value; + } + + private HuffmanNode getParent() { + return parent; + } + + protected int getDepth() { + return depth; + } + + private boolean isFull() { + return full?true:(full=o0!=null&&o0.isFull()&&o1!=null&&o1.isFull()); + } + + private HuffmanNode set0(HuffmanNode value) { + return o0=value; + } + + private HuffmanNode set1(HuffmanNode value) { + return o1=value; + } + + private void setValue(Integer value) { + full=true; + this.value=value; + } + + /** + * creates a new tree node at the first free location at the given + * depth, and assigns the value to it + * + * @param depth the tree depth of the new node (codeword length in bits) + * @param value the node's new value + */ + + public boolean setNewValue(int depth, int value) { + if(isFull()) { + return false; + } + if(depth==1) { + if(o0==null) { + set0(new HuffmanNode(this, value)); + return true; + } + else if(o1==null) { + set1(new HuffmanNode(this, value)); + return true; + } + else { + return false; + } + } + else { + return get0().setNewValue(depth-1, value)? + true: + get1().setNewValue(depth-1, value); + } + } +} diff --git a/src/main/java/de/jarnbjo/vorbis/AudioPacket.java b/src/main/java/de/jarnbjo/vorbis/AudioPacket.java new file mode 100644 index 0000000..88e0c4d --- /dev/null +++ b/src/main/java/de/jarnbjo/vorbis/AudioPacket.java @@ -0,0 +1,320 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: AudioPacket.java,v 1.2 2003/03/16 01:11:12 jarnbjo Exp $ + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: AudioPacket.java,v $ + * Revision 1.2 2003/03/16 01:11:12 jarnbjo + * no message + * + * + */ + +package de.jarnbjo.vorbis; + +import java.io.IOException; +import java.util.*; + +import de.jarnbjo.util.io.*; + +class AudioPacket { + + private int modeNumber; + private Mode mode; + private Mapping mapping; + private int n; // block size + private boolean blockFlag, previousWindowFlag, nextWindowFlag; + + private int windowCenter, leftWindowStart, leftWindowEnd, leftN, rightWindowStart, rightWindowEnd, rightN; + private float[] window; + private float[][] pcm; + private int[][] pcmInt; + + private Floor[] channelFloors; + private boolean[] noResidues; + + private final static float[][] windows=new float[8][]; + + protected AudioPacket(final VorbisStream vorbis, final BitInputStream source) throws VorbisFormatException, IOException { + + final SetupHeader sHeader=vorbis.getSetupHeader(); + final IdentificationHeader iHeader=vorbis.getIdentificationHeader(); + final Mode[] modes=sHeader.getModes(); + final Mapping[] mappings=sHeader.getMappings(); + final Residue[] residues=sHeader.getResidues(); + final int channels=iHeader.getChannels(); + + if(source.getInt(1)!=0) { + throw new VorbisFormatException("Packet type mismatch when trying to create an audio packet."); + } + + modeNumber=source.getInt(Util.ilog(modes.length-1)); + + try { + mode=modes[modeNumber]; + } + catch(ArrayIndexOutOfBoundsException e) { + throw new VorbisFormatException("Reference to invalid mode in audio packet."); + } + + mapping=mappings[mode.getMapping()]; + + final int[] magnitudes=mapping.getMagnitudes(); + final int[] angles=mapping.getAngles(); + + blockFlag=mode.getBlockFlag(); + + final int blockSize0=iHeader.getBlockSize0(); + final int blockSize1=iHeader.getBlockSize1(); + + n=blockFlag?blockSize1:blockSize0; + + if(blockFlag) { + previousWindowFlag=source.getBit(); + nextWindowFlag=source.getBit(); + } + + windowCenter=n/2; + + if(blockFlag && !previousWindowFlag) { + leftWindowStart=n/4-blockSize0/4; + leftWindowEnd=n/4+blockSize0/4; + leftN=blockSize0/2; + } + else { + leftWindowStart=0; + leftWindowEnd=n/2; + leftN=windowCenter; + } + + if(blockFlag && !nextWindowFlag) { + rightWindowStart=n*3/4-blockSize0/4; + rightWindowEnd=n*3/4+blockSize0/4; + rightN=blockSize0/2; + } + else { + rightWindowStart=windowCenter; + rightWindowEnd=n; + rightN=n/2; + } + + window=getComputedWindow();//new double[n]; + + channelFloors=new Floor[channels]; + noResidues=new boolean[channels]; + + pcm=new float[channels][n]; + pcmInt=new int[channels][n]; + + boolean allFloorsEmpty=true; + + for(int i=0; i=0; i--) { + double newA=0, newM=0; + final float[] magnitudeVector=pcm[magnitudes[i]]; + final float[] angleVector=pcm[angles[i]]; + for(int j=0; j0) { + //magnitudeVector[j]=m; + angleVector[j]=m>0?m-a:m+a; + } + else { + magnitudeVector[j]=m>0?m+a:m-a; + angleVector[j]=m; + } + } + } + + for(int i=0; i32767) val=32767; + if(val<-32768) val=-32768; + target[j1++]=val; + } + } + + // use System.arraycopy to copy the middle part (if any) + // of the window + if(leftWindowEnd+132767) val=32767; + if(val<-32768) val=-32768; + buffer[ix+(i*2)+1]=(byte)(val&0xff); + buffer[ix+(i*2)]=(byte)((val>>8)&0xff); + ix+=channels*2; + } + + ix=(leftWindowEnd-leftWindowStart)*channels*2; + for(int j=leftWindowEnd; j32767) val=32767; + if(val<-32768) val=-32768; + buffer[ix+(i*2)+1]=(byte)(val&0xff); + buffer[ix+(i*2)]=(byte)((val>>8)&0xff); + ix+=channels*2; + } + } + } + + protected float[] getWindow() { + return window; + } + + protected int getLeftWindowStart() { + return leftWindowStart; + } + + protected int getLeftWindowEnd() { + return leftWindowEnd; + } + + protected int getRightWindowStart() { + return rightWindowStart; + } + + protected int getRightWindowEnd() { + return rightWindowEnd; + } + + public int[][] getPcm() { + return pcmInt; + } + + public float[][] getFreqencyDomain() { + return pcm; + } +} diff --git a/src/main/java/de/jarnbjo/vorbis/CodeBook.java b/src/main/java/de/jarnbjo/vorbis/CodeBook.java new file mode 100644 index 0000000..46133f4 --- /dev/null +++ b/src/main/java/de/jarnbjo/vorbis/CodeBook.java @@ -0,0 +1,267 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: CodeBook.java,v 1.3 2003/04/10 19:49:04 jarnbjo Exp $ + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: CodeBook.java,v $ + * Revision 1.3 2003/04/10 19:49:04 jarnbjo + * no message + * + * Revision 1.2 2003/03/16 01:11:12 jarnbjo + * no message + * + * + */ + +package de.jarnbjo.vorbis; + +import java.io.*; + +import java.text.*; +import java.util.*; + +import de.jarnbjo.util.io.*; + +class CodeBook { + + private HuffmanNode huffmanRoot; + private int dimensions, entries; + + private int[] entryLengths; + private float[][] valueVector; + + protected CodeBook(BitInputStream source) throws VorbisFormatException, IOException { + + // check sync + if(source.getInt(24)!=0x564342) { + throw new VorbisFormatException("The code book sync pattern is not correct."); + } + + dimensions=source.getInt(16); + entries=source.getInt(24); + + entryLengths=new int[entries]; + + boolean ordered=source.getBit(); + + if(ordered) { + int cl=source.getInt(5)+1; + for(int i=0; ientryLengths.length) { + throw new VorbisFormatException("The codebook entry length list is longer than the actual number of entry lengths."); + } + Arrays.fill(entryLengths, i, i+num, cl); + cl++; + i+=num; + } + } + else { + // !ordered + boolean sparse=source.getBit(); + + if(sparse) { + for(int i=0; i0) { + if(!huffmanRoot.setNewValue(el, i)) { + return false; + } + } + } + return true; + } + + protected int getDimensions() { + return dimensions; + } + + protected int getEntries() { + return entries; + } + + protected HuffmanNode getHuffmanRoot() { + return huffmanRoot; + } + + //public float[] readVQ(ReadableBitChannel source) throws IOException { + // return valueVector[readInt(source)]; + //} + + protected int readInt(final BitInputStream source) throws IOException { + return source.getInt(huffmanRoot); + /* + HuffmanNode node; + for(node=huffmanRoot; node.value==null; node=source.getBit()?node.o1:node.o0); + return node.value.intValue(); + */ + } + + protected void readVvAdd(float[][] a, BitInputStream source, int offset, int length) + throws VorbisFormatException, IOException { + + int i,j;//k;//entry; + int chptr=0; + int ch=a.length; + + if(ch==0) { + return; + } + + int lim=(offset+length)/ch; + + for(i=offset/ch;i8){ + for(i=0;iheader.getCodeBooks().length) { + throw new VorbisFormatException("A floor0_book_list entry is higher than the code book count."); + } + } + } + + protected int getType() { + return 0; + } + + protected Floor decodeFloor(VorbisStream vorbis, BitInputStream source) throws VorbisFormatException, IOException { + /** @todo implement */ + throw new UnsupportedOperationException(); + } + + protected void computeFloor(float[] vector) { + /** @todo implement */ + throw new UnsupportedOperationException(); + } + +} \ No newline at end of file diff --git a/src/main/java/de/jarnbjo/vorbis/Floor1.java b/src/main/java/de/jarnbjo/vorbis/Floor1.java new file mode 100644 index 0000000..b95f6d9 --- /dev/null +++ b/src/main/java/de/jarnbjo/vorbis/Floor1.java @@ -0,0 +1,318 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: Floor1.java,v 1.2 2003/03/16 01:11:12 jarnbjo Exp $multip + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: Floor1.java,v $ + * Revision 1.2 2003/03/16 01:11:12 jarnbjo + * no message + * + * + */ + +package de.jarnbjo.vorbis; + +import java.io.IOException; +import java.util.*; + +import de.jarnbjo.util.io.BitInputStream; + + +class Floor1 extends Floor implements Cloneable { + + private int[] partitionClassList; + private int maximumClass, multiplier, rangeBits; + private int[] classDimensions; + private int[] classSubclasses; + private int[] classMasterbooks; + private int[][] subclassBooks; + private int[] xList; + private int[] yList; + private int[] lowNeighbours, highNeighbours; + //private boolean[] step2Flags; + + private static final int[] RANGES = {256, 128, 86, 64}; + + private Floor1() { + } + + protected Floor1(BitInputStream source, SetupHeader header) throws VorbisFormatException, IOException { + + maximumClass=-1; + int partitions=source.getInt(5); + partitionClassList=new int[partitions]; + + for(int i=0; imaximumClass) { + maximumClass=partitionClassList[i]; + } + } + + + classDimensions=new int[maximumClass+1]; + classSubclasses=new int[maximumClass+1]; + classMasterbooks=new int[maximumClass+1]; + subclassBooks=new int[maximumClass+1][]; + + int xListLength=2; + + for(int i=0; i<=maximumClass; i++) { + classDimensions[i]=source.getInt(3)+1; + xListLength+=classDimensions[i]; + classSubclasses[i]=source.getInt(2); + + if(classDimensions[i] > header.getCodeBooks().length || + classSubclasses[i] > header.getCodeBooks().length) { + throw new VorbisFormatException("There is a class dimension or class subclasses entry higher than the number of codebooks in the setup header."); + } + if(classSubclasses[i]!=0) { + classMasterbooks[i]=source.getInt(8); + } + subclassBooks[i]=new int[1<0) { + cval=source.getInt(vorbis.getSetupHeader().getCodeBooks()[classMasterbooks[cls]].getHuffmanRoot()); + //cval=vorbis.getSetupHeader().getCodeBooks()[classMasterbooks[cls]].readInt(source); + //System.out.println("cval: "+cval); + } + //System.out.println("0: "+cls+" "+cdim+" "+cbits+" "+csub+" "+cval); + for(int j=0; j>>=cbits; + if(book>=0) { + clone.yList[j+offset]=source.getInt(vorbis.getSetupHeader().getCodeBooks()[book].getHuffmanRoot()); + //clone.yList[j+offset]=vorbis.getSetupHeader().getCodeBooks()[book].readInt(source); + //System.out.println("b: "+(j+offset)+" "+book+" "+clone.yList[j+offset]); + //System.out.println(""); + } + else { + clone.yList[j+offset]=0; + } + } + offset+=cdim; + } + + //System.out.println(""); + //for(int i=0; i=room) { + yList[i]=highRoom>lowRoom? + val-lowRoom+predicted: + -val+highRoom+predicted-1; + } + else { + yList[i]=(val&1)==1? + predicted-((val+1)>>1): + predicted+(val>>1); + } + } + else { + step2Flags[i]=false; + yList[i]=predicted; + } + } + + final int[] xList2=new int[values]; + + System.arraycopy(xList, 0, xList2, 0, values); + sort(xList2, yList, step2Flags); + + int hx=0, hy=0, lx=0, ly=yList[0]*multiplier; + + float[] vector2=new float[vector.length]; + float[] vector3=new float[vector.length]; + Arrays.fill(vector2, 1.0f); + System.arraycopy(vector, 0, vector3, 0, vector.length); + + for(int i=1; ioff && x[j-1]>x[j]; j--) { + itmp=x[j]; + x[j]=x[j-1]; + x[j-1]=itmp; + itmp=y[j]; + y[j]=y[j-1]; + y[j-1]=itmp; + btmp=b[j]; + b[j]=b[j-1]; + b[j-1]=btmp; + //swap(x, j, j-1); + //swap(y, j, j-1); + //swap(b, j, j-1); + } + } + } + + private final static void swap(int x[], int a, int b) { + int t = x[a]; + x[a] = x[b]; + x[b] = t; + } + + private final static void swap(boolean x[], int a, int b) { + boolean t = x[a]; + x[a] = x[b]; + x[b] = t; + } +} \ No newline at end of file diff --git a/src/main/java/de/jarnbjo/vorbis/Floor1.java~1~ b/src/main/java/de/jarnbjo/vorbis/Floor1.java~1~ new file mode 100644 index 0000000..bd6d21a --- /dev/null +++ b/src/main/java/de/jarnbjo/vorbis/Floor1.java~1~ @@ -0,0 +1,318 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: Floor1.java,v 1.2 2003/03/16 01:11:12 jarnbjo Exp $ + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: Floor1.java,v $ + * Revision 1.2 2003/03/16 01:11:12 jarnbjo + * no message + * + * + */ + +package de.jarnbjo.vorbis; + +import java.io.IOException; +import java.util.*; + +import de.jarnbjo.util.io.BitInputStream; + + +class Floor1 extends Floor implements Cloneable { + + private int[] partitionClassList; + private int maximumClass, multiplier, rangeBits; + private int[] classDimensions; + private int[] classSubclasses; + private int[] classMasterbooks; + private int[][] subclassBooks; + private int[] xList; + private int[] yList; + private int[] lowNeighbours, highNeighbours; + //private boolean[] step2Flags; + + private static final int[] RANGES = {256, 128, 86, 64}; + + private Floor1() { + } + + protected Floor1(BitInputStream source, SetupHeader header) throws VorbisFormatException, IOException { + + maximumClass=-1; + int partitions=source.getInt(5); + partitionClassList=new int[partitions]; + + for(int i=0; imaximumClass) { + maximumClass=partitionClassList[i]; + } + } + + + classDimensions=new int[maximumClass+1]; + classSubclasses=new int[maximumClass+1]; + classMasterbooks=new int[maximumClass+1]; + subclassBooks=new int[maximumClass+1][]; + + int xListLength=2; + + for(int i=0; i<=maximumClass; i++) { + classDimensions[i]=source.getInt(3)+1; + xListLength+=classDimensions[i]; + classSubclasses[i]=source.getInt(2); + + if(classDimensions[i] > header.getCodeBooks().length || + classSubclasses[i] > header.getCodeBooks().length) { + throw new VorbisFormatException("There is a class dimension or class subclasses entry higher than the number of codebooks in the setup header."); + } + if(classSubclasses[i]!=0) { + classMasterbooks[i]=source.getInt(8); + } + subclassBooks[i]=new int[1<0) { + cval=source.getInt(vorbis.getSetupHeader().getCodeBooks()[classMasterbooks[cls]].getHuffmanRoot()); + //cval=vorbis.getSetupHeader().getCodeBooks()[classMasterbooks[cls]].readInt(source); + //System.out.println("cval: "+cval); + } + //System.out.println("0: "+cls+" "+cdim+" "+cbits+" "+csub+" "+cval); + for(int j=0; j>>=cbits; + if(book>=0) { + clone.yList[j+offset]=source.getInt(vorbis.getSetupHeader().getCodeBooks()[book].getHuffmanRoot()); + //clone.yList[j+offset]=vorbis.getSetupHeader().getCodeBooks()[book].readInt(source); + //System.out.println("b: "+(j+offset)+" "+book+" "+clone.yList[j+offset]); + //System.out.println(""); + } + else { + clone.yList[j+offset]=0; + } + } + offset+=cdim; + } + + //System.out.println(""); + //for(int i=0; i=room) { + yList[i]=highRoom>lowRoom? + val-lowRoom+predicted: + -val+highRoom+predicted-1; + } + else { + yList[i]=(val&1)==1? + predicted-((val+1)>>1): + predicted+(val>>1); + } + } + else { + step2Flags[i]=false; + yList[i]=predicted; + } + } + + final int[] xList2=new int[values]; + + System.arraycopy(xList, 0, xList2, 0, values); + sort(xList2, yList, step2Flags); + + int hx=0, hy=0, lx=0, ly=yList[0]*multiplier; + + float[] vector2=new float[vector.length]; + float[] vector3=new float[vector.length]; + Arrays.fill(vector2, 1.0f); + System.arraycopy(vector, 0, vector3, 0, vector.length); + + for(int i=1; ioff && x[j-1]>x[j]; j--) { + itmp=x[j]; + x[j]=x[j-1]; + x[j-1]=itmp; + itmp=y[j]; + y[j]=y[j-1]; + y[j-1]=itmp; + btmp=b[j]; + b[j]=b[j-1]; + b[j-1]=btmp; + //swap(x, j, j-1); + //swap(y, j, j-1); + //swap(b, j, j-1); + } + } + } + + private final static void swap(int x[], int a, int b) { + int t = x[a]; + x[a] = x[b]; + x[b] = t; + } + + private final static void swap(boolean x[], int a, int b) { + boolean t = x[a]; + x[a] = x[b]; + x[b] = t; + } +} \ No newline at end of file diff --git a/src/main/java/de/jarnbjo/vorbis/IdentificationHeader.java b/src/main/java/de/jarnbjo/vorbis/IdentificationHeader.java new file mode 100644 index 0000000..c0a4568 --- /dev/null +++ b/src/main/java/de/jarnbjo/vorbis/IdentificationHeader.java @@ -0,0 +1,116 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: IdentificationHeader.java,v 1.3 2003/03/31 00:20:16 jarnbjo Exp $ + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: IdentificationHeader.java,v $ + * Revision 1.3 2003/03/31 00:20:16 jarnbjo + * no message + * + * Revision 1.2 2003/03/16 01:11:12 jarnbjo + * no message + * + * + */ + +package de.jarnbjo.vorbis; + +import java.io.*; + +import de.jarnbjo.util.io.BitInputStream; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.event.*; + +/** + */ + +public class IdentificationHeader { + + private int version, channels, sampleRate, bitrateMaximum, bitrateNominal, bitrateMinimum, blockSize0, blockSize1; + private boolean framingFlag; + private MdctFloat[] mdct=new MdctFloat[2]; + //private MdctLong[] mdctInt=new MdctLong[2]; + + private static final long HEADER = 0x736962726f76L; // 'vorbis' + + public IdentificationHeader(BitInputStream source) throws VorbisFormatException, IOException { + //equalizer=new Equalizer(); + //equalizer.pack(); + //equalizer.show(); + + long leading=source.getLong(48); + if(leading!=HEADER) { + throw new VorbisFormatException("The identification header has an illegal leading."); + } + version=source.getInt(32); + channels=source.getInt(8); + sampleRate=source.getInt(32); + bitrateMaximum=source.getInt(32); + bitrateNominal=source.getInt(32); + bitrateMinimum=source.getInt(32); + int bs=source.getInt(8); + blockSize0=1<<(bs&0xf); + blockSize1=1<<(bs>>4); + + mdct[0]=new MdctFloat(blockSize0); + mdct[1]=new MdctFloat(blockSize1); + //mdctInt[0]=new MdctLong(blockSize0); + //mdctInt[1]=new MdctLong(blockSize1); + + framingFlag=source.getInt(8)!=0; + } + + public int getSampleRate() { + return sampleRate; + } + + public int getMaximumBitrate() { + return bitrateMaximum; + } + + public int getNominalBitrate() { + return bitrateNominal; + } + + public int getMinimumBitrate() { + return bitrateMinimum; + } + + public int getChannels() { + return channels; + } + + public int getBlockSize0() { + return blockSize0; + } + + public int getBlockSize1() { + return blockSize1; + } + + protected MdctFloat getMdct0() { + return mdct[0]; + } + + protected MdctFloat getMdct1() { + return mdct[1]; + } + + public int getVersion() { + return version; + } +} \ No newline at end of file diff --git a/src/main/java/de/jarnbjo/vorbis/Mapping.java b/src/main/java/de/jarnbjo/vorbis/Mapping.java new file mode 100644 index 0000000..964be87 --- /dev/null +++ b/src/main/java/de/jarnbjo/vorbis/Mapping.java @@ -0,0 +1,53 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: Mapping.java,v 1.2 2003/03/16 01:11:12 jarnbjo Exp $ + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: Mapping.java,v $ + * Revision 1.2 2003/03/16 01:11:12 jarnbjo + * no message + * + * + */ + +package de.jarnbjo.vorbis; + +import java.io.IOException; + +import de.jarnbjo.util.io.BitInputStream; + +abstract class Mapping { + + protected static Mapping createInstance(VorbisStream vorbis, BitInputStream source, SetupHeader header) throws VorbisFormatException, IOException { + + int type=source.getInt(16); + switch(type) { + case 0: + //System.out.println("mapping type 0"); + return new Mapping0(vorbis, source, header); + default: + throw new VorbisFormatException("Mapping type "+type+" is not supported."); + } + } + + protected abstract int getType(); + protected abstract int[] getAngles(); + protected abstract int[] getMagnitudes() ; + protected abstract int[] getMux(); + protected abstract int[] getSubmapFloors(); + protected abstract int[] getSubmapResidues(); + protected abstract int getCouplingSteps(); + protected abstract int getSubmaps(); + +} \ No newline at end of file diff --git a/src/main/java/de/jarnbjo/vorbis/Mapping0.java b/src/main/java/de/jarnbjo/vorbis/Mapping0.java new file mode 100644 index 0000000..a24dc51 --- /dev/null +++ b/src/main/java/de/jarnbjo/vorbis/Mapping0.java @@ -0,0 +1,140 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: Mapping0.java,v 1.2 2003/03/16 01:11:12 jarnbjo Exp $ + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: Mapping0.java,v $ + * Revision 1.2 2003/03/16 01:11:12 jarnbjo + * no message + * + * + */ + +package de.jarnbjo.vorbis; + +import java.io.IOException; + +import de.jarnbjo.util.io.BitInputStream; + +class Mapping0 extends Mapping { + + private int[] magnitudes, angles, mux, submapFloors, submapResidues; + + protected Mapping0(VorbisStream vorbis, BitInputStream source, SetupHeader header) throws VorbisFormatException, IOException { + + int submaps=1; + + if(source.getBit()) { + submaps=source.getInt(4)+1; + } + + //System.out.println("submaps: "+submaps); + + int channels=vorbis.getIdentificationHeader().getChannels(); + int ilogChannels=Util.ilog(channels-1); + + //System.out.println("ilogChannels: "+ilogChannels); + + if(source.getBit()) { + int couplingSteps=source.getInt(8)+1; + magnitudes=new int[couplingSteps]; + angles=new int[couplingSteps]; + + for(int i=0; i=channels || angles[i]>=channels) { + System.err.println(magnitudes[i]); + System.err.println(angles[i]); + throw new VorbisFormatException("The channel magnitude and/or angle mismatch."); + } + } + } + else { + magnitudes=new int[0]; + angles=new int[0]; + } + + if(source.getInt(2)!=0) { + throw new VorbisFormatException("A reserved mapping field has an invalid value."); + } + + mux=new int[channels]; + if(submaps>1) { + for(int i=0; isubmaps) { + throw new VorbisFormatException("A mapping mux value is higher than the number of submaps"); + } + } + } + else { + for(int i=0; ifloorCount) { + throw new VorbisFormatException("A mapping floor value is higher than the number of floors."); + } + + if(submapResidues[i]>residueCount) { + throw new VorbisFormatException("A mapping residue value is higher than the number of residues."); + } + } + } + + protected int getType() { + return 0; + } + + protected int[] getAngles() { + return angles; + } + + protected int[] getMagnitudes() { + return magnitudes; + } + + protected int[] getMux() { + return mux; + } + + protected int[] getSubmapFloors() { + return submapFloors; + } + + protected int[] getSubmapResidues() { + return submapResidues; + } + + protected int getCouplingSteps() { + return angles.length; + } + + protected int getSubmaps() { + return submapFloors.length; + } +} \ No newline at end of file diff --git a/src/main/java/de/jarnbjo/vorbis/MdctFloat.java b/src/main/java/de/jarnbjo/vorbis/MdctFloat.java new file mode 100644 index 0000000..0c4836f --- /dev/null +++ b/src/main/java/de/jarnbjo/vorbis/MdctFloat.java @@ -0,0 +1,312 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: MdctFloat.java,v 1.3 2003/04/10 19:49:04 jarnbjo Exp $ + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: MdctFloat.java,v $ + * Revision 1.3 2003/04/10 19:49:04 jarnbjo + * no message + * + * Revision 1.2 2003/03/16 01:11:12 jarnbjo + * no message + * + * + */ + +package de.jarnbjo.vorbis; + +class MdctFloat { + static private final float cPI3_8=0.38268343236508977175f; + static private final float cPI2_8=0.70710678118654752441f; + static private final float cPI1_8=0.92387953251128675613f; + + private int n; + private int log2n; + + private float[] trig; + private int[] bitrev; + + private float[] equalizer; + + private float scale; + + private int itmp1, itmp2, itmp3, itmp4, itmp5, itmp6, itmp7, itmp8, itmp9; + private float dtmp1, dtmp2, dtmp3, dtmp4, dtmp5, dtmp6, dtmp7, dtmp8, dtmp9; + + protected MdctFloat(int n) { + bitrev=new int[n/4]; + trig=new float[n+n/4]; + + int n2=n>>>1; + log2n=(int)Math.rint(Math.log(n)/Math.log(2)); + this.n=n; + + int AE=0; + int AO=1; + int BE=AE+n/2; + int BO=BE+1; + int CE=BE+n/2; + int CO=CE+1; + // trig lookups... + for(int i=0;i>>j!=0;j++) + if(((msb>>>j)&i)!=0)acc|=1<>1; + int n4=n>>2; + int n8=n>>3; + + if(equalizer!=null) { + for(int i=0; i32767.0f) temp1=32767.0f; + //if(temp1<-32768.0f) temp1=-32768.0f; + //if(temp2>32767.0f) temp2=32767.0f; + //if(temp2<-32768.0f) temp2=-32768.0f; + + pcm[o1]=(int)(-temp1*window[o1]); + pcm[o2]=(int)( temp1*window[o2]); + pcm[o3]=(int)( temp2*window[o3]); + pcm[o4]=(int)( temp2*window[o4]); + + o1++; + o2--; + o3++; + o4--; + //xx+=2; + //B+=2; + } + } + } + + private float[] kernel(float[] x, float[] w, + int n, int n2, int n4, int n8){ + // step 2 + + int xA=n4; + int xB=0; + int w2=n4; + int A=n2; + + for(int i=0;i>>(i+2); + int k1=1<<(i+3); + int wbase=n2-2; + + A=0; + float[] temp; + + for(int r=0;r<(k0>>>2);r++){ + int w1=wbase; + w2=w1-(k0>>1); + float AEv= trig[A],wA; + float AOv= trig[A+1],wB; + wbase-=2; + + k0++; + for(int s=0;s<(2<header.getMappings().length) { + throw new VorbisFormatException("Mode mapping number is higher than total number of mappings."); + } + } + + protected boolean getBlockFlag() { + return blockFlag; + } + + protected int getWindowType() { + return windowType; + } + + protected int getTransformType() { + return transformType; + } + + protected int getMapping() { + return mapping; + } +} \ No newline at end of file diff --git a/src/main/java/de/jarnbjo/vorbis/Residue.java b/src/main/java/de/jarnbjo/vorbis/Residue.java new file mode 100644 index 0000000..e79fc75 --- /dev/null +++ b/src/main/java/de/jarnbjo/vorbis/Residue.java @@ -0,0 +1,254 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: Residue.java,v 1.3 2003/04/04 08:33:02 jarnbjo Exp $ + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: Residue.java,v $ + * Revision 1.3 2003/04/04 08:33:02 jarnbjo + * no message + * + * Revision 1.2 2003/03/16 01:11:12 jarnbjo + * no message + * + * + */ + +package de.jarnbjo.vorbis; + +import java.io.IOException; +import java.util.HashMap; + +import de.jarnbjo.util.io.*; + + +abstract class Residue { + + protected int begin, end; + protected int partitionSize; // grouping + protected int classifications; // partitions + protected int classBook; // groupbook + protected int[] cascade; // secondstages + protected int[][] books; + protected HashMap looks=new HashMap(); + + protected Residue() { + } + + protected Residue(BitInputStream source, SetupHeader header) throws VorbisFormatException, IOException { + begin=source.getInt(24); + end=source.getInt(24); + partitionSize=source.getInt(24)+1; + classifications=source.getInt(6)+1; + classBook=source.getInt(8); + + cascade=new int[classifications]; + + int acc=0; + + for(int i=0; iheader.getCodeBooks().length) { + throw new VorbisFormatException("Reference to invalid codebook entry in residue header."); + } + } + } + } + } + + + protected static Residue createInstance(BitInputStream source, SetupHeader header) throws VorbisFormatException, IOException { + + int type=source.getInt(16); + switch(type) { + case 0: + //System.out.println("residue type 0"); + return new Residue0(source, header); + case 1: + //System.out.println("residue type 1"); + return new Residue2(source, header); + case 2: + //System.out.println("residue type 2"); + return new Residue2(source, header); + default: + throw new VorbisFormatException("Residue type "+type+" is not supported."); + } + } + + protected abstract int getType(); + protected abstract void decodeResidue(VorbisStream vorbis, BitInputStream source, Mode mode, int ch, boolean[] doNotDecodeFlags, float[][] vectors) throws VorbisFormatException, IOException; + //public abstract double[][] getDecodedVectors(); + + protected int getBegin() { + return begin; + } + + protected int getEnd() { + return end; + } + + protected int getPartitionSize() { + return partitionSize; + } + + protected int getClassifications() { + return classifications; + } + + protected int getClassBook() { + return classBook; + } + + protected int[] getCascade() { + return cascade; + } + + protected int[][] getBooks() { + return books; + } + + protected final void fill(Residue clone) { + clone.begin=begin; + clone.books=books; + clone.cascade=cascade; + clone.classBook=classBook; + clone.classifications=classifications; + clone.end=end; + clone.partitionSize=partitionSize; + } + + protected Look getLook(VorbisStream source, Mode key) { + //return new Look(source, key); + Look look=(Look)looks.get(key); + if(look==null) { + look=new Look(source, key); + looks.put(key, look); + } + return look; + } + + + class Look { + int map; + int parts; + int stages; + CodeBook[] fullbooks; + CodeBook phrasebook; + int[][] partbooks; + int partvals; + int[][] decodemap; + int postbits; + int phrasebits; + int frames; + + protected Look (VorbisStream source, Mode mode) { + int dim=0, acc=0, maxstage=0; + + map=mode.getMapping(); + parts=Residue.this.getClassifications(); + fullbooks=source.getSetupHeader().getCodeBooks(); + phrasebook=fullbooks[Residue.this.getClassBook()]; + dim=phrasebook.getDimensions(); + + partbooks=new int[parts][]; + + for(int j=0;jmaxstage) { + maxstage=stages; + } + partbooks[j]=new int[stages]; + for(int k=0; k0; x>>=1, res++); + return res; + } + + public static final float float32unpack(int x) { + float mantissa=x&0x1fffff; + float e=(x&0x7fe00000)>>21; + if((x&0x80000000)!=0) { + mantissa=-mantissa; + } + return mantissa*(float)Math.pow(2.0, e-788.0); + } + + public static final int lookup1Values(int a, int b) { + int res=(int)Math.pow(Math.E, Math.log(a)/b); + return intPow(res+1, b)<=a?res+1:res; + } + + public static final int intPow(int base, int e) { + int res=1; + for(; e>0; e--, res*=base); + return res; + } + + public static final boolean isBitSet(int value, int bit) { + return (value&(1<0) { + res+=value&1; + value>>=1; + } + return res; + } + + public static final int lowNeighbour(int[] v, int x) { + int max=-1, n=0; + for(int i=0; imax && v[i]v[x]) { + min=v[i]; + n=i; + } + } + return n; + } + + public static final int renderPoint(int x0, int x1, int y0, int y1, int x) { + int dy=y1-y0; + int ady=dy<0?-dy:dy; + int off=(ady*(x-x0))/(x1-x0); + return dy<0?y0-off:y0+off; + } + + public static final void renderLine(final int x0, final int y0, final int x1, final int y1, final float[] v) { + final int dy=y1-y0; + final int adx=x1-x0; + final int base=dy/adx; + final int sy=dy<0?base-1:base+1; + int x=x0; + int y=y0; + int err=0; + final int ady=(dy<0?-dy:dy)-(base>0?base*adx:-base*adx); + + v[x]*=Floor.DB_STATIC_TABLE[y]; + for(x=x0+1; x=adx) { + err-=adx; + v[x]*=Floor.DB_STATIC_TABLE[y+=sy]; + } + else { + v[x]*=Floor.DB_STATIC_TABLE[y+=base]; + } + } + } +} \ No newline at end of file diff --git a/src/main/java/de/jarnbjo/vorbis/VorbisAudioFileReader.java b/src/main/java/de/jarnbjo/vorbis/VorbisAudioFileReader.java new file mode 100644 index 0000000..9bafefd --- /dev/null +++ b/src/main/java/de/jarnbjo/vorbis/VorbisAudioFileReader.java @@ -0,0 +1,196 @@ +package de.jarnbjo.vorbis; + +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: VorbisAudioFileReader.java,v 1.1 2003/08/08 19:48:22 jarnbjo Exp $ + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: VorbisAudioFileReader.java,v $ + * + */ + +import java.io.*; +import java.net.*; +import java.util.*; + +import de.jarnbjo.ogg.*; +import de.jarnbjo.vorbis.*; + +import javax.sound.sampled.*; +import javax.sound.sampled.spi.AudioFileReader; + +public class VorbisAudioFileReader extends AudioFileReader { + + public VorbisAudioFileReader() { + } + + public AudioFileFormat getAudioFileFormat(File file) throws IOException, UnsupportedAudioFileException { + try { + return getAudioFileFormat(new FileStream(new RandomAccessFile(file, "r"))); + } + catch(OggFormatException e) { + throw new UnsupportedAudioFileException(e.getMessage()); + } + } + + public AudioFileFormat getAudioFileFormat(InputStream stream) throws IOException, UnsupportedAudioFileException { + try { + return getAudioFileFormat(new BasicStream(stream)); + } + catch(OggFormatException e) { + throw new UnsupportedAudioFileException(e.getMessage()); + } + } + + public AudioFileFormat getAudioFileFormat(URL url) throws IOException, UnsupportedAudioFileException { + try { + return getAudioFileFormat(new UncachedUrlStream(url)); + } + catch(OggFormatException e) { + throw new UnsupportedAudioFileException(e.getMessage()); + } + } + + private AudioFileFormat getAudioFileFormat(PhysicalOggStream oggStream) throws IOException, UnsupportedAudioFileException { + try { + Collection streams=oggStream.getLogicalStreams(); + if(streams.size()!=1) { + throw new UnsupportedAudioFileException("Only Ogg files with one logical Vorbis stream are supported."); + } + + LogicalOggStream los=(LogicalOggStream)streams.iterator().next(); + if(los.getFormat()!=LogicalOggStream.FORMAT_VORBIS) { + throw new UnsupportedAudioFileException("Only Ogg files with one logical Vorbis stream are supported."); + } + + VorbisStream vs=new VorbisStream(los); + + AudioFormat audioFormat=new AudioFormat( + (float)vs.getIdentificationHeader().getSampleRate(), + 16, + vs.getIdentificationHeader().getChannels(), + true, true); + + return new AudioFileFormat(VorbisFormatType.getInstance(), audioFormat, AudioSystem.NOT_SPECIFIED); + } + catch(OggFormatException e) { + throw new UnsupportedAudioFileException(e.getMessage()); + } + catch(VorbisFormatException e) { + throw new UnsupportedAudioFileException(e.getMessage()); + } + } + + + + public AudioInputStream getAudioInputStream(File file) throws IOException, UnsupportedAudioFileException { + try { + return getAudioInputStream(new FileStream(new RandomAccessFile(file, "r"))); + } + catch(OggFormatException e) { + throw new UnsupportedAudioFileException(e.getMessage()); + } + } + + public AudioInputStream getAudioInputStream(InputStream stream) throws IOException, UnsupportedAudioFileException { + try { + return getAudioInputStream(new BasicStream(stream)); + } + catch(OggFormatException e) { + throw new UnsupportedAudioFileException(e.getMessage()); + } + } + + public AudioInputStream getAudioInputStream(URL url) throws IOException, UnsupportedAudioFileException { + try { + return getAudioInputStream(new UncachedUrlStream(url)); + } + catch(OggFormatException e) { + throw new UnsupportedAudioFileException(e.getMessage()); + } + } + + private AudioInputStream getAudioInputStream(PhysicalOggStream oggStream) throws IOException, UnsupportedAudioFileException { + try { + Collection streams=oggStream.getLogicalStreams(); + if(streams.size()!=1) { + throw new UnsupportedAudioFileException("Only Ogg files with one logical Vorbis stream are supported."); + } + + LogicalOggStream los=(LogicalOggStream)streams.iterator().next(); + if(los.getFormat()!=LogicalOggStream.FORMAT_VORBIS) { + throw new UnsupportedAudioFileException("Only Ogg files with one logical Vorbis stream are supported."); + } + + VorbisStream vs=new VorbisStream(los); + + AudioFormat audioFormat=new AudioFormat( + (float)vs.getIdentificationHeader().getSampleRate(), + 16, + vs.getIdentificationHeader().getChannels(), + true, true); + + return new AudioInputStream(new VorbisInputStream(vs), audioFormat, -1); + } + catch(OggFormatException e) { + throw new UnsupportedAudioFileException(e.getMessage()); + } + catch(VorbisFormatException e) { + throw new UnsupportedAudioFileException(e.getMessage()); + } + } + + + public static class VorbisFormatType extends AudioFileFormat.Type { + + private static final VorbisFormatType instance=new VorbisFormatType(); + + private VorbisFormatType() { + super("VORBIS", "ogg"); + } + + public static AudioFileFormat.Type getInstance() { + return instance; + } + } + + public static class VorbisInputStream extends InputStream { + + private VorbisStream source; + private byte[] buffer=new byte[8192]; + + public VorbisInputStream(VorbisStream source) { + this.source=source; + } + + public int read() throws IOException { + return 0; + } + + public int read(byte[] buffer) throws IOException { + return read(buffer, 0, buffer.length); + } + + public int read(byte[] buffer, int offset, int length) throws IOException { + try { + return source.readPcm(buffer, offset, length); + } + catch(EndOfOggStreamException e) { + return -1; + } + } + } + + +} \ No newline at end of file diff --git a/src/main/java/de/jarnbjo/vorbis/VorbisFormatException.java b/src/main/java/de/jarnbjo/vorbis/VorbisFormatException.java new file mode 100644 index 0000000..fc2a5d5 --- /dev/null +++ b/src/main/java/de/jarnbjo/vorbis/VorbisFormatException.java @@ -0,0 +1,41 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: VorbisFormatException.java,v 1.2 2003/03/16 01:11:12 jarnbjo Exp $ + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: VorbisFormatException.java,v $ + * Revision 1.2 2003/03/16 01:11:12 jarnbjo + * no message + * + * + */ + +package de.jarnbjo.vorbis; + +import java.io.IOException; + +/** + * Exception thrown when trying to read a corrupted Vorbis stream. + */ + +public class VorbisFormatException extends IOException { + + public VorbisFormatException() { + super(); + } + + public VorbisFormatException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/src/main/java/de/jarnbjo/vorbis/VorbisStream.java b/src/main/java/de/jarnbjo/vorbis/VorbisStream.java new file mode 100644 index 0000000..16d285b --- /dev/null +++ b/src/main/java/de/jarnbjo/vorbis/VorbisStream.java @@ -0,0 +1,241 @@ +/* + * $ProjectName$ + * $ProjectRevision$ + * ----------------------------------------------------------- + * $Id: VorbisStream.java,v 1.4 2003/04/10 19:49:04 jarnbjo Exp $ + * ----------------------------------------------------------- + * + * $Author: jarnbjo $ + * + * Description: + * + * Copyright 2002-2003 Tor-Einar Jarnbjo + * ----------------------------------------------------------- + * + * Change History + * ----------------------------------------------------------- + * $Log: VorbisStream.java,v $ + * Revision 1.4 2003/04/10 19:49:04 jarnbjo + * no message + * + * Revision 1.3 2003/03/31 00:20:16 jarnbjo + * no message + * + * Revision 1.2 2003/03/16 01:11:12 jarnbjo + * no message + * + * + */ + +package de.jarnbjo.vorbis; + +import java.io.*; +import java.util.*; + +import de.jarnbjo.ogg.*; +import de.jarnbjo.util.io.*; + +/** + */ + +public class VorbisStream { + + private LogicalOggStream oggStream; + private IdentificationHeader identificationHeader; + private CommentHeader commentHeader; + private SetupHeader setupHeader; + + private AudioPacket lastAudioPacket, nextAudioPacket; + private LinkedList audioPackets=new LinkedList(); + private byte[] currentPcm; + private int currentPcmIndex; + private int currentPcmLimit; + + private static final int IDENTIFICATION_HEADER = 1; + private static final int COMMENT_HEADER = 3; + private static final int SETUP_HEADER = 5; + + private int bitIndex=0; + private byte lastByte=(byte)0; + private boolean initialized=false; + + private Object streamLock=new Object(); + private int pageCounter=0; + + private int currentBitRate=0; + + private long currentGranulePosition; + + public static final int BIG_ENDIAN = 0; + public static final int LITTLE_ENDIAN = 1; + + public VorbisStream() { + } + + public VorbisStream(LogicalOggStream oggStream) throws VorbisFormatException, IOException { + this.oggStream=oggStream; + + for(int i=0; i<3; i++) { + BitInputStream source=new ByteArrayBitInputStream(oggStream.getNextOggPacket()); + int headerType=source.getInt(8); + switch(headerType) { + case IDENTIFICATION_HEADER: + identificationHeader=new IdentificationHeader(source); + break; + case COMMENT_HEADER: + commentHeader=new CommentHeader(source); + break; + case SETUP_HEADER: + setupHeader=new SetupHeader(this, source); + break; + } + } + + if(identificationHeader==null) { + throw new VorbisFormatException("The file has no identification header."); + } + + if(commentHeader==null) { + throw new VorbisFormatException("The file has no commentHeader."); + } + + if(setupHeader==null) { + throw new VorbisFormatException("The file has no setup header."); + } + + //currentPcm=new int[identificationHeader.getChannels()][16384]; + currentPcm=new byte[identificationHeader.getChannels()*identificationHeader.getBlockSize1()*2]; + //new BufferThread().start(); + } + + public IdentificationHeader getIdentificationHeader() { + return identificationHeader; + } + + public CommentHeader getCommentHeader() { + return commentHeader; + } + + protected SetupHeader getSetupHeader() { + return setupHeader; + } + + public boolean isOpen() { + return oggStream.isOpen(); + } + + public void close() throws IOException { + oggStream.close(); + } + + + public int readPcm(byte[] buffer, int offset, int length) throws IOException { + synchronized (streamLock) { + final int channels=identificationHeader.getChannels(); + + if(lastAudioPacket==null) { + lastAudioPacket=getNextAudioPacket(); + } + if(currentPcm==null || currentPcmIndex>=currentPcmLimit) { + AudioPacket ap=getNextAudioPacket(); + try { + ap.getPcm(lastAudioPacket, currentPcm); + currentPcmLimit=ap.getNumberOfSamples()*identificationHeader.getChannels()*2; + } + catch(ArrayIndexOutOfBoundsException e) { + return 0; + } + currentPcmIndex=0; + lastAudioPacket=ap; + } + int written=0; + int i=0; + int arrIx=0; + for(i=currentPcmIndex; i