From ec73305f0eb93c8617a0ddc6c812ebebda47c2e3 Mon Sep 17 00:00:00 2001 From: Chicken-Bones Date: Thu, 10 Apr 2014 17:32:38 +1000 Subject: [PATCH] Restructured directories --- .gitignore | 33 - assets/microblock/models/saw.obj | 164 ---- assets/microblock/textures/items/saw.png | Bin 6233 -> 0 bytes assets/microblock/textures/items/stoneRod.png | Bin 531 -> 0 bytes assets/multipart/lang/de_DE.lang | 32 - assets/multipart/lang/en_US.lang | 35 - assets/multipart/lang/es_ES.lang | 32 - assets/multipart/lang/fr_FR.lang | 32 - assets/multipart/lang/hr_HR.lang | 32 - assets/multipart/lang/nl_NL.lang | 32 - assets/multipart/lang/ru_RU.lang | 35 - assets/multipart/lang/tr_TR.lang | 32 - assets/multipart/lang/zh_CN.lang | 32 - build.gradle | 173 ----- build.properties | 4 - codechicken/core/launch/DepLoader.java | 609 --------------- .../microblock/BlockMicroMaterial.scala | 145 ---- codechicken/microblock/CommonMicroblock.scala | 208 ------ codechicken/microblock/ConfigContent.scala | 186 ----- codechicken/microblock/CornerMicroblock.scala | 70 -- codechicken/microblock/DefaultContent.scala | 56 -- codechicken/microblock/EdgeMicroblock.scala | 264 ------- codechicken/microblock/FaceMicroblock.scala | 84 --- .../microblock/GrassMicroMaterial.scala | 48 -- codechicken/microblock/HollowMicroblock.scala | 253 ------- .../microblock/IMicroMaterialRender.scala | 22 - .../microblock/ISidedHollowConnect.scala | 13 - codechicken/microblock/ItemMicroPart.scala | 169 ----- codechicken/microblock/ItemSaw.scala | 98 --- .../microblock/MicroMaterialRegistry.scala | 236 ------ codechicken/microblock/MicroRecipe.scala | 228 ------ codechicken/microblock/MicroblockClass.scala | 20 - .../microblock/MicroblockClassRegistry.scala | 20 - .../microblock/MicroblockPlacement.scala | 175 ----- codechicken/microblock/PlacementGrids.scala | 164 ---- codechicken/microblock/TMicroOcclusion.scala | 261 ------- .../handler/MicroblockEventHandler.scala | 40 - .../microblock/handler/MicroblockMod.scala | 52 -- .../microblock/handler/packethandlers.scala | 42 -- codechicken/microblock/handler/proxies.scala | 115 --- codechicken/multipart/BlockMultipart.scala | 300 -------- .../multipart/ControlKeyModifier.scala | 58 -- codechicken/multipart/IDWriter.scala | 33 - .../multipart/INeighborTileChange.scala | 15 - .../multipart/IRandomDisplayTick.scala | 16 - codechicken/multipart/IRandomUpdateTick.scala | 12 - codechicken/multipart/IRedstonePart.scala | 243 ------ codechicken/multipart/ItemMultiPart.scala | 54 -- codechicken/multipart/MultiPartRegistry.scala | 183 ----- .../multipart/MultipartGenerator.scala | 219 ------ codechicken/multipart/MultipartHelper.scala | 68 -- codechicken/multipart/MultipartRenderer.scala | 74 -- codechicken/multipart/PacketScheduler.scala | 82 -- codechicken/multipart/PartMap.java | 134 ---- codechicken/multipart/TCuboidPart.scala | 37 - codechicken/multipart/TEdgePart.scala | 12 - codechicken/multipart/TFacePart.scala | 16 - codechicken/multipart/TIconHitEffects.scala | 81 -- codechicken/multipart/TMultiPart.scala | 299 -------- codechicken/multipart/TNormalOcclusion.scala | 68 -- codechicken/multipart/TPartialOcclusion.scala | 76 -- codechicken/multipart/TSlottedPart.scala | 15 - codechicken/multipart/TickScheduler.scala | 279 ------- codechicken/multipart/TileMultipart.scala | 703 ------------------ .../multipart/asm/ASMMixinCompiler.scala | 627 ---------------- .../multipart/asm/ASMMixinFactory.scala | 311 -------- codechicken/multipart/asm/ByteCodecs.scala | 213 ------ .../multipart/asm/IMultipartFactory.scala | 12 - .../multipart/asm/ScalaSignature.scala | 341 --------- codechicken/multipart/asm/StackAnalyser.scala | 314 -------- .../handler/MultipartCompatiblity.scala | 33 - .../handler/MultipartEventHandler.scala | 67 -- .../multipart/handler/MultipartMod.scala | 42 -- .../multipart/handler/MultipartSaveLoad.scala | 69 -- .../multipart/handler/packethandlers.scala | 180 ----- codechicken/multipart/handler/proxies.scala | 92 --- .../multipart/minecraft/ButtonPart.java | 184 ----- codechicken/multipart/minecraft/Content.java | 63 -- .../multipart/minecraft/EventHandler.java | 123 --- .../multipart/minecraft/IPartMeta.java | 16 - .../multipart/minecraft/LeverPart.java | 152 ---- .../multipart/minecraft/McBlockPart.java | 92 --- .../multipart/minecraft/McMetaPart.java | 82 -- .../multipart/minecraft/McMultipartCPH.java | 30 - .../multipart/minecraft/McMultipartSPH.java | 25 - .../multipart/minecraft/McSidedMetaPart.java | 69 -- .../minecraft/MinecraftMultipartMod.java | 26 - .../multipart/minecraft/PartMetaAccess.java | 88 --- .../minecraft/RedstoneTorchPart.java | 246 ------ .../multipart/minecraft/TorchPart.java | 122 --- .../multipart/nei/NEI_MicroblockConfig.java | 44 -- .../scalatraits/TFluidHandlerTile.scala | 130 ---- .../scalatraits/TIInventoryTile.scala | 133 ---- .../scalatraits/TPartialOcclusionTile.scala | 34 - .../scalatraits/TRandomDisplayTickTile.scala | 17 - .../multipart/scalatraits/TRedstoneTile.scala | 87 --- .../multipart/scalatraits/TSlottedTile.scala | 64 -- .../scalatraits/TTileChangeTile.scala | 59 -- dependencies.info | 6 - gradle/wrapper/gradle-wrapper.jar | Bin 51106 -> 0 bytes gradle/wrapper/gradle-wrapper.properties | 6 - gradlew | 164 ---- gradlew.bat | 90 --- mcmod.info | 29 - settings.gradle | 19 - 105 files changed, 11824 deletions(-) delete mode 100644 .gitignore delete mode 100644 assets/microblock/models/saw.obj delete mode 100644 assets/microblock/textures/items/saw.png delete mode 100644 assets/microblock/textures/items/stoneRod.png delete mode 100644 assets/multipart/lang/de_DE.lang delete mode 100644 assets/multipart/lang/en_US.lang delete mode 100644 assets/multipart/lang/es_ES.lang delete mode 100644 assets/multipart/lang/fr_FR.lang delete mode 100644 assets/multipart/lang/hr_HR.lang delete mode 100644 assets/multipart/lang/nl_NL.lang delete mode 100644 assets/multipart/lang/ru_RU.lang delete mode 100644 assets/multipart/lang/tr_TR.lang delete mode 100644 assets/multipart/lang/zh_CN.lang delete mode 100644 build.gradle delete mode 100644 build.properties delete mode 100644 codechicken/core/launch/DepLoader.java delete mode 100644 codechicken/microblock/BlockMicroMaterial.scala delete mode 100644 codechicken/microblock/CommonMicroblock.scala delete mode 100644 codechicken/microblock/ConfigContent.scala delete mode 100644 codechicken/microblock/CornerMicroblock.scala delete mode 100644 codechicken/microblock/DefaultContent.scala delete mode 100644 codechicken/microblock/EdgeMicroblock.scala delete mode 100644 codechicken/microblock/FaceMicroblock.scala delete mode 100644 codechicken/microblock/GrassMicroMaterial.scala delete mode 100644 codechicken/microblock/HollowMicroblock.scala delete mode 100644 codechicken/microblock/IMicroMaterialRender.scala delete mode 100644 codechicken/microblock/ISidedHollowConnect.scala delete mode 100644 codechicken/microblock/ItemMicroPart.scala delete mode 100644 codechicken/microblock/ItemSaw.scala delete mode 100644 codechicken/microblock/MicroMaterialRegistry.scala delete mode 100644 codechicken/microblock/MicroRecipe.scala delete mode 100644 codechicken/microblock/MicroblockClass.scala delete mode 100644 codechicken/microblock/MicroblockClassRegistry.scala delete mode 100644 codechicken/microblock/MicroblockPlacement.scala delete mode 100644 codechicken/microblock/PlacementGrids.scala delete mode 100644 codechicken/microblock/TMicroOcclusion.scala delete mode 100644 codechicken/microblock/handler/MicroblockEventHandler.scala delete mode 100644 codechicken/microblock/handler/MicroblockMod.scala delete mode 100644 codechicken/microblock/handler/packethandlers.scala delete mode 100644 codechicken/microblock/handler/proxies.scala delete mode 100644 codechicken/multipart/BlockMultipart.scala delete mode 100644 codechicken/multipart/ControlKeyModifier.scala delete mode 100644 codechicken/multipart/IDWriter.scala delete mode 100644 codechicken/multipart/INeighborTileChange.scala delete mode 100644 codechicken/multipart/IRandomDisplayTick.scala delete mode 100644 codechicken/multipart/IRandomUpdateTick.scala delete mode 100644 codechicken/multipart/IRedstonePart.scala delete mode 100644 codechicken/multipart/ItemMultiPart.scala delete mode 100644 codechicken/multipart/MultiPartRegistry.scala delete mode 100644 codechicken/multipart/MultipartGenerator.scala delete mode 100644 codechicken/multipart/MultipartHelper.scala delete mode 100644 codechicken/multipart/MultipartRenderer.scala delete mode 100644 codechicken/multipart/PacketScheduler.scala delete mode 100644 codechicken/multipart/PartMap.java delete mode 100644 codechicken/multipart/TCuboidPart.scala delete mode 100644 codechicken/multipart/TEdgePart.scala delete mode 100644 codechicken/multipart/TFacePart.scala delete mode 100644 codechicken/multipart/TIconHitEffects.scala delete mode 100644 codechicken/multipart/TMultiPart.scala delete mode 100644 codechicken/multipart/TNormalOcclusion.scala delete mode 100644 codechicken/multipart/TPartialOcclusion.scala delete mode 100644 codechicken/multipart/TSlottedPart.scala delete mode 100644 codechicken/multipart/TickScheduler.scala delete mode 100644 codechicken/multipart/TileMultipart.scala delete mode 100644 codechicken/multipart/asm/ASMMixinCompiler.scala delete mode 100644 codechicken/multipart/asm/ASMMixinFactory.scala delete mode 100644 codechicken/multipart/asm/ByteCodecs.scala delete mode 100644 codechicken/multipart/asm/IMultipartFactory.scala delete mode 100644 codechicken/multipart/asm/ScalaSignature.scala delete mode 100644 codechicken/multipart/asm/StackAnalyser.scala delete mode 100644 codechicken/multipart/handler/MultipartCompatiblity.scala delete mode 100644 codechicken/multipart/handler/MultipartEventHandler.scala delete mode 100644 codechicken/multipart/handler/MultipartMod.scala delete mode 100644 codechicken/multipart/handler/MultipartSaveLoad.scala delete mode 100644 codechicken/multipart/handler/packethandlers.scala delete mode 100644 codechicken/multipart/handler/proxies.scala delete mode 100644 codechicken/multipart/minecraft/ButtonPart.java delete mode 100644 codechicken/multipart/minecraft/Content.java delete mode 100644 codechicken/multipart/minecraft/EventHandler.java delete mode 100644 codechicken/multipart/minecraft/IPartMeta.java delete mode 100644 codechicken/multipart/minecraft/LeverPart.java delete mode 100644 codechicken/multipart/minecraft/McBlockPart.java delete mode 100644 codechicken/multipart/minecraft/McMetaPart.java delete mode 100644 codechicken/multipart/minecraft/McMultipartCPH.java delete mode 100644 codechicken/multipart/minecraft/McMultipartSPH.java delete mode 100644 codechicken/multipart/minecraft/McSidedMetaPart.java delete mode 100644 codechicken/multipart/minecraft/MinecraftMultipartMod.java delete mode 100644 codechicken/multipart/minecraft/PartMetaAccess.java delete mode 100644 codechicken/multipart/minecraft/RedstoneTorchPart.java delete mode 100644 codechicken/multipart/minecraft/TorchPart.java delete mode 100644 codechicken/multipart/nei/NEI_MicroblockConfig.java delete mode 100644 codechicken/multipart/scalatraits/TFluidHandlerTile.scala delete mode 100644 codechicken/multipart/scalatraits/TIInventoryTile.scala delete mode 100644 codechicken/multipart/scalatraits/TPartialOcclusionTile.scala delete mode 100644 codechicken/multipart/scalatraits/TRandomDisplayTickTile.scala delete mode 100644 codechicken/multipart/scalatraits/TRedstoneTile.scala delete mode 100644 codechicken/multipart/scalatraits/TSlottedTile.scala delete mode 100644 codechicken/multipart/scalatraits/TTileChangeTile.scala delete mode 100644 dependencies.info delete mode 100644 gradle/wrapper/gradle-wrapper.jar delete mode 100644 gradle/wrapper/gradle-wrapper.properties delete mode 100644 gradlew delete mode 100644 gradlew.bat delete mode 100644 mcmod.info delete mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 46eb940..0000000 --- a/.gitignore +++ /dev/null @@ -1,33 +0,0 @@ -#ant stuff -/bin/ -#Remove OS generated garbage -*/.DS_Store -.DS_Store -.DS_Store? -.Spotlight-V100 -.Trashes -Icon? -ehthumbs.db -Thumbs.db -#gradle stuff -/.gradle -/build/ -/run/ -#IDEA files from Gradle -.idea/ -/*.iml -/*.ipr -/*.iws -#Vim backups -*~ -#eclipse stuffs -/.classpath -/.project -/.settings/ -/debug/ -*.lock -/.metadata/ -/config/ -/logs/ -options.txt -/saves/ \ No newline at end of file diff --git a/assets/microblock/models/saw.obj b/assets/microblock/models/saw.obj deleted file mode 100644 index 716f19b..0000000 --- a/assets/microblock/models/saw.obj +++ /dev/null @@ -1,164 +0,0 @@ -# Blender v2.64 (sub 0) OBJ File: 'hackSaw.blend' -# www.blender.org -g Handle -v 0.039250 0.068563 -0.108650 -v 0.039250 -0.196237 -0.108650 -v -0.039250 -0.196237 -0.108650 -v -0.039250 0.068563 -0.108650 -v 0.039250 0.196263 0.108650 -v -0.039250 0.196263 0.108650 -v -0.039250 -0.068537 0.108650 -v 0.039250 -0.068537 0.108650 -v -0.039250 -0.126338 -0.068650 -v -0.039250 0.045662 -0.068650 -v -0.039250 -0.045638 0.068650 -v -0.039250 0.126263 0.068650 -v 0.039250 0.045662 -0.068650 -v 0.039250 -0.126338 -0.068650 -v 0.039250 0.126263 0.068650 -v 0.039250 -0.045638 0.068650 -vt 0.250000 0.562500 -vt 0.250000 0.187500 -vt 0.312500 0.250000 -vt 0.312500 0.500000 -vt 0.625000 0.187500 -vt 0.562500 0.250000 -vt 0.625000 0.562500 -vt 0.562500 0.500000 -vt 0.625000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 0.093750 -vt 0.625000 0.093750 -vt 1.000000 0.187500 -vt 0.250000 0.093750 -vt 0.250000 0.000000 -vt 0.875000 0.468750 -vt 0.625000 0.468750 -vt 0.625000 0.375000 -vt 0.875000 0.375000 -vt 0.875000 0.562500 -vt 0.875000 0.187500 -vt 0.875000 0.281250 -vt 0.625000 0.281250 -vn -1.000000 0.000000 -0.000000 -vn 1.000000 0.000000 0.000000 -vn 0.610523 0.393323 -0.687368 -vn 0.554430 -0.722312 -0.413312 -vn -0.554430 -0.722312 -0.413312 -vn -0.610523 0.393323 -0.687368 -vn 0.554430 0.722312 0.413312 -vn -0.554430 0.722312 0.413312 -vn -0.610523 -0.393323 0.687368 -vn 0.610523 -0.393323 0.687368 -vn -0.958464 0.247505 0.141606 -vn -0.837581 0.271279 -0.474136 -vn 0.837581 0.271279 -0.474136 -vn 0.958464 0.247505 0.141606 -vn -0.958403 -0.247597 -0.141758 -vn 0.958403 -0.247597 -0.141758 -vn -0.837672 -0.271340 0.473952 -vn 0.837672 -0.271340 0.473952 -s off -f 4/1/1 3/2/1 9/3/1 10/4/1 -f 3/2/1 7/5/1 11/6/1 9/3/1 -f 7/5/1 6/7/1 12/8/1 11/6/1 -f 6/7/1 4/1/1 10/4/1 12/8/1 -f 2/2/2 1/1/2 13/4/2 14/3/2 -f 1/1/2 5/7/2 15/8/2 13/4/2 -f 5/7/2 8/5/2 16/6/2 15/8/2 -f 8/5/2 2/2/2 14/3/2 16/6/2 -s 1 -f 1/9/3 2/10/4 3/11/5 4/12/6 -f 5/13/7 6/11/8 7/12/9 8/5/10 -f 1/9/3 4/12/6 6/14/8 5/15/7 -f 3/14/5 2/2/4 8/5/10 7/12/9 -f 9/16/11 11/17/12 16/18/13 14/19/14 -f 11/20/12 12/7/15 15/17/16 16/16/13 -f 12/5/15 10/21/17 13/22/18 15/23/16 -f 10/23/17 9/22/11 14/19/14 13/18/18 -g Blade -v 0.000000 0.067100 -0.081925 -v 0.000000 0.732900 -0.081925 -v 0.000000 0.732900 -0.107925 -v 0.000000 0.067100 -0.107925 -vt 1.000000 1.000000 -vt 0.187500 1.000000 -vt 0.187500 0.953125 -vt 1.000000 0.953125 -vn 0.999969 0.000000 0.000000 -s 1 -f 18/24/19 17/25/2 20/26/19 19/27/2 -g BladeSupport -v -0.025100 0.713937 -0.081525 -v 0.025100 0.719137 0.036975 -v 0.025100 0.167037 0.036975 -v 0.025100 0.713937 -0.081525 -v 0.025100 0.739237 -0.022325 -v -0.025100 0.739237 -0.022325 -v -0.025100 0.167037 0.036975 -v -0.025100 0.719137 0.036975 -v 0.025100 0.748037 -0.127225 -v 0.025100 0.794437 0.003175 -v -0.025100 0.794437 0.003175 -v -0.025100 0.748037 -0.127225 -v 0.025100 0.144237 0.076975 -v -0.025100 0.144237 0.076975 -v -0.025100 0.773937 0.076975 -v 0.025100 0.773937 0.076975 -vt 0.062500 0.859375 -vt 0.062500 0.750000 -vt 0.125000 0.750000 -vt 0.125000 0.859375 -vt 0.125000 1.000000 -vt 0.062500 1.000000 -vt 0.187500 0.140625 -vt 0.125000 0.140625 -vt 0.125000 0.062500 -vt 0.187500 0.062500 -vt 0.125000 0.937500 -vt 0.187500 0.937500 -vt 0.187500 1.000000 -vt 0.062500 0.000000 -vt 0.125000 0.000000 -vt 0.187500 0.203125 -vt 0.125000 0.203125 -vt 0.000000 0.750000 -vt 0.000000 0.859375 -vt 0.187500 0.281250 -vt 0.125000 0.281250 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vn 0.000000 -0.801471 -0.598034 -vn 0.000000 -0.868777 -0.495203 -vn -0.610157 -0.786706 -0.093722 -vn 0.610157 -0.786706 -0.093722 -vn 0.796991 -0.603504 0.023255 -vn -0.796991 -0.603504 0.023255 -vn -0.592944 0.487259 0.641072 -vn 0.592944 0.487259 0.641072 -vn 0.645070 0.763604 -0.027070 -vn -0.645070 0.763604 -0.027070 -vn 0.864193 -0.293130 -0.408887 -vn -0.864193 -0.293130 -0.408887 -vn -0.609577 -0.398236 -0.685385 -vn 0.609577 -0.398236 -0.685385 -vn -0.552568 0.124210 -0.824152 -vn 0.552568 0.124210 -0.824152 -vn -0.554888 -0.719291 0.417951 -vn 0.554888 -0.719291 0.417951 -s off -f 30/28/2 36/29/2 22/30/2 25/31/2 -f 21/32/1 26/31/1 31/28/1 32/33/1 -f 24/34/20 21/35/20 32/36/20 29/37/20 -f 27/38/21 23/39/21 33/40/21 34/32/21 -f 36/29/2 33/41/2 23/42/2 22/30/2 -f 30/28/2 25/31/2 24/32/2 29/33/2 -f 31/28/1 26/31/1 28/30/1 35/29/1 -f 34/41/1 35/29/1 28/30/1 27/42/1 -s 1 -f 21/35/22 24/34/23 25/43/24 26/44/25 -f 35/45/26 36/29/27 30/28/28 31/46/29 -f 26/44/25 25/43/24 22/47/30 28/48/31 -f 27/38/32 28/48/31 22/47/30 23/39/33 -f 32/49/34 31/46/29 30/28/28 29/33/35 -f 36/29/27 35/45/26 34/50/36 33/41/37 diff --git a/assets/microblock/textures/items/saw.png b/assets/microblock/textures/items/saw.png deleted file mode 100644 index 25a0f84e48946b7858988c4342f009a035d61287..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6233 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 Dq*}sx diff --git a/assets/microblock/textures/items/stoneRod.png b/assets/microblock/textures/items/stoneRod.png deleted file mode 100644 index fc7d51d4d0622d2a70c97f939441674210ca944a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 531 zcmV+u0_^>XP)N2bPDNB8 zb~7$DE-^4L^m3s900EClL_t(oN9~ruih@uWg`J1dNNbVkgR~I>3u+N+iy%miNLoa% zG23~|Gn_l#VYrQ@d394CwDB(f@AxP87;j#J)oO(x2;loZ#^W(QKEKM7o(RJb)9DnG z$pp4-_b0I3Zo%~D^BIT3L8KoH2K@=F*K5pXGaQdc?Du;NheMdA*}XuTrih{lm&*mG z(+RHY!f_mw$42J@aU5elpNrvHmSHp+!LqFG1@b%xhwpYf@diB46MHX@f9XshNfIm; z3o(4TT;3#?Xcu5|4!>TnD2hTP=kW6Q2JHfy%|;~W@c(wMqD_FwIsEU=?CROe3&`Zp?p&p@K--V_qnd*l7|AUQEW2uKIfIHBe|qffP+~e+2L5D*kp7jmsAR{ zIXiTh diff --git a/assets/multipart/lang/de_DE.lang b/assets/multipart/lang/de_DE.lang deleted file mode 100644 index 3d42029..0000000 --- a/assets/multipart/lang/de_DE.lang +++ /dev/null @@ -1,32 +0,0 @@ -item.microblock:sawStone.name=Steinsäge -item.microblock:sawIron.name=Eisensäge -item.microblock:sawDiamond.name=Diamantsäge -item.microblock:stoneRod.name=Steinstab - -mcr_face.1.name=%s-Cover -mcr_face.1.subset=Cover -mcr_face.2.name=%s-Platte -mcr_face.2.subset=Platte -mcr_face.4.name=%s-Scheibe -mcr_face.4.subset=Scheibe - -mcr_hllw.1.name=Hohles %s-Cover -mcr_hllw.1.subset=Hohles Cover -mcr_hllw.2.name=Hohles %s-Platte -mcr_hllw.2.subset=Hohle Platte -mcr_hllw.4.name=Hohle %s-Scheibe -mcr_hllw.4.subset=Hohle Scheibe - -mcr_edge.1.name=%s-Streifen -mcr_edge.1.subset=Streifen -mcr_edge.2.name=%s-Pfosten -mcr_edge.2.subset=Pfosten -mcr_edge.4.name=%s-Pfeiler -mcr_edge.4.subset=Pfeiler - -mcr_cnr.1.name=%s-Stückchen -mcr_cnr.1.subset=Stückchen -mcr_cnr.2.name=%s-Ecke -mcr_cnr.2.subset=Ecke -mcr_cnr.4.name=%s-Kerbe -mcr_cnr.4.subset=Kerbe diff --git a/assets/multipart/lang/en_US.lang b/assets/multipart/lang/en_US.lang deleted file mode 100644 index e8fb9f8..0000000 --- a/assets/multipart/lang/en_US.lang +++ /dev/null @@ -1,35 +0,0 @@ -microblock.missing=The following microblocks are not installed on this client: %s -multipart.missing=The following multiparts are not installed on this client: %s - -item.microblock:sawStone.name=Stone Saw -item.microblock:sawIron.name=Iron Saw -item.microblock:sawDiamond.name=Diamond Saw -item.microblock:stoneRod.name=Stone Rod - -mcr_face.1.name=%s Cover -mcr_face.1.subset=Cover -mcr_face.2.name=%s Panel -mcr_face.2.subset=Panel -mcr_face.4.name=%s Slab -mcr_face.4.subset=Slab - -mcr_hllw.1.name=Hollow %s Cover -mcr_hllw.1.subset=Hollow Cover -mcr_hllw.2.name=Hollow %s Panel -mcr_hllw.2.subset=Hollow Panel -mcr_hllw.4.name=Hollow %s Slab -mcr_hllw.4.subset=Hollow Slab - -mcr_edge.1.name=%s Strip -mcr_edge.1.subset=Strip -mcr_edge.2.name=%s Post -mcr_edge.2.subset=Post -mcr_edge.4.name=%s Pillar -mcr_edge.4.subset=Pillar - -mcr_cnr.1.name=%s Nook -mcr_cnr.1.subset=Nook -mcr_cnr.2.name=%s Corner -mcr_cnr.2.subset=Corner -mcr_cnr.4.name=%s Notch -mcr_cnr.4.subset=Notch \ No newline at end of file diff --git a/assets/multipart/lang/es_ES.lang b/assets/multipart/lang/es_ES.lang deleted file mode 100644 index bb3771c..0000000 --- a/assets/multipart/lang/es_ES.lang +++ /dev/null @@ -1,32 +0,0 @@ -item.microblock:sawStone.name=Sierra de Piedra -item.microblock:sawIron.name=Sierra de Hierro -item.microblock:sawDiamond.name=Sierra de Diamante -item.microblock:stoneRod.name=Palo de Piedra - -mcr_face.1.name=Cubierta de %s -mcr_face.1.subset=Cubierta -mcr_face.2.name=Panel de %s -mcr_face.2.subset=Panel -mcr_face.4.name=Losa de %s -mcr_face.4.subset=Losa - -mcr_hllw.1.name=Cubierta Hueca de %s -mcr_hllw.1.subset=Cubierta Hueca -mcr_hllw.2.name=Panel Hueco de %s -mcr_hllw.2.subset=Panel Hueco -mcr_hllw.4.name=Losa Hueca de %s -mcr_hllw.4.subset=Losa Hueca - -mcr_edge.1.name=Listón de %s -mcr_edge.1.subset=Listón -mcr_edge.2.name=Poste de %s -mcr_edge.2.subset=Poste -mcr_edge.4.name=Pilar de %s -mcr_edge.4.subset=Pilar - -mcr_cnr.1.name=Punta de %s -mcr_cnr.1.subset=Punta -mcr_cnr.2.name=Esquina de %s -mcr_cnr.2.subset=Esquina -mcr_cnr.4.name=Cuarto de %s -mcr_cnr.4.subset=Cuarto diff --git a/assets/multipart/lang/fr_FR.lang b/assets/multipart/lang/fr_FR.lang deleted file mode 100644 index bf00b4a..0000000 --- a/assets/multipart/lang/fr_FR.lang +++ /dev/null @@ -1,32 +0,0 @@ -item.microblock:sawStone.name=Scie en pierre -item.microblock:sawIron.name=Scie en fer -item.microblock:sawDiamond.name=Scie en diamant -item.microblock:stoneRod.name=Bâtons en pierre - -mcr_face.1.name=Couvercle de %s -mcr_face.1.subset=Couvercle -mcr_face.2.name=Panneau de %s -mcr_face.2.subset=Panneau -mcr_face.4.name=Dalle de %s -mcr_face.4.subset=Dalle - -mcr_hllw.1.name=Couvercle creux de %s -mcr_hllw.1.subset=Couvercle creux -mcr_hllw.2.name=Panneau creux de %s -mcr_hllw.2.subset=Panneau creux -mcr_hllw.4.name=Dalle creuse de %s -mcr_hllw.4.subset=Dalle creuse - -mcr_edge.1.name=Bande de %s -mcr_edge.1.subset=Bande -mcr_edge.2.name=Pieu de %s -mcr_edge.2.subset=Pieu -mcr_edge.4.name=Pilier de %s -mcr_edge.4.subset=Pilier - -mcr_cnr.1.name=Coin de %s -mcr_cnr.1.subset=Coin -mcr_cnr.2.name=Bordure de %s -mcr_cnr.2.subset=Bordure -mcr_cnr.4.name=Entaille de %s -mcr_cnr.4.subset=Entaille \ No newline at end of file diff --git a/assets/multipart/lang/hr_HR.lang b/assets/multipart/lang/hr_HR.lang deleted file mode 100644 index 301e479..0000000 --- a/assets/multipart/lang/hr_HR.lang +++ /dev/null @@ -1,32 +0,0 @@ -item.microblock:sawStone.name=Kamena Pila -item.microblock:sawIron.name=Željezna Pila -item.microblock:sawDiamond.name=Dijamantna Pila -item.microblock:stoneRod.name=Kameni Štap - -mcr_face.1.name=%si Pokrivač -mcr_face.1.subset=Pokrivač -mcr_face.2.name=%si Panel -mcr_face.2.subset=Panel -mcr_face.4.name=%sa Ploča -mcr_face.4.subset=Ploča - -mcr_hllw.1.name=Izdubljen %si Pokrivač -mcr_hllw.1.subset=Izdubljen Pokrivač -mcr_hllw.2.name=Izdubljen %si Panel -mcr_hllw.2.subset=Izdubljen Panel -mcr_hllw.4.name=Izdubljena %sa Ploča -mcr_hllw.4.subset=Izdubljena Ploča - -mcr_edge.1.name=%sa Pruga -mcr_edge.1.subset=Pruga -mcr_edge.2.name=%si Post -mcr_edge.2.subset=Post -mcr_edge.4.name=%si Stup -mcr_edge.4.subset=Stup - -mcr_cnr.1.name=%si Kutak -mcr_cnr.1.subset=Kutak -mcr_cnr.2.name=%si Ugao -mcr_cnr.2.subset=Ugao -mcr_cnr.4.name=%si Usjek -mcr_cnr.4.subset=Usjek \ No newline at end of file diff --git a/assets/multipart/lang/nl_NL.lang b/assets/multipart/lang/nl_NL.lang deleted file mode 100644 index 9756b92..0000000 --- a/assets/multipart/lang/nl_NL.lang +++ /dev/null @@ -1,32 +0,0 @@ -item.microblock:sawStone.name=Stenen Zaag -item.microblock:sawIron.name=IJzeren Zaag -item.microblock:sawDiamond.name=Diamanten Zaag -item.microblock:stoneRod.name=Stenen Stok - -mcr_face.1.name=%s Bedekking -mcr_face.1.subset=Bedekking -mcr_face.2.name=%s Paneel -mcr_face.2.subset=Paneel -mcr_face.4.name=%s Plaat -mcr_face.4.subset=Plaat - -mcr_hllw.1.name=Holle %s Bedekking -mcr_hllw.1.subset=Holle Bedekking -mcr_hllw.2.name=Hol %s Paneel -mcr_hllw.2.subset=Hol Paneel -mcr_hllw.4.name=Holle %s Plaat -mcr_hllw.4.subset=Holle Plaat - -mcr_edge.1.name=%s Strook -mcr_edge.1.subset=Strook -mcr_edge.2.name=%s Paal -mcr_edge.2.subset=Paal -mcr_edge.4.name=%s Pilaar -mcr_edge.4.subset=Pilaar - -mcr_cnr.1.name=%s Hoekje -mcr_cnr.1.subset=Hoekje -mcr_cnr.2.name=%s Hoek -mcr_cnr.2.subset=Hoek -mcr_cnr.4.name=%s Inkeping -mcr_cnr.4.subset=Inkeping diff --git a/assets/multipart/lang/ru_RU.lang b/assets/multipart/lang/ru_RU.lang deleted file mode 100644 index 52689e5..0000000 --- a/assets/multipart/lang/ru_RU.lang +++ /dev/null @@ -1,35 +0,0 @@ -microblock.missing=Следующие микроблоки не установлены на этом клиенте: %s -multipart.missing=Следующие микроблоки из модов не установлены на этом клиенте: %s - -item.microblock:sawStone.name=Каменная пила -item.microblock:sawIron.name=Железная пила -item.microblock:sawDiamond.name=Алмазная пила -item.microblock:stoneRod.name=Каменная палка - -mcr_face.1.name=Крышка из %s -mcr_face.1.subset=Крышка -mcr_face.2.name=Панель из %s -mcr_face.2.subset=Панель -mcr_face.4.name=Плита из %s -mcr_face.4.subset=Плита - -mcr_hllw.1.name=Крышка из %s с выемкой -mcr_hllw.1.subset=Крышка с выемкой -mcr_hllw.2.name=Панель из %s с выемкой -mcr_hllw.2.subset=Панель с выемкой -mcr_hllw.4.name=Плита из %s с выемкой -mcr_hllw.4.subset=Плита с выемкой - -mcr_edge.1.name=Полоса из %s -mcr_edge.1.subset=Полоса -mcr_edge.2.name=Столб %s -mcr_edge.2.subset=Столб -mcr_edge.4.name=Колонна из %s -mcr_edge.4.subset=Колонна - -mcr_cnr.1.name=Уголок из %s -mcr_cnr.1.subset=Уголок -mcr_cnr.2.name=Угол из %s -mcr_cnr.2.subset=Угол -mcr_cnr.4.name=Большой угол из %s -mcr_cnr.4.subset=Большой угол diff --git a/assets/multipart/lang/tr_TR.lang b/assets/multipart/lang/tr_TR.lang deleted file mode 100644 index 31d3bc9..0000000 --- a/assets/multipart/lang/tr_TR.lang +++ /dev/null @@ -1,32 +0,0 @@ -item.microblock:sawStone.name=Taş Testere -item.microblock:sawIron.name=Demir Testere -item.microblock:sawDiamond.name=Elmas Testere -item.microblock:stoneRod.name=Taş Çubuk - -mcr_face.1.name=%s Kapak -mcr_face.1.subset=Kapak -mcr_face.2.name=%s Panel -mcr_face.2.subset=Panel -mcr_face.4.name=Kalın %s -mcr_face.4.subset=Kalın - -mcr_hllw.1.name=Ortası Boş %s Kapak -mcr_hllw.1.subset=Ortası Boş Cover -mcr_hllw.2.name=Ortası Boş %s Panel -mcr_hllw.2.subset=Ortası Boş Panel -mcr_hllw.4.name=Ortası Boş Kalın %s -mcr_hllw.4.subset=Ortası Boş Kalın - -mcr_edge.1.name=%s Şerit -mcr_edge.1.subset=Şerit -mcr_edge.2.name=Kalın Şerit %s -mcr_edge.2.subset=Kalın Şerit -mcr_edge.4.name=%s Sütun -mcr_edge.4.subset=Sütun - -mcr_cnr.1.name=%s Köşe -mcr_cnr.1.subset=Köşe -mcr_cnr.2.name=Orta Köşe %s -mcr_cnr.2.subset=Orta Köşe -mcr_cnr.4.name=Kalın Köşe %s -mcr_cnr.4.subset=Kalın Köşe diff --git a/assets/multipart/lang/zh_CN.lang b/assets/multipart/lang/zh_CN.lang deleted file mode 100644 index a66c4c3..0000000 --- a/assets/multipart/lang/zh_CN.lang +++ /dev/null @@ -1,32 +0,0 @@ -item.microblock:sawStone.name=石手锯 -item.microblock:sawIron.name=铁手锯 -item.microblock:sawDiamond.name=钻石手锯 -item.microblock:stoneRod.name=石棍 - -mcr_face.1.name=%s 盖板 -mcr_face.1.subset=盖板 -mcr_face.2.name=%s 面板 -mcr_face.2.subset=面板 -mcr_face.4.name=%s 厚板 -mcr_face.4.subset=厚板 - -mcr_hllw.1.name=%s 空心盖板 -mcr_hllw.1.subset=空心盖板 -mcr_hllw.2.name=%s 空心面板 -mcr_hllw.2.subset=空心面板 -mcr_hllw.4.name=%s 空心厚板 -mcr_hllw.4.subset=空心厚板 - -mcr_edge.1.name=%s Strip -mcr_edge.1.subset=Strip -mcr_edge.2.name=%s Post -mcr_edge.2.subset=Post -mcr_edge.4.name=%s 柱 -mcr_edge.4.subset=柱 - -mcr_cnr.1.name=%s Nook -mcr_cnr.1.subset=Nook -mcr_cnr.2.name=%s Corner -mcr_cnr.2.subset=Corner -mcr_cnr.4.name=%s Notch -mcr_cnr.4.subset=Notch diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 82f31a3..0000000 --- a/build.gradle +++ /dev/null @@ -1,173 +0,0 @@ -// This sets us up for building a forge project - you need all of these -buildscript { - repositories { - mavenCentral() - maven { - name = "forge" - url = "http://files.minecraftforge.net/maven" - } - maven { - name = "sonatype" - url = "https://oss.sonatype.org/content/repositories/snapshots/" - } - } - dependencies { - classpath 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT' - } -} - -// Apply the forge plugin - this adds all the magic for automatically obfuscating, deobfuscating etc -apply plugin: 'forge' -apply plugin: 'scala' - -// This is our group -group = "codechicken" // http://maven.apache.org/guides/mini/guide-naming-conventions.html -// This is our actual project within the group. -archivesBaseName = "ForgeMultipart" - -// Define properties file -ext.configFile = file "build.properties" - -configFile.withReader { - // Load config. It shall from now be referenced as simply config or project.config - def prop = new Properties() - prop.load(it) - project.ext.config = new ConfigSlurper().parse prop -} -dependencies { - compile "codechicken:CodeChickenLib:${config.mc_version}-${config.ccl_version}:dev" -} - -version = "${project.config.mod_version}." + System.getenv("BUILD_NUMBER") ?: "1" - -println config.mc_version + "-" + config.forge_version -// Setup the forge minecraft plugin data. Specify the preferred forge/minecraft version here -minecraft { - version = config.mc_version + "-" + config.forge_version -} - -// this sets our output jar to have a 'tag' of 'universal' on it -// It also adds the minecraft version in a custom version name -// The result is files named ---universal.jar -jar { - classifier = 'universal' - version = "${project.minecraft.version}-${project.version}" - manifest { - attributes 'FMLCorePlugin': 'codechicken.core.launch.DepLoader' - attributes 'FMLCorePluginContainsFMLMod': 'true' - } - -} -sourceSets { - main { - scala { - srcDir project.projectDir - include 'codechicken/**/*.*' - } - resources { - srcDir project.projectDir - include 'assets/**/*.*' - include '*.info' - } - } -} -processResources { - // Replace properties in info files - from(sourceSets.main.resources.srcDirs) { - include '*.info' - expand 'version':version,'mc_version':config.mc_version,'ccl_version':config.ccl_version - } - // Copy everything else - from(sourceSets.main.resources.srcDirs) { - include 'assets/**/*.*' - } -} - -// Add in a source jar for people, should they desire to download such a thing -task sourceJar(type: Jar) { - from sourceSets.main.allSource - classifier = 'src' - version = "${project.minecraft.version}-${project.version}" -} - -// Add in an mcp named jar, for those who wish to run in a development environment (assuming mcp naming matches) -task deobfJar(type: Jar) { - from sourceSets.main.output - classifier = 'dev' - version = "${project.minecraft.version}-${project.version}" - manifest { - attributes 'FMLCorePlugin': 'codechicken.core.launch.DepLoader' - attributes 'FMLCorePluginContainsFMLMod': 'true' - } -} - -// Tell the artifact system about our extra jars -artifacts { - archives sourceJar, deobfJar -} - -// Configure an upload task. this is setup for uploading to files.minecraftforge.net. There are other examples around -uploadArchives { - dependsOn 'reobf' - repositories { - if (project.hasProperty("filesmaven")) { - logger.info('Publishing to files server') - - mavenDeployer { - configuration = configurations.deployJars - - repository(url: project.filesmaven.url) { - authentication(userName: project.filesmaven.username, privateKey: project.filesmaven.key) - } - - // This is just the pom data for the maven repo - pom { - groupId = project.group - // Force the maven upload to use the - syntax preferred at files - version = "${project.minecraft.version}-${project.version}" - artifactId = project.archivesBaseName - project { - name project.archivesBaseName - packaging 'jar' - description 'ForgeMultipart' - url 'https://github.com/Chicken-Bones/ForgeMultipart' - - scm { - url 'https://github.com/Chicken-Bones/ForgeMultipart' - connection 'scm:git:git://github.com/Chicken-Bones/ForgeMultipart.git' - developerConnection 'scm:git:git@github.com:Chicken-Bones/ForgeMultipart.git' - } - - issueManagement { - system 'github' - url 'https://github.com/Chicken-Bones/ForgeMultipart/issues' - } - - licenses { - license { - name 'GNU Lesser Public License (GPL), Version 2.1' - url 'https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt' - distribution 'repo' - } - } - - developers { - developer { - id 'chicken-bones' - name 'chicken-bones' - roles { role 'developer' } - } - } - } - } - } - } else { - logger.info('Publishing to repo folder') - - mavenDeployer { - pom.version = "${project.minecraft.version}-${project.version}" - repository(url: 'file://localhost/' + project.file('repo').getAbsolutePath()) - } - } - } -} \ No newline at end of file diff --git a/build.properties b/build.properties deleted file mode 100644 index c1b4d2a..0000000 --- a/build.properties +++ /dev/null @@ -1,4 +0,0 @@ -mc_version=1.7.2 -forge_version=10.12.0.1054 -ccl_version=1.1.0.71 -mod_version=1.1.0 diff --git a/codechicken/core/launch/DepLoader.java b/codechicken/core/launch/DepLoader.java deleted file mode 100644 index 8dc5ba4..0000000 --- a/codechicken/core/launch/DepLoader.java +++ /dev/null @@ -1,609 +0,0 @@ -package codechicken.core.launch; - -import java.awt.*; -import java.awt.Dialog.ModalityType; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.io.*; -import java.lang.reflect.Field; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.net.URLConnection; -import java.nio.ByteBuffer; -import java.util.*; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -import javax.swing.Box; -import javax.swing.JDialog; -import javax.swing.JEditorPane; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JProgressBar; -import javax.swing.WindowConstants; -import javax.swing.event.HyperlinkEvent; -import javax.swing.event.HyperlinkListener; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import net.minecraft.launchwrapper.LaunchClassLoader; - -import cpw.mods.fml.common.versioning.ComparableVersion; -import cpw.mods.fml.relauncher.FMLInjectionData; -import cpw.mods.fml.relauncher.FMLLaunchHandler; -import cpw.mods.fml.relauncher.IFMLCallHook; -import cpw.mods.fml.relauncher.IFMLLoadingPlugin; -import sun.misc.URLClassPath; -import sun.net.util.URLUtil; - -/** - * For autodownloading stuff. - * This is really unoriginal, mostly ripped off FML, credits to cpw. - */ -public class DepLoader implements IFMLLoadingPlugin, IFMLCallHook { - private static ByteBuffer downloadBuffer = ByteBuffer.allocateDirect(1 << 23); - private static final String owner = "CB's DepLoader"; - private static DepLoadInst inst; - - public interface IDownloadDisplay { - void resetProgress(int sizeGuess); - - void setPokeThread(Thread currentThread); - - void updateProgress(int fullLength); - - boolean shouldStopIt(); - - void updateProgressString(String string, Object... data); - - Object makeDialog(); - - void showErrorDialog(String name, String url); - } - - @SuppressWarnings("serial") - public static class Downloader extends JOptionPane implements IDownloadDisplay { - private JDialog container; - private JLabel currentActivity; - private JProgressBar progress; - boolean stopIt; - Thread pokeThread; - - private Box makeProgressPanel() { - Box box = Box.createVerticalBox(); - box.add(Box.createRigidArea(new Dimension(0, 10))); - JLabel welcomeLabel = new JLabel("" + owner + " is setting up your minecraft environment"); - box.add(welcomeLabel); - welcomeLabel.setAlignmentY(LEFT_ALIGNMENT); - welcomeLabel = new JLabel("Please wait, " + owner + " has some tasks to do before you can play"); - welcomeLabel.setAlignmentY(LEFT_ALIGNMENT); - box.add(welcomeLabel); - box.add(Box.createRigidArea(new Dimension(0, 10))); - currentActivity = new JLabel("Currently doing ..."); - box.add(currentActivity); - box.add(Box.createRigidArea(new Dimension(0, 10))); - progress = new JProgressBar(0, 100); - progress.setStringPainted(true); - box.add(progress); - box.add(Box.createRigidArea(new Dimension(0, 30))); - return box; - } - - @Override - public JDialog makeDialog() { - if (container != null) - return container; - - setMessageType(JOptionPane.INFORMATION_MESSAGE); - setMessage(makeProgressPanel()); - setOptions(new Object[]{"Stop"}); - addPropertyChangeListener(new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { - if (evt.getSource() == Downloader.this && evt.getPropertyName() == VALUE_PROPERTY) { - requestClose("This will stop minecraft from launching\nAre you sure you want to do this?"); - } - } - }); - container = new JDialog(null, "Hello", ModalityType.MODELESS); - container.setResizable(false); - container.setLocationRelativeTo(null); - container.add(this); - this.updateUI(); - container.pack(); - container.setMinimumSize(container.getPreferredSize()); - container.setVisible(true); - container.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); - container.addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(WindowEvent e) { - requestClose("Closing this window will stop minecraft from launching\nAre you sure you wish to do this?"); - } - }); - return container; - } - - protected void requestClose(String message) { - int shouldClose = JOptionPane.showConfirmDialog(container, message, "Are you sure you want to stop?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); - if (shouldClose == JOptionPane.YES_OPTION) - container.dispose(); - - stopIt = true; - if (pokeThread != null) - pokeThread.interrupt(); - } - - @Override - public void updateProgressString(String progressUpdate, Object... data) { - //FMLLog.finest(progressUpdate, data); - if (currentActivity != null) - currentActivity.setText(String.format(progressUpdate, data)); - } - - @Override - public void resetProgress(int sizeGuess) { - if (progress != null) - progress.getModel().setRangeProperties(0, 0, 0, sizeGuess, false); - } - - @Override - public void updateProgress(int fullLength) { - if (progress != null) - progress.getModel().setValue(fullLength); - } - - @Override - public void setPokeThread(Thread currentThread) { - this.pokeThread = currentThread; - } - - @Override - public boolean shouldStopIt() { - return stopIt; - } - - @Override - public void showErrorDialog(String name, String url) { - JEditorPane ep = new JEditorPane("text/html", - "" + - owner + " was unable to download required library " + name + - "
Check your internet connection and try restarting or download it manually from" + - "
" + url + " and put it in your mods folder" + - ""); - - ep.setEditable(false); - ep.setOpaque(false); - ep.addHyperlinkListener(new HyperlinkListener() { - @Override - public void hyperlinkUpdate(HyperlinkEvent event) { - try { - if (event.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED)) - Desktop.getDesktop().browse(event.getURL().toURI()); - } catch (Exception e) { - } - } - }); - - JOptionPane.showMessageDialog(null, ep, "A download error has occured", JOptionPane.ERROR_MESSAGE); - } - } - - public static class DummyDownloader implements IDownloadDisplay { - @Override - public void resetProgress(int sizeGuess) { - } - - @Override - public void setPokeThread(Thread currentThread) { - } - - @Override - public void updateProgress(int fullLength) { - } - - @Override - public boolean shouldStopIt() { - return false; - } - - @Override - public void updateProgressString(String string, Object... data) { - } - - @Override - public Object makeDialog() { - return null; - } - - @Override - public void showErrorDialog(String name, String url) { - } - } - - public static class Dependancy { - public String url; - public String[] filesplit; - public ComparableVersion version; - - public String existing; - /** - * Flag set to add this dep to the classpath immediately because it is required for a coremod. - */ - public boolean coreLib; - - public Dependancy(String url, String[] filesplit, boolean coreLib) { - this.url = url; - this.filesplit = filesplit; - this.coreLib = coreLib; - version = new ComparableVersion(filesplit[1]); - } - - public String getName() { - return filesplit[0]; - } - - public String fileName() { - return filesplit[0] + filesplit[1] + filesplit[2]; - } - } - - public static class DepLoadInst { - private File modsDir; - private File v_modsDir; - private IDownloadDisplay downloadMonitor; - private JDialog popupWindow; - - private Map depMap = new HashMap(); - private HashSet depSet = new HashSet(); - - public DepLoadInst() { - String mcVer = (String) FMLInjectionData.data()[4]; - File mcDir = (File) FMLInjectionData.data()[6]; - - modsDir = new File(mcDir, "mods"); - v_modsDir = new File(mcDir, "mods/" + mcVer); - if (!v_modsDir.exists()) - v_modsDir.mkdirs(); - } - - private void addClasspath(String name) { - try { - ((LaunchClassLoader) DepLoader.class.getClassLoader()).addURL(new File(v_modsDir, name).toURI().toURL()); - } catch (MalformedURLException e) { - throw new RuntimeException(e); - } - } - - private void deleteMod(File mod) { - if (mod.delete()) - return; - - try { - ClassLoader cl = DepLoader.class.getClassLoader(); - URL url = mod.toURI().toURL(); - Field f_ucp = URLClassLoader.class.getDeclaredField("ucp"); - Field f_loaders = URLClassPath.class.getDeclaredField("loaders"); - Field f_lmap = URLClassPath.class.getDeclaredField("lmap"); - f_ucp.setAccessible(true); - f_loaders.setAccessible(true); - f_lmap.setAccessible(true); - - URLClassPath ucp = (URLClassPath) f_ucp.get(cl); - Closeable loader = ((Map) f_lmap.get(ucp)).remove(URLUtil.urlNoFragString(url)); - if (loader != null) { - loader.close(); - ((List) f_loaders.get(ucp)).remove(loader); - } - } catch (Exception e) { - e.printStackTrace(); - } - - if (!mod.delete()) { - mod.deleteOnExit(); - String msg = owner + " was unable to delete file " + mod.getPath() + " the game will now try to delete it on exit. If this dialog appears again, delete it manually."; - System.err.println(msg); - if (!GraphicsEnvironment.isHeadless()) - JOptionPane.showMessageDialog(null, msg, "An update error has occured", JOptionPane.ERROR_MESSAGE); - - System.exit(1); - } - } - - private void download(Dependancy dep) { - popupWindow = (JDialog) downloadMonitor.makeDialog(); - File libFile = new File(v_modsDir, dep.fileName()); - try { - URL libDownload = new URL(dep.url + '/' + dep.fileName()); - downloadMonitor.updateProgressString("Downloading file %s", libDownload.toString()); - System.out.format("Downloading file %s\n", libDownload.toString()); - URLConnection connection = libDownload.openConnection(); - connection.setConnectTimeout(5000); - connection.setReadTimeout(5000); - connection.setRequestProperty("User-Agent", "" + owner + " Downloader"); - int sizeGuess = connection.getContentLength(); - download(connection.getInputStream(), sizeGuess, libFile); - downloadMonitor.updateProgressString("Download complete"); - System.out.println("Download complete"); - - scanDepInfo(libFile); - } catch (Exception e) { - libFile.delete(); - if (downloadMonitor.shouldStopIt()) { - System.err.println("You have stopped the downloading operation before it could complete"); - System.exit(1); - return; - } - downloadMonitor.showErrorDialog(dep.fileName(), dep.url + '/' + dep.fileName()); - throw new RuntimeException("A download error occured", e); - } - } - - private void download(InputStream is, int sizeGuess, File target) throws Exception { - if (sizeGuess > downloadBuffer.capacity()) - throw new Exception(String.format("The file %s is too large to be downloaded by " + owner + " - the download is invalid", target.getName())); - - downloadBuffer.clear(); - - int bytesRead, fullLength = 0; - - downloadMonitor.resetProgress(sizeGuess); - try { - downloadMonitor.setPokeThread(Thread.currentThread()); - byte[] smallBuffer = new byte[1024]; - while ((bytesRead = is.read(smallBuffer)) >= 0) { - downloadBuffer.put(smallBuffer, 0, bytesRead); - fullLength += bytesRead; - if (downloadMonitor.shouldStopIt()) { - break; - } - downloadMonitor.updateProgress(fullLength); - } - is.close(); - downloadMonitor.setPokeThread(null); - downloadBuffer.limit(fullLength); - downloadBuffer.position(0); - } catch (InterruptedIOException e) { - // We were interrupted by the stop button. We're stopping now.. clear interruption flag. - Thread.interrupted(); - throw new Exception("Stop"); - } catch (IOException e) { - throw e; - } - - try { - /*String cksum = generateChecksum(downloadBuffer); - if (cksum.equals(validationHash)) - {*/ - if (!target.exists()) - target.createNewFile(); - - - downloadBuffer.position(0); - FileOutputStream fos = new FileOutputStream(target); - fos.getChannel().write(downloadBuffer); - fos.close(); - /*} - else - { - throw new RuntimeException(String.format("The downloaded file %s has an invalid checksum %s (expecting %s). The download did not succeed correctly and the file has been deleted. Please try launching again.", target.getName(), cksum, validationHash)); - }*/ - } catch (Exception e) { - throw e; - } - } - - private String checkExisting(String[] dependency) { - for (File f : modsDir.listFiles()) { - String[] split = splitFileName(f.getName()); - if (split == null || !split[0].equals(dependency[0])) - continue; - - if (f.renameTo(new File(v_modsDir, f.getName()))) - continue; - - deleteMod(f); - } - - for (File f : v_modsDir.listFiles()) { - String[] split = splitFileName(f.getName()); - if (split == null || !split[0].equals(dependency[0])) - continue; - - ComparableVersion found = new ComparableVersion(split[1]); - ComparableVersion requested = new ComparableVersion(dependency[1]); - - int cmp = found.compareTo(requested); - if (cmp < 0) { - System.out.println("Deleted old version " + f.getName()); - deleteMod(f); - return null; - } - if (cmp > 0) { - System.err.println("Warning: version of " + dependency[0] + ", " + split[1] + " is newer than request " + dependency[1]); - return f.getName(); - } - return f.getName();//found dependency - } - return null; - } - - public void load() { - scanDepInfos(); - if (depMap.isEmpty()) - return; - - loadDeps(); - activateDeps(); - } - - private void activateDeps() { - for (Dependancy dep : depMap.values()) - if (dep.coreLib) - addClasspath(dep.existing); - } - - private void loadDeps() { - downloadMonitor = FMLLaunchHandler.side().isClient() ? new Downloader() : new DummyDownloader(); - try { - while (!depSet.isEmpty()) { - Iterator it = depSet.iterator(); - Dependancy dep = depMap.get(it.next()); - it.remove(); - load(dep); - } - } finally { - if (popupWindow != null) { - popupWindow.setVisible(false); - popupWindow.dispose(); - } - } - } - - private void load(Dependancy dep) { - dep.existing = checkExisting(dep.filesplit); - if (dep.existing == null)//download dep - { - download(dep); - dep.existing = dep.fileName(); - } - } - - private List modFiles() { - List list = new LinkedList(); - list.addAll(Arrays.asList(modsDir.listFiles())); - list.addAll(Arrays.asList(v_modsDir.listFiles())); - return list; - } - - private void scanDepInfos() { - for (File file : modFiles()) { - if (!file.getName().endsWith(".jar") && !file.getName().endsWith(".zip")) - continue; - - scanDepInfo(file); - } - } - - private void scanDepInfo(File file) { - try { - ZipFile zip = new ZipFile(file); - ZipEntry e = zip.getEntry("dependancies.info"); - if (e == null) e = zip.getEntry("dependencies.info"); - if (e != null) - loadJSon(zip.getInputStream(e)); - zip.close(); - } catch (Exception e) { - System.err.println("Failed to load dependencies.info from " + file.getName() + " as JSON"); - e.printStackTrace(); - } - } - - private void loadJSon(InputStream input) throws IOException { - InputStreamReader reader = new InputStreamReader(input); - JsonElement root = new JsonParser().parse(reader); - if (root.isJsonArray()) - loadJSonArr(root); - else - loadJson(root.getAsJsonObject()); - reader.close(); - } - - private void loadJSonArr(JsonElement root) throws IOException { - for (JsonElement node : root.getAsJsonArray()) - loadJson(node.getAsJsonObject()); - } - - private void loadJson(JsonObject node) throws IOException { - boolean obfuscated = ((LaunchClassLoader) DepLoader.class.getClassLoader()) - .getClassBytes("net.minecraft.world.World") == null; - - String testClass = node.get("class").getAsString(); - if (DepLoader.class.getResource("/" + testClass.replace('.', '/') + ".class") != null) - return; - - String repo = node.get("repo").getAsString(); - String file = node.get("file").getAsString(); - if (!obfuscated && node.has("dev")) - file = node.get("dev").getAsString(); - - boolean coreLib = node.has("coreLib") && node.get("coreLib").getAsBoolean(); - - String[] split = splitFileName(file); - if (split == null) - throw new RuntimeException("Invalid filename format for dependency: " + file); - - addDep(new Dependancy(repo, split, coreLib)); - } - - private void addDep(Dependancy newDep) { - if (mergeNew(depMap.get(newDep.getName()), newDep)) { - depMap.put(newDep.getName(), newDep); - depSet.add(newDep.getName()); - } - } - - private boolean mergeNew(Dependancy oldDep, Dependancy newDep) { - if (oldDep == null) - return true; - - Dependancy newest = newDep.version.compareTo(oldDep.version) > 0 ? newDep : oldDep; - newest.coreLib = newDep.coreLib || oldDep.coreLib; - - return newest == newDep; - } - } - - public static void load() { - if (inst == null) { - inst = new DepLoadInst(); - inst.load(); - } - } - - private static String[] splitFileName(String filename) { - Pattern p = Pattern.compile("(.+?)([\\d\\.\\w]+)(\\.[^\\d]+)"); - Matcher m = p.matcher(filename); - if (!m.matches()) - return null; - - return new String[]{m.group(1), m.group(2), m.group(3)}; - } - - @Override - public String[] getASMTransformerClass() { - return null; - } - - @Override - public String getModContainerClass() { - return null; - } - - @Override - public String getSetupClass() { - return getClass().getName(); - } - - @Override - public void injectData(Map data) { - } - - @Override - public Void call() { - load(); - - return null; - } - - @Override - public String getAccessTransformerClass() { - return null; - } -} diff --git a/codechicken/microblock/BlockMicroMaterial.scala b/codechicken/microblock/BlockMicroMaterial.scala deleted file mode 100644 index 6bbfe8b..0000000 --- a/codechicken/microblock/BlockMicroMaterial.scala +++ /dev/null @@ -1,145 +0,0 @@ -package codechicken.microblock - -import net.minecraft.block.Block -import codechicken.microblock.MicroMaterialRegistry.IMicroMaterial -import net.minecraft.util.IIcon -import cpw.mods.fml.relauncher.SideOnly -import cpw.mods.fml.relauncher.Side -import net.minecraft.item.ItemStack -import codechicken.lib.vec.{Cuboid6, Vector3} -import net.minecraft.entity.player.EntityPlayer -import codechicken.lib.render.{CCRenderPipeline, ColourMultiplier, CCRenderState} -import codechicken.microblock.handler.MicroblockProxy -import net.minecraft.entity.Entity -import codechicken.lib.render.uv.{UVTransformation, MultiIconTransformation} - -object MaterialRenderHelper -{ - private var pass = 0 - private var builder:CCRenderPipeline#PipelineBuilder = _ - - def start(pos:Vector3, pass:Int, uvt:UVTransformation) = { - this.pass = pass - builder = CCRenderState.pipeline.builder() - builder.add(pos.translation()).add(uvt) - this - } - - def blockColour(colour:Int) = { - builder.add(ColourMultiplier.instance(colour)) - this - } - - def lighting() = { - if(pass != -1) - builder.add(CCRenderState.lightMatrix) - this - } - - def render() = builder.render() -} - -/** - * Standard micro material class suitable for most blocks. - */ -class BlockMicroMaterial(val block:Block, val meta:Int = 0) extends IMicroMaterial -{ - val blockKey = Block.blockRegistry.getNameForObject(block) - - @SideOnly(Side.CLIENT) - var icont:MultiIconTransformation = _ - - @SideOnly(Side.CLIENT) - override def loadIcons() { - def safeIcon(block:Block, side:Int):IIcon = { - try { - return MicroblockProxy.renderBlocks.getIconSafe(block.getIcon(side, meta)) - } - catch { - case e:Exception => - } - return MicroblockProxy.renderBlocks.getIconSafe(null) - } - - val iblock = Block.getBlockFromName(blockKey)//reacquire block instance incase a mod replcaed it - icont = new MultiIconTransformation(Array.tabulate(6)(side => safeIcon(iblock, side)):_*) - } - - def renderMicroFace(pos:Vector3, pass:Int, bounds:Cuboid6) { - MaterialRenderHelper.start(pos, pass, icont).blockColour(getColour(pass)).lighting().render() - } - - def getColour(pass:Int) = { - if(pass == -1) - block.getBlockColor<<8|0xFF - else { - val pos = CCRenderState.lightMatrix.pos - block.colorMultiplier(CCRenderState.lightMatrix.access, pos.x, pos.y, pos.z)<<8|0xFF - } - } - - override def canRenderInPass(pass:Int) = block.canRenderInPass(pass) - - @SideOnly(Side.CLIENT) - def getBreakingIcon(side:Int) = block.getIcon(side, meta) - - def getItem = new ItemStack(block, 1, meta) - - def getLocalizedName = getItem.getDisplayName - - def getStrength(player:EntityPlayer) = { - var hardness = 30F - try { - hardness = block.getBlockHardness(null, 0, 0, 0) - } catch { - case e:Exception => - } - player.getBreakSpeed(block, false, meta) / hardness - } - - def isTransparent = !block.isOpaqueCube - - def getLightValue = block.getLightValue - - def toolClasses = Seq("axe", "pickaxe", "shovel") - - def getCutterStrength = block.getHarvestLevel(meta) - - def getSound = block.stepSound - - def explosionResistance(entity:Entity):Float = block.getExplosionResistance(entity) -} - -/** - * Utility functions for cleaner registry code - */ -object BlockMicroMaterial -{ - def materialKey(block:Block, meta:Int):String = materialKey(block.getUnlocalizedName, meta) - def materialKey(name:String, meta:Int) = name+(if(meta > 0) "_"+meta else "") - - def createAndRegister(block:Block, name:String) - { - createAndRegister(block, 0, name) - } - - def createAndRegister(block:Block, meta:Int = 0) - { - MicroMaterialRegistry.registerMaterial(new BlockMicroMaterial(block, meta), materialKey(block, meta)) - } - - def createAndRegister(block:Block, meta:Seq[Int]) - { - meta.foreach(m => createAndRegister(block, m)) - } - - def createAndRegister(block:Block, meta:Int, name:String) - { - MicroMaterialRegistry.registerMaterial(new BlockMicroMaterial(block, meta), materialKey(name, meta)) - } - - def createAndRegister(block:Block, meta:Seq[Int], name:String) - { - meta.foreach(m => createAndRegister(block, m, name)) - } -} \ No newline at end of file diff --git a/codechicken/microblock/CommonMicroblock.scala b/codechicken/microblock/CommonMicroblock.scala deleted file mode 100644 index 5af8c4c..0000000 --- a/codechicken/microblock/CommonMicroblock.scala +++ /dev/null @@ -1,208 +0,0 @@ -package codechicken.microblock - -import net.minecraft.nbt.NBTTagCompound -import codechicken.lib.lighting.LightMatrix -import codechicken.microblock.MicroMaterialRegistry._ -import codechicken.lib.vec.BlockCoord -import org.lwjgl.opengl.GL11 -import codechicken.lib.render.CCRenderState -import net.minecraft.world.World -import codechicken.lib.vec.Cuboid6 -import codechicken.lib.vec.Vector3 -import codechicken.multipart.TIconHitEffects -import net.minecraft.util.IIcon -import net.minecraft.block.Block -import codechicken.multipart.TCuboidPart -import net.minecraft.util.MovingObjectPosition -import net.minecraft.entity.player.EntityPlayer -import codechicken.multipart.JPartialOcclusion -import codechicken.lib.render.Vertex5 -import net.minecraft.item.ItemStack -import scala.collection.mutable.ListBuffer -import codechicken.lib.data.MCDataOutput -import codechicken.lib.data.MCDataInput -import codechicken.lib.render.RenderUtils -import codechicken.lib.render.IFaceRenderer -import codechicken.multipart.TSlottedPart -import scala.collection.JavaConversions._ -import codechicken.lib.render.TextureUtils -import net.minecraft.entity.Entity -import net.minecraft.init.Blocks -import cpw.mods.fml.relauncher.{Side, SideOnly} -import codechicken.lib.render.BlockRenderer.BlockFace - -object MicroblockRender -{ - def renderHighlight(player:EntityPlayer, hit:MovingObjectPosition, mcrClass:MicroblockClass, size:Int, material:Int) - { - mcrClass.placementProperties.placementGrid.render(new Vector3(hit.hitVec), hit.sideHit) - - val placement = MicroblockPlacement(player, hit, size, material, !player.capabilities.isCreativeMode, mcrClass.placementProperties) - if(placement == null) - return - val pos = placement.pos - val part = placement.part.asInstanceOf[MicroblockClient] - - GL11.glPushMatrix() - GL11.glTranslated(pos.x+0.5, pos.y+0.5, pos.z+0.5) - GL11.glScaled(1.002, 1.002, 1.002) - GL11.glTranslated(-0.5, -0.5, -0.5) - - GL11.glEnable(GL11.GL_BLEND) - GL11.glDepthMask(false) - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA) - - TextureUtils.bindAtlas(0) - CCRenderState.reset() - CCRenderState.alphaOverride = 80 - CCRenderState.useNormals = true - CCRenderState.startDrawing() - part.render(Vector3.zero, -1) - CCRenderState.draw() - - GL11.glDisable(GL11.GL_BLEND) - GL11.glDepthMask(true) - GL11.glPopMatrix() - } - - val face = new BlockFace() - def renderCuboid(pos:Vector3, mat:IMicroMaterial, pass:Int, c:Cuboid6, faces:Int) { - CCRenderState.setModel(face) - for(s <- 0 until 6 if (faces & 1< Blocks.stone.getIcon(0, 0) - case mat => mat.getBreakingIcon(side) - } - - override def renderStatic(pos:Vector3, pass:Int) = { - if(getIMaterial.canRenderInPass(pass)) { - render(pos, pass) - true - } - else - false - } - - def render(pos:Vector3, pass:Int) - - override def getRenderBounds = getBounds -} - -abstract class Microblock(var shape:Byte = 0, var material:Int = 0) extends TCuboidPart -{ - def this(size:Int, shape:Int, material:Int) = this((size<<4|shape).toByte, material) - - override def getStrength(hit:MovingObjectPosition, player:EntityPlayer) = getIMaterial match { - case null => super.getStrength(hit, player) - case mat => mat.getStrength(player) - } - - override def doesTick = false - - def getSize = shape>>4 - - def getShape = shape&0xF - - def getMaterial = material - - def getIMaterial = MicroMaterialRegistry.getMaterial(material) - - def itemClassID:Int = -1 - - override def getDrops = - { - var size = getSize - val items = ListBuffer[ItemStack]() - for(s <- Seq(4, 2, 1)) - { - val m = size/s - size-=m*s - if(m > 0) - items+=ItemMicroPart.create(m, s|itemClassID<<8, MicroMaterialRegistry.materialName(material)) - } - items - } - - override def pickItem(hit:MovingObjectPosition):ItemStack = - { - val size = getSize - for(s <- Seq(4, 2, 1)) - if(size%s == 0 && size/s >= 1) - return ItemMicroPart.create(s|itemClassID<<8, MicroMaterialRegistry.materialName(material)) - return null//unreachable - } - - override def writeDesc(packet:MCDataOutput) - { - packet.writeByte(shape) - writeMaterialID(packet, material) - } - - override def readDesc(packet:MCDataInput) - { - shape = packet.readByte - material = readMaterialID(packet) - } - - override def read(packet:MCDataInput) - { - readDesc(packet) - tile.notifyPartChange(this) - tile.markRender() - } - - override def save(tag:NBTTagCompound) - { - tag.setByte("shape", shape) - tag.setString("material", materialName(material)) - } - - override def load(tag:NBTTagCompound) - { - shape = tag.getByte("shape") - material = materialID(tag.getString("material")) - } - - def isTransparent = getIMaterial.isTransparent - - override def getLightValue = getIMaterial.getLightValue - - def getResistanceFactor:Float - - override def explosionResistance(entity:Entity) = getIMaterial.explosionResistance(entity)*getResistanceFactor -} - -trait CommonMicroblockClient extends CommonMicroblock with MicroblockClient with TMicroOcclusionClient -{ - def render(pos:Vector3, pass:Int) { - if(pass < 0) - MicroblockRender.renderCuboid(pos, getIMaterial, pass, getBounds, 0) - else - MicroblockRender.renderCuboid(pos, getIMaterial, pass, renderBounds, renderMask) - } -} - -abstract class CommonMicroblock(shape$:Byte = 0, material$:Int = 0) extends Microblock(shape$, material$) with JPartialOcclusion with TMicroOcclusion with TSlottedPart -{ - def microClass:MicroblockClass - - def getType = microClass.getName - - def getSlot = getShape - - def getSlotMask = 1< MMap} -import net.minecraft.block.Block -import net.minecraft.item.Item -import java.lang.Exception -import cpw.mods.fml.common.event.FMLInterModComms.IMCMessage -import net.minecraft.item.ItemStack -import BlockMicroMaterial.createAndRegister -import BlockMicroMaterial.materialKey -import java.util.ArrayList -import scala.collection.JavaConversions._ -import net.minecraft.init.Blocks - -object ConfigContent -{ - private val nameMap = MMap[String, Seq[Int]]() - private val idMap = new ArrayList[Seq[Int]]() - - def parse(cfgDir:File) - { - val cfgFile = new File(cfgDir, "microblocks.cfg") - try - { - if(!cfgFile.exists()) - generateDefault(cfgFile) - else - loadLines(cfgFile) - } - catch - { - case e:IOException => e.printStackTrace() - } - } - - def generateDefault(cfgFile:File) - { - val writer = new PrintWriter(cfgFile) - writer.println("#Configuration file for adding microblock materials for aesthetic blocks added by mods") - writer.println("#Each line needs to be of the form :") - writer.println("# may be a numerical id or the unlocalised name of the block/item enclosed in double quotes. NEI can help you find these") - writer.println("# may be ommitted, in which case it defaults to 0, otherwise it can be a number, a comma separated list of numbers, or a dash separated range") - writer.println("#Ex. 3. 5:3. 213:1,2,3,5. \"tile.blockIron\":0-15") - writer.close() - } - - def loadLine(line:String) - { - if(line.startsWith("#")) - return - - var split1 = line.replace(" ", "").split(":") - if(split1.length > 2) - throw new IllegalArgumentException("Invalid number of ':' separators") - if(split1.length == 1) - split1 = Array(split1(0), "0") - - if(split1(0) == "") - return - - val split2 = split1(1).split(",") - val meta = split2.flatMap{s => - if(s.contains("-")) - { - val split2 = s.split("-") - if(split2.length != 2) - throw new IllegalArgumentException("Invalid - separated range") - split2(0).toInt to split2(1).toInt - } - else - { - Seq(s.toInt) - } - } - - val s_id = split1(0) - if(s_id.charAt(0) == '\"') - { - if(!s_id.endsWith("\"")) - throw new IllegalArgumentException("Missing closing \" character") - - val name = s_id.substring(1, s_id.length-1) - nameMap.put(name, meta) - } - else - { - idMap(s_id.toInt) = meta - } - } - - def loadLines(cfgFile:File) - { - val reader = new BufferedReader(new FileReader(cfgFile)) - var s:String = null - do - { - s = reader.readLine - if(s != null) - { - try - { - loadLine(s) - } - catch - { - case e:Exception => - System.err.println("Invalid line in microblocks.cfg: "+s) - System.err.println(e.getMessage) - } - } - } - while(s != null) - reader.close() - } - - def load() - { - for(i <- 0 until idMap.size) - { - val block = Block.getBlockById(i) - if(idMap(i) != null) - { - if(block == Blocks.air) - System.err.println("Warning: Unable to add micro material for block with ID "+i+" as it doesn't exist") - else - createAndRegister(block, idMap(i)) - } - else if(block != null) - { - val name = block.getUnlocalizedName - val value = nameMap.get(name) - if(value.isDefined) - { - nameMap.remove(name) - value.get.foreach{m => - try { - createAndRegister(block, m) - } - catch { - case e:IllegalStateException => System.err.println("Unable to register micro material: "+ - materialKey(block, m)+"\n\t"+e.getMessage) - case e:Exception => - System.err.println("Unable to register micro material: "+materialKey(block, m)) - e.printStackTrace() - } - } - } - } - } - - nameMap.foreach(e => System.err.println("Warning: Unable to add micro material for block with unlocalised name "+e._1+" as it doesn't exist")) - } - - def handleIMC(messages:Seq[IMCMessage]) { - messages.filter(_.key == "microMaterial").foreach{msg => - - def error(s:String) { - System.err.println("Invalid microblock IMC message from "+msg.getSender+": "+s) - } - - if(msg.getMessageType != classOf[ItemStack]) - error("value is not an instanceof ItemStack") - else { - val stack = msg.getItemStackValue - if(Block.blockRegistry.containsId(Item.getIdFromItem(stack.getItem))) - System.err.println("Invalid Block: "+stack.getItem) - else if(stack.getItemDamage < 0 || stack.getItemDamage >= 16) - System.err.println("Invalid metadata: "+stack.getItemDamage) - else { - try { - createAndRegister(Block.getBlockFromItem(stack.getItem), stack.getItemDamage) - } - catch { - case e:IllegalStateException => System.err.println("Unable to register micro material: "+ - materialKey(Block.getBlockFromItem(stack.getItem), stack.getItemDamage)+"\n\t"+e.getMessage) - } - } - } - } - } -} \ No newline at end of file diff --git a/codechicken/microblock/CornerMicroblock.scala b/codechicken/microblock/CornerMicroblock.scala deleted file mode 100644 index f79f5e3..0000000 --- a/codechicken/microblock/CornerMicroblock.scala +++ /dev/null @@ -1,70 +0,0 @@ -package codechicken.microblock - -import codechicken.lib.vec.Cuboid6 -import codechicken.lib.vec.Scale -import codechicken.lib.vec.Vector3 -import Vector3._ - -object CornerPlacement extends PlacementProperties -{ - def microClass = CornerMicroClass - - def placementGrid = CornerPlacementGrid - - def opposite(slot:Int, side:Int) = ((slot-7)^(1<<(side>>1)))+7 -} - -object CornerMicroClass extends MicroblockClass -{ - var aBounds:Array[Cuboid6] = new Array(256) - - for(s <- 0 until 8) - { - val rx = if((s&4) != 0) -1 else 1 - val ry = if((s&1) != 0) -1 else 1 - val rz = if((s&2) != 0) -1 else 1 - val transform = new Scale(new Vector3(rx, ry, rz)).at(center) - - for(t <- 1 until 8) - { - val d = t/8D - aBounds(t<<4|s) = new Cuboid6(0, 0, 0, d, d, d).apply(transform) - } - } - - override def itemSlot = 7 - - def getName = "mcr_cnr" - - def create(client:Boolean) = - if(client) - new CornerMicroblockClient - else - new CornerMicroblock - - def create(size:Int, slot:Int, material:Int, client:Boolean) = - if(client) - new CornerMicroblockClient(size, slot, material) - else - new CornerMicroblock(size, slot, material) - - def placementProperties = CornerPlacement - - def getResistanceFactor = 1 -} - -class CornerMicroblockClient(shape$:Byte = 0, material$:Int = 0) extends CornerMicroblock(shape$, material$) with CommonMicroblockClient -{ - def this(size:Int, slot:Int, material:Int) = this((size<<4|(slot-7)).toByte, material) -} - -class CornerMicroblock(shape$:Byte = 0, material$:Int = 0) extends CommonMicroblock(shape$, material$) -{ - def this(size:Int, slot:Int, material:Int) = this((size<<4|(slot-7)).toByte, material) - - def microClass = CornerMicroClass - - def getBounds = CornerMicroClass.aBounds(shape) - - override def getSlot = getShape+7 -} \ No newline at end of file diff --git a/codechicken/microblock/DefaultContent.scala b/codechicken/microblock/DefaultContent.scala deleted file mode 100644 index 41144ae..0000000 --- a/codechicken/microblock/DefaultContent.scala +++ /dev/null @@ -1,56 +0,0 @@ -package codechicken.microblock - -import net.minecraft.init.Blocks._ -import BlockMicroMaterial._ -import MicroMaterialRegistry._ - -object DefaultContent -{ - def load() - { - FaceMicroClass.register(0) - HollowMicroClass.register(1) - CornerMicroClass.register(2) - EdgeMicroClass.register(3) - PostMicroClass.register() - - createAndRegister(stone) - createAndRegister(dirt) - createAndRegister(cobblestone) - createAndRegister(planks, 0 to 3) - createAndRegister(log, 0 to 3) - createAndRegister(log2, 0 to 1, "tile.log2") - createAndRegister(leaves, 0 to 3) - createAndRegister(sponge) - createAndRegister(glass) - createAndRegister(lapis_block) - createAndRegister(sandstone, 0 to 2) - createAndRegister(wool, 0 to 15) - createAndRegister(gold_block) - createAndRegister(iron_block) - createAndRegister(brick_block) - createAndRegister(bookshelf) - createAndRegister(mossy_cobblestone) - createAndRegister(obsidian) - createAndRegister(diamond_block) - createAndRegister(ice) - createAndRegister(snow) - createAndRegister(clay) - createAndRegister(netherrack) - createAndRegister(soul_sand) - createAndRegister(glowstone) - createAndRegister(stonebrick, 0 to 3) - createAndRegister(nether_brick) - createAndRegister(end_stone) - createAndRegister(emerald_block) - createAndRegister(redstone_block) - createAndRegister(quartz_block) - createAndRegister(stained_hardened_clay, 0 to 15) - createAndRegister(hardened_clay) - createAndRegister(coal_block) - createAndRegister(packed_ice) - createAndRegister(stained_glass) - registerMaterial(new GrassMicroMaterial, grass.getUnlocalizedName) - registerMaterial(new TopMicroMaterial(mycelium), mycelium.getUnlocalizedName) - } -} \ No newline at end of file diff --git a/codechicken/microblock/EdgeMicroblock.scala b/codechicken/microblock/EdgeMicroblock.scala deleted file mode 100644 index 7755e2e..0000000 --- a/codechicken/microblock/EdgeMicroblock.scala +++ /dev/null @@ -1,264 +0,0 @@ -package codechicken.microblock - -import codechicken.lib.vec.Cuboid6 -import codechicken.lib.vec.Scale -import codechicken.lib.vec.Vector3 -import codechicken.lib.vec.TransformationList -import codechicken.lib.vec.AxisCycle -import codechicken.lib.vec.Rotation -import Vector3._ -import Rotation._ -import codechicken.multipart.TMultiPart -import codechicken.multipart.TNormalOcclusion -import codechicken.multipart.JPartialOcclusion -import codechicken.multipart.TileMultipart -import codechicken.multipart.MultiPartRegistry -import codechicken.microblock.MicroMaterialRegistry.IMicroMaterial -import codechicken.lib.raytracer.ExtendedMOP -import codechicken.multipart.TEdgePart -import scala.collection.JavaConversions._ -import codechicken.lib.data.MCDataInput -import codechicken.lib.lighting.LightMatrix - -object EdgePlacement extends PlacementProperties -{ - import codechicken.multipart.PartMap._ - - def microClass = EdgeMicroClass - - def placementGrid = EdgePlacementGrid - - def opposite(slot:Int, side:Int):Int = - { - if(slot < 0)//custom placement - return slot - val e = slot-15 - return 15+ packEdgeBits(e, unpackEdgeBits(e)^(1<<(side>>1))) - } - - override def customPlacement(pmt:MicroblockPlacement):ExecutablePlacement = - { - if(pmt.size%2 == 1) return null - - val part = PostMicroClass.create(pmt.size, pmt.hit.sideHit>>1, pmt.material, pmt.world.isRemote) - if(pmt.doExpand) - { - val hpart = pmt.htile.partList(ExtendedMOP.getData[(Int, _)](pmt.hit)._1) - if(hpart.getType == PostMicroClass.getName) - { - val mpart = hpart.asInstanceOf[Microblock] - if(mpart.material == pmt.material && mpart.getSize + pmt.size < 8) - { - part.shape = ((mpart.getSize+pmt.size)<<4|mpart.getShape).toByte - return pmt.expand(mpart, part) - } - } - } - - if(pmt.slot >= 0) - return null - - if(pmt.internal && !pmt.oppMod) - return pmt.internalPlacement(pmt.htile.asInstanceOf[TileMultipart], part) - - return pmt.externalPlacement(part) - } -} - -object EdgeMicroClass extends MicroblockClass -{ - var aBounds:Array[Cuboid6] = new Array(256) - - for(s <- 0 until 12) - { - val rx = if((s&2) != 0) -1 else 1 - val rz = if((s&1) != 0) -1 else 1 - val transform = new TransformationList(new Scale(new Vector3(rx, 1, rz)), AxisCycle.cycles(s>>2)).at(center) - - for(t <- 1 until 8) - { - val d = t/8D - aBounds(t<<4|s) = new Cuboid6(0, 0, 0, d, 1, d).apply(transform) - } - } - - override def itemSlot = 15 - - def getName = "mcr_edge" - - def create(client:Boolean) = - if(client) - new EdgeMicroblockClient - else - new EdgeMicroblock - - def create(size:Int, slot:Int, material:Int, client:Boolean) = - if(client) - new EdgeMicroblockClient(size, slot, material) - else - new EdgeMicroblock(size, slot, material) - - def placementProperties = EdgePlacement - - def getResistanceFactor = 0.5F -} - -class EdgeMicroblock(shape$:Byte = 0, material$:Int = 0) extends CommonMicroblock(shape$, material$) with TEdgePart -{ - def this(size:Int, slot:Int, material:Int) = this((size<<4|(slot-15)).toByte, material) - - def microClass = EdgeMicroClass - - def getBounds = EdgeMicroClass.aBounds(shape) - - override def getSlot = getShape+15 -} - -class EdgeMicroblockClient(shape$:Byte = 0, material$:Int = 0) extends EdgeMicroblock(shape$, material$) with CommonMicroblockClient -{ - def this(size:Int, slot:Int, material:Int) = this((size<<4|(slot-15)).toByte, material) -} - -object PostMicroClass -{ - var aBounds:Array[Cuboid6] = new Array(256) - - for(s <- 0 until 3) - { - val transform = sideRotations(s<<1).at(center) - for(t <- 2 until 8 by 2) - { - val d1 = 0.5-t/16D - val d2 = 0.5+t/16D - aBounds(t<<4|s) = new Cuboid6(d1, 0, d1, d2, 1, d2).apply(transform) - } - } - - def getName = "mcr_post" - - def create(client:Boolean) = - if(client) - new PostMicroblockClient - else - new PostMicroblock - - def create(size:Int, slot:Int, material:Int, client:Boolean) = - if(client) - new PostMicroblockClient(size, slot, material) - else - new PostMicroblock(size, slot, material) - - def register() = MultiPartRegistry.registerParts((_, c:Boolean) => create(c), getName) - - def getResistanceFactor = 0.5F -} - -class PostMicroblockClient(shape$:Byte = 0, material$:Int = 0) extends PostMicroblock(shape$, material$) with MicroblockClient -{ - var renderBounds1:Cuboid6 = _ - var renderBounds2:Cuboid6 = _ - - def this(size:Int, orient:Int, material:Int) = this((size<<4|orient).toByte, material) - - override def render(pos:Vector3, pass:Int) - { - val mat = getIMaterial - if(pass == -1) - MicroblockRender.renderCuboid(pos, mat, pass, getBounds, 0) - else { - MicroblockRender.renderCuboid(pos, mat, pass, renderBounds1, 0) - if (renderBounds2 != null) - MicroblockRender.renderCuboid(pos, mat, pass, renderBounds2, 0) - } - } - - override def onPartChanged(part:TMultiPart) - { - recalcBounds() - } - - override def onAdded() - { - super.onAdded() - recalcBounds() - } - - override def read(packet:MCDataInput) - { - super.read(packet) - recalcBounds() - } - - def recalcBounds() - { - renderBounds1 = getBounds.copy - renderBounds2 = null - - shrinkFace(getShape<<1) - shrinkFace(getShape<<1|1) - - tile.partList.foreach(p => - if(p.isInstanceOf[PostMicroblock] && p != this) - shrinkPost(p.asInstanceOf[PostMicroblock]) - ) - } - - def shrinkFace(fside:Int) - { - val part = tile.partMap(fside) - if(part != null && part.getType.equals("mcr_face")) - MicroOcclusion.shrink(renderBounds1, part.asInstanceOf[CommonMicroblock].getBounds, fside) - } - - def shrinkPost(post:PostMicroblock) - { - if(post == this) - return - - if(thisShrinks(post)) - { - if(renderBounds2 == null) - renderBounds2 = renderBounds1.copy - else - renderBounds2.set(renderBounds1) - MicroOcclusion.shrink(renderBounds1, post.getBounds, getShape<<1|1) - MicroOcclusion.shrink(renderBounds2, post.getBounds, getShape<<1) - } - } - - def thisShrinks(other:PostMicroblock):Boolean = - { - if(getSize != other.getSize) return getSize < other.getSize - if(isTransparent != other.isTransparent) return isTransparent - return getShape > other.getShape - } -} - -class PostMicroblock(shape$:Byte = 0, material$:Int = 0) extends Microblock(shape$, material$) with JPartialOcclusion with TNormalOcclusion -{ - def this(size:Int, orient:Int, material:Int) = this((size<<4|orient).toByte, material) - - override def getType = PostMicroClass.getName - - def getBounds = PostMicroClass.aBounds(shape) - - def getOcclusionBoxes = Seq(getBounds) - - def getPartialOcclusionBoxes = getOcclusionBoxes - - override def itemClassID = EdgeMicroClass.classID - - override def occlusionTest(npart:TMultiPart): Boolean = - { - if(npart.isInstanceOf[PostMicroblock]) - return npart.asInstanceOf[PostMicroblock].getShape != getShape - - if(npart.getType.equals("mcr_face")) - if(npart.asInstanceOf[CommonMicroblock].getSlot>>1 == getShape) - return true - - return super.occlusionTest(npart) - } - - def getResistanceFactor = PostMicroClass.getResistanceFactor -} \ No newline at end of file diff --git a/codechicken/microblock/FaceMicroblock.scala b/codechicken/microblock/FaceMicroblock.scala deleted file mode 100644 index d78aa95..0000000 --- a/codechicken/microblock/FaceMicroblock.scala +++ /dev/null @@ -1,84 +0,0 @@ -package codechicken.microblock - -import codechicken.lib.vec.Cuboid6 -import codechicken.multipart.TFacePart -import codechicken.lib.vec.Vector3 -import codechicken.lib.vec.Rotation -import codechicken.microblock.MicroMaterialRegistry.IMicroMaterial -import Rotation._ -import Vector3._ -import codechicken.lib.lighting.LightMatrix - -object FacePlacement extends PlacementProperties -{ - def microClass = FaceMicroClass - - def placementGrid = FacePlacementGrid - - def opposite(slot:Int, side:Int) = slot^1 - - override def expand(slot:Int, side:Int) = sneakOpposite(slot, side) - - override def sneakOpposite(slot:Int, side:Int) = slot == (side^1) -} - -object FaceMicroClass extends MicroblockClass -{ - var aBounds:Array[Cuboid6] = new Array(256) - - for(s <- 0 until 6) - { - val transform = sideRotations(s).at(center) - for(t <- 1 until 8) - { - val d = t/8D - aBounds(t<<4|s) = new Cuboid6(0, 0, 0, 1, d, 1).apply(transform) - } - } - - def getName = "mcr_face" - - def create(client:Boolean) = - if(client) - new FaceMicroblockClient - else - new FaceMicroblock - - def create(size:Int, slot:Int, material:Int, client:Boolean) = - if(client) - new FaceMicroblockClient(size, slot, material) - else - new FaceMicroblock(size, slot, material) - - def placementProperties = FacePlacement - - def getResistanceFactor = 1 -} - -class FaceMicroblockClient(shape$:Byte = 0, material$:Int = 0) extends FaceMicroblock(shape$, material$) with CommonMicroblockClient -{ - def this(size:Int, shape:Int, material:Int) = this((size<<4|shape).toByte, material) - - override def render(pos:Vector3, pass:Int) { - if(pass < 0) - MicroblockRender.renderCuboid(pos, getIMaterial, pass, getBounds, 0) - else if(isTransparent) - MicroblockRender.renderCuboid(pos, getIMaterial, pass, renderBounds, renderMask) - else { - val mat = getIMaterial - MicroblockRender.renderCuboid(pos, mat, pass, renderBounds, renderMask | 1< 1) - MaterialRenderHelper.start(pos, pass, new UVTranslation(0, bounds.max.y-1) ++ sideIconT) - .blockColour(getColour(pass)).lighting().render() - } -} - -class TopMicroMaterial($block:Block, $meta:Int = 0) extends BlockMicroMaterial($block, $meta) -{ - override def renderMicroFace(pos:Vector3, pass:Int, bounds:Cuboid6) - { - val face = CCRenderState.model.asInstanceOf[BlockFace] - if(face.side <= 1) - MaterialRenderHelper.start(pos, pass, icont).blockColour(getColour(pass)).lighting().render() - else - MaterialRenderHelper.start(pos, pass, new UVTranslation(0, bounds.max.y-1) ++ icont) - .blockColour(getColour(pass)).lighting().render() - } -} \ No newline at end of file diff --git a/codechicken/microblock/HollowMicroblock.scala b/codechicken/microblock/HollowMicroblock.scala deleted file mode 100644 index dc5ac49..0000000 --- a/codechicken/microblock/HollowMicroblock.scala +++ /dev/null @@ -1,253 +0,0 @@ -package codechicken.microblock - -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.util.MovingObjectPosition -import codechicken.multipart.TFacePart -import codechicken.lib.vec.{Translation, Cuboid6, Rotation, Vector3} -import codechicken.multipart.TNormalOcclusion -import codechicken.microblock.MicroMaterialRegistry.IMicroMaterial -import net.minecraft.client.renderer.RenderBlocks -import codechicken.lib.render.{BlockRenderer, RenderUtils, CCRenderState} -import scala.collection.JavaConversions._ -import Rotation._ -import Vector3._ -import codechicken.lib.raytracer.IndexedCuboid6 -import org.lwjgl.opengl.GL11 -import codechicken.lib.render.uv.IconTransformation -import codechicken.lib.lighting.LightMatrix - -object HollowPlacement extends PlacementProperties -{ - - object HollowPlacementGrid extends FaceEdgeGrid(3 / 8D) - - def microClass = HollowMicroClass - - def placementGrid = HollowPlacementGrid - - def opposite(slot: Int, side: Int) = slot ^ 1 - - override def expand(slot: Int, side: Int) = sneakOpposite(slot, side) - - override def sneakOpposite(slot: Int, side: Int) = slot == (side ^ 1) -} - -object HollowMicroClass extends MicroblockClass -{ - var pBoxes: Array[Seq[Cuboid6]] = new Array(256) - var occBounds: Array[Cuboid6] = new Array(256) - for (s <- 0 until 6) { - val transform = sideRotations(s).at(center) - for (t <- 1 until 8) { - val d = t / 8D - val w1 = 1 / 8D - val w2 = 3 / 16D - pBoxes(t << 4 | s) = Seq( - new Cuboid6(0, 0, 0, w1, d, 1), - new Cuboid6(1 - w1, 0, 0, 1, d, 1), - new Cuboid6(w1, 0, 0, 1 - w1, d, w1), - new Cuboid6(w1, 0, 1 - w1, 1 - w1, d, 1)) - .map(_.apply(transform)) - occBounds(t << 4 | s) = new Cuboid6(1 / 8D, 0, 1 / 8D, 7 / 8D, d, 7 / 8D).apply(transform) - } - } - - def getName = "mcr_hllw" - - def create(client: Boolean) = - if (client) - new HollowMicroblockClient - else - new HollowMicroblock - - def create(size: Int, slot: Int, material: Int, client: Boolean) = - if (client) - new HollowMicroblockClient(size, slot, material) - else - new HollowMicroblock(size, slot, material) - - def placementProperties = HollowPlacement - - def getResistanceFactor = 1 -} - -class HollowMicroblockClient(shape$: Byte = 0, material$: Int = 0) extends HollowMicroblock(shape$, material$) with CommonMicroblockClient -{ - renderMask |= 8 << 8 - - def this(size: Int, shape: Int, material: Int) = this((size << 4 | shape).toByte, material) - - override def recalcBounds() { - super.recalcBounds() - renderMask = renderMask & 0xFF | getHollowSize << 8 - } - - override def drawBreaking(renderBlocks: RenderBlocks) { - CCRenderState.reset() - CCRenderState.setPipeline(new Translation(x, y, z), new IconTransformation(renderBlocks.overrideBlockTexture)) - renderHollow(null, 0, getBounds, 0, false, - (pos: Vector3, mat: IMicroMaterial, pass: Int, c: Cuboid6, sideMask: Int) => - BlockRenderer.renderCuboid(c, sideMask)) - } - - override def render(pos: Vector3, pass: Int) { - if (pass == -1) - renderHollow(pos, pass, getBounds, 0, false, MicroblockRender.renderCuboid) - else if (isTransparent) - renderHollow(pos, pass, renderBounds, renderMask, false, MicroblockRender.renderCuboid) - else { - renderHollow(pos, pass, renderBounds, renderMask | 1 << getSlot, false, MicroblockRender.renderCuboid) - renderHollow(pos, pass, Cuboid6.full, ~(1 << getSlot), true, MicroblockRender.renderCuboid) - } - } - - def renderHollow(pos: Vector3, pass: Int, c: Cuboid6, sideMask: Int, face: Boolean, - f: (Vector3, IMicroMaterial, Int, Cuboid6, Int) => Unit) { - val mat = getIMaterial - val size = renderMask >> 8 - val d1 = 0.5 - size / 32D - val d2 = 0.5 + size / 32D - val x1 = c.min.x - val x2 = c.max.x - val y1 = c.min.y - val y2 = c.max.y - val z1 = c.min.z - val z2 = c.max.z - - var iMask = 0 - getSlot match { - case 0 | 1 => - if (face) - iMask = 0x3C - f(pos, mat, pass, new Cuboid6(d1, y1, d2, d2, y2, z2), 0x3B | iMask) //-z internal - f(pos, mat, pass, new Cuboid6(d1, y1, z1, d2, y2, d1), 0x37 | iMask) //+z internal - - f(pos, mat, pass, new Cuboid6(d2, y1, d1, x2, y2, d2), sideMask & 0x23 | 0xC | iMask) //-x internal -y+y+x external - f(pos, mat, pass, new Cuboid6(x1, y1, d1, d1, y2, d2), sideMask & 0x13 | 0xC | iMask) //+x internal -y+y-x external - - f(pos, mat, pass, new Cuboid6(x1, y1, d2, x2, y2, z2), sideMask & 0x3B | 4 | iMask) //-y+y+z-x+x external - f(pos, mat, pass, new Cuboid6(x1, y1, z1, x2, y2, d1), sideMask & 0x37 | 8 | iMask) //-y+y-z-x+x external - case 2 | 3 => - if (face) - iMask = 0x33 - f(pos, mat, pass, new Cuboid6(d2, d1, z1, x2, d2, z2), 0x2F | iMask) //-x internal - f(pos, mat, pass, new Cuboid6(x1, d1, z1, d1, d2, z2), 0x1F | iMask) //+x internal - - f(pos, mat, pass, new Cuboid6(d1, d2, z1, d2, y2, z2), sideMask & 0xE | 0x30 | iMask) //-y internal -z+z+y external - f(pos, mat, pass, new Cuboid6(d1, y1, z1, d2, d1, z2), sideMask & 0xD | 0x30 | iMask) //+y internal -z+z-y external - - f(pos, mat, pass, new Cuboid6(d2, y1, z1, x2, y2, z2), sideMask & 0x2F | 0x10 | iMask) //-z+z+x-y+y external - f(pos, mat, pass, new Cuboid6(x1, y1, z1, d1, y2, z2), sideMask & 0x1F | 0x20 | iMask) //-z+z-x-y+y external - case 4 | 5 => - if (face) - iMask = 0xF - f(pos, mat, pass, new Cuboid6(x1, d2, d1, x2, y2, d2), 0x3E | iMask) //-y internal - f(pos, mat, pass, new Cuboid6(x1, y1, d1, x2, d1, d2), 0x3D | iMask) //+y internal - - f(pos, mat, pass, new Cuboid6(x1, d1, d2, x2, d2, z2), sideMask & 0x38 | 3 | iMask) //-z internal -x+x+z external - f(pos, mat, pass, new Cuboid6(x1, d1, z1, x2, d2, d1), sideMask & 0x34 | 3 | iMask) //+z internal -x+x-z external - - f(pos, mat, pass, new Cuboid6(x1, d2, z1, x2, y2, z2), sideMask & 0x3E | 1 | iMask) //-x+x+y-z+z external - f(pos, mat, pass, new Cuboid6(x1, y1, z1, x2, d1, z2), sideMask & 0x3D | 2 | iMask) //-x+x-y-z+z external - } - } - - override def drawHighlight(hit: MovingObjectPosition, player: EntityPlayer, frame: Float): Boolean = { - val size = getHollowSize - val d1 = 0.5 - size / 32D - val d2 = 0.5 + size / 32D - val t = (shape >> 4) / 8D - - import GL11._ - glEnable(GL_BLEND) - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) - glDisable(GL_TEXTURE_2D) - glColor4f(0, 0, 0, 0.4F) - glLineWidth(2) - glDepthMask(false) - glPushMatrix() - RenderUtils.translateToWorldCoords(player, frame) - glTranslated(x, y, z) - sideRotations(shape & 0xF).at(center).glApply() - - RenderUtils.drawCuboidOutline(new Cuboid6(0, 0, 0, 1, t, 1).expand(0.001)) - RenderUtils.drawCuboidOutline(new Cuboid6(d1, 0, d1, d2, t, d2).expand(-0.001)) - glPopMatrix() - glDepthMask(true) - glEnable(GL_TEXTURE_2D) - glDisable(GL_BLEND) - return true - } -} - -class HollowMicroblock(shape$: Byte = 0, material$: Int = 0) extends CommonMicroblock(shape$, material$) with TFacePart with TNormalOcclusion -{ - def this(size: Int, shape: Int, material: Int) = this((size << 4 | shape).toByte, material) - - def microClass = HollowMicroClass - - def getBounds: Cuboid6 = FaceMicroClass.aBounds(shape) - - override def getPartialOcclusionBoxes = HollowMicroClass.pBoxes(shape) - - def getHollowSize = tile match { - case null => 8 - case _ => tile.partMap(6) match { - case part: ISidedHollowConnect => part.getHollowSize(getSlot) - case _ => 8 - } - } - - def getOcclusionBoxes = { - val size = getHollowSize - val c = HollowMicroClass.occBounds(shape) - val d1 = 0.5 - size / 32D - val d2 = 0.5 + size / 32D - val x1 = c.min.x - val x2 = c.max.x - val y1 = c.min.y - val y2 = c.max.y - val z1 = c.min.z - val z2 = c.max.z - - getSlot match { - case 0 | 1 => - Seq(new Cuboid6(d2, y1, d1, x2, y2, d2), - new Cuboid6(x1, y1, d1, d1, y2, d2), - new Cuboid6(x1, y1, d2, x2, y2, z2), - new Cuboid6(x1, y1, z1, x2, y2, d1)) - case 2 | 3 => - Seq(new Cuboid6(d1, d2, z1, d2, y2, z2), - new Cuboid6(d1, y1, z1, d2, d1, z2), - new Cuboid6(d2, y1, z1, x2, y2, z2), - new Cuboid6(x1, y1, z1, d1, y2, z2)) - case 4 | 5 => - Seq(new Cuboid6(x1, d1, d2, x2, d2, z2), - new Cuboid6(x1, d1, z1, x2, d2, d1), - new Cuboid6(x1, d2, z1, x2, y2, z2), - new Cuboid6(x1, y1, z1, x2, d1, z2)) - } - } - - override def getCollisionBoxes = { - val size = getHollowSize - val d1 = 0.5 - size / 32D - val d2 = 0.5 + size / 32D - val t = (shape >> 4) / 8D - - val tr = sideRotations(shape & 0xF).at(center) - Seq(new Cuboid6(0, 0, 0, 1, t, d1), - new Cuboid6(0, 0, d2, 1, t, 1), - new Cuboid6(0, 0, d1, d1, t, d2), - new Cuboid6(d2, 0, d1, 1, t, d2)) - .map(c => c.apply(tr)) - } - - override def getSubParts = getCollisionBoxes.map(c => new IndexedCuboid6(0, c)) - - override def allowCompleteOcclusion = true - - override def solid(side: Int) = false - - override def redstoneConductionMap = 0x10 -} \ No newline at end of file diff --git a/codechicken/microblock/IMicroMaterialRender.scala b/codechicken/microblock/IMicroMaterialRender.scala deleted file mode 100644 index 9fb20a9..0000000 --- a/codechicken/microblock/IMicroMaterialRender.scala +++ /dev/null @@ -1,22 +0,0 @@ -package codechicken.microblock - -import codechicken.lib.vec.Cuboid6 -import net.minecraft.world.World - -/** - * Wrapper class blocks/tiles/parts wanting to use the micro material system to render part of their models. - */ -trait IMicroMaterialRender { - /** - * May be null for inventory rendering. - */ - def world:World - def x:Int - def y:Int - def z:Int - - /** - * Return the bounds of the part for texture mapping side decals like grass - */ - def getRenderBounds:Cuboid6 -} \ No newline at end of file diff --git a/codechicken/microblock/ISidedHollowConnect.scala b/codechicken/microblock/ISidedHollowConnect.scala deleted file mode 100644 index 6c6d3b1..0000000 --- a/codechicken/microblock/ISidedHollowConnect.scala +++ /dev/null @@ -1,13 +0,0 @@ -package codechicken.microblock - -/** - * Implement this on center parts that connect through hollow covers to have the covers render their hollows to fit the connection size - */ -trait ISidedHollowConnect -{ - /** - * @param side The side of the block on which the cover resides - * @return The size (width and height) of the connection in pixels. Must be be less than 12 and more than 0 - */ - def getHollowSize(side:Int):Int -} \ No newline at end of file diff --git a/codechicken/microblock/ItemMicroPart.scala b/codechicken/microblock/ItemMicroPart.scala deleted file mode 100644 index 545ec8b..0000000 --- a/codechicken/microblock/ItemMicroPart.scala +++ /dev/null @@ -1,169 +0,0 @@ -package codechicken.microblock - -import net.minecraft.item.Item -import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import ItemMicroPart._ -import net.minecraftforge.client.IItemRenderer -import net.minecraftforge.client.IItemRenderer.ItemRenderType -import net.minecraftforge.client.IItemRenderer.ItemRendererHelper -import org.lwjgl.opengl.GL11 -import codechicken.microblock.MicroMaterialRegistry.IMicroMaterial -import java.util.List -import net.minecraft.creativetab.CreativeTabs -import codechicken.microblock.MicroblockClassRegistry._ -import codechicken.lib.render.CCRenderState -import net.minecraft.client.renderer.texture.IIconRegister -import codechicken.microblock.handler.MicroblockProxy -import net.minecraft.util.{StatCollector, MovingObjectPosition} -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.world.World -import codechicken.lib.raytracer.RayTracer -import codechicken.lib.vec.Vector3 -import codechicken.lib.render.TextureUtils -import net.minecraft.util.MovingObjectPosition.MovingObjectType - -class ItemMicroPart extends Item -{ - setUnlocalizedName("microblock") - setHasSubtypes(true) - - override def getItemStackDisplayName(stack:ItemStack):String = - { - val material = getMaterial(stack) - val mcrClass = MicroblockClassRegistry.getMicroClass(stack.getItemDamage) - val size = stack.getItemDamage&0xFF - if(material == null || mcrClass == null) - return "Unnamed" - - return StatCollector.translateToLocalFormatted(mcrClass.getName+"."+size+".name", material.getLocalizedName) - } - - override def getSubItems(item:Item, tab:CreativeTabs, list$:List[_]) - { - val list = list$.asInstanceOf[List[ItemStack]] - for(classId <- 0 until classes.length) - { - val mcrClass = classes(classId) - if(mcrClass != null) - for(size <- Seq(1, 2, 4)) - MicroMaterialRegistry.getIdMap.foreach(e => list.add(create(classId<<8|size, e._1))) - } - } - - override def registerIcons(register:IIconRegister){} - - override def onItemUse(item:ItemStack, player:EntityPlayer, world:World, x:Int, y:Int, z:Int, s:Int, hitX:Float, hitY:Float, hitZ:Float):Boolean = - { - val material = getMaterialID(item) - val mcrClass = MicroblockClassRegistry.getMicroClass(item.getItemDamage) - val size = item.getItemDamage&0xFF - if(material < 0 || mcrClass == null) - return false - - val hit = RayTracer.retraceBlock(world, player, x, y, z) - if(hit != null && hit.typeOfHit == MovingObjectType.BLOCK) - { - val placement = MicroblockPlacement(player, hit, size, material, !player.capabilities.isCreativeMode, mcrClass.placementProperties) - if(placement == null) - return false - - if(!world.isRemote) - { - placement.place(world, player, item) - if(!player.capabilities.isCreativeMode) - placement.consume(world, player, item) - - val sound = MicroMaterialRegistry.getMaterial(material).getSound - if(sound != null) - world.playSoundEffect(placement.pos.x + 0.5D, placement.pos.y + 0.5D, placement.pos.z + 0.5D, sound.func_150496_b, (sound.getVolume + 1.0F) / 2.0F, sound.getPitch * 0.8F) - } - - return true - } - - return false - } -} - -object ItemMicroPart -{ - def checkTagCompound(stack:ItemStack) - { - if(!stack.hasTagCompound) - stack.setTagCompound(new NBTTagCompound()) - } - - def create(damage:Int, material:Int):ItemStack = create(damage, MicroMaterialRegistry.materialName(material)) - - def create(damage:Int, material:String):ItemStack = create(1, damage, material) - - def create(amount:Int, damage:Int, material:String):ItemStack = - { - val stack = new ItemStack(MicroblockProxy.itemMicro, amount, damage) - checkTagCompound(stack) - stack.getTagCompound.setString("mat", material) - return stack - } - - def getMaterial(stack:ItemStack):IMicroMaterial = - { - checkTagCompound(stack) - if(!stack.getTagCompound.hasKey("mat")) - return null - - return MicroMaterialRegistry.getMaterial(stack.getTagCompound.getString("mat")) - } - - def getMaterialID(stack:ItemStack):Int = - { - checkTagCompound(stack) - if(!stack.getTagCompound.hasKey("mat")) - return 0 - - return MicroMaterialRegistry.materialID(stack.getTagCompound.getString("mat")) - } -} - -object ItemMicroPartRenderer extends IItemRenderer -{ - def handleRenderType(item:ItemStack, t:ItemRenderType) = true - - def shouldUseRenderHelper(t:ItemRenderType, item:ItemStack, helper:ItemRendererHelper) = true - - def renderItem(t:ItemRenderType, item:ItemStack, data:Object*) - { - val material = getMaterial(item) - val mcrClass = MicroblockClassRegistry.getMicroClass(item.getItemDamage) - val size = item.getItemDamage&0xFF - if(material == null || mcrClass == null) - return - - GL11.glPushMatrix() - if(t == ItemRenderType.ENTITY) - GL11.glScaled(0.5, 0.5, 0.5) - if(t == ItemRenderType.INVENTORY || t == ItemRenderType.ENTITY) - GL11.glTranslatef(-0.5F, -0.5F, -0.5F) - - TextureUtils.bindAtlas(0) - CCRenderState.reset() - CCRenderState.useNormals = true - CCRenderState.pullLightmap() - CCRenderState.startDrawing() - val part = mcrClass.create(size, mcrClass.itemSlot, getMaterialID(item), true).asInstanceOf[MicroblockClient] - part.render(new Vector3(0.5, 0.5, 0.5).subtract(part.getBounds.center), -1) - CCRenderState.draw() - GL11.glPopMatrix() - } - - def renderHighlight(player:EntityPlayer, stack:ItemStack, hit:MovingObjectPosition):Boolean = - { - val material = getMaterialID(stack) - val mcrClass = MicroblockClassRegistry.getMicroClass(stack.getItemDamage) - val size = stack.getItemDamage&0xFF - if(material < 0 || mcrClass == null) - return false - - return MicroMaterialRegistry.renderHighlight(player, hit, mcrClass, size, material) - } -} \ No newline at end of file diff --git a/codechicken/microblock/ItemSaw.scala b/codechicken/microblock/ItemSaw.scala deleted file mode 100644 index e879c73..0000000 --- a/codechicken/microblock/ItemSaw.scala +++ /dev/null @@ -1,98 +0,0 @@ -package codechicken.microblock - -import net.minecraft.item.Item -import codechicken.lib.config.ConfigTag -import codechicken.microblock.handler.MicroblockProxy._ -import net.minecraft.item.ItemStack -import net.minecraftforge.client.IItemRenderer -import codechicken.lib.render.CCModel -import net.minecraftforge.client.IItemRenderer.ItemRenderType -import net.minecraftforge.client.IItemRenderer.ItemRendererHelper -import codechicken.lib.vec.SwapYZ -import codechicken.lib.render.CCRenderState -import codechicken.lib.vec.TransformationList -import codechicken.lib.vec.Translation -import codechicken.lib.vec.Scale -import codechicken.lib.vec.Rotation -import org.lwjgl.opengl.GL11 -import ItemRenderType._ -import codechicken.lib.math.MathHelper._ -import net.minecraft.util.ResourceLocation -import net.minecraft.client.renderer.texture.IIconRegister -import codechicken.lib.render.uv.UVTranslation - -/** - * Interface for items that are 'saws' - */ -trait Saw extends Item -{ - /** - * The maximum harvest level that some version of this saw is capable of cutting - */ - def getMaxCuttingStrength:Int = getCuttingStrength(new ItemStack(this)) - /** - * The harvest level this saw is capable of cutting - */ - def getCuttingStrength(item:ItemStack):Int -} - -class ItemSaw(sawTag:ConfigTag, val harvestLevel:Int) extends Item with Saw -{ - { - val maxDamage = sawTag.getTag("durability").getIntValue(1< 0) - setMaxDamage(maxDamage) - setNoRepair() - } - - override def hasContainerItem = true - - override def getContainerItem(stack:ItemStack) = - if(isDamageable) - new ItemStack(stack.getItem, 1, stack.getItemDamage+1) - else - stack - - override def doesContainerItemLeaveCraftingGrid(stack:ItemStack) = false - - def getCuttingStrength(item:ItemStack) = harvestLevel - - override def registerIcons(register:IIconRegister){} -} - -object ItemSawRenderer extends IItemRenderer -{ - val models = CCModel.parseObjModels(new ResourceLocation("microblock", "models/saw.obj"), 7, new SwapYZ()) - val handle = models.get("Handle") - val holder = models.get("BladeSupport") - val blade = models.get("Blade") - - def handleRenderType(item:ItemStack, renderType:ItemRenderType) = true - - def shouldUseRenderHelper(renderType:ItemRenderType, item:ItemStack, helper:ItemRendererHelper) = true - - def renderItem(renderType:ItemRenderType, item:ItemStack, data:Object*) - { - val t = renderType match { - case INVENTORY => new TransformationList(new Scale(1.8), new Translation(0, 0, -0.6), new Rotation(-pi/4, 1, 0, 0), new Rotation(pi*3/4, 0, 1, 0)) - case ENTITY => new TransformationList(new Scale(1), new Translation(0, 0, -0.25), new Rotation(-pi/4, 1, 0, 0)) - case EQUIPPED_FIRST_PERSON => new TransformationList(new Scale(1.5), new Rotation(-pi/3, 1, 0, 0), new Rotation(pi*3/4, 0, 1, 0), new Translation(0.5, 0.5, 0.5)) - case EQUIPPED => new TransformationList(new Scale(1.5), new Rotation(-pi/5, 1, 0, 0), new Rotation(-pi*3/4, 0, 1, 0), new Translation(0.75, 0.5, 0.75)) - case _ => return - } - - CCRenderState.reset() - CCRenderState.useNormals = true - CCRenderState.pullLightmap() - CCRenderState.changeTexture("microblock:textures/items/saw.png") - CCRenderState.startDrawing() - handle.render(t) - holder.render(t) - CCRenderState.draw() - GL11.glDisable(GL11.GL_CULL_FACE) - CCRenderState.startDrawing() - blade.render(t, new UVTranslation(0, (item.getItem.asInstanceOf[Saw].getCuttingStrength(item)-1)*4/64D)) - CCRenderState.draw() - GL11.glEnable(GL11.GL_CULL_FACE) - } -} \ No newline at end of file diff --git a/codechicken/microblock/MicroMaterialRegistry.scala b/codechicken/microblock/MicroMaterialRegistry.scala deleted file mode 100644 index 9f39687..0000000 --- a/codechicken/microblock/MicroMaterialRegistry.scala +++ /dev/null @@ -1,236 +0,0 @@ -package codechicken.microblock - -import codechicken.multipart.IDWriter -import codechicken.lib.packet.PacketCustom -import scala.collection.mutable.HashMap -import codechicken.lib.data.MCDataOutput -import codechicken.lib.data.MCDataInput -import codechicken.multipart.MultiPartRegistry -import cpw.mods.fml.relauncher.SideOnly -import cpw.mods.fml.relauncher.Side -import codechicken.lib.vec.{Cuboid6, Vector3} -import net.minecraft.util.IIcon -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.item.{Item, ItemStack} -import scala.collection.mutable.ListBuffer -import net.minecraft.util.MovingObjectPosition -import net.minecraft.entity.Entity -import scala.collection.JavaConversions._ -import java.util.{Iterator => JIterator} -import net.minecraft.block.Block.SoundType - -object MicroMaterialRegistry -{ - - /** - * Interface for defining a micro material - */ - trait IMicroMaterial - { - /** - * The icon to be used for breaking particles on side - */ - @SideOnly(Side.CLIENT) - def getBreakingIcon(side: Int): IIcon - - /** - * Callback to load icons from the underlying block/etc - */ - @SideOnly(Side.CLIENT) - def loadIcons() {} - - /** - * This function must configure and use the CCRenderState pipeline to draw from the current vertex source. - * CCRenderState.lightMatrix will be set. - * @param pass The current render pass, -1 for inventory rendering - * @param bounds The cuboid bounds of the face being rendered - */ - @SideOnly(Side.CLIENT) - def renderMicroFace(pos: Vector3, pass: Int, bounds: Cuboid6) - - /** - * Get the render pass for which this material renders in. - */ - @SideOnly(Side.CLIENT) - def canRenderInPass(pass: Int) = pass == 0 - - /** - * Return true if this material is not opaque (glass, ice). - */ - def isTransparent: Boolean - - /** - * Return the light level emitted by this material (glowstone) - */ - def getLightValue: Int - - /** - * Return the strength of this material - */ - def getStrength(player: EntityPlayer): Float - - /** - * Return the localised name of this material (normally the block name) - */ - def getLocalizedName: String - - /** - * Get the item that this material is cut from (full block -> slabs) - */ - def getItem: ItemStack - - /** - * Get the strength of saw requried to cut this material - */ - def getCutterStrength: Int - - /** - * Get the breaking/walking sound - */ - def getSound: SoundType - - /** - * Return true if this material is solid and opaque (can run wires on etc) - */ - def isSolid = !isTransparent - - /** - * Get the explosion resistance of this part to an explosion caused by entity - */ - def explosionResistance(entity: Entity): Float - } - - /** - * Interface for overriding the default micro placement highlight handler to show the effect of placement on a certain block/part - */ - trait IMicroHighlightRenderer - { - /** - * Return true if a custom highlight was rendered and the default should be skipped - */ - def renderHighlight(player: EntityPlayer, hit: MovingObjectPosition, mcrClass: MicroblockClass, size: Int, material: Int): Boolean - } - - private val typeMap = HashMap[String, IMicroMaterial]() - private val nameMap = HashMap[String, Int]() - private var idMap: Array[(String, IMicroMaterial)] = _ - private val idWriter = new IDWriter - - private val highlightRenderers = ListBuffer[IMicroHighlightRenderer]() - private var maxCuttingStrength: Int = _ - - /** - * Register a micro material with unique identifier name - */ - def registerMaterial(material: IMicroMaterial, name: String) { - if (MultiPartRegistry.loaded) - throw new IllegalStateException("You must register your materials in the init methods.") - - if (typeMap.contains(name)) { - System.err.println("Material with id " + name + " is already registered.") - return - } - - System.out.println("Registered micro material: " + name) - - typeMap.put(name, material) - } - - /** - * Replace a micro material with unique identifier name - */ - def replaceMaterial(material: IMicroMaterial, name: String) { - if (MultiPartRegistry.loaded) - throw new IllegalStateException("You must register your materials in the init methods.") - - if (typeMap.remove(name).isEmpty) - System.err.println("Material with id " + name + " is was not registered.") - - System.out.println("Replaced micro material: " + name) - - typeMap.put(name, material) - } - - /** - * Registers a highlight renderer - */ - def registerHighlightRenderer(handler: IMicroHighlightRenderer) { - highlightRenderers += handler - } - - private[microblock] def setupIDMap() { - idMap = typeMap.toList.sortBy(_._1).toArray - idWriter.setMax(idMap.length) - nameMap.clear() - for (i <- 0 until idMap.length) - nameMap.put(idMap(i)._1, i) - } - - private[microblock] def calcMaxCuttingStrength() { - val it = Item.itemRegistry.iterator.asInstanceOf[JIterator[Item]] - maxCuttingStrength = it.flatMap { - case saw: Saw => Some(saw.getMaxCuttingStrength) - case _ => None - }.max - } - - private[microblock] def loadIcons() { - MicroMaterialRegistry.getIdMap.foreach(e => e._2.loadIcons()) - } - - def getMaxCuttingStrength = maxCuttingStrength - - def writeIDMap(packet: PacketCustom) { - packet.writeInt(idMap.size) - idMap.foreach(e => packet.writeString(e._1)) - } - - def readIDMap(packet: PacketCustom): Seq[String] = { - val k = packet.readInt() - idWriter.setMax(k) - idMap = new Array(k) - nameMap.clear() - val missing = ListBuffer[String]() - for (i <- 0 until k) { - val s = packet.readString() - val v = typeMap.get(s) - if (v.isEmpty) - missing += s - else { - idMap(i) = (s, v.get) - nameMap.put(s, i) - } - } - return missing - } - - def writeMaterialID(data: MCDataOutput, id: Int) { - idWriter.write(data, id) - } - - def readMaterialID(data: MCDataInput) = idWriter.read(data) - - def materialName(id: Int) = idMap(id)._1 - - def materialID(name: String) = nameMap.get(name) match { - case Some(v) => v - case None => - System.err.println("Missing mapping for part with ID: " + name) - 0 - } - - def getMaterial(name: String) = typeMap.getOrElse(name, null) - - def getMaterial(id: Int) = idMap(id)._2 - - def getIdMap = idMap - - def renderHighlight(player: EntityPlayer, hit: MovingObjectPosition, mcrClass: MicroblockClass, size: Int, material: Int): Boolean = { - val overridden = highlightRenderers.find(_.renderHighlight(player, hit, mcrClass, size, material)) - if (overridden.isDefined) - return true - - MicroblockRender.renderHighlight(player, hit, mcrClass, size, material) - return true - } -} \ No newline at end of file diff --git a/codechicken/microblock/MicroRecipe.scala b/codechicken/microblock/MicroRecipe.scala deleted file mode 100644 index cd70851..0000000 --- a/codechicken/microblock/MicroRecipe.scala +++ /dev/null @@ -1,228 +0,0 @@ -package codechicken.microblock - -import net.minecraft.item.crafting.IRecipe -import net.minecraft.world.World -import net.minecraft.inventory.InventoryCrafting -import net.minecraft.item.ItemStack -import codechicken.microblock.handler.MicroblockProxy._ -import net.minecraftforge.oredict.RecipeSorter - -object MicroRecipe extends IRecipe -{ - RecipeSorter.register("fmp:micro", getClass, RecipeSorter.Category.SHAPED, "after:forge:shapelessore") - - def getRecipeOutput = new ItemStack(sawStone) - - def getRecipeSize = 9 - - def matches(icraft:InventoryCrafting, world:World) = getCraftingResult(icraft) != null - - def getCraftingResult(icraft:InventoryCrafting):ItemStack = - { - var res = getHollowResult(icraft) - if(res != null) return res - res = getGluingResult(icraft) - if(res != null) return res - res = getThinningResult(icraft) - if(res != null) return res - res = getSplittingResult(icraft) - if(res != null) return res - res = getHollowFillResult(icraft) - return res - } - - def create(amount:Int, mcrClass:Int, size:Int, material:Int):ItemStack = - { - if(size == 8) - { - val item = MicroMaterialRegistry.getMaterial(material).getItem.copy - item.stackSize = amount - return item - } - return ItemMicroPart.create(amount, mcrClass<<8|size, MicroMaterialRegistry.materialName(material)) - } - - def microMaterial(item:ItemStack) = - if(item.getItem == itemMicro) - ItemMicroPart.getMaterialID(item) - else - findMaterial(item) - - def microClass(item:ItemStack) = - if(item.getItem == itemMicro) - item.getItemDamage >> 8 - else - 0 - - def microSize(item:ItemStack) = - if(item.getItem == itemMicro) - item.getItemDamage & 0xFF - else - 8 - - def getHollowResult(icraft:InventoryCrafting):ItemStack = - { - if(icraft.getStackInRowAndColumn(1, 1) != null) return null - - val first = icraft.getStackInRowAndColumn(0, 0) - if(first == null || first.getItem != itemMicro || microClass(first) != 0) return null - val size = microSize(first) - val material = microMaterial(first) - - for(i <- 1 to 8 if i != 4) - { - val item = icraft.getStackInSlot(i) - if(item == null || item.getItem != itemMicro || - microMaterial(item) != material || item.getItemDamage != first.getItemDamage) - return null - } - return create(8, 1, size, material) - } - - def getGluingResult(icraft:InventoryCrafting):ItemStack = - { - var size = 0 - var count = 0 - var smallest = 0 - var mcrClass = 0 - var material = 0 - for(i <- 0 until 9) - { - val item = icraft.getStackInSlot(i) - if(item != null) - { - if(item.getItem != itemMicro) return null - if(count == 0) - { - size = microSize(item) - mcrClass = microClass(item) - material = microMaterial(item) - count = 1 - smallest = size - } - else if(microClass(item) != mcrClass || microMaterial(item) != material) return null - else if(mcrClass >= 2 && microSize(item) != smallest) return null - else - { - smallest= Math.min(smallest, microSize(item)) - count+=1 - size+=microSize(item) - } - } - } - - if(count <= 1) return null - - val matName = MicroMaterialRegistry.materialName(material) - mcrClass match { - case 3 => count match { - case 2 => create(1, 0, smallest, material) - case _ => null - } - case 2 => count match { - case 2 => create(1, 3, smallest, material) - case 4 => create(1, 0, smallest, material) - case _ => null - } - case 1|0 => - val base = Seq(1, 2, 4).find(s => (s&size) != 0) - if(base.isEmpty) - create(size/8, 0, 8, material) - else if(base.get <= smallest) - null - else - create(size/base.get, mcrClass, base.get, material) - case _ => null - } - } - - def getSaw(icraft:InventoryCrafting):(Saw, Int, Int) = - { - for(r <- 0 until 3) - for(c <- 0 until 3) - { - val item = icraft.getStackInRowAndColumn(c, r) - if(item != null && item.getItem.isInstanceOf[Saw]) - return (item.getItem.asInstanceOf[Saw], r, c) - } - return (null, 0, 0) - } - - def canCut(saw:Saw, sawItem:ItemStack, material:Int):Boolean = { - val sawStrength = saw.getCuttingStrength(sawItem) - val matStrength = MicroMaterialRegistry.getMaterial(material).getCutterStrength - return sawStrength >= matStrength || sawStrength == MicroMaterialRegistry.getMaxCuttingStrength - } - - def getThinningResult(icraft:InventoryCrafting):ItemStack = - { - val (saw, row, col) = getSaw(icraft) - if(saw == null) - return null - - val item = icraft.getStackInRowAndColumn(col, row+1) - if(item == null) - return null - - val size = microSize(item) - val material = microMaterial(item) - val mcrClass = microClass(item) - if(size == 1 || material < 0 || !canCut(saw, icraft.getStackInRowAndColumn(col, row), material)) - return null - - for(r <- 0 until 3) - for(c <- 0 until 3) - if((c != col || r != row && r != row+1) && - icraft.getStackInRowAndColumn(c, r) != null) - return null - - return create(2, mcrClass, size/2, material) - } - - def findMaterial(item:ItemStack):Int = - MicroMaterialRegistry.getIdMap.find{m => val mitem = m._2.getItem - item.getItem == mitem.getItem && - item.getItemDamage == mitem.getItemDamage && - ItemStack.areItemStackTagsEqual(item, mitem)} match { - case None => -1 - case Some((name, m)) => MicroMaterialRegistry.materialID(name) - } - - val splitMap = Map(0 -> 3, 1 -> 3, 3 -> 2) - def getSplittingResult(icraft:InventoryCrafting):ItemStack = - { - val (saw, row, col) = getSaw(icraft) - if(saw == null) return null - val item = icraft.getStackInRowAndColumn(col+1, row) - if(item == null || item.getItem != itemMicro) return null - val mcrClass = microClass(item) - val material = microMaterial(item) - if(!canCut(saw, icraft.getStackInRowAndColumn(col, row), material)) return null - val split = splitMap.get(mcrClass) - if(split.isEmpty)return null - - for(r <- 0 until 3) - for(c <- 0 until 3) - if((r != row || c != col && c != col+1) && - icraft.getStackInRowAndColumn(c, r) != null) - return null - - return create(2, split.get, microSize(item), material) - } - - def getHollowFillResult(icraft:InventoryCrafting):ItemStack = - { - var cover:ItemStack = null - for(i <- 0 until 9) - { - val item = icraft.getStackInSlot(i) - if(item != null) - { - if(item.getItem != itemMicro || cover != null || microClass(item) != 1) return null - else cover = item - } - } - if(cover == null) return null - return create(1, 0, microSize(cover), microMaterial(cover)) - } -} \ No newline at end of file diff --git a/codechicken/microblock/MicroblockClass.scala b/codechicken/microblock/MicroblockClass.scala deleted file mode 100644 index 78d9cd6..0000000 --- a/codechicken/microblock/MicroblockClass.scala +++ /dev/null @@ -1,20 +0,0 @@ -package codechicken.microblock - -trait MicroblockClass -{ - var classID:Int = _ - - def itemSlot = 3 - - def getName:String - - def create(client:Boolean):CommonMicroblock - - def create(size:Int, slot:Int, material:Int, client:Boolean):CommonMicroblock - - def placementProperties:PlacementProperties - - def register(id:Int) = MicroblockClassRegistry.registerMicroClass(this, id) - - def getResistanceFactor:Float -} \ No newline at end of file diff --git a/codechicken/microblock/MicroblockClassRegistry.scala b/codechicken/microblock/MicroblockClassRegistry.scala deleted file mode 100644 index 984e447..0000000 --- a/codechicken/microblock/MicroblockClassRegistry.scala +++ /dev/null @@ -1,20 +0,0 @@ -package codechicken.microblock - -import codechicken.multipart.MultiPartRegistry - -object MicroblockClassRegistry -{ - val classes = new Array[MicroblockClass](256) - - def getMicroClass(modelId:Int) = classes(modelId>>8) - - def registerMicroClass(mcrClass:MicroblockClass, id:Int) - { - if(classes(id) != null) - throw new IllegalArgumentException("Microblock class id "+id+" is already taken by "+classes(id).getName+" when adding "+mcrClass.getName) - - classes(id) = mcrClass - mcrClass.classID = id - MultiPartRegistry.registerParts((_, c:Boolean) => mcrClass.create(c), mcrClass.getName) - } -} \ No newline at end of file diff --git a/codechicken/microblock/MicroblockPlacement.scala b/codechicken/microblock/MicroblockPlacement.scala deleted file mode 100644 index 63620b1..0000000 --- a/codechicken/microblock/MicroblockPlacement.scala +++ /dev/null @@ -1,175 +0,0 @@ -package codechicken.microblock - -import net.minecraft.world.World -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.util.MovingObjectPosition -import codechicken.lib.vec.Vector3 -import codechicken.lib.vec.BlockCoord -import codechicken.lib.vec.Rotation -import codechicken.multipart.ControlKeyModifer._ -import net.minecraft.item.ItemStack -import codechicken.multipart.TileMultipart -import codechicken.lib.raytracer.ExtendedMOP - -abstract class ExecutablePlacement(val pos:BlockCoord, val part:Microblock) -{ - def place(world:World, player:EntityPlayer, item:ItemStack) - def consume(world:World, player:EntityPlayer, item:ItemStack) -} - -class AdditionPlacement($pos:BlockCoord, $part:Microblock) extends ExecutablePlacement($pos, $part) -{ - def place(world:World, player:EntityPlayer, item:ItemStack) - { - TileMultipart.addPart(world, pos, part) - } - - def consume(world:World, player:EntityPlayer, item:ItemStack) - { - item.stackSize-=1 - } -} - -class ExpandingPlacement($pos:BlockCoord, $part:Microblock, opart:Microblock) extends ExecutablePlacement($pos, $part) -{ - def place(world:World, player:EntityPlayer, item:ItemStack) - { - opart.shape = part.shape - opart.tile.notifyPartChange(opart) - opart.sendDescUpdate() - } - - def consume(world:World, player:EntityPlayer, item:ItemStack) - { - item.stackSize-=1 - } -} - -abstract class PlacementProperties -{ - def opposite(slot:Int, side:Int):Int - - def sneakOpposite(slot:Int, side:Int) = true - - def expand(slot:Int, side:Int) = true - - def microClass:MicroblockClass - - def placementGrid:PlacementGrid - - def customPlacement(pmt:MicroblockPlacement):ExecutablePlacement = null -} - -object MicroblockPlacement -{ - def apply(player:EntityPlayer, hit:MovingObjectPosition, size:Int, material:Int, checkMaterial:Boolean, pp:PlacementProperties):ExecutablePlacement = - new MicroblockPlacement(player, hit, size, material, checkMaterial, pp)() -} - -class MicroblockPlacement(val player:EntityPlayer, val hit:MovingObjectPosition, val size:Int, val material:Int, val checkMaterial:Boolean, val pp:PlacementProperties) -{ - val world = player.worldObj - val mcrClass = pp.microClass - val pos = new BlockCoord(hit.blockX, hit.blockY, hit.blockZ) - val vhit = new Vector3(hit.hitVec).add(-pos.x, -pos.y, -pos.z) - val gtile = TileMultipart.getOrConvertTile2(world, pos) - val htile = gtile._1 - val slot = pp.placementGrid.getHitSlot(vhit, hit.sideHit) - val oslot = pp.opposite(slot, hit.sideHit) - - val d = getHitDepth(vhit, hit.sideHit) - val useOppMod = pp.sneakOpposite(slot, hit.sideHit) - val oppMod = player.isControlDown - val internal = d < 1 && htile != null - val doExpand = internal && !gtile._2 && !player.isSneaking && !(oppMod && useOppMod) && pp.expand(slot, hit.sideHit) - val side = hit.sideHit - - def apply():ExecutablePlacement = - { - val customPlacement = pp.customPlacement(this) - if(customPlacement != null) - return customPlacement - - if(slot < 0) - return null - - if(doExpand) - { - val hpart = htile.partList(ExtendedMOP.getData[(Int, _)](hit)._1) - if(hpart.getType == mcrClass.getName) - { - val mpart = hpart.asInstanceOf[CommonMicroblock] - if(mpart.material == material && mpart.getSize + size < 8) - return expand(mpart) - } - } - - if(internal) - { - if(!useOppMod) - return internalPlacement(htile, slot) - if((1-d)*8 < size) - { - if(htile.canAddPart(create(1, oslot, material))) - return externalPlacement(slot) - } - if(d < 0.5) - { - val ret = internalPlacement(htile, slot) - if(ret != null && !oppMod) - return ret - if(ret != null && oppMod || ret == null && !oppMod) - return internalPlacement(htile, oslot) - //sneaking - if(internalPlacement(htile, oslot) != null) - return externalPlacement(slot) - return null - } - val ret = internalPlacement(htile, oslot) - if(!oppMod) - return ret - if(ret != null) - return externalPlacement(slot) - return null - } - val ret = externalPlacement(slot) - if(ret != null && oppMod && useOppMod) - return externalPlacement(oslot) - return ret - } - - def expand(mpart:CommonMicroblock):ExecutablePlacement = expand(mpart, create(mpart.getSize+size, mpart.getSlot, mpart.material)) - - def expand(mpart:Microblock, npart:Microblock):ExecutablePlacement = - { - val pos = new BlockCoord(mpart.tile) - if(TileMultipart.checkNoEntityCollision(world, pos, npart) && mpart.tile.canReplacePart(mpart, npart)) - return new ExpandingPlacement(pos, npart, mpart) - return null - } - - def internalPlacement(htile:TileMultipart, slot:Int):ExecutablePlacement = internalPlacement(htile, create(size, slot, material)) - - def internalPlacement(htile:TileMultipart, npart:Microblock):ExecutablePlacement = - { - val pos = new BlockCoord(htile) - if(TileMultipart.checkNoEntityCollision(world, pos, npart) && htile.canAddPart(npart)) - return new AdditionPlacement(pos, npart) - return null - } - - def externalPlacement(slot:Int):ExecutablePlacement = externalPlacement(create(size, slot, material)) - - def externalPlacement(npart:Microblock):ExecutablePlacement = - { - val pos = this.pos.copy().offset(side) - if(TileMultipart.canPlacePart(world, pos, npart)) - return new AdditionPlacement(pos, npart) - return null - } - - def getHitDepth(vhit:Vector3, side:Int):Double = - vhit.copy.scalarProject(Rotation.axes(side)) + (side%2^1) - - def create(size:Int, slot:Int, material:Int) = mcrClass.create(size, slot, material, world.isRemote) -} \ No newline at end of file diff --git a/codechicken/microblock/PlacementGrids.scala b/codechicken/microblock/PlacementGrids.scala deleted file mode 100644 index f25cf08..0000000 --- a/codechicken/microblock/PlacementGrids.scala +++ /dev/null @@ -1,164 +0,0 @@ -package codechicken.microblock - -import codechicken.lib.vec.Vector3 -import org.lwjgl.opengl.GL11 -import codechicken.lib.vec.BlockCoord -import codechicken.lib.vec.Rotation -import Rotation._ - -trait PlacementGrid -{ - def getHitSlot(vhit:Vector3, side:Int):Int - - def render(hit:Vector3, side:Int) - - def glTransformFace(hit:Vector3, side:Int) - { - val pos = new BlockCoord(hit) - GL11.glPushMatrix() - GL11.glTranslated(pos.x+0.5, pos.y+0.5, pos.z+0.5) - sideRotations(side).glApply() - val rhit = new Vector3(pos.x+0.5, pos.y+0.5, pos.z+0.5).subtract(hit).apply(sideRotations(side^1).inverse) - GL11.glTranslated(0, rhit.y-0.002, 0) - } -} - -class FaceEdgeGrid(size:Double) extends PlacementGrid -{ - def render(hit:Vector3, side:Int) - { - glTransformFace(hit, side) - - GL11.glLineWidth(2) - GL11.glColor4f(0, 0, 0, 1) - GL11.glBegin(GL11.GL_LINES) - GL11.glVertex3d(-0.5, 0,-0.5) - GL11.glVertex3d(-0.5, 0, 0.5) - - GL11.glVertex3d(-0.5, 0, 0.5) - GL11.glVertex3d( 0.5, 0, 0.5) - - GL11.glVertex3d( 0.5, 0, 0.5) - GL11.glVertex3d( 0.5, 0,-0.5) - - GL11.glVertex3d( 0.5, 0,-0.5) - GL11.glVertex3d(-0.5, 0,-0.5) - - GL11.glVertex3d(0.5, 0, 0.5) - GL11.glVertex3d(size, 0, size) - - GL11.glVertex3d(-0.5, 0, 0.5) - GL11.glVertex3d(-size, 0, size) - - GL11.glVertex3d(0.5, 0, -0.5) - GL11.glVertex3d(size, 0, -size) - - GL11.glVertex3d(-0.5, 0, -0.5) - GL11.glVertex3d(-size, 0, -size) - - GL11.glVertex3d(-size, 0,-size) - GL11.glVertex3d(-size, 0, size) - - GL11.glVertex3d(-size, 0, size) - GL11.glVertex3d( size, 0, size) - - GL11.glVertex3d( size, 0, size) - GL11.glVertex3d( size, 0,-size) - - GL11.glVertex3d( size, 0,-size) - GL11.glVertex3d(-size, 0,-size) - GL11.glEnd() - GL11.glPopMatrix() - } - - def getHitSlot(vhit:Vector3, side:Int):Int = - { - val s1 = (side+2)%6 - val s2 = (side+4)%6 - val u = vhit.copy().add(-0.5, -0.5, -0.5).scalarProject(Rotation.axes(s1)) - val v = vhit.copy().add(-0.5, -0.5, -0.5).scalarProject(Rotation.axes(s2)) - - if(Math.abs(u) < size && Math.abs(v) < size) - return side^1 - if(Math.abs(u) > Math.abs(v)) - return if(u > 0) s1 else s1^1 - else - return if(v > 0) s2 else s2^1 - } -} - -object FacePlacementGrid extends FaceEdgeGrid(1/4D) - -object CornerPlacementGrid extends PlacementGrid -{ - def render(hit:Vector3, side:Int) - { - glTransformFace(hit, side) - GL11.glLineWidth(2) - GL11.glColor4f(0, 0, 0, 1) - GL11.glBegin(GL11.GL_LINES) - - GL11.glVertex3d(-0.5, 0,-0.5) - GL11.glVertex3d(-0.5, 0, 0.5) - - GL11.glVertex3d(-0.5, 0, 0.5) - GL11.glVertex3d( 0.5, 0, 0.5) - - GL11.glVertex3d( 0.5, 0, 0.5) - GL11.glVertex3d( 0.5, 0,-0.5) - - GL11.glVertex3d( 0.5, 0,-0.5) - GL11.glVertex3d(-0.5, 0,-0.5) - - GL11.glVertex3d(0, 0,-0.5) - GL11.glVertex3d(0, 0, 0.5) - - GL11.glVertex3d(-0.5, 0, 0) - GL11.glVertex3d( 0.5, 0, 0) - - GL11.glEnd() - GL11.glPopMatrix() - } - - def getHitSlot(vhit:Vector3, side:Int):Int = - { - val s1 = ((side&6)+3)%6 - val s2 = ((side&6)+5)%6 - val u = vhit.copy().add(-0.5, -0.5, -0.5).scalarProject(Rotation.axes(s1)) - val v = vhit.copy().add(-0.5, -0.5, -0.5).scalarProject(Rotation.axes(s2)) - - val bu = if(u >= 0) 1 else 0 - val bv = if(v >= 0) 1 else 0 - val bw = (side&1)^1 - - return 7+( - bw<<(side>>1)| - bu<<(s1>>1)| - bv<<(s2>>1)) - } -} - -object EdgePlacementGrid extends FaceEdgeGrid(1/4D) -{ - override def getHitSlot(vhit:Vector3, side:Int):Int = - { - val s1 = (side+2)%6 - val s2 = (side+4)%6 - val u = vhit.copy().add(-0.5, -0.5, -0.5).scalarProject(Rotation.axes(s1)) - val v = vhit.copy().add(-0.5, -0.5, -0.5).scalarProject(Rotation.axes(s2)) - - if(Math.abs(u) < 4/16D && Math.abs(v) < 4/16D) - return -1 - var b = side&1 - if(Math.abs(u) > Math.abs(v)) - { - if(u < 0) b^=1 - return 15+((s2&6)<<1 | b<<1 | side&1^1) - } - else - { - if(v < 0) b^=1 - return 15+((s1&6)<<1 | (side&1^1)<<1 | b) - } - } -} \ No newline at end of file diff --git a/codechicken/microblock/TMicroOcclusion.scala b/codechicken/microblock/TMicroOcclusion.scala deleted file mode 100644 index 8017d6d..0000000 --- a/codechicken/microblock/TMicroOcclusion.scala +++ /dev/null @@ -1,261 +0,0 @@ -package codechicken.microblock - -import codechicken.multipart.TMultiPart -import codechicken.lib.vec.Cuboid6 -import codechicken.multipart.PartMap._ -import codechicken.lib.data.MCDataInput - -/** - * Suite of classes for performing microblock style occlusion and shrink rendering. Use at your own peril. - */ -object MicroOcclusion -{ - def shrink(renderBounds:Cuboid6, b:Cuboid6, side:Int) = side match - { - case -1 => - case 0 => if(renderBounds.min.y < b.max.y)renderBounds.min.y = b.max.y - case 1 => if(renderBounds.max.y > b.min.y)renderBounds.max.y = b.min.y - case 2 => if(renderBounds.min.z < b.max.z)renderBounds.min.z = b.max.z - case 3 => if(renderBounds.max.z > b.min.z)renderBounds.max.z = b.min.z - case 4 => if(renderBounds.min.x < b.max.x)renderBounds.min.x = b.max.x - case 5 => if(renderBounds.max.x > b.min.x)renderBounds.max.x = b.min.x - } - - def shrinkFrom(p:JMicroShrinkRender, other:JMicroShrinkRender, renderBounds:Cuboid6):Int = - { - if(shrinkTest(p, other)) - { - shrink(renderBounds, other.getBounds, shrinkSide(p.getSlot, other.getSlot)) - } - else if(other.getSlot < 6 && !other.isTransparent)//other gets full face, we didn't shrink, flag rendermask - { - if(other.getSlot match { - case 0 => renderBounds.min.y <= 0 - case 1 => renderBounds.max.y >= 1 - case 2 => renderBounds.min.z <= 0 - case 3 => renderBounds.max.z >= 1 - case 4 => renderBounds.min.x <= 0 - case 5 => renderBounds.max.x >= 1 - }) - return 1< - renderMask |= shrinkFrom(p, other, renderBounds) - case _ => - } - return renderMask - } - - def shrinkSide(s1:Int, s2:Int):Int = { - if(s2 < 6)//other is a cover - return s2 - if(s1 < 15)//both corners - { - val c1 = s1-7 - val c2 = s2-7 - return c1^c2 match//different axis bits will become 1, same 0 - { - case 1 => c2&1 - case 2 => 2|(c2&2)>>1 - case 4 => 4|(c2&4)>>2 - case _ => -1 - } - } - if(s2 < 15)//edge, other corner - { - val e1 = s1-15 - val c2 = s2-7 - val ebits = unpackEdgeBits(e1) - if((c2&edgeAxisMask(e1)) != ebits) - return -1 - - return (e1&0xC)>>1|(c2&(~ebits))>>(e1>>2) - } - //both edges - { - val e1 = s1-15 - val e2 = s2-15 - val e1bits = unpackEdgeBits(e1) - val e2bits = unpackEdgeBits(e2) - if((e1&0xC) == (e2&0xC))//same axis - { - return e1bits^e2bits match - { - case 1 => if((e2bits&1) == 0) 0 else 1 - case 2 => if((e2bits&2) == 0) 2 else 3 - case 4 => if((e2bits&4) == 0) 4 else 5 - case _ => -1 - } - } - else - { - val mask = edgeAxisMask(e1)&edgeAxisMask(e2) - if((e1bits&mask) != (e2bits&mask)) - return -1 - - return e1>>2 match - { - case 0 => if((e2bits&1) == 0) 0 else 1 - case 1 => if((e2bits&2) == 0) 2 else 3 - case 2 => if((e2bits&4) == 0) 4 else 5 - } - } - } - - throw new IllegalArgumentException("Switch Falloff") - } - - def recalcBounds(p:JMicroShrinkRender, renderBounds:Cuboid6) = - { - if(p.getSlot < 6) - shrink(p, renderBounds, 6) - else if(p.getSlot < 15) - shrink(p, renderBounds, 15) - else - shrink(p, renderBounds, 27) - } - - def shapePriority(slot:Int):Int = - if(slot < 6) - return 2 - else if(slot < 15) - return 1 - else - return 0 - - def shrinkTest(a:JMicroShrinkRender, b:JMicroShrinkRender):Boolean = - { - if(a.getPriorityClass != b.getPriorityClass) return a.getPriorityClass < b.getPriorityClass - - val shape1 = shapePriority(a.getSlot) - val shape2 = shapePriority(b.getSlot) - - if(shape1 != shape2) return shape1 < shape2 - if(a.getSlot < 6)//transparency takes precedence for covers - { - if(a.isTransparent != b.isTransparent) return a.isTransparent - if(a.getSize != b.getSize) return a.getSize < b.getSize - } - else - { - if(a.getSize != b.getSize) return a.getSize < b.getSize - if(a.isTransparent != b.isTransparent) return a.isTransparent - } - return a.getSlot < b.getSlot - } -} - -trait JMicroShrinkRender -{ - def getPriorityClass:Int - def getSlot:Int - def getSize:Int - def isTransparent:Boolean - def getBounds:Cuboid6 -} - -trait TMicroOcclusionClient extends TMicroOcclusion with JMicroShrinkRender -{ - var renderBounds:Cuboid6 = _ - var renderMask:Int = _ - - override def onPartChanged(part:TMultiPart) - { - super.onPartChanged(part) - recalcBounds() - } - - override def onAdded() - { - super.onAdded() - recalcBounds() - } - - override def read(packet:MCDataInput) - { - super.read(packet) - recalcBounds() - } - - def recalcBounds() - { - renderBounds = getBounds.copy - renderMask = MicroOcclusion.recalcBounds(this, renderBounds) - } - - override def getPriorityClass = 0 -} - -trait TMicroOcclusion extends TMultiPart -{ - import MicroOcclusion._ - - def getSlot:Int - def getSize:Int - def getMaterial:Int - def getBounds:Cuboid6 - - override def occlusionTest(npart:TMultiPart):Boolean = - { - if(!super.occlusionTest(npart)) - return false - - if(!npart.isInstanceOf[TMicroOcclusion]) - return true - - val mpart = npart.asInstanceOf[TMicroOcclusion] - val shape1 = shapePriority(getSlot) - val shape2 = shapePriority(mpart.getSlot) - - if(mpart.getSize + getSize > 8)//intersecting if opposite - { - if(shape1 == 2 && shape2 == 2) - if(mpart.getSlot == (getSlot^1)) - return false - - if(mpart.getMaterial != getMaterial) - { - if(shape1 == 1 && shape2 == 1) - { - val axisMask = (getSlot-7)^(mpart.getSlot-7) - if(axisMask == 3 || axisMask == 5 || axisMask == 6) - return false - } - - if(shape1 == 0 && shape2 == 1) - if(!edgeCornerOcclusionTest(this, mpart)) - return false - - if(shape1 == 1 && shape2 == 0) - if(!edgeCornerOcclusionTest(mpart, this)) - return false - - if(shape1 == 0 && shape2 == 0) - { - val e1 = getSlot-15 - val e2 = mpart.getSlot-15 - if((e1&0xC) == (e2&0xC) && ((e1&3)^(e2&3)) == 3) - return false - } - } - } - - return true - } - - def edgeCornerOcclusionTest(edge:TMicroOcclusion, corner:TMicroOcclusion):Boolean = - { - ((corner.getSlot-7)&edgeAxisMask(edge.getSlot-15)) == unpackEdgeBits(edge.getSlot-15) - } -} \ No newline at end of file diff --git a/codechicken/microblock/handler/MicroblockEventHandler.scala b/codechicken/microblock/handler/MicroblockEventHandler.scala deleted file mode 100644 index 6aabaa6..0000000 --- a/codechicken/microblock/handler/MicroblockEventHandler.scala +++ /dev/null @@ -1,40 +0,0 @@ -package codechicken.microblock.handler - -import cpw.mods.fml.common.eventhandler.SubscribeEvent -import cpw.mods.fml.relauncher.SideOnly -import cpw.mods.fml.relauncher.Side -import net.minecraftforge.client.event.TextureStitchEvent -import codechicken.microblock.MicroMaterialRegistry -import net.minecraftforge.client.event.DrawBlockHighlightEvent -import org.lwjgl.opengl.GL11 -import codechicken.lib.render.RenderUtils -import codechicken.microblock.ItemMicroPartRenderer -import cpw.mods.fml.common.Loader -import cpw.mods.fml.common.LoaderState -import net.minecraft.util.MovingObjectPosition.MovingObjectType - -object MicroblockEventHandler -{ - @SubscribeEvent - @SideOnly(Side.CLIENT) - def postTextureStitch(event:TextureStitchEvent.Post) - { - if(event.map.getTextureType == 0 && Loader.instance.hasReachedState(LoaderState.POSTINITIALIZATION)) - MicroMaterialRegistry.loadIcons() - } - - @SubscribeEvent - @SideOnly(Side.CLIENT) - def drawBlockHighlight(event:DrawBlockHighlightEvent) - { - if(event.currentItem != null && event.currentItem.getItem == MicroblockProxy.itemMicro && - event.target != null && event.target.typeOfHit == MovingObjectType.BLOCK) - { - GL11.glPushMatrix() - RenderUtils.translateToWorldCoords(event.player, event.partialTicks) - if(ItemMicroPartRenderer.renderHighlight(event.player, event.currentItem, event.target)) - event.setCanceled(true) - GL11.glPopMatrix() - } - } -} \ No newline at end of file diff --git a/codechicken/microblock/handler/MicroblockMod.scala b/codechicken/microblock/handler/MicroblockMod.scala deleted file mode 100644 index 1379b9e..0000000 --- a/codechicken/microblock/handler/MicroblockMod.scala +++ /dev/null @@ -1,52 +0,0 @@ -package codechicken.microblock.handler - -import cpw.mods.fml.common.Mod -import cpw.mods.fml.common.event.FMLInitializationEvent -import cpw.mods.fml.common.event.FMLPreInitializationEvent -import cpw.mods.fml.common.Mod.EventHandler -import cpw.mods.fml.common.event.FMLServerAboutToStartEvent -import codechicken.microblock.MicroMaterialRegistry -import codechicken.microblock.DefaultContent -import cpw.mods.fml.common.event.FMLPostInitializationEvent -import codechicken.microblock.ConfigContent -import cpw.mods.fml.common.event.FMLInterModComms.IMCEvent -import scala.collection.JavaConversions._ - -@Mod(modid = "ForgeMicroblock", acceptedMinecraftVersions = "[1.7.2]", - dependencies="required-after:ForgeMultipart;after:*", modLanguage="scala") -object MicroblockMod -{ - @EventHandler - def preInit(event:FMLPreInitializationEvent) - { - MicroblockProxy.preInit() - DefaultContent.load() - ConfigContent.parse(event.getModConfigurationDirectory) - } - - @EventHandler - def init(event:FMLInitializationEvent) - { - MicroblockProxy.init() - ConfigContent.load() - } - - @EventHandler - def postInit(event:FMLPostInitializationEvent) - { - MicroMaterialRegistry.setupIDMap() - MicroblockProxy.postInit() - } - - @EventHandler - def beforeServerStart(event:FMLServerAboutToStartEvent) - { - MicroMaterialRegistry.setupIDMap() - } - - @EventHandler - def handleIMC(event:IMCEvent) - { - ConfigContent.handleIMC(event.getMessages) - } -} \ No newline at end of file diff --git a/codechicken/microblock/handler/packethandlers.scala b/codechicken/microblock/handler/packethandlers.scala deleted file mode 100644 index 9bed6fc..0000000 --- a/codechicken/microblock/handler/packethandlers.scala +++ /dev/null @@ -1,42 +0,0 @@ -package codechicken.microblock.handler - -import codechicken.lib.packet.PacketCustom.{IHandshakeHandler, IClientPacketHandler, IServerPacketHandler} -import codechicken.lib.packet.PacketCustom -import net.minecraft.client.Minecraft -import codechicken.microblock.MicroMaterialRegistry -import net.minecraft.entity.player.EntityPlayerMP -import net.minecraft.network.play.{INetHandlerPlayServer, INetHandlerPlayClient} -import net.minecraft.network.play.server.S40PacketDisconnect -import net.minecraft.util.ChatComponentTranslation -import net.minecraft.network.NetHandlerPlayServer - -class MicroblockPH -{ - val registryChannel = "ForgeMicroblock" //Must use the 250 system for ID registry as the NetworkMod idMap hasn't been properly initialized from the server yet. -} - -object MicroblockCPH extends MicroblockPH with IClientPacketHandler -{ - def handlePacket(packet: PacketCustom, mc: Minecraft, netHandler:INetHandlerPlayClient) { - packet.getType match { - case 1 => handleMaterialRegistration(packet, netHandler) - } - } - - def handleMaterialRegistration(packet: PacketCustom, netHandler: INetHandlerPlayClient) { - val missing = MicroMaterialRegistry.readIDMap(packet) - if (!missing.isEmpty) - netHandler.handleDisconnect(new S40PacketDisconnect(new ChatComponentTranslation("microblock.missing", missing.mkString(", ")))) - } -} - -object MicroblockSPH extends MicroblockPH with IServerPacketHandler with IHandshakeHandler -{ - def handlePacket(packet: PacketCustom, sender: EntityPlayerMP, netHandler:INetHandlerPlayServer) {} - - def handshakeRecieved(netHandler: NetHandlerPlayServer) { - val packet = new PacketCustom(registryChannel, 1) - MicroMaterialRegistry.writeIDMap(packet) - netHandler.sendPacket(packet.toPacket) - } -} \ No newline at end of file diff --git a/codechicken/microblock/handler/proxies.scala b/codechicken/microblock/handler/proxies.scala deleted file mode 100644 index 3cc4f16..0000000 --- a/codechicken/microblock/handler/proxies.scala +++ /dev/null @@ -1,115 +0,0 @@ -package codechicken.microblock.handler - -import net.minecraftforge.common.MinecraftForge -import codechicken.multipart.handler.MultipartProxy._ -import codechicken.microblock._ -import net.minecraftforge.client.MinecraftForgeClient -import cpw.mods.fml.relauncher.SideOnly -import cpw.mods.fml.relauncher.Side -import net.minecraft.item.crafting.CraftingManager -import net.minecraft.item.Item -import net.minecraft.item.crafting.IRecipe -import java.util.{List => JList} -import codechicken.lib.config.ConfigFile -import net.minecraftforge.oredict.OreDictionary -import net.minecraft.item.ItemStack -import net.minecraftforge.oredict.ShapedOreRecipe -import net.minecraft.block.Block -import codechicken.lib.packet.PacketCustom -import cpw.mods.fml.common.registry.GameRegistry -import cpw.mods.fml.common.network.NetworkRegistry -import net.minecraft.client.renderer.RenderBlocks -import net.minecraft.init.{Blocks, Items} - -class MicroblockProxy_serverImpl -{ - private var baseID = 24875-1 - - def nextItemID = {baseID+=1; baseID} - - var itemMicro:ItemMicroPart = _ - var sawStone:Item = _ - var sawIron:Item = _ - var sawDiamond:Item = _ - var stoneRod:Item = _ - - def preInit() - { - itemMicro = new ItemMicroPart - GameRegistry.registerItem(itemMicro, "microblock") - sawStone = createSaw(config, "sawStone", 1) - sawIron = createSaw(config, "sawIron", 2) - sawDiamond = createSaw(config, "sawDiamond", 3) - stoneRod = new Item().setUnlocalizedName("microblock:stoneRod").setTextureName("microblock:stoneRod") - GameRegistry.registerItem(stoneRod, "stoneRod") - - OreDictionary.registerOre("rodStone", stoneRod) - MinecraftForge.EVENT_BUS.register(MicroblockEventHandler) - } - - def createSaw(config:ConfigFile, name:String, strength:Int) = { - val saw = new ItemSaw(config.getTag(name).useBraces(), strength).setUnlocalizedName("microblock:"+name) - GameRegistry.registerItem(saw, name) - saw - } - - def addSawRecipe(saw:Item, blade:Item) - { - CraftingManager.getInstance.getRecipeList.asInstanceOf[JList[IRecipe]].add( - new ShapedOreRecipe(new ItemStack(saw), - "srr", - "sbr", - 's':Character, Items.stick, - 'r':Character, "rodStone", - 'b':Character, blade)) - } - - def init() - { - CraftingManager.getInstance.getRecipeList.asInstanceOf[JList[IRecipe]].add(MicroRecipe) - CraftingManager.getInstance.addRecipe(new ItemStack(stoneRod, 4), "s", "s", 's':Character, Blocks.stone) - addSawRecipe(sawStone, Items.flint) - addSawRecipe(sawIron, Items.iron_ingot) - addSawRecipe(sawDiamond, Items.diamond) - } - - def postInit() - { - MicroMaterialRegistry.loadIcons() - MicroMaterialRegistry.calcMaxCuttingStrength() - PacketCustom.assignHandshakeHandler(MicroblockSPH.registryChannel, MicroblockSPH) - } -} - -class MicroblockProxy_clientImpl extends MicroblockProxy_serverImpl -{ - @SideOnly(Side.CLIENT) - private var _renderBlocks:RenderBlocks = _ - @SideOnly(Side.CLIENT) - def renderBlocks = - { - if(_renderBlocks == null) - _renderBlocks = new RenderBlocks - _renderBlocks - } - - @SideOnly(Side.CLIENT) - override def postInit() - { - super.postInit() - MinecraftForgeClient.registerItemRenderer(itemMicro, ItemMicroPartRenderer) - PacketCustom.assignHandler(MicroblockCPH.registryChannel, MicroblockCPH) - } - - @SideOnly(Side.CLIENT) - override def createSaw(config:ConfigFile, name:String, strength:Int) = - { - val saw = super.createSaw(config, name, strength) - MinecraftForgeClient.registerItemRenderer(saw, ItemSawRenderer) - saw - } -} - -object MicroblockProxy extends MicroblockProxy_clientImpl -{ -} diff --git a/codechicken/multipart/BlockMultipart.scala b/codechicken/multipart/BlockMultipart.scala deleted file mode 100644 index 3a4b902..0000000 --- a/codechicken/multipart/BlockMultipart.scala +++ /dev/null @@ -1,300 +0,0 @@ -package codechicken.multipart - -import java.util.List -import java.lang.Iterable -import net.minecraft.block.Block -import net.minecraft.block.material.Material -import net.minecraft.entity.Entity -import net.minecraft.util.AxisAlignedBB -import net.minecraft.world.World -import net.minecraftforge.common.util.ForgeDirection -import net.minecraft.util.Vec3 -import net.minecraft.util.MovingObjectPosition -import codechicken.lib.raytracer.RayTracer -import net.minecraft.entity.player.EntityPlayer -import java.util.Random -import java.util.ArrayList -import net.minecraft.item.ItemStack -import net.minecraft.client.particle.EffectRenderer -import net.minecraft.client.Minecraft -import net.minecraft.client.renderer.texture.IIconRegister -import codechicken.lib.render.TextureUtils -import net.minecraft.world.IBlockAccess -import codechicken.lib.raytracer.ExtendedMOP -import scala.collection.JavaConversions._ - -object BlockMultipart -{ - def getTile(world:IBlockAccess, x:Int, y:Int, z:Int):TileMultipart = - { - val tile = world.getTileEntity(x, y, z) - if(tile.isInstanceOf[TileMultipart]) - tile.asInstanceOf[TileMultipart] - else - null - } - - def getClientTile(world:IBlockAccess, x:Int, y:Int, z:Int):TileMultipartClient = - { - val tile = world.getTileEntity(x, y, z) - if(tile.isInstanceOf[TileMultipartClient]) - tile.asInstanceOf[TileMultipartClient] - else - null - } - - def reduceMOP(hit:MovingObjectPosition):(Int, ExtendedMOP) = { - val ehit = hit.asInstanceOf[ExtendedMOP] - val data:(Int, _) = ExtendedMOP.getData(hit) - return (data._1, new ExtendedMOP(ehit, data._2, ehit.dist)) - } - - def drawHighlight(world:World, player:EntityPlayer, hit:MovingObjectPosition, frame:Float):Boolean = - { - val tile = getTile(world, hit.blockX, hit.blockY, hit.blockZ) - if(tile == null) - return false - - val (index, mop) = reduceMOP(hit) - if(tile.partList(index).drawHighlight(mop, player, frame)) - return true - - tile.partList(index).collisionRayTrace(RayTracer.getStartVec(player), RayTracer.getEndVec(player)) - return false - } -} - -/** - * Block class for all multiparts, should be internal use only. - */ -class BlockMultipart extends Block(Material.rock) -{ - import BlockMultipart._ - - override def hasTileEntity(meta:Int = 0) = true - - override def isBlockSolid(world:IBlockAccess, x:Int, y:Int, z:Int, side:Int):Boolean = - getTile(world, x, y, z) match { - case null => false - case tile => tile.isSolid(side) - } - - override def onNeighborBlockChange(world:World, x:Int, y:Int, z:Int, block:Block) { - val tile = getTile(world, x, y, z) - if(tile != null) - tile.onNeighborBlockChange() - } - - override def collisionRayTrace(world:World, x:Int, y:Int, z:Int, start:Vec3, end:Vec3):ExtendedMOP = - getTile(world, x, y, z) match { - case null => null - case tile => tile.collisionRayTrace(start, end) - } - - def rayTraceAll(world:World, x:Int, y:Int, z:Int, start:Vec3, end:Vec3):Iterable[ExtendedMOP] = - getTile(world, x, y, z) match { - case null => Seq() - case tile => tile.rayTraceAll(start, end) - } - - override def removedByPlayer(world:World, player:EntityPlayer, x:Int, y:Int, z:Int):Boolean = { - val hit = RayTracer.retraceBlock(world, player, x, y, z) - val tile = getTile(world, x, y, z) - - if(hit == null || tile == null) - { - dropAndDestroy(world, x, y, z) - return true - } - - val (index, mop) = reduceMOP(hit) - if(world.isRemote) - { - tile.partList(index).addDestroyEffects(mop, Minecraft.getMinecraft.effectRenderer) - return true - } - - tile.harvestPart(index, mop, player) - return world.getTileEntity(x, y, z) == null - } - - def dropAndDestroy(world:World, x:Int, y:Int, z:Int) { - val tile = getTile(world, x, y, z) - if(tile != null && !world.isRemote) - tile.dropItems(getDrops(world, x, y, z, 0, 0)) - - world.setBlockToAir(x, y, z) - } - - override def quantityDropped(meta:Int, fortune:Int, random:Random) = 0 - - override def getDrops(world:World, x:Int, y:Int, z:Int, meta:Int, fortune:Int):ArrayList[ItemStack] = { - val ai = new ArrayList[ItemStack]() - if(world.isRemote) - return ai - - val tile = getTile(world, x, y, z) - if(tile != null) - tile.partList.foreach(part => part.getDrops.foreach(item => ai.add(item))) - - return ai - } - - override def addCollisionBoxesToList(world:World, x:Int, y:Int, z:Int, ebb:AxisAlignedBB, list$:List[_], entity:Entity) { - val list = list$.asInstanceOf[List[AxisAlignedBB]] - val tile = getTile(world, x, y, z) - if(tile != null) - tile.partList.foreach(part => - part.getCollisionBoxes.foreach{c => - val aabb = c.toAABB.offset(x, y, z) - if(aabb.intersectsWith(ebb)) - list.add(aabb) - }) - } - - override def addHitEffects(world:World, hit:MovingObjectPosition, effectRenderer:EffectRenderer):Boolean = { - val tile = getClientTile(world, hit.blockX, hit.blockY, hit.blockZ) - if(tile != null) { - val (index, mop) = reduceMOP(hit) - if(index < tile.partList.size) - tile.partList(index).addHitEffects(mop, effectRenderer) - } - - return true - } - - override def addDestroyEffects(world:World, x:Int, y:Int, z:Int, s:Int, effectRenderer:EffectRenderer) = true - - override def renderAsNormalBlock() = false - - override def isOpaqueCube = false - - override def getRenderType = TileMultipart.renderID - - override def isAir(world:IBlockAccess, x:Int, y:Int, z:Int):Boolean = - getTile(world, x, y, z) match { - case null => true - case tile => tile.partList.isEmpty - } - - override def isReplaceable(world:IBlockAccess, x:Int, y:Int, z:Int) = isAir(world, x, y, z) - - override def getRenderBlockPass = 1 - - override def canRenderInPass(pass:Int):Boolean = { - MultipartRenderer.pass = pass - return true - } - - override def getPickBlock(hit:MovingObjectPosition, world:World, x:Int, y:Int, z:Int):ItemStack = { - val tile = getTile(world, x, y, z) - if(tile != null) - { - val (index, mop) = reduceMOP(hit) - return tile.partList(index).pickItem(mop) - } - return null - } - - override def getPlayerRelativeBlockHardness(player:EntityPlayer, world:World, x:Int, y:Int, z:Int):Float = { - val hit = RayTracer.retraceBlock(world, player, x, y, z) - val tile = getTile(world, x, y, z) - if(hit != null && tile != null) { - val (index, mop) = reduceMOP(hit) - return tile.partList(index).getStrength(mop, player)/30F - } - - return 1/100F - } - - /** - * Kludge to set PROTECTED blockIcon to a blank icon - */ - override def registerBlockIcons(register:IIconRegister) { - val icon = TextureUtils.getBlankIcon(16, register) - setBlockTextureName(icon.getIconName) - super.registerBlockIcons(register) - } - - override def getLightValue(world:IBlockAccess, x:Int, y:Int, z:Int):Int = - getTile(world, x, y, z) match { - case null => 0 - case tile => tile.getLightValue - } - - override def randomDisplayTick(world:World, x:Int, y:Int, z:Int, random:Random) { - val tile = getClientTile(world, x, y, z) - if(tile != null) - tile.randomDisplayTick(random) - } - - override def onBlockActivated(world:World, x:Int, y:Int, z:Int, player:EntityPlayer, side:Int, hitX:Float, hitY:Float, hitZ:Float):Boolean = { - val hit = RayTracer.retraceBlock(world, player, x, y, z) - if(hit == null) - return false - - val tile = getTile(world, x, y, z) - if(tile == null) - return false - - val (index, mop) = reduceMOP(hit) - return tile.partList(index).activate(player, mop, player.getHeldItem) - } - - override def onBlockClicked(world:World, x:Int, y:Int, z:Int, player:EntityPlayer) { - val hit = RayTracer.retraceBlock(world, player, x, y, z) - if(hit == null) - return - - val tile = getTile(world, x, y, z) - if(tile == null) - return - - val (index, mop) = reduceMOP(hit) - tile.partList(index).click(player, mop, player.getHeldItem) - } - - override def isProvidingStrongPower(world:IBlockAccess, x:Int, y:Int, z:Int, side:Int):Int = - getTile(world, x, y, z) match { - case null => 0 - case tile => tile.strongPowerLevel(side^1) - } - - override def isProvidingWeakPower(world:IBlockAccess, x:Int, y:Int, z:Int, side:Int):Int = - getTile(world, x, y, z) match { - case null => 0 - case tile => tile.weakPowerLevel(side^1) - } - - override def canConnectRedstone(world:IBlockAccess, x:Int, y:Int, z:Int, side:Int):Boolean = - getTile(world, x, y, z) match { - case null => false - case tile => tile.canConnectRedstone(side) - } - - override def onEntityCollidedWithBlock(world:World, x:Int, y:Int, z:Int, entity:Entity) { - val tile = getTile(world, x, y, z) - if(tile != null) - tile.onEntityCollision(entity) - } - - override def onNeighborChange(world:IBlockAccess, x:Int, y:Int, z:Int, tileX:Int, tileY:Int, tileZ:Int) { - val tile = getTile(world, x, y, z) - if(tile != null) - tile.onNeighborTileChange(tileX, tileY, tileZ) - } - - override def getExplosionResistance(entity:Entity, world:World, x:Int, y:Int, z:Int, explosionX:Double, explosionY:Double, explosionZ:Double):Float = - getTile(world, x, y, z) match { - case null => 0 - case tile => tile.getExplosionResistance(entity) - } - - override def getWeakChanges(world:IBlockAccess, x:Int, y:Int, z:Int) = - getTile(world, x, y, z) match { - case null => false - case tile => tile.getWeakChanges() - } - - override def canProvidePower = true -} \ No newline at end of file diff --git a/codechicken/multipart/ControlKeyModifier.scala b/codechicken/multipart/ControlKeyModifier.scala deleted file mode 100644 index e06c6b2..0000000 --- a/codechicken/multipart/ControlKeyModifier.scala +++ /dev/null @@ -1,58 +0,0 @@ -package codechicken.multipart - -import net.minecraft.client.settings.KeyBinding -import org.lwjgl.input.Keyboard -import net.minecraft.client.Minecraft -import codechicken.lib.packet.PacketCustom -import codechicken.multipart.handler.MultipartCPH -import scala.collection.mutable.HashMap -import net.minecraft.entity.player.EntityPlayer -import cpw.mods.fml.common.eventhandler.SubscribeEvent -import cpw.mods.fml.common.gameevent.InputEvent.KeyInputEvent -import cpw.mods.fml.relauncher.{Side, SideOnly} -import cpw.mods.fml.common.gameevent.TickEvent.ClientTickEvent - -/** - * A class that maintains a map server<->client of which players are holding the control (or placement modifier key) much like sneaking. - */ -object ControlKeyModifer -{ - implicit def playerControlValue(p:EntityPlayer) = new ControlKeyValue(p) - - class ControlKeyValue(p:EntityPlayer) - { - def isControlDown = map(p) - } - - val map = HashMap[EntityPlayer, Boolean]().withDefaultValue(false) - - /** - * Implicit static for Java users. - */ - def isControlDown(p:EntityPlayer) = p.isControlDown -} - -/** - * Key Handler implementation - */ -object ControlKeyHandler extends KeyBinding("key.control", Keyboard.KEY_LCONTROL, "key.categories.gameplay") -{ - import ControlKeyModifer._ - var wasPressed = false - - @SubscribeEvent - @SideOnly(Side.CLIENT) - def tick(event:ClientTickEvent) { - val pressed = getIsKeyPressed - if(pressed != wasPressed) { - wasPressed = pressed - if(Minecraft.getMinecraft.getNetHandler != null) - { - map.put(Minecraft.getMinecraft.thePlayer, pressed) - val packet = new PacketCustom(MultipartCPH.channel, 1) - packet.writeBoolean(pressed) - packet.sendToServer() - } - } - } -} \ No newline at end of file diff --git a/codechicken/multipart/IDWriter.scala b/codechicken/multipart/IDWriter.scala deleted file mode 100644 index 9a240df..0000000 --- a/codechicken/multipart/IDWriter.scala +++ /dev/null @@ -1,33 +0,0 @@ -package codechicken.multipart - -import codechicken.lib.data.MCDataOutput -import codechicken.lib.data.MCDataInput - -/** - * Class for reading and writing ids, widening the carrier data type as necessary - */ -class IDWriter -{ - var write:(MCDataOutput, Int)=>Unit = _ - var read:(MCDataInput)=>Int = _ - - def setMax(i:Int) - { - val l = i.toLong & 0xFFFFFFFF - if(l > 0xFFFF) - { - write = (data, i) => data.writeInt(i) - read = (data) => data.readInt() - } - else if(l > 0xFF) - { - write = (data, i) => data.writeShort(i) - read = (data) => data.readUShort() - } - else - { - write = (data, i) => data.writeByte(i) - read = (data) => data.readUByte() - } - } -} \ No newline at end of file diff --git a/codechicken/multipart/INeighborTileChange.scala b/codechicken/multipart/INeighborTileChange.scala deleted file mode 100644 index 6a8eb11..0000000 --- a/codechicken/multipart/INeighborTileChange.scala +++ /dev/null @@ -1,15 +0,0 @@ -package codechicken.multipart - -/** - * Mixin interface for parts that want to be notified of neighbor tile change events (comparators or inventory maintainers) - */ -trait INeighborTileChange { - /** - * Returns whether this part needs calls for tile changes through one solid block - */ - def weakTileChanges():Boolean - /** - * Callback for neighbor tile changes, from same function in Block - */ - def onNeighborTileChanged(side:Int, weak:Boolean) -} \ No newline at end of file diff --git a/codechicken/multipart/IRandomDisplayTick.scala b/codechicken/multipart/IRandomDisplayTick.scala deleted file mode 100644 index a51245d..0000000 --- a/codechicken/multipart/IRandomDisplayTick.scala +++ /dev/null @@ -1,16 +0,0 @@ -package codechicken.multipart - -import java.util.Random - -/** - * Interface for parts that need random display ticks (torches) - * - * Marker interface for TRandomDisplayTickTile - */ -trait IRandomDisplayTick -{ - /** - * Called on a random display tick. - */ - def randomDisplayTick(random:Random) -} \ No newline at end of file diff --git a/codechicken/multipart/IRandomUpdateTick.scala b/codechicken/multipart/IRandomUpdateTick.scala deleted file mode 100644 index f689dce..0000000 --- a/codechicken/multipart/IRandomUpdateTick.scala +++ /dev/null @@ -1,12 +0,0 @@ -package codechicken.multipart - -/** - * Interface for parts with random update ticks. - */ -trait IRandomUpdateTick -{ - /** - * Called on random update. Random ticks are between 800 and 1600 ticks from their last scheduled/random tick - */ - def randomUpdate() -} \ No newline at end of file diff --git a/codechicken/multipart/IRedstonePart.scala b/codechicken/multipart/IRedstonePart.scala deleted file mode 100644 index ab72bea..0000000 --- a/codechicken/multipart/IRedstonePart.scala +++ /dev/null @@ -1,243 +0,0 @@ -package codechicken.multipart - -import net.minecraft.world.World -import net.minecraft.block.Block -import net.minecraft.world.IBlockAccess -import net.minecraft.util.Direction -import codechicken.lib.vec.Rotation._ -import net.minecraft.init.Blocks - -/** - * Interface for parts with redstone interaction - * - * Marker interface for TRedstoneTile. This means that if a part is an instance of IRedstonePart, the container tile may be cast to TRedstoneTile - */ -trait IRedstonePart -{ - /** - * Returns the strong (indirect, through blocks) signal being emitted by this part to the specified side - */ - def strongPowerLevel(side:Int):Int - /** - * Returns the weak (direct) signal being emitted by this part to the specified side - */ - def weakPowerLevel(side:Int):Int - /** - * Returns true if this part can connect to redstone on the specified side. Blocking parts like covers will be handled by RedstoneInteractions - */ - def canConnectRedstone(side:Int):Boolean -} - -/** - * For parts like wires that adhere to a specific face, reduces redstone connections to the specific edge between two faces. - * Should be implemented on parts implementing TFacePart - */ -trait IFaceRedstonePart extends IRedstonePart -{ - /** - * Return the face to which this redstone part is attached - */ - def getFace:Int -} - -/** - * For parts that want to define their own connection masks (like center-center parts) - */ -trait IMaskedRedstonePart extends IRedstonePart -{ - /** - * Returns the redstone connection mask for this part on side. See IRedstoneConnector for mask definition - */ - def getConnectionMask(side:Int):Int -} - -/** - * Interface for tile entities which split their redstone connections into a mask for each side (edges and center) - * - * All connection masks are a 5 bit map. - * The lowest 4 bits correspond to the connection toward the face specified Rotation.rotateSide(side&6, b) where b is the bit index from lowest to highest. - * Bit 5 corresponds to a connection opposite side. - */ -trait IRedstoneConnector -{ - /** - * Returns the redstone connection mask for this tile on side. - */ - def getConnectionMask(side:Int):Int - /** - * Returns the weak power level provided by this tile on side through mask - */ - def weakPowerLevel(side:Int, mask:Int):Int -} - -/** - * Internal interface for TileMultipart instances hosting IRedstonePart - */ -trait IRedstoneTile extends IRedstoneConnector -{ - /** - * Returns a mask of spaces through which a wire could connect on side - */ - def openConnections(side:Int):Int -} - -/** - * Block version of IRedstoneConnector - * Due to the inadequate Block.canConnectRedstone not handling the bottom side (nor the top particularly well) - */ -trait IRedstoneConnectorBlock -{ - def getConnectionMask(world:IBlockAccess, x:Int, y:Int, z:Int, side:Int):Int - def weakPowerLevel(world:IBlockAccess, x:Int, y:Int, z:Int, side:Int, mask:Int):Int -} - -/** - * static helper class for calculating various things about redstone. - * Indirect power (also known as strong power) is not handled here, just use world.getIndirectPowerTo - * Masks are defined in IRedstoneConnector - */ -object RedstoneInteractions -{ - import net.minecraft.util.Facing._ - - val vanillaSideMap = Array(-2, -1, 0, 2, 3, 1) - val sideVanillaMap = Array(1, 2, 5, 3, 4) - - /** - * Hardcoded vanilla overrides for Block.canConnectRedstone (see @IRedstoneConnectorBlock) - */ - val fullVanillaBlocks = Set( - Blocks.redstone_torch, - Blocks.unlit_redstone_torch, - Blocks.lever, - Blocks.stone_button, - Blocks.wooden_button, - Blocks.redstone_block) - - /** - * Get the direct power to p on side - */ - def getPowerTo(p:TMultiPart, side:Int):Int = - { - val tile = p.tile - return getPowerTo(tile.getWorldObj, tile.xCoord, tile.yCoord, tile.zCoord, side, - tile.asInstanceOf[IRedstoneTile].openConnections(side)&connectionMask(p, side)) - } - - /** - * Get the direct power level to space (x, y, z) on side with mask - */ - def getPowerTo(world:World, x:Int, y:Int, z:Int, side:Int, mask:Int):Int = - getPower(world, x+offsetsXForSide(side), y+offsetsYForSide(side), z+offsetsZForSide(side), side^1, mask) - - /** - * Get the direct power level provided by space (x, y, z) on side with mask - */ - def getPower(world:World, x:Int, y:Int, z:Int, side:Int, mask:Int):Int = - { - val tile = world.getTileEntity(x, y, z) - if(tile.isInstanceOf[IRedstoneConnector]) - return tile.asInstanceOf[IRedstoneConnector].weakPowerLevel(side, mask) - - val block = world.getBlock(x, y, z) - if(block.isInstanceOf[IRedstoneConnectorBlock]) - return block.asInstanceOf[IRedstoneConnectorBlock].weakPowerLevel(world, x, y, z, side, mask) - - val vmask = vanillaConnectionMask(block, world, x, y, z, side, true) - if((vmask&mask) > 0) - { - var m = world.getIndirectPowerLevelTo(x, y, z, side^1) - if(m < 15 && block == Blocks.redstone_wire) - m = Math.max(m, world.getBlockMetadata(x, y, z))//painful vanilla kludge - return m - } - return 0 - } - - def vanillaToSide(vside:Int) = sideVanillaMap(vside+1) - - /** - * Get the connection mask of the block on side of (x, y, z). - * @param power, whether the connection mask is for signal transfer or visual connection. (some blocks accept power without visual connection) - */ - def otherConnectionMask(world:IBlockAccess, x:Int, y:Int, z:Int, side:Int, power:Boolean):Int = - getConnectionMask(world, x+offsetsXForSide(side), y+offsetsYForSide(side), z+offsetsZForSide(side), side^1, power) - - /** - * Get the connection mask of part on side - */ - def connectionMask(p:TMultiPart, side:Int):Int = - { - if(p.isInstanceOf[IRedstonePart] && p.asInstanceOf[IRedstonePart].canConnectRedstone(side)) - { - if(p.isInstanceOf[IFaceRedstonePart]) - { - val fside = p.asInstanceOf[IFaceRedstonePart].getFace - if((side&6) == (fside&6)) - return 0x10 - - return 1< MMap} -import codechicken.lib.packet.PacketCustom -import codechicken.lib.data.MCDataOutput -import codechicken.lib.data.MCDataInput -import net.minecraft.world.World -import codechicken.lib.vec.BlockCoord -import scala.collection.mutable.ListBuffer -import cpw.mods.fml.common.ModContainer -import cpw.mods.fml.common.Loader -import net.minecraft.block.Block -import java.lang.Iterable -import com.google.common.collect.ArrayListMultimap -import scala.collection.JavaConversions._ - -/** - * This class handles the registration and internal ID mapping of all multipart classes. - */ -object MultiPartRegistry -{ - /** - * Interface to be registered for constructing parts. - * Every instance of every multipart is constructed from an implementor of this. - */ - trait IPartFactory - { - /** - * Create a new instance of the part with the specified type name identifier - * @param client If the part instance is for the client or the server - */ - def createPart(name: String, client: Boolean): TMultiPart - } - - /** - * An interface for converting existing blocks/tile entities to multipart versions. - */ - trait IPartConverter - { - /** - * Return true if this converter can handle the specific blockID (may or may not actually convert the block) - */ - def blockTypes: Iterable[Block] - - /** - * Return a multipart version of the block at pos in world. Return null if no conversion is possible. - */ - def convert(world: World, pos: BlockCoord): TMultiPart - } - - private val typeMap = MMap[String, (Boolean) => TMultiPart]() - private val nameMap = MMap[String, Int]() - private var idMap: Array[(String, (Boolean) => TMultiPart)] = _ - private val idWriter = new IDWriter - private val converters = ArrayListMultimap.create[Block, IPartConverter]() - private val containers = MMap[String, ModContainer]() - - /** - * The state of the registry. 0 = no parts, 1 = registering, 2 = registered - */ - private var state: Int = 0 - - /** - * Register a part factory with an array of types it is capable of instantiating. Must be called before postInit - */ - def registerParts(partFactory: IPartFactory, types: Array[String]) { - registerParts(partFactory.createPart _, types: _*) - } - - /** - * Scala function version of registerParts - */ - def registerParts(partFactory: (String, Boolean) => TMultiPart, types: String*) { - if (loaded) - throw new IllegalStateException("Parts must be registered in the init methods.") - state = 1 - - val container = Loader.instance.activeModContainer - if (container == null) - throw new IllegalStateException("Parts must be registered during the initialization phase of a mod container") - - types.foreach { - s => - if (typeMap.contains(s)) - throw new IllegalStateException("Part with id " + s + " is already registered.") - - typeMap.put(s, (c: Boolean) => partFactory(s, c)) - containers.put(s, container) - } - } - - /** - * Register a part converter instance - */ - def registerConverter(c: IPartConverter) { - c.blockTypes.foreach(converters.put(_, c)) - } - - private[multipart] def beforeServerStart() { - idMap = typeMap.toList.sortBy(_._1).toArray - idWriter.setMax(idMap.length) - nameMap.clear() - for (i <- 0 until idMap.length) - nameMap.put(idMap(i)._1, i) - } - - private[multipart] def writeIDMap(packet: PacketCustom) { - packet.writeInt(idMap.length) - idMap.foreach(e => packet.writeString(e._1)) - } - - private[multipart] def readIDMap(packet: PacketCustom): Seq[String] = { - val k = packet.readInt() - idWriter.setMax(k) - idMap = new Array(k) - nameMap.clear() - val missing = ListBuffer[String]() - for (i <- 0 until k) { - val s = packet.readString() - val v = typeMap.get(s) - if (v.isEmpty) - missing += s - else { - idMap(i) = (s, v.get) - nameMap.put(s, i) - } - } - return missing - } - - /** - * Return true if any multiparts have been registered - */ - private[multipart] def required = state > 0 - - /** - * Return true if no more parts can be registered - */ - def loaded = state == 2 - - private[multipart] def postInit() { - state = 2 - } - - /** - * Writes the id of part to data - */ - def writePartID(data: MCDataOutput, part: TMultiPart) { - idWriter.write(data, nameMap.get(part.getType).get) - } - - /** - * Uses instantiators to creat a new part from the id read from data - */ - def readPart(data: MCDataInput) = idMap(idWriter.read(data))._2(true) - - /** - * Uses instantiators to create a new part with specified identifier on side - */ - def createPart(name: String, client: Boolean): TMultiPart = { - val part = typeMap.get(name) - if (part.isDefined) - return part.get(client) - else { - System.err.println("Missing mapping for part with ID: " + name) - return null - } - } - - /** - * Calls converters to create a multipart version of the block at pos - */ - def convertBlock(world: World, pos: BlockCoord, block: Block): TMultiPart = { - for (c <- converters.get(block)) { - val ret = c.convert(world, pos) - if (ret != null) - return ret - } - return null - } - - def getModContainer(name: String) = containers(name) -} diff --git a/codechicken/multipart/MultipartGenerator.scala b/codechicken/multipart/MultipartGenerator.scala deleted file mode 100644 index 8a7d16e..0000000 --- a/codechicken/multipart/MultipartGenerator.scala +++ /dev/null @@ -1,219 +0,0 @@ -package codechicken.multipart - -import net.minecraft.tileentity.TileEntity -import scala.collection.immutable.Map -import net.minecraft.world.World -import codechicken.lib.vec.BlockCoord -import codechicken.multipart.handler.MultipartProxy -import codechicken.lib.packet.PacketCustom -import codechicken.multipart.asm.IMultipartFactory -import codechicken.multipart.asm.ASMMixinFactory -import net.minecraft.network.play.server.S23PacketBlockChange - -/** - * This class manages the dynamic construction and allocation of container TileMultipart instances. - * - * Classes that extend TileMultipart, adding tile centric logic, optimisations or interfaces, can be registered to a marker interface on a part instance. - * When a part is added to the tile that implements the certain marker interface, the container tile will be replaced with a class that includes the functionality from the corresponding mixin class. - * - * Classes are generated in a similar fashion to the way scala traits are compiled. To see the output, simply enable the config option and look in the asm/multipart folder of you .minecraft directory. - * - * There are several mixin traits that come with the API included in the scalatraits package. TPartialOcclusionTile is defined as class instead of trait to give an example for Java programmers. - */ -object MultipartGenerator -{ - private var tileTraitMap:Map[Class[_], Set[String]] = Map() - private var interfaceTraitMap_c:Map[String, String] = Map() - private var interfaceTraitMap_s:Map[String, String] = Map() - private var partTraitMap_c:Map[Class[_], Seq[String]] = Map() - private var partTraitMap_s:Map[Class[_], Seq[String]] = Map() - - var factory:IMultipartFactory = ASMMixinFactory - - def partTraitMap(client:Boolean) = if(client) partTraitMap_c else partTraitMap_s - - def interfaceTraitMap(client:Boolean) = if(client) partTraitMap_c else interfaceTraitMap_s - - def traitsForPart(part:TMultiPart, client:Boolean):Seq[String] = - { - var ret = partTraitMap(client).getOrElse(part.getClass, null) - if(ret == null) - { - def heirachy(clazz:Class[_]):Seq[Class[_]] = - { - var superClasses:Seq[Class[_]] = clazz.getInterfaces.flatMap(c => heirachy(c)):+clazz - if(clazz.getSuperclass != null) - superClasses = superClasses++heirachy(clazz.getSuperclass) - return superClasses - } - - val interfaceTraitMap = if(client) interfaceTraitMap_c else interfaceTraitMap_s - ret = heirachy(part.getClass).flatMap(c => interfaceTraitMap.get(c.getName)).distinct - if(client) - partTraitMap_c = partTraitMap_c+(part.getClass -> ret) - else - partTraitMap_s = partTraitMap_s+(part.getClass -> ret) - } - return ret - } - - /** - * Check if part adds any new interfaces to tile, if so, replace tile with a new copy and call tile.addPart(part) - * returns true if tile was replaced - */ - private[multipart] def addPart(world:World, pos:BlockCoord, part:TMultiPart):TileMultipart = - { - val (tile, converted) = TileMultipart.getOrConvertTile2(world, pos) - var partTraits = traitsForPart(part, world.isRemote) - var ntile = tile - if(ntile != null) - { - if(converted)//perform client conversion - { - ntile.partList(0).invalidateConvertedTile() - world.setBlock(pos.x, pos.y, pos.z, MultipartProxy.block, 0, 0) - silentAddTile(world, pos, ntile) - PacketCustom.sendToChunk(new S23PacketBlockChange(pos.x, pos.y, pos.z, world), world, pos.x>>4, pos.z>>4) - ntile.partList(0).onConverted() - ntile.writeAddPart(ntile.partList(0)) - } - - val tileTraits = tileTraitMap(tile.getClass) - partTraits = partTraits.filter(!tileTraits(_)) - if(!partTraits.isEmpty) - { - ntile = factory.generateTile(partTraits++tileTraits, world.isRemote) - tile.setValid(false) - silentAddTile(world, pos, ntile) - ntile.from(tile) - } - } - else - { - world.setBlock(pos.x, pos.y, pos.z, MultipartProxy.block, 0, 0) - ntile = factory.generateTile(partTraits, world.isRemote) - silentAddTile(world, pos, ntile) - } - ntile.addPart_impl(part) - return ntile - } - - /** - * Adds a tile entity to the world without notifying neighbor blocks or adding it to the tick list - */ - def silentAddTile(world:World, pos:BlockCoord, tile:TileEntity) - { - val chunk = world.getChunkFromBlockCoords(pos.x, pos.z) - if(chunk != null) - chunk.func_150812_a(pos.x & 15, pos.y, pos.z & 15, tile) - } - - /** - * Check if tile satisfies all the interfaces required by parts. If not, return a new generated copy of tile - */ - private[multipart] def generateCompositeTile(tile:TileEntity, parts:Seq[TMultiPart], client:Boolean):TileMultipart = - { - val partTraits = parts.flatMap(traitsForPart(_, client)).distinct - if(tile != null && tile.isInstanceOf[TileMultipart]) - { - val tileTraits = tileTraitMap(tile.getClass) - if(partTraits.forall(tileTraits(_)) && partTraits.size == tileTraits.size)//equal contents - return tile.asInstanceOf[TileMultipart] - - } - return factory.generateTile(partTraits, client) - } - - /** - * Check if there are any redundant interfaces on tile, if so, replace tile with new copy - */ - private[multipart] def partRemoved(tile:TileMultipart, part:TMultiPart):TileMultipart = - { - val client = tile.getWorldObj.isRemote - val partTraits = tile.partList.flatMap(traitsForPart(_, client)) - val testSet = partTraits.toSet - if(!traitsForPart(part, client).forall(testSet(_))) - { - val ntile = factory.generateTile(testSet.toSeq, client) - tile.setValid(false) - silentAddTile(tile.getWorldObj, new BlockCoord(tile), ntile) - ntile.from(tile) - ntile.notifyTileChange() - return ntile - } - return tile - } - - /** - * register s_trait to be applied to tiles containing parts implementing s_interface - */ - def registerTrait(s_interface:String, s_trait:String):Unit = registerTrait(s_interface, s_trait, s_trait) - - /** - * register traits to be applied to tiles containing parts implementing s_interface - * s_trait for server worlds (may be null) - * c_trait for client worlds (may be null) - */ - def registerTrait(s_interface:String, c_trait:String, s_trait:String) - { - if(c_trait != null) - { - if(interfaceTraitMap_c.contains(s_interface)) - System.err.println("Trait already registered for "+s_interface) - else - { - interfaceTraitMap_c = interfaceTraitMap_c+(s_interface->c_trait) - factory.registerTrait(s_interface, c_trait, true) - } - } - if(s_trait != null) - { - if(interfaceTraitMap_s.contains(s_interface)) - System.err.println("Trait already registered for "+s_interface) - else - { - interfaceTraitMap_s = interfaceTraitMap_s+(s_interface->s_trait) - factory.registerTrait(s_interface, s_trait, false) - } - } - } - - def registerPassThroughInterface(s_interface:String):Unit = registerPassThroughInterface(s_interface, true, true) - - /** - * A passthrough interface, is an interface to be implemented on the container tile instance, for which all calls are passed directly to the single implementing part. - * Registering a passthrough interface is equivalent to defining a mixin class as follows. - * 1. field 'impl' which contains the reference to the corresponding part - * 2. occlusionTest is overriden to prevent more than one part with s_interface existing in the block space - * 3. implementing s_interface and passing all calls directly to the part instance. - * - * This allows compatibility with APIs that expect interfaces on the tile entity. - */ - def registerPassThroughInterface(s_interface:String, client:Boolean, server:Boolean) - { - val tType = factory.generatePassThroughTrait(s_interface) - if(tType == null) - return - - if(client) - { - if(interfaceTraitMap_c.contains(s_interface)) - System.err.println("Trait already registered for "+s_interface) - else - interfaceTraitMap_c = interfaceTraitMap_c+(s_interface->tType) - } - if(server) - { - if(interfaceTraitMap_s.contains(s_interface)) - System.err.println("Trait already registered for "+s_interface) - else - interfaceTraitMap_s = interfaceTraitMap_s+(s_interface->tType) - } - } - - private[multipart] def registerTileClass(clazz:Class[_ <: TileEntity], traits:Set[String]) - { - tileTraitMap=tileTraitMap+(clazz->traits) - MultipartProxy.onTileClassBuilt(clazz) - } -} \ No newline at end of file diff --git a/codechicken/multipart/MultipartHelper.scala b/codechicken/multipart/MultipartHelper.scala deleted file mode 100644 index 9f32c1c..0000000 --- a/codechicken/multipart/MultipartHelper.scala +++ /dev/null @@ -1,68 +0,0 @@ -package codechicken.multipart - -import net.minecraft.tileentity.TileEntity -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.world.World -import codechicken.multipart.handler.MultipartSaveLoad -import com.google.common.collect.LinkedListMultimap -import scala.collection.JavaConversions._ -import codechicken.multipart.handler.MultipartSPH -import net.minecraft.world.WorldServer -import java.util.Arrays - -/** - * Static helper class for handling the unusual way that multipart tile entities load from nbt and send description packets - *
- * Multipart tile entities will all save themselves with the id "savedMultipart" which if normally loaded by minecraft, - * will create a dummy tile entity which just holds the NBT it was read from. These dummies are then converted to actual container tiles on the ChunkLoad event. - * The createTileFromNBT function should be used to construct a multipart tile from NBT without the ChunkLoad event. - *
- * Multipart tile entities do not send description packets via the conventional means of one packet per tile when PlayerInstance calls for it, to do so would be terribly inefficient. - * Instead, the ChunkWatch event is used to batch all the describing data for a chunk into one packet which is compressed using relative positions. - * The sendDescPacket(s) functions should be used to send the description packet of a tile or tiles without a ChunkWatch event. - *
- * An example of using this class to move blocks/tile entites around can be found at www.chickenbones.craftsaddle.org/Files/Other/ItemDevTool2.java - */ -object MultipartHelper -{ - /*val f_playersInChunk = classOf[PlayerInstance].getDeclaredField( - new ObfMapping("net/minecraft/server/management/PlayerInstance", "playersInChunk", "Ljava/util/List;") - .toRuntime.s_name) - f_playersInChunk.setAccessible(true) - - def playersInChunk(inst:PlayerInstance) = f_playersInChunk.get(inst).asInstanceOf[List[_]]*/ - - def createTileFromNBT(world:World, tag:NBTTagCompound):TileEntity = { - if(!tag.getString("id").equals("savedMultipart")) - return null - - MultipartSaveLoad.loadingWorld = world - return TileMultipart.createFromNBT(tag) - } - - /** - * Note. This method should only be used to send tiles that have been created on the server mid-game via an NBT load to clients. - */ - def sendDescPacket(world:World, tile:TileEntity) { - val c = world.getChunkFromBlockCoords(tile.xCoord, tile.zCoord) - val pkt = MultipartSPH.getDescPacket(c, Arrays.asList(tile).iterator) - if(pkt != null) - pkt.sendToChunk(world, c.xPosition, c.zPosition) - } - - /* Removed for compilation until PlayerInstance access transformer is pulled in forge - def sendDescPackets(world:World, tiles:Iterable[TileEntity]) { - val map = LinkedListMultimap.create[Long, TileEntity]() - tiles.filter(_.isInstanceOf[TileMultipart]).foreach(t => map.put(t.xCoord.toLong<<32|t.zCoord, t)) - - val mgr = world.asInstanceOf[WorldServer].getPlayerManager - map.asMap.entrySet.foreach{e => - val coord = e.getKey - val c = world.getChunkFromBlockCoords((coord>>32).toInt, coord.toInt) - lazy val pkt = MultipartSPH.getDescPacket(c, e.getValue.iterator) - val inst = mgr.getOrCreateChunkWatcher(c.xPosition, c.zPosition, false) - if(!inst.playersWatchingChunk.isEmpty) - inst.sendToAllPlayersWatchingChunk(pkt.toPacket) - } - }*/ -} \ No newline at end of file diff --git a/codechicken/multipart/MultipartRenderer.scala b/codechicken/multipart/MultipartRenderer.scala deleted file mode 100644 index 45947cb..0000000 --- a/codechicken/multipart/MultipartRenderer.scala +++ /dev/null @@ -1,74 +0,0 @@ -package codechicken.multipart - -import codechicken.lib.render.CCRenderState -import codechicken.lib.vec.Vector3 -import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler -import cpw.mods.fml.client.registry.RenderingRegistry -import net.minecraft.block.Block -import net.minecraft.client.renderer.{Tessellator, RenderBlocks} -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer -import net.minecraft.tileentity.TileEntity -import net.minecraft.world.IBlockAccess -import net.minecraft.client.Minecraft -import cpw.mods.fml.relauncher.SideOnly -import cpw.mods.fml.relauncher.Side -import codechicken.lib.raytracer.ExtendedMOP -import codechicken.lib.lighting.LightMatrix - -/** - * Internal class for rendering callbacks. Should be moved to the handler package - */ -@SideOnly(Side.CLIENT) -object MultipartRenderer extends TileEntitySpecialRenderer with ISimpleBlockRenderingHandler -{ - TileMultipart.renderID = RenderingRegistry.getNextAvailableRenderId - var pass:Int = 0 - - override def renderTileEntityAt(t:TileEntity, x:Double, y:Double, z:Double, f:Float) - { - val tmpart = t.asInstanceOf[TileMultipartClient] - if(tmpart.partList.isEmpty) - return - - CCRenderState.reset() - CCRenderState.pullLightmap() - CCRenderState.useNormals = true - - val pos = new Vector3(x, y, z) - tmpart.renderDynamic(pos, f, pass) - } - - override def getRenderId = TileMultipart.renderID - - override def renderWorldBlock(world:IBlockAccess, x:Int, y:Int, z:Int, block:Block, modelId:Int, renderer:RenderBlocks):Boolean = - { - val t = world.getTileEntity(x, y, z) - if(!t.isInstanceOf[TileMultipartClient]) - return false - - val tmpart = t.asInstanceOf[TileMultipartClient] - if(tmpart.partList.isEmpty) - return false - - if(renderer.hasOverrideBlockTexture) - { - val hit = Minecraft.getMinecraft.objectMouseOver - if(hit != null && hit.blockX == x && hit.blockY == y && hit.blockZ == z && ExtendedMOP.getData(hit).isInstanceOf[(_, _)]) - { - val hitInfo:(Int, _) = ExtendedMOP.getData(hit) - if(hitInfo._1.isInstanceOf[Int] && hitInfo._1 >= 0 && hitInfo._1 < tmpart.partList.size) - tmpart.partList(hitInfo._1).drawBreaking(renderer) - } - return false - } - - CCRenderState.reset() - CCRenderState.lightMatrix.locate(world, x, y, z) - return tmpart.renderStatic(new Vector3(x, y, z), pass) - } - - override def renderInventoryBlock(block:Block, meta:Int, modelId:Int, renderer:RenderBlocks) {} - - - def shouldRender3DInInventory(modelId:Int) = false -} diff --git a/codechicken/multipart/PacketScheduler.scala b/codechicken/multipart/PacketScheduler.scala deleted file mode 100644 index 90e3a30..0000000 --- a/codechicken/multipart/PacketScheduler.scala +++ /dev/null @@ -1,82 +0,0 @@ -package codechicken.multipart - -import scala.collection.mutable.{Map => MMap} -import codechicken.lib.data.MCDataOutput -import codechicken.lib.data.MCDataInput - -/** - * Static class for packing update data. - * When a specific property of a part changes and needs sending to the client, a bit can be set in the mask. - * This bit can then be checked in the writeScheduled callback. - * This prevents sending multiple packets if the same property updates more than once per tick. - */ -object PacketScheduler -{ - private val map = MMap[TMultiPart, Long]() - - /** - * Add bits to the current update mask for part. (binary OR) - */ - def schedulePacket(part:TMultiPart, mask:Long) { - if(part.world.isRemote) - throw new IllegalArgumentException("Cannot use PacketScheduler on a client world") - - map.put(part, map.getOrElse(part, 0L)|mask) - } - - private[multipart] def sendScheduled() { - map.foreach{ e => - val (part, mask) = e - if(part.tile != null) { - val ipart = part.asInstanceOf[IScheduledPacketPart] - val w = part.getWriteStream - ipart.maskWidth match { - case 1 => w.writeByte(mask.toInt) - case 2 => w.writeShort(mask.toInt) - case 4 => w.writeInt(mask.toInt) - case 8 => w.writeLong(mask) - } - - ipart.writeScheduled(mask, w) - } - } - map.clear() - } -} - -/** - * Callback interface for PacketScheduler - */ -trait IScheduledPacketPart -{ - /** - * Write scheduled data to the packet, mask is the cumulative mask from calls to schedulePacket - */ - def writeScheduled(mask:Long, packet:MCDataOutput) - - /** - * Returns the width (in bytes) of the data type required to hold all valid mask bits. Valid values are 1, 2, 4 and 8 - */ - def maskWidth:Int - - /** - * Read data matching mask. Estiablishes a method for subclasses to override. This should be called from read - */ - def readScheduled(mask:Long, packet:MCDataInput) -} - -trait TScheduledPacketPart extends TMultiPart with IScheduledPacketPart -{ - final override def read(packet:MCDataInput) { - val mask = maskWidth match { - case 1 => packet.readUByte - case 2 => packet.readUShort - case 4 => packet.readInt - case 8 => packet.readLong - } - readScheduled(mask, packet) - } - - def writeScheduled(mask:Long, packet:MCDataOutput){} - def readScheduled(mask:Long, packet:MCDataInput){} -} \ No newline at end of file diff --git a/codechicken/multipart/PartMap.java b/codechicken/multipart/PartMap.java deleted file mode 100644 index 9100ec9..0000000 --- a/codechicken/multipart/PartMap.java +++ /dev/null @@ -1,134 +0,0 @@ -package codechicken.multipart; - -/** - * Defines what each slot in a multipart tile corresponds to and provides some utility functions. - * For performance reasons, it is recommended that integer constants be useds as opposed to this enum - */ -public enum PartMap -{ - BOTTOM(0), - TOP(1), - NORTH(2), - SOUTH(3), - WEST(4), - EAST(5), - CENTER(6), - CORNER_NNN(7),//0 - CORNER_NPN(8),//1 - CORNER_NNP(9),//2 - CORNER_NPP(10),//3 - CORNER_PNN(11),//4 - CORNER_PPN(12),//5 - CORNER_PNP(13),//6 - CORNER_PPP(14),//7 - EDGE_NYN(15),//0 - EDGE_NYP(16),//1 - EDGE_PYN(17),//2 - EDGE_PYP(18),//3 - EDGE_NNZ(19),//4 - EDGE_PNZ(20),//5 - EDGE_NPZ(21),//6 - EDGE_PPZ(22),//7 - EDGE_XNN(23),//8 - EDGE_XPN(24),//9 - EDGE_XNP(25),//10 - EDGE_XPP(26);//11 - - public final int i; - public final int mask; - - private PartMap(int i) - { - this.i = i; - mask = 1<>2) - { - case 0: return 6; - case 1: return 5; - case 2: return 3; - } - throw new IllegalArgumentException("Switch Falloff"); - } - - /** - * Unpacks an edge index, to a mask where high values indicate positive positions in that axis. - * Note the parameter e is relative to the first edge slot and can range from 0-11 - * For example, edge 1 (slot 16), is EDGE_NYP so the mask returned would be 010 as z is positive. - */ - public static int unpackEdgeBits(int e) - { - switch(e>>2) - { - case 0: return (e&3)<<1; - case 1: return (e&2)>>1|(e&1)<<2; - case 2: return (e&3); - } - throw new IllegalArgumentException("Switch Falloff"); - } - - /** - * Repacks a mask of axis bits indicating positive positions, into an edge in along the same axis as e. - * Note the parameter e is relative to the first edge slot and can range from 0-11 - */ - public static int packEdgeBits(int e, int bits) - { - switch(e>>2) - { - case 0: return e&0xC|bits>>1; - case 1: return e&0xC|(bits&4)>>2|(bits&1)<<1; - case 2: return e&0xC|bits&3; - } - throw new IllegalArgumentException("Switch Falloff"); - } - - private static int[] edgeBetweenMap = new int[]{ - -1, -1, 8, 10, 4, 5, - -1, -1, 9, 11, 6, 7, - -1, -1,-1, -1, 0, 2, - -1, -1,-1, -1, 1, 3}; - - /** - * Returns the slot of the edge between 2 sides. - */ - public static int edgeBetween(int s1, int s2) - { - if(s2 < s1) - return edgeBetween(s2, s1); - if((s1&6) == (s2&6)) - throw new IllegalArgumentException("Faces "+s1+" and "+s2+" are opposites"); - return 15+edgeBetweenMap[s1*6+s2]; - } -} diff --git a/codechicken/multipart/TCuboidPart.scala b/codechicken/multipart/TCuboidPart.scala deleted file mode 100644 index 7535dba..0000000 --- a/codechicken/multipart/TCuboidPart.scala +++ /dev/null @@ -1,37 +0,0 @@ -package codechicken.multipart - -import codechicken.lib.vec.Cuboid6 -import codechicken.lib.raytracer.IndexedCuboid6 -import net.minecraft.client.renderer.RenderBlocks -import codechicken.lib.render.{BlockRenderer, CCRenderState, RenderUtils} -import scala.collection.JavaConversions._ -import java.lang.Iterable -import codechicken.lib.vec.Translation -import codechicken.lib.render.uv.IconTransformation - -/** - * Java class implementation - */ -abstract class JCuboidPart extends TCuboidPart - -/** - * Trait for parts that are simply a cuboid, having one bounding box. Overrides multipart functions to this effect. - */ -trait TCuboidPart extends TMultiPart -{ - /** - * Return the bounding Cuboid6 for this part. - */ - def getBounds:Cuboid6 - - override def getSubParts:Iterable[IndexedCuboid6] = Seq(new IndexedCuboid6(0, getBounds)) - - override def getCollisionBoxes:Iterable[Cuboid6] = Seq(getBounds) - - override def drawBreaking(renderBlocks:RenderBlocks) - { - CCRenderState.reset() - CCRenderState.setPipeline(new Translation(x, y, z), new IconTransformation(renderBlocks.overrideBlockTexture)) - BlockRenderer.renderCuboid(getBounds, 0) - } -} \ No newline at end of file diff --git a/codechicken/multipart/TEdgePart.scala b/codechicken/multipart/TEdgePart.scala deleted file mode 100644 index c8e8e88..0000000 --- a/codechicken/multipart/TEdgePart.scala +++ /dev/null @@ -1,12 +0,0 @@ -package codechicken.multipart - -/** - * Interface which must be implemented by parts that go in an edge slot. - */ -trait TEdgePart extends TSlottedPart -{ - /** - * Return true if this part can conduct redstone signal or let redstone signal pass through it. - */ - def conductsRedstone = false -} \ No newline at end of file diff --git a/codechicken/multipart/TFacePart.scala b/codechicken/multipart/TFacePart.scala deleted file mode 100644 index bb97b1a..0000000 --- a/codechicken/multipart/TFacePart.scala +++ /dev/null @@ -1,16 +0,0 @@ -package codechicken.multipart - -/** - * Inteface which must be implemented by parts that go in a face part. - */ -trait TFacePart extends TSlottedPart -{ - /** - * Passed down from Block.isBlockSolidOnSide. Return true if this part is solid and opaque on the specified side - */ - def solid(side:Int):Boolean = true - /** - * Return the redstone conduction map for which signal can pass through this part on the face. Eg, hollow covers return 0xF as signal can pass through the center hole. - */ - def redstoneConductionMap = 0 -} \ No newline at end of file diff --git a/codechicken/multipart/TIconHitEffects.scala b/codechicken/multipart/TIconHitEffects.scala deleted file mode 100644 index 98cee95..0000000 --- a/codechicken/multipart/TIconHitEffects.scala +++ /dev/null @@ -1,81 +0,0 @@ -package codechicken.multipart - -import codechicken.lib.vec.Cuboid6 -import cpw.mods.fml.relauncher.SideOnly -import cpw.mods.fml.relauncher.Side -import net.minecraft.util.IIcon -import net.minecraft.util.MovingObjectPosition -import net.minecraft.client.particle.EffectRenderer -import codechicken.lib.vec.Vector3 -import codechicken.lib.raytracer.ExtendedMOP -import codechicken.lib.render.EntityDigIconFX - -/** - * This suite of 3 classes provides simple functions for standard minecraft style hit and break particles. - * - * Scala|Java composition setup. - * Due to the lack of mixin inheritance in Java, the classes are structured to suit both languages as follows. - * IconHitEffects contains static implementations of the functions that would be overriden in TMultiPart - * JIconHitEffects is the interface that should be implemented by a Java class, - * which can then override the functions in TMultipart and call the static methods in IconHitEffects with 'this' as the first parameter - * TIconHitEffects is a trait for scala implementors that does includes the overrides/static calls that Java programmers need to include themselves. - */ -object IconHitEffects -{ - def addHitEffects(part:JIconHitEffects, hit:MovingObjectPosition, effectRenderer:EffectRenderer) - { - EntityDigIconFX.addBlockHitEffects(part.tile.getWorldObj, - part.getBounds.copy.add(Vector3.fromTileEntity(part.tile)), hit.sideHit, - part.getBreakingIcon(ExtendedMOP.getData(hit), hit.sideHit), effectRenderer) - } - - def addDestroyEffects(part:JIconHitEffects, effectRenderer:EffectRenderer) - { - addDestroyEffects(part, effectRenderer, true) - } - - def addDestroyEffects(part:JIconHitEffects, effectRenderer:EffectRenderer, scaleDensity:Boolean) - { - val icons = new Array[IIcon](6) - for(i <- 0 until 6) - icons(i) = part.getBrokenIcon(i) - val bounds = - if(scaleDensity) part.getBounds.copy - else Cuboid6.full.copy - EntityDigIconFX.addBlockDestroyEffects(part.tile.getWorldObj, - bounds.add(Vector3.fromTileEntity(part.tile)), icons, effectRenderer) - } -} - -/** - * Java interface containing callbacks for particle rendering. - * Make sure to override addHitEffects and addDestroyEffects as in TIconHitEffects - */ -trait JIconHitEffects extends TMultiPart -{ - def getBounds:Cuboid6 - - @SideOnly(Side.CLIENT) - def getBreakingIcon(subPart:Any, side:Int):IIcon = getBrokenIcon(side) - - @SideOnly(Side.CLIENT) - def getBrokenIcon(side:Int):IIcon -} - -/** - * Trait for scala programmers - */ -trait TIconHitEffects extends JIconHitEffects -{ - @SideOnly(Side.CLIENT) - override def addHitEffects(hit:MovingObjectPosition, effectRenderer:EffectRenderer) - { - IconHitEffects.addHitEffects(this, hit, effectRenderer) - } - - @SideOnly(Side.CLIENT) - override def addDestroyEffects(effectRenderer:EffectRenderer) - { - IconHitEffects.addDestroyEffects(this, effectRenderer) - } -} \ No newline at end of file diff --git a/codechicken/multipart/TMultiPart.scala b/codechicken/multipart/TMultiPart.scala deleted file mode 100644 index b4c3020..0000000 --- a/codechicken/multipart/TMultiPart.scala +++ /dev/null @@ -1,299 +0,0 @@ -package codechicken.multipart - -import codechicken.lib.vec.Cuboid6 -import codechicken.lib.vec.Vector3 -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.MovingObjectPosition -import codechicken.lib.raytracer.IndexedCuboid6 -import cpw.mods.fml.relauncher.SideOnly -import cpw.mods.fml.relauncher.Side -import net.minecraft.client.particle.EffectRenderer -import net.minecraft.client.renderer.RenderBlocks -import codechicken.lib.vec.BlockCoord -import net.minecraft.tileentity.TileEntity -import codechicken.lib.lighting.LightMatrix -import codechicken.lib.data.MCDataOutput -import codechicken.lib.data.MCDataInput -import net.minecraft.entity.Entity -import java.lang.Iterable -import scala.collection.JavaConversions._ -import net.minecraft.util.Vec3 -import codechicken.lib.raytracer.ExtendedMOP -import codechicken.lib.raytracer.RayTracer - -abstract class TMultiPart -{ - /** - * Reference to the container TileMultipart instance - */ - var tile:TileMultipart = _ - - /** - * Legacy helper function for getting the tile entity (from when TileMultipart was a trait). Use tile() now. - */ - @Deprecated - def getTile:TileEntity = tile - /** - * Getter for tile.worldObj - */ - def world = if(tile == null) null else tile.getWorldObj - /** - * Short getter for xCoord - */ - def x = tile.xCoord - /** - * Short getter for yCoord - */ - def y = tile.yCoord - /** - * Short getter for zCoord - */ - def z = tile.zCoord - - /** - * The unique string identifier for this class of multipart. - */ - def getType:String - /** - * Called when the container tile instance is changed to update reference - */ - def bind(t:TileMultipart) - { - tile = t - } - - /** - * Perform an occlusion test to determine whether this and npart can 'fit' in this block space. - */ - def occlusionTest(npart:TMultiPart):Boolean = true - /** - * Return a list of entity collision boxes. - * Note all Cuboid6's returned by methods in TMultiPart should be within (0,0,0)->(1,1,1) - */ - def getCollisionBoxes:Iterable[Cuboid6] = Seq() - /** - * Perform a raytrace of this part. The default implementation does a Cuboid6 ray trace on bounding boxes returned from getSubParts. - * This should only be overridden if you need special ray-tracing capabilities such as triangular faces. - * The returned ExtendedMOP will be passed to methods such as 'activate' so it is recommended to use the data field to indicate information about the hit area. - */ - def collisionRayTrace(start: Vec3, end: Vec3): ExtendedMOP = { - val offset = new Vector3(x, y, z) - val boxes = getSubParts.map(c => new IndexedCuboid6(c.data, c.copy.add(offset))) - return RayTracer.instance.rayTraceCuboids(new Vector3(start), new Vector3(end), boxes.toList, - new BlockCoord(x, y, z), tile.getBlockType).asInstanceOf[ExtendedMOP] - } - /** - * For the default collisionRayTrace implementation, returns a list of indexed bounding boxes. The data field of ExtendedMOP will be set to the index of the cuboid the raytrace hit. - */ - def getSubParts:Iterable[IndexedCuboid6] = Seq() - - /** - * Return a list of items that should be dropped when this part is destroyed. - */ - def getDrops:Iterable[ItemStack] = Seq() - /** - * Return a value indicating how hard this part is to break - * @param hit An instance of ExtendedMOP from collisionRayTrace - */ - def getStrength(hit:MovingObjectPosition, player:EntityPlayer):Float = 1 - /** - * Harvest this part, removing it from the container tile and dropping items if necessary. - * @param hit An instance of ExtendedMOP from collisionRayTrace - * @param player The player harvesting the part - */ - def harvest(hit:MovingObjectPosition, player:EntityPlayer) - { - if(!player.capabilities.isCreativeMode) - tile.dropItems(getDrops) - tile.remPart(this) - } - /** - * The light level emitted by this part - */ - def getLightValue = 0 - - /** - * Explosion resistance of the host tile is the maximum explosion resistance of the contained parts - * @param entity The entity responsible for this explosion - * @return The resistance of this part the the explosion - */ - def explosionResistance(entity:Entity) = 0F - - /** - * Add particles and other effects when a player is mining this part - * @param hit An instance of ExtendedMOP from collisionRayTrace - */ - @SideOnly(Side.CLIENT) - def addHitEffects(hit:MovingObjectPosition, effectRenderer:EffectRenderer){} - /** - * Add particles and other effects when a player broke this part - * @param hit An instance of ExtendedMOP from collisionRayTrace - */ - @SideOnly(Side.CLIENT) - def addDestroyEffects(hit:MovingObjectPosition, effectRenderer:EffectRenderer) {addDestroyEffects(effectRenderer)} - - @SideOnly(Side.CLIENT) - @Deprecated - def addDestroyEffects(effectRenderer:EffectRenderer){} - /** - * Render the static, unmoving faces of this part into the world renderer. - * The Tessellator is already drawing. - * @param pass The render pass, 1 or 0 - * @return true if vertices were added to the tessellator - */ - @SideOnly(Side.CLIENT) - def renderStatic(pos:Vector3, pass:Int) = false - /** - * Render the dynamic, changing faces of this part and other gfx as in a TESR. - * The Tessellator will need to be started if it is to be used. - * @param pos The position of this block space relative to the renderer, same as x, y, z passed to TESR. - * @param frame The partial interpolation frame value for animations between ticks - * @param pass The render pass, 1 or 0 - */ - @SideOnly(Side.CLIENT) - def renderDynamic(pos:Vector3, frame:Float, pass:Int){} - /** - * Draw the breaking overlay for this part. The overrideIcon in RenderBlocks will be set to the fracture icon. - */ - @SideOnly(Side.CLIENT) - def drawBreaking(renderBlocks:RenderBlocks){} - /** - * Override the drawing of the selection box around this part. - * @param hit An instance of ExtendedMOP from collisionRayTrace - * @return true if highlight rendering was overridden. - */ - @SideOnly(Side.CLIENT) - def drawHighlight(hit:MovingObjectPosition, player:EntityPlayer, frame:Float):Boolean = false - /** - * @return A Cuboid6 bounding the render of this part for frustum culling. The bounds are relative to the tile coordinates. - */ - def getRenderBounds = Cuboid6.full - - /** - * Write all the data required to describe a client version of this part to the packet. - * Called serverside, when a client loads this part for the first time. - */ - def writeDesc(packet:MCDataOutput){} - /** - * Fill out this part with the description information contained in packet. Will be exactly as written from writeDesc. - * Called clientside when a client loads this part for the first time. - */ - def readDesc(packet:MCDataInput){} - /** - * Save part to NBT (only called serverside) - */ - def save(tag:NBTTagCompound){} - /** - * Load part from NBT (only called serverside) - */ - def load(tag:NBTTagCompound){} - /** - * Gets a MCDataOutput instance for writing update data to clients with this part loaded. - * The write stream functions as a buffer which is flushed in a compressed databurst packet at the end of the tick. - */ - def getWriteStream:MCDataOutput = tile.getWriteStream(this) - /** - * Read and operate on data written to getWriteStream. Ensure all data this part wrote is read even if it's not going to be used. - * The default implementation assumes a call to sendDescUpdate as the only use of getWriteStream. - */ - def read(packet:MCDataInput) - { - readDesc(packet) - tile.markRender() - } - /** - * Quick and easy method to re-describe the whole part on the client. This will call read on the client which calls readDesc unless overriden. - * Incremental changes should be sent rather than the whole description packet if possible. - */ - def sendDescUpdate() = writeDesc(getWriteStream) - - /** - * Called when a part is added or removed from this block space. - * The part parameter may be null if several things have changed. - */ - def onPartChanged(part:TMultiPart){} - /** - * Called when a neighbor block changed - */ - def onNeighborChanged(){} - /** - * Called when this part is added to the block space - */ - def onAdded() = onWorldJoin() - /** - * Called when this part is removed from the block space - */ - def onRemoved() = onWorldSeparate() - /** - * Called when the containing chunk is loaded on the server. - */ - def onChunkLoad() = onWorldJoin() - /** - * Called when the containing chunk is unloaded on the server. - */ - def onChunkUnload() = onWorldSeparate() - /** - * Called when this part separates from the world (due to removal, chunk unload or other). Use this to sync with external data structures. - */ - def onWorldSeparate(){} - /** - * Called when this part separates from the world (due to removal, chunk unload or other). Use this to sync with external data structures. - */ - def onWorldJoin(){} - /** - * Called when this part is converted from a normal block/tile (only applicable if a converter has been registered) - */ - def onConverted() = onAdded() - /** - * Called when this part is converted from a normal block/tile (only applicable if a converter has been registered) before the original tile has been replaced - * Use this to clear out things like inventory from the old tile. - */ - def invalidateConvertedTile(){} - /** - * Called when this part has been moved without a save/load. - */ - def onMoved() = onWorldJoin() - /** - * Called just before this part is actually removed from the container tile - */ - def preRemove(){} - - /** - * Return whether this part needs update ticks. This will only be called on addition/removal so it should be a constant for this instance. - */ - def doesTick = true - /** - * Called once per world tick. This will be called even if doesTick returns false if another part in the space needs ticks. - */ - def update(){} - /** - * Called when a scheduled tick is executed. - */ - def scheduledTick(){} - /** - * Sets a scheduledTick callback for this part ticks in the future. This is a world time value, so if the chunk is unloaded and reloaded some time later, the tick may fire immediately. - */ - def scheduleTick(ticks:Int) = TickScheduler.scheduleTick(this, ticks) - - /** - * Return the itemstack for the middle click pick-block function. - */ - def pickItem(hit:MovingObjectPosition):ItemStack = null - /** - * Called on block right click. item is the player's held item. - * This should not modify the part client side. If the client call returns false, the server will not call this function. - * @param hit An instance of ExtendedMOP from collisionRayTrace - */ - def activate(player:EntityPlayer, hit:MovingObjectPosition, item:ItemStack) = false - /** - * Called on block left click. item is the player's held item. - * @param hit An instance of ExtendedMOP from collisionRayTrace - */ - def click(player:EntityPlayer, hit:MovingObjectPosition, item:ItemStack){} - /** - * Called when an entity is within this block space. May not actually collide with this part. - */ - def onEntityCollision(entity:Entity){} -} \ No newline at end of file diff --git a/codechicken/multipart/TNormalOcclusion.scala b/codechicken/multipart/TNormalOcclusion.scala deleted file mode 100644 index a6b2e5a..0000000 --- a/codechicken/multipart/TNormalOcclusion.scala +++ /dev/null @@ -1,68 +0,0 @@ -package codechicken.multipart - -import codechicken.lib.vec.Cuboid6 -import scala.collection.JavaConversions._ -import java.lang.Iterable - -/** - * This suite of 3 classes provides simple functions for standard bounding box based occlusion testing. - * If any two parts have overlapping bounding boxes, the test fails - * - * See TIconHitEffects for notes on the Scala|Java composition setup. - */ -object NormalOcclusionTest -{ - /** - * Performs the test, returns true if the test fails - */ - def apply(boxes1:Traversable[Cuboid6], boxes2:Traversable[Cuboid6]):Boolean = - boxes1.forall(v1 => boxes2.forall(v2 => !v1.intersects(v2))) - - /** - * Performs the test, returns true if the test fails - */ - def apply(part1:JNormalOcclusion, part2:TMultiPart):Boolean = - { - var boxes = Seq[Cuboid6]() - if(part2.isInstanceOf[JNormalOcclusion]) - boxes = boxes++part2.asInstanceOf[JNormalOcclusion].getOcclusionBoxes - - if(part2.isInstanceOf[JPartialOcclusion]) - boxes = boxes++part2.asInstanceOf[JPartialOcclusion].getPartialOcclusionBoxes - - return NormalOcclusionTest(boxes, part1.getOcclusionBoxes) - } -} - -/** - * Java interface containing callbacks for normal occlusion testing. - * Make sure to override occlusionTest as in TNormalOcclusion - */ -trait JNormalOcclusion -{ - /** - * Return a list of normal occlusion boxes - */ - def getOcclusionBoxes:Iterable[Cuboid6] -} - -/** - * Trait for scala programmers - */ -trait TNormalOcclusion extends TMultiPart with JNormalOcclusion -{ - override def occlusionTest(npart:TMultiPart):Boolean = - NormalOcclusionTest(this, npart) && super.occlusionTest(npart) -} - -/** - * Utility part class for performing 3rd party occlusion tests - */ -class NormallyOccludedPart(bounds:Iterable[Cuboid6]) extends TMultiPart with TNormalOcclusion -{ - def this(bound:Cuboid6) = this(Seq(bound)) - - def getType = null - - def getOcclusionBoxes = bounds -} \ No newline at end of file diff --git a/codechicken/multipart/TPartialOcclusion.scala b/codechicken/multipart/TPartialOcclusion.scala deleted file mode 100644 index c0b1c79..0000000 --- a/codechicken/multipart/TPartialOcclusion.scala +++ /dev/null @@ -1,76 +0,0 @@ -package codechicken.multipart - -import codechicken.lib.vec.Cuboid6 -import scala.collection.JavaConversions._ -import java.lang.Iterable - -/** - * This class provides a special type of occlusion model used by microblocks. - * The partial occlusion test defines bounding boxes that may intersect, so long as no part is completely obscured by a combination of the others. - * Partial bounding boxes may not intersect with normal bounding boxes from NormalOcclusionTest - * - * This test is actually managed by the mixin trait TPartialOcclusionTile which is generated when the marker interface JPartialOcclusion is found - */ -class PartialOcclusionTest(size:Int) -{ - /** - * The resolution of the test, set to 1/8th of a block - */ - val res = 8 - val bits = new Array[Byte](res*res*res) - val partial = new Array[Boolean](size) - - def fill(i:Int, part:JPartialOcclusion) - { - fill(i, part.getPartialOcclusionBoxes, part.allowCompleteOcclusion) - } - - def fill(i:Int, boxes:Iterable[Cuboid6], complete:Boolean) - { - partial(i) = !complete - boxes.foreach(box => fill(i+1, box)) - } - - def fill(v:Int, box:Cuboid6) - { - for(x <- (box.min.x*res+0.5).toInt until (box.max.x*res+0.5).toInt) - for(y <- (box.min.y*res+0.5).toInt until (box.max.y*res+0.5).toInt) - for(z <- (box.min.z*res+0.5).toInt until (box.max.z*res+0.5).toInt) - { - val i = (x*res+y)*res+z - if(bits(i) == 0) - bits(i) = v.toByte - else - bits(i) = -1 - } - } - - def apply():Boolean = - { - val visible = new Array[Boolean](size) - bits.foreach(n => if(n > 0) visible(n-1) = true) - - var i = 0 - while(i < partial.length) - { - if(partial(i) && !visible(i)) - return false - i+=1 - } - - return true - } -} - -trait JPartialOcclusion -{ - /** - * Return a list of partial occlusion boxes - */ - def getPartialOcclusionBoxes:Iterable[Cuboid6] - - /** - * Return true if this part may be completely obscured - */ - def allowCompleteOcclusion = false -} \ No newline at end of file diff --git a/codechicken/multipart/TSlottedPart.scala b/codechicken/multipart/TSlottedPart.scala deleted file mode 100644 index c6e75a9..0000000 --- a/codechicken/multipart/TSlottedPart.scala +++ /dev/null @@ -1,15 +0,0 @@ -package codechicken.multipart - -/** - * Interface for parts that fill a slot based configuration as defined in PartMap. - * If this is implemented, calling partMap(slot) on the host tile will return this part if the corresponding bit in the slotMask is set - * - * Marker interface for TSlottedTile - */ -trait TSlottedPart extends TMultiPart -{ - /** - * a bitmask of slots that this part fills. slot x is 1<>4, part.tile.zCoord>>4) - .asInstanceOf[ChunkTickScheduler].scheduleTick(part, time, random) - } - - def loadRandom(part:TMultiPart) = scheduleTick(part, nextRandomTick, true) - - override def preTick() - { - processing = true - } - - override def postTick() - { - if(!tickChunks.isEmpty) - tickChunks = tickChunks.filter(_.processTicks()) - - processing = false - pending.foreach(e => _scheduleTick(e.part, e.time, e.random)) - pending.clear() - - schedTime+=1 - } - - def saveDir:File = - { - if(world.provider.dimensionId == 0)//Calling DimensionManager.getCurrentSaveRootDirectory too early breaks game saves, we have a world reference, use it - return world.getSaveHandler.asInstanceOf[SaveHandler].getWorldDirectory - - return new File(DimensionManager.getCurrentSaveRootDirectory, world.provider.getSaveFolder) - } - - def saveFile:File = new File(saveDir, "multipart.dat") - - override def load() - { - try - { - val din = new DataInputStream(new FileInputStream(saveFile)) - loadTag(CompressedStreamTools.readCompressed(din)) - din.close() - } - catch - { - case e:Exception => - } - - loadTag(new NBTTagCompound) - } - - def loadTag(tag:NBTTagCompound) - { - if(tag.hasKey("schedTime")) - schedTime = tag.getLong("schedTime") - else - schedTime = world.getTotalWorldTime - } - - def saveTag:NBTTagCompound = - { - val tag = new NBTTagCompound - tag.setLong("schedTime", schedTime) - return tag - } - - override def save() { - val file = saveFile - if(!file.getParentFile.exists) - file.getParentFile.mkdirs() - if(!file.exists) - file.createNewFile() - - val dout = new DataOutputStream(new FileOutputStream(file)) - CompressedStreamTools.writeCompressed(saveTag, dout) - dout.close() - } - - def nextRandomTick = world.rand.nextInt(800)+800 - } - - def createWorldExtension(world:World):WorldExtension = new WorldTickScheduler(world) - - private class ChunkTickScheduler(chunk$:Chunk, world:WorldTickScheduler) extends ChunkExtension(chunk$, world) - { - import codechicken.multipart.handler.MultipartProxy._ - - var tickList = ListBuffer[PartTickEntry]() - - def schedTime = world.schedTime - - def scheduleTick(part:TMultiPart, time:Long, random:Boolean) - { - val it = tickList.iterator - while(it.hasNext) - { - val e = it.next() - if(e.part == part) - { - if(e.random && !random)//only override an existing tick if we're going from random->scheduled - { - e.time = time - e.random = random - } - return - } - } - tickList+=new PartTickEntry(part, time, random) - if(tickList.size == 1) - world.tickChunks+=this - } - - def nextRandomTick = world.nextRandomTick - - def processTicks():Boolean = - { - tickList = tickList.filter(processTick) - return !tickList.isEmpty - } - - def processTick(e:PartTickEntry):Boolean = - { - if(e.time <= schedTime) - { - if(e.part.tile != null) - { - if(e.random && e.part.isInstanceOf[IRandomUpdateTick]) - e.part.asInstanceOf[IRandomUpdateTick].randomUpdate() - else - e.part.scheduledTick() - - if(e.part.isInstanceOf[IRandomUpdateTick]) - { - e.time = schedTime+nextRandomTick - e.random = true - return true - } - } - return false - } - return true - } - - override def saveData(data:NBTTagCompound) - { - val tagList = new NBTTagList - tickList.foreach{e => - val part = e.part - if(part.tile != null && !e.random) - { - val tag = new NBTTagCompound - tag.setShort("pos", indexInChunk(new BlockCoord(part.tile)).toShort) - tag.setByte("i", part.tile.partList.indexOf(part).toByte) - tag.setLong("time", e.time) - tagList.appendTag(tag) - } - } - if(tagList.tagCount > 0) - data.setTag("multipartTicks", tagList) - } - - override def loadData(data:NBTTagCompound) - { - tickList.clear() - if(!data.hasKey("multipartTicks")) - return - - val tagList = data.getTagList("multipartTicks", 10) - val cc = new ChunkCoordIntPair(0, 0) - for(i <- 0 until tagList.tagCount) - { - val tag = tagList.getCompoundTagAt(i) - val pos = indexInChunk(cc, tag.getShort("pos")) - val tile = chunk.chunkTileEntityMap.get(new ChunkPosition(pos.x, pos.y, pos.z)) - if(tile.isInstanceOf[TileMultipart]) - tickList+=new PartTickEntry(tile.asInstanceOf[TileMultipart].partList(tag.getByte("i")), tag.getLong("time"), false) - } - } - - override def load() - { - val it = new ArrayList(chunk.chunkTileEntityMap.values).iterator - while(it.hasNext) - { - val t = it.next - if(t.isInstanceOf[TileMultipart]) - { - val tmp = t.asInstanceOf[TileMultipart] - tmp.onChunkLoad() - tmp.partList.foreach(p => - if(p.isInstanceOf[IRandomUpdateTick]) - world.scheduleTick(p, nextRandomTick, true)) - } - } - - if(!tickList.isEmpty) - world.tickChunks+=this - } - - override def unload() - { - if(!tickList.isEmpty) - world.tickChunks-=this - } - } - - def createChunkExtension(chunk:Chunk, world:WorldExtension):ChunkExtension = new ChunkTickScheduler(chunk, world.asInstanceOf[WorldTickScheduler]) - - private[multipart] def loadRandomTick(part:TMultiPart) - { - getExtension(part.tile.getWorldObj).asInstanceOf[WorldTickScheduler].loadRandom(part) - } - - /** - * Schedule a tick for part relative to the current time. - */ - def scheduleTick(part:TMultiPart, ticks:Int) - { - getExtension(part.tile.getWorldObj).asInstanceOf[WorldTickScheduler].scheduleTick(part, ticks, false) - } - - /** - * Returns the current scheduler time. Like the world time, but unaffected by the time set command and other things changing time of day. - * Deprecated in favor of world.getTotalWorldTime - */ - @Deprecated - def getSchedulerTime(world:World):Long = getExtension(world).asInstanceOf[WorldTickScheduler].schedTime -} \ No newline at end of file diff --git a/codechicken/multipart/TileMultipart.scala b/codechicken/multipart/TileMultipart.scala deleted file mode 100644 index e831db7..0000000 --- a/codechicken/multipart/TileMultipart.scala +++ /dev/null @@ -1,703 +0,0 @@ -package codechicken.multipart - -import net.minecraft.tileentity.TileEntity -import scala.collection.mutable.ListBuffer -import codechicken.lib.packet.PacketCustom -import codechicken.lib.vec.{Cuboid6, BlockCoord, Vector3} -import net.minecraft.world.World -import java.util.List -import net.minecraft.nbt.NBTTagCompound -import codechicken.lib.data.MCDataOutput -import codechicken.multipart.handler.{MultipartCompatiblity, MultipartProxy, MultipartSPH} -import net.minecraft.block.Block -import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagList -import java.util.Random -import codechicken.lib.lighting.LightMatrix -import net.minecraft.entity.item.EntityItem -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.entity.Entity -import scala.collection.JavaConversions._ -import java.util.Collection -import codechicken.lib.raytracer.ExtendedMOP -import net.minecraft.util.Vec3 -import java.lang.Iterable -import scala.collection.mutable.{Map => MMap} -import net.minecraft.util.AxisAlignedBB - -class TileMultipart extends TileEntity -{ - /** - * List of parts in this tile space - */ - var partList = Seq[TMultiPart]() - - private var doesTick = false - - private[multipart] def from(that:TileMultipart) - { - copyFrom(that) - loadFrom(that) - } - - /** - * This method should be used for copying all the data from the fields in that container tile. - * This method will be automatically generated on java tile traits with fields if it is not overridden. - */ - def copyFrom(that:TileMultipart) - { - partList = that.partList - doesTick = that.doesTick - } - - def loadFrom(that:TileMultipart) - { - partList.foreach(_.bind(this)) - if(doesTick) - { - doesTick = false - setTicking(true) - } - } - - /** - * Overidden in TSlottedTile when a part that goes in a slot is added - */ - def partMap(slot:Int):TMultiPart = null - - /** - * Implicit java conversion of part list - */ - def jPartList():List[TMultiPart] = partList - - override def canUpdate = doesTick - - def operate(f:(TMultiPart)=>Unit) { - val it = partList.iterator - while(it.hasNext) { - val p = it.next() - if(p.tile != null) f(p) - } - } - - override def updateEntity() - { - operate(_.update()) - } - - override def onChunkUnload() - { - operate(_.onChunkUnload()) - } - - def onChunkLoad() - { - operate(_.onChunkLoad()) - } - - final def setValid(b:Boolean) - { - if(b) - super.validate() - else - super.invalidate() - } - - def onMoved() - { - operate(_.onMoved()) - } - - override def invalidate() - { - if(!isInvalid) - { - super.invalidate() - if(worldObj != null) { - partList.foreach(_.onWorldSeparate()) - if(worldObj.isRemote) - TileMultipart.putClientCache(this) - } - } - } - - /** - * Called by parts when they have changed in some form that affects the world. - * Notifies neighbor blocks, parts that share this host and recalculates lighting - */ - def notifyPartChange(part:TMultiPart) - { - internalPartChange(part) - - worldObj.notifyBlocksOfNeighborChange(xCoord, yCoord, zCoord, MultipartProxy.block) - worldObj.func_147451_t(xCoord, yCoord, zCoord) - } - - /** - * Notifies parts sharing this host of a change - */ - def internalPartChange(part:TMultiPart) - { - operate(p => if(part != p) p.onPartChanged(part)) - } - - /** - * Notifies all parts not in the passed collection of a change from all the parts in the collection - */ - def multiPartChange(parts:Collection[TMultiPart]) - { - operate(p => if(!parts.contains(p)) parts.foreach(p.onPartChanged)) - } - - /** - * Notifies neighboring blocks that this tile has changed - */ - def notifyTileChange() - { - worldObj.func_147453_f(xCoord, yCoord, zCoord, MultipartProxy.block) - } - - def onNeighborBlockChange() - { - operate(_.onNeighborChanged()) - } - - /** - * Blank implementation, overriden by TTileChangeTile - */ - def onNeighborTileChange(tileX:Int, tileY:Int, tileZ:Int) {} - - /** - * Blank implementation, overriden by TTileChangeTile - */ - def getWeakChanges() = false - - def getLightValue = partList.view.map(_.getLightValue).max - - def getExplosionResistance(entity:Entity) = partList.view.map(_.explosionResistance(entity)).max - - /** - * Callback for parts to mark the chunk as needs saving - */ - override def markDirty() - { - worldObj.markTileEntityChunkModified(xCoord, yCoord, zCoord, this) - } - - /** - * Mark this block space for a render update. - */ - def markRender() - { - worldObj.func_147479_m(xCoord, yCoord, zCoord) - } - - /** - * Helper function for calling a second level notify on a side (eg indirect power from a lever) - */ - def notifyNeighborChange(side:Int) - { - val pos = new BlockCoord(this).offset(side) - worldObj.notifyBlocksOfNeighborChange(pos.x, pos.y, pos.z, MultipartProxy.block) - } - - def isSolid(side:Int):Boolean = - { - val part = partMap(side) - if(part != null) - return part.asInstanceOf[TFacePart].solid(side) - - return false - } - - private def setTicking(tick:Boolean) - { - if(doesTick == tick) - return - - doesTick = tick - if(worldObj != null && worldObj.getTileEntity(xCoord, yCoord, zCoord) == this) - { - if(tick) - worldObj.addTileEntity(this) - else - worldObj.func_147457_a(this) - } - } - - /** - * Returns true if part can be added to this space - */ - def canAddPart(part:TMultiPart) = - MultipartCompatiblity.canAddPart(worldObj, xCoord, yCoord, zCoord) && - !partList.contains(part) && - occlusionTest(partList, part) - - /** - * Returns true if opart can be replaced with npart (note opart and npart may be the exact same object) - * - * This function should be used for testing if a part can change it's shape (eg. rotation, expansion, cable connection) - * For example, to test whether a cable part can connect to it's neighbor: - * 1. Set the cable part's bounding boxes as if the connection is established - * 2. Call canReplacePart(part, part) - * 3. If canReplacePart succeeds, perform connection, else, revert bounding box - */ - def canReplacePart(opart:TMultiPart, npart:TMultiPart):Boolean = - { - val olist = partList.filterNot(_ == opart) - if(olist.contains(npart)) - return false - - return occlusionTest(olist, npart) - } - - /** - * Returns true if parts do not occlude npart - */ - def occlusionTest(parts:Seq[TMultiPart], npart:TMultiPart):Boolean = - { - return parts.forall(part => part.occlusionTest(npart) && npart.occlusionTest(part)) - } - - /** - * Get the write stream for updates to part - */ - def getWriteStream(part:TMultiPart):MCDataOutput = getWriteStream.writeByte(partList.indexOf(part)) - - private def getWriteStream = MultipartSPH.getTileStream(worldObj, new BlockCoord(this)) - - private[multipart] def addPart_impl(part:TMultiPart) - { - if(!worldObj.isRemote) - writeAddPart(part) - - addPart_do(part) - part.onAdded() - partAdded(part) - notifyPartChange(part) - notifyTileChange() - markDirty() - markRender() - } - - private[multipart] def writeAddPart(part:TMultiPart) - { - val stream = getWriteStream.writeByte(253) - MultiPartRegistry.writePartID(stream, part) - part.writeDesc(stream) - } - - private[multipart] def addPart_do(part:TMultiPart) - { - assert(partList.size < 250, "Tried to add more than 250 parts to the one tile. You're doing it wrong") - - partList = partList:+part - bindPart(part) - part.bind(this) - - if(!doesTick && part.doesTick) - setTicking(true) - } - - /** - * Bind this part to an internal cache. - * Provided for trait overrides, do not call externally. - */ - def bindPart(part:TMultiPart){} - - /** - * Called when a part is added (placement) - * Provided for trait overrides, do not call externally. - */ - def partAdded(part:TMultiPart) - { - if(part.isInstanceOf[IRandomUpdateTick]) - TickScheduler.loadRandomTick(part) - } - - /** - * Removes part from this tile. Note that due to the operation sync, the part may not be removed until the call stack has been passed to all other parts in the space. - */ - def remPart(part:TMultiPart):TileMultipart = - { - assert(!worldObj.isRemote, "Cannot remove multi parts from a client tile") - remPart_impl(part) - } - - private[multipart] def remPart_impl(part:TMultiPart):TileMultipart = - { - remPart_do(part, !worldObj.isRemote) - - if(!isInvalid) - { - val tile = MultipartGenerator.partRemoved(this, part) - notifyPartChange(part) - markDirty() - markRender() - return tile - } - - return null - } - - private def remPart_do(part:TMultiPart, sendPacket:Boolean):Int = - { - val r = partList.indexOf(part) - if(r < 0) - throw new IllegalArgumentException("Tried to remove a non-existant part") - - part.preRemove() - partList = partList.filterNot(_ == part) - - if(sendPacket) - getWriteStream.writeByte(254).writeByte(r) - - partRemoved(part, r) - part.onRemoved() - part.tile = null - - if(partList.isEmpty) - { - worldObj.setBlockToAir(xCoord, yCoord, zCoord) - } - else - { - if(part.doesTick && doesTick) - { - var ntick = false - partList.foreach(part => ntick |= part.doesTick) - if(!ntick) - setTicking(false) - } - } - return r - } - - /** - * Remove this part from internal cache. - * Provided for trait overrides, do not call externally. - */ - def partRemoved(part:TMultiPart, p:Int){} - - private[multipart] def loadParts(parts:ListBuffer[TMultiPart]) - { - clearParts() - parts.foreach(p => addPart_do(p)) - if(worldObj != null) { - if(worldObj.isRemote) - operate(_.onWorldJoin()) - notifyPartChange(null) - } - } - - /** - * Remove all parts from internal cache - * Provided for trait overrides, do not call externally. - */ - def clearParts() - { - partList = Seq() - } - - /** - * Writes the description of this tile, and all parts composing it, to packet - */ - def writeDesc(packet:MCDataOutput) - { - packet.writeByte(partList.size) - partList.foreach{part => - MultiPartRegistry.writePartID(packet, part) - part.writeDesc(packet) - } - } - - /** - * Perform a raytrace returning all intersecting parts sorted nearest to farthest - */ - def rayTraceAll(start:Vec3, end:Vec3):Iterable[ExtendedMOP] = - { - var list = ListBuffer[ExtendedMOP]() - for((p, i) <- partList.view.zipWithIndex) - p.collisionRayTrace(start, end) match { - case mop:ExtendedMOP => - mop.data = (i, mop.data) - list+=mop - case _ => - } - - return list.sorted - } - - /** - * Perform a raytrace returning the nearest intersecting part - */ - def collisionRayTrace(start:Vec3, end:Vec3):ExtendedMOP = rayTraceAll(start, end).headOption.getOrElse(null) - - /** - * Drop and remove part at index (internal mining callback) - */ - def harvestPart(index:Int, hit:ExtendedMOP, player:EntityPlayer) = partList(index) match { - case null => - case part => part.harvest(hit, player) - } - - /** - * Utility function for dropping items around the center of this space - */ - def dropItems(items:Iterable[ItemStack]) - { - val pos = Vector3.fromTileEntityCenter(this) - items.foreach(item => TileMultipart.dropItem(item, worldObj, pos)) - } - - final override def writeToNBT(tag:NBTTagCompound) - { - super.writeToNBT(tag) - val taglist = new NBTTagList - partList.foreach{part => - val parttag = new NBTTagCompound - parttag.setString("id", part.getType) - part.save(parttag) - taglist.appendTag(parttag) - } - tag.setTag("parts", taglist) - } - - /** - * Internal callback - */ - def onEntityCollision(entity:Entity) - { - operate(_.onEntityCollision(entity)) - } - - /** - * Internal callback, overriden in TRedstoneTile - */ - def strongPowerLevel(side:Int) = 0 - - /** - * Internal callback, overriden in TRedstoneTile - */ - def weakPowerLevel(side:Int) = 0 - - /** - * Internal callback, overriden in TRedstoneTile - */ - def canConnectRedstone(side:Int) = false -} - -class TileMultipartClient extends TileMultipart -{ - def renderStatic(pos:Vector3, pass:Int) = - partList.foldLeft(false)((r, part) => part.renderStatic(pos, pass) || r) - - def renderDynamic(pos:Vector3, frame:Float, pass:Int) - { - partList.foreach(part => part.renderDynamic(pos, frame, pass:Int)) - } - - def randomDisplayTick(random:Random){} - - override def shouldRenderInPass(pass:Int) = - { - MultipartRenderer.pass = pass - true - } - - override def getRenderBoundingBox = { - val c = Cuboid6.full.copy - partList.foreach(part => c.enclose(part.getRenderBounds)) - c.add(Vector3.fromTileEntity(this)).toAABB - } -} - -/** - * Static class with multipart manipulation helper functions - */ -object TileMultipart -{ - var renderID = -1 - - /** - * Playerinstance will often remove the tile entity instance and set the block to air on the client before the multipart packet handler fires it's updates. - * In order to maintain the packet data, and make sure all written data is read, the tile needs to be kept around internally until - */ - private val clientFlushMap = MMap[BlockCoord, TileMultipart]() - - private[multipart] def flushClientCache() = clientFlushMap.clear() - - private[multipart] def putClientCache(t:TileMultipart) = clientFlushMap.put(new BlockCoord(t), t) - - /** - * Gets a multipar ttile instance at pos, converting if necessary. - */ - def getOrConvertTile(world:World, pos:BlockCoord) = getOrConvertTile2(world, pos)._1 - - /** - * Gets a multipart tile instance at pos, converting if necessary. - * Note converted tiles are merely a structure formality, - * they do not actually exist in world until they are required to by the addition of another multipart to their space. - * @return (The tile or null if there was none, true if the tile is a result of a conversion) - */ - def getOrConvertTile2(world:World, pos:BlockCoord):(TileMultipart, Boolean) = - { - val t = world.getTileEntity(pos.x, pos.y, pos.z) - if(t.isInstanceOf[TileMultipart]) - return (t.asInstanceOf[TileMultipart], false) - - val p = MultiPartRegistry.convertBlock(world, pos, world.getBlock(pos.x, pos.y, pos.z)) - if(p != null) - { - val t = MultipartGenerator.generateCompositeTile(null, Seq(p), world.isRemote) - t.xCoord = pos.x - t.yCoord = pos.y - t.zCoord = pos.z - t.setWorldObj(world) - t.addPart_do(p) - return (t, true) - } - return (null, false) - } - - /** - * Gets the multipart tile instance at pos, or null if it doesn't exist or is not a multipart tile - */ - def getTile(world:World, pos:BlockCoord) = - world.getTileEntity(pos.x, pos.y, pos.z) match { - case t:TileMultipart => t - case _ => null - } - - def checkNoEntityCollision(world:World, pos:BlockCoord, part:TMultiPart) = - part.getCollisionBoxes.forall(b => world.checkNoEntityCollision(b.toAABB.offset(pos.x, pos.y, pos.z))) - - /** - * Returns whether part can be added to the space at pos. Will do conversions as necessary. - * This function is the recommended way to add parts to the world. - */ - def canPlacePart(world:World, pos:BlockCoord, part:TMultiPart):Boolean = - { - if(!checkNoEntityCollision(world, pos, part)) - return false - - val t = getOrConvertTile(world, pos) - if(t != null) - return t.canAddPart(part) - else if(!MultipartCompatiblity.canAddPart(world, pos.x, pos.y, pos.z)) - return false - - if(!replaceable(world, pos)) - return false - - return true - } - - /** - * Returns if the block at pos is replaceable (air, vines etc) - */ - def replaceable(world:World, pos:BlockCoord):Boolean = - { - val block = world.getBlock(pos.x, pos.y, pos.z) - return block.isAir(world, pos.x, pos.y, pos.z) || block.isReplaceable(world, pos.x, pos.y, pos.z) - } - - /** - * Adds a part to a block space. canPlacePart should always be called first. - * The addition of parts on the client is handled internally. - */ - def addPart(world:World, pos:BlockCoord, part:TMultiPart):TileMultipart = - { - assert(!world.isRemote, "Cannot add multi parts to a client tile.") - return MultipartGenerator.addPart(world, pos, part) - } - - /** - * Constructs this tile and its parts from a desc packet - */ - def handleDescPacket(world:World, pos:BlockCoord, packet:PacketCustom) - { - val nparts = packet.readUByte - val parts = new ListBuffer[TMultiPart]() - for(i <- 0 until nparts) - { - val part:TMultiPart = MultiPartRegistry.readPart(packet) - part.readDesc(packet) - parts+=part - } - - if(parts.size == 0) - return - - val t = world.getTileEntity(pos.x, pos.y, pos.z) - val tilemp = MultipartGenerator.generateCompositeTile(t, parts, true) - if(tilemp != t) { - world.setBlock(pos.x, pos.y, pos.z, MultipartProxy.block) - MultipartGenerator.silentAddTile(world, pos, tilemp) - } - - tilemp.loadParts(parts) - tilemp.notifyTileChange() - tilemp.markRender() - } - - /** - * Handles an update packet, addition, removal and otherwise - */ - def handlePacket(pos:BlockCoord, world:World, i:Int, packet:PacketCustom) - { - lazy val tilemp = Option(BlockMultipart.getTile(world, pos.x, pos.y, pos.z)).getOrElse(clientFlushMap(pos)) - - i match - { - case 253 => - val part = MultiPartRegistry.readPart(packet) - part.readDesc(packet) - MultipartGenerator.addPart(world, pos, part) - case 254 => tilemp.remPart_impl(tilemp.partList(packet.readUByte)) - case _ => tilemp.partList(i).read(packet) - } - } - - /** - * Creates this tile from an NBT tag - */ - def createFromNBT(tag:NBTTagCompound):TileMultipart = - { - val partList = tag.getTagList("parts", 10) - val parts = ListBuffer[TMultiPart]() - - for(i <- 0 until partList.tagCount) - { - val partTag = partList.getCompoundTagAt(i) - val partID = partTag.getString("id") - val part = MultiPartRegistry.createPart(partID, false) - if(part != null) - { - part.load(partTag) - parts+=part - } - } - - if(parts.size == 0) - return null - - val tmb = MultipartGenerator.generateCompositeTile(null, parts, false) - tmb.readFromNBT(tag) - tmb.loadParts(parts) - return tmb - } - - /** - * Drops an item around pos - */ - def dropItem(stack:ItemStack, world:World, pos:Vector3) - { - val item = new EntityItem(world, pos.x, pos.y, pos.z, stack) - item.motionX = world.rand.nextGaussian() * 0.05 - item.motionY = world.rand.nextGaussian() * 0.05 + 0.2 - item.motionZ = world.rand.nextGaussian() * 0.05 - item.delayBeforeCanPickup = 10 - world.spawnEntityInWorld(item) - } -} diff --git a/codechicken/multipart/asm/ASMMixinCompiler.scala b/codechicken/multipart/asm/ASMMixinCompiler.scala deleted file mode 100644 index 20a1e7c..0000000 --- a/codechicken/multipart/asm/ASMMixinCompiler.scala +++ /dev/null @@ -1,627 +0,0 @@ -package codechicken.multipart.asm - -import scala.collection.mutable.{Map => MMap, ListBuffer => MList, Set => MSet} -import java.util.{Set => JSet} -import scala.collection.JavaConversions._ -import org.objectweb.asm.tree._ -import org.objectweb.asm.Opcodes._ -import org.objectweb.asm.ClassReader -import org.objectweb.asm.util.TraceClassVisitor -import org.objectweb.asm.util.Textifier -import org.objectweb.asm.Type -import org.objectweb.asm.MethodVisitor -import Type._ -import codechicken.lib.asm.ASMHelper._ -import codechicken.lib.asm.ObfMapping -import java.io.File -import java.io.PrintWriter -import ScalaSignature._ -import java.lang.reflect.Method -import java.lang.reflect.Modifier -import net.minecraft.launchwrapper.LaunchClassLoader -import codechicken.multipart.handler.MultipartProxy -import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper - -object DebugPrinter -{ - val debug = MultipartProxy.config.getTag("debug_asm").getBooleanValue(!ObfMapping.obfuscated) - - private var permGenUsed = 0 - val dir = new File("asm/multipart") - if(debug) - { - if(!dir.exists) - dir.mkdirs() - for(file <- dir.listFiles) - file.delete - } - - def dump(name:String, bytes:Array[Byte]) - { - if(!debug) return - - val fileout = new File(dir, name.replace('/', '#')+".txt") - val pout = new PrintWriter(fileout) - - new ClassReader(bytes).accept(new TraceClassVisitor(null, new Textifier(), pout), 0) - pout.close() - } - - def defined(name:String, bytes:Array[Byte]) - { - if((permGenUsed+bytes.length)/16000 != permGenUsed/16000) - log((permGenUsed+bytes.length)+" bytes of permGen has been used by ASMMixinCompiler") - - permGenUsed += bytes.length - } - - def log(msg:String) = if(debug) println(msg) -} - -object ASMMixinCompiler -{ - import StackAnalyser.width - - val cl = getClass.getClassLoader.asInstanceOf[LaunchClassLoader] - val m_defineClass = classOf[ClassLoader].getDeclaredMethod("defineClass", classOf[Array[Byte]], Integer.TYPE, Integer.TYPE) - val m_runTransformers = classOf[LaunchClassLoader].getDeclaredMethod("runTransformers", classOf[String], classOf[String], classOf[Array[Byte]]) - val f_transformerExceptions = classOf[LaunchClassLoader].getDeclaredField("transformerExceptions") - m_defineClass.setAccessible(true) - m_runTransformers.setAccessible(true) - f_transformerExceptions.setAccessible(true) - - private val traitByteMap = MMap[String, Array[Byte]]() - private val mixinMap = MMap[String, MixinInfo]() - - def define(name:String, bytes:Array[Byte]) = - { - internalDefine(name, bytes) - DebugPrinter.defined(name, bytes) - - try { - m_defineClass.invoke(cl, bytes, 0:Integer, bytes.length:Integer).asInstanceOf[Class[_]] - } catch { - case link:LinkageError if link.getMessage.contains("duplicate") => - throw new IllegalStateException("class with name: "+name+" already loaded. Do not reference your mixin classes before registering them with MultipartGenerator", link) - } - } - - getBytes("cpw/mods/fml/common/asm/FMLSanityChecker") - - def getBytes(name:String):Array[Byte] = - { - val jName = name.replace('/', '.') - if(jName.equals("java.lang.Object")) - return null - - def useTransformers = f_transformerExceptions.get(cl).asInstanceOf[JSet[String]] - .find(jName.startsWith).isEmpty - - val obfName = if(ObfMapping.obfuscated) FMLDeobfuscatingRemapper.INSTANCE.unmap(name).replace('/', '.') else jName - val bytes = cl.getClassBytes(obfName) - if(bytes != null && useTransformers) - return m_runTransformers.invoke(cl, jName, obfName, bytes).asInstanceOf[Array[Byte]] - - return bytes - } - - def internalDefine(name:String, bytes:Array[Byte]) - { - traitByteMap.put(name.replace('.', '/'), bytes) - BaseNodeInfo.clear(name) - DebugPrinter.dump(name, bytes) - } - - def classNode(name:String) = traitByteMap.getOrElseUpdate(name.replace('.', '/'), getBytes(name.replace('.', '/'))) match { - case null => null - case v => createClassNode(v, ClassReader.EXPAND_FRAMES) - } - - def isScala(cnode:ClassNode) = ScalaSigReader.ann(cnode).isDefined - - def isTrait(cnode:ClassNode) = - { - val csym:ClassSymbol = ScalaSigReader.read(ScalaSigReader.ann(cnode).get).evalT(0) - csym.isTrait && !csym.isInterface - } - - def getMixinInfo(name:String) = mixinMap.get(name) - - case class FieldMixin(name:String, desc:String, access:Int) - { - def accessName(owner:String) = if((access & ACC_PRIVATE) != 0) - owner.replace('/', '$')+"$$"+name - else - name - } - - case class MixinInfo(name:String, parent:String, fields:Seq[FieldMixin], - methods:Seq[MethodNode], supers:Map[String, String]) - { - def tname = name+"$class" - } - - object BaseNodeInfo - { - private val baseNodeMap = MMap[String, BaseNodeInfo]() - - def clear(name:String) = baseNodeMap.remove(name) - - def getNodeInfo(name:String) = baseNodeMap.getOrElseUpdate(name, new BaseNodeInfo(name)) - - private def getNodeInfo(clazz:ClassInfoSource) = clazz match { - case null => null - case v => baseNodeMap.getOrElseUpdate(v.name, new BaseNodeInfo(v)) - } - - case class MethodNodeInfo(owner:String, m:MethodInfoSource) - { - def name = m.name - def desc = m.desc - } - - trait MethodInfoSource - { - def name:String - def desc:String - def isPrivate:Boolean - def isAbstract:Boolean - } - - trait ClassInfoSource - { - def name:String - def superClass:Option[BaseNodeInfo] - def interfaces:Seq[BaseNodeInfo] - def methods:Seq[MethodInfoSource] - } - - implicit def JClassInfoSource(clazz:Class[_]) = if(clazz == null) null else new JClassInfoSource(clazz) - class JClassInfoSource(clazz:Class[_]) extends ClassInfoSource - { - case class JMethodInfoSource(method:Method) extends MethodInfoSource - { - def name = method.getName - def desc = getType(method).getDescriptor - def isPrivate = Modifier.isPrivate(method.getModifiers) - def isAbstract = Modifier.isAbstract(method.getModifiers) - } - - def name = clazz.getName.replace('.', '/') - def superClass = Option(getNodeInfo(clazz.getSuperclass)) - def interfaces = clazz.getInterfaces.map(getNodeInfo(_)) - def methods = clazz.getMethods.map(JMethodInfoSource(_)) - } - - implicit def ClassNodeInfoSource(cnode:ClassNode) = if(cnode == null) null else new ClassNodeInfoSource(cnode) - class ClassNodeInfoSource(cnode:ClassNode) extends ClassInfoSource - { - case class MethodNodeInfoSource(mnode:MethodNode) extends MethodInfoSource - { - def name = mnode.name - def desc = mnode.desc - def isPrivate = (mnode.access & ACC_PRIVATE) != 0 - def isAbstract = (mnode.access & ACC_ABSTRACT) != 0 - } - - def name = cnode.name - def superClass = Option(getNodeInfo(cnode.superName)) - def interfaces = cnode.interfaces match { - case null => Seq() - case v => v.map(getNodeInfo) - } - def methods = cnode.methods.map(MethodNodeInfoSource(_)) - } - - class ScalaNodeInfoSource(cnode:ClassNode) extends ClassNodeInfoSource(cnode) - { - val sig = ScalaSigReader.read(ScalaSigReader.ann(cnode).get) - val csym = sig.evalT(0):ClassSymbol - - override def superClass = Option(getNodeInfo(csym.jParent(sig))) - override def interfaces = csym.jInterfaces(sig).map(getNodeInfo) - } - - def classInfo(name:String):ClassInfoSource = name match { - case null => null - case s => classNode(s) match { - case null => cl.findClass(s.replace('/', '.')) - case v if isScala(v) => new ScalaNodeInfoSource(v) - case v => v - } - } - } - - import BaseNodeInfo._ - class BaseNodeInfo(val clazz:ClassInfoSource) - { - def this(name:String) = this(classInfo(name)) - - val publicmethods = exportedMethods(clazz)//map of nameDesc to owner+method - - def exportedMethods(o:ClassInfoSource):Map[String, MethodNodeInfo] = - { - val eMethods = o.methods.filter(!_.isPrivate)//defined accessible methods - .map(m => (m.name+m.desc, MethodNodeInfo(o.name, m))).toMap - - eMethods ++ (o.superClass++o.interfaces).flatMap(_.publicmethods) - } - } - - def finishBridgeCall(mv:MethodVisitor, mvdesc:String, opcode:Int, owner:String, name:String, desc:String) - { - val args = getArgumentTypes(mvdesc) - val ret = getReturnType(mvdesc) - var localIndex = 1 - args.foreach{arg => - mv.visitVarInsn(arg.getOpcode(ILOAD), localIndex) - localIndex+=width(arg) - } - mv.visitMethodInsn(opcode, owner, name, desc) - mv.visitInsn(ret.getOpcode(IRETURN)) - mv.visitMaxs(Math.max(width(args)+1, width(ret)), width(args)+1) - } - - def writeBridge(mv:MethodVisitor, mvdesc:String, opcode:Int, owner:String, name:String, desc:String) - { - mv.visitVarInsn(ALOAD, 0) - finishBridgeCall(mv, mvdesc, opcode, owner, name, desc) - } - - def writeStaticBridge(mv:MethodNode, mname:String, t:MixinInfo) = - writeBridge(mv, mv.desc, INVOKESTATIC, t.tname, mname, staticDesc(t.name, mv.desc)) - - def mixinClasses(name:String, superClass:String, traits:Seq[String]) = - { - val traitInfos = traits.map(t => mixinMap(t.replace('.', '/'))) - - val cnode = new ClassNode() - cnode.visit(V1_6, ACC_PUBLIC, name, null, superClass.replace('.', '/'), traitInfos.map(_.name).toArray[String]) - - val minit = cnode.visitMethod(ACC_PUBLIC, "", "()V", null, null) - minit.visitVarInsn(ALOAD, 0) - minit.visitMethodInsn(INVOKESPECIAL, cnode.superName, "", "()V") - - val prevInfos = MList[MixinInfo]() - - traitInfos.foreach{ t => - minit.visitVarInsn(ALOAD, 0) - minit.visitMethodInsn(INVOKESTATIC, t.tname, "$init$", "(L"+t.name+";)V") - - t.fields.foreach{ f => - val fv = cnode.visitField(ACC_PRIVATE, f.accessName(t.name), f.desc, null, null).asInstanceOf[FieldNode] - - val ftype = getType(fv.desc) - var mv = cnode.visitMethod(ACC_PUBLIC, fv.name, "()"+f.desc, null, null) - mv.visitVarInsn(ALOAD, 0) - mv.visitFieldInsn(GETFIELD, name, fv.name, fv.desc) - mv.visitInsn(ftype.getOpcode(IRETURN)) - mv.visitMaxs(1, 1) - - mv = cnode.visitMethod(ACC_PUBLIC, fv.name+"_$eq", "("+f.desc+")V", null, null) - mv.visitVarInsn(ALOAD, 0) - mv.visitVarInsn(ftype.getOpcode(ILOAD), 1) - mv.visitFieldInsn(PUTFIELD, name, fv.name, fv.desc) - mv.visitInsn(RETURN) - mv.visitMaxs(width(ftype)+1, width(ftype)+1) - } - - t.supers.foreach{ s => - val (name, desc) = seperateDesc(s._1) - val mv = cnode.visitMethod(ACC_PUBLIC, t.name.replace('/', '$')+"$$super$"+name, desc, null, null).asInstanceOf[MethodNode] - - prevInfos.reverse.find(t => t.supers.contains(s._1)) match {//each super goes to the one before - case Some(st) => writeStaticBridge(mv, name, st) - case None => writeBridge(mv, desc, INVOKESPECIAL, s._2, name, desc) - } - } - - prevInfos+=t - } - - val methodSigs = MSet[String]() - traitInfos.reverse.foreach{ t => //last trait gets first pick on methods - t.methods.foreach{ m => - if(!methodSigs(m.name+m.desc)) - { - val mv = cnode.visitMethod(ACC_PUBLIC, m.name, m.desc, null, Array(m.exceptions:_*)).asInstanceOf[MethodNode] - copy(m, mv) - mv.instructions = new InsnList() - mv.tryCatchBlocks.clear() - - writeStaticBridge(mv, m.name, t) - methodSigs+=m.name+m.desc - } - } - } - - minit.visitInsn(RETURN) - minit.visitMaxs(1, 1) - - define(cnode.name, createBytes(cnode, 0)) - } - - def seperateDesc(nameDesc:String) = { - val n = nameDesc.indexOf('(') - (nameDesc.substring(0, n), nameDesc.substring(n)) - } - - def staticDesc(owner:String, desc:String) = - { - val descT = getMethodType(desc) - getMethodDescriptor(descT.getReturnType, getType("L"+owner+";")+:descT.getArgumentTypes : _*) - } - - def getSuper(minsn:MethodInsnNode, stack:StackAnalyser):Option[String] = - { - import StackAnalyser._ - - if(minsn.getOpcode != INVOKESPECIAL) return None - val oname = stack.owner.getInternalName - - if(minsn.owner.equals(oname)) return None//private this - - stack.peek(Type.getType(minsn.desc).getArgumentTypes.length) match { - case Load(This(o)) => - case _ => return None//have to be invoked on this - } - - getSuper(minsn.name+minsn.desc, oname) - } - - def getSuper(nameDesc:String, cname:String) = - getNodeInfo(cname).clazz.superClass match { - case None => None//no super class - case Some(o) => o.publicmethods.get(nameDesc) match { - case None => None//no method with sig in super - case Some(m) => if(m.m.isAbstract) - None //abstract can't be called for supers - else - Some(m.owner)//congrats, that's a super - } - } - - def registerJavaTrait(cnode:ClassNode) - { - if((cnode.access & ACC_INTERFACE) != 0) - throw new IllegalArgumentException("Cannot register java interface "+cnode.name+" as a multipart trait. Try register passThroughInterface") - if((cnode.access & ACC_ABSTRACT) != 0) - throw new IllegalArgumentException("Cannot register abstract class "+cnode.name+" as a multipart trait") - if(!cnode.innerClasses.isEmpty) - throw new IllegalArgumentException("Inner classes are not permitted for "+cnode.name+" as a multipart trait. Use scala") - - val inode = new ClassNode()//impl node - inode.visit(V1_6, ACC_ABSTRACT|ACC_PUBLIC, cnode.name+"$class", null, "java/lang/Object", null) - inode.sourceFile = cnode.sourceFile - - val fields = cnode.fields.map(f => (f.name, FieldMixin(f.name, f.desc, f.access))).toMap - val supers = MMap[String, String]()//nameDesc to super owner - val methods = MList[MethodNode]() - val methodSigs = cnode.methods.map(m => m.name+m.desc).toSet - - val tnode = new ClassNode()//trait node (interface) - tnode.visit(V1_6, ACC_INTERFACE|ACC_ABSTRACT|ACC_PUBLIC, cnode.name, null, "java/lang/Object", Array(cnode.interfaces:_*)) - - def fname(name:String) = fields(name).accessName(cnode.name) - - fields.values.foreach{ fnode => - tnode.visitMethod(ACC_PUBLIC|ACC_ABSTRACT, fname(fnode.name), "()"+fnode.desc, null, null) - tnode.visitMethod(ACC_PUBLIC|ACC_ABSTRACT, fname(fnode.name)+"_$eq", "("+fnode.desc+")V", null, null) - } - - def superInsn(minsn:MethodInsnNode) = - { - val bridgeName = cnode.name.replace('/', '$')+"$$super$"+minsn.name - if(!supers.contains(minsn.name+minsn.desc)) - { - tnode.visitMethod(ACC_PUBLIC|ACC_ABSTRACT, bridgeName, minsn.desc, null, null) - supers.put(minsn.name+minsn.desc, minsn.owner) - } - new MethodInsnNode(INVOKEINTERFACE, cnode.name, bridgeName, minsn.desc) - } - - def staticClone(mnode:MethodNode, name:String, access:Int) = - { - val mv = inode.visitMethod(access|ACC_STATIC, name, - staticDesc(cnode.name, mnode.desc), - null, Array(mnode.exceptions:_*)).asInstanceOf[MethodNode] - copy(mnode, mv) - mv - } - - def staticTransform(mnode:MethodNode, base:MethodNode) - { - val stack = new StackAnalyser(getType(cnode.name), base) - val insnList = mnode.instructions - var insn = insnList.getFirst - - def replace(newinsn:AbstractInsnNode) - { - insnList.insert(insn, newinsn) - insnList.remove(insn) - insn = newinsn - } - - //transform - while(insn != null) - { - insn match { - case finsn:FieldInsnNode => insn.getOpcode match - { - case GETFIELD => replace(new MethodInsnNode(INVOKEINTERFACE, cnode.name, - fname(finsn.name), "()"+finsn.desc)) - case PUTFIELD => replace(new MethodInsnNode(INVOKEINTERFACE, cnode.name, - fname(finsn.name)+"_$eq", "("+finsn.desc+")V")) - case _ => - } - case minsn:MethodInsnNode => insn.getOpcode match - { - case INVOKESPECIAL => - if(getSuper(minsn, stack).isDefined) - replace(superInsn(minsn)) - case INVOKEVIRTUAL => - if(minsn.owner.equals(cnode.name)) { - if(methodSigs.contains(minsn.name+minsn.desc))//call the interface method - minsn.setOpcode(INVOKEINTERFACE) - else {//cast to parent class and call - val mType = Type.getMethodType(minsn.desc) - val instanceEntry = stack.peek(width(mType.getArgumentTypes)) - insnList.insert(instanceEntry.insn, new TypeInsnNode(CHECKCAST, cnode.superName)) - minsn.owner = cnode.superName - } - } - case _ => - } - case _ => - } - stack.visitInsn(insn) - insn = insn.getNext - } - } - - def convertMethod(mnode:MethodNode) - { - if(mnode.name.equals("")) - throw new IllegalArgumentException("Static initialisers are not permitted "+cnode.name+" as a multipart trait") - - if(mnode.name.equals("")) - { - if(!mnode.desc.equals("()V")) - throw new IllegalArgumentException("Constructor arguments are not permitted "+cnode.name+" as a multipart trait") - - val mv = staticClone(mnode, "$init$", ACC_PUBLIC) - def removeSuperConstructor() - { - def throwI = throw new IllegalArgumentException("Invalid constructor insn sequence "+cnode.name) - - val insnList = mv.instructions - var insn = insnList.getFirst - var state = 0 - while(insn != null && state < 2) - { - val next = insn.getNext - insn match { - case linsn:LabelNode => - case linsn:LineNumberNode => - case vinsn:VarInsnNode => - if(state == 0) - { - if(vinsn.getOpcode == ALOAD && vinsn.`var` == 0) - { - state = 1 - insnList.remove(insn) - } - else - throwI - } - else - throwI - case minsn:MethodInsnNode => - if(state == 1) - { - if(minsn.getOpcode == INVOKESPECIAL && minsn.name.equals("") && - minsn.owner.equals(cnode.superName)) - { - insnList.remove(insn) - state = 2 - } - else - throwI - } - else - throwI - case _ => throwI - } - insn = next - } - if(state != 2) - throwI - } - removeSuperConstructor() - staticTransform(mv, mnode) - return - } - - if((mnode.access & ACC_PRIVATE) == 0) - { - val mv = tnode.visitMethod(ACC_PUBLIC|ACC_ABSTRACT, mnode.name, mnode.desc, null, Array(mnode.exceptions:_*)) - methods+=mv.asInstanceOf[MethodNode] - } - - //convert that method! - val access = if((mnode.access & ACC_PRIVATE) == 0) ACC_PUBLIC else ACC_PRIVATE - val mv = staticClone(mnode, mnode.name, access) - staticTransform(mv, mnode) - } - - cnode.methods.foreach(convertMethod) - - define(inode.name, createBytes(inode, 0)) - define(tnode.name, createBytes(tnode, 0)) - - mixinMap.put(tnode.name, MixinInfo(tnode.name, cnode.superName, - fields.values.toSeq, - methods.toSeq, supers.toMap)) - } - - def registerScalaTrait(cnode:ClassNode) - { - for(i <- cnode.interfaces) - { - val inode = classNode(i) - if(isScala(inode) && isTrait(inode)) - throw new IllegalArgumentException("Multipart trait "+cnode.name+" cannot extend other traits") - } - - val fieldAccessors = MMap[String, MethodSymbol]() - val fields = MList[MethodSymbol]() - val methods = MList[MethodNode]() - val supers = MMap[String, String]() - - val sig = ScalaSigReader.read(ScalaSigReader.ann(cnode).get) - val csym:ClassSymbol = sig.evalT(0) - for(i <- 0 until sig.table.length) - { - import ScalaSignature._ - - val e = sig.table(i) - if(e.id == 8)//method - { - val sym:MethodSymbol = sig.evalT(i) - if(sym.isParam || !sym.owner.equals(csym)){} - else if(sym.isAccessor) - { - fieldAccessors.put(sym.name, sym) - } - else if(sym.isMethod) - { - val desc = sym.jDesc(sig) - if(sym.name.contains("super$")) - { - val name = sym.name.substring(6) - supers.put(name+desc, getSuper(name+desc, cnode.name).get) - } - else if(!sym.name.equals("$init$") && !sym.isPrivate) - { - val map = new ObfMapping(cnode.name, sym.name, desc) - val method = findMethod(map, cnode) - if(method == null) - throw new RuntimeException("Unable to add multipart trait: "+map+" found in scala signature but not in class file. Most likely an obfuscation issue.") - methods+=method - } - } - else - { - fields+=sym - } - } - } - - mixinMap.put(cnode.name, MixinInfo(cnode.name, csym.jParent(sig), - fields.map(sym => FieldMixin(sym.name.trim, getReturnType(sym.jDesc(sig)).getDescriptor, - if(fieldAccessors(sym.name.trim).isPrivate) ACC_PRIVATE else ACC_PUBLIC)), - methods, supers.toMap)) - } - - -} \ No newline at end of file diff --git a/codechicken/multipart/asm/ASMMixinFactory.scala b/codechicken/multipart/asm/ASMMixinFactory.scala deleted file mode 100644 index 8f6c3a6..0000000 --- a/codechicken/multipart/asm/ASMMixinFactory.scala +++ /dev/null @@ -1,311 +0,0 @@ -package codechicken.multipart.asm - -import scala.collection.Seq -import codechicken.multipart.TileMultipart -import codechicken.multipart.TileMultipartClient -import scala.collection.JavaConversions._ -import org.objectweb.asm.Opcodes._ -import codechicken.lib.asm.CC_ClassWriter -import org.objectweb.asm.MethodVisitor -import org.objectweb.asm.FieldVisitor -import org.objectweb.asm.Label -import org.objectweb.asm.tree._ -import codechicken.lib.asm.ASMHelper._ -import codechicken.lib.asm.ObfMapping -import codechicken.multipart.MultipartGenerator -import ASMMixinCompiler._ - -object ASMMixinFactory extends IMultipartFactory -{ - type TMClass = Class[_ <: TileMultipart] - - private var ugenid = 0 - private var generatorMap = Map[SuperSet, Constructor]() - - def uniqueName(prefix:String):String = { - val ret = prefix+"$$"+ugenid - ugenid += 1 - return ret - } - - def simpleName(name:String) = name.substring(name.replace('/', '.').lastIndexOf('.')+1) - - abstract class Constructor - { - def generate():TileMultipart - } - - object SuperSet - { - val TileMultipartType = classOf[TileMultipart].getName - val TileMultipartClientType = classOf[TileMultipartClient].getName - def apply(types:Seq[String], client:Boolean) = new SuperSet(types, client) - } - - class SuperSet(types:Seq[String], client:Boolean) - { - import SuperSet._ - val set = baseType+:types.sorted - - def baseType = if(client) TileMultipartClientType else TileMultipartType - - override def equals(obj:Any) = obj match - { - case x:SuperSet => set == x.set - case _ => false - } - - override def hashCode = set.hashCode() - - def generate:TileMultipart = get.generate() - - def get = generatorMap.getOrElse(this, gen_sync()) - - def gen_sync():Constructor = ASMMixinFactory.synchronized - { - return generatorMap.getOrElse(this, { - val gen = generator() - generatorMap = generatorMap+(this->gen) - gen - }) - } - - def generator():Constructor = - { - val startTime = System.currentTimeMillis - - val cmpClass = if(!types.isEmpty) - mixinClasses(uniqueName("TileMultipart_cmp"), set.head, set.drop(1)) - else - cl.loadClass(baseType) - - MultipartGenerator.registerTileClass(cmpClass.asInstanceOf[TMClass], types.toSet) - val c = constructor(cmpClass) - DebugPrinter.log("Generation ["+types.mkString(", ")+"] took: "+(System.currentTimeMillis-startTime)) - return c - } - } - - def constructor(clazz:Class[_]):Constructor = - { - val name = uniqueName("TileMultipart_gen") - val cw = new CC_ClassWriter(ASM4) - val superName = classOf[Constructor].getName.replace('.', '/') - val className = clazz.getName.replace('.', '/') - var mv:MethodVisitor = null - - cw.visit(V1_6, ACC_PUBLIC|ACC_SUPER, name, null, superName, null) - - mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null) - mv.visitCode() - mv.visitVarInsn(ALOAD, 0) - mv.visitMethodInsn(INVOKESPECIAL, superName, "", "()V") - mv.visitInsn(RETURN) - mv.visitMaxs(1, 1) - mv.visitEnd() - - mv = cw.visitMethod(ACC_PUBLIC, "generate", "()Lcodechicken/multipart/TileMultipart;", null, null) - mv.visitCode() - mv.visitTypeInsn(NEW, className) - mv.visitInsn(DUP) - mv.visitMethodInsn(INVOKESPECIAL, className, "", "()V") - mv.visitInsn(ARETURN) - mv.visitMaxs(2, 1) - mv.visitEnd() - - cw.visitEnd() - - return define(name, cw.toByteArray).newInstance.asInstanceOf[Constructor] - } - - private def autoCompleteJavaTrait(cnode:ClassNode) - { - if(!cnode.fields.isEmpty && findMethod(new ObfMapping(cnode.name, "copyFrom", "(Lcodechicken/multipart/TileMultipart;)V"), cnode) == null) - { - val mv = cnode.visitMethod(ACC_PUBLIC, "copyFrom", "(Lcodechicken/multipart/TileMultipart;)V", null, null) - mv.visitVarInsn(ALOAD, 0) - mv.visitVarInsn(ALOAD, 1) - mv.visitMethodInsn(INVOKESPECIAL, "codechicken/multipart/TileMultipart", "copyFrom", "(Lcodechicken/multipart/TileMultipart;)V") - - mv.visitVarInsn(ALOAD, 1) - mv.visitTypeInsn(INSTANCEOF, cnode.name) - val end = new Label() - mv.visitJumpInsn(IFEQ, end) - - cnode.fields.foreach{ f => - mv.visitVarInsn(ALOAD, 0) - mv.visitVarInsn(ALOAD, 1) - mv.visitFieldInsn(GETFIELD, cnode.name, f.name, f.desc) - mv.visitFieldInsn(PUTFIELD, cnode.name, f.name, f.desc) - } - - mv.visitLabel(end) - mv.visitInsn(RETURN) - mv.visitMaxs(2, 2) - } - } - - def registerTrait(s_interface:String, s_trait:String, client:Boolean) - { - val cnode = classNode(s_trait) - if(cnode == null) - throw new ClassNotFoundException(s_trait) - - def superClass = getMixinInfo(cnode.name) match { - case Some(m) => m.parent - case None => BaseNodeInfo.getNodeInfo(cnode.name).clazz.superClass.get.clazz.name - } - - superClass match { - case "codechicken/multipart/TileMultipartClient" => if(!client) - throw new IllegalArgumentException("Multipart trait "+s_trait+" cannot implement TileMultipartClient on the server") - case "codechicken/multipart/TileMultipart" => - case _ => throw new IllegalArgumentException("Multipart trait "+s_trait+" must implement TileMultipart or TileMultipartClient") - } - - if(getMixinInfo(cnode.name).isDefined) - return - - if(isScala(cnode) && isTrait(cnode)) - { - registerScalaTrait(cnode) - } - else - { - autoCompleteJavaTrait(cnode) - registerJavaTrait(cnode) - } - } - - def generatePassThroughTrait(s_interface:String):String = - { - def passThroughTraitName(iName:String) = - "T" + (if(iName.startsWith("I")) iName.substring(1) else iName) - - val tname = uniqueName(passThroughTraitName(simpleName(s_interface))) - val vname = "impl" - val iname = s_interface.replace('.', '/') - val idesc = "L"+iname+";" - - val inode = classNode(s_interface) - if(inode == null) { - System.out.println("Unable to generate pass through trait for: "+s_interface+" class not found.") - return null - } - if((inode.access&ACC_INTERFACE) == 0) throw new IllegalArgumentException(s_interface+" is not an interface.") - - val cw = new CC_ClassWriter(ASM4) - var mv:MethodVisitor = null - var fv:FieldVisitor = null - - cw.visit(V1_6, ACC_PUBLIC|ACC_SUPER, tname, null, "codechicken/multipart/TileMultipart", Array(iname)) - - { - fv = cw.visitField(ACC_PRIVATE, vname, idesc, null, null) - fv.visitEnd() - } - { - mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null) - mv.visitCode() - mv.visitVarInsn(ALOAD, 0) - mv.visitMethodInsn(INVOKESPECIAL, "codechicken/multipart/TileMultipart", "", "()V") - mv.visitInsn(RETURN) - mv.visitMaxs(1, 1) - mv.visitEnd() - } - { - mv = cw.visitMethod(ACC_PUBLIC, "bindPart", "(Lcodechicken/multipart/TMultiPart;)V", null, null) - mv.visitCode() - mv.visitVarInsn(ALOAD, 0) - mv.visitVarInsn(ALOAD, 1) - mv.visitMethodInsn(INVOKESPECIAL, "codechicken/multipart/TileMultipart", "bindPart", "(Lcodechicken/multipart/TMultiPart;)V") - mv.visitVarInsn(ALOAD, 1) - mv.visitTypeInsn(INSTANCEOF, iname) - val l2 = new Label() - mv.visitJumpInsn(IFEQ, l2) - val l3 = new Label() - mv.visitLabel(l3) - mv.visitVarInsn(ALOAD, 0) - mv.visitVarInsn(ALOAD, 1) - mv.visitTypeInsn(CHECKCAST, iname) - mv.visitFieldInsn(PUTFIELD, tname, vname, idesc) - mv.visitLabel(l2) - mv.visitFrame(F_SAME, 0, null, 0, null) - mv.visitInsn(RETURN) - mv.visitMaxs(2, 2) - mv.visitEnd() - } - { - mv = cw.visitMethod(ACC_PUBLIC, "partRemoved", "(Lcodechicken/multipart/TMultiPart;I)V", null, null) - mv.visitCode() - mv.visitVarInsn(ALOAD, 0) - mv.visitVarInsn(ALOAD, 1) - mv.visitVarInsn(ILOAD, 2) - mv.visitMethodInsn(INVOKESPECIAL, "codechicken/multipart/TileMultipart", "partRemoved", "(Lcodechicken/multipart/TMultiPart;I)V") - mv.visitVarInsn(ALOAD, 1) - mv.visitVarInsn(ALOAD, 0) - mv.visitFieldInsn(GETFIELD, tname, vname, idesc) - val l2 = new Label() - mv.visitJumpInsn(IF_ACMPNE, l2) - val l3 = new Label() - mv.visitLabel(l3) - mv.visitVarInsn(ALOAD, 0) - mv.visitInsn(ACONST_NULL) - mv.visitFieldInsn(PUTFIELD, tname, vname, idesc) - mv.visitLabel(l2) - mv.visitFrame(F_SAME, 0, null, 0, null) - mv.visitInsn(RETURN) - mv.visitMaxs(3, 3) - mv.visitEnd() - } - { - mv = cw.visitMethod(ACC_PUBLIC, "canAddPart", "(Lcodechicken/multipart/TMultiPart;)Z", null, null) - mv.visitCode() - mv.visitVarInsn(ALOAD, 0) - mv.visitFieldInsn(GETFIELD, tname, vname, idesc) - val l1 = new Label() - mv.visitJumpInsn(IFNULL, l1) - mv.visitVarInsn(ALOAD, 1) - mv.visitTypeInsn(INSTANCEOF, iname) - mv.visitJumpInsn(IFEQ, l1) - val l2 = new Label() - mv.visitLabel(l2) - mv.visitInsn(ICONST_0) - mv.visitInsn(IRETURN) - mv.visitLabel(l1) - mv.visitFrame(F_SAME, 0, null, 0, null) - mv.visitVarInsn(ALOAD, 0) - mv.visitVarInsn(ALOAD, 1) - mv.visitMethodInsn(INVOKESPECIAL, "codechicken/multipart/TileMultipart", "canAddPart", "(Lcodechicken/multipart/TMultiPart;)Z") - mv.visitInsn(IRETURN) - mv.visitMaxs(2, 2) - mv.visitEnd() - } - - def methods(cnode:ClassNode):Map[String, MethodNode] = - { - val m = cnode.methods.map(m => (m.name+m.desc, m)).toMap - if(cnode.interfaces != null) - m++cnode.interfaces.flatMap(i => methods(classNode(i))) - else - m - } - - def generatePassThroughMethod(m:MethodNode) - { - mv = cw.visitMethod(ACC_PUBLIC, m.name, m.desc, m.signature, Array(m.exceptions:_*)) - mv.visitVarInsn(ALOAD, 0) - mv.visitFieldInsn(GETFIELD, tname, vname, idesc) - finishBridgeCall(mv, m.desc, INVOKEINTERFACE, iname, m.name, m.desc) - } - - methods(inode).values.foreach(generatePassThroughMethod) - - cw.visitEnd() - internalDefine(tname, cw.toByteArray) - registerTrait(s_interface, tname, false) - return tname - } - - def generateTile(types:Seq[String], client:Boolean) = SuperSet(types, client).generate -} \ No newline at end of file diff --git a/codechicken/multipart/asm/ByteCodecs.scala b/codechicken/multipart/asm/ByteCodecs.scala deleted file mode 100644 index d52c4a4..0000000 --- a/codechicken/multipart/asm/ByteCodecs.scala +++ /dev/null @@ -1,213 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ -package codechicken.multipart.asm - -object ByteCodecs { - - def avoidZero(src: Array[Byte]): Array[Byte] = { - var i = 0 - val srclen = src.length - var count = 0 - while (i < srclen) { - if (src(i) == 0x7f) count += 1 - i += 1 - } - val dst = new Array[Byte](srclen + count) - i = 0 - var j = 0 - while (i < srclen) { - val in = src(i) - if (in == 0x7f) { - dst(j) = (0xc0).toByte - dst(j + 1) = (0x80).toByte - j += 2 - } else { - dst(j) = (in + 1).toByte - j += 1 - } - i += 1 - } - dst - } - - def regenerateZero(src: Array[Byte]): Int = { - var i = 0 - val srclen = src.length - var j = 0 - while (i < srclen) { - val in: Int = src(i) & 0xff - if (in == 0xc0 && (src(i + 1) & 0xff) == 0x80) { - src(j) = 0x7f - i += 2 - } else if (in == 0) { - src(j) = 0x7f - i += 1 - } else { - src(j) = (in - 1).toByte - i += 1 - } - j += 1 - } - j - } - - def encode8to7(src: Array[Byte]): Array[Byte] = { - val srclen = src.length - val dstlen = (srclen * 8 + 6) / 7 - val dst = new Array[Byte](dstlen) - var i = 0 - var j = 0 - while (i + 6 < srclen) { - var in: Int = src(i) & 0xff - dst(j) = (in & 0x7f).toByte - var out: Int = in >>> 7 - in = src(i + 1) & 0xff - dst(j + 1) = (out | (in << 1) & 0x7f).toByte - out = in >>> 6 - in = src(i + 2) & 0xff - dst(j + 2) = (out | (in << 2) & 0x7f).toByte - out = in >>> 5 - in = src(i + 3) & 0xff - dst(j + 3) = (out | (in << 3) & 0x7f).toByte - out = in >>> 4 - in = src(i + 4) & 0xff - dst(j + 4) = (out | (in << 4) & 0x7f).toByte - out = in >>> 3 - in = src(i + 5) & 0xff - dst(j + 5) = (out | (in << 5) & 0x7f).toByte - out = in >>> 2 - in = src(i + 6) & 0xff - dst(j + 6) = (out | (in << 6) & 0x7f).toByte - out = in >>> 1 - dst(j + 7) = out.toByte - i += 7 - j += 8 - } - if (i < srclen) { - var in: Int = src(i) & 0xff - dst(j) = (in & 0x7f).toByte; j += 1 - var out: Int = in >>> 7 - if (i + 1 < srclen) { - in = src(i + 1) & 0xff - dst(j) = (out | (in << 1) & 0x7f).toByte; j += 1 - out = in >>> 6 - if (i + 2 < srclen) { - in = src(i + 2) & 0xff - dst(j) = (out | (in << 2) & 0x7f).toByte; j += 1 - out = in >>> 5 - if (i + 3 < srclen) { - in = src(i + 3) & 0xff - dst(j) = (out | (in << 3) & 0x7f).toByte; j += 1 - out = in >>> 4 - if (i + 4 < srclen) { - in = src(i + 4) & 0xff - dst(j) = (out | (in << 4) & 0x7f).toByte; j += 1 - out = in >>> 3 - if (i + 5 < srclen) { - in = src(i + 5) & 0xff - dst(j) = (out | (in << 5) & 0x7f).toByte; j += 1 - out = in >>> 2 - } - } - } - } - } - if (j < dstlen) dst(j) = out.toByte - } - dst - } - - def decode7to8(src: Array[Byte], srclen: Int): Int = { - var i = 0 - var j = 0 - val dstlen = (srclen * 7 + 7) / 8 - while (i + 7 < srclen) { - var out: Int = src(i).toInt - var in: Byte = src(i + 1) - src(j) = (out | (in & 0x01) << 7).toByte - out = in >>> 1 - in = src(i + 2) - src(j + 1) = (out | (in & 0x03) << 6).toByte - out = in >>> 2 - in = src(i + 3) - src(j + 2) = (out | (in & 0x07) << 5).toByte - out = in >>> 3 - in = src(i + 4) - src(j + 3) = (out | (in & 0x0f) << 4).toByte - out = in >>> 4 - in = src(i + 5) - src(j + 4) = (out | (in & 0x1f) << 3).toByte - out = in >>> 5 - in = src(i + 6) - src(j + 5) = (out | (in & 0x3f) << 2).toByte - out = in >>> 6 - in = src(i + 7) - src(j + 6) = (out | in << 1).toByte - i += 8 - j += 7 - } - if (i < srclen) { - var out: Int = src(i).toInt - if (i + 1 < srclen) { - var in: Byte = src(i + 1) - src(j) = (out | (in & 0x01) << 7).toByte; j += 1 - out = in >>> 1 - if (i + 2 < srclen) { - in = src(i + 2) - src(j) = (out | (in & 0x03) << 6).toByte; j += 1 - out = in >>> 2 - if (i + 3 < srclen) { - in = src(i + 3) - src(j) = (out | (in & 0x07) << 5).toByte; j += 1 - out = in >>> 3 - if (i + 4 < srclen) { - in = src(i + 4) - src(j) = (out | (in & 0x0f) << 4).toByte; j += 1 - out = in >>> 4 - if (i + 5 < srclen) { - in = src(i + 5) - src(j) = (out | (in & 0x1f) << 3).toByte; j += 1 - out = in >>> 5 - if (i + 6 < srclen) { - in = src(i + 6) - src(j) = (out | (in & 0x3f) << 2).toByte; j += 1 - out = in >>> 6 - } - } - } - } - } - } - if (j < dstlen) src(j) = out.toByte - } - dstlen - } - - def encode(xs: Array[Byte]): Array[Byte] = avoidZero(encode8to7(xs)) - - /** - * Destructively decodes array xs and returns the length of the decoded array. - * - * Sometimes returns (length+1) of the decoded array. Example: - * - * scala> val enc = scala.reflect.generic.ByteCodecs.encode(Array(1,2,3)) - * enc: Array[Byte] = Array(2, 5, 13, 1) - * - * scala> scala.reflect.generic.ByteCodecs.decode(enc) - * res43: Int = 4 - * - * scala> enc - * res44: Array[Byte] = Array(1, 2, 3, 0) - * - * However, this does not always happen. - */ - def decode(xs: Array[Byte]): Int = { - val len = regenerateZero(xs) - decode7to8(xs, len) - } -} \ No newline at end of file diff --git a/codechicken/multipart/asm/IMultipartFactory.scala b/codechicken/multipart/asm/IMultipartFactory.scala deleted file mode 100644 index 11a0c3c..0000000 --- a/codechicken/multipart/asm/IMultipartFactory.scala +++ /dev/null @@ -1,12 +0,0 @@ -package codechicken.multipart.asm - -import codechicken.multipart.TileMultipart - -trait IMultipartFactory -{ - def registerTrait(s_interface:String, s_trait:String, client:Boolean) - - def generatePassThroughTrait(s_interface:String):String - - def generateTile(types:Seq[String], client:Boolean):TileMultipart -} \ No newline at end of file diff --git a/codechicken/multipart/asm/ScalaSignature.scala b/codechicken/multipart/asm/ScalaSignature.scala deleted file mode 100644 index 708a1eb..0000000 --- a/codechicken/multipart/asm/ScalaSignature.scala +++ /dev/null @@ -1,341 +0,0 @@ -package codechicken.multipart.asm - -import org.objectweb.asm.tree.ClassNode -import org.objectweb.asm.tree.AnnotationNode -import org.objectweb.asm.tree.FieldNode -import org.objectweb.asm.tree.MethodNode -import java.util.{List => JList} -import scala.collection.mutable.{ListBuffer => MList} -import scala.collection.JavaConverters._ -import scala.collection.JavaConversions._ - -import ScalaSignature._ - -object ScalaSignature -{ - object Bytes - { - implicit def reader(bc:Bytes) = new ByteCodeReader(bc) - - def apply(bytes:Array[Byte], pos:Int, len:Int) = new Bytes(bytes, pos, len) - def apply(bytes:Array[Byte]):Bytes = apply(bytes, 0, bytes.length) - } - - class Bytes(val bytes:Array[Byte], val pos:Int, val len:Int) - { - def section() = bytes take pos drop len - } - - trait Flags - { - def hasFlag(flag:Int):Boolean - - def isPrivate = hasFlag(0x00000004) - def isProtected = hasFlag(0x00000008) - def isAbstract = hasFlag(0x00000080) - def isInterface = hasFlag(0x00000800) - def isMethod = hasFlag(0x00000200) - def isParam = hasFlag(0x00002000) - def isStatic = hasFlag(0x00800000) - def isTrait = hasFlag(0x02000000) - def isAccessor = hasFlag(0x08000000) - } - - trait SymbolRef extends Flags - { - def full:String - def flags:Int - def hasFlag(flag:Int) = (flags&flag) != 0 - } - - case class ClassSymbol(name:String, owner:SymbolRef, flags:Int, info:Int) extends SymbolRef - { - override def toString = "ClassSymbol("+name+","+owner+","+flags.toHexString+","+info+")" - def full = owner.full+"."+name - - def info(sig:ScalaSignature):ClassType = sig.evalT(info) - def jParent(sig:ScalaSignature) = info(sig).parent.jName - def jInterfaces(sig:ScalaSignature) = info(sig).interfaces.map(_.jName) - } - - case class MethodSymbol(name:String, owner:SymbolRef, flags:Int, info:Int) extends SymbolRef - { - override def toString = "MethodSymbol("+name+","+owner+","+flags.toHexString+","+info+")" - def full = owner.full+"."+name - - def info(sig:ScalaSignature):SMethodType = sig.evalT(info) - def jDesc(sig:ScalaSignature):String = info(sig).jDesc(sig) - } - - case class ExternalSymbol(name:String) extends SymbolRef - { - override def toString = name - def full = name - def flags = 0 - } - - case object NoSymbol extends SymbolRef - { - def full = "" - def flags = 0 - } - - trait SMethodType - { - def jDesc(sig:ScalaSignature):String = "("+params.map(m => m.info(sig).returnType.jDesc).mkString+")"+returnType.jDesc - def returnType:TypeRef - def params:List[MethodSymbol] - } - - case class ClassType(owner:SymbolRef, parents:List[TypeRef]) - { - def parent = parents.head - def interfaces = parents.drop(1) - } - - case class MethodType(returnType:TypeRef, params:List[MethodSymbol]) extends SMethodType - - case class ParameterlessType(returnType:TypeRef) extends SMethodType - { - def params = List() - } - - trait TypeRef - { - def name:String - def jName = name.replace('.', '/') match { - case "scala/AnyRef" => "java/lang/Object" - case s => s - } - def jDesc:String = name match - { - case "scala.Array" => null - case "scala.Long" => "J" - case "scala.Int" => "I" - case "scala.Short" => "S" - case "scala.Byte" => "B" - case "scala.Double" => "D" - case "scala.Float" => "F" - case "scala.Boolean" => "Z" - case "scala.Unit" => "V" - case _ => "L"+jName+";" - } - } - - case class TypeRefType(owner:TypeRef, sym:SymbolRef, typArgs:List[TypeRef]) extends TypeRef with SMethodType - { - def params = List() - - def returnType = this - - def name = sym.full - - override def jDesc = name match - { - case "scala.Array" => "["+typArgs(0).jDesc - case _ => super.jDesc - } - } - - case class ThisType(sym:SymbolRef) extends TypeRef - { - def name = sym.full - } - - case class SingleType(owner:TypeRef, sym:SymbolRef) extends TypeRef - { - def name = sym.full - } - - case object NoType extends TypeRef - { - def name = "" - } - - class SigEntry(val start:Int, val bytes:Bytes) - { - def id = bytes.bytes(start) - - def delete() - { - bytes.bytes(start) = 3 - } - } -} -case class ScalaSignature(major:Int, minor:Int, table:Array[SigEntry], bytes:Bytes) -{ - def evalS(i:Int):String = { - val e = table(i) - val bc = e.bytes - val bcr = bc:ByteCodeReader - return e.id match - { - case 1|2 => bcr.readString(bc.len) - case 3 => NoSymbol.full - case 9|10 => - var s = evalS(bcr.readNat) - if(bc.pos+bc.len > bcr.pos) - s = evalS(bcr.readNat)+"."+s - s - } - } - - def evalT[T](i:Int):T = eval(i).asInstanceOf[T] - - def evalList[T](bcr:ByteCodeReader) = - { - var l = MList[T]() - while(bcr.more) - l+=evalT(bcr.readNat) - l.toList - } - - def eval(i:Int):Any = {//we only parse the ones we actually care about - val e = table(i) - val bc = e.bytes - val bcr = bc:ByteCodeReader - return e.id match - { - case 1|2 => evalS(i) - case 6 => ClassSymbol(evalS(bcr.readNat), evalT(bcr.readNat), bcr.readNat, bcr.readNat) - case 8 => MethodSymbol(evalS(bcr.readNat), evalT(bcr.readNat), bcr.readNat, bcr.readNat) - case 9|10 => ExternalSymbol(evalS(i)) - case 11|12 => NoType //12 is actually NoPrefixType (no lower bound) - case 13 => ThisType(evalT(bcr.readNat)) - case 14 => SingleType(evalT(bcr.readNat), evalT(bcr.readNat)) - case 16 => TypeRefType(evalT(bcr.readNat), evalT(bcr.readNat), evalList(bcr)) - case 19 => ClassType(evalT(bcr.readNat), evalList(bcr)) - case 20 => MethodType(evalT(bcr.readNat), evalList(bcr)) - case 21|48 => ParameterlessType(evalT(bcr.readNat))//48 is actually a bounded super type, but it should work fine for our purposes - case _ => NoSymbol - } - } -} - -class ByteCodeReader(val bc:Bytes) -{ - var pos = bc.pos - - def more = pos < bc.pos+bc.len - - def readString(len:Int) = advance(len)(new String(bc.bytes drop pos take len)) - - def readByte = advance(1)(bc.bytes(pos)) - - def readNat:Int = - { - var r = 0 - var b = 0 - do - { - b = readByte - r = r<<7|b&0x7F - } - while((b&0x80) != 0) - return r - } - - def advance[A](len:Int)(r:A):A = - { - if(pos+len > bc.pos+bc.len) - throw new IllegalArgumentException("Ran off the end of bytecode") - pos+=len - return r - } - - def readEntry = - { - val p = pos - val tpe:Int = readByte - val len = readNat - advance(len)(new SigEntry(p, new Bytes(bc.bytes, pos, len))) - } - - def readSig = - { - val major = readByte - val minor = readByte - val table = new Array[SigEntry](readNat) - for(i <- 0 until table.size) - table(i) = readEntry - ScalaSignature(major, minor, table, bc) - } -} - -object ScalaSigReader -{ - def decode(s:String):Array[Byte] = - { - val bytes = s.getBytes - return bytes take ByteCodecs.decode(bytes) - } - - def encode(b:Array[Byte]):String = - { - val bytes = ByteCodecs.encode8to7(b) - var i = 0 - while(i < bytes.length) - { - bytes(i) = ((bytes(i)+1)&0x7F).toByte - i+=1 - } - return new String(bytes.take(bytes.length-1), "UTF-8") - } - - def read(ann:AnnotationNode):ScalaSignature = Bytes(decode(ann.values.get(1).asInstanceOf[String])).readSig - - def write(sig:ScalaSignature, ann:AnnotationNode) = ann.values.set(1, encode(sig.bytes.bytes)) - - def ann(cnode:ClassNode):Option[AnnotationNode] = cnode.visibleAnnotations match { - case null => None - case a => a.find(ann => ann.desc.equals("Lscala/reflect/ScalaSignature;")) - } -} - -class ScalaSigSideTransformer -{ - def transform(ann:AnnotationNode, cnode:ClassNode, removedFields:JList[FieldNode], removedMethods:JList[MethodNode]) - { - if(removedFields.isEmpty && removedMethods.isEmpty) - return - - val remFields = removedFields.asScala.map(f => (f.name, f.desc.replace('$', '/'))) - val remMethods = removedMethods.asScala.map(f => (f.name, f.desc.replace('$', '/'))) - - val sig = ScalaSigReader.read(ann) - for(i <- 0 until sig.table.length) - { - val e = sig.table(i) - if(e.id == 8)//check and remove - { - val sym:MethodSymbol = sig.evalT(i) - if(sym.isAccessor) - { - val fName = if(sym.name.endsWith("_$eq")) sym.name.substring(0, sym.name.length-4) else sym.name - if(remFields.find(t => t._1 == sym.name.trim).nonEmpty) - { - e.delete() - val it = cnode.methods.iterator - while(it.hasNext) - { - val m = it.next - if(m.name == sym.name && m.desc == sym.jDesc(sig)) - it.remove() - } - } - } - else if(sym.isMethod) - { - if(remMethods.find(t => t._1 == sym.name && t._2 == sym.jDesc(sig)).nonEmpty) - e.delete() - } - else//field - { - if(remFields.find(t => t._1 == sym.name.trim).nonEmpty) - e.delete() - } - } - } - ScalaSigReader.write(sig, ann) - } -} \ No newline at end of file diff --git a/codechicken/multipart/asm/StackAnalyser.scala b/codechicken/multipart/asm/StackAnalyser.scala deleted file mode 100644 index 444e778..0000000 --- a/codechicken/multipart/asm/StackAnalyser.scala +++ /dev/null @@ -1,314 +0,0 @@ -package codechicken.multipart.asm - -import scala.collection.mutable.{Map => MMap, ListBuffer => MList} -import org.objectweb.asm.tree._ -import org.objectweb.asm.Opcodes._ -import org.objectweb.asm.Type -import org.objectweb.asm.Type._ -import scala.collection.JavaConversions._ - -object StackAnalyser -{ - def width(t:Type):Int = t.getSize - def width(s:String):Int = width(Type.getType(s)) - def width(it:Iterable[Type]):Int = it.foldLeft(0)(_+width(_)) - - abstract class StackEntry(implicit val insn:AbstractInsnNode) - { - def getType:Type - } - abstract class LocalEntry - { - def getType:Type - } - - case class This(owner:Type) extends LocalEntry - { - def getType = owner - } - case class Param(i:Int, t:Type) extends LocalEntry - { - def getType = t - } - case class Store(e:StackEntry)(implicit val insn:AbstractInsnNode) extends LocalEntry - { - def getType = e.getType - } - - case class Const(c:Any)(implicit insn:AbstractInsnNode) extends StackEntry - { - def getType = c match { - case o:Byte => BYTE_TYPE - case o:Short => SHORT_TYPE - case o:Int => INT_TYPE - case o:Long => LONG_TYPE - case o:Float => FLOAT_TYPE - case o:Double => DOUBLE_TYPE - case o:Char => CHAR_TYPE - case o:Boolean => BOOLEAN_TYPE - case o:String => getObjectType("java/lang/String") - case null => getObjectType("java/lang/Object") - case _ => throw new IllegalArgumentException("Unknown const "+c) - } - } - case class Load(e:LocalEntry)(implicit insn:AbstractInsnNode) extends StackEntry - { - def getType = e.getType - } - case class UnaryOp(op:Int, e:StackEntry)(implicit insn:AbstractInsnNode) extends StackEntry - { - def getType = e.getType - } - case class BinaryOp(op:Int, e2:StackEntry, e1:StackEntry)(implicit insn:AbstractInsnNode) extends StackEntry - { - def getType = e1.getType - } - case class PrimitiveCast(e:StackEntry, t:Type)(implicit insn:AbstractInsnNode) extends StackEntry - { - def getType = t - } - case class ReturnAddress()(implicit insn:AbstractInsnNode) extends StackEntry - { - def getType = INT_TYPE - } - case class GetField(obj:StackEntry, field:FieldInsnNode)(implicit insn:AbstractInsnNode) extends StackEntry - { - def getType = Type.getType(field.desc) - } - case class Invoke(op:Int, params:Array[StackEntry], obj:StackEntry, method:MethodInsnNode)(implicit insn:AbstractInsnNode) extends StackEntry - { - def getType = Type.getMethodType(method.desc).getReturnType - } - case class New(t:Type)(implicit insn:AbstractInsnNode) extends StackEntry - { - def getType = t - } - case class NewArray(len:StackEntry, t:Type)(implicit insn:AbstractInsnNode) extends StackEntry - { - def getType = t - } - case class ArrayLength(array:StackEntry)(implicit insn:AbstractInsnNode) extends StackEntry - { - def getType = INT_TYPE - } - case class ArrayLoad(index:StackEntry, e:StackEntry)(implicit insn:AbstractInsnNode) extends StackEntry - { - def getType = e.getType.getElementType - } - case class Cast(obj:StackEntry, t:Type)(implicit insn:AbstractInsnNode) extends StackEntry - { - def getType = t - } - case class NewMultiArray(sizes:Array[StackEntry], t:Type)(implicit insn:AbstractInsnNode) extends StackEntry - { - def getType = t - } - case class CaughtException(t:Type)(implicit insn:AbstractInsnNode) extends StackEntry - { - def getType = t - } -} - -class StackAnalyser(val owner:Type, val m:MethodNode) -{ - import StackAnalyser._ - - val stack = MList[StackEntry]() - val locals = MList[LocalEntry]() - private val catchHandlers = MMap[LabelNode, TryCatchBlockNode]() - - { - if((m.access & ACC_STATIC) == 0) - pushL(This(owner)) - - val ptypes = getArgumentTypes(m.desc) - for(i <- 0 until ptypes.length) - pushL(Param(i, ptypes(i))) - - m.tryCatchBlocks.foreach(b => catchHandlers.put(b.handler, b)) - } - - def pushL(entry:LocalEntry) = setL(locals.size, entry) - - def setL(i:Int, entry:LocalEntry) = - { - while(i+entry.getType.getSize > locals.size) locals += null - locals(i) = entry - if(entry.getType.getSize == 2) - locals(i+1) = entry - } - - def push(entry:StackEntry) = insert(0, entry) - - def _pop(i:Int = 0) = stack.remove(stack.size-i-1) - - def pop(i:Int = 0) = - { - val e = _pop(i) - if(e.getType.getSize == 2) - { - if(peek(i) != e) throw new IllegalStateException("Wide stack entry elems don't match ("+e+","+peek(i)) - _pop(i) - } - e - } - - def peek(i:Int = 0) = stack(stack.size-i-1) - - def insert(i:Int, entry:StackEntry) - { - if(entry.getType.getSize == 0) - return - stack.insert(stack.size-i, entry) - if(entry.getType.getSize == 2) - stack.insert(stack.size-i, entry) - } - - def popArgs(desc:String) = - { - val t = getType(desc) - val args = new Array[StackEntry](t.getArgumentTypes.length) - for(i <- 0 until args.length) - args(args.length-i-1) = pop() - args - } - - def visitInsn(ainsn:AbstractInsnNode) - { - implicit val thisInsn = ainsn//passes to any StackEntry we create - ainsn match { - case insn:InsnNode => ainsn.getOpcode match - { - case ACONST_NULL => push(Const(null)) - case ICONST_M1 => push(Const(-1)) - case ICONST_0 => push(Const(0)) - case ICONST_1 => push(Const(1)) - case ICONST_2 => push(Const(2)) - case ICONST_3 => push(Const(3)) - case ICONST_4 => push(Const(4)) - case ICONST_5 => push(Const(5)) - case LCONST_0 => push(Const(0L)) - case LCONST_1 => push(Const(1L)) - case FCONST_0 => push(Const(0F)) - case FCONST_1 => push(Const(1F)) - case FCONST_2 => push(Const(2F)) - case DCONST_0 => push(Const(0D)) - case DCONST_1 => push(Const(1D)) - - case i if i >= IALOAD && i <= SALOAD => - push(ArrayLoad(pop(), pop())) - case i if i >= IASTORE && i <= SASTORE => - pop(); pop(); pop() - - case POP => _pop() - case POP2 => _pop(); _pop() - case DUP => push(peek()) - case DUP_X1 => insert(2, peek()) - case DUP_X2 => insert(3, peek()) - case DUP2 => push(peek(1)); push(peek(1)) - case DUP2_X1 => insert(3, peek(1)); insert(3, peek()) - case DUP2_X2 => insert(4, peek(1)); insert(4, peek()) - case SWAP => push(pop(1)) - - case i if i >= IADD && i <= DREM => - push(BinaryOp(i, pop(), pop())) - case i if i >= INEG && i <= DNEG => - push(UnaryOp(i, pop())) - case i if i >= ISHL && i <= LXOR => - push(BinaryOp(i, pop(), pop())) - - case L2I|F2I|D2I => push(PrimitiveCast(pop(), DOUBLE_TYPE)) - case I2L|F2L|D2L => push(PrimitiveCast(pop(), LONG_TYPE)) - case I2F|L2F|D2F => push(PrimitiveCast(pop(), FLOAT_TYPE)) - case I2D|L2D|F2D => push(PrimitiveCast(pop(), DOUBLE_TYPE)) - case I2B => push(PrimitiveCast(pop(), BYTE_TYPE)) - case I2C => push(PrimitiveCast(pop(), CHAR_TYPE)) - case I2S => push(PrimitiveCast(pop(), SHORT_TYPE)) - - case i if i >= LCMP && i <= DCMPG => - push(BinaryOp(i, pop(), pop())) - - case i if i >= IRETURN && i <= ARETURN => pop() - - case ARRAYLENGTH => push(ArrayLength(pop())) - case ATHROW => pop() - case MONITORENTER|MONITOREXIT => pop() - - case _ => - - } - case iinsn:IntInsnNode => ainsn.getOpcode match - { - case BIPUSH => push(Const(iinsn.operand.toByte)) - case SIPUSH => push(Const(iinsn.operand.toShort)) - } - case ldcinsn:LdcInsnNode => ainsn.getOpcode match - { - case LDC => push(Const(ldcinsn.cst)) - } - case vinsn:VarInsnNode => ainsn.getOpcode match - { - case i if i >= ILOAD && i <= ALOAD => - push(Load(locals(vinsn.`var`))) - case i if i >= ISTORE && i <= ASTORE => - setL(vinsn.`var`, Store(pop())) - } - case incinsn:IincInsnNode => ainsn.getOpcode match - { - case IINC => setL(incinsn.`var`, Store(BinaryOp(IINC, Const(incinsn.incr), Load(locals(incinsn.`var`))))) - } - case jinsn:JumpInsnNode => ainsn.getOpcode match - { - case i if i >= IFEQ && i <= IFLE => pop() - case i if i >= IF_ICMPEQ && i <= IF_ACMPNE => pop(); pop() - case JSR => push(ReturnAddress()) - case IFNULL|IFNONNULL => pop() - case GOTO => - } - case sinsn:TableSwitchInsnNode => pop() - case linsn:LookupSwitchInsnNode => pop() - case finsn:FieldInsnNode => ainsn.getOpcode match - { - case GETSTATIC => push(GetField(null, finsn)) - case PUTSTATIC => pop() - case GETFIELD => push(GetField(pop(), finsn)) - case PUTFIELD => pop(); pop() - } - case minsn:MethodInsnNode => ainsn.getOpcode match - { - case INVOKEVIRTUAL|INVOKESPECIAL|INVOKEINTERFACE => - push(Invoke(ainsn.getOpcode, popArgs(minsn.desc), pop(), minsn)) - case INVOKESTATIC => - push(Invoke(ainsn.getOpcode, popArgs(minsn.desc), null, minsn)) - } - case tinsn:TypeInsnNode => ainsn.getOpcode match - { - case NEW => push(New(getType(tinsn.desc))) - case NEWARRAY => push(NewArray(pop(), getType(tinsn.desc))) - case ANEWARRAY => push(NewArray(pop(), getType("["+tinsn.desc))) - case CHECKCAST => push(Cast(pop(), getType(tinsn.desc))) - case INSTANCEOF => push(UnaryOp(INSTANCEOF, pop())) - } - case mainsn:MultiANewArrayInsnNode => - val sizes = new Array[StackEntry](mainsn.dims) - for(i <- 0 until sizes.length) - sizes(i) = pop() - push(NewMultiArray(sizes, getType(mainsn.desc))) - /*case fnode:FrameNode => fnode.`type` match - { - case F_NEW|F_FULL => println("reset stacks/locals") - case F_APPEND => println("add local") - case F_CHOP => println("rem locals") - case F_SAME => println("reset") - case F_SAME1 => println("reset locals and all but bottom stack") - }*/ - case lnode:LabelNode => - catchHandlers.get(lnode) match - { - case Some(tcblock) => push(CaughtException(Type.getType(tcblock.`type`))) - case None => - } - case _ => - } - } -} \ No newline at end of file diff --git a/codechicken/multipart/handler/MultipartCompatiblity.scala b/codechicken/multipart/handler/MultipartCompatiblity.scala deleted file mode 100644 index fbb83c5..0000000 --- a/codechicken/multipart/handler/MultipartCompatiblity.scala +++ /dev/null @@ -1,33 +0,0 @@ -package codechicken.multipart.handler - -import net.minecraft.world.World -import cpw.mods.fml.common.FMLCommonHandler -import net.minecraft.block.Block - -object MultipartCompatiblity -{ - var canAddPart = (world:World, x:Int, y:Int, z:Int) => true - - def load() { - if(FMLCommonHandler.instance().getModName.contains("mcpc")) - MCPCCompatModule.load() - } -} - -object MCPCCompatModule -{ - def load() { - try { - val m_canPlacePart = classOf[World].getDeclaredMethod("canPlaceMultipart", classOf[Block], classOf[Int], classOf[Int], classOf[Int]) - MultipartCompatiblity.canAddPart = (world:World, x:Int, y:Int, z:Int) => { - m_canPlacePart.invoke(world, MultipartProxy.block, x:Integer, y:Integer, z:Integer).asInstanceOf[Boolean].booleanValue() - } - } catch { - case e:Exception => - System.err.println("Failed to integrate MCPC placement hooks") - e.printStackTrace() - } - } -} - - diff --git a/codechicken/multipart/handler/MultipartEventHandler.scala b/codechicken/multipart/handler/MultipartEventHandler.scala deleted file mode 100644 index 327d2bb..0000000 --- a/codechicken/multipart/handler/MultipartEventHandler.scala +++ /dev/null @@ -1,67 +0,0 @@ -package codechicken.multipart.handler - -import codechicken.multipart.TileMultipart -import cpw.mods.fml.common.eventhandler.{EventPriority, SubscribeEvent} -import net.minecraft.server.MinecraftServer -import codechicken.lib.packet.PacketCustom -import codechicken.multipart.MultiPartRegistry -import net.minecraftforge.event.world._ -import java.util.EnumSet -import scala.collection.JavaConverters._ -import java.util.List -import net.minecraft.entity.player.EntityPlayerMP -import cpw.mods.fml.relauncher.SideOnly -import cpw.mods.fml.relauncher.Side -import net.minecraftforge.client.event.DrawBlockHighlightEvent -import codechicken.multipart.BlockMultipart -import net.minecraft.util.MovingObjectPosition -import net.minecraft.util.MovingObjectPosition.MovingObjectType -import cpw.mods.fml.common.gameevent.TickEvent - -object MultipartEventHandler -{ - @SubscribeEvent(priority = EventPriority.HIGHEST) - def tileEntityLoad(event:ChunkDataEvent.Load) - { - MultipartSaveLoad.loadTiles(event.getChunk) - } - - @SubscribeEvent - def worldUnLoad(event:WorldEvent.Unload) - { - MultipartSPH.onWorldUnload(event.world) - } - - @SubscribeEvent - def chunkWatch(event:ChunkWatchEvent.Watch) - { - MultipartSPH.onChunkWatch(event.player, event.chunk) - } - - @SubscribeEvent - def chunkUnWatch(event:ChunkWatchEvent.UnWatch) - { - MultipartSPH.onChunkUnWatch(event.player, event.chunk) - } - - @SubscribeEvent - @SideOnly(Side.CLIENT) - def drawBlockHighlight(event:DrawBlockHighlightEvent) - { - if(event.target != null && event.target.typeOfHit == MovingObjectType.BLOCK && - event.player.worldObj.getTileEntity(event.target.blockX, event.target.blockY, event.target.blockZ).isInstanceOf[TileMultipart]) - { - if(BlockMultipart.drawHighlight(event.player.worldObj, event.player, event.target, event.partialTicks)) - event.setCanceled(true) - } - } - - @SubscribeEvent - def serverTick(event:TickEvent.ServerTickEvent) - { - if(event.phase == TickEvent.Phase.END) - MultipartSPH.onTickEnd( - MinecraftServer.getServer.getConfigurationManager.playerEntityList - .asInstanceOf[List[EntityPlayerMP]].asScala) - } -} \ No newline at end of file diff --git a/codechicken/multipart/handler/MultipartMod.scala b/codechicken/multipart/handler/MultipartMod.scala deleted file mode 100644 index 06e368a..0000000 --- a/codechicken/multipart/handler/MultipartMod.scala +++ /dev/null @@ -1,42 +0,0 @@ -package codechicken.multipart.handler - -import cpw.mods.fml.common.Mod -import cpw.mods.fml.common.event.FMLPostInitializationEvent -import cpw.mods.fml.common.event.FMLPreInitializationEvent -import cpw.mods.fml.common.event.FMLInitializationEvent -import cpw.mods.fml.common.Mod.EventHandler -import cpw.mods.fml.common.event.FMLServerAboutToStartEvent -import codechicken.multipart.MultiPartRegistry - -@Mod(modid = "ForgeMultipart", acceptedMinecraftVersions = "[1.7.2]", - modLanguage="scala") -object MultipartMod -{ - @EventHandler - def preInit(event:FMLPreInitializationEvent) - { - MultipartProxy.preInit(event.getModConfigurationDirectory) - } - - @EventHandler - def init(event:FMLInitializationEvent) - { - MultipartProxy.init() - } - - @EventHandler - def postInit(event:FMLPostInitializationEvent) - { - if(MultiPartRegistry.required) - { - MultiPartRegistry.postInit() - MultipartProxy.postInit() - } - } - - @EventHandler - def beforeServerStart(event:FMLServerAboutToStartEvent) - { - MultiPartRegistry.beforeServerStart() - } -} \ No newline at end of file diff --git a/codechicken/multipart/handler/MultipartSaveLoad.scala b/codechicken/multipart/handler/MultipartSaveLoad.scala deleted file mode 100644 index 0d3fd06..0000000 --- a/codechicken/multipart/handler/MultipartSaveLoad.scala +++ /dev/null @@ -1,69 +0,0 @@ -package codechicken.multipart.handler - -import net.minecraft.tileentity.TileEntity -import net.minecraft.nbt.NBTTagCompound -import java.util.Map -import net.minecraft.world.chunk.Chunk -import net.minecraft.world.ChunkPosition -import codechicken.multipart.TileMultipart -import codechicken.lib.asm.ObfMapping -import net.minecraft.world.World - -/** - * Hack due to lack of TileEntityLoadEvent in forge - */ -object MultipartSaveLoad -{ - var loadingWorld: World = _ - - class TileNBTContainer extends TileEntity - { - var tag: NBTTagCompound = _ - - override def readFromNBT(t: NBTTagCompound) { - super.readFromNBT(t) - tag = t - } - } - - def hookLoader() { - val field = classOf[TileEntity].getDeclaredField( - new ObfMapping("net/minecraft/tileentity/TileEntity", "field_145855_i", "Ljava/util/Map;") - .toRuntime.s_name) - field.setAccessible(true) - val map = field.get(null).asInstanceOf[Map[String, Class[_ <: TileEntity]]] - map.put("savedMultipart", classOf[TileNBTContainer]) - } - - private val classToNameMap = getClassToNameMap - - def registerTileClass(t: Class[_ <: TileEntity]) { - classToNameMap.put(t, "savedMultipart") - } - - def getClassToNameMap = { - val field = classOf[TileEntity].getDeclaredField( - new ObfMapping("net/minecraft/tileentity/TileEntity", "field_145853_j", "Ljava/util/Map;") - .toRuntime.s_name) - field.setAccessible(true) - field.get(null).asInstanceOf[Map[Class[_ <: TileEntity], String]] - } - - def loadTiles(chunk: Chunk) { - loadingWorld = chunk.worldObj - val iterator = chunk.chunkTileEntityMap.asInstanceOf[Map[ChunkPosition, TileEntity]].entrySet.iterator - while (iterator.hasNext) { - val e = iterator.next - if (e.getValue.isInstanceOf[TileNBTContainer]) { - val t = TileMultipart.createFromNBT(e.getValue.asInstanceOf[TileNBTContainer].tag) - if (t != null) { - t.setWorldObj(e.getValue.getWorldObj) - t.validate() - e.setValue(t) - } - else - iterator.remove() - } - } - } -} \ No newline at end of file diff --git a/codechicken/multipart/handler/packethandlers.scala b/codechicken/multipart/handler/packethandlers.scala deleted file mode 100644 index b154b79..0000000 --- a/codechicken/multipart/handler/packethandlers.scala +++ /dev/null @@ -1,180 +0,0 @@ -package codechicken.multipart.handler - -import codechicken.lib.packet.PacketCustom.{IHandshakeHandler, IClientPacketHandler, IServerPacketHandler} -import codechicken.lib.packet.PacketCustom -import net.minecraft.client.Minecraft -import codechicken.multipart.MultiPartRegistry -import net.minecraft.entity.player.EntityPlayerMP -import codechicken.multipart.ControlKeyModifer -import net.minecraft.world.World -import net.minecraft.world.chunk.Chunk -import java.util.{Map => JMap} -import java.util.Iterator -import net.minecraft.tileentity.TileEntity -import codechicken.multipart.TileMultipart -import net.minecraft.entity.player.EntityPlayer -import scala.collection.mutable.{Map, Set, HashMap, MultiMap} -import codechicken.lib.vec.BlockCoord -import codechicken.lib.data.MCOutputStreamWrapper -import java.io.DataOutputStream -import java.io.ByteArrayOutputStream -import net.minecraft.world.ChunkCoordIntPair -import MultipartProxy._ -import codechicken.multipart.PacketScheduler -import java.util.LinkedList -import scala.collection.JavaConversions._ -import net.minecraft.network.play.{INetHandlerPlayServer, INetHandlerPlayClient} -import net.minecraft.network.play.server.S40PacketDisconnect -import net.minecraft.util.ChatComponentTranslation -import net.minecraft.network.NetHandlerPlayServer - -class MultipartPH -{ - val channel = MultipartMod - val registryChannel = "ForgeMultipart" -} - -object MultipartCPH extends MultipartPH with IClientPacketHandler -{ - def handlePacket(packet: PacketCustom, mc: Minecraft, netHandler:INetHandlerPlayClient) { - packet.getType match { - case 1 => handlePartRegistration(packet, netHandler) - case 2 => handleCompressedTileDesc(packet, mc.theWorld) - case 3 => handleCompressedTileData(packet, mc.theWorld) - } - } - - def handlePartRegistration(packet: PacketCustom, netHandler: INetHandlerPlayClient) { - val missing = MultiPartRegistry.readIDMap(packet) - if (!missing.isEmpty) - netHandler.handleDisconnect(new S40PacketDisconnect(new ChatComponentTranslation("multipart.missing", missing.mkString(", ")))) - } - - def handleCompressedTileDesc(packet: PacketCustom, world: World) { - val cc = new ChunkCoordIntPair(packet.readInt, packet.readInt) - val num = packet.readUShort - for (i <- 0 until num) - TileMultipart.handleDescPacket(world, indexInChunk(cc, packet.readShort), packet) - } - - def handleCompressedTileData(packet: PacketCustom, world: World) { - var x = packet.readInt - while (x != Int.MaxValue) { - val pos = new BlockCoord(x, packet.readInt, packet.readInt) - var i = packet.readUByte - while (i < 255) { - TileMultipart.handlePacket(pos, world, i, packet) - i = packet.readUByte - } - x = packet.readInt - } - TileMultipart.flushClientCache() - } -} - -object MultipartSPH extends MultipartPH with IServerPacketHandler with IHandshakeHandler -{ - class MCByteStream(bout: ByteArrayOutputStream) extends MCOutputStreamWrapper(new DataOutputStream(bout)) - { - def getBytes = bout.toByteArray - } - - private val updateMap = Map[World, Map[BlockCoord, MCByteStream]]() - private val chunkWatchers = new HashMap[EntityPlayer, Set[ChunkCoordIntPair]] with MultiMap[EntityPlayer, ChunkCoordIntPair] - private val newWatchers = Map[EntityPlayer, LinkedList[ChunkCoordIntPair]]() - - def handlePacket(packet: PacketCustom, sender: EntityPlayerMP, netHandler:INetHandlerPlayServer) { - packet.getType match { - case 1 => ControlKeyModifer.map.put(sender, packet.readBoolean) - } - } - - def handshakeRecieved(netHandler: NetHandlerPlayServer) { - val packet = new PacketCustom(registryChannel, 1) - MultiPartRegistry.writeIDMap(packet) - netHandler.sendPacket(packet.toPacket) - } - - def onWorldUnload(world: World) { - if (!world.isRemote) - updateMap.remove(world) - } - - def getTileStream(world: World, pos: BlockCoord) = - updateMap.getOrElseUpdate(world, { - if (world.isRemote) - throw new IllegalArgumentException("Cannot use MultipartSPH on a client world") - Map() - }).getOrElseUpdate(pos, { - val s = new MCByteStream(new ByteArrayOutputStream) - s.writeCoord(pos) - s - }) - - def onTickEnd(players: Seq[EntityPlayerMP]) { - PacketScheduler.sendScheduled() - - for (p <- players if chunkWatchers.containsKey(p)) { - updateMap.get(p.worldObj) match { - case Some(m) if !m.isEmpty => - val chunks = chunkWatchers(p) - val packet = new PacketCustom(channel, 3).compress() - var send = false - for ((pos, stream) <- m if chunks(new ChunkCoordIntPair(pos.x >> 4, pos.z >> 4))) { - send = true - packet.writeByteArray(stream.getBytes) - packet.writeByte(255) //terminator - } - if (send) { - packet.writeInt(Int.MaxValue) //terminator - packet.sendToPlayer(p) - } - case _ => - } - } - updateMap.foreach(_._2.clear()) - for ((p, chunks) <- newWatchers) { - chunks.foreach { - c => - val chunk = p.worldObj.getChunkFromChunkCoords(c.chunkXPos, c.chunkZPos) - val pkt = getDescPacket(chunk, chunk.chunkTileEntityMap.asInstanceOf[JMap[_, TileEntity]].values.iterator) - if (pkt != null) pkt.sendToPlayer(p) - chunkWatchers.addBinding(p, c) - } - chunks.clear() - } - } - - def onChunkWatch(player: EntityPlayer, c: ChunkCoordIntPair) { - newWatchers.getOrElseUpdate(player, new LinkedList).add(c) - } - - def onChunkUnWatch(player: EntityPlayer, c: ChunkCoordIntPair) { - newWatchers.get(player) match { - case Some(chunks) => chunks.remove(c) - case _ => - } - chunkWatchers.removeBinding(player, c) - } - - def getDescPacket(chunk: Chunk, it: Iterator[TileEntity]): PacketCustom = { - val s = new MCByteStream(new ByteArrayOutputStream) - - var num = 0 - while (it.hasNext) { - val tile = it.next - if (tile.isInstanceOf[TileMultipart]) { - s.writeShort(indexInChunk(new BlockCoord(tile))) - tile.asInstanceOf[TileMultipart].writeDesc(s) - num += 1 - } - } - if (num != 0) { - return new PacketCustom(channel, 2).compress() - .writeInt(chunk.xPosition).writeInt(chunk.zPosition) - .writeShort(num) - .writeByteArray(s.getBytes) - } - return null - } -} diff --git a/codechicken/multipart/handler/proxies.scala b/codechicken/multipart/handler/proxies.scala deleted file mode 100644 index edf6c3c..0000000 --- a/codechicken/multipart/handler/proxies.scala +++ /dev/null @@ -1,92 +0,0 @@ -package codechicken.multipart.handler - -import codechicken.multipart._ -import cpw.mods.fml.client.registry.RenderingRegistry -import cpw.mods.fml.client.registry.ClientRegistry -import net.minecraft.tileentity.TileEntity -import codechicken.lib.config.ConfigFile -import java.io.File -import codechicken.multipart.handler.MultipartProxy._ -import net.minecraftforge.common.MinecraftForge -import cpw.mods.fml.relauncher.SideOnly -import cpw.mods.fml.relauncher.Side -import codechicken.lib.packet.PacketCustom -import net.minecraft.world.ChunkCoordIntPair -import codechicken.lib.vec.BlockCoord -import codechicken.lib.world.WorldExtensionManager -import cpw.mods.fml.common.FMLCommonHandler -import cpw.mods.fml.common.registry.GameRegistry -import net.minecraft.block.Block - -class MultipartProxy_serverImpl -{ - def preInit(cfgdir:File) - { - config = new ConfigFile(new File(cfgdir, "multipart.cfg")) - .setComment("Multipart API config file") - - GameRegistry.registerBlock(new BlockMultipart().setBlockName("multipart"), null, "block") - block = Block.blockRegistry.getObject("ForgeMultipart:block").asInstanceOf[BlockMultipart] - - MultipartGenerator.registerTrait("codechicken.multipart.TSlottedPart", "codechicken.multipart.scalatraits.TSlottedTile") - MultipartGenerator.registerTrait("net.minecraftforge.fluids.IFluidHandler", "codechicken.multipart.scalatraits.TFluidHandlerTile") - MultipartGenerator.registerTrait("net.minecraft.inventory.IInventory", "codechicken.multipart.scalatraits.JInventoryTile") - MultipartGenerator.registerTrait("net.minecraft.inventory.ISIdedInventory", "codechicken.multipart.scalatraits.JInventoryTile") - MultipartGenerator.registerTrait("codechicken.multipart.JPartialOcclusion", "codechicken.multipart.scalatraits.TPartialOcclusionTile") - MultipartGenerator.registerTrait("codechicken.multipart.IRedstonePart", "codechicken.multipart.scalatraits.TRedstoneTile") - MultipartGenerator.registerTrait("codechicken.multipart.IRandomDisplayTick", "codechicken.multipart.scalatraits.TRandomDisplayTickTile", null) - MultipartGenerator.registerTrait("codechicken.multipart.INeighborTileChange", null, "codechicken.multipart.scalatraits.TTileChangeTile") - - MultipartSaveLoad.hookLoader() - } - - def init(){} - - def postInit() - { - FMLCommonHandler.instance().bus().register(MultipartEventHandler) - MinecraftForge.EVENT_BUS.register(MultipartEventHandler) - PacketCustom.assignHandler(MultipartSPH.channel, MultipartSPH) - PacketCustom.assignHandshakeHandler(MultipartSPH.registryChannel, MultipartSPH) - - WorldExtensionManager.registerWorldExtension(TickScheduler) - - MultipartCompatiblity.load() - } - - def onTileClassBuilt(t:Class[_ <: TileEntity]) - { - MultipartSaveLoad.registerTileClass(t) - } -} - -class MultipartProxy_clientImpl extends MultipartProxy_serverImpl -{ - @SideOnly(Side.CLIENT) - override def postInit() - { - super.postInit() - RenderingRegistry.registerBlockHandler(MultipartRenderer) - PacketCustom.assignHandler(MultipartCPH.channel, MultipartCPH) - PacketCustom.assignHandler(MultipartCPH.registryChannel, MultipartCPH) - - FMLCommonHandler.instance().bus().register(ControlKeyHandler) - ClientRegistry.registerKeyBinding(ControlKeyHandler) - } - - @SideOnly(Side.CLIENT) - override def onTileClassBuilt(t:Class[_ <: TileEntity]) - { - super.onTileClassBuilt(t) - ClientRegistry.bindTileEntitySpecialRenderer(t, MultipartRenderer) - } -} - -object MultipartProxy extends MultipartProxy_clientImpl -{ - var block:BlockMultipart = _ - var config:ConfigFile = _ - - def indexInChunk(cc:ChunkCoordIntPair, i:Int) = new BlockCoord(cc.chunkXPos<<4|i&0xF, (i>>8)&0xFF, cc.chunkZPos<<4|(i&0xF0)>>4) - def indexInChunk(pos:BlockCoord) = pos.x&0xF|pos.y<<8|(pos.z&0xF)<<4 -} \ No newline at end of file diff --git a/codechicken/multipart/minecraft/ButtonPart.java b/codechicken/multipart/minecraft/ButtonPart.java deleted file mode 100644 index af82f33..0000000 --- a/codechicken/multipart/minecraft/ButtonPart.java +++ /dev/null @@ -1,184 +0,0 @@ -package codechicken.multipart.minecraft; - -import codechicken.lib.vec.BlockCoord; -import codechicken.lib.vec.Cuboid6; -import codechicken.lib.vec.Vector3; -import codechicken.multipart.IFaceRedstonePart; -import codechicken.multipart.TickScheduler; -import net.minecraft.block.Block; -import net.minecraft.block.BlockButton; -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.projectile.EntityArrow; -import net.minecraft.init.Blocks; -import net.minecraft.item.ItemStack; -import net.minecraft.util.MovingObjectPosition; -import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - -public class ButtonPart extends McSidedMetaPart implements IFaceRedstonePart -{ - public static BlockButton stoneButton = (BlockButton) Blocks.stone_button; - public static BlockButton woodenButton = (BlockButton) Blocks.wooden_button; - public static int[] metaSideMap = new int[]{-1, 4, 5, 2, 3}; - public static int[] sideMetaMap = new int[]{-1, -1, 3, 4, 1, 2}; - - public static BlockButton getButton(int meta) - { - return (meta&0x10) > 0 ? woodenButton : stoneButton; - } - - public ButtonPart() - { - } - - public ButtonPart(int meta) - { - super(meta); - } - - @Override - public int sideForMeta(int meta) - { - return metaSideMap[meta&7]; - } - - @Override - public Block getBlock() - { - return getButton(meta); - } - - @Override - public String getType() - { - return "mc_button"; - } - - public int delay() - { - return sensitive() ? 30 : 20; - } - - public boolean sensitive() - { - return (meta&0x10) > 0; - } - - @Override - public Cuboid6 getBounds() - { - int m = meta & 7; - double d = pressed() ? 0.0625 : 0.125; - - if (m == 1) - return new Cuboid6(0.0, 0.375, 0.5 - 0.1875, d, 0.625, 0.5 + 0.1875); - if (m == 2) - return new Cuboid6(1.0 - d, 0.375, 0.5 - 0.1875, 1.0, 0.625, 0.5 + 0.1875); - if (m == 3) - return new Cuboid6(0.5 - 0.1875, 0.375, 0.0, 0.5 + 0.1875, 0.625, d); - if (m == 4) - return new Cuboid6(0.5 - 0.1875, 0.375, 1.0 - d, 0.5 + 0.1875, 0.625, 1.0); - - return null;//falloff - } - - public static McBlockPart placement(World world, BlockCoord pos, int side, int type) - { - if(side == 0 || side == 1) - return null; - - pos = pos.copy().offset(side^1); - if(!world.isSideSolid(pos.x, pos.y, pos.z, ForgeDirection.getOrientation(side))) - return null; - - return new ButtonPart(sideMetaMap[side^1]|type<<4); - } - - @Override - public boolean activate(EntityPlayer player, MovingObjectPosition part, ItemStack item) - { - if(pressed()) - return false; - - if(!world().isRemote) - toggle(); - - return true; - } - - @Override - public void scheduledTick() - { - if(pressed()) - updateState(); - } - - public boolean pressed() - { - return (meta&8) > 0; - } - - @Override - public void onEntityCollision(Entity entity) - { - if(!pressed() && !world().isRemote && entity instanceof EntityArrow) - updateState(); - } - - private void toggle() - { - boolean in = !pressed(); - meta^=8; - world().playSoundEffect(x() + 0.5, y() + 0.5, z() + 0.5, "random.click", 0.3F, in ? 0.6F : 0.5F); - if(in) - scheduleTick(delay()); - - sendDescUpdate(); - tile().notifyPartChange(this); - tile().notifyNeighborChange(metaSideMap[meta&7]); - tile().markDirty(); - } - - private void updateState() - { - boolean arrows = sensitive() && !world().getEntitiesWithinAABB(EntityArrow.class, - getBounds().add(Vector3.fromTileEntity(tile())).toAABB()).isEmpty(); - boolean pressed = pressed(); - - if(arrows != pressed) - toggle(); - if(arrows && pressed) - scheduleTick(delay()); - } - - @Override - public void onRemoved() - { - if(pressed()) - tile().notifyNeighborChange(metaSideMap[meta&7]); - } - - @Override - public int weakPowerLevel(int side) - { - return pressed() ? 15 : 0; - } - - @Override - public int strongPowerLevel(int side) - { - return pressed() && side == metaSideMap[meta&7] ? 15 : 0; - } - - @Override - public boolean canConnectRedstone(int side) - { - return true; - } - - @Override - public int getFace() { - return metaSideMap[meta&7]; - } -} diff --git a/codechicken/multipart/minecraft/Content.java b/codechicken/multipart/minecraft/Content.java deleted file mode 100644 index 89e50da..0000000 --- a/codechicken/multipart/minecraft/Content.java +++ /dev/null @@ -1,63 +0,0 @@ -package codechicken.multipart.minecraft; - -import net.minecraft.block.Block; -import net.minecraft.init.Blocks; -import net.minecraft.world.World; -import codechicken.lib.vec.BlockCoord; -import codechicken.multipart.MultiPartRegistry.IPartConverter; -import codechicken.multipart.MultiPartRegistry.IPartFactory; -import codechicken.multipart.MultiPartRegistry; -import codechicken.multipart.TMultiPart; - -import java.util.Arrays; - -public class Content implements IPartFactory, IPartConverter -{ - @Override - public TMultiPart createPart(String name, boolean client) - { - if(name.equals("mc_torch")) return new TorchPart(); - if(name.equals("mc_lever")) return new LeverPart(); - if(name.equals("mc_button")) return new ButtonPart(); - if(name.equals("mc_redtorch")) return new RedstoneTorchPart(); - - return null; - } - - public void init() - { - MultiPartRegistry.registerConverter(this); - MultiPartRegistry.registerParts(this, new String[]{ - "mc_torch", - "mc_lever", - "mc_button", - "mc_redtorch" - }); - } - - @Override - public Iterable blockTypes() { - return Arrays.asList(Blocks.torch, Blocks.lever, Blocks.stone_button, Blocks.wooden_button, Blocks.redstone_torch, Blocks.unlit_redstone_torch); - } - - @Override - public TMultiPart convert(World world, BlockCoord pos) - { - Block b = world.getBlock(pos.x, pos.y, pos.z); - int meta = world.getBlockMetadata(pos.x, pos.y, pos.z); - if(b == Blocks.torch) - return new TorchPart(meta); - if(b == Blocks.lever) - return new LeverPart(meta); - if(b == Blocks.stone_button) - return new ButtonPart(meta); - if(b == Blocks.wooden_button) - return new ButtonPart(meta|0x10); - if(b == Blocks.redstone_torch) - return new RedstoneTorchPart(meta); - if(b == Blocks.unlit_redstone_torch) - return new RedstoneTorchPart(meta|0x10); - - return null; - } -} diff --git a/codechicken/multipart/minecraft/EventHandler.java b/codechicken/multipart/minecraft/EventHandler.java deleted file mode 100644 index 83fddfe..0000000 --- a/codechicken/multipart/minecraft/EventHandler.java +++ /dev/null @@ -1,123 +0,0 @@ -package codechicken.multipart.minecraft; - -import codechicken.lib.packet.PacketCustom; -import codechicken.lib.raytracer.RayTracer; -import codechicken.lib.vec.BlockCoord; -import codechicken.lib.vec.Vector3; -import codechicken.multipart.TileMultipart; -import net.minecraft.block.Block; -import net.minecraft.block.BlockFence; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; -import net.minecraft.item.ItemStack; -import net.minecraft.network.play.client.C08PacketPlayerBlockPlacement; -import net.minecraft.util.MovingObjectPosition; -import net.minecraft.world.World; -import net.minecraftforge.common.MinecraftForge; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent; -import net.minecraftforge.event.entity.player.PlayerInteractEvent; -import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action; - -public class EventHandler -{ - private ThreadLocal placing = new ThreadLocal(); - - @SubscribeEvent - public void playerInteract(PlayerInteractEvent event) - { - if(event.action == Action.RIGHT_CLICK_BLOCK && event.entityPlayer.worldObj.isRemote) - { - if(placing.get() != null) - return;//for mods that do dumb stuff and call this event like MFR - placing.set(event); - if(place(event.entityPlayer, event.entityPlayer.worldObj)) - event.setCanceled(true); - placing.set(null); - } - } - - public static boolean place(EntityPlayer player, World world) - { - MovingObjectPosition hit = RayTracer.reTrace(world, player); - if(hit == null) - return false; - - BlockCoord pos = new BlockCoord(hit.blockX, hit.blockY, hit.blockZ).offset(hit.sideHit); - ItemStack held = player.getHeldItem(); - McBlockPart part = null; - if(held == null) - return false; - - Block heldBlock = Block.getBlockFromItem(held.getItem()); - if(heldBlock == Blocks.air) - return false; - - if(heldBlock == Blocks.torch) - part = TorchPart.placement(world, pos, hit.sideHit); - else if(heldBlock == Blocks.lever) - part = LeverPart.placement(world, pos, player, hit.sideHit); - else if(heldBlock == Blocks.stone_button) - part = ButtonPart.placement(world, pos, hit.sideHit, 0); - else if(heldBlock == Blocks.wooden_button) - part = ButtonPart.placement(world, pos, hit.sideHit, 1); - else if(heldBlock == Blocks.redstone_torch) - part = RedstoneTorchPart.placement(world, pos, hit.sideHit); - - if(part == null) - return false; - - if(world.isRemote && !player.isSneaking())//attempt to use block activated like normal and tell the server the right stuff - { - Vector3 f = new Vector3(hit.hitVec).add(-hit.blockX, -hit.blockY, -hit.blockZ); - Block block = world.getBlock(hit.blockX, hit.blockY, hit.blockZ); - if(!ignoreActivate(block) && block.onBlockActivated(world, hit.blockX, hit.blockY, hit.blockZ, player, hit.sideHit, (float)f.x, (float)f.y, (float)f.z)) - { - player.swingItem(); - PacketCustom.sendToServer(new C08PacketPlayerBlockPlacement( - hit.blockX, hit.blockY, hit.blockZ, hit.sideHit, - player.inventory.getCurrentItem(), - (float)f.x, (float)f.y, (float)f.z)); - return false; - } - } - - TileMultipart tile = TileMultipart.getOrConvertTile(world, pos); - if(tile == null || !tile.canAddPart(part)) - return false; - - if(!world.isRemote) - { - TileMultipart.addPart(world, pos, part); - world.playSoundEffect(pos.x + 0.5, pos.y + 0.5, pos.z + 0.5, - part.getBlock().stepSound.func_150496_b(), - (part.getBlock().stepSound.getVolume() + 1.0F) / 2.0F, - part.getBlock().stepSound.getPitch() * 0.8F); - if(!player.capabilities.isCreativeMode) - { - held.stackSize--; - if (held.stackSize == 0) - { - player.inventory.mainInventory[player.inventory.currentItem] = null; - MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(player, held)); - } - } - } - else - { - player.swingItem(); - new PacketCustom(McMultipartSPH.channel, 1).sendToServer(); - } - return true; - } - - /** - * Because vanilla is weird. - */ - private static boolean ignoreActivate(Block block) - { - if(block instanceof BlockFence) - return true; - return false; - } -} diff --git a/codechicken/multipart/minecraft/IPartMeta.java b/codechicken/multipart/minecraft/IPartMeta.java deleted file mode 100644 index c9e62a5..0000000 --- a/codechicken/multipart/minecraft/IPartMeta.java +++ /dev/null @@ -1,16 +0,0 @@ -package codechicken.multipart.minecraft; - -import codechicken.lib.vec.BlockCoord; -import net.minecraft.block.Block; -import net.minecraft.world.World; - -public interface IPartMeta -{ - public int getMetadata(); - - public World getWorld(); - - public Block getBlock(); - - public BlockCoord getPos(); -} \ No newline at end of file diff --git a/codechicken/multipart/minecraft/LeverPart.java b/codechicken/multipart/minecraft/LeverPart.java deleted file mode 100644 index e638c68..0000000 --- a/codechicken/multipart/minecraft/LeverPart.java +++ /dev/null @@ -1,152 +0,0 @@ -package codechicken.multipart.minecraft; - -import net.minecraft.block.Block; -import net.minecraft.block.BlockLever; -import net.minecraft.client.renderer.RenderBlocks; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; -import net.minecraft.item.ItemStack; -import net.minecraft.util.MovingObjectPosition; -import net.minecraft.world.IBlockAccess; -import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; -import codechicken.lib.vec.BlockCoord; -import codechicken.lib.vec.Cuboid6; -import codechicken.multipart.IFaceRedstonePart; - -public class LeverPart extends McSidedMetaPart implements IFaceRedstonePart -{ - public static BlockLever lever = (BlockLever) Blocks.lever; - public static int[] metaSideMap = new int[]{1, 4, 5, 2, 3, 0, 0, 1}; - public static int[] sideMetaMap = new int[]{6, 0, 3, 4, 1, 2}; - public static int[] metaSwapMap = new int[]{5, 7}; - - public LeverPart() - { - } - - public LeverPart(int meta) - { - super(meta); - } - - @Override - public Block getBlock() - { - return lever; - } - - @Override - public String getType() - { - return "mc_lever"; - } - - public boolean active() - { - return (meta&8) > 0; - } - - @Override - public Cuboid6 getBounds() - { - int m = meta & 7; - double d = 0.1875; - - if (m == 1) - return new Cuboid6(0, 0.2, 0.5 - d, d * 2, 0.8, 0.5 + d); - if (m == 2) - return new Cuboid6(1 - d * 2, 0.2, 0.5 - d, 1, 0.8, 0.5 + d); - if (m == 3) - return new Cuboid6(0.5 - d, 0.2, 0, 0.5 + d, 0.8, d * 2); - if (m == 4) - return new Cuboid6(0.5 - d, 0.2, 1 - d * 2, 0.5 + d, 0.8, 1); - - d = 0.25; - if (m == 0 || m == 7) - return new Cuboid6(0.5 - d, 0.4, 0.5 - d, 0.5 + d, 1, 0.5 + d); - - return new Cuboid6(0.5 - d, 0, 0.5 - d, 0.5 + d, 0.6, 0.5 + d); - } - - @Override - public int sideForMeta(int meta) - { - return metaSideMap[meta&7]; - } - - public static McBlockPart placement(World world, BlockCoord pos, EntityPlayer player, int side) - { - pos = pos.copy().offset(side^1); - if(!world.isSideSolid(pos.x, pos.y, pos.z, ForgeDirection.getOrientation(side))) - return null; - - int meta = sideMetaMap[side^1]; - if(side < 2 && ((int)(player.rotationYaw / 90 + 0.5) & 1) == 0) - meta = metaSwapMap[side^1]; - - return new LeverPart(meta); - } - - @Override - public boolean activate(EntityPlayer player, MovingObjectPosition part, ItemStack item) - { - World world = world(); - if(world.isRemote) - return true; - - world.playSoundEffect(x() + 0.5, y() + 0.5, z() + 0.5, "random.click", 0.3F, !active() ? 0.6F : 0.5F); - meta ^= 8; - sendDescUpdate(); - tile().notifyPartChange(this); - tile().notifyNeighborChange(metaSideMap[meta&7]); - tile().markDirty(); - return true; - } - - @Override - public void drawBreaking(RenderBlocks renderBlocks) - { - IBlockAccess actual = renderBlocks.blockAccess; - renderBlocks.blockAccess = new PartMetaAccess(this); - renderBlocks.renderBlockLever(lever, x(), y(), z()); - renderBlocks.blockAccess = actual; - } - - @Override - public void onRemoved() - { - if(active()) - tile().notifyNeighborChange(metaSideMap[meta&7]); - } - - @Override - public void onConverted() - { - if(active()) - tile().notifyNeighborChange(metaSideMap[meta&7]); - } - - @Override - public int weakPowerLevel(int side) - { - return active() ? 15 : 0; - } - - @Override - public int strongPowerLevel(int side) - { - return active() && side == metaSideMap[meta&7] ? 15 : 0; - } - - @Override - public boolean canConnectRedstone(int side) - { - return true; - } - - @Override - public int getFace() { - return metaSideMap[meta&7]; - } -} diff --git a/codechicken/multipart/minecraft/McBlockPart.java b/codechicken/multipart/minecraft/McBlockPart.java deleted file mode 100644 index 9a43b43..0000000 --- a/codechicken/multipart/minecraft/McBlockPart.java +++ /dev/null @@ -1,92 +0,0 @@ -package codechicken.multipart.minecraft; - -import java.util.Arrays; -import java.util.Collections; - -import net.minecraft.block.Block; -import net.minecraft.client.particle.EffectRenderer; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import net.minecraft.util.MovingObjectPosition; -import codechicken.lib.vec.Cuboid6; -import codechicken.multipart.IconHitEffects; -import codechicken.multipart.JCuboidPart; -import codechicken.multipart.JIconHitEffects; -import codechicken.multipart.JNormalOcclusion; -import codechicken.multipart.NormalOcclusionTest; -import codechicken.multipart.TMultiPart; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -public abstract class McBlockPart extends JCuboidPart implements JNormalOcclusion, JIconHitEffects -{ - public abstract Block getBlock(); - - @Override - public boolean occlusionTest(TMultiPart npart) - { - return NormalOcclusionTest.apply(this, npart); - } - - @Override - public Iterable getOcclusionBoxes() - { - return Arrays.asList(getBounds()); - } - - @Override - public Iterable getCollisionBoxes() - { - return Collections.emptyList(); - } - - @Override - public Iterable getDrops() - { - return Arrays.asList(new ItemStack(getBlock())); - } - - @Override - public ItemStack pickItem(MovingObjectPosition hit) - { - return new ItemStack(getBlock()); - } - - @Override - public float getStrength(MovingObjectPosition hit, EntityPlayer player) - { - return getBlock().getPlayerRelativeBlockHardness(player, player.worldObj, hit.blockX, hit.blockY, hit.blockZ)*30; - } - - @Override - public IIcon getBreakingIcon(Object subPart, int side) - { - return getBlock().getIcon(0, 0); - } - - @Override - @SideOnly(Side.CLIENT) - public IIcon getBrokenIcon(int side) - { - return getBlock().getIcon(0, 0); - } - - @Override - public void addHitEffects(MovingObjectPosition hit, EffectRenderer effectRenderer) - { - IconHitEffects.addHitEffects(this, hit, effectRenderer); - } - - @Override - public void addDestroyEffects(MovingObjectPosition hit, EffectRenderer effectRenderer) - { - IconHitEffects.addDestroyEffects(this, effectRenderer, false); - } - - @Override - public int getLightValue() - { - return getBlock().getLightValue(); - } -} diff --git a/codechicken/multipart/minecraft/McMetaPart.java b/codechicken/multipart/minecraft/McMetaPart.java deleted file mode 100644 index a520d38..0000000 --- a/codechicken/multipart/minecraft/McMetaPart.java +++ /dev/null @@ -1,82 +0,0 @@ -package codechicken.multipart.minecraft; - -import codechicken.lib.data.MCDataInput; -import codechicken.lib.data.MCDataOutput; -import codechicken.lib.lighting.LightMatrix; -import codechicken.lib.vec.BlockCoord; -import codechicken.lib.vec.Vector3; -import net.minecraft.client.renderer.RenderBlocks; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.world.World; - -public abstract class McMetaPart extends McBlockPart implements IPartMeta -{ - public byte meta; - - public McMetaPart() - { - } - - public McMetaPart(int meta) - { - this.meta = (byte)meta; - } - - @Override - public void save(NBTTagCompound tag) - { - tag.setByte("meta", meta); - } - - @Override - public void load(NBTTagCompound tag) - { - meta = tag.getByte("meta"); - } - - @Override - public void writeDesc(MCDataOutput packet) - { - packet.writeByte(meta); - } - - @Override - public void readDesc(MCDataInput packet) - { - meta = packet.readByte(); - } - - @Override - public World getWorld() - { - return world(); - } - - @Override - public int getMetadata() - { - return meta; - } - - @Override - public BlockCoord getPos() - { - return new BlockCoord(tile()); - } - - @Override - public boolean doesTick() - { - return false; - } - - @Override - public boolean renderStatic(Vector3 pos, int pass) - { - if(pass == 0) { - new RenderBlocks(new PartMetaAccess(this)).renderBlockByRenderType(getBlock(), x(), y(), z()); - return true; - } - return false; - } -} diff --git a/codechicken/multipart/minecraft/McMultipartCPH.java b/codechicken/multipart/minecraft/McMultipartCPH.java deleted file mode 100644 index ebe9bc5..0000000 --- a/codechicken/multipart/minecraft/McMultipartCPH.java +++ /dev/null @@ -1,30 +0,0 @@ -package codechicken.multipart.minecraft; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.WorldClient; -import codechicken.lib.packet.PacketCustom; -import codechicken.lib.packet.PacketCustom.IClientPacketHandler; -import codechicken.lib.vec.BlockCoord; -import net.minecraft.network.play.INetHandlerPlayClient; - -public class McMultipartCPH implements IClientPacketHandler -{ - public static Object channel = MinecraftMultipartMod.instance; - - @Override - public void handlePacket(PacketCustom packet, Minecraft mc, INetHandlerPlayClient netHandler) { - switch (packet.getType()) { - case 1: - spawnBurnoutSmoke(mc.theWorld, packet.readCoord()); - break; - } - } - - private void spawnBurnoutSmoke(WorldClient world, BlockCoord pos) { - for (int l = 0; l < 5; l++) - world.spawnParticle("smoke", - pos.x + world.rand.nextDouble() * 0.6 + 0.2, - pos.y + world.rand.nextDouble() * 0.6 + 0.2, - pos.z + world.rand.nextDouble() * 0.6 + 0.2, 0, 0, 0); - } -} diff --git a/codechicken/multipart/minecraft/McMultipartSPH.java b/codechicken/multipart/minecraft/McMultipartSPH.java deleted file mode 100644 index c812d7f..0000000 --- a/codechicken/multipart/minecraft/McMultipartSPH.java +++ /dev/null @@ -1,25 +0,0 @@ -package codechicken.multipart.minecraft; - -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.network.play.INetHandlerPlayServer; -import net.minecraft.world.World; -import codechicken.lib.packet.PacketCustom; -import codechicken.lib.packet.PacketCustom.IServerPacketHandler; - -public class McMultipartSPH implements IServerPacketHandler -{ - public static Object channel = MinecraftMultipartMod.instance; - - @Override - public void handlePacket(PacketCustom packet, EntityPlayerMP sender, INetHandlerPlayServer netHandler) { - switch (packet.getType()) { - case 1: - EventHandler.place(sender, sender.worldObj); - break; - } - } - - public static void spawnBurnoutSmoke(World world, int x, int y, int z) { - new PacketCustom(channel, 1).writeCoord(x, y, z).sendToChunk(world, x >> 4, z >> 4); - } -} diff --git a/codechicken/multipart/minecraft/McSidedMetaPart.java b/codechicken/multipart/minecraft/McSidedMetaPart.java deleted file mode 100644 index 34d83c7..0000000 --- a/codechicken/multipart/minecraft/McSidedMetaPart.java +++ /dev/null @@ -1,69 +0,0 @@ -package codechicken.multipart.minecraft; - -import net.minecraft.item.ItemStack; -import net.minecraftforge.common.util.ForgeDirection; -import codechicken.lib.vec.BlockCoord; -import codechicken.lib.vec.Vector3; -import codechicken.multipart.TFacePart; -import codechicken.multipart.TileMultipart; - -public abstract class McSidedMetaPart extends McMetaPart implements TFacePart -{ - public McSidedMetaPart() - { - } - - public McSidedMetaPart(int meta) - { - super(meta); - } - - public abstract int sideForMeta(int meta); - - @Override - public void onNeighborChanged() - { - if(!world().isRemote) - dropIfCantStay(); - } - - public boolean canStay() - { - BlockCoord pos = new BlockCoord(tile()).offset(sideForMeta(meta)); - return world().isSideSolid(pos.x, pos.y, pos.z, ForgeDirection.getOrientation(sideForMeta(meta)^1)); - } - - public boolean dropIfCantStay() - { - if(!canStay()) - { - drop(); - return true; - } - return false; - } - - public void drop() - { - TileMultipart.dropItem(new ItemStack(getBlock()), world(), Vector3.fromTileEntityCenter(tile())); - tile().remPart(this); - } - - @Override - public int getSlotMask() - { - return 1< 0; - } - - @Override - public String getType() - { - return "mc_redtorch"; - } - - @Override - public int sideForMeta(int meta) - { - return super.sideForMeta(meta&7); - } - - @Override - public Cuboid6 getBounds() - { - return getBounds(meta&7); - } - - public static McBlockPart placement(World world, BlockCoord pos, int side) - { - if(side == 0) - return null; - pos = pos.copy().offset(side^1); - if(!world.isSideSolid(pos.x, pos.y, pos.z, ForgeDirection.getOrientation(side))) - return null; - - return new RedstoneTorchPart(sideMetaMap[side^1]|0x10); - } - - @Override - public void randomDisplayTick(Random random) - { - if(!active()) - return; - - double d0 = x() + 0.5 + (random.nextFloat() - 0.5) * 0.2; - double d1 = y() + 0.7 + (random.nextFloat() - 0.5) * 0.2; - double d2 = z() + 0.5 + (random.nextFloat() - 0.5) * 0.2; - double d3 = 0.22D; - double d4 = 0.27D; - - World world = world(); - int m = meta&7; - if (m == 1) - world.spawnParticle("reddust", d0 - d4, d1 + d3, d2, 0, 0, 0); - else if (m == 2) - world.spawnParticle("reddust", d0 + d4, d1 + d3, d2, 0, 0, 0); - else if (m == 3) - world.spawnParticle("reddust", d0, d1 + d3, d2 - d4, 0, 0, 0); - else if (m == 4) - world.spawnParticle("reddust", d0, d1 + d3, d2 + d4, 0, 0, 0); - else - world.spawnParticle("reddust", d0, d1, d2, 0, 0, 0); - } - - @Override - public ItemStack pickItem(MovingObjectPosition hit) - { - return new ItemStack(torchActive); - } - - @Override - public void onNeighborChanged() - { - if(!world().isRemote) - { - if(!dropIfCantStay() && isBeingPowered() == active()) - scheduleTick(2); - } - } - - public boolean isBeingPowered() - { - int side = metaSideMap[meta&7]; - return RedstoneInteractions.getPowerTo(this, side) > 0; - } - - @Override - public void scheduledTick() - { - if(!world().isRemote && isBeingPowered() == active()) - toggle(); - } - - @Override - public void randomUpdate() - { - scheduledTick(); - } - - private boolean burnedOut(boolean add) - { - long time = world().getTotalWorldTime(); - while(burnout != null && burnout.timeout <= time) - burnout = burnout.next; - - if(add) - { - BurnoutEntry e = new BurnoutEntry(world().getTotalWorldTime()+60); - if(burnout == null) - burnout = e; - else - { - BurnoutEntry b = burnout; - while(b.next != null) - b = b.next; - b.next = e; - } - } - - if(burnout == null) - return false; - - int i = 0; - BurnoutEntry b = burnout; - while(b != null) - { - i++; - b = b.next; - } - return i >= 8; - } - - private void toggle() - { - if(active())//deactivating - { - if(burnedOut(true)) - { - World world = world(); - Random rand = world.rand; - world.playSoundEffect(x()+0.5, y()+0.5, z()+0.5, "random.fizz", 0.5F, 2.6F + (rand.nextFloat() - rand.nextFloat()) * 0.8F); - McMultipartSPH.spawnBurnoutSmoke(world, x(), y(), z()); - } - } - else if(burnedOut(false)) - { - return; - } - - meta ^= 0x10; - sendDescUpdate(); - tile().markDirty(); - tile().notifyPartChange(this); - tile().notifyNeighborChange(1); - } - - @Override - public void drop() { - meta|=0x10;//set state to on for drop - super.drop(); - } - - @Override - public void onRemoved() - { - if(active()) - tile().notifyNeighborChange(1); - } - - @Override - public void onAdded() - { - if(active()) - tile().notifyNeighborChange(1); - onNeighborChanged(); - } - - @Override - public int strongPowerLevel(int side) - { - return side == 1 && active() ? 15 : 0; - } - - @Override - public int weakPowerLevel(int side) - { - return active() && side != metaSideMap[meta&7] ? 15 : 0; - } - - @Override - public boolean canConnectRedstone(int side) - { - return true; - } - - @Override - public int getFace() { - return metaSideMap[meta&7]; - } -} diff --git a/codechicken/multipart/minecraft/TorchPart.java b/codechicken/multipart/minecraft/TorchPart.java deleted file mode 100644 index 0d3df63..0000000 --- a/codechicken/multipart/minecraft/TorchPart.java +++ /dev/null @@ -1,122 +0,0 @@ -package codechicken.multipart.minecraft; - -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.block.BlockTorch; -import net.minecraft.init.Blocks; -import net.minecraft.world.World; -import codechicken.multipart.IRandomDisplayTick; -import codechicken.lib.vec.BlockCoord; -import codechicken.lib.vec.Cuboid6; - -public class TorchPart extends McSidedMetaPart implements IRandomDisplayTick -{ - public static BlockTorch torch = (BlockTorch) Blocks.torch; - public static int[] metaSideMap = new int[]{-1, 4, 5, 2, 3, 0}; - public static int[] sideMetaMap = new int[]{5, 0, 3, 4, 1, 2}; - - public TorchPart() - { - } - - public TorchPart(int meta) - { - super(meta); - } - - @Override - public Block getBlock() - { - return torch; - } - - @Override - public String getType() - { - return "mc_torch"; - } - - @Override - public Cuboid6 getBounds() - { - return getBounds(meta); - } - - public Cuboid6 getBounds(int meta) - { - double d = 0.15; - if (meta == 1) - return new Cuboid6(0, 0.2, 0.5 - d, d * 2, 0.8, 0.5 + d); - if (meta == 2) - return new Cuboid6(1 - d * 2, 0.2, 0.5 - d, 1, 0.8, 0.5 + d); - if (meta == 3) - return new Cuboid6(0.5 - d, 0.2, 0, 0.5 + d, 0.8, d * 2); - if (meta == 4) - return new Cuboid6(0.5 - d, 0.2, 1 - d * 2, 0.5 + d, 0.8, 1); - - d = 0.1; - return new Cuboid6(0.5 - d, 0, 0.5 - d, 0.5 + d, 0.6, 0.5 + d); - } - - @Override - public int sideForMeta(int meta) - { - return metaSideMap[meta]; - } - - @Override - public boolean canStay() - { - return sideForMeta(meta) == 0 && world().getBlock(x(), y() - 1, z()).canPlaceTorchOnTop(world(), x(), y() - 1, z()) || super.canStay(); - } - - public static McBlockPart placement(World world, BlockCoord pos, int side) - { - if(side == 0) - return null; - pos = pos.copy().offset(side^1); - Block block = world.getBlock(pos.x, pos.y, pos.z); - if(!block.isBlockSolid(world, pos.x, pos.y, pos.z, side) && (side != 1 || block.canPlaceTorchOnTop(world, pos.x, pos.y, pos.z))) - return null; - - return new TorchPart(sideMetaMap[side^1]); - } - - @Override - public void randomDisplayTick(Random random) - { - double d0 = x() + 0.5; - double d1 = y() + 0.7; - double d2 = z() + 0.5; - double d3 = 0.22D; - double d4 = 0.27D; - - World world = world(); - if (meta == 1) - { - world.spawnParticle("smoke", d0 - d4, d1 + d3, d2, 0, 0, 0); - world.spawnParticle("flame", d0 - d4, d1 + d3, d2, 0, 0, 0); - } - else if (meta == 2) - { - world.spawnParticle("smoke", d0 + d4, d1 + d3, d2, 0, 0, 0); - world.spawnParticle("flame", d0 + d4, d1 + d3, d2, 0, 0, 0); - } - else if (meta == 3) - { - world.spawnParticle("smoke", d0, d1 + d3, d2 - d4, 0, 0, 0); - world.spawnParticle("flame", d0, d1 + d3, d2 - d4, 0, 0, 0); - } - else if (meta == 4) - { - world.spawnParticle("smoke", d0, d1 + d3, d2 + d4, 0, 0, 0); - world.spawnParticle("flame", d0, d1 + d3, d2 + d4, 0, 0, 0); - } - else - { - world.spawnParticle("smoke", d0, d1, d2, 0, 0, 0); - world.spawnParticle("flame", d0, d1, d2, 0, 0, 0); - } - } -} diff --git a/codechicken/multipart/nei/NEI_MicroblockConfig.java b/codechicken/multipart/nei/NEI_MicroblockConfig.java deleted file mode 100644 index 615ee2c..0000000 --- a/codechicken/multipart/nei/NEI_MicroblockConfig.java +++ /dev/null @@ -1,44 +0,0 @@ -package codechicken.multipart.nei; - -/* Commented until NEI is setup with maven - -import codechicken.microblock.MicroblockClass; -import codechicken.microblock.MicroblockClassRegistry; -import codechicken.nei.api.IConfigureNEI; - -public class NEI_MicroblockConfig implements IConfigureNEI -{ - @Override - public void loadConfig() - { - MicroblockClass[] microClasses = MicroblockClassRegistry.classes(); - for(int c = 0; c < microClasses.length; c++) - { - MicroblockClass mcrClass = microClasses[c]; - if(mcrClass == null) - continue; - - addSubset(mcrClass, c<<8|1); - addSubset(mcrClass, c<<8|2); - addSubset(mcrClass, c<<8|4); - } - } - - private void addSubset(MicroblockClass mcrClass, int i) - { - API.addSetRange("Microblocks."+LangUtil.translateG(mcrClass.getName()+"."+(i&0xFF)+".subset"), - new MultiItemRange().add(MicroblockProxy.itemMicro(), i, i)); - } - - @Override - public String getName() - { - return "ForgeMultipart"; - } - - @Override - public String getVersion() - { - return "1.0.0.0"; - } -}*/ \ No newline at end of file diff --git a/codechicken/multipart/scalatraits/TFluidHandlerTile.scala b/codechicken/multipart/scalatraits/TFluidHandlerTile.scala deleted file mode 100644 index dac81af..0000000 --- a/codechicken/multipart/scalatraits/TFluidHandlerTile.scala +++ /dev/null @@ -1,130 +0,0 @@ -package codechicken.multipart.scalatraits - -import net.minecraftforge.common.util.ForgeDirection -import codechicken.multipart.TMultiPart -import codechicken.multipart.TileMultipart -import net.minecraftforge.fluids.IFluidHandler -import net.minecraftforge.fluids.FluidStack -import net.minecraftforge.fluids.FluidTankInfo -import net.minecraftforge.fluids.Fluid -import java.util.LinkedList -import scala.collection.JavaConversions._ - -/** - * Mixin trait implementation for parts implementing IFluidHandler. - * Distributes fluid manipulation among fluid handling parts. - */ -trait TFluidHandlerTile extends TileMultipart with IFluidHandler -{ - var tankList = new LinkedList[IFluidHandler]() - - override def copyFrom(that:TileMultipart) - { - super.copyFrom(that) - if(that.isInstanceOf[TFluidHandlerTile]) - tankList = that.asInstanceOf[TFluidHandlerTile].tankList - } - - override def bindPart(part:TMultiPart) - { - super.bindPart(part) - if(part.isInstanceOf[IFluidHandler]) - tankList+=part.asInstanceOf[IFluidHandler] - } - - override def partRemoved(part:TMultiPart, p:Int) - { - super.partRemoved(part, p) - if(part.isInstanceOf[IFluidHandler]) - tankList-=part.asInstanceOf[IFluidHandler] - } - - override def clearParts() - { - super.clearParts() - tankList.clear() - } - - override def getTankInfo(dir:ForgeDirection):Array[FluidTankInfo] = - { - var tankCount:Int = 0 - tankList.foreach(t => tankCount += t.getTankInfo(dir).length) - val tanks = new Array[FluidTankInfo](tankCount) - var i = 0 - tankList.foreach(p => p.getTankInfo(dir).foreach{t => - tanks(i) = t - i+=1 - }) - return tanks - } - - override def fill(dir:ForgeDirection, liquid:FluidStack, doFill:Boolean):Int = - { - var filled = 0 - val initial = liquid.amount - tankList.foreach(p => - filled+=p.fill(dir, copy(liquid, initial-filled), doFill) - ) - return filled - } - - override def canFill(dir:ForgeDirection, liquid:Fluid) = tankList.find(_.canFill(dir, liquid)).isDefined - - override def canDrain(dir:ForgeDirection, liquid:Fluid) = tankList.find(_.canDrain(dir, liquid)).isDefined - - private def copy(liquid:FluidStack, quantity:Int):FluidStack = - { - val copy = liquid.copy - copy.amount = quantity - return copy - } - - override def drain(dir:ForgeDirection, amount:Int, doDrain:Boolean):FluidStack = - { - var drained:FluidStack = null - var d_amount = 0 - tankList.foreach{p => - val drain = amount-d_amount - val ret = p.drain(dir, drain, false) - if(ret != null && ret.amount > 0 && (drained == null || drained.isFluidEqual(ret))) - { - if(doDrain) - p.drain(dir, drain, true) - - if(drained == null) - drained = ret - - d_amount+=ret.amount - } - } - if(drained != null) - drained.amount = d_amount - - return drained - } - - override def drain(dir:ForgeDirection, fluid:FluidStack, doDrain:Boolean):FluidStack = - { - val amount = fluid.amount - var drained:FluidStack = null - var d_amount = 0 - tankList.foreach{p => - val drain = copy(fluid, amount-d_amount) - val ret = p.drain(dir, drain, false) - if(ret != null && ret.amount > 0 && (drained == null || drained.isFluidEqual(ret))) - { - if(doDrain) - p.drain(dir, drain, true) - - if(drained == null) - drained = ret - - d_amount+=ret.amount - } - } - if(drained != null) - drained.amount = d_amount - - return drained - } -} \ No newline at end of file diff --git a/codechicken/multipart/scalatraits/TIInventoryTile.scala b/codechicken/multipart/scalatraits/TIInventoryTile.scala deleted file mode 100644 index c3103e5..0000000 --- a/codechicken/multipart/scalatraits/TIInventoryTile.scala +++ /dev/null @@ -1,133 +0,0 @@ -package codechicken.multipart.scalatraits - -import net.minecraft.inventory.{IInventory, ISidedInventory} -import codechicken.multipart.{TMultiPart, TileMultipart} -import java.util.LinkedList -import net.minecraft.item.ItemStack -import net.minecraft.entity.player.EntityPlayer -import scala.collection.JavaConversions._ -import scala.collection.mutable.ArrayBuffer - -trait TIInventoryTile extends TileMultipart with ISidedInventory -{ - var invList = new LinkedList[IInventory]() - var slotMap = Array[(IInventory, Int)]() - - override def copyFrom(that:TileMultipart) - { - super.copyFrom(that) - if(that.isInstanceOf[TIInventoryTile]) { - invList = that.asInstanceOf[TIInventoryTile].invList - rebuildSlotMap() - } - } - - override def bindPart(part:TMultiPart) - { - super.bindPart(part) - if(part.isInstanceOf[IInventory]) { - invList+=part.asInstanceOf[IInventory] - rebuildSlotMap() - } - } - - override def partRemoved(part:TMultiPart, p:Int) - { - super.partRemoved(part, p) - if(part.isInstanceOf[IInventory]) { - invList-=part.asInstanceOf[IInventory] - rebuildSlotMap() - } - } - - override def clearParts() - { - super.clearParts() - invList.clear() - slotMap = Array() - } - - def rebuildSlotMap() { - slotMap = Array.ofDim(invList.map(_.getSizeInventory).sum) - var i = 0 - for(inv <- invList; s <- 0 until inv.getSizeInventory) { - slotMap(i) = (inv, s) - i+=1 - } - } - - def getSizeInventory:Int = slotMap.length - - def getStackInSlot(i:Int) = { - val (inv, slot) = slotMap(i) - inv.getStackInSlot(slot) - } - - def decrStackSize(i:Int, j:Int) = { - val (inv, slot) = slotMap(i) - inv.decrStackSize(slot, j) - } - - def getStackInSlotOnClosing(i:Int) = { - val (inv, slot) = slotMap(i) - inv.getStackInSlotOnClosing(slot) - } - - def setInventorySlotContents(i:Int, itemstack:ItemStack) = { - val (inv, slot) = slotMap(i) - inv.setInventorySlotContents(slot, itemstack) - } - - def getInventoryName = "Multipart Inventory" - - def hasCustomInventoryName = false - - def getInventoryStackLimit = 64 - - def isUseableByPlayer(entityplayer:EntityPlayer) = true - - def openInventory(){} - - def closeInventory(){} - - def isItemValidForSlot(i:Int, itemstack:ItemStack) = { - val (inv, slot) = slotMap(i) - inv.isItemValidForSlot(slot, itemstack) - } - - def getAccessibleSlotsFromSide(side:Int) = { - val buf = new ArrayBuffer[Int]() - var base = 0 - for(inv <- invList) { - inv match { - case isided:ISidedInventory => buf++=isided.getAccessibleSlotsFromSide(side).map(_ + base) - case _ => - } - base+=inv.getSizeInventory - } - buf.toArray - } - - def canInsertItem(i:Int, itemstack:ItemStack, j:Int) = { - val (inv, slot) = slotMap(i) - inv match { - case isided:ISidedInventory => isided.canInsertItem(slot, itemstack, j) - case _ => true - } - } - - def canExtractItem(i:Int, itemstack:ItemStack, j:Int) = { - val (inv, slot) = slotMap(i) - inv match { - case isided:ISidedInventory => isided.canExtractItem(slot, itemstack, j) - case _ => true - } - } -} - -/** - * To handle obfuscation issues, this is registered as a java trait. - */ -class JInventoryTile extends TileMultipart with TIInventoryTile -{ -} \ No newline at end of file diff --git a/codechicken/multipart/scalatraits/TPartialOcclusionTile.scala b/codechicken/multipart/scalatraits/TPartialOcclusionTile.scala deleted file mode 100644 index 7deb968..0000000 --- a/codechicken/multipart/scalatraits/TPartialOcclusionTile.scala +++ /dev/null @@ -1,34 +0,0 @@ -package codechicken.multipart.scalatraits - -import codechicken.multipart.TileMultipart -import codechicken.multipart.TMultiPart -import codechicken.multipart.JPartialOcclusion -import codechicken.multipart.PartialOcclusionTest - -/** - * Implementation for the partial occlusion test. - */ -class TPartialOcclusionTile extends TileMultipart -{ - override def occlusionTest(parts:Seq[TMultiPart], npart:TMultiPart):Boolean = - { - if(npart.isInstanceOf[JPartialOcclusion] && !partialOcclusionTest(parts:+npart)) - return false - - return super.occlusionTest(parts, npart) - } - - def partialOcclusionTest(parts:Seq[TMultiPart]):Boolean = - { - val test = new PartialOcclusionTest(parts.length) - var i = 0 - while(i < parts.length) - { - val part = parts(i) - if(part.isInstanceOf[JPartialOcclusion]) - test.fill(i, part.asInstanceOf[JPartialOcclusion]) - i+=1 - } - return test() - } -} \ No newline at end of file diff --git a/codechicken/multipart/scalatraits/TRandomDisplayTickTile.scala b/codechicken/multipart/scalatraits/TRandomDisplayTickTile.scala deleted file mode 100644 index 0759a66..0000000 --- a/codechicken/multipart/scalatraits/TRandomDisplayTickTile.scala +++ /dev/null @@ -1,17 +0,0 @@ -package codechicken.multipart.scalatraits - -import codechicken.multipart.TileMultipartClient -import codechicken.multipart.IRandomDisplayTick -import java.util.Random - -/** - * Saves processor time looping on tiles that don't need it - */ -trait TRandomDisplayTickTile extends TileMultipartClient -{ - override def randomDisplayTick(random:Random) - { - for(p@(_p: IRandomDisplayTick) <- partList.iterator) - p.randomDisplayTick(random) - } -} \ No newline at end of file diff --git a/codechicken/multipart/scalatraits/TRedstoneTile.scala b/codechicken/multipart/scalatraits/TRedstoneTile.scala deleted file mode 100644 index 627853a..0000000 --- a/codechicken/multipart/scalatraits/TRedstoneTile.scala +++ /dev/null @@ -1,87 +0,0 @@ -package codechicken.multipart.scalatraits - -import codechicken.multipart.TileMultipart -import codechicken.multipart.IRedstonePart -import codechicken.multipart.RedstoneInteractions._ -import codechicken.multipart.PartMap._ -import codechicken.lib.vec.Rotation._ -import codechicken.multipart.IRedstoneTile -import codechicken.multipart.TFacePart -import codechicken.multipart.TEdgePart - -/** - * Mixin trait implementation for IRedstonePart - * Provides and overrides various redstone functions. - */ -trait TRedstoneTile extends TileMultipart with IRedstoneTile -{ - /** - * Returns the strong (indirect) power being emitted fr - */ - override def strongPowerLevel(side:Int):Int = - { - var max = 0 - for(p@(_p: IRedstonePart) <- partList.iterator) - { - val l = p.strongPowerLevel(side) - if(l > max) max = l - } - return max - } - - def openConnections(side:Int):Int = - { - var m = 0x10 - var i = 0 - while(i < 4) - { - if(redstoneConductionE(edgeBetween(side, rotateSide(side&6, i)))) - m|=1< 0x1F - case p => p.asInstanceOf[TFacePart].redstoneConductionMap - } - - def redstoneConductionE(i:Int) = partMap(i) match { - case null => true - case p => p.asInstanceOf[TEdgePart].conductsRedstone - } - - override def weakPowerLevel(side:Int):Int = - weakPowerLevel(side, otherConnectionMask(getWorldObj, xCoord, yCoord, zCoord, side, true)) - - override def canConnectRedstone(side:Int):Boolean = - { - val vside = vanillaToSide(side) - return (getConnectionMask(vside) & otherConnectionMask(getWorldObj, xCoord, yCoord, zCoord, vside, false)) > 0 - } - - def getConnectionMask(side:Int):Int = - { - val mask = openConnections(side) - var res = 0 - partList.foreach(p => - res|=connectionMask(p, side)&mask) - return res - } - - def weakPowerLevel(side:Int, mask:Int):Int = - { - val tmask = openConnections(side)&mask - var max = 0 - partList.foreach(p => - if((connectionMask(p, side)&tmask) > 0) - { - val l = p.asInstanceOf[IRedstonePart].weakPowerLevel(side) - if(l > max) max = l - }) - return max - } -} - diff --git a/codechicken/multipart/scalatraits/TSlottedTile.scala b/codechicken/multipart/scalatraits/TSlottedTile.scala deleted file mode 100644 index 2c1ca63..0000000 --- a/codechicken/multipart/scalatraits/TSlottedTile.scala +++ /dev/null @@ -1,64 +0,0 @@ -package codechicken.multipart.scalatraits - -import codechicken.multipart.TileMultipart -import codechicken.multipart.TMultiPart -import codechicken.multipart.TSlottedPart - -/** - * Mixin implementation for TSlottedPart. - * Puts parts into a slot array for quick access at the cost of memory consumption - */ -trait TSlottedTile extends TileMultipart -{ - var v_partMap = new Array[TMultiPart](27) - - override def copyFrom(that:TileMultipart) - { - super.copyFrom(that) - if(that.isInstanceOf[TSlottedTile]) - v_partMap = that.asInstanceOf[TSlottedTile].v_partMap - } - - override def partMap(slot:Int) = v_partMap(slot) - - override def clearParts() - { - super.clearParts() - for(i <- 0 until v_partMap.length) - v_partMap(i) = null - } - - override def partRemoved(part:TMultiPart, p:Int) - { - super.partRemoved(part, p) - if(part.isInstanceOf[TSlottedPart]) - for(i <- 0 until 27) - if(partMap(i) == part) - v_partMap(i) = null - } - - override def canAddPart(part:TMultiPart):Boolean = - { - if(part.isInstanceOf[TSlottedPart]) - { - val slotMask = part.asInstanceOf[TSlottedPart].getSlotMask - for(i <- 0 until v_partMap.length) - if((slotMask&1< 0) - v_partMap(i) = part - } - } -} \ No newline at end of file diff --git a/codechicken/multipart/scalatraits/TTileChangeTile.scala b/codechicken/multipart/scalatraits/TTileChangeTile.scala deleted file mode 100644 index 38343be..0000000 --- a/codechicken/multipart/scalatraits/TTileChangeTile.scala +++ /dev/null @@ -1,59 +0,0 @@ -package codechicken.multipart.scalatraits - -import codechicken.multipart.TMultiPart -import codechicken.multipart.INeighborTileChange -import codechicken.multipart.TileMultipart -import codechicken.lib.vec.BlockCoord - -/** - * Mixin implementation for INeighborTileChange - * - * Reduces unnecessary computation - */ -trait TTileChangeTile extends TileMultipart { - var weakTileChanges = false - - override def copyFrom(that:TileMultipart) - { - super.copyFrom(that) - if(that.isInstanceOf[TTileChangeTile]) - weakTileChanges = that.asInstanceOf[TTileChangeTile].weakTileChanges - } - - override def bindPart(part:TMultiPart) - { - super.bindPart(part) - if(part.isInstanceOf[INeighborTileChange]) - weakTileChanges|=part.asInstanceOf[INeighborTileChange].weakTileChanges - } - - override def clearParts() - { - super.clearParts() - weakTileChanges = false - } - - override def partRemoved(part:TMultiPart, p:Int) { - super.partRemoved(part, p) - weakTileChanges = partList.exists(p => p.isInstanceOf[INeighborTileChange] && p.asInstanceOf[INeighborTileChange].weakTileChanges) - } - - override def onNeighborTileChange(tileX:Int, tileY:Int, tileZ:Int) - { - super.onNeighborTileChange(tileX, tileY, tileZ) - val offset = new BlockCoord(tileX, tileY, tileZ).sub(xCoord, yCoord, zCoord) - val diff = offset.absSum - val side = offset.toSide - - if(side < 0 || diff <= 0 || diff > 2) - return - - val weak = diff == 2 - operate{ p => - if(p.isInstanceOf[INeighborTileChange]) - p.asInstanceOf[INeighborTileChange].onNeighborTileChanged(side, weak) - } - } - - override def getWeakChanges() = weakTileChanges -} \ No newline at end of file diff --git a/dependencies.info b/dependencies.info deleted file mode 100644 index 8a2d633..0000000 --- a/dependencies.info +++ /dev/null @@ -1,6 +0,0 @@ -{ - "repo": "http://files.minecraftforge.net/maven/codechicken/CodeChickenLib/${mc_version}-${ccl_version}/", - "file": "CodeChickenLib-${mc_version}-${ccl_version}-universal.jar", - "dev": "CodeChickenLib-${mc_version}-${ccl_version}-dev.jar", - "class": "codechicken.lib.asm.ASMHelper" -} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 3c7abdf12790879c06b07176de29647f77aa4129..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51106 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

CflOl1i4(-2^1KXo)&I5QlgjRKFQgM zD6ehCWxkntKAc=>I3D4u%G}7e=qxAA?Sf`7*}AmHFeW@~qH!)52qnK%eE1Y#m6@67 zO3V-|xB*e9&pCv-V1+5(CZj28OXi|x%O;Z1nrRvV`va^-K+)hKm%358ZVl@hdM9FC z`qetqkt}(vC?B4YCb`J1(B|W2FUG9=weI5{@{Eh?>TQW{wfaYPWn!Jhvi4SDn*L$O z+ba3AEvl-&kMm{7T5kJbXBWyP97&!1W`(U0yLFAp9aCM&B={x zw*WRe*|v*CO#xJU;A^drAdD7ha@q#PMDU?H^H2WEu}hJ9kuKa2l$b+q&aPcCIBJZP zAZo7C9ZN3co+jwrzGvV{^s{n)Kc3W#5G$jqL7K|khz zHk9sIccAw2J>9kHTcA3D%3k#TKTv!LRIIO0y^=2-AV?H36JTji*0YMLNu)niMyk&E z>H$==7YOv~!yZRv+ZW0%4RLQvHEY1XN`DS6f_RM3L{@V~P819bgI?8PXV0;)N|M z_OCId;-W+3Nup|vCg}PkK!^wI7siD<`aYadbQJhMK)T2jHdK{cU2vw5dL!&%Od|^+ zWYfAf+WceYJw%7cLdinWYmJUeHjx+QXFw*q9snlQ7#m$U!&XcYZz3&bP|{nHH){)o z2oR$Xj=5F|89VqOZ{-3c&YDC#40G;G2J!EA1>VOXL_hTle3ZoE-^LmYnG|`3MDIzg zpD0HilUchX^S142{rYLEPrp_g1{{gWkr|HPP?SRBwD(v9W_))vD!Q&)ME8 zSqn$@K-gXj!KjW zE?pbiw!2Ea+NTTTYAi+aM_$J>(+K8|w5P|^h~B-Yz!OGn2=d8X+!g;So?07|^!WaL zG~pYy3zW9Cn_v8aRS1-}C#_q$CO(3MwoL5FsS7kld0qI)VlS6;X1*mdSP1 zf$sx2Bhc6b9k@Kibq*xVKTah~}u(zWjRCNOE`wS;aKjJk4K*^DTK@F45G5 zs1PuH;tY6CoP*^A`6iUj4WbjmhEkBPXCYx$O5^JFa7J0@i5stv( z5CV!l5pY>sFbST5=Lb{?BZh-*AO!6q1xfHspjn?W3ABKmv>}p?1@WK+)kX+3@s1F! z@a6z0$q3v-2$yQJ6@76nkN;wH%)hk}hW`wJ z{$~O#VQBZa)bMZg6RURVjI4_CW1D3%A$T89ap1KRfRJL-Fj+UN95AVdizybLu+xp5r`swfpn= zjvny!ra43xQ|=)wj4Z~IJzO5e&iY3B_zMix_<@1W9hr(uHCydIHB2oA#8IpkQgT+x zNiI09f?(F#1AA%lN(g#qU<6HPuq&yXoSvJ!4CO6uvq@+mjByDGIrJ*VVHS%S(`jS$syH!&2}e11N+vIh?Gegr%!V9Q znsd}fZ1@D1I1O2jrXk&3^rhMOaW9j|f3cpz?Es3cEJT}HwVs*DZN1%WScaR;$V{ZW z%Y~-hjEv3h$O4_ECgc)=xQalfgxl&E%1%;*H8ik=eoCA?96gEXG_zGy^AWXy!uh@! zb4Y5$!c2=YYPou!Y-v!_?PmKb;+MwWSFXgU0Y`<9nuc9V+C;__(Yex&NpHS^bZD@m zI!Bnb^yYKNv5V=liHdo3eo1x1c!(*Y72>=TYJhDGLLC4l^8_ZHeG8VUQzuE3^kZcZ z-AOK*YyQVZfmi(nr}(*p?x2ijn6|^2vB$Gf?Rr^iJ+z$Cue}Q|G3jS%W!x^oGxnM- z=f&|d&$K9NE+&H|8_STipg8m9q$i8>`otwi)sLO6{4x}mS`fcdgAOw_6$oytCN4Dw z=BCC8H+b&2>yXo>K`3(@BmZLljT$4t zF(STsM_l~MH;J*a_JRXs+`J%7pRhSsoPKnw-epH+r{2L;s@{cr+TNvmUOxp#>9P1X zNkNxu_>92imp-5#BxyMGrmb@vI&_WfjoJiYak4st&8YGRR%uv&Cgal*X3RLz?OqAr zCYRNQNr^G*rzv_@)~|f)G!2^!i5?=>LRg~my=+!y-(aZk6@p2N$#x2J5AD( zuz2=<&QyfjkY=S=8Yt~53@5u(a|C?f6t58*tEy9`-sZ$S1ZbE2rtT7~xZ?u%dZv#< z%OS~#Do{gG(O?`kF-u&!LwWFe``KTvFJ(Ag{hVufn6?_Bu`N6YNr-Bbvfi-lQkhBb zw_kZ5^rwn|+3W#X>k&|J>cj=oA z@hbF`1VMJSmk6TpEf&>00q}wk-x@+oPr@wmqS1F>K>l-Iq;C@tG4z5trKfu$_WFpI zZ*|+jd}qm73AYoxA>^s~^7I8M8<(4GC=H2pY^V#rUlFqMnr%HpULtphTKUAng9P=* zUokdOwgwK~D5NGY9(eSkM;c_*;HZAQDU$;y#BfZAZpN7$v(1kJzGYr~o8sF+6Gy)`+S(Q) zr+s}~x+LSp%Qp?^1+(DoM=ExNqF;)Z50aCwbAUZy-@!9a6naAy<`_KCIe7i8*e&H> zmjbP^=#|rDtd|(?>^`^&`vd+@muYuNFoXpT0N@A*06_MiU8aJei-n-Gv#G7oe>=() zwLiw2YN+48)>5m=Z7)jWO(Y$Y-CVCoN_D5Cx=@hDta%SeqLX8q>t!NU#dBy)y_z9o z*h2xaZMvaBNB_WL+PGP+L4A(ngJu&`x?NG){25Sx)ywmqb?<%LCjR=v|GEq0fc2B) zfKtNC5v>Y|WhcSnof^&rkBZ1;kKL_-e4h;hNxH-6X(np;xRgk6KxV&tV5mDB783jx z5+eWLZ+`ECl81C}37I!wUi6k7GIt2w{YErr7yX9B-$%2Lp|`hBP1H+uV6E6qVF*Ak zdhg2i4F*r&G^g(IGDFcjGG{M-pF`10z3=_Tci4_R0$=z>nAc5wP#XZ8JQ}5xJ5RH@ zoQkW>>;mW{x2npltVSc<0)o@Q!_CH+p_@r>VxCqjbJ`>w+OfX1Yzo*gfjucps;l;- z)F}Y>v?vPb%^YU89%V;QVJePVZ*S)I5ou#q>u04up%P{4x}!8hEfz}4!=9Pwr$b$J zMD&neYW+eAcpW(a3Rn=MNYeC`oLMW!nPR$a9!7SvuH?4!+BH z5!r?~n_YADL_{zzYajr)U^=2yhC;@qMbfs@Jj4PcHT0xL^dm^^@20Aa%#h>Z{k$Wb z3z&kA+vFqKpav>2Y}o5DtIdOhKymlE6J@0-C7ClXRcQ)+_83FsI>N~6O`Nm)&b}U= z#%_aVvDxAX2vp)}5x#o$5!HF3jMA`$prWl@gTcOX)md|qI^`na4v7?jKq%h)KJsdD z`I>lHnUkA0bDhM>%w?Z?$+go;c51ES86WFNm82c;y}fRs6M(S#3l0rtOh?f(d3cAU z2$7G_7$wa_XV{p?kAyfHf9j1RH?<*x+|&m|*(J^0EA<|^o5~oI+NDZcF@{^Kqdb$z zZ<39FXf86bIY$4^3Z?JYJ$3FERvi?_aiUT;C| z8j&CQ;p-dl_SfeyC!+tad-6}sQ8K;cd-P9Lfi&-8q5Z`}Ey}V@t4PJZS+F9HU_^CL z92kY5fZWlW>Y`08(d~P4`%#CJW~cE#lxM0n$G;OG`8KP0w|OmxGNUXC+S+#gMyj?w+Y zyOBnKWjn{Fq%M&IYL<95=T3*Ud!0yuNcOC`j;6T#3SNr+cU_%(y}j+m>tX|a3Ba_l z9Q_MH?t$gzo)}-D;f6Hztn6*?`4HULz1_)~WRiA8F*@urNZA4KU?yI+jjBTfz6S+A zOViz>$v_8zXEIt#DCUM%CEfAqY zuwgnoo?pw*W{uVU>~w{^%BKef(pOn6t81D9xEj91o6_95845@4*lQ;u-LI1NomHGv zi|(@xs$*NV9BN#N5s*n_$qH& z7B^ zxqxkE?Y<(`5XkPv8N++(%7yd(-AkU!NCTEgs-HXeqePOJ+m>8GwP6i$oGi>5QkFDS zfklKaq>X_7US|R8-AX|FdtQ*bBdVvtm&GOAqTI+IHV1uhvlTqk##pxX#-`knqA@f$ zdg8{xy*R9P#*2$LVm>`z1*`#I5{EFA8Do&EVX8v+USL(ZD|V_`Tx;NQT#&_E7jFI!`b;fCnS=q)qzzWb z#AOZ^R&Aj@^cb3O$gwZ$F!!M<&hE6mp#h^?kd@0r;N?39YFA%mi?}6EJe-m-`FUer z6rVr_Q*YBReUP4X(LgyD1ZL-SavES3{eERTHe%N&;mzvnT$Xxe6rDZ;L_v^oT5&)%0=b)jbKt9Va7oY zkdc)rnbq(^XVo+8vG^aL9AhyuB}O3z7x0CnON&jJk+5x5@+n?6C-`%$oxTavdscjI z*$26X-*YyXpNZhK66TT>pix}ntm$Kr2fdDln2GF}k~m=VpUMt~eYW9BjxfExh)cWiPl&?6%1`T1~X?7fM~1 znq`;Bc#~S?u*rG-Y`u0Zg@5eLhFNhM;R>IAi9f5;wx@bZ5WzWGr<>IiDe*n?GM ze`sfZBp!h^|L7+k`~W=(XLM9DP)-BVLDqvKU%@V#y+|IyHx33W(H-XxnhIVNvjbNb zo}xB3=!j7VcSlj9)T*>gwW@<#vaf*PxkU5D%F<3j>g59 z*$o!9ep;Wxr*uyT2ak>9vs! z&*<(kQ!&@#v>QgR|5?`IC{XbyaVM`H++Qv{4pAvb0f{J<`~KAp#?()oFI= zE4FCX*;1Y^zJ+&_&Qz+LYKCoQB%gfAG<1b9GP0BWekmh+n~uT~71U!YQ+(vT6~&m+ zb%flx&FJR;(6*#qA1B6&@W= ztBRMsjJ!c0c)An}jMP}nd5BpVjc*5IY7#w>j;>PMAM@vlU$h@F7iwD)WFsd414>rm zp`>URjgPz)6_neHMc}Tq7hz_Laha5FC1ml>eoIl-f9H2MieQ@0%pBO9a9XW6^^4$E z5|c3vX|DfxihVpPmlPfmOstV(J=rzf*@yrzRn2PjchS3c5SkeS50F zx3c44b67t_2iPcUl6VZrB60Hz3ma}|keQQ4a&n0xZ>e;MwkS<#tQ6C6G3|IXJzGHV zgtEfyB4Bf+@rY6rIn}UF#V{xEq&-E{m5=$`Q;6-1>DT@mmN++p&{rc7BdGawu}%Ga zOM5?uunCF1o(4BfkD~5F3Xuyeb(*uhusI~OgJ33M%VF4Y z!jQ4qWahGNe#N=(b)#%aUVfg+IrLMvRG-LP<&)w^x)fNB+WC-+AZhX~Ko@qW=6Hc! z%E2#%bG|6bts*D-SIRB=FTa%ABVeirIy*J%x*Ad5070P(UaGz{a6-3UH7NKB9+^3U z_u~XNhLrl)_FP#dnb)23dAL*c%Da=WqZ5ba<>dVk%Wy~fdRAh@-$>4DX6MPRl#H8r zH+eY&;dro{W*$%z)YWrV$!<1u-K1UiwYZ{mWBw)wETyV=`-+I4bSdx;7)$roP>Clw zAkfS>{_aTSJ`rPykk0+rtu(fB^HmRqUSh|@K5dhTn7GHrR9`_Fv>b*ci(%-Bw}KB{ ze_1Al1z5A<=?P^=WY3)@>oK^L_(#YBC#7R=O=S^Tf;_+oV-ndkHp@;pA8IR@7996x#LH@9QcOW#_t#C{f&e(z+t5o3KqLpmFo(9>y^HySTwX!D%EcHX+fC3}3O=OC4D)MzTj*rHat|TP1cfwHq{0DGQPWZ=gCN_OFJXJpW8&466THTA( z#Gp>iH2k4=>4QZ0=->n=y`oiAKb7P7J6tIK(uc#(kV*XGc*5UxIdl%76Vnpe1t)er z_uj6ft8v1Q-4WE$I>=byV8y$iaQbi*Thg@~5GA9fCGz2S&qpR)p2YBZ?$6ofIz$!D zxKmJB)Ek0VQ@u1`JFbG%&4CyzbtU$m+oE;WaAyg0m|O}dB7S{T zLoX?Lu0)j1N*7qJbC*m@yqG5OMp!MJA$?;CI&QZgf5dZ0bU+0?TR}1#0)PX-mR^h& zdez#|IQ6*+0n)YNTtCbm=c1ubk&!}MhQ;z|YsjA@wc^e7WyS?b-dJ6r%S;3p)}&9Q z$sXtOB6)2iOERZ6x~h)_*qT+Ut0I~qIEeKcMJzhu(6!sIo`?$VZ+Fzb$?C+Yq-aa^ zU7D~3JfG!1dTe?NBj~(<{L+~2{o5h|s7wq1dYrYB*z#hcvo97^4C<*A7jNqSFsY3| zv2l{`iG~R-N;O98FRzFPRTgt?N;p_g-Rvxnur$3#yzUvWo(cZNO?VbvH z5h;3AI_2*gDkrEgq&o>xuHVFNk2x(c4begN6|yeOq7`uw-6%vkr4g1``lK#VRL64h zjwL!1Ie4$mPt*-##hA^nhtzU>5Balr6`HaNQi5gkqD$1c?C^pq0ioa1{%a9rZIz@bjrJ^_3H9aV&1;OB;CEnxomgX7|-xI;|5K{+1S zC9*G~N(|C0TU(6+JNvC^}^FTG8uvP2>(Rp(8b-JBb zo{_&(6tsxrix#lNFA$rH9DeJn$Qv)qg_oznaci-5Z8d4ZayvCKd!Zmu3`_t&A$q|) z;gNePIeMKyPX8sl=&u8J#q08K^@^VpK{pscz(eR4*j(7*+j=^eF4xbi?pHkW3LUg# z?XA=JkMhc5(y+S!dbSH%%o~=_+00RG=B}{-SQhC?s`k2>Moxcc z1jpcy`|&vLggdkklBPV_1sc7iPkfyuQWe*t!bY=LLV%}VJc;;0wTkhe${HownLKHT zsB_KL8bvE_nZkaURn|_UKgue5A-6nqUT%=csb5K*ta)sP{nJ{MRfhZ6{K#~zU#y!b zx`CT`-A1Rd3Uqz`K) z8JxZqhB6;IJRe+~KcHh?|A#RBlM&;~9HB~nDL9`^e2&0~FZ|v)BI^{9nSSZdx$4y? zTHz_TLo|n5*rY=*?!X<1%r^q-eA!u9|2Id)WnNfxSN{+5Q!(MI$T0m-8D+S?s6%$_SkWg%;!_3BBM~gO=yiI@ z8(fW2SBZRsO9{D%SOy3} z98{3vD2sA292NqkOhnL{w;d=D@|@=5p>Cl*nLeO~DMai%VH*zzGi2Y~S`MPy$xLf> zou_)@2Xq4k^7(f=ha`yhc8MZHlbS9a9o%0>tYi~Y{d)++@UdMQ{63LZqRDFS96-7! z=XM59m(eJI{qbT@ztPUtfVP*8?cqF4FFeNk1js?I$my4$&|k=fC#}=!{FKsnsFMNB zQJ}irK(TPaQHJr*ToU*o&U6I)0p&UpT7LVPzyQSr1iuDb$x@Rz9!3$fkJK zRw3LTBb{hrEr7uiN zEksU#u#1_)pI=v|t6`CsL@f&0)8h-m{66{v_GQRO*uima4H3D{@AUG+m_Qp@4I=sO zEirmE4F3Ja|IciByI&@9_%D5z^0$fk|H3p2+1tA~yZoh_WeqLulwAy+T>d}qPE&hR z4S{#C5wsGi--Z#y0SF~)L{3=>JD&wIv>qeLAeE~)x}IK4B(k7fS_w_1~6_Jt4Lp3q# z6O*l>?if&-2Sdp)a7N52js2l7FP^=m@Mnz_gfxb~wMT2D-=;PO%7fs~5)SO~Z}lVL zW6y62qvCHGgXGT&?@roc=t)RQKt9Tu1?x*dJOy`Q0FI+FjDWF>GX~Th(`-$@mu+)M zzSA>Qo?%xO-+Bp9u61dt32>NeTv%)?D04*fv@X8+nhM=zmu5GbHPu*&?W$5|swDw; zX!N1Z;B7}PRlRaBixJR3mMxnT4$Wqz8aYo@^40ceJIXd20L$o@g)mEB;%Rjk6qx@YTg-0dNQJ1t1uM&-^a_i6ljzX;K5XByp z)LDD2B~xPVPMOivUUbmgLQ_qByw^0HTXFx%EnEk&n!nU}_YE$zGE)|15UABax>f6F zR&^osrW$)VDavKFk?Cl_SHSI4#S-JaJ2i+RvTv0b&>O|36kMDP(V43=hiyoqvm#AG z)KmBXrjz^KM7FI$S;UOFQW`FRw`o=Kf{3`qNXt}7pg|nZ3Xv;Xd+r0gdiL`h{`*m2 zk2ZGnvN?K@X8sD7E9@=^&GoEk;S_>rG_!lD<*)Z}rAY=S0P@(?B;bI8;-m^a0hFT+-?WdV}VSIodxM@#xDL^v)P{t#HU6MbD zL03b?Nr)tO$mpNs6~?z2MV}VB zU7~&u*Y{mxTzk6E#CK=E#6;T~z0RHCS|Zy!ReI{&gFl>oLiPr{uAUa&P4)Tb6jJZ^ zX_5E@-55W8I;sV_K|w;mBb+lhC%% zptY4mp9jS~x3h?ZZ5NQNL4BQ#)bdg^M}%@@QTaz9F8H-@XYygy5Uwr7B0A7z9H z_dD@nhN)XLtZnj+ZNFDKtSj{B8nIjW#C>wM>*!Jee zC%xu^B(rV0+ipEfPoaLerOpC-eRhA5&$gOg*_N%5rE#Z(Wm--%8r_?PT0A@~%B|NT zO@y=7Zu0b5M-1B?;I=x&(EAO1`+vy)Ktd2}3oca|Q-id)fZzY2aYF-7XfY3uH#d zdc7vobbMnIWsS!gg{H_gw|}21`^28XDXd3vfHbgGjo23lzLiRWqI$x8tBbwnl-EV* zrFh`1hL2M`?TD7QPSY!1(EutAU3466O2I+u5=&iBu8q4b=1H<1%4|U@?NFC5G8Kj* z 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%0DvTus6fLI&f~`9YxjD=W5pR41LBYQt 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 244a668..0000000 --- a/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Wed Mar 26 13:33:58 CDT 2014 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=http\://services.gradle.org/distributions/gradle-1.11-bin.zip diff --git a/gradlew b/gradlew deleted file mode 100644 index 91a7e26..0000000 --- a/gradlew +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat deleted file mode 100644 index 8a0b282..0000000 --- a/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/mcmod.info b/mcmod.info deleted file mode 100644 index 53fa047..0000000 --- a/mcmod.info +++ /dev/null @@ -1,29 +0,0 @@ -[ -{ - "modid": "ForgeMultipart", - "name": "Forge Multipart", - "description": "Open source library for facilitation of multiple functional parts in the one block space.", - "version": "${version}", - "mcversion": "${mc_version}", - "url": "https://github.com/Chicken-Bones/ForgeMultipart", - "authors": [ "ChickenBones" ] -}, -{ - "modid": "McMultipart", - "name": "Minecraft Multipart Plugin", - "description": "Provides multipart versions of some vanilla blocks like torches and buttons.", - "version": "${version}", - "mcversion": "${mc_version}", - "url": "https://github.com/Chicken-Bones/ForgeMultipart", - "authors": [ "ChickenBones" ] -}, -{ - "modid": "ForgeMicroblock", - "name": "Forge Microblocks", - "description": "Microblocks for Forge Multipart.", - "version": "${version}", - "mcversion": "${mc_version}", - "url": "https://github.com/Chicken-Bones/ForgeMultipart", - "authors": [ "ChickenBones" ] -} -] \ No newline at end of file diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index 398e21f..0000000 --- a/settings.gradle +++ /dev/null @@ -1,19 +0,0 @@ -/* - * This settings file was auto generated by the Gradle buildInit task - * by 'sunstrike' at '21/11/13 14:14' with Gradle 1.9 - * - * The settings file is used to specify which projects to include in your build. - * In a single project build this file can be empty or even removed. - * - * Detailed information about configuring a multi-project build in Gradle can be found - * in the user guide at http://gradle.org/docs/1.9/userguide/multi_project_builds.html - */ - -/* -// To declare projects as part of a multi-project build use the 'include' method -include 'shared' -include 'api' -include 'services:webservice' -*/ - -rootProject.name = 'CodeChickenLib'