From a159e29ad95a86bed030d16fdaddf767e73e50c2 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 16 Jul 2025 09:02:01 +0300 Subject: [PATCH] Add fire extinguisher - Spout Carbon Dioxide to fill up - RMB to shoot dry ice --- .gitignore | 3 +- .../resources/assets/tfmg/lang/en_ud.json | 15 ++- .../resources/assets/tfmg/lang/en_us.json | 15 ++- .../models/item/cast_iron_chemical_vat.json | 2 +- .../tfmg/models/item/fire_extinguisher.json | 3 + .../tfmg/models/item/steel_chemical_vat.json | 2 +- .../filling/filled_fire_extinguisher.json | 21 ++++ .../java/com/drmangotea/tfmg/TFMGClient.java | 2 + .../tfmg/base/spark/DryIceFlake.java | 98 +++++++++++++++ .../tfmg/base/spark/DryIceFlakeRenderer.java | 52 ++++++++ .../FireExtinguisherItem.java | 102 ++++++++++++++++ .../FireExtinguisherPacket.java | 46 +++++++ .../FireExtinguisherRenderHandler.java | 36 ++++++ .../values/create/TFMGFillingRecipeGen.java | 16 ++- .../tfmg/registry/TFMGEntityTypes.java | 4 +- .../drmangotea/tfmg/registry/TFMGItems.java | 7 ++ .../assets/tfmg/lang/default/tooltips.json | 5 +- .../resources/assets/tfmg/lang/ru_ru.json | 14 ++- .../models/item/fire_extinguisher/item.json | 115 ++++++++++++++++++ .../tfmg/textures/entity/dry_ice_flake.png | Bin 0 -> 387 bytes .../tfmg/textures/item/fire_extinguisher.png | Bin 0 -> 593 bytes 21 files changed, 545 insertions(+), 13 deletions(-) create mode 100644 src/generated/resources/assets/tfmg/models/item/fire_extinguisher.json create mode 100644 src/generated/resources/data/tfmg/recipes/filling/filled_fire_extinguisher.json create mode 100644 src/main/java/com/drmangotea/tfmg/base/spark/DryIceFlake.java create mode 100644 src/main/java/com/drmangotea/tfmg/base/spark/DryIceFlakeRenderer.java create mode 100644 src/main/java/com/drmangotea/tfmg/content/items/weapons/fire_extinguisher/FireExtinguisherItem.java create mode 100644 src/main/java/com/drmangotea/tfmg/content/items/weapons/fire_extinguisher/FireExtinguisherPacket.java create mode 100644 src/main/java/com/drmangotea/tfmg/content/items/weapons/fire_extinguisher/FireExtinguisherRenderHandler.java create mode 100644 src/main/resources/assets/tfmg/models/item/fire_extinguisher/item.json create mode 100644 src/main/resources/assets/tfmg/textures/entity/dry_ice_flake.png create mode 100644 src/main/resources/assets/tfmg/textures/item/fire_extinguisher.png diff --git a/.gitignore b/.gitignore index 02cc6640..4d4ee8f6 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ /run-data/ /.idea/ /.vscode/ -/build/classes/java/main/ \ No newline at end of file +/build/classes/java/main/ +/src/generated/resources/.cache/ diff --git a/src/generated/resources/assets/tfmg/lang/en_ud.json b/src/generated/resources/assets/tfmg/lang/en_ud.json index 6031b2a1..c2b5a89f 100644 --- a/src/generated/resources/assets/tfmg/lang/en_ud.json +++ b/src/generated/resources/assets/tfmg/lang/en_ud.json @@ -425,7 +425,6 @@ "block.tfmg.red_rebar_concrete_stairs": "sɹıɐʇS ǝʇǝɹɔuoƆ ɹɐqǝᴚ pǝᴚ", "block.tfmg.red_rebar_concrete_wall": "ןןɐM ǝʇǝɹɔuoƆ ɹɐqǝᴚ pǝᴚ", "block.tfmg.regular_engine": "ǝuıbuƎ ɹɐןnbǝᴚ", - "block.tfmg.reinforced_fireproof_bricks": "sʞɔıɹᗺ ɟooɹdǝɹıℲ pǝɔɹoɟuıǝᴚ", "block.tfmg.resistor": "ɹoʇsısǝᴚ", "block.tfmg.resistor.tooltip.behaviour1": "uı sı ʞɔoןq ʇǝbɹɐʇ sʇı dnoɹb ɔıɹʇɔǝןǝ ɹǝʌǝʇɐɥʍ oʇ )dıʇןooʇ sǝuıɥɔɐɯ buıpuıʍ ǝɥʇ ʇɐ ʞooן ǝɔuɐʇsısǝɹ sʇı ǝbuɐɥɔ oʇ ʍoɥ ǝǝs oʇ( ǝɔuɐʇsısǝɹ ǝʌıʇɔǝdsǝɹ sɹoʇsısǝɹ ǝɥʇ sppⱯ", "block.tfmg.resistor.tooltip.condition1": "dnoɹb ɐ uıɥʇıʍ ʞɔoןq ɐ uo pǝɔɐןd uǝɥM", @@ -646,6 +645,7 @@ "effect.tfmg.hellfire": "ǝɹıɟןןǝH", "entity.tfmg.blue_spark": "ʞɹɐdS ǝnןᗺ", "entity.tfmg.copper_grenade": "ǝpɐuǝɹ⅁ ɹǝddoƆ", + "entity.tfmg.dry_ice_flake": "ǝʞɐןℲ ǝɔI ʎɹᗡ", "entity.tfmg.green_spark": "ʞɹɐdS uǝǝɹ⅁", "entity.tfmg.lithium_spark": "ʞɹɐdS ɯnıɥʇıꞀ", "entity.tfmg.napalm_bomb_entity": "ʎʇıʇuƎ qɯoᗺ ɯןɐdɐN", @@ -773,6 +773,8 @@ "item.tfmg.engine_cylinder": "ɹǝpuıןʎƆ ǝuıbuƎ", "item.tfmg.etched_circuit_board": "pɹɐoᗺ ʇınɔɹıƆ pǝɥɔʇƎ", "item.tfmg.ethylene_bucket": "ʞuɐ⟘ ǝuǝןʎɥʇƎ", + "item.tfmg.fire_extinguisher": "ɹǝɥsınbuıʇxƎ ǝɹıℲ", + "item.tfmg.fire_extinguisher.tooltip.summary": "˙sǝɹıɟ ɥsınbuıʇxǝ oʇ ‾ǝpıxoıᗡ uoqɹɐƆ‾ sǝs∩", "item.tfmg.fireclay_ball": "ןןɐᗺ ʎɐןɔǝɹıℲ", "item.tfmg.fireproof_brick": "ʞɔıɹᗺ ɟooɹdǝɹıℲ", "item.tfmg.flamethrower": "ɹǝʍoɹɥʇǝɯɐןℲ", @@ -983,6 +985,8 @@ "tfmg.keyinfo.engine_start": "ǝuıbuƎ ʇɹɐʇS", "tfmg.keyinfo.transmission_shift_down": "uʍoᗡ ʇɟıɥS uoıssıɯsuɐɹ⟘", "tfmg.keyinfo.transmission_shift_up": "d∩ ʇɟıɥS uoıssıɯsuɐɹ⟘", + "tfmg.ponder.arc_furnace.header": "ǝɔɐuɹnℲ ɔɹⱯ", + "tfmg.ponder.arc_furnace.text_1": "ǝɔɐuɹnℲ ɔɹⱯ uɐ ǝʇɐǝɹɔ sǝpoɹʇɔǝןƎ ǝʇıɥdɐɹ⅁ Ɛ", "tfmg.ponder.blast_furnace.header": "", "tfmg.ponder.blast_furnace.text_1": "ʇndʇno ǝɔɐuɹnɟ ʇsɐןq ɐ sı ǝɔɐuɹnɟ ʇsɐןq ɐ ɟo ʇɹɐd uıɐW", "tfmg.ponder.blast_furnace.text_2": "ʇı uı ɥɔʇɐɥ ǝɔɐuɹnɟ ʇsɐןq ǝuo ɥʇıʍ ʇı punoɹɐ sʞɔıɹq ɟooɹdǝɹıɟ ɟo ɹǝpuıןʎɔ ɐ ǝʞɐɯ 'ǝɔɐuɹnɟ ʇsɐןq ɐ pןınq o⟘", @@ -1031,6 +1035,8 @@ "tfmg.ponder.electricity_two.text_5": "ʞɹoʍʇǝuqns ǝɥʇ oʇ sʇǝb ʇɐɥʇ ǝbɐʇןoʌ ɟo ǝbɐʇuǝɔɹǝd ǝɥʇ ʇǝs uɐɔ ǝuo sıɥʇ 'ɹǝʇǝɯoıʇuǝʇod ǝɥʇ sı ǝuo ʇxǝN", "tfmg.ponder.electricity_two.text_6": "ǝuoʇspǝɹ ɥʇıʍ ʇnq ʎןɹɐןıɯıs sʞɹoʍ ɥɔʇıʍs ǝɥ⟘", "tfmg.ponder.electricity_two.text_7": "ןıoɔ ʎɹɐpuoɔǝs puɐ ʎɹɐɯıɹd ǝɥʇ uǝǝʍʇǝq suɹnʇ ɟo oıʇɐɹ ǝɥʇ uo pǝsɐq ǝbɐʇןoʌ sǝbuɐɥɔ ɹǝɯɹoɟsuɐɹʇ ǝɥ⟘", + "tfmg.ponder.electrolysis.header": "sısʎןoɹʇɔǝןƎ", + "tfmg.ponder.electrolysis.text_1": "ɹǝzʎןoɹʇɔǝןƎ uɐ sǝʇɐǝɹɔ sǝpoɹʇɔǝןƎ ɔuıZ ɹo ɹǝddoƆ ɥʇıʍ sɹǝpןoɥ ǝpoɹʇɔǝןǝ ᄅ buıɔɐןԀ", "tfmg.ponder.engines.header": "sǝuıbuƎ", "tfmg.ponder.engines.text_1": "ǝuıן ɐ uı sʞɔoןq ǝuıbuǝ ϛ oʇ dn buıɔɐןd ʎq ʇɹɐʇs 'ǝuıbuǝ uɐ pןınq o⟘", "tfmg.ponder.engines.text_2": "ʎןqɯǝssɐ ǝɥʇ ɹoɟ pǝpǝǝu sɯǝʇı noʎ ʍoɥs ןןıʍ dıʇןooʇ s,ǝuıbuǝ ǝɥ⟘", @@ -1041,13 +1047,18 @@ "tfmg.ponder.engines.text_7": "pǝpɐɹbdn ǝq oʇ sɯǝʇı uıɐʇɹǝɔ ɥʇıʍ pǝʞɔıןɔ ʇɥbıɹ ǝq uɐɔ ʞɔoןq ǝuıbuǝ ʎɹǝʌƎ", "tfmg.ponder.engines.text_8": "sʞuɐʇ buıɹoqɥbıǝu ɯoɹɟ ןǝnɟ ǝɯnsuoɔ ǝuıbuǝ ǝɥʇ ǝʞɐɯ sǝdıd ןɐıɹʇsnpuı ǝןdɯɐxǝ ɹoℲ", "tfmg.ponder.engines.text_9": "ןɐubıs ǝuoʇspǝɹ ɐ ɥʇıʍ pǝʇɹɐʇs ǝq uɐɔ ǝuıbuǝ ǝɥ⟘", + "tfmg.ponder.industrial_mixer.header": "ɹǝxıW ןɐıɹʇsnpuI", + "tfmg.ponder.industrial_mixer.text_1": "ʇɐΛ ןɐɔıɯǝɥƆ ǝɥʇ ɹoɟ ʇuǝɯɥɔɐʇʇɐ ǝuıɥɔɐɯ ɐ sı ɹǝxıW ןɐıɹʇsnpuI ǝɥ⟘", + "tfmg.ponder.industrial_mixer.text_2": "ɹǝxıW ɐ sǝɯoɔǝq ʇɐʌ ǝɥʇ 'pǝʇɹǝsuı sı ǝpɐןᗺ ɹǝxıW ǝɥʇ uǝɥM", + "tfmg.ponder.industrial_mixer.text_3": "ǝbnɟıɹʇuǝƆ ɐ ǝɯoɔǝq osןɐ uɐɔ ɹǝxıW ןɐıɹʇsnpuI ǝɥ⟘", "tfmg.ponder.pumpjack.header": "ʞɔɐظdɯnԀ", "tfmg.ponder.pumpjack.text_1": "ǝɔɐɟɹns ǝɥʇ oʇ ʇısodǝp ɐ ɯoɹɟ sǝdıd ןɐıɹʇsnpuı buıpןınq sı ןıo buıuıɯ ɟo dǝʇs ʇsɹıℲ", "tfmg.ponder.pumpjack.text_2": "ǝdıd ǝɥʇ ɟo doʇ ǝɥʇ uo pǝɔɐןd ǝq oʇ sɐɥ ǝsɐq ʞɔɐظdɯnԀ", "tfmg.ponder.pumpjack.text_3": "ʇı puıɥǝq pǝɔɐןd ǝq oʇ spǝǝu ɹǝpןoH ɹǝɯɯɐH ʞɔɐظdɯnԀ", "tfmg.ponder.pumpjack.text_4": "ǝsɐq ǝɥʇ puɐ ʞuɐɹɔ ǝɥʇ ǝʌoqɐ ʞɔɐظdɯnԀ ǝɥʇ ɟo pɐǝH ǝɥʇ puⱯ ɹoʇɔǝuuoƆ ǝɥʇ buıpןınq sı dǝʇs ʇxǝN", "tfmg.ponder.pumpjack.text_5": "sʇɹɐԀ ɹǝɯɯɐH ʞɔɐظdɯnԀ ɥʇıʍ pǝʇɔǝuuoɔ ǝq oʇ pǝǝu ʎǝɥʇ ʍoN", - "tfmg.ponder.pumpjack.text_6": "ʇı ǝʌoqɐ ʞuɐɹɔ ʞɔɐظdɯnd ɐ ɥʇıʍ )ʞɔɐظdɯnd ǝɥʇ ɹoɟ ʇnduı ɹǝʍod ǝɥʇ sı ɥɔıɥʍ( ʇnduı ǝuıɥɔɐɯ ɐ buıɔɐןd sı dǝʇs ʇsɐן ǝɥ⟘", + "tfmg.ponder.pumpjack.text_6": "ʎןɹǝdoɹd ǝןqɯǝssɐ ʇou ןןıʍ ʞɔɐظdɯnd ǝɥʇ ǝsıʍɹǝɥʇo 'ǝnן⅁ ɹǝdnS ǝsn oʇ ǝɹns ǝʞɐW", + "tfmg.ponder.pumpjack.text_7": "ʇı ǝʌoqɐ ʞuɐɹɔ ʞɔɐظdɯnd ɐ ɥʇıʍ )ʞɔɐظdɯnd ǝɥʇ ɹoɟ ʇnduı ɹǝʍod ǝɥʇ sı ɥɔıɥʍ( ʇnduı ǝuıɥɔɐɯ ɐ buıɔɐןd sı dǝʇs ʇsɐן ǝɥ⟘", "tfmg.ponder.shared.behaviour_modify_value_panel": "ןǝuɐd ǝnןɐʌ ǝɥʇ buısn pǝıɟıpoɯ ǝq uɐɔ ɹnoıʌɐɥǝq sıɥ⟘", "tfmg.ponder.shared.movement_anchors": "˙pǝʌoɯ ǝq uɐɔ sǝɹnʇɔnɹʇs ɹǝbɹɐן 'ǝnן⅁ ɹǝdnS ɟo dןǝɥ ǝɥʇ ɥʇıM", "tfmg.ponder.shared.rpm16": "WԀᴚ 9Ɩ", diff --git a/src/generated/resources/assets/tfmg/lang/en_us.json b/src/generated/resources/assets/tfmg/lang/en_us.json index 5f2d05ac..309fc2c5 100644 --- a/src/generated/resources/assets/tfmg/lang/en_us.json +++ b/src/generated/resources/assets/tfmg/lang/en_us.json @@ -425,7 +425,6 @@ "block.tfmg.red_rebar_concrete_stairs": "Red Rebar Concrete Stairs", "block.tfmg.red_rebar_concrete_wall": "Red Rebar Concrete Wall", "block.tfmg.regular_engine": "Regular Engine", - "block.tfmg.reinforced_fireproof_bricks": "Reinforced Fireproof Bricks", "block.tfmg.resistor": "Resistor", "block.tfmg.resistor.tooltip.behaviour1": "Adds the resistors respective resistance (to see how to change its resistance look at the winding machines tooltip) to whatever electric group its target block is in", "block.tfmg.resistor.tooltip.condition1": "When placed on a block within a group", @@ -646,6 +645,7 @@ "effect.tfmg.hellfire": "Hellfire", "entity.tfmg.blue_spark": "Blue Spark", "entity.tfmg.copper_grenade": "Copper Grenade", + "entity.tfmg.dry_ice_flake": "Dry Ice Flake", "entity.tfmg.green_spark": "Green Spark", "entity.tfmg.lithium_spark": "Lithium Spark", "entity.tfmg.napalm_bomb_entity": "Napalm Bomb Entity", @@ -773,6 +773,8 @@ "item.tfmg.engine_cylinder": "Engine Cylinder", "item.tfmg.etched_circuit_board": "Etched Circuit Board", "item.tfmg.ethylene_bucket": "Ethylene Tank", + "item.tfmg.fire_extinguisher": "Fire Extinguisher", + "item.tfmg.fire_extinguisher.tooltip.summary": "Uses _Carbon Dioxide_ to extinguish fires.", "item.tfmg.fireclay_ball": "Fireclay Ball", "item.tfmg.fireproof_brick": "Fireproof Brick", "item.tfmg.flamethrower": "Flamethrower", @@ -983,6 +985,8 @@ "tfmg.keyinfo.engine_start": "Start Engine", "tfmg.keyinfo.transmission_shift_down": "Transmission Shift Down", "tfmg.keyinfo.transmission_shift_up": "Transmission Shift Up", + "tfmg.ponder.arc_furnace.header": "Arc Furnace", + "tfmg.ponder.arc_furnace.text_1": "3 Graphite Electrodes create an Arc Furnace", "tfmg.ponder.blast_furnace.header": "", "tfmg.ponder.blast_furnace.text_1": "Main part of a blast furnace is a blast furnace output", "tfmg.ponder.blast_furnace.text_2": "To build a blast furnace, make a cylinder of fireproof bricks around it with one blast furnace hatch in it", @@ -1031,6 +1035,8 @@ "tfmg.ponder.electricity_two.text_5": "Next one is the potentiometer, this one can set the percentage of voltage that gets to the subnetwork", "tfmg.ponder.electricity_two.text_6": "The switch works similarly but with redstone", "tfmg.ponder.electricity_two.text_7": "The transformer changes voltage based on the ratio of turns between the primary and secondary coil", + "tfmg.ponder.electrolysis.header": "Electrolysis", + "tfmg.ponder.electrolysis.text_1": "Placing 2 electrode holders with Copper or Zinc Electrodes creates an Electrolyzer", "tfmg.ponder.engines.header": "Engines", "tfmg.ponder.engines.text_1": "To build an engine, start by placing up to 5 engine blocks in a line", "tfmg.ponder.engines.text_2": "The engine's tooltip will show you items needed for the assembly", @@ -1041,13 +1047,18 @@ "tfmg.ponder.engines.text_7": "Every engine block can be right clicked with certain items to be upgraded", "tfmg.ponder.engines.text_8": "For example industrial pipes make the engine consume fuel from neighboring tanks", "tfmg.ponder.engines.text_9": "The engine can be started with a redstone signal", + "tfmg.ponder.industrial_mixer.header": "Industrial Mixer", + "tfmg.ponder.industrial_mixer.text_1": "The Industrial Mixer is a machine attachment for the Chemical Vat", + "tfmg.ponder.industrial_mixer.text_2": "When the Mixer Blade is inserted, the vat becomes a Mixer", + "tfmg.ponder.industrial_mixer.text_3": "The Industrial Mixer can also become a Centrifuge", "tfmg.ponder.pumpjack.header": "Pumpjack", "tfmg.ponder.pumpjack.text_1": "First step of mining oil is building industrial pipes from a deposit to the surface", "tfmg.ponder.pumpjack.text_2": "Pumpjack base has to be placed on the top of the pipe", "tfmg.ponder.pumpjack.text_3": "Pumpjack Hammer Holder needs to be placed behind it", "tfmg.ponder.pumpjack.text_4": "Next step is building the Connector And the Head of the Pumpjack above the crank and the base", "tfmg.ponder.pumpjack.text_5": "Now they need to be connected with Pumpjack Hammer Parts", - "tfmg.ponder.pumpjack.text_6": "The last step is placing a machine input (which is the power input for the pumpjack) with a pumpjack crank above it", + "tfmg.ponder.pumpjack.text_6": "Make sure to use Super Glue, otherwise the pumpjack will not assemble properly", + "tfmg.ponder.pumpjack.text_7": "The last step is placing a machine input (which is the power input for the pumpjack) with a pumpjack crank above it", "tfmg.ponder.shared.behaviour_modify_value_panel": "This behaviour can be modified using the value panel", "tfmg.ponder.shared.movement_anchors": "With the help of Super Glue, larger structures can be moved.", "tfmg.ponder.shared.rpm16": "16 RPM", diff --git a/src/generated/resources/assets/tfmg/models/item/cast_iron_chemical_vat.json b/src/generated/resources/assets/tfmg/models/item/cast_iron_chemical_vat.json index 79110ea3..0e2fc1fa 100644 --- a/src/generated/resources/assets/tfmg/models/item/cast_iron_chemical_vat.json +++ b/src/generated/resources/assets/tfmg/models/item/cast_iron_chemical_vat.json @@ -1,3 +1,3 @@ { - "parent": "tfmg:block/cast_iron_chemical_vat/block_single_window" + "parent": "tfmg:block/cast_iron_chemical_vat/block_single" } \ No newline at end of file diff --git a/src/generated/resources/assets/tfmg/models/item/fire_extinguisher.json b/src/generated/resources/assets/tfmg/models/item/fire_extinguisher.json new file mode 100644 index 00000000..d5b3eee1 --- /dev/null +++ b/src/generated/resources/assets/tfmg/models/item/fire_extinguisher.json @@ -0,0 +1,3 @@ +{ + "parent": "tfmg:item/fire_extinguisher/item" +} \ No newline at end of file diff --git a/src/generated/resources/assets/tfmg/models/item/steel_chemical_vat.json b/src/generated/resources/assets/tfmg/models/item/steel_chemical_vat.json index 5c237f57..d9ded437 100644 --- a/src/generated/resources/assets/tfmg/models/item/steel_chemical_vat.json +++ b/src/generated/resources/assets/tfmg/models/item/steel_chemical_vat.json @@ -1,3 +1,3 @@ { - "parent": "tfmg:block/steel_chemical_vat/block_single_window" + "parent": "tfmg:block/steel_chemical_vat/block_single" } \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/filling/filled_fire_extinguisher.json b/src/generated/resources/data/tfmg/recipes/filling/filled_fire_extinguisher.json new file mode 100644 index 00000000..9f05eb7c --- /dev/null +++ b/src/generated/resources/data/tfmg/recipes/filling/filled_fire_extinguisher.json @@ -0,0 +1,21 @@ +{ + "type": "create:filling", + "ingredients": [ + { + "item": "tfmg:fire_extinguisher" + }, + { + "amount": 1000, + "fluid": "tfmg:carbon_dioxide", + "nbt": {} + } + ], + "results": [ + { + "item": "tfmg:fire_extinguisher", + "nbt": { + "fill_level": 500 + } + } + ] +} \ No newline at end of file diff --git a/src/main/java/com/drmangotea/tfmg/TFMGClient.java b/src/main/java/com/drmangotea/tfmg/TFMGClient.java index 743fc91b..74d431d7 100644 --- a/src/main/java/com/drmangotea/tfmg/TFMGClient.java +++ b/src/main/java/com/drmangotea/tfmg/TFMGClient.java @@ -1,6 +1,7 @@ package com.drmangotea.tfmg; import com.drmangotea.tfmg.content.items.weapons.advanced_potato_cannon.AdvancedPotatoCannonRenderHandler; +import com.drmangotea.tfmg.content.items.weapons.fire_extinguisher.FireExtinguisherRenderHandler; import com.drmangotea.tfmg.content.items.weapons.flamethrover.FlamethrowerRenderHandler; import com.drmangotea.tfmg.content.items.weapons.quad_potato_cannon.QuadPotatoCannonRenderHandler; import com.drmangotea.tfmg.ponder.TFMGPonderPlugin; @@ -22,6 +23,7 @@ public class TFMGClient { public static final AdvancedPotatoCannonRenderHandler ADVANCED_POTATO_CANNON_RENDER_HANDLER = new AdvancedPotatoCannonRenderHandler(); public static final FlamethrowerRenderHandler FLAMETHROWER_RENDER_HANDLER = new FlamethrowerRenderHandler(); + public static final FireExtinguisherRenderHandler FIRE_EXTINGUISHER_RENDER_HANDLER = new FireExtinguisherRenderHandler(); @SuppressWarnings("removal") public TFMGClient() { diff --git a/src/main/java/com/drmangotea/tfmg/base/spark/DryIceFlake.java b/src/main/java/com/drmangotea/tfmg/base/spark/DryIceFlake.java new file mode 100644 index 00000000..e941d949 --- /dev/null +++ b/src/main/java/com/drmangotea/tfmg/base/spark/DryIceFlake.java @@ -0,0 +1,98 @@ +package com.drmangotea.tfmg.base.spark; + +import com.drmangotea.tfmg.registry.TFMGBlocks; +import com.drmangotea.tfmg.registry.TFMGEntityTypes; +import net.minecraft.core.BlockPos; +import net.minecraft.core.particles.ParticleOptions; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.projectile.ThrowableProjectile; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BaseFireBlock; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.EntityHitResult; +import net.minecraft.world.phys.HitResult; + +public class DryIceFlake extends ThrowableProjectile { + public DryIceFlake(EntityType entityType, Level level) { + super(entityType, level); + } + public DryIceFlake(Level level, LivingEntity owner) { + super(TFMGEntityTypes.DRY_ICE_FLAKE.get(), owner, level); + } + public DryIceFlake(Level level, double xCoord, double yCoord, double zCoord) { + super(TFMGEntityTypes.DRY_ICE_FLAKE.get(), xCoord, yCoord, zCoord, level); + } + + @Override + protected float getGravity(){ + return 0.01f; + } + @Override + protected void defineSynchedData() {} + + public void tick(){ + super.tick(); + + if (this.tickCount > 20) this.discard(); + + if(this.level().isClientSide) { + this.level().addParticle(ParticleTypes.SNOWFLAKE, this.getX(), this.getY(), this.getZ(), this.random.nextGaussian() * 0.05D, -this.getDeltaMovement().y * 0.5D, this.random.nextGaussian() * 0.05D); + } + } + + private ParticleOptions getParticle() { + return ParticleTypes.SNOWFLAKE; + } + + public void handleEntityEvent(byte p_37402_) { + if (p_37402_ == 3) { + ParticleOptions particleoptions = this.getParticle(); + + for(int i = 0; i < 8; ++i) { + this.level().addParticle(particleoptions, this.getX(), this.getY(), this.getZ(), 0.0D, 0.0D, 0.0D); + } + } + } + protected void onHitBlock(BlockHitResult blockHit) { + super.onHitBlock(blockHit); + if (!this.level().isClientSide) { + Entity owner = this.getOwner(); + if (!(owner instanceof Mob) || net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.level(), this)) { + BlockPos hitBlockPos = blockHit.getBlockPos().relative(blockHit.getDirection()); + BlockState hitBlockState = this.level().getBlockState(hitBlockPos); + if (hitBlockState.getBlock() instanceof BaseFireBlock) { + this.level().setBlockAndUpdate(hitBlockPos, Blocks.AIR.defaultBlockState()); + } + } + } + } + + protected void onHitEntity(EntityHitResult entityHit) { + super.onHitEntity(entityHit); + if (!this.level().isClientSide) { + Entity hitEntity = entityHit.getEntity(); + hitEntity.extinguishFire(); + } + } + + protected void onHit(HitResult hit) { + super.onHit(hit); + + if (!this.level().isClientSide) { + this.level().broadcastEntityEvent(this, (byte)3); + this.discard(); + } + } + + @SuppressWarnings("unchecked") + public static EntityType.Builder build(EntityType.Builder builder) { + EntityType.Builder entityBuilder = (EntityType.Builder) builder; + return entityBuilder.sized(.25f, .25f); + } +} diff --git a/src/main/java/com/drmangotea/tfmg/base/spark/DryIceFlakeRenderer.java b/src/main/java/com/drmangotea/tfmg/base/spark/DryIceFlakeRenderer.java new file mode 100644 index 00000000..473e3925 --- /dev/null +++ b/src/main/java/com/drmangotea/tfmg/base/spark/DryIceFlakeRenderer.java @@ -0,0 +1,52 @@ +package com.drmangotea.tfmg.base.spark; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.math.Axis; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.entity.EntityRenderer; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import org.joml.Matrix3f; +import org.joml.Matrix4f; + +@OnlyIn(Dist.CLIENT) +public class DryIceFlakeRenderer extends EntityRenderer { + private static final ResourceLocation TEXTURE_LOCATION = new ResourceLocation("tfmg:textures/entity/dry_ice_flake.png"); + private static final RenderType RENDER_TYPE = RenderType.entityCutoutNoCull(TEXTURE_LOCATION); + public DryIceFlakeRenderer(EntityRendererProvider.Context context) { + super(context); + } + + protected int getBlockLightLevel(DryIceFlake flake, BlockPos blockPos) { + return 15; + } + + public void render(DryIceFlake flake, float p_114081_, float p_114082_, PoseStack stack, MultiBufferSource bufferSource, int p_114085_) { + stack.pushPose(); + stack.scale(0.5F, 0.5F, 0.5F); + stack.mulPose(this.entityRenderDispatcher.cameraOrientation()); + stack.mulPose(Axis.YP.rotationDegrees(180.0F)); + PoseStack.Pose posestack$pose = stack.last(); + Matrix4f matrix4f = posestack$pose.pose(); + Matrix3f matrix3f = posestack$pose.normal(); + VertexConsumer vertexconsumer = bufferSource.getBuffer(RENDER_TYPE); + vertex(vertexconsumer, matrix4f, matrix3f, p_114085_, 0.0F, 0, 0, 1); + vertex(vertexconsumer, matrix4f, matrix3f, p_114085_, 1.0F, 0, 1, 1); + vertex(vertexconsumer, matrix4f, matrix3f, p_114085_, 1.0F, 1, 1, 0); + vertex(vertexconsumer, matrix4f, matrix3f, p_114085_, 0.0F, 1, 0, 0); + stack.popPose(); + super.render(flake, p_114081_, p_114082_, stack, bufferSource, p_114085_); + } + private static void vertex(VertexConsumer vertexConsumer, Matrix4f p_114091_, Matrix3f p_114092_, int p_114093_, float p_114094_, int p_114095_, int p_114096_, int p_114097_) { + vertexConsumer.vertex(p_114091_, p_114094_ - 0.5F, (float)p_114095_ - 0.25F, 0.0F).color(255, 255, 255, 255).uv((float)p_114096_, (float)p_114097_).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(p_114093_).normal(p_114092_, 0.0F, 1.0F, 0.0F).endVertex(); + } + public ResourceLocation getTextureLocation(DryIceFlake p_114078_) { + return TEXTURE_LOCATION; + } +} diff --git a/src/main/java/com/drmangotea/tfmg/content/items/weapons/fire_extinguisher/FireExtinguisherItem.java b/src/main/java/com/drmangotea/tfmg/content/items/weapons/fire_extinguisher/FireExtinguisherItem.java new file mode 100644 index 00000000..be31f4cb --- /dev/null +++ b/src/main/java/com/drmangotea/tfmg/content/items/weapons/fire_extinguisher/FireExtinguisherItem.java @@ -0,0 +1,102 @@ +package com.drmangotea.tfmg.content.items.weapons.fire_extinguisher; + +import com.drmangotea.tfmg.TFMGClient; +import com.drmangotea.tfmg.base.spark.DryIceFlake; +import com.drmangotea.tfmg.registry.TFMGEntityTypes; +import com.simibubi.create.foundation.item.CustomArmPoseItem; +import net.minecraft.client.model.HumanoidModel; +import net.minecraft.client.player.AbstractClientPlayer; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResultHolder; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.UseAnim; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.Nullable; + +public class FireExtinguisherItem extends Item implements CustomArmPoseItem { + + + public static final int DRY_ICE_CAPACITY = 500; + + + public FireExtinguisherItem(Properties pProperties) { + super(pProperties); + } + + + public void onUseTick(Level level, LivingEntity entity, ItemStack stack, int time) { + + CompoundTag nbt = stack.getOrCreateTag(); + + int fillLevel = nbt.getInt("fill_level"); + if(fillLevel == 0) return; + + DryIceFlake flake = TFMGEntityTypes.DRY_ICE_FLAKE.create(level); + flake.setPos(entity.getX(),entity.getY()+1.2f,entity.getZ()); + + level.playSound(null, entity.getX(), entity.getY(), entity.getZ(), SoundEvents.FIRE_EXTINGUISH, SoundSource.NEUTRAL, 0.1F, 0.04F); + + nbt.putInt("fill_level",fillLevel > 0? fillLevel - 1 : 0); + + flake.shoot(entity.getLookAngle().x,entity.getLookAngle().y,entity.getLookAngle().z,0.5f,10.0f); + + level.addFreshEntity(flake); + + } + + + + + public int getUseDuration(ItemStack stack) { + return 696969; + } + + @Override + public boolean isBarVisible(ItemStack stack) { + return true; + } + + @Override + public int getBarColor(ItemStack stack) { + return 0xffffff; + } + + @Override + public int getBarWidth(ItemStack stack) { + + float fillLevel = (float)stack.getOrCreateTag().getInt("fill_level") / (float)DRY_ICE_CAPACITY; + return Math.round(13.0f * fillLevel); + + } + + public InteractionResultHolder use(Level level, Player player, InteractionHand hand) { + player.startUsingItem(hand); + + if (level.isClientSide) { + TFMGClient.FIRE_EXTINGUISHER_RENDER_HANDLER.dontAnimateItem(hand); + } + + return InteractionResultHolder.pass(player.getItemInHand(hand)); + } + + @Override + @Nullable + public HumanoidModel.ArmPose getArmPose(ItemStack stack, AbstractClientPlayer player, InteractionHand hand) { + if (!player.swinging) { + return HumanoidModel.ArmPose.CROSSBOW_HOLD; + } + return null; + } + + + @Override + public UseAnim getUseAnimation(ItemStack pStack) { + return UseAnim.NONE; + } +} diff --git a/src/main/java/com/drmangotea/tfmg/content/items/weapons/fire_extinguisher/FireExtinguisherPacket.java b/src/main/java/com/drmangotea/tfmg/content/items/weapons/fire_extinguisher/FireExtinguisherPacket.java new file mode 100644 index 00000000..b09a7d23 --- /dev/null +++ b/src/main/java/com/drmangotea/tfmg/content/items/weapons/fire_extinguisher/FireExtinguisherPacket.java @@ -0,0 +1,46 @@ +package com.drmangotea.tfmg.content.items.weapons.fire_extinguisher; + + +import com.drmangotea.tfmg.TFMGClient; +import com.simibubi.create.content.equipment.zapper.ShootGadgetPacket; +import com.simibubi.create.content.equipment.zapper.ShootableGadgetRenderHandler; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.phys.Vec3; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + +public class FireExtinguisherPacket extends ShootGadgetPacket { + + + + public FireExtinguisherPacket(Vec3 location, InteractionHand hand, boolean self) { + super(location, hand, self); + } + + public FireExtinguisherPacket(FriendlyByteBuf buffer) { + super(buffer); + } + + @Override + protected void readAdditional(FriendlyByteBuf buffer) { + } + + @Override + protected void writeAdditional(FriendlyByteBuf buffer) { + } + + + @Override + @OnlyIn(Dist.CLIENT) + protected void handleAdditional() { + + } + + @Override + @OnlyIn(Dist.CLIENT) + protected ShootableGadgetRenderHandler getHandler() { + return TFMGClient.FIRE_EXTINGUISHER_RENDER_HANDLER; + } + +} diff --git a/src/main/java/com/drmangotea/tfmg/content/items/weapons/fire_extinguisher/FireExtinguisherRenderHandler.java b/src/main/java/com/drmangotea/tfmg/content/items/weapons/fire_extinguisher/FireExtinguisherRenderHandler.java new file mode 100644 index 00000000..7e653a7e --- /dev/null +++ b/src/main/java/com/drmangotea/tfmg/content/items/weapons/fire_extinguisher/FireExtinguisherRenderHandler.java @@ -0,0 +1,36 @@ +package com.drmangotea.tfmg.content.items.weapons.fire_extinguisher; + +import com.drmangotea.tfmg.content.items.weapons.flamethrover.FlamethrowerItem; +import com.mojang.blaze3d.vertex.PoseStack; +import com.simibubi.create.content.equipment.potatoCannon.PotatoProjectileEntity; +import com.simibubi.create.content.equipment.zapper.ShootableGadgetRenderHandler; +import net.minecraft.client.Minecraft; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.phys.Vec3; + +public class FireExtinguisherRenderHandler extends ShootableGadgetRenderHandler { + + private float nextPitch; + + @Override + protected void playSound(InteractionHand hand, Vec3 position) { + PotatoProjectileEntity.playLaunchSound(Minecraft.getInstance().level, position, nextPitch); + } + + @Override + protected boolean appliesTo(ItemStack stack) { + return stack.getItem() instanceof FireExtinguisherItem; + } + + @Override + protected void transformTool(PoseStack ms, float flip, float equipProgress, float recoil, float pt) { + } + + @Override + protected void transformHand(PoseStack ms, float flip, float equipProgress, float recoil, float pt) { + ms.translate(0,-5,0); + } + + +} diff --git a/src/main/java/com/drmangotea/tfmg/datagen/recipes/values/create/TFMGFillingRecipeGen.java b/src/main/java/com/drmangotea/tfmg/datagen/recipes/values/create/TFMGFillingRecipeGen.java index f1443f8c..2a3459d0 100644 --- a/src/main/java/com/drmangotea/tfmg/datagen/recipes/values/create/TFMGFillingRecipeGen.java +++ b/src/main/java/com/drmangotea/tfmg/datagen/recipes/values/create/TFMGFillingRecipeGen.java @@ -1,5 +1,6 @@ package com.drmangotea.tfmg.datagen.recipes.values.create; +import com.drmangotea.tfmg.content.items.weapons.fire_extinguisher.FireExtinguisherItem; import com.drmangotea.tfmg.datagen.recipes.TFMGProcessingRecipeGen; import com.drmangotea.tfmg.registry.TFMGBlocks; import com.drmangotea.tfmg.registry.TFMGFluids; @@ -7,6 +8,7 @@ import com.drmangotea.tfmg.registry.TFMGItems; import com.simibubi.create.AllRecipeTypes; import net.minecraft.data.PackOutput; import net.minecraft.tags.ItemTags; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import static com.drmangotea.tfmg.datagen.recipes.TFMGRecipeProvider.F.*; @@ -81,8 +83,20 @@ public class TFMGFillingRecipeGen extends TFMGProcessingRecipeGen { .require(Items.BUCKET) .require(hotAir(), 1000) .output(hotAirTank()) + ), + + FILLED_FIRE_EXTINGUISHER = create("filled_fire_extinguisher", b -> b + .require(TFMGItems.FIRE_EXTINGUISHER) + .require(carbonDioxide(), 1000) + .output(createFilledExtinguisherStack()) ); + // Helper method to create the filled extinguisher ItemStack + private static ItemStack createFilledExtinguisherStack() { + ItemStack stack = new ItemStack(TFMGItems.FIRE_EXTINGUISHER.get()); + stack.getOrCreateTag().putInt("fill_level", FireExtinguisherItem.DRY_ICE_CAPACITY); + return stack; + } public TFMGFillingRecipeGen(PackOutput output) { super(output); @@ -93,4 +107,4 @@ public class TFMGFillingRecipeGen extends TFMGProcessingRecipeGen { return AllRecipeTypes.FILLING; } -} \ No newline at end of file +} diff --git a/src/main/java/com/drmangotea/tfmg/registry/TFMGEntityTypes.java b/src/main/java/com/drmangotea/tfmg/registry/TFMGEntityTypes.java index 0508e128..bbfbaa7b 100644 --- a/src/main/java/com/drmangotea/tfmg/registry/TFMGEntityTypes.java +++ b/src/main/java/com/drmangotea/tfmg/registry/TFMGEntityTypes.java @@ -22,7 +22,6 @@ import com.tterrag.registrate.util.nullness.NonNullFunction; import com.tterrag.registrate.util.nullness.NonNullSupplier; import net.minecraft.client.renderer.entity.EntityRenderer; import net.minecraft.client.renderer.entity.EntityRendererProvider; -import net.minecraft.client.renderer.entity.ItemEntityRenderer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.MobCategory; @@ -69,6 +68,9 @@ public class TFMGEntityTypes { register("lithium_spark", LithiumSpark::new, () -> LithiumSparkRenderer::new, MobCategory.MISC, 80, 20, true, true, LithiumSpark::build).register(); + public static final EntityEntry DRY_ICE_FLAKE = + register("dry_ice_flake", DryIceFlake::new, () -> DryIceFlakeRenderer::new, + MobCategory.MISC, 4, 20, true, true, DryIceFlake::build).register(); diff --git a/src/main/java/com/drmangotea/tfmg/registry/TFMGItems.java b/src/main/java/com/drmangotea/tfmg/registry/TFMGItems.java index 2da7880c..ad00a16d 100644 --- a/src/main/java/com/drmangotea/tfmg/registry/TFMGItems.java +++ b/src/main/java/com/drmangotea/tfmg/registry/TFMGItems.java @@ -22,6 +22,7 @@ import com.drmangotea.tfmg.content.items.weapons.advanced_potato_cannon.Advanced import com.drmangotea.tfmg.content.items.weapons.explosives.pipe_bomb.PipeBombItem; import com.drmangotea.tfmg.content.items.weapons.explosives.thermite_grenades.ThermiteGrenade; import com.drmangotea.tfmg.content.items.weapons.explosives.thermite_grenades.ThermiteGrenadeItem; +import com.drmangotea.tfmg.content.items.weapons.fire_extinguisher.FireExtinguisherItem; import com.drmangotea.tfmg.content.items.weapons.flamethrover.FlamethrowerItem; import com.drmangotea.tfmg.content.items.weapons.lithium_blade.LitLithiumBladeItem; import com.drmangotea.tfmg.content.items.weapons.lithium_blade.LithiumBladeItem; @@ -270,6 +271,12 @@ public class TFMGItems { .properties(p -> p.stacksTo(1)) .register(); + public static final ItemEntry FIRE_EXTINGUISHER = + REGISTRATE.item("fire_extinguisher", FireExtinguisherItem::new) + .model(AssetLookup.itemModelWithPartials()) + .properties(p -> p.stacksTo(1)) + .register(); + public static final Map> MULTIMETERS = multimeters(); diff --git a/src/main/resources/assets/tfmg/lang/default/tooltips.json b/src/main/resources/assets/tfmg/lang/default/tooltips.json index 36cbbe24..3b54448c 100644 --- a/src/main/resources/assets/tfmg/lang/default/tooltips.json +++ b/src/main/resources/assets/tfmg/lang/default/tooltips.json @@ -253,8 +253,7 @@ "item.tfmg.quad_potato_cannon.tooltip.condition1": "When R-Clicked", "item.tfmg.quad_potato_cannon.tooltip.behaviour1": "_Shoots_ a suitable item from your _Inventory_.", "item.tfmg.quad_potato_cannon.tooltip.condition2": "While wearing Backtank", - "item.tfmg.quad_potato_cannon.tooltip.behaviour2": "_No_ _Durability_ will be used. Instead, _Air_ _pressure_ is drained from the Tank" - - + "item.tfmg.quad_potato_cannon.tooltip.behaviour2": "_No_ _Durability_ will be used. Instead, _Air_ _pressure_ is drained from the Tank", + "item.tfmg.fire_extinguisher.tooltip.summary": "Uses _Carbon Dioxide_ to extinguish fires." } diff --git a/src/main/resources/assets/tfmg/lang/ru_ru.json b/src/main/resources/assets/tfmg/lang/ru_ru.json index dc9e14b5..51579558 100644 --- a/src/main/resources/assets/tfmg/lang/ru_ru.json +++ b/src/main/resources/assets/tfmg/lang/ru_ru.json @@ -1077,5 +1077,17 @@ "tfmg.ponder.tag.oil_processing": "Нефтепереработкой", "tfmg.ponder.tag.oil_processing.description": "Блоки, применяемые для добычи и переработки нефти", "tfmg.subtitle.diesel_engine_sounds": "Шум дизельного двигателя", - "tfmg.subtitle.engine_sounds": "Шум двигателя" + "tfmg.subtitle.engine_sounds": "Шум двигателя", + "entity.tfmg.dry_ice_flake": "Крошка сухого льда", + "item.tfmg.fire_extinguisher": "Огнетушитель", + "item.tfmg.fire_extinguisher.tooltip.summary": "Использует углекислый газ для тушения пожаров", + "tfmg.ponder.arc_furnace.header": "Arc Furnace", + "tfmg.ponder.arc_furnace.text_1": "3 Graphite Electrodes create an Arc Furnace", + "tfmg.ponder.electrolysis.header": "Electrolysis", + "tfmg.ponder.electrolysis.text_1": "Placing 2 electrode holders with Copper or Zinc Electrodes creates an Electrolyzer", + "tfmg.ponder.industrial_mixer.header": "Industrial Mixer", + "tfmg.ponder.industrial_mixer.text_1": "The Industrial Mixer is a machine attachment for the Chemical Vat", + "tfmg.ponder.industrial_mixer.text_2": "When the Mixer Blade is inserted, the vat becomes a Mixer", + "tfmg.ponder.industrial_mixer.text_3": "The Industrial Mixer can also become a Centrifuge", + "tfmg.ponder.pumpjack.text_7": "The last step is placing a machine input (which is the power input for the pumpjack) with a pumpjack crank above it" } diff --git a/src/main/resources/assets/tfmg/models/item/fire_extinguisher/item.json b/src/main/resources/assets/tfmg/models/item/fire_extinguisher/item.json new file mode 100644 index 00000000..3770f1be --- /dev/null +++ b/src/main/resources/assets/tfmg/models/item/fire_extinguisher/item.json @@ -0,0 +1,115 @@ +{ + "format_version": "1.9.0", + "credit": "Made with Blockbench", + "texture_size": [32, 32], + "textures": { + "1": "tfmg:item/fire_extinguisher" + }, + "elements": [ + { + "name": "tank_bottom", + "from": [5.5, 0, 5.5], + "to": [10.5, 10, 10.5], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 5, 8]}, + "faces": { + "north": {"uv": [0, 0, 2.5, 5], "texture": "#1"}, + "east": {"uv": [2.5, 0, 5, 5], "texture": "#1"}, + "south": {"uv": [0, 5, 2.5, 10], "texture": "#1"}, + "west": {"uv": [5, 0, 7.5, 5], "texture": "#1"}, + "up": {"uv": [5, 7.5, 2.5, 5], "texture": "#1"}, + "down": {"uv": [7.5, 5, 5, 7.5], "texture": "#1"} + } + }, + { + "name": "tank_top", + "from": [6, 10, 6], + "to": [10, 11, 10], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 10.5, 8]}, + "faces": { + "north": {"uv": [7.5, 0, 9.5, 0.5], "texture": "#1"}, + "east": {"uv": [7.5, 0.5, 9.5, 1], "texture": "#1"}, + "south": {"uv": [7.5, 1, 9.5, 1.5], "texture": "#1"}, + "west": {"uv": [7.5, 1.5, 9.5, 2], "texture": "#1"}, + "up": {"uv": [7.5, 2, 9.5, 4], "texture": "#1"} + } + }, + { + "name": "head", + "from": [6.5, 11, 6.5], + "to": [9.5, 14, 9.5], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 12.5, 8]}, + "faces": { + "north": {"uv": [9.5, 0, 11, 1.5], "texture": "#1"}, + "east": {"uv": [9.5, 1.5, 11, 3], "texture": "#1"}, + "south": {"uv": [9.5, 3, 11, 4.5], "texture": "#1"}, + "west": {"uv": [9.5, 4.5, 11, 6], "texture": "#1"}, + "up": {"uv": [9.5, 6, 11, 7.5], "texture": "#1"}, + "down": {"uv": [9.5, 7.5, 11, 9], "texture": "#1"} + } + }, + { + "name": "lever_upper", + "from": [7.5, 13, 9], + "to": [8.5, 14, 13], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 13.5, 9]}, + "faces": { + "east": {"uv": [4, 7.5, 6, 8], "texture": "#1"}, + "south": {"uv": [3.5, 8, 4, 8.5], "texture": "#1"}, + "west": {"uv": [4, 8, 6, 8.5], "texture": "#1"}, + "up": {"uv": [2.5, 7.5, 3, 9.5], "texture": "#1"}, + "down": {"uv": [3, 7.5, 3.5, 9.5], "texture": "#1"} + } + }, + { + "name": "lever_lower", + "from": [7.5, 12, 9], + "to": [8.5, 13, 13], + "rotation": {"angle": 0, "axis": "x", "origin": [8, 12.5, 9]}, + "faces": { + "east": {"uv": [4, 7.5, 6, 8], "texture": "#1"}, + "south": {"uv": [3.5, 8, 4, 8.5], "texture": "#1"}, + "west": {"uv": [4, 8, 6, 8.5], "texture": "#1"}, + "up": {"uv": [2.5, 7.5, 3, 9.5], "texture": "#1"}, + "down": {"uv": [3, 7.5, 3.5, 9.5], "texture": "#1"} + } + }, + { + "name": "tube", + "from": [7.5, 12, 5.5], + "to": [8.5, 13, 6.5], + "rotation": {"angle": 0, "axis": "x", "origin": [8, 12.5, 6]}, + "faces": { + "east": {"uv": [4, 8.5, 4.5, 9], "texture": "#1"}, + "west": {"uv": [4.5, 8.5, 5, 9], "texture": "#1"}, + "up": {"uv": [3.5, 8.5, 4, 9], "texture": "#1"}, + "down": {"uv": [3.5, 9, 4, 9.5], "texture": "#1"} + } + }, + { + "name": "nozzle", + "from": [7, 11.5, 3.5], + "to": [9, 13.5, 5.5], + "rotation": {"angle": 0, "axis": "x", "origin": [8, 12.5, 4.5]}, + "faces": { + "north": {"uv": [7.5, 4, 8.5, 5], "texture": "#1"}, + "east": {"uv": [7.5, 5, 8.5, 6], "texture": "#1"}, + "south": {"uv": [7.5, 6, 8.5, 7], "texture": "#1"}, + "west": {"uv": [7.5, 7, 8.5, 8], "texture": "#1"}, + "up": {"uv": [8.5, 4, 9.5, 5], "texture": "#1"}, + "down": {"uv": [8.5, 5, 9.5, 6], "texture": "#1"} + } + } + ], + "display": { + "ground": { + "translation": [0, 4, 0] + }, + "gui": { + "rotation": [-30, 130, 30], + "translation": [0, 1, 0] + }, + "fixed": { + "rotation": [0, 90, 0] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tfmg/textures/entity/dry_ice_flake.png b/src/main/resources/assets/tfmg/textures/entity/dry_ice_flake.png new file mode 100644 index 0000000000000000000000000000000000000000..6c0fe8b8f240d2e046d1c13ad083c95c716143fa GIT binary patch literal 387 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufiR<}hF1enP@=>&q9iy!t)x7$D3u`~F*C13&(AeP!Bo#s z&q6x$)e4}RZK)BSX`Y^1VEb4Zq!?Kl7=glGKr9VqgIuG*$P5-|0b$b#xJG%x_kp2-ud@d|z+17sR`x;Tbt1Sc=h+fnrNRJ}l3(ZL2zuV&SsKYu>V uF<|C+z~%7Z@$r5h1J?*fGi?o49v+6RMPx%3rR#lR9J=WmN9GFKorM+vNHtPm|BVqNpLZE$zYPKE@{3%>D)~I7#aEn3L#VJ z+Qn1w*g`voW)75iY7GY_f`~{_2m%=`wmR5SC09-*8*lo9(CNLqd;h!tyLXcOdflHi z8c3B2zT;3B4gpAO^Y`}wkotYzwcBW#hGkjwdOe90D5UAMPHbFtySz{oYPA}sY4Y^= z2$0Hl-0A!?;b=6LW^^~3KZ4Pe_7EUP3awY;BiyU9x z&l=ws*gs~9lbyiZ`d0vc@+r~&Ba(nb+F2zC2^5RPnB(Td%bDJ1z%&O6_8G?KcwWpy zmStSmO;6ys(+Q7PE#b)h&lWv~wA-0h&#K3;WZRT4FL`C#w0C!56$w^Bxm*t0nI*^) zDA@L(#I;&2Y}>}XzXw23lq}Ot=S(sNS_4Rx3X?_yfQ!w|@QLEiFt{@eSVn@RO8ENx zJk}{7GY`-6D3wYGA%acumzE$}34O+FH_3w!`E^S$|-gEX5>KRPb$6`V+5z7hglY;F1C;b9sq zVXzQF5<(<+(nCu6A^ENATmjvqBb=H3H~oI*)uq9+bzm?UV4CJy0zXS&FVNXE*BLuU fjvP61