diff --git a/src/generated/resources/assets/gtceu/lang/en_ud.json b/src/generated/resources/assets/gtceu/lang/en_ud.json index a0a937ed0cb..f51d500f0c5 100644 --- a/src/generated/resources/assets/gtceu/lang/en_ud.json +++ b/src/generated/resources/assets/gtceu/lang/en_ud.json @@ -66,6 +66,7 @@ "behaviour.lighter.uses": "%d :sǝsn buıuıɐɯǝᴚ", "behaviour.memory_card.client_msg.cleared": "pǝɹɐǝןɔ uoıʇɐɹnbıɟuoɔ pǝɹoʇS", "behaviour.memory_card.client_msg.copied": "uoıʇɐɹnbıɟuoɔ ǝuıɥɔɐɯ pǝıdoƆ", + "behaviour.memory_card.client_msg.missing_items": "uoıʇɐɹnbıɟuoɔ ǝʇsɐd oʇ pǝɹınbǝɹ sɯǝʇı buıssıW", "behaviour.memory_card.client_msg.pasted": "uoıʇɐɹnbıɟuoɔ ǝuıɥɔɐɯ pǝıןddⱯ", "behaviour.memory_card.copy_target": "%s :buıʎdoƆ", "behaviour.memory_card.disabled": "ɹ§pǝןqɐsıᗡɔ§", @@ -1745,6 +1746,7 @@ "config.gtceu.option.addLoot": "ʇooꞀppɐ", "config.gtceu.option.ae2": "ᄅǝɐ", "config.gtceu.option.allowDrumsInputFluidsFromOutputSide": "ǝpıSʇndʇnOɯoɹℲspınןℲʇnduIsɯnɹᗡʍoןןɐ", + "config.gtceu.option.allowedImageDomains": "suıɐɯoᗡǝbɐɯIpǝʍoןןɐ", "config.gtceu.option.animationTime": "ǝɯı⟘uoıʇɐɯıuɐ", "config.gtceu.option.arcRecyclingYield": "pןǝıʎbuıןɔʎɔǝᴚɔɹɐ", "config.gtceu.option.armorHud": "pnHɹoɯɹɐ", @@ -1892,7 +1894,7 @@ "config.gtceu.option.steelSteamMultiblocks": "sʞɔoןqıʇןnWɯɐǝʇSןǝǝʇs", "config.gtceu.option.surfaceRockProspectRange": "ǝbuɐᴚʇɔǝdsoɹԀʞɔoᴚǝɔɐɟɹns", "config.gtceu.option.tankItemFluidPreview": "ʍǝıʌǝɹԀpınןℲɯǝʇIʞuɐʇ", - "config.gtceu.option.temperaturesInKelvin": "uıʌןǝʞuIsǝɹnʇɐɹǝdɯǝʇ", + "config.gtceu.option.temperaturesInCelsius": "snısןǝƆuIsǝɹnʇɐɹǝdɯǝʇ", "config.gtceu.option.titaniumBoilerHeatSpeed": "pǝǝdSʇɐǝHɹǝןıoᗺɯnıuɐʇıʇ", "config.gtceu.option.titaniumBoilerMaxTemperature": "ǝɹnʇɐɹǝdɯǝ⟘xɐWɹǝןıoᗺɯnıuɐʇıʇ", "config.gtceu.option.toggle": "ǝןbboʇ", @@ -2616,6 +2618,7 @@ "gtceu.key.armor_mode_switch": "ɥɔʇıʍS ǝpoW ɹoɯɹⱯ", "gtceu.key.enable_boots": "dɯnſ pǝʇsooᗺ ǝןqɐuƎ", "gtceu.key.enable_jetpack": "ʞɔɐdʇǝſ ǝןqɐuƎ", + "gtceu.key.enable_step_assist": "ʇsıssⱯdǝʇS ǝןqɐuƎ", "gtceu.key.tool_aoe_change": "ɥɔʇıʍS ǝpoW ƎoⱯ ןoo⟘", "gtceu.large_boiler": "ɹǝןıoᗺ ǝbɹɐꞀ", "gtceu.large_chemical_reactor": "ɹoʇɔɐǝᴚ ןɐɔıɯǝɥƆ ǝbɹɐꞀ", @@ -4733,7 +4736,7 @@ "item.gtceu.talc_dust": "ɔןɐ⟘", "item.gtceu.tantalum_capacitor": "ɹoʇıɔɐdɐƆ ɯnןɐʇuɐ⟘", "item.gtceu.terminal": "ןɐuıɯɹǝ⟘", - "item.gtceu.terminal.tooltip": "ʞɔoןq-ıʇןnɯ ǝɥʇ pןınq ʎןןɐɔıʇɐɯoʇnɐ oʇ ɹǝןןoɹʇuoɔ ɐ uo ʞɔıןƆ-ᴚ + ʇɟıɥS", + "item.gtceu.terminal.tooltip": "ʎɹoʇuǝʌuı ɹnoʎ ɯoɹɟ sɯǝʇı ɥʇıʍ ʞɔoןqıʇןnɯ ɐ pןınq ʎןןɐɔıʇɐɯoʇnɐ oʇ ɹǝןןoɹʇuoɔ ɐ uo ʞɔıןƆ-ᴚ + ʇɟıɥS", "item.gtceu.text_module": "ǝןnpoW ʇxǝ⟘", "item.gtceu.tiny_ash_dust": "sǝɥsⱯ ɟo ǝןıԀ ʎuı⟘", "item.gtceu.tiny_basaltic_mineral_sand_dust": "puɐS ןɐɹǝuıW ɔıʇןɐsɐᗺ ɟo ǝןıԀ ʎuı⟘", @@ -4836,7 +4839,7 @@ "item.gtceu.tool.lv_screwdriver.tooltip": "sǝuıɥɔɐW puɐ sɹǝʌoƆ sʇsnظpⱯ8§", "item.gtceu.tool.lv_wirecutter": ")ΛꞀ( ɹǝʇʇnƆ ǝɹıM %s", "item.gtceu.tool.lv_wrench": ")ΛꞀ( ɥɔuǝɹM %s", - "item.gtceu.tool.lv_wrench.tooltip": "sǝuıɥɔɐW ǝןʇuɐɯsıp oʇs ʞɔıןɔ ʇɟǝן pןoH8§", + "item.gtceu.tool.lv_wrench.tooltip": "sǝuıɥɔɐW ǝןʇuɐɯsıp oʇ ʞɔıןɔ ʇɟǝן pןoH8§", "item.gtceu.tool.mallet": "ʇǝןןɐW ʇɟoS %s", "item.gtceu.tool.mallet.tooltip.0": "˙ǝdıɔǝᴚ ʇuǝɹɹnƆ ɹǝʇɟⱯ ǝuıɥɔɐW ǝsnɐԀ oʇ ʞɐǝuS8§", "item.gtceu.tool.mallet.tooltip.1": "sǝuıɥɔɐW sʇɹɐʇS/sdoʇS8§", @@ -5698,20 +5701,24 @@ "metaarmor.message.nightvision.disabled": "ɟɟOɔ§ :uoısıΛʇɥbıNq§", "metaarmor.message.nightvision.enabled": "uOɐ§ :uoısıΛʇɥbıNq§", "metaarmor.message.nightvision.error": "¡ɹǝʍod ɥbnouǝ ʇoNɔ§", - "metaarmor.nms.boosted_jump.disabled": "pǝןqɐsıᗡ ʇsooᗺ dɯnſ :ǝʇınS ™ǝןɔsnWouɐN", - "metaarmor.nms.boosted_jump.enabled": "pǝןqɐuƎ ʇsooᗺ dɯnſ :ǝʇınS ™ǝןɔsnWouɐN", "metaarmor.nms.nightvision.disabled": "pǝןqɐsıᗡ uoısıΛʇɥbıN :ǝʇınS ™ǝןɔsnWouɐN", "metaarmor.nms.nightvision.enabled": "pǝןqɐuƎ uoısıΛʇɥbıN :ǝʇınS ™ǝןɔsnWouɐN", "metaarmor.nms.nightvision.error": "¡ɹǝʍod ɥbnouǝ ʇoNɔ§ :ǝʇınS ™ǝןɔsnWouɐN", "metaarmor.nms.share.disable": "pǝןqɐsıᗡ buıbɹɐɥƆ :ǝʇınS ™ǝןɔsnWouɐN", "metaarmor.nms.share.enable": "pǝןqɐuƎ buıbɹɐɥƆ :ǝʇınS ™ǝןɔsnWouɐN", "metaarmor.nms.share.error": "¡buıbɹɐɥɔ ɹoɟ ɹǝʍod ɥbnouǝ ʇoNɔ§ :ǝʇınS ™ǝןɔsnWouɐN", + "metaarmor.nms.step_assist.disabled": "pǝןqɐsıᗡ ʇsıssⱯdǝʇS :ǝʇınS ™ǝןɔsnWouɐN", + "metaarmor.nms.step_assist.enabled": "pǝןqɐuƎ ʇsıssⱯdǝʇS :ǝʇınS ™ǝןɔsnWouɐN", + "metaarmor.qts.boosted_jump.disabled": "pǝןqɐsıᗡ ʇsooᗺ dɯnſ :ǝʇınS ™ɥɔǝ⟘ʞɹɐnὉ", + "metaarmor.qts.boosted_jump.enabled": "pǝןqɐuƎ ʇsooᗺ dɯnſ :ǝʇınS ™ɥɔǝ⟘ʞɹɐnὉ", "metaarmor.qts.nightvision.disabled": "pǝןqɐsıᗡ uoısıΛʇɥbıN :ǝʇınS ™ɥɔǝ⟘ʞɹɐnὉ", "metaarmor.qts.nightvision.enabled": "pǝןqɐuƎ uoısıΛʇɥbıN :ǝʇınS ™ɥɔǝ⟘ʞɹɐnὉ", "metaarmor.qts.nightvision.error": "¡ɹǝʍod ɥbnouǝ ʇoNɔ§ :ǝʇınS ™ɥɔǝ⟘ʞɹɐnὉ", "metaarmor.qts.share.disable": "pǝןqɐsıᗡ buıbɹɐɥƆ :ǝʇınS ™ɥɔǝ⟘ʞɹɐnὉ", "metaarmor.qts.share.enable": "pǝןqɐuƎ buıbɹɐɥƆ :ǝʇınS ™ɥɔǝ⟘ʞɹɐnὉ", "metaarmor.qts.share.error": "¡buıbɹɐɥɔ ɹoɟ ɹǝʍod ɥbnouǝ ʇoNɔ§ :ǝʇınS ™ɥɔǝ⟘ʞɹɐnὉ", + "metaarmor.qts.step_assist.disabled": "pǝןqɐsıᗡ ʇsıssⱯdǝʇS :ǝʇınS ™ɥɔǝ⟘ʞɹɐnὉ", + "metaarmor.qts.step_assist.enabled": "pǝןqɐuƎ ʇsıssⱯdǝʇS :ǝʇınS ™ɥɔǝ⟘ʞɹɐnὉ", "metaarmor.tooltip.autoeat": "ʎɹoʇuǝʌuI ɯoɹɟ pooℲ buıs∩ ʎq ɹɐᗺ pooℲ sǝɥsıuǝןdǝᴚ", "metaarmor.tooltip.breath": "ɹɐᗺ ɥʇɐǝɹᗺ ɹǝʇɐʍɹǝpu∩ sǝɥsıuǝןdǝᴚ", "metaarmor.tooltip.burning": "buıuɹnᗺ sǝıɟıןןnN", diff --git a/src/generated/resources/assets/gtceu/lang/en_us.json b/src/generated/resources/assets/gtceu/lang/en_us.json index b738160a97f..3ceb805dee1 100644 --- a/src/generated/resources/assets/gtceu/lang/en_us.json +++ b/src/generated/resources/assets/gtceu/lang/en_us.json @@ -66,6 +66,7 @@ "behaviour.lighter.uses": "Remaining uses: %d", "behaviour.memory_card.client_msg.cleared": "Stored configuration cleared", "behaviour.memory_card.client_msg.copied": "Copied machine configuration", + "behaviour.memory_card.client_msg.missing_items": "Missing items required to paste configuration", "behaviour.memory_card.client_msg.pasted": "Applied machine configuration", "behaviour.memory_card.copy_target": "Copying: %s", "behaviour.memory_card.disabled": "§cDisabled§r", @@ -1745,6 +1746,7 @@ "config.gtceu.option.addLoot": "addLoot", "config.gtceu.option.ae2": "ae2", "config.gtceu.option.allowDrumsInputFluidsFromOutputSide": "allowDrumsInputFluidsFromOutputSide", + "config.gtceu.option.allowedImageDomains": "allowedImageDomains", "config.gtceu.option.animationTime": "animationTime", "config.gtceu.option.arcRecyclingYield": "arcRecyclingYield", "config.gtceu.option.armorHud": "armorHud", @@ -1892,7 +1894,7 @@ "config.gtceu.option.steelSteamMultiblocks": "steelSteamMultiblocks", "config.gtceu.option.surfaceRockProspectRange": "surfaceRockProspectRange", "config.gtceu.option.tankItemFluidPreview": "tankItemFluidPreview", - "config.gtceu.option.temperaturesInKelvin": "temperaturesInKelvin", + "config.gtceu.option.temperaturesInCelsius": "temperaturesInCelsius", "config.gtceu.option.titaniumBoilerHeatSpeed": "titaniumBoilerHeatSpeed", "config.gtceu.option.titaniumBoilerMaxTemperature": "titaniumBoilerMaxTemperature", "config.gtceu.option.toggle": "toggle", @@ -2616,8 +2618,8 @@ "gtceu.key.armor_mode_switch": "Armor Mode Switch", "gtceu.key.enable_boots": "Enable Boosted Jump", "gtceu.key.enable_jetpack": "Enable Jetpack", - "gtceu.key.tool_aoe_change": "Tool AoE Mode Switch", "gtceu.key.enable_step_assist": "Enable StepAssist", + "gtceu.key.tool_aoe_change": "Tool AoE Mode Switch", "gtceu.large_boiler": "Large Boiler", "gtceu.large_chemical_reactor": "Large Chemical Reactor", "gtceu.laser_engraver": "Laser Engraver", @@ -4734,7 +4736,7 @@ "item.gtceu.talc_dust": "Talc", "item.gtceu.tantalum_capacitor": "Tantalum Capacitor", "item.gtceu.terminal": "Terminal", - "item.gtceu.terminal.tooltip": "Shift + R-Click on a controller to automatically build the multi-block", + "item.gtceu.terminal.tooltip": "Shift + R-Click on a controller to automatically build a multiblock with items from your inventory", "item.gtceu.text_module": "Text Module", "item.gtceu.tiny_ash_dust": "Tiny Pile of Ashes", "item.gtceu.tiny_basaltic_mineral_sand_dust": "Tiny Pile of Basaltic Mineral Sand", @@ -5699,26 +5701,24 @@ "metaarmor.message.nightvision.disabled": "§bNightVision: §cOff", "metaarmor.message.nightvision.enabled": "§bNightVision: §aOn", "metaarmor.message.nightvision.error": "§cNot enough power!", - "metaarmor.message.step_assist.disabled": "StepAssist: §cOff", - "metaarmor.message.step_assist.enabled": "StepAssist: §aOn", "metaarmor.nms.nightvision.disabled": "NanoMuscle™ Suite: NightVision Disabled", "metaarmor.nms.nightvision.enabled": "NanoMuscle™ Suite: NightVision Enabled", "metaarmor.nms.nightvision.error": "NanoMuscle™ Suite: §cNot enough power!", - "metaarmor.qts.nightvision.disabled": "QuarkTech™ Suite: NightVision Disabled", - "metaarmor.qts.nightvision.enabled": "QuarkTech™ Suite: NightVision Enabled", - "metaarmor.qts.nightvision.error": "QuarkTech™ Suite: §cNot enough power!", - "metaarmor.nms.step_assist.disabled": "NanoMuscle™ Suite: StepAssist Disabled", - "metaarmor.nms.step_assist.enabled": "NanoMuscle™ Suite: StepAssist Enabled", - "metaarmor.qts.step_assist.disabled": "QuarkTech™ Suite: StepAssist Disabled", - "metaarmor.qts.step_assist.enabled": "QuarkTech™ Suite: StepAssist Enabled", "metaarmor.nms.share.disable": "NanoMuscle™ Suite: Charging Disabled", "metaarmor.nms.share.enable": "NanoMuscle™ Suite: Charging Enabled", "metaarmor.nms.share.error": "NanoMuscle™ Suite: §cNot enough power for charging!", + "metaarmor.nms.step_assist.disabled": "NanoMuscle™ Suite: StepAssist Disabled", + "metaarmor.nms.step_assist.enabled": "NanoMuscle™ Suite: StepAssist Enabled", + "metaarmor.qts.boosted_jump.disabled": "QuarkTech™ Suite: Jump Boost Disabled", + "metaarmor.qts.boosted_jump.enabled": "QuarkTech™ Suite: Jump Boost Enabled", + "metaarmor.qts.nightvision.disabled": "QuarkTech™ Suite: NightVision Disabled", + "metaarmor.qts.nightvision.enabled": "QuarkTech™ Suite: NightVision Enabled", + "metaarmor.qts.nightvision.error": "QuarkTech™ Suite: §cNot enough power!", "metaarmor.qts.share.disable": "QuarkTech™ Suite: Charging Disabled", "metaarmor.qts.share.enable": "QuarkTech™ Suite: Charging Enabled", "metaarmor.qts.share.error": "QuarkTech™ Suite: §cNot enough power for charging!", - "metaarmor.qts.boosted_jump.disabled": "QuarkTech™ Suite: Jump Boost Disabled", - "metaarmor.qts.boosted_jump.enabled": "QuarkTech™ Suite: Jump Boost Enabled", + "metaarmor.qts.step_assist.disabled": "QuarkTech™ Suite: StepAssist Disabled", + "metaarmor.qts.step_assist.enabled": "QuarkTech™ Suite: StepAssist Enabled", "metaarmor.tooltip.autoeat": "Replenishes Food Bar by Using Food from Inventory", "metaarmor.tooltip.breath": "Replenishes Underwater Breath Bar", "metaarmor.tooltip.burning": "Nullifies Burning", diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/center.json index 6318ac6c5b3..1916aa7d966 100644 --- a/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/center.json +++ b/src/generated/resources/assets/gtceu/models/block/pipe/huge_duct_pipe/center.json @@ -41,7 +41,6 @@ } ], "textures": { - "end": "gtceu:block/pipe/pipe_duct_in", "side": "gtceu:block/pipe/pipe_duct_side" } } \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/center.json index 26aeac6acf3..39b3a894eac 100644 --- a/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/center.json +++ b/src/generated/resources/assets/gtceu/models/block/pipe/large_duct_pipe/center.json @@ -41,7 +41,6 @@ } ], "textures": { - "end": "gtceu:block/pipe/pipe_duct_in", "side": "gtceu:block/pipe/pipe_duct_side" } } \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/center.json index 55bac017a34..1c7b6fe9ce9 100644 --- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/center.json +++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_duct_pipe/center.json @@ -41,7 +41,6 @@ } ], "textures": { - "end": "gtceu:block/pipe/pipe_duct_in", "side": "gtceu:block/pipe/pipe_duct_side" } } \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center.json index 0cc3032c0e5..9de7a83201f 100644 --- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center.json +++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center.json @@ -79,7 +79,6 @@ } ], "textures": { - "end": "gtceu:block/pipe/pipe_laser_in", "side": "gtceu:block/pipe/pipe_laser_side", "side_overlay": "gtceu:block/pipe/pipe_laser_side_overlay" } diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center_active.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center_active.json index 18781c339d2..088aa774a9f 100644 --- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center_active.json +++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/center_active.json @@ -1,6 +1,115 @@ { - "parent": "gtceu:block/pipe/normal_laser_pipe/center", + "parent": "minecraft:block/block", + "elements": [ + { + "faces": { + "down": { + "texture": "#side", + "tintindex": 0 + }, + "east": { + "texture": "#side", + "tintindex": 0 + }, + "north": { + "texture": "#side", + "tintindex": 0 + }, + "south": { + "texture": "#side", + "tintindex": 0 + }, + "up": { + "texture": "#side", + "tintindex": 0 + }, + "west": { + "texture": "#side", + "tintindex": 0 + } + }, + "from": [ + 5, + 5, + 5 + ], + "to": [ + 11, + 11, + 11 + ] + }, + { + "faces": { + "down": { + "forge_data": { + "ambient_occlusion": false, + "block_light": 15, + "sky_light": 15 + }, + "texture": "#side_overlay", + "tintindex": 2 + }, + "east": { + "forge_data": { + "ambient_occlusion": false, + "block_light": 15, + "sky_light": 15 + }, + "texture": "#side_overlay", + "tintindex": 2 + }, + "north": { + "forge_data": { + "ambient_occlusion": false, + "block_light": 15, + "sky_light": 15 + }, + "texture": "#side_overlay", + "tintindex": 2 + }, + "south": { + "forge_data": { + "ambient_occlusion": false, + "block_light": 15, + "sky_light": 15 + }, + "texture": "#side_overlay", + "tintindex": 2 + }, + "up": { + "forge_data": { + "ambient_occlusion": false, + "block_light": 15, + "sky_light": 15 + }, + "texture": "#side_overlay", + "tintindex": 2 + }, + "west": { + "forge_data": { + "ambient_occlusion": false, + "block_light": 15, + "sky_light": 15 + }, + "texture": "#side_overlay", + "tintindex": 2 + } + }, + "from": [ + 4.998, + 4.998, + 4.998 + ], + "to": [ + 11.002, + 11.002, + 11.002 + ] + } + ], "textures": { + "side": "gtceu:block/pipe/pipe_laser_side", "side_overlay": "gtceu:block/pipe/pipe_laser_side_overlay_emissive" } } \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection_active.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection_active.json index a9170249dab..83cb7127326 100644 --- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection_active.json +++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_laser_pipe/connection_active.json @@ -1,6 +1,99 @@ { - "parent": "gtceu:block/pipe/normal_laser_pipe/connection", + "parent": "minecraft:block/block", + "elements": [ + { + "faces": { + "down": { + "cullface": "down", + "texture": "#end", + "tintindex": 1 + }, + "east": { + "texture": "#side", + "tintindex": 0 + }, + "north": { + "texture": "#side", + "tintindex": 0 + }, + "south": { + "texture": "#side", + "tintindex": 0 + }, + "up": { + "texture": "#end", + "tintindex": 1 + }, + "west": { + "texture": "#side", + "tintindex": 0 + } + }, + "from": [ + 5, + 0, + 5 + ], + "to": [ + 11, + 5, + 11 + ] + }, + { + "faces": { + "east": { + "forge_data": { + "ambient_occlusion": false, + "block_light": 15, + "sky_light": 15 + }, + "texture": "#side_overlay", + "tintindex": 2 + }, + "north": { + "forge_data": { + "ambient_occlusion": false, + "block_light": 15, + "sky_light": 15 + }, + "texture": "#side_overlay", + "tintindex": 2 + }, + "south": { + "forge_data": { + "ambient_occlusion": false, + "block_light": 15, + "sky_light": 15 + }, + "texture": "#side_overlay", + "tintindex": 2 + }, + "west": { + "forge_data": { + "ambient_occlusion": false, + "block_light": 15, + "sky_light": 15 + }, + "texture": "#side_overlay", + "tintindex": 2 + } + }, + "from": [ + 4.998, + -0.002, + 4.998 + ], + "to": [ + 11.002, + 5.002, + 11.002 + ] + } + ], "textures": { + "end": "gtceu:block/pipe/pipe_laser_in", + "side": "gtceu:block/pipe/pipe_laser_side", "side_overlay": "gtceu:block/pipe/pipe_laser_side_overlay_emissive" } } \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center.json index c5356268055..1c46b15f85c 100644 --- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center.json +++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center.json @@ -79,7 +79,6 @@ } ], "textures": { - "end": "gtceu:block/pipe/pipe_optical_in", "side": "gtceu:block/pipe/pipe_optical_side", "side_overlay": "gtceu:block/pipe/pipe_optical_side_overlay" } diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center_active.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center_active.json index ac513d036e5..3a643f6dcc4 100644 --- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center_active.json +++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/center_active.json @@ -1,6 +1,115 @@ { - "parent": "gtceu:block/pipe/normal_optical_pipe/center", + "parent": "minecraft:block/block", + "elements": [ + { + "faces": { + "down": { + "texture": "#side", + "tintindex": 0 + }, + "east": { + "texture": "#side", + "tintindex": 0 + }, + "north": { + "texture": "#side", + "tintindex": 0 + }, + "south": { + "texture": "#side", + "tintindex": 0 + }, + "up": { + "texture": "#side", + "tintindex": 0 + }, + "west": { + "texture": "#side", + "tintindex": 0 + } + }, + "from": [ + 5, + 5, + 5 + ], + "to": [ + 11, + 11, + 11 + ] + }, + { + "faces": { + "down": { + "forge_data": { + "ambient_occlusion": false, + "block_light": 15, + "sky_light": 15 + }, + "texture": "#side_overlay", + "tintindex": 2 + }, + "east": { + "forge_data": { + "ambient_occlusion": false, + "block_light": 15, + "sky_light": 15 + }, + "texture": "#side_overlay", + "tintindex": 2 + }, + "north": { + "forge_data": { + "ambient_occlusion": false, + "block_light": 15, + "sky_light": 15 + }, + "texture": "#side_overlay", + "tintindex": 2 + }, + "south": { + "forge_data": { + "ambient_occlusion": false, + "block_light": 15, + "sky_light": 15 + }, + "texture": "#side_overlay", + "tintindex": 2 + }, + "up": { + "forge_data": { + "ambient_occlusion": false, + "block_light": 15, + "sky_light": 15 + }, + "texture": "#side_overlay", + "tintindex": 2 + }, + "west": { + "forge_data": { + "ambient_occlusion": false, + "block_light": 15, + "sky_light": 15 + }, + "texture": "#side_overlay", + "tintindex": 2 + } + }, + "from": [ + 4.998, + 4.998, + 4.998 + ], + "to": [ + 11.002, + 11.002, + 11.002 + ] + } + ], "textures": { + "side": "gtceu:block/pipe/pipe_optical_side", "side_overlay": "gtceu:block/pipe/pipe_optical_side_overlay_active" } } \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection_active.json b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection_active.json index 224c446f985..962efa95cf6 100644 --- a/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection_active.json +++ b/src/generated/resources/assets/gtceu/models/block/pipe/normal_optical_pipe/connection_active.json @@ -1,6 +1,99 @@ { - "parent": "gtceu:block/pipe/normal_optical_pipe/connection", + "parent": "minecraft:block/block", + "elements": [ + { + "faces": { + "down": { + "cullface": "down", + "texture": "#end", + "tintindex": 1 + }, + "east": { + "texture": "#side", + "tintindex": 0 + }, + "north": { + "texture": "#side", + "tintindex": 0 + }, + "south": { + "texture": "#side", + "tintindex": 0 + }, + "up": { + "texture": "#end", + "tintindex": 1 + }, + "west": { + "texture": "#side", + "tintindex": 0 + } + }, + "from": [ + 5, + 0, + 5 + ], + "to": [ + 11, + 5, + 11 + ] + }, + { + "faces": { + "east": { + "forge_data": { + "ambient_occlusion": false, + "block_light": 15, + "sky_light": 15 + }, + "texture": "#side_overlay", + "tintindex": 2 + }, + "north": { + "forge_data": { + "ambient_occlusion": false, + "block_light": 15, + "sky_light": 15 + }, + "texture": "#side_overlay", + "tintindex": 2 + }, + "south": { + "forge_data": { + "ambient_occlusion": false, + "block_light": 15, + "sky_light": 15 + }, + "texture": "#side_overlay", + "tintindex": 2 + }, + "west": { + "forge_data": { + "ambient_occlusion": false, + "block_light": 15, + "sky_light": 15 + }, + "texture": "#side_overlay", + "tintindex": 2 + } + }, + "from": [ + 4.998, + -0.002, + 4.998 + ], + "to": [ + 11.002, + 5.002, + 11.002 + ] + } + ], "textures": { + "end": "gtceu:block/pipe/pipe_optical_in", + "side": "gtceu:block/pipe/pipe_optical_side", "side_overlay": "gtceu:block/pipe/pipe_optical_side_overlay_active" } } \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/center.json b/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/center.json index 98a31bc47ef..cf2698d2453 100644 --- a/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/center.json +++ b/src/generated/resources/assets/gtceu/models/block/pipe/small_duct_pipe/center.json @@ -41,7 +41,6 @@ } ], "textures": { - "end": "gtceu:block/pipe/pipe_duct_in", "side": "gtceu:block/pipe/pipe_duct_side" } } \ No newline at end of file diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/machine/overlays/HPCAOverlay.java b/src/main/java/com/gregtechceu/gtceu/client/model/machine/overlays/HPCAOverlay.java index 3ea09f9003c..ed8de15bb92 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/model/machine/overlays/HPCAOverlay.java +++ b/src/main/java/com/gregtechceu/gtceu/client/model/machine/overlays/HPCAOverlay.java @@ -3,6 +3,7 @@ import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic.Status; import com.gregtechceu.gtceu.api.registry.registrate.provider.GTBlockstateProvider; import com.gregtechceu.gtceu.common.data.models.GTModels; +import com.gregtechceu.gtceu.utils.data.RuntimeExistingFileHelper; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.resources.ResourceLocation; @@ -23,31 +24,47 @@ public class HPCAOverlay { // spotless:off public static HPCAOverlay get(ResourceLocation normalSprite, ResourceLocation damagedSprite, ExistingFileHelper fileHelper) { - // normal - if (!fileHelper.exists(normalSprite, GTBlockstateProvider.TEXTURE)) { - return HPCAOverlay.EMPTY; + if (fileHelper instanceof RuntimeExistingFileHelper runtimeFileHelper) { + // if fileHelper is an instance of RuntimeExistingFileHelper, we have to enable its existence checking. + // the AutoCloseable warning is suppressed here because there's no clean way to + // use a try-with-resources statement in this. + //noinspection resource + fileHelper = runtimeFileHelper.activeHelper(); } - ResourceLocation activeSprite = normalSprite.withSuffix("_active"); - if (!fileHelper.exists(activeSprite, GTBlockstateProvider.TEXTURE)) activeSprite = normalSprite; - ResourceLocation damagedActiveSprite = damagedSprite.withSuffix("_active"); - if (!fileHelper.exists(damagedActiveSprite, GTBlockstateProvider.TEXTURE)) damagedActiveSprite = damagedSprite; - - // emissive - ResourceLocation normalSpriteEmissive = normalSprite.withSuffix("_emissive"); - if (!fileHelper.exists(normalSpriteEmissive, GTBlockstateProvider.TEXTURE)) normalSpriteEmissive = null; - - ResourceLocation activeSpriteEmissive = activeSprite.withSuffix("_emissive"); - if (!fileHelper.exists(activeSpriteEmissive, GTBlockstateProvider.TEXTURE)) activeSpriteEmissive = null; - - ResourceLocation damagedSpriteEmissive = damagedSprite.withSuffix("_emissive"); - if (!fileHelper.exists(damagedSpriteEmissive, GTBlockstateProvider.TEXTURE)) damagedSpriteEmissive = null; - - ResourceLocation damagedActiveSpriteEmissive = damagedActiveSprite.withSuffix("_emissive"); - if (!fileHelper.exists(damagedActiveSpriteEmissive, GTBlockstateProvider.TEXTURE)) damagedActiveSpriteEmissive = null; - - return new HPCAOverlay(normalSprite, activeSprite, damagedSprite, damagedActiveSprite, - normalSpriteEmissive, activeSpriteEmissive, damagedSpriteEmissive, damagedActiveSpriteEmissive); + try { + // normal + if (!fileHelper.exists(normalSprite, GTBlockstateProvider.TEXTURE)) { + return HPCAOverlay.EMPTY; + } + ResourceLocation activeSprite = normalSprite.withSuffix("_active"); + if (!fileHelper.exists(activeSprite, GTBlockstateProvider.TEXTURE)) activeSprite = normalSprite; + + ResourceLocation damagedActiveSprite = damagedSprite.withSuffix("_active"); + if (!fileHelper.exists(damagedActiveSprite, GTBlockstateProvider.TEXTURE)) damagedActiveSprite = damagedSprite; + + // emissive + ResourceLocation normalSpriteEmissive = normalSprite.withSuffix("_emissive"); + if (!fileHelper.exists(normalSpriteEmissive, GTBlockstateProvider.TEXTURE)) normalSpriteEmissive = null; + + ResourceLocation activeSpriteEmissive = activeSprite.withSuffix("_emissive"); + if (!fileHelper.exists(activeSpriteEmissive, GTBlockstateProvider.TEXTURE)) activeSpriteEmissive = null; + + ResourceLocation damagedSpriteEmissive = damagedSprite.withSuffix("_emissive"); + if (!fileHelper.exists(damagedSpriteEmissive, GTBlockstateProvider.TEXTURE)) damagedSpriteEmissive = null; + + ResourceLocation damagedActiveSpriteEmissive = damagedActiveSprite.withSuffix("_emissive"); + if (!fileHelper.exists(damagedActiveSpriteEmissive, GTBlockstateProvider.TEXTURE)) damagedActiveSpriteEmissive = null; + + return new HPCAOverlay(normalSprite, activeSprite, damagedSprite, damagedActiveSprite, + normalSpriteEmissive, activeSpriteEmissive, damagedSpriteEmissive, damagedActiveSpriteEmissive); + } finally { + if (fileHelper instanceof RuntimeExistingFileHelper.Active activeHelper) { + // close the active helper, just for good measure. + // Also in case we ever make it do anything, this won't be forgotten. + activeHelper.close(); + } + } } // spotless:on diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/machine/overlays/WorkableOverlays.java b/src/main/java/com/gregtechceu/gtceu/client/model/machine/overlays/WorkableOverlays.java index bf09a89f026..373ab7b33c6 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/model/machine/overlays/WorkableOverlays.java +++ b/src/main/java/com/gregtechceu/gtceu/client/model/machine/overlays/WorkableOverlays.java @@ -4,6 +4,7 @@ import com.gregtechceu.gtceu.api.registry.registrate.provider.GTBlockstateProvider; import com.gregtechceu.gtceu.common.data.models.GTMachineModels; import com.gregtechceu.gtceu.common.data.models.GTModels; +import com.gregtechceu.gtceu.utils.data.RuntimeExistingFileHelper; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.Direction; @@ -25,6 +26,14 @@ public class WorkableOverlays { public static WorkableOverlays get(ResourceLocation textureDir, ExistingFileHelper fileHelper) { + if (fileHelper instanceof RuntimeExistingFileHelper runtimeFileHelper) { + // if fileHelper is an instance of RuntimeExistingFileHelper, we have to enable its existence checking. + // the AutoCloseable warning is suppressed here because there's no clean way to + // use a try-with-resources statement in this. + // noinspection resource + fileHelper = runtimeFileHelper.activeHelper(); + } + WorkableOverlays model = new WorkableOverlays(textureDir); for (OverlayFace overlayFace : OverlayFace.VALUES) { @@ -55,6 +64,13 @@ public static WorkableOverlays get(ResourceLocation textureDir, ExistingFileHelp model.textures.put(overlayFace, new StatusTextures(normalSprite, activeSprite, pausedSprite, normalSpriteEmissive, activeSpriteEmissive, pausedSpriteEmissive)); } + + if (fileHelper instanceof RuntimeExistingFileHelper.Active activeHelper) { + // close the active helper, just for good measure. + // Also in case we ever make it do anything, this won't be forgotten. + activeHelper.close(); + } + return model; } diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/ActivablePipeModel.java b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/ActivablePipeModel.java index dc257bd4770..4213be34926 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/ActivablePipeModel.java +++ b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/ActivablePipeModel.java @@ -5,10 +5,14 @@ import com.gregtechceu.gtceu.api.registry.registrate.provider.GTBlockstateProvider; import com.gregtechceu.gtceu.data.model.builder.PipeModelBuilder; +import net.minecraft.core.Direction; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.client.model.generators.BlockModelBuilder; import net.minecraftforge.client.model.generators.IGeneratedBlockState; +import net.minecraftforge.client.model.generators.ModelBuilder; +import net.minecraftforge.client.model.generators.ModelFile; +import it.unimi.dsi.fastutil.objects.Reference2FloatMap; import lombok.Setter; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; @@ -23,6 +27,8 @@ public class ActivablePipeModel extends PipeModel { public @Nullable ResourceLocation sideSecondaryActive, endSecondaryActive; @Setter public @Nullable ResourceLocation sideOverlayActive, endOverlayActive; + @Setter + public int activeEmissivity = 15; /// Use {@link #getOrCreateActiveBlockModel()} instead of referencing this field directly. private BlockModelBuilder activeBlockModel; @@ -67,8 +73,7 @@ protected BlockModelBuilder getOrCreateActiveBlockModel() { // spotless:off return this.activeBlockModel = this.provider.models().getBuilder(this.blockId.withSuffix("_active").toString()) .parent(this.getOrCreateActiveCenterElement()) - .customLoader(PipeModelBuilder::begin) - .thickness(this.thickness).provider(this.provider) + .customLoader(PipeModelBuilder.begin(this.thickness, this.provider)) .centerModels(this.getOrCreateActiveCenterElement().getLocation()) .connectionModels(this.getOrCreateActiveConnectionElement().getLocation()) .end(); @@ -87,7 +92,9 @@ protected BlockModelBuilder getOrCreateActiveCenterElement() { if (this.activeCenterElement != null) { return this.activeCenterElement; } - return this.activeCenterElement = makeActiveVariant(this.getOrCreateCenterElement()); + return this.activeCenterElement = makeActiveElementModel( + this.blockId.withPath(path -> "block/pipe/" + path + "/center_active"), + null, minCoord, minCoord, minCoord, maxCoord, maxCoord, maxCoord); } /** @@ -105,24 +112,82 @@ protected BlockModelBuilder getOrCreateActiveConnectionElement() { if (this.activeConnectionElement != null) { return this.activeConnectionElement; } - return this.activeConnectionElement = makeActiveVariant(this.getOrCreateConnectionElement()); + return this.activeConnectionElement = makeActiveElementModel( + this.blockId.withPath(path -> "block/pipe/" + path + "/connection_active"), + Direction.DOWN, minCoord, 0, minCoord, maxCoord, minCoord, maxCoord); } - protected BlockModelBuilder makeActiveVariant(BlockModelBuilder parentModel) { - BlockModelBuilder model = this.provider.models() - .getBuilder(parentModel.getLocation().withSuffix("_active").toString()) - .parent(parentModel); - // override non-null textures, leave unset ones as is - if (this.sideActive != null) model.texture("side", this.sideActive); - if (this.endActive != null) model.texture("end", this.endActive); - if (this.sideSecondaryActive != null) model.texture("side_secondary", this.sideSecondaryActive); - if (this.endSecondaryActive != null) model.texture("end_secondary", this.endSecondaryActive); - if (this.sideOverlayActive != null) model.texture("side_overlay", this.sideOverlayActive); - if (this.endOverlayActive != null) model.texture("end_overlay", this.endOverlayActive); + /** + * Fills out a model builder with applicable pipe model elements and returns it for further use + *
+ * This method is a copy of {@linkplain #makeElementModel} with the texture references changed for active variants. + * + * @param name the resulting model's path + * @param endFace the model face that's being created + * @param x1 min X coordinate in the range [-16,32] + * @param y1 min Y coordinate in the range [-16,32] + * @param z1 min Z coordinate in the range [-16,32] + * @param x2 max X coordinate in the range [-16,32] + * @param y2 max Y coordinate in the range [-16,32] + * @param z2 max Z coordinate in the range [-16,32] + * @implNote The coordinates must be in the correct order or the resulting model's cubes will be inside out! + * @see #makeElementModel + */ + protected BlockModelBuilder makeActiveElementModel(ResourceLocation name, @Nullable Direction endFace, + final float x1, final float y1, final float z1, + final float x2, final float y2, final float z2) { + Reference2FloatMap faceEndpoints = makeFaceEndpointMap(x1, y1, z1, x2, y2, z2); + + BlockModelBuilder model = this.provider.models().getBuilder(name.toString()) + .parent(new ModelFile.UncheckedModelFile("block/block")); + + ResourceLocation side = this.sideActive != null ? this.sideActive : this.side; + ResourceLocation end = this.endActive != null ? this.endActive : this.end; + ResourceLocation sideSecondary = this.sideSecondaryActive != null ? this.sideSecondaryActive : + this.sideSecondary; + ResourceLocation endSecondary = this.endSecondaryActive != null ? this.endSecondaryActive : this.endSecondary; + ResourceLocation sideOverlay = this.sideOverlayActive != null ? this.sideOverlayActive : this.sideOverlay; + ResourceLocation endOverlay = this.endOverlayActive != null ? this.endOverlayActive : this.endOverlay; + + makePartModelElement(model, endFace, false, faceEndpoints, 0.0f, 0, 1, + x1, y1, z1, x2, y2, z2, side, end, SIDE_KEY, END_KEY, + this.sideActive != null, this.endActive != null); + + makePartModelElement(model, endFace, true, faceEndpoints, 0.001f, 0, 1, + x1, y1, z1, x2, y2, z2, sideSecondary, endSecondary, SIDE_SECONDARY_KEY, END_SECONDARY_KEY, + this.sideSecondaryActive != null, this.endSecondaryActive != null); + + makePartModelElement(model, endFace, true, faceEndpoints, 0.002f, 2, 2, + x1, y1, z1, x2, y2, z2, sideOverlay, endOverlay, SIDE_OVERLAY_KEY, END_OVERLAY_KEY, + this.sideOverlayActive != null, this.endOverlayActive != null); return model; } + protected > void makePartModelElement(T model, @Nullable Direction endFace, + boolean useEndWithFullCube, + Reference2FloatMap faceEndpoints, + float offset, int sideTintIndex, int endTintIndex, + final float x1, final float y1, final float z1, + final float x2, final float y2, final float z2, + @Nullable ResourceLocation sideTexture, + @Nullable ResourceLocation endTexture, + String sideKey, String endKey, + boolean sideEmissive, boolean endEmissive) { + this.makePartModelElement(model, endFace, useEndWithFullCube, faceEndpoints, offset, + sideTintIndex, endTintIndex, x1, y1, z1, x2, y2, z2, sideTexture, endTexture, sideKey, endKey, + (face, textureKey, builder) -> { + if (activeEmissivity == 0) { + return; + } + if (sideEmissive && textureKey.equals(sideKey)) { + builder.emissivity(activeEmissivity, activeEmissivity).ao(false); + } else if (endEmissive && textureKey.equals(endKey)) { + builder.emissivity(activeEmissivity, activeEmissivity).ao(false); + } + }); + } + @Override public IGeneratedBlockState createBlockState() { if (!this.getBlock().defaultBlockState().hasProperty(GTBlockStateProperties.ACTIVE)) { diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModel.java b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModel.java index 83f0ceeb9ca..3fa772c5756 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModel.java +++ b/src/main/java/com/gregtechceu/gtceu/client/model/pipe/PipeModel.java @@ -21,6 +21,7 @@ import lombok.Getter; import lombok.Setter; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.MustBeInvokedByOverriders; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -78,6 +79,16 @@ */ public class PipeModel { + // spotless:off + public static final String + SIDE_KEY = "side", + END_KEY = "end", + SIDE_SECONDARY_KEY = "side_secondary", + END_SECONDARY_KEY = "end_secondary", + SIDE_OVERLAY_KEY = "side_overlay", + END_OVERLAY_KEY = "end_overlay"; + // spotless:on + public static final Set DYNAMIC_MODELS = new HashSet<>(); public static void initDynamicModels() { @@ -149,6 +160,7 @@ public final void dynamicModel() { * @see #getOrCreateCenterElement() * @see #getOrCreateConnectionElement() */ + @MustBeInvokedByOverriders public void initModels() { getOrCreateCenterElement(); getOrCreateConnectionElement(); @@ -174,8 +186,7 @@ protected BlockModelBuilder getOrCreateBlockModel() { return this.blockModel = this.provider.models().getBuilder(this.blockId.toString()) // make the "default" model be based on the center part's model .parent(this.getOrCreateCenterElement()) - .customLoader(PipeModelBuilder::begin) - .thickness(this.thickness).provider(this.provider) + .customLoader(PipeModelBuilder.begin(this.thickness, this.provider)) .centerModels(this.getOrCreateCenterElement().getLocation()) .connectionModels(this.getOrCreateConnectionElement().getLocation()) .end(); @@ -227,7 +238,10 @@ protected BlockModelBuilder getOrCreateConnectionElement() { */ @ApiStatus.OverrideOnly protected ItemModelBuilder getOrCreateItemModel() { - return createItemModel(this.blockId, this.minCoord, this.maxCoord); + if (this.itemModel != null) { + return this.itemModel; + } + return this.itemModel = createItemModel(this.blockId, this.minCoord, this.maxCoord); } /** @@ -271,11 +285,12 @@ protected ItemModelBuilder createItemModel(ResourceLocation name, float min, flo ItemModelBuilder model = this.provider.itemModels().getBuilder(name.toString()) .parent(this.getOrCreateCenterElement()); makePartModelElement(model, Direction.NORTH, false, faceEndpoints, 0.0f, 0, 1, - min, min, 0, max, max, 16, this.side, this.end, "side", "end"); + min, min, 0, max, max, 16, this.side, this.end, SIDE_KEY, END_KEY); makePartModelElement(model, Direction.NORTH, true, faceEndpoints, 0.001f, 0, 1, - min, min, 0, max, max, 16, this.sideSecondary, this.endSecondary, "side_secondary", "end_secondary"); + min, min, 0, max, max, 16, this.sideSecondary, this.endSecondary, SIDE_SECONDARY_KEY, + END_SECONDARY_KEY); makePartModelElement(model, Direction.NORTH, true, faceEndpoints, 0.002f, 2, 2, - min, min, 0, max, max, 16, this.sideOverlay, this.endOverlay, "side_overlay", "end_overlay"); + min, min, 0, max, max, 16, this.sideOverlay, this.endOverlay, SIDE_OVERLAY_KEY, END_OVERLAY_KEY); return model; } @@ -295,23 +310,12 @@ protected ItemModelBuilder createItemModel(ResourceLocation name, float min, flo protected BlockModelBuilder makeElementModel(ResourceLocation name, @Nullable Direction endFace, final float x1, final float y1, final float z1, final float x2, final float y2, final float z2) { - Reference2FloatMap faceEndpoints = new Reference2FloatOpenHashMap<>(); - faceEndpoints.defaultReturnValue(GTMath.max(x1, y1, z1, x2, y2, z2)); - for (Direction dir : GTUtil.DIRECTIONS) { - faceEndpoints.put(dir, switch (dir) { - case DOWN -> Math.min(y1, y2); - case UP -> Math.max(y1, y2); - case NORTH -> Math.min(z1, z2); - case SOUTH -> Math.max(z1, z2); - case WEST -> Math.min(x1, x2); - case EAST -> Math.max(x1, x2); - }); - } + Reference2FloatMap faceEndpoints = makeFaceEndpointMap(x1, y1, z1, x2, y2, z2); BlockModelBuilder model = this.provider.models().getBuilder(name.toString()) .parent(new ModelFile.UncheckedModelFile("block/block")); makePartModelElement(model, endFace, false, faceEndpoints, 0.0f, 0, 1, - x1, y1, z1, x2, y2, z2, this.side, this.end, "side", "end"); + x1, y1, z1, x2, y2, z2, this.side, this.end, SIDE_KEY, END_KEY); makePartModelElement(model, endFace, true, faceEndpoints, 0.001f, 0, 1, x1, y1, z1, x2, y2, z2, this.sideSecondary, this.endSecondary, "side_secondary", "end_secondary"); makePartModelElement(model, endFace, true, faceEndpoints, 0.002f, 2, 2, @@ -328,11 +332,26 @@ protected > void makePartModelElement(T model, @Nullab @Nullable ResourceLocation sideTexture, @Nullable ResourceLocation endTexture, String sideKey, String endKey) { - if (sideTexture == null && endTexture == null) { + makePartModelElement(model, endFace, useEndWithFullCube, faceEndpoints, + offset, sideTintIndex, endTintIndex, x1, y1, z1, x2, y2, z2, + sideTexture, endTexture, sideKey, endKey, (face, texture, builder) -> {}); + } + + protected > void makePartModelElement(T model, @Nullable Direction endFace, + boolean useEndWithFullCube, + Reference2FloatMap faceEndpoints, + float offset, int sideTintIndex, int endTintIndex, + final float x1, final float y1, final float z1, + final float x2, final float y2, final float z2, + @Nullable ResourceLocation sideTexture, + @Nullable ResourceLocation endTexture, + String sideKey, String endKey, + FaceConfigurator faceConfigurator) { + if (sideTexture == null && (endFace == null || endTexture == null)) { return; } if (sideTexture != null) model.texture(sideKey, sideTexture); - if (endTexture != null) model.texture(endKey, endTexture); + if (endFace != null && endTexture != null) model.texture(endKey, endTexture); boolean fullCube = !useEndWithFullCube && (x1 == y1 && x1 == z1 && x1 <= 0.0f) && @@ -344,11 +363,13 @@ protected > void makePartModelElement(T model, @Nullab for (Direction dir : GTUtil.DIRECTIONS) { ModelBuilder.ElementBuilder.FaceBuilder face = null; - boolean isEnd = (endFace == dir || endFace == dir.getOpposite()) && !fullCube; + boolean isEnd = !fullCube && endFace != null && (endFace == dir || endFace == dir.getOpposite()); if (isEnd && endTexture != null) { face = element.face(dir).texture("#" + endKey).tintindex(endTintIndex); + faceConfigurator.accept(dir, endKey, face); } else if (!isEnd && sideTexture != null) { face = element.face(dir).texture("#" + sideKey).tintindex(sideTintIndex); + faceConfigurator.accept(dir, sideKey, face); } float faceEnd = faceEndpoints.getFloat(dir); @@ -358,6 +379,23 @@ protected > void makePartModelElement(T model, @Nullab } } + protected final Reference2FloatMap makeFaceEndpointMap(final float x1, final float y1, final float z1, + final float x2, final float y2, final float z2) { + Reference2FloatMap faceEndpoints = new Reference2FloatOpenHashMap<>(); + faceEndpoints.defaultReturnValue(GTMath.max(x1, y1, z1, x2, y2, z2)); + for (Direction dir : GTUtil.DIRECTIONS) { + faceEndpoints.put(dir, switch (dir) { + case DOWN -> Math.min(y1, y2); + case UP -> Math.max(y1, y2); + case NORTH -> Math.min(z1, z2); + case SOUTH -> Math.max(z1, z2); + case WEST -> Math.min(x1, x2); + case EAST -> Math.max(x1, x2); + }); + } + return faceEndpoints; + } + @Override public boolean equals(Object o) { if (!(o instanceof PipeModel pipeModel)) return false; @@ -374,4 +412,22 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(block, side, end, sideSecondary, endSecondary, sideOverlay, endOverlay); } + + @FunctionalInterface + public interface FaceConfigurator> { + + /** + * This is a callback for modifying a block element face builder in ways not supported by "basic" API.
+ * For example, you can make faces emissive, like {@link ActivablePipeModel#makePartModelElement}. + * + * @param face The normal direction of this face. + * @param texture The texture of the face, usually in {@code #reference} format. + * Note that the String does NOT begin with {@code #}. + * @param builder The face builder. + * @see ActivablePipeModel#makePartModelElement(ModelBuilder, Direction, boolean, Reference2FloatMap, float, + * int, int, float, float, float, float, float, float, ResourceLocation, ResourceLocation, String, String, + * boolean, boolean) ActivablePipeModel.makePartModelElement + */ + void accept(Direction face, String texture, ModelBuilder.ElementBuilder.FaceBuilder builder); + } } diff --git a/src/main/java/com/gregtechceu/gtceu/data/model/builder/PipeModelBuilder.java b/src/main/java/com/gregtechceu/gtceu/data/model/builder/PipeModelBuilder.java index 917e3996be2..57ffd1f470c 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/model/builder/PipeModelBuilder.java +++ b/src/main/java/com/gregtechceu/gtceu/data/model/builder/PipeModelBuilder.java @@ -23,15 +23,14 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import lombok.Getter; -import lombok.Setter; import lombok.experimental.Accessors; import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Range; import org.joml.Vector3f; import java.util.*; +import java.util.function.BiFunction; import static com.gregtechceu.gtceu.data.model.builder.MachineModelBuilder.configuredModelListToJSON; import static com.gregtechceu.gtceu.data.model.builder.MachineModelBuilder.configuredModelToJSON; @@ -40,23 +39,28 @@ @SuppressWarnings("UnusedReturnValue") public class PipeModelBuilder> extends CustomLoaderBuilder { - public static > PipeModelBuilder begin(T parent, - ExistingFileHelper existingFileHelper) { - return new PipeModelBuilder<>(parent, existingFileHelper); + // spotless:off + public static > BiFunction> begin(@Range(from = 0, to = 16) float thickness, + GTBlockstateProvider provider) { + return (parent, existingFileHelper) -> new PipeModelBuilder<>(parent, existingFileHelper, thickness, provider); } + // spotless:on @Accessors(fluent = false) @Getter - private final Map parts = new IdentityHashMap<>(); - @Setter - @Range(from = 0, to = 16) - private float thickness = Float.MIN_VALUE; - @Setter - private @NotNull GTBlockstateProvider provider; - private BlockModelBuilder[] restrictors = null; - - protected PipeModelBuilder(T parent, ExistingFileHelper existingFileHelper) { + private final Map<@Nullable Direction, ConfiguredModelList> parts = new IdentityHashMap<>(); + private final float thickness; + private final GTBlockstateProvider provider; + private BlockModelBuilder @Nullable [] restrictors = null; + + protected PipeModelBuilder(T parent, ExistingFileHelper existingFileHelper, + float thickness, GTBlockstateProvider provider) { super(PipeModelLoader.ID, parent, existingFileHelper); + + Preconditions.checkArgument(thickness > 0.0f && thickness <= 16.0f, + "Thickness must be between 0 (exclusive) and 16 (inclusive). It is %s", thickness); + this.thickness = thickness; + this.provider = provider; } /** @@ -289,12 +293,6 @@ public T end() { @Override public JsonObject toJson(JsonObject json) { - Preconditions.checkState(thickness != Float.MIN_VALUE, "A thickness value must be set!"); - Preconditions.checkState(thickness > 0.0f || thickness <= 16.0f, - "Thickness must be between 0 (exclusive) and 16 (inclusive). is %s", thickness); - // noinspection ConstantValue - Preconditions.checkState(provider != null, "You must pass in a GTBlockStateProvider!"); - json = super.toJson(json); if (!getParts().isEmpty()) { @@ -368,7 +366,7 @@ private static BlockModelBuilder[] getOrCreateRestrictorModels(BlockModelProvide return RESTRICTOR_MODEL_CACHE.apply(provider, thickness); } - private static final MemoizedBiFunction RESTRICTOR_MODEL_CACHE = GTMemoizer + private static final MemoizedBiFunction RESTRICTOR_MODEL_CACHE = GTMemoizer .memoizeFunctionWeakIdent(PipeModelBuilder::makeRestrictorModels); private static BlockModelBuilder[] makeRestrictorModels(BlockModelProvider provider, float thickness) { diff --git a/src/main/java/com/gregtechceu/gtceu/data/model/builder/package-info.java b/src/main/java/com/gregtechceu/gtceu/data/model/builder/package-info.java new file mode 100644 index 00000000000..2f6102b3cd1 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/data/model/builder/package-info.java @@ -0,0 +1,4 @@ +@NotNullByDefault +package com.gregtechceu.gtceu.data.model.builder; + +import org.jetbrains.annotations.NotNullByDefault; diff --git a/src/main/java/com/gregtechceu/gtceu/utils/data/RuntimeExistingFileHelper.java b/src/main/java/com/gregtechceu/gtceu/utils/data/RuntimeExistingFileHelper.java index e6e7c50d4c4..f2d04d3629d 100644 --- a/src/main/java/com/gregtechceu/gtceu/utils/data/RuntimeExistingFileHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/utils/data/RuntimeExistingFileHelper.java @@ -12,7 +12,7 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; -import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.FileNotFoundException; import java.util.Collections; @@ -23,25 +23,41 @@ /** * Existing file helper that wraps the client/server resource manager instead of creating its own.
* Useful for using data generators outside datagen. + *

+ * By default, this class assumes all resources exist and does not check any references' validity. + * To enable actual checking, you may use a try-with-resources statement like this: + * + *

{@code
+ * try (var helper = RuntimeExistingFileHelper.INSTANCE.activeHelper()) {
+ *     // If you don't use a try-with-resources or try-finally block to
+ *     // enable checking, calling `exists` will always return true.
+ *     if (helper.exists(texture, GTBlockstateProvider.TEXTURE)) {
+ *         // do stuff
+ *     }
+ * }
+ * }
+ * */ @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault public class RuntimeExistingFileHelper extends ExistingFileHelper { - public static final RuntimeExistingFileHelper INSTANCE = new RuntimeExistingFileHelper(); + public static final RuntimeExistingFileHelper INSTANCE = new RuntimeExistingFileHelper(HashMultimap.create()); - protected final Multimap generated = HashMultimap.create(); + protected final Multimap generated; + protected @Nullable Active activeHelper; - protected RuntimeExistingFileHelper() { + protected RuntimeExistingFileHelper(Multimap generated) { super(Collections.emptySet(), Collections.emptySet(), false, null, null); + this.generated = generated; } - public static @NotNull ResourceManager getManager(PackType packType) { + public static ResourceManager getManager(PackType packType) { if (packType == PackType.CLIENT_RESOURCES) { return Minecraft.getInstance().getResourceManager(); } else if (packType == PackType.SERVER_DATA) { if (GTCEu.getMinecraftServer() == null) { - throw new IllegalStateException("Cannot get server resources without a server or on a remote client."); + throw new IllegalStateException("Cannot get server resources without a server / on a remote client."); } return GTCEu.getMinecraftServer().getResourceManager(); } else { @@ -53,11 +69,26 @@ protected ResourceLocation getLocation(ResourceLocation base, String prefix, Str return base.withPath(path -> prefix + "/" + path + suffix); } + public RuntimeExistingFileHelper.Active activeHelper() { + if (this.activeHelper == null) { + // pass the same generated resources map into the subclass + // so any resources added/checked by it are automatically updated here + this.activeHelper = new Active(this.generated); + } + return this.activeHelper; + } + + /** + * Bypass the normal {@code exists} function so missing/invalid references etc. don't cause runtime errors.
+ * A toggle for enabling proper functionality is implemented in the form of {@link #activeHelper()}- + */ @Override public boolean exists(ResourceLocation loc, PackType packType) { - return generated.get(packType).contains(loc) || getManager(packType).getResource(loc).isPresent(); + return true; } + /// Implement a copy of the normal {@code exists} function that we can use for checking + @Override public void trackGenerated(ResourceLocation loc, IResourceType type) { trackGenerated(loc, type.getPackType(), type.getSuffix(), type.getPrefix()); @@ -83,4 +114,31 @@ public Resource getResource(ResourceLocation loc, PackType packType) throws File public List getResourceStack(ResourceLocation loc, PackType packType) { return getManager(packType).getResourceStack(loc); } + + /** + * This class implements {@link AutoCloseable} for ease of enabling actual checking when it is required. + *

+ * Note that it's safe to ignore "unclosed AutoCloseable"/{@code resource} warnings on this class, as is done in + * {@linkplain com.gregtechceu.gtceu.client.model.machine.overlays.WorkableOverlays#get WorkableOverlays#get}. + *

+ */ + public static class Active extends RuntimeExistingFileHelper implements AutoCloseable { + + protected Active(Multimap parentGenerated) { + super(parentGenerated); + } + + @Override + public Active activeHelper() { + return this; + } + + @Override + public boolean exists(ResourceLocation loc, PackType packType) { + return this.generated.get(packType).contains(loc) || getManager(packType).getResource(loc).isPresent(); + } + + @Override + public void close() {} + } }