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 000000000..6c9ab3daa --- /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 000000000..a855496fb --- /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 0956a2606..7ef6a667c 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 9b3a7e103..688da9f2b 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 03c54de41..3f552620a 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 bcc27f8c4..7984d1c8a 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 2ff5e2f4c..5518b1057 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 000000000..f2f13bba1 --- /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 39369247c..e463f672c 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 0318fa8ba..cd1cd5095 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 bd81a3d70..57d4b7dc6 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 dc30f51b4..666ac1855 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 000000000..2ad8ac2a1 --- /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 fee8e31b9..d37250317 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 b0f0cad51..9f26f2b22 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 a0960a4c1..18df4ab39 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 be3261f0b..91d6e52b4 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 5d453d2e2..04a61c4e7 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 000000000..f8a5ccc8a --- /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 000000000..5296ddb33 --- /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 000000000..d8fd2390e --- /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 000000000..2d554affc --- /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 000000000..5be73927f --- /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 000000000..ee4d7e9a7 --- /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 000000000..69b646cd1 --- /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 000000000..9c162374d --- /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 000000000..587f3b55d --- /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 000000000..7f44be68a --- /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 24e8108af..000000000 --- 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 4c03c9d8a..000000000 --- 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 7c4518d7a..000000000 --- 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 694708b77..836f9ad11 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 577573578..000000000 --- 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 0aa797bee..000000000 --- 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 4f2664a7f..000000000 --- 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 cffcbd6b5..000000000 --- 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 a6b60ffd6..000000000 --- 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 bd45579f5..000000000 --- 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 993b281ca..000000000 --- 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 ce9186ce6..000000000 --- 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 575dbea0f..000000000 --- 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 1071173f2..000000000 --- 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 26921c918..000000000 --- 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 6b5fcdec4..000000000 --- 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 bcd041255..000000000 --- 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 e065c55fd..a08b9fe2b 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 21000f06c..a82dafc58 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 fab12bca1..71e5e3655 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 c143bc5b1..a7687e37c 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 000000000..01acd833d --- /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 2718d666a..76c7d3552 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 728032056..ea3144c63 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 8fe1d371b..f942eeef0 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 fc4026ba9..0b740b1a5 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 000000000..14542ea70 --- /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 a225af3ef..805cf1bfa 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 85d2a3af2..d32bbc62e 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 ef74cefc5..4f12b5d89 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 8fe9d3f55..a7d73581f 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 000000000..efa12dddc --- /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 a74451249..9c2a43b36 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 3f8563072..4a5c0b587 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 b17ac8ead..827579e3b 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 826c7c7cd..4affd1434 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 af8b4b6d3..0cefa194b 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 c89870412..3e1fd5d8e 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 62a7f89e3..7e475695a 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 68b233a5e..30ef521ed 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 b0acdfa09..8d9e800dd 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 e547b1f2f..56973e858 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 c1d941932..1a5c4bc34 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 000000000..719a96a03 --- /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 000000000..286449cb1 --- /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 000000000..614adacb4 --- /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 000000000..7e54f0262 --- /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 10b54f180..04ed5b61b 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 1020c9c11..bd364ea73 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 d2fc5d056..9d5e7fa25 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 00f1b2ca6..0611cf5c3 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 2cdd4acd1..96eb33362 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 3fdbcf375..da3ff53f4 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 ad110aec7..80b81e059 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 000000000..8d429294b --- /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 b97b0adba..229319938 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 afa4cc187..c2c898bdc 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 6ca1494f4..37cb31402 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 b104945e7..0354bf848 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 00b6ce402..9c84d6d86 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 bf9b17f43..3fe11adeb 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 ae846c43e..8b69676f8 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 9cb1887e8..01e75859d 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 4f1829f07..bb6568b03 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 f89b5d627..15b137d54 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 9ba778f70..866ca039f 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 d52912404..00928b14f 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 e7786372d..c5eb48fac 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 073ae6da4..6ee453de4 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 9a97def45..b7a2d5416 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 6ba84edd2..f47fda283 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 4bdcf4086..570a45a0e 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 83775b522..471d73f89 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 ff419faf0..55ee2c62a 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 000000000..ed1ee471e --- /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 77823edcc..686aeefed 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 000000000..c6b5cca22 --- /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 06d830dfa..c58b440ec 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 000000000..210b5a4d7 --- /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 ed2c7dd52..c9b3490e8 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 8f88855a3..c2955f1eb 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 19c02a10a..bd552b821 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 0a3c14060..e0efd79a1 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 27800ef3f..dbc9a6f2a 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 2ed75e354..364c49ed3 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 8eefc4da4..fcc8e5e2c 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 bc14502fb..545c0d4b0 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 89bb254b8..cbdb818ad 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 daf866735..7fc254a4b 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 121484ec5..e81c58078 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 d90909ebc..4c1f9cfd2 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 219fe154b..33d3d4fd7 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 11f886665..e2037f920 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 30bb24002..77d2c3656 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 099d588f3..000000000 --- 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 774c00f34..8edc45dbc 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 bf8b2dd2e..55d5f7486 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 23ccfab64..9bb15f75c 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 000000000..7d80081fe --- /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 000000000..a9be582c6 --- /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 000000000..065caec23 --- /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 000000000..63df02cf6 --- /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 000000000..c6deba83d --- /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 000000000..bbe41dbe6 --- /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 000000000..1c81b57e7 --- /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 000000000..1c4b568c0 --- /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 000000000..35a60abcd --- /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 000000000..742f4c2f4 --- /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 000000000..0b01e4686 --- /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 000000000..3f7afd331 --- /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 000000000..30001604a --- /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 000000000..c75eadd42 --- /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 000000000..4e26ceabe --- /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 000000000..87b8b259b --- /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 000000000..30001604a --- /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 000000000..c75eadd42 --- /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 000000000..4e26ceabe --- /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 000000000..7afeec005 --- /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 000000000..c2c5f8d81 --- /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 000000000..aac6b686b --- /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 000000000..5c6d3895f --- /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 000000000..e646e4b20 --- /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 000000000..c8ae1a5bb --- /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 000000000..087397905 --- /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 000000000..93229e6e1 --- /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 000000000..331e85b78 --- /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 000000000..a155e7ee9 --- /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 000000000..c2842abde --- /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 000000000..adeb4f5a0 --- /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 000000000..0f889ef14 --- /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 000000000..f10edbe2e --- /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 000000000..613d237f7 --- /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 000000000..196fe72ad --- /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 000000000..fd8f8cf9f --- /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 000000000..83e531caf --- /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 000000000..e8618aede --- /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 000000000..b31d314ce --- /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 000000000..f2f6261d3 --- /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 000000000..53b5b3c85 --- /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 000000000..f3f78e373 --- /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 000000000..f20e68330 --- /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 000000000..b0aaea849 --- /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 000000000..7a7857663 --- /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 000000000..c1cdcf1b9 --- /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 000000000..0c7de6157 --- /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 000000000..2e89eb656 --- /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 000000000..a37b225ea --- /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 000000000..18416f0ad --- /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 000000000..de6adca4d --- /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 000000000..c2c5f8d81 --- /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 000000000..aac6b686b --- /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 000000000..5c6d3895f --- /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 000000000..a0ab249a0 --- /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 000000000..f6ce711c0 --- /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 000000000..ad9e94436 --- /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 000000000..c8c6d1346 --- /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 000000000..db74f5fc8 --- /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 000000000..510ed91f1 --- /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 000000000..44b6826f5 --- /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 000000000..08bb605cf --- /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 000000000..20cdc0f2d --- /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 000000000..6a0e4c0a8 --- /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 000000000..07ae505cf --- /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 000000000..deec78ecd --- /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 000000000..9ea773382 --- /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 zcmbQkv`K7&%ESbbdM^J=XXk)`jQo=P;*9(P1y5&Zg@U5|w9K4T28N1TbA!`Ef?tZ+ ze!us{$-ARrig$jHD2GCjQ+I>NL^Ul%P64kD#f3LT0}l$iy0S>0SkS@T*VoV^8mPn5 z#dU-IiQ=NZ=EWUdr+z=IUYvbx&-Z6%|82c)_k7Lgxtq_kAK>7bR_|dPXxhND(n(J6 zLG$q=#~wb>b7d=7!LT(K42iz{-6Jq z)65vgh8D&HB@->YIT}P59IE=9mN7WEF*eMdp%%=rfQ2F9baK*Th5%iL1oir7ml+!7 z{+L+Tp1z^7(~*%k61F?&}A_23{Uf5*sz`9 zz&Qc#O$;173f3sABHCsdOzeTF=STf?c7nFYQPTR!q zu$5uK%Uj`}3qYacx^TkIn>U|6d2+++h*Napsqor=>4)MEg#XR?S!eU-`_~8i9;q}M z#WuRL{CIHa%om@fGUq38wj|wo*6&{bXFK=*KeCsVj(8^RjL;H!94J)S=Q6A3v(Zwe zPNzwlM^!KVPkD4-=Qp$6eN%=FS$2%o6LnX_CNqEYRu_mUIq>K^1H-4?`3J9Pa4P+ti?&?$RQ^IC$5wRnW6;EHBC+$ZD%*gY9;7jaga4R5SY<6xqwgaQ0NXm+XDVy zi5&9|YV2v`WN|#fA)KgqtAjDAD?+)CLwsiI5524k8#^I(fR~~QPZEcJ?@568aD;n)?eY->b!G>xm1hWBJK+*C5E&5#TLxI zP_#wLw#RJY^9!pp_;2;wIUhGT@Ir#!_(+a{-m$|@8!dD=CnulYsI-P>^)aapVQZLo zcYaMizpMQxYh z&m$5^Muzq65gt0q*M$0o^#!UsoR65R2z5FesqdV?6tqvYKAHRE@Dt-F(oYmWMRUzfawuH#BlwX<(5Wmh$)^HOO`fu) z&MQ44-9^m%Am8hZvX} zzMk=XCjZR*&{xaP2y`P~+go zD><)BTOGP;Zounc>EQJGmDVfTSEaAW53yfT7x}l7E%LC>VSnc(feSXqKi+dpfje1p zbA^s#Ht*`T(nixGY8%hqtSQslJ>#$J?rz&vD;HWi8+#dtZw~rACC#4w@r=SBb4vU; zpKC0i{<*H}p2&O6N1D>hOni14rp9Einl^n}#A=V#fveqL?=@TZcKO_8dtK{yNB(Z) zb3E>)9;5D_-hYmD?(^WA!FQK)Ef@2(wfeeFZ&mhE>4m#p%J=6je>Y>^zPN^YKKaY< zRqlQMOQu%;Z^+-=U(3I`^F*+1=22n0&2vt|=BR05zKyK@@!KB*onsF>I4@0{nmGMo z%fy`*Z5Cg3>viMr$vhVGSmkl-Sx}Dx^>0@_K?0w=@^0hGbVb!Itb7ya!edz6q z+w0$%y~}*perNs}llhwSB8`hL96sUvAn@r$d+zyD4YKdAsq?RQ_HRtz`dnE*S$|^q z+Upy(FD+m7J@LJ`-8Z|U`H$@$+nC=ox)&LL#{9tc6WdSwAI_f_-+JGbFfd-#Ydz*y$+h*x$6a>FL3>iWw)~OjxV< z{rQY@6VGMxwFcC^xORa(@mYOh_u)Do_15;*@HYFtf{qBOi-yxp%P-z>F23*b%VnC& zz1iu8{+8=?y-c<2R_SHg+%n%~vdjLMURvats}XY}JafEdEcLY3ndRl|yZ`6y=k`Z) zA8|jf7N4PiBDSD%;kiR!T9=Eh)DzONn&#ls;b$@BgQI}f3b7v5Pr~J@eO#6Ghhz_> zE9qY}yV!BVIYvv)?~{j?Z`GtX6Ze=_svI?5s`GSbi~7n5dwh6(?#{NFCpN20A=k*( zYOi7Qq=^#>omMIOPTrROD*ahn+37W@t(*QG&FkK-FE^F_WcKC>Ygi+7xwbhidl3?) zab1gjQ+jH6+Wxbhr!1$fo~M2G?U~J|ZcnH;pYwkH|F=SigdR@XwzSPVTvs;Y+1@o- zmYZw}D{pf>7G>3L3u9Yjv!iR9R_;~*)o;V6udCauR^^-B7B|w(R|ZZO@B6>FOT=;tu4Iw!?wKr`pxyW{`9jNw|6&hbKbdlzs-(4smo8E zJ8NwpvLxh7$gdEycbD#NO}zdi@8Ub@>OJ2~-dw#Mz32O1yOaBFhcbrxUQN52`rGsO z=I{3FI#<2?G3|G5>{`Fv!nennFERgRSLWMxedm>{vX^W_g8Hx3Yrl5qJ1)QP-`w}* zy1Zt*p}ljCJyI@kseJPCJLmoHa=ccz%6h8TJY>HtUnZL_tDogG>(eZ^*}=1ZM<+$^ z@;_sD@!G3eCpElioDjdEeeAara_}o_|uWbHJzU+T|_nh6c z*6obR-ubR-@7C(H?=Pk2nV-A+WpCw2vH#bu&aK3}}!{++G0`TW0$U;Fu;S^H=9 z*Pm|VZF@b>!p_q2k$utMmw%Q!pHDfjHc$NDqJO8?iHqsi{kZ!2`niiUE-sw@Y5L^- zxiw4wzB=$)a{cXNhmOhZJ6U0D822UY_uGTzcgkhoFTT(3|D;BtUgLkp&y8P$FD(B( zS#t8^|18WiKL1HJ*1gTZz@U)q5#-CjP^HSi(9q1lQ2+Bk14F}028L1t28LG&3=CE? z7#PI!C&eFiV_;y2^>lFzskn7zvLjc60T0XPy+1?eO^#p3F36mdKI;Vst09QCzGynhq delta 237 zcmdlaHiv0~iX}_Bqpu?a!^VE@KZ&di3=9g%9znhg3{`3j3=J&|48Ir{7#dzMFq9fF zFuY1&V6d9Oz#v{QXIG%jL`Cs>2B{L)h?3y^w370~qEv=}#LT=BJwMkFg)(D3Q$0gN z_s>q|3=9l8o-U3d7XDW!J90G`@UVQ|`%mlqN&VH;0>`H4%GsXgo@Y0+71 rb-SVO&iXAZCItp>e*8Tj@|oe_Mb7w%;bGfn zoE;B(`E<@+v&>)E(0lz=VT<|shTiYzWKXiJbNn3NaFqG*d=J6n$2K0|zPICm_@^0) d{e>FrIvM|ue_1v~nt_3V!PC{xWt~$(6991&Tw(wK 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!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#NB? zT^vI!{F8tD|8MUqv06bBj9Y`Br2m>P(X)nqHRDyqY5&vHDi72u|FHI&nV8+7ruZLB(Z5AGRH{D;z1y;3Mw6ujAf_I1O8JEcJ_~+82ptzkWf5Bv?c#Y$nPj4K* a&Nh|rt-fE(+9wPQ3=E#GelF{r5}E)|RaTAw literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/green.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/green.png new file mode 100644 index 0000000000000000000000000000000000000000..b6209a2426b8d7938aba1bd9a053a58508c68cd2 GIT binary patch literal 296 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#J!% zT^vI!{Ezl-Zy@A2BdIN9v1p_CxMAj8E9!=!-&OaKIqoJ|xgloMXgWbbZ zJnPOR$bB|bV9LL9ps4r8`;!WKA{Rb3UOgaq&xBES{tC9t7FA(Q h7FCh^pU%Lrb+f3^xBb&X7#J8BJYD@<);T3K0RZh_Rj&X5 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!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#MOq zT^vI!{Ezl-5FN-UOD;LhS-(bIlKJ gL4F#k^3m)M>XfU@-nRZ=U|?YIboFyt=akR{0Mw~g$p8QV 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!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#OlW zT^vI!{Etr9$lGAR!(uEi`#VJ`EWvPv-HwWvx;h&?9SgZ?c4%iXEaN!N^)TY#-Z>Ey z9p@Tc*qE^2@94IW1|xelslexA3wn}^cUTw7F@MYXBOY+6@#XvsgGB*;toH(rv+fh< f6Fp?ee~aO(fXFHfySL&D3=9mOu6{1-oD!Mmm(qGt{JYDViVWq;ydm$R}qAL%e+SoX8*YN$w0 z4#y@r9_EBu{pTzin-be5q%d^w9%4>sFjBk4(8VlxQy_)svdgD}S+ hgD}TOAM4o|m|iomT`Bl3%fP_E;OXk;vd$@?2>@R4TB!g4 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/pink.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/pink.png new file mode 100644 index 0000000000000000000000000000000000000000..363ec0a8ce8a3cc834f0f3a06f18a62db536e4ff GIT binary patch literal 291 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#NB@ zT^vI!{Ezk;ay2;cu)P2Optz=+BT4^y1jntl%Q{jF3p&Nbg73&!Yckk9JjJu_j6?s* z*MbN0?i{$tf8%(ofH>Ek$2*PGlFa)X`nK;9lJaDIvgkwn0U^E$`*di(UQ@{Lg!zS;u&QI1_lOCS3j3^P6{_p*YPuaNGIt5c1d_I3XnjT=V zN%2IL0Z&8bzQQkNTy2t0lNc4uIQZu^EYQ|$l% literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/red.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/dense/red.png new file mode 100644 index 0000000000000000000000000000000000000000..3793838284c8aec50c935d2295760d714b9783a4 GIT binary patch literal 285 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#MOr zT^vI!{EuEZ$l2h)<8m=1NmcCWO{+C78of#-=Qr0~r_?7(8A5T-G@yGywohm|^Vz 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!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#OlW zT^vI!{EuGP$a%nk$0hK+edlt671!D14k^cYI20%`c^6K6Br0}C{|0+kDRl1dX&U|?YIboFyt=akR{08Ii~vH$=8 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!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#K=C zT^vI!{Ezl+zopr0G+g4umAu6 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Black.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/black.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Black.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/black.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Blue.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/blue.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Blue.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/blue.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Brown.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/brown.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Brown.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/brown.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Cyan.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/cyan.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Cyan.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/cyan.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Gray.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/gray.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Gray.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/gray.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Green.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/green.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Green.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/green.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/LightBlue.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/lightblue.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/LightBlue.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/lightblue.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/LightGrey.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/lightgray.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/LightGrey.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/lightgray.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Lime.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/lime.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Lime.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/lime.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Magenta.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/magenta.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Magenta.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/magenta.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Orange.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/orange.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Orange.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/orange.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Pink.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/pink.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Pink.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/pink.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Purple.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/purple.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Purple.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/purple.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Red.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/red.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Red.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/red.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Transparent.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/transparent.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Transparent.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/transparent.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/White.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/white.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/White.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/white.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Yellow.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/yellow.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/Yellow.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/core/glass/yellow.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/black.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/black.png new file mode 100644 index 0000000000000000000000000000000000000000..be8d1cee889a586def18c7c07e03501fc626260a GIT binary patch literal 366 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#Q|> zx;Tbd_%EGo$ah46hvla@tEuSz2dW_}E7T3$l*xa3je6L*Lc?QmUN7gI z+WX!1`JL!&=OUSHj|!8?I%MQ2yuKFtwa}f#eCX4N~3=+F9D~zfaHjFVxBX zLTd7yTc@gZCvEGlVOOwN@A|0yLfKwMfhLRH)82d&cIf?7|7T9}f5r(#p7on+x_B8F P7#KWV{an^LB{Ts5ve$tq literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/blue.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/blue.png new file mode 100644 index 0000000000000000000000000000000000000000..e59e547ecdb37b8d1c6ef3b2f8e4bcde282ba6ef GIT binary patch literal 360 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#MbV zx;Tbd_%EFt$kk%N<5Il$*YoM(w+>ISZIhqp`a!@@xJ+f*g;P=z(vQBFW=#p|s^bq` zbLRQUEvv3Y#hwUUtp7{4p~JkI;n=s&-a1P1j4zHqyZdRsT;p=*dycCE*#jRv3+sM) znPck_ZNL1Zyn!oJ;}T~FvQ%`7v83G7W0=kOl4;X6jvbs^kNp0pdd%PHr|;s;zV>Ic zW`37a@e}_f$I$pyN+m{M&N_7l7Db`sLYr-w3Y7oq*FRsRp1A6jt&v=~CIbTlgQu&X J%Q~loCIF<>ezyPs 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!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#J>i zx;Tbd_%EHjk(bGk$91y^t8zHx6#^YjvNcY>Y(Mjam!FmQ z{D^bktzUm=l}N6O(VrRoGjH#S=Z_VaPw6_b@?`p7R)-s>#T-8Fy3f|2JLx;ar^|mT z?b|suiu`6W^v~-%#j>?ZID%C#>#h0enp^Asxt#sX_G0Um1lO~l*?Kco9V9=BGgaJE zYe-Y@Z7`q45O&4p{h#R>|AjiaUr0@!GwZpmxaV!xdrSgz9xHux&e*+-fy1#W*1K#s id%)s9#`e!=>}OV48)Vy1JfDGqfx*+&&t;ucLK6V+--`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!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#Q|@ zx;Tbd_%981Pfjpd}=#ZxD*Wf$&d6F9si`@!L!usdPr3;wDe z+uw44f$7+i9Y<}&I&ZgDpJ! zx;Tbd_%EI8$aO@4$93<#av__>@`9J5y9ys4oKrb1K1eV+<3YdTzddb!ul9WZYteUZ zrA^C);&Xea7`gcQ+P#)%I28Aep)2Y&=LXkL>J5KPwqHBPsZq3VCPV+czGEz#=c#Qd ziaFC|_-)E1-z#Bp?6uRR)~r~&$1gdG)4=UdJA?LnF$d!bx(TM!7{acE-FvTp@t>-Y z_yton%dJztN2%nB|KxKhi0eMWzwm7pvjR(DneNTE>J3s)|NpT3{f~L^wSDUYzkM}g QU|?YIboFyt=akR{0N;IwcK`qY 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!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#L1^ zx;Tbd_%EGo$alzq$F*2g?*OZn@e{E-Tq}jSgVr556>1fl)YNyIlv=ze0$_)&76-TR}A zuIF_59=v#~V6Abn_<>-?l!OOn{Phz&Ivp0buvM7~q+E7>lJimg$(5`-%NP!Kn6PF{ zTXA#k)dT8zJ*o}`>$;CLUnt8JR8SH66Se8KEhBH&{?AtK bznLue&Xv0vzO0ggfq}u()z4*}Q$iB}(C3U3 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!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#MbY zx;Tbd_%EGo$alzq$F+EGO!MLm#r-^M<}^)gm2Nn4E=+RX#q~|1mQ%A{nqT|=efn*y zrPs2)ZF~>}x3PO@@6W$s%`2x zqp&ETW5L6s=zj{6JDe1qc#Zi)dT%->$$yl7QlOlhmdKI;Vst0FD%dg#Z8m literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/lightgray.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/lightgray.png new file mode 100644 index 0000000000000000000000000000000000000000..ba16a837cd67cd758acc43c8988be7b6bb6c0c49 GIT binary patch literal 361 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#MbX zx;Tbd_%EI8$aPeK$7S!lc9ED}AGr3ma+}XP`hR|^-A|>cjD)NiKFb#No~yp^tvNUN zXKAc$%Y|Ss<|hT0BL5mFNe}n6CVf81lJTX?Ky60htOJJv zX9y<0v3zcSBBgDyfitfkuphV(;AJHA>P{2ufJZ)x;v%V ztonY>nqSH3yKkJ_mb-dE+vIbvXEQ#WWz2l^y4=|Vlefl6me?NFul~l%<#}&2qm-@e z7G9=l(iSRGg4dg>8+??6dO3L4SWMWmto=yoQK2gZ%5SeUB>F64Gf{SX-DhD?(`h2{ zp+P#czurx@e_eM~mcx`k_DifnoUU&@-S9%~}C*RKCrT!Pbaa$aX(ksl#o?R??>Ff zAMf`%%IjqQ^xef;^Z6#9KYp|L9P5*UOILp-Ib1n9uhFTh`^gE1s#)>*|9u%w?o4f3 zp)c&xqqZVZL@8s(Jh}P_o-KhL0f#%7ml{;b+o8+% zroQvzW(F>k3?I|&TV5+=?mkh?#`1iZhfP*dH=|%>1##uFjinfA6~d z_vGOz*goS+!OSvykFs4as@X(d*Gyl22WQ%mvv4FO#u8Hjh6rb 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!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#KEs zx;Tbd_%EG&k@K(tkIUY9?XTtH6gE$BdRgww?(sjy{vfNX#O{QHN4rYOH9991o%>o* ztF`>o^W4?<-^O`svK3`Ls@x|ju+P#cpksbgVVZ*7qjK--@{O}QZnDUAy0J7p-Wabi zxx+=-sVS0IrT3-crrsNeK83w5Y-j5*l$5&A^P>0m>c+3rU)Xm#FgG5Xvg5d|xaVzG zJ0k^)^RAB`b^n(TcywF&MDN{sk}m%q?Vs?P|3bUz1I-<|N(>AP44$rjF6*2UngCtK Bfhzz2 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!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#Q|? zx;Tbd_%EG&koS-QkE^Xv_LDPQK8LglP6%#f5kE3haDv344^4HcYcy7dc<aI6KaNc>UI%UBvRb#fd-9 z6q27Q9Lh*BD6q8ouP~8k@x+CVk-Rf<+&b>))HTnE>bDk2keIlT;cU;myK%fZ|2sZT z=P;3&;LH1c$7!X^-6!0cSe|e4ut_THWl*fEW?i}QwsGT``xW9{^$f|TN17M5T&ZPX PU|{fc^>bP0l+XkK+2w|a literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/red.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/red.png new file mode 100644 index 0000000000000000000000000000000000000000..b2470e730bcabadcb0854d6c2b217e99699023f2 GIT binary patch literal 378 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#L1@ zx;Tbd_^+LOk=MzP!}Vtg7rSBI&+Aj?99G=b(ENg-PHOvsIIfoK6TYc>6$Lx#FMrY* z;+441R$}?nnmtCBXJ)TedJ+^I|D~KkDdrr5-1l_$oURk$3|~(tuix%>q08dCkAhsS z>?`4(C|?1WBEuKX>dy|RDz8+H6Z)l*+aVP2NLAYSRQ!<+U7iV*%Nb0VjaXBXB^9`~ zp84J0FHt8Xt|xu>*p%x5-h1|W?2A2-&fsEQJ8=o;!rNQ98v;0vZatEx&v+~2pZx!G bt@~e=tvT_}{jM+r0|SGntDnm{r-UW|KBtDv literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/transparent.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/covered/transparent.png new file mode 100644 index 0000000000000000000000000000000000000000..d72371017f8d44e695f6c8f80403f1f30590530c GIT binary patch literal 304 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkG>W_r3f zhFJJ-op6!!fC7)pW)J({*IhSFeY|7oTTb?sF-sQMRxI$WVL5wu_M$15vewGZxyti` zNzKfN@$hfCMkV2%Kk7fa4%#&xE0xm^2;O|mR9QsfTMLt^wdeywmEgvx?k0|`tg^qt zp@Ij_nHGi_FW{bW;{*%O`)ZahAA?OAAIg~bEwp0}IUD1}z`(%Z>FVdQ&MBb@0P1RE Aa{vGU 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!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#MbX zx;Tbd_%EI8$aPeK$7Sz4^RFUJ)%h2kcN9Fl^nZS;-A|>cjD)NiKFb#No~yp^tvNUN zXKAeMu^Y}D%ufm~MgBEV$SF);uwv^ywrMK%k{C4DO!|D1CF4t(f!d71SqBaU z&X^eV%JRAWiIld*2F|?dd=|Z#iXSCDN 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!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#I$C zx;Tbd_%981BHw?FA$o^E{WWM}NK<+8ZvEP-9I?K}cmPKCM~Z+kQ6n*2R^f9D6bl_HEOwJrt? Q3=9kmp00i_>zopr0HW=HJOBUy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Black.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/black.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Black.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/black.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Blue.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/blue.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Blue.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/blue.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Brown.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/brown.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Brown.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/brown.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Cyan.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/cyan.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Cyan.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/cyan.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Gray.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/gray.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Gray.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/gray.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Green.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/green.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Green.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/green.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/LightBlue.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/lightblue.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/LightBlue.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/lightblue.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/LightGrey.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/lightgray.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/LightGrey.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/lightgray.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Lime.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/lime.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Lime.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/lime.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Magenta.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/magenta.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Magenta.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/magenta.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Orange.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/orange.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Orange.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/orange.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Pink.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/pink.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Pink.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/pink.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Purple.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/purple.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Purple.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/purple.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Red.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/red.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Red.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/red.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Transparent.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/transparent.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Transparent.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/transparent.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/White.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/white.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/White.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/white.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Yellow.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/yellow.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/Yellow.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/cable/dense/yellow.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/black.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/black.png new file mode 100644 index 0000000000000000000000000000000000000000..6c9d898dde7e99dde40f718d78957a777ee1ced6 GIT binary patch literal 441 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd7G?$phPQVgfdp969eo`c7&i8E|4C$JU|>*4 z_6YK2V5m}KU}$JzVEDzrz|io5fuYoZf#FpG1B2BJ1_tqhIlBUF7#J9&1AIbU85kH^ zT3XW5(yXnmySln2OqgJAZ}0E#|NsAgZ-coP85kHCOM?7@862M7NCR<_yxmKLIwr~ N22WQ%mvv4FO#pirkkbGF literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/blue.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/blue.png new file mode 100644 index 0000000000000000000000000000000000000000..e7913f6f7401958f1f3d120a8c89cd8ad8c99f70 GIT binary patch literal 441 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd7G?$phPQVgfdp969eo`c7&i8E|4C$JU|>*4 z_6YK2V5m}KU}$JzVEDzrz|io5fuYoZf#FpG1B2BJ1_tqhIlBUF7#J9&1AIbU85kH= zz5X9~=zpNs|6{NJzj*yWF#LaD%m4rX|1Woo>0)4DU@Qsp3ubV5b|VeMN%D4g;b^-z zwTgj(fwRCPvY3H^Zy5+Pw%=Kq&%nTt=IP=X!g1ZT*O05#K)@xwBWZW1xkuvMKY}^M zEC;(e?#cVqam`MA`1Z_U!Oi-78+QD5IvR5(eB;bUHI9YyiW4rC>F=L1f$!zS85X?T)PQgeyB2Km4^=T+*5EO3Icl4F(1V)e_f;l9a@fRIB8o z)Wnih1|tJQV_gGdT|=V~0}Cr-V=F@oT?11q1A}X>C- zwlXl$H88U>F!*|vdp!dKgA~Yy;QX|b^2DN4hJeJ(yb?V>*ARs=V?9$nLj!{^MGF}i P7#KWV{an^LB{Ts58aS7e literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/brown.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/brown.png new file mode 100644 index 0000000000000000000000000000000000000000..3c4247c5817e579efd2750c6b7adebab409fe56d GIT binary patch literal 441 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd7G?$phPQVgfdp969eo`c7&i8E|4C$JU|>*4 z_6YK2V5m}KU}$JzVEDzrz|io5fuYoZf#FpG1B2BJ1_tqhIlBUF7#J9&1AIbU85kHI zTspCRT78k9>GL~RKfHKc9b!2%%j^ID|1y{VY-eC#U@Qsp3ubV5b|VeMN%D4g;b^-z zwTgj(fwRCPvY3H^Zy5+Pw%=Kq&%nTt=IP=X!g1ZT*O05#K)@xwBWZW1xkuvMKY}^M zEC;(e?#cVqam`MA`1Z_U!Oi-78+QD5IvR5(eB;bUHI9YyiW4rC>F=L1f$!zS85X?T)PQgeyB2Km4^=T+*5EO3Icl4F(1V)e_f;l9a@fRIB8o z)Wnih1|tJQV_gGdT|=V~0}Cr-V=F@oT?11q1A}X>C- zwlXl$H88U>F!*|vdp!dKgA~Yy;QX|b^2DN4hJeJ(yb?V>*ARs=V?9$nLj!{^MGF}i P7#KWV{an^LB{Ts59Kx0e literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/cyan.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/cyan.png new file mode 100644 index 0000000000000000000000000000000000000000..84907c97afa690894904c303e8fb67f677400238 GIT binary patch literal 377 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#L1^ zx;Tbd_)iTo_uv`A)v_0#K#o6R8F5I86{>Ul0N6L1V?h6i05bqE46c^Gl`peP)#1)DWk~;FKwOZ<@Fcw9~PGcB(IRtHaKnd$kloWr=l)Hn@*ejpXXf0pKmLl zd*OcO$m?Glnjc19V^)+}5a|%lJ>#I2Lwi-zAML};POCc$^cc1%Jda(mlJ(2h2FW#P bY5HXg1oi%0yH~)#z`)??>gTe~DWM4f)kKM5 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!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#I$E zx;Tbd_%EG&k@v6ykBg*CC+8;S><^RW*}Olmxv|S4F!1W+H8F1=2YN(bka%oR%yqxo zK5Om8!@=_|*Lbw^-S~dDO0uEm+l^SpFVE&YlU-1mmS&Vv+HynIGW4~yLb&3b)mzJQ zZi_M4G;Ghgu(jskD)*awRcgPZmP@R9-f2?3yL-n)?|mE{OcR=Yd5Zs*v}{*9+LYbD z<1LgVVJCtzQMbelo}iJSn}C TbH|8*fq}u()z4*}Q$iB}9>a_iUEZd2+`zB>M| z(vw-Fq-Nf#nQ=eP*2eSSwW_M9ns>Rzqn&TZzPxLv8J=uD`HpMB_1b&SWEWJXr5U*} zYRp$CbN9RYi}ggP#FJZd!@qvI!N%afeyVAep4gwui*wj()vd$y+g?>Fo$Y(4lvgrA zpJ@@plLX2tDK+A_ c#ADuh8yo{o9gt?8)-JJCLk&A1n|E8j?{qBmnj>$cT&uG@X z|GQ$V8^3?0-)BWxtAzXIuTvR5-ApcLy)e6YR(Zp-nKMsLxGI=b{v>2=enU)a!Mba= zHs(e%d|*4 z_6YK2V5m}KU}$JzVEDzrz|io5fuYoZf#FpG1B2BJ1_tqhIlBUF7#J9&1AIbU85kJ; z|5)|&e_+jjufP9~efs~R?|_!@hljQC0!qIkb zY83+m180FpWHAE+-!c$pY`?QIpMilP&C|s(gyXtvuOU~ffq+YVN7C+2bC1Nie*|-i zSq^q{+>`gIlL@a>tyf}8dEHthKAbTsBn_{N!yY8(sY6(?LO)89X30^iGtGd4V0 z`SzvC`n8`FJ-=Uiw0ir&+8tTp30HP5e)wy#xTG`Rm6R=A8Vn2!swJ)wB`Jv|saDBF zsfi`23`Pcq#<~W^x`sv}1{PMv##V+Fx(23J1_sw$Pwq$2kei>9nN|tcU|an&Ha)b5TFLtNzwkLyW?^`%nPe{5;=i?j3(sO0sjUdVReWxf3EJ(szGEoHx;sOf`h?zMXv ZFGW78N(=6s%fP_E;OXk;vd$@?2>^fYf}{Wd 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!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#L1@ zx;Tbd_)iTo_aC-ZV-5(Bly;<|8rF_FC#a%78dYiLdJEAr{x@UP#HH$Isd-l=@ z#=rCYOLzM2W!oFGOl$sc>pd$Ot{O4Cu;ZqPOV^!trmR7!(gNES0wHW!`0%Z d_4}vr?^F zdg`8O*%cWtEYGr+T;jfSnpL61Y~j2G-}7#9o9xe9tY=xuYG+h0nqqcH^!MAJwpZ7! z=IJR@<^K2aK{|V%(ZgAuS9=zmlB#&C$-A#(f>?v|w3BCo!&msowX+uYR~*sGc0cpw zLyY|FkVx*98;#$XzHdEX+{6B2$vlPsrz#Y-%=&YCCqstgx!D21+;^@soj2Ha?UwYy Y@{BF#k7fHYFfcH9y85}Sb4q9e0NxLb{{R30 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!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#PlY zx;Tbd_)nd5m-mo?K(n#X?hQijs~yscR_^^oc0Rg#WVO+VZUmZ}j{)Mc2hGkNCjbpbPN__&|R zee4Lm);Htj!<}|!D>sR8Y-D=N`YyXMUBdi=r>*0^sUICOOn+`KX1vfe$9&;3u^sDK f=OyN>-KyW+^>gK48@8Pc3=9mOu6{1-oD!M<=Dm&O 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!ia0y~yU=RRd7G?$phPQVgfdp969eo`c7&i8E|4C$JU|>*4 z_6YK2V5m}KU}$JzVEDzrz|io5fuYoZf#FpG1B2BJ1_tqhIlBUF7#J9&1AIbU85kJ; zPr3MCuIfL7&Ht^J{@;7{pUL(=htvQ6|IgJ;1nFli3GxeOaCmkjje&uIG0EHAg`@4> z)G7uB2F?PH$YKTtzGWcH*nVeaJ_7?onx~6n2*-8TUPG={0|A%#j-=h4<{pW2{|M$3 zvmET^xF_#Z$2B|g;oCEZ1vl&SZP@YK>1fQE@QpJY)i@T)D^9pnroVs61iqIOXKZ-1 z^6g8N^=m&VdVat3X!Z7kwL7xH6RzxB{P5ReaY<*sD=AyLG#D5dR7+eVN>UO_QmvAU zQWHy38H@}Jjdcx-bq$R|3@ogSjjaqVbPY_c3=FQhp4^Y3AvZrIGp!P?!N4TM$k@uj z*vh~}*TBrmz~Jju?)3}|3{oH)g7ec#$`gxH83GbB^GfvmTtgJfjP*?Q3=Isv6fI<6 PU|{fc^>bP0l+XkKiaM5H literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/transparent.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/glass/transparent.png new file mode 100644 index 0000000000000000000000000000000000000000..78ebee7c409fa5cde0594e1d7281b1cc99ad5ae6 GIT binary patch literal 394 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWHrDUy2qoFfiQm zba4!^@LxJ%Bd?PokBc!Q?^FHEh=aCI^#w(PH?RsxZ(xY7tC*&@Yeqog$@|kkKTY~C zCYbx1CA7kF&bHrQuUdY{t6ws8j@C?h^_4~f;k+^SI~qCXH*A&`SSNp{#c;>m`E!~7 z$0*(ul8CwHF5Xzn)Zey4O*uG~;n)GwQ-2)2+@6|Bg`6`!_x{V?ud@uCj&IeUlW^^V z>hXKx|LR%m>x25Prazcjn_O7qX2Ql;<72?w7zL5o!~`7CK*EeWk>P`R5YM3;sS} tQ@hhp!hGm!^Xv^gN3L^*C@*4 z_6YK2V5m}KU}$JzVEDzrz|io5fuYoZf#FpG1B2BJ1_tqhIlBUF7#J9&1AIbU85kJe zzkh%G_U(Q9_I>{R`TO_p2M-=RbLPzd|Nra%2J$m7Fff(``2{mLJiCzw;v{*yyKuDK zn_9)dz`$AH5n0T@z_$#98Qbry%x7R=Nb_`Y4B@!$+H1(wY9Qbe-;uPt)7&F*?jOON zVwQv59QWjX>bPbnK74!Tu;6BWz70EmI~|QV6TWd~qZ-FTdBq8r%Jlb7nZWmQ;*1TC zR=$0yvVQF+MbGb-9b=o*+=85n%M%DtX}fk6snLvVgtNqJ&XDnmeGW?qS&pKFLhnX#U!o}q!km!gFX P3=9mOu6{1-oD!M*4 z_6YK2V5m}KU}$JzVEDzrz|io5fuYoZf#FpG1B2BJ1_tqhIlBUF7#J9&1AIbU85kJ; z?_2f1FYw2Ium87>{r~gg|IfhxX9EBK|NkuS%X|g~2F8*gzhDN3XE)M7oFs2|7ml`j zQ>z#l7&r?&B8wRq_?Ce%WBZ+z`3wvUX`U{QAsp9Tdkwi-4Fp``JCb&HntLS9{UexD z%yO`s#U-8juB2?~(qLdQHnuXf&^0i%GBCL2dU8LChTQy=%(P0l1_P52BV#KA zV=Ds_T>~>K1B0(uxz{r=Fi3%H2+mI{DNig)We7;j%q!9Ja}7}_GuAWJGc+*xQnZkP Pfq}u()z4*}Q$iB}?cSN! 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 zcmeAS@N?(olHy`uVBq!ia0y~yU~m9o4mJh`hEJ4}r;Fna-R}9C&vQ4QXFtHfGtI*|(6oVPrIVcCgXZH$jy-&$=g`Qd zQotaExux3<0_f3F`IFE;BUD{V}teks*4DqA25n zi3|$DsU0p18P*JI&WClmGDH|Kh@^QRv1GWR%V6Lcp60=@VLQWta{}C(7&v$s3<5h^ zH5pi{84^w?D_1bI%w!O8`xI{TQG1=hb1epjikX{icB)vqHb!&k7P5zj>&a=H^Ay(> zF-v4hoaLZ*sB)&HQKJd}gU@Fe7#2(v6@1YA`ESKJzIEr$ne}bsi`RX%pY6X=Qqtpp zPtUI|aA06~SW!-AK$!ao;)!p3#s zgq=5UK7I1!hSw3N=)_auwg1u&#UBX&oAa~I=Fj)95B5D$X*7y$bZ7bT;Lw>bK1*fJ zPvUGzy7R2x{m*vp|9@mJD;@Dn+8LoG@;Feau+L>y&u62hN}W!VG>@uY`k(UXzRquE zyZfdL8?x*et0(HNh)rhx=B+LeQF7qXcLs(}yYmlT(coZi$Y_3ezWo1t`@ilBR2dr5 zJSP=0FvPj2=!KlxY=4}Cfx%@#qt*sT=`RN*bPlk|9Av$7ko!-9S&Ng(kwZ=bPFyJs zGDQiRYnq%i+Rko})k@I6;vj2sATXnCasi*-q0k+CwgvpZ5;^7_)Y#L=$>Ml|LpV|K zRtIBJSA=pOhxp9aABqP(ScJM&6i#-C1S)w?H1#kH>IzW^^^pB!Tf}799^kJ-ZK7glHR-|Dw> zK5lT}g#^3tksJfPV~3qKTIg_2PCmU+X${ZnV^SN!)-dnx{F;1zV>ydZqw4`qGnR5E zg+w_=j|iU#zZ)Ja6l7FP1aEPgb27IC9#U7Dyuy2n+AhJLME}D8-DnmTud*=EVCA$RgPL=bUej)tQ>6h*=roUkR zQqIHMCfaNQnusv-zs_doG3wOJe@6TKQZpOTQaSii)@|WMM-242OOs)RkkiWUVmVb5UiD28z zqr!HZ=bVJiQPaYF8(ID1w?76t#~yZYUYa;Har(oSi90XaEWYa2>&D-cc`W9!%H!N) zxyKf(v8gGldHcTdeK#w}cjq$AW!65{KF80VIlJiWwV9@~Z4Iv*J)ix2_VwBKwv291H=cXr7%Oc-x+mqKCWf{3NA~Y&?v)kIaYgMo9Ub}m_;PRb*ll@lDyOw@< z!^dqWx2@bRx#8&zw%hBrnRA0@Uv^IyPv2SG{JEpM)4S=k z-gG;?+0w`Ep4j`utK@58?8B-{U+2!=Jp0hw6}Q*FGkcf$uKmvZGbZyj=S3P9UpRci z`9a{*i}u{}ry6A6UsLDr?BAHa^|`Wsvi`*IwbwUnUs}HEd*XX>yKiziwlTkF zbT2agjQN4>C$^vVKb$`=zV*Iyz4HH*|5g7lGAwUUWlU%8Y;S?Vr%gfn!|Igdc?T_X@;(lB$K12URY(eG1bBDgPE*D#=C!}LF z&B3R`&tl34M**!BVm+##gv(X?xGE3H9!gizzi4)`CP7Ql@s>(@cP`HZ8cA9R+&Psk*(EU!{$j7ClorZQuLj?E&Wycv$V3)Yf@V` z{X3f1yPFp=s`|R5@n@`=I zU_R&l{Qqx-4hcP+v~6jdcet)>#IwC?vMe{*6jt8mdMwJS-4@2S#%4#?Hm%&N{;S`H zPhVHJSFOr7yD{$IsiuQl8M9w=hjKk_t$lsx`rBCl2>rmX)iI>`XbIb}8-UvwOPpqWPw+n*MA$UmowxTU&VVhi!TL z^_%N${pn{lZtrg1=Dc(9ew!V8QkS1Rch=fIWJ$=EkY6EY?=Iclnt1(3-oR2DUt<2tuFSXX z`pzp?WiQ!=1odCje(lb8Tz=obx$nz$dCho3d*>W`q+H-q`Q+ty&imixc&%=g^;EBU z$bMPAOg3FsKg(&>r&(^ZgJ=DYPKw^;f5z_OwO9A5{1XyJxN28I!&9UDe*L)oI^fO3yPtclXQQ%8z3IuU(yI zX?u6?=c@egN56l)FLt-CNd51*)4Ok$tG`>j$A3@!7l*fwH=XacU$u|^cjw0YJM~!y z$`^dTc*p%aTWj03=E|P3=FRl7#OT(FffScPl`Y4#=yX^($mE;q~g|_TaJ7U3OpDVzc++WpYQ3#4>6*6&dK$2TK)-cVukRrlUvf685sWm ZXJ!yOB-fa$k-HD1%+uA+Wt~$(6967vT$%s? 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 zcmeAS@N?(olHy`uVBq!ia0y~yU~m9o4mJh`hEJ4}r;Fna-R}9C&vQ4QXFtHfGtI*|(6oVPrIVcCgXZH$jy-&$=g`Qd zQotaExux3<0_f3F`IFE;BUD{V}teks*4DqA25n zi3|$DsU0p18P*JI&WClmGDH|Kh@^QRv1GWR%V6Lcp60=@VLQWta{}C(7&v$s3<5h^ zH5pi{84^w?D_1bI%w!O8`xI{TQG1=hb1epjikX{icB)vqHb!&k7P5zj>&a=H^Ay(> zF-v4hoaLZ*sB)&HQKJd}gU@Fe7#2(v6@1YA`ESKJzIEr$ne}bsi`RX%pY6X=Qqtpp zPtUI|aA06~SW!-AK$!ao;)!p3#s zgq=5UK7I1!hSw3N=)_auwg1u&#UBX&oAa~I=Fj)95B5D$X*7y$bZ7bT;Lw>bK1*fJ zPvUGzy7R2x{m*vp|9@mJD;@Dn+8LoG@;Feau+L>y&u62hN}W!VG>@uY`k(UXzRquE zyZfdL8?x*et0(HNh)rhx=B+LeQF7qXcLs(}yYmlT(coZi$Y_3ezWo1t`@ilBR2dr5 zJSP=0FvPj2=!KlxY=4}Cfx%@#qt*sT=`RN*bPlk|9Av$7ko!-9S&Ng(kwZ=bPFyJs zGDQiRYnq%i+Rko})k@I6;vj2sATXnCasi*-q0k+CwgvpZ5;^7_)Y#L=$>Ml|LpV|K zRtIBJSA=pOhxp9aABqP(ScJM&6i#-C1S)w?H1#kH>IzW^^^pB!Tf}799^kJ-ZK7glHR-|Dw> zK5lT}g#^3tksJfPV~3qKTIg_2PCmU+X${ZnV^SN!)-dnx{F;1zV>ydZqw4`qGnR5E zg+w_=j|iU#zZ)Ja6l7FP1aEPgb27IC9#U7Dyuy2n+AhJLME}D8-DnmTud*=EVCA$RgPL=bUej)tQ>6h*=roUkR zQqIHMCfaNQnusv-zs_doG3wOJe@6TKQZpOTQaSii)@|WMM-242OOs)RkkiWUVmVb5UiD28z zqr!HZ=bVJiQPaYF8(ID1w?76t#~yZYUYa;Har(oSi90XaEWYa2>&D-cc`W9!%H!N) zxyKf(v8gGldHcTdeK#w}cjq$AW!65{KF80VIlJiWwV9@~Z4Iv*J)ix2_VwBKwv291H=cXr7%Oc-x+mqKCWf{3NA~Y&?v)kIaYgMo9Ub}m_;PRb*ll@lDyOw@< z!^dqWx2@bRx#8&zw%hBrnRA0@Uv^IyPv2SG{JEpM)4S=k z-gG;?+0w`Ep4j`utK@58?8B-{U+2!=Jp0hw6}Q*FGkcf$uKmvZGbZyj=S3P9UpRci z`9a{*i}u{}ry6A6UsLDr?BAHa^|`Wsvi`*IwbwUnUs}HEd*XX>yKiziwlTkF zbT2agjQN4>C$^vVKb$`=zV*Iyz4HH*|5g7lGAwUUWlU%8Y;S?Vr%gfn!|Igdc?T_X@;(lB$K12URY(eG1bBDgPE*D#=C!}LF z&B3R`&tl34M**!BVm+##gv(X?xGE3H9!gizzi4)`CP7Ql@s>(@cP`HZ8cA9R+&Psk*(EU!{$j7ClorZQuLj?E&Wycv$V3)Yf@V` z{X3f1yPFp=s`|R5@n@`=I zU_R&l{Qqx-4hcP+v~6jdcet)>#IwC?vMe{*6jt8mdMwJS-4@2S#%4#?Hm%&N{;S`H zPhVHJSFOr7yD{$IsiuQl8M9w=hjKk_t$lsx`rBCl2>rmX)iI>`XbIb}8-UvwOPpqWPw+n*MA$UmowxTU&VVhi!TL z^_%N${pn{lZtrg1=Dc(9ew!V8QkS1Rch=fIWJ$=EkY6EY?=Iclnt1(3-oR2DUt<2tuFSXX z`pzp?WiQ!=1odCje(lb8Tz=obx$nz$dCho3d*>W`q+H-q`Q+ty&imixc&%=g^;EBU z$bMPAOg3FsKg(&>r&(^ZgJ=DYPKw^;f5z_OwO9A5{1XyJxN28I!&9UDe*L)oI^fO3yPtclXQQ%8z3IuU(yI zX?u6?=c@egN56l)FLt-CNd51*)4Ok$tG`>j$A3@!7l*fwH=XacU$u|^cjw0YJM~!y z$`^dTc*p%aTWj03=E|P3=FRl7#OT(FffScPl`Y4#=yX^*3-o?q~g|_TZVki1_CS&`BVPa zSFW6-HZkKtO6SdMt^E&sRA+CAJ)Ak|YMJU!*&O4@GugH_4A{Ygu0PhF?is#cZudj{ z!MP@TafN-1*5wD@<-d5hJ4}r;Fna-R}9C&vQ4QXFtHfGtI*|(6oVPrIVcCgXZH$jy-&$=g`Qd zQotaExux3<0_f3F`IFE;BUD{V}teks*4DqA25n zi3|$DsU0p18P*JI&WClmGDH|Kh@^QRv1GWR%V6Lcp60=@VLQWta{}C(7&v$s3<5h^ zH5pi{84^w?D_1bI%w!O8`xI{TQG1=hb1epjikX{icB)vqHb!&k7P5zj>&a=H^Ay(> zF-v4hoaLZ*sB)&HQKJd}gU@Fe7#2(v6@1YA`ESKJzIEr$ne}bsi`RX%pY6X=Qqtpp zPtUI|aA06~SW!-AK$!ao;)!p3#s zgq=5UK7I1!hSw3N=)_auwg1u&#UBX&oAa~I=Fj)95B5D$X*7y$bZ7bT;Lw>bK1*fJ zPvUGzy7R2x{m*vp|9@mJD;@Dn+8LoG@;Feau+L>y&u62hN}W!VG>@uY`k(UXzRquE zyZfdL8?x*et0(HNh)rhx=B+LeQF7qXcLs(}yYmlT(coZi$Y_3ezWo1t`@ilBR2dr5 zJSP=0FvPj2=!KlxY=4}Cfx%@#qt*sT=`RN*bPlk|9Av$7ko!-9S&Ng(kwZ=bPFyJs zGDQiRYnq%i+Rko})k@I6;vj2sATXnCasi*-q0k+CwgvpZ5;^7_)Y#L=$>Ml|LpV|K zRtIBJSA=pOhxp9aABqP(ScJM&6i#-C1S)w?H1#kH>IzW^^^pB!Tf}799^kJ-ZK7glHR-|Dw> zK5lT}g#^3tksJfPV~3qKTIg_2PCmU+X${ZnV^SN!)-dnx{F;1zV>ydZqw4`qGnR5E zg+w_=j|iU#zZ)Ja6l7FP1aEPgb27IC9#U7Dyuy2n+AhJLME}D8-DnmTud*=EVCA$RgPL=bUej)tQ>6h*=roUkR zQqIHMCfaNQnusv-zs_doG3wOJe@6TKQZpOTQaSii)@|WMM-242OOs)RkkiWUVmVb5UiD28z zqr!HZ=bVJiQPaYF8(ID1w?76t#~yZYUYa;Har(oSi90XaEWYa2>&D-cc`W9!%H!N) zxyKf(v8gGldHcTdeK#w}cjq$AW!65{KF80VIlJiWwV9@~Z4Iv*J)ix2_VwBKwv291H=cXr7%Oc-x+mqKCWf{3NA~Y&?v)kIaYgMo9Ub}m_;PRb*ll@lDyOw@< z!^dqWx2@bRx#8&zw%hBrnRA0@Uv^IyPv2SG{JEpM)4S=k z-gG;?+0w`Ep4j`utK@58?8B-{U+2!=Jp0hw6}Q*FGkcf$uKmvZGbZyj=S3P9UpRci z`9a{*i}u{}ry6A6UsLDr?BAHa^|`Wsvi`*IwbwUnUs}HEd*XX>yKiziwlTkF zbT2agjQN4>C$^vVKb$`=zV*Iyz4HH*|5g7lGAwUUWlU%8Y;S?Vr%gfn!|Igdc?T_X@;(lB$K12URY(eG1bBDgPE*D#=C!}LF z&B3R`&tl34M**!BVm+##gv(X?xGE3H9!gizzi4)`CP7Ql@s>(@cP`HZ8cA9R+&Psk*(EU!{$j7ClorZQuLj?E&Wycv$V3)Yf@V` z{X3f1yPFp=s`|R5@n@`=I zU_R&l{Qqx-4hcP+v~6jdcet)>#IwC?vMe{*6jt8mdMwJS-4@2S#%4#?Hm%&N{;S`H zPhVHJSFOr7yD{$IsiuQl8M9w=hjKk_t$lsx`rBCl2>rmX)iI>`XbIb}8-UvwOPpqWPw+n*MA$UmowxTU&VVhi!TL z^_%N${pn{lZtrg1=Dc(9ew!V8QkS1Rch=fIWJ$=EkY6EY?=Iclnt1(3-oR2DUt<2tuFSXX z`pzp?WiQ!=1odCje(lb8Tz=obx$nz$dCho3d*>W`q+H-q`Q+ty&imixc&%=g^;EBU z$bMPAOg3FsKg(&>r&(^ZgJ=DYPKw^;f5z_OwO9A5{1XyJxN28I!&9UDe*L)oI^fO3yPtclXQQ%8z3IuU(yI zX?u6?=c@egN56l)FLt-CNd51*)4Ok$tG`>j$A3@!7l*fwH=XacU$u|^cjw0YJM~!y z$`^dTc*p%aTWj03=E|P3=FRl7#OT(FffScPl`Y4#=yX^&eO#)q~g|_TZVki1_CS&`A7cm z-?OsmMaH3%LYsM6Tl+uWbegdx_HgE;t7Wn4pPx0Ge6;4;X=VoO;NQg8%iql{-t+aK ze}g*rKiQfa%w_Ky?xw$Zx#TlbdG@-?M|=1x%74sUV&%a8fRWUe lv6~1H{rr=Of#LsuW(J*yb_HD%I$wi?Jzf1=);T3K0RTy>X`%oC 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 zcmeAS@N?(olHy`uVBq!ia0y~yU~m9o4mJh`hEJ4}r;Fna-R}9C&vQ4QXFtHfGtI*|(6oVPrIVcCgXZH$jy-&$=g`Qd zQotaExux3<0_f3F`IFE;BUD{V}teks*4DqA25n zi3|$DsU0p18P*JI&WClmGDH|Kh@^QRv1GWR%V6Lcp60=@VLQWta{}C(7&v$s3<5h^ zH5pi{84^w?D_1bI%w!O8`xI{TQG1=hb1epjikX{icB)vqHb!&k7P5zj>&a=H^Ay(> zF-v4hoaLZ*sB)&HQKJd}gU@Fe7#2(v6@1YA`ESKJzIEr$ne}bsi`RX%pY6X=Qqtpp zPtUI|aA06~SW!-AK$!ao;)!p3#s zgq=5UK7I1!hSw3N=)_auwg1u&#UBX&oAa~I=Fj)95B5D$X*7y$bZ7bT;Lw>bK1*fJ zPvUGzy7R2x{m*vp|9@mJD;@Dn+8LoG@;Feau+L>y&u62hN}W!VG>@uY`k(UXzRquE zyZfdL8?x*et0(HNh)rhx=B+LeQF7qXcLs(}yYmlT(coZi$Y_3ezWo1t`@ilBR2dr5 zJSP=0FvPj2=!KlxY=4}Cfx%@#qt*sT=`RN*bPlk|9Av$7ko!-9S&Ng(kwZ=bPFyJs zGDQiRYnq%i+Rko})k@I6;vj2sATXnCasi*-q0k+CwgvpZ5;^7_)Y#L=$>Ml|LpV|K zRtIBJSA=pOhxp9aABqP(ScJM&6i#-C1S)w?H1#kH>IzW^^^pB!Tf}799^kJ-ZK7glHR-|Dw> zK5lT}g#^3tksJfPV~3qKTIg_2PCmU+X${ZnV^SN!)-dnx{F;1zV>ydZqw4`qGnR5E zg+w_=j|iU#zZ)Ja6l7FP1aEPgb27IC9#U7Dyuy2n+AhJLME}D8-DnmTud*=EVCA$RgPL=bUej)tQ>6h*=roUkR zQqIHMCfaNQnusv-zs_doG3wOJe@6TKQZpOTQaSii)@|WMM-242OOs)RkkiWUVmVb5UiD28z zqr!HZ=bVJiQPaYF8(ID1w?76t#~yZYUYa;Har(oSi90XaEWYa2>&D-cc`W9!%H!N) zxyKf(v8gGldHcTdeK#w}cjq$AW!65{KF80VIlJiWwV9@~Z4Iv*J)ix2_VwBKwv291H=cXr7%Oc-x+mqKCWf{3NA~Y&?v)kIaYgMo9Ub}m_;PRb*ll@lDyOw@< z!^dqWx2@bRx#8&zw%hBrnRA0@Uv^IyPv2SG{JEpM)4S=k z-gG;?+0w`Ep4j`utK@58?8B-{U+2!=Jp0hw6}Q*FGkcf$uKmvZGbZyj=S3P9UpRci z`9a{*i}u{}ry6A6UsLDr?BAHa^|`Wsvi`*IwbwUnUs}HEd*XX>yKiziwlTkF zbT2agjQN4>C$^vVKb$`=zV*Iyz4HH*|5g7lGAwUUWlU%8Y;S?Vr%gfn!|Igdc?T_X@;(lB$K12URY(eG1bBDgPE*D#=C!}LF z&B3R`&tl34M**!BVm+##gv(X?xGE3H9!gizzi4)`CP7Ql@s>(@cP`HZ8cA9R+&Psk*(EU!{$j7ClorZQuLj?E&Wycv$V3)Yf@V` z{X3f1yPFp=s`|R5@n@`=I zU_R&l{Qqx-4hcP+v~6jdcet)>#IwC?vMe{*6jt8mdMwJS-4@2S#%4#?Hm%&N{;S`H zPhVHJSFOr7yD{$IsiuQl8M9w=hjKk_t$lsx`rBCl2>rmX)iI>`XbIb}8-UvwOPpqWPw+n*MA$UmowxTU&VVhi!TL z^_%N${pn{lZtrg1=Dc(9ew!V8QkS1Rch=fIWJ$=EkY6EY?=Iclnt1(3-oR2DUt<2tuFSXX z`pzp?WiQ!=1odCje(lb8Tz=obx$nz$dCho3d*>W`q+H-q`Q+ty&imixc&%=g^;EBU z$bMPAOg3FsKg(&>r&(^ZgJ=DYPKw^;f5z_OwO9A5{1XyJxN28I!&9UDe*L)oI^fO3yPtclXQQ%8z3IuU(yI zX?u6?=c@egN56l)FLt-CNd51*)4Ok$tG`>j$A3@!7l*fwH=XacU$u|^cjw0YJM~!y z$`^dTc*p%aTWj03=E|P3=FRl7#OT(FffScPl`Y4#=yX^($mE;q~g|_TZVki4g$;vj8FaF z|0d*u;;aoyNp}J^@z}9gT`J>U?iqHwwCKzegWFY=4A{W|{Yg*s8SL`+eqerZuJJoB z|M>=W^9L`>U%XrLnJGMb-Q~kQ^FCyKHuf}iU^W4xXHo`#-#wI9yw8N)M2P6K&#Vj# b|Nk>Hd=T`@lxgnm1_^t*`njxgN@xNAC}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 zcmeAS@N?(olHy`uVBq!ia0y~yU~m9o4mJh`hEJ4}r;Fna-R}9C&vQ4QXFtHfGtI*|(6oVPrIVcCgXZH$jy-&$=g`Qd zQotaExux3<0_f3F`IFE;BUD{V}teks*4DqA25n zi3|$DsU0p18P*JI&WClmGDH|Kh@^QRv1GWR%V6Lcp60=@VLQWta{}C(7&v$s3<5h^ zH5pi{84^w?D_1bI%w!O8`xI{TQG1=hb1epjikX{icB)vqHb!&k7P5zj>&a=H^Ay(> zF-v4hoaLZ*sB)&HQKJd}gU@Fe7#2(v6@1YA`ESKJzIEr$ne}bsi`RX%pY6X=Qqtpp zPtUI|aA06~SW!-AK$!ao;)!p3#s zgq=5UK7I1!hSw3N=)_auwg1u&#UBX&oAa~I=Fj)95B5D$X*7y$bZ7bT;Lw>bK1*fJ zPvUGzy7R2x{m*vp|9@mJD;@Dn+8LoG@;Feau+L>y&u62hN}W!VG>@uY`k(UXzRquE zyZfdL8?x*et0(HNh)rhx=B+LeQF7qXcLs(}yYmlT(coZi$Y_3ezWo1t`@ilBR2dr5 zJSP=0FvPj2=!KlxY=4}Cfx%@#qt*sT=`RN*bPlk|9Av$7ko!-9S&Ng(kwZ=bPFyJs zGDQiRYnq%i+Rko})k@I6;vj2sATXnCasi*-q0k+CwgvpZ5;^7_)Y#L=$>Ml|LpV|K zRtIBJSA=pOhxp9aABqP(ScJM&6i#-C1S)w?H1#kH>IzW^^^pB!Tf}799^kJ-ZK7glHR-|Dw> zK5lT}g#^3tksJfPV~3qKTIg_2PCmU+X${ZnV^SN!)-dnx{F;1zV>ydZqw4`qGnR5E zg+w_=j|iU#zZ)Ja6l7FP1aEPgb27IC9#U7Dyuy2n+AhJLME}D8-DnmTud*=EVCA$RgPL=bUej)tQ>6h*=roUkR zQqIHMCfaNQnusv-zs_doG3wOJe@6TKQZpOTQaSii)@|WMM-242OOs)RkkiWUVmVb5UiD28z zqr!HZ=bVJiQPaYF8(ID1w?76t#~yZYUYa;Har(oSi90XaEWYa2>&D-cc`W9!%H!N) zxyKf(v8gGldHcTdeK#w}cjq$AW!65{KF80VIlJiWwV9@~Z4Iv*J)ix2_VwBKwv291H=cXr7%Oc-x+mqKCWf{3NA~Y&?v)kIaYgMo9Ub}m_;PRb*ll@lDyOw@< z!^dqWx2@bRx#8&zw%hBrnRA0@Uv^IyPv2SG{JEpM)4S=k z-gG;?+0w`Ep4j`utK@58?8B-{U+2!=Jp0hw6}Q*FGkcf$uKmvZGbZyj=S3P9UpRci z`9a{*i}u{}ry6A6UsLDr?BAHa^|`Wsvi`*IwbwUnUs}HEd*XX>yKiziwlTkF zbT2agjQN4>C$^vVKb$`=zV*Iyz4HH*|5g7lGAwUUWlU%8Y;S?Vr%gfn!|Igdc?T_X@;(lB$K12URY(eG1bBDgPE*D#=C!}LF z&B3R`&tl34M**!BVm+##gv(X?xGE3H9!gizzi4)`CP7Ql@s>(@cP`HZ8cA9R+&Psk*(EU!{$j7ClorZQuLj?E&Wycv$V3)Yf@V` z{X3f1yPFp=s`|R5@n@`=I zU_R&l{Qqx-4hcP+v~6jdcet)>#IwC?vMe{*6jt8mdMwJS-4@2S#%4#?Hm%&N{;S`H zPhVHJSFOr7yD{$IsiuQl8M9w=hjKk_t$lsx`rBCl2>rmX)iI>`XbIb}8-UvwOPpqWPw+n*MA$UmowxTU&VVhi!TL z^_%N${pn{lZtrg1=Dc(9ew!V8QkS1Rch=fIWJ$=EkY6EY?=Iclnt1(3-oR2DUt<2tuFSXX z`pzp?WiQ!=1odCje(lb8Tz=obx$nz$dCho3d*>W`q+H-q`Q+ty&imixc&%=g^;EBU z$bMPAOg3FsKg(&>r&(^ZgJ=DYPKw^;f5z_OwO9A5{1XyJxN28I!&9UDe*L)oI^fO3yPtclXQQ%8z3IuU(yI zX?u6?=c@egN56l)FLt-CNd51*)4Ok$tG`>j$A3@!7l*fwH=XacU$u|^cjw0YJM~!y z$`^dTc*p%aTWj03=E|P3=FRl7#OT(FffScPl`Y4#=yX^+SA1`q~g|_TZVki1_CS&`BVPa zSFUt&bQbngNR#$Dv%yYr=9bvQH}hwtY_*Lu-Z|rZRV4#Fc%!9s;{A&|JItDnm{r-UW|Ec#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 zcmeAS@N?(olHy`uVBq!ia0y~yU~m9o4mJh`hEJ4}r;Fna-R}9C&vQ4QXFtHfGtI*|(6oVPrIVcCgXZH$jy-&$=g`Qd zQotaExux3<0_f3F`IFE;BUD{V}teks*4DqA25n zi3|$DsU0p18P*JI&WClmGDH|Kh@^QRv1GWR%V6Lcp60=@VLQWta{}C(7&v$s3<5h^ zH5pi{84^w?D_1bI%w!O8`xI{TQG1=hb1epjikX{icB)vqHb!&k7P5zj>&a=H^Ay(> zF-v4hoaLZ*sB)&HQKJd}gU@Fe7#2(v6@1YA`ESKJzIEr$ne}bsi`RX%pY6X=Qqtpp zPtUI|aA06~SW!-AK$!ao;)!p3#s zgq=5UK7I1!hSw3N=)_auwg1u&#UBX&oAa~I=Fj)95B5D$X*7y$bZ7bT;Lw>bK1*fJ zPvUGzy7R2x{m*vp|9@mJD;@Dn+8LoG@;Feau+L>y&u62hN}W!VG>@uY`k(UXzRquE zyZfdL8?x*et0(HNh)rhx=B+LeQF7qXcLs(}yYmlT(coZi$Y_3ezWo1t`@ilBR2dr5 zJSP=0FvPj2=!KlxY=4}Cfx%@#qt*sT=`RN*bPlk|9Av$7ko!-9S&Ng(kwZ=bPFyJs zGDQiRYnq%i+Rko})k@I6;vj2sATXnCasi*-q0k+CwgvpZ5;^7_)Y#L=$>Ml|LpV|K zRtIBJSA=pOhxp9aABqP(ScJM&6i#-C1S)w?H1#kH>IzW^^^pB!Tf}799^kJ-ZK7glHR-|Dw> zK5lT}g#^3tksJfPV~3qKTIg_2PCmU+X${ZnV^SN!)-dnx{F;1zV>ydZqw4`qGnR5E zg+w_=j|iU#zZ)Ja6l7FP1aEPgb27IC9#U7Dyuy2n+AhJLME}D8-DnmTud*=EVCA$RgPL=bUej)tQ>6h*=roUkR zQqIHMCfaNQnusv-zs_doG3wOJe@6TKQZpOTQaSii)@|WMM-242OOs)RkkiWUVmVb5UiD28z zqr!HZ=bVJiQPaYF8(ID1w?76t#~yZYUYa;Har(oSi90XaEWYa2>&D-cc`W9!%H!N) zxyKf(v8gGldHcTdeK#w}cjq$AW!65{KF80VIlJiWwV9@~Z4Iv*J)ix2_VwBKwv291H=cXr7%Oc-x+mqKCWf{3NA~Y&?v)kIaYgMo9Ub}m_;PRb*ll@lDyOw@< z!^dqWx2@bRx#8&zw%hBrnRA0@Uv^IyPv2SG{JEpM)4S=k z-gG;?+0w`Ep4j`utK@58?8B-{U+2!=Jp0hw6}Q*FGkcf$uKmvZGbZyj=S3P9UpRci z`9a{*i}u{}ry6A6UsLDr?BAHa^|`Wsvi`*IwbwUnUs}HEd*XX>yKiziwlTkF zbT2agjQN4>C$^vVKb$`=zV*Iyz4HH*|5g7lGAwUUWlU%8Y;S?Vr%gfn!|Igdc?T_X@;(lB$K12URY(eG1bBDgPE*D#=C!}LF z&B3R`&tl34M**!BVm+##gv(X?xGE3H9!gizzi4)`CP7Ql@s>(@cP`HZ8cA9R+&Psk*(EU!{$j7ClorZQuLj?E&Wycv$V3)Yf@V` z{X3f1yPFp=s`|R5@n@`=I zU_R&l{Qqx-4hcP+v~6jdcet)>#IwC?vMe{*6jt8mdMwJS-4@2S#%4#?Hm%&N{;S`H zPhVHJSFOr7yD{$IsiuQl8M9w=hjKk_t$lsx`rBCl2>rmX)iI>`XbIb}8-UvwOPpqWPw+n*MA$UmowxTU&VVhi!TL z^_%N${pn{lZtrg1=Dc(9ew!V8QkS1Rch=fIWJ$=EkY6EY?=Iclnt1(3-oR2DUt<2tuFSXX z`pzp?WiQ!=1odCje(lb8Tz=obx$nz$dCho3d*>W`q+H-q`Q+ty&imixc&%=g^;EBU z$bMPAOg3FsKg(&>r&(^ZgJ=DYPKw^;f5z_OwO9A5{1XyJxN28I!&9UDe*L)oI^fO3yPtclXQQ%8z3IuU(yI zX?u6?=c@egN56l)FLt-CNd51*)4Ok$tG`>j$A3@!7l*fwH=XacU$u|^cjw0YJM~!y z$`^dTc*p%aTWj03=E|P3=FRl7#OT(FffScPl`Y4#=yX^+|$J|q~g|_TZTdn3OpxW&i*H 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 zcmeAS@N?(olHy`uVBq!ia0y~yU~m9o4mJh`hEJ4}r;Fna-R}9C&vQ4QXFtHfGtI*|(6oVPrIVcCgXZH$jy-&$=g`Qd zQotaExux3<0_f3F`IFE;BUD{V}teks*4DqA25n zi3|$DsU0p18P*JI&WClmGDH|Kh@^QRv1GWR%V6Lcp60=@VLQWta{}C(7&v$s3<5h^ zH5pi{84^w?D_1bI%w!O8`xI{TQG1=hb1epjikX{icB)vqHb!&k7P5zj>&a=H^Ay(> zF-v4hoaLZ*sB)&HQKJd}gU@Fe7#2(v6@1YA`ESKJzIEr$ne}bsi`RX%pY6X=Qqtpp zPtUI|aA06~SW!-AK$!ao;)!p3#s zgq=5UK7I1!hSw3N=)_auwg1u&#UBX&oAa~I=Fj)95B5D$X*7y$bZ7bT;Lw>bK1*fJ zPvUGzy7R2x{m*vp|9@mJD;@Dn+8LoG@;Feau+L>y&u62hN}W!VG>@uY`k(UXzRquE zyZfdL8?x*et0(HNh)rhx=B+LeQF7qXcLs(}yYmlT(coZi$Y_3ezWo1t`@ilBR2dr5 zJSP=0FvPj2=!KlxY=4}Cfx%@#qt*sT=`RN*bPlk|9Av$7ko!-9S&Ng(kwZ=bPFyJs zGDQiRYnq%i+Rko})k@I6;vj2sATXnCasi*-q0k+CwgvpZ5;^7_)Y#L=$>Ml|LpV|K zRtIBJSA=pOhxp9aABqP(ScJM&6i#-C1S)w?H1#kH>IzW^^^pB!Tf}799^kJ-ZK7glHR-|Dw> zK5lT}g#^3tksJfPV~3qKTIg_2PCmU+X${ZnV^SN!)-dnx{F;1zV>ydZqw4`qGnR5E zg+w_=j|iU#zZ)Ja6l7FP1aEPgb27IC9#U7Dyuy2n+AhJLME}D8-DnmTud*=EVCA$RgPL=bUej)tQ>6h*=roUkR zQqIHMCfaNQnusv-zs_doG3wOJe@6TKQZpOTQaSii)@|WMM-242OOs)RkkiWUVmVb5UiD28z zqr!HZ=bVJiQPaYF8(ID1w?76t#~yZYUYa;Har(oSi90XaEWYa2>&D-cc`W9!%H!N) zxyKf(v8gGldHcTdeK#w}cjq$AW!65{KF80VIlJiWwV9@~Z4Iv*J)ix2_VwBKwv291H=cXr7%Oc-x+mqKCWf{3NA~Y&?v)kIaYgMo9Ub}m_;PRb*ll@lDyOw@< z!^dqWx2@bRx#8&zw%hBrnRA0@Uv^IyPv2SG{JEpM)4S=k z-gG;?+0w`Ep4j`utK@58?8B-{U+2!=Jp0hw6}Q*FGkcf$uKmvZGbZyj=S3P9UpRci z`9a{*i}u{}ry6A6UsLDr?BAHa^|`Wsvi`*IwbwUnUs}HEd*XX>yKiziwlTkF zbT2agjQN4>C$^vVKb$`=zV*Iyz4HH*|5g7lGAwUUWlU%8Y;S?Vr%gfn!|Igdc?T_X@;(lB$K12URY(eG1bBDgPE*D#=C!}LF z&B3R`&tl34M**!BVm+##gv(X?xGE3H9!gizzi4)`CP7Ql@s>(@cP`HZ8cA9R+&Psk*(EU!{$j7ClorZQuLj?E&Wycv$V3)Yf@V` z{X3f1yPFp=s`|R5@n@`=I zU_R&l{Qqx-4hcP+v~6jdcet)>#IwC?vMe{*6jt8mdMwJS-4@2S#%4#?Hm%&N{;S`H zPhVHJSFOr7yD{$IsiuQl8M9w=hjKk_t$lsx`rBCl2>rmX)iI>`XbIb}8-UvwOPpqWPw+n*MA$UmowxTU&VVhi!TL z^_%N${pn{lZtrg1=Dc(9ew!V8QkS1Rch=fIWJ$=EkY6EY?=Iclnt1(3-oR2DUt<2tuFSXX z`pzp?WiQ!=1odCje(lb8Tz=obx$nz$dCho3d*>W`q+H-q`Q+ty&imixc&%=g^;EBU z$bMPAOg3FsKg(&>r&(^ZgJ=DYPKw^;f5z_OwO9A5{1XyJxN28I!&9UDe*L)oI^fO3yPtclXQQ%8z3IuU(yI zX?u6?=c@egN56l)FLt-CNd51*)4Ok$tG`>j$A3@!7l*fwH=XacU$u|^cjw0YJM~!y z$`^dTc*p%aTWj03=E|P3=FRl7#OT(FffScPl`Y4#=yX^%+tj&q~g|_TZViM3OuX<`#$~) zU)NoztamG;VlTr}(Nhk=p^Gh-ajQv&PCb{hZDR!kcF>@%bW)$;Tc~**=04xWP}nQ0|UeV|I7^A Ww#qe5TBD!MADx zh82|tP 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!ia0y~yU~m9o4mJh`hEOZZecfOl%`>}JnkMu{wex-!E zOM6ppZ8&bwFMPpv`h0^kDWozz>Gl;wnsY*Jrc&6Ba1-cAfrCPRzPcHg!CtMI?IBGR@p2Vk& zWvm7n+zm-{z5ID9O)fJ@Y+-fS=(kk8&1P06BhM|S1rf_H2|LT3t#N1MPYk=T{ed^g zqWZ+XUv(Rs_OZr$`SbklaF1qqzn!VTOSwPoUo7LxoqvzGl|m#uX!k16czuXBHtV-Au;nra g(AJlaZ0Zb%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!ia0y~yU~m9o4mJh`hEU?dw`qlfjJw~UR!eps61vkwSswu@wJ>< zb;hm~83)NyhT>zh*1lJ9nApRtv6wI6T*T(Db6GSd6*8n=VLT(5y=~uQ23Mo~f(LqM z@;`nKG4oOUjMjbfH4^sEcdl9}UU7wS%D*0l2_DZ18CSgiB+Pwj)rV5i{CkS)9|xAk z`sjPCPP!1fr?P!dpZnEP!@UY?yBxzmK9l_)_;FRw)eont^c$j2JTbq(ZR@2LyY_R; zRgg<6cFQ7IB)gVxL622~B^g2Uf|=>YcJc6Evo|y8c7I`DU|{fc^>bP0l+XkKICt89 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!ia0y~yU~m9o4mJh`hE+dI!(W;>L&&DZ8%+wUdc6X%%;m~GB|_4%;7 z=!X9J3JS6yLw?7z)(B<)Rr$l*@{@Va+>l@Agq@W`BW4)XH*B8lb-ywxV+j|x@H75` zvY?mN{ye=QiHV15=6+GXwZ~r0d~@!jjb}yf?&1n)VA?@V=Q}X+bMJ_Y*VuY4OmtDP R83O|YgQu&X%Q~loCIBR|zDWQ8 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/channels_11.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/channels_11.png new file mode 100644 index 0000000000000000000000000000000000000000..aff62d1ab0b9fb78b1770a5a656a96d1cf975297 GIT binary patch literal 539 zcmeAS@N?(olHy`uVBq!ia0y~yU~m9o4mJh`hE(@j~|Fk6*`KG2*z&a)Uu@ zPL^a#7E=y`sNYr|CsRhV2Cn5%Yzt>GNISF!>oy1YHt;Suv~rr`3bg}l0S`k?D})Fq zFs~?Bl`61`a|2_D#Z~;q>_52qZ26zNjDK!@R)24N;Oh0bUnkivJO-Qd;6DEcvpM!( z_SU#G-1|KL_}!o9=I?lXZhKP7LzT}AZ?;}KCp*16#!Jl4i2p#G_S-v!J5MYHNlm|O q$Mm4)XQe((U5+OJ9{93Z$jR^dBdc=p*DX+NGkCiCxvX zT^vIy;@(aQtOEv@76cAE7yMAwq8ppn#twB znzb$t@u4c)SUMUaqdOb+t@6m>6ky!EO^C5Jbm9#m1*WuIRivir3kSibu_`MqF4=^bZ&r3ZiB z)G@AO`BBXn-yHX1&z}xfljrvR-Sd8O+8lR&xu+-2p*ZWoqV&2)eJ@r@ynZnC>u-jf zJ1^4Toyd9;bnT$_>+kx<|8g+c)~vht4Ug4I3D?4u7Er}c$@k@$pJzXoSkb$Ofq{X+ M)78&qol`;+0E`&IPXGV_ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/channels_13.png b/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/channels_13.png new file mode 100644 index 0000000000000000000000000000000000000000..774a84d05b2e32f13136b1eab0287d3bc658ba88 GIT binary patch literal 536 zcmeAS@N?(olHy`uVBq!ia0y~yU~m9o4mJh`hE9PQ)y$6O}I7d)TAQ<3z&VPgCi$NFqJf9W@~v1IXCbb{QY%*X%$ 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!ia0y~yU~m9o4mJh`hEm+wvo_+qn`~+SO03+CKXeb8w`bP0 Hl+XkKczMNB 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 bW`<)IgTe~DWM4f62TR< delta 57 zcmcb`c$RU(Y$I7u7sn6_|73}@2lfIEGc6bmv)m4HuqzuW8X7P#q!#dhRCp|J!N9=4 N;OXk;vd$@?2>|>#5SRb} diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/conversion_monitor_medium.png b/src/main/resources/assets/appliedenergistics2/textures/parts/conversion_monitor_medium.png index 0d9a49ead9006b32321b82898b0fe1d70ffa56af..8affc2651889fe6e1c426dad9276ee29dd4fd495 100644 GIT binary patch delta 57 zcmcb`c$RU(Y$I7u7sn6_|73}@2lfIEGc6bmv)m4HuqzuW8X7P#q!#dhRCp|J!N9=4 N;OXk;vd$@?2>|>#5SRb} delta 70 zcmX@hc#CnuYFt8k1A<4?jwL+-(hls!x8xclk bW`<)IgTe~DWM4f62TR< diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/conversion_monitor_dark_locked.png b/src/main/resources/assets/appliedenergistics2/textures/parts/conversion_monitor_medium_locked.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/conversion_monitor_dark_locked.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/conversion_monitor_medium_locked.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/crafting_terminal_bright.png b/src/main/resources/assets/appliedenergistics2/textures/parts/crafting_terminal_bright.png new file mode 100644 index 0000000000000000000000000000000000000000..bf283814e1274d6e6f1e81e0ec10f72bcd4692f9 GIT binary patch literal 256 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#IRP zT^vI!{Fn9}iZNQt(i~Ov_>4$XJBAp@O1TaS?83{1ONjw BOG^L% literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/crafting_terminal_dark.png b/src/main/resources/assets/appliedenergistics2/textures/parts/crafting_terminal_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..c48de0892bf1c73be774604d14f00db2aed39345 GIT binary patch literal 257 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#IRQ zT^vI!{O?XOaCE>*how%O+U&BEN?-P~ zp6PkrD83?OK~SR?tCr}B5RHX@djgLwaNhLqwfv6U2_mapn5>?kV_;xl@O1TaS?83{ F1OPM=Pdoqs 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!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#K1= zT^vI!{I~W5ay1z6IF|?LKk+R)T&E?ObHq&aw8003V|%xKei40QW0Q>biH}~3?zJTz za#CwP?yi<9yN2n*hJyShH zL-)^4<_ruB>pWc?Ln`9lp7rKpRuo~q_@;h;6GxK93rCKh8P>bQc;)YWmRq~^VzvD0 zt5NQnsT>>}PZ+F|=W&DR>$$tG8=hxnVL8Wg@3@MB15-NV{9_>cIm3N0ozAcyO#eKv z-;k4If`gfXu^J;4WA-+XjeghO%Qe h;sOF3jISz~7^SN>Eu6G3kb!}L!PC{xWt~$(69BWqT?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 000000000..4dcf4d630 --- /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!ia0y~yU=UznU}WH6Vqjn}HAs|XU|?WLcl32+VA$Bt{U?!? zfq{Xuz$3Dlfr0M;2s36~>*Qo$V2~(rjVKAuPb(=;EJ|f4NX*PD(aTFMQ83Xn&@=9N zHa&oWf#JNTi(^QJ^V>6lT!#zZnnYq6IFx>Hfsdik3BBzr?)cAV7Pz$!hu+A2PuWhe(s`d))`D^{2d(=*D@qG95q$a zSTE|p_-y&cf(5(67#u#$6XRYJsm-7etgxYIEklD(;DKLTnHY>(8D?MOO32G&C@#(x i%mG=L1!k7~m5$Y3u~l%+!)68s1_n=8KbLh*2~7afdVHAx literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/identity_annihilation_plane_on.png.mcmeta b/src/main/resources/assets/appliedenergistics2/textures/parts/identity_annihilation_plane_on.png.mcmeta new file mode 100644 index 000000000..4dcf4d630 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/textures/parts/identity_annihilation_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/import_sides.png b/src/main/resources/assets/appliedenergistics2/textures/parts/import_bus_sides.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/import_sides.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/import_bus_sides.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/interface_terminal_dark.png b/src/main/resources/assets/appliedenergistics2/textures/parts/interface_terminal_dark.png index 4e73669b9097b7978439cbd8fe6f8c8973eef0d5..8affc2651889fe6e1c426dad9276ee29dd4fd495 100644 GIT binary patch delta 57 zcmaFCc$RU(Y$I7u7sn6_|73}@2lfIEGc6bmv)m4HuqzuW8X7P#q!#dhRCp|J!N9=4 N;OXk;vd$@?2>}0B5T*bC delta 84 zcmX@h_=0i5Y+nmc7sn6_|F>ryxfm39m=FH>f0-+FqS)H)cdU+Y5a_*Kb)wqEzQpyO r@}@^CT+@yOcAx23EOygk3Gd_h>6zyla}6077#KWV{an^LB{Ts5E~q3$ diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/interface_terminal_medium.png b/src/main/resources/assets/appliedenergistics2/textures/parts/interface_terminal_medium.png index 8affc2651889fe6e1c426dad9276ee29dd4fd495..4e73669b9097b7978439cbd8fe6f8c8973eef0d5 100644 GIT binary patch delta 84 zcmX@h_=0i5Y+nmc7sn6_|F>ryxfm39m=FH>f0-+FqS)H)cdU+Y5a_*Kb)wqEzQpyO r@}@^CT+@yOcAx23EOygk3Gd_h>6zyla}6077#KWV{an^LB{Ts5E~q3$ delta 57 zcmaFCc$RU(Y$I7u7sn6_|73}@2lfIEGc6bmv)m4HuqzuW8X7P#q!#dhRCp|J!N9=4 N;OXk;vd$@?2>}0B5T*bC diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/8.png b/src/main/resources/assets/appliedenergistics2/textures/parts/level_emitter_off.png similarity index 91% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/8.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/level_emitter_off.png index 0d74dc97b40a8f9e530302d68044fdf3d288ed79..db860fcea6fd62277308b32c8d8c64fa24aca935 100644 GIT binary patch delta 130 zcmaDSHeF1yGr-TCmrII^fq{Y7)59f*fq_8)ggMw47#QR~|4-bgIG-!r$3v8|Xk;zhZv5CV-~qFmVdwWl i>l=9)82y(#eK8ACIE2JGO6lHf<~hT`k( z_y3;L`%q9(D3NK(#O;^-_FqGeSy?6vL|4Nm+XYpX+qt9}A$$<24)78&qol`;+01C}L0ssI2 diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/0.png b/src/main/resources/assets/appliedenergistics2/textures/parts/level_emitter_on.png similarity index 91% rename from src/main/resources/assets/appliedenergistics2/textures/parts/cable/smart/0.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/level_emitter_on.png index d63a978ca4ee492048b24723a4d50a80b80e771a..f1757d9113fe83dabe1caff505dca8ed88793499 100644 GIT binary patch delta 143 zcmew=wnR*^Gr-TCmrII^fq{Y7)59f*fq_8)ggMw47#QR~|4-bgIG-!U-_yl0q~g|_ zOB;C^6a|i)G-SkiiWpX@A4T}DxbFD@*6b9z!vu9(xp{)dG@Bw_>C8%9>EfZeQV w%YHjJU*+%Nc<)zXzk|nzfq~)we`W>)w#Q*9uXGnPFfcH9y85}Sb4q9e00Ag2RsaA1 delta 225 zcmZ1?_Ek)=Gr-TCmrII^fq{Y7)59f*fq}sRggMw47#LP%7T(*aIG?M2fv1aONX4x; zw*t8u6a-ig)L#6%e$U^pGg(wyKkF^%TgQ>TYj>L3$)^o>=g$0mGwUM*cF>?c>4`YQ z?^WFPjQ8dgOqzAKqLBTLEo1!sh1(~unx$p%>ThpVyBAb%#XH#t{S$;hJTnl14R3Ja eV_;zT|DTy*MuuebA@*8ZkSb4CKbLh*2~7Y2*+ZoO 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 zcmeyu_=R!8k^mbA@6d1iH_p?Nm@U03IrZ>{wyrnzE6i9JJRN4TFotbCe1IV!!Eq+b t!4={esSN9u^zb%caoWmjk&wW^pl|IoU$xerg@J*A!PC{xWt~$(697lGAh`el delta 87 zcmeyu_=R!8k^t6b**~cXKll#?=w&i2`S_n#;hp+rfenoRmotB?KNYiaUd&mA4M|74 t{`2zkK9Oc9v1L=^3^?0xkVis-;WLBljYJ8dECvP!22WQ%mvv4FO#r1oBEtXx diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/monitor_light.png b/src/main/resources/assets/appliedenergistics2/textures/parts/monitor_light.png new file mode 100644 index 0000000000000000000000000000000000000000..ffd577f03b9efa33376fe1c4561db00d43b36e77 GIT binary patch literal 235 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^xl_H+M9WMyDr zP)PO&@?~JCQe$9fXklRZ#lXPO@PdJ%)PRBERRRNp)eHs(@q#(K0&N%=7&r?&B8wRq z_?Ce%WBZ+z`3wvUQYEetCBgY=CFO}lsSE*$nRz98ey$-3WyX4@dWMGXpPkGZ7#OTQ zT^vI!{O_Jx$auhj;qZok|4ZDD@EFAe{jJ~?R#ItQ$@KS3=9kmp00i_>zopr0PpZjg#Z8m 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!ia0y~yU=RRd4mJh`2Kmqb6B!s7BuiW)N`mv#O3D+9QW+dm z@{>{(JaZG%Q-e|yQz{EjrrIztFz9=_IEGZ*O8WEvzdf@Y!{n4BOB*^HoeZ)VM0pY% ryR?!PO*Yd@kn#0!zRS?Sz|4>~mt8@BZ_5J)1_lOCS3j3^P6 delta 244 zcmeBUoWL|erJg0-(btiIVPik{pF~y$1_p&>k04(LhAK4%hK3dfhF=T}3=JFNsoPmKM!PCVt#KM1VZjT`sgCWo1U;q7|M>QX4esM`y zqnS0*xLA0NtE~41u~MCbQCBvyWCtD>LI~JA?~IqbgC>ZqYTMkej5qBpKDAs3>11GF OVDNPHb6Mw<&;$VMj!~Nc diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/pattern_terminal_dark.png b/src/main/resources/assets/appliedenergistics2/textures/parts/pattern_terminal_dark.png index cd0841936e34e97be31b1a760c17ef1bf5c106fb..a4616154e20f1523d11a4ccafbf5fb808aa2008e 100644 GIT binary patch delta 99 zcmZo=`p!6Ec8t5Hi(`m||I(9=Tnq|4M;!kDf9a*K{v7(8A5T-G@yGywqg$u#N! 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 zcmey)*vd3vc2=mTi(`m||J_rLTn8L@oG$MCzciYs@W+H(Ww!Z~7p!BBm9P4y!#iWS zZ{f=9Gp+w01YMuO{r}+7b%x^qoV8{y_YM5%etvm~k^k&TUe7W&XMR|g{ygF}+k~F` WiWPcd?->{v7(8A5T-G@yGywqg$u#N! delta 99 zcmZo=`p!6Ec8t5Hi(`m||I(9=Tnq|4M;!kDf9a*K|>#5SRb} delta 70 zcmX@hc#CnuYFt8k1A<4?jwL+-(hls!x8xclk bW`<)IgTe~DWM4f62TR< diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/storage_monitor_medium_locked.png b/src/main/resources/assets/appliedenergistics2/textures/parts/storage_monitor_dark_locked.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/parts/storage_monitor_medium_locked.png rename to src/main/resources/assets/appliedenergistics2/textures/parts/storage_monitor_dark_locked.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/storage_monitor_medium.png b/src/main/resources/assets/appliedenergistics2/textures/parts/storage_monitor_medium.png index 8affc2651889fe6e1c426dad9276ee29dd4fd495..0d9a49ead9006b32321b82898b0fe1d70ffa56af 100644 GIT binary patch delta 70 zcmX@hc#CnuYFt8k1A<4?jwL+-(hls!x8xclk bW`<)IgTe~DWM4f62TR< delta 57 zcmcb`c$RU(Y$I7u7sn6_|73}@2lfIEGc6bmv)m4HuqzuW8X7P#q!#dhRCp|J!N9=4 N;OXk;vd$@?2>|>#5SRb} diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/terminal_dark.png b/src/main/resources/assets/appliedenergistics2/textures/parts/terminal_dark.png index bd779cbbd8f4cb7888b3ded5303f7b223db242e9..aa70c6203c04ed413c79be063ac2f81dc1c08242 100644 GIT binary patch delta 56 zcmaFIc!qJpY(p7O7sn6_|6~bPW`=*vj8i=2Buo<`Bn)maFf%h0%#we&_v_mL1_lNO MPgg&ebxsLQ0OOVH>|i@j7sn6_|73}@2lgTYNzEB+7}jucaBOrm$z`}9rEuW*G42JgPM9|& wF>LLq5qG#cF`wZmL)JxxT?q^f%*+g>rt1U$x39EiU|?YIboFyt=akR{0PO7`dH?_b 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|& wF>LLq5qG#cF`wZmL)JxxT?q^f%*+g>rt1U$x39EiU|?YIboFyt=akR{0PO7`dH?_b delta 56 zcmaFIc!qJpY(p7O7sn6_|6~bPW`=*vj8i=2Buo<`Bn)maFf%h0%#we&_v_mL1_lNO MPgg&ebxsLQ0O