mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-14 10:03:48 +01:00
Merge branch 'mc1.18/dev' into mc1.18/global-railways
This commit is contained in:
commit
841bf3f350
101 changed files with 5877 additions and 4786 deletions
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
|
@ -49,6 +49,7 @@ body:
|
|||
label: Mod Version
|
||||
description: The version of the mod you were using when the bug occured
|
||||
options:
|
||||
- "0.4.1"
|
||||
- "0.4.0f"
|
||||
- "0.4.0e"
|
||||
- "0.4.0d"
|
||||
|
@ -101,6 +102,7 @@ body:
|
|||
label: Minecraft Version
|
||||
description: The version of Minecraft you were using when the bug occured
|
||||
options:
|
||||
- "1.18.2"
|
||||
- "1.18.1"
|
||||
- "1.18"
|
||||
- "1.17.1"
|
||||
|
|
|
@ -11,14 +11,13 @@ Welcome to Create, a mod offering a variety of tools and blocks for Building, De
|
|||
|
||||
The added elements of tech are designed to leave as many design choices to the player as possible, where item processing doesn't happen inside a single block with funny textures, it requires a set of actors working together in many possible arrangements.
|
||||
|
||||
Check out the wiki and in-game Tool-tips for further info on how to use these features, and stay tuned for an ever-growing selection of possibilities for Creative and Survival Minecraft.
|
||||
Check out the in-game Documentation for further info on how to use the added features, and stay tuned for an ever-growing selection of possibilities for Creative and Survival Minecraft.
|
||||
|
||||
[<img src="https://i.imgur.com/0lLX9Oy.jpg" width="200">](https://github.com/Creators-of-Create/Create/issues "Report Issues")
|
||||
[<img src="https://i.imgur.com/bjEZraY.jpg" width="200">](https://www.youtube.com/channel/UCrKV2QTuyGcv4E3eSJpBiYA/playlists "Watch Videos")
|
||||
[<img src="https://i.imgur.com/aWrjfKJ.jpg" width="200">](https://discord.gg/hmaD7Se "Feedback & Help")
|
||||
[<img src="https://i.imgur.com/xj8o2xC.jpg" width="200">](https://www.patreon.com/simibubi "Support Us")
|
||||
|
||||
- Support for Minecraft 1.12: Not planned
|
||||
- Support for Fabric: Not planned
|
||||
<hr>
|
||||
<h4 align="center">Find out more about Create on our <a href="https://www.curseforge.com/minecraft/mc-mods/create">Project Page</a></h4>
|
||||
<h4 align="center">Looking for the Fabric port? <a href="https://github.com/Fabricators-of-Create/Create">Find it here</a></h4>
|
||||
|
|
|
@ -135,6 +135,10 @@ repositories {
|
|||
//location of the maven for dynamic trees
|
||||
url 'https://harleyoconnor.com/maven'
|
||||
}
|
||||
maven {
|
||||
//location of the maven for curios api
|
||||
url = "https://maven.theillusivec4.top/"
|
||||
}
|
||||
}
|
||||
|
||||
configurations {
|
||||
|
@ -157,6 +161,9 @@ dependencies {
|
|||
compileOnly fg.deobf("mezz.jei:jei-${jei_minecraft_version}:${jei_version}:api")
|
||||
runtimeOnly fg.deobf("mezz.jei:jei-${jei_minecraft_version}:${jei_version}")
|
||||
|
||||
compileOnly fg.deobf("top.theillusivec4.curios:curios-forge:${curios_minecraft_version}-${curios_version}:api")
|
||||
runtimeOnly fg.deobf("top.theillusivec4.curios:curios-forge:${curios_minecraft_version}-${curios_version}")
|
||||
|
||||
// implementation fg.deobf("curse.maven:druidcraft-340991:3101903")
|
||||
// implementation fg.deobf("com.ferreusveritas.dynamictrees:DynamicTrees-1.16.5:0.10.0-Beta25")
|
||||
// runtimeOnly fg.deobf("vazkii.arl:AutoRegLib:1.4-35.69")
|
||||
|
|
|
@ -6,7 +6,7 @@ org.gradle.daemon = false
|
|||
# mod version info
|
||||
mod_version = 0.5.0
|
||||
minecraft_version = 1.18.2
|
||||
forge_version = 40.0.34
|
||||
forge_version = 40.1.0
|
||||
|
||||
# build dependency versions
|
||||
forgegradle_version = 5.1.+
|
||||
|
@ -19,9 +19,11 @@ parchment_version = 2022.03.13
|
|||
|
||||
# dependency versions
|
||||
registrate_version = MC1.18.2-1.0.25
|
||||
flywheel_version = 1.18-0.6.2.66
|
||||
flywheel_version = 1.18-0.7.0.67
|
||||
jei_minecraft_version = 1.18.2
|
||||
jei_version = 9.5.3.143
|
||||
curios_minecraft_version = 1.18.2
|
||||
curios_version = 5.0.7.0
|
||||
|
||||
# curseforge information
|
||||
projectId = 328085
|
||||
|
|
|
@ -546,20 +546,20 @@ bf2b0310500213ff853c748c236eb5d01f61658e assets/create/blockstates/yellow_toolbo
|
|||
b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json
|
||||
bc34b2c5574a903a43729369b32c8981a4098ac1 assets/create/lang/en_ud.json
|
||||
8ff43211f8611542dc2b80125eabe13153bc1fbf assets/create/lang/en_us.json
|
||||
4c857eab126af9dba639b6483e02628f81cc46fb assets/create/lang/unfinished/de_de.json
|
||||
8bf1cfb8b68fd54b9cb796360beba73d83b2ec7f assets/create/lang/unfinished/de_de.json
|
||||
0ce3a240ac9fa0b44674cf886a71dfe43f2bd164 assets/create/lang/unfinished/es_cl.json
|
||||
bc0318d36ad5249bcfe7dd526372137fd8af86b6 assets/create/lang/unfinished/es_es.json
|
||||
3b28c641fdb7ff5eee3b81ffc7b6f37ce38194e3 assets/create/lang/unfinished/es_es.json
|
||||
c15da57f79901b1cddbf6fa3d94e953480ab9467 assets/create/lang/unfinished/fr_fr.json
|
||||
c2e763d4e611143f9a42c0a6a0b8cfa58f254b37 assets/create/lang/unfinished/it_it.json
|
||||
5a173ee5e1f6b5a6ffeff2b301c28e9f75eb762c assets/create/lang/unfinished/ja_jp.json
|
||||
a1d09b3588d98762d0fa56fece59e600507311da assets/create/lang/unfinished/ko_kr.json
|
||||
9ad05595229b0ac2ef8d8b21d43dc86396167485 assets/create/lang/unfinished/nl_nl.json
|
||||
76052baa07a1c9d34a5e98e75e1c7f8a935076c9 assets/create/lang/unfinished/pl_pl.json
|
||||
d6fc8c6f6a1e88021d21546d5363c425863e4204 assets/create/lang/unfinished/pt_br.json
|
||||
f7dd233fa675c1c2c1ff6c4402c16744c6189616 assets/create/lang/unfinished/pt_br.json
|
||||
541b9a302d8ddf3827f29a7ab67b482e345bc207 assets/create/lang/unfinished/pt_pt.json
|
||||
69ba5f485d16706f5438856162fcc337d23c5400 assets/create/lang/unfinished/ro_ro.json
|
||||
64431b39b4cfa1fe1988ec8c4f36145e66714847 assets/create/lang/unfinished/ru_ru.json
|
||||
1dd6ff7ee8d61c16bed0583a5f5d4567f5c76257 assets/create/lang/unfinished/zh_cn.json
|
||||
54faaacfdf8aa4ee3575fbc9ee6e81b5f9bcffe0 assets/create/lang/unfinished/zh_cn.json
|
||||
e8db253724c9b2eeb07b4587d3efb10811941df5 assets/create/lang/unfinished/zh_tw.json
|
||||
487a511a01b2a4531fb672f917922312db78f958 assets/create/models/block/acacia_window.json
|
||||
b48060cba1a382f373a05bf0039054053eccf076 assets/create/models/block/acacia_window_pane_noside.json
|
||||
|
@ -4180,7 +4180,7 @@ a7c97582bae243ab04ff5ff9914b24af25d40d59 data/create/recipes/crushing/iron_horse
|
|||
554b6555888fe01de349efaaab36b68a338ac397 data/create/recipes/crushing/iron_ore.json
|
||||
c9a9d6d28a7eac1210108d52840b60b26d58bcfe data/create/recipes/crushing/lapis_ore.json
|
||||
e870d049abc5cd5f389f70414c67e76ddc14060d data/create/recipes/crushing/leather_horse_armor.json
|
||||
cc5a817901d6f0d68e4ceb3e65d7f2187ab37ceb data/create/recipes/crushing/nether_gold_ore.json
|
||||
cab15acd2d62f1d70e0972b443f7987048d5183a data/create/recipes/crushing/nether_gold_ore.json
|
||||
6cd97c6f12687790943db810f85036b02586c753 data/create/recipes/crushing/nether_quartz_ore.json
|
||||
6e424d7e9f7d8b585384053a713db28f9d36448b data/create/recipes/crushing/nether_wart_block.json
|
||||
8003e7db3ee11066b365c251f04f84028820de94 data/create/recipes/crushing/netherrack.json
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 240",
|
||||
"_": "Missing Localizations: 233",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -582,12 +582,12 @@
|
|||
"item.create.chromatic_compound": "Compuesto cromático",
|
||||
"item.create.cinder_flour": "Harina del Nether",
|
||||
"item.create.copper_backtank": "Depósito trasero de cobre",
|
||||
"item.create.copper_backtank_placeable": "UNLOCALIZED: Copper Backtank Placeable",
|
||||
"item.create.copper_backtank_placeable": "Depósito de cobre colocable",
|
||||
"item.create.copper_nugget": "Pepita de cobre",
|
||||
"item.create.copper_sheet": "Lámina de cobre",
|
||||
"item.create.crafter_slot_cover": "Tapa de ranura del ensamblador mecánico",
|
||||
"item.create.crafting_blueprint": "Plano de elaboración",
|
||||
"item.create.creative_blaze_cake": "´Pastel de blaze creativo",
|
||||
"item.create.creative_blaze_cake": "Pastel de blaze creativo",
|
||||
"item.create.crushed_aluminum_ore": "Mineral de aluminio molido",
|
||||
"item.create.crushed_copper_ore": "Mineral de cobre molido",
|
||||
"item.create.crushed_gold_ore": "Mineral de oro molido",
|
||||
|
@ -654,7 +654,7 @@
|
|||
|
||||
"advancement.create.root": "Bienvenido a Create",
|
||||
"advancement.create.root.desc": "¡Es hora de empezar a construir increíbles artefactos animados!",
|
||||
"advancement.create.andesite_alloy": "UNLOCALIZED: Alliterations Aplenty",
|
||||
"advancement.create.andesite_alloy": "Aliteraciones a montones",
|
||||
"advancement.create.andesite_alloy.desc": "Los materiales de Create tienen nombres extraños, la aleación de andesita es uno de ellos.",
|
||||
"advancement.create.its_alive": "¡Está vivo!",
|
||||
"advancement.create.its_alive.desc": "Mira cómo gira tu primer componente cinético.",
|
||||
|
@ -840,8 +840,8 @@
|
|||
"create.recipe.fan_washing.fan": "Ventilador detrás del agua fluyente",
|
||||
"create.recipe.fan_smoking": "Ahumador a granel",
|
||||
"create.recipe.fan_smoking.fan": "Ventilador detrás del fuego",
|
||||
"create.recipe.fan_haunting": "UNLOCALIZED: Bulk Haunting",
|
||||
"create.recipe.fan_haunting.fan": "UNLOCALIZED: Fan behind Soul Fire",
|
||||
"create.recipe.fan_haunting": "Maldecidor a granel",
|
||||
"create.recipe.fan_haunting.fan": "Ventilador detrás del fuego de alma",
|
||||
"create.recipe.fan_blasting": "Voladuras a granel",
|
||||
"create.recipe.fan_blasting.fan": "Ventilador detrás de la lava",
|
||||
"create.recipe.pressing": "Prensando",
|
||||
|
@ -1193,8 +1193,8 @@
|
|||
"create.item_attributes.furnace_fuel.inverted": "no es combustible para hornos",
|
||||
"create.item_attributes.washable": "se puede lavar",
|
||||
"create.item_attributes.washable.inverted": "no se puede lavar",
|
||||
"create.item_attributes.hauntable": "UNLOCALIZED: can be Haunted",
|
||||
"create.item_attributes.hauntable.inverted": "UNLOCALIZED: cannot be Haunted",
|
||||
"create.item_attributes.hauntable": "puede ser maldito",
|
||||
"create.item_attributes.hauntable.inverted": "no puede ser maldito",
|
||||
"create.item_attributes.crushable": "puede ser molido",
|
||||
"create.item_attributes.crushable.inverted": "no puede ser molido",
|
||||
"create.item_attributes.smeltable": "se puede fundir",
|
||||
|
@ -1259,7 +1259,7 @@
|
|||
"create.tooltip.keyCtrl": "Ctrl",
|
||||
"create.tooltip.speedRequirement": "Requisitos de velocidad: %1$s",
|
||||
"create.tooltip.speedRequirement.none": "Ninguno",
|
||||
"create.tooltip.speedRequirement.slow": "UNLOCALIZED: Slow",
|
||||
"create.tooltip.speedRequirement.slow": "Lento",
|
||||
"create.tooltip.speedRequirement.medium": "Moderado",
|
||||
"create.tooltip.speedRequirement.fast": "Rápido",
|
||||
"create.tooltip.stressImpact": "Impacto de estrés: %1$s",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 1409",
|
||||
"_": "Missing Localizations: 1103",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -823,16 +823,16 @@
|
|||
"death.attack.create.cuckoo_clock_explosion.player": "%1$s foi explodido por relógio cuco adulterado",
|
||||
"death.attack.create.run_over": "UNLOCALIZED: %1$s was run over by %2$s",
|
||||
|
||||
"create.block.deployer.damage_source_name": "UNLOCALIZED: a rogue Deployer",
|
||||
"create.block.cart_assembler.invalid": "UNLOCALIZED: Place your Cart Assembler on a rail block",
|
||||
"create.block.deployer.damage_source_name": "Implantador rebelde",
|
||||
"create.block.cart_assembler.invalid": "Coloque o seu montador de carrinho de minas num trilho",
|
||||
|
||||
"create.menu.return": "UNLOCALIZED: Return to Menu",
|
||||
"create.menu.configure": "UNLOCALIZED: Configure...",
|
||||
"create.menu.ponder_index": "UNLOCALIZED: Ponder Index",
|
||||
"create.menu.only_ingame": "UNLOCALIZED: Available in the Pause Menu",
|
||||
"create.menu.project_page": "UNLOCALIZED: Project Page",
|
||||
"create.menu.report_bugs": "UNLOCALIZED: Report Issues",
|
||||
"create.menu.support": "UNLOCALIZED: Support Us",
|
||||
"create.menu.return": "Retornar ao menu",
|
||||
"create.menu.configure": "Configurar...",
|
||||
"create.menu.ponder_index": "Tabela do ponderamento",
|
||||
"create.menu.only_ingame": "Disponível no menu de pausa",
|
||||
"create.menu.project_page": "Página do projeto",
|
||||
"create.menu.report_bugs": "Informar um erro",
|
||||
"create.menu.support": "Suporte nós",
|
||||
|
||||
"create.recipe.crushing": "Triturando",
|
||||
"create.recipe.milling": "Moendo",
|
||||
|
@ -848,7 +848,7 @@
|
|||
"create.recipe.mixing": "Misturando",
|
||||
"create.recipe.deploying": "Implantando",
|
||||
"create.recipe.automatic_shapeless": "Fabricação sem forma automático",
|
||||
"create.recipe.automatic_brewing": "UNLOCALIZED: Automated Brewing",
|
||||
"create.recipe.automatic_brewing": "Produção de poções",
|
||||
"create.recipe.packing": "Compactando",
|
||||
"create.recipe.automatic_packing": "Compactamento automático",
|
||||
"create.recipe.sawing": "Serrando",
|
||||
|
@ -909,22 +909,22 @@
|
|||
"create.action.discard": "Descartar",
|
||||
|
||||
"create.keyinfo.toolmenu": "Menu Focal da Ferramenta",
|
||||
"create.keyinfo.toolbelt": "UNLOCALIZED: Access Nearby Toolboxes",
|
||||
"create.keyinfo.scrollup": "UNLOCALIZED: Simulate Mousewheel Up (inworld)",
|
||||
"create.keyinfo.scrolldown": "UNLOCALIZED: Simulate Mousewheel Down (inworld)",
|
||||
"create.keyinfo.toolbelt": "Acessa caixas de ferramenta próximas",
|
||||
"create.keyinfo.scrollup": "Simular a roda do mouse (para cima) (no mundo)",
|
||||
"create.keyinfo.scrolldown": "Simular a roda do mouse (para baixo) (no mundo)",
|
||||
|
||||
"create.gui.scrollInput.defaultTitle": "Escolha uma Opção:",
|
||||
"create.gui.scrollInput.scrollToModify": "Role o mouse para Modificar",
|
||||
"create.gui.scrollInput.scrollToAdjustAmount": "Role o mouse para ajustar a quantidade",
|
||||
"create.gui.scrollInput.scrollToSelect": "Role o mouse para Selecionar",
|
||||
"create.gui.scrollInput.shiftScrollsFaster": "UNLOCALIZED: Shift to Scroll Faster",
|
||||
"create.gui.scrollInput.shiftScrollsFaster": "Shift para rolar o mouse mais rapido",
|
||||
"create.gui.toolmenu.focusKey": "Segure [%1$s] para Focar",
|
||||
"create.gui.toolmenu.cycle": "[SCROLL] para Circular",
|
||||
|
||||
"create.toolbox.unequip": "Desequipar: %1$s",
|
||||
"create.toolbox.outOfRange": "Caixa de ferramentas do item segurado fora de alcance",
|
||||
"create.toolbox.detach": "Parar de rastrear e manter item",
|
||||
"create.toolbox.depositAll": "Retornar itens para caixa de ferramenta próxima",
|
||||
"create.toolbox.depositAll": "Retorna itens para caixa de ferramenta próxima",
|
||||
"create.toolbox.depositBox": "Retornar itens para caixa de ferramenta",
|
||||
|
||||
"create.gui.symmetryWand.mirrorType": "Espelhar",
|
||||
|
@ -972,90 +972,90 @@
|
|||
"create.terrainzapper.usingBlock": "UNLOCALIZED: Using: %1$s",
|
||||
"create.terrainzapper.leftClickToSet": "UNLOCALIZED: Left-Click a Block to set Material",
|
||||
|
||||
"create.minecart_coupling.two_couplings_max": "UNLOCALIZED: Minecarts cannot have more than two couplings each",
|
||||
"create.minecart_coupling.unloaded": "UNLOCALIZED: Parts of your train seem to be in unloaded chunks",
|
||||
"create.minecart_coupling.no_loops": "UNLOCALIZED: Couplings cannot form a loop",
|
||||
"create.minecart_coupling.removed": "UNLOCALIZED: Removed all couplings from minecart",
|
||||
"create.minecart_coupling.too_far": "UNLOCALIZED: Minecarts are too far apart",
|
||||
"create.minecart_coupling.two_couplings_max": "Carrinhos de mina não podem ter mais de dois acoplamentos cada",
|
||||
"create.minecart_coupling.unloaded": "Partes do seu trem aparentam estar em um chunk descarregado",
|
||||
"create.minecart_coupling.no_loops": "Acoplamentos não podem formar um loop",
|
||||
"create.minecart_coupling.removed": "Removeu todos os acoplamentos do carrinho de mina",
|
||||
"create.minecart_coupling.too_far": "Carrinhos de mina estão muito distanciados",
|
||||
|
||||
"create.contraptions.movement_mode": "UNLOCALIZED: Movement Mode",
|
||||
"create.contraptions.movement_mode.move_place": "UNLOCALIZED: Always Place when Stopped",
|
||||
"create.contraptions.movement_mode.move_place_returned": "UNLOCALIZED: Place only in Starting Position",
|
||||
"create.contraptions.movement_mode.move_never_place": "UNLOCALIZED: Place only when Anchor Destroyed",
|
||||
"create.contraptions.movement_mode.rotate_place": "UNLOCALIZED: Always Place when Stopped",
|
||||
"create.contraptions.movement_mode.rotate_place_returned": "UNLOCALIZED: Only Place near Initial Angle",
|
||||
"create.contraptions.movement_mode.rotate_never_place": "UNLOCALIZED: Only Place when Anchor Destroyed",
|
||||
"create.contraptions.cart_movement_mode": "UNLOCALIZED: Cart Movement Mode",
|
||||
"create.contraptions.cart_movement_mode.rotate": "UNLOCALIZED: Always face toward motion",
|
||||
"create.contraptions.cart_movement_mode.rotate_paused": "UNLOCALIZED: Pause actors while rotating",
|
||||
"create.contraptions.cart_movement_mode.rotation_locked": "UNLOCALIZED: Lock rotation",
|
||||
"create.contraptions.windmill.rotation_direction": "UNLOCALIZED: Rotation Direction",
|
||||
"create.contraptions.clockwork.clock_hands": "UNLOCALIZED: Clock Hands",
|
||||
"create.contraptions.clockwork.hour_first": "UNLOCALIZED: Hour hand first",
|
||||
"create.contraptions.clockwork.minute_first": "UNLOCALIZED: Minute hand first",
|
||||
"create.contraptions.clockwork.hour_first_24": "UNLOCALIZED: 24-Hour hand first",
|
||||
"create.contraptions.movement_mode": "Modo de movimento",
|
||||
"create.contraptions.movement_mode.move_place": "Sempre colocar quando parado",
|
||||
"create.contraptions.movement_mode.move_place_returned": "Colocar apenas na posição inicial",
|
||||
"create.contraptions.movement_mode.move_never_place": "Colocar apenas caso a âncora seja destruída",
|
||||
"create.contraptions.movement_mode.rotate_place": "Sempre colocar quando parado",
|
||||
"create.contraptions.movement_mode.rotate_place_returned": "Apenas colocar perto do angulo inicial",
|
||||
"create.contraptions.movement_mode.rotate_never_place": "Colocar apenas caso a âncora seja destruída",
|
||||
"create.contraptions.cart_movement_mode": "Modo de movimento do carrinho",
|
||||
"create.contraptions.cart_movement_mode.rotate": "Sempre apontar para a direção do movimento",
|
||||
"create.contraptions.cart_movement_mode.rotate_paused": "Pausar atores quando girando",
|
||||
"create.contraptions.cart_movement_mode.rotation_locked": "Travar a rotação",
|
||||
"create.contraptions.windmill.rotation_direction": "Direção da rotação",
|
||||
"create.contraptions.clockwork.clock_hands": "Ponteiros do relogio",
|
||||
"create.contraptions.clockwork.hour_first": "Ponteiro da hora primeiro",
|
||||
"create.contraptions.clockwork.minute_first": "Ponteiro do minuto primeiro",
|
||||
"create.contraptions.clockwork.hour_first_24": "Ponteiro das 24 horas primeiro",
|
||||
|
||||
"create.logistics.filter": "UNLOCALIZED: Filter",
|
||||
"create.logistics.recipe_filter": "UNLOCALIZED: Recipe Filter",
|
||||
"create.logistics.fluid_filter": "UNLOCALIZED: Fluid Filter",
|
||||
"create.logistics.firstFrequency": "UNLOCALIZED: Freq. #1",
|
||||
"create.logistics.secondFrequency": "UNLOCALIZED: Freq. #2",
|
||||
"create.logistics.filter.apply": "UNLOCALIZED: Applied filter to %1$s.",
|
||||
"create.logistics.filter.apply_click_again": "UNLOCALIZED: Applied filter to %1$s, click again to copy the amount.",
|
||||
"create.logistics.filter.apply_count": "UNLOCALIZED: Applied extraction count to filter.",
|
||||
"create.logistics.filter": "Filtro",
|
||||
"create.logistics.recipe_filter": "Filtro de receitas",
|
||||
"create.logistics.fluid_filter": "Filtro de fluido",
|
||||
"create.logistics.firstFrequency": "Freq. #1",
|
||||
"create.logistics.secondFrequency": "Freq. #2",
|
||||
"create.logistics.filter.apply": "Aplicou filtro para %1$s.",
|
||||
"create.logistics.filter.apply_click_again": "Aplicou filtro para %1$s, Clique denovo para copiar quantidade.",
|
||||
"create.logistics.filter.apply_count": "Aplicou quantidade de extração para o filtro.",
|
||||
|
||||
"create.gui.goggles.generator_stats": "Estatísticas do gerador:",
|
||||
"create.gui.goggles.kinetic_stats": "Estatísticas cinéticas:",
|
||||
"create.gui.goggles.at_current_speed": "Na velocidade atual",
|
||||
"create.gui.goggles.pole_length": "Comprimento da vara:",
|
||||
"create.gui.goggles.fluid_container": "UNLOCALIZED: Fluid Container Info:",
|
||||
"create.gui.goggles.fluid_container.capacity": "UNLOCALIZED: Capacity: ",
|
||||
"create.gui.assembly.exception": "UNLOCALIZED: This Contraption was unable to assemble:",
|
||||
"create.gui.assembly.exception.unmovableBlock": "UNLOCALIZED: Unmovable Block (%4$s) at [%1$s,%2$s,%3$s]",
|
||||
"create.gui.assembly.exception.chunkNotLoaded": "UNLOCALIZED: The Block at [%1$s,%2$s,%3$s] was not in a loaded chunk",
|
||||
"create.gui.assembly.exception.structureTooLarge": "UNLOCALIZED: There are too many Blocks included in the contraption.\nThe configured maximum is: %1$s",
|
||||
"create.gui.assembly.exception.tooManyPistonPoles": "UNLOCALIZED: There are too many extension Poles attached to this Piston.\nThe configured maximum is: %1$s",
|
||||
"create.gui.assembly.exception.noPistonPoles": "UNLOCALIZED: The Piston is missing some extension Poles",
|
||||
"create.gui.assembly.exception.not_enough_sails": "UNLOCALIZED: Attached structure does not include enough sail-like blocks: %1$s\nA minimum of %2$s are required",
|
||||
"create.gui.gauge.info_header": "UNLOCALIZED: Gauge Information:",
|
||||
"create.gui.speedometer.title": "UNLOCALIZED: Rotation Speed",
|
||||
"create.gui.stressometer.title": "UNLOCALIZED: Network Stress",
|
||||
"create.gui.stressometer.capacity": "UNLOCALIZED: Remaining Capacity",
|
||||
"create.gui.stressometer.overstressed": "UNLOCALIZED: Overstressed",
|
||||
"create.gui.stressometer.no_rotation": "UNLOCALIZED: No Rotation",
|
||||
"create.gui.contraptions.not_fast_enough": "UNLOCALIZED: It appears that this %1$s is _not_ rotating with _enough_ _speed_.",
|
||||
"create.gui.contraptions.network_overstressed": "UNLOCALIZED: It appears that this contraption is _overstressed_. Add more sources or _slow_ _down_ the components with a high _stress_ _impact_.",
|
||||
"create.gui.goggles.fluid_container": "Informação do recipiente de fluido:",
|
||||
"create.gui.goggles.fluid_container.capacity": "Capacidade: ",
|
||||
"create.gui.assembly.exception": "Não foi possível montar essa engenhoca:",
|
||||
"create.gui.assembly.exception.unmovableBlock": "Bloco imovel (%4$s) em [%1$s,%2$s,%3$s]",
|
||||
"create.gui.assembly.exception.chunkNotLoaded": "O bloco em [%1$s,%2$s,%3$s] não estava em um chunk carregado",
|
||||
"create.gui.assembly.exception.structureTooLarge": "Tem muitos blocos incluídos na engenhoca. O limite configurado é: %1$s",
|
||||
"create.gui.assembly.exception.tooManyPistonPoles": "Tem muitas varetas de extensão colocadas nesse pistão. O limite configurado é: %1$s",
|
||||
"create.gui.assembly.exception.noPistonPoles": "O pistão esta faltando algumas varetas de extensão",
|
||||
"create.gui.assembly.exception.not_enough_sails": "A estrutura conectada não possui o número suficiente de blocos tipo vela: %1$s\nUm mínimo de %2$s são requeridos",
|
||||
"create.gui.gauge.info_header": "Informação do medidor:",
|
||||
"create.gui.speedometer.title": "Velocidade de rotação",
|
||||
"create.gui.stressometer.title": "Estresse do sistema",
|
||||
"create.gui.stressometer.capacity": "Capacidade restante",
|
||||
"create.gui.stressometer.overstressed": "Sobre estressado",
|
||||
"create.gui.stressometer.no_rotation": "Nenhuma rotação",
|
||||
"create.gui.contraptions.not_fast_enough": "Aparenta que esse %1$s não _está_ girando com _a velocidade_ _necessária_.",
|
||||
"create.gui.contraptions.network_overstressed": "Aparenta que essa engenhoca está _sobre estressada_. Adicione mais fontes ou _desacelere_ __ os componentes que tem um _impacto de_ _stress alto_.",
|
||||
"create.gui.adjustable_crate.title": "UNLOCALIZED: Adjustable Crate",
|
||||
"create.gui.adjustable_crate.storageSpace": "UNLOCALIZED: Storage Space",
|
||||
"create.gui.stockpile_switch.title": "UNLOCALIZED: Stockpile Switch",
|
||||
"create.gui.stockpile_switch.invert_signal": "UNLOCALIZED: Invert Signal",
|
||||
"create.gui.stockpile_switch.move_to_lower_at": "UNLOCALIZED: Move to lower lane at %1$s%%",
|
||||
"create.gui.stockpile_switch.move_to_upper_at": "UNLOCALIZED: Move to upper lane at %1$s%%",
|
||||
"create.gui.sequenced_gearshift.title": "UNLOCALIZED: Sequenced Gearshift",
|
||||
"create.gui.sequenced_gearshift.instruction": "UNLOCALIZED: Instruction",
|
||||
"create.gui.sequenced_gearshift.instruction.turn_angle.descriptive": "UNLOCALIZED: Turn by angle",
|
||||
"create.gui.sequenced_gearshift.instruction.turn_angle": "UNLOCALIZED: Turn",
|
||||
"create.gui.sequenced_gearshift.instruction.turn_angle.angle": "UNLOCALIZED: Angle",
|
||||
"create.gui.sequenced_gearshift.instruction.turn_distance.descriptive": "UNLOCALIZED: Turn to move Piston/Pulley/Gantry",
|
||||
"create.gui.sequenced_gearshift.instruction.turn_distance": "UNLOCALIZED: Piston",
|
||||
"create.gui.sequenced_gearshift.instruction.turn_distance.distance": "UNLOCALIZED: Distance",
|
||||
"create.gui.sequenced_gearshift.instruction.delay.descriptive": "UNLOCALIZED: Timed Delay",
|
||||
"create.gui.sequenced_gearshift.instruction.delay": "UNLOCALIZED: Delay",
|
||||
"create.gui.sequenced_gearshift.instruction.delay.duration": "UNLOCALIZED: Duration",
|
||||
"create.gui.sequenced_gearshift.instruction.end.descriptive": "UNLOCALIZED: End",
|
||||
"create.gui.sequenced_gearshift.instruction.end": "UNLOCALIZED: End",
|
||||
"create.gui.sequenced_gearshift.instruction.await.descriptive": "UNLOCALIZED: Await new Redstone Pulse",
|
||||
"create.gui.sequenced_gearshift.instruction.await": "UNLOCALIZED: Await",
|
||||
"create.gui.sequenced_gearshift.speed": "UNLOCALIZED: Speed, Direction",
|
||||
"create.gui.sequenced_gearshift.speed.forward": "UNLOCALIZED: Input speed, Forwards",
|
||||
"create.gui.sequenced_gearshift.speed.forward_fast": "UNLOCALIZED: Double speed, Forwards",
|
||||
"create.gui.sequenced_gearshift.speed.back": "UNLOCALIZED: Input speed, Reversed",
|
||||
"create.gui.sequenced_gearshift.speed.back_fast": "UNLOCALIZED: Double speed, Reversed",
|
||||
"create.gui.stockpile_switch.title": "Dijuntor de armazenamento",
|
||||
"create.gui.stockpile_switch.invert_signal": "Inverter sinal",
|
||||
"create.gui.stockpile_switch.move_to_lower_at": "Mover para a faixa mais baixa %1$s%%",
|
||||
"create.gui.stockpile_switch.move_to_upper_at": "Mover para a faixa mais alta %1$s%%",
|
||||
"create.gui.sequenced_gearshift.title": "Câmbio sequenciado",
|
||||
"create.gui.sequenced_gearshift.instruction": "Instruções",
|
||||
"create.gui.sequenced_gearshift.instruction.turn_angle.descriptive": "Rotacionar por angulo",
|
||||
"create.gui.sequenced_gearshift.instruction.turn_angle": "Giro",
|
||||
"create.gui.sequenced_gearshift.instruction.turn_angle.angle": "Angulo",
|
||||
"create.gui.sequenced_gearshift.instruction.turn_distance.descriptive": "Rotacionar par mover Pistão/Polia/Portico",
|
||||
"create.gui.sequenced_gearshift.instruction.turn_distance": "Pistão",
|
||||
"create.gui.sequenced_gearshift.instruction.turn_distance.distance": "Distancia",
|
||||
"create.gui.sequenced_gearshift.instruction.delay.descriptive": "Espera",
|
||||
"create.gui.sequenced_gearshift.instruction.delay": "Esperar",
|
||||
"create.gui.sequenced_gearshift.instruction.delay.duration": "Duração",
|
||||
"create.gui.sequenced_gearshift.instruction.end.descriptive": "Terminar",
|
||||
"create.gui.sequenced_gearshift.instruction.end": "Termino",
|
||||
"create.gui.sequenced_gearshift.instruction.await.descriptive": "Esperar novo pulso de redstone",
|
||||
"create.gui.sequenced_gearshift.instruction.await": "Espera",
|
||||
"create.gui.sequenced_gearshift.speed": "Velocidade, Direção",
|
||||
"create.gui.sequenced_gearshift.speed.forward": "Velocidade inicial, Para frente",
|
||||
"create.gui.sequenced_gearshift.speed.forward_fast": "Dobro da velocidade, Para frente",
|
||||
"create.gui.sequenced_gearshift.speed.back": "Velocidade inicial, Para trás",
|
||||
"create.gui.sequenced_gearshift.speed.back_fast": "Dobro da velocidade, Para trás",
|
||||
|
||||
"create.schematicAndQuill.dimensions": "Tamanho Esquema: %1$sx%2$sx%3$s",
|
||||
"create.schematicAndQuill.firstPos": "Primeira posição feita.",
|
||||
"create.schematicAndQuill.secondPos": "Segunda posição feita.",
|
||||
"create.schematicAndQuill.noTarget": "Seguro [Ctrl] para selecionar Blocos de Ar.",
|
||||
"create.schematicAndQuill.noTarget": "Seguro [Ctrl] para seleccionar Blocos de Ar.",
|
||||
"create.schematicAndQuill.abort": "Seleção removida.",
|
||||
"create.schematicAndQuill.title": "Nome do esquema:",
|
||||
"create.schematicAndQuill.convert": "Salvar e carregar arquivo imediatamente",
|
||||
|
@ -1095,7 +1095,7 @@
|
|||
"create.schematic.tool.rotate.description.1": "[CTRL]-Rolar para rolar 90 Graus",
|
||||
"create.schematic.tool.rotate.description.2": "",
|
||||
"create.schematic.tool.rotate.description.3": "",
|
||||
"create.schematic.tool.print.description.0": "Coloca estrutura no mundo instantaneamente",
|
||||
"create.schematic.tool.print.description.0": "Colocá estrutura no mundo instantaneamente",
|
||||
"create.schematic.tool.print.description.1": "[Botão-Direito] para confirmar a posição atual.",
|
||||
"create.schematic.tool.print.description.2": "Esta ferramenta é para o Modo Criativo apenas.",
|
||||
"create.schematic.tool.print.description.3": "",
|
||||
|
@ -1108,11 +1108,11 @@
|
|||
"create.schematics.uploadTooLarge": "Seu esquema é muito grande",
|
||||
"create.schematics.maxAllowedSize": "O tamanho máximo permitido para o esquema é:",
|
||||
|
||||
"create.gui.schematicTable.refresh": "UNLOCALIZED: Refresh Files",
|
||||
"create.gui.schematicTable.open_folder": "UNLOCALIZED: Open Folder",
|
||||
"create.gui.schematicTable.refresh": "atualizar arquivos",
|
||||
"create.gui.schematicTable.open_folder": "Abrir pasta",
|
||||
"create.gui.schematicTable.title": "Mesa de Desenho",
|
||||
"create.gui.schematicTable.availableSchematics": "UNLOCALIZED: Available Schematics",
|
||||
"create.gui.schematicTable.noSchematics": "UNLOCALIZED: No Schematics Saved",
|
||||
"create.gui.schematicTable.availableSchematics": "Esquema disponíveis",
|
||||
"create.gui.schematicTable.noSchematics": "Nenhum esquema salvo",
|
||||
"create.gui.schematicTable.uploading": "Importando...",
|
||||
"create.gui.schematicTable.finished": "Envio Concluído!",
|
||||
"create.gui.schematicannon.title": "Canhão de esquema",
|
||||
|
@ -1122,18 +1122,18 @@
|
|||
"create.gui.schematicannon.shotsRemainingWithBackup": "Com backup: %1$s",
|
||||
"create.gui.schematicannon.optionEnabled": "Habilitado Atualmente",
|
||||
"create.gui.schematicannon.optionDisabled": "Desabilitado Atualmente",
|
||||
"create.gui.schematicannon.showOptions": "UNLOCALIZED: Show Printer Settings",
|
||||
"create.gui.schematicannon.showOptions": "Mostrar as configurações da impressora",
|
||||
"create.gui.schematicannon.option.dontReplaceSolid": "Não Substituir Blocos Sólidos",
|
||||
"create.gui.schematicannon.option.replaceWithSolid": "Substituir Blocos Sólidos",
|
||||
"create.gui.schematicannon.option.replaceWithAny": "Substituir Sólidos com Qualquer",
|
||||
"create.gui.schematicannon.option.replaceWithEmpty": "Substituir Sólidos com Vazio",
|
||||
"create.gui.schematicannon.option.skipMissing": "Pulando Blocos faltantes",
|
||||
"create.gui.schematicannon.option.skipTileEntities": "Proteger Entidades Entalhadas",
|
||||
"create.gui.schematicannon.slot.gunpowder": "UNLOCALIZED: Add gunpowder to fuel the cannon",
|
||||
"create.gui.schematicannon.slot.listPrinter": "UNLOCALIZED: Place books here to print a Checklist for your Schematic",
|
||||
"create.gui.schematicannon.slot.schematic": "UNLOCALIZED: Add your Schematic here. Make sure it is deployed at a specific location.",
|
||||
"create.gui.schematicannon.option.skipMissing.description": "Se o Canhão de esquema não encontrar o Bloco para colocar, ele irá continuar para a próx. Posição.",
|
||||
"create.gui.schematicannon.option.skipTileEntities.description": "O Canhão de esquema vai evitar substituir blocos que contêm dados como Baus.",
|
||||
"create.gui.schematicannon.option.skipTileEntities": "Proteger tile entities",
|
||||
"create.gui.schematicannon.slot.gunpowder": "Adicionar pólvora para carregar o canhão",
|
||||
"create.gui.schematicannon.slot.listPrinter": "Coloque livros aqui para imprimir uma lista para o seu esquema",
|
||||
"create.gui.schematicannon.slot.schematic": "Adicione o seu esquema aqui. Tenha certeza que ele está colocado em um lugar especifico.",
|
||||
"create.gui.schematicannon.option.skipMissing.description": "Se o Canhão de esquema não encontrar o Bloco para colocar, ele irá continuar para a próxima. Posição.",
|
||||
"create.gui.schematicannon.option.skipTileEntities.description": "O Canhão de esquema vai evitar substituir blocos que contêm dados como Baús.",
|
||||
"create.gui.schematicannon.option.dontReplaceSolid.description": "O Canhão de esquema nunca irá substituir Blocos sólidos na área em trabalho, apenas não-Sólidos e Ar.",
|
||||
"create.gui.schematicannon.option.replaceWithSolid.description": "O Canhão de esquema irá apenas substituir Blocos sólidos na área de trabalho, se o Esquema conter um bloco Sólido naquela posição.",
|
||||
"create.gui.schematicannon.option.replaceWithAny.description": "O Canhão de esquema irá substituir Blocos sólidos na área de trabalho, se o Esquema conter qualquer Bloco naquela posição.",
|
||||
|
@ -1157,187 +1157,187 @@
|
|||
"create.schematicannon.status.schematicNotPlaced": "Esquema não Colocado",
|
||||
"create.schematicannon.status.schematicExpired": "Arquivo de Esquema Expirado",
|
||||
|
||||
"create.materialChecklist": "UNLOCALIZED: Material Checklist",
|
||||
"create.materialChecklist": "Lista de materiais",
|
||||
"create.materialChecklist.blocksNotLoaded": "UNLOCALIZED: * Disclaimer *\n\nMaterial List may be inaccurate due to relevant chunks not being loaded.",
|
||||
|
||||
"create.gui.filter.deny_list": "UNLOCALIZED: Deny-List",
|
||||
"create.gui.filter.deny_list.description": "UNLOCALIZED: Items pass if they do NOT match any of the above. An empty Deny-List accepts everything.",
|
||||
"create.gui.filter.allow_list": "UNLOCALIZED: Allow-List",
|
||||
"create.gui.filter.allow_list.description": "UNLOCALIZED: Items pass if they match any of the above. An empty Allow-List rejects everything.",
|
||||
"create.gui.filter.respect_data": "UNLOCALIZED: Respect Data",
|
||||
"create.gui.filter.respect_data.description": "UNLOCALIZED: Items only match if their durability, enchantments, and other attributes match as well.",
|
||||
"create.gui.filter.ignore_data": "UNLOCALIZED: Ignore Data",
|
||||
"create.gui.filter.ignore_data.description": "UNLOCALIZED: Items match regardless of their attributes.",
|
||||
"create.gui.filter.deny_list": "Lista de negação",
|
||||
"create.gui.filter.deny_list.description": "Itens passam se eles não encaixam em nenhum dos acima. Uma lista de negação vazia aceita tudo.",
|
||||
"create.gui.filter.allow_list": "Lista de permissão",
|
||||
"create.gui.filter.allow_list.description": "Itens passam se eles se encaixam em algum dos acima. Uma lista de permissão vazia rejeita tudo.",
|
||||
"create.gui.filter.respect_data": "Respeitar informação",
|
||||
"create.gui.filter.respect_data.description": "Itens apenas se encaixam caso a durabilidade, encantamentos e outros atributos se encaixam também.",
|
||||
"create.gui.filter.ignore_data": "Ignorar informação",
|
||||
"create.gui.filter.ignore_data.description": "Itens se enquadram não importa os seus atributos.",
|
||||
|
||||
"create.item_attributes.placeable": "UNLOCALIZED: is placeable",
|
||||
"create.item_attributes.placeable.inverted": "UNLOCALIZED: is not placeable",
|
||||
"create.item_attributes.consumable": "UNLOCALIZED: can be eaten",
|
||||
"create.item_attributes.consumable.inverted": "UNLOCALIZED: cannot be eaten",
|
||||
"create.item_attributes.fluid_container": "UNLOCALIZED: can store fluids",
|
||||
"create.item_attributes.fluid_container.inverted": "UNLOCALIZED: cannot store fluids",
|
||||
"create.item_attributes.enchanted": "UNLOCALIZED: is enchanted",
|
||||
"create.item_attributes.enchanted.inverted": "UNLOCALIZED: is unenchanted",
|
||||
"create.item_attributes.max_enchanted": "UNLOCALIZED: is enchanted at max level",
|
||||
"create.item_attributes.max_enchanted.inverted": "UNLOCALIZED: is not enchanted at max level",
|
||||
"create.item_attributes.renamed": "UNLOCALIZED: has a custom name",
|
||||
"create.item_attributes.renamed.inverted": "UNLOCALIZED: does not have a custom name",
|
||||
"create.item_attributes.damaged": "UNLOCALIZED: is damaged",
|
||||
"create.item_attributes.damaged.inverted": "UNLOCALIZED: is not damaged",
|
||||
"create.item_attributes.badly_damaged": "UNLOCALIZED: is heavily damaged",
|
||||
"create.item_attributes.badly_damaged.inverted": "UNLOCALIZED: is not heavily damaged",
|
||||
"create.item_attributes.not_stackable": "UNLOCALIZED: cannot stack",
|
||||
"create.item_attributes.not_stackable.inverted": "UNLOCALIZED: can be stacked",
|
||||
"create.item_attributes.equipable": "UNLOCALIZED: can be equipped",
|
||||
"create.item_attributes.equipable.inverted": "UNLOCALIZED: cannot be equipped",
|
||||
"create.item_attributes.furnace_fuel": "UNLOCALIZED: is furnace fuel",
|
||||
"create.item_attributes.furnace_fuel.inverted": "UNLOCALIZED: is not furnace fuel",
|
||||
"create.item_attributes.washable": "UNLOCALIZED: can be Washed",
|
||||
"create.item_attributes.washable.inverted": "UNLOCALIZED: cannot be Washed",
|
||||
"create.item_attributes.hauntable": "UNLOCALIZED: can be Haunted",
|
||||
"create.item_attributes.hauntable.inverted": "UNLOCALIZED: cannot be Haunted",
|
||||
"create.item_attributes.crushable": "UNLOCALIZED: can be Crushed",
|
||||
"create.item_attributes.crushable.inverted": "UNLOCALIZED: cannot be Crushed",
|
||||
"create.item_attributes.smeltable": "UNLOCALIZED: can be Smelted",
|
||||
"create.item_attributes.smeltable.inverted": "UNLOCALIZED: cannot be Smelted",
|
||||
"create.item_attributes.smokable": "UNLOCALIZED: can be Smoked",
|
||||
"create.item_attributes.smokable.inverted": "UNLOCALIZED: cannot be Smoked",
|
||||
"create.item_attributes.blastable": "UNLOCALIZED: is smeltable in Blast Furnace",
|
||||
"create.item_attributes.blastable.inverted": "UNLOCALIZED: is not smeltable in Blast Furnace",
|
||||
"create.item_attributes.shulker_level": "UNLOCALIZED: is shulker %1$s",
|
||||
"create.item_attributes.shulker_level.inverted": "UNLOCALIZED: is shulker not %1$s",
|
||||
"create.item_attributes.shulker_level.full": "UNLOCALIZED: full",
|
||||
"create.item_attributes.shulker_level.empty": "UNLOCALIZED: empty",
|
||||
"create.item_attributes.shulker_level.partial": "UNLOCALIZED: partially filled",
|
||||
"create.item_attributes.in_tag": "UNLOCALIZED: is tagged %1$s",
|
||||
"create.item_attributes.in_tag.inverted": "UNLOCALIZED: is not tagged %1$s",
|
||||
"create.item_attributes.in_item_group": "UNLOCALIZED: is in group '%1$s'",
|
||||
"create.item_attributes.in_item_group.inverted": "UNLOCALIZED: is not in group '%1$s'",
|
||||
"create.item_attributes.added_by": "UNLOCALIZED: was added by %1$s",
|
||||
"create.item_attributes.added_by.inverted": "UNLOCALIZED: was not added by %1$s",
|
||||
"create.item_attributes.has_enchant": "UNLOCALIZED: is enchanted with %1$s",
|
||||
"create.item_attributes.has_enchant.inverted": "UNLOCALIZED: is not enchanted with %1$s",
|
||||
"create.item_attributes.color": "UNLOCALIZED: is dyed %1$s",
|
||||
"create.item_attributes.color.inverted": "UNLOCALIZED: is not dyed %1$s",
|
||||
"create.item_attributes.has_fluid": "UNLOCALIZED: contains %1$s",
|
||||
"create.item_attributes.has_fluid.inverted": "UNLOCALIZED: does not contain %1$s",
|
||||
"create.item_attributes.has_name": "UNLOCALIZED: has the custom name %1$s",
|
||||
"create.item_attributes.has_name.inverted": "UNLOCALIZED: does not have the custom name %1$s",
|
||||
"create.item_attributes.book_author": "UNLOCALIZED: was authored by %1$s",
|
||||
"create.item_attributes.book_author.inverted": "UNLOCALIZED: was not authored by %1$s",
|
||||
"create.item_attributes.book_copy_original": "UNLOCALIZED: is an original",
|
||||
"create.item_attributes.book_copy_original.inverted": "UNLOCALIZED: is not an original",
|
||||
"create.item_attributes.book_copy_first": "UNLOCALIZED: is a first-generation copy",
|
||||
"create.item_attributes.book_copy_first.inverted": "UNLOCALIZED: is not a first-generation copy",
|
||||
"create.item_attributes.book_copy_second": "UNLOCALIZED: is a second-generation copy",
|
||||
"create.item_attributes.book_copy_second.inverted": "UNLOCALIZED: is not a second-generation copy",
|
||||
"create.item_attributes.book_copy_tattered": "UNLOCALIZED: is a tattered mess",
|
||||
"create.item_attributes.book_copy_tattered.inverted": "UNLOCALIZED: is not a tattered mess",
|
||||
"create.item_attributes.astralsorcery_amulet": "UNLOCALIZED: improves %1$s",
|
||||
"create.item_attributes.astralsorcery_amulet.inverted": "UNLOCALIZED: does not improve %1$s",
|
||||
"create.item_attributes.astralsorcery_constellation": "UNLOCALIZED: is attuned to %1$s",
|
||||
"create.item_attributes.astralsorcery_constellation.inverted": "UNLOCALIZED: is not attuned to %1$s",
|
||||
"create.item_attributes.astralsorcery_crystal": "UNLOCALIZED: has crystal attribute %1$s",
|
||||
"create.item_attributes.astralsorcery_crystal.inverted": "UNLOCALIZED: does not have crystal attribute %1$s",
|
||||
"create.item_attributes.astralsorcery_perk_gem": "UNLOCALIZED: has perk attribute %1$s",
|
||||
"create.item_attributes.astralsorcery_perk_gem.inverted": "UNLOCALIZED: does not have perk attribute %1$s",
|
||||
"create.item_attributes.placeable": "É colocavel",
|
||||
"create.item_attributes.placeable.inverted": "Não é colocavel",
|
||||
"create.item_attributes.consumable": "É comestivel",
|
||||
"create.item_attributes.consumable.inverted": "Não é comestivel",
|
||||
"create.item_attributes.fluid_container": "Pode armazenar fluidos",
|
||||
"create.item_attributes.fluid_container.inverted": "Não pode armazenar fluidos",
|
||||
"create.item_attributes.enchanted": "Está encantado",
|
||||
"create.item_attributes.enchanted.inverted": "Não está encantado",
|
||||
"create.item_attributes.max_enchanted": "Está encantado no nível máximo",
|
||||
"create.item_attributes.max_enchanted.inverted": "Não está encantado no nível maximo",
|
||||
"create.item_attributes.renamed": "Tem nome customizado",
|
||||
"create.item_attributes.renamed.inverted": "Não tem nome customizado",
|
||||
"create.item_attributes.damaged": "Está danificado",
|
||||
"create.item_attributes.damaged.inverted": "Não está danificado",
|
||||
"create.item_attributes.badly_damaged": "Está severamente danificado",
|
||||
"create.item_attributes.badly_damaged.inverted": "Não esta severamente danificado",
|
||||
"create.item_attributes.not_stackable": "Não pode ser empilhado",
|
||||
"create.item_attributes.not_stackable.inverted": "Pode ser empilhado",
|
||||
"create.item_attributes.equipable": "Pode ser equipado",
|
||||
"create.item_attributes.equipable.inverted": "Não pode ser equipado",
|
||||
"create.item_attributes.furnace_fuel": "è combustivel",
|
||||
"create.item_attributes.furnace_fuel.inverted": "Não é combustivel",
|
||||
"create.item_attributes.washable": "Pode ser lavado",
|
||||
"create.item_attributes.washable.inverted": "Não pode ser lavado",
|
||||
"create.item_attributes.hauntable": "Pode ser amaldiçoado",
|
||||
"create.item_attributes.hauntable.inverted": "Não pode ser amaldiçoado",
|
||||
"create.item_attributes.crushable": "Pode ser triturado",
|
||||
"create.item_attributes.crushable.inverted": "Não pode ser triturado",
|
||||
"create.item_attributes.smeltable": "Pode ser fundido",
|
||||
"create.item_attributes.smeltable.inverted": "Não pode ser fundido",
|
||||
"create.item_attributes.smokable": "Pode ser defumado",
|
||||
"create.item_attributes.smokable.inverted": "Não pode ser defumado",
|
||||
"create.item_attributes.blastable": "È fundível no alto-forno",
|
||||
"create.item_attributes.blastable.inverted": "Não é fundível no alto-forno",
|
||||
"create.item_attributes.shulker_level": "O shulker é %1$s",
|
||||
"create.item_attributes.shulker_level.inverted": "O shulker não é %1$s",
|
||||
"create.item_attributes.shulker_level.full": "Cheio",
|
||||
"create.item_attributes.shulker_level.empty": "Vazio",
|
||||
"create.item_attributes.shulker_level.partial": "Parcialmente cheio",
|
||||
"create.item_attributes.in_tag": "è marcado %1$s",
|
||||
"create.item_attributes.in_tag.inverted": "Não é marcado %1$s",
|
||||
"create.item_attributes.in_item_group": "Está no grupo '%1$s'",
|
||||
"create.item_attributes.in_item_group.inverted": "Não esta no grupo '%1$s'",
|
||||
"create.item_attributes.added_by": "Foi adicionado por %1$s",
|
||||
"create.item_attributes.added_by.inverted": "Não foi adicionado por %1$s",
|
||||
"create.item_attributes.has_enchant": "Está encantado com %1$s",
|
||||
"create.item_attributes.has_enchant.inverted": "Não esta encantado com %1$s",
|
||||
"create.item_attributes.color": "Esta tingido de %1$s",
|
||||
"create.item_attributes.color.inverted": "Não está tingido de %1$s",
|
||||
"create.item_attributes.has_fluid": "Contem %1$s",
|
||||
"create.item_attributes.has_fluid.inverted": "Não contem %1$s",
|
||||
"create.item_attributes.has_name": "Tem o nome %1$s",
|
||||
"create.item_attributes.has_name.inverted": "Não tem o nome %1$s",
|
||||
"create.item_attributes.book_author": "Tem a autoria de %1$s",
|
||||
"create.item_attributes.book_author.inverted": "Não tem a autoria de %1$s",
|
||||
"create.item_attributes.book_copy_original": "É original",
|
||||
"create.item_attributes.book_copy_original.inverted": "Não é original",
|
||||
"create.item_attributes.book_copy_first": "É uma cópia da primeira geração",
|
||||
"create.item_attributes.book_copy_first.inverted": "Não é uma copia de primeira geração",
|
||||
"create.item_attributes.book_copy_second": "É uma cópia de segunda geração",
|
||||
"create.item_attributes.book_copy_second.inverted": "Não é uma copia de segunda geração",
|
||||
"create.item_attributes.book_copy_tattered": "É uma bagunça esfarrapada",
|
||||
"create.item_attributes.book_copy_tattered.inverted": "Não é uma bagunça esfarrapada",
|
||||
"create.item_attributes.astralsorcery_amulet": "Melhora %1$s",
|
||||
"create.item_attributes.astralsorcery_amulet.inverted": "Não melhora %1$s",
|
||||
"create.item_attributes.astralsorcery_constellation": "Esta sintonizado a %1$s",
|
||||
"create.item_attributes.astralsorcery_constellation.inverted": "Não esta sintonizado a %1$s",
|
||||
"create.item_attributes.astralsorcery_crystal": "Tem atributos de cristais %1$s",
|
||||
"create.item_attributes.astralsorcery_crystal.inverted": "Não tem atributos de cristais %1$s",
|
||||
"create.item_attributes.astralsorcery_perk_gem": " %1$s Tem um atributo de benefio",
|
||||
"create.item_attributes.astralsorcery_perk_gem.inverted": "%1$s Não tem um atributo de benefio",
|
||||
|
||||
"create.gui.attribute_filter.no_selected_attributes": "UNLOCALIZED: No attributes selected",
|
||||
"create.gui.attribute_filter.selected_attributes": "UNLOCALIZED: Selected attributes:",
|
||||
"create.gui.attribute_filter.add_attribute": "UNLOCALIZED: Add attribute to List",
|
||||
"create.gui.attribute_filter.add_inverted_attribute": "UNLOCALIZED: Add opposite attribute to List",
|
||||
"create.gui.attribute_filter.allow_list_disjunctive": "UNLOCALIZED: Allow-List (Any)",
|
||||
"create.gui.attribute_filter.allow_list_disjunctive.description": "UNLOCALIZED: Items pass if they have any of the selected attributes.",
|
||||
"create.gui.attribute_filter.allow_list_conjunctive": "UNLOCALIZED: Allow-List (All)",
|
||||
"create.gui.attribute_filter.allow_list_conjunctive.description": "UNLOCALIZED: Items pass only if they have ALL of the selected attributes.",
|
||||
"create.gui.attribute_filter.deny_list": "UNLOCALIZED: Deny-List",
|
||||
"create.gui.attribute_filter.deny_list.description": "UNLOCALIZED: Items pass if they do NOT have any of the selected attributes.",
|
||||
"create.gui.attribute_filter.add_reference_item": "UNLOCALIZED: Add Reference Item",
|
||||
"create.gui.attribute_filter.no_selected_attributes": "Nenhum atributo selecionado",
|
||||
"create.gui.attribute_filter.selected_attributes": "Atributos selecionados:",
|
||||
"create.gui.attribute_filter.add_attribute": "Adicionar atributo a lista",
|
||||
"create.gui.attribute_filter.add_inverted_attribute": "Adicionar atributo oposto a lista",
|
||||
"create.gui.attribute_filter.allow_list_disjunctive": "Lista de permissão (Qualquer)",
|
||||
"create.gui.attribute_filter.allow_list_disjunctive.description": "Itens passam se eles tiverem qualquer atributo selecionado.",
|
||||
"create.gui.attribute_filter.allow_list_conjunctive": "Lista de permissão (Todos)",
|
||||
"create.gui.attribute_filter.allow_list_conjunctive.description": "Itens passam se eles tiverem TODOS atributos selecionados.",
|
||||
"create.gui.attribute_filter.deny_list": "lista de negação",
|
||||
"create.gui.attribute_filter.deny_list.description": "Itens passam se eles NÃO tiverem qualquer atributo selecionado.",
|
||||
"create.gui.attribute_filter.add_reference_item": "Adicionar item referência",
|
||||
|
||||
"create.tooltip.holdForDescription": "UNLOCALIZED: Hold [%1$s] for Summary",
|
||||
"create.tooltip.holdForControls": "UNLOCALIZED: Hold [%1$s] for Controls",
|
||||
"create.tooltip.keyShift": "UNLOCALIZED: Shift",
|
||||
"create.tooltip.keyCtrl": "UNLOCALIZED: Ctrl",
|
||||
"create.tooltip.speedRequirement": "UNLOCALIZED: Speed Requirement: %1$s",
|
||||
"create.tooltip.speedRequirement.none": "UNLOCALIZED: None",
|
||||
"create.tooltip.speedRequirement.slow": "UNLOCALIZED: Slow",
|
||||
"create.tooltip.speedRequirement.medium": "UNLOCALIZED: Moderate",
|
||||
"create.tooltip.speedRequirement.fast": "UNLOCALIZED: Fast",
|
||||
"create.tooltip.stressImpact": "UNLOCALIZED: Kinetic Stress Impact: %1$s",
|
||||
"create.tooltip.stressImpact.low": "UNLOCALIZED: Low",
|
||||
"create.tooltip.stressImpact.medium": "UNLOCALIZED: Moderate",
|
||||
"create.tooltip.stressImpact.high": "UNLOCALIZED: High",
|
||||
"create.tooltip.stressImpact.overstressed": "UNLOCALIZED: Overstressed",
|
||||
"create.tooltip.capacityProvided": "UNLOCALIZED: Kinetic Stress Capacity: %1$s",
|
||||
"create.tooltip.capacityProvided.low": "UNLOCALIZED: Small",
|
||||
"create.tooltip.capacityProvided.medium": "UNLOCALIZED: Medium",
|
||||
"create.tooltip.capacityProvided.high": "UNLOCALIZED: Large",
|
||||
"create.tooltip.generationSpeed": "UNLOCALIZED: Generates at %1$s %2$s",
|
||||
"create.tooltip.analogStrength": "UNLOCALIZED: Analog Strength: %1$s/15",
|
||||
"create.tooltip.holdForDescription": "Segure [%1$s] para o sumário",
|
||||
"create.tooltip.holdForControls": "Segure [%1$s] para os controles",
|
||||
"create.tooltip.keyShift": "Shift",
|
||||
"create.tooltip.keyCtrl": "Ctrl",
|
||||
"create.tooltip.speedRequirement": "Requerimento de velocidade: %1$s",
|
||||
"create.tooltip.speedRequirement.none": "Nenhum",
|
||||
"create.tooltip.speedRequirement.slow": "Devagar",
|
||||
"create.tooltip.speedRequirement.medium": "Modereado",
|
||||
"create.tooltip.speedRequirement.fast": "Rapido",
|
||||
"create.tooltip.stressImpact": "Impacto de stress: %1$s",
|
||||
"create.tooltip.stressImpact.low": " Baixo",
|
||||
"create.tooltip.stressImpact.medium": " Moderado",
|
||||
"create.tooltip.stressImpact.high": " Alto",
|
||||
"create.tooltip.stressImpact.overstressed": ": Sobre estresse",
|
||||
"create.tooltip.capacityProvided": "Capacidade de stress cinético: %1$s",
|
||||
"create.tooltip.capacityProvided.low": " Pequeno",
|
||||
"create.tooltip.capacityProvided.medium": " Médio",
|
||||
"create.tooltip.capacityProvided.high": " Grande",
|
||||
"create.tooltip.generationSpeed": " Gera em %1$s %2$s",
|
||||
"create.tooltip.analogStrength": " Força analogica: %1$s/15",
|
||||
|
||||
"create.mechanical_arm.extract_from": "UNLOCALIZED: Take items from %1$s",
|
||||
"create.mechanical_arm.deposit_to": "UNLOCALIZED: Deposit items to %1$s",
|
||||
"create.mechanical_arm.summary": "UNLOCALIZED: Mechanical Arm has %1$s input(s) and %2$s output(s).",
|
||||
"create.mechanical_arm.points_outside_range": "UNLOCALIZED: %1$s selected interaction point(s) removed due to range limitations.",
|
||||
"create.mechanical_arm.extract_from": " Pegar itens de %1$s",
|
||||
"create.mechanical_arm.deposit_to": " Depositar itens para %1$s",
|
||||
"create.mechanical_arm.summary": "Braço mecânico tem %1$s entrada(s) e %2$s saida(s).",
|
||||
"create.mechanical_arm.points_outside_range": "%1$s Ponto(s) de interação removidos pelas limitações de alcance.",
|
||||
|
||||
"create.weighted_ejector.target_set": "UNLOCALIZED: Target Selected",
|
||||
"create.weighted_ejector.target_not_valid": "UNLOCALIZED: Ejecting to Adjacent block (Target was not Valid)",
|
||||
"create.weighted_ejector.no_target": "UNLOCALIZED: Ejecting to Adjacent block (No Target was Selected)",
|
||||
"create.weighted_ejector.targeting": "UNLOCALIZED: Ejecting to [%1$s,%2$s,%3$s]",
|
||||
"create.weighted_ejector.stack_size": "UNLOCALIZED: Ejected Stack Size",
|
||||
"create.weighted_ejector.target_set": "Alvo selecionado",
|
||||
"create.weighted_ejector.target_not_valid": "Ejetando para o bloco adjacente (Alvo não foi valido)",
|
||||
"create.weighted_ejector.no_target": "Ejetando para o bloco adjacente (Nenhum alvo foi selecionado)",
|
||||
"create.weighted_ejector.targeting": "Ejetando para [%1$s,%2$s,%3$s]",
|
||||
"create.weighted_ejector.stack_size": "Tamanho da pilha ejetada",
|
||||
|
||||
"create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available",
|
||||
"create.logistics.when_multiple_outputs_available": "Quando multiplas saidas selecionadas",
|
||||
|
||||
"create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
|
||||
"create.mechanical_arm.selection_mode.forced_round_robin": "UNLOCALIZED: Forced Round Robin",
|
||||
"create.mechanical_arm.selection_mode.prefer_first": "UNLOCALIZED: Prefer First Target",
|
||||
"create.mechanical_arm.selection_mode.round_robin": "Rodízio",
|
||||
"create.mechanical_arm.selection_mode.forced_round_robin": "Rodízio forçado",
|
||||
"create.mechanical_arm.selection_mode.prefer_first": "Preferir primeiro alvo",
|
||||
|
||||
"create.tunnel.selection_mode.split": "UNLOCALIZED: Split",
|
||||
"create.tunnel.selection_mode.forced_split": "UNLOCALIZED: Forced Split",
|
||||
"create.tunnel.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
|
||||
"create.tunnel.selection_mode.forced_round_robin": "UNLOCALIZED: Forced Round Robin",
|
||||
"create.tunnel.selection_mode.prefer_nearest": "UNLOCALIZED: Prefer Nearest",
|
||||
"create.tunnel.selection_mode.randomize": "UNLOCALIZED: Randomize",
|
||||
"create.tunnel.selection_mode.synchronize": "UNLOCALIZED: Synchronize Inputs",
|
||||
"create.tunnel.selection_mode.split": "Dividir",
|
||||
"create.tunnel.selection_mode.forced_split": "Divisão forçada",
|
||||
"create.tunnel.selection_mode.round_robin": "Rodízio",
|
||||
"create.tunnel.selection_mode.forced_round_robin": "Rodízio forçado",
|
||||
"create.tunnel.selection_mode.prefer_nearest": "Preferir o mais perto",
|
||||
"create.tunnel.selection_mode.randomize": "Aleatorizar",
|
||||
"create.tunnel.selection_mode.synchronize": "Sincronizar as entradas",
|
||||
|
||||
"create.tooltip.chute.header": "UNLOCALIZED: Chute Information",
|
||||
"create.tooltip.chute.items_move_down": "UNLOCALIZED: Items move Downward",
|
||||
"create.tooltip.chute.items_move_up": "UNLOCALIZED: Items move Upward",
|
||||
"create.tooltip.chute.no_fans_attached": "UNLOCALIZED: No attached fans",
|
||||
"create.tooltip.chute.fans_push_up": "UNLOCALIZED: Fans push from Below",
|
||||
"create.tooltip.chute.fans_push_down": "UNLOCALIZED: Fans push from Above",
|
||||
"create.tooltip.chute.fans_pull_up": "UNLOCALIZED: Fans pull from Above",
|
||||
"create.tooltip.chute.fans_pull_down": "UNLOCALIZED: Fans pull from Below",
|
||||
"create.tooltip.chute.contains": "UNLOCALIZED: Contains: %1$s x%2$s",
|
||||
"create.tooltip.brass_tunnel.contains": "UNLOCALIZED: Currently distributing:",
|
||||
"create.tooltip.brass_tunnel.contains_entry": "UNLOCALIZED: > %1$s x%2$s",
|
||||
"create.tooltip.brass_tunnel.retrieve": "UNLOCALIZED: Right-Click to retrieve",
|
||||
"create.tooltip.chute.header": "Informação da calha",
|
||||
"create.tooltip.chute.items_move_down": "Itens movimentam para baixo",
|
||||
"create.tooltip.chute.items_move_up": "Itens movem para cima",
|
||||
"create.tooltip.chute.no_fans_attached": "Não conectado com um ventilador",
|
||||
"create.tooltip.chute.fans_push_up": "Ventiladores sopram de baixo",
|
||||
"create.tooltip.chute.fans_push_down": "Ventiladores sopram de cima",
|
||||
"create.tooltip.chute.fans_pull_up": "Ventiladores sugam de cima",
|
||||
"create.tooltip.chute.fans_pull_down": "Ventiladores sugam de baixo",
|
||||
"create.tooltip.chute.contains": "Contem: %1$s x%2$s",
|
||||
"create.tooltip.brass_tunnel.contains": "Distribuindo:",
|
||||
"create.tooltip.brass_tunnel.contains_entry": " > %1$s x%2$s",
|
||||
"create.tooltip.brass_tunnel.retrieve": "Clique direito para recuperar item",
|
||||
|
||||
"create.linked_controller.bind_mode": "UNLOCALIZED: Bind mode active",
|
||||
"create.linked_controller.press_keybind": "UNLOCALIZED: Press %1$s, %2$s, %3$s, %4$s, %5$s or %6$s, to bind this frequency to the respective key",
|
||||
"create.linked_controller.key_bound": "UNLOCALIZED: Frequency bound to %1$s",
|
||||
"create.linked_controller.frequency_slot_1": "UNLOCALIZED: Keybind: %1$s, Freq. #1",
|
||||
"create.linked_controller.frequency_slot_2": "UNLOCALIZED: Keybind: %1$s, Freq. #2",
|
||||
"create.linked_controller.bind_mode": "Modo de vinculação",
|
||||
"create.linked_controller.press_keybind": "Aperte %1$s, %2$s, %3$s, %4$s, %5$s or %6$s, para vincular essa frequencia para tecla respectiva",
|
||||
"create.linked_controller.key_bound": "Frequência vinculada com %1$s",
|
||||
"create.linked_controller.frequency_slot_1": "Tecla: %1$s, Freq. #1",
|
||||
"create.linked_controller.frequency_slot_2": "Tecla: %1$s, Freq. #2",
|
||||
|
||||
"create.crafting_blueprint.crafting_slot": "UNLOCALIZED: Ingredient Slot",
|
||||
"create.crafting_blueprint.filter_items_viable": "UNLOCALIZED: Advanced filter items are viable",
|
||||
"create.crafting_blueprint.display_slot": "UNLOCALIZED: Display Slot",
|
||||
"create.crafting_blueprint.inferred": "UNLOCALIZED: Inferred from recipe",
|
||||
"create.crafting_blueprint.manually_assigned": "UNLOCALIZED: Manually assigned",
|
||||
"create.crafting_blueprint.secondary_display_slot": "UNLOCALIZED: Secondary Display Slot",
|
||||
"create.crafting_blueprint.optional": "UNLOCALIZED: Optional",
|
||||
"create.crafting_blueprint.crafting_slot": "Slot de ingrediente",
|
||||
"create.crafting_blueprint.filter_items_viable": "Filtros avançados são viaveis",
|
||||
"create.crafting_blueprint.display_slot": "Slot de exibição",
|
||||
"create.crafting_blueprint.inferred": "Deduzido pela receita",
|
||||
"create.crafting_blueprint.manually_assigned": "Designado manualmente",
|
||||
"create.crafting_blueprint.secondary_display_slot": "Slot de exibição secundario",
|
||||
"create.crafting_blueprint.optional": "Opcional",
|
||||
|
||||
"create.potato_cannon.ammo.attack_damage": "UNLOCALIZED: %1$s Attack Damage",
|
||||
"create.potato_cannon.ammo.reload_ticks": "UNLOCALIZED: %1$s Reload Ticks",
|
||||
"create.potato_cannon.ammo.knockback": "UNLOCALIZED: %1$s Knockback",
|
||||
"create.potato_cannon.ammo.attack_damage": " %1$s Dano de ataque",
|
||||
"create.potato_cannon.ammo.reload_ticks": " %1$s Velocidade de recarregamento",
|
||||
"create.potato_cannon.ammo.knockback": " %1$s Repulsão do projetil",
|
||||
|
||||
"create.hint.hose_pulley.title": "UNLOCALIZED: Bottomless Supply",
|
||||
"create.hint.hose_pulley": "UNLOCALIZED: The targeted body of fluid is considered infinite.",
|
||||
"create.hint.mechanical_arm_no_targets.title": "UNLOCALIZED: No Targets",
|
||||
"create.hint.mechanical_arm_no_targets": "UNLOCALIZED: It appears this _Mechanical_ _Arm_ has not been assigned any _targets._ Select belts, depots, funnels and other blocks by _right-clicking_ them while _holding_ the _Mechanical_ _Arm_ in your _hand_.",
|
||||
"create.hint.empty_bearing.title": "UNLOCALIZED: Update Bearing",
|
||||
"create.hint.empty_bearing": "UNLOCALIZED: _Right-click_ the bearing with an _empty_ _hand_ to _attach_ the structure you just built in front of it.",
|
||||
"create.hint.full_deployer.title": "UNLOCALIZED: Deployer Item Overflow",
|
||||
"create.hint.full_deployer": "UNLOCALIZED: It appears this _Deployer_ contains _excess_ _items_ that need to be _extracted._ Use a _hopper,_ _funnel_ or other means to free it from its overflow.",
|
||||
"create.hint.hose_pulley.title": "Abastecimento sem fundo",
|
||||
"create.hint.hose_pulley": "O corpo de fluido selecionado é considerado infinito.",
|
||||
"create.hint.mechanical_arm_no_targets.title": "Sem alvos",
|
||||
"create.hint.mechanical_arm_no_targets": "Aparentemente esse _Braço_ _Mecânico_ não foi designado nenhum _alvo._ Selecione esteiras, depósitos, funis e outros blocos com o _botão direito do mouse_ enquanto _segurando_ o _Braço_ _Mecanico_ na sua _mão_.",
|
||||
"create.hint.empty_bearing.title": "Atualizar o rolamento",
|
||||
"create.hint.empty_bearing": " _clique com o botão direito_ o rolamento com a _mão_ _vazia_ para _conectar_ a estrutura que você construiu não frente disso.",
|
||||
"create.hint.full_deployer.title": "Implantador transbordando de itens",
|
||||
"create.hint.full_deployer": "Aparenta que esse _inplantador_ contém _itens_ em _excesso_ que precisam ser _extraídos._ Use um _funil,_ _funil de andesito/latão_ ou outros meios para extrair os itens excedentes.",
|
||||
"create.hint.derailed_train.title": "UNLOCALIZED: Derailed Train",
|
||||
"create.hint.derailed_train": "UNLOCALIZED: It appears this _Train_ is no longer sitting on a connected track piece. _Right-Click_ using a _wrench_ in order to relocate it to a nearby track.",
|
||||
|
||||
|
@ -1551,7 +1551,7 @@
|
|||
"create.super_glue.not_enough": "UNLOCALIZED: Not enough glue in inventory",
|
||||
"create.super_glue.sucess": "UNLOCALIZED: Applying Glue...",
|
||||
|
||||
"create.gui.config.overlay1": "UNLOCALIZED: Hi :)",
|
||||
"create.gui.config.overlay1": "Oi :)",
|
||||
"create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay",
|
||||
"create.gui.config.overlay3": "UNLOCALIZED: Click or drag with your mouse",
|
||||
"create.gui.config.overlay4": "UNLOCALIZED: to move this preview",
|
||||
|
@ -1560,62 +1560,62 @@
|
|||
"create.gui.config.overlay7": "UNLOCALIZED: Run /create overlay reset",
|
||||
"create.gui.config.overlay8": "UNLOCALIZED: to reset to the default position",
|
||||
|
||||
"create.command.killTPSCommand": "UNLOCALIZED: killtps",
|
||||
"create.command.killTPSCommand.status.slowed_by.0": "UNLOCALIZED: [Create]: Server tick is currently slowed by %s ms :o",
|
||||
"create.command.killTPSCommand.status.slowed_by.1": "UNLOCALIZED: [Create]: Server tick is slowed by %s ms now >:)",
|
||||
"create.command.killTPSCommand.status.slowed_by.2": "UNLOCALIZED: [Create]: Server tick is back to regular speed :D",
|
||||
"create.command.killTPSCommand.status.usage.0": "UNLOCALIZED: [Create]: use /killtps stop to bring back server tick to regular speed",
|
||||
"create.command.killTPSCommand.status.usage.1": "UNLOCALIZED: [Create]: use /killtps start <tickTime> to artificially slow down the server tick",
|
||||
"create.command.killTPSCommand.argument.tickTime": "UNLOCALIZED: tickTime",
|
||||
"create.command.killTPSCommand": " killtps",
|
||||
"create.command.killTPSCommand.status.slowed_by.0": " [Create]: Server tick is currently slowed by %s ms :o",
|
||||
"create.command.killTPSCommand.status.slowed_by.1": " [Create]: Server tick is slowed by %s ms now >:)",
|
||||
"create.command.killTPSCommand.status.slowed_by.2": " [Create]: Server tick is back to regular speed :D",
|
||||
"create.command.killTPSCommand.status.usage.0": " [Create]: use /killtps stop to bring back server tick to regular speed",
|
||||
"create.command.killTPSCommand.status.usage.1": " [Create]: use /killtps start <tickTime> to artificially slow down the server tick",
|
||||
"create.command.killTPSCommand.argument.tickTime": "tickTime",
|
||||
|
||||
"create.contraption.minecart_contraption_too_big": "UNLOCALIZED: This Cart Contraption seems too big to pick up",
|
||||
"create.contraption.minecart_contraption_illegal_pickup": "UNLOCALIZED: A mystical force is binding this Cart Contraption to the world",
|
||||
"create.contraption.minecart_contraption_too_big": "Essa engenhoca de carrinho aparenta ser muita grande para pegar",
|
||||
"create.contraption.minecart_contraption_illegal_pickup": "Uma força mistica esta segurando esta engenhoca de carrinho",
|
||||
|
||||
|
||||
"_": "->------------------------] Subtitles [------------------------<-",
|
||||
|
||||
"create.subtitle.contraption_disassemble": "UNLOCALIZED: Contraption stops",
|
||||
"create.subtitle.peculiar_bell_use": "UNLOCALIZED: Peculiar Bell tolls",
|
||||
"create.subtitle.mixing": "UNLOCALIZED: Mixing noises",
|
||||
"create.subtitle.mechanical_press_activation_belt": "UNLOCALIZED: Mechanical Press bonks",
|
||||
"create.subtitle.fwoomp": "UNLOCALIZED: Potato Launcher fwoomps",
|
||||
"create.subtitle.worldshaper_place": "UNLOCALIZED: Worldshaper zaps",
|
||||
"create.subtitle.sanding_long": "UNLOCALIZED: Sanding noises",
|
||||
"create.subtitle.crushing_1": "UNLOCALIZED: Crushing noises",
|
||||
"create.subtitle.depot_slide": "UNLOCALIZED: Item slides",
|
||||
"create.subtitle.saw_activate_stone": "UNLOCALIZED: Mechanical Saw activates",
|
||||
"create.subtitle.blaze_munch": "UNLOCALIZED: Blaze Burner munches",
|
||||
"create.subtitle.funnel_flap": "UNLOCALIZED: Funnel flaps",
|
||||
"create.subtitle.schematicannon_finish": "UNLOCALIZED: Schematicannon dings",
|
||||
"create.subtitle.haunted_bell_use": "UNLOCALIZED: Haunted Bell tolls",
|
||||
"create.subtitle.scroll_value": "UNLOCALIZED: Scroll-input clicks",
|
||||
"create.subtitle.crafter_craft": "UNLOCALIZED: Crafter crafts",
|
||||
"create.subtitle.controller_put": "UNLOCALIZED: Controller thumps",
|
||||
"create.subtitle.cranking": "UNLOCALIZED: Hand Crank turns",
|
||||
"create.subtitle.wrench_remove": "UNLOCALIZED: Component breaks",
|
||||
"create.subtitle.sanding_short": "UNLOCALIZED: Sanding noises",
|
||||
"create.subtitle.contraption_disassemble": "Engenhoca para",
|
||||
"create.subtitle.peculiar_bell_use": "Sino peculiar toca",
|
||||
"create.subtitle.mixing": "Sons de mistura",
|
||||
"create.subtitle.mechanical_press_activation_belt": "Bonks da prensa mecanica",
|
||||
"create.subtitle.fwoomp": "Fwoomps do canhão de batata",
|
||||
"create.subtitle.worldshaper_place": "Zaps do terraformador",
|
||||
"create.subtitle.sanding_long": "Sons de lixa",
|
||||
"create.subtitle.crushing_1": "Sons de trituração",
|
||||
"create.subtitle.depot_slide": "Item escorrega",
|
||||
"create.subtitle.saw_activate_stone": "Serra mecânica ativa",
|
||||
"create.subtitle.blaze_munch": "Queimador de blazer mastiga",
|
||||
"create.subtitle.funnel_flap": "Abas do funil batendo",
|
||||
"create.subtitle.schematicannon_finish": "Ding do canhão de esquema",
|
||||
"create.subtitle.haunted_bell_use": "Sino assombrado toca",
|
||||
"create.subtitle.scroll_value": "click do scroll",
|
||||
"create.subtitle.crafter_craft": "Fabricador fábrica",
|
||||
"create.subtitle.controller_put": "Thumps do controle",
|
||||
"create.subtitle.cranking": "Manivela gira",
|
||||
"create.subtitle.wrench_remove": "Componente quebra",
|
||||
"create.subtitle.sanding_short": "Sons de lixa",
|
||||
"create.subtitle.whistle": "UNLOCALIZED: Whistling",
|
||||
"create.subtitle.cogs": "UNLOCALIZED: Cogwheels rumble",
|
||||
"create.subtitle.slime_added": "UNLOCALIZED: Slime squishes",
|
||||
"create.subtitle.wrench_rotate": "UNLOCALIZED: Wrench used",
|
||||
"create.subtitle.potato_hit": "UNLOCALIZED: Vegetable impacts",
|
||||
"create.subtitle.saw_activate_wood": "UNLOCALIZED: Mechanical Saw activates",
|
||||
"create.subtitle.cogs": "tremer da rodas dentadas",
|
||||
"create.subtitle.slime_added": "Slime sendo espremido",
|
||||
"create.subtitle.wrench_rotate": "Chave inglesa usada",
|
||||
"create.subtitle.potato_hit": "Impacto vegetal",
|
||||
"create.subtitle.saw_activate_wood": "Serra mecânica ativa",
|
||||
"create.subtitle.whistle_high": "UNLOCALIZED: High whistling",
|
||||
"create.subtitle.whistle_train": "UNLOCALIZED: Whistling",
|
||||
"create.subtitle.haunted_bell_convert": "UNLOCALIZED: Haunted Bell awakens",
|
||||
"create.subtitle.haunted_bell_convert": "Sino assombrado acorda",
|
||||
"create.subtitle.whistle_train_high": "UNLOCALIZED: High whistling",
|
||||
"create.subtitle.whistle_train_low": "UNLOCALIZED: Low whistling",
|
||||
"create.subtitle.deny": "UNLOCALIZED: Declining boop",
|
||||
"create.subtitle.controller_click": "UNLOCALIZED: Controller clicks",
|
||||
"create.subtitle.deny": "Boop de negação",
|
||||
"create.subtitle.controller_click": "Clicks do controle",
|
||||
"create.subtitle.whistle_low": "UNLOCALIZED: Low whistling",
|
||||
"create.subtitle.schematicannon_launch_block": "UNLOCALIZED: Schematicannon fires",
|
||||
"create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks",
|
||||
"create.subtitle.controller_take": "UNLOCALIZED: Lectern empties",
|
||||
"create.subtitle.mechanical_press_activation": "UNLOCALIZED: Mechanical Press clangs",
|
||||
"create.subtitle.contraption_assemble": "UNLOCALIZED: Contraption moves",
|
||||
"create.subtitle.crafter_click": "UNLOCALIZED: Crafter clicks",
|
||||
"create.subtitle.depot_plop": "UNLOCALIZED: Item lands",
|
||||
"create.subtitle.confirm": "UNLOCALIZED: Affirmative ding",
|
||||
"create.subtitle.schematicannon_launch_block": "Canhão de esquema atira",
|
||||
"create.subtitle.copper_armor_equip": "Tilintar dos equipamentos de mergulho",
|
||||
"create.subtitle.controller_take": "Atril esvaziado",
|
||||
"create.subtitle.mechanical_press_activation": "Clang da prensa mecânica",
|
||||
"create.subtitle.contraption_assemble": "Engenhoca move",
|
||||
"create.subtitle.crafter_click": "Clicks do fabricador",
|
||||
"create.subtitle.depot_plop": "Item pousa",
|
||||
"create.subtitle.confirm": "Ding afirmativo",
|
||||
|
||||
|
||||
"_": "->------------------------] Item Descriptions [------------------------<-",
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -8,11 +8,7 @@
|
|||
"results": [
|
||||
{
|
||||
"item": "minecraft:gold_nugget",
|
||||
"count": 7
|
||||
},
|
||||
{
|
||||
"item": "minecraft:gold_nugget",
|
||||
"chance": 0.5
|
||||
"count": 18
|
||||
},
|
||||
{
|
||||
"item": "create:experience_nugget",
|
||||
|
|
|
@ -8,11 +8,14 @@ import org.apache.logging.log4j.Logger;
|
|||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.simibubi.create.api.behaviour.BlockSpoutingBehaviour;
|
||||
import com.simibubi.create.compat.Mods;
|
||||
import com.simibubi.create.compat.curios.Curios;
|
||||
import com.simibubi.create.content.CreateItemGroup;
|
||||
import com.simibubi.create.content.contraptions.TorquePropagator;
|
||||
import com.simibubi.create.content.curiosities.weapons.BuiltinPotatoProjectileTypes;
|
||||
import com.simibubi.create.content.logistics.RedstoneLinkNetworkHandler;
|
||||
import com.simibubi.create.content.logistics.block.display.AllDisplayBehaviours;
|
||||
import com.simibubi.create.content.logistics.block.mechanicalArm.AllArmInteractionPointTypes;
|
||||
import com.simibubi.create.content.logistics.trains.GlobalRailwayManager;
|
||||
import com.simibubi.create.content.palettes.AllPaletteBlocks;
|
||||
import com.simibubi.create.content.palettes.PalettesItemGroup;
|
||||
|
@ -98,6 +101,7 @@ public class Create {
|
|||
AllMovementBehaviours.register();
|
||||
AllDisplayBehaviours.register();
|
||||
AllInteractionBehaviours.register();
|
||||
AllArmInteractionPointTypes.register();
|
||||
AllWorldFeatures.register();
|
||||
AllEnchantments.register();
|
||||
AllConfigs.register(modLoadingContext);
|
||||
|
@ -120,6 +124,8 @@ public class Create {
|
|||
modEventBus.addGenericListener(DataSerializerEntry.class, AllEntityDataSerializers::register);
|
||||
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> CreateClient.onCtorClient(modEventBus, forgeEventBus));
|
||||
|
||||
Mods.CURIOS.executeIfInstalled(() -> Curios::init);
|
||||
}
|
||||
|
||||
public static void init(final FMLCommonSetupEvent event) {
|
||||
|
|
|
@ -0,0 +1,447 @@
|
|||
package com.simibubi.create.api.connectivity;
|
||||
|
||||
import com.simibubi.create.content.contraptions.fluids.tank.CreativeFluidTankTileEntity;
|
||||
import com.simibubi.create.foundation.tileEntity.IMultiTileContainer;
|
||||
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.IFluidTank;
|
||||
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
||||
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Set;
|
||||
|
||||
public class ConnectivityHandler {
|
||||
|
||||
public static <T extends BlockEntity & IMultiTileContainer> void formMulti(T be) {
|
||||
SearchCache<T> cache = new SearchCache<>();
|
||||
List<T> frontier = new ArrayList<>();
|
||||
frontier.add(be);
|
||||
formMulti(be.getType(), be.getLevel(), cache, frontier);
|
||||
}
|
||||
|
||||
private static <T extends BlockEntity & IMultiTileContainer> void formMulti(BlockEntityType<?> type,
|
||||
BlockGetter level, SearchCache<T> cache, List<T> frontier) {
|
||||
PriorityQueue<Pair<Integer, T>> creationQueue = makeCreationQueue();
|
||||
Set<BlockPos> visited = new HashSet<>();
|
||||
Direction.Axis mainAxis = frontier.get(0)
|
||||
.getMainConnectionAxis();
|
||||
|
||||
// essentially, if it's a vertical multi then the search won't be restricted by
|
||||
// Y
|
||||
// alternately, a horizontal multi search shouldn't be restricted by X or Z
|
||||
int minX = (mainAxis == Direction.Axis.Y ? Integer.MAX_VALUE : Integer.MIN_VALUE);
|
||||
int minY = (mainAxis != Direction.Axis.Y ? Integer.MAX_VALUE : Integer.MIN_VALUE);
|
||||
int minZ = (mainAxis == Direction.Axis.Y ? Integer.MAX_VALUE : Integer.MIN_VALUE);
|
||||
|
||||
for (T be : frontier) {
|
||||
BlockPos pos = be.getBlockPos();
|
||||
minX = Math.min(pos.getX(), minX);
|
||||
minY = Math.min(pos.getY(), minY);
|
||||
minZ = Math.min(pos.getZ(), minZ);
|
||||
}
|
||||
if (mainAxis == Direction.Axis.Y)
|
||||
minX -= frontier.get(0)
|
||||
.getMaxWidth();
|
||||
if (mainAxis != Direction.Axis.Y)
|
||||
minY -= frontier.get(0)
|
||||
.getMaxWidth();
|
||||
if (mainAxis == Direction.Axis.Y)
|
||||
minZ -= frontier.get(0)
|
||||
.getMaxWidth();
|
||||
|
||||
while (!frontier.isEmpty()) {
|
||||
T part = frontier.remove(0);
|
||||
BlockPos partPos = part.getBlockPos();
|
||||
if (visited.contains(partPos))
|
||||
continue;
|
||||
|
||||
visited.add(partPos);
|
||||
|
||||
int amount = tryToFormNewMulti(part, cache, true);
|
||||
if (amount > 1) {
|
||||
creationQueue.add(Pair.of(amount, part));
|
||||
}
|
||||
|
||||
for (Direction.Axis axis : Iterate.axes) {
|
||||
Direction dir = Direction.get(Direction.AxisDirection.NEGATIVE, axis);
|
||||
BlockPos next = partPos.relative(dir);
|
||||
|
||||
if (next.getX() <= minX || next.getY() <= minY || next.getZ() <= minZ)
|
||||
continue;
|
||||
if (visited.contains(next))
|
||||
continue;
|
||||
T nextBe = partAt(type, level, next);
|
||||
if (nextBe == null)
|
||||
continue;
|
||||
if (nextBe.isRemoved())
|
||||
continue;
|
||||
frontier.add(nextBe);
|
||||
}
|
||||
}
|
||||
visited.clear();
|
||||
|
||||
while (!creationQueue.isEmpty()) {
|
||||
Pair<Integer, T> next = creationQueue.poll();
|
||||
T toCreate = next.getValue();
|
||||
if (visited.contains(toCreate.getBlockPos()))
|
||||
continue;
|
||||
|
||||
visited.add(toCreate.getBlockPos());
|
||||
tryToFormNewMulti(toCreate, cache, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static <T extends BlockEntity & IMultiTileContainer> int tryToFormNewMulti(T be, SearchCache<T> cache,
|
||||
boolean simulate) {
|
||||
int bestWidth = 1;
|
||||
int bestAmount = -1;
|
||||
if (!be.isController())
|
||||
return 0;
|
||||
|
||||
int radius = be.getMaxWidth();
|
||||
for (int w = 1; w <= radius; w++) {
|
||||
int amount = tryToFormNewMultiOfWidth(be, w, cache, true);
|
||||
if (amount < bestAmount)
|
||||
continue;
|
||||
bestWidth = w;
|
||||
bestAmount = amount;
|
||||
}
|
||||
|
||||
if (!simulate) {
|
||||
int beWidth = be.getWidth();
|
||||
if (beWidth == bestWidth && beWidth * beWidth * be.getHeight() == bestAmount)
|
||||
return bestAmount;
|
||||
|
||||
splitMultiAndInvalidate(be, cache, false);
|
||||
if (be instanceof IMultiTileContainer.Fluid ifluid && ifluid.hasTank())
|
||||
ifluid.setTankSize(0, bestAmount);
|
||||
|
||||
tryToFormNewMultiOfWidth(be, bestWidth, cache, false);
|
||||
|
||||
be.preventConnectivityUpdate();
|
||||
be.setWidth(bestWidth);
|
||||
be.setHeight(bestAmount / bestWidth / bestWidth);
|
||||
be.notifyMultiUpdated();
|
||||
}
|
||||
return bestAmount;
|
||||
}
|
||||
|
||||
private static <T extends BlockEntity & IMultiTileContainer> int tryToFormNewMultiOfWidth(T be, int width,
|
||||
SearchCache<T> cache, boolean simulate) {
|
||||
int amount = 0;
|
||||
int height = 0;
|
||||
BlockEntityType<?> type = be.getType();
|
||||
Level level = be.getLevel();
|
||||
if (level == null)
|
||||
return 0;
|
||||
BlockPos origin = be.getBlockPos();
|
||||
|
||||
// optional fluid handling
|
||||
IFluidTank beTank = null;
|
||||
FluidStack fluid = FluidStack.EMPTY;
|
||||
if (be instanceof IMultiTileContainer.Fluid ifluid && ifluid.hasTank()) {
|
||||
beTank = ifluid.getTank(0);
|
||||
fluid = beTank.getFluid();
|
||||
}
|
||||
Direction.Axis axis = be.getMainConnectionAxis();
|
||||
|
||||
Search: for (int yOffset = 0; yOffset < be.getMaxLength(axis, width); yOffset++) {
|
||||
for (int xOffset = 0; xOffset < width; xOffset++) {
|
||||
for (int zOffset = 0; zOffset < width; zOffset++) {
|
||||
BlockPos pos = switch (axis) {
|
||||
case X -> origin.offset(yOffset, xOffset, zOffset);
|
||||
case Y -> origin.offset(xOffset, yOffset, zOffset);
|
||||
case Z -> origin.offset(xOffset, zOffset, yOffset);
|
||||
};
|
||||
Optional<T> part = cache.getOrCache(type, level, pos);
|
||||
if (part.isEmpty())
|
||||
break Search;
|
||||
|
||||
T controller = part.get();
|
||||
int otherWidth = controller.getWidth();
|
||||
if (otherWidth > width)
|
||||
break Search;
|
||||
if (otherWidth == width && controller.getHeight() == be.getMaxLength(axis, width))
|
||||
break Search;
|
||||
|
||||
Direction.Axis conAxis = controller.getMainConnectionAxis();
|
||||
if (axis != conAxis)
|
||||
break Search;
|
||||
|
||||
BlockPos conPos = controller.getBlockPos();
|
||||
if (!conPos.equals(origin)) {
|
||||
if (axis == Direction.Axis.Y) { // vertical multi, like a FluidTank
|
||||
if (conPos.getX() < origin.getX())
|
||||
break Search;
|
||||
if (conPos.getZ() < origin.getZ())
|
||||
break Search;
|
||||
if (conPos.getX() + otherWidth > origin.getX() + width)
|
||||
break Search;
|
||||
if (conPos.getZ() + otherWidth > origin.getZ() + width)
|
||||
break Search;
|
||||
} else { // horizontal multi, like an ItemVault
|
||||
if (axis == Direction.Axis.Z && conPos.getX() < origin.getX())
|
||||
break Search;
|
||||
if (conPos.getY() < origin.getY())
|
||||
break Search;
|
||||
if (axis == Direction.Axis.X && conPos.getZ() < origin.getZ())
|
||||
break Search;
|
||||
if (axis == Direction.Axis.Z && conPos.getX() + otherWidth > origin.getX() + width)
|
||||
break Search;
|
||||
if (conPos.getY() + otherWidth > origin.getY() + width)
|
||||
break Search;
|
||||
if (axis == Direction.Axis.X && conPos.getZ() + otherWidth > origin.getZ() + width)
|
||||
break Search;
|
||||
}
|
||||
}
|
||||
if (controller instanceof IMultiTileContainer.Fluid ifluidCon && ifluidCon.hasTank()) {
|
||||
FluidStack otherFluid = ifluidCon.getFluid(0);
|
||||
if (!fluid.isEmpty() && !otherFluid.isEmpty() && !fluid.isFluidEqual(otherFluid))
|
||||
break Search;
|
||||
}
|
||||
}
|
||||
}
|
||||
amount += width * width;
|
||||
height++;
|
||||
}
|
||||
|
||||
if (simulate)
|
||||
return amount;
|
||||
|
||||
Object extraData = be.getExtraData();
|
||||
|
||||
for (int yOffset = 0; yOffset < height; yOffset++) {
|
||||
for (int xOffset = 0; xOffset < width; xOffset++) {
|
||||
for (int zOffset = 0; zOffset < width; zOffset++) {
|
||||
BlockPos pos = switch (axis) {
|
||||
case X -> origin.offset(yOffset, xOffset, zOffset);
|
||||
case Y -> origin.offset(xOffset, yOffset, zOffset);
|
||||
case Z -> origin.offset(xOffset, zOffset, yOffset);
|
||||
};
|
||||
T part = partAt(type, level, pos);
|
||||
if (part == null)
|
||||
continue;
|
||||
if (part == be)
|
||||
continue;
|
||||
|
||||
extraData = be.modifyExtraData(extraData);
|
||||
|
||||
if (part instanceof IMultiTileContainer.Fluid ifluidPart && ifluidPart.hasTank()) {
|
||||
IFluidTank tankAt = ifluidPart.getTank(0);
|
||||
FluidStack fluidAt = tankAt.getFluid();
|
||||
if (!fluidAt.isEmpty()) {
|
||||
// making this generic would be a rather large mess, unfortunately
|
||||
if (beTank != null && fluid.isEmpty()
|
||||
&& beTank instanceof CreativeFluidTankTileEntity.CreativeSmartFluidTank) {
|
||||
((CreativeFluidTankTileEntity.CreativeSmartFluidTank) beTank)
|
||||
.setContainedFluid(fluidAt);
|
||||
}
|
||||
if (be instanceof IMultiTileContainer.Fluid ifluidBE && ifluidBE.hasTank()
|
||||
&& beTank != null) {
|
||||
beTank.fill(fluidAt, IFluidHandler.FluidAction.EXECUTE);
|
||||
}
|
||||
}
|
||||
tankAt.drain(tankAt.getCapacity(), IFluidHandler.FluidAction.EXECUTE);
|
||||
}
|
||||
|
||||
splitMultiAndInvalidate(part, cache, false);
|
||||
part.setController(origin);
|
||||
part.preventConnectivityUpdate();
|
||||
cache.put(pos, be);
|
||||
part.setHeight(height);
|
||||
part.setWidth(width);
|
||||
part.notifyMultiUpdated();
|
||||
}
|
||||
}
|
||||
}
|
||||
be.setExtraData(extraData);
|
||||
be.notifyMultiUpdated();
|
||||
return amount;
|
||||
}
|
||||
|
||||
public static <T extends BlockEntity & IMultiTileContainer> void splitMulti(T be) {
|
||||
splitMultiAndInvalidate(be, null, false);
|
||||
}
|
||||
|
||||
// tryReconnect helps whenever only a few tanks have been removed
|
||||
private static <T extends BlockEntity & IMultiTileContainer> void splitMultiAndInvalidate(T be,
|
||||
@Nullable SearchCache<T> cache, boolean tryReconnect) {
|
||||
Level level = be.getLevel();
|
||||
if (level == null)
|
||||
return;
|
||||
|
||||
be = be.getControllerTE();
|
||||
if (be == null)
|
||||
return;
|
||||
|
||||
int height = be.getHeight();
|
||||
int width = be.getWidth();
|
||||
if (width == 1 && height == 1)
|
||||
return;
|
||||
|
||||
BlockPos origin = be.getBlockPos();
|
||||
List<T> frontier = new ArrayList<>();
|
||||
Direction.Axis axis = be.getMainConnectionAxis();
|
||||
|
||||
// fluid handling, if present
|
||||
FluidStack toDistribute = FluidStack.EMPTY;
|
||||
int maxCapacity = 0;
|
||||
if (be instanceof IMultiTileContainer.Fluid ifluidBE && ifluidBE.hasTank()) {
|
||||
toDistribute = ifluidBE.getFluid(0);
|
||||
maxCapacity = ifluidBE.getTankSize(0);
|
||||
if (!toDistribute.isEmpty() && !be.isRemoved())
|
||||
toDistribute.shrink(maxCapacity);
|
||||
ifluidBE.setTankSize(0, 1);
|
||||
}
|
||||
|
||||
for (int yOffset = 0; yOffset < height; yOffset++) {
|
||||
for (int xOffset = 0; xOffset < width; xOffset++) {
|
||||
for (int zOffset = 0; zOffset < width; zOffset++) {
|
||||
BlockPos pos = switch (axis) {
|
||||
case X -> origin.offset(yOffset, xOffset, zOffset);
|
||||
case Y -> origin.offset(xOffset, yOffset, zOffset);
|
||||
case Z -> origin.offset(xOffset, zOffset, yOffset);
|
||||
};
|
||||
T partAt = partAt(be.getType(), level, pos);
|
||||
if (partAt == null)
|
||||
continue;
|
||||
if (!partAt.getController()
|
||||
.equals(origin))
|
||||
continue;
|
||||
|
||||
T controllerBE = partAt.getControllerTE();
|
||||
partAt.setExtraData((controllerBE == null ? null : controllerBE.getExtraData()));
|
||||
partAt.removeController(true);
|
||||
|
||||
if (!toDistribute.isEmpty() && partAt != be) {
|
||||
FluidStack copy = toDistribute.copy();
|
||||
IFluidTank tank =
|
||||
(partAt instanceof IMultiTileContainer.Fluid ifluidPart ? ifluidPart.getTank(0) : null);
|
||||
// making this generic would be a rather large mess, unfortunately
|
||||
if (tank instanceof CreativeFluidTankTileEntity.CreativeSmartFluidTank creativeTank) {
|
||||
if (creativeTank.isEmpty())
|
||||
creativeTank.setContainedFluid(toDistribute);
|
||||
} else {
|
||||
int split = Math.min(maxCapacity, toDistribute.getAmount());
|
||||
copy.setAmount(split);
|
||||
toDistribute.shrink(split);
|
||||
if (tank != null)
|
||||
tank.fill(copy, IFluidHandler.FluidAction.EXECUTE);
|
||||
}
|
||||
}
|
||||
if (tryReconnect) {
|
||||
frontier.add(partAt);
|
||||
partAt.preventConnectivityUpdate();
|
||||
}
|
||||
if (cache != null) {
|
||||
cache.put(pos, partAt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (be instanceof IMultiTileContainer.Inventory iinv && iinv.hasInventory()) {
|
||||
be.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
|
||||
.invalidate();
|
||||
}
|
||||
if (be instanceof IMultiTileContainer.Fluid ifluid && ifluid.hasTank()) {
|
||||
be.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)
|
||||
.invalidate();
|
||||
}
|
||||
if (tryReconnect) {
|
||||
formMulti(be.getType(), level, cache == null ? new SearchCache<>() : cache, frontier);
|
||||
}
|
||||
}
|
||||
|
||||
private static <T extends BlockEntity & IMultiTileContainer> PriorityQueue<Pair<Integer, T>> makeCreationQueue() {
|
||||
return new PriorityQueue<>((one, two) -> two.getKey() - one.getKey());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static <T extends BlockEntity & IMultiTileContainer> T partAt(BlockEntityType<?> type, BlockGetter level,
|
||||
BlockPos pos) {
|
||||
BlockEntity be = level.getBlockEntity(pos);
|
||||
if (be != null && be.getType() == type)
|
||||
return checked(be);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T extends BlockEntity & IMultiTileContainer> boolean isConnected(BlockGetter level, BlockPos pos,
|
||||
BlockPos other) {
|
||||
T one = checked(level.getBlockEntity(pos));
|
||||
T two = checked(level.getBlockEntity(other));
|
||||
if (one == null || two == null)
|
||||
return false;
|
||||
return one.getController()
|
||||
.equals(two.getController());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T extends BlockEntity & IMultiTileContainer> T checked(BlockEntity be) {
|
||||
if (be instanceof IMultiTileContainer)
|
||||
return (T) be;
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class SearchCache<T extends BlockEntity & IMultiTileContainer> {
|
||||
Map<BlockPos, Optional<T>> controllerMap;
|
||||
|
||||
public SearchCache() {
|
||||
controllerMap = new HashMap<>();
|
||||
}
|
||||
|
||||
void put(BlockPos pos, T target) {
|
||||
controllerMap.put(pos, Optional.of(target));
|
||||
}
|
||||
|
||||
void putEmpty(BlockPos pos) {
|
||||
controllerMap.put(pos, Optional.empty());
|
||||
}
|
||||
|
||||
boolean hasVisited(BlockPos pos) {
|
||||
return controllerMap.containsKey(pos);
|
||||
}
|
||||
|
||||
Optional<T> getOrCache(BlockEntityType<?> type, BlockGetter level, BlockPos pos) {
|
||||
if (hasVisited(pos))
|
||||
return controllerMap.get(pos);
|
||||
|
||||
T partAt = partAt(type, level, pos);
|
||||
if (partAt == null) {
|
||||
putEmpty(pos);
|
||||
return Optional.empty();
|
||||
}
|
||||
T controller = checked(level.getBlockEntity(partAt.getController()));
|
||||
if (controller == null) {
|
||||
putEmpty(pos);
|
||||
return Optional.empty();
|
||||
}
|
||||
put(pos, controller);
|
||||
return Optional.of(controller);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,7 +12,8 @@ import net.minecraftforge.fml.ModList;
|
|||
*/
|
||||
public enum Mods {
|
||||
DYNAMICTREES,
|
||||
TCONSTRUCT;
|
||||
TCONSTRUCT,
|
||||
CURIOS;
|
||||
|
||||
/**
|
||||
* @return a boolean of whether the mod is loaded or not based on mod id
|
||||
|
|
43
src/main/java/com/simibubi/create/compat/curios/Curios.java
Normal file
43
src/main/java/com/simibubi/create/compat/curios/Curios.java
Normal file
|
@ -0,0 +1,43 @@
|
|||
package com.simibubi.create.compat.curios;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.content.contraptions.goggles.GogglesItem;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.fml.InterModComms;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import top.theillusivec4.curios.api.CuriosCapability;
|
||||
import top.theillusivec4.curios.api.SlotTypeMessage;
|
||||
import top.theillusivec4.curios.api.SlotTypePreset;
|
||||
import top.theillusivec4.curios.api.type.inventory.ICurioStacksHandler;
|
||||
|
||||
public class Curios {
|
||||
public static void init() {
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(Curios::onInterModEnqueue);
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(Curios::onClientSetup);
|
||||
|
||||
GogglesItem.addIsWearingPredicate(player -> {
|
||||
AtomicBoolean hasGoggles = new AtomicBoolean(false);
|
||||
player.getCapability(CuriosCapability.INVENTORY).ifPresent(handler -> {
|
||||
ICurioStacksHandler stacksHandler = handler.getCurios().get("head");
|
||||
if(stacksHandler != null) hasGoggles.set(stacksHandler.getStacks().getStackInSlot(0).getItem() == AllItems.GOGGLES.get());
|
||||
});
|
||||
return hasGoggles.get();
|
||||
});
|
||||
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> FMLJavaModLoadingContext.get().getModEventBus().addListener(CuriosRenderers::onLayerRegister));
|
||||
}
|
||||
|
||||
private static void onInterModEnqueue(final InterModEnqueueEvent event) {
|
||||
InterModComms.sendTo("curios", SlotTypeMessage.REGISTER_TYPE, () -> SlotTypePreset.HEAD.getMessageBuilder().build());
|
||||
}
|
||||
|
||||
private static void onClientSetup(final FMLClientSetupEvent event) {
|
||||
CuriosRenderers.register();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.simibubi.create.compat.curios;
|
||||
|
||||
import com.simibubi.create.AllItems;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.model.geom.builders.LayerDefinition;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.client.event.EntityRenderersEvent;
|
||||
import top.theillusivec4.curios.api.client.CuriosRendererRegistry;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class CuriosRenderers {
|
||||
public static void register() {
|
||||
CuriosRendererRegistry.register(AllItems.GOGGLES.get(), () -> new GogglesCurioRenderer(Minecraft.getInstance().getEntityModels().bakeLayer(GogglesCurioRenderer.LAYER)));
|
||||
}
|
||||
|
||||
public static void onLayerRegister(final EntityRenderersEvent.RegisterLayerDefinitions event) {
|
||||
event.registerLayerDefinition(GogglesCurioRenderer.LAYER, () -> LayerDefinition.create(GogglesCurioRenderer.mesh(), 1, 1));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package com.simibubi.create.compat.curios;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.math.Vector3f;
|
||||
import com.simibubi.create.Create;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.model.EntityModel;
|
||||
import net.minecraft.client.model.HumanoidModel;
|
||||
import net.minecraft.client.model.geom.ModelLayerLocation;
|
||||
import net.minecraft.client.model.geom.ModelPart;
|
||||
import net.minecraft.client.model.geom.PartPose;
|
||||
import net.minecraft.client.model.geom.builders.CubeDeformation;
|
||||
import net.minecraft.client.model.geom.builders.CubeListBuilder;
|
||||
import net.minecraft.client.model.geom.builders.MeshDefinition;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.block.model.ItemTransforms;
|
||||
import net.minecraft.client.renderer.entity.RenderLayerParent;
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import top.theillusivec4.curios.api.SlotContext;
|
||||
import top.theillusivec4.curios.api.client.ICurioRenderer;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class GogglesCurioRenderer implements ICurioRenderer {
|
||||
public static final ModelLayerLocation LAYER = new ModelLayerLocation(new ResourceLocation(Create.ID, "goggles"), "goggles");
|
||||
|
||||
private final HumanoidModel<LivingEntity> model;
|
||||
|
||||
public GogglesCurioRenderer(ModelPart part) {
|
||||
this.model = new HumanoidModel<>(part);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends LivingEntity, M extends EntityModel<T>> void render(ItemStack stack, SlotContext slotContext, PoseStack matrixStack, RenderLayerParent<T, M> renderLayerParent, MultiBufferSource renderTypeBuffer, int light, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch) {
|
||||
// Prepare values for transformation
|
||||
model.setupAnim(slotContext.entity(), limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch);
|
||||
model.prepareMobModel(slotContext.entity(), limbSwing, limbSwingAmount, partialTicks);
|
||||
ICurioRenderer.followHeadRotations(slotContext.entity(), model.head);
|
||||
|
||||
// Translate and rotate with our head
|
||||
matrixStack.pushPose();
|
||||
matrixStack.translate(model.head.x / 16.0, model.head.y / 16.0, model.head.z / 16.0);
|
||||
matrixStack.mulPose(Vector3f.YP.rotation(model.head.yRot));
|
||||
matrixStack.mulPose(Vector3f.XP.rotation(model.head.xRot));
|
||||
|
||||
// Translate and scale to our head
|
||||
matrixStack.translate(0, -0.25, 0);
|
||||
matrixStack.mulPose(Vector3f.ZP.rotationDegrees(180.0f));
|
||||
matrixStack.scale(0.625f, 0.625f, 0.625f);
|
||||
|
||||
if(!slotContext.entity().getItemBySlot(EquipmentSlot.HEAD).isEmpty()) {
|
||||
matrixStack.mulPose(Vector3f.ZP.rotationDegrees(180.0f));
|
||||
matrixStack.translate(0, -0.25, 0);
|
||||
}
|
||||
|
||||
// Render
|
||||
Minecraft.getInstance().getItemRenderer().renderStatic(stack, ItemTransforms.TransformType.HEAD, light, OverlayTexture.NO_OVERLAY, matrixStack, renderTypeBuffer, 0);
|
||||
matrixStack.popPose();
|
||||
}
|
||||
|
||||
public static MeshDefinition mesh() {
|
||||
CubeListBuilder builder = new CubeListBuilder();
|
||||
MeshDefinition mesh = HumanoidModel.createMesh(CubeDeformation.NONE, 0);
|
||||
mesh.getRoot().addOrReplaceChild("head", builder, PartPose.ZERO);
|
||||
return mesh;
|
||||
}
|
||||
}
|
|
@ -16,7 +16,7 @@ public class HalfShaftInstance extends SingleRotatingInstance {
|
|||
@Override
|
||||
protected Instancer<RotatingData> getModel() {
|
||||
Direction dir = getShaftDirection();
|
||||
return getRotatingMaterial().getModel(AllBlockPartials.SHAFT_HALF, blockState, dir);
|
||||
return getRotatingMaterial().getModel(AllBlockPartials.SHAFT_HALF, dir);
|
||||
}
|
||||
|
||||
protected Direction getShaftDirection() {
|
||||
|
|
|
@ -39,14 +39,14 @@ public class DrillActorInstance extends ActorInstance {
|
|||
else
|
||||
eulerY = facing.toYRot() + ((axis == Direction.Axis.X) ? 180 : 0);
|
||||
|
||||
drillHead = material.getModel(AllBlockPartials.DRILL_HEAD, state).createInstance();
|
||||
|
||||
drillHead.setPosition(context.localPos)
|
||||
.setBlockLight(localBlockLight())
|
||||
.setRotationOffset(0)
|
||||
.setRotationAxis(0, 0, 1)
|
||||
.setLocalRotation(new Quaternion(eulerX, eulerY, 0, true))
|
||||
.setSpeed(getSpeed(facing));
|
||||
drillHead = material.getModel(AllBlockPartials.DRILL_HEAD)
|
||||
.createInstance()
|
||||
.setPosition(context.localPos)
|
||||
.setBlockLight(localBlockLight())
|
||||
.setRotationOffset(0)
|
||||
.setRotationAxis(0, 0, 1)
|
||||
.setLocalRotation(new Quaternion(eulerX, eulerY, 0, true))
|
||||
.setSpeed(getSpeed(facing));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -21,6 +21,6 @@ public class DrillInstance extends SingleRotatingInstance {
|
|||
protected Instancer<RotatingData> getModel() {
|
||||
BlockState referenceState = blockEntity.getBlockState();
|
||||
Direction facing = referenceState.getValue(BlockStateProperties.FACING);
|
||||
return getRotatingMaterial().getModel(AllBlockPartials.DRILL_HEAD, referenceState, facing);
|
||||
return getRotatingMaterial().getModel(AllBlockPartials.DRILL_HEAD, facing);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.simibubi.create.content.contraptions.components.actors;
|
|||
import com.jozufozu.flywheel.api.Material;
|
||||
import com.jozufozu.flywheel.api.MaterialManager;
|
||||
import com.jozufozu.flywheel.core.Materials;
|
||||
import com.jozufozu.flywheel.core.Models;
|
||||
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
||||
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
|
||||
import com.simibubi.create.AllBlockPartials;
|
||||
|
@ -41,7 +42,8 @@ public class HarvesterActorInstance extends ActorInstance {
|
|||
|
||||
facing = state.getValue(BlockStateProperties.HORIZONTAL_FACING);
|
||||
|
||||
harvester = material.getModel(AllBlockPartials.HARVESTER_BLADE, state).createInstance();
|
||||
harvester = material.model(Models.partial(AllBlockPartials.HARVESTER_BLADE))
|
||||
.createInstance();
|
||||
|
||||
horizontalAngle = facing.toYRot() + ((facing.getAxis() == Direction.Axis.X) ? 180 : 0);
|
||||
|
||||
|
|
|
@ -33,11 +33,11 @@ public class PIInstance {
|
|||
this.lit = lit;
|
||||
middle = materialManager.defaultSolid()
|
||||
.material(Materials.TRANSFORMED)
|
||||
.getModel(PortableStorageInterfaceRenderer.getMiddleForState(blockState, lit), blockState)
|
||||
.getModel(PortableStorageInterfaceRenderer.getMiddleForState(blockState, lit))
|
||||
.createInstance();
|
||||
top = materialManager.defaultSolid()
|
||||
.material(Materials.TRANSFORMED)
|
||||
.getModel(PortableStorageInterfaceRenderer.getTopForState(blockState), blockState)
|
||||
.getModel(PortableStorageInterfaceRenderer.getTopForState(blockState))
|
||||
.createInstance();
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ public class PIInstance {
|
|||
this.lit = lit;
|
||||
materialManager.defaultSolid()
|
||||
.material(Materials.TRANSFORMED)
|
||||
.getModel(PortableStorageInterfaceRenderer.getMiddleForState(blockState, lit), blockState)
|
||||
.getModel(PortableStorageInterfaceRenderer.getMiddleForState(blockState, lit))
|
||||
.stealInstance(middle);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ public class MechanicalCrafterInstance extends SingleRotatingInstance {
|
|||
protected Instancer<RotatingData> getModel() {
|
||||
Direction facing = blockState.getValue(MechanicalCrafterBlock.HORIZONTAL_FACING);
|
||||
|
||||
return getRotatingMaterial().getModel(AllBlockPartials.SHAFTLESS_COGWHEEL, blockState, facing, rotateToFace(facing));
|
||||
return getRotatingMaterial().getModel(AllBlockPartials.SHAFTLESS_COGWHEEL, facing, rotateToFace(facing));
|
||||
}
|
||||
|
||||
private Supplier<PoseStack> rotateToFace(Direction facing) {
|
||||
|
|
|
@ -31,7 +31,7 @@ public class HandCrankInstance extends SingleRotatingInstance implements Dynamic
|
|||
|
||||
facing = blockState.getValue(BlockStateProperties.FACING);
|
||||
Direction opposite = facing.getOpposite();
|
||||
Instancer<ModelData> model = getTransformMaterial().getModel(renderedHandle, blockState, opposite);
|
||||
Instancer<ModelData> model = getTransformMaterial().getModel(renderedHandle, opposite);
|
||||
crank = model.createInstance();
|
||||
|
||||
rotateCrank();
|
||||
|
|
|
@ -61,8 +61,8 @@ public class DeployerActorInstance extends ActorInstance {
|
|||
xRot = facing == Direction.UP ? 270 : facing == Direction.DOWN ? 90 : 0;
|
||||
zRot = rotatePole ? 90 : 0;
|
||||
|
||||
pole = mat.getModel(AllBlockPartials.DEPLOYER_POLE, state).createInstance();
|
||||
hand = mat.getModel(handPose, state).createInstance();
|
||||
pole = mat.getModel(AllBlockPartials.DEPLOYER_POLE).createInstance();
|
||||
hand = mat.getModel(handPose).createInstance();
|
||||
|
||||
Direction.Axis axis = ((IRotate) state.getBlock()).getRotationAxis(state);
|
||||
shaft = materialManager.defaultSolid()
|
||||
|
|
|
@ -47,11 +47,11 @@ public class DeployerInstance extends ShaftInstance implements DynamicInstance,
|
|||
xRot = facing == Direction.UP ? 270 : facing == Direction.DOWN ? 90 : 0;
|
||||
zRot = rotatePole ? 90 : 0;
|
||||
|
||||
pole = getOrientedMaterial().getModel(AllBlockPartials.DEPLOYER_POLE, blockState).createInstance();
|
||||
pole = getOrientedMaterial().getModel(AllBlockPartials.DEPLOYER_POLE).createInstance();
|
||||
|
||||
currentHand = this.tile.getHandPose();
|
||||
|
||||
hand = getOrientedMaterial().getModel(currentHand, blockState).createInstance();
|
||||
hand = getOrientedMaterial().getModel(currentHand).createInstance();
|
||||
|
||||
progress = getProgress(AnimationTickHolder.getPartialTicks());
|
||||
updateRotation(pole, hand, yRot, xRot, zRot);
|
||||
|
@ -64,7 +64,7 @@ public class DeployerInstance extends ShaftInstance implements DynamicInstance,
|
|||
|
||||
if (currentHand != handPose) {
|
||||
currentHand = handPose;
|
||||
getOrientedMaterial().getModel(currentHand, blockState)
|
||||
getOrientedMaterial().getModel(currentHand)
|
||||
.stealInstance(hand);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,10 +25,10 @@ public class FanInstance extends KineticTileInstance<EncasedFanTileEntity> {
|
|||
direction = blockState.getValue(FACING);
|
||||
|
||||
opposite = direction.getOpposite();
|
||||
shaft = getRotatingMaterial().getModel(AllBlockPartials.SHAFT_HALF, blockState, opposite).createInstance();
|
||||
shaft = getRotatingMaterial().getModel(AllBlockPartials.SHAFT_HALF, opposite).createInstance();
|
||||
fan = modelManager.defaultCutout()
|
||||
.material(AllMaterialSpecs.ROTATING)
|
||||
.getModel(AllBlockPartials.ENCASED_FAN_INNER, blockState, opposite)
|
||||
.getModel(AllBlockPartials.ENCASED_FAN_INNER, opposite)
|
||||
.createInstance();
|
||||
|
||||
setup(shaft);
|
||||
|
|
|
@ -15,6 +15,6 @@ public class MillStoneCogInstance extends SingleRotatingInstance {
|
|||
|
||||
@Override
|
||||
protected Instancer<RotatingData> getModel() {
|
||||
return getRotatingMaterial().getModel(AllBlockPartials.MILLSTONE_COG, blockEntity.getBlockState());
|
||||
return getRotatingMaterial().getModel(AllBlockPartials.MILLSTONE_COG);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,13 +22,13 @@ public class MixerInstance extends EncasedCogInstance implements DynamicInstance
|
|||
super(dispatcher, tile, false);
|
||||
this.mixer = tile;
|
||||
|
||||
mixerHead = getRotatingMaterial().getModel(AllBlockPartials.MECHANICAL_MIXER_HEAD, blockState)
|
||||
mixerHead = getRotatingMaterial().getModel(AllBlockPartials.MECHANICAL_MIXER_HEAD)
|
||||
.createInstance();
|
||||
|
||||
mixerHead.setRotationAxis(Direction.Axis.Y);
|
||||
|
||||
mixerPole = getOrientedMaterial()
|
||||
.getModel(AllBlockPartials.MECHANICAL_MIXER_POLE, blockState)
|
||||
.getModel(AllBlockPartials.MECHANICAL_MIXER_POLE)
|
||||
.createInstance();
|
||||
|
||||
|
||||
|
@ -42,7 +42,7 @@ public class MixerInstance extends EncasedCogInstance implements DynamicInstance
|
|||
protected Instancer<RotatingData> getCogModel() {
|
||||
return materialManager.defaultSolid()
|
||||
.material(AllMaterialSpecs.ROTATING)
|
||||
.getModel(AllBlockPartials.SHAFTLESS_COGWHEEL, blockEntity.getBlockState());
|
||||
.getModel(AllBlockPartials.SHAFTLESS_COGWHEEL);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -22,7 +22,7 @@ public class PressInstance extends ShaftInstance implements DynamicInstance {
|
|||
|
||||
pressHead = dispatcher.defaultSolid()
|
||||
.material(Materials.ORIENTED)
|
||||
.getModel(AllBlockPartials.MECHANICAL_PRESS_HEAD, blockState)
|
||||
.getModel(AllBlockPartials.MECHANICAL_PRESS_HEAD)
|
||||
.createInstance();
|
||||
|
||||
Quaternion q = Vector3f.YP
|
||||
|
|
|
@ -25,7 +25,7 @@ public class SawInstance extends SingleRotatingInstance {
|
|||
.isHorizontal()) {
|
||||
BlockState referenceState = blockState.rotate(blockEntity.getLevel(), blockEntity.getBlockPos(), Rotation.CLOCKWISE_180);
|
||||
Direction facing = referenceState.getValue(BlockStateProperties.FACING);
|
||||
return getRotatingMaterial().getModel(AllBlockPartials.SHAFT_HALF, referenceState, facing);
|
||||
return getRotatingMaterial().getModel(AllBlockPartials.SHAFT_HALF, facing);
|
||||
} else {
|
||||
return getRotatingMaterial().getModel(shaft());
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import java.util.List;
|
|||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllTags.AllBlockTags;
|
||||
import com.simibubi.create.api.connectivity.ConnectivityHandler;
|
||||
import com.simibubi.create.content.contraptions.components.actors.AttachedActorBlock;
|
||||
import com.simibubi.create.content.contraptions.components.actors.HarvesterBlock;
|
||||
import com.simibubi.create.content.contraptions.components.actors.PloughBlock;
|
||||
|
@ -28,10 +29,8 @@ import com.simibubi.create.content.contraptions.components.structureMovement.pis
|
|||
import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyBlock;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyTileEntity;
|
||||
import com.simibubi.create.content.contraptions.fluids.tank.FluidTankBlock;
|
||||
import com.simibubi.create.content.contraptions.fluids.tank.FluidTankConnectivityHandler;
|
||||
import com.simibubi.create.content.logistics.block.redstone.RedstoneLinkBlock;
|
||||
import com.simibubi.create.content.logistics.block.vault.ItemVaultBlock;
|
||||
import com.simibubi.create.content.logistics.block.vault.ItemVaultConnectivityHandler;
|
||||
import com.simibubi.create.content.logistics.trains.IBogeyBlock;
|
||||
import com.simibubi.create.content.logistics.trains.ITrackBlock;
|
||||
import com.simibubi.create.content.logistics.trains.management.edgePoint.station.StationBlock;
|
||||
|
@ -338,9 +337,9 @@ public class BlockMovementChecks {
|
|||
return direction.getAxis() != state.getValue(SailBlock.FACING)
|
||||
.getAxis();
|
||||
if (state.getBlock() instanceof FluidTankBlock)
|
||||
return FluidTankConnectivityHandler.isConnected(world, pos, pos.relative(direction));
|
||||
return ConnectivityHandler.isConnected(world, pos, pos.relative(direction));
|
||||
if (state.getBlock() instanceof ItemVaultBlock)
|
||||
return ItemVaultConnectivityHandler.isConnected(world, pos, pos.relative(direction));
|
||||
return ConnectivityHandler.isConnected(world, pos, pos.relative(direction));
|
||||
if (AllBlocks.STICKER.has(state) && state.getValue(StickerBlock.EXTENDED)) {
|
||||
return direction == state.getValue(StickerBlock.FACING)
|
||||
&& !isNotSupportive(world.getBlockState(pos.relative(direction)), direction.getOpposite());
|
||||
|
|
|
@ -35,7 +35,7 @@ public class BearingInstance<B extends KineticTileEntity & IBearingTileEntity> e
|
|||
PartialModel top =
|
||||
bearing.isWoodenTop() ? AllBlockPartials.BEARING_TOP_WOODEN : AllBlockPartials.BEARING_TOP;
|
||||
|
||||
topInstance = getOrientedMaterial().getModel(top, blockState).createInstance();
|
||||
topInstance = getOrientedMaterial().getModel(top).createInstance();
|
||||
|
||||
topInstance.setPosition(getInstancePosition()).setRotation(blockOrientation);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ public class StabilizedBearingInstance extends ActorInstance {
|
|||
|
||||
topInstance = materialManager.defaultSolid()
|
||||
.material(Materials.ORIENTED)
|
||||
.getModel(AllBlockPartials.BEARING_TOP, blockState)
|
||||
.getModel(AllBlockPartials.BEARING_TOP)
|
||||
.createInstance();
|
||||
|
||||
int blockLight = localBlockLight();
|
||||
|
@ -48,7 +48,7 @@ public class StabilizedBearingInstance extends ActorInstance {
|
|||
|
||||
shaft = materialManager.defaultSolid()
|
||||
.material(AllMaterialSpecs.ROTATING)
|
||||
.getModel(AllBlockPartials.SHAFT_HALF, blockState, blockState.getValue(BlockStateProperties.FACING).getOpposite())
|
||||
.getModel(AllBlockPartials.SHAFT_HALF, blockState.getValue(BlockStateProperties.FACING).getOpposite())
|
||||
.createInstance();
|
||||
|
||||
// not rotating so no need to set speed, axis, etc.
|
||||
|
|
|
@ -17,20 +17,20 @@ public class StickerInstance extends BlockEntityInstance<StickerTileEntity> impl
|
|||
float lastOffset = Float.NaN;
|
||||
final Direction facing;
|
||||
final boolean fakeWorld;
|
||||
final int offset;
|
||||
final int extended;
|
||||
|
||||
private final ModelData head;
|
||||
|
||||
public StickerInstance(MaterialManager modelManager, StickerTileEntity tile) {
|
||||
super(modelManager, tile);
|
||||
|
||||
head = getTransformMaterial().getModel(AllBlockPartials.STICKER_HEAD, blockState).createInstance();
|
||||
head = getTransformMaterial().getModel(AllBlockPartials.STICKER_HEAD).createInstance();
|
||||
|
||||
fakeWorld = tile.getLevel() != Minecraft.getInstance().level;
|
||||
facing = blockState.getValue(StickerBlock.FACING);
|
||||
offset = blockState.getValue(StickerBlock.EXTENDED) ? 1 : 0;
|
||||
extended = blockState.getValue(StickerBlock.EXTENDED) ? 1 : 0;
|
||||
|
||||
animateHead(offset);
|
||||
animateHead(extended);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -38,7 +38,7 @@ public class StickerInstance extends BlockEntityInstance<StickerTileEntity> impl
|
|||
float offset = blockEntity.piston.getValue(AnimationTickHolder.getPartialTicks());
|
||||
|
||||
if (fakeWorld)
|
||||
offset = this.offset;
|
||||
offset = this.extended;
|
||||
|
||||
if (Mth.equal(offset, lastOffset))
|
||||
return;
|
||||
|
|
|
@ -30,7 +30,7 @@ public class GantryCarriageInstance extends ShaftInstance implements DynamicInst
|
|||
super(dispatcher, tile);
|
||||
|
||||
gantryCogs = getTransformMaterial()
|
||||
.getModel(AllBlockPartials.GANTRY_COGS, blockState)
|
||||
.getModel(AllBlockPartials.GANTRY_COGS)
|
||||
.createInstance();
|
||||
|
||||
facing = blockState.getValue(GantryCarriageBlock.FACING);
|
||||
|
|
|
@ -162,7 +162,7 @@ public class CartAssemblerTileEntity extends SmartTileEntity implements IDisplay
|
|||
OrientedContraptionEntity entity = OrientedContraptionEntity.create(world, contraption, initialOrientation);
|
||||
if (couplingFound)
|
||||
entity.setCouplingId(cart.getUUID());
|
||||
entity.setPos(pos.getX(), pos.getY(), pos.getZ());
|
||||
entity.setPos(pos.getX() + .5, pos.getY(), pos.getZ() + .5);
|
||||
world.addFreshEntity(entity);
|
||||
entity.startRiding(cart);
|
||||
|
||||
|
|
|
@ -15,27 +15,27 @@ public class HosePulleyInstance extends AbstractPulleyInstance {
|
|||
}
|
||||
|
||||
protected Instancer<OrientedData> getRopeModel() {
|
||||
return getOrientedMaterial().getModel(AllBlockPartials.HOSE, blockState);
|
||||
return getOrientedMaterial().getModel(AllBlockPartials.HOSE);
|
||||
}
|
||||
|
||||
protected Instancer<OrientedData> getMagnetModel() {
|
||||
return materialManager.defaultCutout()
|
||||
.material(Materials.ORIENTED)
|
||||
.getModel(AllBlockPartials.HOSE_MAGNET, blockState);
|
||||
.getModel(AllBlockPartials.HOSE_MAGNET);
|
||||
}
|
||||
|
||||
protected Instancer<OrientedData> getHalfMagnetModel() {
|
||||
return materialManager.defaultCutout()
|
||||
.material(Materials.ORIENTED)
|
||||
.getModel(AllBlockPartials.HOSE_HALF_MAGNET, blockState);
|
||||
.getModel(AllBlockPartials.HOSE_HALF_MAGNET);
|
||||
}
|
||||
|
||||
protected Instancer<OrientedData> getCoilModel() {
|
||||
return getOrientedMaterial().getModel(AllBlockPartials.HOSE_COIL, blockState, rotatingAbout);
|
||||
return getOrientedMaterial().getModel(AllBlockPartials.HOSE_COIL, rotatingAbout);
|
||||
}
|
||||
|
||||
protected Instancer<OrientedData> getHalfRopeModel() {
|
||||
return getOrientedMaterial().getModel(AllBlockPartials.HOSE_HALF, blockState);
|
||||
return getOrientedMaterial().getModel(AllBlockPartials.HOSE_HALF);
|
||||
}
|
||||
|
||||
protected float getOffset() {
|
||||
|
|
|
@ -22,15 +22,15 @@ public class RopePulleyInstance extends AbstractPulleyInstance {
|
|||
}
|
||||
|
||||
protected Instancer<OrientedData> getHalfMagnetModel() {
|
||||
return getOrientedMaterial().getModel(AllBlockPartials.ROPE_HALF_MAGNET, blockState);
|
||||
return getOrientedMaterial().getModel(AllBlockPartials.ROPE_HALF_MAGNET);
|
||||
}
|
||||
|
||||
protected Instancer<OrientedData> getCoilModel() {
|
||||
return getOrientedMaterial().getModel(AllBlockPartials.ROPE_COIL, blockState, rotatingAbout);
|
||||
return getOrientedMaterial().getModel(AllBlockPartials.ROPE_COIL, rotatingAbout);
|
||||
}
|
||||
|
||||
protected Instancer<OrientedData> getHalfRopeModel() {
|
||||
return getOrientedMaterial().getModel(AllBlockPartials.ROPE_HALF, blockState);
|
||||
return getOrientedMaterial().getModel(AllBlockPartials.ROPE_HALF);
|
||||
}
|
||||
|
||||
protected float getOffset() {
|
||||
|
|
|
@ -4,7 +4,7 @@ import static org.lwjgl.opengl.GL11.glBindTexture;
|
|||
import static org.lwjgl.opengl.GL12.GL_TEXTURE_3D;
|
||||
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.backend.RenderLayer;
|
||||
import com.jozufozu.flywheel.api.RenderLayer;
|
||||
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
|
||||
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
|
||||
import com.jozufozu.flywheel.config.BackendType;
|
||||
|
|
|
@ -32,7 +32,7 @@ public class PumpCogInstance extends SingleRotatingInstance implements DynamicIn
|
|||
|
||||
materialManager.defaultSolid()
|
||||
.material(Materials.TRANSFORMED)
|
||||
.getModel(AllBlockPartials.MECHANICAL_PUMP_ARROW, blockState)
|
||||
.getModel(AllBlockPartials.MECHANICAL_PUMP_ARROW)
|
||||
.createInstances(arrows);
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ public class PumpCogInstance extends SingleRotatingInstance implements DynamicIn
|
|||
protected Instancer<RotatingData> getModel() {
|
||||
BlockState referenceState = blockEntity.getBlockState();
|
||||
Direction facing = referenceState.getValue(BlockStateProperties.FACING);
|
||||
return getRotatingMaterial().getModel(AllBlockPartials.MECHANICAL_PUMP_COG, referenceState, facing);
|
||||
return getRotatingMaterial().getModel(AllBlockPartials.MECHANICAL_PUMP_COG, facing);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -30,6 +30,8 @@ import net.minecraftforge.fluids.FluidStack;
|
|||
|
||||
public class FluidDrainingBehaviour extends FluidManipulationBehaviour {
|
||||
|
||||
public static final BehaviourType<FluidDrainingBehaviour> TYPE = new BehaviourType<>();
|
||||
|
||||
Fluid fluid;
|
||||
|
||||
// Execution
|
||||
|
@ -322,8 +324,6 @@ public class FluidDrainingBehaviour extends FluidManipulationBehaviour {
|
|||
tileEntity.sendData();
|
||||
}
|
||||
|
||||
public static BehaviourType<FluidDrainingBehaviour> TYPE = new BehaviourType<>();
|
||||
|
||||
@Override
|
||||
public BehaviourType<?> getType() {
|
||||
return TYPE;
|
||||
|
|
|
@ -41,6 +41,8 @@ import net.minecraft.world.ticks.LevelTicks;
|
|||
|
||||
public class FluidFillingBehaviour extends FluidManipulationBehaviour {
|
||||
|
||||
public static final BehaviourType<FluidFillingBehaviour> TYPE = new BehaviourType<>();
|
||||
|
||||
PriorityQueue<BlockPosEntry> queue;
|
||||
|
||||
List<BlockPosEntry> infinityCheckFrontier;
|
||||
|
@ -72,7 +74,7 @@ public class FluidFillingBehaviour extends FluidManipulationBehaviour {
|
|||
(p, d) -> infinityCheckFrontier.add(new BlockPosEntry(p, d)), true);
|
||||
int maxBlocks = maxBlocks();
|
||||
|
||||
if (infinityCheckVisited.size() > maxBlocks && maxBlocks != -1) {
|
||||
if (infinityCheckVisited.size() > maxBlocks && maxBlocks != -1 && !fillInfinite()) {
|
||||
if (!infinite) {
|
||||
reset();
|
||||
infinite = true;
|
||||
|
@ -163,9 +165,11 @@ public class FluidFillingBehaviour extends FluidManipulationBehaviour {
|
|||
|
||||
if (visited.size() >= maxBlocks && maxBlocks != -1) {
|
||||
infinite = true;
|
||||
visited.clear();
|
||||
queue.clear();
|
||||
return false;
|
||||
if (!fillInfinite()) {
|
||||
visited.clear();
|
||||
queue.clear();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
SpaceType spaceType = getAtPos(world, currentPos, fluid);
|
||||
|
@ -298,8 +302,6 @@ public class FluidFillingBehaviour extends FluidManipulationBehaviour {
|
|||
infinityCheckVisited.clear();
|
||||
}
|
||||
|
||||
public static BehaviourType<FluidFillingBehaviour> TYPE = new BehaviourType<>();
|
||||
|
||||
@Override
|
||||
public BehaviourType<?> getType() {
|
||||
return TYPE;
|
||||
|
|
|
@ -76,6 +76,7 @@ public class ItemDrainTileEntity extends SmartTileEntity implements IHaveGoggleI
|
|||
return returned;
|
||||
|
||||
transportedStack = transportedStack.copy();
|
||||
transportedStack.stack = inserted.copy();
|
||||
transportedStack.beltPosition = side.getAxis()
|
||||
.isVertical() ? .5f : 0;
|
||||
transportedStack.prevSideOffset = transportedStack.sideOffset;
|
||||
|
@ -277,7 +278,7 @@ public class ItemDrainTileEntity extends SmartTileEntity implements IHaveGoggleI
|
|||
heldItem = TransportedItemStack.read(compound.getCompound("HeldItem"));
|
||||
super.read(compound, clientPacket);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
|
||||
if (side != null && side.getAxis()
|
||||
|
|
|
@ -40,7 +40,7 @@ public class FluidValveInstance extends ShaftInstance implements DynamicInstance
|
|||
|
||||
pointer = materialManager.defaultSolid()
|
||||
.material(Materials.TRANSFORMED)
|
||||
.getModel(AllBlockPartials.FLUID_VALVE_POINTER, blockState).createInstance();
|
||||
.getModel(AllBlockPartials.FLUID_VALVE_POINTER).createInstance();
|
||||
|
||||
transformPointer();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.content.contraptions.fluids.tank;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.api.connectivity.ConnectivityHandler;
|
||||
import com.simibubi.create.content.contraptions.fluids.actors.GenericItemFilling;
|
||||
import com.simibubi.create.content.contraptions.fluids.tank.CreativeFluidTankTileEntity.CreativeSmartFluidTank;
|
||||
import com.simibubi.create.content.contraptions.processing.EmptyingByBasin;
|
||||
|
@ -95,7 +96,7 @@ public class FluidTankBlock extends Block implements IWrenchable, ITE<FluidTankT
|
|||
|
||||
@Override
|
||||
public int getLightEmission(BlockState state, BlockGetter world, BlockPos pos) {
|
||||
FluidTankTileEntity tankAt = FluidTankConnectivityHandler.anyTankAt(world, pos);
|
||||
FluidTankTileEntity tankAt = ConnectivityHandler.partAt(getTileEntityType(), world, pos);
|
||||
if (tankAt == null)
|
||||
return 0;
|
||||
FluidTankTileEntity controllerTE = tankAt.getControllerTE();
|
||||
|
@ -130,7 +131,7 @@ public class FluidTankBlock extends Block implements IWrenchable, ITE<FluidTankT
|
|||
return InteractionResult.PASS;
|
||||
|
||||
FluidExchange exchange = null;
|
||||
FluidTankTileEntity te = FluidTankConnectivityHandler.anyTankAt(world, pos);
|
||||
FluidTankTileEntity te = ConnectivityHandler.partAt(getTileEntityType(), world, pos);
|
||||
if (te == null)
|
||||
return InteractionResult.FAIL;
|
||||
|
||||
|
@ -240,7 +241,7 @@ public class FluidTankBlock extends Block implements IWrenchable, ITE<FluidTankT
|
|||
return;
|
||||
FluidTankTileEntity tankTE = (FluidTankTileEntity) te;
|
||||
world.removeBlockEntity(pos);
|
||||
FluidTankConnectivityHandler.splitTank(tankTE);
|
||||
ConnectivityHandler.splitMulti(tankTE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.simibubi.create.content.contraptions.fluids.tank;
|
||||
|
||||
import com.simibubi.create.api.connectivity.ConnectivityHandler;
|
||||
import com.simibubi.create.foundation.block.connected.CTSpriteShiftEntry;
|
||||
import com.simibubi.create.foundation.block.connected.HorizontalCTBehaviour;
|
||||
|
||||
|
@ -21,6 +22,6 @@ public class FluidTankCTBehaviour extends HorizontalCTBehaviour {
|
|||
@Override
|
||||
public boolean connectsTo(BlockState state, BlockState other, BlockAndTintGetter reader, BlockPos pos, BlockPos otherPos,
|
||||
Direction face) {
|
||||
return state.getBlock() == other.getBlock() && FluidTankConnectivityHandler.isConnected(reader, pos, otherPos);
|
||||
return state.getBlock() == other.getBlock() && ConnectivityHandler.isConnected(reader, pos, otherPos); //FluidTankConnectivityHandler.isConnected(reader, pos, otherPos);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,376 +0,0 @@
|
|||
package com.simibubi.create.content.contraptions.fluids.tank;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.simibubi.create.content.contraptions.fluids.tank.CreativeFluidTankTileEntity.CreativeSmartFluidTank;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Direction.Axis;
|
||||
import net.minecraft.core.Direction.AxisDirection;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
|
||||
import net.minecraftforge.fluids.capability.templates.FluidTank;
|
||||
|
||||
public class FluidTankConnectivityHandler {
|
||||
|
||||
public static void formTanks(FluidTankTileEntity te) {
|
||||
TankSearchCache cache = new TankSearchCache();
|
||||
List<FluidTankTileEntity> frontier = new ArrayList<>();
|
||||
frontier.add(te);
|
||||
formTanks(te.getType(), te.getLevel(), cache, frontier);
|
||||
}
|
||||
|
||||
private static void formTanks(BlockEntityType<?> type, BlockGetter world, TankSearchCache cache,
|
||||
List<FluidTankTileEntity> frontier) {
|
||||
PriorityQueue<Pair<Integer, FluidTankTileEntity>> creationQueue = makeCreationQueue();
|
||||
Set<BlockPos> visited = new HashSet<>();
|
||||
|
||||
int minX = Integer.MAX_VALUE;
|
||||
int minZ = Integer.MAX_VALUE;
|
||||
for (FluidTankTileEntity fluidTankTileEntity : frontier) {
|
||||
BlockPos pos = fluidTankTileEntity.getBlockPos();
|
||||
minX = Math.min(pos.getX(), minX);
|
||||
minZ = Math.min(pos.getZ(), minZ);
|
||||
}
|
||||
minX -= FluidTankTileEntity.getMaxSize();
|
||||
minZ -= FluidTankTileEntity.getMaxSize();
|
||||
|
||||
while (!frontier.isEmpty()) {
|
||||
FluidTankTileEntity tank = frontier.remove(0);
|
||||
BlockPos tankPos = tank.getBlockPos();
|
||||
if (visited.contains(tankPos))
|
||||
continue;
|
||||
|
||||
visited.add(tankPos);
|
||||
|
||||
int amount = tryToFormNewTank(tank, cache, true);
|
||||
if (amount > 1)
|
||||
creationQueue.add(Pair.of(amount, tank));
|
||||
|
||||
for (Axis axis : Iterate.axes) {
|
||||
Direction d = Direction.get(AxisDirection.NEGATIVE, axis);
|
||||
BlockPos next = tankPos.relative(d);
|
||||
|
||||
if (next.getX() <= minX || next.getZ() <= minZ)
|
||||
continue;
|
||||
if (visited.contains(next))
|
||||
continue;
|
||||
FluidTankTileEntity nextTank = tankAt(type, world, next);
|
||||
if (nextTank == null)
|
||||
continue;
|
||||
if (nextTank.isRemoved())
|
||||
continue;
|
||||
frontier.add(nextTank);
|
||||
}
|
||||
}
|
||||
|
||||
visited.clear();
|
||||
|
||||
while (!creationQueue.isEmpty()) {
|
||||
Pair<Integer, FluidTankTileEntity> next = creationQueue.poll();
|
||||
FluidTankTileEntity toCreate = next.getValue();
|
||||
if (visited.contains(toCreate.getBlockPos()))
|
||||
continue;
|
||||
visited.add(toCreate.getBlockPos());
|
||||
tryToFormNewTank(toCreate, cache, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void splitTank(FluidTankTileEntity te) {
|
||||
splitTankAndInvalidate(te, null, false);
|
||||
}
|
||||
|
||||
private static int tryToFormNewTank(FluidTankTileEntity te, TankSearchCache cache, boolean simulate) {
|
||||
int bestWidth = 1;
|
||||
int bestAmount = -1;
|
||||
|
||||
if (!te.isController())
|
||||
return 0;
|
||||
|
||||
for (int w = 1; w <= FluidTankTileEntity.getMaxSize(); w++) {
|
||||
int amount = tryToFormNewTankOfWidth(te, w, cache, true);
|
||||
if (amount < bestAmount)
|
||||
continue;
|
||||
bestWidth = w;
|
||||
bestAmount = amount;
|
||||
}
|
||||
|
||||
if (!simulate) {
|
||||
if (te.width == bestWidth && te.width * te.width * te.height == bestAmount)
|
||||
return bestAmount;
|
||||
|
||||
splitTankAndInvalidate(te, cache, false);
|
||||
te.applyFluidTankSize(bestAmount);
|
||||
tryToFormNewTankOfWidth(te, bestWidth, cache, simulate);
|
||||
te.updateConnectivity = false;
|
||||
te.width = bestWidth;
|
||||
te.height = bestAmount / bestWidth / bestWidth;
|
||||
|
||||
BlockState state = te.getBlockState();
|
||||
if (FluidTankBlock.isTank(state)) {
|
||||
state = state.setValue(FluidTankBlock.BOTTOM, true);
|
||||
state = state.setValue(FluidTankBlock.TOP, te.height == 1);
|
||||
te.getLevel()
|
||||
.setBlock(te.getBlockPos(), state, 22);
|
||||
}
|
||||
|
||||
te.setWindows(te.window);
|
||||
te.onFluidStackChanged(te.tankInventory.getFluid());
|
||||
te.updateBoilerState();
|
||||
te.setChanged();
|
||||
}
|
||||
|
||||
return bestAmount;
|
||||
}
|
||||
|
||||
private static int tryToFormNewTankOfWidth(FluidTankTileEntity te, int width, TankSearchCache cache,
|
||||
boolean simulate) {
|
||||
int amount = 0;
|
||||
int height = 0;
|
||||
BlockEntityType<?> type = te.getType();
|
||||
Level world = te.getLevel();
|
||||
BlockPos origin = te.getBlockPos();
|
||||
FluidTank teTank = te.tankInventory;
|
||||
FluidStack fluid = te.tankInventory.getFluidInTank(0);
|
||||
|
||||
Search:
|
||||
|
||||
for (int yOffset = 0; yOffset < FluidTankTileEntity.getMaxHeight(); yOffset++) {
|
||||
for (int xOffset = 0; xOffset < width; xOffset++) {
|
||||
for (int zOffset = 0; zOffset < width; zOffset++) {
|
||||
|
||||
BlockPos pos = origin.offset(xOffset, yOffset, zOffset);
|
||||
Optional<FluidTankTileEntity> tank = cache.getOrCache(type, world, pos);
|
||||
if (!tank.isPresent())
|
||||
break Search;
|
||||
|
||||
FluidTankTileEntity controller = tank.get();
|
||||
int otherWidth = controller.width;
|
||||
if (otherWidth > width)
|
||||
break Search;
|
||||
|
||||
BlockPos controllerPos = controller.getBlockPos();
|
||||
if (!controllerPos.equals(origin)) {
|
||||
if (controllerPos.getX() < origin.getX())
|
||||
break Search;
|
||||
if (controllerPos.getZ() < origin.getZ())
|
||||
break Search;
|
||||
if (controllerPos.getX() + otherWidth > origin.getX() + width)
|
||||
break Search;
|
||||
if (controllerPos.getZ() + otherWidth > origin.getZ() + width)
|
||||
break Search;
|
||||
}
|
||||
|
||||
FluidStack otherFluid = controller.getTankInventory()
|
||||
.getFluid();
|
||||
if (!fluid.isEmpty() && !otherFluid.isEmpty() && !fluid.isFluidEqual(otherFluid))
|
||||
break Search;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
amount += width * width;
|
||||
height++;
|
||||
}
|
||||
|
||||
if (simulate)
|
||||
return amount;
|
||||
|
||||
boolean opaque = false;
|
||||
|
||||
for (int yOffset = 0; yOffset < height; yOffset++) {
|
||||
for (int xOffset = 0; xOffset < width; xOffset++) {
|
||||
for (int zOffset = 0; zOffset < width; zOffset++) {
|
||||
BlockPos pos = origin.offset(xOffset, yOffset, zOffset);
|
||||
FluidTankTileEntity tank = tankAt(type, world, pos);
|
||||
if (tank == te)
|
||||
continue;
|
||||
|
||||
opaque |= !tank.window;
|
||||
FluidTank tankTank = tank.tankInventory;
|
||||
FluidStack fluidInTank = tankTank.getFluid();
|
||||
if (!fluidInTank.isEmpty()) {
|
||||
if (teTank.isEmpty() && teTank instanceof CreativeSmartFluidTank)
|
||||
((CreativeSmartFluidTank) teTank).setContainedFluid(fluidInTank);
|
||||
teTank.fill(fluidInTank, FluidAction.EXECUTE);
|
||||
}
|
||||
tankTank.setFluid(FluidStack.EMPTY);
|
||||
|
||||
splitTankAndInvalidate(tank, cache, false);
|
||||
tank.setController(origin);
|
||||
tank.updateConnectivity = false;
|
||||
cache.put(pos, te);
|
||||
|
||||
BlockState state = world.getBlockState(pos);
|
||||
if (!FluidTankBlock.isTank(state))
|
||||
continue;
|
||||
state = state.setValue(FluidTankBlock.BOTTOM, yOffset == 0);
|
||||
state = state.setValue(FluidTankBlock.TOP, yOffset == height - 1);
|
||||
world.setBlock(pos, state, 22);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
te.setWindows(!opaque);
|
||||
return amount;
|
||||
}
|
||||
|
||||
private static void splitTankAndInvalidate(FluidTankTileEntity te, @Nullable TankSearchCache cache,
|
||||
boolean tryReconnect) {
|
||||
// tryReconnect helps whenever only few tanks have been removed
|
||||
|
||||
te = te.getControllerTE();
|
||||
if (te == null)
|
||||
return;
|
||||
|
||||
int height = te.height;
|
||||
int width = te.width;
|
||||
if (width == 1 && height == 1)
|
||||
return;
|
||||
|
||||
Level world = te.getLevel();
|
||||
BlockPos origin = te.getBlockPos();
|
||||
List<FluidTankTileEntity> frontier = new ArrayList<>();
|
||||
FluidStack toDistribute = te.tankInventory.getFluid()
|
||||
.copy();
|
||||
int maxCapacity = FluidTankTileEntity.getCapacityMultiplier();
|
||||
if (!toDistribute.isEmpty() && !te.isRemoved())
|
||||
toDistribute.shrink(maxCapacity);
|
||||
te.applyFluidTankSize(1);
|
||||
|
||||
for (int yOffset = 0; yOffset < height; yOffset++) {
|
||||
for (int xOffset = 0; xOffset < width; xOffset++) {
|
||||
for (int zOffset = 0; zOffset < width; zOffset++) {
|
||||
|
||||
BlockPos pos = origin.offset(xOffset, yOffset, zOffset);
|
||||
FluidTankTileEntity tankAt = tankAt(te.getType(), world, pos);
|
||||
if (tankAt == null)
|
||||
continue;
|
||||
if (!tankAt.getController()
|
||||
.equals(origin))
|
||||
continue;
|
||||
FluidTankTileEntity controllerTE = tankAt.getControllerTE();
|
||||
tankAt.window = controllerTE == null || controllerTE.window;
|
||||
tankAt.removeController(true);
|
||||
|
||||
if (!toDistribute.isEmpty() && tankAt != te) {
|
||||
FluidStack copy = toDistribute.copy();
|
||||
FluidTank tankInventory = tankAt.tankInventory;
|
||||
if (tankInventory.isEmpty() && tankInventory instanceof CreativeSmartFluidTank)
|
||||
((CreativeSmartFluidTank) tankInventory).setContainedFluid(toDistribute);
|
||||
else {
|
||||
int split = Math.min(maxCapacity, toDistribute.getAmount());
|
||||
copy.setAmount(split);
|
||||
toDistribute.shrink(split);
|
||||
tankInventory.fill(copy, FluidAction.EXECUTE);
|
||||
}
|
||||
}
|
||||
|
||||
if (tryReconnect) {
|
||||
frontier.add(tankAt);
|
||||
tankAt.updateConnectivity = false;
|
||||
}
|
||||
if (cache != null)
|
||||
cache.put(pos, tankAt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
te.fluidCapability.invalidate();
|
||||
if (tryReconnect)
|
||||
formTanks(te.getType(), world, cache == null ? new TankSearchCache() : cache, frontier);
|
||||
}
|
||||
|
||||
private static PriorityQueue<Pair<Integer, FluidTankTileEntity>> makeCreationQueue() {
|
||||
return new PriorityQueue<>(new Comparator<Pair<Integer, FluidTankTileEntity>>() {
|
||||
@Override
|
||||
public int compare(Pair<Integer, FluidTankTileEntity> o1, Pair<Integer, FluidTankTileEntity> o2) {
|
||||
return o2.getKey() - o1.getKey();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static FluidTankTileEntity tankAt(BlockEntityType<?> type, BlockGetter world, BlockPos pos) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
if (te instanceof FluidTankTileEntity && te.getType() == type)
|
||||
return (FluidTankTileEntity) te;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static FluidTankTileEntity anyTankAt(BlockGetter world, BlockPos pos) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
if (te instanceof FluidTankTileEntity)
|
||||
return (FluidTankTileEntity) te;
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class TankSearchCache {
|
||||
Map<BlockPos, Optional<FluidTankTileEntity>> controllerMap;
|
||||
|
||||
public TankSearchCache() {
|
||||
controllerMap = new HashMap<>();
|
||||
}
|
||||
|
||||
void put(BlockPos pos, FluidTankTileEntity target) {
|
||||
controllerMap.put(pos, Optional.of(target));
|
||||
}
|
||||
|
||||
void putEmpty(BlockPos pos) {
|
||||
controllerMap.put(pos, Optional.empty());
|
||||
}
|
||||
|
||||
boolean hasVisited(BlockPos pos) {
|
||||
return controllerMap.containsKey(pos);
|
||||
}
|
||||
|
||||
Optional<FluidTankTileEntity> getOrCache(BlockEntityType<?> type, BlockGetter world, BlockPos pos) {
|
||||
if (hasVisited(pos))
|
||||
return controllerMap.get(pos);
|
||||
FluidTankTileEntity tankAt = tankAt(type, world, pos);
|
||||
if (tankAt == null) {
|
||||
putEmpty(pos);
|
||||
return Optional.empty();
|
||||
}
|
||||
FluidTankTileEntity controller = tankAt.getControllerTE();
|
||||
if (controller == null) {
|
||||
putEmpty(pos);
|
||||
return Optional.empty();
|
||||
}
|
||||
put(pos, controller);
|
||||
return Optional.of(controller);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static boolean isConnected(BlockGetter world, BlockPos tankPos, BlockPos otherTankPos) {
|
||||
BlockEntity te1 = world.getBlockEntity(tankPos);
|
||||
BlockEntity te2 = world.getBlockEntity(otherTankPos);
|
||||
if (!(te1 instanceof FluidTankTileEntity) || !(te2 instanceof FluidTankTileEntity))
|
||||
return false;
|
||||
return ((FluidTankTileEntity) te1).getController()
|
||||
.equals(((FluidTankTileEntity) te2).getController());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,9 @@
|
|||
package com.simibubi.create.content.contraptions.fluids.tank;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.api.connectivity.ConnectivityHandler;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
@ -71,7 +75,10 @@ public class FluidTankItem extends BlockItem {
|
|||
|
||||
if (!FluidTankBlock.isTank(placedOnState))
|
||||
return;
|
||||
FluidTankTileEntity tankAt = FluidTankConnectivityHandler.anyTankAt(world, placedOnPos);
|
||||
boolean creative = getBlock().equals(AllBlocks.CREATIVE_FLUID_TANK.get());
|
||||
FluidTankTileEntity tankAt = ConnectivityHandler.partAt(
|
||||
creative ? AllTileEntities.CREATIVE_FLUID_TANK.get() : AllTileEntities.FLUID_TANK.get(), world, placedOnPos
|
||||
);
|
||||
if (tankAt == null)
|
||||
return;
|
||||
FluidTankTileEntity controllerTE = tankAt.getControllerTE();
|
||||
|
|
|
@ -7,6 +7,7 @@ import java.util.List;
|
|||
import java.util.Random;
|
||||
|
||||
import com.simibubi.create.AllSpriteShifts;
|
||||
import com.simibubi.create.api.connectivity.ConnectivityHandler;
|
||||
import com.simibubi.create.foundation.block.connected.CTModel;
|
||||
import com.simibubi.create.foundation.block.connected.CTSpriteShiftEntry;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
|
@ -28,20 +29,20 @@ public class FluidTankModel extends CTModel {
|
|||
public static FluidTankModel standard(BakedModel originalModel) {
|
||||
return new FluidTankModel(originalModel, AllSpriteShifts.FLUID_TANK, AllSpriteShifts.COPPER_CASING);
|
||||
}
|
||||
|
||||
|
||||
public static FluidTankModel creative(BakedModel originalModel) {
|
||||
return new FluidTankModel(originalModel, AllSpriteShifts.CREATIVE_FLUID_TANK, AllSpriteShifts.CREATIVE_CASING);
|
||||
}
|
||||
|
||||
|
||||
private FluidTankModel(BakedModel originalModel, CTSpriteShiftEntry side, CTSpriteShiftEntry top) {
|
||||
super(originalModel, new FluidTankCTBehaviour(side, top));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Builder gatherModelData(Builder builder, BlockAndTintGetter world, BlockPos pos, BlockState state) {
|
||||
CullData cullData = new CullData();
|
||||
for (Direction d : Iterate.horizontalDirections)
|
||||
cullData.setCulled(d, FluidTankConnectivityHandler.isConnected(world, pos, pos.relative(d)));
|
||||
cullData.setCulled(d, ConnectivityHandler.isConnected(world, pos, pos.relative(d))); //FluidTankConnectivityHandler.isConnected(world, pos, pos.relative(d)));
|
||||
return super.gatherModelData(builder, world, pos, state).withInitial(CULL_PROPERTY, cullData);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import java.util.List;
|
|||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.simibubi.create.api.connectivity.ConnectivityHandler;
|
||||
import com.simibubi.create.content.contraptions.fluids.tank.FluidTankBlock.Shape;
|
||||
import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
|
@ -36,7 +37,7 @@ import net.minecraftforge.fluids.capability.IFluidHandler;
|
|||
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
|
||||
import net.minecraftforge.fluids.capability.templates.FluidTank;
|
||||
|
||||
public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleInformation, IMultiTileContainer {
|
||||
public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleInformation, IMultiTileContainer.Fluid {
|
||||
|
||||
private static final int MAX_SIZE = 3;
|
||||
|
||||
|
@ -83,7 +84,7 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI
|
|||
return;
|
||||
if (!isController())
|
||||
return;
|
||||
FluidTankConnectivityHandler.formTanks(this);
|
||||
ConnectivityHandler.formMulti(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -151,7 +152,7 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI
|
|||
for (int xOffset = 0; xOffset < width; xOffset++) {
|
||||
for (int zOffset = 0; zOffset < width; zOffset++) {
|
||||
BlockPos pos = this.worldPosition.offset(xOffset, yOffset, zOffset);
|
||||
FluidTankTileEntity tankAt = FluidTankConnectivityHandler.anyTankAt(level, pos);
|
||||
FluidTankTileEntity tankAt = ConnectivityHandler.partAt(getType(), level, pos);
|
||||
if (tankAt == null)
|
||||
continue;
|
||||
level.updateNeighbourForOutputSignal(pos, tankAt.getBlockState()
|
||||
|
@ -507,4 +508,82 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI
|
|||
this.fluidLevel = fluidLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preventConnectivityUpdate() { updateConnectivity = false; }
|
||||
|
||||
@Override
|
||||
public void notifyMultiUpdated() {
|
||||
BlockState state = this.getBlockState();
|
||||
if (FluidTankBlock.isTank(state)) { // safety
|
||||
state = state.setValue(FluidTankBlock.BOTTOM, getController().getY() == getBlockPos().getY());
|
||||
state = state.setValue(FluidTankBlock.TOP, getController().getY() + height - 1 == getBlockPos().getY());
|
||||
level.setBlock(getBlockPos(), state, 22);
|
||||
}
|
||||
setWindows(window);
|
||||
onFluidStackChanged(tankInventory.getFluid());
|
||||
setChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExtraData(@Nullable Object data) {
|
||||
if (data instanceof Boolean) window = (boolean)data;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object getExtraData() { return window; }
|
||||
|
||||
@Override
|
||||
public Object modifyExtraData(Object data) {
|
||||
if (data instanceof Boolean windows) {
|
||||
windows |= window;
|
||||
return windows;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Direction.Axis getMainConnectionAxis() { return Direction.Axis.Y; }
|
||||
|
||||
@Override
|
||||
public int getMaxLength(Direction.Axis longAxis, int width) {
|
||||
if (longAxis == Direction.Axis.Y) return getMaxHeight();
|
||||
return getMaxWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxWidth() { return MAX_SIZE; }
|
||||
|
||||
@Override
|
||||
public int getHeight() { return height; }
|
||||
|
||||
@Override
|
||||
public void setHeight(int height) { this.height = height; }
|
||||
|
||||
@Override
|
||||
public int getWidth() { return width; }
|
||||
|
||||
@Override
|
||||
public void setWidth(int width) { this.width = width; }
|
||||
|
||||
@Override
|
||||
public boolean hasTank() { return true; }
|
||||
|
||||
@Override
|
||||
public int getTankSize(int tank) { return getCapacityMultiplier(); }
|
||||
|
||||
@Override
|
||||
public void setTankSize(int tank, int blocks) {
|
||||
applyFluidTankSize(blocks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFluidTank getTank(int tank) {
|
||||
return tankInventory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidStack getFluid(int tank) {
|
||||
return tankInventory.getFluid().copy();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@ import java.util.List;
|
|||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
|
||||
import com.simibubi.create.foundation.utility.recipe.IRecipeTypeInfo;
|
||||
import com.simibubi.create.AllRecipeTypes;
|
||||
import com.simibubi.create.content.contraptions.processing.ProcessingRecipeBuilder.ProcessingRecipeParams;
|
||||
import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel;
|
||||
|
@ -173,7 +175,7 @@ public class BasinRecipe extends ProcessingRecipe<SmartInventory> {
|
|||
return basinRecipe;
|
||||
}
|
||||
|
||||
protected BasinRecipe(AllRecipeTypes type, ProcessingRecipeParams params) {
|
||||
protected BasinRecipe(IRecipeTypeInfo type, ProcessingRecipeParams params) {
|
||||
super(type, params);
|
||||
}
|
||||
|
||||
|
|
|
@ -62,9 +62,9 @@ public class BeltInstance extends KineticTileInstance<BeltTileEntity> {
|
|||
PartialModel beltPartial = BeltRenderer.getBeltPartial(diagonal, start, end, bottom);
|
||||
SpriteShiftEntry spriteShift = BeltRenderer.getSpriteShiftEntry(color, diagonal, bottom);
|
||||
|
||||
Instancer<BeltData> beltModel = materialManager.defaultSolid()
|
||||
.material(AllMaterialSpecs.BELTS)
|
||||
.getModel(beltPartial, blockState);
|
||||
Instancer<BeltData> beltModel = materialManager.defaultSolid()
|
||||
.material(AllMaterialSpecs.BELTS)
|
||||
.getModel(beltPartial);
|
||||
|
||||
keys.add(setup(beltModel.createInstance(), bottom, spriteShift));
|
||||
|
||||
|
@ -143,7 +143,7 @@ public class BeltInstance extends KineticTileInstance<BeltTileEntity> {
|
|||
return modelTransform;
|
||||
};
|
||||
|
||||
return getRotatingMaterial().getModel(AllBlockPartials.BELT_PULLEY, blockState, dir, ms);
|
||||
return getRotatingMaterial().getModel(AllBlockPartials.BELT_PULLEY, dir, ms);
|
||||
}
|
||||
|
||||
private Direction getOrientation() {
|
||||
|
|
|
@ -38,8 +38,7 @@ public class BracketedKineticTileInstance extends SingleRotatingInstance {
|
|||
BlockPos pos = blockEntity.getBlockPos();
|
||||
float offset = BracketedKineticTileRenderer.getShaftAngleOffset(axis, pos);
|
||||
Direction facing = Direction.fromAxisAndDirection(axis, AxisDirection.POSITIVE);
|
||||
Instancer<RotatingData> half = getRotatingMaterial().getModel(AllBlockPartials.COGWHEEL_SHAFT, blockState,
|
||||
facing, () -> this.rotateToAxis(axis));
|
||||
Instancer<RotatingData> half = getRotatingMaterial().getModel(AllBlockPartials.COGWHEEL_SHAFT, facing, () -> this.rotateToAxis(axis));
|
||||
|
||||
additionalShaft = setup(half.createInstance(), speed);
|
||||
additionalShaft.setRotationOffset(offset);
|
||||
|
@ -52,7 +51,7 @@ public class BracketedKineticTileInstance extends SingleRotatingInstance {
|
|||
|
||||
Axis axis = KineticTileEntityRenderer.getRotationAxisOf(blockEntity);
|
||||
Direction facing = Direction.fromAxisAndDirection(axis, AxisDirection.POSITIVE);
|
||||
return getRotatingMaterial().getModel(AllBlockPartials.SHAFTLESS_LARGE_COGWHEEL, blockState, facing,
|
||||
return getRotatingMaterial().getModel(AllBlockPartials.SHAFTLESS_LARGE_COGWHEEL, facing,
|
||||
() -> this.rotateToAxis(axis));
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ public class EncasedCogInstance extends KineticTileInstance<KineticTileEntity> {
|
|||
for (Direction d : Iterate.directionsInAxis(axis)) {
|
||||
if (!def.hasShaftTowards(blockEntity.getLevel(), blockEntity.getBlockPos(), blockState, d))
|
||||
continue;
|
||||
RotatingData data = setup(getRotatingMaterial().getModel(AllBlockPartials.SHAFT_HALF, blockState, d)
|
||||
RotatingData data = setup(getRotatingMaterial().getModel(AllBlockPartials.SHAFT_HALF, d)
|
||||
.createInstance());
|
||||
if (d.getAxisDirection() == AxisDirection.POSITIVE)
|
||||
rotatingTopShaft = Optional.of(data);
|
||||
|
@ -94,7 +94,7 @@ public class EncasedCogInstance extends KineticTileInstance<KineticTileEntity> {
|
|||
Direction.fromAxisAndDirection(referenceState.getValue(BlockStateProperties.AXIS), AxisDirection.POSITIVE);
|
||||
PartialModel partial = large ? AllBlockPartials.SHAFTLESS_LARGE_COGWHEEL : AllBlockPartials.SHAFTLESS_COGWHEEL;
|
||||
|
||||
return getRotatingMaterial().getModel(partial, referenceState, facing, () -> {
|
||||
return getRotatingMaterial().getModel(partial, facing, () -> {
|
||||
PoseStack poseStack = new PoseStack();
|
||||
TransformStack.cast(poseStack)
|
||||
.centre()
|
||||
|
|
|
@ -30,7 +30,7 @@ public class SplitShaftInstance extends KineticTileInstance<SplitShaftTileEntity
|
|||
|
||||
for (Direction dir : Iterate.directionsInAxis(getRotationAxis())) {
|
||||
|
||||
Instancer<RotatingData> half = rotatingMaterial.getModel(AllBlockPartials.SHAFT_HALF, blockState, dir);
|
||||
Instancer<RotatingData> half = rotatingMaterial.getModel(AllBlockPartials.SHAFT_HALF, dir);
|
||||
|
||||
float splitSpeed = speed * tile.getRotationSpeedModifier(dir);
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ public abstract class GaugeInstance extends ShaftInstance implements DynamicInst
|
|||
GaugeTileEntity gaugeTile = (GaugeTileEntity) tile;
|
||||
GaugeBlock gaugeBlock = (GaugeBlock) blockState.getBlock();
|
||||
|
||||
Instancer<ModelData> dialModel = getTransformMaterial().getModel(AllBlockPartials.GAUGE_DIAL, blockState);
|
||||
Instancer<ModelData> dialModel = getTransformMaterial().getModel(AllBlockPartials.GAUGE_DIAL);
|
||||
Instancer<ModelData> headModel = getHeadModel();
|
||||
|
||||
ms = new PoseStack();
|
||||
|
@ -150,7 +150,7 @@ public abstract class GaugeInstance extends ShaftInstance implements DynamicInst
|
|||
|
||||
@Override
|
||||
protected Instancer<ModelData> getHeadModel() {
|
||||
return getTransformMaterial().getModel(AllBlockPartials.GAUGE_HEAD_SPEED, blockState);
|
||||
return getTransformMaterial().getModel(AllBlockPartials.GAUGE_HEAD_SPEED);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,7 +161,7 @@ public abstract class GaugeInstance extends ShaftInstance implements DynamicInst
|
|||
|
||||
@Override
|
||||
protected Instancer<ModelData> getHeadModel() {
|
||||
return getTransformMaterial().getModel(AllBlockPartials.GAUGE_HEAD_STRESS, blockState);
|
||||
return getTransformMaterial().getModel(AllBlockPartials.GAUGE_HEAD_STRESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ public class GearboxInstance extends KineticTileInstance<GearboxTileEntity> {
|
|||
if (boxAxis == axis)
|
||||
continue;
|
||||
|
||||
Instancer<RotatingData> shaft = rotatingMaterial.getModel(AllBlockPartials.SHAFT_HALF, blockState, direction);
|
||||
Instancer<RotatingData> shaft = rotatingMaterial.getModel(AllBlockPartials.SHAFT_HALF, direction);
|
||||
|
||||
RotatingData key = shaft.createInstance();
|
||||
|
||||
|
|
|
@ -4,14 +4,18 @@ import com.simibubi.create.foundation.utility.worldWrappers.PlacementSimulationS
|
|||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.item.BoneMealItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.context.UseOnContext;
|
||||
import net.minecraft.world.level.block.AzaleaBlock;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.BonemealableBlock;
|
||||
import net.minecraft.world.level.block.SaplingBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
|
||||
public class TreeFertilizerItem extends Item {
|
||||
|
||||
|
@ -24,7 +28,7 @@ public class TreeFertilizerItem extends Item {
|
|||
BlockState state = context.getLevel()
|
||||
.getBlockState(context.getClickedPos());
|
||||
Block block = state.getBlock();
|
||||
if (block instanceof SaplingBlock) {
|
||||
if (block instanceof BonemealableBlock bonemealableBlock && state.is(BlockTags.SAPLINGS)) {
|
||||
|
||||
if (context.getLevel().isClientSide) {
|
||||
BoneMealItem.addGrowthParticles(context.getLevel(), context.getClickedPos(), 100);
|
||||
|
@ -38,11 +42,11 @@ public class TreeFertilizerItem extends Item {
|
|||
if (context.getLevel()
|
||||
.getBlockState(saplingPos.offset(pos))
|
||||
.getBlock() == block)
|
||||
world.setBlockAndUpdate(pos.above(10), state.setValue(SaplingBlock.STAGE, 1));
|
||||
world.setBlockAndUpdate(pos.above(10), withStage(state, 1));
|
||||
}
|
||||
|
||||
((SaplingBlock) block).performBonemeal(world, world.getRandom(), BlockPos.ZERO.above(10),
|
||||
state.setValue(SaplingBlock.STAGE, 1));
|
||||
bonemealableBlock.performBonemeal(world, world.getRandom(), BlockPos.ZERO.above(10),
|
||||
withStage(state, 1));
|
||||
|
||||
for (BlockPos pos : world.blocksAdded.keySet()) {
|
||||
BlockPos actualPos = pos.offset(saplingPos).below(10);
|
||||
|
@ -76,6 +80,12 @@ public class TreeFertilizerItem extends Item {
|
|||
return super.useOn(context);
|
||||
}
|
||||
|
||||
private BlockState withStage(BlockState original, int stage) {
|
||||
if (!original.hasProperty(BlockStateProperties.STAGE))
|
||||
return original;
|
||||
return original.setValue(BlockStateProperties.STAGE, 1);
|
||||
}
|
||||
|
||||
private static class TreesDreamWorld extends PlacementSimulationServerWorld {
|
||||
private final BlockPos saplingPos;
|
||||
private final BlockState soil;
|
||||
|
|
|
@ -15,7 +15,7 @@ public class CopperBacktankInstance extends SingleRotatingInstance {
|
|||
|
||||
@Override
|
||||
protected Instancer<RotatingData> getModel() {
|
||||
return getRotatingMaterial().getModel(AllBlockPartials.COPPER_BACKTANK_SHAFT, blockState);
|
||||
return getRotatingMaterial().getModel(AllBlockPartials.COPPER_BACKTANK_SHAFT);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,12 +32,12 @@ public class ToolBoxInstance extends BlockEntityInstance<ToolboxTileEntity> impl
|
|||
|
||||
Instancer<ModelData> drawerModel = materialManager.defaultSolid()
|
||||
.material(Materials.TRANSFORMED)
|
||||
.getModel(AllBlockPartials.TOOLBOX_DRAWER, blockState);
|
||||
.getModel(AllBlockPartials.TOOLBOX_DRAWER);
|
||||
|
||||
drawers = new ModelData[]{drawerModel.createInstance(), drawerModel.createInstance()};
|
||||
lid = materialManager.defaultCutout()
|
||||
.material(Materials.TRANSFORMED)
|
||||
.getModel(AllBlockPartials.TOOLBOX_LIDS.get(blockEntity.getColor()), blockState)
|
||||
.getModel(AllBlockPartials.TOOLBOX_LIDS.get(blockEntity.getColor()))
|
||||
.createInstance();
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.content.curiosities.toolbox;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -111,6 +112,7 @@ public class ToolboxHandler {
|
|||
.sorted((p1, p2) -> Double.compare(distance(location, p1), distance(location, p2)))
|
||||
.limit(maxAmount)
|
||||
.map(toolboxes.get(world)::get)
|
||||
.filter(ToolboxTileEntity::isFullyInitialized)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import static com.simibubi.create.foundation.gui.AllGuiTextures.TOOLBELT_SELECTE
|
|||
import static com.simibubi.create.foundation.gui.AllGuiTextures.TOOLBELT_SELECTED_ON;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
@ -111,10 +112,7 @@ public class ToolboxHandlerClient {
|
|||
Level level = player.level;
|
||||
|
||||
List<ToolboxTileEntity> toolboxes = ToolboxHandler.getNearest(player.level, player, 8);
|
||||
|
||||
if (!toolboxes.isEmpty())
|
||||
Collections.sort(toolboxes, (te1, te2) -> te1.getUniqueId()
|
||||
.compareTo(te2.getUniqueId()));
|
||||
toolboxes.sort(Comparator.comparing(ToolboxTileEntity::getUniqueId));
|
||||
|
||||
CompoundTag compound = player.getPersistentData()
|
||||
.getCompound("CreateToolboxData");
|
||||
|
|
|
@ -380,6 +380,11 @@ public class ToolboxTileEntity extends SmartTileEntity implements MenuProvider,
|
|||
return uniqueId;
|
||||
}
|
||||
|
||||
public boolean isFullyInitialized() {
|
||||
// returns true when uniqueId has been initialized
|
||||
return uniqueId != null;
|
||||
}
|
||||
|
||||
public void setCustomName(Component customName) {
|
||||
this.customName = customName;
|
||||
}
|
||||
|
|
|
@ -29,8 +29,8 @@ public class BeltTunnelInstance extends BlockEntityInstance<BeltTunnelTileEntity
|
|||
tunnelFlaps = new EnumMap<>(Direction.class);
|
||||
|
||||
Instancer<FlapData> model = modelManager.defaultSolid()
|
||||
.material(AllMaterialSpecs.FLAPS)
|
||||
.getModel(AllBlockPartials.BELT_TUNNEL_FLAP, blockState);
|
||||
.material(AllMaterialSpecs.FLAPS)
|
||||
.getModel(AllBlockPartials.BELT_TUNNEL_FLAP);
|
||||
|
||||
int blockLight = world.getBrightness(LightLayer.BLOCK, pos);
|
||||
int skyLight = world.getBrightness(LightLayer.SKY, pos);
|
||||
|
|
|
@ -41,7 +41,7 @@ import net.minecraftforge.items.ItemStackHandler;
|
|||
|
||||
public class DepotBehaviour extends TileEntityBehaviour {
|
||||
|
||||
public static BehaviourType<DepotBehaviour> TYPE = new BehaviourType<>();
|
||||
public static final BehaviourType<DepotBehaviour> TYPE = new BehaviourType<>();
|
||||
|
||||
TransportedItemStack heldItem;
|
||||
List<TransportedItemStack> incoming;
|
||||
|
|
|
@ -21,7 +21,7 @@ public class EjectorInstance extends ShaftInstance implements DynamicInstance {
|
|||
super(dispatcher, tile);
|
||||
this.tile = tile;
|
||||
|
||||
plate = getTransformMaterial().getModel(AllBlockPartials.EJECTOR_TOP, blockState).createInstance();
|
||||
plate = getTransformMaterial().getModel(AllBlockPartials.EJECTOR_TOP).createInstance();
|
||||
|
||||
pivotPlate();
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ public class BrassDiodeInstance extends BlockEntityInstance<BrassDiodeTileEntity
|
|||
|
||||
indicator = modelManager.defaultSolid()
|
||||
.material(Materials.TRANSFORMED)
|
||||
.getModel(AllBlockPartials.FLEXPEATER_INDICATOR, blockState).createInstance();
|
||||
.getModel(AllBlockPartials.FLEXPEATER_INDICATOR).createInstance();
|
||||
|
||||
indicator.loadIdentity()
|
||||
.translate(getInstancePosition())
|
||||
|
|
|
@ -30,8 +30,8 @@ public class FunnelInstance extends BlockEntityInstance<FunnelTileEntity> implem
|
|||
PartialModel flapPartial = (blockState.getBlock() instanceof FunnelBlock ? AllBlockPartials.FUNNEL_FLAP
|
||||
: AllBlockPartials.BELT_FUNNEL_FLAP);
|
||||
Instancer<FlapData> model = modelManager.defaultSolid()
|
||||
.material(AllMaterialSpecs.FLAPS)
|
||||
.getModel(flapPartial, blockState);
|
||||
.material(AllMaterialSpecs.FLAPS)
|
||||
.getModel(flapPartial);
|
||||
|
||||
int blockLight = world.getBrightness(LightLayer.BLOCK, pos);
|
||||
int skyLight = world.getBrightness(LightLayer.SKY, pos);
|
||||
|
|
|
@ -0,0 +1,689 @@
|
|||
package com.simibubi.create.content.logistics.block.mechanicalArm;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterBlock;
|
||||
import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterTileEntity;
|
||||
import com.simibubi.create.content.contraptions.components.deployer.DeployerBlock;
|
||||
import com.simibubi.create.content.contraptions.components.saw.SawBlock;
|
||||
import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.BeltHelper;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
|
||||
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelBlock;
|
||||
import com.simibubi.create.content.logistics.block.chute.AbstractChuteBlock;
|
||||
import com.simibubi.create.content.logistics.block.funnel.AbstractFunnelBlock;
|
||||
import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock;
|
||||
import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock.Shape;
|
||||
import com.simibubi.create.content.logistics.block.funnel.FunnelBlock;
|
||||
import com.simibubi.create.content.logistics.block.funnel.FunnelTileEntity;
|
||||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||
import com.simibubi.create.foundation.item.SmartInventory;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InvManipulationBehaviour;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.Containers;
|
||||
import net.minecraft.world.InteractionResultHolder;
|
||||
import net.minecraft.world.WorldlyContainer;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.RecordItem;
|
||||
import net.minecraft.world.item.crafting.CampfireCookingRecipe;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.CampfireBlock;
|
||||
import net.minecraft.world.level.block.ComposterBlock;
|
||||
import net.minecraft.world.level.block.JukeboxBlock;
|
||||
import net.minecraft.world.level.block.RespawnAnchorBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.CampfireBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.JukeboxBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
||||
import net.minecraftforge.items.wrapper.SidedInvWrapper;
|
||||
|
||||
public class AllArmInteractionPointTypes {
|
||||
|
||||
public static final BasinType BASIN = register("basin", BasinType::new);
|
||||
public static final BeltType BELT = register("belt", BeltType::new);
|
||||
public static final BlazeBurnerType BLAZE_BURNER = register("blaze_burner", BlazeBurnerType::new);
|
||||
public static final ChuteType CHUTE = register("chute", ChuteType::new);
|
||||
public static final CrafterType CRAFTER = register("crafter", CrafterType::new);
|
||||
public static final CrushingWheelsType CRUSHING_WHEELS = register("crushing_wheels", CrushingWheelsType::new);
|
||||
public static final DeployerType DEPLOYER = register("deployer", DeployerType::new);
|
||||
public static final DepotType DEPOT = register("depot", DepotType::new);
|
||||
public static final FunnelType FUNNEL = register("funnel", FunnelType::new);
|
||||
public static final MillstoneType MILLSTONE = register("millstone", MillstoneType::new);
|
||||
public static final SawType SAW = register("saw", SawType::new);
|
||||
|
||||
public static final CampfireType CAMPFIRE = register("campfire", CampfireType::new);
|
||||
public static final ComposterType COMPOSTER = register("composter", ComposterType::new);
|
||||
public static final JukeboxType JUKEBOX = register("jukebox", JukeboxType::new);
|
||||
public static final RespawnAnchorType RESPAWN_ANCHOR = register("respawn_anchor", RespawnAnchorType::new);
|
||||
|
||||
private static <T extends ArmInteractionPointType> T register(String id, Function<ResourceLocation, T> factory) {
|
||||
T type = factory.apply(Create.asResource(id));
|
||||
ArmInteractionPointType.register(type);
|
||||
return type;
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
public static class BasinType extends ArmInteractionPointType {
|
||||
public BasinType(ResourceLocation id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||
return AllBlocks.BASIN.has(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||
return new ArmInteractionPoint(this, level, pos, state);
|
||||
}
|
||||
}
|
||||
|
||||
public static class BeltType extends ArmInteractionPointType {
|
||||
public BeltType(ResourceLocation id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||
return AllBlocks.BELT.has(state) && !(level.getBlockState(pos.above())
|
||||
.getBlock() instanceof BeltTunnelBlock);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||
return new BeltPoint(this, level, pos, state);
|
||||
}
|
||||
}
|
||||
|
||||
public static class BlazeBurnerType extends ArmInteractionPointType {
|
||||
public BlazeBurnerType(ResourceLocation id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||
return AllBlocks.BLAZE_BURNER.has(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||
return new BlazeBurnerPoint(this, level, pos, state);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ChuteType extends ArmInteractionPointType {
|
||||
public ChuteType(ResourceLocation id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||
return AbstractChuteBlock.isChute(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||
return new TopFaceArmInteractionPoint(this, level, pos, state);
|
||||
}
|
||||
}
|
||||
|
||||
public static class CrafterType extends ArmInteractionPointType {
|
||||
public CrafterType(ResourceLocation id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||
return AllBlocks.MECHANICAL_CRAFTER.has(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||
return new CrafterPoint(this, level, pos, state);
|
||||
}
|
||||
}
|
||||
|
||||
public static class CrushingWheelsType extends ArmInteractionPointType {
|
||||
public CrushingWheelsType(ResourceLocation id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||
return AllBlocks.CRUSHING_WHEEL_CONTROLLER.has(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||
return new TopFaceArmInteractionPoint(this, level, pos, state);
|
||||
}
|
||||
}
|
||||
|
||||
public static class DeployerType extends ArmInteractionPointType {
|
||||
public DeployerType(ResourceLocation id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||
return AllBlocks.DEPLOYER.has(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||
return new DeployerPoint(this, level, pos, state);
|
||||
}
|
||||
}
|
||||
|
||||
public static class DepotType extends ArmInteractionPointType {
|
||||
public DepotType(ResourceLocation id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||
return AllBlocks.DEPOT.has(state) || AllBlocks.WEIGHTED_EJECTOR.has(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||
return new DepotPoint(this, level, pos, state);
|
||||
}
|
||||
}
|
||||
|
||||
public static class FunnelType extends ArmInteractionPointType {
|
||||
public FunnelType(ResourceLocation id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||
return state.getBlock() instanceof AbstractFunnelBlock
|
||||
&& !(state.hasProperty(FunnelBlock.EXTRACTING) && state.getValue(FunnelBlock.EXTRACTING))
|
||||
&& !(state.hasProperty(BeltFunnelBlock.SHAPE) && state.getValue(BeltFunnelBlock.SHAPE) == Shape.PUSHING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||
return new FunnelPoint(this, level, pos, state);
|
||||
}
|
||||
}
|
||||
|
||||
public static class MillstoneType extends ArmInteractionPointType {
|
||||
public MillstoneType(ResourceLocation id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||
return AllBlocks.MILLSTONE.has(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||
return new ArmInteractionPoint(this, level, pos, state);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SawType extends ArmInteractionPointType {
|
||||
public SawType(ResourceLocation id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||
return AllBlocks.MECHANICAL_SAW.has(state) && state.getValue(SawBlock.FACING) == Direction.UP
|
||||
&& ((KineticTileEntity) level.getBlockEntity(pos)).getSpeed() != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||
return new DepotPoint(this, level, pos, state);
|
||||
}
|
||||
}
|
||||
|
||||
public static class CampfireType extends ArmInteractionPointType {
|
||||
public CampfireType(ResourceLocation id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||
return state.getBlock() instanceof CampfireBlock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||
return new CampfirePoint(this, level, pos, state);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ComposterType extends ArmInteractionPointType {
|
||||
public ComposterType(ResourceLocation id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||
return state.is(Blocks.COMPOSTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||
return new ComposterPoint(this, level, pos, state);
|
||||
}
|
||||
}
|
||||
|
||||
public static class JukeboxType extends ArmInteractionPointType {
|
||||
public JukeboxType(ResourceLocation id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||
return state.is(Blocks.JUKEBOX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||
return new JukeboxPoint(this, level, pos, state);
|
||||
}
|
||||
}
|
||||
|
||||
public static class RespawnAnchorType extends ArmInteractionPointType {
|
||||
public RespawnAnchorType(ResourceLocation id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||
return state.is(Blocks.RESPAWN_ANCHOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||
return new RespawnAnchorPoint(this, level, pos, state);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
public static class DepositOnlyArmInteractionPoint extends ArmInteractionPoint {
|
||||
public DepositOnlyArmInteractionPoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||
super(type, level, pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cycleMode() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack extract(int slot, int amount, boolean simulate) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlotCount() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TopFaceArmInteractionPoint extends ArmInteractionPoint {
|
||||
public TopFaceArmInteractionPoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||
super(type, level, pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Vec3 getInteractionPositionVector() {
|
||||
return Vec3.atLowerCornerOf(pos).add(.5f, 1, .5f);
|
||||
}
|
||||
}
|
||||
|
||||
public static class BeltPoint extends DepotPoint {
|
||||
public BeltPoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||
super(type, level, pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keepAlive() {
|
||||
super.keepAlive();
|
||||
BeltTileEntity beltTE = BeltHelper.getSegmentTE(level, pos);
|
||||
if (beltTE == null)
|
||||
return;
|
||||
TransportedItemStackHandlerBehaviour transport =
|
||||
beltTE.getBehaviour(TransportedItemStackHandlerBehaviour.TYPE);
|
||||
if (transport == null)
|
||||
return;
|
||||
MutableBoolean found = new MutableBoolean(false);
|
||||
transport.handleProcessingOnAllItems(tis -> {
|
||||
if (found.isTrue())
|
||||
return TransportedResult.doNothing();
|
||||
tis.lockedExternally = true;
|
||||
found.setTrue();
|
||||
return TransportedResult.doNothing();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static class BlazeBurnerPoint extends DepositOnlyArmInteractionPoint {
|
||||
public BlazeBurnerPoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||
super(type, level, pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack insert(ItemStack stack, boolean simulate) {
|
||||
ItemStack input = stack.copy();
|
||||
InteractionResultHolder<ItemStack> res = BlazeBurnerBlock.tryInsert(cachedState, level, pos, input, false, false, simulate);
|
||||
ItemStack remainder = res.getObject();
|
||||
if (input.isEmpty()) {
|
||||
return remainder;
|
||||
} else {
|
||||
if (!simulate)
|
||||
Containers.dropItemStack(level, pos.getX(), pos.getY(), pos.getZ(), remainder);
|
||||
return input;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class CrafterPoint extends ArmInteractionPoint {
|
||||
public CrafterPoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||
super(type, level, pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Direction getInteractionDirection() {
|
||||
return cachedState.getValue(MechanicalCrafterBlock.HORIZONTAL_FACING)
|
||||
.getOpposite();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Vec3 getInteractionPositionVector() {
|
||||
return super.getInteractionPositionVector()
|
||||
.add(Vec3.atLowerCornerOf(getInteractionDirection().getNormal()).scale(.5f));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCachedState() {
|
||||
BlockState oldState = cachedState;
|
||||
super.updateCachedState();
|
||||
if (oldState != cachedState)
|
||||
cachedAngles = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack extract(int slot, int amount, boolean simulate) {
|
||||
BlockEntity te = level.getBlockEntity(pos);
|
||||
if (!(te instanceof MechanicalCrafterTileEntity))
|
||||
return ItemStack.EMPTY;
|
||||
MechanicalCrafterTileEntity crafter = (MechanicalCrafterTileEntity) te;
|
||||
SmartInventory inventory = crafter.getInventory();
|
||||
inventory.allowExtraction();
|
||||
ItemStack extract = super.extract(slot, amount, simulate);
|
||||
inventory.forbidExtraction();
|
||||
return extract;
|
||||
}
|
||||
}
|
||||
|
||||
public static class DeployerPoint extends ArmInteractionPoint {
|
||||
public DeployerPoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||
super(type, level, pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Direction getInteractionDirection() {
|
||||
return cachedState.getValue(DeployerBlock.FACING)
|
||||
.getOpposite();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Vec3 getInteractionPositionVector() {
|
||||
return super.getInteractionPositionVector()
|
||||
.add(Vec3.atLowerCornerOf(getInteractionDirection().getNormal()).scale(.65f));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCachedState() {
|
||||
BlockState oldState = cachedState;
|
||||
super.updateCachedState();
|
||||
if (oldState != cachedState)
|
||||
cachedAngles = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class DepotPoint extends ArmInteractionPoint {
|
||||
public DepotPoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||
super(type, level, pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Vec3 getInteractionPositionVector() {
|
||||
return Vec3.atLowerCornerOf(pos).add(.5f, 14 / 16f, .5f);
|
||||
}
|
||||
}
|
||||
|
||||
public static class FunnelPoint extends DepositOnlyArmInteractionPoint {
|
||||
public FunnelPoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||
super(type, level, pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Vec3 getInteractionPositionVector() {
|
||||
return VecHelper.getCenterOf(pos)
|
||||
.add(Vec3.atLowerCornerOf(FunnelBlock.getFunnelFacing(cachedState)
|
||||
.getNormal()).scale(-.15f));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Direction getInteractionDirection() {
|
||||
return FunnelBlock.getFunnelFacing(cachedState)
|
||||
.getOpposite();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCachedState() {
|
||||
BlockState oldState = cachedState;
|
||||
super.updateCachedState();
|
||||
if (oldState != cachedState)
|
||||
cachedAngles = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack insert(ItemStack stack, boolean simulate) {
|
||||
FilteringBehaviour filtering = TileEntityBehaviour.get(level, pos, FilteringBehaviour.TYPE);
|
||||
InvManipulationBehaviour inserter = TileEntityBehaviour.get(level, pos, InvManipulationBehaviour.TYPE);
|
||||
if (cachedState.getOptionalValue(BlockStateProperties.POWERED).orElse(false))
|
||||
return stack;
|
||||
if (inserter == null)
|
||||
return stack;
|
||||
if (filtering != null && !filtering.test(stack))
|
||||
return stack;
|
||||
if (simulate)
|
||||
inserter.simulate();
|
||||
ItemStack insert = inserter.insert(stack);
|
||||
if (!simulate && insert.getCount() != stack.getCount()) {
|
||||
BlockEntity tileEntity = level.getBlockEntity(pos);
|
||||
if (tileEntity instanceof FunnelTileEntity) {
|
||||
FunnelTileEntity funnelTileEntity = (FunnelTileEntity) tileEntity;
|
||||
funnelTileEntity.onTransfer(stack);
|
||||
if (funnelTileEntity.hasFlap())
|
||||
funnelTileEntity.flap(true);
|
||||
}
|
||||
}
|
||||
return insert;
|
||||
}
|
||||
}
|
||||
|
||||
public static class CampfirePoint extends DepositOnlyArmInteractionPoint {
|
||||
public CampfirePoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||
super(type, level, pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack insert(ItemStack stack, boolean simulate) {
|
||||
BlockEntity blockEntity = level.getBlockEntity(pos);
|
||||
if (!(blockEntity instanceof CampfireBlockEntity campfireBE))
|
||||
return stack;
|
||||
Optional<CampfireCookingRecipe> recipe = campfireBE.getCookableRecipe(stack);
|
||||
if (recipe.isEmpty())
|
||||
return stack;
|
||||
if (simulate) {
|
||||
boolean hasSpace = false;
|
||||
for (ItemStack campfireStack : campfireBE.getItems()) {
|
||||
if (campfireStack.isEmpty()) {
|
||||
hasSpace = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasSpace)
|
||||
return stack;
|
||||
ItemStack remainder = stack.copy();
|
||||
remainder.shrink(1);
|
||||
return remainder;
|
||||
}
|
||||
ItemStack remainder = stack.copy();
|
||||
campfireBE.placeFood(remainder, recipe.get().getCookingTime());
|
||||
return remainder;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ComposterPoint extends ArmInteractionPoint {
|
||||
public ComposterPoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||
super(type, level, pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Vec3 getInteractionPositionVector() {
|
||||
return Vec3.atLowerCornerOf(pos).add(.5f, 13 / 16f, .5f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCachedState() {
|
||||
BlockState oldState = cachedState;
|
||||
super.updateCachedState();
|
||||
if (oldState != cachedState)
|
||||
cachedHandler.invalidate();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected IItemHandler getHandler() {
|
||||
if (!cachedHandler.isPresent()) {
|
||||
cachedHandler = LazyOptional.of(() -> {
|
||||
ComposterBlock composterBlock = (ComposterBlock) Blocks.COMPOSTER;
|
||||
WorldlyContainer container = composterBlock.getContainer(cachedState, level, pos);
|
||||
SidedInvWrapper insertionHandler = new SidedInvWrapper(container, Direction.UP);
|
||||
SidedInvWrapper extractionHandler = new SidedInvWrapper(container, Direction.DOWN);
|
||||
return new CombinedInvWrapper(insertionHandler, extractionHandler);
|
||||
});
|
||||
}
|
||||
return cachedHandler.orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
public static class JukeboxPoint extends TopFaceArmInteractionPoint {
|
||||
public JukeboxPoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||
super(type, level, pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlotCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack insert(ItemStack stack, boolean simulate) {
|
||||
Item item = stack.getItem();
|
||||
if (!(item instanceof RecordItem))
|
||||
return stack;
|
||||
if (cachedState.getValue(JukeboxBlock.HAS_RECORD))
|
||||
return stack;
|
||||
BlockEntity blockEntity = level.getBlockEntity(pos);
|
||||
if (!(blockEntity instanceof JukeboxBlockEntity jukeboxBE))
|
||||
return stack;
|
||||
if (!jukeboxBE.getRecord()
|
||||
.isEmpty())
|
||||
return stack;
|
||||
ItemStack remainder = stack.copy();
|
||||
ItemStack toInsert = remainder.split(1);
|
||||
if (!simulate) {
|
||||
jukeboxBE.setRecord(toInsert);
|
||||
level.setBlock(pos, cachedState.setValue(JukeboxBlock.HAS_RECORD, true), 2);
|
||||
level.levelEvent(null, 1010, pos, Item.getId(item));
|
||||
AllTriggers.triggerForNearbyPlayers(AllTriggers.MUSICAL_ARM, level, pos, 10);
|
||||
}
|
||||
return remainder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack extract(int slot, int amount, boolean simulate) {
|
||||
if (!cachedState.getValue(JukeboxBlock.HAS_RECORD))
|
||||
return ItemStack.EMPTY;
|
||||
BlockEntity blockEntity = level.getBlockEntity(pos);
|
||||
if (!(blockEntity instanceof JukeboxBlockEntity jukeboxBE))
|
||||
return ItemStack.EMPTY;
|
||||
ItemStack record = jukeboxBE.getRecord();
|
||||
if (record.isEmpty())
|
||||
return ItemStack.EMPTY;
|
||||
if (!simulate) {
|
||||
level.levelEvent(1010, pos, 0);
|
||||
jukeboxBE.clearContent();
|
||||
level.setBlock(pos, cachedState.setValue(JukeboxBlock.HAS_RECORD, false), 2);
|
||||
}
|
||||
return record;
|
||||
}
|
||||
}
|
||||
|
||||
public static class RespawnAnchorPoint extends DepositOnlyArmInteractionPoint {
|
||||
public RespawnAnchorPoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||
super(type, level, pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Vec3 getInteractionPositionVector() {
|
||||
return Vec3.atLowerCornerOf(pos).add(.5f, 1, .5f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack insert(ItemStack stack, boolean simulate) {
|
||||
if (!stack.is(Items.GLOWSTONE))
|
||||
return stack;
|
||||
if (cachedState.getValue(RespawnAnchorBlock.CHARGE) == 4)
|
||||
return stack;
|
||||
if (!simulate)
|
||||
RespawnAnchorBlock.charge(level, pos, cachedState);
|
||||
ItemStack remainder = stack.copy();
|
||||
remainder.shrink(1);
|
||||
return remainder;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -11,7 +11,7 @@ import net.minecraft.world.phys.Vec3;
|
|||
|
||||
public class ArmAngleTarget {
|
||||
|
||||
static ArmAngleTarget NO_TARGET = new ArmAngleTarget();
|
||||
static final ArmAngleTarget NO_TARGET = new ArmAngleTarget();
|
||||
|
||||
float baseAngle;
|
||||
float lowerArmAngle;
|
||||
|
|
|
@ -49,13 +49,13 @@ public class ArmInstance extends SingleRotatingInstance implements DynamicInstan
|
|||
|
||||
Material<ModelData> mat = getTransformMaterial();
|
||||
|
||||
base = mat.getModel(AllBlockPartials.ARM_BASE, blockState).createInstance();
|
||||
lowerBody = mat.getModel(AllBlockPartials.ARM_LOWER_BODY, blockState).createInstance();
|
||||
upperBody = mat.getModel(AllBlockPartials.ARM_UPPER_BODY, blockState).createInstance();
|
||||
head = mat.getModel(AllBlockPartials.ARM_HEAD, blockState).createInstance();
|
||||
claw = mat.getModel(AllBlockPartials.ARM_CLAW_BASE, blockState).createInstance();
|
||||
base = mat.getModel(AllBlockPartials.ARM_BASE).createInstance();
|
||||
lowerBody = mat.getModel(AllBlockPartials.ARM_LOWER_BODY).createInstance();
|
||||
upperBody = mat.getModel(AllBlockPartials.ARM_UPPER_BODY).createInstance();
|
||||
head = mat.getModel(AllBlockPartials.ARM_HEAD).createInstance();
|
||||
claw = mat.getModel(AllBlockPartials.ARM_CLAW_BASE).createInstance();
|
||||
|
||||
Instancer<ModelData> clawHalfModel = mat.getModel(AllBlockPartials.ARM_CLAW_GRIP, blockState);
|
||||
Instancer<ModelData> clawHalfModel = mat.getModel(AllBlockPartials.ARM_CLAW_GRIP);
|
||||
ModelData clawGrip1 = clawHalfModel.createInstance();
|
||||
ModelData clawGrip2 = clawHalfModel.createInstance();
|
||||
|
||||
|
@ -172,7 +172,7 @@ public class ArmInstance extends SingleRotatingInstance implements DynamicInstan
|
|||
|
||||
@Override
|
||||
protected Instancer<RotatingData> getModel() {
|
||||
return getRotatingMaterial().getModel(AllBlockPartials.ARM_COG, blockEntity.getBlockState());
|
||||
return getRotatingMaterial().getModel(AllBlockPartials.ARM_COG);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,114 +1,66 @@
|
|||
package com.simibubi.create.content.logistics.block.mechanicalArm;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterBlock;
|
||||
import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterTileEntity;
|
||||
import com.simibubi.create.content.contraptions.components.deployer.DeployerBlock;
|
||||
import com.simibubi.create.content.contraptions.components.saw.SawBlock;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
||||
import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.BeltHelper;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
|
||||
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelBlock;
|
||||
import com.simibubi.create.content.logistics.block.chute.AbstractChuteBlock;
|
||||
import com.simibubi.create.content.logistics.block.funnel.AbstractFunnelBlock;
|
||||
import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock;
|
||||
import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock.Shape;
|
||||
import com.simibubi.create.content.logistics.block.funnel.FunnelBlock;
|
||||
import com.simibubi.create.content.logistics.block.funnel.FunnelTileEntity;
|
||||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||
import com.simibubi.create.foundation.item.SmartInventory;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InvManipulationBehaviour;
|
||||
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.world.Containers;
|
||||
import net.minecraft.world.InteractionResultHolder;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.RecordItem;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.ComposterBlock;
|
||||
import net.minecraft.world.level.block.JukeboxBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.JukeboxBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
import net.minecraftforge.items.wrapper.InvWrapper;
|
||||
|
||||
public abstract class ArmInteractionPoint {
|
||||
public enum Mode {
|
||||
DEPOSIT, TAKE
|
||||
}
|
||||
public class ArmInteractionPoint {
|
||||
|
||||
protected BlockPos pos;
|
||||
protected BlockState state;
|
||||
protected Mode mode;
|
||||
protected final ArmInteractionPointType type;
|
||||
protected Level level;
|
||||
protected final BlockPos pos;
|
||||
protected Mode mode = Mode.DEPOSIT;
|
||||
|
||||
protected LazyOptional<IItemHandler> cachedHandler;
|
||||
protected BlockState cachedState;
|
||||
protected LazyOptional<IItemHandler> cachedHandler = LazyOptional.empty();
|
||||
protected ArmAngleTarget cachedAngles;
|
||||
|
||||
protected static final HashMap<ArmInteractionPoint, Supplier<ArmInteractionPoint>> POINTS = new HashMap<>();
|
||||
|
||||
static {
|
||||
addPoint(new Saw(), Saw::new);
|
||||
addPoint(new Belt(), Belt::new);
|
||||
addPoint(new Depot(), Depot::new);
|
||||
addPoint(new Chute(), Chute::new);
|
||||
addPoint(new Basin(), Basin::new);
|
||||
addPoint(new Funnel(), Funnel::new);
|
||||
addPoint(new Jukebox(), Jukebox::new);
|
||||
addPoint(new Crafter(), Crafter::new);
|
||||
addPoint(new Deployer(), Deployer::new);
|
||||
addPoint(new Composter(), Composter::new);
|
||||
addPoint(new Millstone(), Millstone::new);
|
||||
addPoint(new BlazeBurner(), BlazeBurner::new);
|
||||
addPoint(new CrushingWheels(), CrushingWheels::new);
|
||||
public ArmInteractionPoint(ArmInteractionPointType type, Level level, BlockPos pos, BlockState state) {
|
||||
this.type = type;
|
||||
this.level = level;
|
||||
this.pos = pos;
|
||||
this.cachedState = state;
|
||||
}
|
||||
|
||||
public static void addPoint(ArmInteractionPoint instance, Supplier<ArmInteractionPoint> factory) {
|
||||
if (POINTS.containsKey(instance))
|
||||
Create.LOGGER.warn("Point for " + instance.getClass()
|
||||
.getSimpleName() + " was overridden");
|
||||
POINTS.put(instance, factory);
|
||||
public ArmInteractionPointType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public ArmInteractionPoint() {
|
||||
cachedHandler = LazyOptional.empty();
|
||||
public Level getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
protected void transformFlag(PoseStack stack) {}
|
||||
public void setLevel(Level level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
protected void cycleMode() {
|
||||
public BlockPos getPos() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
public Mode getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
public void cycleMode() {
|
||||
mode = mode == Mode.DEPOSIT ? Mode.TAKE : Mode.DEPOSIT;
|
||||
}
|
||||
|
||||
|
@ -120,22 +72,7 @@ public abstract class ArmInteractionPoint {
|
|||
return Direction.DOWN;
|
||||
}
|
||||
|
||||
protected boolean isStillValid(BlockGetter reader) {
|
||||
return isValid(reader, pos, reader.getBlockState(pos));
|
||||
}
|
||||
|
||||
protected void keepAlive(LevelAccessor world) {}
|
||||
|
||||
protected abstract boolean isValid(BlockGetter reader, BlockPos pos, BlockState state);
|
||||
|
||||
protected static boolean isInteractable(BlockGetter reader, BlockPos pos, BlockState state) {
|
||||
for (ArmInteractionPoint armInteractionPoint : POINTS.keySet())
|
||||
if (armInteractionPoint.isValid(reader, pos, state))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
protected ArmAngleTarget getTargetAngles(BlockPos armPos, boolean ceiling) {
|
||||
public ArmAngleTarget getTargetAngles(BlockPos armPos, boolean ceiling) {
|
||||
if (cachedAngles == null)
|
||||
cachedAngles =
|
||||
new ArmAngleTarget(armPos, getInteractionPositionVector(), getInteractionDirection(), ceiling);
|
||||
|
@ -143,10 +80,21 @@ public abstract class ArmInteractionPoint {
|
|||
return cachedAngles;
|
||||
}
|
||||
|
||||
public void updateCachedState() {
|
||||
cachedState = level.getBlockState(pos);
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
updateCachedState();
|
||||
return type.canCreatePoint(level, pos, cachedState);
|
||||
}
|
||||
|
||||
public void keepAlive() {}
|
||||
|
||||
@Nullable
|
||||
protected IItemHandler getHandler(Level world) {
|
||||
protected IItemHandler getHandler() {
|
||||
if (!cachedHandler.isPresent()) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
BlockEntity te = level.getBlockEntity(pos);
|
||||
if (te == null)
|
||||
return null;
|
||||
cachedHandler = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, Direction.UP);
|
||||
|
@ -154,401 +102,106 @@ public abstract class ArmInteractionPoint {
|
|||
return cachedHandler.orElse(null);
|
||||
}
|
||||
|
||||
protected ItemStack insert(Level world, ItemStack stack, boolean simulate) {
|
||||
IItemHandler handler = getHandler(world);
|
||||
public ItemStack insert(ItemStack stack, boolean simulate) {
|
||||
IItemHandler handler = getHandler();
|
||||
if (handler == null)
|
||||
return stack;
|
||||
return ItemHandlerHelper.insertItem(handler, stack, simulate);
|
||||
}
|
||||
|
||||
protected ItemStack extract(Level world, int slot, int amount, boolean simulate) {
|
||||
IItemHandler handler = getHandler(world);
|
||||
public ItemStack extract(int slot, int amount, boolean simulate) {
|
||||
IItemHandler handler = getHandler();
|
||||
if (handler == null)
|
||||
return ItemStack.EMPTY;
|
||||
return handler.extractItem(slot, amount, simulate);
|
||||
}
|
||||
|
||||
protected ItemStack extract(Level world, int slot, boolean simulate) {
|
||||
return extract(world, slot, 64, simulate);
|
||||
public ItemStack extract(int slot, boolean simulate) {
|
||||
return extract(slot, 64, simulate);
|
||||
}
|
||||
|
||||
protected int getSlotCount(Level world) {
|
||||
IItemHandler handler = getHandler(world);
|
||||
public int getSlotCount() {
|
||||
IItemHandler handler = getHandler();
|
||||
if (handler == null)
|
||||
return 0;
|
||||
return handler.getSlots();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected static ArmInteractionPoint createAt(BlockGetter world, BlockPos pos) {
|
||||
BlockState state = world.getBlockState(pos);
|
||||
ArmInteractionPoint point = null;
|
||||
|
||||
for (ArmInteractionPoint armInteractionPoint : POINTS.keySet())
|
||||
if (armInteractionPoint.isValid(world, pos, state))
|
||||
point = POINTS.get(armInteractionPoint)
|
||||
.get();
|
||||
|
||||
if (point != null) {
|
||||
point.state = state;
|
||||
point.pos = pos;
|
||||
point.mode = Mode.DEPOSIT;
|
||||
}
|
||||
|
||||
return point;
|
||||
protected void serialize(CompoundTag nbt, BlockPos anchor) {
|
||||
NBTHelper.writeEnum(nbt, "Mode", mode);
|
||||
}
|
||||
|
||||
protected CompoundTag serialize(BlockPos anchor) {
|
||||
protected void deserialize(CompoundTag nbt, BlockPos anchor) {
|
||||
mode = NBTHelper.readEnum(nbt, "Mode", Mode.class);
|
||||
}
|
||||
|
||||
public final CompoundTag serialize(BlockPos anchor) {
|
||||
CompoundTag nbt = new CompoundTag();
|
||||
nbt.putString("Type", type.getId().toString());
|
||||
nbt.put("Pos", NbtUtils.writeBlockPos(pos.subtract(anchor)));
|
||||
NBTHelper.writeEnum(nbt, "Mode", mode);
|
||||
serialize(nbt, anchor);
|
||||
return nbt;
|
||||
}
|
||||
|
||||
protected static ArmInteractionPoint deserialize(BlockGetter world, BlockPos anchor, CompoundTag nbt) {
|
||||
BlockPos pos = NbtUtils.readBlockPos(nbt.getCompound("Pos"));
|
||||
ArmInteractionPoint interactionPoint = createAt(world, pos.offset(anchor));
|
||||
if (interactionPoint == null)
|
||||
@Nullable
|
||||
public static ArmInteractionPoint deserialize(CompoundTag nbt, Level level, BlockPos anchor) {
|
||||
ResourceLocation id = ResourceLocation.tryParse(nbt.getString("Type"));
|
||||
if (id == null)
|
||||
return null;
|
||||
interactionPoint.mode = NBTHelper.readEnum(nbt, "Mode", Mode.class);
|
||||
return interactionPoint;
|
||||
ArmInteractionPointType type = ArmInteractionPointType.get(id);
|
||||
if (type == null)
|
||||
return null;
|
||||
BlockPos pos = NbtUtils.readBlockPos(nbt.getCompound("Pos")).offset(anchor);
|
||||
ArmInteractionPoint point = type.createPoint(level, pos, level.getBlockState(pos));
|
||||
if (point == null)
|
||||
return null;
|
||||
point.deserialize(nbt, anchor);
|
||||
return point;
|
||||
}
|
||||
|
||||
protected static void transformPos(StructureTransform transform, CompoundTag nbt) {
|
||||
public static void transformPos(CompoundTag nbt, StructureTransform transform) {
|
||||
BlockPos pos = NbtUtils.readBlockPos(nbt.getCompound("Pos"));
|
||||
pos = transform.applyWithoutOffset(pos);
|
||||
nbt.put("Pos", NbtUtils.writeBlockPos(pos));
|
||||
}
|
||||
|
||||
public static abstract class TopFaceArmInteractionPoint extends ArmInteractionPoint {
|
||||
|
||||
@Override
|
||||
protected Vec3 getInteractionPositionVector() {
|
||||
return Vec3.atLowerCornerOf(pos)
|
||||
.add(.5f, 1, .5f);
|
||||
}
|
||||
|
||||
public static boolean isInteractable(Level level, BlockPos pos, BlockState state) {
|
||||
return ArmInteractionPointType.getPrimaryType(level, pos, state) != null;
|
||||
}
|
||||
|
||||
public static class Depot extends ArmInteractionPoint {
|
||||
|
||||
@Override
|
||||
protected Vec3 getInteractionPositionVector() {
|
||||
return Vec3.atLowerCornerOf(pos)
|
||||
.add(.5f, 14 / 16f, .5f);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
||||
return AllBlocks.DEPOT.has(state) || AllBlocks.WEIGHTED_EJECTOR.has(state)
|
||||
|| AllBlocks.TRACK_STATION.has(state);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ArmInteractionPoint create(Level level, BlockPos pos, BlockState state) {
|
||||
ArmInteractionPointType type = ArmInteractionPointType.getPrimaryType(level, pos, state);
|
||||
if (type == null)
|
||||
return null;
|
||||
return type.createPoint(level, pos, state);
|
||||
}
|
||||
|
||||
public static class Saw extends Depot {
|
||||
public enum Mode {
|
||||
DEPOSIT("mechanical_arm.deposit_to", ChatFormatting.GOLD, 0xFFCB74),
|
||||
TAKE("mechanical_arm.extract_from", ChatFormatting.AQUA, 0x4F8A8B);
|
||||
|
||||
@Override
|
||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
||||
return AllBlocks.MECHANICAL_SAW.has(state) && state.getValue(SawBlock.FACING) == Direction.UP
|
||||
&& ((KineticTileEntity) reader.getBlockEntity(pos)).getSpeed() != 0;
|
||||
private final String translationKey;
|
||||
private final ChatFormatting chatColor;
|
||||
private final int color;
|
||||
|
||||
Mode(String translationKey, ChatFormatting chatColor, int color) {
|
||||
this.translationKey = translationKey;
|
||||
this.chatColor = chatColor;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Millstone extends ArmInteractionPoint {
|
||||
|
||||
@Override
|
||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
||||
return AllBlocks.MILLSTONE.has(state);
|
||||
public String getTranslationKey() {
|
||||
return translationKey;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class CrushingWheels extends TopFaceArmInteractionPoint {
|
||||
|
||||
@Override
|
||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
||||
return AllBlocks.CRUSHING_WHEEL_CONTROLLER.has(state);
|
||||
public ChatFormatting getChatColor() {
|
||||
return chatColor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Composter extends TopFaceArmInteractionPoint {
|
||||
|
||||
@Override
|
||||
protected Vec3 getInteractionPositionVector() {
|
||||
return Vec3.atLowerCornerOf(pos)
|
||||
.add(.5f, 13 / 16f, .5f);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
||||
return Blocks.COMPOSTER.equals(state.getBlock());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected IItemHandler getHandler(Level world) {
|
||||
return new InvWrapper(
|
||||
((ComposterBlock) Blocks.COMPOSTER).getContainer(world.getBlockState(pos), world, pos));
|
||||
public int getColor() {
|
||||
return color;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Deployer extends ArmInteractionPoint {
|
||||
|
||||
@Override
|
||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
||||
return AllBlocks.DEPLOYER.has(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Direction getInteractionDirection() {
|
||||
return state.getValue(DeployerBlock.FACING)
|
||||
.getOpposite();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Vec3 getInteractionPositionVector() {
|
||||
return super.getInteractionPositionVector().add(Vec3.atLowerCornerOf(getInteractionDirection().getNormal())
|
||||
.scale(.65f));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class BlazeBurner extends ArmInteractionPoint {
|
||||
|
||||
@Override
|
||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
||||
return AllBlocks.BLAZE_BURNER.has(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemStack extract(Level world, int slot, int amount, boolean simulate) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemStack insert(Level world, ItemStack stack, boolean simulate) {
|
||||
ItemStack input = stack.copy();
|
||||
InteractionResultHolder<ItemStack> res =
|
||||
BlazeBurnerBlock.tryInsert(state, world, pos, input, false, false, simulate);
|
||||
ItemStack remainder = res.getObject();
|
||||
if (input.isEmpty()) {
|
||||
return remainder;
|
||||
} else {
|
||||
if (!simulate)
|
||||
Containers.dropItemStack(world, pos.getX(), pos.getY(), pos.getZ(), remainder);
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void cycleMode() {}
|
||||
|
||||
}
|
||||
|
||||
public static class Crafter extends ArmInteractionPoint {
|
||||
|
||||
@Override
|
||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
||||
return AllBlocks.MECHANICAL_CRAFTER.has(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Direction getInteractionDirection() {
|
||||
return state.getValue(MechanicalCrafterBlock.HORIZONTAL_FACING)
|
||||
.getOpposite();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemStack extract(Level world, int slot, int amount, boolean simulate) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
if (!(te instanceof MechanicalCrafterTileEntity))
|
||||
return ItemStack.EMPTY;
|
||||
MechanicalCrafterTileEntity crafter = (MechanicalCrafterTileEntity) te;
|
||||
SmartInventory inventory = crafter.getInventory();
|
||||
inventory.allowExtraction();
|
||||
ItemStack extract = super.extract(world, slot, amount, simulate);
|
||||
inventory.forbidExtraction();
|
||||
return extract;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Vec3 getInteractionPositionVector() {
|
||||
return super.getInteractionPositionVector().add(Vec3.atLowerCornerOf(getInteractionDirection().getNormal())
|
||||
.scale(.5f));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Basin extends ArmInteractionPoint {
|
||||
|
||||
@Override
|
||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
||||
return AllBlocks.BASIN.has(state);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Jukebox extends TopFaceArmInteractionPoint {
|
||||
|
||||
@Override
|
||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
||||
return state.getBlock() instanceof JukeboxBlock;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSlotCount(Level world) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemStack insert(Level world, ItemStack stack, boolean simulate) {
|
||||
BlockEntity tileEntity = world.getBlockEntity(pos);
|
||||
if (!(tileEntity instanceof JukeboxBlockEntity))
|
||||
return stack;
|
||||
if (!(state.getBlock() instanceof JukeboxBlock))
|
||||
return stack;
|
||||
JukeboxBlock jukeboxBlock = (JukeboxBlock) state.getBlock();
|
||||
JukeboxBlockEntity jukeboxTE = (JukeboxBlockEntity) tileEntity;
|
||||
if (!jukeboxTE.getRecord()
|
||||
.isEmpty())
|
||||
return stack;
|
||||
if (!(stack.getItem() instanceof RecordItem))
|
||||
return stack;
|
||||
ItemStack remainder = stack.copy();
|
||||
ItemStack toInsert = remainder.split(1);
|
||||
if (!simulate && !world.isClientSide) {
|
||||
jukeboxBlock.setRecord(world, pos, state, toInsert);
|
||||
world.levelEvent(null, 1010, pos, Item.getId(toInsert.getItem()));
|
||||
AllTriggers.triggerForNearbyPlayers(AllTriggers.MUSICAL_ARM, world, pos, 10);
|
||||
}
|
||||
return remainder;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemStack extract(Level world, int slot, int amount, boolean simulate) {
|
||||
BlockEntity tileEntity = world.getBlockEntity(pos);
|
||||
if (!(tileEntity instanceof JukeboxBlockEntity))
|
||||
return ItemStack.EMPTY;
|
||||
if (!(state.getBlock() instanceof JukeboxBlock))
|
||||
return ItemStack.EMPTY;
|
||||
JukeboxBlockEntity jukeboxTE = (JukeboxBlockEntity) tileEntity;
|
||||
ItemStack itemstack = jukeboxTE.getRecord();
|
||||
if (itemstack.isEmpty())
|
||||
return ItemStack.EMPTY;
|
||||
if (!simulate && !world.isClientSide) {
|
||||
world.levelEvent(1010, pos, 0);
|
||||
jukeboxTE.clearContent();
|
||||
world.setBlock(pos, state.setValue(JukeboxBlock.HAS_RECORD, false), 2);
|
||||
}
|
||||
return itemstack;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Belt extends Depot {
|
||||
|
||||
@Override
|
||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
||||
return AllBlocks.BELT.has(state) && !(reader.getBlockState(pos.above())
|
||||
.getBlock() instanceof BeltTunnelBlock);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void keepAlive(LevelAccessor world) {
|
||||
super.keepAlive(world);
|
||||
BeltTileEntity beltTE = BeltHelper.getSegmentTE(world, pos);
|
||||
if (beltTE == null)
|
||||
return;
|
||||
TransportedItemStackHandlerBehaviour transport =
|
||||
beltTE.getBehaviour(TransportedItemStackHandlerBehaviour.TYPE);
|
||||
if (transport == null)
|
||||
return;
|
||||
MutableBoolean found = new MutableBoolean(false);
|
||||
transport.handleProcessingOnAllItems(tis -> {
|
||||
if (found.isTrue())
|
||||
return TransportedResult.doNothing();
|
||||
tis.lockedExternally = true;
|
||||
found.setTrue();
|
||||
return TransportedResult.doNothing();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Chute extends TopFaceArmInteractionPoint {
|
||||
|
||||
@Override
|
||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
||||
return AbstractChuteBlock.isChute(state);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Funnel extends ArmInteractionPoint {
|
||||
|
||||
@Override
|
||||
protected Vec3 getInteractionPositionVector() {
|
||||
return VecHelper.getCenterOf(pos)
|
||||
.add(Vec3.atLowerCornerOf(FunnelBlock.getFunnelFacing(state)
|
||||
.getNormal())
|
||||
.scale(-.15f));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSlotCount(Level world) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemStack extract(Level world, int slot, int amount, boolean simulate) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Direction getInteractionDirection() {
|
||||
return FunnelBlock.getFunnelFacing(state)
|
||||
.getOpposite();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemStack insert(Level world, ItemStack stack, boolean simulate) {
|
||||
FilteringBehaviour filtering = TileEntityBehaviour.get(world, pos, FilteringBehaviour.TYPE);
|
||||
InvManipulationBehaviour inserter = TileEntityBehaviour.get(world, pos, InvManipulationBehaviour.TYPE);
|
||||
BlockState state = world.getBlockState(pos);
|
||||
if (state.getOptionalValue(BlockStateProperties.POWERED)
|
||||
.orElse(false))
|
||||
return stack;
|
||||
if (inserter == null)
|
||||
return stack;
|
||||
if (filtering != null && !filtering.test(stack))
|
||||
return stack;
|
||||
if (simulate)
|
||||
inserter.simulate();
|
||||
ItemStack insert = inserter.insert(stack);
|
||||
if (!simulate && insert.getCount() != stack.getCount()) {
|
||||
BlockEntity tileEntity = world.getBlockEntity(pos);
|
||||
if (tileEntity instanceof FunnelTileEntity) {
|
||||
FunnelTileEntity funnelTileEntity = (FunnelTileEntity) tileEntity;
|
||||
funnelTileEntity.onTransfer(stack);
|
||||
if (funnelTileEntity.hasFlap())
|
||||
funnelTileEntity.flap(true);
|
||||
}
|
||||
}
|
||||
return insert;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isValid(BlockGetter reader, BlockPos pos, BlockState state) {
|
||||
return state.getBlock() instanceof AbstractFunnelBlock
|
||||
&& !(state.hasProperty(FunnelBlock.EXTRACTING) && state.getValue(FunnelBlock.EXTRACTING))
|
||||
&& !(state.hasProperty(BeltFunnelBlock.SHAPE)
|
||||
&& state.getValue(BeltFunnelBlock.SHAPE) == Shape.PUSHING);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void cycleMode() {}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ import net.minecraft.ChatFormatting;
|
|||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
@ -52,9 +52,10 @@ public class ArmInteractionPointHandler {
|
|||
return;
|
||||
|
||||
ArmInteractionPoint selected = getSelected(pos);
|
||||
BlockState state = world.getBlockState(pos);
|
||||
|
||||
if (selected == null) {
|
||||
ArmInteractionPoint point = ArmInteractionPoint.createAt(world, pos);
|
||||
ArmInteractionPoint point = ArmInteractionPoint.create(world, pos, state);
|
||||
if (point == null)
|
||||
return;
|
||||
selected = point;
|
||||
|
@ -63,10 +64,9 @@ public class ArmInteractionPointHandler {
|
|||
|
||||
selected.cycleMode();
|
||||
if (player != null) {
|
||||
String key = selected.mode == Mode.DEPOSIT ? "mechanical_arm.deposit_to" : "mechanical_arm.extract_from";
|
||||
ChatFormatting colour = selected.mode == Mode.DEPOSIT ? ChatFormatting.GOLD : ChatFormatting.AQUA;
|
||||
TranslatableComponent translatedBlock = new TranslatableComponent(selected.state.getBlock()
|
||||
.getDescriptionId());
|
||||
String key = selected.getMode().getTranslationKey();
|
||||
ChatFormatting colour = selected.getMode().getChatColor();
|
||||
MutableComponent translatedBlock = state.getBlock().getName();
|
||||
player.displayClientMessage((Lang.translate(key, translatedBlock.withStyle(ChatFormatting.WHITE, colour)).withStyle(colour)),
|
||||
true);
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ public class ArmInteractionPointHandler {
|
|||
int removed = 0;
|
||||
for (Iterator<ArmInteractionPoint> iterator = currentSelection.iterator(); iterator.hasNext();) {
|
||||
ArmInteractionPoint point = iterator.next();
|
||||
if (point.pos.closerThan(pos, ArmTileEntity.getRange()))
|
||||
if (point.getPos().closerThan(pos, ArmTileEntity.getRange()))
|
||||
continue;
|
||||
iterator.remove();
|
||||
removed++;
|
||||
|
@ -109,7 +109,7 @@ public class ArmInteractionPointHandler {
|
|||
int inputs = 0;
|
||||
int outputs = 0;
|
||||
for (ArmInteractionPoint armInteractionPoint : currentSelection) {
|
||||
if (armInteractionPoint.mode == Mode.DEPOSIT)
|
||||
if (armInteractionPoint.getMode() == Mode.DEPOSIT)
|
||||
outputs++;
|
||||
else
|
||||
inputs++;
|
||||
|
@ -179,22 +179,22 @@ public class ArmInteractionPointHandler {
|
|||
}
|
||||
|
||||
private static void drawOutlines(Collection<ArmInteractionPoint> selection) {
|
||||
Level world = Minecraft.getInstance().level;
|
||||
for (Iterator<ArmInteractionPoint> iterator = selection.iterator(); iterator.hasNext();) {
|
||||
ArmInteractionPoint point = iterator.next();
|
||||
BlockPos pos = point.pos;
|
||||
BlockState state = world.getBlockState(pos);
|
||||
|
||||
if (!point.isValid(world, pos, state)) {
|
||||
if (!point.isValid()) {
|
||||
iterator.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
VoxelShape shape = state.getShape(world, pos);
|
||||
Level level = point.getLevel();
|
||||
BlockPos pos = point.getPos();
|
||||
BlockState state = level.getBlockState(pos);
|
||||
VoxelShape shape = state.getShape(level, pos);
|
||||
if (shape.isEmpty())
|
||||
continue;
|
||||
|
||||
int color = point.mode == Mode.DEPOSIT ? 0xffcb74 : 0x4f8a8b;
|
||||
int color = point.getMode().getColor();
|
||||
CreateClient.OUTLINER.showAABB(point, shape.bounds()
|
||||
.move(pos))
|
||||
.colored(color)
|
||||
|
@ -214,10 +214,9 @@ public class ArmInteractionPointHandler {
|
|||
}
|
||||
|
||||
private static ArmInteractionPoint getSelected(BlockPos pos) {
|
||||
for (ArmInteractionPoint point : currentSelection) {
|
||||
if (point.pos.equals(pos))
|
||||
for (ArmInteractionPoint point : currentSelection)
|
||||
if (point.getPos().equals(pos))
|
||||
return point;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
package com.simibubi.create.content.logistics.block.mechanicalArm;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public abstract class ArmInteractionPointType {
|
||||
|
||||
private static final Map<ResourceLocation, ArmInteractionPointType> TYPES = new HashMap<>();
|
||||
private static final List<ArmInteractionPointType> SORTED_TYPES = new ArrayList<>();
|
||||
|
||||
protected final ResourceLocation id;
|
||||
|
||||
public ArmInteractionPointType(ResourceLocation id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public static void register(ArmInteractionPointType type) {
|
||||
ResourceLocation id = type.getId();
|
||||
if (TYPES.containsKey(id))
|
||||
throw new IllegalArgumentException("Tried to override ArmInteractionPointType registration for id '" + id + "'. This is not supported!");
|
||||
TYPES.put(id, type);
|
||||
SORTED_TYPES.add(type);
|
||||
SORTED_TYPES.sort((t1, t2) -> t2.getPriority() - t1.getPriority());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ArmInteractionPointType get(ResourceLocation id) {
|
||||
return TYPES.get(id);
|
||||
}
|
||||
|
||||
public static void forEach(Consumer<ArmInteractionPointType> action) {
|
||||
SORTED_TYPES.forEach(action);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ArmInteractionPointType getPrimaryType(Level level, BlockPos pos, BlockState state) {
|
||||
for (ArmInteractionPointType type : SORTED_TYPES)
|
||||
if (type.canCreatePoint(level, pos, state))
|
||||
return type;
|
||||
return null;
|
||||
}
|
||||
|
||||
public final ResourceLocation getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public abstract boolean canCreatePoint(Level level, BlockPos pos, BlockState state);
|
||||
|
||||
@Nullable
|
||||
public abstract ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state);
|
||||
|
||||
public int getPriority() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -9,7 +9,6 @@ import com.simibubi.create.Create;
|
|||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableTE;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
||||
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPoint.Jukebox;
|
||||
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPoint.Mode;
|
||||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
|
@ -35,6 +34,7 @@ import net.minecraft.sounds.SoundEvents;
|
|||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.JukeboxBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
@ -116,7 +116,7 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
|||
if (phase == Phase.MOVE_TO_INPUT) {
|
||||
ArmInteractionPoint point = getTargetedInteractionPoint();
|
||||
if (point != null)
|
||||
point.keepAlive(level);
|
||||
point.keepAlive();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -164,9 +164,9 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
|||
|
||||
private boolean checkForMusicAmong(List<ArmInteractionPoint> list) {
|
||||
for (ArmInteractionPoint armInteractionPoint : list) {
|
||||
if (!(armInteractionPoint instanceof Jukebox))
|
||||
if (!(armInteractionPoint instanceof AllArmInteractionPointTypes.JukeboxPoint))
|
||||
continue;
|
||||
BlockState state = level.getBlockState(armInteractionPoint.pos);
|
||||
BlockState state = level.getBlockState(armInteractionPoint.getPos());
|
||||
if (state.getOptionalValue(JukeboxBlock.HAS_RECORD).orElse(false))
|
||||
return true;
|
||||
}
|
||||
|
@ -236,9 +236,9 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
|||
|
||||
InteractionPoints: for (int i = startIndex; i < scanRange; i++) {
|
||||
ArmInteractionPoint armInteractionPoint = inputs.get(i);
|
||||
if (!armInteractionPoint.isStillValid(level))
|
||||
if (!armInteractionPoint.isValid())
|
||||
continue;
|
||||
for (int j = 0; j < armInteractionPoint.getSlotCount(level); j++) {
|
||||
for (int j = 0; j < armInteractionPoint.getSlotCount(); j++) {
|
||||
if (getDistributableAmount(armInteractionPoint, j) == 0)
|
||||
continue;
|
||||
|
||||
|
@ -274,10 +274,10 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
|||
|
||||
for (int i = startIndex; i < scanRange; i++) {
|
||||
ArmInteractionPoint armInteractionPoint = outputs.get(i);
|
||||
if (!armInteractionPoint.isStillValid(level))
|
||||
if (!armInteractionPoint.isValid())
|
||||
continue;
|
||||
|
||||
ItemStack remainder = armInteractionPoint.insert(level, held, true);
|
||||
ItemStack remainder = armInteractionPoint.insert(held, true);
|
||||
if (remainder.equals(heldItem, false))
|
||||
continue;
|
||||
|
||||
|
@ -311,7 +311,7 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
|||
}
|
||||
|
||||
protected int getDistributableAmount(ArmInteractionPoint armInteractionPoint, int i) {
|
||||
ItemStack stack = armInteractionPoint.extract(level, i, true);
|
||||
ItemStack stack = armInteractionPoint.extract(i, true);
|
||||
ItemStack remainder = simulateInsertion(stack);
|
||||
if (stack.sameItem(remainder)) {
|
||||
return stack.getCount() - remainder.getCount();
|
||||
|
@ -320,11 +320,21 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
|||
}
|
||||
}
|
||||
|
||||
private ItemStack simulateInsertion(ItemStack stack) {
|
||||
for (ArmInteractionPoint armInteractionPoint : outputs) {
|
||||
if (armInteractionPoint.isValid())
|
||||
stack = armInteractionPoint.insert(stack, true);
|
||||
if (stack.isEmpty())
|
||||
break;
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
protected void depositItem() {
|
||||
ArmInteractionPoint armInteractionPoint = getTargetedInteractionPoint();
|
||||
if (armInteractionPoint != null) {
|
||||
if (armInteractionPoint != null && armInteractionPoint.isValid()) {
|
||||
ItemStack toInsert = heldItem.copy();
|
||||
ItemStack remainder = armInteractionPoint.insert(level, toInsert, false);
|
||||
ItemStack remainder = armInteractionPoint.insert(toInsert, false);
|
||||
heldItem = remainder;
|
||||
}
|
||||
phase = heldItem.isEmpty() ? Phase.SEARCH_INPUTS : Phase.SEARCH_OUTPUTS;
|
||||
|
@ -339,14 +349,14 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
|||
|
||||
protected void collectItem() {
|
||||
ArmInteractionPoint armInteractionPoint = getTargetedInteractionPoint();
|
||||
if (armInteractionPoint != null)
|
||||
for (int i = 0; i < armInteractionPoint.getSlotCount(level); i++) {
|
||||
if (armInteractionPoint != null && armInteractionPoint.isValid())
|
||||
for (int i = 0; i < armInteractionPoint.getSlotCount(); i++) {
|
||||
int amountExtracted = getDistributableAmount(armInteractionPoint, i);
|
||||
if (amountExtracted == 0)
|
||||
continue;
|
||||
|
||||
ItemStack prevHeld = heldItem;
|
||||
heldItem = armInteractionPoint.extract(level, i, amountExtracted, false);
|
||||
heldItem = armInteractionPoint.extract(i, amountExtracted, false);
|
||||
phase = Phase.SEARCH_OUTPUTS;
|
||||
chasedPointProgress = 0;
|
||||
chasedPointIndex = -1;
|
||||
|
@ -366,15 +376,6 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
|||
setChanged();
|
||||
}
|
||||
|
||||
private ItemStack simulateInsertion(ItemStack stack) {
|
||||
for (ArmInteractionPoint armInteractionPoint : outputs) {
|
||||
stack = armInteractionPoint.insert(level, stack, true);
|
||||
if (stack.isEmpty())
|
||||
break;
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
public void redstoneUpdate() {
|
||||
if (level.isClientSide)
|
||||
return;
|
||||
|
@ -392,8 +393,8 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
|||
if (interactionPointTag == null)
|
||||
return;
|
||||
|
||||
for (Tag inbt : interactionPointTag) {
|
||||
ArmInteractionPoint.transformPos(transform, (CompoundTag) inbt);
|
||||
for (Tag tag : interactionPointTag) {
|
||||
ArmInteractionPoint.transformPos((CompoundTag) tag, transform);
|
||||
}
|
||||
|
||||
notifyUpdate();
|
||||
|
@ -408,15 +409,15 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
|||
outputs.clear();
|
||||
|
||||
boolean hasBlazeBurner = false;
|
||||
for (Tag inbt : interactionPointTag) {
|
||||
ArmInteractionPoint point = ArmInteractionPoint.deserialize(level, worldPosition, (CompoundTag) inbt);
|
||||
for (Tag tag : interactionPointTag) {
|
||||
ArmInteractionPoint point = ArmInteractionPoint.deserialize((CompoundTag) tag, level, worldPosition);
|
||||
if (point == null)
|
||||
continue;
|
||||
if (point.mode == Mode.DEPOSIT)
|
||||
if (point.getMode() == Mode.DEPOSIT)
|
||||
outputs.add(point);
|
||||
if (point.mode == Mode.TAKE)
|
||||
else if (point.getMode() == Mode.TAKE)
|
||||
inputs.add(point);
|
||||
hasBlazeBurner |= point instanceof ArmInteractionPoint.BlazeBurner;
|
||||
hasBlazeBurner |= point instanceof AllArmInteractionPointTypes.BlazeBurnerPoint;
|
||||
}
|
||||
|
||||
if (!level.isClientSide) {
|
||||
|
@ -496,6 +497,10 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
|||
previousPoint == null ? ArmAngleTarget.NO_TARGET : previousPoint.getTargetAngles(worldPosition, ceiling);
|
||||
if (previousPoint != null)
|
||||
previousBaseAngle = previousPoint.getTargetAngles(worldPosition, ceiling).baseAngle;
|
||||
|
||||
ArmInteractionPoint targetedPoint = getTargetedInteractionPoint();
|
||||
if (targetedPoint != null)
|
||||
targetedPoint.updateCachedState();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -518,6 +523,16 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
|
|||
return true;
|
||||
}
|
||||
|
||||
public void setLevel(Level level) {
|
||||
super.setLevel(level);
|
||||
for (ArmInteractionPoint input : inputs) {
|
||||
input.setLevel(level);
|
||||
}
|
||||
for (ArmInteractionPoint output : outputs) {
|
||||
output.setLevel(level);
|
||||
}
|
||||
}
|
||||
|
||||
private class SelectionModeValueBox extends CenteredSideValueBoxTransform {
|
||||
|
||||
public SelectionModeValueBox() {
|
||||
|
|
|
@ -28,8 +28,8 @@ public class AnalogLeverInstance extends BlockEntityInstance<AnalogLeverTileEnti
|
|||
|
||||
Material<ModelData> mat = getTransformMaterial();
|
||||
|
||||
handle = mat.getModel(AllBlockPartials.ANALOG_LEVER_HANDLE, blockState).createInstance();
|
||||
indicator = mat.getModel(AllBlockPartials.ANALOG_LEVER_INDICATOR, blockState).createInstance();
|
||||
handle = mat.getModel(AllBlockPartials.ANALOG_LEVER_HANDLE).createInstance();
|
||||
indicator = mat.getModel(AllBlockPartials.ANALOG_LEVER_INDICATOR).createInstance();
|
||||
|
||||
transform(indicator);
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import javax.annotation.Nullable;
|
|||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.api.connectivity.ConnectivityHandler;
|
||||
import com.simibubi.create.content.contraptions.wrench.IWrenchable;
|
||||
import com.simibubi.create.foundation.block.ITE;
|
||||
import com.simibubi.create.foundation.item.ItemHelper;
|
||||
|
@ -85,7 +86,7 @@ public class ItemVaultBlock extends Block implements IWrenchable, ITE<ItemVaultT
|
|||
.getBlockEntity(context.getClickedPos());
|
||||
if (te instanceof ItemVaultTileEntity) {
|
||||
ItemVaultTileEntity vault = (ItemVaultTileEntity) te;
|
||||
ItemVaultConnectivityHandler.splitVault(vault);
|
||||
ConnectivityHandler.splitMulti(vault);
|
||||
vault.removeController(true);
|
||||
}
|
||||
state = state.setValue(LARGE, false);
|
||||
|
@ -100,10 +101,10 @@ public class ItemVaultBlock extends Block implements IWrenchable, ITE<ItemVaultT
|
|||
BlockEntity te = world.getBlockEntity(pos);
|
||||
if (!(te instanceof ItemVaultTileEntity))
|
||||
return;
|
||||
ItemVaultTileEntity tankTE = (ItemVaultTileEntity) te;
|
||||
ItemHelper.dropContents(world, pos, tankTE.inventory);
|
||||
ItemVaultTileEntity vaultTE = (ItemVaultTileEntity) te;
|
||||
ItemHelper.dropContents(world, pos, vaultTE.inventory);
|
||||
world.removeBlockEntity(pos);
|
||||
ItemVaultConnectivityHandler.splitVault(tankTE);
|
||||
ConnectivityHandler.splitMulti(vaultTE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.content.logistics.block.vault;
|
||||
|
||||
import com.simibubi.create.AllSpriteShifts;
|
||||
import com.simibubi.create.api.connectivity.ConnectivityHandler;
|
||||
import com.simibubi.create.foundation.block.connected.CTSpriteShiftEntry;
|
||||
import com.simibubi.create.foundation.block.connected.ConnectedTextureBehaviour;
|
||||
|
||||
|
@ -62,7 +63,7 @@ public class ItemVaultCTBehaviour extends ConnectedTextureBehaviour {
|
|||
@Override
|
||||
public boolean connectsTo(BlockState state, BlockState other, BlockAndTintGetter reader, BlockPos pos,
|
||||
BlockPos otherPos, Direction face) {
|
||||
return state == other && ItemVaultConnectivityHandler.isConnected(reader, pos, otherPos);
|
||||
return state == other && ConnectivityHandler.isConnected(reader, pos, otherPos); //ItemVaultConnectivityHandler.isConnected(reader, pos, otherPos);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,329 +0,0 @@
|
|||
package com.simibubi.create.content.logistics.block.vault;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Direction.Axis;
|
||||
import net.minecraft.core.Direction.AxisDirection;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class ItemVaultConnectivityHandler {
|
||||
|
||||
public static void formVaults(ItemVaultTileEntity te) {
|
||||
VaultSearchCache cache = new VaultSearchCache();
|
||||
List<ItemVaultTileEntity> frontier = new ArrayList<>();
|
||||
frontier.add(te);
|
||||
formVaults(te.getType(), te.getLevel(), cache, frontier);
|
||||
}
|
||||
|
||||
private static void formVaults(BlockEntityType<?> type, BlockGetter world, VaultSearchCache cache,
|
||||
List<ItemVaultTileEntity> frontier) {
|
||||
PriorityQueue<Pair<Integer, ItemVaultTileEntity>> creationQueue = makeCreationQueue();
|
||||
Set<BlockPos> visited = new HashSet<>();
|
||||
|
||||
int minY = Integer.MAX_VALUE;
|
||||
for (ItemVaultTileEntity fluidTankTileEntity : frontier) {
|
||||
BlockPos pos = fluidTankTileEntity.getBlockPos();
|
||||
minY = Math.min(pos.getY(), minY);
|
||||
}
|
||||
|
||||
minY -= 3;
|
||||
|
||||
while (!frontier.isEmpty()) {
|
||||
ItemVaultTileEntity tank = frontier.remove(0);
|
||||
BlockPos tankPos = tank.getBlockPos();
|
||||
if (visited.contains(tankPos))
|
||||
continue;
|
||||
|
||||
visited.add(tankPos);
|
||||
|
||||
int amount = tryToFormNewVault(tank, cache, true);
|
||||
if (amount > 1)
|
||||
creationQueue.add(Pair.of(amount, tank));
|
||||
|
||||
for (Axis axis : Iterate.axes) {
|
||||
Direction d = Direction.fromAxisAndDirection(axis, AxisDirection.NEGATIVE);
|
||||
BlockPos next = tankPos.relative(d);
|
||||
|
||||
if (next.getY() <= minY)
|
||||
continue;
|
||||
if (visited.contains(next))
|
||||
continue;
|
||||
ItemVaultTileEntity nextTank = vaultAt(type, world, next);
|
||||
if (nextTank == null)
|
||||
continue;
|
||||
if (nextTank.isRemoved())
|
||||
continue;
|
||||
frontier.add(nextTank);
|
||||
}
|
||||
}
|
||||
|
||||
visited.clear();
|
||||
|
||||
while (!creationQueue.isEmpty()) {
|
||||
Pair<Integer, ItemVaultTileEntity> next = creationQueue.poll();
|
||||
ItemVaultTileEntity toCreate = next.getValue();
|
||||
if (visited.contains(toCreate.getBlockPos()))
|
||||
continue;
|
||||
visited.add(toCreate.getBlockPos());
|
||||
tryToFormNewVault(toCreate, cache, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void splitVault(ItemVaultTileEntity te) {
|
||||
splitVaultAndInvalidate(te, null, false);
|
||||
}
|
||||
|
||||
private static int tryToFormNewVault(ItemVaultTileEntity te, VaultSearchCache cache, boolean simulate) {
|
||||
int bestWidth = 1;
|
||||
int bestAmount = -1;
|
||||
|
||||
if (!te.isController())
|
||||
return 0;
|
||||
|
||||
for (int w = 1; w <= 3; w++) {
|
||||
int amount = tryToFormNewVaultOfRadius(te, w, cache, true);
|
||||
if (amount < bestAmount)
|
||||
continue;
|
||||
bestWidth = w;
|
||||
bestAmount = amount;
|
||||
}
|
||||
|
||||
if (!simulate) {
|
||||
if (te.radius == bestWidth && te.radius * te.radius * te.length == bestAmount)
|
||||
return bestAmount;
|
||||
|
||||
splitVaultAndInvalidate(te, cache, false);
|
||||
tryToFormNewVaultOfRadius(te, bestWidth, cache, simulate);
|
||||
te.updateConnectivity = false;
|
||||
te.radius = bestWidth;
|
||||
te.length = bestAmount / bestWidth / bestWidth;
|
||||
|
||||
BlockState state = te.getBlockState();
|
||||
if (ItemVaultBlock.isVault(state))
|
||||
te.getLevel()
|
||||
.setBlock(te.getBlockPos(), state.setValue(ItemVaultBlock.LARGE, te.radius > 2), 22);
|
||||
|
||||
te.itemCapability.invalidate();
|
||||
te.setChanged();
|
||||
}
|
||||
|
||||
return bestAmount;
|
||||
}
|
||||
|
||||
private static int tryToFormNewVaultOfRadius(ItemVaultTileEntity te, int width, VaultSearchCache cache,
|
||||
boolean simulate) {
|
||||
int amount = 0;
|
||||
int height = 0;
|
||||
BlockEntityType<?> type = te.getType();
|
||||
Level world = te.getLevel();
|
||||
BlockPos origin = te.getBlockPos();
|
||||
boolean alongZ = ItemVaultBlock.getVaultBlockAxis(te.getBlockState()) == Axis.Z;
|
||||
|
||||
Search:
|
||||
|
||||
for (int yOffset = 0; yOffset < ItemVaultTileEntity.getMaxLength(width); yOffset++) {
|
||||
for (int xOffset = 0; xOffset < width; xOffset++) {
|
||||
for (int zOffset = 0; zOffset < width; zOffset++) {
|
||||
|
||||
BlockPos pos =
|
||||
alongZ ? origin.offset(xOffset, zOffset, yOffset) : origin.offset(yOffset, xOffset, zOffset);
|
||||
Optional<ItemVaultTileEntity> tank = cache.getOrCache(type, world, pos);
|
||||
if (!tank.isPresent())
|
||||
break Search;
|
||||
|
||||
ItemVaultTileEntity controller = tank.get();
|
||||
int otherWidth = controller.radius;
|
||||
if (otherWidth > width)
|
||||
break Search;
|
||||
if (otherWidth == width && controller.length == ItemVaultTileEntity.getMaxLength(width))
|
||||
break Search;
|
||||
if ((ItemVaultBlock.getVaultBlockAxis(controller.getBlockState()) == Axis.Z) != alongZ)
|
||||
break Search;
|
||||
|
||||
BlockPos controllerPos = controller.getBlockPos();
|
||||
if (!controllerPos.equals(origin)) {
|
||||
if (alongZ && controllerPos.getX() < origin.getX())
|
||||
break Search;
|
||||
if (controllerPos.getY() < origin.getY())
|
||||
break Search;
|
||||
if (!alongZ && controllerPos.getZ() < origin.getZ())
|
||||
break Search;
|
||||
if (alongZ && controllerPos.getX() + otherWidth > origin.getX() + width)
|
||||
break Search;
|
||||
if (controllerPos.getY() + otherWidth > origin.getY() + width)
|
||||
break Search;
|
||||
if (!alongZ && controllerPos.getZ() + otherWidth > origin.getZ() + width)
|
||||
break Search;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
amount += width * width;
|
||||
height++;
|
||||
}
|
||||
|
||||
if (simulate)
|
||||
return amount;
|
||||
|
||||
for (int yOffset = 0; yOffset < height; yOffset++) {
|
||||
for (int xOffset = 0; xOffset < width; xOffset++) {
|
||||
for (int zOffset = 0; zOffset < width; zOffset++) {
|
||||
BlockPos pos =
|
||||
alongZ ? origin.offset(xOffset, zOffset, yOffset) : origin.offset(yOffset, xOffset, zOffset);
|
||||
ItemVaultTileEntity tank = vaultAt(type, world, pos);
|
||||
if (tank == te)
|
||||
continue;
|
||||
|
||||
splitVaultAndInvalidate(tank, cache, false);
|
||||
tank.setController(origin);
|
||||
tank.updateConnectivity = false;
|
||||
cache.put(pos, te);
|
||||
|
||||
BlockState state = world.getBlockState(pos);
|
||||
if (!ItemVaultBlock.isVault(state))
|
||||
continue;
|
||||
state = state.setValue(ItemVaultBlock.LARGE, width > 2);
|
||||
world.setBlock(pos, state, 22);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
private static void splitVaultAndInvalidate(ItemVaultTileEntity te, @Nullable VaultSearchCache cache,
|
||||
boolean tryReconnect) {
|
||||
// tryReconnect helps whenever only few tanks have been removed
|
||||
|
||||
te = te.getControllerTE();
|
||||
if (te == null)
|
||||
return;
|
||||
|
||||
int height = te.length;
|
||||
int width = te.radius;
|
||||
BlockState state = te.getBlockState();
|
||||
boolean alongZ = ItemVaultBlock.getVaultBlockAxis(state) == Axis.Z;
|
||||
if (width == 1 && height == 1)
|
||||
return;
|
||||
|
||||
Level world = te.getLevel();
|
||||
BlockPos origin = te.getBlockPos();
|
||||
List<ItemVaultTileEntity> frontier = new ArrayList<>();
|
||||
|
||||
for (int yOffset = 0; yOffset < height; yOffset++) {
|
||||
for (int xOffset = 0; xOffset < width; xOffset++) {
|
||||
for (int zOffset = 0; zOffset < width; zOffset++) {
|
||||
|
||||
BlockPos pos =
|
||||
alongZ ? origin.offset(xOffset, zOffset, yOffset) : origin.offset(yOffset, xOffset, zOffset);
|
||||
ItemVaultTileEntity tankAt = vaultAt(te.getType(), world, pos);
|
||||
if (tankAt == null)
|
||||
continue;
|
||||
if (!tankAt.getController()
|
||||
.equals(origin))
|
||||
continue;
|
||||
|
||||
tankAt.removeController(true);
|
||||
|
||||
if (tryReconnect) {
|
||||
frontier.add(tankAt);
|
||||
tankAt.updateConnectivity = false;
|
||||
}
|
||||
if (cache != null)
|
||||
cache.put(pos, tankAt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
te.itemCapability.invalidate();
|
||||
if (tryReconnect)
|
||||
formVaults(te.getType(), world, cache == null ? new VaultSearchCache() : cache, frontier);
|
||||
}
|
||||
|
||||
private static PriorityQueue<Pair<Integer, ItemVaultTileEntity>> makeCreationQueue() {
|
||||
return new PriorityQueue<>(new Comparator<Pair<Integer, ItemVaultTileEntity>>() {
|
||||
@Override
|
||||
public int compare(Pair<Integer, ItemVaultTileEntity> o1, Pair<Integer, ItemVaultTileEntity> o2) {
|
||||
return o2.getKey() - o1.getKey();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ItemVaultTileEntity vaultAt(BlockEntityType<?> type, BlockGetter world, BlockPos pos) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
if (te instanceof ItemVaultTileEntity && te.getType() == type)
|
||||
return (ItemVaultTileEntity) te;
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class VaultSearchCache {
|
||||
Map<BlockPos, Optional<ItemVaultTileEntity>> controllerMap;
|
||||
|
||||
public VaultSearchCache() {
|
||||
controllerMap = new HashMap<>();
|
||||
}
|
||||
|
||||
void put(BlockPos pos, ItemVaultTileEntity target) {
|
||||
controllerMap.put(pos, Optional.of(target));
|
||||
}
|
||||
|
||||
void putEmpty(BlockPos pos) {
|
||||
controllerMap.put(pos, Optional.empty());
|
||||
}
|
||||
|
||||
boolean hasVisited(BlockPos pos) {
|
||||
return controllerMap.containsKey(pos);
|
||||
}
|
||||
|
||||
Optional<ItemVaultTileEntity> getOrCache(BlockEntityType<?> type, BlockGetter world, BlockPos pos) {
|
||||
if (hasVisited(pos))
|
||||
return controllerMap.get(pos);
|
||||
ItemVaultTileEntity tankAt = vaultAt(type, world, pos);
|
||||
if (tankAt == null) {
|
||||
putEmpty(pos);
|
||||
return Optional.empty();
|
||||
}
|
||||
ItemVaultTileEntity controller = tankAt.getControllerTE();
|
||||
if (controller == null) {
|
||||
putEmpty(pos);
|
||||
return Optional.empty();
|
||||
}
|
||||
put(pos, controller);
|
||||
return Optional.of(controller);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static boolean isConnected(BlockGetter world, BlockPos tankPos, BlockPos otherTankPos) {
|
||||
BlockEntity te1 = world.getBlockEntity(tankPos);
|
||||
BlockEntity te2 = world.getBlockEntity(otherTankPos);
|
||||
if (!(te1 instanceof ItemVaultTileEntity) || !(te2 instanceof ItemVaultTileEntity))
|
||||
return false;
|
||||
return ((ItemVaultTileEntity) te1).getController()
|
||||
.equals(((ItemVaultTileEntity) te2).getController());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.content.logistics.block.vault;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.api.connectivity.ConnectivityHandler;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -64,7 +65,7 @@ public class ItemVaultItem extends BlockItem {
|
|||
|
||||
if (!ItemVaultBlock.isVault(placedOnState))
|
||||
return;
|
||||
ItemVaultTileEntity tankAt = ItemVaultConnectivityHandler.vaultAt(AllTileEntities.ITEM_VAULT.get(), world, placedOnPos);
|
||||
ItemVaultTileEntity tankAt = ConnectivityHandler.partAt(AllTileEntities.ITEM_VAULT.get(), world, placedOnPos);
|
||||
if (tankAt == null)
|
||||
return;
|
||||
ItemVaultTileEntity controllerTE = tankAt.getControllerTE();
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.simibubi.create.content.logistics.block.vault;
|
|||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.api.connectivity.ConnectivityHandler;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.tileEntity.IMultiTileContainer;
|
||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||
|
@ -25,7 +26,7 @@ import net.minecraftforge.items.IItemHandlerModifiable;
|
|||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
||||
|
||||
public class ItemVaultTileEntity extends SmartTileEntity implements IMultiTileContainer {
|
||||
public class ItemVaultTileEntity extends SmartTileEntity implements IMultiTileContainer.Inventory {
|
||||
|
||||
protected LazyOptional<IItemHandler> itemCapability;
|
||||
|
||||
|
@ -62,7 +63,7 @@ public class ItemVaultTileEntity extends SmartTileEntity implements IMultiTileCo
|
|||
return;
|
||||
if (!isController())
|
||||
return;
|
||||
ItemVaultConnectivityHandler.formVaults(this);
|
||||
ConnectivityHandler.formMulti(this);
|
||||
}
|
||||
|
||||
protected void updateComparators() {
|
||||
|
@ -94,7 +95,7 @@ public class ItemVaultTileEntity extends SmartTileEntity implements IMultiTileCo
|
|||
if (updateConnectivity)
|
||||
updateConnectivity();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BlockPos getLastKnownPos() {
|
||||
return lastKnownPos;
|
||||
|
@ -105,7 +106,7 @@ public class ItemVaultTileEntity extends SmartTileEntity implements IMultiTileCo
|
|||
return controller == null || worldPosition.getX() == controller.getX()
|
||||
&& worldPosition.getY() == controller.getY() && worldPosition.getZ() == controller.getZ();
|
||||
}
|
||||
|
||||
|
||||
private void onPositionChanged() {
|
||||
removeController(true);
|
||||
lastKnownPos = worldPosition;
|
||||
|
@ -155,7 +156,7 @@ public class ItemVaultTileEntity extends SmartTileEntity implements IMultiTileCo
|
|||
public BlockPos getController() {
|
||||
return isController() ? worldPosition : controller;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void read(CompoundTag compound, boolean clientPacket) {
|
||||
super.read(compound, clientPacket);
|
||||
|
@ -209,11 +210,11 @@ public class ItemVaultTileEntity extends SmartTileEntity implements IMultiTileCo
|
|||
compound.put("Inventory", inventory.serializeNBT());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public ItemStackHandler getInventoryOfBlock() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
|
||||
public void applyInventoryToBlock(ItemStackHandler handler) {
|
||||
for (int i = 0; i < inventory.getSlots(); i++)
|
||||
inventory.setStackInSlot(i, i < handler.getSlots() ? handler.getStackInSlot(i) : ItemStack.EMPTY);
|
||||
|
@ -248,7 +249,7 @@ public class ItemVaultTileEntity extends SmartTileEntity implements IMultiTileCo
|
|||
BlockPos vaultPos = alongZ ? worldPosition.offset(xOffset, zOffset, yOffset)
|
||||
: worldPosition.offset(yOffset, xOffset, zOffset);
|
||||
ItemVaultTileEntity vaultAt =
|
||||
ItemVaultConnectivityHandler.vaultAt(AllTileEntities.ITEM_VAULT.get(), level, vaultPos);
|
||||
ConnectivityHandler.partAt(AllTileEntities.ITEM_VAULT.get(), level, vaultPos);
|
||||
invs[yOffset * radius * radius + xOffset * radius + zOffset] =
|
||||
vaultAt != null ? vaultAt.inventory : new ItemStackHandler();
|
||||
}
|
||||
|
@ -263,4 +264,45 @@ public class ItemVaultTileEntity extends SmartTileEntity implements IMultiTileCo
|
|||
return radius * 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preventConnectivityUpdate() { updateConnectivity = false; }
|
||||
|
||||
@Override
|
||||
public void notifyMultiUpdated() {
|
||||
BlockState state = this.getBlockState();
|
||||
if (ItemVaultBlock.isVault(state)) { // safety
|
||||
level.setBlock(getBlockPos(), state.setValue(ItemVaultBlock.LARGE, radius > 2), 22);
|
||||
}
|
||||
itemCapability.invalidate();
|
||||
setChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Direction.Axis getMainConnectionAxis() { return getMainAxisOf(this); }
|
||||
|
||||
@Override
|
||||
public int getMaxLength(Direction.Axis longAxis, int width) {
|
||||
if (longAxis == Direction.Axis.Y) return getMaxWidth();
|
||||
return getMaxLength(width);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxWidth() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() { return length; }
|
||||
|
||||
@Override
|
||||
public int getWidth() { return radius; }
|
||||
|
||||
@Override
|
||||
public void setHeight(int height) { this.length = height; }
|
||||
|
||||
@Override
|
||||
public void setWidth(int width) { this.radius = width; }
|
||||
|
||||
@Override
|
||||
public boolean hasInventory() { return true; }
|
||||
}
|
||||
|
|
|
@ -77,6 +77,13 @@ public interface ItemAttribute {
|
|||
return attributeType;
|
||||
}
|
||||
|
||||
static ItemAttribute fromNBT(CompoundTag nbt) {
|
||||
for (ItemAttribute itemAttribute : types)
|
||||
if (itemAttribute.canRead(nbt))
|
||||
return itemAttribute.readNBT(nbt.getCompound(itemAttribute.getNBTKey()));
|
||||
return null;
|
||||
}
|
||||
|
||||
default boolean appliesTo(ItemStack stack, Level world) {
|
||||
return appliesTo(stack);
|
||||
}
|
||||
|
@ -87,29 +94,20 @@ public interface ItemAttribute {
|
|||
return listAttributesOf(stack);
|
||||
}
|
||||
|
||||
public List<ItemAttribute> listAttributesOf(ItemStack stack);
|
||||
List<ItemAttribute> listAttributesOf(ItemStack stack);
|
||||
|
||||
public String getTranslationKey();
|
||||
String getTranslationKey();
|
||||
|
||||
void writeNBT(CompoundTag nbt);
|
||||
|
||||
ItemAttribute readNBT(CompoundTag nbt);
|
||||
|
||||
public default void serializeNBT(CompoundTag nbt) {
|
||||
default void serializeNBT(CompoundTag nbt) {
|
||||
CompoundTag compound = new CompoundTag();
|
||||
writeNBT(compound);
|
||||
nbt.put(getNBTKey(), compound);
|
||||
}
|
||||
|
||||
public static ItemAttribute fromNBT(CompoundTag nbt) {
|
||||
for (ItemAttribute itemAttribute : types) {
|
||||
if (!itemAttribute.canRead(nbt))
|
||||
continue;
|
||||
return itemAttribute.readNBT(nbt.getCompound(itemAttribute.getNBTKey()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
default Object[] getTranslationParameters() {
|
||||
return new String[0];
|
||||
}
|
||||
|
|
|
@ -22,8 +22,8 @@ public class SchematicannonInstance extends BlockEntityInstance<SchematicannonTi
|
|||
|
||||
Material<ModelData> mat = getTransformMaterial();
|
||||
|
||||
connector = mat.getModel(AllBlockPartials.SCHEMATICANNON_CONNECTOR, blockState).createInstance();
|
||||
pipe = mat.getModel(AllBlockPartials.SCHEMATICANNON_PIPE, blockState).createInstance();
|
||||
connector = mat.getModel(AllBlockPartials.SCHEMATICANNON_CONNECTOR).createInstance();
|
||||
pipe = mat.getModel(AllBlockPartials.SCHEMATICANNON_PIPE).createInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.simibubi.create.content.schematics.client;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
|
@ -33,7 +33,7 @@ public class SchematicRenderer {
|
|||
|
||||
private static final ThreadLocal<ThreadLocalObjects> THREAD_LOCAL_OBJECTS = ThreadLocal.withInitial(ThreadLocalObjects::new);
|
||||
|
||||
private final Map<RenderType, SuperByteBuffer> bufferCache = new HashMap<>(getLayerCount());
|
||||
private final Map<RenderType, SuperByteBuffer> bufferCache = new LinkedHashMap<>(getLayerCount());
|
||||
private boolean active;
|
||||
private boolean changed;
|
||||
protected SchematicWorld schematic;
|
||||
|
|
|
@ -30,6 +30,7 @@ import com.tterrag.registrate.util.nullness.NonNullFunction;
|
|||
import com.tterrag.registrate.util.nullness.NonNullSupplier;
|
||||
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
|
@ -168,12 +169,26 @@ public class CreateRegistrate extends AbstractRegistrate<CreateRegistrate> {
|
|||
Create.asResource("fluid/" + name + "_flow"), attributesFactory, factory));
|
||||
}
|
||||
|
||||
public <T extends ForgeFlowingFluid> FluidBuilder<T, CreateRegistrate> virtualFluid(String name, ResourceLocation still, ResourceLocation flow,
|
||||
BiFunction<FluidAttributes.Builder, Fluid, FluidAttributes> attributesFactory,
|
||||
NonNullFunction<ForgeFlowingFluid.Properties, T> factory) {
|
||||
return entry(name,
|
||||
c -> new VirtualFluidBuilder<>(self(), self(), name, c, still,
|
||||
flow, attributesFactory, factory));
|
||||
}
|
||||
|
||||
public FluidBuilder<VirtualFluid, CreateRegistrate> virtualFluid(String name) {
|
||||
return entry(name,
|
||||
c -> new VirtualFluidBuilder<>(self(), self(), name, c, Create.asResource("fluid/" + name + "_still"),
|
||||
Create.asResource("fluid/" + name + "_flow"), null, VirtualFluid::new));
|
||||
}
|
||||
|
||||
public FluidBuilder<VirtualFluid, CreateRegistrate> virtualFluid(String name, ResourceLocation still, ResourceLocation flow) {
|
||||
return entry(name,
|
||||
c -> new VirtualFluidBuilder<>(self(), self(), name, c, still,
|
||||
flow, null, VirtualFluid::new));
|
||||
}
|
||||
|
||||
public FluidBuilder<ForgeFlowingFluid.Flowing, CreateRegistrate> standardFluid(String name) {
|
||||
return fluid(name, Create.asResource("fluid/" + name + "_still"), Create.asResource("fluid/" + name + "_flow"));
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ public class CrushingRecipeGen extends ProcessingRecipeGen {
|
|||
DEEP_REDSTONE_ORE = deepslateOre(() -> Items.DEEPSLATE_REDSTONE_ORE, () -> Items.REDSTONE, 7.5f, 350),
|
||||
DEEP_LAPIS_ORE = deepslateOre(() -> Items.DEEPSLATE_LAPIS_ORE, () -> Items.LAPIS_LAZULI, 12.5f, 350),
|
||||
|
||||
NETHER_GOLD_ORE = netherOre(() -> Items.NETHER_GOLD_ORE, () -> Items.GOLD_NUGGET, 7.5f, 350),
|
||||
NETHER_GOLD_ORE = netherOre(() -> Items.NETHER_GOLD_ORE, () -> Items.GOLD_NUGGET, 18, 350),
|
||||
NETHER_QUARTZ_ORE = netherOre(() -> Items.NETHER_QUARTZ_ORE, () -> Items.QUARTZ, 2.25f, 350),
|
||||
|
||||
RAW_COPPER_ORE = rawOre(() -> Items.RAW_COPPER, AllItems.CRUSHED_COPPER::get, 1),
|
||||
|
|
|
@ -229,7 +229,7 @@ public class ItemHelper {
|
|||
for (int slot = 0; slot < inv.getSlots(); slot++) {
|
||||
if (extracting.isEmpty()) {
|
||||
ItemStack stackInSlot = inv.getStackInSlot(slot);
|
||||
if (stackInSlot.isEmpty())
|
||||
if (stackInSlot.isEmpty() || !test.test(stackInSlot))
|
||||
continue;
|
||||
int maxExtractionCountForItem = amountFunction.apply(stackInSlot);
|
||||
if (maxExtractionCountForItem == 0)
|
||||
|
|
|
@ -1,12 +1,75 @@
|
|||
package com.simibubi.create.foundation.tileEntity;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.IFluidTank;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public interface IMultiTileContainer {
|
||||
|
||||
public BlockPos getController();
|
||||
public boolean isController();
|
||||
public void setController(BlockPos pos);
|
||||
public BlockPos getLastKnownPos();
|
||||
|
||||
BlockPos getController();
|
||||
<T extends BlockEntity & IMultiTileContainer> T getControllerTE ();
|
||||
boolean isController();
|
||||
void setController(BlockPos pos);
|
||||
void removeController (boolean keepContents);
|
||||
BlockPos getLastKnownPos();
|
||||
|
||||
void preventConnectivityUpdate ();
|
||||
void notifyMultiUpdated ();
|
||||
|
||||
// only used for FluidTank windows at present. Might be useful for similar properties on other things?
|
||||
default void setExtraData (@Nullable Object data) {}
|
||||
@Nullable
|
||||
default Object getExtraData () { return null; }
|
||||
default Object modifyExtraData (Object data) { return data; }
|
||||
|
||||
// multiblock structural information
|
||||
Direction.Axis getMainConnectionAxis();
|
||||
default Direction.Axis getMainAxisOf (BlockEntity be) { // this feels redundant, but it gives us a default to use when defining ::getMainConnectionAxis
|
||||
BlockState state = be.getBlockState();
|
||||
|
||||
Direction.Axis axis;
|
||||
if (state.hasProperty(BlockStateProperties.HORIZONTAL_AXIS)) {
|
||||
axis = state.getValue(BlockStateProperties.HORIZONTAL_AXIS);
|
||||
}
|
||||
else if (state.hasProperty(BlockStateProperties.FACING)) {
|
||||
axis = state.getValue(BlockStateProperties.FACING).getAxis();
|
||||
}
|
||||
else if (state.hasProperty(BlockStateProperties.HORIZONTAL_FACING)) {
|
||||
axis = state.getValue(BlockStateProperties.HORIZONTAL_FACING).getAxis();
|
||||
}
|
||||
else axis = Direction.Axis.Y;
|
||||
|
||||
return axis;
|
||||
}
|
||||
|
||||
int getMaxLength (Direction.Axis longAxis, int width);
|
||||
int getMaxWidth ();
|
||||
|
||||
int getHeight ();
|
||||
void setHeight (int height);
|
||||
int getWidth ();
|
||||
void setWidth (int width);
|
||||
|
||||
public interface Inventory extends IMultiTileContainer {
|
||||
default boolean hasInventory() { return false; }
|
||||
}
|
||||
|
||||
public interface Fluid extends IMultiTileContainer {
|
||||
// done here rather than through the Capability to allow greater flexibility
|
||||
default boolean hasTank() { return false; }
|
||||
|
||||
default int getTankSize(int tank) { return 0; }
|
||||
|
||||
default void setTankSize(int tank, int blocks) {}
|
||||
|
||||
default IFluidTank getTank(int tank) { return null; }
|
||||
|
||||
default FluidStack getFluid(int tank) { return FluidStack.EMPTY; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,8 @@ import net.minecraft.world.phys.Vec3;
|
|||
|
||||
public class TransportedItemStackHandlerBehaviour extends TileEntityBehaviour {
|
||||
|
||||
public static BehaviourType<TransportedItemStackHandlerBehaviour> TYPE = new BehaviourType<>();
|
||||
public static final BehaviourType<TransportedItemStackHandlerBehaviour> TYPE = new BehaviourType<>();
|
||||
|
||||
private ProcessingCallback processingCallback;
|
||||
private PositionGetter positionGetter;
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ import net.minecraftforge.items.ItemHandlerHelper;
|
|||
|
||||
public class FilteringBehaviour extends TileEntityBehaviour {
|
||||
|
||||
public static BehaviourType<FilteringBehaviour> TYPE = new BehaviourType<>();
|
||||
public static final BehaviourType<FilteringBehaviour> TYPE = new BehaviourType<>();
|
||||
|
||||
ValueBoxTransform slotPositioning;
|
||||
boolean showCount;
|
||||
|
|
|
@ -22,7 +22,7 @@ import net.minecraftforge.fluids.capability.IFluidHandler;
|
|||
|
||||
public class SmartFluidTankBehaviour extends TileEntityBehaviour {
|
||||
|
||||
public static BehaviourType<SmartFluidTankBehaviour>
|
||||
public static final BehaviourType<SmartFluidTankBehaviour>
|
||||
|
||||
TYPE = new BehaviourType<>(), INPUT = new BehaviourType<>("Input"), OUTPUT = new BehaviourType<>("Output");
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
|
|||
|
||||
public class TankManipulationBehaviour extends CapManipulationBehaviourBase<IFluidHandler, TankManipulationBehaviour> {
|
||||
|
||||
public static BehaviourType<TankManipulationBehaviour> OBSERVE = new BehaviourType<>();
|
||||
public static final BehaviourType<TankManipulationBehaviour> OBSERVE = new BehaviourType<>();
|
||||
private BehaviourType<TankManipulationBehaviour> behaviourType;
|
||||
|
||||
public TankManipulationBehaviour(SmartTileEntity te, InterfaceProvider target) {
|
||||
|
|
|
@ -23,7 +23,7 @@ import net.minecraft.world.phys.Vec3;
|
|||
|
||||
public class LinkBehaviour extends TileEntityBehaviour implements IRedstoneLinkable {
|
||||
|
||||
public static BehaviourType<LinkBehaviour> TYPE = new BehaviourType<>();
|
||||
public static final BehaviourType<LinkBehaviour> TYPE = new BehaviourType<>();
|
||||
|
||||
enum Mode {
|
||||
TRANSMIT, RECEIVE
|
||||
|
|
|
@ -18,7 +18,7 @@ import net.minecraft.world.phys.Vec3;
|
|||
|
||||
public class ScrollValueBehaviour extends TileEntityBehaviour {
|
||||
|
||||
public static BehaviourType<ScrollValueBehaviour> TYPE = new BehaviourType<>();
|
||||
public static final BehaviourType<ScrollValueBehaviour> TYPE = new BehaviourType<>();
|
||||
|
||||
ValueBoxTransform slotPositioning;
|
||||
Vec3 textShift;
|
||||
|
|
|
@ -10,7 +10,7 @@ import net.minecraft.nbt.CompoundTag;
|
|||
|
||||
public class DeferralBehaviour extends TileEntityBehaviour {
|
||||
|
||||
public static BehaviourType<DeferralBehaviour> TYPE = new BehaviourType<>();
|
||||
public static final BehaviourType<DeferralBehaviour> TYPE = new BehaviourType<>();
|
||||
|
||||
private boolean needsUpdate;
|
||||
private Supplier<Boolean> callback;
|
||||
|
|
|
@ -18,7 +18,7 @@ Technology that empowers the player.'''
|
|||
[[dependencies.create]]
|
||||
modId="forge"
|
||||
mandatory=true
|
||||
versionRange="[40.0.0,)"
|
||||
versionRange="[40.1.0,)"
|
||||
ordering="NONE"
|
||||
side="BOTH"
|
||||
|
||||
|
@ -32,6 +32,6 @@ Technology that empowers the player.'''
|
|||
[[dependencies.create]]
|
||||
modId="flywheel"
|
||||
mandatory=true
|
||||
versionRange="[1.18-0.6.2,1.18-0.6.3)"
|
||||
versionRange="[1.18-0.7.0,1.18-0.7.1)"
|
||||
ordering="AFTER"
|
||||
side="CLIENT"
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,4 @@
|
|||
{
|
||||
"_": "Missing Localizations: 330",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -567,11 +566,12 @@
|
|||
"item.create.chromatic_compound": "Compuesto cromático",
|
||||
"item.create.cinder_flour": "Harina del Nether",
|
||||
"item.create.copper_backtank": "Depósito trasero de cobre",
|
||||
"item.create.copper_backtank_placeable": "Depósito de cobre colocable",
|
||||
"item.create.copper_nugget": "Pepita de cobre",
|
||||
"item.create.copper_sheet": "Lámina de cobre",
|
||||
"item.create.crafter_slot_cover": "Tapa de ranura del ensamblador mecánico",
|
||||
"item.create.crafting_blueprint": "Plano de elaboración",
|
||||
"item.create.creative_blaze_cake": "´Pastel de blaze creativo",
|
||||
"item.create.creative_blaze_cake": "Pastel de blaze creativo",
|
||||
"item.create.crushed_aluminum_ore": "Mineral de aluminio molido",
|
||||
"item.create.crushed_copper_ore": "Mineral de cobre molido",
|
||||
"item.create.crushed_gold_ore": "Mineral de oro molido",
|
||||
|
@ -636,7 +636,7 @@
|
|||
|
||||
"advancement.create.root": "Bienvenido a Create",
|
||||
"advancement.create.root.desc": "¡Es hora de empezar a construir increíbles artefactos animados!",
|
||||
"advancement.creatse.andesite_alloy": "Aleaciones en abundancia",
|
||||
"advancement.create.andesite_alloy": "Aliteraciones a montones",
|
||||
"advancement.create.andesite_alloy.desc": "Los materiales de Create tienen nombres extraños, la aleación de andesita es uno de ellos.",
|
||||
"advancement.create.its_alive": "¡Está vivo!",
|
||||
"advancement.create.its_alive.desc": "Mira cómo gira tu primer componente cinético.",
|
||||
|
@ -821,6 +821,8 @@
|
|||
"create.recipe.fan_washing.fan": "Ventilador detrás del agua fluyente",
|
||||
"create.recipe.fan_smoking": "Ahumador a granel",
|
||||
"create.recipe.fan_smoking.fan": "Ventilador detrás del fuego",
|
||||
"create.recipe.fan_haunting": "Maldecidor a granel",
|
||||
"create.recipe.fan_haunting.fan": "Ventilador detrás del fuego de alma",
|
||||
"create.recipe.fan_blasting": "Voladuras a granel",
|
||||
"create.recipe.fan_blasting.fan": "Ventilador detrás de la lava",
|
||||
"create.recipe.pressing": "Prensando",
|
||||
|
@ -1163,6 +1165,8 @@
|
|||
"create.item_attributes.furnace_fuel.inverted": "no es combustible para hornos",
|
||||
"create.item_attributes.washable": "se puede lavar",
|
||||
"create.item_attributes.washable.inverted": "no se puede lavar",
|
||||
"create.item_attributes.hauntable": "puede ser maldito",
|
||||
"create.item_attributes.hauntable.inverted": "no puede ser maldito",
|
||||
"create.item_attributes.crushable": "puede ser molido",
|
||||
"create.item_attributes.crushable.inverted": "no puede ser molido",
|
||||
"create.item_attributes.smeltable": "se puede fundir",
|
||||
|
@ -1227,6 +1231,7 @@
|
|||
"create.tooltip.keyCtrl": "Ctrl",
|
||||
"create.tooltip.speedRequirement": "Requisitos de velocidad: %1$s",
|
||||
"create.tooltip.speedRequirement.none": "Ninguno",
|
||||
"create.tooltip.speedRequirement.slow": "Lento",
|
||||
"create.tooltip.speedRequirement.medium": "Moderado",
|
||||
"create.tooltip.speedRequirement.fast": "Rápido",
|
||||
"create.tooltip.stressImpact": "Impacto de estrés: %1$s",
|
||||
|
@ -2438,6 +2443,6 @@
|
|||
"create.ponder.windmill_structure.header": "Artefactos estacionarios de molinos de viento",
|
||||
"create.ponder.windmill_structure.text_1": "Cualquier estructura puede contar como un molino de viento válido, siempre que contenga al menos 8 velas.",
|
||||
|
||||
"_": "¡Gracias por traducir Create!"
|
||||
"_": "Thank you for translating Create!"
|
||||
|
||||
}
|
|
@ -803,6 +803,16 @@
|
|||
"death.attack.create.cuckoo_clock_explosion": "%1$s foi explodido por relógio cuco adulterado",
|
||||
"death.attack.create.cuckoo_clock_explosion.player": "%1$s foi explodido por relógio cuco adulterado",
|
||||
|
||||
"create.block.deployer.damage_source_name": "Implantador rebelde",
|
||||
"create.block.cart_assembler.invalid": "Coloque o seu montador de carrinho de minas num trilho",
|
||||
|
||||
"create.menu.return": "Retornar ao menu",
|
||||
"create.menu.configure": "Configurar...",
|
||||
"create.menu.ponder_index": "Tabela do ponderamento",
|
||||
"create.menu.only_ingame": "Disponível no menu de pausa",
|
||||
"create.menu.project_page": "Página do projeto",
|
||||
"create.menu.report_bugs": "Informar um erro",
|
||||
"create.menu.support": "Suporte nós",
|
||||
|
||||
"create.recipe.crushing": "Triturando",
|
||||
"create.recipe.milling": "Moendo",
|
||||
|
@ -818,6 +828,7 @@
|
|||
"create.recipe.mixing": "Misturando",
|
||||
"create.recipe.deploying": "Implantando",
|
||||
"create.recipe.automatic_shapeless": "Fabricação sem forma automático",
|
||||
"create.recipe.automatic_brewing": "Produção de poções",
|
||||
"create.recipe.packing": "Compactando",
|
||||
"create.recipe.automatic_packing": "Compactamento automático",
|
||||
"create.recipe.sawing": "Serrando",
|
||||
|
@ -869,18 +880,22 @@
|
|||
"create.action.discard": "Descartar",
|
||||
|
||||
"create.keyinfo.toolmenu": "Menu Focal da Ferramenta",
|
||||
"create.keyinfo.toolbelt": "Acessa caixas de ferramenta próximas",
|
||||
"create.keyinfo.scrollup": "Simular a roda do mouse (para cima) (no mundo)",
|
||||
"create.keyinfo.scrolldown": "Simular a roda do mouse (para baixo) (no mundo)",
|
||||
|
||||
"create.gui.scrollInput.defaultTitle": "Escolha uma Opção:",
|
||||
"create.gui.scrollInput.scrollToModify": "Role o mouse para Modificar",
|
||||
"create.gui.scrollInput.scrollToAdjustAmount": "Role o mouse para ajustar a quantidade",
|
||||
"create.gui.scrollInput.scrollToSelect": "Role o mouse para Selecionar",
|
||||
"create.gui.scrollInput.shiftScrollsFaster": "Shift para rolar o mouse mais rapido",
|
||||
"create.gui.toolmenu.focusKey": "Segure [%1$s] para Focar",
|
||||
"create.gui.toolmenu.cycle": "[SCROLL] para Circular",
|
||||
|
||||
"create.toolbox.unequip": "Desequipar: %1$s",
|
||||
"create.toolbox.outOfRange": "Caixa de ferramentas do item segurado fora de alcance",
|
||||
"create.toolbox.detach": "Parar de rastrear e manter item",
|
||||
"create.toolbox.depositAll": "Retornar itens para caixa de ferramenta próxima",
|
||||
"create.toolbox.depositAll": "Retorna itens para caixa de ferramenta próxima",
|
||||
"create.toolbox.depositBox": "Retornar itens para caixa de ferramenta",
|
||||
|
||||
"create.gui.symmetryWand.mirrorType": "Espelhar",
|
||||
|
@ -895,17 +910,90 @@
|
|||
"create.orientation.horizontal": "Horizontal",
|
||||
"create.orientation.alongZ": "Através de Z",
|
||||
"create.orientation.alongX": "Através de X",
|
||||
"create.minecart_coupling.two_couplings_max": "Carrinhos de mina não podem ter mais de dois acoplamentos cada",
|
||||
"create.minecart_coupling.unloaded": "Partes do seu trem aparentam estar em um chunk descarregado",
|
||||
"create.minecart_coupling.no_loops": "Acoplamentos não podem formar um loop",
|
||||
"create.minecart_coupling.removed": "Removeu todos os acoplamentos do carrinho de mina",
|
||||
"create.minecart_coupling.too_far": "Carrinhos de mina estão muito distanciados",
|
||||
|
||||
"create.contraptions.movement_mode": "Modo de movimento",
|
||||
"create.contraptions.movement_mode.move_place": "Sempre colocar quando parado",
|
||||
"create.contraptions.movement_mode.move_place_returned": "Colocar apenas na posição inicial",
|
||||
"create.contraptions.movement_mode.move_never_place": "Colocar apenas caso a âncora seja destruída",
|
||||
"create.contraptions.movement_mode.rotate_place": "Sempre colocar quando parado",
|
||||
"create.contraptions.movement_mode.rotate_place_returned": "Apenas colocar perto do angulo inicial",
|
||||
"create.contraptions.movement_mode.rotate_never_place": "Colocar apenas caso a âncora seja destruída",
|
||||
"create.contraptions.cart_movement_mode": "Modo de movimento do carrinho",
|
||||
"create.contraptions.cart_movement_mode.rotate": "Sempre apontar para a direção do movimento",
|
||||
"create.contraptions.cart_movement_mode.rotate_paused": "Pausar atores quando girando",
|
||||
"create.contraptions.cart_movement_mode.rotation_locked": "Travar a rotação",
|
||||
"create.contraptions.windmill.rotation_direction": "Direção da rotação",
|
||||
"create.contraptions.clockwork.clock_hands": "Ponteiros do relogio",
|
||||
"create.contraptions.clockwork.hour_first": "Ponteiro da hora primeiro",
|
||||
"create.contraptions.clockwork.minute_first": "Ponteiro do minuto primeiro",
|
||||
"create.contraptions.clockwork.hour_first_24": "Ponteiro das 24 horas primeiro",
|
||||
|
||||
"create.logistics.filter": "Filtro",
|
||||
"create.logistics.recipe_filter": "Filtro de receitas",
|
||||
"create.logistics.fluid_filter": "Filtro de fluido",
|
||||
"create.logistics.firstFrequency": "Freq. #1",
|
||||
"create.logistics.secondFrequency": "Freq. #2",
|
||||
"create.logistics.filter.apply": "Aplicou filtro para %1$s.",
|
||||
"create.logistics.filter.apply_click_again": "Aplicou filtro para %1$s, Clique denovo para copiar quantidade.",
|
||||
"create.logistics.filter.apply_count": "Aplicou quantidade de extração para o filtro.",
|
||||
|
||||
"create.gui.goggles.generator_stats": "Estatísticas do gerador:",
|
||||
"create.gui.goggles.kinetic_stats": "Estatísticas cinéticas:",
|
||||
"create.gui.goggles.at_current_speed": "Na velocidade atual",
|
||||
"create.gui.goggles.pole_length": "Comprimento da vara:",
|
||||
"create.gui.goggles.fluid_container": "Informação do recipiente de fluido:",
|
||||
"create.gui.goggles.fluid_container.capacity": "Capacidade: ",
|
||||
"create.gui.assembly.exception": "Não foi possível montar essa engenhoca:",
|
||||
"create.gui.assembly.exception.unmovableBlock": "Bloco imovel (%4$s) em [%1$s,%2$s,%3$s]",
|
||||
"create.gui.assembly.exception.chunkNotLoaded": "O bloco em [%1$s,%2$s,%3$s] não estava em um chunk carregado",
|
||||
"create.gui.assembly.exception.structureTooLarge": "Tem muitos blocos incluídos na engenhoca. O limite configurado é: %1$s",
|
||||
"create.gui.assembly.exception.tooManyPistonPoles": "Tem muitas varetas de extensão colocadas nesse pistão. O limite configurado é: %1$s",
|
||||
"create.gui.assembly.exception.noPistonPoles": "O pistão esta faltando algumas varetas de extensão",
|
||||
"create.gui.assembly.exception.not_enough_sails": "A estrutura conectada não possui o número suficiente de blocos tipo vela: %1$s\nUm mínimo de %2$s são requeridos",
|
||||
"create.gui.gauge.info_header": "Informação do medidor:",
|
||||
"create.gui.speedometer.title": "Velocidade de rotação",
|
||||
"create.gui.stressometer.title": "Estresse do sistema",
|
||||
"create.gui.stressometer.capacity": "Capacidade restante",
|
||||
"create.gui.stressometer.overstressed": "Sobre estressado",
|
||||
"create.gui.stressometer.no_rotation": "Nenhuma rotação",
|
||||
"create.gui.contraptions.not_fast_enough": "Aparenta que esse %1$s não _está_ girando com _a velocidade_ _necessária_.",
|
||||
"create.gui.contraptions.network_overstressed": "Aparenta que essa engenhoca está _sobre estressada_. Adicione mais fontes ou _desacelere_ __ os componentes que tem um _impacto de_ _stress alto_.",
|
||||
"create.gui.adjustable_crate.title": "UNLOCALIZED: Adjustable Crate",
|
||||
"create.gui.adjustable_crate.storageSpace": "UNLOCALIZED: Storage Space",
|
||||
"create.gui.stockpile_switch.title": "Dijuntor de armazenamento",
|
||||
"create.gui.stockpile_switch.invert_signal": "Inverter sinal",
|
||||
"create.gui.stockpile_switch.move_to_lower_at": "Mover para a faixa mais baixa %1$s%%",
|
||||
"create.gui.stockpile_switch.move_to_upper_at": "Mover para a faixa mais alta %1$s%%",
|
||||
"create.gui.sequenced_gearshift.title": "Câmbio sequenciado",
|
||||
"create.gui.sequenced_gearshift.instruction": "Instruções",
|
||||
"create.gui.sequenced_gearshift.instruction.turn_angle.descriptive": "Rotacionar por angulo",
|
||||
"create.gui.sequenced_gearshift.instruction.turn_angle": "Giro",
|
||||
"create.gui.sequenced_gearshift.instruction.turn_angle.angle": "Angulo",
|
||||
"create.gui.sequenced_gearshift.instruction.turn_distance.descriptive": "Rotacionar par mover Pistão/Polia/Portico",
|
||||
"create.gui.sequenced_gearshift.instruction.turn_distance": "Pistão",
|
||||
"create.gui.sequenced_gearshift.instruction.turn_distance.distance": "Distancia",
|
||||
"create.gui.sequenced_gearshift.instruction.delay.descriptive": "Espera",
|
||||
"create.gui.sequenced_gearshift.instruction.delay": "Esperar",
|
||||
"create.gui.sequenced_gearshift.instruction.delay.duration": "Duração",
|
||||
"create.gui.sequenced_gearshift.instruction.end.descriptive": "Terminar",
|
||||
"create.gui.sequenced_gearshift.instruction.end": "Termino",
|
||||
"create.gui.sequenced_gearshift.instruction.await.descriptive": "Esperar novo pulso de redstone",
|
||||
"create.gui.sequenced_gearshift.instruction.await": "Espera",
|
||||
"create.gui.sequenced_gearshift.speed": "Velocidade, Direção",
|
||||
"create.gui.sequenced_gearshift.speed.forward": "Velocidade inicial, Para frente",
|
||||
"create.gui.sequenced_gearshift.speed.forward_fast": "Dobro da velocidade, Para frente",
|
||||
"create.gui.sequenced_gearshift.speed.back": "Velocidade inicial, Para trás",
|
||||
"create.gui.sequenced_gearshift.speed.back_fast": "Dobro da velocidade, Para trás",
|
||||
|
||||
"create.schematicAndQuill.dimensions": "Tamanho Esquema: %1$sx%2$sx%3$s",
|
||||
"create.schematicAndQuill.firstPos": "Primeira posição feita.",
|
||||
"create.schematicAndQuill.secondPos": "Segunda posição feita.",
|
||||
"create.schematicAndQuill.noTarget": "Seguro [Ctrl] para selecionar Blocos de Ar.",
|
||||
"create.schematicAndQuill.noTarget": "Seguro [Ctrl] para seleccionar Blocos de Ar.",
|
||||
"create.schematicAndQuill.abort": "Seleção removida.",
|
||||
"create.schematicAndQuill.title": "Nome do esquema:",
|
||||
"create.schematicAndQuill.convert": "Salvar e carregar arquivo imediatamente",
|
||||
|
@ -945,7 +1033,7 @@
|
|||
"create.schematic.tool.rotate.description.1": "[CTRL]-Rolar para rolar 90 Graus",
|
||||
"create.schematic.tool.rotate.description.2": "",
|
||||
"create.schematic.tool.rotate.description.3": "",
|
||||
"create.schematic.tool.print.description.0": "Coloca estrutura no mundo instantaneamente",
|
||||
"create.schematic.tool.print.description.0": "Colocá estrutura no mundo instantaneamente",
|
||||
"create.schematic.tool.print.description.1": "[Botão-Direito] para confirmar a posição atual.",
|
||||
"create.schematic.tool.print.description.2": "Esta ferramenta é para o Modo Criativo apenas.",
|
||||
"create.schematic.tool.print.description.3": "",
|
||||
|
@ -957,7 +1045,12 @@
|
|||
"create.schematics.synchronizing": "Sincronizando...",
|
||||
"create.schematics.uploadTooLarge": "Seu esquema é muito grande",
|
||||
"create.schematics.maxAllowedSize": "O tamanho máximo permitido para o esquema é:",
|
||||
|
||||
"create.gui.schematicTable.refresh": "atualizar arquivos",
|
||||
"create.gui.schematicTable.open_folder": "Abrir pasta",
|
||||
"create.gui.schematicTable.title": "Mesa de Desenho",
|
||||
"create.gui.schematicTable.availableSchematics": "Esquema disponíveis",
|
||||
"create.gui.schematicTable.noSchematics": "Nenhum esquema salvo",
|
||||
"create.gui.schematicTable.uploading": "Importando...",
|
||||
"create.gui.schematicTable.finished": "Envio Concluído!",
|
||||
"create.gui.schematicannon.title": "Canhão de esquema",
|
||||
|
@ -967,14 +1060,18 @@
|
|||
"create.gui.schematicannon.shotsRemainingWithBackup": "Com backup: %1$s",
|
||||
"create.gui.schematicannon.optionEnabled": "Habilitado Atualmente",
|
||||
"create.gui.schematicannon.optionDisabled": "Desabilitado Atualmente",
|
||||
"create.gui.schematicannon.showOptions": "Mostrar as configurações da impressora",
|
||||
"create.gui.schematicannon.option.dontReplaceSolid": "Não Substituir Blocos Sólidos",
|
||||
"create.gui.schematicannon.option.replaceWithSolid": "Substituir Blocos Sólidos",
|
||||
"create.gui.schematicannon.option.replaceWithAny": "Substituir Sólidos com Qualquer",
|
||||
"create.gui.schematicannon.option.replaceWithEmpty": "Substituir Sólidos com Vazio",
|
||||
"create.gui.schematicannon.option.skipMissing": "Pulando Blocos faltantes",
|
||||
"create.gui.schematicannon.option.skipTileEntities": "Proteger Entidades Entalhadas",
|
||||
"create.gui.schematicannon.option.skipMissing.description": "Se o Canhão de esquema não encontrar o Bloco para colocar, ele irá continuar para a próx. Posição.",
|
||||
"create.gui.schematicannon.option.skipTileEntities.description": "O Canhão de esquema vai evitar substituir blocos que contêm dados como Baus.",
|
||||
"create.gui.schematicannon.option.skipTileEntities": "Proteger tile entities",
|
||||
"create.gui.schematicannon.slot.gunpowder": "Adicionar pólvora para carregar o canhão",
|
||||
"create.gui.schematicannon.slot.listPrinter": "Coloque livros aqui para imprimir uma lista para o seu esquema",
|
||||
"create.gui.schematicannon.slot.schematic": "Adicione o seu esquema aqui. Tenha certeza que ele está colocado em um lugar especifico.",
|
||||
"create.gui.schematicannon.option.skipMissing.description": "Se o Canhão de esquema não encontrar o Bloco para colocar, ele irá continuar para a próxima. Posição.",
|
||||
"create.gui.schematicannon.option.skipTileEntities.description": "O Canhão de esquema vai evitar substituir blocos que contêm dados como Baús.",
|
||||
"create.gui.schematicannon.option.dontReplaceSolid.description": "O Canhão de esquema nunca irá substituir Blocos sólidos na área em trabalho, apenas não-Sólidos e Ar.",
|
||||
"create.gui.schematicannon.option.replaceWithSolid.description": "O Canhão de esquema irá apenas substituir Blocos sólidos na área de trabalho, se o Esquema conter um bloco Sólido naquela posição.",
|
||||
"create.gui.schematicannon.option.replaceWithAny.description": "O Canhão de esquema irá substituir Blocos sólidos na área de trabalho, se o Esquema conter qualquer Bloco naquela posição.",
|
||||
|
@ -998,10 +1095,239 @@
|
|||
"create.schematicannon.status.schematicNotPlaced": "Esquema não Colocado",
|
||||
"create.schematicannon.status.schematicExpired": "Arquivo de Esquema Expirado",
|
||||
|
||||
"create.materialChecklist": "Lista de materiais",
|
||||
"create.gui.filter.deny_list": "Lista de negação",
|
||||
"create.gui.filter.deny_list.description": "Itens passam se eles não encaixam em nenhum dos acima. Uma lista de negação vazia aceita tudo.",
|
||||
"create.gui.filter.allow_list": "Lista de permissão",
|
||||
"create.gui.filter.allow_list.description": "Itens passam se eles se encaixam em algum dos acima. Uma lista de permissão vazia rejeita tudo.",
|
||||
"create.gui.filter.respect_data": "Respeitar informação",
|
||||
"create.gui.filter.respect_data.description": "Itens apenas se encaixam caso a durabilidade, encantamentos e outros atributos se encaixam também.",
|
||||
"create.gui.filter.ignore_data": "Ignorar informação",
|
||||
"create.gui.filter.ignore_data.description": "Itens se enquadram não importa os seus atributos.",
|
||||
|
||||
"create.item_attributes.placeable": "É colocavel",
|
||||
"create.item_attributes.placeable.inverted": "Não é colocavel",
|
||||
"create.item_attributes.consumable": "É comestivel",
|
||||
"create.item_attributes.consumable.inverted": "Não é comestivel",
|
||||
"create.item_attributes.fluid_container": "Pode armazenar fluidos",
|
||||
"create.item_attributes.fluid_container.inverted": "Não pode armazenar fluidos",
|
||||
"create.item_attributes.enchanted": "Está encantado",
|
||||
"create.item_attributes.enchanted.inverted": "Não está encantado",
|
||||
"create.item_attributes.max_enchanted": "Está encantado no nível máximo",
|
||||
"create.item_attributes.max_enchanted.inverted": "Não está encantado no nível maximo",
|
||||
"create.item_attributes.renamed": "Tem nome customizado",
|
||||
"create.item_attributes.renamed.inverted": "Não tem nome customizado",
|
||||
"create.item_attributes.damaged": "Está danificado",
|
||||
"create.item_attributes.damaged.inverted": "Não está danificado",
|
||||
"create.item_attributes.badly_damaged": "Está severamente danificado",
|
||||
"create.item_attributes.badly_damaged.inverted": "Não esta severamente danificado",
|
||||
"create.item_attributes.not_stackable": "Não pode ser empilhado",
|
||||
"create.item_attributes.not_stackable.inverted": "Pode ser empilhado",
|
||||
"create.item_attributes.equipable": "Pode ser equipado",
|
||||
"create.item_attributes.equipable.inverted": "Não pode ser equipado",
|
||||
"create.item_attributes.furnace_fuel": "è combustivel",
|
||||
"create.item_attributes.furnace_fuel.inverted": "Não é combustivel",
|
||||
"create.item_attributes.washable": "Pode ser lavado",
|
||||
"create.item_attributes.washable.inverted": "Não pode ser lavado",
|
||||
"create.item_attributes.hauntable": "Pode ser amaldiçoado",
|
||||
"create.item_attributes.hauntable.inverted": "Não pode ser amaldiçoado",
|
||||
"create.item_attributes.crushable": "Pode ser triturado",
|
||||
"create.item_attributes.crushable.inverted": "Não pode ser triturado",
|
||||
"create.item_attributes.smeltable": "Pode ser fundido",
|
||||
"create.item_attributes.smeltable.inverted": "Não pode ser fundido",
|
||||
"create.item_attributes.smokable": "Pode ser defumado",
|
||||
"create.item_attributes.smokable.inverted": "Não pode ser defumado",
|
||||
"create.item_attributes.blastable": "È fundível no alto-forno",
|
||||
"create.item_attributes.blastable.inverted": "Não é fundível no alto-forno",
|
||||
"create.item_attributes.shulker_level": "O shulker é %1$s",
|
||||
"create.item_attributes.shulker_level.inverted": "O shulker não é %1$s",
|
||||
"create.item_attributes.shulker_level.full": "Cheio",
|
||||
"create.item_attributes.shulker_level.empty": "Vazio",
|
||||
"create.item_attributes.shulker_level.partial": "Parcialmente cheio",
|
||||
"create.item_attributes.in_tag": "è marcado %1$s",
|
||||
"create.item_attributes.in_tag.inverted": "Não é marcado %1$s",
|
||||
"create.item_attributes.in_item_group": "Está no grupo '%1$s'",
|
||||
"create.item_attributes.in_item_group.inverted": "Não esta no grupo '%1$s'",
|
||||
"create.item_attributes.added_by": "Foi adicionado por %1$s",
|
||||
"create.item_attributes.added_by.inverted": "Não foi adicionado por %1$s",
|
||||
"create.item_attributes.has_enchant": "Está encantado com %1$s",
|
||||
"create.item_attributes.has_enchant.inverted": "Não esta encantado com %1$s",
|
||||
"create.item_attributes.color": "Esta tingido de %1$s",
|
||||
"create.item_attributes.color.inverted": "Não está tingido de %1$s",
|
||||
"create.item_attributes.has_fluid": "Contem %1$s",
|
||||
"create.item_attributes.has_fluid.inverted": "Não contem %1$s",
|
||||
"create.item_attributes.has_name": "Tem o nome %1$s",
|
||||
"create.item_attributes.has_name.inverted": "Não tem o nome %1$s",
|
||||
"create.item_attributes.book_author": "Tem a autoria de %1$s",
|
||||
"create.item_attributes.book_author.inverted": "Não tem a autoria de %1$s",
|
||||
"create.item_attributes.book_copy_original": "É original",
|
||||
"create.item_attributes.book_copy_original.inverted": "Não é original",
|
||||
"create.item_attributes.book_copy_first": "É uma cópia da primeira geração",
|
||||
"create.item_attributes.book_copy_first.inverted": "Não é uma copia de primeira geração",
|
||||
"create.item_attributes.book_copy_second": "É uma cópia de segunda geração",
|
||||
"create.item_attributes.book_copy_second.inverted": "Não é uma copia de segunda geração",
|
||||
"create.item_attributes.book_copy_tattered": "É uma bagunça esfarrapada",
|
||||
"create.item_attributes.book_copy_tattered.inverted": "Não é uma bagunça esfarrapada",
|
||||
"create.item_attributes.astralsorcery_amulet": "Melhora %1$s",
|
||||
"create.item_attributes.astralsorcery_amulet.inverted": "Não melhora %1$s",
|
||||
"create.item_attributes.astralsorcery_constellation": "Esta sintonizado a %1$s",
|
||||
"create.item_attributes.astralsorcery_constellation.inverted": "Não esta sintonizado a %1$s",
|
||||
"create.item_attributes.astralsorcery_crystal": "Tem atributos de cristais %1$s",
|
||||
"create.item_attributes.astralsorcery_crystal.inverted": "Não tem atributos de cristais %1$s",
|
||||
"create.item_attributes.astralsorcery_perk_gem": " %1$s Tem um atributo de benefio",
|
||||
"create.item_attributes.astralsorcery_perk_gem.inverted": "%1$s Não tem um atributo de benefio",
|
||||
|
||||
"create.gui.attribute_filter.no_selected_attributes": "Nenhum atributo selecionado",
|
||||
"create.gui.attribute_filter.selected_attributes": "Atributos selecionados:",
|
||||
"create.gui.attribute_filter.add_attribute": "Adicionar atributo a lista",
|
||||
"create.gui.attribute_filter.add_inverted_attribute": "Adicionar atributo oposto a lista",
|
||||
"create.gui.attribute_filter.allow_list_disjunctive": "Lista de permissão (Qualquer)",
|
||||
"create.gui.attribute_filter.allow_list_disjunctive.description": "Itens passam se eles tiverem qualquer atributo selecionado.",
|
||||
"create.gui.attribute_filter.allow_list_conjunctive": "Lista de permissão (Todos)",
|
||||
"create.gui.attribute_filter.allow_list_conjunctive.description": "Itens passam se eles tiverem TODOS atributos selecionados.",
|
||||
"create.gui.attribute_filter.deny_list": "lista de negação",
|
||||
"create.gui.attribute_filter.deny_list.description": "Itens passam se eles NÃO tiverem qualquer atributo selecionado.",
|
||||
"create.gui.attribute_filter.add_reference_item": "Adicionar item referência",
|
||||
|
||||
"create.tooltip.holdForDescription": "Segure [%1$s] para o sumário",
|
||||
"create.tooltip.holdForControls": "Segure [%1$s] para os controles",
|
||||
"create.tooltip.keyShift": "Shift",
|
||||
"create.tooltip.keyCtrl": "Ctrl",
|
||||
"create.tooltip.speedRequirement": "Requerimento de velocidade: %1$s",
|
||||
"create.tooltip.speedRequirement.none": "Nenhum",
|
||||
"create.tooltip.speedRequirement.slow": "Devagar",
|
||||
"create.tooltip.speedRequirement.medium": "Modereado",
|
||||
"create.tooltip.speedRequirement.fast": "Rapido",
|
||||
"create.tooltip.stressImpact": "Impacto de stress: %1$s",
|
||||
"create.tooltip.stressImpact.low": " Baixo",
|
||||
"create.tooltip.stressImpact.medium": " Moderado",
|
||||
"create.tooltip.stressImpact.high": " Alto",
|
||||
"create.tooltip.stressImpact.overstressed": ": Sobre estresse",
|
||||
"create.tooltip.capacityProvided": "Capacidade de stress cinético: %1$s",
|
||||
"create.tooltip.capacityProvided.low": " Pequeno",
|
||||
"create.tooltip.capacityProvided.medium": " Médio",
|
||||
"create.tooltip.capacityProvided.high": " Grande",
|
||||
"create.tooltip.generationSpeed": " Gera em %1$s %2$s",
|
||||
"create.tooltip.analogStrength": " Força analogica: %1$s/15",
|
||||
|
||||
"create.mechanical_arm.extract_from": " Pegar itens de %1$s",
|
||||
"create.mechanical_arm.deposit_to": " Depositar itens para %1$s",
|
||||
"create.mechanical_arm.summary": "Braço mecânico tem %1$s entrada(s) e %2$s saida(s).",
|
||||
"create.mechanical_arm.points_outside_range": "%1$s Ponto(s) de interação removidos pelas limitações de alcance.",
|
||||
|
||||
"create.weighted_ejector.target_set": "Alvo selecionado",
|
||||
"create.weighted_ejector.target_not_valid": "Ejetando para o bloco adjacente (Alvo não foi valido)",
|
||||
"create.weighted_ejector.no_target": "Ejetando para o bloco adjacente (Nenhum alvo foi selecionado)",
|
||||
"create.weighted_ejector.targeting": "Ejetando para [%1$s,%2$s,%3$s]",
|
||||
"create.weighted_ejector.stack_size": "Tamanho da pilha ejetada",
|
||||
|
||||
"create.logistics.when_multiple_outputs_available": "Quando multiplas saidas selecionadas",
|
||||
|
||||
"create.mechanical_arm.selection_mode.round_robin": "Rodízio",
|
||||
"create.mechanical_arm.selection_mode.forced_round_robin": "Rodízio forçado",
|
||||
"create.mechanical_arm.selection_mode.prefer_first": "Preferir primeiro alvo",
|
||||
|
||||
"create.tunnel.selection_mode.split": "Dividir",
|
||||
"create.tunnel.selection_mode.forced_split": "Divisão forçada",
|
||||
"create.tunnel.selection_mode.round_robin": "Rodízio",
|
||||
"create.tunnel.selection_mode.forced_round_robin": "Rodízio forçado",
|
||||
"create.tunnel.selection_mode.prefer_nearest": "Preferir o mais perto",
|
||||
"create.tunnel.selection_mode.randomize": "Aleatorizar",
|
||||
"create.tunnel.selection_mode.synchronize": "Sincronizar as entradas",
|
||||
|
||||
"create.tooltip.chute.header": "Informação da calha",
|
||||
"create.tooltip.chute.items_move_down": "Itens movimentam para baixo",
|
||||
"create.tooltip.chute.items_move_up": "Itens movem para cima",
|
||||
"create.tooltip.chute.no_fans_attached": "Não conectado com um ventilador",
|
||||
"create.tooltip.chute.fans_push_up": "Ventiladores sopram de baixo",
|
||||
"create.tooltip.chute.fans_push_down": "Ventiladores sopram de cima",
|
||||
"create.tooltip.chute.fans_pull_up": "Ventiladores sugam de cima",
|
||||
"create.tooltip.chute.fans_pull_down": "Ventiladores sugam de baixo",
|
||||
"create.tooltip.chute.contains": "Contem: %1$s x%2$s",
|
||||
"create.tooltip.brass_tunnel.contains": "Distribuindo:",
|
||||
"create.tooltip.brass_tunnel.contains_entry": " > %1$s x%2$s",
|
||||
"create.tooltip.brass_tunnel.retrieve": "Clique direito para recuperar item",
|
||||
|
||||
"create.linked_controller.bind_mode": "Modo de vinculação",
|
||||
"create.linked_controller.press_keybind": "Aperte %1$s, %2$s, %3$s, %4$s, %5$s or %6$s, para vincular essa frequencia para tecla respectiva",
|
||||
"create.linked_controller.key_bound": "Frequência vinculada com %1$s",
|
||||
"create.linked_controller.frequency_slot_1": "Tecla: %1$s, Freq. #1",
|
||||
"create.linked_controller.frequency_slot_2": "Tecla: %1$s, Freq. #2",
|
||||
|
||||
"create.crafting_blueprint.crafting_slot": "Slot de ingrediente",
|
||||
"create.crafting_blueprint.filter_items_viable": "Filtros avançados são viaveis",
|
||||
"create.crafting_blueprint.display_slot": "Slot de exibição",
|
||||
"create.crafting_blueprint.inferred": "Deduzido pela receita",
|
||||
"create.crafting_blueprint.manually_assigned": "Designado manualmente",
|
||||
"create.crafting_blueprint.secondary_display_slot": "Slot de exibição secundario",
|
||||
"create.crafting_blueprint.optional": "Opcional",
|
||||
|
||||
"create.potato_cannon.ammo.attack_damage": " %1$s Dano de ataque",
|
||||
"create.potato_cannon.ammo.reload_ticks": " %1$s Velocidade de recarregamento",
|
||||
"create.potato_cannon.ammo.knockback": " %1$s Repulsão do projetil",
|
||||
|
||||
"create.hint.hose_pulley.title": "Abastecimento sem fundo",
|
||||
"create.hint.hose_pulley": "O corpo de fluido selecionado é considerado infinito.",
|
||||
"create.hint.mechanical_arm_no_targets.title": "Sem alvos",
|
||||
"create.hint.mechanical_arm_no_targets": "Aparentemente esse _Braço_ _Mecânico_ não foi designado nenhum _alvo._ Selecione esteiras, depósitos, funis e outros blocos com o _botão direito do mouse_ enquanto _segurando_ o _Braço_ _Mecanico_ na sua _mão_.",
|
||||
"create.hint.empty_bearing.title": "Atualizar o rolamento",
|
||||
"create.hint.empty_bearing": " _clique com o botão direito_ o rolamento com a _mão_ _vazia_ para _conectar_ a estrutura que você construiu não frente disso.",
|
||||
"create.hint.full_deployer.title": "Implantador transbordando de itens",
|
||||
"create.hint.full_deployer": "Aparenta que esse _inplantador_ contém _itens_ em _excesso_ que precisam ser _extraídos._ Use um _funil,_ _funil de andesito/latão_ ou outros meios para extrair os itens excedentes.",
|
||||
|
||||
"create.gui.config.overlay1": "Oi :)",
|
||||
|
||||
"create.command.killTPSCommand": " killtps",
|
||||
"create.command.killTPSCommand.status.slowed_by.0": " [Create]: Server tick is currently slowed by %s ms :o",
|
||||
"create.command.killTPSCommand.status.slowed_by.1": " [Create]: Server tick is slowed by %s ms now >:)",
|
||||
"create.command.killTPSCommand.status.slowed_by.2": " [Create]: Server tick is back to regular speed :D",
|
||||
"create.command.killTPSCommand.status.usage.0": " [Create]: use /killtps stop to bring back server tick to regular speed",
|
||||
"create.command.killTPSCommand.status.usage.1": " [Create]: use /killtps start <tickTime> to artificially slow down the server tick",
|
||||
"create.command.killTPSCommand.argument.tickTime": "tickTime",
|
||||
|
||||
"create.contraption.minecart_contraption_too_big": "Essa engenhoca de carrinho aparenta ser muita grande para pegar",
|
||||
"create.contraption.minecart_contraption_illegal_pickup": "Uma força mistica esta segurando esta engenhoca de carrinho",
|
||||
|
||||
|
||||
"_": "->------------------------] Subtitles [------------------------<-",
|
||||
|
||||
"create.subtitle.contraption_disassemble": "Engenhoca para",
|
||||
"create.subtitle.peculiar_bell_use": "Sino peculiar toca",
|
||||
"create.subtitle.mixing": "Sons de mistura",
|
||||
"create.subtitle.mechanical_press_activation_belt": "Bonks da prensa mecanica",
|
||||
"create.subtitle.fwoomp": "Fwoomps do canhão de batata",
|
||||
"create.subtitle.worldshaper_place": "Zaps do terraformador",
|
||||
"create.subtitle.sanding_long": "Sons de lixa",
|
||||
"create.subtitle.crushing_1": "Sons de trituração",
|
||||
"create.subtitle.depot_slide": "Item escorrega",
|
||||
"create.subtitle.saw_activate_stone": "Serra mecânica ativa",
|
||||
"create.subtitle.blaze_munch": "Queimador de blazer mastiga",
|
||||
"create.subtitle.funnel_flap": "Abas do funil batendo",
|
||||
"create.subtitle.schematicannon_finish": "Ding do canhão de esquema",
|
||||
"create.subtitle.haunted_bell_use": "Sino assombrado toca",
|
||||
"create.subtitle.scroll_value": "click do scroll",
|
||||
"create.subtitle.crafter_craft": "Fabricador fábrica",
|
||||
"create.subtitle.controller_put": "Thumps do controle",
|
||||
"create.subtitle.cranking": "Manivela gira",
|
||||
"create.subtitle.wrench_remove": "Componente quebra",
|
||||
"create.subtitle.sanding_short": "Sons de lixa",
|
||||
"create.subtitle.cogs": "tremer da rodas dentadas",
|
||||
"create.subtitle.slime_added": "Slime sendo espremido",
|
||||
"create.subtitle.wrench_rotate": "Chave inglesa usada",
|
||||
"create.subtitle.potato_hit": "Impacto vegetal",
|
||||
"create.subtitle.saw_activate_wood": "Serra mecânica ativa",
|
||||
"create.subtitle.haunted_bell_convert": "Sino assombrado acorda",
|
||||
"create.subtitle.deny": "Boop de negação",
|
||||
"create.subtitle.controller_click": "Clicks do controle",
|
||||
"create.subtitle.schematicannon_launch_block": "Canhão de esquema atira",
|
||||
"create.subtitle.copper_armor_equip": "Tilintar dos equipamentos de mergulho",
|
||||
"create.subtitle.controller_take": "Atril esvaziado",
|
||||
"create.subtitle.mechanical_press_activation": "Clang da prensa mecânica",
|
||||
"create.subtitle.contraption_assemble": "Engenhoca move",
|
||||
"create.subtitle.crafter_click": "Clicks do fabricador",
|
||||
"create.subtitle.depot_plop": "Item pousa",
|
||||
"create.subtitle.confirm": "Ding afirmativo",
|
||||
|
||||
|
||||
"_": "->------------------------] Item Descriptions [------------------------<-",
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue