From 2346b97c032cde32f9bcef0958e7c52f37c3d4db Mon Sep 17 00:00:00 2001 From: PeytonPlayz595 <106421860+PeytonPlayz595@users.noreply.github.com> Date: Mon, 10 Jul 2023 15:24:41 -0400 Subject: [PATCH] Added Minecraft Classic src --- resources/2char.png | Bin 0 -> 318 bytes resources/META-INF/MANIFEST.MF | 2 + resources/armor/chain.png | Bin 0 -> 364 bytes resources/armor/plate.png | Bin 0 -> 742 bytes resources/char.png | Bin 0 -> 1360 bytes resources/clouds.png | Bin 0 -> 9875 bytes resources/default.gif | Bin 0 -> 2774 bytes resources/default.png | Bin 0 -> 3696 bytes resources/dirt.png | Bin 0 -> 1011 bytes resources/glsl/core.glsl | 144 ++ resources/glsl/fxaa.glsl | 255 +++ resources/glsl/occl.glsl | 25 + resources/glsl/pvert.glsl | 13 + resources/grass.png | Bin 0 -> 1193 bytes resources/gui/gui.png | Bin 0 -> 14210 bytes resources/gui/icons.png | Bin 0 -> 2368 bytes resources/item/arrows.png | Bin 0 -> 322 bytes resources/item/sign.png | Bin 0 -> 1260 bytes resources/mob/creeper.png | Bin 0 -> 3000 bytes resources/mob/pig.png | Bin 0 -> 3791 bytes resources/mob/sheep.png | Bin 0 -> 2434 bytes resources/mob/sheep_fur.png | Bin 0 -> 1661 bytes resources/mob/skeleton.png | Bin 0 -> 894 bytes resources/mob/spider.png | Bin 0 -> 2554 bytes resources/mob/zombie.png | Bin 0 -> 1343 bytes resources/null | 0 resources/particles.png | Bin 0 -> 574 bytes resources/rain.png | Bin 0 -> 2553 bytes resources/terrain.png | Bin 0 -> 28961 bytes resources/water.png | Bin 0 -> 306 bytes .../java/com/mojang/minecraft/ChatLine.java | 13 + .../java/com/mojang/minecraft/Entity.java | 477 +++++ .../com/mojang/minecraft/GameSettings.java | 287 +++ .../java/com/mojang/minecraft/KeyBinding.java | 13 + .../com/mojang/minecraft/Minecraft$OS.java | 16 + .../java/com/mojang/minecraft/Minecraft.java | 1804 +++++++++++++++++ .../mojang/minecraft/MinecraftApplet$1.java | 32 + .../com/mojang/minecraft/MinecraftApplet.java | 115 ++ .../minecraft/MovingObjectPosition.java | 37 + .../minecraft/OperatingSystemLookup.java | 37 + .../mojang/minecraft/ProgressBarDisplay.java | 99 + .../minecraft/ResourceDownloadThread.java | 244 +++ .../com/mojang/minecraft/SessionData.java | 66 + .../mojang/minecraft/SkinDownloadThread.java | 51 + .../mojang/minecraft/SleepForeverThread.java | 27 + .../mojang/minecraft/StopGameException.java | 6 + src/main/java/com/mojang/minecraft/Timer.java | 21 + .../minecraft/gamemode/CreativeGameMode.java | 58 + .../mojang/minecraft/gamemode/GameMode.java | 108 + .../minecraft/gamemode/SurvivalGameMode.java | 174 ++ .../minecraft/gui/BlockSelectScreen.java | 74 + .../java/com/mojang/minecraft/gui/Button.java | 33 + .../mojang/minecraft/gui/ChatInputScreen.java | 69 + .../mojang/minecraft/gui/ControlsScreen.java | 57 + .../com/mojang/minecraft/gui/ErrorScreen.java | 26 + .../mojang/minecraft/gui/FontRenderer.java | 158 ++ .../mojang/minecraft/gui/GameOverScreen.java | 46 + .../minecraft/gui/GenerateLevelScreen.java | 38 + .../com/mojang/minecraft/gui/GuiMods.java | 40 + .../com/mojang/minecraft/gui/GuiMore.java | 40 + .../com/mojang/minecraft/gui/GuiOptifine.java | 40 + .../com/mojang/minecraft/gui/GuiScreen.java | 117 ++ .../com/mojang/minecraft/gui/HUDScreen.java | 215 ++ .../com/mojang/minecraft/gui/LevelDialog.java | 52 + .../mojang/minecraft/gui/LevelNameScreen.java | 85 + .../mojang/minecraft/gui/LoadLevelScreen.java | 164 ++ .../mojang/minecraft/gui/OptionButton.java | 10 + .../mojang/minecraft/gui/OptionsScreen.java | 58 + .../com/mojang/minecraft/gui/PauseScreen.java | 63 + .../mojang/minecraft/gui/SaveLevelScreen.java | 56 + .../java/com/mojang/minecraft/gui/Screen.java | 75 + .../java/com/mojang/minecraft/item/Arrow.java | 294 +++ .../java/com/mojang/minecraft/item/Item.java | 149 ++ .../com/mojang/minecraft/item/ItemModel.java | 62 + .../com/mojang/minecraft/item/PrimedTnt.java | 192 ++ .../mojang/minecraft/item/TakeEntityAnim.java | 63 + .../mojang/minecraft/level/BlockMap$Slot.java | 86 + .../com/mojang/minecraft/level/BlockMap.java | 280 +++ .../com/mojang/minecraft/level/Level.java | 1013 +++++++++ .../com/mojang/minecraft/level/LevelIO.java | 258 +++ .../level/LevelObjectInputStream.java | 35 + .../mojang/minecraft/level/MobSpawner.java | 106 + .../minecraft/level/NextTickListEntry.java | 19 + .../minecraft/level/SyntheticClass.java | 6 + .../level/generator/LevelGenerator.java | 544 +++++ .../level/generator/noise/CombinedNoise.java | 19 + .../level/generator/noise/Noise.java | 7 + .../level/generator/noise/OctaveNoise.java | 37 + .../level/generator/noise/PerlinNoise.java | 135 ++ .../minecraft/level/liquid/LiquidType.java | 17 + .../mojang/minecraft/level/tile/Block.java | 742 +++++++ .../minecraft/level/tile/BookshelfBlock.java | 28 + .../minecraft/level/tile/DirtBlock.java | 20 + .../minecraft/level/tile/FlowerBlock.java | 103 + .../minecraft/level/tile/GlassBlock.java | 29 + .../minecraft/level/tile/GrassBlock.java | 44 + .../minecraft/level/tile/LeavesBaseBlock.java | 26 + .../minecraft/level/tile/LeavesBlock.java | 19 + .../minecraft/level/tile/LiquidBlock.java | 168 ++ .../minecraft/level/tile/MetalBlock.java | 25 + .../minecraft/level/tile/MushroomBlock.java | 32 + .../mojang/minecraft/level/tile/OreBlock.java | 24 + .../minecraft/level/tile/SandBlock.java | 55 + .../minecraft/level/tile/SaplingBlock.java | 38 + .../minecraft/level/tile/SlabBlock.java | 67 + .../minecraft/level/tile/SpongeBlock.java | 46 + .../level/tile/StillLiquidBlock.java | 57 + .../minecraft/level/tile/StoneBlock.java | 20 + .../mojang/minecraft/level/tile/TNTBlock.java | 48 + .../minecraft/level/tile/Tile$SoundType.java | 35 + .../minecraft/level/tile/WoodBlock.java | 29 + .../com/mojang/minecraft/mob/Creeper$1.java | 46 + .../com/mojang/minecraft/mob/Creeper.java | 28 + .../com/mojang/minecraft/mob/HumanoidMob.java | 70 + .../java/com/mojang/minecraft/mob/Mob.java | 443 ++++ .../java/com/mojang/minecraft/mob/Pig.java | 34 + .../mojang/minecraft/mob/QuadrupedMob.java | 17 + .../com/mojang/minecraft/mob/Sheep$1.java | 51 + .../java/com/mojang/minecraft/mob/Sheep.java | 113 ++ .../com/mojang/minecraft/mob/Skeleton$1.java | 30 + .../com/mojang/minecraft/mob/Skeleton.java | 38 + .../java/com/mojang/minecraft/mob/Spider.java | 23 + .../java/com/mojang/minecraft/mob/Zombie.java | 23 + .../java/com/mojang/minecraft/mob/ai/AI.java | 19 + .../com/mojang/minecraft/mob/ai/BasicAI.java | 119 ++ .../minecraft/mob/ai/BasicAttackAI.java | 87 + .../mojang/minecraft/mob/ai/JumpAttackAI.java | 24 + .../mojang/minecraft/model/AnimalModel.java | 52 + .../mojang/minecraft/model/CreeperModel.java | 52 + .../mojang/minecraft/model/HumanoidModel.java | 69 + .../com/mojang/minecraft/model/Model.java | 10 + .../mojang/minecraft/model/ModelManager.java | 30 + .../com/mojang/minecraft/model/ModelPart.java | 152 ++ .../com/mojang/minecraft/model/PigModel.java | 10 + .../mojang/minecraft/model/SheepFurModel.java | 30 + .../mojang/minecraft/model/SheepModel.java | 17 + .../mojang/minecraft/model/SkeletonModel.java | 24 + .../mojang/minecraft/model/SpiderModel.java | 113 ++ .../mojang/minecraft/model/TexturedQuad.java | 31 + .../com/mojang/minecraft/model/Vec3D.java | 69 + .../com/mojang/minecraft/model/Vertex.java | 31 + .../mojang/minecraft/model/ZombieModel.java | 25 + .../mojang/minecraft/net/NetworkManager.java | 74 + .../mojang/minecraft/net/NetworkPlayer.java | 235 +++ .../com/mojang/minecraft/net/PacketType.java | 86 + .../mojang/minecraft/net/PositionUpdate.java | 45 + .../minecraft/net/ServerConnectThread.java | 53 + .../minecraft/net/SkinDownloadThread.java | 46 + .../mojang/minecraft/particle/Particle.java | 101 + .../minecraft/particle/ParticleManager.java | 47 + .../minecraft/particle/SmokeParticle.java | 46 + .../minecraft/particle/TerrainParticle.java | 40 + .../minecraft/particle/WaterDropParticle.java | 52 + .../java/com/mojang/minecraft/phys/AABB.java | 308 +++ .../mojang/minecraft/player/InputHandler.java | 20 + .../minecraft/player/InputHandlerImpl.java | 90 + .../mojang/minecraft/player/Inventory.java | 127 ++ .../com/mojang/minecraft/player/Player$1.java | 26 + .../com/mojang/minecraft/player/Player.java | 162 ++ .../com/mojang/minecraft/render/Chunk.java | 123 ++ .../render/ChunkDirtyDistanceComparator.java | 43 + .../render/ChunkDistanceComparator.java | 33 + .../com/mojang/minecraft/render/Frustrum.java | 21 + .../mojang/minecraft/render/FrustrumImpl.java | 85 + .../mojang/minecraft/render/HeldBlock.java | 23 + .../minecraft/render/LevelRenderer.java | 266 +++ .../com/mojang/minecraft/render/Renderer.java | 170 ++ .../minecraft/render/ShapeRenderer.java | 157 ++ .../minecraft/render/TextureManager.java | 99 + .../minecraft/render/texture/TextureFX.java | 17 + .../render/texture/TextureLavaFX.java | 87 + .../render/texture/TextureWaterFX.java | 90 + .../com/mojang/minecraft/sound/Audio.java | 6 + .../com/mojang/minecraft/sound/AudioInfo.java | 11 + .../mojang/minecraft/sound/BaseSoundPos.java | 50 + .../minecraft/sound/EntitySoundPos.java | 27 + .../mojang/minecraft/sound/LevelSoundPos.java | 31 + .../com/mojang/minecraft/sound/Music.java | 80 + .../minecraft/sound/MusicPlayThread.java | 101 + .../com/mojang/minecraft/sound/Sound.java | 62 + .../com/mojang/minecraft/sound/SoundData.java | 13 + .../com/mojang/minecraft/sound/SoundInfo.java | 35 + .../mojang/minecraft/sound/SoundManager.java | 96 + .../mojang/minecraft/sound/SoundPlayer.java | 107 + .../com/mojang/minecraft/sound/SoundPos.java | 8 + .../mojang/minecraft/sound/SoundReader.java | 89 + .../java/com/mojang/net/NetworkHandler.java | 164 ++ src/main/java/com/mojang/util/MathHelper.java | 43 + src/main/java/de/jarnbjo/ogg/BasicStream.java | 107 + .../java/de/jarnbjo/ogg/CachedUrlStream.java | 246 +++ .../jarnbjo/ogg/EndOfOggStreamException.java | 35 + src/main/java/de/jarnbjo/ogg/FileStream.java | 148 ++ .../java/de/jarnbjo/ogg/LogicalOggStream.java | 145 ++ .../de/jarnbjo/ogg/LogicalOggStreamImpl.java | 207 ++ .../de/jarnbjo/ogg/OggFormatException.java | 40 + src/main/java/de/jarnbjo/ogg/OggPage.java | 425 ++++ .../de/jarnbjo/ogg/OnDemandUrlStream.java | 121 ++ .../de/jarnbjo/ogg/PhysicalOggStream.java | 118 ++ .../de/jarnbjo/ogg/UncachedUrlStream.java | 201 ++ .../util/audio/FadeableAudioInputStream.java | 62 + .../de/jarnbjo/util/io/BitInputStream.java | 179 ++ .../util/io/ByteArrayBitInputStream.java | 346 ++++ .../java/de/jarnbjo/util/io/HuffmanNode.java | 138 ++ .../java/de/jarnbjo/vorbis/AudioPacket.java | 320 +++ src/main/java/de/jarnbjo/vorbis/CodeBook.java | 267 +++ .../java/de/jarnbjo/vorbis/CommentHeader.java | 237 +++ src/main/java/de/jarnbjo/vorbis/Floor.java | 118 ++ src/main/java/de/jarnbjo/vorbis/Floor0.java | 68 + src/main/java/de/jarnbjo/vorbis/Floor1.java | 318 +++ .../java/de/jarnbjo/vorbis/Floor1.java~1~ | 318 +++ .../jarnbjo/vorbis/IdentificationHeader.java | 116 ++ src/main/java/de/jarnbjo/vorbis/Mapping.java | 53 + src/main/java/de/jarnbjo/vorbis/Mapping0.java | 140 ++ .../java/de/jarnbjo/vorbis/MdctFloat.java | 312 +++ src/main/java/de/jarnbjo/vorbis/Mode.java | 69 + src/main/java/de/jarnbjo/vorbis/Residue.java | 254 +++ src/main/java/de/jarnbjo/vorbis/Residue0.java | 45 + src/main/java/de/jarnbjo/vorbis/Residue1.java | 47 + src/main/java/de/jarnbjo/vorbis/Residue2.java | 115 ++ .../java/de/jarnbjo/vorbis/SetupHeader.java | 125 ++ src/main/java/de/jarnbjo/vorbis/Util.java | 121 ++ .../jarnbjo/vorbis/VorbisAudioFileReader.java | 196 ++ .../jarnbjo/vorbis/VorbisFormatException.java | 41 + .../java/de/jarnbjo/vorbis/VorbisStream.java | 241 +++ .../org/oyasunadev/minecraft/MCApplet.java | 76 + .../org/oyasunadev/minecraft/SPFrame.java | 49 + .../java/org/oyasunadev/minecraft/Start.java | 43 + 227 files changed, 22399 insertions(+) create mode 100644 resources/2char.png create mode 100644 resources/META-INF/MANIFEST.MF create mode 100644 resources/armor/chain.png create mode 100644 resources/armor/plate.png create mode 100644 resources/char.png create mode 100644 resources/clouds.png create mode 100644 resources/default.gif create mode 100644 resources/default.png create mode 100644 resources/dirt.png create mode 100644 resources/glsl/core.glsl create mode 100644 resources/glsl/fxaa.glsl create mode 100644 resources/glsl/occl.glsl create mode 100644 resources/glsl/pvert.glsl create mode 100644 resources/grass.png create mode 100644 resources/gui/gui.png create mode 100644 resources/gui/icons.png create mode 100644 resources/item/arrows.png create mode 100644 resources/item/sign.png create mode 100644 resources/mob/creeper.png create mode 100644 resources/mob/pig.png create mode 100644 resources/mob/sheep.png create mode 100644 resources/mob/sheep_fur.png create mode 100644 resources/mob/skeleton.png create mode 100644 resources/mob/spider.png create mode 100644 resources/mob/zombie.png create mode 100644 resources/null create mode 100644 resources/particles.png create mode 100644 resources/rain.png create mode 100644 resources/terrain.png create mode 100644 resources/water.png create mode 100644 src/main/java/com/mojang/minecraft/ChatLine.java create mode 100644 src/main/java/com/mojang/minecraft/Entity.java create mode 100644 src/main/java/com/mojang/minecraft/GameSettings.java create mode 100644 src/main/java/com/mojang/minecraft/KeyBinding.java create mode 100644 src/main/java/com/mojang/minecraft/Minecraft$OS.java create mode 100644 src/main/java/com/mojang/minecraft/Minecraft.java create mode 100644 src/main/java/com/mojang/minecraft/MinecraftApplet$1.java create mode 100644 src/main/java/com/mojang/minecraft/MinecraftApplet.java create mode 100644 src/main/java/com/mojang/minecraft/MovingObjectPosition.java create mode 100644 src/main/java/com/mojang/minecraft/OperatingSystemLookup.java create mode 100644 src/main/java/com/mojang/minecraft/ProgressBarDisplay.java create mode 100644 src/main/java/com/mojang/minecraft/ResourceDownloadThread.java create mode 100644 src/main/java/com/mojang/minecraft/SessionData.java create mode 100644 src/main/java/com/mojang/minecraft/SkinDownloadThread.java create mode 100644 src/main/java/com/mojang/minecraft/SleepForeverThread.java create mode 100644 src/main/java/com/mojang/minecraft/StopGameException.java create mode 100644 src/main/java/com/mojang/minecraft/Timer.java create mode 100644 src/main/java/com/mojang/minecraft/gamemode/CreativeGameMode.java create mode 100644 src/main/java/com/mojang/minecraft/gamemode/GameMode.java create mode 100644 src/main/java/com/mojang/minecraft/gamemode/SurvivalGameMode.java create mode 100644 src/main/java/com/mojang/minecraft/gui/BlockSelectScreen.java create mode 100644 src/main/java/com/mojang/minecraft/gui/Button.java create mode 100644 src/main/java/com/mojang/minecraft/gui/ChatInputScreen.java create mode 100644 src/main/java/com/mojang/minecraft/gui/ControlsScreen.java create mode 100644 src/main/java/com/mojang/minecraft/gui/ErrorScreen.java create mode 100644 src/main/java/com/mojang/minecraft/gui/FontRenderer.java create mode 100644 src/main/java/com/mojang/minecraft/gui/GameOverScreen.java create mode 100644 src/main/java/com/mojang/minecraft/gui/GenerateLevelScreen.java create mode 100644 src/main/java/com/mojang/minecraft/gui/GuiMods.java create mode 100644 src/main/java/com/mojang/minecraft/gui/GuiMore.java create mode 100644 src/main/java/com/mojang/minecraft/gui/GuiOptifine.java create mode 100644 src/main/java/com/mojang/minecraft/gui/GuiScreen.java create mode 100644 src/main/java/com/mojang/minecraft/gui/HUDScreen.java create mode 100644 src/main/java/com/mojang/minecraft/gui/LevelDialog.java create mode 100644 src/main/java/com/mojang/minecraft/gui/LevelNameScreen.java create mode 100644 src/main/java/com/mojang/minecraft/gui/LoadLevelScreen.java create mode 100644 src/main/java/com/mojang/minecraft/gui/OptionButton.java create mode 100644 src/main/java/com/mojang/minecraft/gui/OptionsScreen.java create mode 100644 src/main/java/com/mojang/minecraft/gui/PauseScreen.java create mode 100644 src/main/java/com/mojang/minecraft/gui/SaveLevelScreen.java create mode 100644 src/main/java/com/mojang/minecraft/gui/Screen.java create mode 100644 src/main/java/com/mojang/minecraft/item/Arrow.java create mode 100644 src/main/java/com/mojang/minecraft/item/Item.java create mode 100644 src/main/java/com/mojang/minecraft/item/ItemModel.java create mode 100644 src/main/java/com/mojang/minecraft/item/PrimedTnt.java create mode 100644 src/main/java/com/mojang/minecraft/item/TakeEntityAnim.java create mode 100644 src/main/java/com/mojang/minecraft/level/BlockMap$Slot.java create mode 100644 src/main/java/com/mojang/minecraft/level/BlockMap.java create mode 100644 src/main/java/com/mojang/minecraft/level/Level.java create mode 100644 src/main/java/com/mojang/minecraft/level/LevelIO.java create mode 100644 src/main/java/com/mojang/minecraft/level/LevelObjectInputStream.java create mode 100644 src/main/java/com/mojang/minecraft/level/MobSpawner.java create mode 100644 src/main/java/com/mojang/minecraft/level/NextTickListEntry.java create mode 100644 src/main/java/com/mojang/minecraft/level/SyntheticClass.java create mode 100644 src/main/java/com/mojang/minecraft/level/generator/LevelGenerator.java create mode 100644 src/main/java/com/mojang/minecraft/level/generator/noise/CombinedNoise.java create mode 100644 src/main/java/com/mojang/minecraft/level/generator/noise/Noise.java create mode 100644 src/main/java/com/mojang/minecraft/level/generator/noise/OctaveNoise.java create mode 100644 src/main/java/com/mojang/minecraft/level/generator/noise/PerlinNoise.java create mode 100644 src/main/java/com/mojang/minecraft/level/liquid/LiquidType.java create mode 100644 src/main/java/com/mojang/minecraft/level/tile/Block.java create mode 100644 src/main/java/com/mojang/minecraft/level/tile/BookshelfBlock.java create mode 100644 src/main/java/com/mojang/minecraft/level/tile/DirtBlock.java create mode 100644 src/main/java/com/mojang/minecraft/level/tile/FlowerBlock.java create mode 100644 src/main/java/com/mojang/minecraft/level/tile/GlassBlock.java create mode 100644 src/main/java/com/mojang/minecraft/level/tile/GrassBlock.java create mode 100644 src/main/java/com/mojang/minecraft/level/tile/LeavesBaseBlock.java create mode 100644 src/main/java/com/mojang/minecraft/level/tile/LeavesBlock.java create mode 100644 src/main/java/com/mojang/minecraft/level/tile/LiquidBlock.java create mode 100644 src/main/java/com/mojang/minecraft/level/tile/MetalBlock.java create mode 100644 src/main/java/com/mojang/minecraft/level/tile/MushroomBlock.java create mode 100644 src/main/java/com/mojang/minecraft/level/tile/OreBlock.java create mode 100644 src/main/java/com/mojang/minecraft/level/tile/SandBlock.java create mode 100644 src/main/java/com/mojang/minecraft/level/tile/SaplingBlock.java create mode 100644 src/main/java/com/mojang/minecraft/level/tile/SlabBlock.java create mode 100644 src/main/java/com/mojang/minecraft/level/tile/SpongeBlock.java create mode 100644 src/main/java/com/mojang/minecraft/level/tile/StillLiquidBlock.java create mode 100644 src/main/java/com/mojang/minecraft/level/tile/StoneBlock.java create mode 100644 src/main/java/com/mojang/minecraft/level/tile/TNTBlock.java create mode 100644 src/main/java/com/mojang/minecraft/level/tile/Tile$SoundType.java create mode 100644 src/main/java/com/mojang/minecraft/level/tile/WoodBlock.java create mode 100644 src/main/java/com/mojang/minecraft/mob/Creeper$1.java create mode 100644 src/main/java/com/mojang/minecraft/mob/Creeper.java create mode 100644 src/main/java/com/mojang/minecraft/mob/HumanoidMob.java create mode 100644 src/main/java/com/mojang/minecraft/mob/Mob.java create mode 100644 src/main/java/com/mojang/minecraft/mob/Pig.java create mode 100644 src/main/java/com/mojang/minecraft/mob/QuadrupedMob.java create mode 100644 src/main/java/com/mojang/minecraft/mob/Sheep$1.java create mode 100644 src/main/java/com/mojang/minecraft/mob/Sheep.java create mode 100644 src/main/java/com/mojang/minecraft/mob/Skeleton$1.java create mode 100644 src/main/java/com/mojang/minecraft/mob/Skeleton.java create mode 100644 src/main/java/com/mojang/minecraft/mob/Spider.java create mode 100644 src/main/java/com/mojang/minecraft/mob/Zombie.java create mode 100644 src/main/java/com/mojang/minecraft/mob/ai/AI.java create mode 100644 src/main/java/com/mojang/minecraft/mob/ai/BasicAI.java create mode 100644 src/main/java/com/mojang/minecraft/mob/ai/BasicAttackAI.java create mode 100644 src/main/java/com/mojang/minecraft/mob/ai/JumpAttackAI.java create mode 100644 src/main/java/com/mojang/minecraft/model/AnimalModel.java create mode 100644 src/main/java/com/mojang/minecraft/model/CreeperModel.java create mode 100644 src/main/java/com/mojang/minecraft/model/HumanoidModel.java create mode 100644 src/main/java/com/mojang/minecraft/model/Model.java create mode 100644 src/main/java/com/mojang/minecraft/model/ModelManager.java create mode 100644 src/main/java/com/mojang/minecraft/model/ModelPart.java create mode 100644 src/main/java/com/mojang/minecraft/model/PigModel.java create mode 100644 src/main/java/com/mojang/minecraft/model/SheepFurModel.java create mode 100644 src/main/java/com/mojang/minecraft/model/SheepModel.java create mode 100644 src/main/java/com/mojang/minecraft/model/SkeletonModel.java create mode 100644 src/main/java/com/mojang/minecraft/model/SpiderModel.java create mode 100644 src/main/java/com/mojang/minecraft/model/TexturedQuad.java create mode 100644 src/main/java/com/mojang/minecraft/model/Vec3D.java create mode 100644 src/main/java/com/mojang/minecraft/model/Vertex.java create mode 100644 src/main/java/com/mojang/minecraft/model/ZombieModel.java create mode 100644 src/main/java/com/mojang/minecraft/net/NetworkManager.java create mode 100644 src/main/java/com/mojang/minecraft/net/NetworkPlayer.java create mode 100644 src/main/java/com/mojang/minecraft/net/PacketType.java create mode 100644 src/main/java/com/mojang/minecraft/net/PositionUpdate.java create mode 100644 src/main/java/com/mojang/minecraft/net/ServerConnectThread.java create mode 100644 src/main/java/com/mojang/minecraft/net/SkinDownloadThread.java create mode 100644 src/main/java/com/mojang/minecraft/particle/Particle.java create mode 100644 src/main/java/com/mojang/minecraft/particle/ParticleManager.java create mode 100644 src/main/java/com/mojang/minecraft/particle/SmokeParticle.java create mode 100644 src/main/java/com/mojang/minecraft/particle/TerrainParticle.java create mode 100644 src/main/java/com/mojang/minecraft/particle/WaterDropParticle.java create mode 100644 src/main/java/com/mojang/minecraft/phys/AABB.java create mode 100644 src/main/java/com/mojang/minecraft/player/InputHandler.java create mode 100644 src/main/java/com/mojang/minecraft/player/InputHandlerImpl.java create mode 100644 src/main/java/com/mojang/minecraft/player/Inventory.java create mode 100644 src/main/java/com/mojang/minecraft/player/Player$1.java create mode 100644 src/main/java/com/mojang/minecraft/player/Player.java create mode 100644 src/main/java/com/mojang/minecraft/render/Chunk.java create mode 100644 src/main/java/com/mojang/minecraft/render/ChunkDirtyDistanceComparator.java create mode 100644 src/main/java/com/mojang/minecraft/render/ChunkDistanceComparator.java create mode 100644 src/main/java/com/mojang/minecraft/render/Frustrum.java create mode 100644 src/main/java/com/mojang/minecraft/render/FrustrumImpl.java create mode 100644 src/main/java/com/mojang/minecraft/render/HeldBlock.java create mode 100644 src/main/java/com/mojang/minecraft/render/LevelRenderer.java create mode 100644 src/main/java/com/mojang/minecraft/render/Renderer.java create mode 100644 src/main/java/com/mojang/minecraft/render/ShapeRenderer.java create mode 100644 src/main/java/com/mojang/minecraft/render/TextureManager.java create mode 100644 src/main/java/com/mojang/minecraft/render/texture/TextureFX.java create mode 100644 src/main/java/com/mojang/minecraft/render/texture/TextureLavaFX.java create mode 100644 src/main/java/com/mojang/minecraft/render/texture/TextureWaterFX.java create mode 100644 src/main/java/com/mojang/minecraft/sound/Audio.java create mode 100644 src/main/java/com/mojang/minecraft/sound/AudioInfo.java create mode 100644 src/main/java/com/mojang/minecraft/sound/BaseSoundPos.java create mode 100644 src/main/java/com/mojang/minecraft/sound/EntitySoundPos.java create mode 100644 src/main/java/com/mojang/minecraft/sound/LevelSoundPos.java create mode 100644 src/main/java/com/mojang/minecraft/sound/Music.java create mode 100644 src/main/java/com/mojang/minecraft/sound/MusicPlayThread.java create mode 100644 src/main/java/com/mojang/minecraft/sound/Sound.java create mode 100644 src/main/java/com/mojang/minecraft/sound/SoundData.java create mode 100644 src/main/java/com/mojang/minecraft/sound/SoundInfo.java create mode 100644 src/main/java/com/mojang/minecraft/sound/SoundManager.java create mode 100644 src/main/java/com/mojang/minecraft/sound/SoundPlayer.java create mode 100644 src/main/java/com/mojang/minecraft/sound/SoundPos.java create mode 100644 src/main/java/com/mojang/minecraft/sound/SoundReader.java create mode 100644 src/main/java/com/mojang/net/NetworkHandler.java create mode 100644 src/main/java/com/mojang/util/MathHelper.java create mode 100644 src/main/java/de/jarnbjo/ogg/BasicStream.java create mode 100644 src/main/java/de/jarnbjo/ogg/CachedUrlStream.java create mode 100644 src/main/java/de/jarnbjo/ogg/EndOfOggStreamException.java create mode 100644 src/main/java/de/jarnbjo/ogg/FileStream.java create mode 100644 src/main/java/de/jarnbjo/ogg/LogicalOggStream.java create mode 100644 src/main/java/de/jarnbjo/ogg/LogicalOggStreamImpl.java create mode 100644 src/main/java/de/jarnbjo/ogg/OggFormatException.java create mode 100644 src/main/java/de/jarnbjo/ogg/OggPage.java create mode 100644 src/main/java/de/jarnbjo/ogg/OnDemandUrlStream.java create mode 100644 src/main/java/de/jarnbjo/ogg/PhysicalOggStream.java create mode 100644 src/main/java/de/jarnbjo/ogg/UncachedUrlStream.java create mode 100644 src/main/java/de/jarnbjo/util/audio/FadeableAudioInputStream.java create mode 100644 src/main/java/de/jarnbjo/util/io/BitInputStream.java create mode 100644 src/main/java/de/jarnbjo/util/io/ByteArrayBitInputStream.java create mode 100644 src/main/java/de/jarnbjo/util/io/HuffmanNode.java create mode 100644 src/main/java/de/jarnbjo/vorbis/AudioPacket.java create mode 100644 src/main/java/de/jarnbjo/vorbis/CodeBook.java create mode 100644 src/main/java/de/jarnbjo/vorbis/CommentHeader.java create mode 100644 src/main/java/de/jarnbjo/vorbis/Floor.java create mode 100644 src/main/java/de/jarnbjo/vorbis/Floor0.java create mode 100644 src/main/java/de/jarnbjo/vorbis/Floor1.java create mode 100644 src/main/java/de/jarnbjo/vorbis/Floor1.java~1~ create mode 100644 src/main/java/de/jarnbjo/vorbis/IdentificationHeader.java create mode 100644 src/main/java/de/jarnbjo/vorbis/Mapping.java create mode 100644 src/main/java/de/jarnbjo/vorbis/Mapping0.java create mode 100644 src/main/java/de/jarnbjo/vorbis/MdctFloat.java create mode 100644 src/main/java/de/jarnbjo/vorbis/Mode.java create mode 100644 src/main/java/de/jarnbjo/vorbis/Residue.java create mode 100644 src/main/java/de/jarnbjo/vorbis/Residue0.java create mode 100644 src/main/java/de/jarnbjo/vorbis/Residue1.java create mode 100644 src/main/java/de/jarnbjo/vorbis/Residue2.java create mode 100644 src/main/java/de/jarnbjo/vorbis/SetupHeader.java create mode 100644 src/main/java/de/jarnbjo/vorbis/Util.java create mode 100644 src/main/java/de/jarnbjo/vorbis/VorbisAudioFileReader.java create mode 100644 src/main/java/de/jarnbjo/vorbis/VorbisFormatException.java create mode 100644 src/main/java/de/jarnbjo/vorbis/VorbisStream.java create mode 100644 src/main/java/org/oyasunadev/minecraft/MCApplet.java create mode 100644 src/main/java/org/oyasunadev/minecraft/SPFrame.java create mode 100644 src/main/java/org/oyasunadev/minecraft/Start.java diff --git a/resources/2char.png b/resources/2char.png new file mode 100644 index 0000000000000000000000000000000000000000..56196afd007faf49d255b84645e9dba1cb32e4a2 GIT binary patch literal 318 zcmV-E0m1%>P)7 z?2qUNfF$rp3e6_czj{EMzJGfU07+np6z_(R{gOI(cr&#o(5jMjzCs7 zVCNeEM8FbWT~Ge&KSF7M1Aqvm6KMA*|8oV}38nX+6F>yg3AFo@|JT0(Um{*I&@44_ Q-~a#s07*qoM6N<$f>6DIE&u=k literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..5c26ea8e2aab7924d179ffc5c682e9f2da8e975f GIT binary patch literal 364 zcmV-y0h9iTP)6Zd%GEumwpUNz$3`nb;B@@mm)aS5&2OatsheNhD3f;4}t78@rFZwR8NH; z^*fIsQ9X4Nyy1`^)l=dB3AlOF^PUJg@oU}NucW{9CYFZp-C3m`gI7)f8_N2hqV+?#=@vNHCKpFg<^dn5Z)#%jH>hIo9b7gSl`s}`{EnI_K`4-RtACq0000< KMNUMnLSTX}WSCC? literal 0 HcmV?d00001 diff --git a/resources/armor/plate.png b/resources/armor/plate.png new file mode 100644 index 0000000000000000000000000000000000000000..5350f3fa98e5e6509510206a538533c68217d8dd GIT binary patch literal 742 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..fd7a724e77b279c74893b19356aeaca21ff73a17 GIT binary patch literal 1193 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fHRz`)E9 z;1lBN)+Q4$K`nHucGxtX@aeh{GxQ>7>PO8oh@Nd2Gsh@)u5sKvllb|j2@A{;7n&z6 zvPfQRnX<$xb*XjQGMn_}wizqzGFRGXt#Zg-?U=L1DR-@N-a423^{zz=ohny&)~@j_ z*x**U(Yt=QpLxzoRTcVOMVkox_hjT-`+HU>3s3U1vJ z+O{>UeOq|P_K40MkzG5Zx_3qQ?uqT+7e8TtLc@Wurb7`eN21z~$9A5KpLif~(!r$3 zhmxlpPMLZnb=uLi>BrJ%9M70@I%n>g-1+D77o0Cxc%g97#iGTRikDn2S$U&!)y=B4 zcWO7>ZvckOC>RX^{|%B`fuSH#;u=vBoS#-wo>-L15RjOeSEA?V8lq5UtY>Vt^7$iG zpqlTVE{-7@!K?>6otg|J7#_r*W-kc^U0dTGLb&W@O&{_>ceccgHzyZ3ibB z`|4&rn#SF^c~5n~jIL9@EwWjMf4!bNIO5v>Noo^}?7p2zP z#ay4hZPV@3XIgXa+?DP{V9?yRb_L3do6VQ@l4jT?d0MUS0|hQdbu}ij--r7@)}l7UqLJ878Pzi zrs&88-xW73S-xla;hitGsIvZF_pj@uu{Pg^xS7q5?fRamEPQ$>u4&$;Yh^O^Rrj5J cYRvw!?=DkHyy<$j2$WbnUHx3vIVCg!0EBfXbpQYW literal 0 HcmV?d00001 diff --git a/resources/gui/gui.png b/resources/gui/gui.png new file mode 100644 index 0000000000000000000000000000000000000000..81af329e601467a046f59bdff22f450d23b7c7c4 GIT binary patch literal 14210 zcmeHuXIB%z7HvXrQl4YM^BLt*cK|mluP(KR|AIsgE0&G@eV0{{T{uL}gw zQ2lG10;)XzH58sY_jLdOWETDTBg%hct{?;ZAS+*wpy!VQ+yNGko;(YZH8Zdl3Q>|( zy7O`QuQ&jp!fvduV;$a`KxM13djw}AE4CLr4fEze)2j-%0}P# zuOb?aP9Bh#XJA;8LUT5C0tS9DXRi*gji}*?J(QK1n!BRr8bo;eikD0d zozH^p}w` ze-ukjy)?VkzBl|R5;LZHTGxpA;n}$^6ULRbUT60*E28hO&s(RqkPV)t1Ap$V%d@T7 zxNA`3a@FYb;X>$ci_B+#2c?r>NGMHZ#8$`iGzQBf2Dx&*a_oX*qG)pfNvuBTo8V^W z+2+ZzYUOWZrX$>A>eIWODqSZ-k}m)pWLLN@CACHKdd={avzN?5aWXd=(a%{&Jd<5Z zD`w1!V*#*qD|5|*Z4{BcUNzvV?ef9Q<}XKIeuf%&e$M!zTnv6!ff$*7v5P1Vw~t*+ zc+=c!R(`{%eR=l4Apn;n^wPaGd=?p!{uk`DPYW6@uz4S^y&Z2f zHR?iT@nIj%bvlF@7_KZ2S(|TkIdD$GM=m}eUcQ_cJjt9tBWKcRcmY5u3~O9~mIF?r zGHyjh!_><#2^KF|{9T*uK&ANTq32AVr^ohzG9&J(vD6d^%fu%xu#wftX++s@bbpEY9Jt8?4mKVJOzh=;v1CFY_Wp5UodyC6U)x2Jzav^^1c3oVy!aGUT zfK1{TRf)~K!ASxO*RI3ta(J=EH?yN*we`Le7%SRh7YoOCnooV#Bx3;&9u9PRMo>6l zAjJTCvSfhb+wT>*!e3O~Xp&{n8mf_|+unEfC@qjrH?3Im%>{N?q%odmf+8W?INh`^cLT0N^ z*IjchVVyW={F6qqpPN?bls>lpL|i)DGvOY(pD}$Pl*hAfIsK)w;Y-KE9WTjvz^~!U zY@I5y=Ddq9j+C|c0o4F&9w>k;)-^E1ZVn5ckC0Kbsh)>9ETzV>@Pniub!26wkOyYS zR4I*{Fv#Ow_trdYSwcC|VuiRDDwtm;!_zhQt-dSQNN}lmxYU0}n{zvwD98~yoH>p& zyUFHF-QVTHs~UV?Io#T&Zj&AxzRNB0F5sa=c|(Yze-X8#sXwsT+xYciV6DtlP1XXK z!>`Ehrj>&^2e7vELKs*>)?9oc92;B>_hA8WI}WeB_X|=73JjbMR+RZKn3hrg(P{sj zmT%aM5$M;sciHe6?O!Ftm1UaaZZD~#xKn|zr+;K zq-xwBga&sQ(mF^twwKDWVSyp!kYeF5C(3+Z0Btc`?|3QbNoIkrKSjv0TLVLJW)^i1 zyV@)l0nqf#Sk;2>8Uwp(^ph(U0$e;G53dQG-LS+1_(3$(!OraFavqdk6w-70%GnIZ z#iL?t%KQc@tj6w&BugHkV)}jSjI~+2n-v@qbv&O$eTKOmG5Fz?msaO3EY*+FwPH#V zN5t@{&IgtOn}o_8v522O{E%8YSB3UsDR_%cM%1ID$EI;C(8dC*)s{KGI|W>2x1|De zgozq8GzPKC)?$qTAa!4vltyvNZsR4sK405#ROib`m+r@ApZssnge{k<#H=A3-Zj)V zy?3K6$^gTL1WXRol{@%6jN_sTnZ6NsoLfB*GL6B_Q+iNUe_AN%H67rav<8t4K2M3#kdymD^3Hmh$^H7S)}2y~z{>noIZf{|D@KOs zc$r6+-d8;;I3f98lkIjDMlQL~AVPlj=ih1BHm%rHNmg{ph|zW`7juIPYRoVkKd^(` z`7l8pQ^XP?wxAX}d?+~SohinKqvbX;q^u}u`{a%`*|`aq1OABx{+__WH^u?6_dnu@ zmG0*3%2}S?CErv8{68lNgg@@o=UysR%LP@%rDJvJ-;-q6(&SP1WlFs5t?&Xs*{O!0 z4tD0>8slH9Dcn--Pu-0a0XgqQkv%HC1uXC(Q-6YbM6I?iaQym6XjVqmfLTNsW7l=d zguTWsa*R!+aEdcx5L4i@Jl^+HmLLknttZrCu|-|!n$7#~1+@YdXNX(h zpXtE=P{Ft&#HZ^hA9TDcZ*rQoue(jq62t2hHNLHLnkA80Nb`%~{{13xJ{K?Cp3|tsrf1 zkTJ_4Gne-1z4OiE6RVe#&l-F}S?&kA`Yvb`Q2=NM5#*W|w*XtfUU;@J$6Z(3zbC&f z85hJ070L4fM0fq&s2HD}oa_1(&9JoN%@#!w;61Q6p`Ioy{coL;T-kBm#rCnxO7#}< z+=+%}iX5E-rImJ?1P=4l5l}Ocr+(gCpYu zo*8btnDPO&(+#o$Y%@T+&*tWf_DE_d#0+dQh{?6NaacXVCS?4gR?O_|#Sc{v*@Jln z4vM)f&0s;1V#FGUtEyY%4FAL=UGj_Iu-)I!BzV^yqy*#$P*-ucEi77{SapYEf(!<8V*=t@KYZ2cYyz@1345#!aIpGM1xue-Vi0dXVV%6TX4E;{rS`bacaJjrSOE%od8K5<= zuesWeGp{P3ahokk-?Hp|eiW5{@;rpBq`4^hsi8!Al-E06;m9Z}Yeb?#VzXq0f zRJZIqM?~-$eei$duZLk+XM9t!Zx>9ohh`03m)C$C?byG~GhXu5*_FK_4JrF=Yxm9L z%cF4Q#xVUwSW?N30mrPKuxRzCt+2u1=E43577d_9c0*C}j6#o88_0#^pdT>GDyr3- z=F9OkdKOu3XS1Ya#_)>M?e7ub94Yd3J3&;|auPsgHDt$*K8%l8`f>(;# z?>+hbvAhn4)6m;~zM)uGSHo1UHUQ)@awx;|r0q-w>1vf14;(ZQz_Ma63)(Yke*5$IK7 zBoGFZjrnPCG>#>=4ftp-0qM=#$;K@rI(eQCUS*Hte|R!%RRfyM$;g4na&^aYBggfd z+XG57zhV}XAReQFsmF4iBUzBrogHlSP$Fb*w2)9gCuDcNSa$4uLF6NZp7)!cyO$hG z8x9uZIM42J4Dl}?Ddeb}jSDt89?~22kx;!m#|HdOi)Fv}!p7@`Pojc$AU^&3JxorL z2$q&<$T2D4v}rJNr*lb~?6DA>;9Iq0buUThpKco9l^pRc!pRduZg}up!ZUs5T z2VS}I(ei82XH&Cfk?W4Lug*`dF86RMSJ-k>m-8+;v&$9jiy6Q6ZQtm?UHm0+i?RIb zd(7F}lLPIO`WV&7%hH$&-aW7Vlb_nBg#uGiAINF$_3F9?vRGty9{){aqm;oKm7UCe zJ2JoQ$uiU0dtWIb7=23Kb6})(FoTo3B4**c0-cY_PS1&Y#nR8(YiV2qr>m8>D1j_+ zRA<~_sR~4)Wp{2d&*acqxkRqx*#vXn>7f7kYw09>gzs;q7SgFnB0hqVR5ly4OTbE$ zUy>>lw`_p>e<{V6F(PPIFhxbh^iAfjtF7n=p*#_Isffb`eJmRsP6J*)^z7VTP!NV| zpFw8%Xk2G~?CdE0$Vhfp*U3P-05Vluc6gsY)Hz~(ThRTd#9U^rRVjTeF&(`l0)I%x z=h-v9{Q`{ygDJK%e4~9jpUtioS_2FKAOqAXCz&K5mS_n)pYAEIyN_mbZF}{Gc~XH) z1Rir)9uuQGvKa*K;CrVDcb;&vhyZ{n8~-iA^2S1)f#)?>Cza$tQWx>J2%PBC&eO#_ zd6P^8&@od}F`lLg;?L5APoK%jl1<($9PeUQouRP+p7(2?^e()q!E1X^SQNvtQvtW5 zh5Zd< zD(pZhcvjSsUXLL8#&zmLz&=*@KL`5n?zn+5EGyq?W{^;_<7w?P%mOmz6c^5ZtUC26 zQH~;$_TS;O&za;*XReOrOg{&9jphOz1HPx|$T*r82u1gHD-YaH%E5>uc zJZ98(i*+T*;MhMWoMG~D_L?nC$z6)`oAA4HtIK6v(Q78!C*REzqE=HypGl+X!8#E`S)GBZ`+=?xS+}iRPh*)nB#haS)B?r#|2iGe`g~mTIt9H};#K)DpqP<#m=iVovcO>9EU0YYK(6No9 z2dU#kk%5KV^Os=XFI&k}#k9CNx3`W9~V4I<;)7qgJlPvaGYMU5^dk=-u2zhkcqrRUh za%2)0J9s%I#6jPG$i-#8&BzacGJ*?u^Wsg>+yvse8I|f6(48WRlahUnIj)#mw-gu~ zxqP0NO^UgnJ3HWO{8-_oze^vJ6U`-(fq#R;Sm)^WhagRrc>{j*LIH+|$bHYq#* zJx$6BDd2R_#Wmm1o=EP0nEoW#TMS6Uhrh>#A?KFdMtM1SgoGR|0>M^>Puu%uo>{~E zJ$H8cZe*Jm*!+ow;x--f2l494n{w$H8%3H_o0FHcIxOURfkL8C%bN|KcRDABg7pOu zD$;&lrFee#)=N zOWlRRyaP*SbYzaCP2P+gW!K%WNF@%{{i6$7ynePrbDe}A>e{{iZX7gZZ%D6RzE8tt z^KUwLw1B=p`A?)@*ou;&G6idIp*xB6&}m8kuV<9pbcrg`Q;Y(F*OM|E`Mv*QJF@=9 z6ip@YtI|Ff#(8B!VGnMzQl;zUna!9~p-G55Uj zWfadfDOGoSpH6EsRktt@?Qeb@!Y~6EDbL&&ql3VxH7UjIAGytp&4>@)AHItx%c(_b z_3NNol-hmMSG63}3a}2VDUmPu&&p*Wob^%f-{(`~??m3RYZum{#;JJ;-_IGXTMcc-y2=Qk6kJpMV6 z^gKc>yxDSj0LY}puNMl^*%Phf-x<_wCumTzJ}uY+nfyB}*e0$2Y9Qzdt8y?}Bc`mf}7OK$Ot z32LDYg}d9*Eq1=h2=_`Uu^w0N7(7$IlL(k3_j8@h9^gWtT~&g)D{5n>3!i=FGM$m7 zS1v5ZI?F;B$na$AwFkF<70Pxt+k);IdFEu}JNmob*mb`XW9c59$bLQjzJ^2YJBOf@ zqS}85j|ho2q>q=xAT)S-q;Gz);i%09JF!YR>M2f&vu4=oPEv+pX&j)6A%@Hj57JQc z^}J_X%-I@g5wzc5%{(tDebmvr?;a1zi%Z1HaUtj)*+}e*_n@T2X9oCw1_wD1mnRWh zoz`G&z8eKURW$;P@!k%(tJmW>$t3QgNL%hP5|W2+@A;n~=6T}F?tewnB`^FP03PHF zJ{!1u2u%S_LvPP-5FeyPn9-S;jdog#@mc|E={U&#l-?V>pR$VSBbz)^;EZxJoHDbB za7-_}WnS`AUqc|$W#~AxbFktX_l<(4&PP(Ue_o@UcMHe4?Lu=~!t`HhvL!jW6$Iwu zNC2E+u4nYZFSWYjQX!P<;`>`th_5nf?1j`_1)|x)-AU)jfOK5nQH^5m5nUfLp=wmx zwyd>FfnttPU_iIzd!q#fkNmX48}jNbPkOG&#!sHM({{$`qmh~$d!Zaz_)*&ImBGW41%{9=IN^mOy& zXcQO)tET|TKE<5Qss9(?p+^hWviAH}PQ_pHqs+u6p>-J^EZ7 zZWgI&IXta(f-JQoNxzN>vY*nwz3p} zIm)!%7O=_p96{1iMOAUE2+n@#BP%zhS5Uio&!rPuKWI3~s5^XjL}|M)V_VyXjP7qb zSP2r?F`4xMf|K#?*iE>h$i2fh8~TfjR}U~M?{LT8lYijzXMgIXRUDnmB?c`JC?v;8 zxUt7ibhiQ9KFW^r=U|f8IxArjtWU(;1ymkl-|y@BPR!Qu#E=j<_F|f|KlLizL5Kc? z_b1lIq2(*&-2R}~4`^Xoe#i?hhqeq%a$>4b!45O~#hYh8a4L4wb=lq#ANP&*5_@~j)*WnhzI*I9r@l@1k9-*i zvYDEPFcB@`zUoXF6VS~O?Ban;86~GqktQ%@&)sVSxz;zu`o~NcdPc1!5Ib;NATaY2 zuEW`os_Z0qw&u3vi^BFdnfp^!bnx3uq+5$o&;j!B^w<1%pFimTu`+n+T)uuE9nLl) zt#C&Mn>;n8&XSe$3)SBz&3!bG;XsD2f~AMEZTDrp{aFkrzWaRBm&~l-d~7Q~rfs&T zLnld{E`B%m4|OUaRVY?%9H1aC*|%n44ioDVbV zKpl0_SoeKPOYZ0|*8nVHsmSv|DF&0=>Tz+qye`l@N+9NZr-ih#8ql&?hgBpX=0U&Y z#s(HsLcmP0A4iYL3G%!>J~u9Q^05LD-afou-Ux?sZt1=63LQv;r8G;k&bA>8rsHI( znELN57g_c!?pN8VjAQ$AnrxAUK_@=Q3}36|s4O*opY z1c%=0?XA4pR7%`jKf9*#rvd(Y;647SWJgpdgYRZdN5k0HA1c3fHnR1IPh}>YXZby0 z$wYncQ6@DmtKC2TSbq9|yIRhkrW4m3Yu!jd|7MvlSKO9Iki0k1b_n2P}6~G+6oO+S@F5 zvCj4~kDihg}JREL`;TtN7zFf~PdXVh6DptnUM`;DdF=fc;I zlVlv2dwx5FB-*RCMdy(E-lHPR&? zmVj`#Cf)TA5Djw93Q5y{fA+MpMbuL9%julbzGRINpPP+j+nnAp>i3)+vwQ6wgBj}& zJme4B{>e`&Nr2CcsTE;Vk_~T(fDedJ?kPi~mkNs%d}TI$q3PtKU-Po(adlkRpn5bE z+v+yy)Syg#@MBbL} zq^p||N{4{YH*;gP3xcQp9UL)2%-I5=6yh6?oKKOAqIuai^81C6`#s$>Tr{S8?(0t# zbELSK)Z-FdliiVWF*Ia|TLpd4VeIkBR)jq*@7#A5Y+Bk1Ess6v~Gu}}$rb68|5#p^|I;nf%Ve7|6KXf^46bMd)R#0xQ6t^(b zy$f$#Ho2;k?Vmu4}n1TcfVHn;E^XzcN54r8d#C zh`@Jl`1m@uP}t`?M|{<;2LPDn+>^fwFB4v+4?fgxK4{{~`k=9W9xVgGZq6rAAgFI- zUN5x@_y}=IJTCFa<*feo@`5m>Me6HbPWt4>8=zi@X;_S6rMVA!b{wce4@8PrL4=}C z1$$+t1igklmbc!Kl6e@Tia+?ce7c^k6zk9c3gdY_9{R3baf*-$wVH2k;&bC;)pX-2 zoTlS3!~%fB2g$uqTJdaq$%qP!sUSbO9y6Z;`AOy(YH&^LbFFjx7w-*T?EdW=W<@zK zeILFq_f(lhVqf!f{u-#+he!4;S({js6GTuuBxfK*3l2GzjfFi$N9N~m=V26W*i*6U}Zd%v2_}xp- zq2yWQOxzA&UQURzqtr9BR!!W@=rDr6MOv=-)}OShvLbvFbd$|IU{?5_E=6;NB~fzX z>YtMHqpk^Tgst+Z;L*c4$ti7}$`z89fJ0%fmSfV}7%|$YW$|0yHB$Yv8QVt&8hMR; z-2$E0w+HL-$lOORUyPQtDcZUW?k(mWjCW)>lIeRUySI71=2~cI02wmysZrH`TT?RZ z?&~c0smUKeb-Jx8R}d=@x^w#xpM+LSmV+;jKq4`474^eCoPw_~fI44F@Z8kzNh~^DDkn0dq{y*I>7a?X_#r^f;$o4N%-%J(15g4#s5OlE)k4v^H7PeB6+o3A zyq2~1!)3Q^$1cAQN|CHr)rEMU&9ASUKesnB@ejK45oQbq-#Hiy?xc5rR6ubeQPuFy zNv)bok(;c4c(Q~tZ5(Y`;y45Q4$p5Hmc%oBTDPWv!m>y%{NT_*WbJM|^RF=WuSwX* z8W^7ddB2}jSkOwA(9GrG7kn4QubZ;xc4=_?!6#q-;m?rZnU07f{UpqOG>;YUExy+0 zCyNO4f7KnJ&qx053>*C-kP@qymV?aa?a*v1qxLM4(}exn+m_&8$FHnv>+iIFz(;3v zwpQ-6UkiN7hqaivjlhgLeM3*39`jiF{1i}oBhX6C_zFT?9l8CeGP>{nR8`yQqr3sx zHt&(?WuV@LTJ7(rC7Kb344#pCp5A|(fgo>Thd*VR{Hn&Dum!DXGR8lZK1+dftQ+sP zT!l5!8qIi&)4>-&OPM};srD_z$l+Kc`2&3(A_Fc4JyS1O&bdi5O{UT&X zX|Z*b21o_0sW2gq!CS!2dzZ0*&f^2z0)3Yj_po~BK5rgwImSm(O+)is{YWk5L?!Dm zWumNnW=wUh9$9wwJ12f8=vUO~staHF){JM7#>~};uS{kVUr(4i0>5!IawR=>*($I+ z7R(PR>z9pWj5&A=T3y|Ua#|WE1P7}rFU2teXWd)l>yMtF8Gs@WzDTg~r{8RUa}5TW zF!s6qVJW-z+YaI5W$TBKuG90sT+hC&KzVp&(1uV0hH<&J#L~{wDI*vzax}^$d^`$LzIC=L=QC^txL)vM=NNeu=^ucPhZO#~Qi2E!JMd2Ltv{_K9tvt}v>Z)C zO5`!-oku4@CFQ4tWl8Ow?L9rgrg8rXb1jt;ZiH9*>fRH^PEq=e***HMJA=3j!I%}3 zJnEQBX|~efA@{M{b!~M7&!L+Ro6&PEud|lIjzl5+80(1Xm?np@7~GCa_$hEDAYU5i+Xl} z^pr$69lRd;2TvrZY?l})ScW%sQmoco#1aRKrsW0Bzf2#InB_NB1G3$rYXZY!MtOlI zcm9jabx6aD!?H=adF$yVukMM8JfI0IK}!Es_V*Z0ScneNA@ zz<+%G(T%m^&CnAJ;_%3}Ol*PZF_zwT5u>4D1yyu)dT9}iJ-@tN{}i!5%B}g+ur;0< z_D$oMgW{f_5wBrPHeXIc!K1moQL_N&kPV}Mh}ilR_!;zs!&_0vhvMh0qv&U4w114< zM+8gNyU3WAcfqNK-J@^Fe=v%qGJ>0QDstTWhGAj&LkF}d2)M|dIk@WJvY;>DpCb0< zckGb;ch=?MYJMzcV}3!OU2mk{mIV@b@1FqM(7%sYl-hW|uBbclXY`rNZQ-{IBY!eW z@#|XT%@onS-Q=8c-AUOtKHHp9Vi}TZLW@bWSL=GYj~JvTrY9m{fi!S&z@p%yh>p<- z4?ng1&DWU1U*wcVFWFWsY^`G4WrjEjj)CEXL3@RP?A0f7x)l&Zn5uXYhTj(YSOA3@ z);{X4mwQ?GISa}*QZ|hi&*hvLH&X3os8XfTq<$>Fn`c;CiYol-b|yM7>T+O27M z!5BW02!3}juy_RH!x|NP(kO;zeZudyn`#tp%xELboIo-Z*UtwQVRxnlCNsp>^Cw~g z0%_(5s~_%CY00z=`U|J61d+|g>kWUbc-K)+|52+??2lE!SO@aNq4B}P+>aekEg(#A zt{|80(8L#9ZVseg9kf~q@{jv9E!$xEO3d#2msv!hp-=|PHOATyhinhAje$Fod-m)p zB?doX5oFi?ZX=^K@ek-h_nM2hF2{v|*-qKTi?8H@t7hJip1xK1iIoN;sHfjBSxj5J zcJr-H9yp5f4x|CI!>?msvmbj`(|{E}gZmX7mD9I)VGcUPme|Frq|K8*k)Jk?P~hY} z;aPmNtAYtz&oXnyn<(J6*v&P&%NA}^Cs{fHBOLxI9}0Xfuz7nFg|_E_^U@mFeh6(#BtFz zCxM2F$+|!b=2gOpl^g>Vps0)E)Ul@Kj$|29vEmkkx&FR-T%qFZ&;N>!e(YLEH_>(X z>MN>Tm4rGxd@`I-4M1_m$|wH=tX@rKhXLuP<`}>D zHnx5M1wNuO3sMLryprP?a)|W)^yOJtCOOf%FO^MKLcwag^nKi&H#8ixT%yH0aVc_^ z%82T6n*pl0pYe#N#&?*P{?UbM%2}s9BUE-KX8Zmxq$WTwCZ= z@oa!=(vq>SY(eik^-SlyaegmXjs`(xG`Os~LNLFd{Y)FF#ts$(#11Y&oJ{DHfwj|t z$S<31|KM4Y{p=%{95t;7r0tnxLk=63FCq&J?N8CyP*m@(jP8{6c($J`w{lztv`Nyo z%@de2TCG!Jq-$Au1=942QdIGJ4nbgslp5msBEzx?!s>0Feg_86N*jY!6+OHAO&n#K ztc8(3dm!zCI=BFeh~o#~J+=8>6a>1>0rTdqkr}#nGklRe1iAaCN*qpu2EuJbZ@}4~ zCp_7z9Wu=Kv{XysGntr#i%74$`mf|W_*MjBj?JAm?%$f1Ck*I8vpA;x|HCE3tA(&| zfPsWsODt)UA@~pn}%2O!+?M&W-Xai*Xd1q zTK6^axo)Znxi@e|hH1a_US6vBv){YUfm-J#kYep%;hRrnakU}TTj!+n@5+&h7viP) zKdW-@Jfp3EAJ{noZv;lh_CvoR&!9lIfoCX~Q%pbYLc%)5(`MOT1!&5KPSF9h=$oi+ ziDf{qBrQeyDJ-k;t64rv4SfllTF{5;2LOYJUOFlfcH`Zpx2KKzV^IewHaWiS#u8G> z4F&BKg2x$}m*c^5O~e6Ho>`pMz@P{<|L?+|#bKZQ9o^Zlg&PabY`$f+fGBF^v-IY5 z_)$JVw*OWo^Xq}FKY$Q1+I>4e22Gqi!+|xZY;caH+sK)V?qDxhfy&(V3Pp9Q_y*L` zV$oQmSaFB~xssd?H!?d~7Ucd|3|R82_AYb7rI>snUYeQ`*~Rse(1WmQH^A9HEvIA< zj~3H$*Rr|(k8`}~OXlTw`^PyRyWDwM8q|S$r1UKPvCv<8jC7+Ff7~tJ$(Z6h|U+v9-W+K1KNYTcmo3&cOZ{&O>zaL;fedUa7P1<5nzieDN zlTU7wrT6F*i%Kn-pK~tfFQ8SeucueIvhrwrWpg~LGNIQx*cD- zpGo~$nv~UIr^t7ML3{3m8D6dbNJka6xVL&S6#hFiOv7D}@PnizFZFfRD-?w9KO7`_ zITlj3GI^VS?Ci;4T3zUsAL*4=;CM$3qt+e5^8vQJjY{a&hX3m6`}1{FHp?Ha~hlupkK>Ma~F1y+NNxxsg zLChYlOaGUbz|4ofYc`NedgFr;oP1v;7_gB{PH#&0`DN-lSH}WD*ux@0-$7rpnX^r~ z!FWSV>(UZ-8Mw^2)%_mNb%UHO$ri*1&V0Q?(R^B+!AFC&0hO3$8cx}W#rO2z)C}D( z68fhJ_i~a>-amSF_wLc3uxXrf;)1Tx=99V`2x>M|+gNqIJlAj|V2tY@Ir$q3{aVd0 zmZFg@wCAC}LX5vQL8V!lz`PUxn8qSwz4rz;ZD`!J!363BmgU5Asus^U+u7}i8Ts5v^T+^+-UAT-y>HfXK`KSS*_>0>up zZji0aB)kU;k7R;bz@U)vM&=cPSP}TAs(H-}iN0=enQgoaZu? z;%|bsMgss~5*Xlj5CDvpQzHPmZaIXpDx#MI{FG0y4*=9$H`YWUmd_iL_R^9LF{6{t zN3l)<)Tr2mBm!mcVO+8s!Hsxt?3DumAbSG+d=95XObz-Zj1VmVX_(Wvb6Q?q;ZP)@ z`yAB20KyI^MUwdF{tjTO^hpHS#PX0J_Syae-{A!q@+JEluVj2(y*(*4t#Md3&#I`- z5hi7Bit^0tFySn?=g{fN7aih*WIaUYSDji)`wgUNpV`e~9&gNHG`VpzDYqb7pv69f3TTAUo6&hbRdA#at(^e+-Pavx**c4B=%eEDeW$ zzRrh-DEUD%5iU6vwN3PpX~ixhW8bsRyiGUXSPN+CIGU*RB7ReF>_0lErrEr2P3u}0 zQwv4mu+A|F$aDhc!j%J4de;4-U9bT8-Qy3m)~2@TPMGMW$DQzEMeHp1d&z+N7^)bb zeGh5CP4PEs*aq4iJ$rpuYEWy}74j`j+#e^LJ8AI!Z9EJVcNTMn?5LWvuda`isIUPz zu_$?JXZ zrCYJFEJxsCURIF2#|?&1NV#_kvVSB`rB9YOxD*>%F!k*hBeRZBZCWd}wyzVyz;NW? z%k{Y8Rtt_7p$#UHX~#AodKhz!BsPKYi4QhdaSef!hA&~s6W)kaWXf;GovK9#YACR8 zdRP{JDVKa4>Nam6>RJYKw@A5U2ADt8EbKQmfm%TR=ZOqW{$msW5*KIyZY|2DKeDq1 z^AQP|`V1GX^;w&1WID)iz94H^Lt5!Np78r;<3W-0@T&YZq*|1Fntqi*GL8zfSwlK) z9y6~qFs!H$NBg?Nt&QKk)@nk#_+Qk&M9w=E{9VrZr0coYnz_2ewG4S4iL@gxql?H|t6$YddBD8GfD#MD3={TaFZ%K_L zVyLTmVVA+CT44!axmH=RVAZD8=?_{29BGOpvjHRUWAf32k2m3ed<6~PD7-P8UeYje SA7%Lq1O)D-_*LzRyzn2v%q{T% literal 0 HcmV?d00001 diff --git a/resources/item/arrows.png b/resources/item/arrows.png new file mode 100644 index 0000000000000000000000000000000000000000..75c582877e773a81080d0af6a9dc5822657fcef5 GIT binary patch literal 322 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzmUKs7M+SzC{oH>NS%G|s64!{5 z;QX|b^2DN4hJeJ(yb?V>*ARs=V?ATDmCqlk0@Ymgba4!caDN+O$i-wRuqXen@;k<; z2$_8j`xS0PaW!US>V_$`{84$LtSx+^@Tj8B8$&Tp9?sx5erf72i_SH*?oHNR+aa-d z?t|Nz0uOe)ep-6d??=q>L+35$9ISkQG^FJkBL{8gOj`t6rf<0QwoY`N zvcrKD=O;dMC~cqCI3;MKoV6-*#wt-krwzhy+BY+_*Xf@>TYIRwMx^fCL!NV%>dTb2 z@HsFf7#ZajPhRHjxPx#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy7<5HgbW?9;ba!ELWdKlNX>N2bPDNB8b~7$BHmT?0B>(^fMoC0L zRA@u(S4mG4Q4k((9P}oM8!9Gpk$q7HWf@>_0aQQ+#mE6SWJko66ClhCGseUP-0)zc ztTz)cCjJBef(MUy(*w8ieXpmQN7FqsP0|@MNK)yZ_g;0q`l{-yBE=Q?`|_-fzW?~? z@)Tsqm6gALcuRk#?bs>T@k~ukb^ZFi;!59@CihoYS6zwJuj!mk*>GVy3%4&8(onnG zQn0TIpEX-E`;OE4c6?oT_S;MceHd?8C(Gehf?$0q?9=zAhH7Xo(4@;^$VU*PK6F@r z`Kk6D2!KJRvB0*OeRW;kk4N7&5PUiRKo!jgn`u6v$x;M>Iq|MKZFH7@uYrT}Yx?qg z;=Am$mA;vCII9AN_gMP20bsNdDO?nhgY#IVj^ zrQp032bggQpH;aeUVYmDs2RYu9~777`bUi;vY#RTCRz|#urQ?w&dA?-W@wxM;8-8u zL>U5D@2rgOF+p4|~O$SL#YG09WWdAUGt#0r+mTxj~&lV$Bs+ zvj~6RHUMTEVC?^D$|Blunt8yC1ET38lCe4hmw{QS#L~A70H-3Nh*oH9gDMFcFT|;j zbwr;BBee}m5{%3NMt!x;%|MC92kMN#Ll%N*8vv_mj7bd6uw&>1nxoo00K@9L>LB#N z{<5&}#Iu&4DHy?tCyWqIk;d+9j69Iho#QAYA-LPfzrx^W?w`rF)8a&$N0_soMc()pW> zdC3nzY4%=fugj(D=X0dfoy`UG`r%nB&p$x7n(~t$0HnLOr_B5MJFoMVJpT8#o_=1Y1Du0|1l&oX13n z`bP%fnc(X=Z~jEiKIy1CYmaPwOo|wbw?!KS;i2w%7Es$_-{q3z&j9Ch?7xLAjle$} WXIQ$!=VBB90000pgDhO5Usw|))NaUhG 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 FV1oXoX$$}W literal 0 HcmV?d00001 diff --git a/resources/mob/sheep.png b/resources/mob/sheep.png new file mode 100644 index 0000000000000000000000000000000000000000..98cfa9ac57ba0d9f896454d38108afa571c2bfff GIT binary patch literal 2434 zcmV-|34Qj7P)y#s&Af_O5$b+iS0P?Zsv7wb#7? zq4zG)LA>#Tgih}7tnY>(Im22gg=D3xnc2B>=X~G!PPvofa`;`kbV-=<{P}ZNN=k}r z?b@}jXV0FwUc7jr=TDzLb#2(N!L@$3;&= zHU@6rzOA0WbLWm8@icj1YHCUqK$YM>LV)mi+wi-PKj0red?;tno>kC<0U^LOnI94u zSFc|E_YnY?^XJcN{1VG}oB>e&BL^@R7Z+uIem*hA#>V9M@#9(+@&4n-k2N1K7b3XF z8kEU}g#{&zxhp9I6)pBR%de3x9pk zd2?j2_K*ZiQ`HGcD-hZ8Ach0rMK~lbo%tmVxR_yHzT4(vp(GvlvL& zU^GDK8^{~iu3b}4;yHlu-%19KG~`RHtwh(F?RKlz0gH#HIxA(VuR#_=4RU6*E1`^O zLlC4)nCF6Jd!?u7=i~`Mwl=9jfNgtil7pbi)UQMa26R9Oz<3UV@Gb!HE^{G)*yV^S zn8SUDp^;jN0PZ1e<^%dfxKRKIA$S_e6B>}Bt$0t3o`>C8>Ur!484{9K03O6Zj<&%8 z{Pgs+E=sK1u((oRujhEv=8j-6sB=kn%(Zy{!!eXlvGI>GRx%I*$6AUd+L*6#jx)wu zOBCcnuuc|wJu=tp)yfm|RSF@)J+6nnhfNaPqq!hy0{-d;2q#n)DBLASjpuBOO$Y&s zP=J7e+H6$-Acq@^luYsiLy0od=b7>50vYmTYtHf)?9%hewqm_z{MGmz-`9C~tJI}` zp$Y;3B`nfdAcNjq1w|MP*XOD1=S|Eng_|{e@OrehROiN8i{qecvNRF*7~pu{Z_ZI8 z3Pus_**_#t0O4S}JG}G$yYKvAI3jeIKp0>&Ympt4s@SJ_21SKR_DE;$Hu2|~VXnK4x>%p}be%Jt!^sGbheC>|+%y?fsyFZlXjL)12c-iZ)2XFwgyR!>J0ORFrVi^x4 z8)K9`2%u>S*JQ`#?XTAMcg~F2?wWX?ZwSCS04EQOnDR$nhvap3mtzQXUY0*E<}+Ec1R!C&kAw+5Bo83UUteXW zL`{>UJ3!L~V%vPcqbi}pq-yYdq%KF}pU|Y+nu7pDH} z{(E_+hT*Z6!i2Y0(`qUKW<5yNZq6tHPyiyNXl?+F*KIB!-w+BD?WI~OsYs}gT)^|R z$Aj)n1rLT^(;xJiohpiObWl&;4_Zd3r7)_=rTCWwyW#2sYN+SDg(xOgi5bbFzxnh z5kR77NZ+i0`wVy%4_EDzX#HUssmnHv$6g7Pq%QxTDIKQnY8Eyl;yLKd@GCCBXszW& z)@*nH#pZ_nKC;yga9Q@KkNZ?9&MgVd!Sf94j_(I{>Uq$3zddVwZF}wbf`9siSGT*ba}D$C%-+P_;P2+=HyZ$lP(uI(hX4Qo07*qoM6N<$f-%~h AC;$Ke literal 0 HcmV?d00001 diff --git a/resources/mob/sheep_fur.png b/resources/mob/sheep_fur.png new file mode 100644 index 0000000000000000000000000000000000000000..f1291a5fa1e4303d3f4c8ea8222ba76e280d71ab GIT binary patch literal 1661 zcmV-@27>vCP)(+tLNwEPPg0b3=R%gMLAkoBXE56@SQlarI`<>jT2 zu(h>Sz|YRkmU{%8ot>5Y9|ay5;CLSqybR>d&Q7(mvQq8t?iMvXJv~+X`}>8YA4kC5 z-CY6x@bFNsfC`Jn#l=E^9N{+#ppG9$0Ph3;`ubWO92^wTR6qfq#XS<79|`gM5&+cE z(NU2xN%K6go`u22#zwWawpPu|%v9Uk+a($D`uqEP2?K2q;GORz$MyB~LYB5)UK!-e zi+})>d-C?Yxw%jq!d(;F@`UX=$kd759KJBDrF8bhPqbvhzN9fMJXfDv5udYfC^vDPiP_ zc;mY!9Q_VBGT7|*si~=QMSR=wzFa$Mp(G^oKA;?uE6GzR;M#x#&VQrC|0)W_e6#_u;WI!Syg;sJ9={xn2v%*ZBQJ=y9lSF~ef=fGKoosV>pP9l{8zF=+XQuRtiHZJ`BKf5R&OL^Cj@-OMTQ60+h;Zij%ZU9`Jo@0(8pTI>dBpYK9uj zzzE2Ig@u2Qek#3qf^jL9Ol|I+JfEE=-~o#*Ns@+j4>-VVt1E-k^y$=}vrz%!J!^Vo zWB~CL*#i%(BQ?6VpV9>8d4RD<@J~%>vn40@OS#{urn*$v;5Z^V0@s24of1F99iD zNM0V{Vg2eeipxffw)I&GDD6Uud$wlr#9{2pa+(Sn?MuPnipgw##``H)vO6q>5#sup z5Xj!6I7I*l=r2>T-+4DXKR`NMopMw9@Lj4tM6f+ucF9|f1f&j6^#pKsfys-cQnqUA zU6jyjp6#(9@tGayEQYe5n9@7tZ+*#&to%`vKWik?IExeOTV$;^N$Vd2mgy&}F(d#T zg8@j^^=%`=U%dg@qzZG7ge*iPC%+}$lfhGDP|a7z*JR&6kmqXQXg6bB00000NkvXX Hu0mjf5#|dL;4E|VXE)sI=B}^{ zA=%wYa^}orGRapf@+=mM43X#a+3IvUPMS7PyWMWRUa!&-`u+Y_Y>toq4*}!xINNMC zuIQa_l+kG92ns!A|2|r23l4>){B$~P9s#nxEKe;`s2k$}D2oSB>~d%X0U_lT4;n#$ ztUjO5od--NlRO|cf&eM5C7@ua7yt=H<>RCMY&Od%QVwOe+ikX9uk*58E}g}ZBPb%v zHwcg%eJoKLS3#40w#_@9R69XF0Vswd)Vtlz)hfK7&*$uPI=OH3m5lm`NJ~Ij9#K01 zQUu^Aft3J{b)?kwdd+UPTlRQ7vitq+%JFz~$|Hj;edsGM;9Xu)mPgc1fPk-7tK6z` zae$-f<#KT~*5B{E?&zBsZ zJ?AT3wRP15#PWs^0U=z%{Wd(~TDeE?Fc&AZ=ES7?&+*`ZxH#^&vAOXD_OMGl8tFzOr^~EFGGxTnc>OaM&B4P&)>?%K!30J7#ix z_Us;NSE*oZELq#iCC8V1f|%CkzpVYI1pEMBP*j&9scw?r#h1Ll?hjMlB&Sy3AGp-U UUwDhUp8x;=07*qoM6N<$f<>*N3;+NC literal 0 HcmV?d00001 diff --git a/resources/mob/spider.png b/resources/mob/spider.png new file mode 100644 index 0000000000000000000000000000000000000000..08344a837ac94ea48fef5f8405f65b9479185e1d GIT binary patch literal 2554 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 literal 0 HcmV?d00001 diff --git a/resources/rain.png b/resources/rain.png new file mode 100644 index 0000000000000000000000000000000000000000..e9dc16c6360957f81a55cbd6cecb6cba7be770cb GIT binary patch literal 2553 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 literal 0 HcmV?d00001 diff --git a/resources/terrain.png b/resources/terrain.png new file mode 100644 index 0000000000000000000000000000000000000000..cbf4e3cbb78f86b9aeaf233eeaf0798c46647d5e GIT binary patch literal 28961 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 s%UZRwP-`5x zwQO*qyzD}1rgd~@w$)8(<1+DV`bb1TiO0^}C*mS)RC6TK3;G5;QCI$@{;`e4QSP`O zq*E1lE_|_td9Wa!D28VDZ3MrJOfButiG=*Ylr?gyEHoN#JI zS6p+Ldb8jagZ5Q=VUZ~FETztOYso)^3l96L*>yj}3PRsKr-{{lDY@$@rq0bk9Y8J@ zn6^gA=lTf>M9Ku~Fq-QisTQXJyeF{Povy@x#}#?B^OeF0=-_hbU^miXfriXXoM9pE-}*?^-Xp7^VyY>jZQQ#R;hdMJ}LGkHiCosZK@@HcE!)Ir%lRr_#k`I~Os0iqmNTQhj>WWxNL4!YSMcQiOgqtwB zeo*D~$9`Hl-VFtG7&1;VL&o-o-l6S6PBumc+5|Tgy9Yw;Jpz~3Ys%e2?Pq!~qRgp? zZGWg|2@J0lbs#}INNEIVPzp4a*(chLr7?(zj@}Eh)l2SaCzxKyReH{AApB4FU;AEj zREuM4Z&~o)CPCqs*1x$s%hm$Z512ms?x%bV7ke&yFUx+hE-t}`zU7x*%yXP%)@j}y6HTf`DcALq)UeqU0ltRgW>;wPt z&;Egtp8HTNCQ0X`xZ||uU7EpcT5~MV!m@98UNI8mSu4qS%0Aqall9Ndc+4}z3oA&| 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 C&3H)w literal 0 HcmV?d00001 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