From bcfe4a389e8f66c1f2180c50e63ae1e932be3b55 Mon Sep 17 00:00:00 2001 From: LordMZTE Date: Mon, 28 Nov 2022 22:31:53 +0100 Subject: [PATCH] feat: initial (very borked) port --- .clang-format | 130 +++ .gitignore | 5 +- austri3Fix.md | 4 + .../net/anvilcraft/thaummach/AuraUtils.java | 79 +- .../net/anvilcraft/thaummach/ClientProxy.java | 44 + .../net/anvilcraft/thaummach/CommonProxy.java | 30 + .../net/anvilcraft/thaummach/TMBlocks.java | 21 + .../java/net/anvilcraft/thaummach/TMTab.java | 17 + .../thaummach/ThaumicMachinery.java | 19 +- .../thaummach/blocks/BlockApparatus.java | 142 +++ .../blocks/BlockApparatusFragile.java | 609 +++++++++++ .../thaummach/blocks/BlockApparatusMetal.java | 973 ++++++++++++++++++ .../thaummach/items/ItemBlockApparatus.java | 31 + .../items/ItemBlockApparatusFragile.java | 23 + .../items/ItemBlockApparatusMetal.java | 23 + .../render/BlockApparatusRenderer.java | 53 + .../apparatus/ApparatusRenderingHelper.java | 62 ++ .../render/apparatus/IApparatusRenderer.java | 24 + .../fragile/ConduitApparatusRenderer.java | 320 ++++++ .../fragile/ConduitPumpApparatusRenderer.java | 83 ++ .../fragile/ConduitTankApparatusRenderer.java | 142 +++ ...ConduitValveAdvancedApparatusRenderer.java | 154 +++ .../ConduitValveApparatusRenderer.java | 165 +++ .../fragile/FilterApparatusRenderer.java | 162 +++ .../fragile/PurifierApparatusRenderer.java | 47 + .../metal/ArcaneFurnaceApparatusRenderer.java | 87 ++ .../metal/CrucibleApparatusRenderer.java | 186 ++++ .../metal/CrystallizerApparatusRenderer.java | 89 ++ .../thaummach/render/model/ModelPump.java | 72 ++ .../render/tile/TileConduitPumpRenderer.java | 82 ++ .../thaummach/tiles/TileArcaneFurnace.java | 490 +++++++++ .../thaummach/tiles/TileConduit.java | 464 +++++---- .../thaummach/tiles/TileConduitPump.java | 209 ++++ .../thaummach/tiles/TileConduitTank.java | 485 +++++---- .../thaummach/tiles/TileConduitValve.java | 101 ++ .../tiles/TileConduitValveAdvanced.java | 106 ++ .../thaummach/tiles/TileCrucible.java | 599 +++++++++++ .../thaummach/tiles/TileCrystallizer.java | 361 +++++++ .../thaummach/tiles/TileFilter.java | 183 ++-- .../thaummach/tiles/TilePurifier.java | 89 ++ .../assets/thaummach/lang/en_US.lang | 24 + .../thaummach/textures/blocks/apparatus.png | Bin 0 -> 524 bytes .../textures/blocks/arcane_furnace_bottom.png | Bin 0 -> 467 bytes .../textures/blocks/arcane_furnace_inside.png | Bin 0 -> 459 bytes .../textures/blocks/arcane_furnace_side.png | Bin 0 -> 517 bytes .../textures/blocks/arcane_furnace_top.png | Bin 0 -> 455 bytes .../thaummach/textures/blocks/conduit.png | Bin 0 -> 198 bytes .../textures/blocks/conduit_connection.png | Bin 0 -> 208 bytes .../textures/blocks/conduit_extension.png | Bin 0 -> 555 bytes .../textures/blocks/conduit_inventory.png | Bin 0 -> 601 bytes .../textures/blocks/conduit_pump_side.png | Bin 0 -> 678 bytes .../textures/blocks/conduit_pump_top.png | Bin 0 -> 587 bytes .../blocks/conduit_valve_advanced_off.png | Bin 0 -> 322 bytes .../conduit_valve_advanced_on_taint.png | Bin 0 -> 357 bytes .../blocks/conduit_valve_advanced_on_vis.png | Bin 0 -> 348 bytes .../textures/blocks/conduit_valve_off.png | Bin 0 -> 314 bytes .../textures/blocks/conduit_valve_on.png | Bin 0 -> 325 bytes .../textures/blocks/crystallizer_bottom.png | Bin 0 -> 580 bytes .../textures/blocks/crystallizer_side.png | Bin 0 -> 597 bytes .../textures/blocks/crystallizer_top.png | Bin 0 -> 616 bytes .../textures/blocks/eyes_crucible_1.png | Bin 0 -> 317 bytes .../textures/blocks/eyes_crucible_2.png | Bin 0 -> 304 bytes .../textures/blocks/eyes_crucible_3.png | Bin 0 -> 387 bytes .../textures/blocks/eyes_crucible_4.png | Bin 0 -> 151 bytes .../textures/blocks/eyes_crucible_5.png | Bin 0 -> 466 bytes .../textures/blocks/eyes_crucible_6.png | Bin 0 -> 448 bytes .../textures/blocks/eyes_crucible_7.png | Bin 0 -> 297 bytes .../textures/blocks/filter_bottom.png | Bin 0 -> 549 bytes .../textures/blocks/filter_front.png | Bin 0 -> 552 bytes .../thaummach/textures/blocks/filter_side.png | Bin 0 -> 523 bytes .../thaummach/textures/blocks/generator_1.png | Bin 0 -> 465 bytes .../thaummach/textures/blocks/generator_2.png | Bin 0 -> 682 bytes .../thaummach/textures/blocks/generator_3.png | Bin 0 -> 693 bytes .../textures/blocks/normal_crucible_1.png | Bin 0 -> 349 bytes .../textures/blocks/normal_crucible_2.png | Bin 0 -> 364 bytes .../textures/blocks/normal_crucible_3.png | Bin 0 -> 460 bytes .../textures/blocks/normal_crucible_4.png | Bin 0 -> 174 bytes .../textures/blocks/normal_crucible_6.png | Bin 0 -> 491 bytes .../textures/blocks/normal_crucible_7.png | Bin 0 -> 330 bytes .../textures/blocks/purifier_front.png | Bin 0 -> 793 bytes .../textures/blocks/purifier_side.png | Bin 0 -> 698 bytes .../textures/blocks/purifier_top.png | Bin 0 -> 695 bytes .../textures/blocks/soul_brazier_bottom.png | Bin 0 -> 378 bytes .../textures/blocks/soul_brazier_side.png | Bin 0 -> 475 bytes .../textures/blocks/soul_crucible_bottom.png | Bin 0 -> 433 bytes .../textures/blocks/soul_crucible_face_0.png | Bin 0 -> 513 bytes .../textures/blocks/soul_crucible_face_1.png | Bin 0 -> 492 bytes .../textures/blocks/soul_crucible_face_2.png | Bin 0 -> 485 bytes .../textures/blocks/soul_crucible_face_3.png | Bin 0 -> 488 bytes .../textures/blocks/soul_crucible_top.png | Bin 0 -> 606 bytes .../textures/blocks/soul_crucible_top_inv.png | Bin 0 -> 563 bytes .../thaummach/textures/blocks/tank_bottom.png | Bin 0 -> 462 bytes .../thaummach/textures/blocks/tank_side.png | Bin 0 -> 485 bytes .../thaummach/textures/blocks/tcubeanim.png | Bin 0 -> 65316 bytes .../textures/blocks/tcubeanim.png.mcmeta | 60 ++ .../textures/blocks/thaumium_crucible_1.png | Bin 0 -> 357 bytes .../textures/blocks/thaumium_crucible_2.png | Bin 0 -> 366 bytes .../textures/blocks/thaumium_crucible_3.png | Bin 0 -> 474 bytes .../textures/blocks/thaumium_crucible_4.png | Bin 0 -> 151 bytes .../textures/blocks/thaumium_crucible_5.png | Bin 0 -> 583 bytes .../textures/blocks/thaumium_crucible_6.png | Bin 0 -> 579 bytes .../textures/blocks/thaumium_crucible_7.png | Bin 0 -> 338 bytes .../textures/blocks/void_chest_bottom.png | Bin 0 -> 561 bytes .../textures/blocks/void_chest_side.png | Bin 0 -> 606 bytes .../blocks/void_chest_side_transparent.png | Bin 0 -> 740 bytes .../textures/blocks/void_chest_top.png | Bin 0 -> 577 bytes .../textures/blocks/void_interface_bottom.png | Bin 0 -> 569 bytes .../textures/blocks/void_interface_side.png | Bin 0 -> 379 bytes .../textures/models/conduit_pump.png | Bin 0 -> 3809 bytes 109 files changed, 6540 insertions(+), 509 deletions(-) create mode 100644 .clang-format create mode 100644 austri3Fix.md create mode 100644 src/main/java/net/anvilcraft/thaummach/ClientProxy.java create mode 100644 src/main/java/net/anvilcraft/thaummach/CommonProxy.java create mode 100644 src/main/java/net/anvilcraft/thaummach/TMBlocks.java create mode 100644 src/main/java/net/anvilcraft/thaummach/TMTab.java create mode 100644 src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatus.java create mode 100644 src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatusFragile.java create mode 100644 src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatusMetal.java create mode 100644 src/main/java/net/anvilcraft/thaummach/items/ItemBlockApparatus.java create mode 100644 src/main/java/net/anvilcraft/thaummach/items/ItemBlockApparatusFragile.java create mode 100644 src/main/java/net/anvilcraft/thaummach/items/ItemBlockApparatusMetal.java create mode 100644 src/main/java/net/anvilcraft/thaummach/render/BlockApparatusRenderer.java create mode 100644 src/main/java/net/anvilcraft/thaummach/render/apparatus/ApparatusRenderingHelper.java create mode 100644 src/main/java/net/anvilcraft/thaummach/render/apparatus/IApparatusRenderer.java create mode 100644 src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/ConduitApparatusRenderer.java create mode 100644 src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/ConduitPumpApparatusRenderer.java create mode 100644 src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/ConduitTankApparatusRenderer.java create mode 100644 src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/ConduitValveAdvancedApparatusRenderer.java create mode 100644 src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/ConduitValveApparatusRenderer.java create mode 100644 src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/FilterApparatusRenderer.java create mode 100644 src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/PurifierApparatusRenderer.java create mode 100644 src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/metal/ArcaneFurnaceApparatusRenderer.java create mode 100644 src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/metal/CrucibleApparatusRenderer.java create mode 100644 src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/metal/CrystallizerApparatusRenderer.java create mode 100644 src/main/java/net/anvilcraft/thaummach/render/model/ModelPump.java create mode 100644 src/main/java/net/anvilcraft/thaummach/render/tile/TileConduitPumpRenderer.java create mode 100644 src/main/java/net/anvilcraft/thaummach/tiles/TileArcaneFurnace.java create mode 100644 src/main/java/net/anvilcraft/thaummach/tiles/TileConduitPump.java create mode 100644 src/main/java/net/anvilcraft/thaummach/tiles/TileConduitValve.java create mode 100644 src/main/java/net/anvilcraft/thaummach/tiles/TileConduitValveAdvanced.java create mode 100644 src/main/java/net/anvilcraft/thaummach/tiles/TileCrucible.java create mode 100644 src/main/java/net/anvilcraft/thaummach/tiles/TileCrystallizer.java create mode 100644 src/main/java/net/anvilcraft/thaummach/tiles/TilePurifier.java create mode 100644 src/main/resources/assets/thaummach/lang/en_US.lang create mode 100644 src/main/resources/assets/thaummach/textures/blocks/apparatus.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/arcane_furnace_bottom.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/arcane_furnace_inside.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/arcane_furnace_side.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/arcane_furnace_top.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/conduit.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/conduit_connection.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/conduit_extension.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/conduit_inventory.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/conduit_pump_side.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/conduit_pump_top.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/conduit_valve_advanced_off.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/conduit_valve_advanced_on_taint.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/conduit_valve_advanced_on_vis.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/conduit_valve_off.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/conduit_valve_on.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/crystallizer_bottom.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/crystallizer_side.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/crystallizer_top.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/eyes_crucible_1.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/eyes_crucible_2.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/eyes_crucible_3.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/eyes_crucible_4.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/eyes_crucible_5.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/eyes_crucible_6.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/eyes_crucible_7.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/filter_bottom.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/filter_front.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/filter_side.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/generator_1.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/generator_2.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/generator_3.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/normal_crucible_1.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/normal_crucible_2.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/normal_crucible_3.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/normal_crucible_4.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/normal_crucible_6.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/normal_crucible_7.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/purifier_front.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/purifier_side.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/purifier_top.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/soul_brazier_bottom.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/soul_brazier_side.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/soul_crucible_bottom.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/soul_crucible_face_0.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/soul_crucible_face_1.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/soul_crucible_face_2.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/soul_crucible_face_3.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/soul_crucible_top.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/soul_crucible_top_inv.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/tank_bottom.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/tank_side.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/tcubeanim.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/tcubeanim.png.mcmeta create mode 100644 src/main/resources/assets/thaummach/textures/blocks/thaumium_crucible_1.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/thaumium_crucible_2.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/thaumium_crucible_3.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/thaumium_crucible_4.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/thaumium_crucible_5.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/thaumium_crucible_6.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/thaumium_crucible_7.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/void_chest_bottom.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/void_chest_side.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/void_chest_side_transparent.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/void_chest_top.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/void_interface_bottom.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/void_interface_side.png create mode 100644 src/main/resources/assets/thaummach/textures/models/conduit_pump.png diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..d48bed8 --- /dev/null +++ b/.clang-format @@ -0,0 +1,130 @@ +--- +AccessModifierOffset: 0 +AlignAfterOpenBracket: BlockIndent +AlignArrayOfStructures: None +AlignConsecutiveAssignments: None +AlignConsecutiveMacros: None +AlignConsecutiveBitFields: None +AlignConsecutiveDeclarations: None +AlignEscapedNewlines: DontAlign +AlignOperands: DontAlign +AlignTrailingComments: false +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: Empty +AllowShortCaseLabelsOnASingleLine: false +AllowShortEnumsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Empty +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: MultiLine +AttributeMacros: [] +BinPackArguments: false +BinPackParameters: false +BitFieldColonSpacing: After +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: false +BreakAfterJavaFieldAnnotations: true +#BreakArrays: false +BreakBeforeBinaryOperators: All +BreakBeforeBraces: Custom +BreakBeforeConceptDeclarations: true +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: AfterColon +BreakInheritanceList: AfterColon +BreakStringLiterals: true +ColumnLimit: 90 +CompactNamespaces: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: false +DeriveLineEnding: false +DerivePointerAlignment: false +DisableFormat: false # wtf +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: Always +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: false +ForEachMacros: ["BOOST_FOREACH"] +IfMacros: [] +IncludeBlocks: Regroup +IndentAccessModifiers: false +IndentCaseBlocks: false +IndentCaseLabels: true +IndentExternBlock: Indent +IndentGotoLabels: true +IndentPPDirectives: BeforeHash +#IndentRequiresClause: false +IndentWidth: 4 +IndentWrappedFunctionNames: false +#InsertBraces: false +InsertTrailingCommas: Wrapped +JavaImportGroups: ["java"] +JavaScriptQuotes: Double +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +LambdaBodyIndentation: OuterScope +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: All +PackConstructorInitializers: NextLine +PointerAlignment: Left +QualifierAlignment: Left +ReferenceAlignment: Left +ReflowComments: true +#RemoveSemicolon: true +#RequiresClausePosition: OwnLine +#RequiresExpressionIndentation: OuterScope +SeparateDefinitionBlocks: Always +SortIncludes: CaseInsensitive +SortJavaStaticImport: Before +SortUsingDeclarations: true +SpaceAfterCStyleCast: true +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: false +SpaceAroundPointerQualifiers: After +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: false +SpaceBeforeInheritanceColon: false +SpaceBeforeParens: ControlStatementsExceptControlMacros +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesInAngles: Never +SpacesInCStyleCastParentheses: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: false +SpacesInLineCommentPrefix: + Minimum: 0 + Maximum: -1 +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: c++20 +StatementAttributeLikeMacros: [] +StatementMacros: [] +TabWidth: 4 +TypenameMacros: [] +UseCRLF: false # wtf +UseTab: Never +WhitespaceSensitiveMacros: ["BOOST_PP_STRINGSIZE"] diff --git a/.gitignore b/.gitignore index 4d59512..bbc8ac8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ +.project +.classpath +bin +.settings .gradle .idea build run -bin \ No newline at end of file diff --git a/austri3Fix.md b/austri3Fix.md new file mode 100644 index 0000000..5c3e7ca --- /dev/null +++ b/austri3Fix.md @@ -0,0 +1,4 @@ +- apparati don't render in some chunks and some Y-levels (WTF) +- models of all sorts of stuff look borked in hand (see arcane furnace) +- filter looks borked in world (see bottom side of top surface) +- you can sometimes walk through tanks diff --git a/src/main/java/net/anvilcraft/thaummach/AuraUtils.java b/src/main/java/net/anvilcraft/thaummach/AuraUtils.java index 508bdfe..c139b0a 100644 --- a/src/main/java/net/anvilcraft/thaummach/AuraUtils.java +++ b/src/main/java/net/anvilcraft/thaummach/AuraUtils.java @@ -1,28 +1,79 @@ package net.anvilcraft.thaummach; +import dev.tilera.auracore.api.machine.IConnection; +import dev.tilera.auracore.aura.AuraManager; +import net.minecraft.client.Minecraft; +import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; +import thaumcraft.client.fx.particles.FXWisp; public class AuraUtils { + public static void taintExplosion(World w, int x, int y, int z) { + w.createExplosion( + null, + (double) ((float) x + 0.5F), + (double) ((float) y + 0.5F), + (double) ((float) z + 0.5F), + 1.0F, + false + ); - public static void taintExplosion(World w, int x, int y, int z) { - w.createExplosion(null, (double)((float)x + 0.5F), (double)((float)y + 0.5F), (double)((float)z + 0.5F), 1.0F, false); - int xx; - for(xx = x - 2; xx <= x + 2; ++xx) { - for(int yy = y - 2; yy <= y + 2; ++yy) { - for(int zz = z - 2; zz <= z + 2; ++zz) { - //increaseTaintedPlants(w, xx, yy, zz); - } - } + for (xx = x - 2; xx <= x + 2; ++xx) { + for (int yy = y - 2; yy <= y + 2; ++yy) { + for (int zz = z - 2; zz <= z + 2; ++zz) { + // increaseTaintedPlants(w, xx, yy, zz); + } + } } - + /*for(xx = 0; xx < 100; ++xx) { - FXWisp ef = new FXWisp(w, (double)((float)x + 0.5F), (double)((float)y + 0.5F), (double)((float)z + 0.5F), (double)((float)x + 0.5F + (w.rand.nextFloat() - w.rand.nextFloat()) * 2.0F), (double)((float)y + 0.5F + (w.rand.nextFloat() - w.rand.nextFloat()) * 2.0F), (double)((float)z + 0.5F + (w.rand.nextFloat() - w.rand.nextFloat()) * 2.0F), 1.0F, 5); + FXWisp ef = new FXWisp(w, (double)((float)x + 0.5F), (double)((float)y + + 0.5F), (double)((float)z + 0.5F), (double)((float)x + 0.5F + + (w.rand.nextFloat() - w.rand.nextFloat()) * 2.0F), (double)((float)y + 0.5F + + (w.rand.nextFloat() - w.rand.nextFloat()) * 2.0F), (double)((float)z + + 0.5F + (w.rand.nextFloat() - w.rand.nextFloat()) * 2.0F), 1.0F, 5); ef.setGravity(0.02F); ef.shrink = true; ModLoader.getMinecraftInstance().effectRenderer.addEffect(ef); }*/ - - } - + } + + public static void spillTaint(World world, int x, int y, int z) { + TileEntity tc = world.getTileEntity(x, y, z); + if (tc != null && tc instanceof IConnection) { + IConnection ic = (IConnection) tc; + if (ic.getTaintedVis() > 0.0F) { + int at = (int) ic.getTaintedVis(); + AuraManager.addTaintToClosest(world, x, y, z, at); + world.playSoundEffect( + (double) x, + (double) y, + (double) z, + "random.fizz", + 0.2F, + 2.0F + world.rand.nextFloat() * 0.4F + ); + + for (int a = 0; a < Math.min(at, 50); ++a) { + float x1 = (float) x + world.rand.nextFloat(); + float y1 = (float) y + world.rand.nextFloat(); + float z1 = (float) z + world.rand.nextFloat(); + FXWisp ef = new FXWisp( + world, + (double) x1, + (double) y1, + (double) z1, + (double) x1, + (double) (y1 + 1.0F), + (double) z1, + 0.5F, + 5 + ); + ef.tinkle = false; + Minecraft.getMinecraft().effectRenderer.addEffect(ef); + } + } + } + } } diff --git a/src/main/java/net/anvilcraft/thaummach/ClientProxy.java b/src/main/java/net/anvilcraft/thaummach/ClientProxy.java new file mode 100644 index 0000000..121184a --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/ClientProxy.java @@ -0,0 +1,44 @@ +package net.anvilcraft.thaummach; + +import cpw.mods.fml.client.registry.ClientRegistry; +import cpw.mods.fml.client.registry.RenderingRegistry; +import cpw.mods.fml.common.registry.GameRegistry; +import net.anvilcraft.thaummach.render.BlockApparatusRenderer; +import net.anvilcraft.thaummach.render.tile.TileConduitPumpRenderer; +import net.anvilcraft.thaummach.tiles.TileConduit; +import net.anvilcraft.thaummach.tiles.TileConduitPump; +import net.anvilcraft.thaummach.tiles.TileConduitTank; +import net.anvilcraft.thaummach.tiles.TileConduitValve; +import net.anvilcraft.thaummach.tiles.TileConduitValveAdvanced; +import net.anvilcraft.thaummach.tiles.TileCrucible; +import net.anvilcraft.thaummach.tiles.TileCrystallizer; +import net.anvilcraft.thaummach.tiles.TileFilter; +import net.anvilcraft.thaummach.tiles.TilePurifier; + +public class ClientProxy extends CommonProxy { + @Override + public void preInit() { + super.preInit(); + + BlockApparatusRenderer.RI = RenderingRegistry.getNextAvailableRenderId(); + RenderingRegistry.registerBlockHandler(new BlockApparatusRenderer()); + } + + @Override + public void registerTileEntities() { + GameRegistry.registerTileEntity(TileConduit.class, "conduit"); + GameRegistry.registerTileEntity(TileConduitTank.class, "conduit_tank"); + GameRegistry.registerTileEntity(TileConduitValve.class, "conduit_valve"); + GameRegistry.registerTileEntity( + TileConduitValveAdvanced.class, "conduit_valve_advanced" + ); + GameRegistry.registerTileEntity(TileCrucible.class, "crucible"); + GameRegistry.registerTileEntity(TileCrystallizer.class, "crystallizer"); + GameRegistry.registerTileEntity(TileFilter.class, "filter"); + GameRegistry.registerTileEntity(TilePurifier.class, "purifier"); + + ClientRegistry.registerTileEntity( + TileConduitPump.class, "conduit_pump", new TileConduitPumpRenderer() + ); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/CommonProxy.java b/src/main/java/net/anvilcraft/thaummach/CommonProxy.java new file mode 100644 index 0000000..686d5d9 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/CommonProxy.java @@ -0,0 +1,30 @@ +package net.anvilcraft.thaummach; + +import cpw.mods.fml.common.registry.GameRegistry; +import net.anvilcraft.thaummach.tiles.TileConduit; +import net.anvilcraft.thaummach.tiles.TileConduitPump; +import net.anvilcraft.thaummach.tiles.TileConduitTank; +import net.anvilcraft.thaummach.tiles.TileConduitValve; +import net.anvilcraft.thaummach.tiles.TileConduitValveAdvanced; +import net.anvilcraft.thaummach.tiles.TileCrucible; +import net.anvilcraft.thaummach.tiles.TileCrystallizer; +import net.anvilcraft.thaummach.tiles.TileFilter; +import net.anvilcraft.thaummach.tiles.TilePurifier; + +public class CommonProxy { + public void preInit() {} + + public void registerTileEntities() { + GameRegistry.registerTileEntity(TileConduit.class, "conduit"); + GameRegistry.registerTileEntity(TileConduitPump.class, "conduit_pump"); + GameRegistry.registerTileEntity(TileConduitTank.class, "conduit_tank"); + GameRegistry.registerTileEntity(TileConduitValve.class, "conduit_valve"); + GameRegistry.registerTileEntity( + TileConduitValveAdvanced.class, "conduit_valve_advanced" + ); + GameRegistry.registerTileEntity(TileCrucible.class, "crucible"); + GameRegistry.registerTileEntity(TileCrystallizer.class, "crystallizer"); + GameRegistry.registerTileEntity(TileFilter.class, "filter"); + GameRegistry.registerTileEntity(TilePurifier.class, "purifier"); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/TMBlocks.java b/src/main/java/net/anvilcraft/thaummach/TMBlocks.java new file mode 100644 index 0000000..1c410a3 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/TMBlocks.java @@ -0,0 +1,21 @@ +package net.anvilcraft.thaummach; + +import cpw.mods.fml.common.registry.GameRegistry; +import net.anvilcraft.thaummach.blocks.BlockApparatusFragile; +import net.anvilcraft.thaummach.blocks.BlockApparatusMetal; +import net.anvilcraft.thaummach.items.ItemBlockApparatusFragile; +import net.anvilcraft.thaummach.items.ItemBlockApparatusMetal; +import net.minecraft.block.Block; + +public class TMBlocks { + public static Block apparatusFragile; + public static Block apparatusMetal; + + public static void init() { + apparatusFragile = new BlockApparatusFragile(); + apparatusMetal = new BlockApparatusMetal(); + + GameRegistry.registerBlock(apparatusFragile, ItemBlockApparatusFragile.class, "apparatus_fragile"); + GameRegistry.registerBlock(apparatusMetal, ItemBlockApparatusMetal.class, "apparatus_metal"); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/TMTab.java b/src/main/java/net/anvilcraft/thaummach/TMTab.java new file mode 100644 index 0000000..4d6a5dc --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/TMTab.java @@ -0,0 +1,17 @@ +package net.anvilcraft.thaummach; + +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; + +public class TMTab extends CreativeTabs { + public TMTab() { + super("thaummach"); + } + + public static TMTab INSTANCE = new TMTab(); + + @Override + public Item getTabIconItem() { + return Item.getItemFromBlock(TMBlocks.apparatusFragile); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/ThaumicMachinery.java b/src/main/java/net/anvilcraft/thaummach/ThaumicMachinery.java index 06fcbeb..1bb267b 100644 --- a/src/main/java/net/anvilcraft/thaummach/ThaumicMachinery.java +++ b/src/main/java/net/anvilcraft/thaummach/ThaumicMachinery.java @@ -1,5 +1,22 @@ package net.anvilcraft.thaummach; +import cpw.mods.fml.common.Mod; +import cpw.mods.fml.common.SidedProxy; +import cpw.mods.fml.common.event.FMLPreInitializationEvent; + +@Mod(modid = "thaummach") public class ThaumicMachinery { - + @SidedProxy( + modId = "thaummach", + serverSide = "net.anvilcraft.thaummach.CommonProxy", + clientSide = "net.anvilcraft.thaummach.ClientProxy" + ) + public static CommonProxy proxy; + + @Mod.EventHandler + public void preInit(FMLPreInitializationEvent ev) { + proxy.preInit(); + proxy.registerTileEntities(); + TMBlocks.init(); + } } diff --git a/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatus.java b/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatus.java new file mode 100644 index 0000000..7752761 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatus.java @@ -0,0 +1,142 @@ +package net.anvilcraft.thaummach.blocks; + +import java.util.Random; + +import net.anvilcraft.thaummach.TMTab; +import net.anvilcraft.thaummach.render.apparatus.IApparatusRenderer; +import net.minecraft.block.Block; +import net.minecraft.block.BlockContainer; +import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; + +public abstract class BlockApparatus extends BlockContainer { + protected int currentPass; + public IIcon iconTcubeanim; + + public BlockApparatus(Material m) { + super(m); + // TODO: WTF + //this.setRequiresSelfNotify(); + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + this.currentPass = 1; + this.setTickRandomly(true); + this.setCreativeTab(TMTab.INSTANCE); + } + + @Override + public void registerBlockIcons(IIconRegister reg) { + this.iconTcubeanim = reg.registerIcon("thaummach:tcubeanim"); + } + + public abstract IApparatusRenderer getApparatusRenderer(int meta); + + @Override + public int quantityDropped(Random random) { + return 1; + } + + @Override + public boolean renderAsNormalBlock() { + return false; + } + + @Override + public boolean isOpaqueCube() { + return false; + } + + @Override + public boolean onBlockActivated( + World world, + int i, + int j, + int k, + EntityPlayer entityplayer, + // useless parameters + int alec1, + float alec2, + float alec3, + float alec4 + ) { + if (!world.isRemote && !entityplayer.isSneaking()) { + // TODO: WTF + //TileEntity te = world.getTileEntity(i, j, k); + //if (te != null && te instanceof ITileGui) { + // ModLoader.openGUI(entityplayer, ((ITileGui) te).getGui(entityplayer)); + // return true; + //} else { + // return false; + //} + + return false; + } else { + return false; + } + } + + @Override + public void breakBlock(World world, int x, int y, int z, Block block, int meta) { + TileEntity te = world.getTileEntity(x, y, z); + if (te != null && te instanceof IInventory) { + for (int l = 0; l < ((IInventory) te).getSizeInventory(); ++l) { + ItemStack itemstack = ((IInventory) te).getStackInSlot(l); + if (itemstack != null) { + float f = world.rand.nextFloat() * 0.8F + 0.1F; + float f1 = world.rand.nextFloat() * 0.8F + 0.1F; + float f2 = world.rand.nextFloat() * 0.8F + 0.1F; + + while (itemstack.stackSize > 0) { + int i1 = world.rand.nextInt(21) + 10; + if (i1 > itemstack.stackSize) { + i1 = itemstack.stackSize; + } + + itemstack.stackSize -= i1; + EntityItem entityitem = new EntityItem( + world, + (double) ((float) x + f), + (double) ((float) y + f1), + (double) ((float) z + f2), + new ItemStack( + itemstack.getItem(), i1, itemstack.getItemDamage() + ) + ); + float f3 = 0.05F; + entityitem.motionX + = (double) ((float) world.rand.nextGaussian() * f3); + entityitem.motionY + = (double) ((float) world.rand.nextGaussian() * f3 + 0.2F); + entityitem.motionZ + = (double) ((float) world.rand.nextGaussian() * f3); + world.spawnEntityInWorld(entityitem); + } + } + } + } + super.breakBlock(world, x, y, z, block, meta); + } + + @Override + public boolean canRenderInPass(int n) { + this.currentPass = n; + return true; + } + + @Override + public int getRenderBlockPass() { + return this.currentPass; + } + + @Override + public void onPostBlockPlaced(World world, int x, int y, int z, int meta) { + world.setBlockMetadataWithNotify(x, y, z, meta, 3); + super.onPostBlockPlaced(world, x, y, z, meta); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatusFragile.java b/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatusFragile.java new file mode 100644 index 0000000..2055b62 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatusFragile.java @@ -0,0 +1,609 @@ +package net.anvilcraft.thaummach.blocks; + +import java.util.List; +import java.util.Random; + +import dev.tilera.auracore.api.HelperLocation; +import dev.tilera.auracore.client.FXSparkle; +import net.anvilcraft.thaummach.AuraUtils; +import net.anvilcraft.thaummach.render.BlockApparatusRenderer; +import net.anvilcraft.thaummach.render.apparatus.IApparatusRenderer; +import net.anvilcraft.thaummach.render.apparatus.apparati.fragile.ConduitApparatusRenderer; +import net.anvilcraft.thaummach.render.apparatus.apparati.fragile.ConduitPumpApparatusRenderer; +import net.anvilcraft.thaummach.render.apparatus.apparati.fragile.ConduitTankApparatusRenderer; +import net.anvilcraft.thaummach.render.apparatus.apparati.fragile.ConduitValveAdvancedApparatusRenderer; +import net.anvilcraft.thaummach.render.apparatus.apparati.fragile.ConduitValveApparatusRenderer; +import net.anvilcraft.thaummach.render.apparatus.apparati.fragile.FilterApparatusRenderer; +import net.anvilcraft.thaummach.render.apparatus.apparati.fragile.PurifierApparatusRenderer; +import net.anvilcraft.thaummach.tiles.TileConduit; +import net.anvilcraft.thaummach.tiles.TileConduitPump; +import net.anvilcraft.thaummach.tiles.TileConduitTank; +import net.anvilcraft.thaummach.tiles.TileConduitValve; +import net.anvilcraft.thaummach.tiles.TileConduitValveAdvanced; +import net.anvilcraft.thaummach.tiles.TileFilter; +import net.anvilcraft.thaummach.tiles.TilePurifier; +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.IIcon; +import net.minecraft.util.MathHelper; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; +import thaumcraft.client.fx.particles.FXWisp; + +public class BlockApparatusFragile extends BlockApparatus { + public IIcon iconConduit; + public IIcon iconConduitConnection; + public IIcon iconConduitExtension; + public IIcon iconConduitInventory; + public IIcon iconConduitPumpSide; + public IIcon iconConduitPumpTop; + public IIcon iconFilterBottom; + public IIcon iconFilterFront; + public IIcon iconFilterSide; + public IIcon iconPurifierFront; + public IIcon iconPurifierSide; + public IIcon iconPurifierTop; + public IIcon iconTankBottom; + public IIcon iconTankSide; + public IIcon iconTcubeanim; + public IIcon iconValveAdvancedOff; + public IIcon iconValveAdvancedOnTaint; + public IIcon iconValveAdvancedOnVis; + public IIcon iconValveOff; + public IIcon iconValveOn; + + public BlockApparatusFragile() { + super(Material.wood); + this.setHardness(1.0F); + this.setStepSound(Block.soundTypeWood); + this.setTickRandomly(true); + } + + @Override + public void registerBlockIcons(IIconRegister reg) { + super.registerBlockIcons(reg); + this.blockIcon = reg.registerIcon("thaummach:apparatus"); + + this.iconConduit = reg.registerIcon("thaummach:conduit"); + this.iconConduitConnection = reg.registerIcon("thaummach:conduit_connection"); + this.iconConduitExtension = reg.registerIcon("thaummach:conduit_extension"); + this.iconConduitInventory = reg.registerIcon("thaummach:conduit_inventory"); + this.iconConduitPumpSide = reg.registerIcon("thaummach:conduit_pump_side"); + this.iconConduitPumpTop = reg.registerIcon("thaummach:conduit_pump_top"); + this.iconFilterBottom = reg.registerIcon("thaummach:filter_bottom"); + this.iconFilterFront = reg.registerIcon("thaummach:filter_front"); + this.iconFilterSide = reg.registerIcon("thaummach:filter_side"); + this.iconPurifierFront = reg.registerIcon("thaummach:purifier_front"); + this.iconPurifierSide = reg.registerIcon("thaummach:purifier_side"); + this.iconPurifierTop = reg.registerIcon("thaummach:purifier_top"); + this.iconTankBottom = reg.registerIcon("thaummach:tank_bottom"); + this.iconTankSide = reg.registerIcon("thaummach:tank_side"); + this.iconTcubeanim = reg.registerIcon("thaummach:tcubeanim"); + this.iconValveAdvancedOff + = reg.registerIcon("thaummach:conduit_valve_advanced_off"); + this.iconValveAdvancedOnTaint + = reg.registerIcon("thaummach:conduit_valve_advanced_on_taint"); + this.iconValveAdvancedOnVis + = reg.registerIcon("thaummach:conduit_valve_advanced_on_vis"); + this.iconValveOff = reg.registerIcon("thaummach:conduit_valve_off"); + this.iconValveOn = reg.registerIcon("thaummach:conduit_valve_on"); + } + + @Override + public IApparatusRenderer getApparatusRenderer(int meta) { + switch (MetaVals.get(meta)) { + case CONDUIT: + return ConduitApparatusRenderer.INSTANCE; + + case FILTER: + return FilterApparatusRenderer.INSTANCE; + + case CONDUIT_TANK: + return ConduitTankApparatusRenderer.INSTANCE; + + case CONDUIT_VALVE: + return ConduitValveApparatusRenderer.INSTANCE; + + case PURIFIER: + return PurifierApparatusRenderer.INSTANCE; + + case CONDUIT_VALVE_ADVANCED: + return ConduitValveAdvancedApparatusRenderer.INSTANCE; + + case CONDUIT_PUMP: + return ConduitPumpApparatusRenderer.INSTANCE; + + default: + break; + } + return null; + } + + @Override + public float getBlockHardness(World world, int x, int y, int z) { + MetaVals meta = MetaVals.get(world.getBlockMetadata(x, y, z)); + + if (meta != MetaVals.CONDUIT && meta != MetaVals.CONDUIT_VALVE + && meta != MetaVals.CONDUIT_VALVE_ADVANCED) { + return meta == null ? 0.0F : super.getBlockHardness(world, x, y, z); + } else { + return 0.25F; + } + } + + @Override + @SuppressWarnings({ "unchecked", "rawtypes" }) + public void getSubBlocks(Item p_149666_1_, CreativeTabs p_149666_2_, List itemList) { + for (MetaVals meta : MetaVals.values()) { + itemList.add(new ItemStack(this, 1, meta.ordinal())); + } + } + + @Override + public TileEntity createNewTileEntity(World world, int meta_) { + MetaVals meta = MetaVals.get(meta_); + + switch (meta) { + case CONDUIT: + return new TileConduit(); + + case FILTER: + return new TileFilter(); + + case CONDUIT_TANK: + return new TileConduitTank(); + + case CONDUIT_VALVE: + return new TileConduitValve(); + + case PURIFIER: + return new TilePurifier(); + + case CONDUIT_VALVE_ADVANCED: + return new TileConduitValveAdvanced(); + + case CONDUIT_PUMP: + return new TileConduitPump(); + + default: + return null; + } + } + + @Override + public void + setBlockBoundsBasedOnState(IBlockAccess iblockaccess, int i, int j, int k) { + MetaVals md = MetaVals.get(iblockaccess.getBlockMetadata(i, j, k)); + float w1; + if (md != MetaVals.CONDUIT && md != MetaVals.CONDUIT_VALVE + && md != MetaVals.CONDUIT_VALVE_ADVANCED) { + if (md != MetaVals.FILTER) { + if (md == MetaVals.CONDUIT_VALVE) { + w1 = 0.0625F; + this.setBlockBounds(w1, 0.0F, w1, 1.0F - w1, 1.0F, 1.0F - w1); + } else if (md == null) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F); + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + } else { + w1 = 0.125F; + this.setBlockBounds(w1, 0.0F, w1, 1.0F - w1, 1.0F, 1.0F - w1); + } + } else { + w1 = 0.25F; + this.setBlockBounds(w1, w1, w1, 1.0F - w1, 1.0F - w1, 1.0F - w1); + } + } + + @Override + public AxisAlignedBB getSelectedBoundingBoxFromPool(World w, int i, int j, int k) { + MetaVals md = MetaVals.get(w.getBlockMetadata(i, j, k)); + float w1; + if (md != MetaVals.CONDUIT && md != MetaVals.CONDUIT_VALVE + && md != MetaVals.CONDUIT_VALVE_ADVANCED) { + if (md != MetaVals.FILTER) { + if (md == MetaVals.CONDUIT_TANK) { + w1 = 0.0625F; + AxisAlignedBB.getBoundingBox( + (double) w1, + 0.0, + (double) w1, + (double) (1.0F - w1), + 1.0, + (double) (1.0F - w1) + ); + } else { + AxisAlignedBB.getBoundingBox(0.0, 0.0, 0.0, 1.0, 1.0, 1.0); + } + } else { + w1 = 0.125F; + AxisAlignedBB.getBoundingBox( + (double) w1, + 0.0, + (double) w1, + (double) (1.0F - w1), + 1.0, + (double) (1.0F - w1) + ); + } + } else { + w1 = 0.25F; + AxisAlignedBB.getBoundingBox( + (double) w1, + (double) w1, + (double) w1, + (double) (1.0F - w1), + (double) (1.0F - w1), + (double) (1.0F - w1) + ); + } + + return super.getSelectedBoundingBoxFromPool(w, i, j, k); + } + + @Override + public void onBlockPlacedBy( + World world, int i, int j, int k, EntityLivingBase entityliving, ItemStack is + ) { + MetaVals md = MetaVals.get(world.getBlockMetadata(i, j, k)); + int l = MathHelper.floor_double( + (double) (entityliving.rotationYaw * 4.0F / 360.0F) + 0.5 + ) + & 3; + if (md == MetaVals.PURIFIER) { + TilePurifier tp = (TilePurifier) world.getTileEntity(i, j, k); + tp.orientation = l; + world.markBlockForUpdate(tp.xCoord, tp.yCoord, tp.zCoord); + } + + if (md == MetaVals.CONDUIT_PUMP) { + TileConduitPump tb = (TileConduitPump) world.getTileEntity(i, j, k); + if (MathHelper.abs((float) entityliving.posX - (float) i) < 1.0F + && MathHelper.abs((float) entityliving.posZ - (float) k) < 1.0F) { + double d = entityliving.posY + 1.82 - (double) entityliving.yOffset; + if (d - (double) j > 2.0) { + tb.orientation = 1; + } + + if ((double) j - d > 0.0) { + tb.orientation = 0; + } + } else { + if (l == 0) { + tb.orientation = 2; + } + + if (l == 1) { + tb.orientation = 5; + } + + if (l == 2) { + tb.orientation = 3; + } + + if (l == 3) { + tb.orientation = 4; + } + } + } + } + + @Override + public boolean onBlockActivated( + World world, + int i, + int j, + int k, + EntityPlayer entityplayer, + + // useless parameters + int alec1, + float alec2, + float alec3, + float alec4 + ) { + if (!entityplayer.isSneaking()) { + MetaVals meta = MetaVals.get(world.getBlockMetadata(i, j, k)); + if (meta == MetaVals.CONDUIT_VALVE) { + if (entityplayer.isSneaking()) { + return false; + } else { + if (world.isRemote) + return true; + + TileConduitValve tileentity + = (TileConduitValve) world.getTileEntity(i, j, k); + if (tileentity != null) { + tileentity.open = !tileentity.open; + world.markBlockForUpdate( + tileentity.xCoord, tileentity.yCoord, tileentity.zCoord + ); + world.playSoundEffect( + (double) i + 0.5, + (double) j + 0.5, + (double) k + 0.5, + "random.click", + 0.3F, + tileentity.open ? 0.6F : 0.5F + ); + world.notifyBlocksOfNeighborChange(i, j, k, this); + } + + return true; + } + } else if (meta == MetaVals.CONDUIT_VALVE_ADVANCED) { + if (entityplayer.isSneaking()) { + return false; + } else { + TileConduitValveAdvanced tileentity + = (TileConduitValveAdvanced) world.getTileEntity(i, j, k); + if (tileentity != null) { + ++tileentity.setting; + if (tileentity.setting > 2) { + tileentity.setting = 0; + } + + world.markBlockForUpdate( + tileentity.xCoord, tileentity.yCoord, tileentity.zCoord + ); + world.playSoundEffect( + (double) i + 0.5, + (double) j + 0.5, + (double) k + 0.5, + "random.click", + 0.3F, + 0.5F + ); + world.notifyBlocksOfNeighborChange(i, j, k, this); + } + + return true; + } + } else { + return super.onBlockActivated( + world, i, j, k, entityplayer, alec1, alec2, alec3, alec4 + ); + } + } else { + return false; + } + } + + @Override + public void breakBlock(World world, int x, int y, int z, Block block, int meta_) { + // TODO: not sure if param 6 is meta + MetaVals meta = MetaVals.get(meta_); + + if (meta != MetaVals.CONDUIT_PUMP) { + AuraUtils.spillTaint(world, x, y, z); + } + super.breakBlock(world, x, y, z, block, meta_); + } + + @Override + public int getRenderType() { + return BlockApparatusRenderer.RI; + } + + //public int getBlockTextureFromSide(int i) { + // return 15; + //} + + @Override + public IIcon getIcon(IBlockAccess iblockaccess, int i, int j, int k, int l) { + MetaVals md = MetaVals.get(iblockaccess.getBlockMetadata(i, j, k)); + if (md == MetaVals.FILTER) { + if (l <= 1) { + return this.iconFilterBottom; + } else { + TileConduit tf = (TileFilter) iblockaccess.getTileEntity(i, j, k); + HelperLocation loc = new HelperLocation(tf); + switch (l) { + case 2: + loc.facing = ForgeDirection.NORTH; + break; + case 3: + loc.facing = ForgeDirection.SOUTH; + break; + case 4: + loc.facing = ForgeDirection.WEST; + break; + case 5: + loc.facing = ForgeDirection.EAST; + } + + if (!tf.getConnectable(loc.facing)) { + return this.iconFilterSide; + } else { + TileEntity te = loc.getConnectableTile(iblockaccess); + return te != null ? this.iconFilterFront : this.iconFilterSide; + } + } + } else if (md == MetaVals.CONDUIT_TANK) { + return l <= 1 ? this.iconTankBottom : this.iconTankSide; + } else if (md == MetaVals.PURIFIER) { + TileEntity te = iblockaccess.getTileEntity(i, j, k); + if (te != null && te instanceof TilePurifier) { + TilePurifier tp = (TilePurifier) te; + if (tp.orientation != 0 && tp.orientation != 2) { + return l > 3 ? this.iconPurifierFront : this.iconPurifierSide; + } else if (l <= 1) { + return this.iconPurifierTop; + } else { + return l <= 3 ? this.iconPurifierFront : this.iconPurifierSide; + } + } else { + return this.iconPurifierFront; + } + } + return this.blockIcon; + } + + @Override + public boolean isBlockSolid(IBlockAccess world, int i, int j, int k, int side) { + MetaVals md = MetaVals.get(world.getBlockMetadata(i, j, k)); + //return md > 2 && md != 4; + return md != MetaVals.CONDUIT && md != MetaVals.FILTER; + } + + //public int idDropped(int i, Random random, int j) { + // return i == 10 ? mod_ThaumCraft.itemComponents.shiftedIndex + // : super.idDropped(i, random, j); + //} + + @Override + public int damageDropped(int i) { + return i; + } + + public int getLightValue(IBlockAccess iba, int i, int j, int k) { + int md = iba.getBlockMetadata(i, j, k); + if (md != 0 && md != 1 && md != 3) { + if (md == 4) { + return 8; + } else { + return md == 10 ? 14 : super.getLightValue(iba, i, j, k); + } + } else { + return 5; + } + } + + //public boolean renderAppFragileBlock( + // World w, + // RenderBlocks renderblocks, + // int i, + // int j, + // int k, + // Block block, + // boolean inv, + // int md + //) { + // if (md == -9) { + // md = w.getBlockMetadata(i, j, k); + // } + + // if (md == 0) { + // return ThaumCraftRenderer.renderBlockConduit( + // w, renderblocks, i, j, k, block, md, inv + // ); + // } else if (md == 1) { + // return ThaumCraftRenderer.renderBlockFilter( + // w, renderblocks, i, j, k, block, md, inv + // ); + // } else if (md == 2) { + // return ThaumCraftRenderer.renderBlockBellows( + // w, renderblocks, i, j, k, block, md, inv + // ); + // } else if (md == 3) { + // return ThaumCraftRenderer.renderBlockTank( + // w, renderblocks, i, j, k, block, md, inv + // ); + // } else if (md == 4) { + // return ThaumCraftRenderer.renderBlockBrain( + // w, renderblocks, i, j, k, block, md, inv + // ); + // } else if (md == 5) { + // return ThaumCraftRenderer.renderBlockValve( + // w, renderblocks, i, j, k, block, md, inv + // ); + // } else if (md == 6) { + // return ThaumCraftRenderer.renderBlockPurifier( + // w, renderblocks, i, j, k, block, md, inv + // ); + // } else if (md == 7) { + // return ThaumCraftRenderer.renderTrunk( + // w, renderblocks, i, j, k, block, md, inv + // ); + // } else if (md == 8) { + // return ThaumCraftRenderer.renderBlockValveAdvanced( + // w, renderblocks, i, j, k, block, md, inv + // ); + // } else { + // return md == 9 ? ThaumCraftRenderer.renderBlockPump( + // w, renderblocks, i, j, k, block, md, inv + // ) + // : false; + // } + //} + + @Override + public void randomDisplayTick(World w, int i, int j, int k, Random r) { + int md = w.getBlockMetadata(i, j, k); + if (md == 10) { + FXSparkle ef2 = new FXSparkle( + w, + (double) ((float) i + 0.5F), + (double) ((float) j + 0.5F), + (double) ((float) k + 0.5F), + (double) ((float) i + 0.5F + (r.nextFloat() - r.nextFloat()) / 3.0F), + (double) ((float) j + 0.5F + (r.nextFloat() - r.nextFloat()) / 3.0F), + (double) ((float) k + 0.5F + (r.nextFloat() - r.nextFloat()) / 3.0F), + 1.0F, + 6, + 3 + ); + ef2.setGravity(0.05F); + Minecraft.getMinecraft().effectRenderer.addEffect(ef2); + } + } + + public void updateTick(World w, int i, int j, int k, Random r) { + int md = w.getBlockMetadata(i, j, k); + if (md == 10) { + w.scheduleBlockUpdate(i, j, k, this, 5 + r.nextInt(3)); + FXWisp ef = new FXWisp( + w, + (double) ((float) i + 0.5F), + (double) ((float) j + 0.5F), + (double) ((float) k + 0.5F), + 0.5F, + 4 + ); + ef.shrink = true; + ef.setGravity(-0.03F); + Minecraft.getMinecraft().effectRenderer.addEffect(ef); + ef = new FXWisp( + w, + (double) ((float) i + 0.5F), + (double) ((float) j + 0.5F), + (double) ((float) k + 0.5F), + 0.25F, + 1 + ); + ef.setGravity(-0.01F); + Minecraft.getMinecraft().effectRenderer.addEffect(ef); + } + + super.updateTick(w, i, j, k, r); + } + + public static enum MetaVals { + // original metas in comments + CONDUIT, // 0 + FILTER, // 1 + CONDUIT_TANK, // 3 + CONDUIT_VALVE, // 5 + PURIFIER, // 6 + CONDUIT_VALVE_ADVANCED, // 8 + CONDUIT_PUMP; // 9 + + public static MetaVals get(int meta) { + if (meta >= 0 && meta < MetaVals.values().length) + return MetaVals.values()[meta]; + + return null; + } + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatusMetal.java b/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatusMetal.java new file mode 100644 index 0000000..a792470 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatusMetal.java @@ -0,0 +1,973 @@ +package net.anvilcraft.thaummach.blocks; + +import java.util.List; +import java.util.Random; +import java.util.stream.IntStream; + +import dev.tilera.auracore.client.FXSparkle; +import net.anvilcraft.thaummach.AuraUtils; +import net.anvilcraft.thaummach.render.BlockApparatusRenderer; +import net.anvilcraft.thaummach.render.apparatus.IApparatusRenderer; +import net.anvilcraft.thaummach.render.apparatus.apparati.metal.ArcaneFurnaceApparatusRenderer; +import net.anvilcraft.thaummach.render.apparatus.apparati.metal.CrucibleApparatusRenderer; +import net.anvilcraft.thaummach.render.apparatus.apparati.metal.CrystallizerApparatusRenderer; +import net.anvilcraft.thaummach.tiles.TileArcaneFurnace; +import net.anvilcraft.thaummach.tiles.TileConduitTank; +import net.anvilcraft.thaummach.tiles.TileCrucible; +import net.anvilcraft.thaummach.tiles.TileCrystallizer; +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.DamageSource; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; +import thaumcraft.common.entities.monster.EntityThaumicSlime; +import thaumcraft.common.tiles.TileBellows; + +public class BlockApparatusMetal extends BlockApparatus { + private int delay = 0; + + public IIcon iconArcaneFurnaceBottom; + public IIcon iconArcaneFurnaceInside; + public IIcon iconArcaneFurnaceSide; + public IIcon iconArcaneFurnaceTop; + public IIcon iconCrystallizerBottom; + public IIcon iconCrystallizerSide; + public IIcon iconCrystallizerTop; + public IIcon iconGenerator1; + public IIcon iconGenerator2; + public IIcon iconGenerator3; + public IIcon iconSoulBrazierBottom; + public IIcon iconSoulBrazierSide; + public IIcon iconSoulCrucibleBottom; + public IIcon iconSoulCrucibleFace0; + public IIcon iconSoulCrucibleFace1; + public IIcon iconSoulCrucibleFace2; + public IIcon iconSoulCrucibleFace3; + public IIcon iconSoulCrucibleTop; + public IIcon iconSoulCrucibleTopInv; + public IIcon iconVoidChestBottom; + public IIcon iconVoidChestSide; + public IIcon iconVoidChestSideTransparent; + public IIcon iconVoidChestTop; + public IIcon iconVoidInterfaceBottom; + public IIcon iconVoidInterfaceSide; + + public IIcon[] iconsEyesCrucible; + public IIcon[] iconsNormalCrucible; + public IIcon[] iconsThaumiumCrucible; + + public BlockApparatusMetal() { + super(Material.rock); + this.setHardness(3.0F); + this.setResistance(17.0F); + this.setStepSound(Block.soundTypeMetal); + this.setBlockName("tcbappmetal"); + } + + @Override + public void registerBlockIcons(IIconRegister reg) { + super.registerBlockIcons(reg); + + this.iconArcaneFurnaceBottom + = reg.registerIcon("thaummach:arcane_furnace_bottom"); + this.iconArcaneFurnaceInside + = reg.registerIcon("thaummach:arcane_furnace_inside"); + this.iconArcaneFurnaceSide = reg.registerIcon("thaummach:arcane_furnace_side"); + this.iconArcaneFurnaceTop = reg.registerIcon("thaummach:arcane_furnace_top"); + this.iconCrystallizerBottom = reg.registerIcon("thaummach:crystallizer_bottom"); + this.iconCrystallizerSide = reg.registerIcon("thaummach:crystallizer_side"); + this.iconCrystallizerTop = reg.registerIcon("thaummach:crystallizer_top"); + this.iconGenerator1 = reg.registerIcon("thaummach:generator_1"); + this.iconGenerator2 = reg.registerIcon("thaummach:generator_2"); + this.iconGenerator3 = reg.registerIcon("thaummach:generator_3"); + this.iconSoulBrazierBottom = reg.registerIcon("thaummach:soul_brazier_bottom"); + this.iconSoulBrazierSide = reg.registerIcon("thaummach:soul_brazier_side"); + this.iconSoulCrucibleBottom = reg.registerIcon("thaummach:soul_crucible_bottom"); + this.iconSoulCrucibleFace0 = reg.registerIcon("thaummach:soul_crucible_face_0"); + this.iconSoulCrucibleFace1 = reg.registerIcon("thaummach:soul_crucible_face_1"); + this.iconSoulCrucibleFace2 = reg.registerIcon("thaummach:soul_crucible_face_2"); + this.iconSoulCrucibleFace3 = reg.registerIcon("thaummach:soul_crucible_face_3"); + this.iconSoulCrucibleTop = reg.registerIcon("thaummach:soul_crucible_top"); + this.iconSoulCrucibleTopInv = reg.registerIcon("thaummach:soul_crucible_top_inv"); + this.iconVoidChestBottom = reg.registerIcon("thaummach:void_chest_bottom"); + this.iconVoidChestSide = reg.registerIcon("thaummach:void_chest_side"); + this.iconVoidChestSideTransparent + = reg.registerIcon("thaummach:void_chest_side_transparent"); + this.iconVoidChestTop = reg.registerIcon("thaummach:void_chest_top"); + this.iconVoidInterfaceBottom + = reg.registerIcon("thaummach:void_interface_bottom"); + this.iconVoidInterfaceSide = reg.registerIcon("thaummach:void_interface_side"); + + this.iconsEyesCrucible + = IntStream.rangeClosed(1, 7) + .mapToObj(i -> reg.registerIcon("thaummach:eyes_crucible_" + i)) + .toArray(IIcon[] ::new); + + this.iconsNormalCrucible + = IntStream.rangeClosed(1, 7) + .mapToObj( + i + -> i == 5 ? null + : reg.registerIcon("thaummach:normal_crucible_" + i) + ) + .toArray(IIcon[] ::new); + + this.iconsThaumiumCrucible + = IntStream.rangeClosed(1, 7) + .mapToObj(i -> reg.registerIcon("thaummach:thaumium_crucible_" + i)) + .toArray(IIcon[] ::new); + } + + @Override + public IApparatusRenderer getApparatusRenderer(int md) { + MetaVals meta = MetaVals.get(md); + + switch (meta) { + case NORMAL_CRUCIBLE: + case EYES_CRUCIBLE: + case THAUMIUM_CRUCIBLE: + case SOUL_CRUCIBLE: + return CrucibleApparatusRenderer.INSTANCE; + + case ARCANE_FURNACE: + return ArcaneFurnaceApparatusRenderer.INSTANCE; + + case CRYSTALLIZER: + return CrystallizerApparatusRenderer.INSTANCE; + + default: + return null; + } + } + + @Override + public TileEntity createNewTileEntity(World world, int meta) { + MetaVals md = MetaVals.get(meta); + if (md.isCrucible()) { + TileCrucible tc = new TileCrucible(); + tc.setTier((short) (md.ordinal() + 1)); + return tc; + } else if (md == MetaVals.ARCANE_FURNACE) { + //return new TileArcaneFurnace(); + } else if (md == MetaVals.GENERATOR) { + //return new TileGenerator(); + } else if (md == MetaVals.CRYSTALLIZER) { + return new TileCrystallizer(); + } else if (md == MetaVals.BORE) { + //return new TileBore(); + } else if (md == MetaVals.VOID_CHEST) { + //return new TileVoidChest(); + } else if (md == MetaVals.VOID_INTERFACE) { + //return new TileVoidInterface(); + } else if (md == MetaVals.TANK) { + return new TileConduitTank(); + } else if (md == MetaVals.SOUL_BRAZIER) { + //return new TileSoulBrazier(); + } + + return null; + } + + @Override + @SuppressWarnings({ "unchecked", "rawtypes" }) + public void getSubBlocks(Item item, CreativeTabs tab, List list) { + for (MetaVals meta : MetaVals.values()) { + list.add(new ItemStack(this, 1, meta.ordinal())); + } + } + + @Override + public void + onEntityCollidedWithBlock(World world, int i, int j, int k, Entity entity) { + MetaVals md = MetaVals.get(world.getBlockMetadata(i, j, k)); + if (md == MetaVals.NORMAL_CRUCIBLE || md == MetaVals.EYES_CRUCIBLE + || md == MetaVals.THAUMIUM_CRUCIBLE) { + if (entity instanceof EntityItem && entity.posY <= (double) j + 0.7) { + entity.motionX += (double + ) ((world.rand.nextFloat() - world.rand.nextFloat()) * 0.05F); + entity.motionY += (double) (world.rand.nextFloat() * 0.1F); + entity.motionZ += (double + ) ((world.rand.nextFloat() - world.rand.nextFloat()) * 0.05F); + ((EntityItem) entity).delayBeforeCanPickup = 10; + ((EntityItem) entity).age = 0; + } + + ++this.delay; + if (this.delay >= 5) { + this.delay = 0; + if (entity instanceof EntityLiving + && !(entity instanceof EntityThaumicSlime)) { + entity.attackEntityFrom(DamageSource.magic, 1); + world.playSoundEffect( + (double) i, + (double) j, + (double) k, + "random.fizz", + 0.4F, + 2.0F + world.rand.nextFloat() * 0.4F + ); + } + } + } + } + + @Override + public int getRenderType() { + return BlockApparatusRenderer.RI; + } + + @Override + public IIcon getIcon(int i, int j) { + MetaVals meta = MetaVals.get(j); + if (meta == MetaVals.GENERATOR) { + return this.iconGenerator2; + } else if (meta == MetaVals.VOID_CHEST) { + if (i == 0) { + return this.iconVoidChestBottom; + } else { + return i == 1 ? this.iconVoidChestTop : this.iconVoidChestSide; + } + } else if (meta == MetaVals.VOID_INTERFACE) { + return i <= 1 ? this.iconVoidInterfaceBottom : this.iconVoidInterfaceSide; + } else if (meta == MetaVals.SOUL_BRAZIER) { + return i <= 1 ? this.iconSoulBrazierBottom : this.iconSoulBrazierSide; + } else { + return super.getIcon(i, j); + } + } + + @Override + public IIcon getIcon(IBlockAccess iblockaccess, int i, int j, int k, int side) { + MetaVals meta = MetaVals.get(iblockaccess.getBlockMetadata(i, j, k)); + TileCrucible tc; + if (meta == MetaVals.NORMAL_CRUCIBLE || meta == MetaVals.EYES_CRUCIBLE + || meta == MetaVals.THAUMIUM_CRUCIBLE) { + if (side == 1) { + return CrucibleApparatusRenderer.getIcons(this, meta)[0]; + } else if (side == 0) { + return CrucibleApparatusRenderer.getIcons(this, meta)[3]; + } else { + tc = (TileCrucible) iblockaccess.getTileEntity(i, j, k); + return meta != MetaVals.NORMAL_CRUCIBLE && tc != null && tc.isPowering + ? CrucibleApparatusRenderer.getIcons(this, meta)[3] + : CrucibleApparatusRenderer.getIcons(this, meta)[5]; + } + } else if (meta == MetaVals.SOUL_CRUCIBLE) { + if (side == 1) { + return this.iconSoulCrucibleTop; + } else if (side == 0) { + return this.iconSoulCrucibleBottom; + } else { + tc = (TileCrucible) iblockaccess.getTileEntity(i, j, k); + switch (tc == null ? 3 : tc.face) { + case 0: + return this.iconSoulCrucibleFace0; + + case 1: + return this.iconSoulCrucibleFace1; + + case 2: + return this.iconSoulCrucibleFace2; + + default: + return this.iconSoulCrucibleFace3; + } + } + } else if (meta == MetaVals.ARCANE_FURNACE) { + if (side == 1) { + return this.iconArcaneFurnaceTop; + } else if (side == 0) { + return this.iconArcaneFurnaceBottom; + } else { + return this.iconArcaneFurnaceSide; + } + } + //else if (meta == 5) { + // return 144; + //} + else if (meta == MetaVals.CRYSTALLIZER) { + if (side == 1) { + return this.iconCrystallizerTop; + } else if (side == 0) { + return this.iconCrystallizerBottom; + } else { + return this.iconCrystallizerSide; + } + } + //else if (meta == 8) { + // if (side == 0) { + // return 104; + // } else { + // return side == 1 ? 97 : 255; + // } + //} else if (meta == 10) { + // return side <= 1 ? 78 : 79; + //} else { + // return super.getBlockTexture(iblockaccess, i, j, k, side); + //} + return null; + } + + @Override + public int damageDropped(int i) { + return i; + } + + @Override + public void addCollisionBoxesToList( + World world, + int i, + int j, + int k, + AxisAlignedBB axisalignedbb, + List arraylist, + Entity entity + ) { + MetaVals meta = MetaVals.get(world.getBlockMetadata(i, j, k)); + float t4; + if (meta == MetaVals.NORMAL_CRUCIBLE || meta == MetaVals.EYES_CRUCIBLE + || meta == MetaVals.THAUMIUM_CRUCIBLE) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.3125F, 1.0F); + super.addCollisionBoxesToList( + world, i, j, k, axisalignedbb, arraylist, entity + ); + t4 = 0.125F; + this.setBlockBounds(0.0F, 0.0F, 0.0F, t4, 1.0F, 1.0F); + super.addCollisionBoxesToList( + world, i, j, k, axisalignedbb, arraylist, entity + ); + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, t4); + super.addCollisionBoxesToList( + world, i, j, k, axisalignedbb, arraylist, entity + ); + this.setBlockBounds(1.0F - t4, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + super.addCollisionBoxesToList( + world, i, j, k, axisalignedbb, arraylist, entity + ); + this.setBlockBounds(0.0F, 0.0F, 1.0F - t4, 1.0F, 1.0F, 1.0F); + super.addCollisionBoxesToList( + world, i, j, k, axisalignedbb, arraylist, entity + ); + this.setBlockBoundsForItemRender(); + } else if (meta != MetaVals.GENERATOR && meta != MetaVals.BORE) { + if (meta == MetaVals.VOID_INTERFACE) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.4375F, 1.0F); + super.addCollisionBoxesToList( + world, i, j, k, axisalignedbb, arraylist, entity + ); + } else if (meta == MetaVals.TANK) { + t4 = 0.0625F; + this.setBlockBounds(t4, 0.0F, t4, 1.0F - t4, 1.0F, 1.0F - t4); + super.addCollisionBoxesToList( + world, i, j, k, axisalignedbb, arraylist, entity + ); + } else if (meta == MetaVals.SOUL_BRAZIER) { + t4 = 0.25F; + this.setBlockBounds(t4, 0.0F, t4, 1.0F - t4, 0.75F, 1.0F - t4); + super.addCollisionBoxesToList( + world, i, j, k, axisalignedbb, arraylist, entity + ); + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + super.addCollisionBoxesToList( + world, i, j, k, axisalignedbb, arraylist, entity + ); + this.setBlockBoundsForItemRender(); + } + } else { + t4 = 0.125F; + this.setBlockBounds(t4, t4, t4, 1.0F - t4, 1.0F - t4, 1.0F - t4); + super.addCollisionBoxesToList( + world, i, j, k, axisalignedbb, arraylist, entity + ); + } + } + + @Override + public void + setBlockBoundsBasedOnState(IBlockAccess iblockaccess, int i, int j, int k) { + MetaVals md = MetaVals.get(iblockaccess.getBlockMetadata(i, j, k)); + float t4; + if (md != MetaVals.GENERATOR && md != MetaVals.BORE) { + if (md == MetaVals.TANK) { + t4 = 0.0625F; + this.setBlockBounds(t4, 0.0F, t4, 1.0F - t4, 1.0F, 1.0F - t4); + } else if (md == MetaVals.SOUL_BRAZIER) { + t4 = 0.25F; + this.setBlockBounds(t4, 0.0F, t4, 1.0F - t4, 0.75F, 1.0F - t4); + } else if (md == MetaVals.VOID_INTERFACE) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.4375F, 1.0F); + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + } else { + t4 = 0.125F; + this.setBlockBounds(t4, t4, t4, 1.0F - t4, 1.0F - t4, 1.0F - t4); + } + } + + @Override + public AxisAlignedBB getSelectedBoundingBoxFromPool(World w, int i, int j, int k) { + MetaVals md = MetaVals.get(w.getBlockMetadata(i, j, k)); + float t4; + if (md != MetaVals.GENERATOR && md != MetaVals.BORE) { + if (md == MetaVals.VOID_INTERFACE) { + AxisAlignedBB.getBoundingBox(0.0, 0.0, 0.0, 1.0, 0.4375, 1.0); + } else if (md == MetaVals.TANK) { + t4 = 0.0625F; + AxisAlignedBB.getBoundingBox( + (double) t4, + 0.0, + (double) t4, + (double) (1.0F - t4), + 1.0, + (double) (1.0F - t4) + ); + } else if (md == MetaVals.SOUL_BRAZIER) { + t4 = 0.25F; + AxisAlignedBB.getBoundingBox( + (double) t4, + 0.0, + (double) t4, + (double) (1.0F - t4), + 0.75, + (double) (1.0F - t4) + ); + } else { + AxisAlignedBB.getBoundingBox(0.0, 0.0, 0.0, 1.0, 1.0, 1.0); + } + } else { + t4 = 0.125F; + AxisAlignedBB.getBoundingBox( + (double) t4, + (double) t4, + (double) t4, + (double) (1.0F - t4), + (double) (1.0F - t4), + (double) (1.0F - t4) + ); + } + + return super.getSelectedBoundingBoxFromPool(w, i, j, k); + } + + @Override + public void setBlockBoundsForItemRender() { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + @Override + public void randomDisplayTick(World w, int i, int j, int k, Random r) { + MetaVals meta = MetaVals.get(w.getBlockMetadata(i, j, k)); + if (meta.isCrucible()) { + try { + //TileCrucible data = (TileCrucible) w.getTileEntity(i, j, k); + } catch (Exception var15) { + return; + } + + // TODO: FX + //ThaumCraftCore.createGreenFlameFX( + // w, + // (float) i + 0.2F + r.nextFloat() * 0.6F, + // (float) j + 0.1F, + // (float) k + 0.2F + r.nextFloat() * 0.6F + //); + } + + int arcs; + if (meta == MetaVals.ARCANE_FURNACE) { + TileArcaneFurnace data; + try { + data = (TileArcaneFurnace) w.getTileEntity(i, j, k); + } catch (Exception var14) { + return; + } + + if (!data.isWorking()) { + return; + } + + float f1; + float f2; + float f3; + for (arcs = 0; arcs < 3; ++arcs) { + f1 = r.nextFloat() * 0.6F; + f2 = r.nextFloat() * 0.5F; + f3 = r.nextFloat() * 0.6F; + w.spawnParticle( + "smoke", + (double) ((float) i + f1 + 0.2F), + (double) ((float) j + 0.1F + f2), + (double) ((float) k + f3 + 0.2F), + 0.0, + 0.06, + 0.0 + ); + w.spawnParticle( + "flame", + (double) ((float) i + f1 + 0.2F), + (double) ((float) j + 0.1F + f2), + (double) ((float) k + f3 + 0.2F), + 0.0, + 0.06, + 0.0 + ); + } + + float f = (float) i + 0.5F; + f1 = (float) j + 0.3F + r.nextFloat() * 0.4F; + f2 = (float) k + 0.5F; + f3 = 0.45F; + float f4 = r.nextFloat() * 0.6F - 0.3F; + + for (int a = 0; a < 4; ++a) { + if (a == 0 && !w.getBlock(i - 1, j, k).isOpaqueCube()) { + w.spawnParticle( + "smoke", + (double) (f - f3), + (double) f1, + (double) (f2 + f4), + 0.0, + 0.0, + 0.0 + ); + w.spawnParticle( + "flame", + (double) (f - f3), + (double) f1, + (double) (f2 + f4), + 0.0, + 0.0, + 0.0 + ); + } else if (a == 1 && !w.getBlock(i + 1, j, k).isOpaqueCube()) { + w.spawnParticle( + "smoke", + (double) (f + f3), + (double) f1, + (double) (f2 + f4), + 0.0, + 0.0, + 0.0 + ); + w.spawnParticle( + "flame", + (double) (f + f3), + (double) f1, + (double) (f2 + f4), + 0.0, + 0.0, + 0.0 + ); + } else if (a == 2 && !w.getBlock(i, j, k - 1).isOpaqueCube()) { + w.spawnParticle( + "smoke", + (double) (f + f4), + (double) f1, + (double) (f2 - f3), + 0.0, + 0.0, + 0.0 + ); + w.spawnParticle( + "flame", + (double) (f + f4), + (double) f1, + (double) (f2 - f3), + 0.0, + 0.0, + 0.0 + ); + } else if (a == 3 && !w.getBlock(i, j, k + 1).isOpaqueCube()) { + w.spawnParticle( + "smoke", + (double) (f + f4), + (double) f1, + (double) (f2 + f3), + 0.0, + 0.0, + 0.0 + ); + w.spawnParticle( + "flame", + (double) (f + f4), + (double) f1, + (double) (f2 + f3), + 0.0, + 0.0, + 0.0 + ); + } + } + } + + if (meta == MetaVals.GENERATOR) { + // TODO: generator + //TileGenerator tg = (TileGenerator) w.getTileEntity(i, j, k); + //int arcs = 20; + //if (!ModLoader.getMinecraftInstance().gameSettings.fancyGraphics + // || Config.lowGfx) { + // arcs = 10; + //} + + //arcs = arcs * tg.storedEnergy / tg.energyMax; + //if (w.rand.nextInt(20) < arcs) { + // LightningBolt bolt = new LightningBolt( + // w, + // (double) i + 0.5, + // (double) j + 0.5, + // (double) k + 0.5, + // (double) i + 0.1 + (double) w.rand.nextFloat() * 0.8, + // (double) j + 0.1 + (double) w.rand.nextFloat() * 0.8, + // (double) k + 0.1 + (double) w.rand.nextFloat() * 0.8, + // w.rand.nextLong(), + // 6, + // 9.0F + // ); + // bolt.defaultFractal(); + // bolt.setType(0); + // bolt.setNonLethal(); + // bolt.finalizeBolt(); + //} + } + + if (meta == MetaVals.CRYSTALLIZER) { + FXSparkle ef2 = new FXSparkle( + w, + (double) ((float) i + 0.1F + w.rand.nextFloat() * 0.8F), + (double) ((float) j + 0.6F + w.rand.nextFloat() * 0.6F), + (double) ((float) k + 0.1F + w.rand.nextFloat() * 0.8F), + 1.0F, + w.rand.nextInt(5), + 3 + ); + Minecraft.getMinecraft().effectRenderer.addEffect(ef2); + } + + if (meta == MetaVals.VOID_INTERFACE) { + // TODO: void interface + //TileVoidInterface tvi = (TileVoidInterface) w.getTileEntity(i, j, k); + //if (tvi != null && tvi.linked && w.rand.nextInt(10) == 0) { + // LightningBolt bolt = new LightningBolt( + // w, + // new WRVector3((double) i + 0.5, (double) j + 0.75, (double) k + + // 0.5), new WRVector3( + // (double) i + 0.5 + (double) w.rand.nextFloat() + // - (double) w.rand.nextFloat(), + // (double) (j + 2), + // (double) k + 0.5 + (double) w.rand.nextFloat() + // - (double) w.rand.nextFloat() + // ), + // w.rand.nextLong() + // ); + // bolt.setMultiplier(4.0F); + // bolt.defaultFractal(); + // bolt.setType(5); + // bolt.setNonLethal(); + // bolt.finalizeBolt(); + //} + } + } + + @Override + public void breakBlock(World world, int i, int j, int k, Block block, int meta_) { + MetaVals meta = MetaVals.get(meta_); + if (meta.isCrucible() || meta == MetaVals.TANK) { + AuraUtils.spillTaint(world, i, j, k); + } + + if (meta == MetaVals.VOID_INTERFACE) { + // TODO: void interface + //TileVoidInterface ts = (TileVoidInterface) world.getTileEntity(i, j, + //k); if (ts != null) { + // ts.invalidateLinks(); + // SISpecialTile pd = new SISpecialTile( + // i, + // j, + // k, + // ts.network, + // (byte) ModLoader.getMinecraftInstance().thePlayer.dimension, + // (byte) 1 + // ); + // mod_ThaumCraft.DeleteSpecialTileFromList(pd); + //} + + } else { + super.breakBlock(world, i, j, k, block, meta_); + } + } + + @Override + public boolean + isSideSolid(IBlockAccess world, int i, int j, int k, ForgeDirection side) { + MetaVals md = MetaVals.get(world.getBlockMetadata(i, j, k)); + return md != MetaVals.VOID_CHEST && md != MetaVals.VOID_INTERFACE; + } + + @Override + public void onBlockPlacedBy( + World world, int i, int j, int k, EntityLivingBase entityliving, ItemStack is + ) { + MetaVals md = MetaVals.get(world.getBlockMetadata(i, j, k)); + if (md == MetaVals.VOID_INTERFACE) { + // TODO: void interface + //if (world.getBlock(i, j - 1, k) == this + // && world.getBlockMetadata(i, j - 1, k) == 8) { + // TileVoidInterface tvi + // = (TileVoidInterface) world.getTileEntity(i, j, k); + // if (tvi != null) { + // tvi.network = (byte) world.rand.nextInt(6); + // SISpecialTile pd = new SISpecialTile( + // i, + // j, + // k, + // tvi.network, + // (byte) ModLoader.getMinecraftInstance().thePlayer.dimension, + // (byte) 1 + // ); + // mod_ThaumCraft.AddSpecialTileToList(pd); + // tvi.invalidateLinks(); + // tvi.establishLinks(); + // } + //} else { + // this.dropBlockAsItem(world, i, j, k, md, 0); + // world.setBlock(i, j, k, 0); + //} + } else if (md == MetaVals.BORE) { + // TODO: bore + //TileBore tb = (TileBore) world.getTileEntity(i, j, k); + //if (MathHelper.abs((float) entityliving.posX - (float) i) < 1.0F + // && MathHelper.abs((float) entityliving.posZ - (float) k) < 1.0F) { + // double d = entityliving.posY + 1.82 - (double) entityliving.yOffset; + // if (d - (double) j > 2.0) { + // tb.orientation = 1; + // } + + // if ((double) j - d > 0.0) { + // tb.orientation = 0; + // } + //} else { + // int l = MathHelper.floor_double( + // (double) (entityliving.rotationYaw * 4.0F / 360.0F) + 0.5 + // ) + // & 3; + // if (l == 0) { + // tb.orientation = 2; + // } + + // if (l == 1) { + // tb.orientation = 5; + // } + + // if (l == 2) { + // tb.orientation = 3; + // } + + // if (l == 3) { + // tb.orientation = 4; + // } + //} + } + + super.onBlockPlacedBy(world, i, j, k, entityliving, is); + } + + @Override + public boolean canProvidePower() { + return true; + } + + @Override + public int + isProvidingStrongPower(IBlockAccess iblockaccess, int i, int j, int k, int l) { + MetaVals meta = MetaVals.get(iblockaccess.getBlockMetadata(i, j, k)); + if (meta == MetaVals.EYES_CRUCIBLE || meta == MetaVals.THAUMIUM_CRUCIBLE) { + // TODO: crucibles + //TileCrucible data = (TileCrucible) iblockaccess.getTileEntity(i, j, k); + //if (l == 1) { + // TileEntity below = iblockaccess.getTileEntity(i, j - 1, k); + // if (below != null && below instanceof TileArcaneFurnace) { + // return 0; + // } + //} + + //if (data.isPowering) { + // return 15; + //} + } + + return 0; + } + + @Override + public int isProvidingWeakPower(IBlockAccess world, int i, int j, int k, int l) { + return this.isProvidingStrongPower(world, i, j, k, l); + } + + @Override + public void onNeighborBlockChange(World world, int i, int j, int k, Block l) { + super.onNeighborBlockChange(world, i, j, k, l); + MetaVals meta = MetaVals.get(world.getBlockMetadata(i, j, k)); + int bellows = 0; + if (world.getTileEntity(i + 1, j, k) instanceof TileBellows) { + ++bellows; + } + + if (world.getTileEntity(i - 1, j, k) instanceof TileBellows) { + ++bellows; + } + + if (world.getTileEntity(i, j, k + 1) instanceof TileBellows) { + ++bellows; + } + + if (world.getTileEntity(i, j, k - 1) instanceof TileBellows) { + ++bellows; + } + + if (meta.isCrucible()) { + // TODO: crucibles + //TileCrucible data = (TileCrucible) world.getTileEntity(i, j, k); + //data.bellows = bellows; + } else if (meta == MetaVals.ARCANE_FURNACE) { + // TODO: arcane furnace + //TileArcaneFurnace data + // = (TileArcaneFurnace) world.getTileEntity(i, j, k); + //data.bellows = bellows; + } else { + if (meta == MetaVals.VOID_INTERFACE + && (world.getBlock(i, j - 1, k) != this + || MetaVals.get(world.getBlockMetadata(i, j - 1, k)) + != MetaVals.VOID_CHEST)) { + this.dropBlockAsItem(world, i, j, k, meta.ordinal(), 0); + world.setBlockToAir(i, j, k); + } + } + } + + @Override + public int getLightValue(IBlockAccess iba, int i, int j, int k) { + MetaVals md = MetaVals.get(iba.getBlockMetadata(i, j, k)); + if (md.isCrucible()) { + return 5; + } else { + TileEntity tsb; + if (md == MetaVals.ARCANE_FURNACE) { + // TODO: arcane furnace + //tsb = iba.getTileEntity(i, j, k); + //return tsb != null && tsb instanceof TileArcaneFurnace + // && ((TileArcaneFurnace) tsb).isWorking() + // ? 13 + // : 0; + } else if (md == MetaVals.SOUL_BRAZIER) { + // TODO: soul brazier + //tsb = iba.getTileEntity(i, j, k); + //return tsb != null && tsb instanceof TileSoulBrazier + // && ((TileSoulBrazier) tsb).isWorking() + // ? 15 + // : 0; + } else { + return super.getLightValue(iba, i, j, k); + } + } + return 0; + } + + //@Override + //public boolean renderAppMetalBlock( + // World w, RenderBlocks rb, int i, int j, int k, Block block, boolean inv, int md + //) { + // if (md == -9) { + // md = w.getBlockMetadata(i, j, k); + // } + + // switch (md) { + // case 0: + // case 1: + // case 2: + // case 3: + // ThaumCraftRenderer.renderBlockCrucible(w, rb, i, j, k, block, md, inv); + // return true; + // case 4: + // ThaumCraftRenderer.renderBlockArcaneFurnace( + // w, rb, i, j, k, block, md, inv + // ); + // return true; + // case 5: + // ThaumCraftRenderer.renderBlockGenerator(w, rb, i, j, k, block, md, inv); + // return true; + // case 6: + // ThaumCraftRenderer.renderBlockCrystalizer(w, rb, i, j, k, block, md, + // inv); return true; + // case 7: + // ThaumCraftRenderer.renderBlockBore(w, rb, i, j, k, block, md, inv); + // return true; + // case 8: + // block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + // if (block.getRenderBlockPass() == 0 && !inv) { + // rb.renderStandardBlock(block, i, j, k); + // } else if (inv) { + // ThaumCraftRenderer.DrawFaces( + // rb, block, 97, 104, 103, 103, 103, 103, false + // ); + // } + + // return true; + // case 9: + // ThaumCraftRenderer.renderBlockVoidInterface( + // w, rb, i, j, k, block, md, inv + // ); + // return true; + // case 10: + // ThaumCraftRenderer.renderBlockTank(w, rb, i, j, k, block, md, inv); + // return true; + // case 11: + // ThaumCraftRenderer.renderBlockSoulBrazier(w, rb, i, j, k, block, md, + // inv); return true; + // default: + // return false; + // } + //} + + public static enum MetaVals { + NORMAL_CRUCIBLE, // 0 + EYES_CRUCIBLE, // 1 + THAUMIUM_CRUCIBLE, // 2 + SOUL_CRUCIBLE, // 3 + ARCANE_FURNACE, // 4 + GENERATOR, // 5 + CRYSTALLIZER, // 6 + BORE, // 7 + VOID_CHEST, // 8 + VOID_INTERFACE, // 9 + TANK, // 10 + SOUL_BRAZIER; // 11 + + public static MetaVals get(int meta) { + if (meta >= 0 && meta < MetaVals.values().length) { + return MetaVals.values()[meta]; + } + + return null; + } + + public boolean isCrucible() { + return this == NORMAL_CRUCIBLE || this == EYES_CRUCIBLE + || this == THAUMIUM_CRUCIBLE || this == SOUL_CRUCIBLE; + } + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/items/ItemBlockApparatus.java b/src/main/java/net/anvilcraft/thaummach/items/ItemBlockApparatus.java new file mode 100644 index 0000000..da6b77a --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/items/ItemBlockApparatus.java @@ -0,0 +1,31 @@ +package net.anvilcraft.thaummach.items; + +import net.anvilcraft.thaummach.TMTab; +import net.minecraft.block.Block; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; + +public abstract class ItemBlockApparatus extends ItemBlock { + public ItemBlockApparatus(Block block) { + super(block); + this.setHasSubtypes(true); + this.setMaxDamage(0); + this.setCreativeTab(TMTab.INSTANCE); + } + + public abstract String getTypeString(); + public abstract String getNameExtension(int meta); + + @Override + public int getMetadata(int meta) { + return meta; + } + + @Override + public String getUnlocalizedName(ItemStack is) { + String metaExt = this.getNameExtension(is.getItemDamage()); + if (metaExt == null) + return "tile.thaummach:alec"; + return "tile.thaummach:apparatus_" + this.getTypeString() + "_" + metaExt; + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/items/ItemBlockApparatusFragile.java b/src/main/java/net/anvilcraft/thaummach/items/ItemBlockApparatusFragile.java new file mode 100644 index 0000000..e6c65ba --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/items/ItemBlockApparatusFragile.java @@ -0,0 +1,23 @@ +package net.anvilcraft.thaummach.items; + +import net.anvilcraft.thaummach.blocks.BlockApparatusFragile.MetaVals; +import net.minecraft.block.Block; + +public class ItemBlockApparatusFragile extends ItemBlockApparatus { + public ItemBlockApparatusFragile(Block block) { + super(block); + } + + @Override + public String getTypeString() { + return "fragile"; + } + + @Override + public String getNameExtension(int meta_) { + MetaVals meta = MetaVals.get(meta_); + if (meta == null) + return null; + return meta.toString().toLowerCase(); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/items/ItemBlockApparatusMetal.java b/src/main/java/net/anvilcraft/thaummach/items/ItemBlockApparatusMetal.java new file mode 100644 index 0000000..f4efd68 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/items/ItemBlockApparatusMetal.java @@ -0,0 +1,23 @@ +package net.anvilcraft.thaummach.items; + +import net.anvilcraft.thaummach.blocks.BlockApparatusMetal.MetaVals; +import net.minecraft.block.Block; + +public class ItemBlockApparatusMetal extends ItemBlockApparatus { + public ItemBlockApparatusMetal(Block block) { + super(block); + } + + @Override + public String getTypeString() { + return "metal"; + } + + @Override + public String getNameExtension(int meta_) { + MetaVals meta = MetaVals.get(meta_); + if (meta == null) + return null; + return meta.toString().toLowerCase(); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/render/BlockApparatusRenderer.java b/src/main/java/net/anvilcraft/thaummach/render/BlockApparatusRenderer.java new file mode 100644 index 0000000..20a0a4d --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/render/BlockApparatusRenderer.java @@ -0,0 +1,53 @@ +package net.anvilcraft.thaummach.render; + +import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; +import net.anvilcraft.thaummach.blocks.BlockApparatus; +import net.anvilcraft.thaummach.render.apparatus.IApparatusRenderer; +import net.minecraft.block.Block; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.world.IBlockAccess; + +public class BlockApparatusRenderer implements ISimpleBlockRenderingHandler { + public static int RI; + + @Override + public void + renderInventoryBlock(Block block, int metadata, int modelId, RenderBlocks renderer) { + if (block instanceof BlockApparatus) { + IApparatusRenderer ren + = ((BlockApparatus) block).getApparatusRenderer(metadata); + if (ren != null) + ren.renderApparatus(null, renderer, 0, 0, 0, block, metadata, true); + } + } + + @Override + public boolean renderWorldBlock( + IBlockAccess world, + int x, + int y, + int z, + Block block, + int modelId, + RenderBlocks renderer + ) { + if (block instanceof BlockApparatus) { + int meta = world.getBlockMetadata(x, y, z); + IApparatusRenderer ren + = ((BlockApparatus) block).getApparatusRenderer(meta); + if (ren != null) + ren.renderApparatus(world, renderer, x, y, z, block, meta, false); + } + return false; + } + + @Override + public boolean shouldRender3DInInventory(int modelId) { + return true; + } + + @Override + public int getRenderId() { + return RI; + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/render/apparatus/ApparatusRenderingHelper.java b/src/main/java/net/anvilcraft/thaummach/render/apparatus/ApparatusRenderingHelper.java new file mode 100644 index 0000000..8db3247 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/render/apparatus/ApparatusRenderingHelper.java @@ -0,0 +1,62 @@ +package net.anvilcraft.thaummach.render.apparatus; + +import net.minecraft.block.Block; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.util.IIcon; +import org.lwjgl.opengl.GL11; + +public class ApparatusRenderingHelper { + public static void + drawFaces(RenderBlocks renderblocks, Block block, IIcon i, boolean st) { + drawFaces(renderblocks, block, i, i, i, i, i, i, st); + } + + public static void drawFaces( + RenderBlocks renderblocks, + Block block, + IIcon i1, + IIcon i2, + IIcon i3, + IIcon i4, + IIcon i5, + IIcon i6, + boolean solidtop + ) { + Tessellator tessellator = Tessellator.instance; + GL11.glTranslatef(-0.5F, -0.5F, -0.5F); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, -1.0F, 0.0F); + renderblocks.renderFaceYNeg(block, 0.0, 0.0, 0.0, i1); + tessellator.draw(); + if (solidtop) { + GL11.glDisable(3008); + } + + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + renderblocks.renderFaceYPos(block, 0.0, 0.0, 0.0, i2); + tessellator.draw(); + if (solidtop) { + GL11.glEnable(3008); + } + + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 0.0F, 1.0F); + renderblocks.renderFaceZNeg(block, 0.0, 0.0, 0.0, i3); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 0.0F, -1.0F); + renderblocks.renderFaceZPos(block, 0.0, 0.0, 0.0, i4); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(1.0F, 0.0F, 0.0F); + renderblocks.renderFaceXPos(block, 0.0, 0.0, 0.0, i5); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(-1.0F, 0.0F, 0.0F); + renderblocks.renderFaceXNeg(block, 0.0, 0.0, 0.0, i6); + tessellator.draw(); + GL11.glTranslatef(0.5F, 0.5F, 0.5F); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/render/apparatus/IApparatusRenderer.java b/src/main/java/net/anvilcraft/thaummach/render/apparatus/IApparatusRenderer.java new file mode 100644 index 0000000..0b38848 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/render/apparatus/IApparatusRenderer.java @@ -0,0 +1,24 @@ +package net.anvilcraft.thaummach.render.apparatus; + +import net.minecraft.block.Block; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.world.IBlockAccess; + +/** + * IApparatusRenderer is an interface that provides an interface for rendering an + * apparatus block. + * + * It is an attempt to debullshit azanor's rendering code. + */ +public interface IApparatusRenderer { + public void renderApparatus( + IBlockAccess w, + RenderBlocks rb, + int x, + int y, + int z, + Block block, + int meta, + boolean inv + ); +} diff --git a/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/ConduitApparatusRenderer.java b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/ConduitApparatusRenderer.java new file mode 100644 index 0000000..f1daf66 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/ConduitApparatusRenderer.java @@ -0,0 +1,320 @@ +package net.anvilcraft.thaummach.render.apparatus.apparati.fragile; + +import dev.tilera.auracore.api.HelperLocation; +import dev.tilera.auracore.api.machine.IConnection; +import net.anvilcraft.thaummach.blocks.BlockApparatusFragile; +import net.anvilcraft.thaummach.render.apparatus.ApparatusRenderingHelper; +import net.anvilcraft.thaummach.render.apparatus.IApparatusRenderer; +import net.anvilcraft.thaummach.tiles.TileConduit; +import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.IBlockAccess; +import net.minecraftforge.common.util.ForgeDirection; + +public class ConduitApparatusRenderer implements IApparatusRenderer { + public static ConduitApparatusRenderer INSTANCE = new ConduitApparatusRenderer(); + + @Override + public void renderApparatus( + IBlockAccess w, + RenderBlocks rb, + int x, + int y, + int z, + Block block_, + int meta, + boolean inv + ) { + BlockApparatusFragile block = (BlockApparatusFragile) block_; + float w4 = 0.25F; + float w6 = 0.375F; + float wq = 0.38125F; + Tessellator tessellator = Tessellator.instance; + if (!inv) { + TileConduit tc = (TileConduit) w.getTileEntity(x, y, z); + float b = 0.0F; + float total = 0.0F; + float hfill = 0.0F; + boolean visible = false; + total = Math.min(tc.pureVis + tc.taintedVis, tc.maxVis); + hfill = (1.0F - wq * 2.0F) * (total / tc.maxVis); + if (block.getRenderBlockPass() == 0) { + rb.overrideBlockTexture = block.iconConduit; + rb.setRenderBounds(w6, w6, w6, w6 + w4, w6 + w4, w6 + w4); + rb.renderStandardBlock(block, x, y, z); + visible = tc.pureVis + tc.taintedVis >= 0.1F; + if (visible) { + b = Math.min(1.0F, tc.pureVis / (tc.taintedVis + tc.pureVis)); + tessellator.setBrightness(20 + (int) (b * 210.0F)); + tessellator.setColorOpaque_F(1.0F, 1.0F, 1.0F); + rb.setRenderBounds(wq, wq, wq, 1.0F - wq, wq + hfill, 1.0F - wq); + rb.overrideBlockTexture = null; + rb.renderFaceXNeg( + block, (double) x, (double) y, (double) z, block.iconTcubeanim + ); + rb.renderFaceXPos( + block, (double) x, (double) y, (double) z, block.iconTcubeanim + ); + rb.renderFaceYNeg( + block, (double) x, (double) y, (double) z, block.iconTcubeanim + ); + rb.renderFaceYPos( + block, (double) x, (double) y, (double) z, block.iconTcubeanim + ); + rb.renderFaceZNeg( + block, (double) x, (double) y, (double) z, block.iconTcubeanim + ); + rb.renderFaceZPos( + block, (double) x, (double) y, (double) z, block.iconTcubeanim + ); + if (/*!Config.lowGfx && Config.pipedrips && */ Minecraft + .getMinecraft() + .theWorld.rand.nextInt(50) + == 1 + && w.isAirBlock(x, y - 1, z) + && tc.pureVis + tc.taintedVis > 3.5F) { + // TODO: FXDrip + //FXDrip obj = new FXDrip( + // w, + // (double) ((float) x + w6 + w.rand.nextFloat() * w4), + // (double) ((float) y + w6 - 0.05F), + // (double) ((float) z + w6 + w.rand.nextFloat() * w4) + //); + //obj.func_40097_b( + // (0.4F + w.rand.nextFloat() * 0.2F) * (b + 0.1F), + // 0.0F, + // (0.8F + w.rand.nextFloat() * 0.2F) * (b + 0.1F) + //); + //ModLoader.getMinecraftInstance().effectRenderer.addEffect(obj); + } + } + } + + rb.overrideBlockTexture = block.iconConduitExtension; + for (int dir = 0; dir < 6; ++dir) { + HelperLocation loc = new HelperLocation(tc); + loc.facing = ForgeDirection.getOrientation(dir); + + TileEntity te = loc.getConnectableTile(w); + if (te != null) { + if (block.getRenderBlockPass() == 0) { + switch (loc.facing.getOpposite().ordinal()) { + case 0: + rb.setRenderBounds( + w6, w6 + w4, w6, w6 + w4, 1.0F, w6 + w4 + ); + rb.renderStandardBlock(block, x, y, z); + break; + case 1: + rb.setRenderBounds(w6, 0.0F, w6, w6 + w4, w6, w6 + w4); + rb.renderStandardBlock(block, x, y, z); + break; + case 2: + rb.setRenderBounds( + w6, w6, w6 + w4, w6 + w4, w6 + w4, 1.0F + ); + rb.renderStandardBlock(block, x, y, z); + break; + case 3: + rb.setRenderBounds(w6, w6, 0.0F, w6 + w4, w6 + w4, w6); + rb.renderStandardBlock(block, x, y, z); + break; + case 4: + rb.setRenderBounds( + w6 + w4, w6, w6, 1.0F, w6 + w4, w6 + w4 + ); + rb.renderStandardBlock(block, x, y, z); + break; + case 5: + rb.setRenderBounds(0.0F, w6, w6, w6, w6 + w4, w6 + w4); + rb.renderStandardBlock(block, x, y, z); + } + + if (visible || !((IConnection) te).isVisConduit()) { + rb.overrideBlockTexture = null; + tessellator.setBrightness(20 + (int) (b * 210.0F)); + tessellator.setColorOpaque_F(1.0F, 1.0F, 1.0F); + renderConduitVis( + w, + rb, + x, + y, + z, + block, + loc.facing.getOpposite().ordinal(), + hfill + ); + rb.overrideBlockTexture = block.iconConduitExtension; + } + } + } + } + } else { + rb.setRenderBounds(w6, 0.0F, w6, w6 + w4, 1.0F, w6 + w4); + ApparatusRenderingHelper.drawFaces( + rb, block, block.iconConduitInventory, false + ); + } + + rb.overrideBlockTexture = null; + rb.setRenderBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + public static void renderConduitVis( + IBlockAccess w, + RenderBlocks rb, + int i, + int j, + int k, + BlockApparatusFragile block, + int dir, + float hfill + ) { + float wq = 0.38125F; + switch (dir) { + case 0: + rb.setRenderBounds( + 0.5F - hfill / 2.0F, + wq + hfill, + 0.5F - hfill / 2.0F, + 0.5F + hfill / 2.0F, + 1.0F, + 0.5F + hfill / 2.0F + ); + rb.renderFaceZNeg( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceZPos( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceXNeg( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceXPos( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceYPos( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceYNeg( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + break; + case 1: + rb.setRenderBounds( + 0.5F - hfill / 2.0F, + 0.0F, + 0.5F - hfill / 2.0F, + 0.5F + hfill / 2.0F, + wq, + 0.5F + hfill / 2.0F + ); + rb.renderFaceZNeg( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceZPos( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceXNeg( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceXPos( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceYPos( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceYNeg( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + break; + case 2: + rb.setRenderBounds(wq, wq, 1.0F - wq, 1.0F - wq, wq + hfill, 1.0F); + rb.renderFaceZNeg( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceZPos( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceXNeg( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceXPos( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceYPos( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceYNeg( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + break; + case 3: + rb.setRenderBounds(wq, wq, 0.0F, 1.0F - wq, wq + hfill, wq); + rb.renderFaceZNeg( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceZPos( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceXNeg( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceXPos( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceYPos( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceYNeg( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + break; + case 4: + rb.setRenderBounds(1.0F - wq, wq, wq, 1.0F, wq + hfill, 1.0F - wq); + rb.renderFaceZNeg( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceZPos( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceXNeg( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceXPos( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceYPos( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceYNeg( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + break; + case 5: + rb.setRenderBounds(0.0F, wq, wq, wq, wq + hfill, 1.0F - wq); + rb.renderFaceZNeg( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceZPos( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceXNeg( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceXPos( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceYPos( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceYNeg( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + break; + } + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/ConduitPumpApparatusRenderer.java b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/ConduitPumpApparatusRenderer.java new file mode 100644 index 0000000..cdabc66 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/ConduitPumpApparatusRenderer.java @@ -0,0 +1,83 @@ +package net.anvilcraft.thaummach.render.apparatus.apparati.fragile; + +import net.anvilcraft.thaummach.blocks.BlockApparatusFragile; +import net.anvilcraft.thaummach.render.apparatus.ApparatusRenderingHelper; +import net.anvilcraft.thaummach.render.apparatus.IApparatusRenderer; +import net.minecraft.block.Block; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.world.IBlockAccess; + +public class ConduitPumpApparatusRenderer implements IApparatusRenderer { + public static ConduitPumpApparatusRenderer INSTANCE + = new ConduitPumpApparatusRenderer(); + + @Override + public void renderApparatus( + IBlockAccess w, + RenderBlocks rb, + int x, + int y, + int z, + Block block_, + int meta, + boolean inv + ) { + BlockApparatusFragile block = (BlockApparatusFragile) block_; + float w4 = 0.25F; + float w3 = 0.1875F; + float w2 = 0.125F; + if (inv) { + rb.setRenderBounds(w2, 0.0F, w2, 1.0F - w2, w2, 1.0F - w2); + ApparatusRenderingHelper.drawFaces( + rb, + block, + block.iconConduitPumpTop, + block.iconConduitPumpTop, + block.iconConduitPumpSide, + block.iconConduitPumpSide, + block.iconConduitPumpSide, + block.iconConduitPumpSide, + false + ); + rb.setRenderBounds(w3, w2, w3, 1.0F - w3, w4, 1.0F - w3); + ApparatusRenderingHelper.drawFaces( + rb, + block, + block.iconConduitPumpTop, + block.iconConduitPumpTop, + block.iconConduitPumpSide, + block.iconConduitPumpSide, + block.iconConduitPumpSide, + block.iconConduitPumpSide, + false + ); + rb.setRenderBounds(0.0F, w4, 0.0F, 1.0F, 0.5F + w2, 1.0F); + ApparatusRenderingHelper.drawFaces( + rb, + block, + block.iconConduitPumpTop, + block.iconConduitPumpTop, + block.iconConduitPumpSide, + block.iconConduitPumpSide, + block.iconConduitPumpSide, + block.iconConduitPumpSide, + false + ); + rb.setRenderBounds(w2, 0.5F + w2, w2, 1.0F - w2, 1.0F, 1.0F - w2); + ApparatusRenderingHelper.drawFaces( + rb, + block, + block.iconConduitPumpTop, + block.iconConduitPumpTop, + block.iconConduitPumpSide, + block.iconConduitPumpSide, + block.iconConduitPumpSide, + block.iconConduitPumpSide, + false + ); + } + + rb.overrideBlockTexture = null; + rb.setRenderBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/ConduitTankApparatusRenderer.java b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/ConduitTankApparatusRenderer.java new file mode 100644 index 0000000..b801951 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/ConduitTankApparatusRenderer.java @@ -0,0 +1,142 @@ +package net.anvilcraft.thaummach.render.apparatus.apparati.fragile; + +import dev.tilera.auracore.api.HelperLocation; +import net.anvilcraft.thaummach.blocks.BlockApparatusFragile; +import net.anvilcraft.thaummach.render.apparatus.ApparatusRenderingHelper; +import net.anvilcraft.thaummach.render.apparatus.IApparatusRenderer; +import net.anvilcraft.thaummach.tiles.TileConduitTank; +import net.minecraft.block.Block; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; +import net.minecraftforge.common.util.ForgeDirection; + +public class ConduitTankApparatusRenderer implements IApparatusRenderer { + public static final ConduitTankApparatusRenderer INSTANCE + = new ConduitTankApparatusRenderer(); + + @Override + public void renderApparatus( + IBlockAccess w, + RenderBlocks rb, + int i, + int j, + int k, + Block block_, + int md, + boolean inv + ) { + BlockApparatusFragile block = (BlockApparatusFragile) block_; + float w1; + float w2; + if (block.getRenderBlockPass() == 0 || inv) { + w1 = 0.0625F; + w2 = 0.125F; + IIcon t1 = block.iconTankBottom; + IIcon t2 = block.iconTankSide; + // TODO: WTF + //if (md != 3) { + // t1 = 78; + // t2 = 79; + //} + + rb.setRenderBounds(w1, 0.0F, w1, 1.0F - w1, 1.0F, 1.0F - w1); + if (inv) { + ApparatusRenderingHelper.drawFaces( + rb, block, t1, t1, t2, t2, t2, t2, false + ); + } else { + rb.renderStandardBlock(block, i, j, k); + } + + if (!inv) { + rb.overrideBlockTexture = block.iconTankBottom; + TileConduitTank tc = (TileConduitTank) w.getTileEntity(i, j, k); + HelperLocation loc = new HelperLocation(tc); + loc.facing = ForgeDirection.WEST; + TileEntity te = loc.getConnectableTile(w); + if (te != null && tc.getConnectable(loc.facing) + && !(te instanceof TileConduitTank)) { + rb.setRenderBounds( + 0.0F, 0.5F - w2, 0.5F - w2, w1, 0.5F + w2, 0.5F + w2 + ); + rb.renderStandardBlock(block, i, j, k); + } + + loc = new HelperLocation(tc); + loc.facing = ForgeDirection.EAST; + te = loc.getConnectableTile(w); + if (te != null && tc.getConnectable(loc.facing) + && !(te instanceof TileConduitTank)) { + rb.setRenderBounds( + 1.0F - w1, 0.5F - w2, 0.5F - w2, 1.0F, 0.5F + w2, 0.5F + w2 + ); + rb.renderStandardBlock(block, i, j, k); + } + + loc = new HelperLocation(tc); + loc.facing = ForgeDirection.NORTH; + te = loc.getConnectableTile(w); + if (te != null && tc.getConnectable(loc.facing) + && !(te instanceof TileConduitTank)) { + rb.setRenderBounds( + 0.5F - w2, 0.5F - w2, 0.0F, 0.5F + w2, 0.5F + w2, w1 + ); + rb.renderStandardBlock(block, i, j, k); + } + + loc = new HelperLocation(tc); + loc.facing = ForgeDirection.SOUTH; + te = loc.getConnectableTile(w); + if (te != null && tc.getConnectable(loc.facing) + && !(te instanceof TileConduitTank)) { + rb.setRenderBounds( + 0.5F - w2, 0.5F - w2, 1.0F - w1, 0.5F + w2, 0.5F + w2, 1.0F + ); + rb.renderStandardBlock(block, i, j, k); + } + } + } + + rb.overrideBlockTexture = null; + + if (block.getRenderBlockPass() == 0 && !inv) { + w1 = 0.003F; + w2 = 0.0625F; + TileConduitTank tc = (TileConduitTank) w.getTileEntity(i, j, k); + if (tc != null && tc.pureVis + tc.taintedVis > 0.1F) { + Tessellator tessellator = Tessellator.instance; + float hfill = (1.0F - w1 * 2.0F) + * ((tc.pureVis + tc.taintedVis) / tc.getMaxVis()); + float b = Math.min(1.0F, tc.pureVis / (tc.taintedVis + tc.pureVis)); + rb.setRenderBounds( + w1 + w2, w1, w1 + w2, 1.0F - w1 - w2, w1 + hfill, 1.0F - w1 - w2 + ); + tessellator.setBrightness(20 + (int) (b * 210.0F)); + tessellator.setColorOpaque_F(1.0F, 1.0F, 1.0F); + rb.renderFaceZPos( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceZNeg( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceXNeg( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceXPos( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceYPos( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + rb.renderFaceYNeg( + block, (double) i, (double) j, (double) k, block.iconTcubeanim + ); + } + } + + rb.setRenderBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/ConduitValveAdvancedApparatusRenderer.java b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/ConduitValveAdvancedApparatusRenderer.java new file mode 100644 index 0000000..2ad7abb --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/ConduitValveAdvancedApparatusRenderer.java @@ -0,0 +1,154 @@ +package net.anvilcraft.thaummach.render.apparatus.apparati.fragile; + +import dev.tilera.auracore.api.HelperLocation; +import dev.tilera.auracore.api.machine.IConnection; +import net.anvilcraft.thaummach.blocks.BlockApparatusFragile; +import net.anvilcraft.thaummach.render.apparatus.ApparatusRenderingHelper; +import net.anvilcraft.thaummach.render.apparatus.IApparatusRenderer; +import net.anvilcraft.thaummach.tiles.TileConduitValveAdvanced; +import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.IBlockAccess; +import net.minecraftforge.common.util.ForgeDirection; + +public class ConduitValveAdvancedApparatusRenderer implements IApparatusRenderer { + public static final ConduitValveAdvancedApparatusRenderer INSTANCE + = new ConduitValveAdvancedApparatusRenderer(); + + @Override + public void renderApparatus( + IBlockAccess w, + RenderBlocks rb, + int i, + int j, + int k, + Block block_, + int meta, + boolean inv + ) { + BlockApparatusFragile block = (BlockApparatusFragile) block_; + float w4 = 0.25F; + float wq = 0.38125F; + float w6 = 0.375F; + Tessellator tessellator = Tessellator.instance; + if (!inv) { + TileConduitValveAdvanced tc + = (TileConduitValveAdvanced) w.getTileEntity(i, j, k); + float b = 0.0F; + float total = 0.0F; + float hfill = 0.0F; + boolean visible = false; + if (block.getRenderBlockPass() == 0) { + switch (tc.setting) { + case 0: + rb.overrideBlockTexture = block.iconValveAdvancedOff; + break; + case 1: + rb.overrideBlockTexture = block.iconValveAdvancedOnVis; + break; + case 2: + rb.overrideBlockTexture = block.iconValveAdvancedOnTaint; + } + + rb.setRenderBounds(w4, w4, w4, 1.0F - w4, 1.0F - w4, 1.0F - w4); + rb.renderStandardBlock(block, i, j, k); + rb.overrideBlockTexture = block.iconConduitExtension; + } else { + visible = tc.pureVis + tc.taintedVis >= 0.1F; + if (visible) { + b = Math.min( + 1.0F, tc.pureVis / (tc.taintedVis + tc.pureVis) + ); + total = Math.min(tc.pureVis + tc.taintedVis, tc.maxVis); + hfill = (1.0F - wq * 2.0F) * (total / tc.maxVis); + tessellator.setBrightness(20 + (int) (b * 210.0F)); + tessellator.setColorOpaque_F(1.0F, 1.0F, 1.0F); + if (Minecraft.getMinecraft().theWorld.rand.nextInt(50) == 1 + && w.isAirBlock(i, j - 1, k) + && tc.pureVis + tc.taintedVis > 3.5F) { + // TODO: WTF + //FXDrip obj = new FXDrip( + // w, + // (double) ((float) i + w4 + w.rand.nextFloat() * w6), + // (double) ((float) j + w4 - 0.05F), + // (double) ((float) k + w4 + w.rand.nextFloat() * w6) + //); + //obj.func_40097_b( + // (0.4F + w.rand.nextFloat() * 0.2F) * (b + 0.1F), + // 0.0F, + // (0.8F + w.rand.nextFloat() * 0.2F) * (b + 0.1F) + //); + //ModLoader.getMinecraftInstance().effectRenderer.addEffect(obj); + } + } + } + + for (int dir = 0; dir < 6; ++dir) { + HelperLocation loc = new HelperLocation(tc); + loc.facing = ForgeDirection.getOrientation(dir).getOpposite(); + + TileEntity te = loc.getConnectableTile(w); + if (te != null) { + if (block.getRenderBlockPass() == 0) { + switch (dir) { + case 0: + rb.setRenderBounds( + w6, 1.0F - w4, w6, 1.0F - w6, 1.0F, 1.0F - w6 + ); + rb.renderStandardBlock(block, i, j, k); + break; + case 1: + rb.setRenderBounds( + w6, 0.0F, w6, 1.0F - w6, w6, 1.0F - w6 + ); + rb.renderStandardBlock(block, i, j, k); + break; + case 2: + rb.setRenderBounds( + w6, w6, 1.0F - w4, 1.0F - w6, 1.0F - w6, 1.0F + ); + rb.renderStandardBlock(block, i, j, k); + break; + case 3: + rb.setRenderBounds( + w6, w6, 0.0F, 1.0F - w6, 1.0F - w6, w4 + ); + rb.renderStandardBlock(block, i, j, k); + break; + case 4: + rb.setRenderBounds( + 1.0F - w4, w6, w6, 1.0F, 1.0F - w6, 1.0F - w6 + ); + rb.renderStandardBlock(block, i, j, k); + break; + case 5: + rb.setRenderBounds( + 0.0F, w6, w6, w4, 1.0F - w6, 1.0F - w6 + ); + rb.renderStandardBlock(block, i, j, k); + } + } else if (visible && (((IConnection)te).getPureVis() + ((IConnection)te).getTaintedVis() > 0.1F || !((IConnection)te).isVisConduit())) { + ConduitApparatusRenderer.renderConduitVis( + w, rb, i, j, k, block, dir, hfill + ); + } + } + } + } else { + rb.setRenderBounds(w6, 0.0F, w6, 1.0F - w6, 1.0F, 1.0F - w6); + ApparatusRenderingHelper.drawFaces( + rb, block, block.iconConduitInventory, false + ); + rb.setRenderBounds(w4, w4, w4, 1.0F - w4, 1.0F - w4, 1.0F - w4); + ApparatusRenderingHelper.drawFaces( + rb, block, block.iconValveAdvancedOff, false + ); + } + + rb.overrideBlockTexture = null; + rb.setRenderBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/ConduitValveApparatusRenderer.java b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/ConduitValveApparatusRenderer.java new file mode 100644 index 0000000..415afc6 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/ConduitValveApparatusRenderer.java @@ -0,0 +1,165 @@ +package net.anvilcraft.thaummach.render.apparatus.apparati.fragile; + +import dev.tilera.auracore.api.HelperLocation; +import dev.tilera.auracore.api.machine.IConnection; +import net.anvilcraft.thaummach.blocks.BlockApparatusFragile; +import net.anvilcraft.thaummach.render.apparatus.ApparatusRenderingHelper; +import net.anvilcraft.thaummach.render.apparatus.IApparatusRenderer; +import net.anvilcraft.thaummach.tiles.TileConduitValve; +import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.IBlockAccess; +import net.minecraftforge.common.util.ForgeDirection; + +public class ConduitValveApparatusRenderer implements IApparatusRenderer { + public static final ConduitValveApparatusRenderer INSTANCE + = new ConduitValveApparatusRenderer(); + + @Override + public void renderApparatus( + IBlockAccess w, + RenderBlocks rb, + int i, + int j, + int k, + Block block_, + int meta, + boolean inv + ) { + BlockApparatusFragile block = (BlockApparatusFragile) block_; + float w4 = 0.25F; + float wq = 0.38125F; + float w6 = 0.375F; + Tessellator tessellator = Tessellator.instance; + if (!inv) { + TileConduitValve tc = (TileConduitValve) w.getTileEntity(i, j, k); + float b = Math.min(1.0F, tc.pureVis / (tc.taintedVis + tc.pureVis)); + float total = 0.0F; + float hfill = 0.0F; + boolean visible = tc.pureVis + tc.taintedVis >= 0.1F; + if (block.getRenderBlockPass() == 0) { + if (tc.open) { + rb.overrideBlockTexture = block.iconValveOn; + } else { + rb.overrideBlockTexture = block.iconValveOff; + } + + rb.setRenderBounds(w4, w4, w4, 1.0F - w4, 1.0F - w4, 1.0F - w4); + rb.renderStandardBlock(block, i, j, k); + rb.overrideBlockTexture = block.iconConduitExtension; + } else { + if (visible) { + total = Math.min(tc.pureVis + tc.taintedVis, tc.maxVis); + hfill = (1.0F - wq * 2.0F) * (total / tc.maxVis); + tessellator.setBrightness(20 + (int) (b * 210.0F)); + tessellator.setColorOpaque_F(1.0F, 1.0F, 1.0F); + if (Minecraft.getMinecraft().theWorld.rand.nextInt(50) == 1 + && w.isAirBlock(i, j - 1, k) + && tc.pureVis + tc.taintedVis > 3.5F) { + // TODO: FXDrip + //FXDrip obj = new FXDrip( + // w, + // (double) ((float) i + w4 + w.rand.nextFloat() * w6), + // (double) ((float) j + w4 - 0.05F), + // (double) ((float) k + w4 + w.rand.nextFloat() * w6) + //); + //obj.func_40097_b( + // (0.4F + w.rand.nextFloat() * 0.2F) * (b + 0.1F), + // 0.0F, + // (0.8F + w.rand.nextFloat() * 0.2F) * (b + 0.1F) + //); + //ModLoader.getMinecraftInstance().effectRenderer.addEffect(obj); + } + } + } + + for (int dir = 0; dir < 6; ++dir) { + HelperLocation loc = new HelperLocation(tc); + switch (dir) { + case 0: + loc.facing = ForgeDirection.UP; + break; + case 1: + loc.facing = ForgeDirection.DOWN; + break; + case 2: + loc.facing = ForgeDirection.SOUTH; + break; + case 3: + loc.facing = ForgeDirection.NORTH; + break; + case 4: + loc.facing = ForgeDirection.EAST; + break; + case 5: + loc.facing = ForgeDirection.WEST; + } + + TileEntity te = loc.getConnectableTile(w); + if (te != null) { + if (block.getRenderBlockPass() == 0) { + switch (dir) { + case 0: + rb.setRenderBounds( + w6, 1.0F - w4, w6, 1.0F - w6, 1.0F, 1.0F - w6 + ); + rb.renderStandardBlock(block, i, j, k); + break; + case 1: + rb.setRenderBounds( + w6, 0.0F, w6, 1.0F - w6, w6, 1.0F - w6 + ); + rb.renderStandardBlock(block, i, j, k); + break; + case 2: + rb.setRenderBounds( + w6, w6, 1.0F - w4, 1.0F - w6, 1.0F - w6, 1.0F + ); + rb.renderStandardBlock(block, i, j, k); + break; + case 3: + rb.setRenderBounds( + w6, w6, 0.0F, 1.0F - w6, 1.0F - w6, w4 + ); + rb.renderStandardBlock(block, i, j, k); + break; + case 4: + rb.setRenderBounds( + 1.0F - w4, w6, w6, 1.0F, 1.0F - w6, 1.0F - w6 + ); + rb.renderStandardBlock(block, i, j, k); + break; + case 5: + rb.setRenderBounds( + 0.0F, w6, w6, w4, 1.0F - w6, 1.0F - w6 + ); + rb.renderStandardBlock(block, i, j, k); + } + if (visible) { + rb.overrideBlockTexture = null; + tessellator.setBrightness(20 + (int) (b * 210.0F)); + tessellator.setColorOpaque_F(1.0F, 1.0F, 1.0F); + ConduitApparatusRenderer.renderConduitVis( + w, rb, i, j, k, block, dir, hfill + ); + rb.overrideBlockTexture = block.iconConduitExtension; + } + } + } + } + } else { + rb.setRenderBounds(w6, 0.0F, w6, 1.0F - w6, 1.0F, 1.0F - w6); + ApparatusRenderingHelper.drawFaces( + rb, block, block.iconConduitInventory, false + ); + rb.setRenderBounds(w4, w4, w4, 1.0F - w4, 1.0F - w4, 1.0F - w4); + ApparatusRenderingHelper.drawFaces(rb, block, block.iconValveOn, false); + } + + rb.overrideBlockTexture = null; + rb.setRenderBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/FilterApparatusRenderer.java b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/FilterApparatusRenderer.java new file mode 100644 index 0000000..0d52b5a --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/FilterApparatusRenderer.java @@ -0,0 +1,162 @@ +package net.anvilcraft.thaummach.render.apparatus.apparati.fragile; + +import dev.tilera.auracore.api.HelperLocation; +import dev.tilera.auracore.api.machine.IConnection; +import net.anvilcraft.thaummach.blocks.BlockApparatusFragile; +import net.anvilcraft.thaummach.render.apparatus.ApparatusRenderingHelper; +import net.anvilcraft.thaummach.render.apparatus.IApparatusRenderer; +import net.anvilcraft.thaummach.tiles.TileConduit; +import net.minecraft.block.Block; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.IBlockAccess; +import net.minecraftforge.common.util.ForgeDirection; + +public class FilterApparatusRenderer implements IApparatusRenderer { + public static final FilterApparatusRenderer INSTANCE = new FilterApparatusRenderer(); + + @Override + public void renderApparatus( + IBlockAccess w, + RenderBlocks rb, + int x, + int y, + int z, + Block block_, + int meta, + boolean inv + ) { + BlockApparatusFragile block = (BlockApparatusFragile) block_; + float w4 = 0.25F; + float w3 = 0.1875F; + float w2 = 0.125F; + if (block.getRenderBlockPass() == 0 || inv) { + rb.setRenderBounds(w2, 0.0F, w2, 1.0F - w2, w3, 1.0F - w2); + if (inv) { + ApparatusRenderingHelper.drawFaces( + rb, + block, + block.iconFilterBottom, + block.iconFilterBottom, + block.iconFilterSide, + block.iconFilterSide, + block.iconFilterSide, + block.iconFilterSide, + false + ); + } else { + rb.renderStandardBlock(block, x, y, z); + } + + rb.setRenderBounds(w2, 1.0F - w3, w2, 1.0F - w2, 1.0F, 1.0F - w2); + if (inv) { + ApparatusRenderingHelper.drawFaces( + rb, + block, + block.iconFilterBottom, + block.iconFilterBottom, + block.iconFilterSide, + block.iconFilterSide, + block.iconFilterSide, + block.iconFilterSide, + false + ); + } else { + rb.renderStandardBlock(block, x, y, z); + } + + rb.setRenderBounds(w3, w3, w3, 1.0F - w3, 1.0F - w3, 1.0F - w3); + if (inv) { + ApparatusRenderingHelper.drawFaces( + rb, + block, + block.iconFilterBottom, + block.iconFilterBottom, + block.iconFilterSide, + block.iconFilterSide, + block.iconFilterSide, + block.iconFilterSide, + false + ); + } else { + rb.renderStandardBlock(block, x, y, z); + } + } + + if (!inv) { + float w6 = 0.375F; + float wq = 0.38125F; + TileConduit tc = (TileConduit) w.getTileEntity(x, y, z); + Tessellator tessellator = Tessellator.instance; + float b = 0.0F; + float total = 0.0F; + float hfill = 0.0F; + boolean visible = false; + if (block.getRenderBlockPass() != 0) { + visible = tc.pureVis + tc.taintedVis >= 0.1F; + if (visible) { + b = Math.min( + 1.0F, tc.pureVis / (tc.taintedVis + tc.pureVis) + ); + total = Math.min(tc.pureVis + tc.taintedVis, tc.maxVis); + hfill = (1.0F - wq * 2.0F) * (total / tc.maxVis); + tessellator.setBrightness(20 + (int) (b * 210.0F)); + tessellator.setColorOpaque_F(1.0F, 1.0F, 1.0F); + } + } + + for (int dir = 2; dir < 6; ++dir) { + HelperLocation loc = new HelperLocation(tc); + switch (dir) { + case 2: + loc.facing = ForgeDirection.SOUTH; + break; + case 3: + loc.facing = ForgeDirection.NORTH; + break; + case 4: + loc.facing = ForgeDirection.EAST; + break; + case 5: + loc.facing = ForgeDirection.WEST; + } + + TileEntity te = loc.getConnectableTile(w); + if (te != null && tc.getConnectable(loc.facing)) { + if (block.getRenderBlockPass() == 0) { + rb.overrideBlockTexture = block.iconConduitConnection; + switch (dir) { + case 2: + rb.setRenderBounds( + w6, w6, 1.0F - w3, w6 + w4, w6 + w4, 1.0F + ); + rb.renderStandardBlock(block, x, y, z); + break; + case 3: + rb.setRenderBounds(w6, w6, 0.0F, w6 + w4, w6 + w4, w3); + rb.renderStandardBlock(block, x, y, z); + break; + case 4: + rb.setRenderBounds( + 1.0F - w3, w6, w6, 1.0F, w6 + w4, w6 + w4 + ); + rb.renderStandardBlock(block, x, y, z); + break; + case 5: + rb.setRenderBounds(0.0F, w6, w6, w3, w6 + w4, w6 + w4); + rb.renderStandardBlock(block, x, y, z); + } + } else if (visible && (((IConnection)te).getPureVis() + ((IConnection)te).getTaintedVis() > 0.1F || !((IConnection)te).isVisConduit())) { + ConduitApparatusRenderer.renderConduitVis( + w, rb, x, y, z, block, dir, hfill + ); + } + } + } + } + + rb.overrideBlockTexture = null; + rb.setRenderBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/PurifierApparatusRenderer.java b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/PurifierApparatusRenderer.java new file mode 100644 index 0000000..32fd700 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/fragile/PurifierApparatusRenderer.java @@ -0,0 +1,47 @@ +package net.anvilcraft.thaummach.render.apparatus.apparati.fragile; + +import net.anvilcraft.thaummach.blocks.BlockApparatusFragile; +import net.anvilcraft.thaummach.render.apparatus.ApparatusRenderingHelper; +import net.anvilcraft.thaummach.render.apparatus.IApparatusRenderer; +import net.minecraft.block.Block; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.world.IBlockAccess; + +public class PurifierApparatusRenderer implements IApparatusRenderer { + public static PurifierApparatusRenderer INSTANCE = new PurifierApparatusRenderer(); + + @Override + public void renderApparatus( + IBlockAccess w, + RenderBlocks rb, + int i, + int j, + int k, + Block block_, + int meta, + boolean inv + ) { + BlockApparatusFragile block = (BlockApparatusFragile) block_; + if (block.getRenderBlockPass() == 0 || inv) { + rb.setRenderBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + if (inv) { + ApparatusRenderingHelper.drawFaces( + rb, + block, + block.iconPurifierTop, + block.iconPurifierTop, + block.iconPurifierFront, + block.iconPurifierFront, + block.iconPurifierSide, + block.iconPurifierSide, + false + ); + } else { + rb.renderStandardBlock(block, i, j, k); + } + } + + rb.overrideBlockTexture = null; + rb.setRenderBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/metal/ArcaneFurnaceApparatusRenderer.java b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/metal/ArcaneFurnaceApparatusRenderer.java new file mode 100644 index 0000000..ef9cdcd --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/metal/ArcaneFurnaceApparatusRenderer.java @@ -0,0 +1,87 @@ +package net.anvilcraft.thaummach.render.apparatus.apparati.metal; + +import net.anvilcraft.thaummach.blocks.BlockApparatusMetal; +import net.anvilcraft.thaummach.render.apparatus.ApparatusRenderingHelper; +import net.anvilcraft.thaummach.render.apparatus.IApparatusRenderer; +import net.minecraft.block.Block; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.world.IBlockAccess; + +public class ArcaneFurnaceApparatusRenderer implements IApparatusRenderer { + public static ArcaneFurnaceApparatusRenderer INSTANCE + = new ArcaneFurnaceApparatusRenderer(); + + @Override + public void renderApparatus( + IBlockAccess w, + RenderBlocks rb, + int i, + int j, + int k, + Block block_, + int meta, + boolean inv + ) { + BlockApparatusMetal block = (BlockApparatusMetal) block_; + if (block.getRenderBlockPass() == 0 && !inv) { + float w3 = 0.1875F; + rb.setRenderBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + rb.renderStandardBlock(block, i, j, k); + rb.renderFaceYPos( + block, + (double) i, + (double) ((float) j - 1.0F + w3), + (double) k, + block.iconArcaneFurnaceInside + ); + rb.renderFaceXPos( + block, + (double) ((float) (i - 1) + w3), + (double) j, + (double) k, + block.iconArcaneFurnaceInside + ); + rb.renderFaceXNeg( + block, + (double) ((float) (i + 1) - w3), + (double) j, + (double) k, + block.iconArcaneFurnaceInside + ); + rb.renderFaceZPos( + block, + (double) i, + (double) j, + (double) ((float) (k - 1) + w3), + block.iconArcaneFurnaceInside + ); + rb.renderFaceZNeg( + block, + (double) i, + (double) j, + (double) ((float) (k + 1) - w3), + block.iconArcaneFurnaceInside + ); + } else if (inv) { + rb.setRenderBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + ApparatusRenderingHelper.drawFaces( + rb, + block, + block.iconArcaneFurnaceBottom, + block.iconArcaneFurnaceTop, + block.iconArcaneFurnaceSide, + block.iconArcaneFurnaceSide, + block.iconArcaneFurnaceSide, + block.iconArcaneFurnaceSide, + true + ); + rb.setRenderBounds(0.1F, 0.1F, 0.1F, 0.9F, 0.99F, 0.9F); + ApparatusRenderingHelper.drawFaces( + rb, block, block.iconArcaneFurnaceInside, false + ); + } + + rb.overrideBlockTexture = null; + rb.setRenderBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/metal/CrucibleApparatusRenderer.java b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/metal/CrucibleApparatusRenderer.java new file mode 100644 index 0000000..71154da --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/metal/CrucibleApparatusRenderer.java @@ -0,0 +1,186 @@ +package net.anvilcraft.thaummach.render.apparatus.apparati.metal; + +import net.anvilcraft.thaummach.blocks.BlockApparatusMetal; +import net.anvilcraft.thaummach.blocks.BlockApparatusMetal.MetaVals; +import net.anvilcraft.thaummach.render.apparatus.ApparatusRenderingHelper; +import net.anvilcraft.thaummach.render.apparatus.IApparatusRenderer; +import net.anvilcraft.thaummach.tiles.TileCrucible; +import net.minecraft.block.Block; +import net.minecraft.client.renderer.EntityRenderer; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; + +public class CrucibleApparatusRenderer implements IApparatusRenderer { + public static CrucibleApparatusRenderer INSTANCE = new CrucibleApparatusRenderer(); + + @Override + public void renderApparatus( + IBlockAccess w, + RenderBlocks rb, + int i, + int j, + int k, + Block block_, + int meta, + boolean inv + ) { + BlockApparatusMetal block = (BlockApparatusMetal) block_; + MetaVals md = MetaVals.get(meta); + IIcon[] icons = getIcons(block, md); + if (block.getRenderBlockPass() == 0 && !inv) { + rb.setRenderBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + rb.renderStandardBlock(block, i, j, k); + } else if (inv && + (md == MetaVals.NORMAL_CRUCIBLE + || md == MetaVals.EYES_CRUCIBLE + || md == MetaVals.THAUMIUM_CRUCIBLE) + ) { + rb.setRenderBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + ApparatusRenderingHelper.drawFaces( + rb, + block, + icons[3], + icons[6], + icons[5], + icons[5], + icons[5], + icons[5], + true + ); + } else if (inv && md == MetaVals.SOUL_CRUCIBLE) { + rb.setRenderBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + ApparatusRenderingHelper.drawFaces( + rb, + block, + block.iconSoulCrucibleBottom, + block.iconSoulCrucibleTopInv, + block.iconSoulCrucibleFace3, + block.iconSoulCrucibleFace3, + block.iconSoulCrucibleFace3, + block.iconSoulCrucibleFace3, + true + ); + } + + Tessellator tessellator = Tessellator.instance; + if (!inv) + tessellator.setBrightness(block.getMixedBrightnessForBlock(w, i, j, k)); + float f = 1.0F; + int l = block.colorMultiplier(w, i, j, k); + float f1 = (float) (l >> 16 & 255) / 255.0F; + float f2 = (float) (l >> 8 & 255) / 255.0F; + float f3 = (float) (l & 255) / 255.0F; + float f5; + if (EntityRenderer.anaglyphEnable) { + float f6 = (f1 * 30.0F + f2 * 59.0F + f3 * 11.0F) / 100.0F; + float f4 = (f1 * 30.0F + f2 * 70.0F) / 100.0F; + f5 = (f1 * 30.0F + f3 * 70.0F) / 100.0F; + f1 = f6; + f2 = f4; + f3 = f5; + } + + tessellator.setColorOpaque_F(f * f1, f * f2, f * f3); + IIcon c = md != MetaVals.SOUL_CRUCIBLE ? icons[2] : block.iconSoulCrucibleFace3; + IIcon c1 = md != MetaVals.SOUL_CRUCIBLE ? icons[1] : block.iconSoulCrucibleBottom; + + f5 = 0.123F; + if (!inv) { + if (block.getRenderBlockPass() == 0) { + rb.renderFaceXPos( + block, (double) ((float) i - 1.0F + f5), (double) j, (double) k, c + ); + rb.renderFaceXNeg( + block, (double) ((float) i + 1.0F - f5), (double) j, (double) k, c + ); + rb.renderFaceZPos( + block, (double) i, (double) j, (double) ((float) k - 1.0F + f5), c + ); + rb.renderFaceZNeg( + block, (double) i, (double) j, (double) ((float) k + 1.0F - f5), c + ); + rb.renderFaceYPos( + block, (double) i, (double) ((float) j - 1.0F + 0.25F), (double) k, + c1 + ); + rb.renderFaceYNeg( + block, (double) i, (double) ((float) j + 1.0F - 0.75F), (double) k, + c1 + ); + + } else if (block.getRenderBlockPass() == 1) { + TileCrucible tc = (TileCrucible) w.getTileEntity(i, j, k); + float tvis = tc.pureVis + tc.taintedVis; + if (tvis > 0.1F) { + float h = Math.min(tvis, tc.maxVis); + float level = 0.75F * (h / tc.maxVis); + if (tc.maxVis == tvis) { + level = (float) ((double) level - 0.001); + } + + float b = Math.min(1.0F, tc.pureVis / (tc.taintedVis + tc.pureVis)); + tessellator.setBrightness(20 + (int) (b * 210.0F)); + rb.renderFaceYPos( + block, + (double) i, + (double) ((float) j + 0.25F + level - 1.0F), + (double) k, + block.iconTcubeanim + ); + if (tvis > tc.maxVis) { + // TODO: WTF + //rb.renderSouthFace( + // block, + // (double) i, + // (double) j, + // (double) k, + // mod_ThaumCraft.visDripFX + //); + //rb.renderNorthFace( + // block, + // (double) i, + // (double) j, + // (double) k, + // mod_ThaumCraft.visDripFX + //); + //rb.renderWestFace( + // block, + // (double) i, + // (double) j, + // (double) k, + // mod_ThaumCraft.visDripFX + //); + //rb.renderEastFace( + // block, + // (double) i, + // (double) j, + // (double) k, + // mod_ThaumCraft.visDripFX + //); + } + } + } + } + + rb.overrideBlockTexture = null; + rb.setRenderBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + public static IIcon[] getIcons(BlockApparatusMetal block, MetaVals meta) { + switch (meta) { + case NORMAL_CRUCIBLE: + return block.iconsNormalCrucible; + + case EYES_CRUCIBLE: + return block.iconsEyesCrucible; + + case THAUMIUM_CRUCIBLE: + return block.iconsThaumiumCrucible; + + default: + return null; + } + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/metal/CrystallizerApparatusRenderer.java b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/metal/CrystallizerApparatusRenderer.java new file mode 100644 index 0000000..da8d8c5 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/metal/CrystallizerApparatusRenderer.java @@ -0,0 +1,89 @@ +package net.anvilcraft.thaummach.render.apparatus.apparati.metal; + +import net.anvilcraft.thaummach.blocks.BlockApparatusMetal; +import net.anvilcraft.thaummach.render.apparatus.ApparatusRenderingHelper; +import net.anvilcraft.thaummach.render.apparatus.IApparatusRenderer; +import net.minecraft.block.Block; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.world.IBlockAccess; + +public class CrystallizerApparatusRenderer implements IApparatusRenderer { + public static CrystallizerApparatusRenderer INSTANCE + = new CrystallizerApparatusRenderer(); + + @Override + public void renderApparatus( + IBlockAccess w, + RenderBlocks rb, + int i, + int j, + int k, + Block block_, + int meta, + boolean inv + ) { + BlockApparatusMetal block = (BlockApparatusMetal) block_; + float w2 = 0.125F; + if (block.getRenderBlockPass() == 0 || inv) { + rb.setRenderBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F + w2, 1.0F); + if (inv) { + ApparatusRenderingHelper.drawFaces( + rb, + block, + block.iconCrystallizerBottom, + block.iconCrystallizerTop, + block.iconCrystallizerSide, + block.iconCrystallizerSide, + block.iconCrystallizerSide, + block.iconCrystallizerSide, + true + ); + } else { + rb.renderStandardBlock(block, i, j, k); + } + + if (!inv) { + float w3 = 0.1875F; + rb.setRenderBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F + w2, 1.0F); + rb.renderFaceXPos( + block, + (double) ((float) (i - 1) + w3), + (double) j, + (double) k, + block.iconArcaneFurnaceInside + ); + rb.renderFaceXNeg( + block, + (double) ((float) (i + 1) - w3), + (double) j, + (double) k, + block.iconArcaneFurnaceInside + ); + rb.renderFaceZPos( + block, + (double) i, + (double) j, + (double) ((float) (k - 1) + w3), + block.iconArcaneFurnaceInside + ); + rb.renderFaceZNeg( + block, + (double) i, + (double) j, + (double) ((float) (k + 1) - w3), + block.iconArcaneFurnaceInside + ); + rb.renderFaceYPos( + block, + (double) i, + (double) ((float) j - 0.49F), + (double) k, + block.iconArcaneFurnaceInside + ); + } + } + + rb.overrideBlockTexture = null; + rb.setRenderBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/render/model/ModelPump.java b/src/main/java/net/anvilcraft/thaummach/render/model/ModelPump.java new file mode 100644 index 0000000..4d6ece2 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/render/model/ModelPump.java @@ -0,0 +1,72 @@ +package net.anvilcraft.thaummach.render.model; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; + +public class ModelPump extends ModelBase { + public ModelRenderer front; + public ModelRenderer moveBase; + public ModelRenderer moveFrill; + public ModelRenderer center; + public ModelRenderer back; + + public ModelPump() { + super.textureWidth = 128; + super.textureHeight = 64; + this.front = new ModelRenderer(this, 0, 0); + this.front.addBox(0.0F, 0.0F, 0.0F, 12, 6, 12); + this.front.setRotationPoint(-6.0F, 18.0F, -6.0F); + this.front.setTextureSize(128, 64); + this.front.mirror = true; + this.setRotation(this.front, 0.0F, 0.0F, 0.0F); + this.moveBase = new ModelRenderer(this, 0, 18); + this.moveBase.addBox(0.0F, 0.0F, 0.0F, 12, 2, 12); + this.moveBase.setRotationPoint(-6.0F, 8.0F, -6.0F); + this.moveBase.setTextureSize(128, 64); + this.moveBase.mirror = true; + this.setRotation(this.moveBase, 0.0F, 0.0F, 0.0F); + this.moveFrill = new ModelRenderer(this, 0, 32); + this.moveFrill.addBox(0.0F, 0.0F, 0.0F, 10, 4, 10); + this.moveFrill.setRotationPoint(-5.0F, 10.0F, -5.0F); + this.moveFrill.setTextureSize(128, 64); + this.moveFrill.mirror = true; + this.setRotation(this.moveFrill, 0.0F, 0.0F, 0.0F); + this.center = new ModelRenderer(this, 48, 0); + this.center.addBox(0.0F, 0.0F, 0.0F, 16, 4, 16); + this.center.setRotationPoint(-8.0F, 14.0F, -8.0F); + this.center.setTextureSize(128, 64); + this.center.mirror = true; + this.setRotation(this.center, 0.0F, 0.0F, 0.0F); + this.back = new ModelRenderer(this, 0, 46); + this.back.addBox(0.0F, 0.0F, 0.0F, 6, 6, 6); + this.back.setRotationPoint(-3.0F, 8.0F, -3.0F); + this.back.setTextureSize(128, 64); + this.back.mirror = true; + this.setRotation(this.back, 0.0F, 0.0F, 0.0F); + } + + @Override + public void + render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) { + super.render(entity, f, f1, f2, f3, f4, f5); + this.setRotationAngles(f, f1, f2, f3, f4, f5, entity); + this.front.render(f5); + this.moveBase.render(f5); + this.moveFrill.render(f5); + this.center.render(f5); + this.back.render(f5); + } + + public void render() { + this.front.render(0.0625F); + this.center.render(0.0625F); + this.back.render(0.0625F); + } + + private void setRotation(ModelRenderer model, float x, float y, float z) { + model.rotateAngleX = x; + model.rotateAngleY = y; + model.rotateAngleZ = z; + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/render/tile/TileConduitPumpRenderer.java b/src/main/java/net/anvilcraft/thaummach/render/tile/TileConduitPumpRenderer.java new file mode 100644 index 0000000..e5531e2 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/render/tile/TileConduitPumpRenderer.java @@ -0,0 +1,82 @@ +package net.anvilcraft.thaummach.render.tile; + +import net.anvilcraft.thaummach.render.model.ModelPump; +import net.anvilcraft.thaummach.tiles.TileConduitPump; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.opengl.GL11; + +public class TileConduitPumpRenderer extends TileEntitySpecialRenderer { + private ModelPump model = new ModelPump(); + + private void translateFromOrientation(double x, double y, double z, int orientation) { + GL11.glTranslatef((float) x + 0.5F, (float) y + 0.5F, (float) z + 0.5F); + if (orientation != 0) { + if (orientation == 1) { + GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F); + } else if (orientation == 2) { + GL11.glRotatef(90.0F, 1.0F, 0.0F, 0.0F); + } else if (orientation == 3) { + GL11.glRotatef(-90.0F, 1.0F, 0.0F, 0.0F); + } else if (orientation == 4) { + GL11.glRotatef(-90.0F, 0.0F, 0.0F, 1.0F); + } else if (orientation == 5) { + GL11.glRotatef(90.0F, 0.0F, 0.0F, 1.0F); + } + } + + GL11.glTranslatef(0.0F, -1.0F, 0.0F); + } + + public void + renderEntityAt(TileConduitPump pump, double x, double y, double z, float fq) { + int count = Minecraft.getMinecraft().thePlayer.ticksExisted; + float bob = 1.0F; + if (!pump.gettingPower()) { + bob = Math.abs(MathHelper.sin((float) count / 10.0F) * 1.0F); + } + + this.bindTexture( + new ResourceLocation("thaummach", "textures/models/conduit_pump.png") + ); + GL11.glEnable(2977); + GL11.glEnable(3042); + GL11.glPushMatrix(); + GL11.glEnable(32826); + GL11.glBlendFunc(770, 771); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + this.translateFromOrientation( + (double) ((float) x), + (double) ((float) y), + (double) ((float) z), + pump.orientation + ); + GL11.glPushMatrix(); + GL11.glPushMatrix(); + GL11.glTranslatef(0.0F, 0.251F - bob / 4.0F, 0.0F); + this.model.moveBase.render(0.0625F); + GL11.glPopMatrix(); + GL11.glTranslatef(0.0F, 0.875F, 0.0F); + GL11.glPushMatrix(); + GL11.glScalef(1.0F, bob, 1.0F); + this.model.moveFrill.setRotationPoint(-5.0F, 0.0F, -5.0F); + GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F); + this.model.moveFrill.render(0.0625F); + GL11.glScalef(1.0F, 1.0F, 1.0F); + GL11.glPopMatrix(); + GL11.glPopMatrix(); + this.model.render(); + GL11.glDisable(32826); + GL11.glPopMatrix(); + GL11.glDisable(3042); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + } + + public void + renderTileEntityAt(TileEntity tileentity, double d, double d1, double d2, float f) { + this.renderEntityAt((TileConduitPump) tileentity, d, d1, d2, f); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/tiles/TileArcaneFurnace.java b/src/main/java/net/anvilcraft/thaummach/tiles/TileArcaneFurnace.java new file mode 100644 index 0000000..383e72e --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/tiles/TileArcaneFurnace.java @@ -0,0 +1,490 @@ +package net.anvilcraft.thaummach.tiles; + +import java.util.stream.IntStream; + +import dev.tilera.auracore.api.machine.TileVisUser; +import dev.tilera.auracore.aura.AuraManager; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.FurnaceRecipes; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.tileentity.TileEntityFurnace; +import net.minecraft.world.EnumSkyBlock; +import net.minecraftforge.common.util.ForgeDirection; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; + +public class TileArcaneFurnace extends TileVisUser implements ISidedInventory { + private ItemStack[] furnaceItemStacks = new ItemStack[19]; + public int furnaceBurnTime = 0; + public int currentItemBurnTime = 0; + public int furnaceCookTime = 0; + public int furnaceMaxCookTime = 180; + public int bellows = 0; + public float vis; + public boolean boost; + + // TODO: GUIs + //public GuiScreen getGui(EntityPlayer player) { + // return new GuiArcaneFurnace(player.inventory, this); + //} + + @Override + public int getSizeInventory() { + return this.furnaceItemStacks.length; + } + + //@Override + //public int getStartInventorySide(int side) { + // if (side == 0) { + // return 18; + // } else { + // return side == 1 ? 0 : 9; + // } + //} + + //@Override + //public int getSizeInventorySide(int side) { + // return side == 0 ? 1 : 9; + //} + + @Override + public ItemStack getStackInSlot(int i) { + return this.furnaceItemStacks[i]; + } + + @Override + public ItemStack decrStackSize(int i, int j) { + if (this.furnaceItemStacks[i] != null) { + ItemStack itemstack1; + if (this.furnaceItemStacks[i].stackSize <= j) { + itemstack1 = this.furnaceItemStacks[i]; + this.furnaceItemStacks[i] = null; + return itemstack1; + } else { + itemstack1 = this.furnaceItemStacks[i].splitStack(j); + if (this.furnaceItemStacks[i].stackSize == 0) { + this.furnaceItemStacks[i] = null; + } + + return itemstack1; + } + } else { + return null; + } + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemstack) { + this.furnaceItemStacks[i] = itemstack; + if (itemstack != null && itemstack.stackSize > this.getInventoryStackLimit()) { + itemstack.stackSize = this.getInventoryStackLimit(); + } + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + NBTTagList nbttaglist = nbttagcompound.getTagList("Items", 10); + this.furnaceItemStacks = new ItemStack[this.getSizeInventory()]; + + for (int i = 0; i < nbttaglist.tagCount(); ++i) { + NBTTagCompound nbttagcompound1 + = (NBTTagCompound) nbttaglist.getCompoundTagAt(i); + byte byte0 = nbttagcompound1.getByte("Slot"); + if (byte0 >= 0 && byte0 < this.furnaceItemStacks.length) { + this.furnaceItemStacks[byte0] + = ItemStack.loadItemStackFromNBT(nbttagcompound1); + } + } + + this.furnaceBurnTime = nbttagcompound.getShort("BurnTime"); + this.currentItemBurnTime = nbttagcompound.getShort("MaxBurnTime"); + this.furnaceCookTime = nbttagcompound.getShort("CookTime"); + this.furnaceMaxCookTime = nbttagcompound.getShort("MaxCookTime"); + this.bellows = nbttagcompound.getShort("bellows"); + this.boost = nbttagcompound.getBoolean("boost"); + this.vis = nbttagcompound.getFloat("vis"); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + nbttagcompound.setShort("BurnTime", (short) this.furnaceBurnTime); + nbttagcompound.setShort("CookTime", (short) this.furnaceCookTime); + nbttagcompound.setShort("MaxBurnTime", (short) this.currentItemBurnTime); + nbttagcompound.setShort("MaxCookTime", (short) this.furnaceMaxCookTime); + nbttagcompound.setShort("bellows", (short) this.bellows); + nbttagcompound.setBoolean("boost", this.boost); + nbttagcompound.setFloat("vis", this.vis); + NBTTagList nbttaglist = new NBTTagList(); + + for (int i = 0; i < this.furnaceItemStacks.length; ++i) { + if (this.furnaceItemStacks[i] != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setByte("Slot", (byte) i); + this.furnaceItemStacks[i].writeToNBT(nbttagcompound1); + nbttaglist.appendTag(nbttagcompound1); + } + } + + nbttagcompound.setTag("Items", nbttaglist); + } + + @Override + public int getInventoryStackLimit() { + return 64; + } + + public int getCookProgressScaled(int i) { + return this.furnaceCookTime * i / this.furnaceMaxCookTime; + } + + public int getBurnTimeRemainingScaled(int i) { + int bt = this.currentItemBurnTime; + if (bt == 0) { + bt = 200; + } + + return this.furnaceBurnTime * i / bt; + } + + public boolean isBurning() { + return this.furnaceBurnTime > 0 + //&& !super.worldObj.isBlockGettingPowered( + // super.xCoord, super.yCoord, super.zCoord + //) + && !super.worldObj.isBlockIndirectlyGettingPowered( + super.xCoord, super.yCoord, super.zCoord + ); + } + + public boolean isWorking() { + return this.furnaceBurnTime > 0 + && (this.furnaceCookTime > 0 || this.belowHeatableTile()) + //&& !super.worldObj.isBlockGettingPowered( + // super.xCoord, super.yCoord, super.zCoord + //) + && !super.worldObj.isBlockIndirectlyGettingPowered( + super.xCoord, super.yCoord, super.zCoord + ); + } + + public boolean belowHeatableTile() { + TileEntity te + = super.worldObj.getTileEntity(super.xCoord, super.yCoord + 1, super.zCoord); + return te != null && te instanceof TileCrucible; + } + + @Override + public void updateEntity() { + boolean flag = this.furnaceBurnTime > 0; + boolean flag1 = false; + this.setSuction(0); + if (!super.worldObj.isRemote && this.vis < this.getMaxVis()) { + this.vis += this.getAvailablePureVis(this.getMaxVis() - this.vis); + } + + if (!super.worldObj.isRemote + //&& !super.worldObj.isBlockGettingPowered( + // super.xCoord, super.yCoord, super.zCoord + //) + && !super.worldObj.isBlockIndirectlyGettingPowered( + super.xCoord, super.yCoord, super.zCoord + )) { + if (this.furnaceBurnTime > 0 + && (this.furnaceCookTime > 0 || this.belowHeatableTile())) { + --this.furnaceBurnTime; + } + + if (this.furnaceBurnTime <= 0 + && (this.canSmelt() || this.belowHeatableTile())) { + this.currentItemBurnTime = this.furnaceBurnTime + = getItemBurnTime(this.furnaceItemStacks[18]); + if (this.furnaceBurnTime > 0) { + if (this.vis >= (float) this.currentItemBurnTime / 1600.0F) { + this.vis -= (float) this.currentItemBurnTime / 1600.0F; + this.currentItemBurnTime + = (int) ((float) this.currentItemBurnTime * 1.25F); + this.furnaceBurnTime + = (int) ((float) this.furnaceBurnTime * 1.25F); + } + + flag1 = true; + if (this.furnaceItemStacks[18] != null) { + if (this.vis >= 0.25F) { + this.vis -= 0.25F; + this.furnaceMaxCookTime = 100; + this.boost = true; + } else { + this.furnaceMaxCookTime = 180; + this.boost = false; + } + + this.furnaceMaxCookTime = (int + ) ((float) this.furnaceMaxCookTime + * (1.0F - (float) this.bellows * 0.1F)); + this.worldObj.markBlockForUpdate( + this.xCoord, this.yCoord, this.zCoord + ); + super.worldObj.updateLightByType( + EnumSkyBlock.Block, super.xCoord, super.yCoord, super.zCoord + ); + // TODO: WTF + //if (this.furnaceItemStacks[18].getItem().func_46056_k()) { + // this.furnaceItemStacks[18] = new ItemStack( + // this.furnaceItemStacks[18].getItem().setFull3D() + // ); + //} else { + --this.furnaceItemStacks[18].stackSize; + //} + + if (this.furnaceItemStacks[18].stackSize == 0) { + this.furnaceItemStacks[18] = null; + } + } + } + } + + if (this.isBurning() && this.canSmelt()) { + ++this.furnaceCookTime; + if (this.furnaceCookTime >= this.furnaceMaxCookTime) { + this.furnaceCookTime = 0; + if (this.vis >= 0.25F) { + this.vis -= 0.25F; + this.furnaceMaxCookTime = 100; + this.boost = true; + } else { + this.furnaceMaxCookTime = 180; + this.boost = false; + } + + this.furnaceMaxCookTime = (int + ) ((float) this.furnaceMaxCookTime + * (1.0F - (float) this.bellows * 0.2F)); + this.smeltItem(); + this.worldObj.markBlockForUpdate( + this.xCoord, this.yCoord, this.zCoord + ); + super.worldObj.updateLightByType( + EnumSkyBlock.Block, super.xCoord, super.yCoord, super.zCoord + ); + flag1 = true; + } + } else { + this.furnaceCookTime = 0; + } + + if (flag != this.furnaceBurnTime > 0) { + flag1 = true; + } + } + + if (flag1) { + // TODO: WTF + //this.onInventoryChanged(); + } + } + + private boolean canSmelt(int slotIn, int slotOut) { + if (this.furnaceItemStacks[slotIn] == null) { + return false; + } else { + ItemStack itemstack = FurnaceRecipes.smelting().getSmeltingResult( + this.furnaceItemStacks[slotIn] + ); + if (itemstack == null) { + return false; + } else if (this.furnaceItemStacks[slotOut] == null) { + return true; + } else if (!this.furnaceItemStacks[slotOut].isItemEqual(itemstack)) { + return false; + } else { + int result + = this.furnaceItemStacks[slotOut].stackSize + itemstack.stackSize; + return result <= this.getInventoryStackLimit() + && result <= itemstack.getMaxStackSize(); + } + } + } + + private boolean canSmelt() { + for (int input = 9; input < 18; ++input) { + for (int output = 0; output < 9; ++output) { + if (this.canSmelt(input, output)) { + return true; + } + } + } + + return false; + } + + public void smeltItem() { + for (int input = 9; input < 18; ++input) { + for (int output = 0; output < 9; ++output) { + boolean smelted = false; + + boolean tryAgain; + do { + tryAgain = false; + if (this.canSmelt(input, output)) { + ItemStack itemstack = FurnaceRecipes.smelting().getSmeltingResult( + this.furnaceItemStacks[input] + ); + if (this.furnaceItemStacks[output] != null + && this.furnaceItemStacks[output].isItemEqual(itemstack) + && this.furnaceItemStacks[output].getItemDamage() + == itemstack.getItemDamage()) { + ItemStack var10000 = this.furnaceItemStacks[output]; + var10000.stackSize += itemstack.stackSize; + smelted = true; + } else if (this.furnaceItemStacks[output] == null) { + this.furnaceItemStacks[output] = itemstack.copy(); + smelted = true; + } + + if (smelted + && super.worldObj.rand.nextInt(90) < 5 + this.bellows * 7 + && this.vis >= 0.5F) { + this.vis -= 0.5F; + tryAgain = true; + AuraManager.addFluxToClosest( + this.worldObj, + this.xCoord, + this.yCoord, + this.zCoord, + new AspectList().add(Aspect.FIRE, 2) + ); + } + } + } while (tryAgain); + + if (smelted) { + // TODO: WTF + //if (this.furnaceItemStacks[input].getItem().func_46056_k()) { + // this.furnaceItemStacks[input] = new ItemStack( + // this.furnaceItemStacks[input].getItem().setFull3D() + // ); + //} else { + --this.furnaceItemStacks[input].stackSize; + //} + + if (this.furnaceItemStacks[input].stackSize <= 0) { + this.furnaceItemStacks[input] = null; + } + + return; + } + } + } + } + + public static int getItemBurnTime(ItemStack par1ItemStack) { + return TileEntityFurnace.getItemBurnTime(par1ItemStack); + } + + @Override + public boolean isUseableByPlayer(EntityPlayer entityplayer) { + if (super.worldObj.getTileEntity(super.xCoord, super.yCoord, super.zCoord) + != this) { + return false; + } else { + return entityplayer.getDistanceSq( + (double) super.xCoord + 0.5, + (double) super.yCoord + 0.5, + (double) super.zCoord + 0.5 + ) + <= 64.0; + } + } + + @Override + public boolean getConnectable(ForgeDirection face) { + switch (face) { + case DOWN: + case EAST: + case SOUTH: + case WEST: + case NORTH: + return true; + + default: + return false; + } + } + + @Override + public ItemStack getStackInSlotOnClosing(int var1) { + if (this.furnaceItemStacks[var1] != null) { + ItemStack var2 = this.furnaceItemStacks[var1]; + this.furnaceItemStacks[var1] = null; + return var2; + } else { + return null; + } + } + + @Override + public float getPureVis() { + return this.vis; + } + + @Override + public float getMaxVis() { + return 5.0F; + } + + @Override + public String getInventoryName() { + return "thaummach:arcane_furnace"; + } + + @Override + public boolean hasCustomInventoryName() { + return false; + } + + @Override + public void openInventory() {} + + @Override + public void closeInventory() {} + + @Override + public boolean isItemValidForSlot(int slot, ItemStack is) { + if (slot >= 9 && slot <= 17) + return false; + + if (slot == 18) + return getItemBurnTime(is) > 0; + + return true; + } + + @Override + public int[] getAccessibleSlotsFromSide(int side) { + if (side == 0) + return new int[] { 18 }; + + if (side == 1) + return IntStream.rangeClosed(0, 8).toArray(); + + return IntStream.rangeClosed(9, 17).toArray(); + } + + @Override + public boolean + canInsertItem(int slot, ItemStack is, int side) { + return this.isItemValidForSlot(slot, is); + } + + @Override + public boolean + canExtractItem(int slot, ItemStack is, int side) { + return slot >= 9 && slot <= 17; + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/tiles/TileConduit.java b/src/main/java/net/anvilcraft/thaummach/tiles/TileConduit.java index 29bbfe9..32d5375 100644 --- a/src/main/java/net/anvilcraft/thaummach/tiles/TileConduit.java +++ b/src/main/java/net/anvilcraft/thaummach/tiles/TileConduit.java @@ -3,250 +3,280 @@ package net.anvilcraft.thaummach.tiles; import dev.tilera.auracore.api.HelperLocation; import dev.tilera.auracore.api.machine.IConnection; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.Packet; +import net.minecraft.network.play.server.S35PacketUpdateTileEntity; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.MathHelper; import net.minecraftforge.common.util.ForgeDirection; public class TileConduit extends TileEntity implements IConnection { - public float pureVis = 0.0F; - public float taintedVis = 0.0F; - public float maxVis = 4.0F; - float fillAmount = 4.0F; - public float displayPure; - public float displayTaint; - public float prevdisplayPure; - public float prevdisplayTaint; - public int visSuction = 0; - public int taintSuction = 0; + public float pureVis = 0.0F; + public float taintedVis = 0.0F; + public float maxVis = 4.0F; + float fillAmount = 4.0F; + public float prevPure; + public float prevTaint; + public int visSuction = 0; + public int taintSuction = 0; - @Override - public void updateEntity() { - if (!super.worldObj.isRemote) { - if (this.prevdisplayPure != this.displayPure || this.prevdisplayTaint != this.displayTaint) { - super.worldObj.markBlockForUpdate(super.xCoord, super.yCoord, super.zCoord); - this.prevdisplayPure = this.displayPure; - this.prevdisplayTaint = this.displayTaint; - } - - this.calculateSuction(); - if (this.getSuction((HelperLocation)null) > 0) { - this.equalizeWithNeighbours(); - } - - this.displayTaint = Math.max(this.displayTaint, MathHelper.clamp_float(this.taintedVis, 0.0F, this.maxVis)); - this.displayPure = Math.max(this.displayPure, MathHelper.clamp_float(this.pureVis, 0.0F, this.maxVis)); - if (this.displayTaint + this.displayPure < 0.1F) { - this.displayTaint = 0.0F; - this.displayPure = 0.0F; - } - - } - } - - protected void calculateSuction() { - this.setSuction(0); - - for(int dir = 0; dir < 6; ++dir) { - HelperLocation loc = new HelperLocation(this); - switch (dir) { - case 0: - loc.facing = ForgeDirection.UP; - break; - case 1: - loc.facing = ForgeDirection.DOWN; - break; - case 2: - loc.facing = ForgeDirection.SOUTH; - break; - case 3: - loc.facing = ForgeDirection.NORTH; - break; - case 4: - loc.facing = ForgeDirection.EAST; - break; - case 5: - loc.facing = ForgeDirection.WEST; - } - - if (this.getConnectable(loc.facing)) { - TileEntity te = loc.getConnectableTile(super.worldObj); - if (te != null && te instanceof IConnection) { - IConnection ic = (IConnection)te; - if (this.getVisSuction((HelperLocation)null) < ic.getVisSuction(new HelperLocation(this)) - 1) { - this.setVisSuction(ic.getVisSuction(new HelperLocation(this)) - 1); - } - - if (this.getTaintSuction((HelperLocation)null) < ic.getTaintSuction(new HelperLocation(this)) - 1) { - this.setTaintSuction(ic.getTaintSuction(new HelperLocation(this)) - 1); - } + @Override + public void updateEntity() { + if (!super.worldObj.isRemote) { + this.calculateSuction(); + if (this.getSuction(null) > 0) { + this.equalizeWithNeighbours(); } - } - } - - } - - protected void equalizeWithNeighbours() { - for(int dir = 0; dir < 6; ++dir) { - HelperLocation loc = new HelperLocation(this); - switch (dir) { - case 0: - loc.facing = ForgeDirection.UP; - break; - case 1: - loc.facing = ForgeDirection.DOWN; - break; - case 2: - loc.facing = ForgeDirection.SOUTH; - break; - case 3: - loc.facing = ForgeDirection.NORTH; - break; - case 4: - loc.facing = ForgeDirection.EAST; - break; - case 5: - loc.facing = ForgeDirection.WEST; - } - - if (this.getConnectable(loc.facing)) { - TileEntity te = loc.getConnectableTile(super.worldObj); - if (te != null && te instanceof IConnection) { - IConnection ent = (IConnection)te; - if (this.pureVis + this.taintedVis < this.maxVis && (this.getVisSuction((HelperLocation)null) > ent.getVisSuction(new HelperLocation(this)) || this.getTaintSuction((HelperLocation)null) > ent.getTaintSuction(new HelperLocation(this)))) { - float qq = Math.min((ent.getPureVis() + ent.getTaintedVis()) / 4.0F, this.fillAmount); - float[] results = ent.subtractVis(Math.min(qq, this.maxVis - (this.pureVis + this.taintedVis))); - if (this.getVisSuction((HelperLocation)null) > ent.getVisSuction(new HelperLocation(this))) { - this.pureVis += results[0]; - } else { - ent.setPureVis(results[0] + ent.getPureVis()); - } - - if (this.getTaintSuction((HelperLocation)null) > ent.getTaintSuction(new HelperLocation(this))) { - this.taintedVis += results[1]; - } else { - ent.setTaintedVis(results[1] + ent.getTaintedVis()); - } - } + if (this.prevPure != this.pureVis || this.prevTaint != this.taintedVis) { + super.worldObj.markBlockForUpdate( + super.xCoord, super.yCoord, super.zCoord + ); + this.prevPure = this.pureVis; + this.prevTaint = this.taintedVis; } - } - } + } + } - this.pureVis = MathHelper.clamp_float(this.pureVis, 0.0F, this.maxVis); - this.taintedVis = MathHelper.clamp_float(this.taintedVis, 0.0F, this.maxVis); - } + protected void calculateSuction() { + this.setSuction(0); - @Override - public void readFromNBT(NBTTagCompound nbttagcompound) { - super.readFromNBT(nbttagcompound); - this.pureVis = nbttagcompound.getFloat("pureVis"); - this.taintedVis = nbttagcompound.getFloat("taintedVis"); - } + for (int dir = 0; dir < 6; ++dir) { + HelperLocation loc = new HelperLocation(this); + switch (dir) { + case 0: + loc.facing = ForgeDirection.UP; + break; + case 1: + loc.facing = ForgeDirection.DOWN; + break; + case 2: + loc.facing = ForgeDirection.SOUTH; + break; + case 3: + loc.facing = ForgeDirection.NORTH; + break; + case 4: + loc.facing = ForgeDirection.EAST; + break; + case 5: + loc.facing = ForgeDirection.WEST; + } - @Override - public void writeToNBT(NBTTagCompound nbttagcompound) { - super.writeToNBT(nbttagcompound); - nbttagcompound.setFloat("pureVis", this.pureVis); - nbttagcompound.setFloat("taintedVis", this.taintedVis); - } + if (this.getConnectable(loc.facing)) { + TileEntity te = loc.getConnectableTile(super.worldObj); + if (te != null && te instanceof IConnection) { + IConnection ic = (IConnection) te; + if (this.getVisSuction((HelperLocation) null) + < ic.getVisSuction(new HelperLocation(this)) - 1) { + this.setVisSuction( + ic.getVisSuction(new HelperLocation(this)) - 1 + ); + } - @Override - public boolean getConnectable(ForgeDirection face) { - return true; - } + if (this.getTaintSuction((HelperLocation) null) + < ic.getTaintSuction(new HelperLocation(this)) - 1) { + this.setTaintSuction( + ic.getTaintSuction(new HelperLocation(this)) - 1 + ); + } + } + } + } + } - @Override - public boolean isVisSource() { - return false; - } + protected void equalizeWithNeighbours() { + for (int dir = 0; dir < 6; ++dir) { + HelperLocation loc = new HelperLocation(this); + switch (dir) { + case 0: + loc.facing = ForgeDirection.UP; + break; + case 1: + loc.facing = ForgeDirection.DOWN; + break; + case 2: + loc.facing = ForgeDirection.SOUTH; + break; + case 3: + loc.facing = ForgeDirection.NORTH; + break; + case 4: + loc.facing = ForgeDirection.EAST; + break; + case 5: + loc.facing = ForgeDirection.WEST; + } - @Override - public boolean isVisConduit() { - return true; - } + if (this.getConnectable(loc.facing)) { + TileEntity te = loc.getConnectableTile(super.worldObj); + if (te != null && te instanceof IConnection) { + IConnection ent = (IConnection) te; + if (this.pureVis + this.taintedVis < this.maxVis + && (this.getVisSuction((HelperLocation) null) + > ent.getVisSuction(new HelperLocation(this)) + || this.getTaintSuction((HelperLocation) null) + > ent.getTaintSuction(new HelperLocation(this)))) { + float qq = Math.min( + (ent.getPureVis() + ent.getTaintedVis()) / 4.0F, + this.fillAmount + ); + float[] results = ent.subtractVis( + Math.min(qq, this.maxVis - (this.pureVis + this.taintedVis)) + ); + if (this.getVisSuction((HelperLocation) null) + > ent.getVisSuction(new HelperLocation(this))) { + this.pureVis += results[0]; + } else { + ent.setPureVis(results[0] + ent.getPureVis()); + } - @Override - public float getPureVis() { - return this.pureVis; - } + if (this.getTaintSuction((HelperLocation) null) + > ent.getTaintSuction(new HelperLocation(this))) { + this.taintedVis += results[1]; + } else { + ent.setTaintedVis(results[1] + ent.getTaintedVis()); + } + } + } + } + } - @Override - public void setPureVis(float amount) { - this.pureVis = amount; - } + this.pureVis = MathHelper.clamp_float(this.pureVis, 0.0F, this.maxVis); + this.taintedVis = MathHelper.clamp_float(this.taintedVis, 0.0F, this.maxVis); + } - @Override - public float getTaintedVis() { - return this.taintedVis; - } + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + this.pureVis = nbttagcompound.getFloat("pureVis"); + this.taintedVis = nbttagcompound.getFloat("taintedVis"); + } - @Override - public void setTaintedVis(float amount) { - this.taintedVis = amount; - } + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + nbttagcompound.setFloat("pureVis", this.pureVis); + nbttagcompound.setFloat("taintedVis", this.taintedVis); + } - @Override - public float getMaxVis() { - return this.maxVis; - } + @Override + public Packet getDescriptionPacket() { + NBTTagCompound nbt = new NBTTagCompound(); - @Override - public float[] subtractVis(float amount) { - float pureAmount = amount / 2.0F; - float taintAmount = amount / 2.0F; - float[] result = new float[]{0.0F, 0.0F}; - if (amount < 0.001F) { - return result; - } else { - if (this.pureVis < pureAmount) { - pureAmount = this.pureVis; - } + nbt.setFloat("pureVis", this.pureVis); + nbt.setFloat("taintedVis", this.taintedVis); - if (this.taintedVis < taintAmount) { - taintAmount = this.taintedVis; - } + return new S35PacketUpdateTileEntity( + this.xCoord, this.yCoord, this.zCoord, this.getBlockMetadata(), nbt + ); + } - if (pureAmount < amount / 2.0F && taintAmount == amount / 2.0F) { - taintAmount = Math.min(amount - pureAmount, this.taintedVis); - } else if (taintAmount < amount / 2.0F && pureAmount == amount / 2.0F) { - pureAmount = Math.min(amount - taintAmount, this.pureVis); - } + @Override + public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { + NBTTagCompound nbt = pkt.func_148857_g(); - this.pureVis -= pureAmount; - this.taintedVis -= taintAmount; - result[0] = pureAmount; - result[1] = taintAmount; - return result; - } - } + this.pureVis = nbt.getFloat("pureVis"); + this.taintedVis = nbt.getFloat("taintedVis"); + } - @Override - public int getVisSuction(HelperLocation loc) { - return this.visSuction; - } + @Override + public boolean getConnectable(ForgeDirection face) { + return true; + } - @Override - public void setVisSuction(int suction) { - this.visSuction = suction; - } + @Override + public boolean isVisSource() { + return false; + } - @Override - public int getTaintSuction(HelperLocation loc) { - return this.taintSuction; - } + @Override + public boolean isVisConduit() { + return true; + } - @Override - public void setTaintSuction(int suction) { - this.taintSuction = suction; - } + @Override + public float getPureVis() { + return this.pureVis; + } - @Override - public void setSuction(int suction) { - this.visSuction = suction; - this.taintSuction = suction; - } + @Override + public void setPureVis(float amount) { + this.pureVis = amount; + } - @Override - public int getSuction(HelperLocation loc) { - return Math.max(this.visSuction, this.taintSuction); - } + @Override + public float getTaintedVis() { + return this.taintedVis; + } + + @Override + public void setTaintedVis(float amount) { + this.taintedVis = amount; + } + + @Override + public float getMaxVis() { + return this.maxVis; + } + + @Override + public float[] subtractVis(float amount) { + float pureAmount = amount / 2.0F; + float taintAmount = amount / 2.0F; + float[] result = new float[] { 0.0F, 0.0F }; + if (amount < 0.001F) { + return result; + } else { + if (this.pureVis < pureAmount) { + pureAmount = this.pureVis; + } + + if (this.taintedVis < taintAmount) { + taintAmount = this.taintedVis; + } + + if (pureAmount < amount / 2.0F && taintAmount == amount / 2.0F) { + taintAmount = Math.min(amount - pureAmount, this.taintedVis); + } else if (taintAmount < amount / 2.0F && pureAmount == amount / 2.0F) { + pureAmount = Math.min(amount - taintAmount, this.pureVis); + } + + this.pureVis -= pureAmount; + this.taintedVis -= taintAmount; + result[0] = pureAmount; + result[1] = taintAmount; + return result; + } + } + + @Override + public int getVisSuction(HelperLocation loc) { + return this.visSuction; + } + + @Override + public void setVisSuction(int suction) { + this.visSuction = suction; + } + + @Override + public int getTaintSuction(HelperLocation loc) { + return this.taintSuction; + } + + @Override + public void setTaintSuction(int suction) { + this.taintSuction = suction; + } + + @Override + public void setSuction(int suction) { + this.visSuction = suction; + this.taintSuction = suction; + } + + @Override + public int getSuction(HelperLocation loc) { + return Math.max(this.visSuction, this.taintSuction); + } } diff --git a/src/main/java/net/anvilcraft/thaummach/tiles/TileConduitPump.java b/src/main/java/net/anvilcraft/thaummach/tiles/TileConduitPump.java new file mode 100644 index 0000000..2b9ad09 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/tiles/TileConduitPump.java @@ -0,0 +1,209 @@ +package net.anvilcraft.thaummach.tiles; + +import dev.tilera.auracore.api.HelperLocation; +import dev.tilera.auracore.api.machine.IConnection; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.common.util.ForgeDirection; +import thaumcraft.common.tiles.TileBellows; + +public class TileConduitPump extends TileEntity implements IConnection { + public float pureVis = 0.0F; + public float taintedVis = 0.0F; + public float maxVis = 4.0F; + float fillAmount = 1.0F; + public int orientation = 0; + + @Override + public void updateEntity() { + if (!super.worldObj.isRemote) { + if (!this.gettingPower()) { + if (this.pureVis + this.taintedVis < this.maxVis) { + HelperLocation me = new HelperLocation(this, this.orientation); + TileEntity te = me.getConnectableTile(super.worldObj); + if (te != null + && (((IConnection) te).isVisConduit() + || ((IConnection) te).isVisSource())) { + float suckamount = Math.min( + this.fillAmount, + this.maxVis - (this.pureVis + this.taintedVis) + ); + float[] yum = ((IConnection) te).subtractVis(suckamount); + this.pureVis += yum[0]; + this.taintedVis += yum[1]; + } + } + } + } + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + this.pureVis = nbttagcompound.getFloat("pureVis"); + this.taintedVis = nbttagcompound.getFloat("taintedVis"); + this.orientation = nbttagcompound.getShort("orientation"); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + nbttagcompound.setFloat("pureVis", this.pureVis); + nbttagcompound.setFloat("taintedVis", this.taintedVis); + nbttagcompound.setShort("orientation", (short) this.orientation); + } + + @Override + public boolean getConnectable(ForgeDirection face) { + if (this.orientation != 4 && this.orientation != 5 + || face != ForgeDirection.EAST && face != ForgeDirection.WEST) { + if (this.orientation != 2 && this.orientation != 3 + || face != ForgeDirection.SOUTH && face != ForgeDirection.NORTH) { + return (this.orientation == 0 || this.orientation == 1) + && (face == ForgeDirection.UP || face == ForgeDirection.DOWN); + } else { + return true; + } + } else { + return true; + } + } + + @Override + public boolean isVisSource() { + return true; + } + + @Override + public boolean isVisConduit() { + return false; + } + + @Override + public float getPureVis() { + return this.pureVis; + } + + @Override + public void setPureVis(float amount) { + this.pureVis = amount; + } + + @Override + public float getTaintedVis() { + return this.taintedVis; + } + + @Override + public void setTaintedVis(float amount) { + this.taintedVis = amount; + } + + @Override + public float getMaxVis() { + return this.maxVis; + } + + @Override + public float[] subtractVis(float amount) { + float pureAmount = amount / 2.0F; + float taintAmount = amount / 2.0F; + float[] result = new float[] { 0.0F, 0.0F }; + if (amount < 0.001F) { + return result; + } else { + if (this.pureVis < pureAmount) { + pureAmount = this.pureVis; + } + + if (this.taintedVis < taintAmount) { + taintAmount = this.taintedVis; + } + + if (pureAmount < amount / 2.0F && taintAmount == amount / 2.0F) { + taintAmount = Math.min(amount - pureAmount, this.taintedVis); + } else if (taintAmount < amount / 2.0F && pureAmount == amount / 2.0F) { + pureAmount = Math.min(amount - taintAmount, this.pureVis); + } + + this.pureVis -= pureAmount; + this.taintedVis -= taintAmount; + result[0] = pureAmount; + result[1] = taintAmount; + return result; + } + } + + @Override + public int getVisSuction(HelperLocation loc) { + return this.getSuction(loc); + } + + @Override + public void setVisSuction(int suction) {} + + @Override + public int getTaintSuction(HelperLocation loc) { + return this.getSuction(loc); + } + + @Override + public void setTaintSuction(int suction) {} + + @Override + public void setSuction(int suction) {} + + @Override + public int getSuction(HelperLocation loc) { + if (loc == null) { + loc = new HelperLocation(this, this.orientation); + loc.moveForwards(1.0); + } + + if (this.gettingPower()) { + return 0; + } else { + int bellows = 0; + + TileBellows.getBellows( + this.worldObj, + this.xCoord, + this.yCoord, + this.zCoord, + new ForgeDirection[] { ForgeDirection.NORTH, + ForgeDirection.EAST, + ForgeDirection.SOUTH, + ForgeDirection.WEST } + ); + + HelperLocation me = new HelperLocation(this, this.orientation); + me.moveForwards(1.0); + if (loc.equals(me)) { + return 20 + bellows * 10; + } else { + return 0; + } + } + } + + // TODO: IRotatable? + //@Override + public boolean rotate() { + ++this.orientation; + if (this.orientation > 5) { + this.orientation -= 6; + } + + return true; + } + + public boolean gettingPower() { + return /*super.worldObj.isBlockGettingPowered( + super.xCoord, super.yCoord, super.zCoord + ) + || */ + super.worldObj.isBlockIndirectlyGettingPowered( + super.xCoord, super.yCoord, super.zCoord + ); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/tiles/TileConduitTank.java b/src/main/java/net/anvilcraft/thaummach/tiles/TileConduitTank.java index ea1dce8..efdad28 100644 --- a/src/main/java/net/anvilcraft/thaummach/tiles/TileConduitTank.java +++ b/src/main/java/net/anvilcraft/thaummach/tiles/TileConduitTank.java @@ -5,251 +5,324 @@ import dev.tilera.auracore.api.machine.IConnection; import net.anvilcraft.thaummach.AuraUtils; import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.Packet; +import net.minecraft.network.play.server.S35PacketUpdateTileEntity; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.MathHelper; import net.minecraftforge.common.util.ForgeDirection; import thaumcraft.common.tiles.TileBellows; public class TileConduitTank extends TileEntity implements IConnection { - public float pureVis = 0.0F; - public float taintedVis = 0.0F; - float fillAmount = 1.0F; - int wait; - public float displayPure; - public float displayTaint; - public float prevdisplayPure; - public float prevdisplayTaint; - public int visSuction = 10; - public int taintSuction = 10; + public float pureVis = 0.0F; + public float taintedVis = 0.0F; + float fillAmount = 1.0F; + int wait; + public float displayPure; + public float displayTaint; + public float prevdisplayPure; + public float prevdisplayTaint; + public int visSuction = 10; + public int taintSuction = 10; - public void updateEntity() { - if (!super.worldObj.isRemote) { - --this.wait; - if (this.wait <= 0) { - if (this.prevdisplayPure != this.displayPure || this.prevdisplayTaint != this.displayTaint) { - super.worldObj.markBlockForUpdate(super.xCoord, super.yCoord, super.zCoord); - this.prevdisplayPure = this.displayPure; - this.prevdisplayTaint = this.displayTaint; + public void updateEntity() { + if (!super.worldObj.isRemote) { + --this.wait; + if (this.wait <= 0) { + if (this.prevdisplayPure != this.displayPure + || this.prevdisplayTaint != this.displayTaint) { + super.worldObj.markBlockForUpdate( + super.xCoord, super.yCoord, super.zCoord + ); + this.prevdisplayPure = this.displayPure; + this.prevdisplayTaint = this.displayTaint; + } + + this.wait = 10; + this.calculateSuction(); + int breakchance = 999; + if (this.getBlockMetadata() != 3) { + breakchance = 3333; + } + + if (this.taintedVis > this.getMaxVis() * 0.9F) { + if (this.getBlockMetadata() == 3 + && super.worldObj.rand.nextInt(breakchance) == 123) { + AuraUtils.taintExplosion( + super.worldObj, super.xCoord, super.yCoord, super.zCoord + ); + super.worldObj.setBlock( + super.xCoord, super.yCoord, super.zCoord, Blocks.air, 0, 3 + ); + } else if (super.worldObj.rand.nextInt(breakchance / 8) == 42) { + super.worldObj.playSoundEffect( + (double) ((float) super.xCoord + 0.5F), + (double) ((float) super.yCoord + 0.5F), + (double) ((float) super.zCoord + 0.5F), + "thaumcraft.creaking", + 0.75F, + 1.0F + ); + } + } } - this.wait = 10; - this.calculateSuction(); - int breakchance = 999; - if (this.getBlockMetadata() != 3) { - breakchance = 3333; + this.equalizeWithNeighbours(); + this.displayTaint = Math.max( + this.displayTaint, + MathHelper.clamp_float(this.taintedVis, 0.0F, this.getMaxVis()) + ); + this.displayPure = Math.max( + this.displayPure, + MathHelper.clamp_float(this.pureVis, 0.0F, this.getMaxVis()) + ); + if (this.displayTaint + this.displayPure < 0.1F) { + this.displayTaint = 0.0F; + this.displayPure = 0.0F; + } + } + } + + public void calculateSuction() { + this.setSuction(10); + + int bellows = TileBellows.getBellows( + this.worldObj, + this.xCoord, + this.yCoord, + this.zCoord, + new ForgeDirection[] { ForgeDirection.NORTH, + ForgeDirection.SOUTH, + ForgeDirection.WEST, + ForgeDirection.EAST } + ); + if (bellows > 0) + this.setSuction(this.getSuction((HelperLocation) null) + (10 * bellows)); + } + + protected void equalizeWithNeighbours() { + float stackpureVis = this.pureVis; + float stacktaintedVis = this.taintedVis; + float stackmaxVis = this.getMaxVis(); + + TileEntity ts; + int count; + for (count = 1; (ts = super.worldObj.getTileEntity( + super.xCoord, super.yCoord + count, super.zCoord + )) instanceof TileConduitTank; + ++count) { + stackpureVis += ((TileConduitTank) ts).pureVis; + stacktaintedVis += ((TileConduitTank) ts).taintedVis; + stackmaxVis += ((TileConduitTank) ts).getMaxVis(); + } + + for (int dir = 0; dir < 6; ++dir) { + HelperLocation loc = new HelperLocation(this); + switch (dir) { + case 0: + loc.facing = ForgeDirection.UP; + break; + case 1: + loc.facing = ForgeDirection.DOWN; + break; + case 2: + loc.facing = ForgeDirection.SOUTH; + break; + case 3: + loc.facing = ForgeDirection.NORTH; + break; + case 4: + loc.facing = ForgeDirection.EAST; + break; + case 5: + loc.facing = ForgeDirection.WEST; } - if (this.taintedVis > this.getMaxVis() * 0.9F) { - if (this.getBlockMetadata() == 3 && super.worldObj.rand.nextInt(breakchance) == 123) { - AuraUtils.taintExplosion(super.worldObj, super.xCoord, super.yCoord, super.zCoord); - super.worldObj.setBlock(super.xCoord, super.yCoord, super.zCoord, Blocks.air, 0, 3); - } else if (super.worldObj.rand.nextInt(breakchance / 8) == 42) { - super.worldObj.playSoundEffect((double)((float)super.xCoord + 0.5F), (double)((float)super.yCoord + 0.5F), (double)((float)super.zCoord + 0.5F), "thaumcraft.creaking", 0.75F, 1.0F); - } + if (this.getConnectable(loc.facing)) { + TileEntity te = loc.getConnectableTile(super.worldObj); + if (te != null && te instanceof IConnection) { + IConnection ent = (IConnection) te; + if (!(te instanceof TileConduitTank) + && stackpureVis + stacktaintedVis < stackmaxVis + && (this.getVisSuction((HelperLocation) null) + > ent.getVisSuction(new HelperLocation(this)) + || this.getTaintSuction((HelperLocation) null) + > ent.getTaintSuction(new HelperLocation(this)))) { + float[] results = ent.subtractVis(Math.min( + this.fillAmount, + stackmaxVis - (stackpureVis + stacktaintedVis) + )); + if (this.getVisSuction((HelperLocation) null) + > ent.getVisSuction(new HelperLocation(this))) { + stackpureVis += results[0]; + } else { + ent.setPureVis(results[0] + ent.getPureVis()); + } + + if (this.getTaintSuction((HelperLocation) null) + > ent.getTaintSuction(new HelperLocation(this))) { + stacktaintedVis += results[1]; + } else { + ent.setTaintedVis(results[1] + ent.getTaintedVis()); + } + } + } } - } + } - this.equalizeWithNeighbours(); - this.displayTaint = Math.max(this.displayTaint, MathHelper.clamp_float(this.taintedVis, 0.0F, this.getMaxVis())); - this.displayPure = Math.max(this.displayPure, MathHelper.clamp_float(this.pureVis, 0.0F, this.getMaxVis())); - if (this.displayTaint + this.displayPure < 0.1F) { - this.displayTaint = 0.0F; - this.displayPure = 0.0F; - } + float total = stackpureVis + stacktaintedVis; + if ((float) Math.round(total) >= stackmaxVis) { + this.setSuction(0); + } - } - } + float pratio = stackpureVis / total; + float tratio = stacktaintedVis / total; + count = 0; - public void calculateSuction() { - this.setSuction(10); - - int bellows = TileBellows.getBellows(this.worldObj, this.xCoord, this.yCoord, this.zCoord, new ForgeDirection[] {ForgeDirection.NORTH, ForgeDirection.SOUTH, ForgeDirection.WEST, ForgeDirection.EAST}); - if (bellows > 0) - this.setSuction(this.getSuction((HelperLocation)null) + (10 * bellows)); - - } - - protected void equalizeWithNeighbours() { - float stackpureVis = this.pureVis; - float stacktaintedVis = this.taintedVis; - float stackmaxVis = this.getMaxVis(); - - TileEntity ts; - int count; - for(count = 1; (ts = super.worldObj.getTileEntity(super.xCoord, super.yCoord + count, super.zCoord)) instanceof TileConduitTank; ++count) { - stackpureVis += ((TileConduitTank)ts).pureVis; - stacktaintedVis += ((TileConduitTank)ts).taintedVis; - stackmaxVis += ((TileConduitTank)ts).getMaxVis(); - } - - for(int dir = 0; dir < 6; ++dir) { - HelperLocation loc = new HelperLocation(this); - switch (dir) { - case 0: - loc.facing = ForgeDirection.UP; - break; - case 1: - loc.facing = ForgeDirection.DOWN; - break; - case 2: - loc.facing = ForgeDirection.SOUTH; - break; - case 3: - loc.facing = ForgeDirection.NORTH; - break; - case 4: - loc.facing = ForgeDirection.EAST; - break; - case 5: - loc.facing = ForgeDirection.WEST; - } - - if (this.getConnectable(loc.facing)) { - TileEntity te = loc.getConnectableTile(super.worldObj); - if (te != null && te instanceof IConnection) { - IConnection ent = (IConnection)te; - if (!(te instanceof TileConduitTank) && stackpureVis + stacktaintedVis < stackmaxVis && (this.getVisSuction((HelperLocation)null) > ent.getVisSuction(new HelperLocation(this)) || this.getTaintSuction((HelperLocation)null) > ent.getTaintSuction(new HelperLocation(this)))) { - float[] results = ent.subtractVis(Math.min(this.fillAmount, stackmaxVis - (stackpureVis + stacktaintedVis))); - if (this.getVisSuction((HelperLocation)null) > ent.getVisSuction(new HelperLocation(this))) { - stackpureVis += results[0]; - } else { - ent.setPureVis(results[0] + ent.getPureVis()); - } - - if (this.getTaintSuction((HelperLocation)null) > ent.getTaintSuction(new HelperLocation(this))) { - stacktaintedVis += results[1]; - } else { - ent.setTaintedVis(results[1] + ent.getTaintedVis()); - } - } + for (boolean clearrest = false; + (ts = super.worldObj.getTileEntity( + super.xCoord, super.yCoord + count, super.zCoord + )) instanceof TileConduitTank; + ++count) { + if (clearrest) { + ((TileConduitTank) ts).pureVis = 0.0F; + ((TileConduitTank) ts).taintedVis = 0.0F; + } else if (total <= ((TileConduitTank) ts).getMaxVis()) { + ((TileConduitTank) ts).pureVis = stackpureVis; + ((TileConduitTank) ts).taintedVis = stacktaintedVis; + clearrest = true; + } else { + ((TileConduitTank) ts).pureVis + = ((TileConduitTank) ts).getMaxVis() * pratio; + ((TileConduitTank) ts).taintedVis + = ((TileConduitTank) ts).getMaxVis() * tratio; + stackpureVis -= ((TileConduitTank) ts).pureVis; + stacktaintedVis -= ((TileConduitTank) ts).taintedVis; } - } - } - float total = stackpureVis + stacktaintedVis; - if ((float)Math.round(total) >= stackmaxVis) { - this.setSuction(0); - } + total = stackpureVis + stacktaintedVis; + } + } - float pratio = stackpureVis / total; - float tratio = stacktaintedVis / total; - count = 0; + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + this.pureVis = nbttagcompound.getFloat("pureVis"); + this.taintedVis = nbttagcompound.getFloat("taintedVis"); + } - for(boolean clearrest = false; (ts = super.worldObj.getTileEntity(super.xCoord, super.yCoord + count, super.zCoord)) instanceof TileConduitTank; ++count) { - if (clearrest) { - ((TileConduitTank)ts).pureVis = 0.0F; - ((TileConduitTank)ts).taintedVis = 0.0F; - } else if (total <= ((TileConduitTank)ts).getMaxVis()) { - ((TileConduitTank)ts).pureVis = stackpureVis; - ((TileConduitTank)ts).taintedVis = stacktaintedVis; - clearrest = true; - } else { - ((TileConduitTank)ts).pureVis = ((TileConduitTank)ts).getMaxVis() * pratio; - ((TileConduitTank)ts).taintedVis = ((TileConduitTank)ts).getMaxVis() * tratio; - stackpureVis -= ((TileConduitTank)ts).pureVis; - stacktaintedVis -= ((TileConduitTank)ts).taintedVis; - } + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + nbttagcompound.setFloat("pureVis", this.pureVis); + nbttagcompound.setFloat("taintedVis", this.taintedVis); + } - total = stackpureVis + stacktaintedVis; - } + @Override + public Packet getDescriptionPacket() { + NBTTagCompound nbt = new NBTTagCompound(); - } + nbt.setFloat("pureVis", this.pureVis); + nbt.setFloat("taintedVis", this.taintedVis); - public void readFromNBT(NBTTagCompound nbttagcompound) { - super.readFromNBT(nbttagcompound); - this.pureVis = nbttagcompound.getFloat("pureVis"); - this.taintedVis = nbttagcompound.getFloat("taintedVis"); - } + return new S35PacketUpdateTileEntity( + this.xCoord, this.yCoord, this.zCoord, this.getBlockMetadata(), nbt + ); + } - public void writeToNBT(NBTTagCompound nbttagcompound) { - super.writeToNBT(nbttagcompound); - nbttagcompound.setFloat("pureVis", this.pureVis); - nbttagcompound.setFloat("taintedVis", this.taintedVis); - } + @Override + public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { + NBTTagCompound nbt = pkt.func_148857_g(); - public boolean getConnectable(ForgeDirection face) { - return true; - } + this.pureVis = nbt.getFloat("pureVis"); + this.taintedVis = nbt.getFloat("taintedVis"); - public boolean isVisSource() { - return true; - } + this.worldObj.markBlockRangeForRenderUpdate( + this.xCoord, this.yCoord, this.zCoord, this.xCoord, this.yCoord, this.zCoord + ); + } - public boolean isVisConduit() { - return false; - } + public boolean getConnectable(ForgeDirection face) { + return true; + } - public float getPureVis() { - return this.pureVis; - } + public boolean isVisSource() { + return true; + } - public void setPureVis(float amount) { - this.pureVis = amount; - } + public boolean isVisConduit() { + return false; + } - public float getTaintedVis() { - return this.taintedVis; - } + public float getPureVis() { + return this.pureVis; + } - public void setTaintedVis(float amount) { - this.taintedVis = amount; - } + public void setPureVis(float amount) { + this.pureVis = amount; + } - public float getMaxVis() { - return this.getBlockMetadata() != 3 ? 1000.0F : 500.0F; - } + public float getTaintedVis() { + return this.taintedVis; + } - public float[] subtractVis(float amount) { - float pureAmount = amount / 2.0F; - float taintAmount = amount / 2.0F; - float[] result = new float[]{0.0F, 0.0F}; - if (amount < 0.001F) { - return result; - } else { - if (this.pureVis < pureAmount) { - pureAmount = this.pureVis; - } + public void setTaintedVis(float amount) { + this.taintedVis = amount; + } - if (this.taintedVis < taintAmount) { - taintAmount = this.taintedVis; - } + public float getMaxVis() { + return this.getBlockMetadata() != 3 ? 1000.0F : 500.0F; + } - if (pureAmount < amount / 2.0F && taintAmount == amount / 2.0F) { - taintAmount = Math.min(amount - pureAmount, this.taintedVis); - } else if (taintAmount < amount / 2.0F && pureAmount == amount / 2.0F) { - pureAmount = Math.min(amount - taintAmount, this.pureVis); - } + public float[] subtractVis(float amount) { + float pureAmount = amount / 2.0F; + float taintAmount = amount / 2.0F; + float[] result = new float[] { 0.0F, 0.0F }; + if (amount < 0.001F) { + return result; + } else { + if (this.pureVis < pureAmount) { + pureAmount = this.pureVis; + } - this.pureVis -= pureAmount; - this.taintedVis -= taintAmount; - result[0] = pureAmount; - result[1] = taintAmount; - return result; - } - } + if (this.taintedVis < taintAmount) { + taintAmount = this.taintedVis; + } - public int getVisSuction(HelperLocation loc) { - return this.visSuction; - } + if (pureAmount < amount / 2.0F && taintAmount == amount / 2.0F) { + taintAmount = Math.min(amount - pureAmount, this.taintedVis); + } else if (taintAmount < amount / 2.0F && pureAmount == amount / 2.0F) { + pureAmount = Math.min(amount - taintAmount, this.pureVis); + } - public void setVisSuction(int suction) { - this.visSuction = suction; - } + this.pureVis -= pureAmount; + this.taintedVis -= taintAmount; + result[0] = pureAmount; + result[1] = taintAmount; + return result; + } + } - public int getTaintSuction(HelperLocation loc) { - return this.taintSuction; - } + public int getVisSuction(HelperLocation loc) { + return this.visSuction; + } - public void setTaintSuction(int suction) { - this.taintSuction = suction; - } + public void setVisSuction(int suction) { + this.visSuction = suction; + } - public void setSuction(int suction) { - this.visSuction = suction; - this.taintSuction = suction; - } + public int getTaintSuction(HelperLocation loc) { + return this.taintSuction; + } - public int getSuction(HelperLocation loc) { - return Math.max(this.visSuction, this.taintSuction); - } + public void setTaintSuction(int suction) { + this.taintSuction = suction; + } + + public void setSuction(int suction) { + this.visSuction = suction; + this.taintSuction = suction; + } + + public int getSuction(HelperLocation loc) { + return Math.max(this.visSuction, this.taintSuction); + } } diff --git a/src/main/java/net/anvilcraft/thaummach/tiles/TileConduitValve.java b/src/main/java/net/anvilcraft/thaummach/tiles/TileConduitValve.java new file mode 100644 index 0000000..186f81b --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/tiles/TileConduitValve.java @@ -0,0 +1,101 @@ +package net.anvilcraft.thaummach.tiles; + +import dev.tilera.auracore.api.HelperLocation; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.Packet; +import net.minecraft.network.play.server.S35PacketUpdateTileEntity; + +public class TileConduitValve extends TileConduit { + public boolean open = false; + private boolean prevPower; + + @Override + public void updateEntity() { + if (!super.worldObj.isRemote) { + this.calculateSuction(); + if (!this.open) { + this.setSuction(0); + } + + if (this.getSuction((HelperLocation) null) > 0) { + this.equalizeWithNeighbours(); + } + + if (super.prevPure != super.pureVis || super.prevTaint != super.taintedVis) { + super.worldObj.markBlockForUpdate( + super.xCoord, super.yCoord, super.zCoord + ); + super.prevPure = super.pureVis; + super.prevTaint = super.taintedVis; + } + + if (this.gettingPower()) { + this.prevPower = true; + this.open = false; + this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); + super.worldObj.notifyBlocksOfNeighborChange( + super.xCoord, super.yCoord, super.zCoord, this.getBlockType() + ); + } + + if (!this.gettingPower() && this.prevPower) { + this.open = true; + this.prevPower = false; + this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); + super.worldObj.notifyBlocksOfNeighborChange( + super.xCoord, super.yCoord, super.zCoord, this.getBlockType() + ); + } + } + } + + protected boolean gettingPower() { + return super.worldObj.isBlockIndirectlyGettingPowered( + super.xCoord, super.yCoord, super.zCoord + ) + || super.worldObj.isBlockIndirectlyGettingPowered( + super.xCoord, super.yCoord + 1, super.zCoord + ); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + this.open = nbttagcompound.getBoolean("open"); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + nbttagcompound.setBoolean("open", this.open); + } + + @Override + public Packet getDescriptionPacket() { + NBTTagCompound nbt = new NBTTagCompound(); + + nbt.setBoolean("open", this.open); + nbt.setFloat("pureVis", this.pureVis); + nbt.setFloat("taintedVis", this.taintedVis); + + return new S35PacketUpdateTileEntity( + this.xCoord, this.yCoord, this.zCoord, this.getBlockMetadata(), nbt + ); + } + + @Override + public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { + NBTTagCompound nbt = pkt.func_148857_g(); + + this.open = nbt.getBoolean("open"); + this.pureVis = nbt.getFloat("pureVis"); + this.taintedVis = nbt.getFloat("taintedVis"); + + System.out.println(this.pureVis + this.taintedVis); + + this.worldObj.markBlockRangeForRenderUpdate( + this.xCoord, this.yCoord, this.zCoord, this.xCoord, this.yCoord, this.zCoord + ); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/tiles/TileConduitValveAdvanced.java b/src/main/java/net/anvilcraft/thaummach/tiles/TileConduitValveAdvanced.java new file mode 100644 index 0000000..65c3758 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/tiles/TileConduitValveAdvanced.java @@ -0,0 +1,106 @@ +package net.anvilcraft.thaummach.tiles; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.Packet; +import net.minecraft.network.play.server.S35PacketUpdateTileEntity; + +public class TileConduitValveAdvanced extends TileConduit { + public int setting = 0; + public int prevsetting = 0; + private boolean prevPower; + + @Override + public void updateEntity() { + if (!super.worldObj.isRemote) { + if (super.prevPure != super.pureVis + || super.prevTaint != super.taintedVis) { + this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); + super.prevPure = super.pureVis; + super.prevTaint = super.taintedVis; + } + + this.calculateSuction(); + if (this.setting == 0) { + this.setSuction(0); + } + + if (this.setting == 1) { + this.setTaintSuction(0); + } + + if (this.setting == 2) { + this.setVisSuction(0); + } + + if (this.getSuction(null) > 0) { + this.equalizeWithNeighbours(); + } + + if (this.gettingPower()) { + if (!this.prevPower) { + this.prevsetting = this.setting; + } + + this.prevPower = true; + this.setting = 0; + this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); + super.worldObj.notifyBlocksOfNeighborChange( + super.xCoord, super.yCoord, super.zCoord, this.getBlockType() + ); + } + + if (!this.gettingPower() && this.prevPower) { + this.setting = this.prevsetting; + this.prevPower = false; + this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); + super.worldObj.notifyBlocksOfNeighborChange( + super.xCoord, super.yCoord, super.zCoord, this.getBlockType() + ); + } + } + } + + protected boolean gettingPower() { + return super.worldObj.isBlockIndirectlyGettingPowered( + super.xCoord, super.yCoord, super.zCoord + ) + || super.worldObj.isBlockIndirectlyGettingPowered( + super.xCoord, super.yCoord + 1, super.zCoord + ); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + this.setting = nbttagcompound.getInteger("setting"); + this.prevsetting = nbttagcompound.getInteger("prevsetting"); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + nbttagcompound.setInteger("setting", this.setting); + nbttagcompound.setInteger("prevsetting", this.prevsetting); + } + + @Override + public Packet getDescriptionPacket() { + NBTTagCompound nbt = new NBTTagCompound(); + + nbt.setInteger("setting", this.setting); + nbt.setInteger("prevsetting", this.prevsetting); + + return new S35PacketUpdateTileEntity( + this.xCoord, this.yCoord, this.zCoord, this.getBlockMetadata(), nbt + ); + } + + @Override + public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { + NBTTagCompound nbt = pkt.func_148857_g(); + + this.setting = nbt.getInteger("setting"); + this.prevsetting = nbt.getInteger("prevsetting"); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/tiles/TileCrucible.java b/src/main/java/net/anvilcraft/thaummach/tiles/TileCrucible.java new file mode 100644 index 0000000..6f0e2e8 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/tiles/TileCrucible.java @@ -0,0 +1,599 @@ +package net.anvilcraft.thaummach.tiles; + +import java.util.List; + +import dev.tilera.auracore.api.HelperLocation; +import dev.tilera.auracore.api.machine.IConnection; +import dev.tilera.auracore.aura.AuraManager; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.monster.EntitySnowman; +import net.minecraft.entity.passive.EntityTameable; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.Packet; +import net.minecraft.network.play.server.S35PacketUpdateTileEntity; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.DamageSource; +import net.minecraftforge.common.util.ForgeDirection; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.client.fx.particles.FXWisp; +import thaumcraft.common.entities.golems.EntityTravelingTrunk; + +public class TileCrucible extends TileEntity implements IConnection { + public int smeltDelay; + public float pureVis = 0.0F; + public float taintedVis = 0.0F; + public float maxVis; + public int face = 3; + private short type; + private float conversion; + private float speed; + public int bellows = 0; + private int soundDelay = 25; + float pPure; + float pTaint; + int wait; + boolean updateNextPeriod; + public boolean isPowering = false; + + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + this.pureVis = nbttagcompound.getFloat("pureVis"); + this.taintedVis = nbttagcompound.getFloat("taintedVis"); + this.type = nbttagcompound.getShort("type"); + this.setTier(this.type); + this.bellows = nbttagcompound.getShort("bellows"); + } + + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + nbttagcompound.setFloat("pureVis", this.pureVis); + nbttagcompound.setFloat("taintedVis", this.taintedVis); + nbttagcompound.setShort("type", this.type); + nbttagcompound.setShort("bellows", (short) this.bellows); + } + + @Override + public Packet getDescriptionPacket() { + NBTTagCompound nbt = new NBTTagCompound(); + + nbt.setFloat("pureVis", this.pureVis); + nbt.setFloat("taintedVis", this.taintedVis); + nbt.setShort("type", this.type); + nbt.setInteger("bellows", this.bellows); + + return new S35PacketUpdateTileEntity( + this.xCoord, this.yCoord, this.zCoord, this.getBlockMetadata(), nbt + ); + } + + @Override + public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { + NBTTagCompound nbt = pkt.func_148857_g(); + + this.pureVis = nbt.getFloat("pureVis"); + this.taintedVis = nbt.getFloat("taintedVis"); + this.type = nbt.getShort("type"); + this.bellows = nbt.getInteger("bellows"); + } + + public void setTier(short t) { + switch (t) { + case 1: + this.maxVis = 500.0F; + this.conversion = 0.5F; + this.speed = 0.25F; + this.type = 1; + break; + case 2: + this.maxVis = 600.0F; + this.conversion = 0.6F; + this.speed = 0.5F; + this.type = 2; + break; + case 3: + this.maxVis = 750.0F; + this.conversion = 0.7F; + this.speed = 0.75F; + this.type = 3; + break; + case 4: + this.maxVis = 750.0F; + this.conversion = 0.4F; + this.speed = 0.75F; + this.type = 4; + break; + } + } + + public void updateEntity() { + if (this.worldObj.isRemote) + return; + + float totalVis = this.pureVis + this.taintedVis; + --this.smeltDelay; + --this.wait; + if (this.pPure != this.pureVis || this.pTaint != this.taintedVis) { + this.pTaint = this.taintedVis; + this.pPure = this.pureVis; + this.updateNextPeriod = true; + } + + if (this.wait <= 0 && this.updateNextPeriod) { + this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); + this.updateNextPeriod = false; + this.wait = 10; + } + + --this.soundDelay; + if (this.soundDelay <= 0) { + this.soundDelay = 15 + super.worldObj.rand.nextInt(15); + } + + if (totalVis > this.maxVis) { + float overflowSplit + = Math.min((this.pureVis + this.taintedVis - this.maxVis) / 2.0F, 1.0F); + if (this.pureVis >= overflowSplit) { + this.pureVis -= overflowSplit; + } + + if (overflowSplit >= 1.0F) { + if (this.taintedVis >= 1.0F) { + AuraManager.addTaintToClosest( + this.worldObj, this.xCoord, this.yCoord, this.zCoord, 1 + ); + --this.taintedVis; + FXWisp ef = new FXWisp( + super.worldObj, + (double) ((float) super.xCoord + super.worldObj.rand.nextFloat()), + (double) ((float) super.yCoord + 0.8F), + (double) ((float) super.zCoord + super.worldObj.rand.nextFloat()), + (double + ) ((float) super.xCoord + 0.5F + + (super.worldObj.rand.nextFloat() + - super.worldObj.rand.nextFloat())), + (double + ) ((float) super.yCoord + 3.0F + super.worldObj.rand.nextFloat()), + (double + ) ((float) super.zCoord + 0.5F + + (super.worldObj.rand.nextFloat() + - super.worldObj.rand.nextFloat())), + 0.5F, + 5 + ); + Minecraft.getMinecraft().effectRenderer.addEffect(ef); + } + } + + this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); + } + + if (this.getBlockMetadata() == 1 || this.getBlockMetadata() == 2) { + boolean oldPower = this.isPowering; + if ((double) totalVis >= (double) this.maxVis * 0.9) { + this.isPowering = true; + } else { + this.isPowering = false; + } + + if (oldPower != this.isPowering) { + for (int a = -1; a < 2; ++a) { + for (int b = -1; b < 2; ++b) { + for (int c = -1; c < 2; ++c) { + this.worldObj.markBlockForUpdate( + this.xCoord + a, this.yCoord + b, this.zCoord + c + ); + this.worldObj.notifyBlocksOfNeighborChange( + this.xCoord + a, + this.yCoord + b, + this.zCoord + c, + Blocks.air + ); + } + } + } + } + } + + float tconv = 0.0f; + float sa; + float pureCook; + float taintCook; + boolean aboveFurnace; + boolean aboveBoostedFurnace; + if (this.smeltDelay <= 0 && this.getBlockMetadata() != 3) { + this.smeltDelay = 5; + List list = this.getContents(); + if (list.size() > 0) { + EntityItem entity + = (EntityItem) list.get(super.worldObj.rand.nextInt(list.size())); + ItemStack item = entity.getEntityItem(); + if (this.canCook(item)) { + aboveFurnace = false; + aboveBoostedFurnace = false; + if (super.worldObj.getTileEntity( + super.xCoord, super.yCoord - 1, super.zCoord + ) instanceof TileArcaneFurnace + && ((TileArcaneFurnace) super.worldObj.getTileEntity( + super.xCoord, super.yCoord - 1, super.zCoord + )) + .isBurning()) { + aboveFurnace = true; + if (((TileArcaneFurnace) super.worldObj.getTileEntity( + super.xCoord, super.yCoord - 1, super.zCoord + )) + .boost) { + aboveBoostedFurnace = true; + } + } + + // TODO: recipes + //tconv + // = RecipesCrucible.smelting().getSmeltingResult(item, true, + // false); + sa = this.conversion; + if (aboveFurnace) { + sa += 0.1F + + (float) ((TileArcaneFurnace) super.worldObj.getTileEntity( + super.xCoord, super.yCoord - 1, super.zCoord + )) + .bellows + * 0.025F; + if (aboveBoostedFurnace) { + sa += 0.1F; + } + + sa = Math.min(sa, 1.0F); + } + + pureCook = tconv * sa; + taintCook = tconv - pureCook; + if (this.getBlockMetadata() != 2 + || !(totalVis + tconv > this.maxVis)) { + this.pureVis += pureCook; + this.taintedVis += taintCook; + float tspeed = this.speed + (float) this.bellows * 0.1F; + this.smeltDelay = 10 + Math.round(tconv / 5.0F / tspeed); + if (aboveFurnace) { + this.smeltDelay = (int + ) ((float) this.smeltDelay + * (0.8F + - (float + ) ((TileArcaneFurnace) super.worldObj.getTileEntity( + super.xCoord, super.yCoord - 1, super.zCoord + )) + .bellows + * 0.05F)); + } + + AuraManager.addFluxToClosest( + this.worldObj, + this.xCoord, + this.yCoord, + this.zCoord, + new AspectList().add(Aspect.TAINT, (int) (tconv / 10.0)) + ); + + --item.stackSize; + if (item.stackSize <= 0) { + entity.setDead(); + } + + this.worldObj.markBlockForUpdate( + this.xCoord, this.yCoord, this.zCoord + ); + super.worldObj.spawnParticle( + "largesmoke", + entity.posX, + entity.posY, + entity.posZ, + 0.0, + 0.0, + 0.0 + ); + super.worldObj.playSoundEffect( + (double) ((float) super.xCoord + 0.5F), + (double) ((float) super.yCoord + 0.5F), + (double) ((float) super.zCoord + 0.5F), + "thaumcraft.bubbling", + 0.25F, + 0.9F + super.worldObj.rand.nextFloat() * 0.2F + ); + } + } else { + entity.motionX = (double + ) ((super.worldObj.rand.nextFloat() - super.worldObj.rand.nextFloat()) + * 0.2F); + entity.motionY + = (double) (0.2F + super.worldObj.rand.nextFloat() * 0.3F); + entity.motionZ = (double + ) ((super.worldObj.rand.nextFloat() - super.worldObj.rand.nextFloat()) + * 0.2F); + super.worldObj.playSoundAtEntity( + entity, + "random.pop", + 0.5F, + 2.0F + super.worldObj.rand.nextFloat() * 0.45F + ); + entity.delayBeforeCanPickup = 10; + entity.age = 0; + } + } + } else if (this.smeltDelay <= 0 && this.getBlockMetadata() == 3 && (float) Math.round(totalVis + 1.0F) <= this.maxVis) { + this.smeltDelay = 20 - this.bellows * 2; + List list = super.worldObj.getEntitiesWithinAABB( + EntityLivingBase.class, + AxisAlignedBB.getBoundingBox( + (double) (super.xCoord - 4), + (double) (super.yCoord - 4), + (double) (super.zCoord - 4), + (double) (super.xCoord + 5), + (double) (super.yCoord + 5), + (double) (super.zCoord + 5) + ) + ); + boolean sucked = false; + + for (int a = 0; a < list.size(); ++a) { + if (!(list.get(a) instanceof EntityPlayer) + && !(list.get(a) instanceof EntityTameable) + && !(list.get(a) instanceof EntityTravelingTrunk) + && ((EntityLiving) list.get(a)).hurtTime <= 0 + && ((EntityLiving) list.get(a)).deathTime <= 0) { + if (list.get(a) instanceof EntitySnowman) { + ((EntityLiving) list.get(a)).spawnExplosionParticle(); + ((EntityLiving) list.get(a)).setDead(); + } + + aboveFurnace = false; + aboveBoostedFurnace = false; + if (super.worldObj.getTileEntity( + super.xCoord, super.yCoord - 1, super.zCoord + ) instanceof TileArcaneFurnace + && ((TileArcaneFurnace) super.worldObj.getTileEntity( + super.xCoord, super.yCoord - 1, super.zCoord + )) + .isBurning()) { + aboveFurnace = true; + if (((TileArcaneFurnace) super.worldObj.getTileEntity( + super.xCoord, super.yCoord - 1, super.zCoord + )) + .boost) { + aboveBoostedFurnace = true; + } + } + + tconv = this.conversion; + if (aboveFurnace) { + tconv += 0.1F + + (float) ((TileArcaneFurnace) super.worldObj.getTileEntity( + super.xCoord, super.yCoord - 1, super.zCoord + )) + .bellows + * 0.025F; + if (aboveBoostedFurnace) { + tconv += 0.1F; + } + + tconv = Math.min(tconv, 1.0F); + } + + sa = 1.0F; + if (((EntityLiving) list.get(a)).isEntityUndead()) { + sa = 0.5F; + } + + pureCook = sa * tconv; + taintCook = sa - pureCook; + this.pureVis += pureCook; + this.taintedVis += taintCook; + ((EntityLiving) list.get(a)) + .attackEntityFrom(DamageSource.generic, 1); + ((EntityLiving) list.get(a)) + .addPotionEffect(new PotionEffect(Potion.hunger.id, 3000, 0)); + sucked = true; + + for (int b = 0; b < 3; ++b) { + //FXWisp ef = new FXWisp( + // super.worldObj, + // ((EntityLiving) list.get(a)).posX + // + (double) super.worldObj.rand.nextFloat() + // - (double) super.worldObj.rand.nextFloat(), + // ((EntityLiving) list.get(a)).posY + // + (double) (((EntityLiving) list.get(a)).height / 2.0F) + // + (double) super.worldObj.rand.nextFloat() + // - (double) super.worldObj.rand.nextFloat(), + // ((EntityLiving) list.get(a)).posZ + // + (double) super.worldObj.rand.nextFloat() + // - (double) super.worldObj.rand.nextFloat(), + // (double) ((float) super.xCoord + 0.5F), + // (double) ((float) super.yCoord + 0.25F), + // (double) ((float) super.zCoord + 0.5F), + // 0.3F, + // 5 + //); + //Minecraft.getMinecraft().effectRenderer.addEffect(ef); + } + } + } + + if (sucked) { + AuraManager.addFluxToClosest( + this.worldObj, + this.xCoord, + this.yCoord, + this.zCoord, + new AspectList().add(Aspect.SOUL, 1) + ); + + this.face = 0; + super.worldObj.playSoundEffect( + (double) super.xCoord, + (double) super.yCoord, + (double) super.zCoord, + "thaumcraft:suck", + 0.1F, + 0.8F + super.worldObj.rand.nextFloat() * 0.3F + ); + this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); + } else if (this.face < 3) { + ++this.face; + this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); + } + } + } + + @SuppressWarnings("unchecked") + private List getContents() { + float t2x = 0.0F; + List list = super.worldObj.getEntitiesWithinAABB( + EntityItem.class, + AxisAlignedBB.getBoundingBox( + (double) super.xCoord, + (double) ((float) super.yCoord + t2x), + (double) super.zCoord, + (double) super.xCoord + 1.0, + (double) super.yCoord + 1.0 - (double) t2x, + (double) super.zCoord + 1.0 + ) + ); + return list; + } + + public boolean ejectContents(EntityPlayer player) { + boolean ret = false; + List list = this.getContents(); + + for (int a = 0; a < list.size(); ++a) { + ((EntityItem) list.get(a)).noClip = true; + ((EntityItem) list.get(a)).delayBeforeCanPickup = 0; + ((EntityItem) list.get(a)).motionX + = (player.posX - ((EntityItem) list.get(a)).posX) * 0.20000000298023224; + ((EntityItem) list.get(a)).motionY + = (player.posY - ((EntityItem) list.get(a)).posY) * 0.20000000298023224; + ((EntityItem) list.get(a)).motionZ + = (player.posZ - ((EntityItem) list.get(a)).posZ) * 0.20000000298023224; + ((EntityItem) list.get(a)) + .moveEntity( + ((EntityItem) list.get(a)).motionX, + ((EntityItem) list.get(a)).motionY, + ((EntityItem) list.get(a)).motionZ + ); + ((EntityItem) list.get(a)).noClip = false; + ret = true; + } + + return ret; + } + + private boolean canCook(ItemStack items) { + // TODO: recipes + //if (items == null) { + // return false; + //} else { + // float cookvalue + // = RecipesCrucible.smelting().getSmeltingResult(items, true, false); + // return cookvalue != 0.0F; + //} + return false; + } + + public boolean getConnectable(ForgeDirection face) { + switch (face) { + case EAST: + case SOUTH: + case WEST: + case NORTH: + case DOWN: + return true; + + default: + return false; + } + } + + public boolean isVisSource() { + return true; + } + + public boolean isVisConduit() { + return false; + } + + public float getPureVis() { + return this.pureVis; + } + + public void setPureVis(float amount) { + this.pureVis = amount; + } + + public float getTaintedVis() { + return this.taintedVis; + } + + public void setTaintedVis(float amount) { + this.taintedVis = amount; + } + + public float getMaxVis() { + return this.maxVis; + } + + public float[] subtractVis(float amount) { + float pureAmount = amount / 2.0F; + float taintAmount = amount / 2.0F; + float[] result = new float[] { 0.0F, 0.0F }; + if (amount < 0.001F) { + return result; + } else { + if (this.pureVis < pureAmount) { + pureAmount = this.pureVis; + } + + if (this.taintedVis < taintAmount) { + taintAmount = this.taintedVis; + } + + if (pureAmount < amount / 2.0F && taintAmount == amount / 2.0F) { + taintAmount = Math.min(amount - pureAmount, this.taintedVis); + } else if (taintAmount < amount / 2.0F && pureAmount == amount / 2.0F) { + pureAmount = Math.min(amount - taintAmount, this.pureVis); + } + + this.pureVis -= pureAmount; + this.taintedVis -= taintAmount; + result[0] = pureAmount; + result[1] = taintAmount; + return result; + } + } + + public int getVisSuction(HelperLocation loc) { + return 0; + } + + public void setVisSuction(int suction) {} + + public int getTaintSuction(HelperLocation loc) { + return 0; + } + + public void setTaintSuction(int suction) {} + + public void setSuction(int suction) {} + + public int getSuction(HelperLocation loc) { + return 0; + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/tiles/TileCrystallizer.java b/src/main/java/net/anvilcraft/thaummach/tiles/TileCrystallizer.java new file mode 100644 index 0000000..923b064 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/tiles/TileCrystallizer.java @@ -0,0 +1,361 @@ +package net.anvilcraft.thaummach.tiles; + +import java.util.stream.IntStream; + +import dev.tilera.auracore.api.machine.IUpgradable; +import dev.tilera.auracore.api.machine.TileVisUser; +import dev.tilera.auracore.aura.AuraManager; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraftforge.common.util.ForgeDirection; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.common.config.ConfigItems; + +public class TileCrystallizer + extends TileVisUser implements ISidedInventory, IUpgradable { + private ItemStack[] crystalizerItemStacks = new ItemStack[10]; + public float crystalTime = 0.0F; + public float maxTime = 30.0F; + public float sucked = 0.0F; + public int boost = 0; + private byte[] upgrades = new byte[] { -1 }; + int boostDelay = 20; + + // TODO: GUIs + //public GuiScreen getGui(EntityPlayer player) { + // return new GuiCrystalizer(player.inventory, this); + //} + + @Override + public int getSizeInventory() { + return this.crystalizerItemStacks.length; + } + + @Override + public ItemStack getStackInSlot(int i) { + return this.crystalizerItemStacks[i]; + } + + @Override + public ItemStack decrStackSize(int i, int j) { + if (this.crystalizerItemStacks[i] != null) { + ItemStack itemstack1; + if (this.crystalizerItemStacks[i].stackSize <= j) { + itemstack1 = this.crystalizerItemStacks[i]; + this.crystalizerItemStacks[i] = null; + return itemstack1; + } else { + itemstack1 = this.crystalizerItemStacks[i].splitStack(j); + if (this.crystalizerItemStacks[i].stackSize == 0) { + this.crystalizerItemStacks[i] = null; + } + + return itemstack1; + } + } else { + return null; + } + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemstack) { + this.crystalizerItemStacks[i] = itemstack; + if (itemstack != null && itemstack.stackSize > this.getInventoryStackLimit()) { + itemstack.stackSize = this.getInventoryStackLimit(); + } + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + NBTTagList nbttaglist = nbttagcompound.getTagList("Items", 10); + this.crystalizerItemStacks = new ItemStack[this.getSizeInventory()]; + + for (int i = 0; i < nbttaglist.tagCount(); ++i) { + NBTTagCompound nbttagcompound1 + = (NBTTagCompound) nbttaglist.getCompoundTagAt(i); + byte byte0 = nbttagcompound1.getByte("SlotCrystalizer"); + if (byte0 >= 0 && byte0 < this.crystalizerItemStacks.length) { + this.crystalizerItemStacks[byte0] + = ItemStack.loadItemStackFromNBT(nbttagcompound1); + } + } + + this.crystalTime = nbttagcompound.getFloat("Time"); + this.upgrades = nbttagcompound.getByteArray("upgrades"); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + nbttagcompound.setFloat("Time", this.crystalTime); + nbttagcompound.setByteArray("upgrades", this.upgrades); + NBTTagList nbttaglist = new NBTTagList(); + + for (int i = 0; i < this.crystalizerItemStacks.length; ++i) { + if (this.crystalizerItemStacks[i] != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setByte("SlotCrystalizer", (byte) i); + this.crystalizerItemStacks[i].writeToNBT(nbttagcompound1); + nbttaglist.appendTag(nbttagcompound1); + } + } + + nbttagcompound.setTag("Items", nbttaglist); + } + + @Override + public int getInventoryStackLimit() { + return 64; + } + + public int getCookProgressScaled(int i) { + return Math.round(this.crystalTime / this.maxTime * (float) i); + } + + public int getBoostScaled() { + return Math.round(0.1F + (float) this.boost / 2.0F) * 6; + } + + public boolean isCooking() { + return this.crystalTime > 0.0F; + } + + @Override + public void updateEntity() { + super.updateEntity(); + if (!super.worldObj.isRemote) { + this.maxTime = this.hasUpgrade((byte) 1) ? 25.0F : 30.0F; + if (this.crystalTime > 0.0F + && !super.worldObj.isBlockIndirectlyGettingPowered( + super.xCoord, super.yCoord, super.zCoord + )) { + float sa = 0.025F + 0.0025F * (float) this.boost + + (this.hasUpgrade((byte) 0) ? 0.025F : 0.0F); + this.sucked = this.getAvailablePureVis(sa); + this.crystalTime -= this.sucked; + } else { + this.sucked = 0.0F; + } + + if (this.crystalTime > 0.0F + && (this.crystalizerItemStacks[6] == null + || this.crystalizerItemStacks[6].getItem() != ConfigItems.itemShard + )) { + super.worldObj.playSoundEffect( + (double) super.xCoord + 0.5, + (double) super.yCoord + 0.5, + (double) super.zCoord + 0.5, + "random.fizz", + 1.0F, + 1.6F + ); + this.crystalTime = 0.0F; + } + + if (this.crystalTime < 0.0F && this.crystalizerItemStacks[6] != null + && this.crystalizerItemStacks[6].getItem() == ConfigItems.itemShard) { + // TODO: WTF + //this.addCrystal(ThaumCraftCore.getCrystalByBiome( + // super.worldObj, + // super.xCoord, + // super.zCoord, + // this.hasUpgrade((byte) 3) ? 3 : 0 + //)); + this.crystalTime = 0.0F; + AuraManager.addFluxToClosest( + this.worldObj, + this.xCoord, + this.yCoord, + this.zCoord, + new AspectList().add(Aspect.CRYSTAL, 5) + ); + } + + if (this.crystalTime == 0.0F && this.crystalizerItemStacks[6] != null + && this.crystalizerItemStacks[6].getItem() == ConfigItems.itemShard) { + if (this.crystalizerItemStacks[6].isItemEqual( + // TODO: definetely wrong meta + new ItemStack(ConfigItems.itemShard, 1, 6) + )) { + this.crystalTime = this.maxTime; + } else { + this.crystalTime = this.maxTime * 2.0F / 3.0F; + } + } + + if (this.boostDelay <= 0 || this.boostDelay == 10) { + // TODO: magic boost + //ac = (SIAuraChunk) mod_ThaumCraft.AuraHM.get(Arrays.asList( + // auraX, auraZ, ThaumCraftCore.getDimension(super.worldObj) + //)); + //if (ac != null && this.boost < 10 && ac.boost > 0) { + // ++this.boost; + // --ac.boost; + //} + } + + if (this.boostDelay <= 0) { + if (this.boost > 0) { + --this.boost; + } + + this.boostDelay = 20; + } else { + --this.boostDelay; + } + } + } + + private void addCrystal(int type) { + ItemStack itemstack = new ItemStack(ConfigItems.itemShard, 1, type); + if (this.crystalizerItemStacks[type] == null) { + this.crystalizerItemStacks[type] = itemstack.copy(); + } else if (this.crystalizerItemStacks[type].isItemEqual(itemstack) && this.crystalizerItemStacks[type].stackSize < itemstack.getMaxStackSize()) { + ItemStack var10000 = this.crystalizerItemStacks[type]; + var10000.stackSize += itemstack.stackSize; + } + + --this.crystalizerItemStacks[6].stackSize; + if (this.crystalizerItemStacks[6].stackSize <= 0) { + this.crystalizerItemStacks[6] = null; + } + } + + public boolean canInteractWith(EntityPlayer entityplayer) { + if (super.worldObj.getTileEntity(super.xCoord, super.yCoord, super.zCoord) + != this) { + return false; + } else { + return entityplayer.getDistanceSq( + (double) super.xCoord + 0.5, + (double) super.yCoord + 0.5, + (double) super.zCoord + 0.5 + ) + <= 64.0; + } + } + + @Override + public boolean isUseableByPlayer(EntityPlayer entityplayer) { + return true; + } + + @Override + public boolean getConnectable(ForgeDirection face) { + return face != ForgeDirection.UP; + } + + @Override + public boolean canAcceptUpgrade(byte upgrade) { + if (upgrade != 0 && upgrade != 1 && upgrade != 3) { + return false; + } else { + return !this.hasUpgrade(upgrade); + } + } + + @Override + public int getUpgradeLimit() { + return 1; + } + + @Override + public byte[] getUpgrades() { + return this.upgrades; + } + + @Override + public boolean hasUpgrade(byte upgrade) { + if (this.upgrades.length < 1) { + return false; + } else { + for (int a = 0; a < this.getUpgradeLimit(); ++a) { + if (this.upgrades[a] == upgrade) { + return true; + } + } + + return false; + } + } + + @Override + public boolean setUpgrade(byte upgrade) { + for (int a = 0; a < this.getUpgradeLimit(); ++a) { + if (this.upgrades[a] < 0 && this.canAcceptUpgrade(upgrade)) { + this.upgrades[a] = upgrade; + return true; + } + } + + return false; + } + + @Override + public boolean clearUpgrade(int index) { + if (this.upgrades[index] >= 0) { + this.upgrades[index] = -1; + return true; + } else { + return false; + } + } + + @Override + public ItemStack getStackInSlotOnClosing(int var1) { + if (this.crystalizerItemStacks[var1] != null) { + ItemStack var2 = this.crystalizerItemStacks[var1]; + this.crystalizerItemStacks[var1] = null; + return var2; + } else { + return null; + } + } + + @Override + public String getInventoryName() { + return "thaummach:crystallizer"; + } + + @Override + public boolean hasCustomInventoryName() { + return false; + } + + @Override + public void openInventory() {} + + @Override + public void closeInventory() {} + + @Override + public boolean isItemValidForSlot(int slot, ItemStack stack) { + // TODO: WTF + return true; + } + + @Override + public int[] getAccessibleSlotsFromSide(int side) { + if (side != 0 && side != 1) { + return IntStream.rangeClosed(0, 5).toArray(); + } else { + return new int[] { 6 }; + } + } + + @Override + public boolean canInsertItem(int slot, ItemStack stack, int side) { + return this.isItemValidForSlot(slot, stack); + } + + @Override + public boolean canExtractItem(int slot, ItemStack stack, int side) { + // TODO: WTF + return true; + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/tiles/TileFilter.java b/src/main/java/net/anvilcraft/thaummach/tiles/TileFilter.java index d70db7e..b0cb2e0 100644 --- a/src/main/java/net/anvilcraft/thaummach/tiles/TileFilter.java +++ b/src/main/java/net/anvilcraft/thaummach/tiles/TileFilter.java @@ -1,90 +1,133 @@ package net.anvilcraft.thaummach.tiles; import dev.tilera.auracore.api.HelperLocation; -import dev.tilera.auracore.api.machine.IConnection; import dev.tilera.auracore.aura.AuraManager; -import net.anvilcraft.thaummach.blocks.BlockApparatusFragile; +import net.anvilcraft.thaummach.TMBlocks; import net.minecraft.client.Minecraft; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.Packet; +import net.minecraft.network.play.server.S35PacketUpdateTileEntity; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.MathHelper; import net.minecraftforge.common.util.ForgeDirection; import thaumcraft.client.fx.particles.FXWisp; -public class TileFilter extends TileConduit implements IConnection { - public short taintedStore; - public short stack; +public class TileFilter extends TileConduit { + public short taintedStore; + public short stack; - public void updateEntity() { - if (!super.worldObj.isRemote) { - if (Math.round(super.prevdisplayPure) != Math.round(super.displayPure) || Math.round(super.prevdisplayTaint) != Math.round(super.displayTaint)) { - super.worldObj.markBlockForUpdate(super.xCoord, super.yCoord, super.zCoord); - super.prevdisplayPure = super.displayPure; - super.prevdisplayTaint = super.displayTaint; - } - - this.calculateSuction(); - if (super.taintSuction < 15) { - this.setTaintSuction(15); - } - - if (this.getSuction((HelperLocation)null) > 0) { - this.equalizeWithNeighbours(); - } - - super.displayTaint = Math.max(super.displayTaint, MathHelper.clamp_float(super.taintedVis, 0.0F, super.maxVis)); - super.displayPure = Math.max(super.displayPure, MathHelper.clamp_float(super.pureVis, 0.0F, super.maxVis)); - if (super.displayTaint + super.displayPure < 0.1F) { - super.displayTaint = 0.0F; - super.displayPure = 0.0F; - } - - if (this.taintedStore < 40 + this.stack * 4 && super.taintedVis >= 0.025F) { - ++this.taintedStore; - super.taintedVis -= 0.025F; - this.stack = 0; - - for(TileEntity te = super.worldObj.getTileEntity(super.xCoord, super.yCoord + 1, super.zCoord); te != null && te instanceof TileFilter && super.yCoord + 1 + this.stack < super.worldObj.getHeight(); te = super.worldObj.getTileEntity(super.xCoord, super.yCoord + 1 + this.stack, super.zCoord)) { - ++this.stack; + public void updateEntity() { + if (!super.worldObj.isRemote) { + if (super.prevPure != super.pureVis + || super.prevTaint != super.taintedVis) { + super.worldObj.markBlockForUpdate( + super.xCoord, super.yCoord, super.zCoord + ); + super.prevPure = super.pureVis; + super.prevTaint = super.taintedVis; } - if (this.taintedStore % 16 == 0) { - FXWisp ef = new FXWisp(super.worldObj, (double)((float)super.xCoord + 0.5F), (double)((float)super.yCoord + 0.8F + (float)this.stack), (double)((float)super.zCoord + 0.5F), (double)((float)super.xCoord + 0.5F + (super.worldObj.rand.nextFloat() - super.worldObj.rand.nextFloat())), (double)((float)super.yCoord + 3.0F + (float)this.stack + super.worldObj.rand.nextFloat()), (double)((float)super.zCoord + 0.5F + (super.worldObj.rand.nextFloat() - super.worldObj.rand.nextFloat())), 0.5F, 5); - Minecraft.getMinecraft().effectRenderer.addEffect(ef); + this.calculateSuction(); + if (super.taintSuction < 15) { + this.setTaintSuction(15); } - } - if (this.taintedStore >= 40 + this.stack * 4) { - int auraX = super.xCoord >> 4; - int auraZ = super.zCoord >> 4; - AuraManager.addTaintToClosest(this.worldObj, this.xCoord, this.yCoord, this.zCoord, 1); - this.taintedStore = 0; - } + if (this.getSuction((HelperLocation) null) > 0) { + this.equalizeWithNeighbours(); + } - } - } + if (this.taintedStore < 40 + this.stack * 4 && super.taintedVis >= 0.025F) { + ++this.taintedStore; + super.taintedVis -= 0.025F; + this.stack = 0; - public void readFromNBT(NBTTagCompound nbttagcompound) { - super.readFromNBT(nbttagcompound); - this.taintedStore = nbttagcompound.getShort("taintedStore"); - } + for (TileEntity te = super.worldObj.getTileEntity( + super.xCoord, super.yCoord + 1, super.zCoord + ); + te != null && te instanceof TileFilter + && super.yCoord + 1 + this.stack < super.worldObj.getHeight(); + te = super.worldObj.getTileEntity( + super.xCoord, super.yCoord + 1 + this.stack, super.zCoord + )) { + ++this.stack; + } - public void writeToNBT(NBTTagCompound nbttagcompound) { - super.writeToNBT(nbttagcompound); - nbttagcompound.setShort("taintedStore", this.taintedStore); - } + if (this.taintedStore % 16 == 0) { + FXWisp ef = new FXWisp( + super.worldObj, + (double) ((float) super.xCoord + 0.5F), + (double) ((float) super.yCoord + 0.8F + (float) this.stack), + (double) ((float) super.zCoord + 0.5F), + (double + ) ((float) super.xCoord + 0.5F + + (super.worldObj.rand.nextFloat() + - super.worldObj.rand.nextFloat())), + (double + ) ((float) super.yCoord + 3.0F + (float) this.stack + + super.worldObj.rand.nextFloat()), + (double + ) ((float) super.zCoord + 0.5F + + (super.worldObj.rand.nextFloat() + - super.worldObj.rand.nextFloat())), + 0.5F, + 5 + ); + Minecraft.getMinecraft().effectRenderer.addEffect(ef); + } + } - public boolean getConnectable(ForgeDirection face) { //TODO: BLOCK - if (super.worldObj.getBlock(super.xCoord, super.yCoord - 1, super.zCoord) == new BlockApparatusFragile() && super.worldObj.getBlockMetadata(super.xCoord, super.yCoord - 1, super.zCoord) == this.getBlockMetadata()) { - return false; - } else { - switch (face) { - case UP: - case UNKNOWN: - return false; - default: - return true; - } - } - } + if (this.taintedStore >= 40 + this.stack * 4) { + AuraManager.addTaintToClosest( + this.worldObj, this.xCoord, this.yCoord, this.zCoord, 1 + ); + this.taintedStore = 0; + } + } + } + + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + this.taintedStore = nbttagcompound.getShort("taintedStore"); + } + + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + nbttagcompound.setShort("taintedStore", this.taintedStore); + } + + @Override + public Packet getDescriptionPacket() { + NBTTagCompound nbt = new NBTTagCompound(); + + nbt.setShort("taintedStore", this.taintedStore); + + return new S35PacketUpdateTileEntity( + this.xCoord, this.yCoord, this.zCoord, this.getBlockMetadata(), nbt + ); + } + + @Override + public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { + NBTTagCompound nbt = pkt.func_148857_g(); + + this.taintedStore = nbt.getShort("taintedStore"); + } + + public boolean getConnectable(ForgeDirection face) { + if (super.worldObj.getBlock(super.xCoord, super.yCoord - 1, super.zCoord) + == TMBlocks.apparatusFragile + && super.worldObj.getBlockMetadata( + super.xCoord, super.yCoord - 1, super.zCoord + ) == this.getBlockMetadata()) { + return false; + } else { + switch (face) { + case UP: + case UNKNOWN: + return false; + default: + return true; + } + } + } } diff --git a/src/main/java/net/anvilcraft/thaummach/tiles/TilePurifier.java b/src/main/java/net/anvilcraft/thaummach/tiles/TilePurifier.java new file mode 100644 index 0000000..df7a7ba --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/tiles/TilePurifier.java @@ -0,0 +1,89 @@ +package net.anvilcraft.thaummach.tiles; + +import dev.tilera.auracore.api.HelperLocation; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.Packet; +import net.minecraft.network.play.server.S35PacketUpdateTileEntity; +import net.minecraftforge.common.util.ForgeDirection; + +public class TilePurifier extends TileConduit { + public int orientation = 0; + + public TilePurifier() { + super.pureVis = 0.0F; + super.taintedVis = 0.0F; + this.orientation = -1; + } + + @Override + public void updateEntity() { + if (!super.worldObj.isRemote) { + this.calculateSuction(); + if (super.taintSuction < 5) { + this.setTaintSuction(5); + } + + if (this.getSuction((HelperLocation) null) > 0) { + this.equalizeWithNeighbours(); + } + + if ((double) super.taintedVis > 0.01) { + super.taintedVis -= 0.01F; + } + } + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + this.orientation = nbttagcompound.getShort("orientation"); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + nbttagcompound.setShort("orientation", (short) this.orientation); + } + + @Override + public Packet getDescriptionPacket() { + NBTTagCompound nbt = new NBTTagCompound(); + + nbt.setShort("orientation", (short) this.orientation); + + return new S35PacketUpdateTileEntity( + this.xCoord, this.yCoord, this.zCoord, this.getBlockMetadata(), nbt + ); + } + + @Override + public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { + NBTTagCompound nbt = pkt.func_148857_g(); + + this.orientation = nbt.getShort("orientation"); + this.worldObj.markBlockRangeForRenderUpdate( + this.xCoord, this.yCoord, this.zCoord, this.xCoord, this.yCoord, this.zCoord + ); + } + + @Override + public boolean getConnectable(ForgeDirection face) { + if (this.orientation != 1 && this.orientation != 3 + || face != ForgeDirection.EAST && face != ForgeDirection.WEST) { + return (this.orientation == 0 || this.orientation == 2) + && (face == ForgeDirection.SOUTH || face == ForgeDirection.NORTH); + } else { + return true; + } + } + + public boolean rotate() { + ++this.orientation; + if (this.orientation > 3) { + this.orientation -= 4; + } + + return true; + } +} diff --git a/src/main/resources/assets/thaummach/lang/en_US.lang b/src/main/resources/assets/thaummach/lang/en_US.lang new file mode 100644 index 0000000..d1cb65e --- /dev/null +++ b/src/main/resources/assets/thaummach/lang/en_US.lang @@ -0,0 +1,24 @@ +itemGroup.thaummach=Thaumic Machinery + +# ---- BLOCKS ---- + +tile.thaummach:apparatus_fragile_conduit.name=Vis Conduit +tile.thaummach:apparatus_fragile_conduit_pump.name=Vis Pump +tile.thaummach:apparatus_fragile_conduit_tank.name=Vis Tank +tile.thaummach:apparatus_fragile_conduit_valve.name=Vis Valve +tile.thaummach:apparatus_fragile_conduit_valve_advanced.name=Advanced Vis Valve +tile.thaummach:apparatus_fragile_filter.name=Vis Filter +tile.thaummach:apparatus_fragile_purifier.name=Vis Purifier + +tile.thaummach:apparatus_metal_normal_crucible.name=Crucible +tile.thaummach:apparatus_metal_eyes_crucible.name=Crucible of Eyes +tile.thaummach:apparatus_metal_thaumium_crucible.name=Thaumium Crucible +tile.thaummach:apparatus_metal_soul_crucible.name=Soul Crucible +tile.thaummach:apparatus_metal_arcane_furnace.name=Arcane Furnace +tile.thaummach:apparatus_metal_generator.name=Thaumic Generator +tile.thaummach:apparatus_metal_crystallizer.name=Thaumic Crystallizer +tile.thaummach:apparatus_metal_bore.name=Arcane Bore +tile.thaummach:apparatus_metal_void_chest.name=Void Chest +tile.thaummach:apparatus_metal_void_interface.name=Void Interface +tile.thaummach:apparatus_metal_tank.name=Thaumium Reinforced Tank +tile.thaummach:apparatus_metal_soul_brazier.name=Soul Brazier diff --git a/src/main/resources/assets/thaummach/textures/blocks/apparatus.png b/src/main/resources/assets/thaummach/textures/blocks/apparatus.png new file mode 100644 index 0000000000000000000000000000000000000000..b1cea6ff164842988c5b3d8252810c747a6d4918 GIT binary patch literal 524 zcmV+n0`vWeP)Q zxq|KYb&G09j4_W^h1ptw$6RX#|DK6g;U^KzY|hDqmvbew6p)ceQdG>$v&hH*7T@P7 zj094IsOZ%mt#V3kPHHJuEb}BSm1+jG7FZh_!zT>E^kyN7LXv>9qV;I4Xz^GG?SQSo z4FvIQ7O_XKs&dZ-@*cAsy|>nSt%O~3XsUEL!5GD4#zC|&Md!!!pbm^u?eoa6`yR+e z(wu&>n63gEP+41L!4tkGN7Lc2nKoVr#@1aSaB8J_p;;}BrVq|R+U!oLN2gN4Ax-X9 zjih)(PEwcs%5?DS8Y8#NM3!Qrq+c6j1uQs0DrGmM*PH>#potMg8ww3gwXMfT`64M=O4-`W3&GkTjq^t<~ z%{(+TRZb_2ij>L=R+OX_XC&8Avmbg7@1n8X@|w_h-A$J(1ttF<0R{llLsgO?Fa#U` O0000OiXzV$ zslM;u@Av2Pu^?lN@B5^IlH0b;I8z9LEDnI(Zf79yCmDglFyspj1U@zKLuW~nn8+D4 zI3#FBy+NL)2_^(-acFD8Bc><;rIh14j-ynWP>m^N@Wi1Gl9$V+ZCjxU@AvzcpiNkg zwxO6kR8<9scFVGCn&xmgzz0JYR$9%Vp*q7bz`WgVbzSfGdx|gv7zW^LyY>DIoK|!^ z9(BUy5PJX3uo;AbDn>HPvg`Gl=Q$w-QRUWfKvK={1H^t19+wk14iYxiO@AF5R5oI|bk_Yx;(w5T_uDG7OM+MZq- zP!2gUf~rfzG`A$xl~%Vn>$=V^Ue8N7($dot()Kh402F@&7yzRqRxfe&#q|IH002ov JPDHLkV1gNC%hmt@ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/arcane_furnace_inside.png b/src/main/resources/assets/thaummach/textures/blocks/arcane_furnace_inside.png new file mode 100644 index 0000000000000000000000000000000000000000..d65c633d58c411c02214f41190acf35d45d48414 GIT binary patch literal 459 zcmV;+0W|)JP)?-s!Gy>i_@c z&73Z9NxC|7wNtw^KnVElc8dtp>TY-MuK5XjX5oC>dHUn=z=`L~jNlCqgEz0{s%jH@ z#-+oIj$gRJ!4^&xQP-F4fLq`YHV8= z)ONF1#MAv{h5$(?8`tXwnjk&8&(>@8bi$B~Jws{9E#eoRD4G^# zK1PE%s!k9WN>k06^`u9-p>fXMb4L7rzk|;*hNgq?b>aX3002ovPDHLkV1kim B&{hBd literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/arcane_furnace_side.png b/src/main/resources/assets/thaummach/textures/blocks/arcane_furnace_side.png new file mode 100644 index 0000000000000000000000000000000000000000..b4e1eb4d9092a0e599922043e4ee38fbe6955c13 GIT binary patch literal 517 zcmV+g0{Z=lP)4RzFi$wDixndBqW_q%Vx8Ye!uVJ z7tLnVuh(mqaz3A>*Xyah)oS_0Vj-u~Ne+jDxN5cPqtU1&lSv7JK;rSZK)BoOZDOhT^@K{eG{BwujI;C&%Ma_rwDTm4F``K)`CX z(hdl;0=ZmH318zOR07yJ?{>SDR4S#8$z-BuHq`5NKcCN)tWYRujuyblg0`pAsT&T5 zj`O~Qgz^g6^n*{t_uh-`_f<~k9!PaiKpEjEhogEA;ip8Ro%Vl3Gm1H)XeN@e6v(o8wJZEP{ ztYcTJ)jZX0+E5lz5sDK00000NkvXX Hu0mjf$U){? literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/arcane_furnace_top.png b/src/main/resources/assets/thaummach/textures/blocks/arcane_furnace_top.png new file mode 100644 index 0000000000000000000000000000000000000000..40e7e8313cdbf53774dd93b1eb46d9f314d6380a GIT binary patch literal 455 zcmV;&0XY7NP)}$^K%!!*$r#^}zan8wPGLiLqZR8h= z#lj~^!l%S>ESt?n*JrbtACJd!JRaqGy^2ZG)CWPJ1ifBQPN$PRpHJy@I@0g=mEiOF z$m8+Q0a+M^a=Bb|?uNtR_YkbF*GuQ`_gl%TsuE+24r{IMQIGowgecC2PEZ?&q8fb6JQ<*QP}=n zYzoZ#s=*9Q@!mHkxZQ3VJ3XN(UKKkA#Fh95NHak)k=H5O%nKp5A*rl zn=H#b39tYO9Y%Z8(skB=ig*Ri=d%tq@qWK+jP+q+g{US2{5bUwHX4oeGIO3{xc~_! xvQd_$*>1N6MI2zT&-!k+GpOJ)in#kDzyPfg&g((8vk?FQ002ovPDHLkV1mjC&)@(6 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/conduit.png b/src/main/resources/assets/thaummach/textures/blocks/conduit.png new file mode 100644 index 0000000000000000000000000000000000000000..3019d00ca0fbd410338ef478aba0ba3e71f2b2fd GIT binary patch literal 198 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XGCW-zLn>}1{rdmko>_H9XQPur76UUgw;pG8?a}`^Yu51W z|Nk%X!NVshH;Ue9DSNUR7#SMAv8mNWn89ZJ6T-G@yGywqcen}1B^+RU^F`#};T!j+Mg1>anS4m~;E9$AzdpVe zXMV|MprDhQl%jH%fzQm$V)oprQxiWhxdmiwW}N%u_j`FZIX}O)wa3>RKDyknu1=uh z;9;M?|LYT${QdiRc4PD0xryA2`U_UeA4y<&%G$ud%&=*p2H!H*o=rg889ZJ6T-G@y GGywp5t5EI$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/conduit_extension.png b/src/main/resources/assets/thaummach/textures/blocks/conduit_extension.png new file mode 100644 index 0000000000000000000000000000000000000000..c66d6adbb2b2a5b4ddf9f43b681cbd15ce0323d6 GIT binary patch literal 555 zcmV+`0@VG9P)h|$ z+vI&9DFKAWUM-lPt0{sL9*1e3l?L;9uv*%59ULmvnv~k42ap2P+gXhNp{8v6#G*2R z3G*h*NjH5j9Ul6W9B3@rTX@>NhZW%A<*(msGan*BIJ2{pjeOhmy8z+-=Gv%(0UF@o zNRNYh-o1t6z`Nhq)}`p1;K>#8)Rjc3)ptMUJSW`z_}b(>?%dLTm^{WX)MnPV=59 t&nY884lL-8OpxH}!Q z$nV>u819cB?xnUaVqIcP5<`#>R8&olmEKwTioWjG&MJQA9FPl%)V2x6`ylt2j)PI~#}O z-PoCyfHsEcXp_%@q=X_g&T49Yo-H6a;pa3jTm?1fgWb|@7~lxfKo&{MC=^iC$61a4 zp{I;Fv8l{J!n_$grCrWmDRL9N%BdFFrx9?QyuZ4z(y9~ag-EuKC^7(5PC)(f^^5Je zf9(y{d%nNBdiLL#PuG{0wrp>0OXC^AeIv2@;nj1a4kl=T#4(mc5uTw;!${+92Ori5 zA2-31E941o7q)9_zWY-tOIMKj`O9}beEa3?xuxSYdyIip7Ua4E*Vr1XCI@|<$h!Rl zm5CX8pkf)%djg|@iX!YW4_;L$)6f zk6o!if-Hz*i*%%(SFvy$v*`J4gJ4FJJS+%_hT|wIvY}pIJ~6V-IWu^eU4gpH%NK_- nMqw{5>czPMrFt>`9{~mcX@xRC(PoJ900000NkvXXu0mjfJT4L^ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/conduit_pump_side.png b/src/main/resources/assets/thaummach/textures/blocks/conduit_pump_side.png new file mode 100644 index 0000000000000000000000000000000000000000..0be98291e45cc7b12dc56aace44affda34373957 GIT binary patch literal 678 zcmV;X0$KfuP)`O z0-wGYXg_=coi&oQ8C8$j6@}Yxihhz;bVmnn|u>w$`xByVsUOD|d7j2dYq2ks50y zZN${4(yA$C{FO{!-X5NwUE~vZ`gko!F9?`1F3PEOn6W=?HaUC#@~v8sQP$SSJtBJa zdsp~Mz{D%8^g1{>DM(s@%xRMBFNRzO5dHUmR`~jDA4!&>ERL`-MU3C5;*A(GH*F-(j#B?-YquL+Wpng6{*THW>T@}32jXUL={IM zLw*zq{Y`n_Z|`27Mrn-s955V;nm0Jk6?;O@WRww*i58OQ>#qO<0D24fXh`m*p#T5? M07*qoM6N<$f}L+RdjJ3c literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/conduit_pump_top.png b/src/main/resources/assets/thaummach/textures/blocks/conduit_pump_top.png new file mode 100644 index 0000000000000000000000000000000000000000..7ca51602ac8c9ec0a1d9667ead3a166e46663cfe GIT binary patch literal 587 zcmV-R0<`^!P)an|a9V88M zY0m}x|36coeCVMl0>pWEA9{A^L@=x+CCvtl2Ti@SWNpN7^dF3b8d=}2vCT0^J0m>Z}i_5 zl!_a~X1Cj^3(O!Pb>XXY^{_Q~*-NW9xXEtbs?o>eQT1FdV1-3E0s=q*EnvZh6jrI_ z+Z2}9zwg`jjF!jnaG2JVmANY(v8$dXHN z_UV3tEpY1A5)tjUnse9<{pRM~ez?(h`Ixt_FKaPxL|HH=2KHjOb#T-bLs>22w|V(5 ZzyN=CFYoY)tj_=d002ovPDHLkV1iaM5;6b) literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/conduit_valve_advanced_off.png b/src/main/resources/assets/thaummach/textures/blocks/conduit_valve_advanced_off.png new file mode 100644 index 0000000000000000000000000000000000000000..2ccbaf0ad4e29258e226cc7d8c8cd96aafd7a0c7 GIT binary patch literal 322 zcmV-I0lof-P)_#)~jStpvG{qmko4YYm?iF~~eZ363YpZ<~kh zHS)xtE~PODA{d-6z=E|}ms$8W7BzpKg&NqGJ?=A#78)CgNgmoA-VN0MFW@e~0Mvjy U06c+SU#(*Ui4`AXG_zET#Rwg7QB>pep6qebg!-O@t!nny~li%!q z^P9 zN6xN#eg_3njyR!t-C>qNHGx_M`i+6hc>z&m2NUorcF(&hVHk2Ze5Od^TJa81D=TXD zs}KYMT5D>FtrWR=cpc2<;zH`#$2XTR?1}yHRA3ayvR?qczTt^`My(ztDx@69*O(~} zF6RZvcG4O4#roQfZAm(D@&5S}pzJ>X?^VtXSP3uyysK~;W!r)j00000NkvXXu0mjf D-gJ}l literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/conduit_valve_advanced_on_vis.png b/src/main/resources/assets/thaummach/textures/blocks/conduit_valve_advanced_on_vis.png new file mode 100644 index 0000000000000000000000000000000000000000..ccc06b0b2e2b428d2e3896dcb34331def192fc07 GIT binary patch literal 348 zcmV-i0i*tjP)B}D zmSOX1O~Ni<1&K&YFzi?)$MEA91A_oB1A`zx1A}qED~KE+1K8L=A;ZM*0qEScCO!rh zpbL&He8<4azzFsV!9ZkUgcu+!z`(%F%nW2QF$nTPYyyP`K^Oe^3Dgg?6{L9c52K@d5wCTw+2KU704D8G-4E#WitU&QM|NnyJ2pRxPoeT%}8Gw8N uaSbELD-iq%OR8Z6rRSlYlqogs) z%1}MnplKTMRe&0+s)7*r200=$aYNEH^*acH04&yPp2IXvV2pt{jzN?qpLy>< zDFxIKOk|b=u?|W{X=h-i?EDJnH zsIK`gPRIedBWFDG3eca6qTndxhAPFlAmcc`35ZX*{_8347I+FU0D@zEXP|vgMF0Q* M07*qoM6N<$f{Ryv$N&HU literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/conduit_valve_on.png b/src/main/resources/assets/thaummach/textures/blocks/conduit_valve_on.png new file mode 100644 index 0000000000000000000000000000000000000000..da0a46a177ef88dfa0428ba23e08a119545d8987 GIT binary patch literal 325 zcmV-L0lNN)P)3gab{z3gLl=5lhHCM7kROW=tIA&Vlj0?V=xP&_3Gx~_xky6`*? zhb+UHYQ{IPZ5!Oia;vIBS(ch~Lpio$BoIRAr0@HBP)ey)tY&*g3oKjB&0!d7`E^}` zclUj7CK!eRH;Tv01zUg XDtUjDodaI;00000NkvXXu0mjfpLm2k literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/crystallizer_bottom.png b/src/main/resources/assets/thaummach/textures/blocks/crystallizer_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..980bc7dc4f8147b74026d67e31767f57fd7e027c GIT binary patch literal 580 zcmV-K0=xZ*P){A`VsWT)6kA@&iB|xFISb6;&vr5eJ0axOHr2KZdt9^`T-8Bah$An~%42 z{x&;2P((tKP>L>B=EGM#o6WS=Wm&#n6c12!{8GO;Ne-T>rr}NHw4#p}6m=%01bUXI zf`u0Xo`g{Qd&%MRjAWz}v-jA4`|(>!QuhWlNstzdeQ2WCn-CxZ13QwjlpgePj1LL) z$@H0Ut+g!?O-7Nr+j`R$Z7aMNt>K%pl`=spV0fV3RN#{&!ApYG#noUI#5+VK%D7;G3lshxV^rH_qMH3|T#65}v%JX~}2{2M8lL_d@<1zk2yJ4ih zSRKu;A87ey<+CgUSyfdp_OJe<^y#a#m&Q4UNS`lT*BO>M&h`1bBlb1h?XKOv|FjKS zb}BOFk0E44!$IJI*0JIg-7x4V%Rd2d2@3cSb}aGlnYANjfcj@ zKu+4+A&vU`!UGL24`eRLiatSUd~tYAB39zh2B7SBKq*k`0&zqFtK%K~6<`2Yoq0!6 SxiQxO0000IqP)YKp4hk7xzBJov{S+`WI2mD$ujo# zE8?t0ln5qgF7nyi0IfC6KHR@`iYjZOMfs0SyDPdvX_!QUH=kCKQc_hFvfuAptIfGO zm@|)!ZT|wz&d!dFFdmPQoeN|4UEQLW6l25pVwIK**G zk|cIoEdx|72zv>yALgX#5#J9=Wavfg%~HlEH5)wvLg0$p#%e^AQZ_=7CyYl6h6ddA z%>v&osC0>wq)SG}@akj0(|7B%eUGj$tU!~|^E`Xc<5MQbQ=ac?9=z-jrIPd9nDsot zmA+$hb-P_Q)(qL!1-#{QX{@GJs4Nu0iZUF0%Vn@``lLY4;>uXAxOa2GAj~*hD5i7l z)W&{O4d8id`V5;#w`Xi^ro@Rhz|A5J$0d`gCNp;8q{Qr#c}s&r{1s>z9Q@W4nIX7ZhRz2~I^rC6yKE)4VT zxgY1AtKPkWiRM7E1@8I4_aDHgZ@`<=7P8qaXsguXCOGZ}wrjnR1f_y_sRYMyFq_RV8jY}AE|oY^3&YUV>vdEr6!%u0j70C5~ET(j|btR%*8oI;^sM@7A8#py7ptROT9KS<2a^wS4Mxt2a6G(h<#2#Lf`jKSuC=dXCjH2c#t7F{xA&ge*_o+yLXNHSXaut P00000NkvXXu0mjf2k?A| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/eyes_crucible_2.png b/src/main/resources/assets/thaummach/textures/blocks/eyes_crucible_2.png new file mode 100644 index 0000000000000000000000000000000000000000..b7b5f4ce006eac6da241f5fe3769666bf7a4f55d GIT binary patch literal 304 zcmV-00nh%4P)bRaR6X*z~~} zV>qI(;*%5mzHbH8t2QF=QI!mU67`)oYAa}HTZGDnX@VS2YM8>!xe3qeM8nE~nab866>Ru*ynM6~&*oq#wNk zB@uFKZ;#;D3|3OtS38KT{&ep3ii~03=dTa>BftPA0_40|)4jz20000po z?sSfn`}LA$8-E$X;1Lm=a~K>so_m<3coFCcZ?LU4W(d z0-jOj3q=)`(mJhAxz0u`&&+oZ-fL1`oDDD0b@3+7vc`I?6-D$#a{X~0iVibLB;d~U z>WL&yW_IeV*B6QP$MKE!M}h3~Jb(SVzMs$M$Bl6un_(EvNSNasyzDbou=npH$Dm)~ he}*diVo!bq7yu<(UPH;(iKqYo002ovPDHLkV1msPs4@Tm literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/eyes_crucible_4.png b/src/main/resources/assets/thaummach/textures/blocks/eyes_crucible_4.png new file mode 100644 index 0000000000000000000000000000000000000000..f740b944308c4b325c9c81d9f7ab2d98f5e824e8 GIT binary patch literal 151 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XEInNuLn>}1i3kh-KF`3qK5lPPiUO0u>%^o50tOSatXF2a wAJkaDpU{%Z6Es=fM_zcFjNA1)90Cap3AcoLOO~|F0UE;K>FVdQ&MBb@01J&R+yDRo literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/eyes_crucible_5.png b/src/main/resources/assets/thaummach/textures/blocks/eyes_crucible_5.png new file mode 100644 index 0000000000000000000000000000000000000000..d1ad7a82e55050efc058c53923cbd636eecbba65 GIT binary patch literal 466 zcmV;@0WJQCP)PK(^^?*ttbk6KA)CSvg+}$bh}yS zSxu)lpU>^x_j-SR_+HLAuzlZKX&!nxnN0W_D}a~d(OwS+OHM=t0zzOF#d5jK5UQ#Q zBEZ@~jXRmmX7R3ffwzwjYn@0Dig#TX!o_;M&e#SBL2eeF=t!;e!c%ub0rGyoM<$3$ zDpLfTH}9X7Bo;0L0RaTTk}(6RXa?AWNINR51goJ_C<#amwtVA!KF5k}ToEGTLc%3K zaxez49{m&!ehM5TuEs9aT1d+p!;xhHMIt38JdyOkDs|n7{eB-Uh$Lr5f}z z+jelES&i{ANU6)B1~gWS%jNRZ z1BkCXyRaHemfGLt1F^P>iN;rU|MY5oXz9pME;QRgVBT0av00O?j zlJ0?6H$O;=xc%SY$CD>-0R{l0DlxEr;l!E%0000;#OvXlrkVg>#{8F{yfip-`90@T~|uMAyR9_$HAHz30UW_ZClecoXObt zT^Hau4#h>F3P%r;`?{{>3-dhpeQ$WGkpWFi?K0UK$@sv_5YF=q!mGw77&Y|B&p;a0 zt)xMRwrxY*XKV0jWrs-X|Hlw#F=-H7O v1TKbQP)DLd literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/filter_bottom.png b/src/main/resources/assets/thaummach/textures/blocks/filter_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..208ddc917c2d9360dfa031d5f30a2ee43bbd871f GIT binary patch literal 549 zcmV+=0^0qFP)`A6JZi&Gws z6HUA3(y1bKziW+=~9uv)DU$FW~;HXF?6b1>3D(|$wBOnNX-87_+y?c)yD>(5v$ z7T&*HE`f)8lDPAYJg904(1x_94i{OBuJ4fSzvEpb&~+s5kKcHv!~YI7sU@i&W(uh4 z&JT^T)>ra}rc%~!+k%xtg`8%<&5Jnd!3an~2{FqN(fB%s(T0F60wGY-_&Ru&L^NOu nvn&|_%=(OPx0CvH literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/filter_front.png b/src/main/resources/assets/thaummach/textures/blocks/filter_front.png new file mode 100644 index 0000000000000000000000000000000000000000..bd28dfa7a0d595a0831cdcd6905da6c188e42025 GIT binary patch literal 552 zcmV+@0@wYCP)J4x7%U4 zTw<|UzNLw>6paivn+=MhK$d0kjH8Vr&jPRuDUv>Crf@9c zn(WBxO$H2hJe^LlXiO$3#p5@QHw!Rcn$>DG>CA@!ES|jwyU!oROiMIf1EYI<5HndX zLI#>iioHJ);cSHyQY_HF=a63s+Y7HeM z?xrcM2ZA$zh~Oy9S_f?{jB$8-{}7B*I9jPKcHcjURRl@<0|gGpV;CYl5K|mQ^fj== z#QVlh1e@O-R3s2d2}#^J5e`cOPnmsiaP(uHhY$kZhd#mACKL1dJS0hi!C*i^o`3;d zVyqNmiqWK|EK96DSE9j5bSxsNiU9m&@Mtu`bULliIJ=Z>NNdMVUL44o*6THv%VkY= z?z>9BPF`^wBTds2kX6+69+jP&x+FgwYhNrD7}HH`w_9*;oO3;bo&q*jzyx`oBg?WH zWQ?hO&AYisz!`W|Rn_YOlUsTl?Eja5gV?$~U8ep$WI@GwQVKR;?^vy7N*o0o=SYbAKMh?0O3 zPK1C;3N5Vs9ioMe|H96~U*Z3-_ZLXYG!jsPS46Hzh{Vf%turfkUV;dcEIgREJM-@5 z?G9mKd7fwL^*WSNNRq_vIgW!gO)(yi;rqTS=hLD6RK1yAo}rA z_+S|0^L~Vg`57Z*>^$zzFPIm@*<379-07!mU8=b}n$}8Km7) zw6E+N4lHzvK(3>wKh;u z!v7lIW-B~<5??A1&lSBb=fBV|EZ)2YEd5&72Kl`_#$m2-UY00V7O!7sB-FS!EPS3C zm^jvmtitTH!RdK}vI17?2J=-NcF;;AF$!54!G#QjSfiK4BqxE^D(uqPAb<|m^nc^l z11hn|^BhG{VEp+bvTG5_wL`Vp;`d?;ktpH9GpG<4SGAFW231vIGMQjB8X<}zo=nR; zfHcuOVujdff-gd}L7ERgJZ03@qu1*Np!gLPl6_4QQEUkAA13G@BrxLZ-!W+fU$TVg z`1m-;pU>yvTdc)N0Zrm1)?E*^W>^FaDA_fCg4{K8k`XhWcHM5B_uqduc=aL! z=fRU=om5a}jMQ2Mz?ZM5xHHHwIw^OXDCK+lFr{S0q*VY&jU`Zas_O(vZ{JLLvHVro z?lU~f*s!iNl7S(SBySrZj(hT>`u}ZAlL#pbBiA`t^9Xs!O%&hz&tCxs04L8aD&BL5 Q6aWAK07*qoM6N<$g1x;m-T(jq literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/generator_3.png b/src/main/resources/assets/thaummach/textures/blocks/generator_3.png new file mode 100644 index 0000000000000000000000000000000000000000..6161c7a3a62913fbeb5ac73ca4899c1c67f24092 GIT binary patch literal 693 zcmV;m0!safP)!O~t7Www|J@Eerv|A!5WroW1M=*v95aoB^=b;MJR7xO`snP@v93 z&Jxg*O#-D;2qE!#cZU17lT!xQ*L%LD$d*ra(TteGUBk0uS#+f_;K zM6==IN{%N#ON>IWSjVhzIGC-IE{&Ba>%+J$eK4kJ{FNpGolIbNt5V7L(_Dhu?=DA6fLdEoDvvWOW0MH%*T$%A800000NkvXXu0mjf0>?l% literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/normal_crucible_1.png b/src/main/resources/assets/thaummach/textures/blocks/normal_crucible_1.png new file mode 100644 index 0000000000000000000000000000000000000000..9d21e45499a2288997a125b2be741746a959d28b GIT binary patch literal 349 zcmV-j0iyniP)-A$S!18)S)6lfGsdVLUu=$76h+eay^$Aa+xD)iN-T^p`(WEP zv1mfeTM$^~@H2XRq7&Rcg?WoOjz5KF<5L5&{t}SNTO>&$d7g_!3$1*MX_{2J%d*T% z!ZS>ofe#oyC1O;4G9a)P5dtoaj|3jKEQ@xbX&P(wh%dSc%B@ub9O}B( vL()PU*OoznoOY4nQ#Ab87e%4_KLG{+#HOH}EQvRS00000NkvXXu0mjfzG9Gw literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/normal_crucible_2.png b/src/main/resources/assets/thaummach/textures/blocks/normal_crucible_2.png new file mode 100644 index 0000000000000000000000000000000000000000..4894c67e2997ed0bc85cc6e41253f46ead82ad36 GIT binary patch literal 364 zcmV-y0h9iTP) z?BuJP5#;7Tdr=w!RD zD{GGEp>iCDEKOoLSW}{n#lG(#Sg_@ESr#&t2D*$8EuU!q2@Arg^9Pi3+9=6E6+|Cl zvwtw_fuoQ_A60v-Is^TDy$%CVH4sa%$#Vlzm-&ZHTm99(eH2= zaZzuO1NdpSD0O&vMtH{_r?xlR{;(jo6X15dZ`CK%skm;=*vtPPkw&ut16-fhLm5zd zfTohrI;NLX78#O!l~(gb`9kXmw@8H|grx_$eL3k^Z%N1YBftR3h7u*H=ofDQ0000< KMNUMnLSTZD?40ue literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/normal_crucible_3.png b/src/main/resources/assets/thaummach/textures/blocks/normal_crucible_3.png new file mode 100644 index 0000000000000000000000000000000000000000..9000b7643e0546a8b4949dfd372e0f663302b5d5 GIT binary patch literal 460 zcmV;-0W{a_U= zgZ(dnRUm;{mA-)XSa%TjrwESvzaJkR|dV{|{n5Khx%Aq1P}+2h0_%&@^sC5);7QNY^U zIF25JjJ#M?m2Z$(kBcp&+5yPh$L`_(&s85tJ2hD&uF)%tIS0Gk`7)i8(q2hYIdYnYs zBCeb0KHVtwCL#ea)aX`fHWcw8!U&M%j=vMpzp?l2O?grMh`sOo>g$@iuKRz7zt%KO zQrGoDqE0S|O~ZuGewYTXp>G5jNA=54C9G!h5nuo`EqfQ0o6e8`0000}1UAcJi=XnO!@O3eXDGE#nz8Dx885ta8ag+&S z@Ua!{U_3NkKVIz?OH!;AmmA|>24$V(3A1cUOH2PRe!@C~L37qYwt!cx4Ghc-8tKA1 USJ%GR0-DX>>FVdQ&MBb@0QFTid;kCd literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/normal_crucible_6.png b/src/main/resources/assets/thaummach/textures/blocks/normal_crucible_6.png new file mode 100644 index 0000000000000000000000000000000000000000..cac68d703c2e3e2279fb844463fb7904fee70881 GIT binary patch literal 491 zcmV-Bn`JQ|JMIT#GQZIU4(k%Nx{Wm&#uMG`qwMb~69 z@!;ih@njBfx#K7zCMCsSWwJ69~ ztyV694mATXBE=WQN|2#^N;w=3w%_l)IzARliJC*yf}o8cM3?{=9cU{>0-^gE4wu<% z_6BGs9IdpBMB>Ne@uw@bT@;0Xce`C;zZk2}SIZapU3s3{cs%|y83V(%PN!2}c^64# h9{)A4n#q>{0|2y9Hmq5cu<8H+002ovPDHLkV1l=!)6oC` literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/normal_crucible_7.png b/src/main/resources/assets/thaummach/textures/blocks/normal_crucible_7.png new file mode 100644 index 0000000000000000000000000000000000000000..24d42756ad5325fab931ed2ca9aed4b4df8496ed GIT binary patch literal 330 zcmV-Q0k!^#P)`6pHRCwBql1Z+FFbqT!6J`kk=RvHw zHTOYc%RKbU&sT5TULeP~%H_ch!;t6sec#u0?fYKW_4~f(c|Ol0BE}dTB5@p(5JizA zG)+@@lQGXTU>qXrx;p20T5E}r;DRMdGLED9Wqsc_O(US;FgiPqL(qpZO}70rAscZ@ zde|lOqyeO9>gR!{>;WPF019aUS(cS$DJWyI8o;tFh<8O%C?$p6`3lMbj0lSh?Sh$oJ;>A{}0C*#r2|wk=UAqLO1~L9j4HDu+h-i(ge0 c{zrfT06{vPo?1^Wga7~l07*qoM6N<$g7CG7Jpcdz literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/purifier_front.png b/src/main/resources/assets/thaummach/textures/blocks/purifier_front.png new file mode 100644 index 0000000000000000000000000000000000000000..bdb53b3e534e480b772491bf5895eef3e70d7172 GIT binary patch literal 793 zcmV+!1LpjRP)hcc+XfPIg?L~lX81wr{#P!K{yMWUH8N>(P34^vG|b2*+l_kC^K zdR=R?f4{Z<@b0a`(IJ#EA;v;VDY%qCLcoLo0$@!87(pQr;jrh)?S{nr2I0X9j;NI~ zWFZqYTF8r%X$wm(-GHSHI+*8nU_~)30dsU6;%nqNEtAv`zweJ2!*QiQGf<;j@PnS<|EHysvp%H^(7dj~Jn zM&~l?dJ;RL_+&jpNJj|qdTpQYx2vQ5lsXM>Drv4E5-0~5F{3jRpXqTCK)$yw$k? zFf0~bQ^x@o2mlFyh$&G<8rBFQi9`bYFJ0F;=V13RYAHZn1^|R(3Y~!4JMOiU9{@6+ zz8NT&%R@s$hGD2arS$UnqT@yn>*HR;83Tx^Wq`2RvN32sczHnaC~n)f6;-`nS8wh- zKjeE&HPEp=KbDwDnC}BuCb!%u%Q&ANugp$<+w5HAjNh1AxwkN)sD9af{rajOawH+< zLUz2=r{<~JPk!du2f*CF-I5ZcjCXs%^~o1M+Ue!(Qz#8n#v&muR>4vlt{52Q3g|QK0nSQHlPfdJC>gnaLQ-yrq^J+W$?DKYIbfj^1foW33DV;E8?l+E^ znMoxRhn@ab#nlq+Bj(X&+pCLWo?3aW1;n0&sd> z06dQ4C@-@zMHDvtdGX0&=w?rb1Tio3HnZ;T-Yl{Ys5$#D(WM-(=!AyQIN zs|Vdt^*o{C`e{c^>&>QV43Gxp5e+!99r1DfV0)+Ic`jV}zQ3ejXmNbX79#6_$}~;K zO@|+Vl@L7h=oTPd&&jsq9=FWt+p9`kFIH#s<5%F(xAHGQ!noo2f<{jN<5JVEWrKuz zZk#ei74DB#l+r9NZq g)0-T``;Pzv0AX}~Uh(p9mjD0&07*qoM6N<$f@`2R$^ZZW literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/purifier_top.png b/src/main/resources/assets/thaummach/textures/blocks/purifier_top.png new file mode 100644 index 0000000000000000000000000000000000000000..fb3dce4e459f794c92fc04edd5e1bd6362b0680a GIT binary patch literal 695 zcmV;o0!aOdP)) zdSmn??fLb|^Pawa`r`M`E}ZX^sDu@Y{17E82nE~;!4g4B1CN-Mg*tRXP(Snvn*$2wes}wO@I&iYNGrPZ&$X7s;c+z zPK;k2W{f3Z7{))4cxI;WnWjlKjor9nN~}*+zvQN-e6lagTeoxLEPYASN|Te1v`k4` z+Pak++$wZbRVUD*ERSfaAD7p!rSS}Qc2Ug(w{`Z~g zUabL8EH{s8mTg;wV!l!>IgV2(AMYI=gPD4sH+N@weY2j?TC-z|-)QT#*_<6+tZJt( z04~pOxbCZrJvTc4*=;=cNZeA}K6N?*Qb&S!T;X(u*R=uSmM}>=6oH*U+|u&bhx?6A zt+o1QV|u&NtlRl_n-8i#-J{0GrS%zrU)I{oPtzw&j!>QkL6FU;NY&wI4P{ea#3-eM zSwm2RF=gc9SwVex`Sr13`JfYr0heY_s~tZ;-fho~fhmas#Q;TBJvRm^32%(8W2m!FW3Ji+`OV`QKaee1UJ(Y@~RQavz_-`ohH2`)iyT$Se zURxMCXA(0_;J@)+Fs>(h;UOUqQ*gvlGMAvA)FbM2Im~t#ad0P-3=ZBal_`vB42d2_ dkU0M%zyL8GP0rCThq3?w002ovPDHLkV1kjeH~s(s literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/soul_brazier_bottom.png b/src/main/resources/assets/thaummach/textures/blocks/soul_brazier_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..1944cc19ee7722416529b2453f5d870c9edc0686 GIT binary patch literal 378 zcmV-=0fqjFP)wun_F~23huK7mFCWu5(qS3>~a2-_T}&Jbz_34TKOF zE)mcI=Nx;Ea1N_gf}ncdV7tw1UDpuDF|=(9MNxoK@6Id?C2Te+oX;m5hd{ag{+Ue- z2tIBFbs9lJAGge?18fe4*b&Y-g3V^1ZoU4c<#Hk5PbTj!iX_#w zrp;zetJM$3r_&F{Ef(MG$Fw&oB_&DPxg><3D2geL?MeI`7YMf74Qbub!QXmdLdLYz zw#V^PTp$2z6h(CK6H3#RoJ&~EEnFb5)<8Io$8QeFN-3XgIfidId~w#=fD0`h2ppkM zQS@jqcxE3TQ5P@$eIx;Qp}-i+;HJ^OM@^_^jPZZL=RD6jvBO`aZsJtV$tW2qj=JPKGc6l+K89-7-48R!%`EA?s zQk~lc0Y-;5@D)W7;vhU8=S>1A!}4fd`-*i?fayF$fK>%B&kO4H%9F|u5mZ&h3WQL; z@7>a5S;|CB)7&S(1In_3XI_>G$B@|F`dtD%9Hstv=2F(2h{uE0u95r;FaV)8-!ssy RH--QJ002ovPDHLkV1hS?(*ghh literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/soul_crucible_bottom.png b/src/main/resources/assets/thaummach/textures/blocks/soul_crucible_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..6660f2d824ebf2c88e6a5af8bb1732f1bc969c8b GIT binary patch literal 433 zcmV;i0Z#sjP)=W_%!>EgWj)iG$s6n4VLhtn`dQrX1scrG=0?T2^}!<6xX3@2 z%YSCV-}pc+<0QDJ!>!@rchAST+f`E-7aR&ws{Aap#Zav}4QDrMpuQy*5Fs>rCXZXu z8DUdm0x|XzJJ-6Wq9kSubPa~If$uO49bq*aBJS%+GA2qlrK(kKlhcs3BbqUZBa)=> zHs0lgl5dQxBi}G4(@Agq!f6~PKnhJm3cM)l=5mE2{We#K9LkP86^T(8EF8V6I z%#7v#r9*&Ve=yK74rXbnA&?kXh_Q#PIUg7UK}4rOXDG5B=?b+3Ii0=$341Bst{*=| z;u5!QJ0sGp1#GZqh*1}8V7kPW2`Q@Tf_GcbI8!A~mis}_?)z7q0IAbc4;+wnT~CPj zVr#kA06HG*rFa?B4NP$YQo=p6JUwt=X*!WG0Wn0YMcTLc3$|)`U_CfoRtSpa;WaxF zq9OIL)Yl&OALmFQCVRDyc;xqk&Wemvqr*WSFhv_LRWEg43C>cYRC+E#90aI-S-t5X zhKYhOV@q28gzF7roIsYO)Xu#;BwKN&U8KZ}Cia!zI z_&;<25G(@=H`cb4W1s3$O&INo^T#(bTS1tEMz^>~vG5{*-O}Avh8sm(3DYoW& z4Nylzd(KjZx`8b+fD-PNlGFnc%nwP}XbGY09nPk7RrIhQ0{Yp15bw@TREgg|pAQd) i4aUsVdTufP1Q-CaPb7)vV|8+ayAf|X_NwLi5U|s9!V7?kdQ&Y~uy);mcu6+L zXAV$DO?!-zhPr_*UH~QBOKDdRL@>W3VH4wy6w4Mv=*zO1HHFZbJwvC66nZ#8VkM%% zC#k1|b-XRmgPv|{spaBKI`juV2s)G^EOB)dH!wM=2{i|#8spj|U8_KTx7no#=v3>> ztAw0RIcM>X2uAJus_5pXu%;woYRoeLB_SGWy?%d~{|zo5^(S9+RH8~e%JXR43_VKr bSAYQk-{Ks%Ss4i{00000NkvXXu0mjfhQH7b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/soul_crucible_face_3.png b/src/main/resources/assets/thaummach/textures/blocks/soul_crucible_face_3.png new file mode 100644 index 0000000000000000000000000000000000000000..d21f9af03ea514fc1765021f20c74c51cf00034e GIT binary patch literal 488 zcmVP)v8eA6_Z zFM~18yRPe2h)k(yIEXViXFVL)dKX9`MYh)C>%t0mTH}PvauKlW^#(Tp%IsCuq>(j* z9`Rgkj!O+-M~!=oT!yHDEp9+csF%_#8ZcpVql8V2GfKRSKi+r4@uL}G9Dl)+NpgB9 zK`bSrkq<}He1RQ&=Y5Y9A*^yqU&A~2U@PKUiECscj`q*5m|qTW@Bz2o>`$j}ph1-% zs}|cBLqsGXd83?StdrD$!i0TFu@Na&mR5;|GW=MrdL)x;MI70(N^Rj!x&U?0^C<2n zP8I3Yt%a;CIcIhg4aZM$sbx^`J^1jAO_;|f!*f+yhL(55UvI%|19|U6p{VJI)DM zhL*lxeKJ3;KO1XX9>b5|>**H*ADF=p41d&$YX;2q%`iBfwWEZZ7RQ}`)|I4ahJ&XJ zig?+EEy_9%=x$w55@)JG7}V7BVlEeCG@nmpf2EHio(_l4cz^GR-K{Ur-+O%e_%%<) zmwx^H?48GZyN5jNKVi$FtZ^!f%@;Qw?`#ifEo_`EfB*6r`c%R~Q&_EX>TT_!K$Iq3 zO4A-qe}0u$Mw;i%?3?KA9`f5oN1@xQB475e0Xr;DNM$%8kAo!e*a4k zrN)j9!%IzTu91R%u8b~M(5~B??<-LcSiS$ZGN@X+osdOK0=VABCdL+J sLQoi4)d3e^gh}$QbmTiK;vWG90Kc{g$C6mgssI2007*qoM6N<$g2dkwH2?qr literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/soul_crucible_top_inv.png b/src/main/resources/assets/thaummach/textures/blocks/soul_crucible_top_inv.png new file mode 100644 index 0000000000000000000000000000000000000000..328eb1e794da97584e9390a79f721a2d1df999a4 GIT binary patch literal 563 zcmV-30?hr1P))O(6a1TG0zTVNMLXT@H@h<@z4!Rf(xAAzz4l3#VKJLy zyG!T*xHvyUT|2-xP})FC1*HTni99c`Niy6&K8pa5<|Wo|3GMc9&cPAFHYs4OK~+`| zQo?AB#(Bh6(*+GSpDCBN4AP>cLg49TE%1w2Ew6mHm;5nWLdo$@#KcbvANFm|7zKSO z2;Z5t1Y$QJwP1A&|04?=IDxB#tO5@_5h65ogTY+3g!m;0N@&T zbXY^$!w`X~?*W8xBvFI!Xb%Tll=YYapztH@!EBs&bg3B2$hJI1n{&h2M3$X70Puv^ z>3Xc^Y0fHz@-Vlc-A9@S#MScB^DJW0nPp}F6Fj&f%PhkHCHCaps&0CK*Y_QHKZhlU z@mnBs2d%kHDcE)Nh)8Nr38s=26_TuI73q5aYkUbX02qE*`wn6eV6!Bk4Ruqf*Y b@GrmsU)8;jbJ$^U00000NkvXXu0mjfv%1XU literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/tcubeanim.png b/src/main/resources/assets/thaummach/textures/blocks/tcubeanim.png new file mode 100644 index 0000000000000000000000000000000000000000..5a7294d6b73e8045fd6c56f86073c667f1620e30 GIT binary patch literal 65316 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

