From 7e027da804202ec915fced753528fba74f14d5e0 Mon Sep 17 00:00:00 2001 From: Sebastian Hartte Date: Mon, 29 Aug 2016 09:47:17 +0200 Subject: [PATCH] Reimplemented cable and parts rendering. --- src/api/java/appeng/api/AEInjectable.java | 17 + src/api/java/appeng/api/AEPlugin.java | 20 + src/api/java/appeng/api/IAppEngApi.java | 2 +- .../api/features/IRegistryContainer.java | 8 + src/api/java/appeng/api/parts/BusSupport.java | 5 +- .../java/appeng/api/parts/IFacadePart.java | 11 - src/api/java/appeng/api/parts/IPart.java | 40 +- .../java/appeng/api/parts/IPartModels.java | 35 + src/api/java/appeng/api/util/AECableType.java | 43 +- src/api/java/appeng/api/util/AEColor.java | 51 ++ .../block/networking/BlockCableBus.java | 91 ++- .../block/networking/CableBusColor.java | 30 +- .../CableBusRenderStateProperty.java | 37 + .../block/networking/CableBusRendering.java | 36 +- .../java/appeng/bootstrap/BlockRendering.java | 4 +- src/main/java/appeng/client/ClientHelper.java | 82 +-- .../render/ColorableTileBlockColor.java | 11 +- .../appeng/client/render/StaticItemColor.java | 11 +- .../client/render/cablebus/CableBuilder.java | 673 ++++++++++++++++++ .../render/cablebus/CableBusBakedModel.java | 260 +++++++ .../client/render/cablebus/CableBusModel.java | 94 +++ .../render/cablebus/CableBusRenderState.java | 116 +++ .../client/render/cablebus/CableCoreType.java | 35 + .../client/render/cablebus/CubeBuilder.java | 275 +++++++ .../client/render/cablebus/QuadRotator.java | 169 +++++ .../render/cablebus/SmartCableTextures.java | 81 +++ .../render/model/AutoRotatingCacheKey.java | 71 ++ .../render/model/AutoRotatingModel.java | 276 +++++++ .../model/CachingRotatingBakedModel.java | 96 --- .../client/render/model/ModelCompass.java | 119 ---- .../client/render/model/ModelsCache.java | 119 ---- .../client/render/model/RenderHelper.java | 2 +- .../pipeline/BakingPipelineBakedModel.java | 72 -- .../pipeline/DoubleFacingQuadRotator.java | 117 --- .../model/pipeline/FacingQuadRotator.java | 39 - .../model/pipeline/MatVecApplicator.java | 141 ---- .../client/render/model/pipeline/Merge.java | 37 - .../render/model/pipeline/ParentQuads.java | 21 - .../render/model/pipeline/QuadVertexData.java | 121 ---- .../model/pipeline/StatePosRecolorator.java | 71 -- .../model/pipeline/TintIndexModifier.java | 45 -- .../model/pipeline/TypeTransformer.java | 62 -- .../pipeline/cable/CableAndConnections.java | 53 -- .../render/model/pipeline/cable/Facades.java | 55 -- .../render/model/pipeline/cable/Parts.java | 55 -- src/main/java/appeng/core/Api.java | 3 +- src/main/java/appeng/core/ApiDefinitions.java | 8 +- src/main/java/appeng/core/AppEng.java | 10 +- src/main/java/appeng/core/CommonHelper.java | 3 +- src/main/java/appeng/core/PluginLoader.java | 146 ++++ src/main/java/appeng/core/Registration.java | 3 - src/main/java/appeng/core/api/ApiPart.java | 46 +- .../core/api/definitions/ApiBlocks.java | 17 +- .../appeng/core/api/definitions/ApiParts.java | 14 +- .../core/features/registries/PartModels.java | 40 ++ .../registries/RegistryContainer.java | 9 + src/main/java/appeng/facade/FacadePart.java | 133 ---- .../appeng/items/parts/ItemMultiPart.java | 5 +- .../items/parts/ItemMultipartRendering.java | 58 +- .../java/appeng/items/parts/PartModels.java | 21 + .../java/appeng/items/parts/PartType.java | 139 +++- src/main/java/appeng/parts/AEBasePart.java | 44 -- .../java/appeng/parts/CableBusContainer.java | 95 ++- .../java/appeng/parts/ICableBusContainer.java | 4 + .../appeng/parts/NullCableBusContainer.java | 8 + .../automation/PartAnnihilationPlane.java | 91 +++ .../parts/automation/PartExportBus.java | 41 ++ .../parts/automation/PartFormationPlane.java | 91 +++ .../PartIdentityAnnihilationPlane.java | 17 + .../parts/automation/PartImportBus.java | 43 ++ .../parts/automation/PartLevelEmitter.java | 44 +- .../parts/automation/PlaneBakedModel.java | 104 +++ .../parts/automation/PlaneConnections.java | 121 ++++ .../appeng/parts/automation/PlaneModel.java | 66 ++ .../appeng/parts/automation/PlaneModels.java | 79 ++ .../appeng/parts/misc/PartCableAnchor.java | 17 - .../java/appeng/parts/misc/PartInterface.java | 39 + .../parts/misc/PartInvertedToggleBus.java | 34 +- .../appeng/parts/misc/PartStorageBus.java | 41 ++ .../java/appeng/parts/misc/PartToggleBus.java | 43 +- .../appeng/parts/networking/PartCable.java | 98 +-- .../parts/networking/PartQuartzFiber.java | 14 + src/main/java/appeng/parts/p2p/P2PModels.java | 60 ++ .../java/appeng/parts/p2p/PartP2PItems.java | 17 + .../java/appeng/parts/p2p/PartP2PLight.java | 18 + .../java/appeng/parts/p2p/PartP2PLiquids.java | 17 + .../appeng/parts/p2p/PartP2PRedstone.java | 19 + .../appeng/parts/p2p/PartP2PTunnelME.java | 18 + .../parts/reporting/AbstractPartDisplay.java | 16 + .../parts/reporting/AbstractPartMonitor.java | 133 ++-- .../parts/reporting/AbstractPartPanel.java | 7 + .../reporting/AbstractPartReporting.java | 18 + .../reporting/PartConversionMonitor.java | 30 + .../parts/reporting/PartCraftingTerminal.java | 22 + .../appeng/parts/reporting/PartDarkPanel.java | 24 +- .../reporting/PartInterfaceTerminal.java | 24 + .../appeng/parts/reporting/PartPanel.java | 23 +- .../parts/reporting/PartPatternTerminal.java | 21 + .../parts/reporting/PartSemiDarkPanel.java | 23 +- .../parts/reporting/PartStorageMonitor.java | 33 +- .../appeng/parts/reporting/PartTerminal.java | 23 + src/main/java/appeng/server/ServerHelper.java | 2 +- .../appeng/tile/networking/CableBusTESR.java | 34 + .../appeng/tile/networking/TileCableBus.java | 22 + .../tile/networking/TileCableBusTESR.java | 30 + .../java/appeng/util/item/AEItemStack.java | 9 +- .../blockstates/cable_bus.json | 5 + .../models/block/chest/lights_off.json | 2 +- .../models/block/chest/lights_on.json | 6 +- .../models/block/security_station_off.json | 6 +- .../models/block/security_station_on.json | 6 +- .../item/part/cable_covered_lightgray.json | 2 +- .../item/part/cable_dense_lightgray.json | 2 +- .../item/part/cable_glass_lightgray.json | 2 +- .../models/item/part/cable_smart_base.json | 30 +- .../item/part/cable_smart_lightgray.json | 2 +- .../models/item/part/crafting_terminal.json | 6 +- .../models/item/part/dark_monitor.json | 2 +- .../models/item/part/display.json | 13 +- .../models/item/part/export_bus.json | 2 +- .../models/item/part/import_bus.json | 2 +- .../models/item/part/semi_dark_monitor.json | 5 +- .../models/part/annihilation_plane.json | 32 - .../models/part/cable/glass/center.json | 2 +- .../models/part/cable/glass/connection.json | 2 +- .../models/part/cable/glass/straight.json | 2 +- .../part/conversion_monitor_locked_off.json | 8 + .../part/conversion_monitor_locked_on.json | 31 + .../models/part/conversion_monitor_off.json | 8 + .../models/part/conversion_monitor_on.json | 31 + .../models/part/crafting_terminal_off.json | 8 + .../models/part/crafting_terminal_on.json | 31 + .../models/part/display_base.json | 33 + .../models/part/display_off.json | 30 + .../part/display_status_has_channel.json | 18 + .../models/part/display_status_off.json | 17 + .../models/part/display_status_on.json | 18 + .../models/part/export_bus_base.json | 57 ++ .../models/part/export_bus_has_channel.json | 18 + .../models/part/export_bus_off.json | 17 + .../models/part/export_bus_on.json | 18 + .../models/part/import_bus_base.json | 57 ++ .../models/part/import_bus_has_channel.json | 18 + .../models/part/import_bus_off.json | 17 + .../models/part/import_bus_on.json | 18 + .../models/part/interface_base.json | 45 ++ .../models/part/interface_has_channel.json | 18 + .../models/part/interface_off.json | 17 + .../models/part/interface_on.json | 18 + .../models/part/interface_terminal_off.json | 8 + .../models/part/interface_terminal_on.json | 31 + .../models/part/inverted_toggle_bus_base.json | 6 + .../models/part/level_emitter_base_off.json | 18 + .../models/part/level_emitter_base_on.json | 45 ++ .../level_emitter_status_has_channel.json | 18 + .../models/part/level_emitter_status_off.json | 17 + .../models/part/level_emitter_status_on.json | 18 + .../models/part/monitor_base.json | 33 + .../models/part/monitor_bright_off.json | 14 + .../models/part/monitor_bright_on.json | 17 + .../models/part/monitor_dark_off.json | 14 + .../models/part/monitor_dark_on.json | 15 + .../models/part/monitor_medium_off.json | 14 + .../models/part/monitor_medium_on.json | 15 + .../models/part/p2p/p2p_tunnel_base.json | 62 ++ .../models/part/p2p/p2p_tunnel_items.json | 6 + .../models/part/p2p/p2p_tunnel_light.json | 6 + .../models/part/p2p/p2p_tunnel_liquids.json | 6 + .../models/part/p2p/p2p_tunnel_me.json | 6 + .../models/part/p2p/p2p_tunnel_redstone.json | 6 + .../p2p/p2p_tunnel_status_has_channel.json | 18 + .../part/p2p/p2p_tunnel_status_off.json | 17 + .../models/part/p2p/p2p_tunnel_status_on.json | 18 + .../models/part/pattern_terminal_off.json | 8 + .../models/part/pattern_terminal_on.json | 31 + .../models/part/quartz_fiber.json | 19 + .../models/part/storage_bus_base.json | 55 ++ .../models/part/storage_bus_has_channel.json | 18 + .../models/part/storage_bus_off.json | 17 + .../models/part/storage_bus_on.json | 18 + .../part/storage_monitor_locked_off.json | 8 + .../part/storage_monitor_locked_on.json | 31 + .../models/part/storage_monitor_off.json | 8 + .../models/part/storage_monitor_on.json | 31 + .../models/part/terminal_off.json | 8 + .../models/part/terminal_on.json | 31 + .../models/part/toggle_bus_base.json | 40 ++ .../part/toggle_bus_status_has_channel.json | 18 + .../models/part/toggle_bus_status_off.json | 17 + .../models/part/toggle_bus_status_on.json | 18 + .../part/transition_plane_has_channel.json | 31 + .../models/part/transition_plane_off.json | 30 + .../models/part/transition_plane_on.json | 31 + .../textures/items/part/p2p_tunnel_back2.png | Bin 284 -> 2866 bytes ...cmeta => annihilation_plane_on.png.mcmeta} | 0 .../Black.png => core/covered/black.png} | Bin .../Blue.png => core/covered/blue.png} | Bin .../Brown.png => core/covered/brown.png} | Bin .../Cyan.png => core/covered/cyan.png} | Bin .../Gray.png => core/covered/gray.png} | Bin .../Green.png => core/covered/green.png} | Bin .../covered/lightblue.png} | Bin .../covered/lightgray.png} | Bin .../Lime.png => core/covered/lime.png} | Bin .../Magenta.png => core/covered/magenta.png} | Bin .../Orange.png => core/covered/orange.png} | Bin .../Pink.png => core/covered/pink.png} | Bin .../Purple.png => core/covered/purple.png} | Bin .../{covered/Red.png => core/covered/red.png} | Bin .../covered/transparent.png} | Bin .../White.png => core/covered/white.png} | Bin .../Yellow.png => core/covered/yellow.png} | Bin .../textures/parts/cable/core/dense/black.png | Bin 0 -> 286 bytes .../textures/parts/cable/core/dense/blue.png | Bin 0 -> 280 bytes .../textures/parts/cable/core/dense/brown.png | Bin 0 -> 290 bytes .../textures/parts/cable/core/dense/cyan.png | Bin 0 -> 295 bytes .../textures/parts/cable/core/dense/gray.png | Bin 0 -> 278 bytes .../textures/parts/cable/core/dense/green.png | Bin 0 -> 296 bytes .../parts/cable/core/dense/lightblue.png | Bin 0 -> 288 bytes .../parts/cable/core/dense/lightgray.png | Bin 0 -> 284 bytes .../textures/parts/cable/core/dense/lime.png | Bin 0 -> 283 bytes .../parts/cable/core/dense/magenta.png | Bin 0 -> 288 bytes .../parts/cable/core/dense/orange.png | Bin 0 -> 288 bytes .../textures/parts/cable/core/dense/pink.png | Bin 0 -> 291 bytes .../parts/cable/core/dense/purple.png | Bin 0 -> 289 bytes .../textures/parts/cable/core/dense/red.png | Bin 0 -> 285 bytes .../parts/cable/core/dense/transparent.png | Bin 0 -> 300 bytes .../textures/parts/cable/core/dense/white.png | Bin 0 -> 283 bytes .../parts/cable/core/dense/yellow.png | Bin 0 -> 292 bytes .../{glass/Black.png => core/glass/black.png} | Bin .../{glass/Blue.png => core/glass/blue.png} | Bin .../{glass/Brown.png => core/glass/brown.png} | Bin .../{glass/Cyan.png => core/glass/cyan.png} | Bin .../{glass/Gray.png => core/glass/gray.png} | Bin .../{glass/Green.png => core/glass/green.png} | Bin .../glass/lightblue.png} | Bin .../glass/lightgray.png} | Bin .../{glass/Lime.png => core/glass/lime.png} | Bin .../Magenta.png => core/glass/magenta.png} | Bin .../Orange.png => core/glass/orange.png} | Bin .../{glass/Pink.png => core/glass/pink.png} | Bin .../Purple.png => core/glass/purple.png} | Bin .../{glass/Red.png => core/glass/red.png} | Bin .../glass/transparent.png} | Bin .../{glass/White.png => core/glass/white.png} | Bin .../Yellow.png => core/glass/yellow.png} | Bin .../textures/parts/cable/covered/black.png | Bin 0 -> 366 bytes .../textures/parts/cable/covered/blue.png | Bin 0 -> 360 bytes .../textures/parts/cable/covered/brown.png | Bin 0 -> 384 bytes .../textures/parts/cable/covered/cyan.png | Bin 0 -> 367 bytes .../textures/parts/cable/covered/gray.png | Bin 0 -> 366 bytes .../textures/parts/cable/covered/green.png | Bin 0 -> 377 bytes .../parts/cable/covered/lightblue.png | Bin 0 -> 363 bytes .../parts/cable/covered/lightgray.png | Bin 0 -> 361 bytes .../textures/parts/cable/covered/lime.png | Bin 0 -> 367 bytes .../textures/parts/cable/covered/magenta.png | Bin 0 -> 370 bytes .../textures/parts/cable/covered/orange.png | Bin 0 -> 367 bytes .../textures/parts/cable/covered/pink.png | Bin 0 -> 353 bytes .../textures/parts/cable/covered/purple.png | Bin 0 -> 365 bytes .../textures/parts/cable/covered/red.png | Bin 0 -> 378 bytes .../parts/cable/covered/transparent.png | Bin 0 -> 304 bytes .../textures/parts/cable/covered/white.png | Bin 0 -> 361 bytes .../textures/parts/cable/covered/yellow.png | Bin 0 -> 368 bytes .../cable/dense/{Black.png => black.png} | Bin .../parts/cable/dense/{Blue.png => blue.png} | Bin .../cable/dense/{Brown.png => brown.png} | Bin .../parts/cable/dense/{Cyan.png => cyan.png} | Bin .../parts/cable/dense/{Gray.png => gray.png} | Bin .../cable/dense/{Green.png => green.png} | Bin .../dense/{LightBlue.png => lightblue.png} | Bin .../dense/{LightGrey.png => lightgray.png} | Bin .../parts/cable/dense/{Lime.png => lime.png} | Bin .../cable/dense/{Magenta.png => magenta.png} | Bin .../cable/dense/{Orange.png => orange.png} | Bin .../parts/cable/dense/{Pink.png => pink.png} | Bin .../cable/dense/{Purple.png => purple.png} | Bin .../parts/cable/dense/{Red.png => red.png} | Bin .../{Transparent.png => transparent.png} | Bin .../cable/dense/{White.png => white.png} | Bin .../cable/dense/{Yellow.png => yellow.png} | Bin .../textures/parts/cable/glass/black.png | Bin 0 -> 441 bytes .../textures/parts/cable/glass/blue.png | Bin 0 -> 441 bytes .../textures/parts/cable/glass/brown.png | Bin 0 -> 441 bytes .../textures/parts/cable/glass/cyan.png | Bin 0 -> 377 bytes .../textures/parts/cable/glass/gray.png | Bin 0 -> 369 bytes .../textures/parts/cable/glass/green.png | Bin 0 -> 391 bytes .../textures/parts/cable/glass/lightblue.png | Bin 0 -> 377 bytes .../textures/parts/cable/glass/lightgray.png | Bin 0 -> 370 bytes .../textures/parts/cable/glass/lime.png | Bin 0 -> 441 bytes .../textures/parts/cable/glass/magenta.png | Bin 0 -> 376 bytes .../textures/parts/cable/glass/orange.png | Bin 0 -> 378 bytes .../textures/parts/cable/glass/pink.png | Bin 0 -> 373 bytes .../textures/parts/cable/glass/purple.png | Bin 0 -> 380 bytes .../textures/parts/cable/glass/red.png | Bin 0 -> 441 bytes .../parts/cable/glass/transparent.png | Bin 0 -> 394 bytes .../textures/parts/cable/glass/white.png | Bin 0 -> 441 bytes .../textures/parts/cable/glass/yellow.png | Bin 0 -> 441 bytes .../textures/parts/cable/smart/1.png | Bin 2942 -> 0 bytes .../textures/parts/cable/smart/2.png | Bin 2946 -> 0 bytes .../textures/parts/cable/smart/3.png | Bin 2947 -> 0 bytes .../textures/parts/cable/smart/4.png | Bin 2942 -> 0 bytes .../textures/parts/cable/smart/5.png | Bin 2944 -> 0 bytes .../textures/parts/cable/smart/6.png | Bin 2940 -> 0 bytes .../textures/parts/cable/smart/7.png | Bin 2939 -> 0 bytes .../cable/smart/{Black.png => black.png} | Bin .../parts/cable/smart/{Blue.png => blue.png} | Bin .../cable/smart/{Brown.png => brown.png} | Bin .../parts/cable/smart/channels_00.png | Bin 0 -> 677 bytes .../parts/cable/smart/channels_01.png | Bin 0 -> 469 bytes .../parts/cable/smart/channels_02.png | Bin 0 -> 546 bytes .../parts/cable/smart/channels_03.png | Bin 0 -> 558 bytes .../parts/cable/smart/channels_04.png | Bin 0 -> 477 bytes .../parts/cable/smart/channels_10.png | Bin 0 -> 493 bytes .../parts/cable/smart/channels_11.png | Bin 0 -> 539 bytes .../parts/cable/smart/channels_12.png | Bin 0 -> 503 bytes .../parts/cable/smart/channels_13.png | Bin 0 -> 536 bytes .../parts/cable/smart/channels_14.png | Bin 0 -> 529 bytes .../parts/cable/smart/{Cyan.png => cyan.png} | Bin .../parts/cable/smart/{Gray.png => gray.png} | Bin .../cable/smart/{Green.png => green.png} | Bin .../smart/{LightBlue.png => lightblue.png} | Bin .../smart/{LightGrey.png => lightgray.png} | Bin .../parts/cable/smart/{Lime.png => lime.png} | Bin .../cable/smart/{Magenta.png => magenta.png} | Bin .../cable/smart/{Orange.png => orange.png} | Bin .../parts/cable/smart/{Pink.png => pink.png} | Bin .../cable/smart/{Purple.png => purple.png} | Bin .../parts/cable/smart/{Red.png => red.png} | Bin .../{Transparent.png => transparent.png} | Bin .../cable/smart/{White.png => white.png} | Bin .../cable/smart/{Yellow.png => yellow.png} | Bin .../parts/conversion_monitor_dark.png | Bin 205 -> 218 bytes .../parts/conversion_monitor_medium.png | Bin 218 -> 205 bytes ...g => conversion_monitor_medium_locked.png} | Bin .../parts/crafting_terminal_bright.png | Bin 0 -> 256 bytes .../textures/parts/crafting_terminal_dark.png | Bin 0 -> 257 bytes .../parts/crafting_terminal_medium.png | Bin 0 -> 281 bytes ...{export_sides.png => export_bus_sides.png} | Bin .../textures/parts/formation_plane_on.png | Bin 0 -> 306 bytes .../parts/formation_plane_on.png.mcmeta | 23 + .../parts/identity_annihilation_plane_on.png | Bin 0 -> 337 bytes .../identity_annihilation_plane_on.png.mcmeta | 23 + ...{import_sides.png => import_bus_sides.png} | Bin .../parts/interface_terminal_dark.png | Bin 232 -> 205 bytes .../parts/interface_terminal_medium.png | Bin 205 -> 232 bytes .../smart/8.png => level_emitter_off.png} | Bin 2926 -> 2839 bytes .../smart/0.png => level_emitter_on.png} | Bin 2933 -> 2852 bytes .../monitor_front.png} | Bin 244 -> 244 bytes .../textures/parts/monitor_light.png | Bin 0 -> 235 bytes .../monitor_sides_status_has_channel.png | Bin 0 -> 141 bytes .../parts/monitor_sides_status_on.png | Bin 272 -> 142 bytes .../textures/parts/pattern_terminal_dark.png | Bin 261 -> 247 bytes .../parts/pattern_terminal_medium.png | Bin 247 -> 261 bytes .../textures/parts/storage_monitor_dark.png | Bin 218 -> 205 bytes ...ed.png => storage_monitor_dark_locked.png} | Bin .../textures/parts/storage_monitor_medium.png | Bin 205 -> 218 bytes .../textures/parts/terminal_dark.png | Bin 238 -> 204 bytes .../textures/parts/terminal_medium.png | Bin 204 -> 238 bytes 358 files changed, 5964 insertions(+), 1901 deletions(-) create mode 100644 src/api/java/appeng/api/AEInjectable.java create mode 100644 src/api/java/appeng/api/AEPlugin.java create mode 100644 src/api/java/appeng/api/parts/IPartModels.java create mode 100644 src/main/java/appeng/block/networking/CableBusRenderStateProperty.java create mode 100644 src/main/java/appeng/client/render/cablebus/CableBuilder.java create mode 100644 src/main/java/appeng/client/render/cablebus/CableBusBakedModel.java create mode 100644 src/main/java/appeng/client/render/cablebus/CableBusModel.java create mode 100644 src/main/java/appeng/client/render/cablebus/CableBusRenderState.java create mode 100644 src/main/java/appeng/client/render/cablebus/CableCoreType.java create mode 100644 src/main/java/appeng/client/render/cablebus/CubeBuilder.java create mode 100644 src/main/java/appeng/client/render/cablebus/QuadRotator.java create mode 100644 src/main/java/appeng/client/render/cablebus/SmartCableTextures.java create mode 100644 src/main/java/appeng/client/render/model/AutoRotatingCacheKey.java create mode 100644 src/main/java/appeng/client/render/model/AutoRotatingModel.java delete mode 100644 src/main/java/appeng/client/render/model/CachingRotatingBakedModel.java delete mode 100644 src/main/java/appeng/client/render/model/ModelCompass.java delete mode 100644 src/main/java/appeng/client/render/model/ModelsCache.java delete mode 100644 src/main/java/appeng/client/render/model/pipeline/BakingPipelineBakedModel.java delete mode 100644 src/main/java/appeng/client/render/model/pipeline/DoubleFacingQuadRotator.java delete mode 100644 src/main/java/appeng/client/render/model/pipeline/FacingQuadRotator.java delete mode 100644 src/main/java/appeng/client/render/model/pipeline/MatVecApplicator.java delete mode 100644 src/main/java/appeng/client/render/model/pipeline/Merge.java delete mode 100644 src/main/java/appeng/client/render/model/pipeline/ParentQuads.java delete mode 100644 src/main/java/appeng/client/render/model/pipeline/QuadVertexData.java delete mode 100644 src/main/java/appeng/client/render/model/pipeline/StatePosRecolorator.java delete mode 100644 src/main/java/appeng/client/render/model/pipeline/TintIndexModifier.java delete mode 100644 src/main/java/appeng/client/render/model/pipeline/TypeTransformer.java delete mode 100644 src/main/java/appeng/client/render/model/pipeline/cable/CableAndConnections.java delete mode 100644 src/main/java/appeng/client/render/model/pipeline/cable/Facades.java delete mode 100644 src/main/java/appeng/client/render/model/pipeline/cable/Parts.java create mode 100644 src/main/java/appeng/core/PluginLoader.java create mode 100644 src/main/java/appeng/core/features/registries/PartModels.java create mode 100644 src/main/java/appeng/items/parts/PartModels.java create mode 100644 src/main/java/appeng/parts/automation/PlaneBakedModel.java create mode 100644 src/main/java/appeng/parts/automation/PlaneConnections.java create mode 100644 src/main/java/appeng/parts/automation/PlaneModel.java create mode 100644 src/main/java/appeng/parts/automation/PlaneModels.java create mode 100644 src/main/java/appeng/parts/p2p/P2PModels.java create mode 100644 src/main/java/appeng/tile/networking/CableBusTESR.java create mode 100644 src/main/java/appeng/tile/networking/TileCableBusTESR.java create mode 100644 src/main/resources/assets/appliedenergistics2/blockstates/cable_bus.json delete mode 100644 src/main/resources/assets/appliedenergistics2/models/part/annihilation_plane.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/conversion_monitor_locked_off.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/conversion_monitor_locked_on.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/conversion_monitor_off.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/conversion_monitor_on.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/crafting_terminal_off.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/crafting_terminal_on.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/display_base.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/display_off.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/display_status_has_channel.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/display_status_off.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/display_status_on.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/export_bus_base.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/export_bus_has_channel.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/export_bus_off.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/export_bus_on.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/import_bus_base.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/import_bus_has_channel.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/import_bus_off.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/import_bus_on.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/interface_base.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/interface_has_channel.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/interface_off.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/interface_on.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/interface_terminal_off.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/interface_terminal_on.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/inverted_toggle_bus_base.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/level_emitter_base_off.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/level_emitter_base_on.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/level_emitter_status_has_channel.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/level_emitter_status_off.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/level_emitter_status_on.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/monitor_base.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/monitor_bright_off.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/monitor_bright_on.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/monitor_dark_off.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/monitor_dark_on.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/monitor_medium_off.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/monitor_medium_on.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_base.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_items.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_light.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_liquids.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_me.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_redstone.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_status_has_channel.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_status_off.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_status_on.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/pattern_terminal_off.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/pattern_terminal_on.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/quartz_fiber.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/storage_bus_base.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/storage_bus_has_channel.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/storage_bus_off.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/storage_bus_on.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/storage_monitor_locked_off.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/storage_monitor_locked_on.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/storage_monitor_off.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/storage_monitor_on.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/terminal_off.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/terminal_on.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/toggle_bus_base.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/toggle_bus_status_has_channel.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/toggle_bus_status_off.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/toggle_bus_status_on.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/transition_plane_has_channel.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/transition_plane_off.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/part/transition_plane_on.json rename src/main/resources/assets/appliedenergistics2/textures/parts/{annihilation_plane_on.mcmeta => annihilation_plane_on.png.mcmeta} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{covered/Black.png => core/covered/black.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{covered/Blue.png => core/covered/blue.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{covered/Brown.png => core/covered/brown.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{covered/Cyan.png => core/covered/cyan.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{covered/Gray.png => core/covered/gray.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{covered/Green.png => core/covered/green.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{covered/LightBlue.png => core/covered/lightblue.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{covered/LightGrey.png => core/covered/lightgray.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{covered/Lime.png => core/covered/lime.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{covered/Magenta.png => core/covered/magenta.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{covered/Orange.png => core/covered/orange.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{covered/Pink.png => core/covered/pink.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{covered/Purple.png => core/covered/purple.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{covered/Red.png => core/covered/red.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{covered/Transparent.png => core/covered/transparent.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{covered/White.png => core/covered/white.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{covered/Yellow.png => core/covered/yellow.png} (100%) create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/black.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/blue.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/brown.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/cyan.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/gray.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/green.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/lightblue.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/lightgray.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/lime.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/magenta.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/orange.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/pink.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/purple.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/red.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/transparent.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/white.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/yellow.png rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{glass/Black.png => core/glass/black.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{glass/Blue.png => core/glass/blue.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{glass/Brown.png => core/glass/brown.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{glass/Cyan.png => core/glass/cyan.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{glass/Gray.png => core/glass/gray.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{glass/Green.png => core/glass/green.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{glass/LightBlue.png => core/glass/lightblue.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{glass/LightGrey.png => core/glass/lightgray.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{glass/Lime.png => core/glass/lime.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{glass/Magenta.png => core/glass/magenta.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{glass/Orange.png => core/glass/orange.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{glass/Pink.png => core/glass/pink.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{glass/Purple.png => core/glass/purple.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{glass/Red.png => core/glass/red.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{glass/Transparent.png => core/glass/transparent.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{glass/White.png => core/glass/white.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/{glass/Yellow.png => core/glass/yellow.png} (100%) create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/black.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/blue.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/brown.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/cyan.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/gray.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/green.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/lightblue.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/lightgray.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/lime.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/magenta.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/orange.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/pink.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/purple.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/red.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/transparent.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/white.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/yellow.png rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/{Black.png => black.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/{Blue.png => blue.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/{Brown.png => brown.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/{Cyan.png => cyan.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/{Gray.png => gray.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/{Green.png => green.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/{LightBlue.png => lightblue.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/{LightGrey.png => lightgray.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/{Lime.png => lime.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/{Magenta.png => magenta.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/{Orange.png => orange.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/{Pink.png => pink.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/{Purple.png => purple.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/{Red.png => red.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/{Transparent.png => transparent.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/{White.png => white.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/{Yellow.png => yellow.png} (100%) create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/black.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/blue.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/brown.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/cyan.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/gray.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/green.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/lightblue.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/lightgray.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/lime.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/magenta.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/orange.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/pink.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/purple.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/red.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/transparent.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/white.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/yellow.png delete mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/1.png delete mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/2.png delete mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/3.png delete mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/4.png delete mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/5.png delete mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/6.png delete mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/7.png rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/{Black.png => black.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/{Blue.png => blue.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/{Brown.png => brown.png} (100%) create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/channels_00.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/channels_01.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/channels_02.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/channels_03.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/channels_04.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/channels_10.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/channels_11.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/channels_12.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/channels_13.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/channels_14.png rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/{Cyan.png => cyan.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/{Gray.png => gray.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/{Green.png => green.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/{LightBlue.png => lightblue.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/{LightGrey.png => lightgray.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/{Lime.png => lime.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/{Magenta.png => magenta.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/{Orange.png => orange.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/{Pink.png => pink.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/{Purple.png => purple.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/{Red.png => red.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/{Transparent.png => transparent.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/{White.png => white.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/{Yellow.png => yellow.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/{conversion_monitor_dark_locked.png => conversion_monitor_medium_locked.png} (100%) create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/crafting_terminal_bright.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/crafting_terminal_dark.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/crafting_terminal_medium.png rename src/main/resources/assets/appliedenergistics2/textures/parts/{export_sides.png => export_bus_sides.png} (100%) create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/formation_plane_on.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/formation_plane_on.png.mcmeta create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/identity_annihilation_plane_on.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/identity_annihilation_plane_on.png.mcmeta rename src/main/resources/assets/appliedenergistics2/textures/parts/{import_sides.png => import_bus_sides.png} (100%) rename src/main/resources/assets/appliedenergistics2/textures/parts/{cable/smart/8.png => level_emitter_off.png} (91%) rename src/main/resources/assets/appliedenergistics2/textures/parts/{cable/smart/0.png => level_emitter_on.png} (91%) rename src/main/resources/assets/appliedenergistics2/textures/{items/part/level_emitter_on.png => parts/monitor_front.png} (55%) create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/monitor_light.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/monitor_sides_status_has_channel.png rename src/main/resources/assets/appliedenergistics2/textures/parts/{storage_monitor_medium_locked.png => storage_monitor_dark_locked.png} (100%) diff --git a/src/api/java/appeng/api/AEInjectable.java b/src/api/java/appeng/api/AEInjectable.java new file mode 100644 index 00000000..6c9ab3da --- /dev/null +++ b/src/api/java/appeng/api/AEInjectable.java @@ -0,0 +1,17 @@ +package appeng.api; + + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +/** + * Marks interfaces that can be used as injectable constructor arguments for an {@link AEPlugin}. + */ +@Target( ElementType.TYPE ) +@Retention( RetentionPolicy.RUNTIME ) +public @interface AEInjectable +{ +} diff --git a/src/api/java/appeng/api/AEPlugin.java b/src/api/java/appeng/api/AEPlugin.java new file mode 100644 index 00000000..a855496f --- /dev/null +++ b/src/api/java/appeng/api/AEPlugin.java @@ -0,0 +1,20 @@ +package appeng.api; + + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +/** + * Use this annotation on a class in your Mod to have it instantiated during the initialization phase of Applied Energistics. + * AE expects your class to have a single constructor and can supply certain arguments to your constructor using dependency injection. + */ +@Target( ElementType.TYPE ) +@Retention( RetentionPolicy.RUNTIME ) +@Documented +public @interface AEPlugin +{ +} diff --git a/src/api/java/appeng/api/IAppEngApi.java b/src/api/java/appeng/api/IAppEngApi.java index 0956a260..7ef6a667 100644 --- a/src/api/java/appeng/api/IAppEngApi.java +++ b/src/api/java/appeng/api/IAppEngApi.java @@ -33,7 +33,7 @@ import appeng.api.networking.IGridNode; import appeng.api.parts.IPartHelper; import appeng.api.storage.IStorageHelper; - +@AEInjectable public interface IAppEngApi { /** diff --git a/src/api/java/appeng/api/features/IRegistryContainer.java b/src/api/java/appeng/api/features/IRegistryContainer.java index 9b3a7e10..688da9f2 100644 --- a/src/api/java/appeng/api/features/IRegistryContainer.java +++ b/src/api/java/appeng/api/features/IRegistryContainer.java @@ -24,8 +24,10 @@ package appeng.api.features; +import appeng.api.AEInjectable; import appeng.api.movable.IMovableRegistry; import appeng.api.networking.IGridCacheRegistry; +import appeng.api.parts.IPartModels; import appeng.api.storage.ICellRegistry; import appeng.api.storage.IExternalStorageRegistry; @@ -36,6 +38,7 @@ import appeng.api.storage.IExternalStorageRegistry; * @version rv2 * @since rv0 */ +@AEInjectable public interface IRegistryContainer { @@ -109,4 +112,9 @@ public interface IRegistryContainer * get access to the world-gen api. */ IWorldGen worldgen(); + + /** + * Register your IPart models before using them. + */ + IPartModels partModels(); } diff --git a/src/api/java/appeng/api/parts/BusSupport.java b/src/api/java/appeng/api/parts/BusSupport.java index 03c54de4..3f552620 100644 --- a/src/api/java/appeng/api/parts/BusSupport.java +++ b/src/api/java/appeng/api/parts/BusSupport.java @@ -28,7 +28,6 @@ public enum BusSupport { CABLE, - DENSE_CABLE, - - NO_PARTS + DENSE_CABLE + } diff --git a/src/api/java/appeng/api/parts/IFacadePart.java b/src/api/java/appeng/api/parts/IFacadePart.java index bcc27f8c..7984d1c8 100644 --- a/src/api/java/appeng/api/parts/IFacadePart.java +++ b/src/api/java/appeng/api/parts/IFacadePart.java @@ -24,19 +24,11 @@ package appeng.api.parts; -import java.util.List; - -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.entity.Entity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumFacing; import net.minecraft.util.math.AxisAlignedBB; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -import appeng.api.client.BakingPipeline; import appeng.api.util.AEPartLocation; @@ -80,7 +72,4 @@ public interface IFacadePart void setThinFacades( boolean useThinFacades ); boolean isTransparent(); - - @SideOnly( Side.CLIENT ) - public List getOrBakeQuads( IPartHost host, BakingPipeline rotatingPipeline, IBlockState state, EnumFacing side, long rand ); } \ No newline at end of file diff --git a/src/api/java/appeng/api/parts/IPart.java b/src/api/java/appeng/api/parts/IPart.java index 2ff5e2f4..5518b105 100644 --- a/src/api/java/appeng/api/parts/IPart.java +++ b/src/api/java/appeng/api/parts/IPart.java @@ -25,30 +25,29 @@ package appeng.api.parts; import java.io.IOException; +import java.util.Collections; import java.util.List; import java.util.Random; import io.netty.buffer.ByteBuf; -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; -import appeng.api.client.BakingPipeline; import appeng.api.networking.IGridNode; import appeng.api.util.AECableType; +import appeng.api.util.AEColor; import appeng.api.util.AEPartLocation; @@ -69,6 +68,15 @@ public interface IPart extends IBoxProvider, ICustomCableConnection */ ItemStack getItemStack( PartItemStack type ); + /** + * Render dynamic portions of this part, as part of the cable bus TESR. This part has to return true for {@link #requireDynamicRender()} in order for + * this method to be called. + */ + @SideOnly( Side.CLIENT ) + default void renderDynamic( double x, double y, double z, float partialTicks, int destroyStage ) + { + } + /** * return true only if your part require dynamic rendering, must be consistent. * @@ -255,7 +263,27 @@ public interface IPart extends IBoxProvider, ICustomCableConnection */ boolean canBePlacedOn( BusSupport what ); - @SideOnly( Side.CLIENT ) - public List getOrBakeQuads( BakingPipeline rotatingPipeline, IBlockState state, EnumFacing side, long rand ); + /** + * This method is used when a chunk is rebuilt to determine how this part should be rendered. The returned models should represent the + * part oriented north. They will be automatically rotated to match the part's actual orientation. Tint indices 1-4 can be used in the + * models to access the parts color. + * + *
+ *
Tint Index 1
+ *
The {@link AEColor#blackVariant dark variant color} of the cable that this part is attached to.
+ *
Tint Index 2
+ *
The {@link AEColor#mediumVariant color} of the cable that this part is attached to.
+ *
Tint Index 3
+ *
The {@link AEColor#whiteVariant bright variant color} of the cable that this part is attached to.
+ *
Tint Index 4
+ *
A color variant that is between the cable's {@link AEColor#mediumVariant color} and its {@link AEColor#whiteVariant bright variant}.
+ *
+ * + * Important: All models must have been registered via the {@link IPartModels} API before use. + */ + default List getStaticModels() + { + return Collections.emptyList(); + } } \ No newline at end of file diff --git a/src/api/java/appeng/api/parts/IPartModels.java b/src/api/java/appeng/api/parts/IPartModels.java new file mode 100644 index 00000000..f2f13bba --- /dev/null +++ b/src/api/java/appeng/api/parts/IPartModels.java @@ -0,0 +1,35 @@ +package appeng.api.parts; + + +import java.util.Arrays; +import java.util.Collection; + +import net.minecraft.util.ResourceLocation; + +import appeng.api.AEInjectable; + + +/** + * Allows registration of part models that can then be used in {@link IPart#getStaticModels()}. + */ +@AEInjectable +public interface IPartModels +{ + + /** + * Allows registration of part models that can then be used in {@link IPart#getStaticModels()}. + * + * Models can be registered multiple times without causing issues. + * + * This method must be called during the pre-init phase (as part of your plugin's constructor). + */ + void registerModels( Collection partModels ); + + /** + * Convenience overload of {@link #registerModels(Collection)} + */ + default void registerModels( ResourceLocation... partModels ) + { + registerModels( Arrays.asList( partModels ) ); + } +} diff --git a/src/api/java/appeng/api/util/AECableType.java b/src/api/java/appeng/api/util/AECableType.java index 39369247..e463f672 100644 --- a/src/api/java/appeng/api/util/AECableType.java +++ b/src/api/java/appeng/api/util/AECableType.java @@ -26,49 +26,61 @@ package appeng.api.util; import net.minecraft.util.ResourceLocation; +import appeng.client.render.cablebus.CableCoreType; +import appeng.core.AppEng; + public enum AECableType { /** * No Cable present. */ - NONE( null, 0 ), + NONE( null, 0, null, null ), /** * Connections to this block should render as glass. */ - GLASS( "glass", 0 ), + GLASS( "glass", 0, CableCoreType.GLASS, "parts/cable/glass/" ), /** * Connections to this block should render as covered. */ - COVERED( "covered", 0 ), + COVERED( "covered", 0, CableCoreType.COVERED, "parts/cable/covered/" ), /** * Connections to this block should render as smart. */ - SMART( "smart", 8 ), + SMART( "smart", 8, CableCoreType.COVERED, "parts/cable/smart/" ), /** * Dense Cable, represents a tier 2 block that can carry 32 channels. */ - DENSE( "dense", 32 ); + DENSE( "dense", 32, CableCoreType.DENSE, "parts/cable/dense/" ); - public static final AECableType[] VALIDCABLES = { GLASS, COVERED, SMART, DENSE }; + public static final AECableType[] VALIDCABLES = { + GLASS, + COVERED, + SMART, + DENSE + }; + private final CableCoreType coreType; private final String type; private final int displayedChannels; private final ResourceLocation model; private final ResourceLocation connectionModel; private final ResourceLocation straightModel; + private final String textureFolder; - private AECableType( String type, int displayedChannels ) + private AECableType( String type, int displayedChannels, CableCoreType coreType, String textureFolder ) { this.type = type; this.displayedChannels = displayedChannels; this.model = new ResourceLocation( "appliedenergistics2", "part/cable/" + type + "/center" ); this.connectionModel = new ResourceLocation( "appliedenergistics2", "part/cable/" + type + "/connection" ); this.straightModel = new ResourceLocation( "appliedenergistics2", "part/cable/" + type + "/straight" ); + this.coreType = coreType; + this.textureFolder = textureFolder; } public int displayedChannels() @@ -91,4 +103,21 @@ public enum AECableType return straightModel; } + /** + * @return The type of core that should be rendered when this cable isn't straight and needs to have a core to attach connections to. Is null for the NULL + * cable. + */ + public CableCoreType getCoreType() + { + return coreType; + } + + public ResourceLocation getConnectionTexture( AEColor color ) + { + if ( textureFolder == null ) { + throw new IllegalStateException( "Cable type " + name() + " does not support connections." ); + } + return new ResourceLocation( AppEng.MOD_ID, textureFolder + color.name().toLowerCase() ); + } + } diff --git a/src/api/java/appeng/api/util/AEColor.java b/src/api/java/appeng/api/util/AEColor.java index 0318fa8b..cd1cd509 100644 --- a/src/api/java/appeng/api/util/AEColor.java +++ b/src/api/java/appeng/api/util/AEColor.java @@ -27,6 +27,7 @@ package appeng.api.util; import java.util.Arrays; import java.util.List; +import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.item.EnumDyeColor; import net.minecraft.util.text.translation.I18n; @@ -75,6 +76,27 @@ public enum AEColor public static final List VALID_COLORS = Arrays.asList( White, Orange, Magenta, LightBlue, Yellow, Lime, Pink, Gray, LightGray, Cyan, Purple, Blue, Brown, Green, Red, Black ); + /** + * The {@link BakedQuad#getTintIndex() tint index} that can normally be used to get the {@link #blackVariant dark variant} of the apprioriate AE color. + */ + public static final int TINTINDEX_DARK = 1; + + /** + * The {@link BakedQuad#getTintIndex() tint index} that can normally be used to get the {@link #mediumVariant medium variant} of the apprioriate AE color. + */ + public static final int TINTINDEX_MEDIUM = 2; + + /** + * The {@link BakedQuad#getTintIndex() tint index} that can normally be used to get the {@link #whiteVariant bright variant} of the apprioriate AE color. + */ + public static final int TINTINDEX_BRIGHT = 3; + + /** + * The {@link BakedQuad#getTintIndex() tint index} that can normally be used to get a color between the {@link #mediumVariant medium} + * and {@link #whiteVariant bright variant} of the apprioriate AE color. + */ + public static final int TINTINDEX_MEDIUM_BRIGHT = 4; + /** * Unlocalized name for color. */ @@ -109,6 +131,35 @@ public enum AEColor this.dye = dye; } + /** + * Will return a variant of this color based on the given tint index. + * + * @param tintIndex A tint index as it can be used for {@link BakedQuad#getTintIndex()}. + * @return The appropriate color variant, or -1. + */ + public int getVariantByTintIndex( int tintIndex ) + { + switch( tintIndex ) + { + // Please note that tintindex 0 is hardcoded for the block breaking particles. Returning anything other than -1 for tintindex=0 here + // will cause issues with those particles + case 0: + return -1; + case TINTINDEX_DARK: + return blackVariant; + case TINTINDEX_MEDIUM: + return mediumVariant; + case TINTINDEX_BRIGHT: + return whiteVariant; + case TINTINDEX_MEDIUM_BRIGHT: + final int light = whiteVariant; + final int dark = mediumVariant; + return ( ( ( ( ( light >> 16 ) & 0xff ) + ( ( dark >> 16 ) & 0xff ) ) / 2 ) << 16 ) | ( ( ( ( ( light >> 8 ) & 0xff ) + ( ( dark >> 8 ) & 0xff ) ) / 2 ) << 8 ) | ( ( ( ( light ) & 0xff ) + ( ( dark ) & 0xff ) ) / 2 ); + default: + return -1; + } + } + /** * Logic to see which colors match each other.. special handle for Transparent */ diff --git a/src/main/java/appeng/block/networking/BlockCableBus.java b/src/main/java/appeng/block/networking/BlockCableBus.java index bd81a3d7..57d4b7dc 100644 --- a/src/main/java/appeng/block/networking/BlockCableBus.java +++ b/src/main/java/appeng/block/networking/BlockCableBus.java @@ -28,7 +28,11 @@ import net.minecraft.block.Block; import net.minecraft.block.properties.IProperty; import net.minecraft.block.state.BlockStateContainer; import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.particle.ParticleDigging; import net.minecraft.client.particle.ParticleManager; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; @@ -57,6 +61,8 @@ import appeng.api.parts.PartItemStack; import appeng.api.parts.SelectedPart; import appeng.api.util.AEColor; import appeng.block.AEBaseTileBlock; +import appeng.client.render.cablebus.CableBusBakedModel; +import appeng.client.render.cablebus.CableBusRenderState; import appeng.core.AEConfig; import appeng.core.Api; import appeng.core.features.AEFeature; @@ -68,15 +74,21 @@ import appeng.parts.ICableBusContainer; import appeng.parts.NullCableBusContainer; import appeng.tile.AEBaseTile; import appeng.tile.networking.TileCableBus; +import appeng.tile.networking.TileCableBusTESR; import appeng.util.Platform; public class BlockCableBus extends AEBaseTileBlock { + public static final CableBusRenderStateProperty RENDER_STATE_PROPERTY = new CableBusRenderStateProperty(); + private static final ICableBusContainer NULL_CABLE_BUS = new NullCableBusContainer(); + private static Class noTesrTile; + private static Class tesrTile; + public BlockCableBus() { super( AEGlassMaterial.INSTANCE ); @@ -89,8 +101,6 @@ public class BlockCableBus extends AEBaseTileBlock this.setTileEntity( TileCableBus.class ); } - public static final CableBusContainerUnlistedProperty cableBus = new CableBusContainerUnlistedProperty(); - @Override public boolean isFullCube( IBlockState state ) { @@ -100,14 +110,15 @@ public class BlockCableBus extends AEBaseTileBlock @Override protected BlockStateContainer createBlockState() { - return new ExtendedBlockState( this, new IProperty[0], new IUnlistedProperty[] { FORWARD, UP, cableBus } ); + return new ExtendedBlockState( this, new IProperty[0], new IUnlistedProperty[] { RENDER_STATE_PROPERTY } ); } @Override public IBlockState getExtendedState( IBlockState state, IBlockAccess world, BlockPos pos ) { - return ( (IExtendedBlockState) super.getExtendedState( state, world, pos ) ) - .withProperty( cableBus, ( (TileCableBus) world.getTileEntity( pos ) ).getCableBus() ); + CableBusRenderState renderState = cb( world, pos ).getRenderState(); + return ( (IExtendedBlockState) state ) + .withProperty( RENDER_STATE_PROPERTY, renderState ); } @Override @@ -274,24 +285,40 @@ public class BlockCableBus extends AEBaseTileBlock @Override public boolean addDestroyEffects( final World world, final BlockPos pos, final ParticleManager effectRenderer ) { - final Object object = this.cb( world, pos ); - if( object instanceof IPartHost ) - { - final IPartHost host = (IPartHost) object; + ICableBusContainer cb = this.cb( world, pos ); - // TODO DESTROY EFFECTS - /* - * for( AEPartLocation side : AEPartLocation.values() ) { IPart p = - * host.getPart( side ); TextureAtlasSprite ico = this.getIcon( p ); - * if( ico == null ) { continue; } byte b0 = 3; for( int i1 = 0; i1 - * < b0; ++i1 ) { for( int j1 = 0; j1 < b0; ++j1 ) { for( int k1 = - * 0; k1 < b0; ++k1 ) { double d0 = x + ( i1 + 0.5D ) / b0; double - * d1 = y + ( j1 + 0.5D ) / b0; double d2 = z + ( k1 + 0.5D ) / b0; - * EntityDiggingFX fx = ( new EntityDiggingFX( world, d0, d1, d2, d0 - * - x - 0.5D, d1 - y - 0.5D, d2 - z - 0.5D, this, meta ) - * ).applyColourMultiplier( x, y, z ); fx.setParticleIcon( ico ); - * effectRenderer.addEffect( fx ); } } } } - */ + // Our built-in model has the actual baked sprites we need + IBakedModel model = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState( getDefaultState() ); + + // We cannot add the effect if we dont have the model + if( !( model instanceof CableBusBakedModel ) ) + { + return true; + } + + CableBusBakedModel cableBusModel = (CableBusBakedModel) model; + + CableBusRenderState renderState = cb.getRenderState(); + + for( TextureAtlasSprite texture : cableBusModel.getParticleTextures( renderState ) ) + { + // Shamelessly inspired by ParticleManager.addBlockDestroyEffects + for( int j = 0; j < 4; ++j ) + { + for( int k = 0; k < 4; ++k ) + { + for( int l = 0; l < 4; ++l ) + { + double d0 = (double) pos.getX() + ( (double) j + 0.5D ) / 4.0D; + double d1 = (double) pos.getY() + ( (double) k + 0.5D ) / 4.0D; + double d2 = (double) pos.getZ() + ( (double) l + 0.5D ) / 4.0D; + ParticleDigging particle = new DestroyFX( world, d0, d1, d2, d0 - (double) pos.getX() - 0.5D, d1 - (double) pos.getY() - 0.5D, d2 - (double) pos.getZ() - 0.5D, getDefaultState() ) + .setBlockPos( pos ); + particle.setParticleTexture( texture ); + effectRenderer.addEffect( particle ); + } + } + } } return true; @@ -356,9 +383,14 @@ public class BlockCableBus extends AEBaseTileBlock public void setupTile() { - noTesrTile = Api.INSTANCE.partHelper().getCombinedInstance( TileCableBus.class.getName() ); + noTesrTile = Api.INSTANCE.partHelper().getCombinedInstance( TileCableBus.class ); this.setTileEntity( noTesrTile ); GameRegistry.registerTileEntity( noTesrTile, "BlockCableBus" ); + if( Platform.isClient() ) + { + tesrTile = Api.INSTANCE.partHelper().getCombinedInstance( TileCableBusTESR.class ); + GameRegistry.registerTileEntity( tesrTile, "ClientOnly_TESR_CableBus" ); + } } public static Class getNoTesrTile() @@ -366,4 +398,17 @@ public class BlockCableBus extends AEBaseTileBlock return noTesrTile; } + public static Class getTesrTile() + { + return tesrTile; + } + + // Helper to get access to the protected constructor + private static class DestroyFX extends ParticleDigging + { + DestroyFX( World worldIn, double xCoordIn, double yCoordIn, double zCoordIn, double xSpeedIn, double ySpeedIn, double zSpeedIn, IBlockState state ) + { + super( worldIn, xCoordIn, yCoordIn, zCoordIn, xSpeedIn, ySpeedIn, zSpeedIn, state ); + } + } } diff --git a/src/main/java/appeng/block/networking/CableBusColor.java b/src/main/java/appeng/block/networking/CableBusColor.java index dc30f51b..666ac185 100644 --- a/src/main/java/appeng/block/networking/CableBusColor.java +++ b/src/main/java/appeng/block/networking/CableBusColor.java @@ -10,10 +10,12 @@ import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import appeng.api.util.AEColor; -import appeng.api.util.AEPartLocation; -import appeng.parts.CableBusContainer; +import appeng.client.render.cablebus.CableBusRenderState; +/** + * Exposes the cable bus color as tint indices 0 (dark variant), 1 (medium variant) and 2 (bright variant). + */ @SideOnly( Side.CLIENT ) public class CableBusColor implements IBlockColor { @@ -22,32 +24,18 @@ public class CableBusColor implements IBlockColor public int colorMultiplier( IBlockState state, IBlockAccess worldIn, BlockPos pos, int color ) { - boolean active = true; AEColor busColor = AEColor.Transparent; if( state instanceof IExtendedBlockState ) { - AEPartLocation side = AEPartLocation.fromOrdinal( ( color >> 2 ) & 7 ); - CableBusContainer bus = ( (IExtendedBlockState) state ).getValue( BlockCableBus.cableBus ); - if( bus != null ) + CableBusRenderState renderState = ( (IExtendedBlockState) state ).getValue( BlockCableBus.RENDER_STATE_PROPERTY ); + if( renderState != null ) { - active = bus.getGridNode( side ) != null && bus.getGridNode( side ).isActive(); - busColor = bus.getColor(); + busColor = renderState.getCableColor(); } } - switch( color & 3 ) - { - case 0: - return active ? 0xffffff : 0; - case 1: - return busColor.blackVariant; - case 2: - return busColor.mediumVariant; - case 3: - return busColor.whiteVariant; - default: - return color; - } + return busColor.getVariantByTintIndex( color ); + } } diff --git a/src/main/java/appeng/block/networking/CableBusRenderStateProperty.java b/src/main/java/appeng/block/networking/CableBusRenderStateProperty.java new file mode 100644 index 00000000..2ad8ac2a --- /dev/null +++ b/src/main/java/appeng/block/networking/CableBusRenderStateProperty.java @@ -0,0 +1,37 @@ +package appeng.block.networking; + + +import net.minecraftforge.common.property.IUnlistedProperty; + +import appeng.client.render.cablebus.CableBusRenderState; + + +/** + * An unlisted property for the cable bus block's render state. + */ +public class CableBusRenderStateProperty implements IUnlistedProperty +{ + @Override + public String getName() + { + return "cable_bus_render_state"; + } + + @Override + public boolean isValid( CableBusRenderState value ) + { + return value != null; + } + + @Override + public Class getType() + { + return CableBusRenderState.class; + } + + @Override + public String valueToString( CableBusRenderState value ) + { + return value.toString(); + } +} diff --git a/src/main/java/appeng/block/networking/CableBusRendering.java b/src/main/java/appeng/block/networking/CableBusRendering.java index fee8e31b..d3725031 100644 --- a/src/main/java/appeng/block/networking/CableBusRendering.java +++ b/src/main/java/appeng/block/networking/CableBusRendering.java @@ -1,24 +1,14 @@ package appeng.block.networking; -import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.renderer.block.model.IBakedModel; -import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; -import appeng.api.client.BakingPipeline; import appeng.bootstrap.BlockRenderingCustomizer; import appeng.bootstrap.IBlockRendering; import appeng.bootstrap.IItemRendering; -import appeng.client.render.model.pipeline.BakingPipelineBakedModel; -import appeng.client.render.model.pipeline.FacingQuadRotator; -import appeng.client.render.model.pipeline.Merge; -import appeng.client.render.model.pipeline.TintIndexModifier; -import appeng.client.render.model.pipeline.TypeTransformer; -import appeng.client.render.model.pipeline.cable.CableAndConnections; -import appeng.client.render.model.pipeline.cable.Facades; -import appeng.client.render.model.pipeline.cable.Parts; +import appeng.client.render.cablebus.CableBusModel; +import appeng.core.features.registries.PartModels; /** @@ -26,27 +16,19 @@ import appeng.client.render.model.pipeline.cable.Parts; */ public class CableBusRendering extends BlockRenderingCustomizer { + private final PartModels partModels; - private final BakingPipeline rotatingPipeline = new BakingPipeline<>( TypeTransformer.quads2vecs, new FacingQuadRotator(), TypeTransformer.vecs2quads ); - private final TintIndexModifier tintIndexModifier = new TintIndexModifier( tint -> tint ); - private final BakingPipeline tintIndexFixPipeline = new BakingPipeline<>( TypeTransformer.quads2vecs, tintIndexModifier, TypeTransformer.vecs2quads ); + public CableBusRendering( PartModels partModels ) + { + this.partModels = partModels; + } @Override @SideOnly( Side.CLIENT ) public void customize( IBlockRendering rendering, IItemRendering itemRendering ) { - rendering.modelCustomizer( this::customizeModel ); + rendering.builtInModel( "models/block/builtin/cable_bus", new CableBusModel( partModels ) ); rendering.blockColor( new CableBusColor() ); - } - - private IBakedModel customizeModel( ResourceLocation location, IBakedModel model ) - { - return new BakingPipelineBakedModel( model, - new Merge<>( - new CableAndConnections( rotatingPipeline, tintIndexModifier, tintIndexFixPipeline ), - new Facades( rotatingPipeline, tintIndexModifier, tintIndexFixPipeline ), - new Parts( rotatingPipeline, tintIndexModifier, tintIndexFixPipeline ) - ) - ); + rendering.modelCustomizer( ( loc, model ) -> model ); } } diff --git a/src/main/java/appeng/bootstrap/BlockRendering.java b/src/main/java/appeng/bootstrap/BlockRendering.java index b0f0cad5..9f26f2b2 100644 --- a/src/main/java/appeng/bootstrap/BlockRendering.java +++ b/src/main/java/appeng/bootstrap/BlockRendering.java @@ -19,7 +19,7 @@ import appeng.block.AEBaseTileBlock; import appeng.bootstrap.components.BlockColorComponent; import appeng.bootstrap.components.StateMapperComponent; import appeng.bootstrap.components.TesrComponent; -import appeng.client.render.model.CachingRotatingBakedModel; +import appeng.client.render.model.AutoRotatingModel; class BlockRendering implements IBlockRendering @@ -96,7 +96,7 @@ class BlockRendering implements IBlockRendering else if ( block instanceof AEBaseTileBlock ) { // This is a default rotating model if the base-block uses an AE tile entity which exposes UP/FRONT as extended props - factory.modelOverrideComponent.addOverride( block.getRegistryName().getResourcePath(), ( l, m ) -> new CachingRotatingBakedModel( m ) ); + factory.modelOverrideComponent.addOverride( block.getRegistryName().getResourcePath(), ( l, m ) -> new AutoRotatingModel( m ) ); } builtInModels.forEach( factory::addBuiltInModel ); diff --git a/src/main/java/appeng/client/ClientHelper.java b/src/main/java/appeng/client/ClientHelper.java index a0960a4c..18df4ab3 100644 --- a/src/main/java/appeng/client/ClientHelper.java +++ b/src/main/java/appeng/client/ClientHelper.java @@ -24,33 +24,28 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; -import com.google.common.collect.ImmutableMap; - import org.lwjgl.opengl.GL11; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.RenderItem; import net.minecraft.client.renderer.entity.RenderManager; -import net.minecraft.client.resources.IReloadableResourceManager; -import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumHand; -import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import net.minecraftforge.client.event.MouseEvent; import net.minecraftforge.client.event.RenderLivingEvent; import net.minecraftforge.client.event.TextureStitchEvent; -import net.minecraftforge.client.model.IModel; import net.minecraftforge.client.model.ModelLoaderRegistry; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import appeng.api.parts.CableRenderMode; -import appeng.api.util.AECableType; import appeng.api.util.AEColor; import appeng.block.AEBaseBlock; import appeng.client.render.effects.AssemblerFX; @@ -59,12 +54,10 @@ import appeng.client.render.effects.EnergyFx; import appeng.client.render.effects.LightningArcFX; import appeng.client.render.effects.LightningFX; import appeng.client.render.effects.VibrantFX; -import appeng.client.render.model.ModelsCache; import appeng.client.render.model.UVLModelLoader; import appeng.client.render.textures.ParticleTextures; import appeng.core.AEConfig; import appeng.core.AELog; -import appeng.core.AppEng; import appeng.core.CommonHelper; import appeng.core.sync.network.NetworkHandler; import appeng.core.sync.packets.PacketAssemblerAnimation; @@ -76,8 +69,6 @@ import appeng.entity.RenderTinyTNTPrimed; import appeng.helpers.IMouseWheelItem; import appeng.hooks.TickHandler; import appeng.hooks.TickHandler.PlayerColor; -import appeng.items.parts.PartType; -import appeng.parts.AEBasePart; import appeng.server.ServerHelper; import appeng.transformer.MissingCoreMod; import appeng.util.Platform; @@ -91,7 +82,6 @@ public class ClientHelper extends ServerHelper { MinecraftForge.EVENT_BUS.register( this ); ModelLoaderRegistry.registerLoader( UVLModelLoader.INSTANCE ); - ( (IReloadableResourceManager) Minecraft.getMinecraft().getResourceManager() ).registerReloadListener( ModelsCache.INSTANCE ); } @Override @@ -204,26 +194,26 @@ public class ClientHelper extends ServerHelper } @Override - public void doRenderItem( final ItemStack itemstack, final World w ) + public void doRenderItem( final ItemStack itemstack ) { if( itemstack != null ) { - final EntityItem entityitem = new EntityItem( w, 0.0D, 0.0D, 0.0D, itemstack ); - entityitem.getEntityItem().stackSize = 1; - // set all this stuff and then do shit? meh? - entityitem.hoverStart = 0; - entityitem.setNoDespawn(); - entityitem.rotationYaw = 0; + GlStateManager.pushMatrix(); - GL11.glPushMatrix(); - GL11.glTranslatef( 0, -0.04F, 0 ); - GL11.glColor4f( 1.0F, 1.0F, 1.0F, 1.0F ); - // GL11.glDisable( GL11.GL_CULL_FACE ); + // The Z-scaling by 0.0001 causes the model to be visually "flattened" + // This cannot replace a proper projection, but it's cheap and gives the desired + // effect at least from head-on + final float scale = 0.8f; + GlStateManager.scale( scale / 32.0f, scale / 32.0f, 0.0001f ); + // Position the item icon at the top middle of the panel + GlStateManager.translate( -8, -11, 0 ); - // TODO RENDER ITEM FOR STORAGE MONITOR! + RenderItem renderItem = Minecraft.getMinecraft().getRenderItem(); + renderItem.renderItemAndEffectIntoGUI(itemstack, 0, 0); + + GlStateManager.popMatrix(); - GL11.glPopMatrix(); } } @@ -398,47 +388,5 @@ public class ClientHelper extends ServerHelper public void onTextureStitch( final TextureStitchEvent.Pre event ) { ParticleTextures.registerSprite( event ); - for( AECableType type : AECableType.VALIDCABLES ) - { - for( IModel model : new IModel[] { ModelsCache.INSTANCE.getOrLoadModel( type.getModel() ), ModelsCache.INSTANCE.getOrLoadModel( type.getConnectionModel() ), ModelsCache.INSTANCE.getOrLoadModel( type.getStraightModel() ) } ) - { - for( ResourceLocation location : model.getTextures() ) - { - for( AEColor color : AEColor.values() ) - { - if( type.displayedChannels() > 0 ) - { - for( int i = 0; i <= type.displayedChannels(); i++ ) - { - event.getMap().registerSprite( AEBasePart.replaceProperties( location, ImmutableMap.of( "color", color.name(), "channels", String.valueOf( i ) ) ) ); - } - } - else - { - event.getMap().registerSprite( AEBasePart.replaceProperties( location, ImmutableMap.of( "color", color.name() ) ) ); - } - } - } - } - } - for( PartType part : PartType.values() ) - { - if( !part.isCable() ) - { - IModel model = ModelsCache.INSTANCE.getOrLoadModel( part.getModel() ); - for( ResourceLocation location : model.getTextures() ) - { - for( AEColor color : AEColor.values() ) - { - event.getMap().registerSprite( AEBasePart.replaceProperties( location, ImmutableMap.of( "color", color.name() ) ) ); - } - } - } - } - - for( ResourceLocation location : ModelsCache.INSTANCE.getOrLoadModel( new ResourceLocation( AppEng.MOD_ID, "part/cable_facade" ) ).getTextures() ) - { - event.getMap().registerSprite( location ); - } } } \ No newline at end of file diff --git a/src/main/java/appeng/client/render/ColorableTileBlockColor.java b/src/main/java/appeng/client/render/ColorableTileBlockColor.java index be3261f0..91d6e52b 100644 --- a/src/main/java/appeng/client/render/ColorableTileBlockColor.java +++ b/src/main/java/appeng/client/render/ColorableTileBlockColor.java @@ -53,15 +53,6 @@ public class ColorableTileBlockColor implements IBlockColor } } - switch( tintIndex ) - { - default: - case 0: - return color.whiteVariant; - case 1: - return color.mediumVariant; - case 2: - return color.blackVariant; - } + return color.getVariantByTintIndex( tintIndex ); } } diff --git a/src/main/java/appeng/client/render/StaticItemColor.java b/src/main/java/appeng/client/render/StaticItemColor.java index 5d453d2e..04a61c4e 100644 --- a/src/main/java/appeng/client/render/StaticItemColor.java +++ b/src/main/java/appeng/client/render/StaticItemColor.java @@ -23,16 +23,7 @@ public class StaticItemColor implements IItemColor @Override public int getColorFromItemstack( ItemStack stack, int tintIndex ) { - switch( tintIndex ) - { - default: - case 0: - return color.whiteVariant; - case 1: - return color.mediumVariant; - case 2: - return color.blackVariant; - } + return color.getVariantByTintIndex( tintIndex ); } } diff --git a/src/main/java/appeng/client/render/cablebus/CableBuilder.java b/src/main/java/appeng/client/render/cablebus/CableBuilder.java new file mode 100644 index 00000000..f8a5ccc8 --- /dev/null +++ b/src/main/java/appeng/client/render/cablebus/CableBuilder.java @@ -0,0 +1,673 @@ +package appeng.client.render.cablebus; + + +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.List; + +import com.google.common.base.Function; + +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; + +import appeng.api.util.AECableType; +import appeng.api.util.AEColor; + + +/** + * A helper class that builds quads for cable connections. + */ +class CableBuilder +{ + + private final VertexFormat format; + + // Textures for the cable core types, one per type/color pair + private final EnumMap> coreTextures; + + // Textures for rendering the actual connection cubes, one per type/color pair + private final EnumMap> connectionTextures; + + private final SmartCableTextures smartCableTextures; + + CableBuilder( VertexFormat format, Function bakedTextureGetter ) + { + this.format = format; + this.coreTextures = new EnumMap<>( CableCoreType.class ); + + for( CableCoreType type : CableCoreType.values() ) + { + EnumMap colorTextures = new EnumMap<>( AEColor.class ); + + for( AEColor color : AEColor.values() ) + { + colorTextures.put( color, bakedTextureGetter.apply( type.getTexture( color ) ) ); + } + + coreTextures.put( type, colorTextures ); + } + + this.connectionTextures = new EnumMap<>( AECableType.class ); + + for( AECableType type : AECableType.VALIDCABLES ) + { + EnumMap colorTextures = new EnumMap<>( AEColor.class ); + + for( AEColor color : AEColor.values() ) + { + colorTextures.put( color, bakedTextureGetter.apply( type.getConnectionTexture( color ) ) ); + } + + connectionTextures.put( type, colorTextures ); + } + + smartCableTextures = new SmartCableTextures( bakedTextureGetter ); + } + + /** + * Adds the core of a cable to the given list of quads. + * + * The type of cable core is automatically deduced from the given cable type. + */ + public void addCableCore( AECableType cableType, AEColor color, List quadsOut ) + { + switch( cableType ) + { + case GLASS: + addCableCore( CableCoreType.GLASS, color, quadsOut ); + break; + case COVERED: + case SMART: + addCableCore( CableCoreType.COVERED, color, quadsOut ); + break; + case DENSE: + addCableCore( CableCoreType.DENSE, color, quadsOut ); + break; + default: + } + } + + public void addCableCore( CableCoreType coreType, AEColor color, List quadsOut ) + { + CubeBuilder cubeBuilder = new CubeBuilder( format, quadsOut ); + + TextureAtlasSprite texture = coreTextures.get( coreType ).get( color ); + cubeBuilder.setTexture( texture ); + + switch( coreType ) + { + case GLASS: + cubeBuilder.addCube( 6, 6, 6, 10, 10, 10 ); + break; + case COVERED: + cubeBuilder.addCube( 5, 5, 5, 11, 11, 11 ); + break; + case DENSE: + cubeBuilder.addCube( 3, 3, 3, 13, 13, 13 ); + break; + } + } + + public void addGlassConnection( EnumFacing facing, AEColor cableColor, AECableType connectionType, boolean cableBusAdjacent, List quadsOut ) + { + CubeBuilder cubeBuilder = new CubeBuilder( format, quadsOut ); + + // We render all faces except the one on the connection side + cubeBuilder.setDrawFaces( EnumSet.complementOf( EnumSet.of( facing ) ) ); + + // For to-machine connections, use a thicker end-cap for the connection + if( connectionType != AECableType.GLASS && !cableBusAdjacent ) + { + TextureAtlasSprite texture = connectionTextures.get( AECableType.COVERED ).get( cableColor ); + cubeBuilder.setTexture( texture ); + + addBigCoveredCableSizedCube( facing, cubeBuilder ); + } + + TextureAtlasSprite texture = connectionTextures.get( AECableType.GLASS ).get( cableColor ); + cubeBuilder.setTexture( texture ); + + switch( facing ) + { + case DOWN: + cubeBuilder.addCube( 6, 0, 6, 10, 6, 10 ); + break; + case EAST: + cubeBuilder.addCube( 10, 6, 6, 16, 10, 10 ); + break; + case NORTH: + cubeBuilder.addCube( 6, 6, 0, 10, 10, 6 ); + break; + case SOUTH: + cubeBuilder.addCube( 6, 6, 10, 10, 10, 16 ); + break; + case UP: + cubeBuilder.addCube( 6, 10, 6, 10, 16, 10 ); + break; + case WEST: + cubeBuilder.addCube( 0, 6, 6, 6, 10, 10 ); + break; + } + } + + public void addStraightGlassConnection( EnumFacing facing, AEColor cableColor, List quadsOut ) + { + CubeBuilder cubeBuilder = new CubeBuilder( format, quadsOut ); + + // We render all faces except the connection caps. We can do this because the glass cable is the smallest one + // and its ends will always be covered by something + cubeBuilder.setDrawFaces( EnumSet.complementOf( EnumSet.of( facing, facing.getOpposite() ) ) ); + + TextureAtlasSprite texture = connectionTextures.get( AECableType.GLASS ).get( cableColor ); + cubeBuilder.setTexture( texture ); + + switch( facing ) + { + case DOWN: + case UP: + cubeBuilder.addCube( 6, 0, 6, 10, 16, 10 ); + break; + case NORTH: + case SOUTH: + cubeBuilder.addCube( 6, 6, 0, 10, 10, 16 ); + break; + case EAST: + case WEST: + cubeBuilder.addCube( 0, 6, 6, 16, 10, 10 ); + break; + } + } + + public void addConstrainedGlassConnection( EnumFacing facing, AEColor cableColor, int distanceFromEdge, List quadsOut ) + { + + // Glass connections reach only 6 voxels from the edge + if( distanceFromEdge >= 6 ) + { + return; + } + + CubeBuilder cubeBuilder = new CubeBuilder( format, quadsOut ); + + TextureAtlasSprite texture = connectionTextures.get( AECableType.GLASS ).get( cableColor ); + cubeBuilder.setTexture( texture ); + + switch( facing ) + { + case DOWN: + cubeBuilder.addCube( 6, distanceFromEdge, 6, 10, 6, 10 ); + break; + case EAST: + cubeBuilder.addCube( 10, 6, 6, 16 - distanceFromEdge, 10, 10 ); + break; + case NORTH: + cubeBuilder.addCube( 6, 6, distanceFromEdge, 10, 10, 6 ); + break; + case SOUTH: + cubeBuilder.addCube( 6, 6, 10, 10, 10, 16 - distanceFromEdge ); + break; + case UP: + cubeBuilder.addCube( 6, 10, 6, 10, 16 - distanceFromEdge, 10 ); + break; + case WEST: + cubeBuilder.addCube( distanceFromEdge, 6, 6, 6, 10, 10 ); + break; + } + } + + public void addCoveredConnection( EnumFacing facing, AEColor cableColor, AECableType connectionType, boolean cableBusAdjacent, List quadsOut ) + { + + CubeBuilder cubeBuilder = new CubeBuilder( format, quadsOut ); + + // We render all faces except the one on the connection side + cubeBuilder.setDrawFaces( EnumSet.complementOf( EnumSet.of( facing ) ) ); + + TextureAtlasSprite texture = connectionTextures.get( AECableType.COVERED ).get( cableColor ); + cubeBuilder.setTexture( texture ); + + // Draw a covered connection, if anything but glass is requested + if( connectionType != AECableType.GLASS && !cableBusAdjacent ) + { + addBigCoveredCableSizedCube( facing, cubeBuilder ); + } + + addCoveredCableSizedCube( facing, cubeBuilder ); + } + + public void addStraightCoveredConnection( EnumFacing facing, AEColor cableColor, List quadsOut ) + { + CubeBuilder cubeBuilder = new CubeBuilder( format, quadsOut ); + + TextureAtlasSprite texture = connectionTextures.get( AECableType.COVERED ).get( cableColor ); + cubeBuilder.setTexture( texture ); + + setStraightCableUVs( cubeBuilder, facing, 5, 11 ); + + addStraightCoveredCableSizedCube( facing, cubeBuilder ); + + + + } + + private static void setStraightCableUVs( CubeBuilder cubeBuilder, EnumFacing facing, int x, int y ) + { + switch( facing ) + { + case DOWN: + case UP: + cubeBuilder.setCustomUv( EnumFacing.NORTH, x, 0, y, x ); + cubeBuilder.setCustomUv( EnumFacing.EAST, x, 0, y, x ); + cubeBuilder.setCustomUv( EnumFacing.SOUTH, x, 0, y, x ); + cubeBuilder.setCustomUv( EnumFacing.WEST, x, 0, y, x ); + break; + case EAST: + case WEST: + cubeBuilder.setCustomUv( EnumFacing.UP, 0, x, x, y ); + cubeBuilder.setCustomUv( EnumFacing.DOWN, 0, x, x, y ); + cubeBuilder.setCustomUv( EnumFacing.NORTH, 0, x, x, y ); + cubeBuilder.setCustomUv( EnumFacing.SOUTH, 0, x, x, y ); + break; + case NORTH: + case SOUTH: + cubeBuilder.setCustomUv( EnumFacing.UP, x, 0, y, x ); + cubeBuilder.setCustomUv( EnumFacing.DOWN, x, 0, y, x ); + cubeBuilder.setCustomUv( EnumFacing.EAST, 0, x, x, y ); + cubeBuilder.setCustomUv( EnumFacing.WEST, 0, x, x, y ); + break; + } + } + + public void addConstrainedCoveredConnection( EnumFacing facing, AEColor cableColor, int distanceFromEdge, List quadsOut ) + { + + // The core of a covered cable reaches up to 5 voxels from the block edge, so + // drawing a connection can only occur from there onwards + if( distanceFromEdge >= 5 ) + { + return; + } + + CubeBuilder cubeBuilder = new CubeBuilder( format, quadsOut ); + + TextureAtlasSprite texture = connectionTextures.get( AECableType.COVERED ).get( cableColor ); + cubeBuilder.setTexture( texture ); + + addCoveredCableSizedCube( facing, distanceFromEdge, cubeBuilder ); + + } + + public void addSmartConnection( EnumFacing facing, AEColor cableColor, AECableType connectionType, boolean cableBusAdjacent, int channels, List quadsOut ) + { + + CubeBuilder cubeBuilder = new CubeBuilder( format, quadsOut ); + + // We render all faces except the one on the connection side + cubeBuilder.setDrawFaces( EnumSet.complementOf( EnumSet.of( facing ) ) ); + + TextureAtlasSprite texture = connectionTextures.get( AECableType.SMART ).get( cableColor ); + cubeBuilder.setTexture( texture ); + + TextureAtlasSprite oddChannel = smartCableTextures.getOddTextureForChannels( channels ); + TextureAtlasSprite evenChannel = smartCableTextures.getEvenTextureForChannels( channels ); + + // For to-machine connections, use a thicker end-cap for the connection + if( connectionType != AECableType.GLASS && !cableBusAdjacent ) + { + addBigCoveredCableSizedCube( facing, cubeBuilder ); + + // Render the channel indicators brightly lit at night + cubeBuilder.setRenderFullBright( true ); + + cubeBuilder.setTexture( oddChannel ); + cubeBuilder.setColorRGB( cableColor.blackVariant ); + addBigCoveredCableSizedCube( facing, cubeBuilder ); + + cubeBuilder.setTexture( evenChannel ); + cubeBuilder.setColorRGB( cableColor.whiteVariant ); + addBigCoveredCableSizedCube( facing, cubeBuilder ); + + // Reset back to normal rendering for the rest + cubeBuilder.setRenderFullBright( false ); + cubeBuilder.setTexture( texture ); + } + + addCoveredCableSizedCube( facing, cubeBuilder ); + + // Render the channel indicators brightly lit at night + cubeBuilder.setRenderFullBright( true ); + + cubeBuilder.setTexture( oddChannel ); + cubeBuilder.setColorRGB( cableColor.blackVariant ); + addCoveredCableSizedCube( facing, cubeBuilder ); + + cubeBuilder.setTexture( evenChannel ); + cubeBuilder.setColorRGB( cableColor.whiteVariant ); + addCoveredCableSizedCube( facing, cubeBuilder ); + + /* TODO: this.setSmartConnectionRotations( of, renderer ); + renderer.uvRotateBottom = renderer.uvRotateEast = renderer.uvRotateNorth = renderer.uvRotateSouth = renderer.uvRotateTop = renderer.uvRotateWest = 0;*/ + } + + public void addStraightSmartConnection( EnumFacing facing, AEColor cableColor, int channels, List quadsOut ) + { + CubeBuilder cubeBuilder = new CubeBuilder( format, quadsOut ); + + TextureAtlasSprite texture = connectionTextures.get( AECableType.SMART ).get( cableColor ); + cubeBuilder.setTexture( texture ); + + setStraightCableUVs( cubeBuilder, facing, 5, 11 ); + + addStraightCoveredCableSizedCube( facing, cubeBuilder ); + + TextureAtlasSprite oddChannel = smartCableTextures.getOddTextureForChannels( channels ); + TextureAtlasSprite evenChannel = smartCableTextures.getEvenTextureForChannels( channels ); + + // Render the channel indicators brightly lit at night + cubeBuilder.setRenderFullBright( true ); + + cubeBuilder.setTexture( oddChannel ); + cubeBuilder.setColorRGB( cableColor.blackVariant ); + addStraightCoveredCableSizedCube( facing, cubeBuilder ); + + cubeBuilder.setTexture( evenChannel ); + cubeBuilder.setColorRGB( cableColor.whiteVariant ); + addStraightCoveredCableSizedCube( facing, cubeBuilder ); + } + + public void addConstrainedSmartConnection( EnumFacing facing, AEColor cableColor, int distanceFromEdge, int channels, List quadsOut ) + { + // Same as with covered cables, the smart cable's core extends up to 5 voxels away from the edge. + // Drawing a connection to any point before that point is fruitless + if( distanceFromEdge >= 5 ) + { + return; + } + + CubeBuilder cubeBuilder = new CubeBuilder( format, quadsOut ); + + TextureAtlasSprite texture = connectionTextures.get( AECableType.SMART ).get( cableColor ); + cubeBuilder.setTexture( texture ); + + addCoveredCableSizedCube( facing, distanceFromEdge, cubeBuilder ); + + TextureAtlasSprite oddChannel = smartCableTextures.getOddTextureForChannels( channels ); + TextureAtlasSprite evenChannel = smartCableTextures.getEvenTextureForChannels( channels ); + + // Render the channel indicators brightly lit at night + cubeBuilder.setRenderFullBright( true ); + + cubeBuilder.setTexture( oddChannel ); + cubeBuilder.setColorRGB( cableColor.blackVariant ); + addCoveredCableSizedCube( facing, distanceFromEdge, cubeBuilder ); + + cubeBuilder.setTexture( evenChannel ); + cubeBuilder.setColorRGB( cableColor.whiteVariant ); + addCoveredCableSizedCube( facing, distanceFromEdge, cubeBuilder ); + } + + public void addDenseConnection( EnumFacing facing, AEColor cableColor, AECableType connectionType, boolean cableBusAdjacent, int channels, List quadsOut ) + { + // Dense cables only render their connections as dense if the adjacent blocks actually wants that + if( connectionType == AECableType.SMART ) + { + addSmartConnection( facing, cableColor, connectionType, cableBusAdjacent, channels, quadsOut ); + return; + } + else if( connectionType != AECableType.DENSE ) + { + addCoveredConnection( facing, cableColor, connectionType, cableBusAdjacent, quadsOut ); + return; + } + + CubeBuilder cubeBuilder = new CubeBuilder( format, quadsOut ); + + // We render all faces except the one on the connection side + cubeBuilder.setDrawFaces( EnumSet.complementOf( EnumSet.of( facing ) ) ); + + TextureAtlasSprite texture = connectionTextures.get( AECableType.DENSE ).get( cableColor ); + cubeBuilder.setTexture( texture ); + + addDenseCableSizedCube( facing, cubeBuilder ); + + // Dense cables show used channels in groups of 4, rounded up + channels = (channels + 3) / 4; + + TextureAtlasSprite oddChannel = smartCableTextures.getOddTextureForChannels( channels ); + TextureAtlasSprite evenChannel = smartCableTextures.getEvenTextureForChannels( channels ); + + // Render the channel indicators brightly lit at night + cubeBuilder.setRenderFullBright( true ); + + cubeBuilder.setTexture( oddChannel ); + cubeBuilder.setColorRGB( cableColor.blackVariant ); + addDenseCableSizedCube( facing, cubeBuilder ); + + cubeBuilder.setTexture( evenChannel ); + cubeBuilder.setColorRGB( cableColor.whiteVariant ); + addDenseCableSizedCube( facing, cubeBuilder ); + + // Reset back to normal rendering for the rest + cubeBuilder.setRenderFullBright( false ); + cubeBuilder.setTexture( texture ); + + } + + public void addStraightDenseConnection( EnumFacing facing, AEColor cableColor, int channels, List quadsOut ) + { + CubeBuilder cubeBuilder = new CubeBuilder( format, quadsOut ); + + TextureAtlasSprite texture = connectionTextures.get( AECableType.DENSE ).get( cableColor ); + cubeBuilder.setTexture( texture ); + + setStraightCableUVs( cubeBuilder, facing, 5, 11 ); + + addStraightDenseCableSizedCube( facing, cubeBuilder ); + + // Dense cables show used channels in groups of 4, rounded up + channels = (channels + 3) / 4; + + TextureAtlasSprite oddChannel = smartCableTextures.getOddTextureForChannels( channels ); + TextureAtlasSprite evenChannel = smartCableTextures.getEvenTextureForChannels( channels ); + + // Render the channel indicators brightly lit at night + cubeBuilder.setRenderFullBright( true ); + + cubeBuilder.setTexture( oddChannel ); + cubeBuilder.setColorRGB( cableColor.blackVariant ); + addStraightDenseCableSizedCube( facing, cubeBuilder ); + + cubeBuilder.setTexture( evenChannel ); + cubeBuilder.setColorRGB( cableColor.whiteVariant ); + addStraightDenseCableSizedCube( facing, cubeBuilder ); + } + + + private static void addDenseCableSizedCube( EnumFacing facing, CubeBuilder cubeBuilder ) + { + switch( facing ) + { + case DOWN: + cubeBuilder.addCube( 4, 0, 4, 12, 5, 12 ); + break; + case EAST: + cubeBuilder.addCube( 11, 4, 4, 16, 12, 12 ); + break; + case NORTH: + cubeBuilder.addCube( 4, 4, 0, 12, 12, 5 ); + break; + case SOUTH: + cubeBuilder.addCube( 4, 4, 11, 12, 12, 16 ); + break; + case UP: + cubeBuilder.addCube( 4, 11, 4, 12, 16, 12 ); + break; + case WEST: + cubeBuilder.addCube( 0, 4, 4, 5, 12, 12 ); + break; + } + } + + // Adds a cube to the given cube builder that has the size of a dense cable connection and spans the entire block for the given direction + private static void addStraightDenseCableSizedCube( EnumFacing facing, CubeBuilder cubeBuilder ) + { + switch( facing ) + { + case DOWN: + case UP: + cubeBuilder.addCube( 3, 0, 3, 13, 16, 13 ); + break; + case EAST: + case WEST: + /*renderer.uvRotateEast = renderer.uvRotateWest = 1; + renderer.uvRotateBottom = renderer.uvRotateTop = 1;*/ + cubeBuilder.addCube( 0, 3, 3, 16, 13, 13 ); + break; + case NORTH: + case SOUTH: + // TODO renderer.uvRotateNorth = renderer.uvRotateSouth = 1; + cubeBuilder.addCube( 3, 3, 0, 13, 13, 16 ); + break; + } + } + + // Adds a cube to the given cube builder that has the size of a covered cable connection from the core of the cable to the given face + private static void addCoveredCableSizedCube( EnumFacing facing, CubeBuilder cubeBuilder ) + { + switch( facing ) + { + case DOWN: + cubeBuilder.addCube( 6, 0, 6, 10, 5, 10 ); + break; + case EAST: + cubeBuilder.addCube( 11, 6, 6, 16, 10, 10 ); + break; + case NORTH: + cubeBuilder.addCube( 6, 6, 0, 10, 10, 5 ); + break; + case SOUTH: + cubeBuilder.addCube( 6, 6, 11, 10, 10, 16 ); + break; + case UP: + cubeBuilder.addCube( 6, 11, 6, 10, 16, 10 ); + break; + case WEST: + cubeBuilder.addCube( 0, 6, 6, 5, 10, 10 ); + break; + } + } + + // Adds a cube to the given cube builder that has the size of a covered cable connection and spans the entire block for the given direction + private static void addStraightCoveredCableSizedCube( EnumFacing facing, CubeBuilder cubeBuilder ) + { + switch( facing ) + { + case DOWN: + case UP: + cubeBuilder.addCube( 5, 0, 5, 11, 16, 11 ); + break; + case EAST: + case WEST: + /*renderer.uvRotateEast = renderer.uvRotateWest = 1; + renderer.uvRotateBottom = renderer.uvRotateTop = 1;*/ + cubeBuilder.addCube( 0, 5, 5, 16, 11, 11 ); + break; + case NORTH: + case SOUTH: + // TODO renderer.uvRotateNorth = renderer.uvRotateSouth = 1; + cubeBuilder.addCube( 5, 5, 0, 11, 11, 16 ); + break; + } + } + + private static void addCoveredCableSizedCube( EnumFacing facing, int distanceFromEdge, CubeBuilder cubeBuilder ) + { + switch( facing ) + { + case DOWN: + cubeBuilder.addCube( 6, distanceFromEdge, 6, 10, 5, 10 ); + break; + case EAST: + cubeBuilder.addCube( 11, 6, 6, 16 - distanceFromEdge, 10, 10 ); + break; + case NORTH: + cubeBuilder.addCube( 6, 6, distanceFromEdge, 10, 10, 5 ); + break; + case SOUTH: + cubeBuilder.addCube( 6, 6, 11, 10, 10, 16 - distanceFromEdge ); + break; + case UP: + cubeBuilder.addCube( 6, 11, 6, 10, 16 - distanceFromEdge, 10 ); + break; + case WEST: + cubeBuilder.addCube( distanceFromEdge, 6, 6, 5, 10, 10 ); + break; + } + } + + /** + * This renders a slightly bigger covered cable connection to the specified side. This is used to connect cable cores with adjacent machines + * that do not want to be connected to using a glass cable connection. This applies to most machines (interfaces, etc.) + */ + private void addBigCoveredCableSizedCube( EnumFacing facing, CubeBuilder cubeBuilder ) + { + switch( facing ) + { + case DOWN: + cubeBuilder.addCube( 5, 0, 5, 11, 4, 11 ); + break; + case EAST: + cubeBuilder.addCube( 12, 5, 5, 16, 11, 11 ); + break; + case NORTH: + cubeBuilder.addCube( 5, 5, 0, 11, 11, 4 ); + break; + case SOUTH: + cubeBuilder.addCube( 5, 5, 12, 11, 11, 16 ); + break; + case UP: + cubeBuilder.addCube( 5, 12, 5, 11, 16, 11 ); + break; + case WEST: + cubeBuilder.addCube( 0, 5, 5, 4, 11, 11 ); + break; + } + } + + // Get all textures needed for building the actual cable quads + public static List getTextures() + { + List locations = new ArrayList<>(); + + for( CableCoreType coreType : CableCoreType.values() ) + { + for( AEColor color : AEColor.values() ) + { + locations.add( coreType.getTexture( color ) ); + } + } + + for( AECableType cableType : AECableType.VALIDCABLES ) + { + for( AEColor color : AEColor.values() ) + { + locations.add( cableType.getConnectionTexture( color ) ); + } + } + + Collections.addAll( locations, SmartCableTextures.SMART_CHANNELS_TEXTURES ); + + return locations; + } + + public TextureAtlasSprite getCoreTexture( CableCoreType coreType, AEColor color ) + { + return coreTextures.get( coreType ).get( color ); + } + +} diff --git a/src/main/java/appeng/client/render/cablebus/CableBusBakedModel.java b/src/main/java/appeng/client/render/cablebus/CableBusBakedModel.java new file mode 100644 index 00000000..5296ddb3 --- /dev/null +++ b/src/main/java/appeng/client/render/cablebus/CableBusBakedModel.java @@ -0,0 +1,260 @@ +package appeng.client.render.cablebus; + + +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import javax.annotation.Nullable; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms; +import net.minecraft.client.renderer.block.model.ItemOverrideList; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.common.property.IExtendedBlockState; + +import appeng.api.util.AECableType; +import appeng.api.util.AEColor; +import appeng.block.networking.BlockCableBus; + + +public class CableBusBakedModel implements IBakedModel +{ + + private final CableBuilder cableBuilder; + + private final Map partModels; + + CableBusBakedModel( CableBuilder cableBuilder, Map partModels ) + { + this.cableBuilder = cableBuilder; + this.partModels = partModels; + } + + @Override + public List getQuads( @Nullable IBlockState state, @Nullable EnumFacing side, long rand ) + { + CableBusRenderState renderState = getRenderingState( state ); + + if( renderState == null || side != null ) + { + return Collections.emptyList(); + } + + // First, handle the cable at the center of the cable bus + List quads = new ArrayList<>(); + addCableQuads( renderState, quads ); + + for( EnumFacing facing : EnumFacing.values() ) + { + List models = renderState.getAttachments().get( facing ); + if( models == null ) + { + continue; + } + + for( ResourceLocation model : models ) + { + IBakedModel bakedModel = partModels.get( model ); + + if( bakedModel == null ) + { + throw new IllegalStateException( "Trying to use an unregistered part model: " + model ); + } + + List partQuads = bakedModel.getQuads( state, null, rand ); + + // Rotate quads accordingly + QuadRotator rotator = new QuadRotator(); + partQuads = rotator.rotateQuads( partQuads, facing, EnumFacing.UP ); + + quads.addAll( partQuads ); + } + } + + return quads; + } + + + // Determines whether a cable is connected to exactly two sides that are opposite each other + private static boolean isStraightLine( Set sides ) + { + Iterator it = sides.iterator(); + if( !it.hasNext() ) + { + return false; // No connections + } + EnumFacing firstSide = it.next(); + if( !it.hasNext() ) + { + return false; // Only a single connection + } + if( firstSide.getOpposite() != it.next() ) + { + return false; // Connected to two sides that are not opposite each other + } + return !it.hasNext(); // Must not have any other connection points + } + + private void addCableQuads( CableBusRenderState renderState, List quadsOut ) + { + AECableType cableType = renderState.getCableType(); + if( cableType == AECableType.NONE ) + { + return; + } + + AEColor cableColor = renderState.getCableColor(); + EnumMap connectionTypes = renderState.getConnectionTypes(); + + // If the connection is straight, no busses are attached, and no overed core has been forced (in case of glass + // cables), then render the cable as a simplified straight line. + boolean noAttachments = renderState.getAttachments().isEmpty(); + if( isStraightLine( connectionTypes.keySet() ) && noAttachments ) + { + EnumFacing facing = connectionTypes.keySet().iterator().next(); + + switch (cableType) { + case GLASS: + cableBuilder.addStraightGlassConnection( facing, cableColor, quadsOut ); + break; + case COVERED: + cableBuilder.addStraightCoveredConnection( facing, cableColor, quadsOut ); + break; + case SMART: + cableBuilder.addStraightSmartConnection( facing, cableColor, renderState.getChannelsOnSide().get(facing), quadsOut ); + break; + case DENSE: + cableBuilder.addStraightDenseConnection( facing, cableColor, renderState.getChannelsOnSide().get(facing), quadsOut ); + break; + } + + return; // Don't render the other form of connection + } + + cableBuilder.addCableCore( renderState.getCoreType(), cableColor, quadsOut ); + + // Render all internal connections to attachments + EnumMap attachmentConnections = renderState.getAttachmentConnections(); + for( EnumFacing facing : attachmentConnections.keySet() ) + { + int distance = attachmentConnections.get( facing ); + int channels = renderState.getChannelsOnSide().get( facing ); + + switch( cableType ) + { + case GLASS: + cableBuilder.addConstrainedGlassConnection( facing, cableColor, distance, quadsOut ); + break; + case COVERED: + cableBuilder.addConstrainedCoveredConnection( facing, cableColor, distance, quadsOut ); + break; + case SMART: + cableBuilder.addConstrainedSmartConnection( facing, cableColor, distance, channels, quadsOut ); + break; + case DENSE: + // Dense cables do not render connections to parts since none can be attached + break; + } + } + + // Render all outgoing connections using the appropriate type + for( EnumFacing facing : connectionTypes.keySet() ) + { + AECableType connectionType = connectionTypes.get( facing ); + boolean cableBusAdjacent = renderState.getCableBusAdjacent().contains( facing ); + int channels = renderState.getChannelsOnSide().get( facing ); + + switch( cableType ) + { + case GLASS: + cableBuilder.addGlassConnection( facing, cableColor, connectionType, cableBusAdjacent, quadsOut ); + break; + case COVERED: + cableBuilder.addCoveredConnection( facing, cableColor, connectionType, cableBusAdjacent, quadsOut ); + break; + case SMART: + cableBuilder.addSmartConnection( facing, cableColor, connectionType, cableBusAdjacent, channels, quadsOut ); + break; + case DENSE: + cableBuilder.addDenseConnection( facing, cableColor, connectionType, cableBusAdjacent, channels, quadsOut ); + break; + } + } + } + + /** + * Gets a list of texture sprites appropriate for particles (digging, etc.) given the render state for a cable bus. + */ + public List getParticleTextures( CableBusRenderState renderState ) + { + CableCoreType coreType = renderState.getCableType().getCoreType(); + AEColor cableColor = renderState.getCableColor(); + + if( coreType != null ) + { + return Collections.singletonList( cableBuilder.getCoreTexture( coreType, cableColor ) ); + } + else + { + return Collections.emptyList(); + } + + // TODO: Add break particles even for the attachments, not just the cable + + } + + private static CableBusRenderState getRenderingState( IBlockState state ) + { + if( state == null || !( state instanceof IExtendedBlockState ) ) + { + return null; + } + + IExtendedBlockState extendedBlockState = (IExtendedBlockState) state; + return extendedBlockState.getValue( BlockCableBus.RENDER_STATE_PROPERTY ); + } + + @Override + public boolean isAmbientOcclusion() + { + return false; + } + + @Override + public boolean isGui3d() + { + return false; + } + + @Override + public boolean isBuiltInRenderer() + { + return false; + } + + @Override + public TextureAtlasSprite getParticleTexture() + { + return null; + } + + @Override + public ItemCameraTransforms getItemCameraTransforms() + { + return ItemCameraTransforms.DEFAULT; + } + + @Override + public ItemOverrideList getOverrides() + { + return ItemOverrideList.NONE; + } +} diff --git a/src/main/java/appeng/client/render/cablebus/CableBusModel.java b/src/main/java/appeng/client/render/cablebus/CableBusModel.java new file mode 100644 index 00000000..d8fd2390 --- /dev/null +++ b/src/main/java/appeng/client/render/cablebus/CableBusModel.java @@ -0,0 +1,94 @@ +package appeng.client.render.cablebus; + + +import java.util.Collection; +import java.util.Map; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableMap; + +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.model.IModel; +import net.minecraftforge.client.model.ModelLoaderRegistry; +import net.minecraftforge.common.model.IModelState; +import net.minecraftforge.common.model.TRSRTransformation; + +import appeng.core.AELog; +import appeng.core.features.registries.PartModels; + + +/** + * The built-in model for the cable bus block. + */ +public class CableBusModel implements IModel +{ + + private final PartModels partModels; + + public CableBusModel( PartModels partModels ) + { + this.partModels = partModels; + } + + @Override + public Collection getDependencies() + { + partModels.setInitialized( true ); + return partModels.getModels(); + } + + @Override + public Collection getTextures() + { + return CableBuilder.getTextures(); + } + + @Override + public IBakedModel bake( IModelState state, VertexFormat format, Function bakedTextureGetter ) + { + + Map partModels = loadPartModels( state, format, bakedTextureGetter ); + + CableBuilder cableBuilder = new CableBuilder( format, bakedTextureGetter ); + return new CableBusBakedModel( cableBuilder, partModels ); + } + + private Map loadPartModels( + IModelState state, + VertexFormat format, + Function bakedTextureGetter ) + { + ImmutableMap.Builder result = ImmutableMap.builder(); + + for( ResourceLocation location : partModels.getModels() ) + { + IModel model = tryLoadPartModel( location ); + IBakedModel bakedModel = model.bake( state, format, bakedTextureGetter ); + result.put( location, bakedModel ); + } + + return result.build(); + } + + private IModel tryLoadPartModel( ResourceLocation location ) + { + try + { + return ModelLoaderRegistry.getModel( location ); + } + catch( Exception e ) + { + AELog.error( e, "Unable to load part model " + location ); + return ModelLoaderRegistry.getMissingModel(); + } + } + + @Override + public IModelState getDefaultState() + { + return TRSRTransformation.identity(); + } +} diff --git a/src/main/java/appeng/client/render/cablebus/CableBusRenderState.java b/src/main/java/appeng/client/render/cablebus/CableBusRenderState.java new file mode 100644 index 00000000..2d554aff --- /dev/null +++ b/src/main/java/appeng/client/render/cablebus/CableBusRenderState.java @@ -0,0 +1,116 @@ +package appeng.client.render.cablebus; + + +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.List; + +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; + +import appeng.api.util.AECableType; +import appeng.api.util.AEColor; + + +/** + * This class captures the entire rendering state needed for a cable bus and transports it to the rendering thread + * for processing. + */ +public class CableBusRenderState +{ + + // The cable type used for rendering the outgoing connections to other blocks and attached parts + private AECableType cableType = AECableType.NONE; + + // The type to use for rendering the core of the cable. + private CableCoreType coreType; + + private AEColor cableColor = AEColor.Transparent; + + // Describes the outgoing connections of this cable bus to other blocks, and how they should be rendered + private EnumMap connectionTypes = new EnumMap<>( EnumFacing.class ); + + // Indicate on which sides signified by connectionTypes above, there is another cable bus. If a side is connected, but it is absent from this + // set, then it means that there is a Grid host, but not a cable bus on that side (i.e. an interface, a controller, etc.) + private EnumSet cableBusAdjacent = EnumSet.noneOf( EnumFacing.class ); + + // Specifies the number of channels used for the connection to a given side. Only contains entries if + // connections contains a corresponding entry. + private EnumMap channelsOnSide = new EnumMap<>( EnumFacing.class ); + + private EnumMap> attachments = new EnumMap<>( EnumFacing.class ); + + // For each attachment, this contains the distance from the edge until which a cable connection should be drawn + private EnumMap attachmentConnections = new EnumMap<>( EnumFacing.class ); + + public CableCoreType getCoreType() + { + return coreType; + } + + public void setCoreType( CableCoreType coreType ) + { + this.coreType = coreType; + } + + public AECableType getCableType() + { + return cableType; + } + + public void setCableType( AECableType cableType ) + { + this.cableType = cableType; + } + + public AEColor getCableColor() + { + return cableColor; + } + + public void setCableColor( AEColor cableColor ) + { + this.cableColor = cableColor; + } + + public EnumMap getChannelsOnSide() + { + return channelsOnSide; + } + + public EnumMap getConnectionTypes() + { + return connectionTypes; + } + + public void setConnectionTypes( EnumMap connectionTypes ) + { + this.connectionTypes = connectionTypes; + } + + public void setChannelsOnSide( EnumMap channelsOnSide ) + { + this.channelsOnSide = channelsOnSide; + } + + public EnumSet getCableBusAdjacent() + { + return cableBusAdjacent; + } + + public void setCableBusAdjacent( EnumSet cableBusAdjacent ) + { + this.cableBusAdjacent = cableBusAdjacent; + } + + public EnumMap> getAttachments() + { + return attachments; + } + + public EnumMap getAttachmentConnections() + { + return attachmentConnections; + } + +} diff --git a/src/main/java/appeng/client/render/cablebus/CableCoreType.java b/src/main/java/appeng/client/render/cablebus/CableCoreType.java new file mode 100644 index 00000000..5be73927 --- /dev/null +++ b/src/main/java/appeng/client/render/cablebus/CableCoreType.java @@ -0,0 +1,35 @@ +package appeng.client.render.cablebus; + + +import net.minecraft.util.ResourceLocation; + +import appeng.api.util.AEColor; +import appeng.core.AppEng; + + +/** + * AE can render the core of a cable (the core that connections are made to, in case the cable is not a straight line) + * in three different ways: + * - Glass + * - Covered (also used by the Smart Cable) + * - Dense + */ +public enum CableCoreType +{ + GLASS( "parts/cable/core/glass" ), + COVERED( "parts/cable/core/covered" ), + DENSE( "parts/cable/core/dense" ); + + private final String textureFolder; + + CableCoreType( String textureFolder ) + { + this.textureFolder = textureFolder; + } + + public ResourceLocation getTexture( AEColor color ) + { + return new ResourceLocation( AppEng.MOD_ID, textureFolder + "/" + color.name().toLowerCase() ); + } + +} diff --git a/src/main/java/appeng/client/render/cablebus/CubeBuilder.java b/src/main/java/appeng/client/render/cablebus/CubeBuilder.java new file mode 100644 index 00000000..ee4d7e9a --- /dev/null +++ b/src/main/java/appeng/client/render/cablebus/CubeBuilder.java @@ -0,0 +1,275 @@ +package appeng.client.render.cablebus; + + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.List; +import javax.vecmath.Vector4f; + +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.client.renderer.vertex.VertexFormatElement; +import net.minecraft.util.EnumFacing; +import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad; + + +/** + * Builds the quads for a cube. + */ +public class CubeBuilder { + + private VertexFormat format; + + private final List output; + + private final EnumMap textures = new EnumMap<>(EnumFacing.class); + + private EnumSet drawFaces = EnumSet.allOf(EnumFacing.class); + + private final EnumMap customUv = new EnumMap<>(EnumFacing.class); + + private int color = 0xFFFFFFFF; + + private boolean renderFullBright; + + public CubeBuilder(VertexFormat format, List output) { + this.output = output; + this.format = format; + } + + public CubeBuilder(VertexFormat format) { + this(format, new ArrayList<>(6)); + } + + public void addCube(float x1, float y1, float z1, float x2, float y2, float z2) { + x1 /= 16.0f; + y1 /= 16.0f; + z1 /= 16.0f; + x2 /= 16.0f; + y2 /= 16.0f; + z2 /= 16.0f; + + // If brightness is forced to specific values, extend the vertex format to contain the multi-texturing lightmap offset + VertexFormat savedFormat = null; + if (renderFullBright) { + savedFormat = format; + format = new VertexFormat(savedFormat); + if (!format.getElements().contains(DefaultVertexFormats.TEX_2S)) { + format.addElement(DefaultVertexFormats.TEX_2S); + } + } + + for (EnumFacing face : drawFaces) { + putFace(face, x1, y1, z1, x2, y2, z2); + } + + // Restore old format + if (savedFormat != null) { + format = savedFormat; + } + } + + private void putFace(EnumFacing face, + float x1, float y1, float z1, + float x2, float y2, float z2 + ) { + + TextureAtlasSprite texture = textures.get(face); + + UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder(format); + builder.setTexture(texture); + builder.setQuadOrientation(face); + + float u1 = 0; + float v1 = 0; + float u2 = 0; + float v2 = 0; + + // The user might have set specific UV coordinates for this face + Vector4f customUv = this.customUv.get( face ); + if( customUv != null ) + { + u1 = texture.getInterpolatedU( customUv.x ); + v1 = texture.getInterpolatedV( customUv.y ); + u2 = texture.getInterpolatedU( customUv.z ); + v2 = texture.getInterpolatedV( customUv.w ); + } + + switch (face) { + case DOWN: + if (customUv == null) + { + u1 = texture.getInterpolatedU( x1 * 16 ); + v1 = texture.getInterpolatedV( z1 * 16 ); + u2 = texture.getInterpolatedU( x2 * 16 ); + v2 = texture.getInterpolatedV( z2 * 16 ); + } + + putVertex(builder, face, x2, y1, z1, u2, v1); + putVertex(builder, face, x2, y1, z2, u2, v2); + putVertex(builder, face, x1, y1, z2, u1, v2); + putVertex(builder, face, x1, y1, z1, u1, v1); + break; + case UP: + if (customUv == null) + { + u1 = texture.getInterpolatedU( x1 * 16 ); + v1 = texture.getInterpolatedV( z1 * 16 ); + u2 = texture.getInterpolatedU( x2 * 16 ); + v2 = texture.getInterpolatedV( z2 * 16 ); + } + + putVertex(builder, face, x1, y2, z1, u1, v1); + putVertex(builder, face, x1, y2, z2, u1, v2); + putVertex(builder, face, x2, y2, z2, u2, v2); + putVertex(builder, face, x2, y2, z1, u2, v1); + break; + case NORTH: + if (customUv == null) + { + u1 = texture.getInterpolatedU( x1 * 16 ); + v1 = texture.getInterpolatedV( 16 - y1 * 16 ); + u2 = texture.getInterpolatedU( x2 * 16 ); + v2 = texture.getInterpolatedV( 16 - y2 * 16 ); + } + + putVertex(builder, face, x2, y2, z1, u1, v2); + putVertex(builder, face, x2, y1, z1, u1, v1); + putVertex(builder, face, x1, y1, z1, u2, v1); + putVertex(builder, face, x1, y2, z1, u2, v2); + break; + case SOUTH: + if (customUv == null) + { + u1 = texture.getInterpolatedU( x1 * 16 ); + v1 = texture.getInterpolatedV( 16 - y1 * 16 ); + u2 = texture.getInterpolatedU( x2 * 16 ); + v2 = texture.getInterpolatedV( 16 - y2 * 16 ); + } + + putVertex(builder, face, x1, y2, z2, u1, v2); + putVertex(builder, face, x1, y1, z2, u1, v1); + putVertex(builder, face, x2, y1, z2, u2, v1); + putVertex(builder, face, x2, y2, z2, u2, v2); + break; + case WEST: + if (customUv == null) + { + u1 = texture.getInterpolatedU( z1 * 16 ); + v1 = texture.getInterpolatedV( 16 - y1 * 16 ); + u2 = texture.getInterpolatedU( z2 * 16 ); + v2 = texture.getInterpolatedV( 16 - y2 * 16 ); + } + + putVertex(builder, face, x1, y1, z1, u1, v1); + putVertex(builder, face, x1, y1, z2, u2, v1); + putVertex(builder, face, x1, y2, z2, u2, v2); + putVertex(builder, face, x1, y2, z1, u1, v2); + break; + case EAST: + if (customUv == null) + { + u1 = texture.getInterpolatedU( z2 * 16 ); + v1 = texture.getInterpolatedV( 16 - y1 * 16 ); + u2 = texture.getInterpolatedU( z1 * 16 ); + v2 = texture.getInterpolatedV( 16 - y2 * 16 ); + } + + putVertex(builder, face, x2, y2, z1, u1, v2); + putVertex(builder, face, x2, y2, z2, u2, v2); + putVertex(builder, face, x2, y1, z2, u2, v1); + putVertex(builder, face, x2, y1, z1, u1, v1); + break; + } + + int[] vertexData = builder.build().getVertexData(); + output.add(new BakedQuad(vertexData, -1, face, texture, true, format)); + } + + private void putVertex(UnpackedBakedQuad.Builder builder, EnumFacing face, float x, float y, float z, float u, float v) { + VertexFormat format = builder.getVertexFormat(); + + for (int i = 0; i < format.getElementCount(); i++) { + VertexFormatElement e = format.getElement(i); + switch (e.getUsage()) { + case POSITION: + builder.put(i, x, y, z); + break; + case NORMAL: + builder.put(i, + face.getFrontOffsetX(), + face.getFrontOffsetY(), + face.getFrontOffsetZ()); + break; + case COLOR: + // Color format is RGBA + float r = (color >> 16 & 0xFF) / 255f; + float g = (color >> 8 & 0xFF) / 255f; + float b = (color & 0xFF) / 255f; + float a = (color >> 24 & 0xFF) / 255f; + builder.put(i, r, g, b, a); + break; + case UV: + if (e.getIndex() == 0) { + builder.put(i, u, v); + } else { + // Force Brightness to 15, this is for full bright mode + // this vertex element will only be present in that case + final float lightMapU = (float) (15 * 0x20) / 0xFFFF; + final float lightMapV = (float) (15 * 0x20) / 0xFFFF; + builder.put(i, lightMapU, lightMapV); + } + break; + default: + builder.put(i); + break; + } + } + } + + public void setTexture(TextureAtlasSprite texture) { + for (EnumFacing face : EnumFacing.values()) { + textures.put(face, texture); + } + } + + public void setTextures(TextureAtlasSprite up, TextureAtlasSprite down, TextureAtlasSprite north, TextureAtlasSprite south, TextureAtlasSprite east, TextureAtlasSprite west) { + textures.put(EnumFacing.UP, up); + textures.put(EnumFacing.DOWN, down); + textures.put(EnumFacing.NORTH, north); + textures.put(EnumFacing.SOUTH, south); + textures.put(EnumFacing.EAST, east); + textures.put(EnumFacing.WEST, west); + } + + public void setDrawFaces(EnumSet drawFaces) { + this.drawFaces = drawFaces; + } + + public void setColor(int color) { + this.color = color; + } + + /** + * Sets the vertex color for future vertices to the given RGB value, and forces the alpha component to 255. + */ + public void setColorRGB(int color) { + setColor(color | 0xFF000000); + } + + public void setRenderFullBright(boolean renderFullBright) { + this.renderFullBright = renderFullBright; + } + + public void setCustomUv( EnumFacing facing, float u1, float v1, float u2, float v2 ) + { + customUv.put( facing, new Vector4f( u1, v1, u2, v2 ) ); + } + + public List getOutput() { + return output; + } +} diff --git a/src/main/java/appeng/client/render/cablebus/QuadRotator.java b/src/main/java/appeng/client/render/cablebus/QuadRotator.java new file mode 100644 index 00000000..69b646cd --- /dev/null +++ b/src/main/java/appeng/client/render/cablebus/QuadRotator.java @@ -0,0 +1,169 @@ +package appeng.client.render.cablebus; + + +import java.util.ArrayList; +import java.util.List; +import javax.vecmath.Matrix4f; +import javax.vecmath.Point3f; +import javax.vecmath.Vector3f; + +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.client.renderer.vertex.VertexFormatElement; +import net.minecraft.util.EnumFacing; + +import appeng.client.render.FacingToRotation; +import appeng.core.AELog; + + +/** + * Assuming a default-orientation of forward=NORTH and up=UP, this class rotates a given list of quads to the desired facing + */ +public class QuadRotator +{ + + public List rotateQuads( List quads, EnumFacing newForward, EnumFacing newUp ) + { + if( newForward == EnumFacing.NORTH && newUp == EnumFacing.UP ) + { + return quads; // This is the default orientation + } + + List result = new ArrayList<>( quads.size() ); + + for( BakedQuad quad : quads ) + { + result.add( rotateQuad( quad, newForward, newUp ) ); + } + + return result; + } + + private BakedQuad rotateQuad( BakedQuad quad, EnumFacing forward, EnumFacing up ) + { + // Sanitize forward/up + if (forward.getAxis() == up.getAxis()) { + if (up.getAxis() == EnumFacing.Axis.Y) { + up = EnumFacing.NORTH; + } else { + up = EnumFacing.UP; + } + } + + FacingToRotation rotation = FacingToRotation.get( forward, up ); + Matrix4f mat = rotation.getMat(); + + // Clone the vertex data used by the quad + int[] newData = quad.getVertexData().clone(); + + // Figure out where the position is in the array + VertexFormat format = quad.getFormat(); + int posIdx = findPositionOffset( format ) / 4; + int stride = format.getNextOffset() / 4; + int normalIdx = format.getNormalOffset(); + VertexFormatElement.EnumType normalType = null; + // Figure out the type of the normals + if( normalIdx != -1 ) + { + for( int i = 0; i < format.getElements().size(); i++ ) + { + VertexFormatElement element = format.getElement( i ); + if( element.getUsage() == VertexFormatElement.EnumUsage.NORMAL ) + { + normalType = element.getType(); + } + } + } + + for( int i = 0; i < 4; i++ ) + { + Point3f pos = new Point3f( + Float.intBitsToFloat( newData[i * stride + posIdx] ) - 0.5f, + Float.intBitsToFloat( newData[i * stride + posIdx + 1] ) - 0.5f, + Float.intBitsToFloat( newData[i * stride + posIdx + 2] ) - 0.5f + ); + + // Rotate stuff around + mat.transform( pos ); + + // Write back + newData[i * stride + posIdx] = Float.floatToIntBits( pos.getX() + 0.5f ); + newData[i * stride + posIdx + 1] = Float.floatToIntBits( pos.getY() + 0.5f ); + newData[i * stride + posIdx + 2] = Float.floatToIntBits( pos.getZ() + 0.5f ); + + // Transform the normal if one is present + if ( normalIdx != -1 ) { + if( normalType == VertexFormatElement.EnumType.FLOAT ) + { + Vector3f normal = new Vector3f( + Float.intBitsToFloat( newData[i * stride + normalIdx] ), + Float.intBitsToFloat( newData[i * stride + normalIdx + 1] ), + Float.intBitsToFloat( newData[i * stride + normalIdx + 2] ) + ); + + // Rotate stuff around + mat.transform( normal ); + + // Write back + newData[i * stride + normalIdx] = Float.floatToIntBits( normal.getX() ); + newData[i * stride + normalIdx + 1] = Float.floatToIntBits( normal.getY() ); + newData[i * stride + normalIdx + 2] = Float.floatToIntBits( normal.getZ() ); + } + else if( normalType == VertexFormatElement.EnumType.BYTE ) + { + int idx = i * stride * 4 + normalIdx; + Vector3f normal = new Vector3f( getByte( newData, idx ) / 127.0f, getByte( newData, idx + 1 ) / 127.0f, getByte( newData, idx + 2 ) / 127.0f ); + + // Rotate stuff around + mat.transform( normal ); + + // Write back + setByte( newData, idx, (int) ( normal.getX() * 127 ) ); + setByte( newData, idx + 1, (int) ( normal.getY() * 127 ) ); + setByte( newData, idx + 2, (int) ( normal.getZ() * 127 ) ); + } + else + { + AELog.warn( "Unsupported normal format: {}", normalType ); + } + } + } + + EnumFacing newFace = rotation.rotate( quad.getFace() ); + return new BakedQuad( newData, quad.getTintIndex(), newFace, quad.getSprite(), quad.shouldApplyDiffuseLighting(), quad.getFormat() ); + } + + private static int getByte( int[] data, int offset ) + { + int idx = offset / 4; + int subOffset = offset % 4; + return (byte) ( data[idx] >> ( subOffset * 8 ) ); + } + + private static void setByte( int[] data, int offset, int value ) + { + int idx = offset / 4; + int subOffset = offset % 4; + int mask = 0xFF << ( subOffset * 8 ); + data[idx] = data[idx] & ( ~mask ) | ( (value & 0xFF) << (subOffset * 8) ); + } + + private int findPositionOffset( VertexFormat format ) + { + List elements = format.getElements(); + for( int i = 0; i < elements.size(); i++ ) + { + VertexFormatElement e = elements.get( i ); + if( e.isPositionElement() ) + { + if( e.getType() != VertexFormatElement.EnumType.FLOAT ) + { + throw new IllegalArgumentException( "Only floating point positions are supported" ); + } + return i; + } + } + + throw new IllegalArgumentException( "Vertex format " + format + " has no position attribute!" ); + } +} diff --git a/src/main/java/appeng/client/render/cablebus/SmartCableTextures.java b/src/main/java/appeng/client/render/cablebus/SmartCableTextures.java new file mode 100644 index 00000000..9c162374 --- /dev/null +++ b/src/main/java/appeng/client/render/cablebus/SmartCableTextures.java @@ -0,0 +1,81 @@ +package appeng.client.render.cablebus; + + +import java.util.Arrays; + +import com.google.common.base.Function; + +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.util.ResourceLocation; + +import appeng.core.AppEng; + + +/** + * Manages the channel textures for smart cables. + */ +public class SmartCableTextures +{ + + public static final ResourceLocation[] SMART_CHANNELS_TEXTURES = { + new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_00" ), + new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_01" ), + new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_02" ), + new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_03" ), + new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_04" ), + new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_10" ), + new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_11" ), + new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_12" ), + new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_13" ), + new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_14" ) + }; + + // Textures used to display channels on smart cables. There's two sets of 5 textures each, and + // one of each set are composed together to get even/odd colored channels + private final TextureAtlasSprite[] textures; + + public SmartCableTextures( Function bakedTextureGetter ) + { + textures = Arrays.stream( SMART_CHANNELS_TEXTURES ) + .map( bakedTextureGetter::apply ) + .toArray( TextureAtlasSprite[]::new ); + } + + /** + * The odd variant is used for displaying channels 1-4 as in use. + */ + public TextureAtlasSprite getOddTextureForChannels( int channels ) + { + if( channels < 0 ) + { + return textures[0]; + } + else if( channels <= 4 ) + { + return textures[channels]; + } + else + { + return textures[4]; + } + } + + /** + * The odd variant is used for displaying channels 5-8 as in use. + */ + public TextureAtlasSprite getEvenTextureForChannels( int channels ) + { + if( channels < 5 ) + { + return textures[5]; + } + else if( channels <= 9 ) + { + return textures[channels]; + } + else + { + return textures[9]; + } + } +} diff --git a/src/main/java/appeng/client/render/model/AutoRotatingCacheKey.java b/src/main/java/appeng/client/render/model/AutoRotatingCacheKey.java new file mode 100644 index 00000000..587f3b55 --- /dev/null +++ b/src/main/java/appeng/client/render/model/AutoRotatingCacheKey.java @@ -0,0 +1,71 @@ +package appeng.client.render.model; + + +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; + + +/** + * Used as the cache key for caching automatically rotated baked models. + */ +final class AutoRotatingCacheKey +{ + private final IBlockState blockState; + private final EnumFacing forward; + private final EnumFacing up; + private final EnumFacing side; + + AutoRotatingCacheKey( IBlockState blockState, EnumFacing forward, EnumFacing up, EnumFacing side ) + { + this.blockState = blockState; + this.forward = forward; + this.up = up; + this.side = side; + } + + public IBlockState getBlockState() + { + return blockState; + } + + public EnumFacing getForward() + { + return forward; + } + + public EnumFacing getUp() + { + return up; + } + + public EnumFacing getSide() + { + return side; + } + + @Override + public boolean equals( Object o ) + { + if( this == o ) + { + return true; + } + if( o == null || getClass() != o.getClass() ) + { + return false; + } + + AutoRotatingCacheKey cacheKey = (AutoRotatingCacheKey) o; + return blockState.equals( cacheKey.blockState ) && forward == cacheKey.forward && up == cacheKey.up && side == cacheKey.side; + } + + @Override + public int hashCode() + { + int result = blockState.hashCode(); + result = 31 * result + forward.hashCode(); + result = 31 * result + up.hashCode(); + result = 31 * result + ( side != null ? side.hashCode() : 0 ); + return result; + } +} diff --git a/src/main/java/appeng/client/render/model/AutoRotatingModel.java b/src/main/java/appeng/client/render/model/AutoRotatingModel.java new file mode 100644 index 00000000..7f44be68 --- /dev/null +++ b/src/main/java/appeng/client/render/model/AutoRotatingModel.java @@ -0,0 +1,276 @@ + +package appeng.client.render.model; + + +import java.util.ArrayList; +import java.util.List; +import javax.vecmath.Vector3f; +import javax.vecmath.Vector4f; + +import com.google.common.base.Objects; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms; +import net.minecraft.client.renderer.block.model.ItemOverrideList; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.client.renderer.vertex.VertexFormatElement; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.Vec3i; +import net.minecraftforge.client.model.pipeline.IVertexConsumer; +import net.minecraftforge.client.model.pipeline.QuadGatheringTransformer; +import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad; +import net.minecraftforge.common.property.IExtendedBlockState; + +import appeng.block.AEBaseTileBlock; +import appeng.client.render.FacingToRotation; + + +public class AutoRotatingModel implements IBakedModel +{ + + private final IBakedModel parent; + private final LoadingCache> quadCache; + + public AutoRotatingModel( IBakedModel parent ) + { + this.parent = parent; + // 6 (DUNSWE) * 6 (DUNSWE) * 7 (DUNSWE + null) = 252 + this.quadCache = CacheBuilder.newBuilder().maximumSize( 252 ).build( new CacheLoader>() + { + @Override + public List load( AutoRotatingCacheKey key ) throws Exception + { + return getRotatedModel( key.getBlockState(), key.getSide(), key.getForward(), key.getUp() ); + } + } ); + } + + private List getRotatedModel( IBlockState state, EnumFacing side, EnumFacing forward, EnumFacing up ) + { + FacingToRotation f2r = FacingToRotation.get( forward, up ); + List original = AutoRotatingModel.this.parent.getQuads( state, f2r.resultingRotate( side ), 0 ); + List rotated = new ArrayList<>( original.size() ); + for( BakedQuad quad : original ) + { + VertexFormat format = quad.getFormat(); + UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder( format ); + VertexRotator rot = new VertexRotator( f2r, quad.getFace() ); + rot.setParent( builder ); + quad.pipe( rot ); + builder.setQuadOrientation( f2r.rotate( quad.getFace() ) ); + BakedQuad q = builder.build(); + rotated.add( q ); + } + return rotated; + } + + @Override + public boolean isAmbientOcclusion() + { + return parent.isAmbientOcclusion(); + } + + @Override + public boolean isGui3d() + { + return parent.isGui3d(); + } + + @Override + public boolean isBuiltInRenderer() + { + return parent.isBuiltInRenderer(); + } + + @Override + public TextureAtlasSprite getParticleTexture() + { + return parent.getParticleTexture(); + } + + @Override + public ItemCameraTransforms getItemCameraTransforms() + { + return parent.getItemCameraTransforms(); + } + + @Override + public ItemOverrideList getOverrides() + { + return parent.getOverrides(); + } + + @Override + public List getQuads( IBlockState state, EnumFacing side, long rand ) + { + if( !( state instanceof IExtendedBlockState ) ) + { + return parent.getQuads( state, side, rand ); + } + + IExtendedBlockState extState = (IExtendedBlockState) state; + + EnumFacing forward = extState.getValue( AEBaseTileBlock.FORWARD ); + EnumFacing up = extState.getValue( AEBaseTileBlock.UP ); + + if( forward == null || up == null ) + { + return parent.getQuads( state, side, rand ); + } + + // The model has other properties than just forward/up, so it would cause our cache to inadvertendly also cache these + // additional states, possibly leading to huge isseus if the other extended state properties do not implement equals/hashCode correctly + if( extState.getUnlistedProperties().size() != 2 ) + { + return getRotatedModel( extState, side, forward, up ); + } + + AutoRotatingCacheKey key = new AutoRotatingCacheKey( extState.getClean(), forward, up, side ); + + return quadCache.getUnchecked( key ); + } + + public static class VertexRotator extends QuadGatheringTransformer + { + private final FacingToRotation f2r; + private final EnumFacing face; + + public VertexRotator( FacingToRotation f2r, EnumFacing face ) + { + this.f2r = f2r; + this.face = face; + } + + @Override + public void setParent( IVertexConsumer parent ) + { + super.setParent( parent ); + if( Objects.equal( getVertexFormat(), parent.getVertexFormat() ) ) + { + return; + } + setVertexFormat( parent.getVertexFormat() ); + } + + @Override + protected void processQuad() + { + VertexFormat format = parent.getVertexFormat(); + int count = format.getElementCount(); + + for( int v = 0; v < 4; v++ ) + { + for( int e = 0; e < count; e++ ) + { + VertexFormatElement element = format.getElement( e ); + if( element.getUsage() == VertexFormatElement.EnumUsage.POSITION ) + { + parent.put( e, transform( quadData[e][v] ) ); + } + else if( element.getUsage() == VertexFormatElement.EnumUsage.NORMAL ) + { + parent.put( e, transformNormal( quadData[e][v] ) ); + } + else + { + parent.put( e, quadData[e][v] ); + } + } + } + } + + private float[] transform( float[] fs ) + { + switch( fs.length ) + { + case 3: + Vector3f vec = new Vector3f( fs[0], fs[1], fs[2] ); + vec.x -= 0.5f; + vec.y -= 0.5f; + vec.z -= 0.5f; + f2r.getMat().transform( vec ); + vec.x += 0.5f; + vec.y += 0.5f; + vec.z += 0.5f; + return new float[] { + vec.x, + vec.y, + vec.z + }; + case 4: + Vector4f vecc = new Vector4f( fs[0], fs[1], fs[2], fs[3] ); + vecc.x -= 0.5f; + vecc.y -= 0.5f; + vecc.z -= 0.5f; + f2r.getMat().transform( vecc ); + vecc.x += 0.5f; + vecc.y += 0.5f; + vecc.z += 0.5f; + return new float[] { + vecc.x, + vecc.y, + vecc.z, + vecc.w + }; + + default: + return fs; + } + } + + private float[] transformNormal( float[] fs ) + { + switch( fs.length ) + { + case 3: + Vec3i vec = f2r.rotate( face ).getDirectionVec(); + return new float[] { + vec.getX(), + vec.getY(), + vec.getZ() + }; + case 4: + Vector4f veccc = new Vector4f( fs[0], fs[1], fs[2], fs[3] ); + Vec3i vecc = f2r.rotate( face ).getDirectionVec(); + return new float[] { + vecc.getX(), + vecc.getY(), + vecc.getZ(), + veccc.w + }; + + default: + return fs; + } + } + + public void setQuadTint( int tint ) + { + parent.setQuadTint( tint ); + } + + @Override + public void setQuadOrientation( EnumFacing orientation ) + { + parent.setQuadOrientation( orientation ); + } + + @Override + public void setApplyDiffuseLighting( boolean diffuse ) + { + parent.setApplyDiffuseLighting( diffuse ); + } + + @Override + public void setTexture( TextureAtlasSprite texture ) + { + parent.setTexture( texture ); + } + } +} diff --git a/src/main/java/appeng/client/render/model/CachingRotatingBakedModel.java b/src/main/java/appeng/client/render/model/CachingRotatingBakedModel.java deleted file mode 100644 index 24e8108a..00000000 --- a/src/main/java/appeng/client/render/model/CachingRotatingBakedModel.java +++ /dev/null @@ -1,96 +0,0 @@ - -package appeng.client.render.model; - - -import java.util.List; - -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; - -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.apache.commons.lang3.tuple.Pair; - -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.renderer.block.model.IBakedModel; -import net.minecraft.client.renderer.block.model.ItemCameraTransforms; -import net.minecraft.client.renderer.block.model.ItemOverrideList; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.util.EnumFacing; - -import appeng.api.client.BakingPipeline; -import appeng.client.render.model.pipeline.DoubleFacingQuadRotator; -import appeng.client.render.model.pipeline.ParentQuads; -import appeng.client.render.model.pipeline.TypeTransformer; - - -public class CachingRotatingBakedModel implements IBakedModel -{ - - private static final BakingPipeline pipeline = new BakingPipeline<>( new ParentQuads(), TypeTransformer.quads2vecs, new DoubleFacingQuadRotator(), TypeTransformer.vecs2quads ); - private final IBakedModel parent; - private final LoadingCache, List> quadCache; - - public CachingRotatingBakedModel( IBakedModel parent ) - { - this.parent = parent; - // 6 (DUNSWE) * 6 (DUNSWE) * 7 (DUNSWE + null) = 252 - this.quadCache = CacheBuilder.newBuilder().maximumSize( 252 ).build( new CacheLoader, List>(){ - - @Override - public List load( Pair key ) throws Exception - { - return pipeline.pipe( null, parent, key.getLeft(), key.getRight(), 0 ); - } - - } ); - } - - @Override - public boolean isAmbientOcclusion() - { - return parent.isAmbientOcclusion(); - } - - @Override - public boolean isGui3d() - { - return parent.isGui3d(); - } - - @Override - public boolean isBuiltInRenderer() - { - return parent.isBuiltInRenderer(); - } - - @Override - public TextureAtlasSprite getParticleTexture() - { - return parent.getParticleTexture(); - } - - @Override - public ItemCameraTransforms getItemCameraTransforms() - { - return parent.getItemCameraTransforms(); - } - - @Override - public ItemOverrideList getOverrides() - { - return parent.getOverrides(); - } - - @Override - public List getQuads( IBlockState state, EnumFacing side, long rand ) - { - if( state == null ) - { - return parent.getQuads( state, side, rand ); - } - return quadCache.getUnchecked( new ImmutablePair( state, side ) ); - } - -} diff --git a/src/main/java/appeng/client/render/model/ModelCompass.java b/src/main/java/appeng/client/render/model/ModelCompass.java deleted file mode 100644 index 4c03c9d8..00000000 --- a/src/main/java/appeng/client/render/model/ModelCompass.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * This file is part of Applied Energistics 2. - * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. - * - * Applied Energistics 2 is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Applied Energistics 2 is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Applied Energistics 2. If not, see . - */ - -package appeng.client.render.model; - - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelRenderer; - - -public class ModelCompass extends ModelBase -{ - - private final ModelRenderer Ring1; - private final ModelRenderer Ring2; - private final ModelRenderer Ring3; - private final ModelRenderer Ring4; - private final ModelRenderer Middle; - private final ModelRenderer Base; - - private final ModelRenderer Pointer; - - public ModelCompass() - { - this.textureWidth = 16; - this.textureHeight = 8; - - this.Ring1 = new ModelRenderer( this, 0, 0 ); - this.Ring1.addBox( 0F, 0F, 0F, 4, 1, 1 ); - this.Ring1.setRotationPoint( -2F, 22F, 2F ); - this.Ring1.setTextureSize( 16, 8 ); - this.Ring1.mirror = true; - this.setRotation( this.Ring1, 0F, 0F, 0F ); - - this.Ring2 = new ModelRenderer( this, 0, 0 ); - this.Ring2.addBox( 0F, 0F, 0F, 1, 1, 4 ); - this.Ring2.setRotationPoint( -3F, 22F, -2F ); - this.Ring2.setTextureSize( 16, 8 ); - this.Ring2.mirror = true; - this.setRotation( this.Ring2, 0F, 0F, 0F ); - - this.Ring3 = new ModelRenderer( this, 0, 0 ); - this.Ring3.addBox( 0F, 0F, 0F, 4, 1, 1 ); - this.Ring3.setRotationPoint( -2F, 22F, -3F ); - this.Ring3.setTextureSize( 16, 8 ); - this.Ring3.mirror = true; - this.setRotation( this.Ring3, 0F, 0F, 0F ); - - this.Ring4 = new ModelRenderer( this, 0, 0 ); - this.Ring4.addBox( 0F, 0F, 0F, 1, 1, 4 ); - this.Ring4.setRotationPoint( 2F, 22F, -2F ); - this.Ring4.setTextureSize( 16, 8 ); - this.Ring4.mirror = true; - this.setRotation( this.Ring4, 0F, 0F, 0F ); - - this.Middle = new ModelRenderer( this, 0, 0 ); - this.Middle.addBox( 0F, 0F, 0F, 1, 1, 1 ); - this.Middle.setRotationPoint( -0.5333334F, 22F, -0.5333334F ); - this.Middle.setTextureSize( 16, 8 ); - this.Middle.mirror = true; - this.setRotation( this.Middle, 0F, 0F, 0F ); - - this.Pointer = new ModelRenderer( this, 0, 0 ); - this.Pointer.setTextureOffset( 0, 5 ); - this.Pointer.addBox( -0.5F, 0F, 0F, 1, 1, 2 ); - this.Pointer.setRotationPoint( 0.5F, 22.5F, 0.5F ); - this.Pointer.setTextureSize( 16, 8 ); - this.Pointer.mirror = true; - this.Pointer.offsetZ = -0.034f; - this.Pointer.offsetX = -0.034f; - this.setRotation( this.Pointer, 0F, 0F, 0F ); - - this.Base = new ModelRenderer( this, 0, 0 ); - this.Base.addBox( 0F, 0F, 0F, 4, 1, 4 ); - this.Base.setRotationPoint( -2F, 23F, -2F ); - this.Base.setTextureSize( 16, 8 ); - this.Base.mirror = true; - this.setRotation( this.Base, 0F, 0F, 0F ); - } - - private void setRotation( final ModelRenderer model, final float x, final float y, final float z ) - { - model.rotateAngleX = x; - model.rotateAngleY = y; - model.rotateAngleZ = z; - } - - public void renderAll( final float rad ) - { - this.setRotation( this.Pointer, 0F, 0F, 0F ); - - this.Pointer.rotateAngleY = rad; - - this.Base.render( 0.0625F ); - this.Middle.render( 0.0625F ); - - this.Pointer.render( 0.0625F ); - - this.Ring1.render( 0.0625F ); - this.Ring2.render( 0.0625F ); - this.Ring3.render( 0.0625F ); - this.Ring4.render( 0.0625F ); - } -} diff --git a/src/main/java/appeng/client/render/model/ModelsCache.java b/src/main/java/appeng/client/render/model/ModelsCache.java deleted file mode 100644 index 7c4518d7..00000000 --- a/src/main/java/appeng/client/render/model/ModelsCache.java +++ /dev/null @@ -1,119 +0,0 @@ - -package appeng.client.render.model; - - -import java.util.HashMap; -import java.util.Map; - -import com.google.common.base.Function; -import com.google.common.base.Optional; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.block.model.IBakedModel; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; -import net.minecraft.client.renderer.vertex.VertexFormat; -import net.minecraft.client.resources.IResourceManager; -import net.minecraft.client.resources.IResourceManagerReloadListener; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.client.model.IModel; -import net.minecraftforge.client.model.ModelLoaderRegistry; -import net.minecraftforge.common.model.IModelState; - - -public enum ModelsCache implements IResourceManagerReloadListener -{ - - INSTANCE; - - public static final IModelState DEFAULTMODELSTATE = opt -> Optional.absent(); - public static final VertexFormat DEFAULTVERTEXFORMAT = DefaultVertexFormats.BLOCK; - public static final Function DEFAULTTEXTUREGETTER = texture -> Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite( texture.toString() ); - - private final Map cache = new HashMap<>(); - private final Map bakedCache = new HashMap<>(); - - public IModel getOrLoadModel( ResourceLocation location ) - { - IModel model = cache.get( location ); - if( model == null ) - { - try - { - model = ModelLoaderRegistry.getModel( location ); - } - catch( Exception e ) - { - // TODO 1.10.2-R - log this in pretty way - e.printStackTrace(); - model = ModelLoaderRegistry.getMissingModel(); - } - cache.put( location, model ); - } - return model; - } - - public IBakedModel getModel( ResourceLocation key ) - { - return bakedCache.get( key ); - } - - public IBakedModel getOrLoadModel( ResourceLocation key, ResourceLocation location, IModelState state, VertexFormat format, Function textureGetter ) - { - IBakedModel model = getModel( key ); - if( model == null ) - { - model = getOrLoadModel( location ).bake( state, format, textureGetter ); - bakedCache.put( key, model ); - } - return model; - } - - public IBakedModel getOrLoadModel( ResourceLocation key, ResourceLocation location, IModelState state, VertexFormat format ) - { - return getOrLoadModel( key, location, state, format, DEFAULTTEXTUREGETTER ); - } - - public IBakedModel getOrLoadModel( ResourceLocation key, ResourceLocation location, IModelState state, Function textureGetter ) - { - return getOrLoadModel( key, location, state, DEFAULTVERTEXFORMAT, textureGetter ); - } - - public IBakedModel getOrLoadModel( ResourceLocation key, ResourceLocation location, VertexFormat format, Function textureGetter ) - { - return getOrLoadModel( key, location, DEFAULTMODELSTATE, format, textureGetter ); - } - - public IBakedModel getOrLoadModel( ResourceLocation key, ResourceLocation location, IModelState state ) - { - return getOrLoadModel( key, location, state, DEFAULTVERTEXFORMAT, DEFAULTTEXTUREGETTER ); - } - - public IBakedModel getOrLoadModel( ResourceLocation key, ResourceLocation location, VertexFormat format ) - { - return getOrLoadModel( key, location, DEFAULTMODELSTATE, format, DEFAULTTEXTUREGETTER ); - } - - public IBakedModel getOrLoadModel( ResourceLocation key, ResourceLocation location, Function textureGetter ) - { - return getOrLoadModel( key, location, DEFAULTMODELSTATE, DEFAULTVERTEXFORMAT, textureGetter ); - } - - public IBakedModel getOrLoadModel( ResourceLocation key, ResourceLocation location ) - { - return getOrLoadModel( key, location, DEFAULTMODELSTATE, DEFAULTVERTEXFORMAT, DEFAULTTEXTUREGETTER ); - } - - public IBakedModel getOrLoadBakedModel( ResourceLocation location ) - { - return getOrLoadModel( location, location, DEFAULTMODELSTATE, DEFAULTVERTEXFORMAT, DEFAULTTEXTUREGETTER ); - } - - @Override - public void onResourceManagerReload( IResourceManager resourceManager ) - { - cache.clear(); - bakedCache.clear(); - } - -} diff --git a/src/main/java/appeng/client/render/model/RenderHelper.java b/src/main/java/appeng/client/render/model/RenderHelper.java index 694708b7..836f9ad1 100644 --- a/src/main/java/appeng/client/render/model/RenderHelper.java +++ b/src/main/java/appeng/client/render/model/RenderHelper.java @@ -27,7 +27,7 @@ import com.google.common.collect.Lists; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.Vec3d; - +// TODO: Investigate use of CubeBuilder instead final class RenderHelper { diff --git a/src/main/java/appeng/client/render/model/pipeline/BakingPipelineBakedModel.java b/src/main/java/appeng/client/render/model/pipeline/BakingPipelineBakedModel.java deleted file mode 100644 index 57757357..00000000 --- a/src/main/java/appeng/client/render/model/pipeline/BakingPipelineBakedModel.java +++ /dev/null @@ -1,72 +0,0 @@ - -package appeng.client.render.model.pipeline; - - -import java.util.ArrayList; -import java.util.List; - -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.renderer.block.model.IBakedModel; -import net.minecraft.client.renderer.block.model.ItemCameraTransforms; -import net.minecraft.client.renderer.block.model.ItemOverrideList; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.util.EnumFacing; - -import appeng.api.client.BakingPipeline; -import appeng.api.client.BakingPipelineElement; - - -public class BakingPipelineBakedModel extends BakingPipeline implements IBakedModel -{ - - private final IBakedModel parent; - public BakingPipelineBakedModel( IBakedModel parent, BakingPipelineElement... pipeline ) - { - super( pipeline ); - this.parent = parent; - } - - @Override - public List getQuads( IBlockState state, EnumFacing side, long rand ) - { - return pipe( new ArrayList(), parent, state, side, rand ); - } - - @Override - public boolean isAmbientOcclusion() - { - return parent.isAmbientOcclusion(); - } - - @Override - public boolean isGui3d() - { - return parent.isGui3d(); - } - - @Override - public boolean isBuiltInRenderer() - { - return parent.isBuiltInRenderer(); - } - - @Override - public TextureAtlasSprite getParticleTexture() - { - return parent.getParticleTexture(); - } - - @Override - public ItemCameraTransforms getItemCameraTransforms() - { - return parent.getItemCameraTransforms(); - } - - @Override - public ItemOverrideList getOverrides() - { - return parent.getOverrides(); - } - -} diff --git a/src/main/java/appeng/client/render/model/pipeline/DoubleFacingQuadRotator.java b/src/main/java/appeng/client/render/model/pipeline/DoubleFacingQuadRotator.java deleted file mode 100644 index 0aa797be..00000000 --- a/src/main/java/appeng/client/render/model/pipeline/DoubleFacingQuadRotator.java +++ /dev/null @@ -1,117 +0,0 @@ - -package appeng.client.render.model.pipeline; - - -import java.util.ArrayList; -import java.util.List; -import javax.vecmath.Vector3f; -import javax.vecmath.Vector4f; - -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.block.model.IBakedModel; -import net.minecraft.client.renderer.vertex.VertexFormatElement; -import net.minecraft.util.EnumFacing; -import net.minecraftforge.common.property.IExtendedBlockState; - -import appeng.api.client.BakingPipelineElement; -import appeng.block.AEBaseTileBlock; -import appeng.client.render.FacingToRotation; - - -public class DoubleFacingQuadRotator implements BakingPipelineElement -{ - - @Override - public List pipe( List elements, IBakedModel parent, IBlockState state, EnumFacing side, long rand ) - { - if( state != null ) - { - IExtendedBlockState extState = (IExtendedBlockState) state; - - EnumFacing forward = extState.getValue( AEBaseTileBlock.FORWARD ); - if( forward == null ) - { - forward = EnumFacing.NORTH; - } - EnumFacing up = extState.getValue( AEBaseTileBlock.UP ); - if( up == null ) - { - up = EnumFacing.UP; - } - final FacingToRotation f2r = FacingToRotation.get( forward, up ); - List rotated = new ArrayList<>(); - for( QuadVertexData data : elements ) - { - data.setFace( f2r.rotate( data.getFace() ) ); - float[][][] qd = data.getData(); - for( int v = 0; v < 4; v++ ) - { - for( int e = 0; e < data.getFormat().getElementCount(); e++ ) - { - VertexFormatElement element = data.getFormat().getElement( e ); - if( element.getUsage() == VertexFormatElement.EnumUsage.POSITION ) - { - qd[v][e] = transform( f2r, qd[v][e] ); - } - else if( element.getUsage() == VertexFormatElement.EnumUsage.NORMAL ) - { - qd[v][e] = transformNormal( f2r, qd[v][e] ); - } - } - } - rotated.add( new QuadVertexData( data.getFormat(), qd, data.getTintIndex(), data.getFace(), data.getSprite(), data.shouldApplyDiffuseLighting() ) ); - } - return rotated; - } - return elements; - } - - private float[] transform( FacingToRotation f2r, float[] fs ) - { - switch( fs.length ) - { - case 3: - Vector3f vec = new Vector3f( fs[0], fs[1], fs[2] ); - vec.x -= 0.5f; - vec.y -= 0.5f; - vec.z -= 0.5f; - f2r.getMat().transform( vec ); - vec.x += 0.5f; - vec.y += 0.5f; - vec.z += 0.5f; - return new float[] { vec.x, vec.y, vec.z }; - case 4: - Vector4f vecc = new Vector4f( fs[0], fs[1], fs[2], fs[3] ); - vecc.x -= 0.5f; - vecc.y -= 0.5f; - vecc.z -= 0.5f; - f2r.getMat().transform( vecc ); - vecc.x += 0.5f; - vecc.y += 0.5f; - vecc.z += 0.5f; - return new float[] { vecc.x, vecc.y, vecc.z, vecc.w }; - - default: - return fs; - } - } - - private float[] transformNormal( FacingToRotation f2r, float[] fs ) - { - switch( fs.length ) - { - case 3: - Vector3f vec = new Vector3f( fs[0], fs[1], fs[2] ); - f2r.getMat().transform( vec ); - return new float[] { vec.x, vec.y, vec.z }; - case 4: - Vector4f vecc = new Vector4f( fs[0], fs[1], fs[2], fs[3] ); - f2r.getMat().transform( vecc ); - return new float[] { vecc.x, vecc.y, vecc.z, vecc.w }; - - default: - return fs; - } - } - -} diff --git a/src/main/java/appeng/client/render/model/pipeline/FacingQuadRotator.java b/src/main/java/appeng/client/render/model/pipeline/FacingQuadRotator.java deleted file mode 100644 index 4f2664a7..00000000 --- a/src/main/java/appeng/client/render/model/pipeline/FacingQuadRotator.java +++ /dev/null @@ -1,39 +0,0 @@ - -package appeng.client.render.model.pipeline; - - -import java.util.List; - -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.block.model.IBakedModel; -import net.minecraft.util.EnumFacing; -import net.minecraftforge.common.model.TRSRTransformation; - - -public class FacingQuadRotator extends MatVecApplicator -{ - - private EnumFacing override; - - public FacingQuadRotator( EnumFacing override ) - { - super( TRSRTransformation.getMatrix( override ) ); - this.override = override; - } - - public FacingQuadRotator() - { - this.override = null; - } - - @Override - public List pipe( List elements, IBakedModel parent, IBlockState state, EnumFacing side, long rand ) - { - if( override == null ) - { - setMatrix( TRSRTransformation.getMatrix( side ) ); - } - return super.pipe( elements, parent, state, side, rand ); - } - -} diff --git a/src/main/java/appeng/client/render/model/pipeline/MatVecApplicator.java b/src/main/java/appeng/client/render/model/pipeline/MatVecApplicator.java deleted file mode 100644 index cffcbd6b..00000000 --- a/src/main/java/appeng/client/render/model/pipeline/MatVecApplicator.java +++ /dev/null @@ -1,141 +0,0 @@ - -package appeng.client.render.model.pipeline; - - -import java.util.ArrayList; -import java.util.List; - -import javax.vecmath.Matrix4f; -import javax.vecmath.Vector3f; -import javax.vecmath.Vector4f; - -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.block.model.IBakedModel; -import net.minecraft.client.renderer.vertex.VertexFormatElement; -import net.minecraft.util.EnumFacing; -import net.minecraftforge.common.model.TRSRTransformation; - -import appeng.api.client.BakingPipelineElement; - - -public class MatVecApplicator implements BakingPipelineElement -{ - - private Matrix4f matrix; - private boolean forceTranslate; - - public MatVecApplicator( Matrix4f matrix, boolean forceTranslate ) - { - this.matrix = matrix; - this.forceTranslate = forceTranslate; - } - - public MatVecApplicator( Matrix4f matrix ) - { - this( matrix, false ); - } - - public MatVecApplicator() - { - this( new Matrix4f() ); - } - - public Matrix4f getMatrix() - { - return matrix; - } - - public void setMatrix( Matrix4f matrix ) - { - this.matrix = matrix; - } - - public boolean forceTranslate() - { - return forceTranslate; - } - - public void setForceTranslate( boolean forceTranslate ) - { - this.forceTranslate = forceTranslate; - } - - @Override - public List pipe( List elements, IBakedModel parent, IBlockState state, EnumFacing side, long rand ) - { - List rotated = new ArrayList(); - for( QuadVertexData data : elements ) - { - float[][][] qd = data.getData(); - data.setFace( side != null ? TRSRTransformation.rotate( matrix, side ) : side ); - for( int v = 0; v < 4; v++ ) - { - for( int e = 0; e < data.getFormat().getElementCount(); e++ ) - { - VertexFormatElement element = data.getFormat().getElement( e ); - if( element.getUsage() == VertexFormatElement.EnumUsage.POSITION ) - { - qd[v][e] = transform( qd[v][e] ); - } - else if( element.getUsage() == VertexFormatElement.EnumUsage.NORMAL ) - { - qd[v][e] = transformNormal( qd[v][e] ); - } - } - } - rotated.add( new QuadVertexData( data.getFormat(), qd, data.getTintIndex(), data.getFace(), data.getSprite(), data.shouldApplyDiffuseLighting() ) ); - } - return rotated; - } - - private float[] transform( float[] fs ) - { - switch( fs.length ) - { - case 3: - Vector4f vec = new Vector4f( fs[0], fs[1], fs[2], forceTranslate ? 1 : 0 ); - vec.x -= 0.5f; - vec.y -= 0.5f; - vec.z -= 0.5f; - this.matrix.transform( vec ); - vec.x += 0.5f; - vec.y += 0.5f; - vec.z += 0.5f; - return new float[] { vec.x, vec.y, vec.z }; - case 4: - Vector4f vecc = new Vector4f( fs[0], fs[1], fs[2], forceTranslate ? 1 : fs[3] ); - vecc.x -= 0.5f; - vecc.y -= 0.5f; - vecc.z -= 0.5f; - this.matrix.transform( vecc ); - vecc.x += 0.5f; - vecc.y += 0.5f; - vecc.z += 0.5f; - return new float[] { vecc.x, vecc.y, vecc.z, vecc.w }; - - default: - return fs; - } - } - - private float[] transformNormal( float[] fs ) - { - switch( fs.length ) - { - case 3: - Vector3f vec = new Vector3f( fs[0], fs[1], fs[2] ); - this.matrix.transform( vec ); - vec.normalize(); - return new float[] { vec.x, vec.y, vec.z }; - case 4: - Vector4f vecc = new Vector4f( fs[0], fs[1], fs[2], fs[3] ); - this.matrix.transform( vecc ); - vecc.normalize(); - return new float[] { vecc.x, vecc.y, vecc.z, vecc.w }; - - default: - return fs; - } - } - -} diff --git a/src/main/java/appeng/client/render/model/pipeline/Merge.java b/src/main/java/appeng/client/render/model/pipeline/Merge.java deleted file mode 100644 index a6b60ffd..00000000 --- a/src/main/java/appeng/client/render/model/pipeline/Merge.java +++ /dev/null @@ -1,37 +0,0 @@ - -package appeng.client.render.model.pipeline; - - -import java.util.ArrayList; -import java.util.List; - -import com.google.common.collect.ImmutableList; - -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.block.model.IBakedModel; -import net.minecraft.util.EnumFacing; - -import appeng.api.client.BakingPipelineElement; - - -public class Merge implements BakingPipelineElement -{ - - private final ImmutableList> pipeline; - - public Merge( BakingPipelineElement... pipeline ) - { - this.pipeline = ImmutableList.copyOf( pipeline ); - } - - @Override - public List pipe( List elements, IBakedModel parent, IBlockState state, EnumFacing side, long rand ) - { - for( BakingPipelineElement element : pipeline ) - { - elements.addAll( element.pipe( new ArrayList<>(), parent, state, side, rand ) ); - } - return elements; - } - -} diff --git a/src/main/java/appeng/client/render/model/pipeline/ParentQuads.java b/src/main/java/appeng/client/render/model/pipeline/ParentQuads.java deleted file mode 100644 index bd45579f..00000000 --- a/src/main/java/appeng/client/render/model/pipeline/ParentQuads.java +++ /dev/null @@ -1,21 +0,0 @@ -package appeng.client.render.model.pipeline; - -import java.util.List; - -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.renderer.block.model.IBakedModel; -import net.minecraft.util.EnumFacing; - -import appeng.api.client.BakingPipelineElement; - -public class ParentQuads implements BakingPipelineElement -{ - - @Override - public List pipe( List elements, IBakedModel parent, IBlockState state, EnumFacing side, long rand ) - { - return parent.getQuads( state, side, rand ); - } - -} diff --git a/src/main/java/appeng/client/render/model/pipeline/QuadVertexData.java b/src/main/java/appeng/client/render/model/pipeline/QuadVertexData.java deleted file mode 100644 index 993b281c..00000000 --- a/src/main/java/appeng/client/render/model/pipeline/QuadVertexData.java +++ /dev/null @@ -1,121 +0,0 @@ - -package appeng.client.render.model.pipeline; - - -import java.lang.reflect.Field; - -import com.google.common.base.Throwables; - -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.renderer.vertex.VertexFormat; -import net.minecraft.util.EnumFacing; -import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad; -import net.minecraftforge.fml.relauncher.ReflectionHelper; - - -public final class QuadVertexData -{ - - private static final Field unpackedData = ReflectionHelper.findField( UnpackedBakedQuad.class, "unpackedData" ); - - private static float[][][] unpackedData( UnpackedBakedQuad quad ) - { - try - { - return (float[][][]) unpackedData.get( quad ); - } - catch( Exception e ) - { - throw Throwables.propagate( e ); - } - } - - private VertexFormat format; - private float[][][] data; - - private int tintIndex; - private EnumFacing face; - private TextureAtlasSprite sprite; - protected boolean applyDiffuseLighting; - - public QuadVertexData( VertexFormat format, float[][][] data, int tintIndex, EnumFacing face, TextureAtlasSprite sprite, boolean applyDiffuseLighting ) - { - this.format = format; - this.data = data; - this.tintIndex = tintIndex; - this.face = face; - this.sprite = sprite; - this.applyDiffuseLighting = applyDiffuseLighting; - } - - public QuadVertexData( UnpackedBakedQuad quad ) - { - this( quad.getFormat(), unpackedData( quad ), quad.getTintIndex(), quad.getFace(), quad.getSprite(), quad.shouldApplyDiffuseLighting() ); - } - - public UnpackedBakedQuad toQuad() - { - return new UnpackedBakedQuad( data, tintIndex, face, sprite, applyDiffuseLighting, format ); - } - - public VertexFormat getFormat() - { - return format; - } - - public void setFormat( VertexFormat format ) - { - this.format = format; - } - - public float[][][] getData() - { - return data; - } - - public void setData( float[][][] data ) - { - this.data = data; - } - - public int getTintIndex() - { - return tintIndex; - } - - public void setTintIndex( int tintIndex ) - { - this.tintIndex = tintIndex; - } - - public EnumFacing getFace() - { - return face; - } - - public void setFace( EnumFacing face ) - { - this.face = face; - } - - public TextureAtlasSprite getSprite() - { - return sprite; - } - - public void setSprite( TextureAtlasSprite sprite ) - { - this.sprite = sprite; - } - - public boolean shouldApplyDiffuseLighting() - { - return applyDiffuseLighting; - } - - public void setApplyDiffuseLighting( boolean applyDiffuseLighting ) - { - this.applyDiffuseLighting = applyDiffuseLighting; - } - -} diff --git a/src/main/java/appeng/client/render/model/pipeline/StatePosRecolorator.java b/src/main/java/appeng/client/render/model/pipeline/StatePosRecolorator.java deleted file mode 100644 index ce9186ce..00000000 --- a/src/main/java/appeng/client/render/model/pipeline/StatePosRecolorator.java +++ /dev/null @@ -1,71 +0,0 @@ - -package appeng.client.render.model.pipeline; - - -import java.util.List; - -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.block.model.IBakedModel; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.IBlockAccess; - -import appeng.api.client.BakingPipelineElement; - - -public class StatePosRecolorator implements BakingPipelineElement -{ - - private IBlockAccess blockAccess; - private BlockPos pos; - private IBlockState state; - - public StatePosRecolorator( IBlockAccess blockAccess, BlockPos pos, IBlockState state ) - { - this.blockAccess = blockAccess; - this.pos = pos; - this.state = state; - } - - public IBlockAccess getBlockAccess() - { - return blockAccess; - } - - public void setBlockAccess( IBlockAccess blockAccess ) - { - this.blockAccess = blockAccess; - } - - public BlockPos getPos() - { - return pos; - } - - public void setPos( BlockPos pos ) - { - this.pos = pos; - } - - public IBlockState getState() - { - return state; - } - - public void setState( IBlockState state ) - { - this.state = state; - } - - @Override - public List pipe( List elements, IBakedModel parent, IBlockState state, EnumFacing side, long rand ) - { - for( QuadVertexData data : elements ) - { - data.setTintIndex( Minecraft.getMinecraft().getBlockColors().colorMultiplier( this.state, blockAccess, this.pos, data.getTintIndex() ) ); - } - return elements; - } - -} diff --git a/src/main/java/appeng/client/render/model/pipeline/TintIndexModifier.java b/src/main/java/appeng/client/render/model/pipeline/TintIndexModifier.java deleted file mode 100644 index 575dbea0..00000000 --- a/src/main/java/appeng/client/render/model/pipeline/TintIndexModifier.java +++ /dev/null @@ -1,45 +0,0 @@ - -package appeng.client.render.model.pipeline; - - -import java.util.List; -import java.util.function.Function; - -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.block.model.IBakedModel; -import net.minecraft.util.EnumFacing; - -import appeng.api.client.BakingPipelineElement; - - -public class TintIndexModifier implements BakingPipelineElement -{ - - private Function tintTransformer; - - public TintIndexModifier( Function tintTransformer ) - { - this.tintTransformer = tintTransformer; - } - - public Function getTintTransformer() - { - return tintTransformer; - } - - public void setTintTransformer( Function tintTransformer ) - { - this.tintTransformer = tintTransformer; - } - - @Override - public List pipe( List elements, IBakedModel parent, IBlockState state, EnumFacing side, long rand ) - { - for( QuadVertexData quad : elements ) - { - quad.setTintIndex( tintTransformer.apply( quad.getTintIndex() ) ); - } - return elements; - } - -} diff --git a/src/main/java/appeng/client/render/model/pipeline/TypeTransformer.java b/src/main/java/appeng/client/render/model/pipeline/TypeTransformer.java deleted file mode 100644 index 1071173f..00000000 --- a/src/main/java/appeng/client/render/model/pipeline/TypeTransformer.java +++ /dev/null @@ -1,62 +0,0 @@ - -package appeng.client.render.model.pipeline; - - -import java.util.ArrayList; -import java.util.List; - -import com.google.common.collect.Lists; - -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.renderer.block.model.IBakedModel; -import net.minecraft.util.EnumFacing; -import net.minecraftforge.client.model.pipeline.LightUtil; -import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad; - -import appeng.api.client.BakingPipelineElement; - - -public class TypeTransformer -{ - - public static final BakingPipelineElement quads2vecs = new BakingPipelineElement(){ - - @Override - public List pipe( List elements, IBakedModel parent, IBlockState state, EnumFacing side, long rand ) - { - return Lists.transform( elements != null ? elements : new ArrayList<>(), ( quad ) -> { - if( quad instanceof UnpackedBakedQuad ) - { - return new QuadVertexData( (UnpackedBakedQuad) quad ); - } - else - { - int[] qdata = quad.getVertexData(); - float[][][] data = new float[4][quad.getFormat().getElementCount()][4]; - for( int v = 0; v < data.length; v++ ) - { - float[][] vd = data[v]; - for( int e = 0; e < vd.length; e++ ) - { - LightUtil.unpack( qdata, vd[e], quad.getFormat(), v, e ); - } - } - return new QuadVertexData( quad.getFormat(), data, quad.getTintIndex(), quad.getFace(), quad.getSprite(), quad.shouldApplyDiffuseLighting() ); - } - } ); - } - - }; - - public static final BakingPipelineElement vecs2quads = new BakingPipelineElement(){ - - @Override - public List pipe( List elements, IBakedModel parent, IBlockState state, EnumFacing side, long rand ) - { - return Lists.transform( elements != null ? elements : new ArrayList<>(), data -> data.toQuad() ); - } - - }; - -} diff --git a/src/main/java/appeng/client/render/model/pipeline/cable/CableAndConnections.java b/src/main/java/appeng/client/render/model/pipeline/cable/CableAndConnections.java deleted file mode 100644 index 26921c91..00000000 --- a/src/main/java/appeng/client/render/model/pipeline/cable/CableAndConnections.java +++ /dev/null @@ -1,53 +0,0 @@ - -package appeng.client.render.model.pipeline.cable; - - -import java.util.List; - -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.renderer.block.model.IBakedModel; -import net.minecraft.util.EnumFacing; -import net.minecraftforge.common.property.IExtendedBlockState; - -import appeng.api.client.BakingPipeline; -import appeng.api.client.BakingPipelineElement; -import appeng.api.implementations.parts.IPartCable; -import appeng.api.parts.IPart; -import appeng.api.util.AEPartLocation; -import appeng.block.networking.BlockCableBus; -import appeng.client.render.model.pipeline.TintIndexModifier; -import appeng.parts.CableBusContainer; - - -public class CableAndConnections implements BakingPipelineElement -{ - - private final BakingPipeline rotatingPipeline; - private final TintIndexModifier tintIndexModifier; - private final BakingPipeline tintIndexFixPipeline; - - public CableAndConnections( BakingPipeline rotatingPipeline, TintIndexModifier tintIndexModifier, BakingPipeline tintIndexFixPipeline ) - { - this.rotatingPipeline = rotatingPipeline; - this.tintIndexModifier = tintIndexModifier; - this.tintIndexFixPipeline = tintIndexFixPipeline; - } - - @Override - public List pipe( List elements, IBakedModel parent, IBlockState state, EnumFacing side, long rand ) - { - if( state != null ) - { - CableBusContainer cableBus = ( (IExtendedBlockState) state ).getValue( BlockCableBus.cableBus ); - IPart part = cableBus.getPart( AEPartLocation.INTERNAL ); - if( part instanceof IPartCable ) - { - tintIndexModifier.setTintTransformer( tint -> ( AEPartLocation.INTERNAL.ordinal() << 2 ) | tint ); - elements.addAll( tintIndexFixPipeline.pipe( ( (IPartCable) part ).getOrBakeQuads( rotatingPipeline, state, side, rand ), parent, state, side, rand ) ); - } - } - return elements; - } - -} diff --git a/src/main/java/appeng/client/render/model/pipeline/cable/Facades.java b/src/main/java/appeng/client/render/model/pipeline/cable/Facades.java deleted file mode 100644 index 6b5fcdec..00000000 --- a/src/main/java/appeng/client/render/model/pipeline/cable/Facades.java +++ /dev/null @@ -1,55 +0,0 @@ - -package appeng.client.render.model.pipeline.cable; - - -import java.util.List; - -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.renderer.block.model.IBakedModel; -import net.minecraft.util.EnumFacing; -import net.minecraftforge.common.property.IExtendedBlockState; - -import appeng.api.client.BakingPipeline; -import appeng.api.client.BakingPipelineElement; -import appeng.api.parts.IFacadePart; -import appeng.api.util.AEPartLocation; -import appeng.block.networking.BlockCableBus; -import appeng.client.render.model.pipeline.TintIndexModifier; -import appeng.parts.CableBusContainer; - - -public class Facades implements BakingPipelineElement -{ - - private final BakingPipeline rotatingPipeline; - private final TintIndexModifier tintIndexModifier; - private final BakingPipeline tintIndexFixPipeline; - - public Facades( BakingPipeline rotatingPipeline, TintIndexModifier tintIndexModifier, BakingPipeline tintIndexFixPipeline ) - { - this.rotatingPipeline = rotatingPipeline; - this.tintIndexModifier = tintIndexModifier; - this.tintIndexFixPipeline = tintIndexFixPipeline; - } - - @Override - public List pipe( List elements, IBakedModel parent, IBlockState state, EnumFacing side, long rand ) - { - if( state != null ) - { - CableBusContainer cableBus = ( (IExtendedBlockState) state ).getValue( BlockCableBus.cableBus ); - for( AEPartLocation facing : AEPartLocation.SIDE_LOCATIONS ) - { - IFacadePart facade = cableBus.getFacadeContainer().getFacade( facing ); - if( facade != null ) - { - tintIndexModifier.setTintTransformer( tint -> ( facing.ordinal() << 2 ) | tint ); - elements.addAll( tintIndexFixPipeline.pipe( facade.getOrBakeQuads( cableBus, rotatingPipeline, state, side, rand ), parent, state, side, rand ) ); - } - } - } - return elements; - } - -} diff --git a/src/main/java/appeng/client/render/model/pipeline/cable/Parts.java b/src/main/java/appeng/client/render/model/pipeline/cable/Parts.java deleted file mode 100644 index bcd04125..00000000 --- a/src/main/java/appeng/client/render/model/pipeline/cable/Parts.java +++ /dev/null @@ -1,55 +0,0 @@ - -package appeng.client.render.model.pipeline.cable; - - -import java.util.List; - -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.renderer.block.model.IBakedModel; -import net.minecraft.util.EnumFacing; -import net.minecraftforge.common.property.IExtendedBlockState; - -import appeng.api.client.BakingPipeline; -import appeng.api.client.BakingPipelineElement; -import appeng.api.parts.IPart; -import appeng.api.util.AEPartLocation; -import appeng.block.networking.BlockCableBus; -import appeng.client.render.model.pipeline.TintIndexModifier; -import appeng.parts.CableBusContainer; - - -public class Parts implements BakingPipelineElement -{ - - private final BakingPipeline rotatingPipeline; - private final TintIndexModifier tintIndexModifier; - private final BakingPipeline tintIndexFixPipeline; - - public Parts( BakingPipeline rotatingPipeline, TintIndexModifier tintIndexModifier, BakingPipeline tintIndexFixPipeline ) - { - this.rotatingPipeline = rotatingPipeline; - this.tintIndexModifier = tintIndexModifier; - this.tintIndexFixPipeline = tintIndexFixPipeline; - } - - @Override - public List pipe( List elements, IBakedModel parent, IBlockState state, EnumFacing side, long rand ) - { - if( state != null ) - { - CableBusContainer cableBus = ( (IExtendedBlockState) state ).getValue( BlockCableBus.cableBus ); - for( AEPartLocation facing : AEPartLocation.SIDE_LOCATIONS ) - { - IPart part = cableBus.getPart( facing ); - if( part != null ) - { - tintIndexModifier.setTintTransformer( tint -> ( facing.ordinal() << 2 ) | tint ); - elements.addAll( tintIndexFixPipeline.pipe( part.getOrBakeQuads( rotatingPipeline, state, side, rand ), parent, state, side, rand ) ); - } - } - } - return elements; - } - -} diff --git a/src/main/java/appeng/core/Api.java b/src/main/java/appeng/core/Api.java index e065c55f..a08b9fe2 100644 --- a/src/main/java/appeng/core/Api.java +++ b/src/main/java/appeng/core/Api.java @@ -29,6 +29,7 @@ import appeng.api.storage.IStorageHelper; import appeng.api.util.AEPartLocation; import appeng.core.api.ApiPart; import appeng.core.api.ApiStorage; +import appeng.core.features.registries.PartModels; import appeng.core.features.registries.RegistryContainer; import appeng.me.GridConnection; import appeng.me.GridNode; @@ -51,7 +52,7 @@ public final class Api implements IAppEngApi this.storageHelper = new ApiStorage(); this.registryContainer = new RegistryContainer(); this.partHelper = new ApiPart(); - this.definitions = new ApiDefinitions( this.partHelper ); + this.definitions = new ApiDefinitions( (PartModels) this.registryContainer.partModels() ); } @Override diff --git a/src/main/java/appeng/core/ApiDefinitions.java b/src/main/java/appeng/core/ApiDefinitions.java index 21000f06..a82dafc5 100644 --- a/src/main/java/appeng/core/ApiDefinitions.java +++ b/src/main/java/appeng/core/ApiDefinitions.java @@ -20,12 +20,12 @@ package appeng.core; import appeng.api.definitions.IDefinitions; -import appeng.api.parts.IPartHelper; import appeng.bootstrap.FeatureFactory; import appeng.core.api.definitions.ApiBlocks; import appeng.core.api.definitions.ApiItems; import appeng.core.api.definitions.ApiMaterials; import appeng.core.api.definitions.ApiParts; +import appeng.core.features.registries.PartModels; /** @@ -40,12 +40,12 @@ public final class ApiDefinitions implements IDefinitions private final FeatureFactory registry = new FeatureFactory(); - public ApiDefinitions( final IPartHelper partHelper ) + public ApiDefinitions( final PartModels partModels ) { - this.blocks = new ApiBlocks( registry ); + this.blocks = new ApiBlocks( registry, partModels ); this.items = new ApiItems( registry ); this.materials = new ApiMaterials( registry ); - this.parts = new ApiParts( registry, partHelper ); + this.parts = new ApiParts( registry, partModels ); } public FeatureFactory getRegistry() diff --git a/src/main/java/appeng/core/AppEng.java b/src/main/java/appeng/core/AppEng.java index fab12bca..71e5e365 100644 --- a/src/main/java/appeng/core/AppEng.java +++ b/src/main/java/appeng/core/AppEng.java @@ -20,11 +20,12 @@ package appeng.core; import java.io.File; +import java.util.List; import java.util.concurrent.TimeUnit; - import javax.annotation.Nonnull; import com.google.common.base.Stopwatch; +import com.google.common.collect.Lists; import net.minecraftforge.common.config.Configuration; import net.minecraftforge.fml.common.FMLCommonHandler; @@ -41,6 +42,7 @@ import net.minecraftforge.fml.common.event.FMLServerStoppedEvent; import net.minecraftforge.fml.common.event.FMLServerStoppingEvent; import net.minecraftforge.fml.common.network.NetworkRegistry; +import appeng.api.AEApi; import appeng.core.crash.CrashInfo; import appeng.core.crash.IntegrationCrashEnhancement; import appeng.core.crash.ModCrashEnhancement; @@ -169,6 +171,12 @@ public final class AppEng } AELog.info( "Pre Initialization ( ended after " + watch.elapsed( TimeUnit.MILLISECONDS ) + "ms )" ); + + // Instantiate all Plugins + List injectables = Lists.newArrayList( + AEApi.instance() + ); + new PluginLoader().loadPlugins( injectables, event.getAsmData() ); } private void startService( final String serviceName, final Thread thread ) diff --git a/src/main/java/appeng/core/CommonHelper.java b/src/main/java/appeng/core/CommonHelper.java index c143bc5b..a7687e37 100644 --- a/src/main/java/appeng/core/CommonHelper.java +++ b/src/main/java/appeng/core/CommonHelper.java @@ -25,7 +25,6 @@ import java.util.Random; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.World; import net.minecraftforge.fml.common.SidedProxy; @@ -60,7 +59,7 @@ public abstract class CommonHelper public abstract RayTraceResult getRTR(); - public abstract void doRenderItem( ItemStack itemstack, World w ); + public abstract void doRenderItem( ItemStack itemstack ); public abstract void postInit(); diff --git a/src/main/java/appeng/core/PluginLoader.java b/src/main/java/appeng/core/PluginLoader.java new file mode 100644 index 00000000..01acd833 --- /dev/null +++ b/src/main/java/appeng/core/PluginLoader.java @@ -0,0 +1,146 @@ +package appeng.core; + + +import java.lang.reflect.Constructor; +import java.util.Collection; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import com.google.common.collect.ImmutableMap; + +import net.minecraftforge.fml.common.discovery.ASMDataTable; + +import appeng.api.AEInjectable; +import appeng.api.AEPlugin; +import appeng.api.exceptions.AppEngException; + + +/** + * Loads AE plugins on startup and provides them with access to various components of the AE API. + */ +class PluginLoader +{ + + public void loadPlugins( Collection injectables, ASMDataTable asmDataTable ) + { + Map, Object> injectableMap = mapInjectables( injectables ); + findAndInstantiatePlugins( asmDataTable, injectableMap ); + } + + private static void findAndInstantiatePlugins( ASMDataTable dataTable, Map, Object> injectableMap ) + { + Set allAnnotated = dataTable.getAll( AEPlugin.class.getCanonicalName() ); + + for( ASMDataTable.ASMData candidate : allAnnotated ) + { + + Class aClass; + try + { + aClass = Class.forName( candidate.getClassName() ); + } + catch( ClassNotFoundException e ) + { + AELog.error( e, "Couldn't find annotated AE plugin class " + candidate.getClassName() ); + throw new RuntimeException( "Couldn't find annotated AE plugin class " + candidate.getClassName(), e ); + } + + // Try instantiating the plugin + try + { + Object plugin = instantiatePlugin( aClass, injectableMap ); + AELog.info( "Loaded AE2 Plugin {}", plugin.getClass() ); + } + catch( Exception e ) + { + AELog.error( e, "Unable to instantiate AE plugin " + candidate.getClassName() ); + throw new RuntimeException( "Unable to instantiate AE plugin " + candidate.getClassName(), e ); + } + } + } + + private static Object instantiatePlugin( Class aClass, Map, Object> injectableMap ) throws Exception + { + + Constructor[] constructors = aClass.getDeclaredConstructors(); + + if( constructors.length == 0 ) + { + // This is the default no-arg constructor, although it seems pointless to instantiate anything but not take any AE dependencies as parameters + return aClass.newInstance(); + } + else if( constructors.length != 1 ) + { + throw new IllegalArgumentException( "Expected a single constructor, but found: " + constructors.length ); + } + + Constructor constructor = constructors[0]; + constructor.setAccessible( true ); + + Object[] args = findInjectables( constructor, injectableMap ); + + return constructor.newInstance( args ); + } + + private static Object[] findInjectables( Constructor constructor, Map, Object> injectableMap ) + { + + Class[] types = constructor.getParameterTypes(); + Object[] args = new Object[types.length]; + + for( int i = 0; i < types.length; i++ ) + { + args[i] = injectableMap.get( types[i] ); + if( args[i] == null ) + { + throw new IllegalArgumentException( "Constructor has parameter of type " + types[i] + " which is not an injectable type." + + " Please see the documentation for @AEPlugin." ); + } + } + + return args; + } + + private static Map, Object> mapInjectables( Collection injectables ) + { + ImmutableMap.Builder, Object> builder = ImmutableMap.builder(); + + for( Object injectable : injectables ) + { + // Get all super-interfaces that were annotated with @AEInjectable + Set> injectableIfs = getInjectableInterfaces( injectable.getClass() ); + for( Class injectableIf : injectableIfs ) + { + builder.put( injectableIf, injectable ); + } + } + + return builder.build(); + } + + private static Set> getInjectableInterfaces( Class aClass ) + { + Set> hierarchy = new HashSet<>(); + getFullHierarchy( aClass, hierarchy ); + + return hierarchy.stream() + .filter( c -> c.getAnnotation( AEInjectable.class ) != null ) + .collect( Collectors.toSet() ); + } + + // Recursively gather all superclasses and superinterfaces of the given class and put them into the given collection + private static void getFullHierarchy( Class aClass, Set> classes ) + { + classes.add( aClass ); + for( Class anIf : aClass.getInterfaces() ) + { + getFullHierarchy( anIf, classes ); + } + if( aClass.getSuperclass() != null ) + { + getFullHierarchy( aClass.getSuperclass(), classes ); + } + } +} diff --git a/src/main/java/appeng/core/Registration.java b/src/main/java/appeng/core/Registration.java index 2718d666..76c7d355 100644 --- a/src/main/java/appeng/core/Registration.java +++ b/src/main/java/appeng/core/Registration.java @@ -55,7 +55,6 @@ import appeng.api.networking.spatial.ISpatialCache; import appeng.api.networking.storage.IStorageGrid; import appeng.api.networking.ticking.ITickManager; import appeng.api.parts.IPartHelper; -import appeng.block.networking.BlockCableBus; import appeng.core.features.AEFeature; import appeng.core.features.registries.P2PTunnelRegistry; import appeng.core.features.registries.entries.BasicCellHandler; @@ -145,7 +144,6 @@ public final class Registration // Register all detected handlers and features (items, blocks) in pre-init definitions.getRegistry().getBootstrapComponents().forEach( b -> b.preInitialize( event.getSide() ) ); - } private void registerSpatial( final boolean force ) @@ -342,7 +340,6 @@ public final class Registration GuiText.values(); Api.INSTANCE.partHelper().initFMPSupport(); - blocks.multiPart().maybeBlock().ifPresent( block -> ( (BlockCableBus) block ).setupTile() ); definitions.getRegistry().getBootstrapComponents().forEach( b -> b.postInitialize( event.getSide() ) ); diff --git a/src/main/java/appeng/core/api/ApiPart.java b/src/main/java/appeng/core/api/ApiPart.java index 72803205..ea3144c6 100644 --- a/src/main/java/appeng/core/api/ApiPart.java +++ b/src/main/java/appeng/core/api/ApiPart.java @@ -57,13 +57,14 @@ import appeng.integration.IntegrationRegistry; import appeng.integration.IntegrationType; import appeng.integration.abstraction.IFMP; import appeng.parts.PartPlacement; +import appeng.tile.AEBaseTile; import appeng.tile.networking.TileCableBus; public class ApiPart implements IPartHelper { - private final Map tileImplementations = new HashMap(); + private final Map> tileImplementations = new HashMap<>(); private final Map, String> interfaces2Layer = new HashMap, String>(); private final Map roots = new HashMap(); private final List desc = new LinkedList(); @@ -79,18 +80,13 @@ public class ApiPart implements IPartHelper } } - public Class getCombinedInstance( final String base ) + public Class getCombinedInstance( final Class baseClass ) { + String base = baseClass.getName(); + if( this.desc.isEmpty() ) { - try - { - return Class.forName( base ); - } - catch( final ClassNotFoundException e ) - { - throw new IllegalStateException( e ); - } + return baseClass; } final String description = base + ':' + Joiner.on( ";" ).skipNulls().join( this.desc.iterator() ); @@ -101,25 +97,8 @@ public class ApiPart implements IPartHelper } String f = base;// TileCableBus.class.getName(); - String Addendum = ""; - try - { - Addendum = Class.forName( base ).getSimpleName(); - } - catch( final ClassNotFoundException e ) - { - AELog.debug( e ); - } - Class myCLass; - - try - { - myCLass = Class.forName( f ); - } - catch( final ClassNotFoundException e ) - { - throw new IllegalStateException( e ); - } + String Addendum = baseClass.getSimpleName(); + Class myClass = baseClass; String path = f; @@ -128,21 +107,20 @@ public class ApiPart implements IPartHelper try { final String newPath = path + ';' + name; - myCLass = this.getClassByDesc( Addendum, newPath, f, this.interfaces2Layer.get( Class.forName( name ) ) ); + myClass = this.getClassByDesc( baseClass.getSimpleName(), newPath, f, this.interfaces2Layer.get( Class.forName( name ) ) ); path = newPath; } catch( final Throwable t ) { AELog.warn( "Error loading " + name ); AELog.debug( t ); - // throw new RuntimeException( t ); } - f = myCLass.getName(); + f = myClass.getName(); } - this.tileImplementations.put( description, myCLass ); + this.tileImplementations.put( description, myClass ); - return myCLass; + return myClass; } private Class getClassByDesc( final String addendum, final String fullPath, final String root, final String next ) diff --git a/src/main/java/appeng/core/api/definitions/ApiBlocks.java b/src/main/java/appeng/core/api/definitions/ApiBlocks.java index 8fe1d371..f942eeef 100644 --- a/src/main/java/appeng/core/api/definitions/ApiBlocks.java +++ b/src/main/java/appeng/core/api/definitions/ApiBlocks.java @@ -23,6 +23,7 @@ import net.minecraft.block.BlockDispenser; import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.oredict.OreDictionary; @@ -85,6 +86,7 @@ import appeng.bootstrap.IItemRendering; import appeng.client.render.model.GlassModel; import appeng.core.AppEng; import appeng.core.features.AEFeature; +import appeng.core.features.registries.PartModels; import appeng.debug.BlockChunkloader; import appeng.debug.BlockCubeGenerator; import appeng.debug.BlockItemGen; @@ -101,6 +103,8 @@ import appeng.decorative.solid.BlockSkyStone; import appeng.decorative.solid.BlockSkyStone.SkystoneType; import appeng.decorative.stair.BlockStairCommon; import appeng.hooks.DispenserBehaviorTinyTNT; +import appeng.tile.networking.CableBusTESR; +import appeng.util.Platform; /** @@ -184,7 +188,7 @@ public final class ApiBlocks implements IBlocks private final IBlockDefinition phantomNode; private final IBlockDefinition cubeGenerator; - public ApiBlocks( FeatureFactory registry ) + public ApiBlocks( FeatureFactory registry, PartModels partModels ) { // this.quartzOre = new BlockDefinition( "ore.quartz", new OreQuartz() ); this.quartzOre = registry.block( "quartz_ore", BlockQuartzOre::new ) @@ -357,8 +361,15 @@ public final class ApiBlocks implements IBlocks this.chiseledQuartzStairs = makeStairs( "chiseled_quartz_stairs", registry, this.chiseledQuartzBlock() ); this.quartzPillarStairs = makeStairs( "quartz_pillar_stairs", registry, this.quartzPillar() ); - this.multiPart = registry.block( "multipart_block", BlockCableBus::new ) - .rendering( new CableBusRendering() ) + this.multiPart = registry.block( "cable_bus", BlockCableBus::new ) + .rendering( new CableBusRendering( partModels ) ) + .postInit( (block, item) -> { + ( (BlockCableBus) block ).setupTile(); + if( Platform.isClient() ) + { + ClientRegistry.bindTileEntitySpecialRenderer( BlockCableBus.getTesrTile(), new CableBusTESR() ); + } + } ) .build(); // TODO Re-Add Slabs... diff --git a/src/main/java/appeng/core/api/definitions/ApiParts.java b/src/main/java/appeng/core/api/definitions/ApiParts.java index fc4026ba..0b740b1a 100644 --- a/src/main/java/appeng/core/api/definitions/ApiParts.java +++ b/src/main/java/appeng/core/api/definitions/ApiParts.java @@ -22,13 +22,13 @@ package appeng.core.api.definitions; import appeng.api.definitions.IItemDefinition; import appeng.api.definitions.IParts; import appeng.api.exceptions.MissingDefinition; -import appeng.api.parts.IPartHelper; import appeng.api.util.AEColor; import appeng.api.util.AEColoredItemDefinition; import appeng.bootstrap.FeatureFactory; import appeng.core.features.ColoredItemDefinition; import appeng.core.features.DamagedItemDefinition; import appeng.core.features.ItemStackSrc; +import appeng.core.features.registries.PartModels; import appeng.items.parts.ItemMultiPart; import appeng.items.parts.ItemMultipartRendering; import appeng.items.parts.PartType; @@ -78,13 +78,19 @@ public final class ApiParts implements IParts private final IItemDefinition storageMonitor; private final IItemDefinition conversionMonitor; - public ApiParts( FeatureFactory registry, IPartHelper partHelper ) + public ApiParts( FeatureFactory registry, PartModels partModels ) { - final ItemMultiPart itemMultiPart = new ItemMultiPart( partHelper ); + final ItemMultiPart itemMultiPart = new ItemMultiPart(); registry.item( "multipart", () -> itemMultiPart ) - .rendering( new ItemMultipartRendering( itemMultiPart ) ) + .rendering( new ItemMultipartRendering( partModels, itemMultiPart ) ) .build(); + // Register all part models + for( PartType partType : PartType.values() ) + { + partModels.registerModels( partType.getModels() ); + } + this.cableSmart = constructColoredDefinition( itemMultiPart, PartType.CableSmart ); this.cableCovered = constructColoredDefinition( itemMultiPart, PartType.CableCovered ); this.cableGlass = constructColoredDefinition( itemMultiPart, PartType.CableGlass ); diff --git a/src/main/java/appeng/core/features/registries/PartModels.java b/src/main/java/appeng/core/features/registries/PartModels.java new file mode 100644 index 00000000..14542ea7 --- /dev/null +++ b/src/main/java/appeng/core/features/registries/PartModels.java @@ -0,0 +1,40 @@ +package appeng.core.features.registries; + + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import net.minecraft.util.ResourceLocation; + +import appeng.api.parts.IPartModels; + + +public class PartModels implements IPartModels +{ + + private final Set models = new HashSet<>(); + + private boolean initialized = false; + + @Override + public void registerModels( Collection partModels ) + { + if( initialized ) + { + throw new IllegalStateException( "Cannot register models after the pre-initialization phase!" ); + } + + models.addAll( partModels ); + } + + public Set getModels() + { + return models; + } + + public void setInitialized( boolean initialized ) + { + this.initialized = initialized; + } +} diff --git a/src/main/java/appeng/core/features/registries/RegistryContainer.java b/src/main/java/appeng/core/features/registries/RegistryContainer.java index a225af3e..805cf1bf 100644 --- a/src/main/java/appeng/core/features/registries/RegistryContainer.java +++ b/src/main/java/appeng/core/features/registries/RegistryContainer.java @@ -32,6 +32,7 @@ import appeng.api.features.IWirelessTermRegistry; import appeng.api.features.IWorldGen; import appeng.api.movable.IMovableRegistry; import appeng.api.networking.IGridCacheRegistry; +import appeng.api.parts.IPartModels; import appeng.api.storage.ICellRegistry; import appeng.api.storage.IExternalStorageRegistry; @@ -59,6 +60,7 @@ public class RegistryContainer implements IRegistryContainer private final IMatterCannonAmmoRegistry matterCannonReg = new MatterCannonAmmoRegistry(); private final IPlayerRegistry playerRegistry = new PlayerRegistry(); private final IRecipeHandlerRegistry recipeReg = new RecipeHandlerRegistry(); + private final IPartModels partModels = new PartModels(); @Override public IMovableRegistry movable() @@ -143,4 +145,11 @@ public class RegistryContainer implements IRegistryContainer { return WorldGenRegistry.INSTANCE; } + + @Override + public IPartModels partModels() + { + return partModels; + } + } diff --git a/src/main/java/appeng/facade/FacadePart.java b/src/main/java/appeng/facade/FacadePart.java index 85d2a3af..d32bbc62 100644 --- a/src/main/java/appeng/facade/FacadePart.java +++ b/src/main/java/appeng/facade/FacadePart.java @@ -19,48 +19,20 @@ package appeng.facade; -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.List; - import javax.annotation.Nullable; -import org.lwjgl.util.vector.Matrix4f; -import org.lwjgl.util.vector.Vector3f; - import net.minecraft.block.Block; -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3i; -import net.minecraft.world.IBlockAccess; -import net.minecraftforge.common.model.TRSRTransformation; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; import appeng.api.AEApi; -import appeng.api.client.BakingPipeline; import appeng.api.parts.IBoxProvider; -import appeng.api.parts.IFacadeContainer; import appeng.api.parts.IFacadePart; import appeng.api.parts.IPartCollisionHelper; -import appeng.api.parts.IPartHost; import appeng.api.util.AEPartLocation; -import appeng.client.render.model.ModelsCache; -import appeng.client.render.model.pipeline.MatVecApplicator; -import appeng.client.render.model.pipeline.ParentQuads; -import appeng.client.render.model.pipeline.StatePosRecolorator; -import appeng.client.render.model.pipeline.TypeTransformer; -import appeng.core.AppEng; import appeng.integration.IntegrationRegistry; import appeng.integration.IntegrationType; import appeng.integration.abstraction.IBuildCraftTransport; @@ -193,114 +165,9 @@ public class FacadePart implements IFacadePart, IBoxProvider return null; } - private EnumSet calculateFaceOpenFaces( final IBlockAccess blockAccess, final IFacadeContainer fc, final BlockPos pos, final AEPartLocation side ) - { - final EnumSet out = EnumSet.of( side, side.getOpposite() ); - final IFacadePart facade = fc.getFacade( side ); - - for( final AEPartLocation it : AEPartLocation.SIDE_LOCATIONS ) - { - if( !out.contains( it ) && this.hasAlphaDiff( blockAccess.getTileEntity( pos.offset( it.getFacing() ) ), side, facade ) ) - { - out.add( it ); - } - } - - if( out.contains( AEPartLocation.UP ) && ( side.xOffset != 0 || side.zOffset != 0 ) ) - { - final IFacadePart fp = fc.getFacade( AEPartLocation.UP ); - if( fp != null && ( fp.isTransparent() == facade.isTransparent() ) ) - { - out.remove( AEPartLocation.UP ); - } - } - - if( out.contains( AEPartLocation.DOWN ) && ( side.xOffset != 0 || side.zOffset != 0 ) ) - { - final IFacadePart fp = fc.getFacade( AEPartLocation.DOWN ); - if( fp != null && ( fp.isTransparent() == facade.isTransparent() ) ) - { - out.remove( AEPartLocation.DOWN ); - } - } - - if( out.contains( AEPartLocation.SOUTH ) && ( side.xOffset != 0 ) ) - { - final IFacadePart fp = fc.getFacade( AEPartLocation.SOUTH ); - if( fp != null && ( fp.isTransparent() == facade.isTransparent() ) ) - { - out.remove( AEPartLocation.SOUTH ); - } - } - - if( out.contains( AEPartLocation.NORTH ) && ( side.xOffset != 0 ) ) - { - final IFacadePart fp = fc.getFacade( AEPartLocation.NORTH ); - if( fp != null && ( fp.isTransparent() == facade.isTransparent() ) ) - { - out.remove( AEPartLocation.NORTH ); - } - } - - /* - * if ( out.contains( AEPartLocation.EAST ) && (side.offsetZ != 0) ) { IFacadePart fp = fc.getFacade( - * AEPartLocation.EAST ); if ( fp != null && (fp.isTransparent() == facade.isTransparent()) ) out.remove( - * AEPartLocation.EAST ); } - * if ( out.contains( AEPartLocation.WEST ) && (side.offsetZ != 0) ) { IFacadePart fp = fc.getFacade( - * AEPartLocation.WEST ); if ( fp != null && (fp.isTransparent() == facade.isTransparent()) ) out.remove( - * AEPartLocation.WEST ); } - * if ( out.contains( AEPartLocation.NORTH ) && (side.offsetY != 0) ) { IFacadePart fp = fc.getFacade( - * AEPartLocation.NORTH ); if ( fp != null && (fp.isTransparent() == facade.isTransparent()) ) out.remove( - * AEPartLocation.NORTH ); } - * if ( out.contains( AEPartLocation.SOUTH ) && (side.offsetY != 0) ) { IFacadePart fp = fc.getFacade( - * AEPartLocation.SOUTH ); if ( fp != null && (fp.isTransparent() == facade.isTransparent()) ) out.remove( - * AEPartLocation.SOUTH ); } - * if ( out.contains( AEPartLocation.EAST ) && (side.offsetY != 0) ) { IFacadePart fp = fc.getFacade( - * AEPartLocation.EAST ); if ( fp != null && (fp.isTransparent() == facade.isTransparent()) ) out.remove( - * AEPartLocation.EAST ); } - * if ( out.contains( AEPartLocation.WEST ) && (side.offsetY != 0) ) { IFacadePart fp = fc.getFacade(s - * AEPartLocation.WEST ); if ( fp != null && (fp.isTransparent() == facade.isTransparent()) ) out.remove( - * AEPartLocation.WEST ); } - */ - return out; - } - - private boolean hasAlphaDiff( final TileEntity tileEntity, final AEPartLocation side, final IFacadePart facade ) - { - if( tileEntity instanceof IPartHost ) - { - final IPartHost ph = (IPartHost) tileEntity; - final IFacadePart fp = ph.getFacadeContainer().getFacade( side ); - - return fp == null || ( fp.isTransparent() != facade.isTransparent() ); - } - - return true; - } - @Override public void getBoxes( final IPartCollisionHelper bch ) { this.getBoxes( bch, null ); } - - @Override - @SideOnly( Side.CLIENT ) - public List getOrBakeQuads( IPartHost host, BakingPipeline rotatingPipeline, IBlockState state, EnumFacing side, long rand ) - { - List elements = new ArrayList(); - elements.addAll( rotatingPipeline.pipe( ModelsCache.INSTANCE.getOrLoadBakedModel( new ResourceLocation( AppEng.MOD_ID, "part/cable_facade" ) ).getQuads( state, side, rand ), null, state, getSide().getFacing(), rand ) ); - - ItemStack titem = getTexture(); - if( titem != null && titem.getItem() != null && Block.getBlockFromItem( titem.getItem() ) != null ) - { - Block tblock = Block.getBlockFromItem( titem.getItem() ); - IBlockState tstate = tblock.getStateFromMeta( titem.getItem().getMetadata( titem.getItemDamage() ) ); - Vec3i s = getSide().getFacing().getDirectionVec(); - Vector3f scale = new Vector3f( s.getX() == 0 ? 0.9999f : 0.125f, s.getY() == 0 ? 0.9999f : 0.125f, s.getZ() == 0 ? 0.9999f : 0.125f ); - Vector3f trans = new Vector3f( s.getX() * 3.5f, s.getY() * 3.5f, s.getZ() * 3.5f ); - elements.addAll( new BakingPipeline( new ParentQuads(), TypeTransformer.quads2vecs, new MatVecApplicator( TRSRTransformation.toVecmath( new Matrix4f().scale( scale ).translate( trans ) ), true ), new StatePosRecolorator( host.getTile().getWorld(), host.getLocation().getPos(), tstate ), TypeTransformer.vecs2quads ).pipe( new ArrayList<>(), Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState( tstate ), tstate, side, rand ) ); - } - return elements; - } } diff --git a/src/main/java/appeng/items/parts/ItemMultiPart.java b/src/main/java/appeng/items/parts/ItemMultiPart.java index ef74cefc..4f12b5d8 100644 --- a/src/main/java/appeng/items/parts/ItemMultiPart.java +++ b/src/main/java/appeng/items/parts/ItemMultiPart.java @@ -46,7 +46,6 @@ import net.minecraft.world.World; import appeng.api.AEApi; import appeng.api.implementations.items.IItemGroup; import appeng.api.parts.IPart; -import appeng.api.parts.IPartHelper; import appeng.api.parts.IPartItem; import appeng.api.util.AEColor; import appeng.core.AEConfig; @@ -67,10 +66,8 @@ public final class ItemMultiPart extends AEBaseItem implements IPartItem, IItemG public static ItemMultiPart instance; private final Map registered; - public ItemMultiPart( final IPartHelper partHelper ) + public ItemMultiPart() { - Preconditions.checkNotNull( partHelper ); - this.registered = new HashMap<>( INITIAL_REGISTERED_CAPACITY ); this.setHasSubtypes( true ); diff --git a/src/main/java/appeng/items/parts/ItemMultipartRendering.java b/src/main/java/appeng/items/parts/ItemMultipartRendering.java index 8fe9d3f5..a7d73581 100644 --- a/src/main/java/appeng/items/parts/ItemMultipartRendering.java +++ b/src/main/java/appeng/items/parts/ItemMultipartRendering.java @@ -1,25 +1,35 @@ package appeng.items.parts; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.stream.Collectors; import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; import appeng.api.util.AEColor; import appeng.bootstrap.IItemRendering; import appeng.bootstrap.ItemRenderingCustomizer; import appeng.client.render.StaticItemColor; +import appeng.core.AppEng; +import appeng.core.features.registries.PartModels; +import appeng.parts.automation.PlaneConnections; +import appeng.parts.automation.PlaneModel; public class ItemMultipartRendering extends ItemRenderingCustomizer { + private final PartModels partModels; + private final ItemMultiPart item; - public ItemMultipartRendering( ItemMultiPart item ) + public ItemMultipartRendering( PartModels partModels, ItemMultiPart item ) { + this.partModels = partModels; this.item = item; } @@ -35,6 +45,52 @@ public class ItemMultipartRendering extends ItemRenderingCustomizer rendering.variants( Arrays.stream( PartType.values() ) .flatMap( part -> part.getItemModels().stream() ) .collect( Collectors.toList() ) ); + + // TODO All of this has to go somewhere else! (I.e. when the part is registered) + // Register the built-in models for annihilation planes + ResourceLocation annihilationPlaneTexture = new ResourceLocation( AppEng.MOD_ID, "items/part/annihilation_plane" ); + ResourceLocation annihilationPlaneOnTexture = new ResourceLocation( AppEng.MOD_ID, "parts/annihilation_plane_on" ); + ResourceLocation identityAnnihilationPlaneTexture = new ResourceLocation( AppEng.MOD_ID, "items/part/identity_annihilation_plane" ); + ResourceLocation identityAnnihilationPlaneOnTexture = new ResourceLocation( AppEng.MOD_ID, "parts/identity_annihilation_plane_on" ); + ResourceLocation formationPlaneTexture = new ResourceLocation( AppEng.MOD_ID, "items/part/formation_plane" ); + ResourceLocation formationPlaneOnTexture = new ResourceLocation( AppEng.MOD_ID, "parts/formation_plane_on" ); + ResourceLocation sidesTexture = new ResourceLocation( AppEng.MOD_ID, "parts/plane_sides" ); + ResourceLocation backTexture = new ResourceLocation( AppEng.MOD_ID, "parts/transition_plane_back" ); + + List modelNames = new ArrayList<>(); + + for( PlaneConnections connection : PlaneConnections.PERMUTATIONS ) + { + PlaneModel model = new PlaneModel( annihilationPlaneTexture, sidesTexture, backTexture, connection ); + rendering.builtInModel( "models/part/annihilation_plane_" + connection.getFilenameSuffix(), model ); + modelNames.add( "part/annihilation_plane_" + connection.getFilenameSuffix() ); + + model = new PlaneModel( annihilationPlaneOnTexture, sidesTexture, backTexture, connection ); + rendering.builtInModel( "models/part/annihilation_plane_on_" + connection.getFilenameSuffix(), model ); + modelNames.add( "part/annihilation_plane_on_" + connection.getFilenameSuffix() ); + + model = new PlaneModel( identityAnnihilationPlaneTexture, sidesTexture, backTexture, connection ); + rendering.builtInModel( "models/part/identity_annihilation_plane_" + connection.getFilenameSuffix(), model ); + modelNames.add( "part/identity_annihilation_plane_" + connection.getFilenameSuffix() ); + + model = new PlaneModel( identityAnnihilationPlaneOnTexture, sidesTexture, backTexture, connection ); + rendering.builtInModel( "models/part/identity_annihilation_plane_on_" + connection.getFilenameSuffix(), model ); + modelNames.add( "part/identity_annihilation_plane_on_" + connection.getFilenameSuffix() ); + + model = new PlaneModel( formationPlaneTexture, sidesTexture, backTexture, connection ); + rendering.builtInModel( "models/part/formation_plane_" + connection.getFilenameSuffix(), model ); + modelNames.add( "part/formation_plane_" + connection.getFilenameSuffix() ); + + model = new PlaneModel( formationPlaneOnTexture, sidesTexture, backTexture, connection ); + rendering.builtInModel( "models/part/formation_plane_on_" + connection.getFilenameSuffix(), model ); + modelNames.add( "part/formation_plane_on_" + connection.getFilenameSuffix() ); + + } + + List partResourceLocs = modelNames.stream() + .map( name -> new ResourceLocation( AppEng.MOD_ID, name ) ) + .collect( Collectors.toList() ); + partModels.registerModels( partResourceLocs ); } private ModelResourceLocation getItemMeshDefinition( ItemStack is ) diff --git a/src/main/java/appeng/items/parts/PartModels.java b/src/main/java/appeng/items/parts/PartModels.java new file mode 100644 index 00000000..efa12ddd --- /dev/null +++ b/src/main/java/appeng/items/parts/PartModels.java @@ -0,0 +1,21 @@ +package appeng.items.parts; + + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +/** + * This annotation is used to mark static fields or static methods that return/contain models used + * for a part. They are automatically registered as part of the part item registration. + */ +@Retention( RetentionPolicy.RUNTIME ) +@Target( { + ElementType.FIELD, + ElementType.METHOD +} ) +public @interface PartModels +{ +} diff --git a/src/main/java/appeng/items/parts/PartType.java b/src/main/java/appeng/items/parts/PartType.java index a7445124..9c2a43b3 100644 --- a/src/main/java/appeng/items/parts/PartType.java +++ b/src/main/java/appeng/items/parts/PartType.java @@ -20,9 +20,16 @@ package appeng.items.parts; import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.EnumSet; +import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -34,6 +41,7 @@ import net.minecraft.util.ResourceLocation; import appeng.api.parts.IPart; import appeng.api.util.AEColor; +import appeng.core.AELog; import appeng.core.AppEng; import appeng.core.features.AEFeature; import appeng.core.localization.GuiText; @@ -213,6 +221,7 @@ public enum PartType private final Class myPart; private final GuiText extraName; private final List itemModels; + private final Set models; private Constructor constructor; PartType( final int baseMetaValue, final String name, final Set features, final Set integrations, final Class c ) @@ -229,6 +238,14 @@ public enum PartType this.myPart = c; this.extraName = en; this.itemModels = createItemModels( name ); + if( c != null ) + { + this.models = new HashSet<>( createModels( c ) ); + } + else + { + this.models = Collections.emptySet(); + } } protected List createItemModels( String baseName ) @@ -295,5 +312,125 @@ public enum PartType { return itemModels; } - + + public Set getModels() + { + return models; + } + + private List createModels( Class clazz ) + { + List locations = new ArrayList<>( ); + + // Check all static fields for used models + Field[] fields = clazz.getDeclaredFields(); + for( Field field : fields ) + { + if( field.getAnnotation( PartModels.class ) == null ) + { + continue; + } + + + if( !Modifier.isStatic( field.getModifiers() ) ) + { + AELog.error( "The @PartModels annotation can only be used on static fields or methods. Was seen on: " + field ); + continue; + } + + Object value; + try + { + field.setAccessible( true ); + value = field.get( null ); + } + catch( IllegalAccessException e ) + { + AELog.error( e, "Cannot access field annotated with @PartModels: " + field ); + continue; + } + + convertAndAddLocation( field, value, locations ); + } + + // Check all static methods for the annotation + for( Method method : clazz.getDeclaredMethods() ) + { + if( method.getAnnotation( PartModels.class ) == null ) + { + continue; + } + + if( !Modifier.isStatic( method.getModifiers() ) ) + { + AELog.error( "The @PartModels annotation can only be used on static fields or methods. Was seen on: " + method ); + continue; + } + + // Check for parameter count + if( method.getParameters().length != 0 ) + { + AELog.error( "The @PartModels annotation can only be used on static methods without parameters. Was seen on: " + method ); + continue; + } + + // Make sure we can handle the return type + Class returnType = method.getReturnType(); + if( !ResourceLocation.class.isAssignableFrom( returnType ) && !Collection.class.isAssignableFrom( returnType ) ) + { + AELog.error( "The @PartModels annotation can only be used on static methods that return a ResourceLocation or Collection of " + + "ResourceLocations. Was seen on: " + method ); + continue; + } + + Object value = null; + try + { + method.setAccessible( true ); + value = method.invoke( null ); + } + catch( IllegalAccessException | InvocationTargetException e ) + { + AELog.error( e, "Failed to invoke the @PartModels annotated method " + method ); + continue; + } + + convertAndAddLocation( method, value, locations ); + } + + if( clazz.getSuperclass() != null ) + { + locations.addAll( createModels( clazz.getSuperclass() ) ); + } + + return locations; + } + + private void convertAndAddLocation( Object source, Object value, List locations ) + { + if( value == null ) + { + return; + } + + if( value instanceof ResourceLocation ) + { + locations.add( (ResourceLocation) value ); + } + else if( value instanceof Collection ) + { + // Check that each object is a ResourceLocation + Collection values = (Collection) value; + for( Object candidate : values ) + { + if ( !( candidate instanceof ResourceLocation )) { + AELog.error( "List of locations obtained from {} contains a non resource location: {}", source, candidate ); + continue; + } + + locations.add( (ResourceLocation) candidate ); + } + } + } + } diff --git a/src/main/java/appeng/parts/AEBasePart.java b/src/main/java/appeng/parts/AEBasePart.java index 3f856307..4a5c0b58 100644 --- a/src/main/java/appeng/parts/AEBasePart.java +++ b/src/main/java/appeng/parts/AEBasePart.java @@ -25,18 +25,12 @@ import java.util.EnumSet; import java.util.List; import java.util.Optional; import java.util.Random; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import com.google.common.base.Function; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; import io.netty.buffer.ByteBuf; -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.crash.CrashReportCategory; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; @@ -55,7 +49,6 @@ import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import appeng.api.AEApi; -import appeng.api.client.BakingPipeline; import appeng.api.config.Upgrades; import appeng.api.definitions.IDefinitions; import appeng.api.implementations.IUpgradeableHost; @@ -73,7 +66,6 @@ import appeng.api.util.AEColor; import appeng.api.util.AEPartLocation; import appeng.api.util.DimensionalCoord; import appeng.api.util.IConfigManager; -import appeng.client.render.model.ModelsCache; import appeng.helpers.ICustomNameObject; import appeng.helpers.IPriorityHost; import appeng.items.parts.ItemMultiPart; @@ -89,35 +81,6 @@ import appeng.util.SettingsFrom; public abstract class AEBasePart implements IPart, IGridProxyable, IActionHost, IUpgradeableHost, ICustomNameObject { - private static final Pattern PROPERTY_PATTERN = Pattern.compile( "\\$\\{([\\p{Alnum}_\\-\\.]+)\\}" ); - - public static final ResourceLocation replaceProperties( ResourceLocation location, ImmutableMap properties ) - { - Matcher m = PROPERTY_PATTERN.matcher( location.getResourcePath() ); - StringBuffer buffer = new StringBuffer(); - while( m.find() ) - { - m.appendReplacement( buffer, properties.get( m.group( 1 ) ) ); - } - m.appendTail( buffer ); - return new ResourceLocation( location.getResourceDomain(), buffer.toString() ); - } - - protected static final Function propertyTextureGetter( ImmutableMap properties ) - { - return location -> ModelsCache.DEFAULTTEXTUREGETTER.apply( replaceProperties( location, properties ) ); - } - - protected static final Function propertyTextureGetter( ImmutableMap.Builder properties ) - { - return propertyTextureGetter( properties.build() ); - } - - protected static final ResourceLocation withProperties( ResourceLocation location, ImmutableMap.Builder properties ) - { - return new ResourceLocation( location.getResourceDomain(), location.getResourcePath() + properties.build().toString() ); - } - private final AENetworkProxy proxy; private final ItemStack is; private TileEntity tile = null; @@ -567,13 +530,6 @@ public abstract class AEBasePart implements IPart, IGridProxyable, IActionHost, return false; } - @Override - @SideOnly( Side.CLIENT ) - public List getOrBakeQuads( BakingPipeline rotatingPipeline, IBlockState state, EnumFacing side, long rand ) - { - return rotatingPipeline.pipe( ModelsCache.INSTANCE.getOrLoadModel( withProperties( getDefaultModelLocation(), propertiesForModel( getSide().getFacing() ) ), getDefaultModelLocation(), propertyTextureGetter( propertiesForModel( getSide().getFacing() ) ) ).getQuads( state, side, rand ), null, state, getSide().getFacing(), rand ); - } - protected ImmutableMap.Builder propertiesForModel( EnumFacing facing ) { return ImmutableMap.builder().put( "color", getColor().name() ); diff --git a/src/main/java/appeng/parts/CableBusContainer.java b/src/main/java/appeng/parts/CableBusContainer.java index b17ac8ea..827579e3 100644 --- a/src/main/java/appeng/parts/CableBusContainer.java +++ b/src/main/java/appeng/parts/CableBusContainer.java @@ -25,7 +25,6 @@ import java.util.LinkedList; import java.util.List; import java.util.Random; import java.util.Set; - import javax.annotation.Nullable; import io.netty.buffer.ByteBuf; @@ -63,6 +62,8 @@ import appeng.api.util.AECableType; import appeng.api.util.AEColor; import appeng.api.util.AEPartLocation; import appeng.api.util.DimensionalCoord; +import appeng.client.render.cablebus.CableBusRenderState; +import appeng.client.render.cablebus.CableCoreType; import appeng.core.AELog; import appeng.facade.FacadeContainer; import appeng.helpers.AEMultiTile; @@ -70,6 +71,7 @@ import appeng.integration.IntegrationRegistry; import appeng.integration.IntegrationType; import appeng.integration.abstraction.ICLApi; import appeng.me.GridConnection; +import appeng.parts.networking.PartCable; import appeng.util.Platform; @@ -1148,4 +1150,95 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I { this.requiresDynamicRender = requiresDynamicRender; } + + @Override + public CableBusRenderState getRenderState() + { + // TODO: Inspect whether this is a problem. PartCable is the only implementor of IPartCable, which is not part of the public API + PartCable cable = (PartCable) getCenter(); + + CableBusRenderState renderState = new CableBusRenderState(); + + if( cable != null ) + { + renderState.setCableColor( cable.getCableColor() ); + renderState.setCableType( cable.getCableConnectionType() ); + renderState.setCoreType( cable.getCableConnectionType().getCoreType() ); + + // Check each outgoing connection for the desired characteristics + for( EnumFacing facing : EnumFacing.values() ) + { + // Is there a connection? + if( !cable.isConnected( facing ) ) + { + continue; + } + + // If there is one, check out which type it has, but default to this cable's type + AECableType connectionType = cable.getCableConnectionType(); + + // Only use the incoming cable-type of the adjacent block, if it's not a cable bus itself + // Dense cables however also respect the adjacent cable-type since their outgoing connection + // point would look too big for other cable types + BlockPos adjacentPos = this.getTile().getPos().offset( facing ); + TileEntity adjacentTe = this.getTile().getWorld().getTileEntity( adjacentPos ); + if( adjacentTe instanceof IGridHost ) + { + if( !( adjacentTe instanceof IPartHost ) || cable.getCableConnectionType() == AECableType.DENSE ) + { + IGridHost gridHost = (IGridHost) adjacentTe; + connectionType = gridHost.getCableConnectionType( AEPartLocation.fromFacing( facing.getOpposite() ) ); + } + } + + // Check if the adjacent TE is a cable bus or not + if( adjacentTe instanceof IPartHost ) + { + renderState.getCableBusAdjacent().add( facing ); + } + + renderState.getConnectionTypes().put( facing, connectionType ); + } + + // Collect the number of channels used per side + // We have to do this even for non-smart cables since a glass cable can display a connection as smart if the adjacent tile requires it + for( EnumFacing facing : EnumFacing.values() ) + { + int channels = cable.getChannelsOnSide( facing ); + renderState.getChannelsOnSide().put( facing, channels ); + } + } + + for( EnumFacing facing : EnumFacing.values() ) + { + IPart part = getPart( facing ); + + if( part == null ) + { + continue; + } + + if( part instanceof IGridHost ) + { + // Some attachments want a thicker cable than glass, account for that + IGridHost gridHost = (IGridHost) part; + AECableType desiredType = gridHost.getCableConnectionType( AEPartLocation.INTERNAL ); + if( renderState.getCoreType() == CableCoreType.GLASS && ( desiredType == AECableType.SMART || desiredType == AECableType.COVERED ) ) + { + renderState.setCoreType( CableCoreType.COVERED ); + } + + int length = (int) part.getCableConnectionLength( null ); + if( length > 0 && length <= 8 ) + { + renderState.getAttachmentConnections().put( facing, length ); + } + } + + renderState.getAttachments().put( facing, part.getStaticModels() ); + } + + return renderState; + } + } diff --git a/src/main/java/appeng/parts/ICableBusContainer.java b/src/main/java/appeng/parts/ICableBusContainer.java index 826c7c7c..4affd143 100644 --- a/src/main/java/appeng/parts/ICableBusContainer.java +++ b/src/main/java/appeng/parts/ICableBusContainer.java @@ -35,6 +35,7 @@ import net.minecraftforge.fml.relauncher.SideOnly; import appeng.api.parts.SelectedPart; import appeng.api.util.AEColor; +import appeng.client.render.cablebus.CableBusRenderState; public interface ICableBusContainer @@ -66,4 +67,7 @@ public interface ICableBusContainer void randomDisplayTick( World world, BlockPos pos, Random r ); int getLightValue(); + + CableBusRenderState getRenderState(); + } diff --git a/src/main/java/appeng/parts/NullCableBusContainer.java b/src/main/java/appeng/parts/NullCableBusContainer.java index af8b4b6d..0cefa194 100644 --- a/src/main/java/appeng/parts/NullCableBusContainer.java +++ b/src/main/java/appeng/parts/NullCableBusContainer.java @@ -33,6 +33,7 @@ import net.minecraft.world.World; import appeng.api.parts.SelectedPart; import appeng.api.util.AEColor; +import appeng.client.render.cablebus.CableBusRenderState; public class NullCableBusContainer implements ICableBusContainer @@ -115,4 +116,11 @@ public class NullCableBusContainer implements ICableBusContainer { return 0; } + + @Override + public CableBusRenderState getRenderState() + { + return new CableBusRenderState(); + } + } diff --git a/src/main/java/appeng/parts/automation/PartAnnihilationPlane.java b/src/main/java/appeng/parts/automation/PartAnnihilationPlane.java index c8987041..3e1fd5d8 100644 --- a/src/main/java/appeng/parts/automation/PartAnnihilationPlane.java +++ b/src/main/java/appeng/parts/automation/PartAnnihilationPlane.java @@ -31,6 +31,7 @@ import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -58,6 +59,7 @@ import appeng.api.util.AEPartLocation; import appeng.core.settings.TickRates; import appeng.core.sync.packets.PacketTransitionEffect; import appeng.hooks.TickHandler; +import appeng.items.parts.PartModels; import appeng.me.GridAccessException; import appeng.parts.PartBasicState; import appeng.server.ServerHelper; @@ -69,6 +71,14 @@ import appeng.util.item.AEItemStack; public class PartAnnihilationPlane extends PartBasicState implements IGridTickable, IWorldCallable { + private static final PlaneModels MODELS = new PlaneModels( "part/annihilation_plane_", "part/annihilation_plane_on_" ); + + @PartModels + public static List getModels() + { + return MODELS.getModels(); + } + private final BaseActionSource mySrc = new MachineSource( this ); private boolean isAccepting = true; private boolean breaking = false; @@ -128,6 +138,78 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab bch.addBox( minX, minY, 15, maxX, maxY, bch.isBBCollision() ? 15 : 16 ); } + /** + * @return An object describing which adjacent planes this plane connects to visually. + */ + public PlaneConnections getConnections() + { + + final EnumFacing facingRight, facingUp; + AEPartLocation location = getSide(); + switch( location ) + { + case UP: + facingRight = EnumFacing.EAST; + facingUp = EnumFacing.NORTH; + break; + case DOWN: + facingRight = EnumFacing.WEST; + facingUp = EnumFacing.NORTH; + break; + case NORTH: + facingRight = EnumFacing.WEST; + facingUp = EnumFacing.UP; + break; + case SOUTH: + facingRight = EnumFacing.EAST; + facingUp = EnumFacing.UP; + break; + case WEST: + facingRight = EnumFacing.SOUTH; + facingUp = EnumFacing.UP; + break; + case EAST: + facingRight = EnumFacing.NORTH; + facingUp = EnumFacing.UP; + break; + default: + case INTERNAL: + return PlaneConnections.of( false, false, false, false ); + } + + boolean left = false, right = false, down = false, up = false; + + final IPartHost host = this.getHost(); + if( host != null ) + { + final TileEntity te = host.getTile(); + + final BlockPos pos = te.getPos(); + + if( this.isAnnihilationPlane( te.getWorld().getTileEntity( pos.offset( facingRight.getOpposite() ) ), this.getSide() ) ) + { + left = true; + } + + if( this.isAnnihilationPlane( te.getWorld().getTileEntity( pos.offset( facingRight ) ), this.getSide() ) ) + { + right = true; + } + + if( this.isAnnihilationPlane( te.getWorld().getTileEntity( pos.offset( facingUp.getOpposite() ) ), this.getSide() ) ) + { + down = true; + } + + if( this.isAnnihilationPlane( te.getWorld().getTileEntity( pos.offset( facingUp ) ), this.getSide() ) ) + { + up = true; + } + } + + return PlaneConnections.of( up, right, down, left ); + } + @Override public void onNeighborChanged() { @@ -235,6 +317,7 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab * Stores an {@link ItemStack} inside the network. * * @param item {@link ItemStack} to store + * * @return the leftover items, which could not be stored inside the network */ private IAEItemStack storeItemStack( final ItemStack item ) @@ -265,6 +348,7 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab * * @param entityItem the entity to update or destroy * @param overflow the leftover {@link IAEItemStack} + * * @return true, if the entity was changed otherwise false. */ private boolean handleOverflow( final EntityItem entityItem, final IAEItemStack overflow ) @@ -496,4 +580,11 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab this.spawnOverflow( overflow ); } } + + @Override + public List getStaticModels() + { + return MODELS.getModel( getConnections(), isPowered(), isActive() ); + } + } diff --git a/src/main/java/appeng/parts/automation/PartExportBus.java b/src/main/java/appeng/parts/automation/PartExportBus.java index 62a7f89e..7e475695 100644 --- a/src/main/java/appeng/parts/automation/PartExportBus.java +++ b/src/main/java/appeng/parts/automation/PartExportBus.java @@ -19,6 +19,8 @@ package appeng.parts.automation; +import java.util.List; + import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; @@ -26,6 +28,7 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.Vec3d; import appeng.api.config.Actionable; @@ -51,10 +54,12 @@ import appeng.api.storage.IMEMonitor; import appeng.api.storage.data.IAEItemStack; import appeng.api.util.AECableType; import appeng.core.AELog; +import appeng.core.AppEng; import appeng.core.settings.TickRates; import appeng.core.sync.GuiBridge; import appeng.helpers.MultiCraftingTracker; import appeng.helpers.Reflected; +import appeng.items.parts.PartModels; import appeng.me.GridAccessException; import appeng.util.InventoryAdaptor; import appeng.util.Platform; @@ -63,6 +68,24 @@ import appeng.util.item.AEItemStack; public class PartExportBus extends PartSharedItemBus implements ICraftingRequester { + + public static final ResourceLocation MODEL_BASE = new ResourceLocation( AppEng.MOD_ID, "part/export_bus_base" ); + @PartModels + public static final List MODELS_OFF = ImmutableList.of( + MODEL_BASE, + new ResourceLocation( AppEng.MOD_ID, "part/export_bus_off" ) + ); + @PartModels + public static final List MODELS_ON = ImmutableList.of( + MODEL_BASE, + new ResourceLocation( AppEng.MOD_ID, "part/export_bus_on" ) + ); + @PartModels + public static final List MODELS_HAS_CHANNEL = ImmutableList.of( + MODEL_BASE, + new ResourceLocation( AppEng.MOD_ID, "part/export_bus_has_channel" ) + ); + private final MultiCraftingTracker craftingTracker = new MultiCraftingTracker( this, 9 ); private final BaseActionSource mySrc; private long itemToSend = 1; @@ -337,4 +360,22 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest this.nextSlot = ( this.nextSlot + x ) % this.availableSlots(); } } + + @Override + public List getStaticModels() + { + if( isActive() && isPowered() ) + { + return MODELS_HAS_CHANNEL; + } + else if( isPowered() ) + { + return MODELS_ON; + } + else + { + return MODELS_OFF; + } + } + } diff --git a/src/main/java/appeng/parts/automation/PartFormationPlane.java b/src/main/java/appeng/parts/automation/PartFormationPlane.java index 68b233a5..30ef521e 100644 --- a/src/main/java/appeng/parts/automation/PartFormationPlane.java +++ b/src/main/java/appeng/parts/automation/PartFormationPlane.java @@ -37,6 +37,7 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; @@ -73,6 +74,7 @@ import appeng.api.util.IConfigManager; import appeng.core.AEConfig; import appeng.core.sync.GuiBridge; import appeng.helpers.IPriorityHost; +import appeng.items.parts.PartModels; import appeng.me.GridAccessException; import appeng.me.storage.MEInventoryHandler; import appeng.tile.inventory.AppEngInternalAEInventory; @@ -84,6 +86,15 @@ import appeng.util.prioitylist.PrecisePriorityList; public class PartFormationPlane extends PartUpgradeable implements ICellContainer, IPriorityHost, IMEInventory { + + private static final PlaneModels MODELS = new PlaneModels( "part/formation_plane_", "part/formation_plane_on_" ); + + @PartModels + public static List getModels() + { + return MODELS.getModels(); + } + private final MEInventoryHandler myHandler = new MEInventoryHandler( this, StorageChannel.ITEMS ); private final AppEngInternalAEInventory Config = new AppEngInternalAEInventory( this, 63 ); private int priority = 0; @@ -262,6 +273,79 @@ public class PartFormationPlane extends PartUpgradeable implements ICellContaine bch.addBox( minX, minY, 15, maxX, maxY, 16 ); } + // TODO: Consolidate this with the impl in PartAnnihilationPlane + /** + * @return An object describing which adjacent planes this plane connects to visually. + */ + public PlaneConnections getConnections() + { + + final EnumFacing facingRight, facingUp; + AEPartLocation location = getSide(); + switch( location ) + { + case UP: + facingRight = EnumFacing.EAST; + facingUp = EnumFacing.NORTH; + break; + case DOWN: + facingRight = EnumFacing.WEST; + facingUp = EnumFacing.NORTH; + break; + case NORTH: + facingRight = EnumFacing.WEST; + facingUp = EnumFacing.UP; + break; + case SOUTH: + facingRight = EnumFacing.EAST; + facingUp = EnumFacing.UP; + break; + case WEST: + facingRight = EnumFacing.SOUTH; + facingUp = EnumFacing.UP; + break; + case EAST: + facingRight = EnumFacing.NORTH; + facingUp = EnumFacing.UP; + break; + default: + case INTERNAL: + return PlaneConnections.of( false, false, false, false ); + } + + boolean left = false, right = false, down = false, up = false; + + final IPartHost host = this.getHost(); + if( host != null ) + { + final TileEntity te = host.getTile(); + + final BlockPos pos = te.getPos(); + + if( this.isTransitionPlane( te.getWorld().getTileEntity( pos.offset( facingRight.getOpposite() ) ), this.getSide() ) ) + { + left = true; + } + + if( this.isTransitionPlane( te.getWorld().getTileEntity( pos.offset( facingRight ) ), this.getSide() ) ) + { + right = true; + } + + if( this.isTransitionPlane( te.getWorld().getTileEntity( pos.offset( facingUp.getOpposite() ) ), this.getSide() ) ) + { + down = true; + } + + if( this.isTransitionPlane( te.getWorld().getTileEntity( pos.offset( facingUp ) ), this.getSide() ) ) + { + up = true; + } + } + + return PlaneConnections.of( up, right, down, left ); + } + @Override public void onNeighborChanged() { @@ -525,4 +609,11 @@ public class PartFormationPlane extends PartUpgradeable implements ICellContaine { // nope! } + + @Override + public List getStaticModels() + { + return MODELS.getModel( getConnections(), isPowered(), isActive() ); + } + } diff --git a/src/main/java/appeng/parts/automation/PartIdentityAnnihilationPlane.java b/src/main/java/appeng/parts/automation/PartIdentityAnnihilationPlane.java index b0acdfa0..8d9e800d 100644 --- a/src/main/java/appeng/parts/automation/PartIdentityAnnihilationPlane.java +++ b/src/main/java/appeng/parts/automation/PartIdentityAnnihilationPlane.java @@ -26,6 +26,7 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.WorldServer; import net.minecraftforge.common.util.FakePlayer; @@ -34,11 +35,20 @@ import net.minecraftforge.common.util.FakePlayerFactory; import appeng.api.parts.IPart; import appeng.api.parts.IPartHost; import appeng.api.util.AEPartLocation; +import appeng.items.parts.PartModels; public class PartIdentityAnnihilationPlane extends PartAnnihilationPlane { + private static final PlaneModels MODELS = new PlaneModels( "part/identity_annihilation_plane_", "part/identity_annihilation_plane_on_" ); + + @PartModels + public static List getModels() + { + return MODELS.getModels(); + } + private static final float SILK_TOUCH_FACTOR = 16; public PartIdentityAnnihilationPlane( final ItemStack is ) @@ -93,4 +103,11 @@ public class PartIdentityAnnihilationPlane extends PartAnnihilationPlane return super.obtainBlockDrops( w, pos ); } } + + @Override + public List getStaticModels() + { + return MODELS.getModel( getConnections(), isPowered(), isActive() ); + } + } diff --git a/src/main/java/appeng/parts/automation/PartImportBus.java b/src/main/java/appeng/parts/automation/PartImportBus.java index e547b1f2..56973e85 100644 --- a/src/main/java/appeng/parts/automation/PartImportBus.java +++ b/src/main/java/appeng/parts/automation/PartImportBus.java @@ -19,9 +19,14 @@ package appeng.parts.automation; +import java.util.List; + +import com.google.common.collect.ImmutableList; + import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.Vec3d; import appeng.api.AEApi; @@ -43,9 +48,11 @@ import appeng.api.storage.IMEInventory; import appeng.api.storage.IMEMonitor; import appeng.api.storage.data.IAEItemStack; import appeng.api.util.AECableType; +import appeng.core.AppEng; import appeng.core.settings.TickRates; import appeng.core.sync.GuiBridge; import appeng.helpers.Reflected; +import appeng.items.parts.PartModels; import appeng.me.GridAccessException; import appeng.util.InventoryAdaptor; import appeng.util.Platform; @@ -55,6 +62,24 @@ import appeng.util.item.AEItemStack; public class PartImportBus extends PartSharedItemBus implements IInventoryDestination { + + public static final ResourceLocation MODEL_BASE = new ResourceLocation( AppEng.MOD_ID, "part/import_bus_base" ); + @PartModels + public static final List MODELS_OFF = ImmutableList.of( + MODEL_BASE, + new ResourceLocation( AppEng.MOD_ID, "part/import_bus_off" ) + ); + @PartModels + public static final List MODELS_ON = ImmutableList.of( + MODEL_BASE, + new ResourceLocation( AppEng.MOD_ID, "part/import_bus_on" ) + ); + @PartModels + public static final List MODELS_HAS_CHANNEL = ImmutableList.of( + MODEL_BASE, + new ResourceLocation( AppEng.MOD_ID, "part/import_bus_has_channel" ) + ); + private final BaseActionSource source; private IMEInventory destination = null; private IAEItemStack lastItemChecked = null; @@ -294,4 +319,22 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin { return (RedstoneMode) this.getConfigManager().getSetting( Settings.REDSTONE_CONTROLLED ); } + + @Override + public List getStaticModels() + { + if( isActive() && isPowered() ) + { + return MODELS_HAS_CHANNEL; + } + else if( isPowered() ) + { + return MODELS_ON; + } + else + { + return MODELS_OFF; + } + } + } diff --git a/src/main/java/appeng/parts/automation/PartLevelEmitter.java b/src/main/java/appeng/parts/automation/PartLevelEmitter.java index c1d94193..1a5c4bc3 100644 --- a/src/main/java/appeng/parts/automation/PartLevelEmitter.java +++ b/src/main/java/appeng/parts/automation/PartLevelEmitter.java @@ -20,8 +20,11 @@ package appeng.parts.automation; import java.util.Collection; +import java.util.List; import java.util.Random; +import com.google.common.collect.ImmutableList; + import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryCrafting; @@ -30,6 +33,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumHand; import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; @@ -67,8 +71,10 @@ import appeng.api.storage.data.IItemList; import appeng.api.util.AECableType; import appeng.api.util.AEPartLocation; import appeng.api.util.IConfigManager; +import appeng.core.AppEng; import appeng.core.sync.GuiBridge; import appeng.helpers.Reflected; +import appeng.items.parts.PartModels; import appeng.me.GridAccessException; import appeng.tile.inventory.AppEngInternalAEInventory; import appeng.tile.inventory.InvOperation; @@ -78,6 +84,24 @@ import appeng.util.Platform; public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherHost, IStackWatcherHost, ICraftingWatcherHost, IMEMonitorHandlerReceiver, ICraftingProvider { + @PartModels + public static final ResourceLocation MODEL_BASE_OFF = new ResourceLocation( AppEng.MOD_ID, "part/level_emitter_base_off" ); + @PartModels + public static final ResourceLocation MODEL_BASE_ON = new ResourceLocation( AppEng.MOD_ID, "part/level_emitter_base_on" ); + @PartModels + public static final ResourceLocation MODEL_STATUS_OFF = new ResourceLocation( AppEng.MOD_ID, "part/level_emitter_status_off" ); + @PartModels + public static final ResourceLocation MODEL_STATUS_ON = new ResourceLocation( AppEng.MOD_ID, "part/level_emitter_status_on" ); + @PartModels + public static final ResourceLocation MODEL_STATUS_HAS_CHANNEL = new ResourceLocation( AppEng.MOD_ID, "part/level_emitter_status_has_channel" ); + + public static final List MODEL_OFF_OFF = ImmutableList.of( MODEL_BASE_OFF, MODEL_STATUS_OFF ); + public static final List MODEL_OFF_ON = ImmutableList.of( MODEL_BASE_OFF, MODEL_STATUS_ON ); + public static final List MODEL_OFF_HAS_CHANNEL = ImmutableList.of( MODEL_BASE_OFF, MODEL_STATUS_HAS_CHANNEL ); + public static final List MODEL_ON_OFF = ImmutableList.of( MODEL_BASE_ON, MODEL_STATUS_OFF ); + public static final List MODEL_ON_ON = ImmutableList.of( MODEL_BASE_ON, MODEL_STATUS_ON ); + public static final List MODEL_ON_HAS_CHANNEL = ImmutableList.of( MODEL_BASE_ON, MODEL_STATUS_HAS_CHANNEL ); + private static final int FLAG_ON = 4; private final AppEngInternalAEInventory config = new AppEngInternalAEInventory( this, 1 ); @@ -142,7 +166,8 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH } } - private boolean isLevelEmitterOn() + // TODO: Make private again + public boolean isLevelEmitterOn() { if( Platform.isClient() ) { @@ -534,4 +559,21 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH } } } + + @Override + public List getStaticModels() + { + if( isActive() && isPowered() ) + { + return isLevelEmitterOn() ? MODEL_ON_HAS_CHANNEL : MODEL_OFF_HAS_CHANNEL; + } + else if( isPowered() ) + { + return isLevelEmitterOn() ? MODEL_ON_ON : MODEL_OFF_ON; + } + else + { + return isLevelEmitterOn() ? MODEL_ON_OFF : MODEL_OFF_OFF; + } + } } diff --git a/src/main/java/appeng/parts/automation/PlaneBakedModel.java b/src/main/java/appeng/parts/automation/PlaneBakedModel.java new file mode 100644 index 00000000..719a96a0 --- /dev/null +++ b/src/main/java/appeng/parts/automation/PlaneBakedModel.java @@ -0,0 +1,104 @@ +package appeng.parts.automation; + + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import javax.annotation.Nullable; + +import com.google.common.collect.ImmutableList; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms; +import net.minecraft.client.renderer.block.model.ItemOverrideList; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.util.EnumFacing; + +import appeng.client.render.cablebus.CubeBuilder; + + +/** + * Built-in model for annihilation planes that supports connected textures. + */ +public class PlaneBakedModel implements IBakedModel +{ + + private final TextureAtlasSprite frontTexture; + + private final List quads; + + PlaneBakedModel( VertexFormat format, TextureAtlasSprite frontTexture, TextureAtlasSprite sidesTexture, TextureAtlasSprite backTexture, + PlaneConnections connections ) + { + this.frontTexture = frontTexture; + + List quads = new ArrayList<>( 4 * 6 ); + + CubeBuilder builder = new CubeBuilder( format, quads ); + + builder.setTextures( sidesTexture, sidesTexture, frontTexture, backTexture, sidesTexture, sidesTexture ); + + // Keep the orientation of the X axis in mind here. When looking at a quad facing north from the front, + // The X-axis points left + int minX = connections.isRight() ? 0 : 1; + int maxX = connections.isLeft() ? 16 : 15; + int minY = connections.isDown() ? 0 : 1; + int maxY = connections.isUp() ? 16 : 15; + + builder.addCube( minX, minY, 0, maxX, maxY, 1 ); + + this.quads = ImmutableList.copyOf( quads ); + } + + @Override + public List getQuads( @Nullable IBlockState state, @Nullable EnumFacing side, long rand ) + { + if( side == null ) + { + return quads; + } + else + { + return Collections.emptyList(); + } + } + + @Override + public boolean isAmbientOcclusion() + { + return false; + } + + @Override + public boolean isGui3d() + { + return false; + } + + @Override + public boolean isBuiltInRenderer() + { + return false; + } + + @Override + public TextureAtlasSprite getParticleTexture() + { + return frontTexture; + } + + @Override + public ItemCameraTransforms getItemCameraTransforms() + { + return ItemCameraTransforms.DEFAULT; + } + + @Override + public ItemOverrideList getOverrides() + { + return ItemOverrideList.NONE; + } +} diff --git a/src/main/java/appeng/parts/automation/PlaneConnections.java b/src/main/java/appeng/parts/automation/PlaneConnections.java new file mode 100644 index 00000000..286449cb --- /dev/null +++ b/src/main/java/appeng/parts/automation/PlaneConnections.java @@ -0,0 +1,121 @@ +package appeng.parts.automation; + + +import java.util.ArrayList; +import java.util.List; + +import com.google.common.base.Strings; + + +/** + * Models in which directions - looking at the front face - a plane (annihilation, formation, etc.) is connected to other planes of the same type. + */ +public final class PlaneConnections +{ + + private final boolean up; + private final boolean right; + private final boolean down; + private final boolean left; + + private static final int BITMASK_UP = 8; + private static final int BITMASK_RIGHT = 4; + private static final int BITMASK_DOWN = 2; + private static final int BITMASK_LEFT = 1; + + public static final List PERMUTATIONS = generatePermutations(); + + private static List generatePermutations() + { + List connections = new ArrayList<>( 16 ); + + for( int i = 0; i < 16; i++ ) + { + boolean up = ( i & BITMASK_UP ) != 0; + boolean right = ( i & BITMASK_RIGHT ) != 0; + boolean down = ( i & BITMASK_DOWN ) != 0; + boolean left = ( i & BITMASK_LEFT ) != 0; + + connections.add( new PlaneConnections( up, right, down, left ) ); + } + + return connections; + } + + private PlaneConnections( boolean up, boolean right, boolean down, boolean left ) + { + this.up = up; + this.right = right; + this.down = down; + this.left = left; + } + + public static PlaneConnections of( boolean up, boolean right, boolean down, boolean left ) + { + return PERMUTATIONS.get( getIndex( up, right, down, left ) ); + } + + public boolean isUp() + { + return up; + } + + public boolean isRight() + { + return right; + } + + public boolean isDown() + { + return down; + } + + public boolean isLeft() + { + return left; + } + + // The combination of connections expressed as a number ranging from [0,15] + public int getIndex() + { + return getIndex( up, right, down, left ); + } + + private static int getIndex( boolean up, boolean right, boolean down, boolean left ) + { + return ( up ? BITMASK_UP : 0 ) + ( right ? BITMASK_RIGHT : 0 ) + ( left ? BITMASK_LEFT : 0 ) + ( down ? BITMASK_DOWN : 0 ); + } + + // Returns a suffix that expresses the connection states as a string + public String getFilenameSuffix() + { + String suffix = Integer.toBinaryString( getIndex() ); + return Strings.padStart(suffix, 4, '0'); + } + + @Override + public boolean equals( Object o ) + { + if( this == o ) + { + return true; + } + if( o == null || getClass() != o.getClass() ) + { + return false; + } + + PlaneConnections that = (PlaneConnections) o; + return up == that.up && right == that.right && down == that.down && left == that.left; + } + + @Override + public int hashCode() + { + int result = ( up ? 1 : 0 ); + result = 31 * result + ( right ? 1 : 0 ); + result = 31 * result + ( down ? 1 : 0 ); + result = 31 * result + ( left ? 1 : 0 ); + return result; + } +} diff --git a/src/main/java/appeng/parts/automation/PlaneModel.java b/src/main/java/appeng/parts/automation/PlaneModel.java new file mode 100644 index 00000000..614adacb --- /dev/null +++ b/src/main/java/appeng/parts/automation/PlaneModel.java @@ -0,0 +1,66 @@ +package appeng.parts.automation; + + +import java.util.Collection; +import java.util.Collections; + +import com.google.common.base.Function; +import com.google.common.collect.Lists; + +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.model.IModel; +import net.minecraftforge.common.model.IModelState; +import net.minecraftforge.common.model.TRSRTransformation; + + +/** + * Built-in model for annihilation planes that supports connected textures. + */ +public class PlaneModel implements IModel +{ + + private final ResourceLocation frontTexture; + private final ResourceLocation sidesTexture; + private final ResourceLocation backTexture; + private final PlaneConnections connections; + + public PlaneModel( ResourceLocation frontTexture, ResourceLocation sidesTexture, ResourceLocation backTexture, PlaneConnections connections ) + { + this.frontTexture = frontTexture; + this.sidesTexture = sidesTexture; + this.backTexture = backTexture; + this.connections = connections; + } + + @Override + public Collection getDependencies() + { + return Collections.emptyList(); + } + + @Override + public Collection getTextures() + { + return Lists.newArrayList( frontTexture, sidesTexture, backTexture ); + } + + @Override + public IBakedModel bake( IModelState state, VertexFormat format, Function bakedTextureGetter ) + { + TextureAtlasSprite frontSprite = bakedTextureGetter.apply( frontTexture ); + TextureAtlasSprite sidesSprite = bakedTextureGetter.apply( sidesTexture ); + TextureAtlasSprite backSprite = bakedTextureGetter.apply( backTexture ); + + return new PlaneBakedModel( format, frontSprite, sidesSprite, backSprite, connections ); + } + + @Override + public IModelState getDefaultState() + { + return TRSRTransformation.identity(); + } + +} diff --git a/src/main/java/appeng/parts/automation/PlaneModels.java b/src/main/java/appeng/parts/automation/PlaneModels.java new file mode 100644 index 00000000..7e54f026 --- /dev/null +++ b/src/main/java/appeng/parts/automation/PlaneModels.java @@ -0,0 +1,79 @@ +package appeng.parts.automation; + + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +import net.minecraft.util.ResourceLocation; + +import appeng.core.AppEng; + + +/** + * Contains a mapping from a Plane's connections to the models to use for that state. + */ +class PlaneModels +{ + + public static final ResourceLocation MODEL_CHASSIS_OFF = new ResourceLocation( AppEng.MOD_ID, "part/transition_plane_off" ); + public static final ResourceLocation MODEL_CHASSIS_ON = new ResourceLocation( AppEng.MOD_ID, "part/transition_plane_on" ); + public static final ResourceLocation MODEL_CHASSIS_HAS_CHANNEL = new ResourceLocation( AppEng.MOD_ID, "part/transition_plane_has_channel" ); + + private final Map> modelsOff; + + private final Map> modelsOn; + + private final Map> modelsHasChannel; + + public PlaneModels( String prefixOff, String prefixOn ) + { + Map> modelsOff = new HashMap<>(); + Map> modelsOn = new HashMap<>(); + Map> modelsHasChannel = new HashMap<>(); + + for( PlaneConnections permutation : PlaneConnections.PERMUTATIONS ) + { + ResourceLocation planeOff = new ResourceLocation( AppEng.MOD_ID, prefixOff + permutation.getFilenameSuffix() ); + ResourceLocation planeOn = new ResourceLocation( AppEng.MOD_ID, prefixOn + permutation.getFilenameSuffix() ); + + modelsOff.put( permutation, ImmutableList.of( MODEL_CHASSIS_OFF, planeOff ) ); + modelsOn.put( permutation, ImmutableList.of( MODEL_CHASSIS_ON, planeOff ) ); + modelsHasChannel.put( permutation, ImmutableList.of( MODEL_CHASSIS_HAS_CHANNEL, planeOn ) ); + } + + this.modelsOff = ImmutableMap.copyOf( modelsOff ); + this.modelsOn = ImmutableMap.copyOf( modelsOn ); + this.modelsHasChannel = ImmutableMap.copyOf( modelsHasChannel ); + } + + public List getModel( PlaneConnections connections, boolean hasPower, boolean hasChannel ) + { + if( hasPower && hasChannel ) + { + return modelsHasChannel.get( connections ); + } + else if( hasPower ) + { + return modelsOn.get( connections ); + } + else + { + return modelsOff.get( connections ); + } + } + + public List getModels() + { + List result = new ArrayList<>(); + modelsOff.values().forEach( result::addAll ); + modelsOn.values().forEach( result::addAll ); + modelsHasChannel.values().forEach( result::addAll ); + return result; + } + +} diff --git a/src/main/java/appeng/parts/misc/PartCableAnchor.java b/src/main/java/appeng/parts/misc/PartCableAnchor.java index 10b54f18..04ed5b61 100644 --- a/src/main/java/appeng/parts/misc/PartCableAnchor.java +++ b/src/main/java/appeng/parts/misc/PartCableAnchor.java @@ -20,30 +20,22 @@ package appeng.parts.misc; import java.io.IOException; -import java.util.ArrayList; import java.util.List; import java.util.Random; import io.netty.buffer.ByteBuf; -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; -import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -import appeng.api.client.BakingPipeline; import appeng.api.networking.IGridNode; import appeng.api.parts.BusSupport; import appeng.api.parts.IPart; @@ -52,8 +44,6 @@ import appeng.api.parts.IPartHost; import appeng.api.parts.PartItemStack; import appeng.api.util.AECableType; import appeng.api.util.AEPartLocation; -import appeng.client.render.model.ModelsCache; -import appeng.core.AppEng; public class PartCableAnchor implements IPart @@ -238,11 +228,4 @@ public class PartCableAnchor implements IPart return what == BusSupport.CABLE || what == BusSupport.DENSE_CABLE; } - @Override - @SideOnly( Side.CLIENT ) - public List getOrBakeQuads( BakingPipeline rotatingPipeline, IBlockState state, EnumFacing side, long rand ) - { - return rotatingPipeline.pipe( ModelsCache.INSTANCE.getOrLoadBakedModel( new ResourceLocation( AppEng.MOD_ID, "part/cable_anchor" ) ).getQuads( state, side, rand ), null, state, mySide.getFacing(), rand ); - } - } diff --git a/src/main/java/appeng/parts/misc/PartInterface.java b/src/main/java/appeng/parts/misc/PartInterface.java index 1020c9c1..bd364ea7 100644 --- a/src/main/java/appeng/parts/misc/PartInterface.java +++ b/src/main/java/appeng/parts/misc/PartInterface.java @@ -22,6 +22,7 @@ package appeng.parts.misc; import java.util.EnumSet; import java.util.List; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import net.minecraft.entity.player.EntityPlayer; @@ -33,6 +34,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.Vec3d; import net.minecraft.util.text.ITextComponent; @@ -57,11 +59,13 @@ import appeng.api.storage.data.IAEFluidStack; import appeng.api.storage.data.IAEItemStack; import appeng.api.util.AECableType; import appeng.api.util.IConfigManager; +import appeng.core.AppEng; import appeng.core.sync.GuiBridge; import appeng.helpers.DualityInterface; import appeng.helpers.IInterfaceHost; import appeng.helpers.IPriorityHost; import appeng.helpers.Reflected; +import appeng.items.parts.PartModels; import appeng.parts.PartBasicState; import appeng.tile.inventory.IAEAppEngInventory; import appeng.tile.inventory.InvOperation; @@ -72,6 +76,23 @@ import appeng.util.inv.IInventoryDestination; public class PartInterface extends PartBasicState implements IGridTickable, IStorageMonitorable, IInventoryDestination, IInterfaceHost, ISidedInventory, IAEAppEngInventory, ITileStorageMonitorable, IPriorityHost { + public static final ResourceLocation MODEL_BASE = new ResourceLocation( AppEng.MOD_ID, "part/interface_base" ); + @PartModels + public static final List MODELS_OFF = ImmutableList.of( + MODEL_BASE, + new ResourceLocation( AppEng.MOD_ID, "part/interface_off" ) + ); + @PartModels + public static final List MODELS_ON = ImmutableList.of( + MODEL_BASE, + new ResourceLocation( AppEng.MOD_ID, "part/interface_on" ) + ); + @PartModels + public static final List MODELS_HAS_CHANNEL = ImmutableList.of( + MODEL_BASE, + new ResourceLocation( AppEng.MOD_ID, "part/interface_has_channel" ) + ); + private final DualityInterface duality = new DualityInterface( this.getProxy(), this ); @Reflected @@ -405,4 +426,22 @@ public class PartInterface extends PartBasicState implements IGridTickable, ISto { return null; } + + @Override + public List getStaticModels() + { + if( isActive() && isPowered() ) + { + return MODELS_HAS_CHANNEL; + } + else if( isPowered() ) + { + return MODELS_ON; + } + else + { + return MODELS_OFF; + } + } + } diff --git a/src/main/java/appeng/parts/misc/PartInvertedToggleBus.java b/src/main/java/appeng/parts/misc/PartInvertedToggleBus.java index d2fc5d05..9d5e7fa2 100644 --- a/src/main/java/appeng/parts/misc/PartInvertedToggleBus.java +++ b/src/main/java/appeng/parts/misc/PartInvertedToggleBus.java @@ -19,13 +19,27 @@ package appeng.parts.misc; -import net.minecraft.item.ItemStack; +import java.util.List; +import com.google.common.collect.ImmutableList; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; + +import appeng.core.AppEng; import appeng.helpers.Reflected; +import appeng.items.parts.PartModels; public class PartInvertedToggleBus extends PartToggleBus { + @PartModels + public static final ResourceLocation MODEL_BASE = new ResourceLocation( AppEng.MOD_ID, "part/inverted_toggle_bus_base" ); + + public static final List MODELS_OFF = ImmutableList.of(MODEL_BASE, MODEL_STATUS_OFF); + public static final List MODELS_ON = ImmutableList.of(MODEL_BASE, MODEL_STATUS_ON); + public static final List MODELS_HAS_CHANNEL = ImmutableList.of(MODEL_BASE, MODEL_STATUS_HAS_CHANNEL); + @Reflected public PartInvertedToggleBus( final ItemStack is ) { @@ -41,4 +55,22 @@ public class PartInvertedToggleBus extends PartToggleBus { return !super.getIntention(); } + + @Override + public List getStaticModels() + { + if( hasRedstoneFlag() && isActive() && isPowered() ) + { + return MODELS_HAS_CHANNEL; + } + else if( hasRedstoneFlag() && isPowered() ) + { + return MODELS_ON; + } + else + { + return MODELS_OFF; + } + } + } diff --git a/src/main/java/appeng/parts/misc/PartStorageBus.java b/src/main/java/appeng/parts/misc/PartStorageBus.java index 00f1b2ca..0611cf5c 100644 --- a/src/main/java/appeng/parts/misc/PartStorageBus.java +++ b/src/main/java/appeng/parts/misc/PartStorageBus.java @@ -23,12 +23,15 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import com.google.common.collect.ImmutableList; + import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.Vec3d; import appeng.api.AEApi; @@ -64,12 +67,14 @@ import appeng.api.storage.data.IItemList; import appeng.api.util.AECableType; import appeng.api.util.AEPartLocation; import appeng.api.util.IConfigManager; +import appeng.core.AppEng; import appeng.core.settings.TickRates; import appeng.core.stats.Achievements; import appeng.core.sync.GuiBridge; import appeng.helpers.IInterfaceHost; import appeng.helpers.IPriorityHost; import appeng.helpers.Reflected; +import appeng.items.parts.PartModels; import appeng.me.GridAccessException; import appeng.me.storage.MEInventoryHandler; import appeng.me.storage.MEMonitorIInventory; @@ -88,6 +93,24 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC * IPipeConnection */, IPriorityHost { + + public static final ResourceLocation MODEL_BASE = new ResourceLocation( AppEng.MOD_ID, "part/storage_bus_base" ); + @PartModels + public static final List MODELS_OFF = ImmutableList.of( + MODEL_BASE, + new ResourceLocation( AppEng.MOD_ID, "part/storage_bus_off" ) + ); + @PartModels + public static final List MODELS_ON = ImmutableList.of( + MODEL_BASE, + new ResourceLocation( AppEng.MOD_ID, "part/storage_bus_on" ) + ); + @PartModels + public static final List MODELS_HAS_CHANNEL = ImmutableList.of( + MODEL_BASE, + new ResourceLocation( AppEng.MOD_ID, "part/storage_bus_has_channel" ) + ); + private final BaseActionSource mySrc; private final AppEngInternalAEInventory Config = new AppEngInternalAEInventory( this, 63 ); private int priority = 0; @@ -530,4 +553,22 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC { // nope! } + + @Override + public List getStaticModels() + { + if( isActive() && isPowered() ) + { + return MODELS_HAS_CHANNEL; + } + else if( isPowered() ) + { + return MODELS_ON; + } + else + { + return MODELS_OFF; + } + } + } diff --git a/src/main/java/appeng/parts/misc/PartToggleBus.java b/src/main/java/appeng/parts/misc/PartToggleBus.java index 2cdd4acd..96eb3336 100644 --- a/src/main/java/appeng/parts/misc/PartToggleBus.java +++ b/src/main/java/appeng/parts/misc/PartToggleBus.java @@ -23,16 +23,14 @@ import java.util.ArrayList; import java.util.EnumSet; import java.util.List; -import org.lwjgl.opengl.GL11; +import com.google.common.collect.ImmutableList; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraft.util.ResourceLocation; import appeng.api.AEApi; import appeng.api.exceptions.FailedConnection; @@ -42,7 +40,9 @@ import appeng.api.parts.IPartCollisionHelper; import appeng.api.parts.IPartHost; import appeng.api.util.AECableType; import appeng.api.util.AEPartLocation; +import appeng.core.AppEng; import appeng.helpers.Reflected; +import appeng.items.parts.PartModels; import appeng.me.helpers.AENetworkProxy; import appeng.parts.PartBasicState; import appeng.util.Platform; @@ -50,6 +50,20 @@ import appeng.util.Platform; public class PartToggleBus extends PartBasicState { + + @PartModels + public static final ResourceLocation MODEL_BASE = new ResourceLocation( AppEng.MOD_ID, "part/toggle_bus_base" ); + @PartModels + public static final ResourceLocation MODEL_STATUS_OFF = new ResourceLocation( AppEng.MOD_ID, "part/toggle_bus_status_off" ); + @PartModels + public static final ResourceLocation MODEL_STATUS_ON = new ResourceLocation( AppEng.MOD_ID, "part/toggle_bus_status_on" ); + @PartModels + public static final ResourceLocation MODEL_STATUS_HAS_CHANNEL = new ResourceLocation( AppEng.MOD_ID, "part/toggle_bus_status_has_channel" ); + + public static final List MODELS_OFF = ImmutableList.of(MODEL_BASE, MODEL_STATUS_OFF); + public static final List MODELS_ON = ImmutableList.of(MODEL_BASE, MODEL_STATUS_ON); + public static final List MODELS_HAS_CHANNEL = ImmutableList.of(MODEL_BASE, MODEL_STATUS_HAS_CHANNEL); + private static final int REDSTONE_FLAG = 4; private final AENetworkProxy outerProxy = new AENetworkProxy( this, "outer", null, true ); private IGridConnection connection; @@ -72,6 +86,10 @@ public class PartToggleBus extends PartBasicState return cf | ( this.getIntention() ? REDSTONE_FLAG : 0 ); } + public boolean hasRedstoneFlag() { + return (getClientFlags() & REDSTONE_FLAG) == REDSTONE_FLAG; + } + protected boolean getIntention() { return this.getHost().hasRedstone( this.getSide() ); @@ -202,4 +220,21 @@ public class PartToggleBus extends PartBasicState { return this.outerProxy; } + + @Override + public List getStaticModels() + { + if( hasRedstoneFlag() && isActive() && isPowered() ) + { + return MODELS_HAS_CHANNEL; + } + else if( hasRedstoneFlag() && isPowered() ) + { + return MODELS_ON; + } + else + { + return MODELS_OFF; + } + } } diff --git a/src/main/java/appeng/parts/networking/PartCable.java b/src/main/java/appeng/parts/networking/PartCable.java index 3fdbcf37..da3ff53f 100644 --- a/src/main/java/appeng/parts/networking/PartCable.java +++ b/src/main/java/appeng/parts/networking/PartCable.java @@ -20,31 +20,18 @@ package appeng.parts.networking; import java.io.IOException; -import java.util.ArrayList; import java.util.EnumSet; -import java.util.Iterator; -import java.util.List; import com.google.common.collect.ImmutableSet; -import org.lwjgl.util.vector.Matrix4f; -import org.lwjgl.util.vector.Vector3f; - import io.netty.buffer.ByteBuf; -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; -import net.minecraftforge.common.model.TRSRTransformation; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; import appeng.api.AEApi; -import appeng.api.client.BakingPipeline; import appeng.api.config.SecurityPermissions; import appeng.api.definitions.IParts; import appeng.api.implementations.parts.IPartCable; @@ -53,7 +40,6 @@ import appeng.api.networking.IGridConnection; import appeng.api.networking.IGridHost; import appeng.api.networking.IGridNode; import appeng.api.parts.BusSupport; -import appeng.api.parts.ICustomCableConnection; import appeng.api.parts.IPart; import appeng.api.parts.IPartCollisionHelper; import appeng.api.parts.IPartHost; @@ -61,10 +47,6 @@ import appeng.api.util.AECableType; import appeng.api.util.AEColor; import appeng.api.util.AEPartLocation; import appeng.api.util.IReadOnlyCollection; -import appeng.client.render.model.ModelsCache; -import appeng.client.render.model.pipeline.FacingQuadRotator; -import appeng.client.render.model.pipeline.MatVecApplicator; -import appeng.client.render.model.pipeline.TypeTransformer; import appeng.items.parts.ItemMultiPart; import appeng.me.GridAccessException; import appeng.parts.AEBasePart; @@ -401,86 +383,16 @@ public class PartCable extends AEBasePart implements IPartCable return !myC.equals( this.getConnections() ) || wasPowered != this.powered || channelsChanged; } - @Override - @SideOnly( Side.CLIENT ) - public List getOrBakeQuads( BakingPipeline rotatingPipeline, IBlockState state, EnumFacing side, long rand ) - { - List elements = new ArrayList<>(); - if( isStraight( getHost(), connections ) ) - { - EnumFacing facing = getConnections().contains( AEPartLocation.DOWN ) ? EnumFacing.DOWN : getConnections().contains( AEPartLocation.NORTH ) ? EnumFacing.NORTH : getConnections().contains( AEPartLocation.EAST ) ? EnumFacing.EAST : EnumFacing.NORTH; - elements.addAll( rotatingPipeline.pipe( ModelsCache.INSTANCE.getOrLoadModel( withProperties( getCableConnectionType().getStraightModel(), propertiesForModel( facing ) ), getCableConnectionType().getStraightModel(), propertyTextureGetter( propertiesForModel( facing ) ) ).getQuads( state, side, rand ), null, state, connections.contains( AEPartLocation.DOWN ) ? EnumFacing.DOWN : connections.contains( AEPartLocation.NORTH ) ? EnumFacing.NORTH : connections.contains( AEPartLocation.EAST ) ? EnumFacing.EAST : EnumFacing.NORTH, rand ) ); - } - else - { - elements.addAll( ModelsCache.INSTANCE.getOrLoadModel( withProperties( getCableConnectionType().getModel(), propertiesForModel( null ) ), getCableConnectionType().getModel(), propertyTextureGetter( propertiesForModel( null ) ) ).getQuads( state, side, rand ) ); - for( EnumFacing facing : EnumFacing.values() ) - { - if( isConnected( facing ) || getHost().getPart( facing ) != null ) - { - float f = 4; - if( getHost().getPart( facing ) != null ) - { - f = getHost().getPart( facing ).getCableConnectionLength( this.getCableConnectionType() ); - } - else - { - TileEntity to = getHost().getTile().getWorld().getTileEntity( getHost().getTile().getPos().offset( facing ) ); - if( to instanceof ICustomCableConnection ) - { - f = ( (ICustomCableConnection) to ).getCableConnectionLength( this.getCableConnectionType() ); - } - } - if( f != -1 ) - { - elements.addAll( new BakingPipeline( TypeTransformer.quads2vecs, new MatVecApplicator( TRSRTransformation.toVecmath( new Matrix4f().scale( new Vector3f( 1, 1, f / 4f ) ) ) ), new FacingQuadRotator( facing ), TypeTransformer.vecs2quads ).pipe( ModelsCache.INSTANCE.getOrLoadModel( withProperties( getCableConnectionType().getConnectionModel(), propertiesForModel( facing ) ), getCableConnectionType().getConnectionModel(), propertyTextureGetter( propertiesForModel( facing ) ) ).getQuads( state, side, rand ), null, state, facing, rand ) ); - } - } - } - } - return elements; - } - - /** - * A cable connection is considered straight, if there are exactly two connection points on opposite sides, - * and the cable has no attached busses. - */ - protected boolean isStraight( IPartHost host, final EnumSet sides ) - { - if (sides.size() != 2) { - return false; - } - - Iterator it = sides.iterator(); - EnumFacing firstSide = it.next().getFacing(); - EnumFacing secondSide = it.next().getFacing(); - - // Not on opposite sides - if (firstSide.getOpposite() != secondSide) { - return false; - } - - // Check any other point for attachments - for( EnumFacing facing : EnumFacing.values() ) - { - if( facing != firstSide && facing != secondSide ) - { - // Check for an attached part here - if( host.getPart( facing ) != null ) - { - return false; - } - } - } - - return true; - } - int getChannelsOnSide( final int i ) { return this.channelsOnSide[i]; } + public int getChannelsOnSide( EnumFacing side ) + { + return this.channelsOnSide[side.ordinal()]; + } + void setChannelsOnSide( final int i, final int channels ) { this.channelsOnSide[i] = channels; diff --git a/src/main/java/appeng/parts/networking/PartQuartzFiber.java b/src/main/java/appeng/parts/networking/PartQuartzFiber.java index ad110aec..80b81e05 100644 --- a/src/main/java/appeng/parts/networking/PartQuartzFiber.java +++ b/src/main/java/appeng/parts/networking/PartQuartzFiber.java @@ -19,7 +19,9 @@ package appeng.parts.networking; +import java.util.Collections; import java.util.EnumSet; +import java.util.List; import java.util.Set; import net.minecraft.entity.player.EntityPlayer; @@ -27,6 +29,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; import appeng.api.config.Actionable; import appeng.api.networking.GridFlags; @@ -37,6 +40,8 @@ import appeng.api.parts.IPartCollisionHelper; import appeng.api.parts.IPartHost; import appeng.api.util.AECableType; import appeng.api.util.AEPartLocation; +import appeng.core.AppEng; +import appeng.items.parts.PartModels; import appeng.me.GridAccessException; import appeng.me.helpers.AENetworkProxy; import appeng.parts.AEBasePart; @@ -45,6 +50,9 @@ import appeng.parts.AEBasePart; public class PartQuartzFiber extends AEBasePart implements IEnergyGridProvider { + @PartModels + private static final List MODELS = Collections.singletonList( new ResourceLocation( AppEng.MOD_ID, "part/quartz_fiber" ) ); + private final AENetworkProxy outerProxy = new AENetworkProxy( this, "outer", this.getProxy().getMachineRepresentation(), true ); public PartQuartzFiber( final ItemStack is ) @@ -210,4 +218,10 @@ public class PartQuartzFiber extends AEBasePart implements IEnergyGridProvider return demand; } + + @Override + public List getStaticModels() + { + return MODELS; + } } diff --git a/src/main/java/appeng/parts/p2p/P2PModels.java b/src/main/java/appeng/parts/p2p/P2PModels.java new file mode 100644 index 00000000..8d429294 --- /dev/null +++ b/src/main/java/appeng/parts/p2p/P2PModels.java @@ -0,0 +1,60 @@ +package appeng.parts.p2p; + + +import java.util.ArrayList; +import java.util.List; + +import com.google.common.collect.ImmutableList; + +import net.minecraft.util.ResourceLocation; + +import appeng.core.AppEng; + + +/** + * Helper for maintaining the models used for a variant of the P2P bus. + */ +class P2PModels +{ + + public static final ResourceLocation MODEL_STATUS_OFF = new ResourceLocation( AppEng.MOD_ID, "part/p2p/p2p_tunnel_status_off" ); + public static final ResourceLocation MODEL_STATUS_ON = new ResourceLocation( AppEng.MOD_ID, "part/p2p/p2p_tunnel_status_on" ); + public static final ResourceLocation MODEL_STATUS_HAS_CHANNEL = new ResourceLocation( AppEng.MOD_ID, "part/p2p/p2p_tunnel_status_has_channel" ); + + private final List modelsOff; + private final List modelsOn; + private final List modelsHasChannel; + + public P2PModels( String frontModelPath ) + { + ResourceLocation frontModel = new ResourceLocation( AppEng.MOD_ID, frontModelPath ); + modelsOff = ImmutableList.of( MODEL_STATUS_OFF, frontModel ); + modelsOn = ImmutableList.of( MODEL_STATUS_ON, frontModel ); + modelsHasChannel = ImmutableList.of( MODEL_STATUS_HAS_CHANNEL, frontModel ); + } + + public List getModel( boolean hasPower, boolean hasChannel ) + { + if( hasPower && hasChannel ) + { + return modelsHasChannel; + } + else if( hasPower ) + { + return modelsOn; + } + else + { + return modelsOff; + } + } + + public List getModels() { + List result = new ArrayList<>(); + result.addAll( modelsOff ); + result.addAll( modelsOn ); + result.addAll( modelsHasChannel ); + return result; + } + +} diff --git a/src/main/java/appeng/parts/p2p/PartP2PItems.java b/src/main/java/appeng/parts/p2p/PartP2PItems.java index b97b0adb..22931993 100644 --- a/src/main/java/appeng/parts/p2p/PartP2PItems.java +++ b/src/main/java/appeng/parts/p2p/PartP2PItems.java @@ -29,6 +29,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityChest; import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.text.ITextComponent; import appeng.api.networking.IGridNode; @@ -43,6 +44,7 @@ import appeng.core.settings.TickRates; import appeng.integration.IntegrationRegistry; import appeng.integration.IntegrationType; import appeng.integration.abstraction.IBuildCraftTransport; +import appeng.items.parts.PartModels; import appeng.me.GridAccessException; import appeng.me.cache.helpers.TunnelCollection; import appeng.tile.inventory.AppEngNullInventory; @@ -57,6 +59,14 @@ import appeng.util.inv.WrapperMCISidedInventory; public class PartP2PItems extends PartP2PTunnel implements /* IPipeConnection, */ISidedInventory, IGridTickable { + private static final P2PModels MODELS = new P2PModels( "part/p2p/p2p_tunnel_items" ); + + @PartModels + public static List getModels() + { + return MODELS.getModels(); + } + private final LinkedList which = new LinkedList(); private int oldSize = 0; private boolean requested; @@ -412,4 +422,11 @@ public class PartP2PItems extends PartP2PTunnel implements /* IPip // { // return this.side == with && type == PipeType.ITEM ? ConnectOverride.CONNECT : ConnectOverride.DEFAULT; // } + + @Override + public List getStaticModels() + { + return MODELS.getModel( isPowered(), isActive() ); + } + } diff --git a/src/main/java/appeng/parts/p2p/PartP2PLight.java b/src/main/java/appeng/parts/p2p/PartP2PLight.java index afa4cc18..c2c898bd 100644 --- a/src/main/java/appeng/parts/p2p/PartP2PLight.java +++ b/src/main/java/appeng/parts/p2p/PartP2PLight.java @@ -20,12 +20,14 @@ package appeng.parts.p2p; import java.io.IOException; +import java.util.List; import io.netty.buffer.ByteBuf; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import appeng.api.networking.IGridNode; @@ -35,12 +37,21 @@ import appeng.api.networking.ticking.IGridTickable; import appeng.api.networking.ticking.TickRateModulation; import appeng.api.networking.ticking.TickingRequest; import appeng.core.settings.TickRates; +import appeng.items.parts.PartModels; import appeng.me.GridAccessException; public class PartP2PLight extends PartP2PTunnel implements IGridTickable { + private static final P2PModels MODELS = new P2PModels( "part/p2p/p2p_tunnel_light" ); + + @PartModels + public static List getModels() + { + return MODELS.getModels(); + } + private int lastValue = 0; private float opacity = -1; @@ -213,4 +224,11 @@ public class PartP2PLight extends PartP2PTunnel implements IGridTi { return 0.5f; } + + @Override + public List getStaticModels() + { + return MODELS.getModel( isPowered(), isActive() ); + } + } diff --git a/src/main/java/appeng/parts/p2p/PartP2PLiquids.java b/src/main/java/appeng/parts/p2p/PartP2PLiquids.java index 6ca1494f..37cb3140 100644 --- a/src/main/java/appeng/parts/p2p/PartP2PLiquids.java +++ b/src/main/java/appeng/parts/p2p/PartP2PLiquids.java @@ -27,17 +27,27 @@ import java.util.Stack; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTankInfo; import net.minecraftforge.fluids.IFluidHandler; +import appeng.items.parts.PartModels; import appeng.me.GridAccessException; public class PartP2PLiquids extends PartP2PTunnel implements IFluidHandler { + private static final P2PModels MODELS = new P2PModels( "part/p2p/p2p_tunnel_liquids" ); + + @PartModels + public static List getModels() + { + return MODELS.getModels(); + } + private static final ThreadLocal> DEPTH = new ThreadLocal>(); private static final FluidTankInfo[] ACTIVE_TANK = { new FluidTankInfo( null, 10000 ) }; private static final FluidTankInfo[] INACTIVE_TANK = { new FluidTankInfo( null, 0 ) }; @@ -292,4 +302,11 @@ public class PartP2PLiquids extends PartP2PTunnel implements IFl } return INACTIVE_TANK; } + + @Override + public List getStaticModels() + { + return MODELS.getModel( isPowered(), isActive() ); + } + } diff --git a/src/main/java/appeng/parts/p2p/PartP2PRedstone.java b/src/main/java/appeng/parts/p2p/PartP2PRedstone.java index b104945e..0354bf84 100644 --- a/src/main/java/appeng/parts/p2p/PartP2PRedstone.java +++ b/src/main/java/appeng/parts/p2p/PartP2PRedstone.java @@ -19,12 +19,15 @@ package appeng.parts.p2p; +import java.util.List; + import net.minecraft.block.Block; import net.minecraft.block.BlockRedstoneWire; import net.minecraft.block.state.IBlockState; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -32,6 +35,7 @@ import appeng.api.networking.events.MENetworkBootingStatusChange; import appeng.api.networking.events.MENetworkChannelsChanged; import appeng.api.networking.events.MENetworkEventSubscribe; import appeng.api.networking.events.MENetworkPowerStatusChange; +import appeng.items.parts.PartModels; import appeng.me.GridAccessException; import appeng.util.Platform; @@ -39,6 +43,14 @@ import appeng.util.Platform; public class PartP2PRedstone extends PartP2PTunnel { + private static final P2PModels MODELS = new P2PModels( "part/p2p/p2p_tunnel_redstone" ); + + @PartModels + public static List getModels() + { + return MODELS.getModels(); + } + private int power; private boolean recursive = false; @@ -195,4 +207,11 @@ public class PartP2PRedstone extends PartP2PTunnel // :P } } + + @Override + public List getStaticModels() + { + return MODELS.getModel( isPowered(), isActive() ); + } + } diff --git a/src/main/java/appeng/parts/p2p/PartP2PTunnelME.java b/src/main/java/appeng/parts/p2p/PartP2PTunnelME.java index 00b6ce40..9c84d6d8 100644 --- a/src/main/java/appeng/parts/p2p/PartP2PTunnelME.java +++ b/src/main/java/appeng/parts/p2p/PartP2PTunnelME.java @@ -22,12 +22,14 @@ package appeng.parts.p2p; import java.util.EnumSet; import java.util.Iterator; import java.util.LinkedList; +import java.util.List; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; import appeng.api.AEApi; import appeng.api.exceptions.FailedConnection; @@ -42,6 +44,7 @@ import appeng.api.util.AEPartLocation; import appeng.core.AELog; import appeng.core.settings.TickRates; import appeng.hooks.TickHandler; +import appeng.items.parts.PartModels; import appeng.me.GridAccessException; import appeng.me.cache.helpers.Connections; import appeng.me.cache.helpers.TunnelConnection; @@ -51,6 +54,14 @@ import appeng.me.helpers.AENetworkProxy; public class PartP2PTunnelME extends PartP2PTunnel implements IGridTickable { + private static final P2PModels MODELS = new P2PModels( "part/p2p/p2p_tunnel_me" ); + + @PartModels + public static List getModels() + { + return MODELS.getModels(); + } + private final Connections connection = new Connections( this ); private final AENetworkProxy outerProxy = new AENetworkProxy( this, "outer", null, true ); @@ -246,4 +257,11 @@ public class PartP2PTunnelME extends PartP2PTunnel implements I } } } + + @Override + public List getStaticModels() + { + return MODELS.getModel( isPowered(), isActive() ); + } + } diff --git a/src/main/java/appeng/parts/reporting/AbstractPartDisplay.java b/src/main/java/appeng/parts/reporting/AbstractPartDisplay.java index bf9b17f4..3fe11ade 100644 --- a/src/main/java/appeng/parts/reporting/AbstractPartDisplay.java +++ b/src/main/java/appeng/parts/reporting/AbstractPartDisplay.java @@ -20,6 +20,10 @@ package appeng.parts.reporting; import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; + +import appeng.core.AppEng; +import appeng.items.parts.PartModels; /** @@ -36,6 +40,18 @@ import net.minecraft.item.ItemStack; public abstract class AbstractPartDisplay extends AbstractPartReporting { + // The base chassis of all display parts + @PartModels + protected static final ResourceLocation MODEL_BASE = new ResourceLocation( AppEng.MOD_ID, "part/display_base" ); + + // Models that contain the status indicator light + @PartModels + protected static final ResourceLocation MODEL_STATUS_OFF = new ResourceLocation( AppEng.MOD_ID, "part/display_status_off" ); + @PartModels + protected static final ResourceLocation MODEL_STATUS_ON = new ResourceLocation( AppEng.MOD_ID, "part/display_status_on" ); + @PartModels + protected static final ResourceLocation MODEL_STATUS_HAS_CHANNEL = new ResourceLocation( AppEng.MOD_ID, "part/display_status_has_channel" ); + public AbstractPartDisplay( final ItemStack is ) { super( is, true ); diff --git a/src/main/java/appeng/parts/reporting/AbstractPartMonitor.java b/src/main/java/appeng/parts/reporting/AbstractPartMonitor.java index ae846c43..8b69676f 100644 --- a/src/main/java/appeng/parts/reporting/AbstractPartMonitor.java +++ b/src/main/java/appeng/parts/reporting/AbstractPartMonitor.java @@ -20,22 +20,21 @@ package appeng.parts.reporting; import java.io.IOException; +import java.util.List; import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL12; import io.netty.buffer.ByteBuf; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; -import net.minecraft.client.renderer.GLAllocation; -import net.minecraft.client.renderer.OpenGlHelper; -import net.minecraft.client.renderer.VertexBuffer; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.Vec3d; import net.minecraftforge.fml.relauncher.Side; @@ -52,7 +51,6 @@ import appeng.api.storage.data.IAEStack; import appeng.api.storage.data.IItemList; import appeng.api.util.AEPartLocation; import appeng.client.ClientHelper; -import appeng.core.AELog; import appeng.core.localization.PlayerMessages; import appeng.helpers.Reflected; import appeng.me.GridAccessException; @@ -80,10 +78,6 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements private String lastHumanReadableText; private boolean isLocked; private IStackWatcher myWatcher; - @SideOnly( Side.CLIENT ) - private boolean updateList; - @SideOnly( Side.CLIENT ) - private Integer dspList; @Reflected public AbstractPartMonitor( final ItemStack is ) @@ -151,8 +145,6 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements this.configuredItem = null; } - this.updateList = true; - return needRedraw; } @@ -246,34 +238,26 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements @Override @SideOnly( Side.CLIENT ) - protected void finalize() throws Throwable + public void renderDynamic( double x, double y, double z, float partialTicks, int destroyStage ) { - super.finalize(); - if( this.dspList != null ) + if( ( this.getClientFlags() & ( PartPanel.POWERED_FLAG | PartPanel.CHANNEL_FLAG ) ) != ( PartPanel.POWERED_FLAG | PartPanel.CHANNEL_FLAG ) ) { - GLAllocation.deleteDisplayLists( this.dspList ); + return; } - } - @Override - public boolean requireDynamicRender() - { - return true; - } + final IAEItemStack ais = (IAEItemStack) this.getDisplayed(); - @Override - public IAEStack getDisplayed() - { - return this.configuredItem; - } + if( ais == null ) + { + return; + } - private void tesrRenderScreen( final VertexBuffer wr, final IAEItemStack ais ) - { - // GL11.glPushAttrib( GL11.GL_ALL_ATTRIB_BITS ); + GlStateManager.pushMatrix(); + GL11.glTranslated( x + 0.5, y + 0.5, z + 0.5 ); final AEPartLocation d = this.getSide(); - GL11.glTranslated( d.xOffset * 0.77, d.yOffset * 0.77, d.zOffset * 0.77 ); + GL11.glTranslated( d.xOffset * 0.50, d.yOffset * 0.50, d.zOffset * 0.50 ); switch( d ) { @@ -312,46 +296,33 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements break; } - try - { - final ItemStack sis = ais.getItemStack(); - sis.stackSize = 1; - - final int br = 16 << 20 | 16 << 4; - final int var11 = br % 65536; - final int var12 = br / 65536; - OpenGlHelper.setLightmapTextureCoords( OpenGlHelper.lightmapTexUnit, var11 * 0.8F, var12 * 0.8F ); - - GL11.glColor4f( 1.0F, 1.0F, 1.0F, 1.0F ); - - GL11.glDisable( GL11.GL_LIGHTING ); - GL11.glDisable( GL12.GL_RESCALE_NORMAL ); - // RenderHelper.enableGUIStandardItemLighting(); - - ClientHelper.proxy.doRenderItem( sis, this.getTile().getWorld() ); - } - catch( final Exception e ) - { - AELog.debug( e ); - } - finally - { - GL11.glEnable( GL11.GL_LIGHTING ); - GL11.glEnable( GL12.GL_RESCALE_NORMAL ); - } - - GL11.glTranslatef( 0.0f, 0.14f, -0.24f ); - GL11.glScalef( 1.0f / 62.0f, 1.0f / 62.0f, 1.0f / 62.0f ); + ClientHelper.proxy.doRenderItem( ais.getItemStack() ); final long stackSize = ais.getStackSize(); final String renderedStackSize = NUMBER_CONVERTER.toWideReadableForm( stackSize ); + // Render the item count final FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; final int width = fr.getStringWidth( renderedStackSize ); - GL11.glTranslatef( -0.5f * width, 0.0f, -1.0f ); + GL11.glTranslatef( 0.0f, 0.17f, 0 ); + GL11.glScalef( 1.0f / 62.0f, 1.0f / 62.0f, 1.0f / 62.0f ); + GL11.glTranslatef( -0.5f * width, 0.0f, 0.5f ); fr.drawString( renderedStackSize, 0, 0, 0 ); - // GL11.glPopAttrib(); + GlStateManager.popMatrix(); + + } + + @Override + public boolean requireDynamicRender() + { + return true; + } + + @Override + public IAEStack getDisplayed() + { + return this.configuredItem; } @Override @@ -397,4 +368,42 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements { return false; } + + protected List selectModel(List off, List on, List hasChannel, + List lockedOff, List lockedOn, List lockedHasChannel) { + if( isActive() ) + { + if( isLocked() ) + { + return lockedHasChannel; + } + else + { + return hasChannel; + } + } + else if( isPowered() ) + { + if( isLocked() ) + { + return lockedOn; + } + else + { + return on; + } + } + else + { + if( isLocked() ) + { + return lockedOff; + } + else + { + return off; + } + } + } + } diff --git a/src/main/java/appeng/parts/reporting/AbstractPartPanel.java b/src/main/java/appeng/parts/reporting/AbstractPartPanel.java index 9cb1887e..01e75859 100644 --- a/src/main/java/appeng/parts/reporting/AbstractPartPanel.java +++ b/src/main/java/appeng/parts/reporting/AbstractPartPanel.java @@ -20,8 +20,11 @@ package appeng.parts.reporting; import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; import appeng.api.util.AEColor; +import appeng.core.AppEng; +import appeng.items.parts.PartModels; /** @@ -36,6 +39,10 @@ import appeng.api.util.AEColor; */ public abstract class AbstractPartPanel extends AbstractPartReporting { + + @PartModels + public static final ResourceLocation MODEL_BASE = new ResourceLocation( AppEng.MOD_ID, "part/monitor_base" ); + public AbstractPartPanel( final ItemStack is ) { super( is, false ); diff --git a/src/main/java/appeng/parts/reporting/AbstractPartReporting.java b/src/main/java/appeng/parts/reporting/AbstractPartReporting.java index 4f1829f0..bb6568b0 100644 --- a/src/main/java/appeng/parts/reporting/AbstractPartReporting.java +++ b/src/main/java/appeng/parts/reporting/AbstractPartReporting.java @@ -20,6 +20,7 @@ package appeng.parts.reporting; import java.io.IOException; +import java.util.List; import io.netty.buffer.ByteBuf; @@ -28,6 +29,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; @@ -289,6 +291,22 @@ public abstract class AbstractPartReporting extends AEBasePart implements IPartM } } + protected List selectModel( List offModels, List onModels, List hasChannelModels ) + { + if( isActive() ) + { + return hasChannelModels; + } + else if( isPowered() ) + { + return onModels; + } + else + { + return offModels; + } + } + public final int getClientFlags() { return this.clientFlags; diff --git a/src/main/java/appeng/parts/reporting/PartConversionMonitor.java b/src/main/java/appeng/parts/reporting/PartConversionMonitor.java index f89b5d62..15b137d5 100644 --- a/src/main/java/appeng/parts/reporting/PartConversionMonitor.java +++ b/src/main/java/appeng/parts/reporting/PartConversionMonitor.java @@ -22,18 +22,23 @@ package appeng.parts.reporting; import java.util.Collections; import java.util.List; +import com.google.common.collect.ImmutableList; + import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.Vec3d; import appeng.api.networking.energy.IEnergySource; import appeng.api.networking.security.PlayerSource; import appeng.api.storage.IMEMonitor; import appeng.api.storage.data.IAEItemStack; +import appeng.core.AppEng; import appeng.helpers.Reflected; +import appeng.items.parts.PartModels; import appeng.me.GridAccessException; import appeng.util.InventoryAdaptor; import appeng.util.Platform; @@ -42,6 +47,23 @@ import appeng.util.item.AEItemStack; public class PartConversionMonitor extends AbstractPartMonitor { + + @PartModels + public static final ResourceLocation MODEL_OFF = new ResourceLocation( AppEng.MOD_ID, "part/conversion_monitor_off" ); + @PartModels + public static final ResourceLocation MODEL_ON = new ResourceLocation( AppEng.MOD_ID, "part/conversion_monitor_on" ); + @PartModels + public static final ResourceLocation MODEL_LOCKED_OFF = new ResourceLocation( AppEng.MOD_ID, "part/conversion_monitor_locked_off" ); + @PartModels + public static final ResourceLocation MODEL_LOCKED_ON = new ResourceLocation( AppEng.MOD_ID, "part/conversion_monitor_locked_on" ); + + public static final List MODELS_OFF = ImmutableList.of( MODEL_BASE, MODEL_OFF, MODEL_STATUS_OFF ); + public static final List MODELS_ON = ImmutableList.of( MODEL_BASE, MODEL_ON, MODEL_STATUS_ON ); + public static final List MODELS_HAS_CHANNEL = ImmutableList.of( MODEL_BASE, MODEL_ON, MODEL_STATUS_HAS_CHANNEL ); + public static final List MODELS_LOCKED_OFF = ImmutableList.of( MODEL_BASE, MODEL_LOCKED_OFF, MODEL_STATUS_OFF ); + public static final List MODELS_LOCKED_ON = ImmutableList.of( MODEL_BASE, MODEL_LOCKED_ON, MODEL_STATUS_ON ); + public static final List MODELS_LOCKED_HAS_CHANNEL = ImmutableList.of( MODEL_BASE, MODEL_LOCKED_ON, MODEL_STATUS_HAS_CHANNEL ); + @Reflected public PartConversionMonitor( final ItemStack is ) { @@ -160,4 +182,12 @@ public class PartConversionMonitor extends AbstractPartMonitor } } } + + @Override + public List getStaticModels() + { + return selectModel( MODELS_OFF, MODELS_ON, MODELS_HAS_CHANNEL, + MODELS_LOCKED_OFF, MODELS_LOCKED_ON, MODELS_LOCKED_HAS_CHANNEL ); + } + } diff --git a/src/main/java/appeng/parts/reporting/PartCraftingTerminal.java b/src/main/java/appeng/parts/reporting/PartCraftingTerminal.java index 9ba778f7..866ca039 100644 --- a/src/main/java/appeng/parts/reporting/PartCraftingTerminal.java +++ b/src/main/java/appeng/parts/reporting/PartCraftingTerminal.java @@ -21,18 +21,33 @@ package appeng.parts.reporting; import java.util.List; +import com.google.common.collect.ImmutableList; + import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ResourceLocation; +import appeng.core.AppEng; import appeng.core.sync.GuiBridge; import appeng.helpers.Reflected; +import appeng.items.parts.PartModels; import appeng.tile.inventory.AppEngInternalInventory; public class PartCraftingTerminal extends AbstractPartTerminal { + + @PartModels + public static final ResourceLocation MODEL_OFF = new ResourceLocation( AppEng.MOD_ID, "part/terminal_off" ); + @PartModels + public static final ResourceLocation MODEL_ON = new ResourceLocation( AppEng.MOD_ID, "part/terminal_on" ); + + public static final List MODELS_OFF = ImmutableList.of( MODEL_BASE, MODEL_OFF, MODEL_STATUS_OFF ); + public static final List MODELS_ON = ImmutableList.of( MODEL_BASE, MODEL_ON, MODEL_STATUS_ON ); + public static final List MODELS_HAS_CHANNEL = ImmutableList.of( MODEL_BASE, MODEL_ON, MODEL_STATUS_HAS_CHANNEL ); + private final AppEngInternalInventory craftingGrid = new AppEngInternalInventory( this, 9 ); @Reflected @@ -98,4 +113,11 @@ public class PartCraftingTerminal extends AbstractPartTerminal } return super.getInventoryByName( name ); } + + @Override + public List getStaticModels() + { + return selectModel( MODELS_OFF, MODELS_ON, MODELS_HAS_CHANNEL ); + } + } diff --git a/src/main/java/appeng/parts/reporting/PartDarkPanel.java b/src/main/java/appeng/parts/reporting/PartDarkPanel.java index d5291240..00928b14 100644 --- a/src/main/java/appeng/parts/reporting/PartDarkPanel.java +++ b/src/main/java/appeng/parts/reporting/PartDarkPanel.java @@ -19,14 +19,29 @@ package appeng.parts.reporting; -import net.minecraft.item.ItemStack; +import java.util.List; +import com.google.common.collect.ImmutableList; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; + +import appeng.core.AppEng; import appeng.helpers.Reflected; +import appeng.items.parts.PartModels; public class PartDarkPanel extends AbstractPartPanel { + @PartModels + public static final ResourceLocation MODEL_OFF = new ResourceLocation( AppEng.MOD_ID, "part/monitor_dark_off" ); + @PartModels + public static final ResourceLocation MODEL_ON = new ResourceLocation( AppEng.MOD_ID, "part/monitor_dark_on" ); + + public static final List MODELS_OFF = ImmutableList.of( MODEL_BASE, MODEL_OFF ); + public static final List MODELS_ON = ImmutableList.of( MODEL_BASE, MODEL_ON ); + @Reflected public PartDarkPanel( final ItemStack is ) { @@ -38,4 +53,11 @@ public class PartDarkPanel extends AbstractPartPanel { return this.getColor().mediumVariant; } + + @Override + public List getStaticModels() + { + return isPowered() ? MODELS_ON : MODELS_OFF; + } + } diff --git a/src/main/java/appeng/parts/reporting/PartInterfaceTerminal.java b/src/main/java/appeng/parts/reporting/PartInterfaceTerminal.java index e7786372..c5eb48fa 100644 --- a/src/main/java/appeng/parts/reporting/PartInterfaceTerminal.java +++ b/src/main/java/appeng/parts/reporting/PartInterfaceTerminal.java @@ -19,17 +19,34 @@ package appeng.parts.reporting; +import java.util.List; + +import com.google.common.collect.ImmutableList; + import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.Vec3d; +import appeng.core.AppEng; import appeng.core.sync.GuiBridge; +import appeng.items.parts.PartModels; import appeng.util.Platform; public class PartInterfaceTerminal extends AbstractPartDisplay { + + @PartModels + public static final ResourceLocation MODEL_OFF = new ResourceLocation( AppEng.MOD_ID, "part/interface_terminal_off" ); + @PartModels + public static final ResourceLocation MODEL_ON = new ResourceLocation( AppEng.MOD_ID, "part/interface_terminal_on" ); + + public static final List MODELS_OFF = ImmutableList.of( MODEL_BASE, MODEL_OFF, MODEL_STATUS_OFF ); + public static final List MODELS_ON = ImmutableList.of( MODEL_BASE, MODEL_ON, MODEL_STATUS_ON ); + public static final List MODELS_HAS_CHANNEL = ImmutableList.of( MODEL_BASE, MODEL_ON, MODEL_STATUS_HAS_CHANNEL ); + public PartInterfaceTerminal( final ItemStack is ) { super( is ); @@ -55,4 +72,11 @@ public class PartInterfaceTerminal extends AbstractPartDisplay return false; } + + @Override + public List getStaticModels() + { + return selectModel( MODELS_OFF, MODELS_ON, MODELS_HAS_CHANNEL ); + } + } diff --git a/src/main/java/appeng/parts/reporting/PartPanel.java b/src/main/java/appeng/parts/reporting/PartPanel.java index 073ae6da..6ee453de 100644 --- a/src/main/java/appeng/parts/reporting/PartPanel.java +++ b/src/main/java/appeng/parts/reporting/PartPanel.java @@ -19,14 +19,29 @@ package appeng.parts.reporting; -import net.minecraft.item.ItemStack; +import java.util.List; +import com.google.common.collect.ImmutableList; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; + +import appeng.core.AppEng; import appeng.helpers.Reflected; +import appeng.items.parts.PartModels; public class PartPanel extends AbstractPartPanel { + @PartModels + public static final ResourceLocation MODEL_OFF = new ResourceLocation( AppEng.MOD_ID, "part/monitor_bright_off" ); + @PartModels + public static final ResourceLocation MODEL_ON = new ResourceLocation( AppEng.MOD_ID, "part/monitor_bright_on" ); + + public static final List MODELS_OFF = ImmutableList.of( MODEL_BASE, MODEL_OFF ); + public static final List MODELS_ON = ImmutableList.of( MODEL_BASE, MODEL_ON ); + @Reflected public PartPanel( final ItemStack is ) { @@ -39,4 +54,10 @@ public class PartPanel extends AbstractPartPanel return this.getColor().whiteVariant; } + @Override + public List getStaticModels() + { + return isPowered() ? MODELS_ON : MODELS_OFF; + } + } diff --git a/src/main/java/appeng/parts/reporting/PartPatternTerminal.java b/src/main/java/appeng/parts/reporting/PartPatternTerminal.java index 9a97def4..b7a2d541 100644 --- a/src/main/java/appeng/parts/reporting/PartPatternTerminal.java +++ b/src/main/java/appeng/parts/reporting/PartPatternTerminal.java @@ -21,22 +21,37 @@ package appeng.parts.reporting; import java.util.List; +import com.google.common.collect.ImmutableList; + import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ResourceLocation; import appeng.api.implementations.ICraftingPatternItem; import appeng.api.networking.crafting.ICraftingPatternDetails; import appeng.api.storage.data.IAEItemStack; +import appeng.core.AppEng; import appeng.core.sync.GuiBridge; import appeng.helpers.Reflected; +import appeng.items.parts.PartModels; import appeng.tile.inventory.AppEngInternalInventory; import appeng.tile.inventory.InvOperation; public class PartPatternTerminal extends AbstractPartTerminal { + + @PartModels + public static final ResourceLocation MODEL_OFF = new ResourceLocation( AppEng.MOD_ID, "part/pattern_terminal_off" ); + @PartModels + public static final ResourceLocation MODEL_ON = new ResourceLocation( AppEng.MOD_ID, "part/pattern_terminal_on" ); + + public static final List MODELS_OFF = ImmutableList.of( MODEL_BASE, MODEL_OFF, MODEL_STATUS_OFF ); + public static final List MODELS_ON = ImmutableList.of( MODEL_BASE, MODEL_ON, MODEL_STATUS_ON ); + public static final List MODELS_HAS_CHANNEL = ImmutableList.of( MODEL_BASE, MODEL_ON, MODEL_STATUS_HAS_CHANNEL ); + private final AppEngInternalInventory crafting = new AppEngInternalInventory( this, 9 ); private final AppEngInternalInventory output = new AppEngInternalInventory( this, 3 ); private final AppEngInternalInventory pattern = new AppEngInternalInventory( this, 2 ); @@ -197,4 +212,10 @@ public class PartPatternTerminal extends AbstractPartTerminal return super.getInventoryByName( name ); } + + @Override + public List getStaticModels() + { + return selectModel( MODELS_OFF, MODELS_ON, MODELS_HAS_CHANNEL ); + } } diff --git a/src/main/java/appeng/parts/reporting/PartSemiDarkPanel.java b/src/main/java/appeng/parts/reporting/PartSemiDarkPanel.java index 6ba84edd..f47fda28 100644 --- a/src/main/java/appeng/parts/reporting/PartSemiDarkPanel.java +++ b/src/main/java/appeng/parts/reporting/PartSemiDarkPanel.java @@ -19,13 +19,27 @@ package appeng.parts.reporting; -import net.minecraft.item.ItemStack; +import java.util.List; +import com.google.common.collect.ImmutableList; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; + +import appeng.core.AppEng; import appeng.helpers.Reflected; +import appeng.items.parts.PartModels; public class PartSemiDarkPanel extends AbstractPartPanel { + @PartModels + public static final ResourceLocation MODEL_OFF = new ResourceLocation( AppEng.MOD_ID, "part/monitor_medium_off" ); + @PartModels + public static final ResourceLocation MODEL_ON = new ResourceLocation( AppEng.MOD_ID, "part/monitor_medium_on" ); + + public static final List MODELS_OFF = ImmutableList.of( MODEL_BASE, MODEL_OFF ); + public static final List MODELS_ON = ImmutableList.of( MODEL_BASE, MODEL_ON ); @Reflected public PartSemiDarkPanel( final ItemStack is ) @@ -40,4 +54,11 @@ public class PartSemiDarkPanel extends AbstractPartPanel final int dark = this.getColor().mediumVariant; return ( ( ( ( ( light >> 16 ) & 0xff ) + ( ( dark >> 16 ) & 0xff ) ) / 2 ) << 16 ) | ( ( ( ( ( light >> 8 ) & 0xff ) + ( ( dark >> 8 ) & 0xff ) ) / 2 ) << 8 ) | ( ( ( ( light ) & 0xff ) + ( ( dark ) & 0xff ) ) / 2 ); } + + @Override + public List getStaticModels() + { + return isPowered() ? MODELS_ON : MODELS_OFF; + } + } diff --git a/src/main/java/appeng/parts/reporting/PartStorageMonitor.java b/src/main/java/appeng/parts/reporting/PartStorageMonitor.java index 4bdcf408..570a45a0 100644 --- a/src/main/java/appeng/parts/reporting/PartStorageMonitor.java +++ b/src/main/java/appeng/parts/reporting/PartStorageMonitor.java @@ -19,9 +19,16 @@ package appeng.parts.reporting; -import net.minecraft.item.ItemStack; +import java.util.List; +import com.google.common.collect.ImmutableList; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; + +import appeng.core.AppEng; import appeng.helpers.Reflected; +import appeng.items.parts.PartModels; /** @@ -33,9 +40,33 @@ import appeng.helpers.Reflected; public class PartStorageMonitor extends AbstractPartMonitor { + @PartModels + public static final ResourceLocation MODEL_OFF = new ResourceLocation( AppEng.MOD_ID, "part/storage_monitor_off" ); + @PartModels + public static final ResourceLocation MODEL_ON = new ResourceLocation( AppEng.MOD_ID, "part/storage_monitor_on" ); + @PartModels + public static final ResourceLocation MODEL_LOCKED_OFF = new ResourceLocation( AppEng.MOD_ID, "part/storage_monitor_locked_off" ); + @PartModels + public static final ResourceLocation MODEL_LOCKED_ON = new ResourceLocation( AppEng.MOD_ID, "part/storage_monitor_locked_on" ); + + public static final List MODELS_OFF = ImmutableList.of( MODEL_BASE, MODEL_OFF, MODEL_STATUS_OFF ); + public static final List MODELS_ON = ImmutableList.of( MODEL_BASE, MODEL_ON, MODEL_STATUS_ON ); + public static final List MODELS_HAS_CHANNEL = ImmutableList.of( MODEL_BASE, MODEL_ON, MODEL_STATUS_HAS_CHANNEL ); + + public static final List MODELS_LOCKED_OFF = ImmutableList.of( MODEL_BASE, MODEL_LOCKED_OFF, MODEL_STATUS_OFF ); + public static final List MODELS_LOCKED_ON = ImmutableList.of( MODEL_BASE, MODEL_LOCKED_ON, MODEL_STATUS_ON ); + public static final List MODELS_LOCKED_HAS_CHANNEL = ImmutableList.of( MODEL_BASE, MODEL_LOCKED_ON, MODEL_STATUS_HAS_CHANNEL ); + @Reflected public PartStorageMonitor( final ItemStack is ) { super( is ); } + + @Override + public List getStaticModels() + { + return selectModel( MODELS_OFF, MODELS_ON, MODELS_HAS_CHANNEL, + MODELS_LOCKED_OFF, MODELS_LOCKED_ON, MODELS_LOCKED_HAS_CHANNEL ); + } } diff --git a/src/main/java/appeng/parts/reporting/PartTerminal.java b/src/main/java/appeng/parts/reporting/PartTerminal.java index 83775b52..471d73f8 100644 --- a/src/main/java/appeng/parts/reporting/PartTerminal.java +++ b/src/main/java/appeng/parts/reporting/PartTerminal.java @@ -19,14 +19,37 @@ package appeng.parts.reporting; +import java.util.List; + +import com.google.common.collect.ImmutableList; + import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; + +import appeng.core.AppEng; +import appeng.items.parts.PartModels; public class PartTerminal extends AbstractPartTerminal { + @PartModels + public static final ResourceLocation MODEL_OFF = new ResourceLocation( AppEng.MOD_ID, "part/crafting_terminal_off" ); + @PartModels + public static final ResourceLocation MODEL_ON = new ResourceLocation( AppEng.MOD_ID, "part/crafting_terminal_on" ); + + public static final List MODELS_OFF = ImmutableList.of( MODEL_BASE, MODEL_OFF, MODEL_STATUS_OFF ); + public static final List MODELS_ON = ImmutableList.of( MODEL_BASE, MODEL_ON, MODEL_STATUS_ON ); + public static final List MODELS_HAS_CHANNEL = ImmutableList.of( MODEL_BASE, MODEL_ON, MODEL_STATUS_HAS_CHANNEL ); + public PartTerminal( final ItemStack is ) { super( is ); } + + @Override + public List getStaticModels() + { + return selectModel( MODELS_OFF, MODELS_ON, MODELS_HAS_CHANNEL ); + } } diff --git a/src/main/java/appeng/server/ServerHelper.java b/src/main/java/appeng/server/ServerHelper.java index ff419faf..55ee2c62 100644 --- a/src/main/java/appeng/server/ServerHelper.java +++ b/src/main/java/appeng/server/ServerHelper.java @@ -135,7 +135,7 @@ public class ServerHelper extends CommonHelper } @Override - public void doRenderItem( final ItemStack sis, final World tile ) + public void doRenderItem( final ItemStack sis ) { } diff --git a/src/main/java/appeng/tile/networking/CableBusTESR.java b/src/main/java/appeng/tile/networking/CableBusTESR.java new file mode 100644 index 00000000..ed1ee471 --- /dev/null +++ b/src/main/java/appeng/tile/networking/CableBusTESR.java @@ -0,0 +1,34 @@ +package appeng.tile.networking; + + +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.util.EnumFacing; + +import appeng.api.parts.IPart; +import appeng.tile.AEBaseTile; + + +public class CableBusTESR extends TileEntitySpecialRenderer +{ + + @Override + public void renderTileEntityAt( AEBaseTile te, double x, double y, double z, float partialTicks, int destroyStage ) + { + + if( !( te instanceof TileCableBusTESR ) ) + { + return; + } + + TileCableBusTESR realTe = (TileCableBusTESR) te; + + for( EnumFacing facing : EnumFacing.values() ) + { + IPart part = realTe.getPart( facing ); + if( part != null && part.requireDynamicRender() ) + { + part.renderDynamic( x, y, z, partialTicks, destroyStage ); + } + } + } +} diff --git a/src/main/java/appeng/tile/networking/TileCableBus.java b/src/main/java/appeng/tile/networking/TileCableBus.java index 77823edc..686aeefe 100644 --- a/src/main/java/appeng/tile/networking/TileCableBus.java +++ b/src/main/java/appeng/tile/networking/TileCableBus.java @@ -45,6 +45,7 @@ import appeng.api.util.AECableType; import appeng.api.util.AEColor; import appeng.api.util.AEPartLocation; import appeng.api.util.DimensionalCoord; +import appeng.block.networking.BlockCableBus; import appeng.helpers.AEMultiTile; import appeng.helpers.ICustomCollision; import appeng.hooks.TickHandler; @@ -89,9 +90,30 @@ public class TileCableBus extends AEBaseTile implements AEMultiTile, ICustomColl this.worldObj.checkLight( this.pos ); } + this.updateTileSetting(); return ret; } + /** + * Changes this tile to the TESR version if any of the parts require dynamic rendering. + */ + protected void updateTileSetting() + { + if( this.getCableBus().isRequiresDynamicRender() ) + { + try + { + final TileCableBus tcb = (TileCableBus) BlockCableBus.getTesrTile().newInstance(); + tcb.copyFrom( this ); + this.getWorld().setTileEntity( pos, tcb ); + } + catch( final Throwable ignored ) + { + + } + } + } + protected void copyFrom( final TileCableBus oldTile ) { final CableBusContainer tmpCB = this.getCableBus(); diff --git a/src/main/java/appeng/tile/networking/TileCableBusTESR.java b/src/main/java/appeng/tile/networking/TileCableBusTESR.java new file mode 100644 index 00000000..c6b5cca2 --- /dev/null +++ b/src/main/java/appeng/tile/networking/TileCableBusTESR.java @@ -0,0 +1,30 @@ +package appeng.tile.networking; + + +import appeng.block.networking.BlockCableBus; + + +public class TileCableBusTESR extends TileCableBus +{ + + /** + * Changes this tile to the non-TESR version, if none of the parts require dynamic rendering. + */ + @Override + protected void updateTileSetting() + { + if( !this.getCableBus().isRequiresDynamicRender() ) + { + try + { + final TileCableBus tcb = (TileCableBus) BlockCableBus.getNoTesrTile().newInstance(); + tcb.copyFrom( this ); + this.getWorld().setTileEntity( pos, tcb ); + } + catch( final Throwable ignored ) + { + + } + } + } +} diff --git a/src/main/java/appeng/util/item/AEItemStack.java b/src/main/java/appeng/util/item/AEItemStack.java index 06d830df..c58b440e 100644 --- a/src/main/java/appeng/util/item/AEItemStack.java +++ b/src/main/java/appeng/util/item/AEItemStack.java @@ -26,7 +26,6 @@ import java.io.DataOutputStream; import java.io.IOException; import java.security.InvalidParameterException; import java.util.List; - import javax.annotation.Nullable; import io.netty.buffer.ByteBuf; @@ -153,7 +152,9 @@ public final class AEItemStack extends AEStack implements IAEItemS // don't send this... final NBTTagCompound d = new NBTTagCompound(); - d.setShort( "id", data.readShort() ); + // For some insane reason, Vanilla can only parse numeric item ids if they are strings + short itemNumericId = data.readShort(); + d.setString( "id", String.valueOf( itemNumericId ) ); d.setShort( "Damage", data.readShort() ); d.setByte( "Count", (byte) 0 ); @@ -217,7 +218,9 @@ public final class AEItemStack extends AEStack implements IAEItemS /* * if ( id != null && id instanceof NBTTagShort ) ((NBTTagShort) id).data = (short) this.def.item.itemID; else */ - i.setShort( "id", (short) Item.REGISTRY.getIDForObject( this.getDefinition().getItem() ) ); + // i.setShort( "id", (short) Item.REGISTRY.getIDForObject( this.getDefinition().getItem() ) ); + ResourceLocation resourcelocation = Item.REGISTRY.getNameForObject( this.getItem() ); + i.setString( "id", resourcelocation == null ? "minecraft:air" : resourcelocation.toString() ); /* * if ( Count != null && Count instanceof NBTTagByte ) ((NBTTagByte) Count).data = (byte) 0; else diff --git a/src/main/resources/assets/appliedenergistics2/blockstates/cable_bus.json b/src/main/resources/assets/appliedenergistics2/blockstates/cable_bus.json new file mode 100644 index 00000000..210b5a4d --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/blockstates/cable_bus.json @@ -0,0 +1,5 @@ +{ + "variants": { + "normal": { "model": "appliedenergistics2:builtin/cable_bus" } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/block/chest/lights_off.json b/src/main/resources/assets/appliedenergistics2/models/block/chest/lights_off.json index ed2c7dd5..c9b3490e 100644 --- a/src/main/resources/assets/appliedenergistics2/models/block/chest/lights_off.json +++ b/src/main/resources/assets/appliedenergistics2/models/block/chest/lights_off.json @@ -7,7 +7,7 @@ "from": [0, 0, 0], "to": [16, 16, 16], "faces": { - "up": { "texture": "#lights", "tintindex": 0 } + "up": { "texture": "#lights", "tintindex": 3 } } } ] diff --git a/src/main/resources/assets/appliedenergistics2/models/block/chest/lights_on.json b/src/main/resources/assets/appliedenergistics2/models/block/chest/lights_on.json index 8f88855a..c2955f1e 100644 --- a/src/main/resources/assets/appliedenergistics2/models/block/chest/lights_on.json +++ b/src/main/resources/assets/appliedenergistics2/models/block/chest/lights_on.json @@ -10,21 +10,21 @@ "from": [0, 0, 0], "to": [16, 16, 16], "faces": { - "up": {"texture": "#lights_bright", "tintindex": 0, "uvlightmap": { "block": 0.007, "sky": 0.007 }} + "up": {"texture": "#lights_bright", "tintindex": 3, "uvlightmap": { "block": 0.007, "sky": 0.007 }} } }, { "from": [0, 0, 0], "to": [16, 16, 16], "faces": { - "up": {"texture": "#lights_medium", "tintindex": 1, "uvlightmap": { "block": 0.007, "sky": 0.007 }} + "up": {"texture": "#lights_medium", "tintindex": 2, "uvlightmap": { "block": 0.007, "sky": 0.007 }} } }, { "from": [0, 0, 0], "to": [16, 16, 16], "faces": { - "up": {"texture": "#lights_dark", "tintindex": 2, "uvlightmap": { "block": 0.007, "sky": 0.007 }} + "up": {"texture": "#lights_dark", "tintindex": 1, "uvlightmap": { "block": 0.007, "sky": 0.007 }} } } ] diff --git a/src/main/resources/assets/appliedenergistics2/models/block/security_station_off.json b/src/main/resources/assets/appliedenergistics2/models/block/security_station_off.json index 19c02a10..bd552b82 100644 --- a/src/main/resources/assets/appliedenergistics2/models/block/security_station_off.json +++ b/src/main/resources/assets/appliedenergistics2/models/block/security_station_off.json @@ -26,21 +26,21 @@ "from": [ 0, 15, 0 ], "to": [ 16, 16, 16 ], "faces": { - "up": { "texture": "#lightsBright", "tintindex": 0 } + "up": { "texture": "#lightsBright", "tintindex": 3 } } }, { "from": [ 0, 15, 0 ], "to": [ 16, 16, 16 ], "faces": { - "up": { "texture": "#lightsMedium", "tintindex": 1 } + "up": { "texture": "#lightsMedium", "tintindex": 2 } } }, { "from": [ 0, 15, 0 ], "to": [ 16, 16, 16 ], "faces": { - "up": { "texture": "#lightsDark", "tintindex": 2 } + "up": { "texture": "#lightsDark", "tintindex": 1 } } } ] diff --git a/src/main/resources/assets/appliedenergistics2/models/block/security_station_on.json b/src/main/resources/assets/appliedenergistics2/models/block/security_station_on.json index 0a3c1406..e0efd79a 100644 --- a/src/main/resources/assets/appliedenergistics2/models/block/security_station_on.json +++ b/src/main/resources/assets/appliedenergistics2/models/block/security_station_on.json @@ -27,21 +27,21 @@ "from": [ 0, 15, 0 ], "to": [ 16, 16, 16 ], "faces": { - "up": { "texture": "#lightsBright", "tintindex": 0, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + "up": { "texture": "#lightsBright", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } } } }, { "from": [ 0, 15, 0 ], "to": [ 16, 16, 16 ], "faces": { - "up": { "texture": "#lightsMedium", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + "up": { "texture": "#lightsMedium", "tintindex": 2, "uvlightmap": { "sky": 0.007, "block": 0.007 } } } }, { "from": [ 0, 15, 0 ], "to": [ 16, 16, 16 ], "faces": { - "up": { "texture": "#lightsDark", "tintindex": 2, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + "up": { "texture": "#lightsDark", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } } } } ] diff --git a/src/main/resources/assets/appliedenergistics2/models/item/part/cable_covered_lightgray.json b/src/main/resources/assets/appliedenergistics2/models/item/part/cable_covered_lightgray.json index 27800ef3..dbc9a6f2 100644 --- a/src/main/resources/assets/appliedenergistics2/models/item/part/cable_covered_lightgray.json +++ b/src/main/resources/assets/appliedenergistics2/models/item/part/cable_covered_lightgray.json @@ -1,6 +1,6 @@ { "parent": "appliedenergistics2:item/part/cable_covered_base", "textures": { - "base": "appliedenergistics2:parts/cable/covered/lightgrey" + "base": "appliedenergistics2:parts/cable/covered/lightgray" } } \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/item/part/cable_dense_lightgray.json b/src/main/resources/assets/appliedenergistics2/models/item/part/cable_dense_lightgray.json index 2ed75e35..364c49ed 100644 --- a/src/main/resources/assets/appliedenergistics2/models/item/part/cable_dense_lightgray.json +++ b/src/main/resources/assets/appliedenergistics2/models/item/part/cable_dense_lightgray.json @@ -1,6 +1,6 @@ { "parent": "appliedenergistics2:item/part/cable_dense_base", "textures": { - "base": "appliedenergistics2:parts/cable/dense/lightgrey" + "base": "appliedenergistics2:parts/cable/dense/lightgray" } } \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/item/part/cable_glass_lightgray.json b/src/main/resources/assets/appliedenergistics2/models/item/part/cable_glass_lightgray.json index 8eefc4da..fcc8e5e2 100644 --- a/src/main/resources/assets/appliedenergistics2/models/item/part/cable_glass_lightgray.json +++ b/src/main/resources/assets/appliedenergistics2/models/item/part/cable_glass_lightgray.json @@ -1,6 +1,6 @@ { "parent": "appliedenergistics2:item/part/cable_glass_base", "textures": { - "base": "appliedenergistics2:parts/cable/glass/lightgrey" + "base": "appliedenergistics2:parts/cable/glass/lightgray" } } \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/item/part/cable_smart_base.json b/src/main/resources/assets/appliedenergistics2/models/item/part/cable_smart_base.json index bc14502f..545c0d4b 100644 --- a/src/main/resources/assets/appliedenergistics2/models/item/part/cable_smart_base.json +++ b/src/main/resources/assets/appliedenergistics2/models/item/part/cable_smart_base.json @@ -1,7 +1,8 @@ { "parent": "appliedenergistics2:item/part/part", "textures": { - "channels": "appliedenergistics2:parts/cable/smart/0" + "channelsOdd": "appliedenergistics2:parts/cable/smart/channels_00", + "channelsEven": "appliedenergistics2:parts/cable/smart/channels_10" }, "elements": [ { @@ -18,16 +19,29 @@ } }, { - "name": "Channels", + "name": "Channels Odd", "from": [ 5.0, 5.0, 2.0 ], "to": [ 11.0, 11.0, 14.0 ], "faces": { - "north": { "texture": "#channels", "uv": [ 5.0, 5.0, 11.0, 11.0 ] }, - "east": { "texture": "#channels", "uv": [ 0.0, 5.0, 5.0, 11.0 ] }, - "south": { "texture": "#channels", "uv": [ 11.0, 5.0, 5.0, 11.0 ] }, - "west": { "texture": "#channels", "uv": [ 5.0, 5.0, 0.0, 11.0 ] }, - "up": { "texture": "#channels", "uv": [ 5.0, 0.0, 11.0, 5.0 ] }, - "down": { "texture": "#channels", "uv": [ 5.0, 11.0, 11.0, 16.0 ] } + "north": { "texture": "#channelsOdd", "uv": [ 5.0, 5.0, 11.0, 11.0 ] }, + "east": { "texture": "#channelsOdd", "uv": [ 0.0, 5.0, 5.0, 11.0 ] }, + "south": { "texture": "#channelsOdd", "uv": [ 11.0, 5.0, 5.0, 11.0 ] }, + "west": { "texture": "#channelsOdd", "uv": [ 5.0, 5.0, 0.0, 11.0 ] }, + "up": { "texture": "#channelsOdd", "uv": [ 5.0, 0.0, 11.0, 5.0 ] }, + "down": { "texture": "#channelsOdd", "uv": [ 5.0, 11.0, 11.0, 16.0 ] } + } + }, + { + "name": "Channels Even", + "from": [ 5.0, 5.0, 2.0 ], + "to": [ 11.0, 11.0, 14.0 ], + "faces": { + "north": { "texture": "#channelsEven", "uv": [ 5.0, 5.0, 11.0, 11.0 ] }, + "east": { "texture": "#channelsEven", "uv": [ 0.0, 5.0, 5.0, 11.0 ] }, + "south": { "texture": "#channelsEven", "uv": [ 11.0, 5.0, 5.0, 11.0 ] }, + "west": { "texture": "#channelsEven", "uv": [ 5.0, 5.0, 0.0, 11.0 ] }, + "up": { "texture": "#channelsEven", "uv": [ 5.0, 0.0, 11.0, 5.0 ] }, + "down": { "texture": "#channelsEven", "uv": [ 5.0, 11.0, 11.0, 16.0 ] } } } ] diff --git a/src/main/resources/assets/appliedenergistics2/models/item/part/cable_smart_lightgray.json b/src/main/resources/assets/appliedenergistics2/models/item/part/cable_smart_lightgray.json index 89bb254b..cbdb818a 100644 --- a/src/main/resources/assets/appliedenergistics2/models/item/part/cable_smart_lightgray.json +++ b/src/main/resources/assets/appliedenergistics2/models/item/part/cable_smart_lightgray.json @@ -1,6 +1,6 @@ { "parent": "appliedenergistics2:item/part/cable_smart_base", "textures": { - "base": "appliedenergistics2:parts/cable/smart/lightgrey" + "base": "appliedenergistics2:parts/cable/smart/lightgray" } } \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/item/part/crafting_terminal.json b/src/main/resources/assets/appliedenergistics2/models/item/part/crafting_terminal.json index daf86673..7fc254a4 100644 --- a/src/main/resources/assets/appliedenergistics2/models/item/part/crafting_terminal.json +++ b/src/main/resources/assets/appliedenergistics2/models/item/part/crafting_terminal.json @@ -2,8 +2,8 @@ "parent": "appliedenergistics2:item/part/display", "textures": { "front": "appliedenergistics2:items/part/crafting_terminal", - "front_bright": "appliedenergistics2:parts/crafting_terminal/l2", - "front_medium": "appliedenergistics2:parts/crafting_terminal/l1", - "front_dark": "appliedenergistics2:parts/crafting_terminal/l0" + "front_bright": "appliedenergistics2:parts/crafting_terminal_bright", + "front_medium": "appliedenergistics2:parts/crafting_terminal_medium", + "front_dark": "appliedenergistics2:parts/crafting_terminal_dark" } } \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/item/part/dark_monitor.json b/src/main/resources/assets/appliedenergistics2/models/item/part/dark_monitor.json index 121484ec..e81c5807 100644 --- a/src/main/resources/assets/appliedenergistics2/models/item/part/dark_monitor.json +++ b/src/main/resources/assets/appliedenergistics2/models/item/part/dark_monitor.json @@ -1,7 +1,7 @@ { "parent": "appliedenergistics2:item/part/display", "textures": { - "front": "appliedenergistics2:items/part/crafting_terminal", + "front": "appliedenergistics2:parts/monitor_front", "front_bright": "appliedenergistics2:parts/monitor_colored", "front_medium": "appliedenergistics2:parts/monitor_bright", "front_dark": "appliedenergistics2:parts/monitor_colored" diff --git a/src/main/resources/assets/appliedenergistics2/models/item/part/display.json b/src/main/resources/assets/appliedenergistics2/models/item/part/display.json index d90909eb..4c1f9cfd 100644 --- a/src/main/resources/assets/appliedenergistics2/models/item/part/display.json +++ b/src/main/resources/assets/appliedenergistics2/models/item/part/display.json @@ -2,7 +2,8 @@ "parent": "appliedenergistics2:item/part/part", "textures": { "sides": "appliedenergistics2:parts/monitor_sides", - "back": "appliedenergistics2:parts/monitor_back" + "back": "appliedenergistics2:parts/monitor_back", + "front_medium_bright": "appliedenergistics2:parts/monitor_colored" }, "elements": [ { @@ -23,7 +24,15 @@ "from": [ 2, 2, 8 ], "to": [ 14, 14, 9 ], "faces": { - "north": { "texture": "#front_bright", "tintindex": 0 } + "north": { "texture": "#front_bright", "tintindex": 3 } + } + }, + { + "name": "Front Medium Bright", + "from": [ 2, 2, 8 ], + "to": [ 14, 14, 9 ], + "faces": { + "north": { "texture": "#front_medium_bright", "tintindex": 4 } } }, { diff --git a/src/main/resources/assets/appliedenergistics2/models/item/part/export_bus.json b/src/main/resources/assets/appliedenergistics2/models/item/part/export_bus.json index 219fe154..33d3d4fd 100644 --- a/src/main/resources/assets/appliedenergistics2/models/item/part/export_bus.json +++ b/src/main/resources/assets/appliedenergistics2/models/item/part/export_bus.json @@ -1,7 +1,7 @@ { "parent": "appliedenergistics2:item/part/part", "textures": { - "sides": "appliedenergistics2:parts/export_sides", + "sides": "appliedenergistics2:parts/export_bus_sides", "back": "appliedenergistics2:parts/monitor_back", "front": "appliedenergistics2:items/part/export_bus" }, diff --git a/src/main/resources/assets/appliedenergistics2/models/item/part/import_bus.json b/src/main/resources/assets/appliedenergistics2/models/item/part/import_bus.json index 11f88666..e2037f92 100644 --- a/src/main/resources/assets/appliedenergistics2/models/item/part/import_bus.json +++ b/src/main/resources/assets/appliedenergistics2/models/item/part/import_bus.json @@ -1,7 +1,7 @@ { "parent": "appliedenergistics2:item/part/part", "textures": { - "sides": "appliedenergistics2:parts/import_sides", + "sides": "appliedenergistics2:parts/import_bus_sides", "back": "appliedenergistics2:parts/monitor_back", "front": "appliedenergistics2:items/part/import_bus" }, diff --git a/src/main/resources/assets/appliedenergistics2/models/item/part/semi_dark_monitor.json b/src/main/resources/assets/appliedenergistics2/models/item/part/semi_dark_monitor.json index 30bb2400..77d2c365 100644 --- a/src/main/resources/assets/appliedenergistics2/models/item/part/semi_dark_monitor.json +++ b/src/main/resources/assets/appliedenergistics2/models/item/part/semi_dark_monitor.json @@ -1,9 +1,10 @@ { "parent": "appliedenergistics2:item/part/display", "textures": { - "front": "appliedenergistics2:items/part/crafting_terminal", + "front": "appliedenergistics2:parts/monitor_front", "front_bright": "appliedenergistics2:parts/monitor_colored", + "front_medium_bright": "appliedenergistics2:parts/monitor_bright", "front_medium": "appliedenergistics2:parts/monitor_colored", - "front_dark": "appliedenergistics2:parts/monitor_bright" + "front_dark": "appliedenergistics2:parts/monitor_colored" } } \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/annihilation_plane.json b/src/main/resources/assets/appliedenergistics2/models/part/annihilation_plane.json deleted file mode 100644 index 099d588f..00000000 --- a/src/main/resources/assets/appliedenergistics2/models/part/annihilation_plane.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "textures": { - "sides": "appliedenergistics2:parts/plane_sides", - "plane": "appliedenergistics2:items/part/annihilation_plane" - }, - "elements": [ - { - "from": [ 1, 1, 0 ], - "to": [ 15, 15, 1 ], - "faces": { - "north": { "texture": "plane" }, - "east": { "texture": "sides" }, - "south": { "texture": "sides" }, - "west": { "texture": "sides" }, - "up": { "texture": "sides" }, - "down": { "texture": "sides" } - } - }, - { - "from": [ 5, 5, 1 ], - "to": [ 11, 11, 2 ], - "faces": { - "north": { "texture": "plane" }, - "east": { "texture": "sides" }, - "south": { "texture": "sides" }, - "west": { "texture": "sides" }, - "up": { "texture": "sides" }, - "down": { "texture": "sides" } - } - } - ] -} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/cable/glass/center.json b/src/main/resources/assets/appliedenergistics2/models/part/cable/glass/center.json index 774c00f3..8edc45db 100644 --- a/src/main/resources/assets/appliedenergistics2/models/part/cable/glass/center.json +++ b/src/main/resources/assets/appliedenergistics2/models/part/cable/glass/center.json @@ -1,6 +1,6 @@ { "textures": { - "base": "appliedenergistics2:parts/cable/glass/${color}" + "base": "appliedenergistics2:parts/cable/glass/transparent" }, "elements": [ { diff --git a/src/main/resources/assets/appliedenergistics2/models/part/cable/glass/connection.json b/src/main/resources/assets/appliedenergistics2/models/part/cable/glass/connection.json index bf8b2dd2..55d5f748 100644 --- a/src/main/resources/assets/appliedenergistics2/models/part/cable/glass/connection.json +++ b/src/main/resources/assets/appliedenergistics2/models/part/cable/glass/connection.json @@ -1,6 +1,6 @@ { "textures": { - "base": "appliedenergistics2:parts/cable/glass/${color}" + "base": "appliedenergistics2:parts/cable/glass/transparent" }, "elements": [ { diff --git a/src/main/resources/assets/appliedenergistics2/models/part/cable/glass/straight.json b/src/main/resources/assets/appliedenergistics2/models/part/cable/glass/straight.json index 23ccfab6..9bb15f75 100644 --- a/src/main/resources/assets/appliedenergistics2/models/part/cable/glass/straight.json +++ b/src/main/resources/assets/appliedenergistics2/models/part/cable/glass/straight.json @@ -1,6 +1,6 @@ { "textures": { - "base": "appliedenergistics2:parts/cable/glass/${color}" + "base": "appliedenergistics2:parts/cable/glass/transparent" }, "elements": [ { diff --git a/src/main/resources/assets/appliedenergistics2/models/part/conversion_monitor_locked_off.json b/src/main/resources/assets/appliedenergistics2/models/part/conversion_monitor_locked_off.json new file mode 100644 index 00000000..7d80081f --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/conversion_monitor_locked_off.json @@ -0,0 +1,8 @@ +{ + "parent": "appliedenergistics2:part/display_off", + "textures": { + "lightsBright": "appliedenergistics2:parts/conversion_monitor_bright", + "lightsMedium": "appliedenergistics2:parts/conversion_monitor_medium", + "lightsDark": "appliedenergistics2:parts/conversion_monitor_dark_locked" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/conversion_monitor_locked_on.json b/src/main/resources/assets/appliedenergistics2/models/part/conversion_monitor_locked_on.json new file mode 100644 index 00000000..a9be582c --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/conversion_monitor_locked_on.json @@ -0,0 +1,31 @@ +{ + "uvlMarker": true, + "textures": { + "lightsBright": "appliedenergistics2:parts/conversion_monitor_bright", + "lightsMedium": "appliedenergistics2:parts/conversion_monitor_medium", + "lightsDark": "appliedenergistics2:parts/conversion_monitor_dark_locked" + }, + "elements": [ + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsBright", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + }, + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsMedium", "tintindex": 2, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + }, + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsDark", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/conversion_monitor_off.json b/src/main/resources/assets/appliedenergistics2/models/part/conversion_monitor_off.json new file mode 100644 index 00000000..065caec2 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/conversion_monitor_off.json @@ -0,0 +1,8 @@ +{ + "parent": "appliedenergistics2:part/display_off", + "textures": { + "lightsBright": "appliedenergistics2:parts/conversion_monitor_bright", + "lightsMedium": "appliedenergistics2:parts/conversion_monitor_medium", + "lightsDark": "appliedenergistics2:parts/conversion_monitor_dark" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/conversion_monitor_on.json b/src/main/resources/assets/appliedenergistics2/models/part/conversion_monitor_on.json new file mode 100644 index 00000000..63df02cf --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/conversion_monitor_on.json @@ -0,0 +1,31 @@ +{ + "uvlMarker": true, + "textures": { + "lightsBright": "appliedenergistics2:parts/conversion_monitor_bright", + "lightsMedium": "appliedenergistics2:parts/conversion_monitor_medium", + "lightsDark": "appliedenergistics2:parts/conversion_monitor_dark" + }, + "elements": [ + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsBright", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + }, + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsMedium", "tintindex": 2, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + }, + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsDark", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/crafting_terminal_off.json b/src/main/resources/assets/appliedenergistics2/models/part/crafting_terminal_off.json new file mode 100644 index 00000000..c6deba83 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/crafting_terminal_off.json @@ -0,0 +1,8 @@ +{ + "parent": "appliedenergistics2:part/display_off", + "textures": { + "lightsBright": "appliedenergistics2:parts/crafting_terminal_bright", + "lightsMedium": "appliedenergistics2:parts/crafting_terminal_medium", + "lightsDark": "appliedenergistics2:parts/crafting_terminal_dark" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/crafting_terminal_on.json b/src/main/resources/assets/appliedenergistics2/models/part/crafting_terminal_on.json new file mode 100644 index 00000000..bbe41dbe --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/crafting_terminal_on.json @@ -0,0 +1,31 @@ +{ + "uvlMarker": true, + "textures": { + "lightsBright": "appliedenergistics2:parts/crafting_terminal_bright", + "lightsMedium": "appliedenergistics2:parts/crafting_terminal_medium", + "lightsDark": "appliedenergistics2:parts/crafting_terminal_dark" + }, + "elements": [ + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsBright", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + }, + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsMedium", "tintindex": 2, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + }, + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsDark", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/display_base.json b/src/main/resources/assets/appliedenergistics2/models/part/display_base.json new file mode 100644 index 00000000..1c81b57e --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/display_base.json @@ -0,0 +1,33 @@ +{ + "textures": { + "sides": "appliedenergistics2:parts/monitor_sides", + "sidesStatus": "appliedenergistics2:parts/monitor_sides_status", + "back": "appliedenergistics2:parts/monitor_back", + "front": "appliedenergistics2:parts/monitor_front" + }, + "elements": [ + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "down": { "texture": "#sides" }, + "up": { "texture": "#sides" }, + "south": { "texture": "#back" }, + "east": { "texture": "#sides" }, + "north": { "texture": "#front" }, + "west": { "texture": "#sides" } + } + }, + { + "from": [4, 4, 2], + "to": [12, 12, 3], + "faces": { + "down": { "texture": "#sidesStatus" }, + "up": { "texture": "#sidesStatus" }, + "south": { "texture": "#back" }, + "east": { "texture": "#sidesStatus" }, + "west": { "texture": "#sidesStatus" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/display_off.json b/src/main/resources/assets/appliedenergistics2/models/part/display_off.json new file mode 100644 index 00000000..1c4b568c --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/display_off.json @@ -0,0 +1,30 @@ +{ + "textures": { + "lightsBright": "appliedenergistics2:parts/terminal_bright", + "lightsMedium": "appliedenergistics2:parts/terminal_medium", + "lightsDark": "appliedenergistics2:parts/terminal_dark" + }, + "elements": [ + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsBright", "tintindex": 3 } + } + }, + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsMedium", "tintindex": 2 } + } + }, + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsDark", "tintindex": 1 } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/display_status_has_channel.json b/src/main/resources/assets/appliedenergistics2/models/part/display_status_has_channel.json new file mode 100644 index 00000000..35a60abc --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/display_status_has_channel.json @@ -0,0 +1,18 @@ +{ + "uvlMarker": true, + "textures": { + "indicator": "appliedenergistics2:parts/monitor_sides_status_has_channel" + }, + "elements": [ + { + "from": [4, 4, 2], + "to": [12, 12, 3], + "faces": { + "down": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "up": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "east": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "west": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/display_status_off.json b/src/main/resources/assets/appliedenergistics2/models/part/display_status_off.json new file mode 100644 index 00000000..742f4c2f --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/display_status_off.json @@ -0,0 +1,17 @@ +{ + "textures": { + "indicator": "appliedenergistics2:parts/monitor_sides_status_off" + }, + "elements": [ + { + "from": [4, 4, 2], + "to": [12, 12, 3], + "faces": { + "down": { "texture": "#indicator" }, + "up": { "texture": "#indicator" }, + "east": { "texture": "#indicator" }, + "west": { "texture": "#indicator" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/display_status_on.json b/src/main/resources/assets/appliedenergistics2/models/part/display_status_on.json new file mode 100644 index 00000000..0b01e468 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/display_status_on.json @@ -0,0 +1,18 @@ +{ + "uvlMarker": true, + "textures": { + "indicator": "appliedenergistics2:parts/monitor_sides_status_on" + }, + "elements": [ + { + "from": [4, 4, 2], + "to": [12, 12, 3], + "faces": { + "down": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "up": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "east": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "west": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/export_bus_base.json b/src/main/resources/assets/appliedenergistics2/models/part/export_bus_base.json new file mode 100644 index 00000000..3f7afd33 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/export_bus_base.json @@ -0,0 +1,57 @@ +{ + "textures": { + "sides": "appliedenergistics2:parts/export_bus_sides", + "sidesStatus": "appliedenergistics2:parts/monitor_sides_status", + "back": "appliedenergistics2:parts/monitor_back", + "front": "appliedenergistics2:items/part/export_bus" + }, + "elements": [ + { + "from": [4, 4, 2], + "to": [12, 12, 4], + "faces": { + "down": { "texture": "#sides" }, + "up": { "texture": "#sides" }, + "south": { "texture": "#back" }, + "east": { "texture": "#sides" }, + "north": { "texture": "#front" }, + "west": { "texture": "#sides" } + } + }, + { + "from": [5, 5, 1], + "to": [11, 11, 2], + "faces": { + "down": { "texture": "#sides" }, + "up": { "texture": "#sides" }, + "south": { "texture": "#back" }, + "east": { "texture": "#sides" }, + "north": { "texture": "#front" }, + "west": { "texture": "#sides" } + } + }, + { + "from": [6, 6, 0], + "to": [10, 10, 1], + "faces": { + "down": { "texture": "#sides" }, + "up": { "texture": "#sides" }, + "south": { "texture": "#back" }, + "east": { "texture": "#sides" }, + "north": { "texture": "#front" }, + "west": { "texture": "#sides" } + } + }, + { + "from": [6, 6, 4], + "to": [10, 10, 5], + "faces": { + "down": { "texture": "#sidesStatus" }, + "up": { "texture": "#sidesStatus" }, + "south": { "texture": "#back" }, + "east": { "texture": "#sidesStatus" }, + "west": { "texture": "#sidesStatus" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/export_bus_has_channel.json b/src/main/resources/assets/appliedenergistics2/models/part/export_bus_has_channel.json new file mode 100644 index 00000000..30001604 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/export_bus_has_channel.json @@ -0,0 +1,18 @@ +{ + "uvlMarker": true, + "textures": { + "indicator": "appliedenergistics2:parts/monitor_sides_status_has_channel" + }, + "elements": [ + { + "from": [6, 6, 4], + "to": [10, 10, 5], + "faces": { + "down": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "up": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "east": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "west": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/export_bus_off.json b/src/main/resources/assets/appliedenergistics2/models/part/export_bus_off.json new file mode 100644 index 00000000..c75eadd4 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/export_bus_off.json @@ -0,0 +1,17 @@ +{ + "textures": { + "indicator": "appliedenergistics2:parts/monitor_sides_status_off" + }, + "elements": [ + { + "from": [6, 6, 4], + "to": [10, 10, 5], + "faces": { + "down": { "texture": "#indicator" }, + "up": { "texture": "#indicator" }, + "east": { "texture": "#indicator" }, + "west": { "texture": "#indicator" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/export_bus_on.json b/src/main/resources/assets/appliedenergistics2/models/part/export_bus_on.json new file mode 100644 index 00000000..4e26ceab --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/export_bus_on.json @@ -0,0 +1,18 @@ +{ + "uvlMarker": true, + "textures": { + "indicator": "appliedenergistics2:parts/monitor_sides_status_on" + }, + "elements": [ + { + "from": [6, 6, 4], + "to": [10, 10, 5], + "faces": { + "down": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "up": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "east": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "west": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/import_bus_base.json b/src/main/resources/assets/appliedenergistics2/models/part/import_bus_base.json new file mode 100644 index 00000000..87b8b259 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/import_bus_base.json @@ -0,0 +1,57 @@ +{ + "textures": { + "sides": "appliedenergistics2:parts/import_bus_sides", + "sidesStatus": "appliedenergistics2:parts/monitor_sides_status", + "back": "appliedenergistics2:parts/monitor_back", + "front": "appliedenergistics2:items/part/import_bus" + }, + "elements": [ + { + "from": [4, 4, 0], + "to": [12, 12, 2], + "faces": { + "down": { "texture": "#sides" }, + "up": { "texture": "#sides" }, + "south": { "texture": "#back" }, + "east": { "texture": "#sides" }, + "north": { "texture": "#front" }, + "west": { "texture": "#sides" } + } + }, + { + "from": [5, 5, 2], + "to": [11, 11, 3], + "faces": { + "down": { "texture": "#sides" }, + "up": { "texture": "#sides" }, + "south": { "texture": "#back" }, + "east": { "texture": "#sides" }, + "north": { "texture": "#front" }, + "west": { "texture": "#sides" } + } + }, + { + "from": [6, 6, 3], + "to": [10, 10, 4], + "faces": { + "down": { "texture": "#sides" }, + "up": { "texture": "#sides" }, + "south": { "texture": "#back" }, + "east": { "texture": "#sides" }, + "north": { "texture": "#front" }, + "west": { "texture": "#sides" } + } + }, + { + "from": [6, 6, 4], + "to": [10, 10, 5], + "faces": { + "down": { "texture": "#sidesStatus" }, + "up": { "texture": "#sidesStatus" }, + "south": { "texture": "#back" }, + "east": { "texture": "#sidesStatus" }, + "west": { "texture": "#sidesStatus" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/import_bus_has_channel.json b/src/main/resources/assets/appliedenergistics2/models/part/import_bus_has_channel.json new file mode 100644 index 00000000..30001604 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/import_bus_has_channel.json @@ -0,0 +1,18 @@ +{ + "uvlMarker": true, + "textures": { + "indicator": "appliedenergistics2:parts/monitor_sides_status_has_channel" + }, + "elements": [ + { + "from": [6, 6, 4], + "to": [10, 10, 5], + "faces": { + "down": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "up": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "east": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "west": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/import_bus_off.json b/src/main/resources/assets/appliedenergistics2/models/part/import_bus_off.json new file mode 100644 index 00000000..c75eadd4 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/import_bus_off.json @@ -0,0 +1,17 @@ +{ + "textures": { + "indicator": "appliedenergistics2:parts/monitor_sides_status_off" + }, + "elements": [ + { + "from": [6, 6, 4], + "to": [10, 10, 5], + "faces": { + "down": { "texture": "#indicator" }, + "up": { "texture": "#indicator" }, + "east": { "texture": "#indicator" }, + "west": { "texture": "#indicator" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/import_bus_on.json b/src/main/resources/assets/appliedenergistics2/models/part/import_bus_on.json new file mode 100644 index 00000000..4e26ceab --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/import_bus_on.json @@ -0,0 +1,18 @@ +{ + "uvlMarker": true, + "textures": { + "indicator": "appliedenergistics2:parts/monitor_sides_status_on" + }, + "elements": [ + { + "from": [6, 6, 4], + "to": [10, 10, 5], + "faces": { + "down": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "up": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "east": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "west": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/interface_base.json b/src/main/resources/assets/appliedenergistics2/models/part/interface_base.json new file mode 100644 index 00000000..7afeec00 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/interface_base.json @@ -0,0 +1,45 @@ +{ + "textures": { + "sides": "appliedenergistics2:parts/export_bus_sides", + "sidesStatus": "appliedenergistics2:parts/monitor_sides_status", + "back": "appliedenergistics2:parts/monitor_back", + "front": "appliedenergistics2:items/part/interface" + }, + "elements": [ + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "down": { "texture": "#sides" }, + "up": { "texture": "#sides" }, + "south": { "texture": "#back" }, + "east": { "texture": "#sides" }, + "north": { "texture": "#front" }, + "west": { "texture": "#sides" } + } + }, + { + "from": [5, 5, 3], + "to": [11, 11, 4], + "faces": { + "down": { "texture": "#sides" }, + "up": { "texture": "#sides" }, + "south": { "texture": "#back" }, + "east": { "texture": "#sides" }, + "north": { "texture": "#front" }, + "west": { "texture": "#sides" } + } + }, + { + "from": [5, 5, 2], + "to": [11, 11, 3], + "faces": { + "down": { "texture": "#sidesStatus" }, + "up": { "texture": "#sidesStatus" }, + "south": { "texture": "#back" }, + "east": { "texture": "#sidesStatus" }, + "west": { "texture": "#sidesStatus" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/interface_has_channel.json b/src/main/resources/assets/appliedenergistics2/models/part/interface_has_channel.json new file mode 100644 index 00000000..c2c5f8d8 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/interface_has_channel.json @@ -0,0 +1,18 @@ +{ + "uvlMarker": true, + "textures": { + "indicator": "appliedenergistics2:parts/monitor_sides_status_has_channel" + }, + "elements": [ + { + "from": [5, 5, 2], + "to": [11, 11, 3], + "faces": { + "down": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "up": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "east": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "west": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/interface_off.json b/src/main/resources/assets/appliedenergistics2/models/part/interface_off.json new file mode 100644 index 00000000..aac6b686 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/interface_off.json @@ -0,0 +1,17 @@ +{ + "textures": { + "indicator": "appliedenergistics2:parts/monitor_sides_status_off" + }, + "elements": [ + { + "from": [5, 5, 2], + "to": [11, 11, 3], + "faces": { + "down": { "texture": "#indicator" }, + "up": { "texture": "#indicator" }, + "east": { "texture": "#indicator" }, + "west": { "texture": "#indicator" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/interface_on.json b/src/main/resources/assets/appliedenergistics2/models/part/interface_on.json new file mode 100644 index 00000000..5c6d3895 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/interface_on.json @@ -0,0 +1,18 @@ +{ + "uvlMarker": true, + "textures": { + "indicator": "appliedenergistics2:parts/monitor_sides_status_on" + }, + "elements": [ + { + "from": [5, 5, 2], + "to": [11, 11, 3], + "faces": { + "down": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "up": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "east": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "west": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/interface_terminal_off.json b/src/main/resources/assets/appliedenergistics2/models/part/interface_terminal_off.json new file mode 100644 index 00000000..e646e4b2 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/interface_terminal_off.json @@ -0,0 +1,8 @@ +{ + "parent": "appliedenergistics2:part/display_off", + "textures": { + "lightsBright": "appliedenergistics2:parts/interface_terminal_bright", + "lightsMedium": "appliedenergistics2:parts/interface_terminal_medium", + "lightsDark": "appliedenergistics2:parts/interface_terminal_dark" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/interface_terminal_on.json b/src/main/resources/assets/appliedenergistics2/models/part/interface_terminal_on.json new file mode 100644 index 00000000..c8ae1a5b --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/interface_terminal_on.json @@ -0,0 +1,31 @@ +{ + "uvlMarker": true, + "textures": { + "lightsBright": "appliedenergistics2:parts/interface_terminal_bright", + "lightsMedium": "appliedenergistics2:parts/interface_terminal_medium", + "lightsDark": "appliedenergistics2:parts/interface_terminal_dark" + }, + "elements": [ + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsBright", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + }, + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsMedium", "tintindex": 2, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + }, + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsDark", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/inverted_toggle_bus_base.json b/src/main/resources/assets/appliedenergistics2/models/part/inverted_toggle_bus_base.json new file mode 100644 index 00000000..08739790 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/inverted_toggle_bus_base.json @@ -0,0 +1,6 @@ +{ + "parent": "appliedenergistics2:part/toggle_bus_base", + "textures": { + "bus": "appliedenergistics2:items/part/inverted_toggle_bus" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/level_emitter_base_off.json b/src/main/resources/assets/appliedenergistics2/models/part/level_emitter_base_off.json new file mode 100644 index 00000000..93229e6e --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/level_emitter_base_off.json @@ -0,0 +1,18 @@ +{ + "textures": { + "emitter": "appliedenergistics2:parts/level_emitter_off" + }, + "elements": [ + { + "from": [7, 7, 0], + "to": [9, 9, 4], + "faces": { + "up": { "texture": "#emitter", "uv": [6, 7, 10, 9], "rotation": 90 }, + "down": { "texture": "#emitter", "uv": [6, 7, 10, 9], "rotation": 270 }, + "east": { "texture": "#emitter", "uv": [6, 7, 10, 9], "rotation": 180 }, + "north": { "texture": "#emitter", "uv": [6, 7, 8, 9] }, + "west": { "texture": "#emitter", "uv": [6, 7, 10, 9] } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/level_emitter_base_on.json b/src/main/resources/assets/appliedenergistics2/models/part/level_emitter_base_on.json new file mode 100644 index 00000000..331e85b7 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/level_emitter_base_on.json @@ -0,0 +1,45 @@ +{ + "uvlMarker": true, + "ambientocclusion": false, + "textures": { + "emitter": "appliedenergistics2:parts/level_emitter_on" + }, + "elements": [ + { + "from": [7, 7, 3], + "to": [9, 9, 4], + "faces": { + "up": { "texture": "#emitter", "uv": [9, 7, 10, 9], "rotation": 90 }, + "down": { "texture": "#emitter", "uv": [9, 7, 10, 9], "rotation": 270 }, + "east": { "texture": "#emitter", "uv": [9, 7, 10, 9], "rotation": 180 }, + "west": { "texture": "#emitter", "uv": [9, 7, 10, 9] } + } + }, + { + "from": [7, 7, 0], + "to": [9, 9, 3], + "shade": false, + "faces": { + "north": { "texture": "#emitter", "uv": [6, 7, 8, 9], "rotation": 270, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + }, + { + "from": [6, 7, -1], + "to": [10, 9, 3], + "shade": false, + "faces": { + "up": { "texture": "#emitter", "uv": [5, 6, 9, 10], "rotation": 90, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "down": { "texture": "#emitter", "uv": [5, 6, 9, 10], "rotation": 270, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + }, + { + "from": [7, 6, -1], + "to": [9, 10, 3], + "shade": false, + "faces": { + "west": { "texture": "#emitter", "uv": [5, 6, 9, 10], "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "east": { "texture": "#emitter", "uv": [5, 6, 9, 10], "rotation": 180, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/level_emitter_status_has_channel.json b/src/main/resources/assets/appliedenergistics2/models/part/level_emitter_status_has_channel.json new file mode 100644 index 00000000..a155e7ee --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/level_emitter_status_has_channel.json @@ -0,0 +1,18 @@ +{ + "uvlMarker": true, + "textures": { + "indicator": "appliedenergistics2:parts/monitor_sides_status_has_channel" + }, + "elements": [ + { + "from": [7, 7, 4], + "to": [9, 9, 5], + "faces": { + "down": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "up": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "east": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "west": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/level_emitter_status_off.json b/src/main/resources/assets/appliedenergistics2/models/part/level_emitter_status_off.json new file mode 100644 index 00000000..c2842abd --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/level_emitter_status_off.json @@ -0,0 +1,17 @@ +{ + "textures": { + "indicator": "appliedenergistics2:parts/monitor_sides_status_off" + }, + "elements": [ + { + "from": [7, 7, 4], + "to": [9, 9, 5], + "faces": { + "down": { "texture": "#indicator" }, + "up": { "texture": "#indicator" }, + "east": { "texture": "#indicator" }, + "west": { "texture": "#indicator" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/level_emitter_status_on.json b/src/main/resources/assets/appliedenergistics2/models/part/level_emitter_status_on.json new file mode 100644 index 00000000..adeb4f5a --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/level_emitter_status_on.json @@ -0,0 +1,18 @@ +{ + "uvlMarker": true, + "textures": { + "indicator": "appliedenergistics2:parts/monitor_sides_status_on" + }, + "elements": [ + { + "from": [7, 7, 4], + "to": [9, 9, 5], + "faces": { + "down": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "up": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "east": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "west": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/monitor_base.json b/src/main/resources/assets/appliedenergistics2/models/part/monitor_base.json new file mode 100644 index 00000000..0f889ef1 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/monitor_base.json @@ -0,0 +1,33 @@ +{ + "uvlMarker": true, + "textures": { + "sides": "appliedenergistics2:parts/monitor_sides", + "back": "appliedenergistics2:parts/monitor_back", + "front": "appliedenergistics2:parts/monitor_front" + }, + "elements": [ + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "down": { "texture": "#sides" }, + "up": { "texture": "#sides" }, + "south": { "texture": "#back" }, + "east": { "texture": "#sides" }, + "north": { "texture": "#front" }, + "west": { "texture": "#sides" } + } + }, + { + "from": [4, 4, 2], + "to": [12, 12, 3], + "faces": { + "down": { "texture": "#sides" }, + "up": { "texture": "#sides" }, + "south": { "texture": "#back" }, + "east": { "texture": "#sides" }, + "west": { "texture": "#sides" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/monitor_bright_off.json b/src/main/resources/assets/appliedenergistics2/models/part/monitor_bright_off.json new file mode 100644 index 00000000..f10edbe2 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/monitor_bright_off.json @@ -0,0 +1,14 @@ +{ + "textures": { + "lights": "appliedenergistics2:parts/monitor_light" + }, + "elements": [ + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lights", "tintindex": 3 } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/monitor_bright_on.json b/src/main/resources/assets/appliedenergistics2/models/part/monitor_bright_on.json new file mode 100644 index 00000000..613d237f --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/monitor_bright_on.json @@ -0,0 +1,17 @@ +{ + "uvlMarker": true, + "ambientocclusion": false, + "textures": { + "lights": "appliedenergistics2:parts/monitor_light" + }, + "elements": [ + { + "shade": false, + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lights", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/monitor_dark_off.json b/src/main/resources/assets/appliedenergistics2/models/part/monitor_dark_off.json new file mode 100644 index 00000000..196fe72a --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/monitor_dark_off.json @@ -0,0 +1,14 @@ +{ + "textures": { + "lights": "appliedenergistics2:parts/monitor_light" + }, + "elements": [ + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lights", "tintindex": 2 } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/monitor_dark_on.json b/src/main/resources/assets/appliedenergistics2/models/part/monitor_dark_on.json new file mode 100644 index 00000000..fd8f8cf9 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/monitor_dark_on.json @@ -0,0 +1,15 @@ +{ + "uvlMarker": true, + "textures": { + "lights": "appliedenergistics2:parts/monitor_light" + }, + "elements": [ + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lights", "tintindex": 2, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/monitor_medium_off.json b/src/main/resources/assets/appliedenergistics2/models/part/monitor_medium_off.json new file mode 100644 index 00000000..83e531ca --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/monitor_medium_off.json @@ -0,0 +1,14 @@ +{ + "textures": { + "lights": "appliedenergistics2:parts/monitor_light" + }, + "elements": [ + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lights", "tintindex": 4 } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/monitor_medium_on.json b/src/main/resources/assets/appliedenergistics2/models/part/monitor_medium_on.json new file mode 100644 index 00000000..e8618aed --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/monitor_medium_on.json @@ -0,0 +1,15 @@ +{ + "uvlMarker": true, + "textures": { + "lights": "appliedenergistics2:parts/monitor_light" + }, + "elements": [ + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lights", "tintindex": 4, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_base.json b/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_base.json new file mode 100644 index 00000000..b31d314c --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_base.json @@ -0,0 +1,62 @@ +{ + "textures": { + "front": "appliedenergistics2:items/part/p2p_tunnel_front", + "sides": "appliedenergistics2:parts/p2p_tunnel_sides", + "back": "appliedenergistics2:items/part/p2p_tunnel_back", + "back2": "appliedenergistics2:items/part/p2p_tunnel_back2" + }, + "elements": [ + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#type" } + } + }, + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#front" }, + "south": { "texture": "#back" }, + "west": { "texture": "#sides" }, + "east": { "texture": "#sides" }, + "up": { "texture": "#sides" }, + "down": { "texture": "#sides" } + } + }, + { + "from": [3, 3, 2], + "to": [13, 13, 3], + "faces": { + "south": { "texture": "#back" }, + "west": { "texture": "#sides" }, + "east": { "texture": "#sides" }, + "up": { "texture": "#sides" }, + "down": { "texture": "#sides" } + } + }, + { + "from": [6, 5, 3], + "to": [10, 11, 4], + "faces": { + "south": { "texture": "#back2" }, + "west": { "texture": "#back2" }, + "east": { "texture": "#back2" }, + "up": { "texture": "#back2" }, + "down": { "texture": "#back2" } + } + }, + { + "from": [5, 6, 3], + "to": [11, 10, 4], + "faces": { + "south": { "texture": "#back2" }, + "west": { "texture": "#back2" }, + "east": { "texture": "#back2" }, + "up": { "texture": "#back2" }, + "down": { "texture": "#back2" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_items.json b/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_items.json new file mode 100644 index 00000000..f2f6261d --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_items.json @@ -0,0 +1,6 @@ +{ + "parent": "appliedenergistics2:part/p2p/p2p_tunnel_base", + "textures": { + "type": "blocks/hopper_outside" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_light.json b/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_light.json new file mode 100644 index 00000000..53b5b3c8 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_light.json @@ -0,0 +1,6 @@ +{ + "parent": "appliedenergistics2:part/p2p/p2p_tunnel_base", + "textures": { + "type": "blocks/quartz_block_top" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_liquids.json b/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_liquids.json new file mode 100644 index 00000000..f3f78e37 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_liquids.json @@ -0,0 +1,6 @@ +{ + "parent": "appliedenergistics2:part/p2p/p2p_tunnel_base", + "textures": { + "type": "blocks/lapis_block" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_me.json b/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_me.json new file mode 100644 index 00000000..f20e6833 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_me.json @@ -0,0 +1,6 @@ +{ + "parent": "appliedenergistics2:part/p2p/p2p_tunnel_base", + "textures": { + "type": "appliedenergistics2:blocks/quartz_block" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_redstone.json b/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_redstone.json new file mode 100644 index 00000000..b0aaea84 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_redstone.json @@ -0,0 +1,6 @@ +{ + "parent": "appliedenergistics2:part/p2p/p2p_tunnel_base", + "textures": { + "type": "blocks/redstone_block" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_status_has_channel.json b/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_status_has_channel.json new file mode 100644 index 00000000..7a785766 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_status_has_channel.json @@ -0,0 +1,18 @@ +{ + "uvlMarker": true, + "textures": { + "indicator": "appliedenergistics2:parts/monitor_sides_status_has_channel" + }, + "elements": [ + { + "from": [5, 6, 3], + "to": [11, 10, 4], + "faces": { + "down": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "up": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "east": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "west": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_status_off.json b/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_status_off.json new file mode 100644 index 00000000..c1cdcf1b --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_status_off.json @@ -0,0 +1,17 @@ +{ + "textures": { + "indicator": "appliedenergistics2:parts/monitor_sides_status_off" + }, + "elements": [ + { + "from": [5, 6, 3], + "to": [11, 10, 4], + "faces": { + "down": { "texture": "#indicator" }, + "up": { "texture": "#indicator" }, + "east": { "texture": "#indicator" }, + "west": { "texture": "#indicator" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_status_on.json b/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_status_on.json new file mode 100644 index 00000000..0c7de615 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_status_on.json @@ -0,0 +1,18 @@ +{ + "uvlMarker": true, + "textures": { + "indicator": "appliedenergistics2:parts/monitor_sides_status_on" + }, + "elements": [ + { + "from": [5, 6, 3], + "to": [11, 10, 4], + "faces": { + "down": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "up": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "east": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "west": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/pattern_terminal_off.json b/src/main/resources/assets/appliedenergistics2/models/part/pattern_terminal_off.json new file mode 100644 index 00000000..2e89eb65 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/pattern_terminal_off.json @@ -0,0 +1,8 @@ +{ + "parent": "appliedenergistics2:part/display_off", + "textures": { + "lightsBright": "appliedenergistics2:parts/pattern_terminal_bright", + "lightsMedium": "appliedenergistics2:parts/pattern_terminal_medium", + "lightsDark": "appliedenergistics2:parts/pattern_terminal_dark" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/pattern_terminal_on.json b/src/main/resources/assets/appliedenergistics2/models/part/pattern_terminal_on.json new file mode 100644 index 00000000..a37b225e --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/pattern_terminal_on.json @@ -0,0 +1,31 @@ +{ + "uvlMarker": true, + "textures": { + "lightsBright": "appliedenergistics2:parts/pattern_terminal_bright", + "lightsMedium": "appliedenergistics2:parts/pattern_terminal_medium", + "lightsDark": "appliedenergistics2:parts/pattern_terminal_dark" + }, + "elements": [ + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsBright", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + }, + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsMedium", "tintindex": 2, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + }, + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsDark", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/quartz_fiber.json b/src/main/resources/assets/appliedenergistics2/models/part/quartz_fiber.json new file mode 100644 index 00000000..18416f0a --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/quartz_fiber.json @@ -0,0 +1,19 @@ +{ + "textures": { + "fiber": "appliedenergistics2:items/part/quartz_fiber" + }, + "elements": [ + { + "from": [6, 6, 0], + "to": [10, 10, 6], + "faces": { + "down": { "texture": "#fiber" }, + "up": { "texture": "#fiber" }, + "south": { "texture": "#fiber" }, + "east": { "texture": "#fiber" }, + "north": { "texture": "#fiber" }, + "west": { "texture": "#fiber" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/storage_bus_base.json b/src/main/resources/assets/appliedenergistics2/models/part/storage_bus_base.json new file mode 100644 index 00000000..de6adca4 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/storage_bus_base.json @@ -0,0 +1,55 @@ +{ + "textures": { + "sides": "appliedenergistics2:parts/storage_bus_sides", + "sidesStatus": "appliedenergistics2:parts/monitor_sides_status", + "back": "appliedenergistics2:parts/storage_bus_back", + "front": "appliedenergistics2:items/part/storage_bus" + }, + "elements": [ + { + "from": [3, 3, 0], + "to": [13, 13, 1], + "faces": { + "down": { "texture": "#sides" }, + "up": { "texture": "#sides" }, + "south": { "texture": "#back" }, + "east": { "texture": "#sides" }, + "north": { "texture": "#front" }, + "west": { "texture": "#sides" } + } + }, + { + "from": [2, 2, 1], + "to": [14, 14, 2], + "faces": { + "down": { "texture": "#sides" }, + "up": { "texture": "#sides" }, + "south": { "texture": "#back" }, + "east": { "texture": "#sides" }, + "north": { "texture": "#front" }, + "west": { "texture": "#sides" } + } + }, + { + "from": [5, 5, 3], + "to": [11, 11, 4], + "faces": { + "down": { "texture": "#sides" }, + "up": { "texture": "#sides" }, + "south": { "texture": "#back" }, + "east": { "texture": "#sides" }, + "west": { "texture": "#sides" } + } + }, + { + "from": [5, 5, 2], + "to": [11, 11, 3], + "faces": { + "down": { "texture": "#sides" }, + "up": { "texture": "#sides" }, + "east": { "texture": "#sides" }, + "west": { "texture": "#sides" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/storage_bus_has_channel.json b/src/main/resources/assets/appliedenergistics2/models/part/storage_bus_has_channel.json new file mode 100644 index 00000000..c2c5f8d8 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/storage_bus_has_channel.json @@ -0,0 +1,18 @@ +{ + "uvlMarker": true, + "textures": { + "indicator": "appliedenergistics2:parts/monitor_sides_status_has_channel" + }, + "elements": [ + { + "from": [5, 5, 2], + "to": [11, 11, 3], + "faces": { + "down": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "up": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "east": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "west": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/storage_bus_off.json b/src/main/resources/assets/appliedenergistics2/models/part/storage_bus_off.json new file mode 100644 index 00000000..aac6b686 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/storage_bus_off.json @@ -0,0 +1,17 @@ +{ + "textures": { + "indicator": "appliedenergistics2:parts/monitor_sides_status_off" + }, + "elements": [ + { + "from": [5, 5, 2], + "to": [11, 11, 3], + "faces": { + "down": { "texture": "#indicator" }, + "up": { "texture": "#indicator" }, + "east": { "texture": "#indicator" }, + "west": { "texture": "#indicator" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/storage_bus_on.json b/src/main/resources/assets/appliedenergistics2/models/part/storage_bus_on.json new file mode 100644 index 00000000..5c6d3895 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/storage_bus_on.json @@ -0,0 +1,18 @@ +{ + "uvlMarker": true, + "textures": { + "indicator": "appliedenergistics2:parts/monitor_sides_status_on" + }, + "elements": [ + { + "from": [5, 5, 2], + "to": [11, 11, 3], + "faces": { + "down": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "up": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "east": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "west": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/storage_monitor_locked_off.json b/src/main/resources/assets/appliedenergistics2/models/part/storage_monitor_locked_off.json new file mode 100644 index 00000000..a0ab249a --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/storage_monitor_locked_off.json @@ -0,0 +1,8 @@ +{ + "parent": "appliedenergistics2:part/display_off", + "textures": { + "lightsBright": "appliedenergistics2:parts/storage_monitor_bright", + "lightsMedium": "appliedenergistics2:parts/storage_monitor_medium_locked", + "lightsDark": "appliedenergistics2:parts/storage_monitor_dark" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/storage_monitor_locked_on.json b/src/main/resources/assets/appliedenergistics2/models/part/storage_monitor_locked_on.json new file mode 100644 index 00000000..f6ce711c --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/storage_monitor_locked_on.json @@ -0,0 +1,31 @@ +{ + "uvlMarker": true, + "textures": { + "lightsBright": "appliedenergistics2:parts/storage_monitor_bright", + "lightsMedium": "appliedenergistics2:parts/storage_monitor_medium_locked", + "lightsDark": "appliedenergistics2:parts/storage_monitor_dark" + }, + "elements": [ + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsBright", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + }, + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsMedium", "tintindex": 2, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + }, + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsDark", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/storage_monitor_off.json b/src/main/resources/assets/appliedenergistics2/models/part/storage_monitor_off.json new file mode 100644 index 00000000..ad9e9443 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/storage_monitor_off.json @@ -0,0 +1,8 @@ +{ + "parent": "appliedenergistics2:part/display_off", + "textures": { + "lightsBright": "appliedenergistics2:parts/storage_monitor_bright", + "lightsMedium": "appliedenergistics2:parts/storage_monitor_medium", + "lightsDark": "appliedenergistics2:parts/storage_monitor_dark" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/storage_monitor_on.json b/src/main/resources/assets/appliedenergistics2/models/part/storage_monitor_on.json new file mode 100644 index 00000000..c8c6d134 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/storage_monitor_on.json @@ -0,0 +1,31 @@ +{ + "uvlMarker": true, + "textures": { + "lightsBright": "appliedenergistics2:parts/storage_monitor_bright", + "lightsMedium": "appliedenergistics2:parts/storage_monitor_medium", + "lightsDark": "appliedenergistics2:parts/storage_monitor_dark" + }, + "elements": [ + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsBright", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + }, + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsMedium", "tintindex": 2, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + }, + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsDark", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/terminal_off.json b/src/main/resources/assets/appliedenergistics2/models/part/terminal_off.json new file mode 100644 index 00000000..db74f5fc --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/terminal_off.json @@ -0,0 +1,8 @@ +{ + "parent": "appliedenergistics2:part/display_off", + "textures": { + "lightsBright": "appliedenergistics2:parts/terminal_bright", + "lightsMedium": "appliedenergistics2:parts/terminal_medium", + "lightsDark": "appliedenergistics2:parts/terminal_dark" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/terminal_on.json b/src/main/resources/assets/appliedenergistics2/models/part/terminal_on.json new file mode 100644 index 00000000..510ed91f --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/terminal_on.json @@ -0,0 +1,31 @@ +{ + "uvlMarker": true, + "textures": { + "lightsBright": "appliedenergistics2:parts/terminal_bright", + "lightsMedium": "appliedenergistics2:parts/terminal_medium", + "lightsDark": "appliedenergistics2:parts/terminal_dark" + }, + "elements": [ + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsBright", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + }, + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsMedium", "tintindex": 2, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + }, + { + "from": [2, 2, 0], + "to": [14, 14, 2], + "faces": { + "north": { "texture": "#lightsDark", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/toggle_bus_base.json b/src/main/resources/assets/appliedenergistics2/models/part/toggle_bus_base.json new file mode 100644 index 00000000..44b6826f --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/toggle_bus_base.json @@ -0,0 +1,40 @@ +{ + "textures": { + "bus": "appliedenergistics2:items/part/toggle_bus", + "sides": "appliedenergistics2:parts/monitor_sides_status" + }, + "elements": [ + { + "from": [6, 6, 0], + "to": [10, 10, 2], + "faces": { + "down": { "texture": "#bus" }, + "up": { "texture": "#bus" }, + "east": { "texture": "#bus" }, + "north": { "texture": "#bus" }, + "west": { "texture": "#bus" } + } + }, + { + "from": [6, 6, 3], + "to": [10, 10, 5], + "faces": { + "down": { "texture": "#bus" }, + "up": { "texture": "#bus" }, + "south": { "texture": "#bus" }, + "east": { "texture": "#bus" }, + "west": { "texture": "#bus" } + } + }, + { + "from": [6, 6, 2], + "to": [10, 10, 3], + "faces": { + "down": { "texture": "#sides" }, + "up": { "texture": "#sides" }, + "east": { "texture": "#sides" }, + "west": { "texture": "#sides" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/toggle_bus_status_has_channel.json b/src/main/resources/assets/appliedenergistics2/models/part/toggle_bus_status_has_channel.json new file mode 100644 index 00000000..08bb605c --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/toggle_bus_status_has_channel.json @@ -0,0 +1,18 @@ +{ + "uvlMarker": true, + "textures": { + "indicator": "appliedenergistics2:parts/monitor_sides_status_on" + }, + "elements": [ + { + "from": [6, 6, 2], + "to": [10, 10, 3], + "faces": { + "down": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "up": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "east": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "west": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/toggle_bus_status_off.json b/src/main/resources/assets/appliedenergistics2/models/part/toggle_bus_status_off.json new file mode 100644 index 00000000..20cdc0f2 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/toggle_bus_status_off.json @@ -0,0 +1,17 @@ +{ + "textures": { + "indicator": "appliedenergistics2:parts/monitor_sides_status_off" + }, + "elements": [ + { + "from": [6, 6, 2], + "to": [10, 10, 3], + "faces": { + "down": { "texture": "#indicator" }, + "up": { "texture": "#indicator" }, + "east": { "texture": "#indicator" }, + "west": { "texture": "#indicator" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/toggle_bus_status_on.json b/src/main/resources/assets/appliedenergistics2/models/part/toggle_bus_status_on.json new file mode 100644 index 00000000..6a0e4c0a --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/toggle_bus_status_on.json @@ -0,0 +1,18 @@ +{ + "uvlMarker": true, + "textures": { + "indicator": "appliedenergistics2:parts/monitor_sides_status_on" + }, + "elements": [ + { + "from": [6, 6, 2], + "to": [10, 10, 3], + "faces": { + "down": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "up": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "east": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "west": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/transition_plane_has_channel.json b/src/main/resources/assets/appliedenergistics2/models/part/transition_plane_has_channel.json new file mode 100644 index 00000000..07ae505c --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/transition_plane_has_channel.json @@ -0,0 +1,31 @@ +{ + "uvlMarker": true, + "textures": { + "sides": "appliedenergistics2:parts/monitor_sides_status", + "back": "appliedenergistics2:parts/transition_plane_back", + "indicator": "appliedenergistics2:parts/monitor_sides_status_has_channel" + }, + "elements": [ + { + "from": [ 5, 5, 1 ], + "to": [ 11, 11, 2 ], + "faces": { + "east": { "texture": "#sides" }, + "south": { "texture": "#back" }, + "west": { "texture": "#sides" }, + "up": { "texture": "#sides" }, + "down": { "texture": "#sides" } + } + }, + { + "from": [ 5, 5, 1 ], + "to": [ 11, 11, 2 ], + "faces": { + "down": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "up": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "east": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "west": { "texture": "#indicator", "tintindex": 1, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/transition_plane_off.json b/src/main/resources/assets/appliedenergistics2/models/part/transition_plane_off.json new file mode 100644 index 00000000..deec78ec --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/transition_plane_off.json @@ -0,0 +1,30 @@ +{ + "textures": { + "sides": "appliedenergistics2:parts/monitor_sides_status", + "back": "appliedenergistics2:parts/transition_plane_back", + "indicator": "appliedenergistics2:parts/monitor_sides_status_off" + }, + "elements": [ + { + "from": [ 5, 5, 1 ], + "to": [ 11, 11, 2 ], + "faces": { + "east": { "texture": "#sides" }, + "south": { "texture": "#back" }, + "west": { "texture": "#sides" }, + "up": { "texture": "#sides" }, + "down": { "texture": "#sides" } + } + }, + { + "from": [ 5, 5, 1 ], + "to": [ 11, 11, 2 ], + "faces": { + "east": { "texture": "#indicator" }, + "west": { "texture": "#indicator" }, + "up": { "texture": "#indicator" }, + "down": { "texture": "#indicator" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/part/transition_plane_on.json b/src/main/resources/assets/appliedenergistics2/models/part/transition_plane_on.json new file mode 100644 index 00000000..9ea77338 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/part/transition_plane_on.json @@ -0,0 +1,31 @@ +{ + "uvlMarker": true, + "textures": { + "sides": "appliedenergistics2:parts/monitor_sides_status", + "back": "appliedenergistics2:parts/transition_plane_back", + "indicator": "appliedenergistics2:parts/monitor_sides_status_on" + }, + "elements": [ + { + "from": [ 5, 5, 1 ], + "to": [ 11, 11, 2 ], + "faces": { + "east": { "texture": "#sides" }, + "south": { "texture": "#back" }, + "west": { "texture": "#sides" }, + "up": { "texture": "#sides" }, + "down": { "texture": "#sides" } + } + }, + { + "from": [ 5, 5, 1 ], + "to": [ 11, 11, 2 ], + "faces": { + "down": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "up": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "east": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } }, + "west": { "texture": "#indicator", "tintindex": 3, "uvlightmap": { "sky": 0.007, "block": 0.007 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/textures/items/part/p2p_tunnel_back2.png b/src/main/resources/assets/appliedenergistics2/textures/items/part/p2p_tunnel_back2.png index 3e146a87d058dae8ee54ec322a74a243ebe929fa..ceffe1de697d9e4f74e900b861098877bd65c451 100644 GIT binary patch delta 2842 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 s$_LGynhq delta 237 zcmV0Dy!50Qvv`0D$NK z0Cg|`0P0`>06Lfe02gqax=}olAs2rD8gxZibW?9;ba!ELWdKlNX>N2bPDNB8b~7$D zE-^7j^FlWO003-BL_t(IPt}t_3V<*S1oOTAD$mI;t9uZ}lr0`Ss4yTgGqeYzs^-NQ zV`k!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5%JXz_46*P(I&mZK z0Rs+}z0ivlY*7^q}n2Y_^ zY~?w#gPS$zUbVD~5Z98LbA}yDR35l~n(r`K?871t6OiQf{4)!z-9E6IuX)f`c|lG> Xf6nPkAv1vbP0l+XkKo(WxF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/blue.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/blue.png new file mode 100644 index 0000000000000000000000000000000000000000..73defd47f919023b1bc63c6a08b7a1312d628550 GIT binary patch literal 280 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5%J6h?46*P(dSN4P zg8`4r#WU{5{d^8fi0DjK>}${|;ZskX-1JCvW66FGMgtc)<0poPZJ%*=Jm}@qIeX1A ze_=!K^;d;0=I0xFzn_ym$+FJzb9}>5=EL(n1dkuvc!2xfjsxPKW+?U-YOw2M{6GF> S*%WD@oeZ9?elF{r5}E*U6I@~d literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/brown.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/brown.png new file mode 100644 index 0000000000000000000000000000000000000000..0d992170f1439caadd7a064841969c639d17e06e GIT binary patch literal 290 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5D)Mx346*P}{_+36 zy{p7(1x+w+4StgTYraI!8urzUR~4uIPfx2{m@q*iknMoU{rwd(tjf|&YuFDn%y{;^ zeBGji8Hy^B1qD^S68v)*Pt3?**5GqVah_o4V;smPaOgx;0FMHDvZx9x5X=2fXJEL_ Xd?vW=^3ESX+ZjAv{an^LB{Ts5ywg`{ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/cyan.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/cyan.png new file mode 100644 index 0000000000000000000000000000000000000000..eb468020cf277d3f6ff48886d239cab54f2cc817 GIT binary patch literal 295 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5D))4846*P(+Gohu zpdi5Vb7KC(+G}QFc88kce=tS=7UfW>{wVZr%Z3?Es>T8gHBPd&D;BdC&UnTub|a9v z(6_@{rP7#n*B;sF4a#q9n0@`!S!^G1UAdp~kK5pzL*-W28Jni=PHa$aQk%`Bd_%C& g9H_f=OLGCUblca*8~3*F06Kxe)78&qol`;+0I-Bzga7~l literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/gray.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/gray.png new file mode 100644 index 0000000000000000000000000000000000000000..b2401a542676f9afb22df207d0566086eb0b9f2a GIT binary patch literal 278 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5O7nDa46*P(I>C^O z!H|RHbAf#FOKq0;G!Ml!a|)_7*GU*~8@o>19Us^ye5%l?N?>BS!*U*j&D|c4a@IPW zNSk(m!>Zrm#Hv{xCo~G)9j<3wBD>?COOJx$cBcFVlbPZ*j&nY}ar`>lRKB!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5s_=Ai46*P(+Pjgr z!GMQlGZ*&;2Gi;dyxA8FoY)dsSIl@ck=r}}Xi$!Z#<~-(^?D3;4^Q!|JCh*y*-U{c z|IUG;-W%^vD(Hz^_}F;$fZ#n7M%no**m{>R6$Sp#KhVNl6sX)|@$)sC#i17#A}3Fa>GCH!L7AGH!yg*`njxgN@xNACn{cE literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/lightblue.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/lightblue.png new file mode 100644 index 0000000000000000000000000000000000000000..5c18a568817ed722361ae82d42e503e1822d5052 GIT binary patch literal 288 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5D)4l146*P}{_+36 zy{p7(1x+w+oqVPGm%X7xB!3w5tZO#^_kaBqFTx|Fe2QVlv*h{z7AK@QPxzW3!Em|e zv9wm3q|+ou1v3u*IgBS}WH4*+xd3GieT)Oy1P-033gA&-PZm{S1!B4X=?n~8H;Wp5 T+dnM?Xg7nWtDnm{r-UW|?O;`} literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/lightgray.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/lightgray.png new file mode 100644 index 0000000000000000000000000000000000000000..95858586ffc5b1596fb42fe004b3ff9b05b499b9 GIT binary patch literal 284 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5%JFn@46*P(+PjhW zfB^@~-v54E*4=2BWw}9Pf*k9~2_l;7K19~*82@(BRG(7hR3$L6^nkDAjcRFQ^*dXc z48=SW literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/lime.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/lime.png new file mode 100644 index 0000000000000000000000000000000000000000..1b4b650d2ff465f10e8806d28028ef41ea3a5106 GIT binary patch literal 283 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5%Jy_|46*P(I$hVvApc>6s52P!xeTrDqia9Z18j}!hXM_ z+d>+Q?A4?KpNlQ%NiN=DT`0%=E$5GTz@^5Q^D_(<1^BVv3pmcYPoPiqkRksqhOYu5 Vt1Rr^iUX}>@O1TaS?83{1ORX0SL^@) literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/magenta.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/magenta.png new file mode 100644 index 0000000000000000000000000000000000000000..a4999d584912eb199772d410eec232e5dd45ed44 GIT binary patch literal 288 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5D)4l146*P}{_+36 zy{p7(1x+w+y{vNm%Y2ERHSDVyt+$l@iGN+r%G!LS!-!$o&$6qbB0V`Ao8)+y6K3_F zvuJEeY@3k6(7}6%Ii0~s?G{59v*1mE6rRgIQy5zeHpz)FpEwx7>IuZ1$Nx(*2zp;X U?W@LO3bdQS)78&qol`;+06`d6KmY&$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/orange.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/orange.png new file mode 100644 index 0000000000000000000000000000000000000000..cda4454cad18e8e20c14b5b152d4f9efde6435ab GIT binary patch literal 288 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5D)4l146*P}{_+36 zy{p7(1x+w+{an23X?>ExCb>0ie`Y=X^#8h*36F^KDTW!(-ltDrl#t>);cJ2v!__}e z?{SLo7`Lb}AK1q9@qlDQPp5gqB?lKX7FK6d;Zz32o;B=88Hx!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5D)w}746*P(+H1(w z;K0N3{{MsGnr@CH{p%4Nx7IG}NHHwv6cY=+BV(<}VE6D8&$=@X{VQJ!9?ZLQ;3EHx z5Ag?t_)fU?3QV88KdnKDO}3p$_e~p9enBc* d_%TOIMi&d6e@TjGl!4YWc)I$ztaD0e0ss};Tju}( literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/purple.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/purple.png new file mode 100644 index 0000000000000000000000000000000000000000..04108da7667be835bbdf0837cad1f6b3e67e07a6 GIT binary patch literal 289 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5D)e-546*P}{_+36 zy{p7(1x+w+y_~Y)rM;m!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5%Jp<{46*P(df^~v zg9DGt#gHUbv8Ok!*0^k7(!S7ktb<2I%Ak;6?w%amCw^^)SuM$~7GXaet7?V6EVa1M zdtgiD^J!ckD)wy@EdI>%q2i{kn^$Av-aq0SE;T;$-y+z3eB}Y@+LP>d9LKu~&NRz7 X{`z!XUuVH1pv4THu6{1-oD!M!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5s_}Gj46*P(I&mZK z0Roa(PPMS;+gM`&sqnj9;|0l(`AV6x7g3M+|cH6 npK!{9KEWDAo^X!CHc@$-VzwBYvTP0nx`V;f)z4*}Q$iB}OPFEp literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/white.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/white.png new file mode 100644 index 0000000000000000000000000000000000000000..8aafeab54a540e17870b9afdc3fa08c2c0062f07 GIT binary patch literal 283 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5%Jy_|46*P(dSN5y z0RtYF!1wl@%MDgsXOlam9OL0opv2@|IPsCF*d6^l3^JVkq7OG7vb`2{;(@QkjAEzI zxxc4z-H33J>HF|Zbi+r9!y7#`FI3n65l?t|;G=p`%S{W>8xMQAYXs%A4<*apVx1>q VD901?BnoIPgQu&X%Q~loCIC$WTCxBD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/yellow.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/yellow.png new file mode 100644 index 0000000000000000000000000000000000000000..725d7942b94da65ce7b838bd340193d37f5232f0 GIT binary patch literal 292 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5D)Dr246*P(+P9In z!GMRwSYEa}RiJG_3WwSW4iOK39n}}QI!D`@9(C1}Ojlu;Z*ZLBnS`S(pU;N_eUc9I z8cQ!;IV-y3Y3=2JmbvK*PN!eo;-RCkU+^Ed!Mlb%H!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5+UM!w7-HeSbh07e z5d|KWpW>{hqWd4HhODe$+y5l5!>mX^X<||)|LHaAVdn}BkHvYtoO5dLciZQ8qO+Z! zTzRtjAEUyXr+f=6`W~~~Q2HtCP&X@k?Q<3p%lkeJ?*8t{O_Bb>5te#stpZhEFV(WN z*EidF^M+jsi(78EmPJDOpL4_1a_$9^C&V^Lc{6BdX}|wIJ>$PnC-)1f$#ZUH_f!3!Im!PSClq!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5+TrQq7-HeSbaEh9 zivf>I@!nt0r;Fb@JjJ$6exB8KXlER=O?$Ux)v3C zB5<+(FWH6;^J<1;-#&ZmD9JOvIR5PJr~Pt`%bo8zt`1}meDo}=`{iYhtw*%|@{jTc zu279joE^wg(JjW3a!-$8HsedCP1`tjaBe;F`=9DDf2W_mi#Pk)pUs;2T}s7I{F59* z<5ww_7=bzK)EQV5g^mktwq+_%{;OaAe35$Ms#mr~a^adlKQMT@`njxgN@xNAq}6`6 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/brown.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/brown.png new file mode 100644 index 0000000000000000000000000000000000000000..70c8c57a763f44045d6f40e6776796439207bfb2 GIT binary patch literal 384 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5y5Q;J7-HeSbn-@C zCPN%_{F>3>-rZk!f#__*snTZ8VT?+l+V|EaWZ=hP_jo5|2W zukRGg)+*r$R=upZ=BI0Jt^4P4_A}dytydCUfpl-Cs)OW5ai)rUY7J=$z76Kn7{adD zy#F&jp9G#d??RW)E2W$JqY)jQz|i WYlCbXisu9U#^CAd=d#Wzp$P!+--`YK literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/cyan.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/cyan.png new file mode 100644 index 0000000000000000000000000000000000000000..7e1ac7e76cc4beef87bee6aa9b7d848df909281b GIT binary patch literal 367 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5+VAP&7-HeSG}w{r zumR8K{%?IUzxT~$Pi(hc)c!B&`@wa)cTbBJJ>Rk>l@IH=`C`HJi>SRdaW?C(eI0M(#G-W`i`AlX4eNoxGM^xSLJj@RIBYhkL^Agq<(=t9opI%K-+aV@q}% zwH52U-CBK~q4jfw%AX_8B$-8i{^KY)oY&7|^#9TGm=e}?O4ny=hK9-my~5z>>gTe~ HDWM4f=kkgw literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/gray.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/gray.png new file mode 100644 index 0000000000000000000000000000000000000000..d0a99df2e57b68bd29ebe7915e47091dac532783 GIT binary patch literal 366 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5+UM!w7-HeSbh0DY z5d|LCz4OY2Y#Pf8UW)E2e0*?D<+S)9!RU+!{fhtgwE4Z-^Zln?Hs2@(Y~1s{qy>cv232FwxKBIOqb!eDVKb& zgvGJfPLo=*V(lKkLG zk}Lj`&!Hf$`w0KSw^hsvEQMvdH{Yr^NIm`k!}9k(=Ec|ctq=V6)d=Vl22WQ%mvv4F FO#t70hj#z~ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/green.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/green.png new file mode 100644 index 0000000000000000000000000000000000000000..990574ee745e31e176d357987c6450c7a7a74d4e GIT binary patch literal 377 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5I_c@+7-HeSbh07e zAp;)QVo|*VtX9TP#O`pd6y^?Eci>d0RcKOE@6iuIe^0pt2CbY{mwfa7{`j@RNj+ti zeaBY*DY3m#X%*$A**s@f#k~2f9QSiLHQud1uJoY$i7n$t$$56~k21QR)8%{c;;n+U z#>L_Xf*Dg19+>ghPw?n;Slq%^Wh#(z+4)J%NAV|DvhFNnINV{vnlWv~&9zq#{Of;F z-|5iIc=Jj@?{2+G+q(CtIuxwyKGJ-lELTuLMd(k|rrWlRyj}Z0Te<&cvfMjY?q>M1 RN}#70JYD@<);T3K0RYhFj1vF= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/lightblue.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/lightblue.png new file mode 100644 index 0000000000000000000000000000000000000000..a65687f89ba38d256d86a090daf9c32f03d8d180 GIT binary patch literal 363 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5+U@D$7-HeSbh07e zAp;)Q;=M7=i#HVa^Q@WEG_h5>;mEl#$$1yoH;GzK&3b8m?fduXx2=|5%lf`ua`~sj zFSCw+J{*6|40QTj=Na&DG`vD!+;qa7D_DD%Df-|<&pP~*Y^!>cxz)^#s= zt8|`+<6P;)iZ4&Zn4PNXS$A%{ZQQ)#ex>-TT83_Y-sY4qcI-fJFnGH9xvX!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5+Ue=y7-HeSbh0DY zQ3W2Cz4O{dVs?Gt+S|%)KJV!N`Kfk4m7+2dvS#=!TiAQ9`o6d3+~A+3v9>K2g1wlZ z6kLk@YoL%*n7&}e)_ZKzRO}@^{EM^S&SRML`6Nrmmofvj8HKYB915HvnEb}_x&4Wh zw#5d{yy|=wy_t$1B|b_&DbRj`ps{4Me(1tTg7!A06oFr>FVdQ&MBb@0B8J# AH2?qr literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/lime.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/lime.png new file mode 100644 index 0000000000000000000000000000000000000000..4cae7679118bda18fdec6324b22589e394d67650 GIT binary patch literal 367 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5+VAP&7-HeSbh0Dg zAp;(k&wC3V+wW;C52IH3+&%K___;8jn^U>>aXAex?8Yfv|dsx5v8!wmVz0HhLwz6AznWjlws7MK3 zZ>nzaQ4;Fq;9X-eVau}iBc(@$t`sQ0z0#2Avy9C|+3j_og+WcHiNuEn>CFCmH`)Gm z-Bno*Q~ua5u?lgzzV&p&3$>H;Rk!aodC`1H{?FXae;F(nG5&1-_*@_86$VdNKbLh* G2~7a^GlvEM literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/magenta.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/magenta.png new file mode 100644 index 0000000000000000000000000000000000000000..1ffc9d5312b9ef3e5b24196083e70925ebacf854 GIT binary patch literal 370 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5I^^l%7-HeSbn-#o zLk2vqww%lxJoR{vYz#JV(z~;pL5TUl%5pxP#0tm#Twzl}RxQ0BasPh2-|Hx^lljwk z7i-Pun|%KG&Ej*cPYNzw{gvc!<>gEJCmgC~#pnO`WjMJrwP}UEuuG5HibN5m zj2-jj>L+-%1a<@*?qFVKnC-D=&iuUl3hmjMyV*>N&#z-V+Hq}%F5jE_&X1cJxJ)v9 zOt)`&t(3X@L^T`B^IaY`Sw-E9inTkN?%a4g(ecXrKjM?>85B8J2OR&iJq+j@22WQ% Jmvv4FO#m8jhVcLZ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/orange.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/orange.png new file mode 100644 index 0000000000000000000000000000000000000000..99d579dc60be1d501ebf87c903910e36649d11f6 GIT binary patch literal 367 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5+VAP&7-HeSbn-^N zLk2u9pQGRC{5<6K#$)CW;eE|hc`qLQ5VLbrkEhbrOQzR;R_$GuxpM2N*L9*{ukWAs zymmV>Dx0gy;&SC)serm0#v6=kJD;35@a5No=gHm-C#@zcyfSq>qS5G{D4^*5_u;kE zX+nVo{Rsw#8cjcd+xtr}ykLUGDph#}2zXZ?^rt>+;`|ho@lsj4uT< z%j`YMcD<-(6M0=XVMj&Lu?C~P`0o4Iv>USaTb^>bP0 Hl+XkK{2Yy! literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/pink.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/pink.png new file mode 100644 index 0000000000000000000000000000000000000000..6343b8c4362eb3710d4adf1f136d83278567b19d GIT binary patch literal 353 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5+UV)x7-HeSbn->c z!v;Jqd*`*kmWxx^JjLl{xih=R{}}s&tgaHf6Am8jDk<0KoK$q~YelWr@=womSKogd z=dH80()4&^yu#!T7iFiWNM4oR zmx`NuZyfp*_PVg0t;0}K>O#+p-rK7izfON)-|4{Icx=j!gTe~DWM4fUB-bc literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/purple.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/purple.png new file mode 100644 index 0000000000000000000000000000000000000000..8727b9cd91955297b79cebd7a14c5e455aa7de03 GIT binary patch literal 365 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5+Ux1!7-HeSbn-#o zLk2vqwnEuY&T#o0(keJ1xRFKt$V|Zr5{EuC)upb{SQ+BIf8(3?>+fIN7}Ry&ul#vP z-JRIKd+ICJZf%@1t777PmW~@ToEk^A$IRjEIRD}GTYGj9%j*^={ybAiex`6JBgLS= z(&oRyM4rVH7dA%n&d71=xT90oJSVE(S|mYY;zEYAJ@f9y@#g&R_&A-zL}G$3@An<2 zl`?mqaA#t9zRANTsj!zpv96kR<;L5_jc4vxh!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5I_2r&7-HeScJf7D zCqoX`pCw%EhIK!$Pn~mEaaTk03x+zW?FZtxTCPv{rs`D`?4-Z^NoR;x;yzo6=$QCR8qGFkv=gO-Yti;M#iTcYD7?oshVm z^xb1qt_OJU+2^q@_Cz{^i*@b9C7cUyZ{=!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|Q<>FMGaV&T7a!bQ#l z3Op{GJ?wv9cilAg@s6c$IoVgnELmV%vB0y26%4S}Qx}D$ffhH8Uf|!@uPk zm4ti#sQ>6XXxDVCR8Bu2c=It+Wf6sMElj4?q7MvJf*Yf{n>ezv%Ki$63LZFTS{P=$ qfP2P`6D&OMt692y3^r+eC}ZBY(2hCeY>XGsEexKnelF{r5}E+&YGZQ% literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/white.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/white.png new file mode 100644 index 0000000000000000000000000000000000000000..23d24bb2b79ff2db59b642dac3c347b68d9d442e GIT binary patch literal 361 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5+Ue=y7-HeSbh0DY zQ3W2Cz4Oe!iZoT{UvS=0@bJ?A`Kfk4m7+2dvS#=!TiAQ9`o6d3+~A+3v9`xyd^Dotv{y=FR81qVf0i>o>pIB~(nOa+lxf26}?Q)78&qol`;+06x%$ A3jhEB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/yellow.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/yellow.png new file mode 100644 index 0000000000000000000000000000000000000000..4e3923fbc8bcc40a1a7b56e90c850737b200acf6 GIT binary patch literal 368 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5I^gNz7-HeSG}w`g z*^uK)^~<&LudSWrFDCofI>uj6-x5$@>~?hO1f4YoF2@R$BBy(4p6R!Kyk$;)_`grB z*=w1eJn#|!dY3`4%b24e#sWpB9gW}qqTbO4&75oU_vHPZAJ|rkFs9VH7&HL=!r|NsC0dmGHX2$W_l3GxeOaCmkj4a7hrbq!OFHviN!ik+0kl!I#5JNMC9x#cD!C{XNHG{07#iyu80#7u zg&0^^85>&}TId>>S{WEzb3M5qMMG|WN@iLmT!Vp0h>@|C0T7w!8khk!e7(xO9;iVI vWJ7R%T1k0gQ7S_~VrE{6o}X)oLYc9ish**M!Iz?iKvfK$u6{1-oD!Mh=G?L;nN4 z{vUh&{{@g8{y(tgKM*W;i|GPNGnNGT1v5B2yO9RsBze2LaJ1cOU%XTmqmY*gb|D6cr-Qknk#DHHf!PMopf(aN_kRo1Wlr0Dtm(xcVe z57zF;3QxGQbMeDpi^V0K`L3jF>Cyn&s9NG0QIe8al4_M)lnSI6j0_Bobq$Pl4UIw! zEUb);tqd)64NR>J46eDJ+>fFmH$NpatrD)mz$C=T*vbHiOmq#*fEvDDJZDBSziDD|ChP^XFE`uu_VYZn8D%MjWiG^$=lt9qwU_*DjbPbn zK74!Tu;6BWz70EmI~|QV6TWd~qZ-FTdBq8r%Jlb7nZWmQ;*1TCR=$0yvVQF+MbGb- z976Mf!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5I_c@+7-Hc+HOP?f zkb%H%`H$1~tS=U4le@TZf5Q4Br{o?f+gZ9VI5bK0^z$8_A9oF0Qyy6_cYnf~o*jn52=CwiY-x1m`1K-kmuO+LGIvd`*xYiFp|?%!B2 zt@m4F?ctTzU&Mb{ToRDHLQ31m8hmx(sbPZSsGfa~XfWt$gl<`LQh?kvz_*rM<}cEw88FIyWV*QBNCmn{&~`*ZDH Q0nk$np00i_>zopr0M$f^VE_OC literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/gray.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/gray.png new file mode 100644 index 0000000000000000000000000000000000000000..12c94eeac5e128e34005502de1a93c8ea24615fb GIT binary patch literal 369 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5I_T-*7-HeSbn->s z!wNhuk}{o~o0zjdOqOT!{=DYKE{njxtCQEnynP(#5q&}8u|YA{{c8KHwHFTu&%0dX z(av|{``s$ZhMI3TVi~_YoAXR|L1kK+QA%mc4Oz?3*U}2%igQ+PEz7wr#$eO1J?FyK znuDv{Z}L^C{f=5LvFdrJN%ijT9T&a#ada?EX!hkP{#(+rUF~R7cK?ne+kgExU1YHQ z1K$Vlpoa8{druNsKUn^s@^ayaUs@dL3_%S})Bd-974-VaAS3Xk^iIwlBcNv(JYD@< J);T3K0RSGyj1K?+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/green.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/green.png new file mode 100644 index 0000000000000000000000000000000000000000..a9fd11bd9da437267c5b45c23fd81adf0018432c GIT binary patch literal 391 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5y6)-X7-Hc+b+RGf zAp;)QVo|*VM~X*o^UthaTsXO`V_`ga|W|5Mbd8=l| z{Wx12&wtmds-kM%&=UP??ryV{Ywcxi9q*=tTxkS3j3^P6!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5I_c@+7-Hc+b&?~O zlc9ifby)wSd$V_Z716s}!OZ&o-I9OiCeAW!7acO{W_e~8HoPuACm?-c_u z2(Ub_UK7mvDT~n~*7t?^4*RqW(TaI{1-2gHZV>y}o9_X|_+U;wCO9xDOmxm_4=rZ_BwSg%T0zPn64U?(kcBDBF(z zt literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/lightgray.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/lightgray.png new file mode 100644 index 0000000000000000000000000000000000000000..0b4d0087b31ef1b27c0cece7c16184913b6e3a44 GIT binary patch literal 370 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5I^^l%7-HeSbn->s z!wNhuH|yC|*iLZe9CWXnp?Y?6((6YquA%;$injKT_Z&W>S@Ztyimh(^{*`{8 z6=kgw?w7w#W%zV6xt#UF?BZGF4bNuIJUQX2U{d*$khS>@F|7sbuHD+08_n>6;oc_4 z>z`Ox%cWYsnE57qZqkZ*>X+WU)qCWo|5HhU%Yo0#@XXiCg7;>LaIdp{By|7P|LYxx z<{Yv2qMy|+z;@8|Yo-$v3uIRYuLlh`189ZJ6 KT-G@yGywqMm5e0- literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/lime.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/lime.png new file mode 100644 index 0000000000000000000000000000000000000000..d208a45780b48ceefce541486b04a583aaae2b57 GIT binary patch literal 441 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFeNBb~+k!CVb<}Mm3Iw@`@8KmFe%FGJ)^q#2FhNt$h1ZW&PSuik{yu zJzBl}VC{~q@PsQn7eD;9SX|PX?@G#+E)AfKswJ)wB`Jv|saDBFsX&Us$iUE8*T7iU z&?v;f!phj#%FsgBz|_jX;F{~n{U{o8^HVa@D&ZOoOhSx|tqg$3MAyI!sNw5X?)5+o xQXm_G^V3So6N^$A0unRxO7#3(Llnx4^-T2)4Gg{%Ed;7!@O1TaS?83{1OWHUm^lCd literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/magenta.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/magenta.png new file mode 100644 index 0000000000000000000000000000000000000000..aede2d06f92348807680e44366ce4e56a4f3b200 GIT binary patch literal 376 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5I^pT!7-HeSbkafI zLk>JF>xH-$NN_!xsg==GFXga^q2l9nN9Ia7N$qWB(^y^Bq@-@%zFpk<`hlk%@{rO_|W(m$Y**Qa_R+kKb$QVd~nV#T>x3xy>4q^B7tbxi&K z|2{|4nTF~HzKhIv4i~e=UeP}hF3HOhK5_S4<_5Nu{eq&V530G>?q$3b`KT%_xN|Ph OPYj-}elF{r5}E*i?t-KM literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/orange.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/orange.png new file mode 100644 index 0000000000000000000000000000000000000000..17f56381096e0403b07f1cd3d60aefe3e5069739 GIT binary patch literal 378 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5I_2r&7-Hc+HOP?f zkb%JI?KgIRIOO$a&7YR?4Vx5qwcP4$&UWpH+Vtq2ARP0 zZ_F~S`M<6AtYo-q#PGtZdx3wzeEuxf9rCtaJeDP_H7fP2D%@vITFu|N?e7ZvD_{5O#+|{`91y{u!!JiJicWgd1$QZ7?eCuEC zsjD`hE?qdvmBG5=9pk5jy9a06IsQAff-$yQ@EH$-jly4%xGxM>i<{Q(pTfUWLHsRq TlF4eIuNXXC{an^LB{Ts5*)fc0 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/pink.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/pink.png new file mode 100644 index 0000000000000000000000000000000000000000..6dd845e2cbacf6cd3c5ee51be63fb07afe6fc7e0 GIT binary patch literal 373 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5I_l}-7-Hc+by6(X zVFRA#;`$qfRnrV5s^7g}+_ZhoeDUg4hRLEGE4mi_xxn@-Sz4`Z!Taf{d!}VqWW2CE z%U*Jc`_5@rg%Y!c^A>#1yTxs?KX0*~WhtwjQN3u2*&)&2Z-3feUALO2r%aXm-^T~( z?0rTLXL(-jS#V0K;;km{zK#iE4bIa}o(T?L;Um}1THIf8L@V3<%$E-_^0PxCxm#{D zeq;K+^?-2?`->&>6#k#8P}nl-&+VNI8II>>2LyB9xz2RnVB57@(hJKowwynf?FaM_ NgQu&X%Q~loCIH?KjQ;=t literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/purple.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/purple.png new file mode 100644 index 0000000000000000000000000000000000000000..3fd0bd115312c9890fe362f01c3bcfad2c2ab9eb GIT binary patch literal 380 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5I^*f$7-Hc+b<$nl zLk0rP#zMO{FiqaT#S^fRMZY86%^|75rmb%Ios+h61-7OfEtPrhp8KG#l1Etk!t=wq zG5zO1T)0p?i~q$E@g38-9bV)(**da z+?uNM<9PG7X4%w3rju7mI!-nHa4T4|gVYbfXnY-5o%(UU-ekS*^BlKF|jF%60 z+L^7~B*w9k=`HKK?8bBn^9!D~j{l~9bjUFMxxJY2Lem`ch0DZttY@8|B3jpYCU literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/red.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/red.png new file mode 100644 index 0000000000000000000000000000000000000000..b37bd466f65ae14142ca8a46fe2edd2b2cf0c834 GIT binary patch literal 441 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFF=L1f$!zS85X?T)PQgeyB2Km4^=T+*5EO3Icl4WNyxC9V-ADTyViR>?)FK#IZ0z|dINz*yJN zD8#_R%GlV-&_dV1)XKo%n(N8^C>nC}Q!>*k;TjA~LX3>941mZ)*T4*@;p!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85$UTDOw0rb<5MmF~q`u>4c5E zPKG=##*DmA^)n+5+CJ466b;_MDkQyuA-b+&n%=G%0f{H?PyhTh>A#p@?r)aR3d=d$ zet*4c`5~`<$<#SoGv(D+8VQ8+#@O#@arAO~YAO|S&iLH>FMGevGH^P+Rew&xwF|1p?}`7bXRSM@ zvvWcC0b|~okFQ+FHeyhocl5en0*^$fO$1x$e4vdI8|I%&FfaJ~fKBaALkaVtug$YJ i@Ep0$8KS&sFQe^IQO$!UlIcKSGI+ZBxvXg)KX~xqnKNhp|NmeAH;^AF%~%rT7tG-B>_!@hljQC0!qIkbY88;fS>O>_ z%)r3641^im@2t!R3Z{9wIEHXsckMOgYBdmWiSJ0--D&QTIQNfWPBF{DZjO8MK6PBP z6Cb`kb69Y*KHr8NznzZ8oC)7Jvr&y>p}gXROJ(}|r%d2`IdR5@M=RgHR9V0FlcMMM zOOIA>KUljXD?H)K&czRZEf$w_=DU)zrAq^7qiTt3L`h0wNvc(HQ7VvPFfuSS)-^EJ zH8ct_u&^>VwlcKPH88a@Fu3M=azBcO-29Zxv`V-J1CtOVV=Dt7GSM|K18Vqsm3uu< ygA~Yy;QX|b^2DN4hJeJ(yb?V>*ARs=V?9$nLj!{^MGJwd7(8A5T-G@yGywpry_#GA literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/yellow.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/yellow.png new file mode 100644 index 0000000000000000000000000000000000000000..3871cf871a9ce8dadbbce14e7b511de62000568d GIT binary patch literal 441 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPF|Nm!sU*-d)8B2ovf*Bm1-ADs*lDyqrINI(_tpaj53p^r= z85sDMfiPqHot61O!8A`7#}JO|uDym_tp)-v@f}IKJIy^3=l&7QDP}p?&2dlOr;clO z;={LR4hwG9=i9L3x6{#>GvOO&HmY$flvkW^sZ4+WlnHzCx)#2Wxj^g(qCux%lC)#p06Ad{R4s9hC`m~yNwrEYN(E93Mh1q)x(3F& zhDIR<7FNc_R)!Y32Bua92G?9q?nlv(o1c=IRteW&U=m_vY-IpMCb|Y@Kn-87a<2z! xkOJ8doS#-wo>-L15RjOeSEA?V8lq5UtY@lcXkhTAXdzG)gQu&X%Q~loCIIc;nb!aS literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/1.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/1.png deleted file mode 100644 index 0bc8ce4340a56109702fa25f3a59539c2a83471e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2942 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 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/2.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/2.png deleted file mode 100644 index c1c2d6d70476ca99e1db9162e843c64d18b74ca5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2946 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 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/4.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/4.png deleted file mode 100644 index 2cf5601ad46822f75e4b51d0d411e24f4af9abed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2942 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 bP^q-w=P4VXvoQ}-{w2(fZH#K6uF?MiC}Lrf diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/5.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/5.png deleted file mode 100644 index 3eb6c342b02d00084be149eb2d645c51b0d90201..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2944 zcmZuzX*d*m7yr9t-;yQ7B|^g3WoO2|hS7|qtTQAHQe%n6zFv~-ji~HPBBKd4mXKwH ztYgU@!p+hs%e?yVe!J&+e&=_dvpvr_=gUdFVq?m|D#Qu^;4n8cvOi&iKVW7&(G@-c zGbhC2Z{~Ct0M3#>po^a>#{j@;>jQ&bx#Eop!rb-7_=}mtU}FA(7?jU#F93ok@eXLX z!z#Znb!Hc8nSgs@iLvKn7PE&Y<9O4hWW`yyEfU0wCiv`HPa7LE2zM7I(5I&2QuyrT z*ppbtnHI&Lr$)a>Na{J53wz-^+Du*UKW-S)TdCT?*AFm}nAx+;RP5An?B!6=(_f>z zIy&bT6$~O-CH(<6bG@hd-6IJ)upgnLbLl*Z={=we9%f?(B3k>C?i>Y^Icvyd^;81qP5HGCjI{Ia?hD6D1C{ZmdJy5q z=(d|A#L?|v5juy|y|3@*B_owxB25|gzqa-5S{0ugc+3*xKDC@?df3QDI}{l{-(l`f zM9T6m*zp9U8s(+zC>Nhkgg(Cb@xlalo|9=9qLt5;-dvMuday1<(zmlrDjl~K6*}9YuP@87WO($xK3~ON*(p?ewTiwe zanEDmHI{)V(wM}e&VYrAxrrK@A+3-$<7Q=I=Ok56PqJvR(8t)dNuSRsvwS1yxez~m$C1;Wg)o4y`;Lt=#`^v==dVf ze!8p(ep)T<8nn8IVE@W4zU++Zy*$nSXnu3c;_By_!$RHy-c+Ag--6zqp3W4t$^MKO z>RmPcmi>)>7t78O#~0m|fR+)=Kg)C$Er>n)D#xlsa5!183$Cc4w4Sq)%ax09M9LCm zAMmC3ux46hN@WVmLg3{UB^5IjY>qpQz3{a18xG+$CXOl&3*{_dvML=b@K@FygdNc3 z+GX(-=rRmk|7C>JQ6i&LyH&d_?4@1d>zfPBonmYrg7v|2;=UY}arYwCI;39rPdvCU z+mv%8(v+-QQC_48Q?XD%)Z6boLFqFs77G_O8DT%%Dc#H|cz**|V1+52329mReJ&hw1V8foUAkw=j%2K7mt>@{lh5jW zR13i9h(Nk1KkQ&G?FO)7w@kO}xtMg~pw5dClYdOOQhYkEFGw!wn%qnyZ$tt2Cy(lE0EamOtC*dM)^x9HETx*2}zZ@mh(~ zCZYLG>@`iNVx;3WmwJ9ZL>^{h|z*~J1UmAjwYyJ27LmIn3No@FZf&Q?X(!fYea4J#554@f$q zdaSmw7+XPg+Y-?GsTcTcL2p4vV@7$#>1Lk>sj<7U*R~x~a5Hum_E3W6NeiV7f>PWC zIy8M^q+z7T6NFe%4KF7^V~w4fzbyqN<~oTC2sqyT3oG7N@S{kkiRN zoUvCTzKwona$9ywZjWG>j*X8+#ObH{Cm@9em9o{agHy1(vqry-vW#Z((MqHCd>Kj4gk>i)~MgP{eJdvV<&zdKhL%hCXfT^cJU7> zBDd|vmhzV?@W^Rp8CWIQTz>MeA-8N9f69gJGuR8MtRZb8ZRqomLG{6eaoBZPQJZZu zS?kcp-_x7bLL@(`6w56UW2DO;HCu65P3LPB@aNqZ^HbKZiI+tGJW!`e^hnKNuHGeE%^q&CNn0>REPFLpg!~`_Go5R7F_Dz z=&SFcJkof&^^CT`)5bIRm{1&NiI5jTF1J+O(yY@72%)ep@SVC8ca^b9=WP-})^EhN zas!cF6VW0SYV8|&qqQfhwSmreoz0PTDK>n4YHY*B771~hZE*V?hZol4OH8War3hs6 zJsg*r3SJV9$Mk&2oqF=7yt0GnIe;2MtuD{V7dUffRb($`bKc>Yn0&)Ad-cu6-cMr+ zB)eaR(iBaA5np`JdE4w&`ib1Htq*?*--Z8%t8WfXH@J=M-x=H#4r~6Y`hA4r+)O>v z`}CgTNatuhf*SEUFh8iL>enPztnOzW__+=%Fd)Z?31RI!+-LJMd3FldDm~8R+eS6nrK=JVN2ulq=;q zA#BBiJbQ}^v-OTUXl}@umb{|ftWCbY{WfU3jSo*Ko4W=Zh7+*q_z`{Q{MEAT5lXj+KgSwEc#yh diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/6.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/6.png deleted file mode 100644 index ac6a20a1a54998df40963ac3f79d6e8e85743cd2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2940 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 b9+^xDaCOo_&yvmV{!JL`Tj*6noumE-0x?}? diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/7.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/7.png deleted file mode 100644 index a73015de9d685d0b730dd84d7b4f200f19b43dbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2939 zcmZuzcQhRO68^bFZxJOTT)nfp=SlJa4-4YQc5-ns`ZRgt0(>5N`1tY~!C<_;{yy%W_uT*pn#Ee9 z;MN=L8l;5-s7V|;!^FpmjhfdAnuumi6&B~CVK$EAE1F@m?6|C_N5R!!7)PF*j80;+ zl%!9fou*pldzlu!sD5L<6LoUuM;HDIC6nXk}9H6mBxuImhE`yJa ztS}YuUU7@l1s-akdgNAu9zeH#%9kg<%576TNa zz_DLIAP7X|0#^M!g!&JOTIO}}i%sR$tK$V#^e}eRQhrnjgfx#R!H7eGRmtfur#x-x z&fr{5IgA3+m;H|b6sEFWOuK&?L}08X5R{T}j1E$pA1KfHot;k%3|cU@kTJSNv%R0MVRG|56!rONNPkpDChVMYeD zFOvY+Yw_v$EJ{s|_J~{>2|VA`IyER10%&)mG(Q0D>IzE32OG5dr~%L|#E94Fa2<49 zm29WH-f?NJgYLvpDGDms-3eue(z>Fr`#XwNM?ghmhU>V+9U-5!xfR+iJz~;*8KpaI z-Z5(UGW~X6gn0iZ%&-9Hje7W+qDE*gopIifE^HSIg z^FR5&y{3_*RJ8u7%7bY(MHAL1)Bf!$m3;So8R_0G=$jjoH0drwZ}_X}t9q~1-Kr*U zi9d81c@s#%g3)WIQKATh@;dS87$QxP=F^7dyw?R4F3-{^(~w75c8c()mz%s5Zod4h z`>L~?Y%J1HQecuLW0*Wl^iad&Zn=%xem3lx{h4IyS|5 zR`caW@XLxRx1lvfIIGu|vE^439_6VFN3t84l+?V;9KYtl;X(3z{VkyR@_Z(bdG;s7 z*wBW-x9o4^2Z8hqF>H~2aVSyF{Hs(~QJjHSU+0*Xa*ii*_Q7S8Ww&zHbD45|Y>?tO z@h5DlgS45(nZlV|;t+U6WohL?C7sQ_%@91L;;waAt-g)C^-2ZJ=d3E5O6<)oYc6Y4 zg<5%RC92#9uJtP1_B5W-w#&530`|(X@QuStYcDUI3ui-+B%c>URm>xdVz=;{;h86o z#anVtxmyx7Dl3XqVDiTDhz6_u40kQ6l^nmL=K!M}Z`{4--th-{%VqB#Prg&L5 zd#}o@>?~xJVU=Z-!B(46?RFWqv`w$Y_87yc(`PJVFJgd7AzZ?)ThCa}m(iB7n`x*X z)=F1;m2efc=mvgxP_~m(@cu5kz|^N~A-HY*_w_KyDg4y?ciEuC%RkIAuCzFGZ!|N7aib^#9RkO7iTrUlCmK?)C017N!*D6E-p1 zG~3CuGQ*dOm8zMlnf48T9DX@GnX8zuAv-0vp1+(T4 z4zBe<^lcT}5~R)TI}Q3Z*cze9mYSBb%Vl`;bn~i$NmN(e58ME*qKUI^ZJLr;i}S{X zIiZ|6P)$9xT|4P*>0!-b|D0-2F~rU=R&n3v4uAO8pH=mi>Ovmj`Hogt&q3A(1ce-7 z9+{S3!Ce^=>-NN2=Z_npI8gY9k^6Cp@g@;N(%G8Q`CPs8{cWqp0f&BfmO{o3vH1=8 zo!jNa*E>o(o;$H~FFq=~5G$~ifB31ZANIv^ZB&cyMW&3`Vs*F$%mRaITo-`2KvEGk zQ*})xft4huT@KBkn*J|VG*{G>7vvUf9X=|zH}y9SS#-Z?-3EzigEmfl1&-$5douop%4x3I&L`}q6M-87x|MzD#e5CapLMp+N zG5Tisx5-abPG6l8yTa*3qGO{GF)QnWZ|={NXo(J67NdXyW&{ljqlph{L%fyD6k z$A&@TGv(*IFV44FI$4&|a3wJ&2q|vl*S6|=D)s7q!9>~>wo4K*whekPzF&MyKB~ST0Sr_=H+kB1bmc z(`nJUpf#>opTQ5ga~W?ds=D#6Bkp7F8($Zs3hWrODzm?4Gd^ILnSIN!ccLSvulo)LOdEUD$;Hw+Fx_)_RI%;nu37d%x3zz;i=SX~s z3te|1EZ$@C*==SHSQ^tiPh3}PRU_E%y$jf@C$3#VyhG%@R(0^+4A@jZOCPuBYkA(1 zSBtmz!taE%HHNyAHn<9u3G)YS!9Uo~CnpM2H0Im(Lwra*q{Bt_`EY-cQ^HWoOrXe4 zO{+z#!-4j;&J1imc0$YUY;JmY?&-buz{35}IRg@9bmYic>R}2K>{3c@%1{hL%vQk- zO%;`8E&tPvlQP(d>xggx$JxuXp;``hNchpj))ZkhXS67LFFXB%_mh&-&Gs$M*Tmk= zUY_>@LGrS94{jZAcLdG_a_<%|GFhxX;e9H4?(yr*q4lS-<8;pS^m7XGoc$9Qc`4$> zzsc)jXk`XKh!6niNC1AFU*HA+k7NMYbOb;(2LKMAG>0Dji`r5nT^)GP?Dtt&Ml>(| zrJL`6oFQrx{RE_EJ%ZZ68rz_@wN0@~DV;E!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob~0yRVEpRo;uum9_jZC~ z))5B*=I{UKmnAhH$n@H&a&f@NoR)ltr-cKLKmlP zF+6xlWsz=Xa??^zm*`8!SiC29Y+KUHIZaJ4*HcZ`(bn7>*3`#3{%yXzgYTPlfR&@V)9RZpJ#tr%lJL- zS010KzsRUn{qsMj-R(=>?|FPiJaFcr$(8kucbzYl-z$99y~5|=$vyiIoKw7cKf?M; z;pESgueU2czstM9#L`v&?sLX@>=kkiboMQo;oJZCD{EQf;$n_^pAuj)VeoYIb6Mw< G&;$TEi4z$B literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/channels_01.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/channels_01.png new file mode 100644 index 0000000000000000000000000000000000000000..eb2e0d23e445201a5472e157ce25e11b78000598 GIT binary patch literal 469 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob~0yRU{v*VaSW-5dpqGG z*I@%5=HLJA=dQiS zHNRlJ?u+cl!v40IYxSy6Zb<~X%7FWIoKfzLWC@lthw{A5`fS@A9j>}EFbO=^mhu=R n91_c-z`#h9)B$0Zp2w_{rhPK1{h#Cs3|0nDS3j3^P6!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob~0yRU@Y=xcu7)9?TGcUN~a-&{GR+4*|{uMN*igR75i&YL_hJR7to_+_VJe_9kn^EL*JYb(DT znc!}$+u#_@Ao4n-D(S@HnPLYP=rVMbYS|h-x#+{4a6ydWsMXYY5}z`bu^MD>HzdvV z^5>~Exy&T7h1FrB-%|B9n^~ERJhzw@L@d7~>@0V-#+{KrG3>(j2i_oy>J$5Z)opCr z#~KgR_PfJ9n&JI+rUEbJ{pgpQJ44OnefM*a=zzvzW}+;AntsLJyOa1 zdp7@OPH}IYSCjP3ZOxm;^0NAdGb=XiKWO(V(0F}_H#Y0HFtFt^2GG`*k8J7~Zupt< U?0LGf4H!oZp00i_>zopr0E7|Gu>b%7 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/channels_03.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/channels_03.png new file mode 100644 index 0000000000000000000000000000000000000000..5f050f28e322d25878d9c1f89552a6c14b7b3d12 GIT binary patch literal 558 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob~0yRV65|WaSW-5dpn_V z)!_gR=imSB?}l!?e7EgTh06L39PX;3d6RSRmz(}ByJD4m_FB2n0*_;iQv%ry(%0Pl z<;Ns)(xSoW6~nV0)9Cx24N8*i0dBGf=4?!RZOs{=@|fY&3g#Kc*K%sr8M{(s93)E_ zijU1&`(DLiVh^*%V!niP5u3lxWzm>a$dG!4@r-2lwtbTsT#fb%9_XFP|M)q?%t!Gv zTKCD{`ABJys2tWCYC%W~Lk4#lwHi-pr)i{RJ3b44$rjF6*2UngBR=+I|24 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/channels_04.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/channels_04.png new file mode 100644 index 0000000000000000000000000000000000000000..e2f171d7d5e789d5438c218e71883f16763c7357 GIT binary patch literal 477 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob~0yRVAS<=aSW-5dpqGE z7n7j~^Y{PtyS8oOHj=KM=yK3TV$%`lvogs&CXZ)qKdG_FB$!bmhVca1jL-5+X36(> z_ZxNT*gyPw<^AOH!}I57zEPK3+pzgRFXJkc&&5oa%6|(hRC(8Zxi;JSk-5C@{alld zdn*;oU!RrzIJ!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob~0yRV6^pgaSW-5dpp4~ zi`kKfiY{PaEik^VCU@KC;@Z^=tQrloZ<>9)k=B(L%c|kP zc<0Qv&f{jmC9ky}@N-ve?>uvv?NHh_Uz>kzzn6SZoM$FrwmJ9J=fm!z8~W!fD9C~g z`5n(%Bb5DD@o)x*fiz}dkX$Li(@4(2!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob~0yRV9fS(aSW-5dpqf3 z)?o$_r{DkW=jyI$irBvV>5`l{3(=kl8nrUV3)zo9ejRtkh~p~D4F;__S&}VTOgRjq zep`8*Oc~7@xRyt;Eu6(5?a&&m+Z^EAz`Nkk%4v=()DEx(JPbLl5F(twyrN)Ls=zAF z4U8ccSMeLO|KR4c<$vxn{<-y8{k`#ltJmXxon*W47;Mgi`}`lw=GcGPTjSDj@ALfQ zcYmInzvJ<_?MW#QRX#Jk*?Q@m?DXy!FEKwO{sVE^Z|@ZDJh2ocHT|+3(}S9ymHISw hIi3J`;LBzqC%@;9tjfh-w?MJY;OXk;vd$@?2>?I|$CCg6 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/channels_12.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/channels_12.png new file mode 100644 index 0000000000000000000000000000000000000000..bc1beae816cc9a226fdafaa553f7509e07b755c3 GIT binary patch literal 503 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob~0yRV08C%aSW-5dpjwR z>rj9IbM=4k>uqoKKK1-7)tYr+hfwRRgSq#=Ti@8OT>Ev~dM%-7CYJ+i*19;vhpKF2 z>1c?I?rhk%$|HwUfN}FSA;#L!i8q84n9_1pnSQNO+NkQla^{v7%a>5sB<}`}8C$1v zyjb0JWEz8@LAJKwg>cbMUB@``R?=N_ksnbcbxf^9{hPz$GDE=M>S)7 zbKHwPe>zxAp4<0#&-=+~bKLpmo}M^|;;aXY((4}ey;v#n`oYw%zZr7wyhwj{BI`-e zwS(HPzw00W%fVn!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob~0yRV9fAzaSW-5dpjvG z>u`VobM1fc-DVNp6=8p``Z%p>UD+a3G4aK=_rI-gY=0a!Rkc&mfqlldWt&tCSza() zz7{e~rHw&0;nu8Ela2^1VD^a)j+`XHRML={t>rD`+`wm$>znGC#BqUf+1iylo;-|J z2ez2vHROZ-j$40@edl{H-ERMnIgD|&FE2Lp71VzF#~8%%;XV5giF5W}?$#Y)s=8h; zSN?pq|ATTHulsAi0Qo$3=H}Zq-v6jkyZsXPi&*1=@_j##Sih?gP1fDBsqX*NCGv~~ mc6F4xk1S9An85h$E&E^3U5i=|1-%2t41=eupUXO@geCybp3KMq literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/channels_14.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/channels_14.png new file mode 100644 index 0000000000000000000000000000000000000000..a014aa30f4b6d7beb34d9be85d67615d18791f98 GIT binary patch literal 529 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob~0yRU`+IMaSW-5dpqf% zA9J9H)9?TGwtQ(GJk7B$GZ)`^!m+SBd`16bi@1XyE!MBp@#JMRa}e8pYSI;f1m={& z)l?SvpuU5v_V|6-2d}rD*T0wEaDU&o7bn?v*j4{!&}I4Yop}%MFX#Jjy;)wowCA_o z`;+I-Iro>lr}ACco%X;l-;R0z=fGciOPRl{liYE6_W1+vYo_dre#x-+8!Lxh{i|i0 xR7_cJFht(b@(yxt;GJ-EE$s!&B_CAOFs$_FEXYmTGancw44$rjF6*2UngDot#Zv$P literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/Cyan.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/cyan.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/Cyan.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/cyan.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/Gray.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/gray.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/Gray.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/gray.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/Green.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/green.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/Green.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/green.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/LightBlue.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/lightblue.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/LightBlue.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/lightblue.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/LightGrey.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/lightgray.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/LightGrey.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/lightgray.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/Lime.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/lime.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/Lime.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/lime.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/Magenta.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/magenta.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/Magenta.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/magenta.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/Orange.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/orange.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/Orange.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/orange.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/Pink.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/pink.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/Pink.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/pink.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/Purple.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/purple.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/Purple.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/purple.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/Red.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/red.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/Red.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/red.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/Transparent.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/transparent.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/Transparent.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/transparent.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/White.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/white.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/White.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/white.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/Yellow.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/yellow.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/Yellow.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/yellow.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/conversion_monitor_dark.png b/src/main/resources/assets/appliedenergistics2/textures/parts/conversion_monitor_dark.png index 8affc2651889fe6e1c426dad9276ee29dd4fd495..0d9a49ead9006b32321b82898b0fe1d70ffa56af 100644 GIT binary patch delta 70 zcmX@hc#CnuYFt8k1A<4?jwL+-(hls!x8xclk ZW`<)IFt8k1A<4?jwL+-(hls!x8xclk ZW`<)I!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R53h;Ds46*QE+INtX zL4k+adIk4R&+Q>CHdELP11&bVdr0qnDjuR0u+m|vlOXf^Z}%!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R53iNbw46*RPJIRoX zL4k+)cYys9|6krqFDM>WIFcupcVcNt;OxWE0V^GrI&o^V%T6kN+0S~W=XIm_ijW0C ujb5x;qANl)7XIxCJhs4j)4$j9J8~z8ta4$pdVUUQID@CFpUXO@geCwq5>Gq; literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/crafting_terminal_medium.png b/src/main/resources/assets/appliedenergistics2/textures/parts/crafting_terminal_medium.png new file mode 100644 index 0000000000000000000000000000000000000000..aea3238540b479b7b51efe1b4ab11b6a404e7b02 GIT binary patch literal 281 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5%Jg(`46*Rv+7rmt zV8G*C9-#lkx9o78mSoNmGttuq9~6%5-S+uK^ofm4GTJ9TdM&!wmUzfXt@*gSTB__C zrVo>o)0pMU4mI9XT=nliBcIEI!+sV4FB3%1&pvWOu&Jv`x=pKSjl%KwU&@%b9^raD Tovl0)XeooItDnm{r-UW|CQw|{ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/export_sides.png b/src/main/resources/assets/appliedenergistics2/textures/parts/export_bus_sides.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/export_sides.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/export_bus_sides.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/formation_plane_on.png b/src/main/resources/assets/appliedenergistics2/textures/parts/formation_plane_on.png new file mode 100644 index 0000000000000000000000000000000000000000..631f561fd7412d2d101a44d53ea64bb6d31757b8 GIT binary patch literal 306 zcmeAS@N?(olHy`uVBq!ia0vp^0t^g{3><7g)~=v$en5&P-O<;Pfnj4m_n$;oAfL0q zBeIx*f$ty)Gwzs}{T3)FRpJ^^5}cn_Ql40p$`Fv4nOCCc=Nh6=W~^tbXK3jD*~uKJ zYMrNxV@O5Z+q2$W%!(qc7vI$HZ{kSOc;U$LGsAj!7_a=D&vI+GUaXd1eKpEmGnIpb z;|YUx@;q)3eLZ*Ab;I+lEG*|(?j2WAa9~PjoPP{NKWDfPrqdbrgXy0K_8W3?OmHwW zFjiw^6gt70239`vz^NH5EFKE{5wepT7&ucH%fYHG58MT-X4?Q!%}{pCMqEIEgYi`b Z6QgwXriGLC1p-~p;OXk;vd$@?2>`RgT?haG literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/formation_plane_on.png.mcmeta b/src/main/resources/assets/appliedenergistics2/textures/parts/formation_plane_on.png.mcmeta new file mode 100644 index 00000000..4dcf4d63 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/textures/parts/formation_plane_on.png.mcmeta @@ -0,0 +1,23 @@ +{ + "animation": { + "frametime": 2, + "frames": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15 + ] + } +} diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/identity_annihilation_plane_on.png b/src/main/resources/assets/appliedenergistics2/textures/parts/identity_annihilation_plane_on.png new file mode 100644 index 0000000000000000000000000000000000000000..e21fef78a4561dfc6b7a0d6e184c5ba2f3891e08 GIT binary patch literal 337 zcmeAS@N?(olHy`uVBq!ia0vp^0t^g{3>-{AmZ?FaB#>fBcl32+VA$Bt{U?zX$mcBZ zh%9Dc;5z`qj9J$@Ie~%_C9V-A!TD(=<%vb93~dIoyNJ)dOjoW(2dqh8U qMcyN_;;2Pt#8HdPh@%$SIHV2ZUzcgm0c|k=0000)dOjoW(2dqh8U qMcyN_;;2Pt#8HdPh@%$SIHV2ZUzcgm0c|k=0000F!Z!Q}0 z9xxC%8gN;2va^7V{5eC53cj`#-l3@FHKCEUY`gJe!+;0OYKEQP53O(H eWnlRKpPAur``73iHr_m-u?(KBelF{r5}E)kTr7G3 delta 218 zcmbO(_D)Q(Gr-TCmrII^fq{Y7)59eQNIQTq2OE%Fm05UiqvCw7`k9_Cjv*Dd-rRKL zI$*%TavF!Z!T@* zWl$7gKB)WGN?}Rs>3y=ZEOi-06~4Hz@XhH-Ik{p^3;Q1y29byjTyGdztpawlrY-yJ r;Cz+8hvU6ph5Zg5AE2TC|1&cfusse-d8NA;$YtbP0l+XkK0Vpn3 delta 225 zcmZ1?_Ek)=Gr-TCmrII^fq{Y7)59eQNIQTq2OE%Fm05UiqvCw7`URdYjv*Dd-rNf0 zYETehJy3h`@A^G|zs_V)ZT+mbpl=;V_O9J&YA2sI+?_k~^UbV}K)u*NgZiW=;tao6 zaoaQAn^Q1p*4>Ii_B*zW@%I;QpS)_8mcgsPy;bdAP@NU;WFPcT5CZYcuo(st+u*_n cB>(?sW|)y7*?fq-))pk{>FVdQ&MBb@00G%Ur2qf` diff --git a/src/main/resources/assets/appliedenergistics2/textures/items/part/level_emitter_on.png b/src/main/resources/assets/appliedenergistics2/textures/parts/monitor_front.png similarity index 55% rename from src/main/resources/assets/appliedenergistics2/textures/items/part/level_emitter_on.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/monitor_front.png index 747af2a9bd8d3b43e6bb7f547b3b1bb9136b75b7..c5c2a4c1edaa8f868bb93b8996ca72dde1ea2609 100644 GIT binary patch delta 87 zcmV-d0I2`;0rUZoq)#T(O>9%^!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5vi5Xw46*RPduk!$ z0Rx7^8~*(-aX-Ri6chN{=Gng#{n|~_?QVL{f3wv8+a>ktmy`E?IT`m0B)tFO9R9ZN WeGN|)<$eH-VeoYIb6Mw<&;$VQ@JxjO literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/monitor_sides_status_has_channel.png b/src/main/resources/assets/appliedenergistics2/textures/parts/monitor_sides_status_has_channel.png new file mode 100644 index 0000000000000000000000000000000000000000..adb4c26f22672af2af4bb041fe1ecf9c9681cea6 GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5X^gUf1Ln>}1{rUgjo>`7za>|jV4V{fn23ZWEJPD3nT1ks0 lo9QLU_!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z_$#98Qbry z%m)femAFQf1m~xflqVLYG6W=M=9TFAxrQi|8S9zq85+8Ob}|R5O7L`X46*QE+hfSZ zV90a$*MI-#QOyUMUtAK_Xl9KxE*4(nD(k&LtW@V<)Rm1a*@4G}5CS&OJLBcgn;Y}ui3_Leemz%f?*kImJ#Ukst^-{kdiE?0 zn5Ru~scX!I|KL*Bm<#{GrLHj-{zEF6r%h4$N6)8JGEbY5O6F;^Y4E0J=UD3okc{6U TcrF(200000NkvXXu0mjf^vN{p diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/pattern_terminal_medium.png b/src/main/resources/assets/appliedenergistics2/textures/parts/pattern_terminal_medium.png index a4616154e20f1523d11a4ccafbf5fb808aa2008e..cd0841936e34e97be31b1a760c17ef1bf5c106fb 100644 GIT binary patch delta 113 zcmV-%0FM9n0fhpPn`%`_L_t(IPukImJ#Ukst^-{kdiE?0 zn5Ru~scX!I|KL*Bm<#{GrLHj-{zEF6r%h4$N6)8JGEbY5O6F;^Y4E0J=UD3okc{6U TcrF(200000NkvXXu0mjf^vN{p delta 99 zcmZo=`p!6Ec8t5Hi(`m||I(9=Tnq|4M;!kDf9a*Kgn;Y}ui3_Leemz%f?*Ft8k1A<4?jwL+-(hls!x8xclk ZW`<)IFt8k1A<4?jwL+-(hls!x8xclk ZW`<)IbP0l+XkK==>3M delta 90 zcmX@Z_>OVH>|i@j7sn6_|73}@2lgTYNzEB+7}jucaBOrm$z`}9rEuW*G42JgPM9|& uF>LLq5qG#cF`wZmL)JxxT?q^f%*+g>rt1U$x39Ei00K`}KbLh*2~7a(?I3yp diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/terminal_medium.png b/src/main/resources/assets/appliedenergistics2/textures/parts/terminal_medium.png index aa70c6203c04ed413c79be063ac2f81dc1c08242..bd779cbbd8f4cb7888b3ded5303f7b223db242e9 100644 GIT binary patch delta 90 zcmX@Z_>OVH>|i@j7sn6_|73}@2lgTYNzEB+7}jucaBOrm$z`}9rEuW*G42JgPM9|& uF>LLq5qG#cF`wZmL)JxxT?q^f%*+g>rt1U$x39Ei00K`}KbLh*2~7a(?I3yp delta 56 zcmaFIc!qJpY(p7O7sn6_|6~bPW`=*vj8i=2Buo<`Bn)maFf%h0%#we&_v_mL1|aZs L^>bP0l+XkK==>3M