diff --git a/src/js/net/minecraft/client/Minecraft.js b/src/js/net/minecraft/client/Minecraft.js index e037068..0d89ee5 100644 --- a/src/js/net/minecraft/client/Minecraft.js +++ b/src/js/net/minecraft/client/Minecraft.js @@ -229,6 +229,8 @@ window.Minecraft = class { this.world.setBlockAt(hitResult.x, hitResult.y, hitResult.z, 0); } } + + this.player.swingArm(); } // Pick block diff --git a/src/js/net/minecraft/client/entity/Entity.js b/src/js/net/minecraft/client/entity/Entity.js index 272958b..e9263eb 100644 --- a/src/js/net/minecraft/client/entity/Entity.js +++ b/src/js/net/minecraft/client/entity/Entity.js @@ -15,7 +15,6 @@ window.Entity = class { this.motionZ = 0; this.onGround = false; - this.sneaking = false; this.rotationYaw = 0; @@ -32,6 +31,8 @@ window.Entity = class { this.nextStepDistance = 1; this.ticksExisted = 0; + + this.boundingBox = new BoundingBox(); } onUpdate() { @@ -49,4 +50,15 @@ window.Entity = class { this.ticksExisted++; } + getEntityBrightness() { + let x = MathHelper.floor(this.x); + let y = MathHelper.floor(this.y + this.getEyeHeight()); + let z = MathHelper.floor(this.z); + return this.world.getLightBrightness(x, y, z); + } + + getEyeHeight() { + return this.boundingBox.height() * 0.8; + } + } \ No newline at end of file diff --git a/src/js/net/minecraft/client/entity/EntityLiving.js b/src/js/net/minecraft/client/entity/EntityLiving.js index a92da71..e889abb 100644 --- a/src/js/net/minecraft/client/entity/EntityLiving.js +++ b/src/js/net/minecraft/client/entity/EntityLiving.js @@ -11,6 +11,9 @@ window.EntityLiving = class extends Entity { this.moveStrafing = 0.0; this.swingProgress = 0; + this.prevSwingProgress = 0; + this.swingProgressInt = 0; + this.swingInProgress = false; this.renderYawOffset = 0; this.rotationYawHead = 0; @@ -141,6 +144,9 @@ window.EntityLiving = class extends Entity { onEntityUpdate() { this.prevRenderYawOffset = this.renderYawOffset; this.prevRotationYawHead = this.rotationYawHead; + this.prevSwingProgress = this.swingProgress; + + this.updateArmSwingProgress(); super.onEntityUpdate(); } @@ -169,6 +175,31 @@ window.EntityLiving = class extends Entity { return distanceTravelledSqrt; } + swingArm() { + let swingAnimationEnd = 6; + if (!this.isSwingInProgress || this.swingProgressInt >= swingAnimationEnd / 2 || this.swingProgressInt < 0) { + this.swingProgressInt = -1; + this.isSwingInProgress = true; + } + } + + updateArmSwingProgress() { + let swingAnimationEnd = 6; + + if (this.isSwingInProgress) { + ++this.swingProgressInt; + + if (this.swingProgressInt >= swingAnimationEnd) { + this.swingProgressInt = 0; + this.isSwingInProgress = false; + } + } else { + this.swingProgressInt = 0; + } + + this.swingProgress = this.swingProgressInt / swingAnimationEnd; + } + computeAngleWithBound(value, subtract, limit) { let wrapped = MathHelper.wrapAngleTo180(value - subtract); if (wrapped < -limit) { diff --git a/src/js/net/minecraft/client/entity/PlayerEntity.js b/src/js/net/minecraft/client/entity/PlayerEntity.js index f495538..2cfb67f 100644 --- a/src/js/net/minecraft/client/entity/PlayerEntity.js +++ b/src/js/net/minecraft/client/entity/PlayerEntity.js @@ -213,9 +213,9 @@ window.PlayerEntity = class extends EntityLiving { // Step sound if (!isSlow) { - let blockX = MathHelper.floor_double(this.x); - let blockY = MathHelper.floor_double(this.y - 0.2); - let blockZ = MathHelper.floor_double(this.z); + let blockX = MathHelper.floor(this.x); + let blockY = MathHelper.floor(this.y - 0.2); + let blockZ = MathHelper.floor(this.z); let typeId = this.world.getBlockAt(blockX, blockY, blockZ); let distanceX = this.x - prevX; diff --git a/src/js/net/minecraft/client/render/WorldRenderer.js b/src/js/net/minecraft/client/render/WorldRenderer.js index 3c76fb8..e46c580 100644 --- a/src/js/net/minecraft/client/render/WorldRenderer.js +++ b/src/js/net/minecraft/client/render/WorldRenderer.js @@ -92,6 +92,8 @@ window.WorldRenderer = class { // Render entities for (let entity of this.minecraft.world.entities) { if (entity === player && this.minecraft.settings.thirdPersonView === 0) { + entity.group.clear(); + entity.lastRenderedBrightness = -1; // TODO: Find a better way to trigger this continue; } this.renderEntity(entity, partialTicks); diff --git a/src/js/net/minecraft/client/render/entity/EntityRenderer.js b/src/js/net/minecraft/client/render/entity/EntityRenderer.js index 6bf70ba..dd0c3b7 100644 --- a/src/js/net/minecraft/client/render/entity/EntityRenderer.js +++ b/src/js/net/minecraft/client/render/entity/EntityRenderer.js @@ -2,13 +2,26 @@ window.EntityRenderer = class { constructor(model) { this.model = model; + this.tessellator = new Tessellator(); } - rebuild(tessellator, entity) { - this.model.rebuild(tessellator, entity.group); + rebuild(entity) { + let brightness = entity.getEntityBrightness(); + entity.lastRenderedBrightness = brightness; + + // Apply brightness + this.tessellator.setColor(brightness, brightness, brightness); + + // Rebuild + this.model.rebuild(this.tessellator, entity.group); } render(entity, partialTicks) { + let brightness = entity.getEntityBrightness(); + if (entity.lastRenderedBrightness !== brightness) { + this.rebuild(entity); + } + let group = entity.group; let rotationBody = this.interpolateRotation(entity.prevRenderYawOffset, entity.renderYawOffset, partialTicks); @@ -32,19 +45,20 @@ window.EntityRenderer = class { // Actual size of the entity let scale = 7.0 / 120.0; - group.scale.set(scale, -scale, scale); + group.scale.set(-scale,- scale, scale); // Rotate entity model group.rotation.y = MathHelper.toRadians(-rotationBody + 180); // Render entity model let timeAlive = entity.ticksExisted + partialTicks; - this.model.render(entity, limbSwingAmount, limbSwing, timeAlive, yaw, pitch); + this.model.render(entity, limbSwingAmount, limbSwing, timeAlive, yaw, pitch, partialTicks); } interpolateRotation(prevValue, value, partialTicks) { let factor; - for (factor = value - prevValue; factor < -180.0; factor += 360.0) {} + for (factor = value - prevValue; factor < -180.0; factor += 360.0) { + } while (factor >= 180.0) { factor -= 360.0; } diff --git a/src/js/net/minecraft/client/render/entity/entity/PlayerRenderer.js b/src/js/net/minecraft/client/render/entity/entity/PlayerRenderer.js index 1f23400..087ff25 100644 --- a/src/js/net/minecraft/client/render/entity/entity/PlayerRenderer.js +++ b/src/js/net/minecraft/client/render/entity/entity/PlayerRenderer.js @@ -10,13 +10,12 @@ window.PlayerRenderer = class extends EntityRenderer { } rebuild(tessellator, entity) { - tessellator.bindTexture(this.textureCharacter); + this.tessellator.bindTexture(this.textureCharacter); super.rebuild(tessellator, entity); } render(entity, partialTicks) { super.render(entity, partialTicks); - } } \ No newline at end of file diff --git a/src/js/net/minecraft/client/render/gui/FontRenderer.js b/src/js/net/minecraft/client/render/gui/FontRenderer.js index 57446da..421e7d5 100644 --- a/src/js/net/minecraft/client/render/gui/FontRenderer.js +++ b/src/js/net/minecraft/client/render/gui/FontRenderer.js @@ -8,6 +8,7 @@ window.FontRenderer = class { constructor() { this.charWidths = []; + this.isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); this.texture = Gui.loadTexture("gui/font.png") let bitMap = this.createBitMap(this.texture); @@ -44,7 +45,9 @@ window.FontRenderer = class { } drawString(stack, string, x, y, color = -1) { - this.drawStringRaw(stack, string, x + 1, y + 1, (color & 0xFCFCFC) >> 2, true); + if (!this.isSafari) { // TODO Fix brightness filter on Safari + this.drawStringRaw(stack, string, x + 1, y + 1, (color & 0xFCFCFC) >> 2, true); + } this.drawStringRaw(stack, string, x, y, color, false); } diff --git a/src/js/net/minecraft/client/render/model/model/ModelPlayer.js b/src/js/net/minecraft/client/render/model/model/ModelPlayer.js index 1e6a338..7bae055 100644 --- a/src/js/net/minecraft/client/render/model/model/ModelPlayer.js +++ b/src/js/net/minecraft/client/render/model/model/ModelPlayer.js @@ -19,18 +19,18 @@ window.ModelPlayer = class extends ModelBase { .setTextureOffset(16, 16) .setBox(-4.0, 0.0, -2.0, 8, 12, 4); - // Right arm ModelRenderer - this.rightArm = new ModelRenderer(width, height) - .setTextureOffset(40, 16) - .setRotationPoint(-5.0, 2.0, 0.0) - .setBox(-3.0, -2.0, -2.0, 4, 12, 4); - // Left arm ModelRenderer this.leftArm = new ModelRenderer(width, height) .setTextureOffset(40, 16) - .setRotationPoint(5.0, 2.0, 0.0) + .setRotationPoint(-5.0, 2.0, 0.0) .setBox(-1.0, -2.0, -2.0, 4, 12, 4); + // Right arm ModelRenderer + this.rightArm = new ModelRenderer(width, height) + .setTextureOffset(40, 16) + .setRotationPoint(-3.0, 2.0, -2.0) + .setBox(-3.0, -2.0, -2.0, 4, 12, 4); + // Right Legs ModelRenderer this.rightLeg = new ModelRenderer(width, height) .setTextureOffset(0, 16) @@ -55,7 +55,7 @@ window.ModelPlayer = class extends ModelBase { this.rightLeg.rebuild(tessellator, group); } - render(entity, limbSwingAmount, limbSwing, timeAlive, yaw, pitch) { + render(entity, limbSwingAmount, limbSwing, timeAlive, yaw, pitch, partialTicks) { let group = entity.group; this.head.rotateAngleY = MathHelper.toRadians(yaw); @@ -71,6 +71,40 @@ window.ModelPlayer = class extends ModelBase { this.rightArm.rotateAngleY = 0.0; this.rightArm.rotateAngleZ = 0.0; + this.leftArm.rotateAngleY = 0.0; + + // Swing progress + let swingProgress = entity.swingProgress - entity.prevSwingProgress; + if (swingProgress < 0.0) { + swingProgress++; + } + let interpolatedSwingProgress = entity.prevSwingProgress + swingProgress * partialTicks; + if (interpolatedSwingProgress > -9990.0) { + let swingProgress = interpolatedSwingProgress; + + this.body.rotateAngleY = Math.sin(Math.sqrt(swingProgress) * Math.PI * 2.0) * 0.2; + + this.rightArm.rotationPointZ = Math.sin(this.body.rotateAngleY) * 5.0; + this.rightArm.rotationPointX = -Math.cos(this.body.rotateAngleY) * 5.0; + this.leftArm.rotationPointZ = -Math.sin(this.body.rotateAngleY) * 5.0; + this.leftArm.rotationPointX = Math.cos(this.body.rotateAngleY) * 5.0; + + this.rightArm.rotateAngleY += this.body.rotateAngleY; + this.leftArm.rotateAngleY += this.body.rotateAngleY; + this.leftArm.rotateAngleX += this.body.rotateAngleY; + + swingProgress = 1.0 - interpolatedSwingProgress; + swingProgress = swingProgress * swingProgress; + swingProgress = swingProgress * swingProgress; + swingProgress = 1.0 - swingProgress; + + let value1 = Math.sin(swingProgress * Math.PI); + let value2 = Math.sin(interpolatedSwingProgress * Math.PI) * -(this.head.rotateAngleX - 0.7) * 0.75; + + this.rightArm.rotateAngleX = (this.rightArm.rotateAngleX - (value1 * 1.2 + value2)); + this.rightArm.rotateAngleY += this.body.rotateAngleY * 2.0; + this.rightArm.rotateAngleZ += Math.sin(interpolatedSwingProgress * Math.PI) * -0.4; + } if (entity.sneaking) { this.body.rotateAngleX = 0.5; diff --git a/src/js/net/minecraft/client/render/model/renderer/ModelRenderer.js b/src/js/net/minecraft/client/render/model/renderer/ModelRenderer.js index 04a11c5..06167e5 100644 --- a/src/js/net/minecraft/client/render/model/renderer/ModelRenderer.js +++ b/src/js/net/minecraft/client/render/model/renderer/ModelRenderer.js @@ -157,7 +157,7 @@ window.ModelRenderer = class { this.bone.rotation.order = 'ZYX'; this.bone.rotation.x = this.rotateAngleX; - this.bone.rotation.y = -this.rotateAngleY; + this.bone.rotation.y = this.rotateAngleY; this.bone.rotation.z = this.rotateAngleZ; this.bone.updateMatrix(); diff --git a/src/js/net/minecraft/client/render/model/renderer/Polygon.js b/src/js/net/minecraft/client/render/model/renderer/Polygon.js index a153203..46f48b0 100644 --- a/src/js/net/minecraft/client/render/model/renderer/Polygon.js +++ b/src/js/net/minecraft/client/render/model/renderer/Polygon.js @@ -21,9 +21,6 @@ window.Polygon = class { } render(tessellator) { - // Set color of polygon - tessellator.setColor(1, 1, 1); - // Render all vertices for (let i = 3; i >= 0; i--) { let vertex = this.vertices[i]; diff --git a/src/js/net/minecraft/client/world/World.js b/src/js/net/minecraft/client/world/World.js index 78a365d..1fc1fc4 100644 --- a/src/js/net/minecraft/client/world/World.js +++ b/src/js/net/minecraft/client/world/World.js @@ -15,6 +15,13 @@ window.World = class { this.time = 0; + // Generate light brightness table + this.lightBrightnessTable = []; + for (let i = 0; i <= 15; i++) { + let brightness = 1.0 - i / 15; + this.lightBrightnessTable[i] = ((1.0 - brightness) / (brightness * 3 + 1.0)) * (1.0 - 0.05) + 0.05; + } + // Load world this.generator = new WorldGenerator(this, Date.now() % 100000); @@ -88,12 +95,12 @@ window.World = class { getCollisionBoxes(region) { let boundingBoxList = []; - let minX = MathHelper.floor_double(region.minX); - let maxX = MathHelper.floor_double(region.maxX + 1.0); - let minY = MathHelper.floor_double(region.minY); - let maxY = MathHelper.floor_double(region.maxY + 1.0); - let minZ = MathHelper.floor_double(region.minZ); - let maxZ = MathHelper.floor_double(region.maxZ + 1.0); + let minX = MathHelper.floor(region.minX); + let maxX = MathHelper.floor(region.maxX + 1.0); + let minY = MathHelper.floor(region.minY); + let maxY = MathHelper.floor(region.maxY + 1.0); + let minZ = MathHelper.floor(region.minZ); + let maxZ = MathHelper.floor(region.maxZ + 1.0); for (let x = minX; x < maxX; x++) { for (let y = minY; y < maxY; y++) { @@ -331,13 +338,13 @@ window.World = class { } rayTraceBlocks(from, to) { - let toX = MathHelper.floor_double(to.x); - let toY = MathHelper.floor_double(to.y); - let toZ = MathHelper.floor_double(to.z); + let toX = MathHelper.floor(to.x); + let toY = MathHelper.floor(to.y); + let toZ = MathHelper.floor(to.z); - let x = MathHelper.floor_double(from.x); - let y = MathHelper.floor_double(from.y); - let z = MathHelper.floor_double(from.z); + let x = MathHelper.floor(from.x); + let y = MathHelper.floor(from.y); + let z = MathHelper.floor(from.z); let blockId = this.getBlockAt(x, y, z); let block = Block.getById(blockId); @@ -429,9 +436,9 @@ window.World = class { from = new Vector3(from.x + diffX * nearestZ, from.y + diffY * nearestZ, nearestZ1); } - x = MathHelper.floor_double(from.x) - (face === EnumBlockFace.EAST ? 1 : 0); - y = MathHelper.floor_double(from.y) - (face === EnumBlockFace.TOP ? 1 : 0); - z = MathHelper.floor_double(from.z) - (face === EnumBlockFace.SOUTH ? 1 : 0); + x = MathHelper.floor(from.x) - (face === EnumBlockFace.EAST ? 1 : 0); + y = MathHelper.floor(from.y) - (face === EnumBlockFace.TOP ? 1 : 0); + z = MathHelper.floor(from.z) - (face === EnumBlockFace.SOUTH ? 1 : 0); let blockId = this.getBlockAt(x, y, z); let block = Block.getById(blockId); @@ -480,6 +487,11 @@ window.World = class { return (Math.round(red * 255) << 16) | (Math.round(green * 255) << 8) | Math.round(blue * 255); } + getLightBrightness(x, y, z) { + let level = this.getTotalLightAt(x, y, z); + return this.lightBrightnessTable[level]; + } + getSkyColorByTemp(temperature) { temperature /= 3; if (temperature < -1) { @@ -506,13 +518,6 @@ window.World = class { addEntity(entity) { this.entities.push(entity); this.group.add(entity.group); - - let tessellator = new Tessellator(); - - // Rebuild entity model - let worldRenderer = this.minecraft.worldRenderer; - let renderer = worldRenderer.entityRenderManager.getEntityRendererByEntity(entity); - renderer.rebuild(tessellator, entity); } removeEntityById(id) { diff --git a/src/js/net/minecraft/util/BoundingBox.js b/src/js/net/minecraft/util/BoundingBox.js index 851d0cc..79c5e8d 100644 --- a/src/js/net/minecraft/util/BoundingBox.js +++ b/src/js/net/minecraft/util/BoundingBox.js @@ -10,7 +10,7 @@ window.BoundingBox = class { * @param maxY Maximum y side * @param maxZ Maximum z side */ - constructor(minX, minY, minZ, maxX, maxY, maxZ) { + constructor(minX = 0, minY = 0, minZ = 0, maxX = 0, maxY = 0, maxZ = 0) { this.epsilon = 0.0; this.minX = minX; diff --git a/src/js/net/minecraft/util/MathHelper.js b/src/js/net/minecraft/util/MathHelper.js index 7d598a0..3dd5c7f 100644 --- a/src/js/net/minecraft/util/MathHelper.js +++ b/src/js/net/minecraft/util/MathHelper.js @@ -3,7 +3,7 @@ window.MathHelper = class { /** * Returns the greatest integer less than or equal to the double argument */ - static floor_double(value) { + static floor(value) { let i = parseInt(value); return value < i ? i - 1 : i; }