v0g+T3`d$2B*GU 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 z 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�QR=_uQPj0ruK`(Gj9_gShWl)Ea0Kx15)~3IRt#*w)@*cMadTu zE;NA;XaoB|;{#9ze(>;toe*d?TEUJ#NU{5|>r5g&+0wKdu}@Bx8UB^=Dp?1lFaKENBZ z?DP=pk-6ih-~)M-89r{uubR2xzo{v_vG_m|@qxdYjt{)~S`8ma4u}tgO=orO5b%Lh zkL23Y4-Fr9{n_^*K0u~z`^dY24`c_!2k?>!_piKE#TQKM+4#WIrdv1@ABeix4}QVY zahmgc;{yuULodDl6QhoH4&*)Y0ZMziE4%RlO8n(3%qKduaD2d39QMNpXa~XvuDmiG zAAtCpoARdcl{!Aan7;4uflM^O;Rncvf)8Yobr~3C8vg)JtHc)@=HF9c?a3-$3UKOS z%N0UF9^a2)b$kF>;!*(se1O^PYgLTw-~-``NYVRJ=|yaq8{TrN;<;Ds(5?j8m1o)j zv@&&98aP26ACLn0sFv2@>%5K+&?xO<+&YW7G9q{&*10>M>u;E?ryg;8)e@N)H7&1` zsdi1cZIo$O!v~zN$oGYE51kg8D-}CD&(2dvLST}rjDrOB`X+;|7hg?3a?~W>S)6abq`BEK#yzlmL0s?1A`z1**795aXmOS#iVRQPwC`W!F1TY(gIlCjX9Z9!k`KL*- zH$b5$493S(vw9nQf4AFT6I=7yZ-k+GK1qK5i`E-t*>RMEjTnR>AfSQWPuygG-WZS-D0RYNIUF|?+^!t8rJUC7gt zJ&i1Js}o+QH%=uvEqB}qvF(99rZBo8+lI;5)_e%7r@>SD7qM*IoL$WE0lqALGHQed z!?5l%ZNnP(8a^=Db1p&b{54L7#3UAR&N17f8#~)hhFu9L)3jH2?1y)M#t5t~JXx6U zm}WAujt`u8pp~5aZjsC_8Lz;R=)96$N8W+Mb;IpcW*<|a6$4yPeL*9y)+?qKyoe`- z{7l@0sZX*>97Av0GA1`hkGJVZqEs4u=ES|d-nb&XvMeLS!(3`0AOF$cG#-IV!Ic6p z$cuU1(-oX`^Wd)e4~Jpis29S9(uwqNRA8r(2FhJ|>7k99y8wF{91R=~UcE2@~C9dZa&J0d9yNe>J;{*O>_kw&`*6WTI zPIQu$NE<>G4&Dzp9IjhVxjdqMLUTR9*ng;gs3nrSs!h+DCwEl8X&Wx6RPbb>s#PFe zGfZZ(bN4b@B|d;##*Aj$tkVJmtqBL304ancELA1FN+l1|-i4XdeT{s4fck$hfp~yZ zAJ4~wk*+;T-Re;UM*xdU)-bnGD?^?V3bAdw^j=5zdVsS04npJYp|(&6QSn}}>6qvV zA5%^StKgw8CCNvB!-^pk9|Y%93DMceh_R8AXwJU5hRT6M5gdlKkvCgLXttG>{Dj&Q z=6KDvyc`-<@P~gJ{e#SO@4R)xx^#TtK$FlIxzf-Jqf%&9sx9!=-d!m+nL+8OxtWN2RA9DG2UGyu^pQt;a*8xcI@#qjp7OAO%w%kBPOOT^-h+|;u% zzZ56++NDA1SMu*X@v1x6y?RMH)9(rQb<#7Q6w27={?(vaAUH=r0Up^rR2JNe9&xKm z<8qwY->@0ui&lsO);G3nsKhrSRZfh=H-F@B!aFMV1eJbO=V4PTItl zqq1c4s zi3~(hcv;dyaxDov2S_#kpZSAUa_O0Na{0MdGTmXFD+SZ;c-UMzQ3c*tq329o&J&aZ z6dvx4XCkHGtCs#(#IuY>9??km>$vz6|JYBC-^(%##_3fnXr06d7~bwyU-&^5&z9JS zcM%uJ(mGX~jC8XL$hd7u{_ zx4Uw9anGkS?F+J)9ehEb7ga?~VQjD#KW5dG}f^a9((7DS7K< zlN=k=(m2*vEU^rmF6*{v%WG6r^M-0(*nc$pRU%@eIJ zYDqSh2NukHsKN)Nj~ux#`4BRy*ri4@bwJN;vZcnhSpz93ghNCX8Y#*G*|stB6vE*p zu`f_vW0d2W=!g&e0C-E3_A%RaJ{)d3iJtm!fe(D|AJ&y$gxNjuk+3sn3#F$GJ^&`o zGL{b7em7T1FBuT7_SfJ0`wr_+IQiVSdfFR+0Jsje0rU)GmBppl!1OxfGR^w>G^uMj!sdsAO zJ5C5Q{^Wzll9&H$$B?k_7o_meNcp8a+$;8_bFyS}16Pl-!iK?aNhx~8pLxQa8tpG7 z{(hv>-MLm;&f;o2Squ{jo|4W&hzEy_(g2b4eCe4OAt$!~qg&wnh1z9KOjZWc8KaxX zA?$4wQPV`JE(*_~Y|#8biD^`nh6=0Mz1B#!BG}EidhfC3u^ng|)m^i4a%*Rd`UQ{~ z^Mj3zDnqLBhB{*k9hJ^us;wH_4+90_wHX``)SwtPW(t!am?6@kLNYETIl0d15k3qXJ|CNp_dpt@!cdHqyOp(*{hIIr ze#Aw9SAbACGZ=4aISl0wbMt~&F{~gZHgaZ=nyXGqxU_GQy`y6r0&<9YMwH*`G?P0| z=Mz61nQlQOMB<^hx2;5&18p7zM@7ny{^=bokD#hAFu6fJIr#(Q1?<%X5jjr82Tpy` zD(hnELFuZwkjg=ZL52wLmbX{X*=9nuRRoRAcNs~UyGv+=m*PySQi@(qHOT)Wbb zeN`k|y;VD=X|^I`|7>u(#0P9BtRhwrY_$1wE%ux8?#&L`ik)Qn{6G?u6w0#ZO@3&6 z3F|yyFchi&%(n+0kdm{y-@b^4ytZci0}Cg!Qu7ki`U`(#L$!LbDUCwu6z!O%#i#~{ zPOhZcZ3JCJ!^U`Ic+c50cE~g+wv*M%na+{dnHNu(ZP)gCi*3;~XkfsU*RO<#IvyO8 zb;pY}JLuZ&Z3h~Bi6wEEr|X!in5~?ZwDb5aUeFC>nmQW4WKUn11xt zaeTmigE~F{inbFECs>ZW5vjYpxd|-Br@dyR`V6(sBRUo_3A}&@;V+t_GdlSWMu%Xt zYH1jbwypE^ZG~T^c^bzudO^?z5cO~|JZ8u)iYczUUjsi=XGR5+NOSHQ4M)q)3yBpmdi);6zs$NS6+R$T zJiHA^cZm-yMigySZO00=!t!FDKypUpmz|c;4M%(c6rFv5w@wFNMoty*eN;rIBI z2ge5@ps5F1nZO57jej7R=nK}p6ulTe5P2xxdWZPH-Ji;mV|UxQ2_J|RHco`$7@-dV z!1)cu2QL12N%;fs8+;&%NZ6s_1E8Yln;bemKo3mA2NXZt4154$WX$p;J|Oa~gW?0& z_;-R2utcv9A81-+i^IX&-za>*^Ue0h2adjTe1J11gn8=tK<8%S18nIZe0+fUqP&nA zKEV9(JdyqIfrjG)qarPDUT^jM0sl8KqT>UA)4ntvAHYk-G5P7h2bALdQ-Kd8>3a|# zxbqV?5g%Yy&ke@$fv5iYX5a&hX3cQP4iz7Olh*YOS1&Y^AO4*Uo6__)ZW2C#ZP)f1 zX8mGhbDWJ2q&Eg1zx`@d4t!cMl&J?T-(*(Bk_KA85ZP@PY1heBcsf1<&6A zd_XSUZhQbwitw$$X7Wz(0RdDse1M*qiVrj`XMoB1!N&)@L~L_ye|+Ho0fMLLZ~qO} Q>i_@%07*qoM6N<$f;Fy@@Bjb+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/tcubeanim.png.mcmeta b/src/main/resources/assets/thaummach/textures/blocks/tcubeanim.png.mcmeta new file mode 100644 index 0000000..3ead965 --- /dev/null +++ b/src/main/resources/assets/thaummach/textures/blocks/tcubeanim.png.mcmeta @@ -0,0 +1,60 @@ +{ + "animation": { + "width": 1, + "height": 51, + "frametime": 1, + "frames": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50 + ] + } +} diff --git a/src/main/resources/assets/thaummach/textures/blocks/thaumium_crucible_1.png b/src/main/resources/assets/thaummach/textures/blocks/thaumium_crucible_1.png new file mode 100644 index 0000000000000000000000000000000000000000..a9ee88f6f3a799aab5caa32331ac53c6477ad028 GIT binary patch literal 357 zcmV-r0h<1aP)DqxJ<+ zEpB5k*a93Ks~194zpUpddDz$41a!{N|cFm$@V5nWurMP1Z*}h7H1a! z#vBk1&c&z*T-R?>iI!|ZV)`vtp9dp=v~IV@e*p0<-#w-vK*8nb%+!Iy?pU7ngD= zA)UhPQbt_x#)Fq5P}b@~>+9|&GV9$1^z(=cSdT|rL+p27rCpSE^B(5}m1_!ihJ559 zrjW73x9Tk%F-1s*O&~2cA_>XhMxLGbI=%bie*z2ur!R{Dq^lUP00000NkvXXu0mjf Dqvw_? literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/thaumium_crucible_2.png b/src/main/resources/assets/thaummach/textures/blocks/thaumium_crucible_2.png new file mode 100644 index 0000000000000000000000000000000000000000..489f27e81557959201bd23e7386a989c79f322e7 GIT binary patch literal 366 zcmV-!0g?WRP)z=KQpYO8(2``A%|jmdr%Elc%%+Hrx#PqY_Gtqr?K~Ct8XG=h7<$tUKT?GDWNCh} z;b?ec(Xr20TC5oGvzQiXAV>!m`Fa=;fwSrjblp0h1$AQrR5GlCjQ{x*DX0yu(}YkW z9TVFl79L<=aJE#BpU;S;Uf`}psT^A?B?bL;5uc=9*7+y&Yf-kh<;ZUlTtitEZ(J0u zQL#%zT4vteU(s2&#*47z(H3@vgK)h3@xFJOd87I0QAJuuWlsQD*gj7hA54LdQRCwBaQ?X7%F${E^JPKlfg_Vhc zmH+>d&afkaglJ!067HP14VA!ANpLRqo$VK%?q8aQC?TlSRwU__v{r>an!+Ej)_Rl} zl9aaDJ+Zm2qWt4d0%%DW+arQh_zS=cxB<&x4U5J-WkjwBpm@y7Q&#*Kv_r*icrGp5 zf4Lkia9VU{bQVx2eP-eAb`I1mL1{~uiiDJ<1nuID0V(A=-I@fR3FMEDnSeVbQ>t@Q z0_h~sE|Bf8eOWf@?!IDlOU=f{^kXL`%{15YJ&M?~G5BoW87n##dLimG9pF-UZq|W* zK7y5ZXl7wGuppB@r|Yv}^7xQzwAF*8Q%|XBWaoLqN?2Y4;~W0nHmDh34AxruB=X^T#QS7w7*j_uDOpEG#yXb!F6|eC7JBq5`2la= z-#+*C^1tRDde02BE*R334L Qc>n+a07*qoM6N<$g6-PZ9smFU literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/thaumium_crucible_4.png b/src/main/resources/assets/thaummach/textures/blocks/thaumium_crucible_4.png new file mode 100644 index 0000000000000000000000000000000000000000..08a11ac57c62cf83c642c92e043636ce72d5c818 GIT binary patch literal 151 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XEInNuLn>}1O?eRZ=R5+zGH%!Ja0nzY#I^}dOxbYD184|?r>mdKI;Vst0CIXS8~^|S literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/thaumium_crucible_5.png b/src/main/resources/assets/thaummach/textures/blocks/thaumium_crucible_5.png new file mode 100644 index 0000000000000000000000000000000000000000..9949878d85ddca0ad52c3f9abb2885ef91796b55 GIT binary patch literal 583 zcmV-N0=WH&P)G;L;HZ}=n2t=+@Lcd_{}FF@?_g;GflLetoQ1QF z@U(kgS~?iBD}fxAG~DpKY}O1kN4g!hIEKI^JpnWNY0v!#6U9YZdT_&i=4DTZT^aGC zzrSJ)EO9}5B9oCxK(aCSWXC|!)2C88TYEsCkIqKgXsoEsz(AokWH(EPm=RS^o+t1K z3ym92q^Dpd6@Ua2?U{b^kDRh6`kN3!OrUC1{df_v#r^4vBQ@N2w()!K7AMnDy>Pyh z`ueU8OsG=i_<8>UpB~u3w{#9h6HT60nL|fz3+@#RDz0ZcwYlXgAzlX`e+q-@EWClgX^2CyJ$Yx=^b+ z_#4RC%kU0xt!3$D+9~hZo{V*K<1I|le0651;@Tg2M7JNt9bzN{wT!<74%1J^+aA9C zR_`z4N%ySiKQRJDed_g!=v`W2+y6UQN literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/thaumium_crucible_6.png b/src/main/resources/assets/thaummach/textures/blocks/thaumium_crucible_6.png new file mode 100644 index 0000000000000000000000000000000000000000..2fc3b1ee3889765ee9ac63c87feef2e988fcfcfb GIT binary patch literal 579 zcmV-J0=)f+P)P_`7h;v>_&7!`O zT8qqilqo+*A1-94k0jMuf>X(LF+bm?GK&{j`^X10^$`z>ytw}$uYSCf7zQE8f&hnA zv6{K7{#lJcjiE<^Xb%H+ANI0~m$<7T9j03;2ux+PE~$$lH#gx>vdiqY-XjfJT8FI&(jjNo*Ih{oxcaP z@b&(!b%?nLLIIno4Op!NS1nLoXAZWCj1KeHGwoHh^*fi9iDcT)!#2XpMy=^Un{&1@ z7`O^4=gHJDAJLvH`}oA#$(bmduvNixx@ z4$muRMFGV2d-i$<^Z{dhH~l-9_I>=~I2RZ3u?c*Zl>dqUHNNFEQj=c-3;;+#8KPk} RB)9+o002ovPDHLkV1j340wn+d literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/thaumium_crucible_7.png b/src/main/resources/assets/thaummach/textures/blocks/thaumium_crucible_7.png new file mode 100644 index 0000000000000000000000000000000000000000..6443848273e69d062a2c86f2d9a87d167b721ebd GIT binary patch literal 338 zcmV-Y0j>UtP)5-Xlab&c({xW8|!)hE(p0#Htk5l1j~|Ny3EL>88q^dTXX^k k8bFqr?DO=>D}MqE0KJ2V0s`M*ga7~l07*qoM6N<$f`G!5<^TWy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/void_chest_bottom.png b/src/main/resources/assets/thaummach/textures/blocks/void_chest_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..5574d963f02722d726140ebe19b35d26c76fe2ec GIT binary patch literal 561 zcmV-10?z%3P)mt6 zsXz^xoq~KQ(pyC`xR+Y+6!7jJm-(hoXECM^s5M}Pp*bf2KI{xiYl>OQJT3@;O@vfD zG~&eBi6+l#*jkBYD|W)r{{l{({-7y{{$ES&vi^9g^qkw00000NkvXXu0mjfs@nXy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/void_chest_side.png b/src/main/resources/assets/thaummach/textures/blocks/void_chest_side.png new file mode 100644 index 0000000000000000000000000000000000000000..a1743a309eaba98a83c68825346d20ebf13f9d95 GIT binary patch literal 606 zcmV-k0-^nhP)wK@JkVcnU8=j+7LP(;yAt4P(E5pI4G7T}Npkfe5ixaYWkW%s{ zq#RO8!ys6hjW2&witG@*I9bOw;@;(eRKCa zgF$IG+ixiG!Sbf0{P_OM+4=(D&G!3H45Uf8q|_hYevUEv=y1sgmx~6gvhDzn(G`gA z&Oa5!pviN-JJ=RgQYf&UchK(k4^6$G0Il?He-B}Z?&;}Khv0{y=xmGAL~yqKGYRcs z4@zgBagPJdna*l4J9e%^C2rD7U=Vq*dlHN`ecy!`xEZ^KMrqV)xqfW_Aq-N~qpA?( zN|Aq=1!JnQsuX6`(qRS#RAn=@2^ee*!4;z+HD<)*vn#T5&r|2cdUd{QAMyw=MINfD z-=&!W!36Z~K+d8$ri^h+SIbivd)EPgeF(#u$rB0_8HfqMUt~7*3-RjYqW2btJhm0v s_AL#;s3CV_s+bv>*US0r=)V9105{iH1lxhq`2YX_07*qoM6N<$f=L4qB>(^b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/void_chest_side_transparent.png b/src/main/resources/assets/thaummach/textures/blocks/void_chest_side_transparent.png new file mode 100644 index 0000000000000000000000000000000000000000..fd8c718b9f4a49bcbdb4d43a360fdbae8fe5ee3a GIT binary patch literal 740 zcmV~tM$uW`RIQDwIe6vmHk&#BbJD$fk z^NrQT(iBt!vJ3DhHfPi}P+26>f(Amt zCx5z|)bq#gPC(p<687nEmlK+UZ@c`<(L4U3`-V4RC%<3)qkW1M6#Tn?w1X;=217zg z2sQ~hk!-GS`Hi&)p5T8!`Miln`jkijju%1=*Kgi?j&b$anS?uL6iy7RxBvAuZ^m;y z6uWfe>c(S+<^+wTw0R4>{yaQBxO^7RyHfeeXF?sxdo2H6#8G1#g_JnnexHdyIcSNy1}T4D#Z(Tx%2 z5XVvL+<1}_Ymb&Xt6N2x*JxQQ;!>+9!pAiw)jaNZF{l)j(o&3VHNg+UEq8no=p5Q# zO~->}qoYQm=9!}9K_&^M?5jvnLH(o{3F}I1Y1;v%;IuDXaQLGQXOei1VJFyM0R{l= WZ%uPTWlJXj00001r;P)=TMeU4 zrIftKptYI9GzV|B($3b_I^0Pcr8LpJ0LUd<<1n15b4e*jlcEKR2GN9)ZQEY~hVFl)Ev4wCN`w-@c|8804CIp2xf+)9@HfVp7E`)R zH|EG?LF!jmH{XBXGf@COOz4Jw8BtecJW0zUWTu!1A`jQT+wPw4Uu>`G)%ETM7lI*$ zQMv>U`pFMV=G`P)?`S>bI-Ywy#MlK8>h8l#u&spYM_-C zQkMO&D5d9Rnip@BRE@F5G#p2zrBr0I10dyObVJZ+n{tdP=ok!84t~CT=b*JcNP?V_ zpD%6Oi<~chBqzq@@!^?*rqXELALV z!FO=m>f`u^F^~WNtNN2=D7uCi z>Opx?D~9v(E)!mt;-MHIE{mz^CUNE=@VvDFT!T+P{{0fhdEP)ZW9^aQApa2PaUZP}QG!*=-S<7|CLV=hu6bRRPUFLorihWoeG}@uv4LHdg_( zuFKzX@Lufj@O0bzVt*8GlN^jDXl;W@KPN2J-dPj+_LooJF& zBcw%4mN8K%w5-H2IV^Dz=N*iWf*t9YeGBVaXs)3=JN1Gn1xoEHA^v*jxX?2g^>;0{ z#GJE1W!*0K*B^prPhgH#Yb=xOn*&aC9LRwo2LdM?bnn7QvT5s3bm$hu{&@@HOS3Nl Z1^}6ctxUNw_Q?PM002ovPDHLkV1hfjpc4Q9 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/models/conduit_pump.png b/src/main/resources/assets/thaummach/textures/models/conduit_pump.png new file mode 100644 index 0000000000000000000000000000000000000000..a743f905961187dd9c7e453ca002a6d6b4f65d87 GIT binary patch literal 3809 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