mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-03-04 14:54:42 +01:00
merge changes from 1.20.1/feature-dev
This commit is contained in:
commit
0e69448d0a
205 changed files with 73724 additions and 67918 deletions
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
|
@ -49,6 +49,8 @@ body:
|
|||
label: Mod Version
|
||||
description: The version of the mod you were using when the bug occured
|
||||
options:
|
||||
- "0.5.1f"
|
||||
- "0.5.1e"
|
||||
- "0.5.1d"
|
||||
- "0.5.1c"
|
||||
- "0.5.1b"
|
||||
|
|
|
@ -258,6 +258,8 @@ dependencies {
|
|||
// runtimeOnly fg.deobf("slimeknights.tconstruct:TConstruct:1.16.5-3.1.1.252")
|
||||
// runtimeOnly fg.deobf("maven.modrinth:rubidium:0.5.3")
|
||||
// implementation fg.deobf("com.railwayteam.railways:railways-1.18.2-1.1.1:all") { transitive = false }
|
||||
// runtimeOnly fg.deobf("maven.modrinth:aether:1.19.2-1.0.0-beta.1.1-forge")
|
||||
// runtimeOnly fg.deobf("maven.modrinth:spark:1.10.38-forge")
|
||||
|
||||
// https://discord.com/channels/313125603924639766/725850371834118214/910619168821354497
|
||||
// Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
"translation": "src/main/resources/assets/create/lang/%locale_with_underscore%.json",
|
||||
"languages_mapping": {
|
||||
"locale_with_underscore": {
|
||||
"be": "be_by",
|
||||
"cs": "cs_cz",
|
||||
"cy": "cy_gb",
|
||||
"da": "da_dk",
|
||||
|
@ -18,6 +19,7 @@
|
|||
"es-CL": "es_cl",
|
||||
"es-ES": "es_es",
|
||||
"es-MX": "es_mx",
|
||||
"et": "et_ee",
|
||||
"fa": "fa_ir",
|
||||
"fi": "fi_fi",
|
||||
"fr": "fr_fr",
|
||||
|
@ -41,6 +43,7 @@
|
|||
"tok": "tok",
|
||||
"tr": "tr_tr",
|
||||
"uk": "uk_ua",
|
||||
"vi": "vi_vn",
|
||||
"zh-CN": "zh_cn",
|
||||
"zh-TW": "zh_tw",
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ org.gradle.jvmargs = -Xmx3G
|
|||
org.gradle.daemon = false
|
||||
|
||||
# mod version info
|
||||
mod_version = 0.5.1.e
|
||||
mod_version = 0.6.0
|
||||
artifact_minecraft_version = 1.20.1
|
||||
|
||||
minecraft_version = 1.20.1
|
||||
|
@ -23,13 +23,13 @@ use_parchment = true
|
|||
# dependency versions
|
||||
registrate_version = MC1.20-1.3.3
|
||||
flywheel_minecraft_version = 1.20.1
|
||||
flywheel_version = 0.6.10-6
|
||||
flywheel_version = 0.6.10-7
|
||||
jei_minecraft_version = 1.20.1
|
||||
jei_version = 15.2.0.22
|
||||
curios_minecraft_version = 1.20.1
|
||||
curios_version = 5.2.0-beta.3
|
||||
catnip_version = 0.7.4
|
||||
ponder_version = 0.7.4
|
||||
curios_version = 5.3.1
|
||||
catnip_version = 0.7.5
|
||||
ponder_version = 0.7.5
|
||||
|
||||
cc_tweaked_enable = true
|
||||
cc_tweaked_minecraft_version = 1.20.1
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// 1.20.1 2023-07-04T18:31:12.3951444 Create's Sequenced Assembly Recipes
|
||||
// 1.20.1 2023-09-20T19:40:25.4471912 Create's Sequenced Assembly Recipes
|
||||
dbaca5a5aa312f3bc7b826e51e665d32e798a5d7 data/create/recipes/sequenced_assembly/precision_mechanism.json
|
||||
0cdbd4f583aa0a2aa8f3ca2827199bede1732722 data/create/recipes/sequenced_assembly/sturdy_sheet.json
|
||||
1274315b5c570722d6f5b2ed7f5e53fe01b6288a data/create/recipes/sequenced_assembly/track.json
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// 1.20.1 2023-08-22T15:37:03.5601186 Registrate Provider for create [Recipes, Advancements, Loot Tables, Tags (blocks), Tags (items), Tags (fluids), Tags (entity_types), Blockstates, Item models, Lang (en_us/en_ud)]
|
||||
// 1.20.1 2023-11-17T16:06:13.2756739 Registrate Provider for create [Recipes, Advancements, Loot Tables, Tags (blocks), Tags (items), Tags (fluids), Tags (entity_types), Blockstates, Item models, Lang (en_us/en_ud)]
|
||||
60bbdf92d2ac9824ea6144955c74043a6005f79d assets/create/blockstates/acacia_window.json
|
||||
6a67703c2697d81b7dc83e9d72a66f9c9ff08383 assets/create/blockstates/acacia_window_pane.json
|
||||
c3ae87b62e81d8e9476eccd793bb1548d74c66a1 assets/create/blockstates/adjustable_chain_gearshift.json
|
||||
|
@ -585,8 +585,8 @@ b0d8f08968763a5f74e5cd5644377a76a9f39753 assets/create/blockstates/yellow_toolbo
|
|||
fe8c497aacc641c2f01cec90bba9f19e59cc2ed2 assets/create/blockstates/yellow_valve_handle.json
|
||||
e819e93fdcbe9fd9c050a052d2718ff3b3539365 assets/create/blockstates/zinc_block.json
|
||||
64121dcb216381c83b4fe28aa361ea07c24c9ad0 assets/create/blockstates/zinc_ore.json
|
||||
3a1e0c68a9f1d6a252f47b3f7311278711f2aae0 assets/create/lang/en_ud.json
|
||||
a0c0e4f23540bef4b1796ad9f4e4ace609d2919b assets/create/lang/en_us.json
|
||||
807ea2be63882ed9e2d14267abf902a4c9313027 assets/create/lang/en_ud.json
|
||||
50e19fb11134116092d9f05811ff63bc116a997c assets/create/lang/en_us.json
|
||||
a97e1060e00ae701a02e39cd4ef8054cf345fac4 assets/create/models/block/acacia_window.json
|
||||
103e032c0b1a0a6a27c67da8c91179a564bd281c assets/create/models/block/acacia_window_pane_noside.json
|
||||
fb00b627abda76ad4fea867ca57dbfadd24fffa3 assets/create/models/block/acacia_window_pane_noside_alt.json
|
||||
|
@ -4171,6 +4171,10 @@ f1a03ac86925e26cbec6aeeada2eafb40008fc8e data/create/recipes/weathered_copper_ti
|
|||
35133e95f1c8fdd7a1c21afcc231fc0bffefb9a8 data/create/tags/blocks/contraption_inventory_deny.json
|
||||
c7ec0dbc18e9c1b58e568ed925287b89df11a136 data/create/tags/blocks/copycat_allow.json
|
||||
876eb9210f4a14898a2fe6d225699c66b5bdfeef data/create/tags/blocks/copycat_deny.json
|
||||
f675c20350ed60da4878b5d6301f02c8c05624bd data/create/tags/blocks/fan_processing_catalysts/blasting.json
|
||||
0592b99f657415f6546564ed8efa1fcbef07ba15 data/create/tags/blocks/fan_processing_catalysts/haunting.json
|
||||
9386dd9a1d234813f9b8ae4ec88866d396aa1d37 data/create/tags/blocks/fan_processing_catalysts/smoking.json
|
||||
35133e95f1c8fdd7a1c21afcc231fc0bffefb9a8 data/create/tags/blocks/fan_processing_catalysts/splashing.json
|
||||
6858173c670bb593664ac3c62ded726d57d581f1 data/create/tags/blocks/fan_transparent.json
|
||||
2589b135c0e96ad29076569e144528fe32ea5b39 data/create/tags/blocks/girdable_tracks.json
|
||||
a1e21c22f32354fd1a82a1b0a59dd786c0deaba0 data/create/tags/blocks/movable_empty_collider.json
|
||||
|
@ -4185,9 +4189,14 @@ a5874f73c7dc0a3ae12999e6ae8abf45bc7fb9be data/create/tags/blocks/passive_boiler_
|
|||
da739ad2160e7df4e0e5cc89587670ce5e9450c3 data/create/tags/blocks/valve_handles.json
|
||||
72143286fb5cb372a0696550e2eac76ca50e6fbc data/create/tags/blocks/windmill_sails.json
|
||||
58987ea71d488cc48192ceb00c00aa2903e51304 data/create/tags/blocks/wrench_pickup.json
|
||||
76c0522664726c09461ad4565b6fba80b4f816b2 data/create/tags/entity_types/blaze_burner_capturable.json
|
||||
35133e95f1c8fdd7a1c21afcc231fc0bffefb9a8 data/create/tags/entity_types/ignore_seat.json
|
||||
894e1e4fd1e32712abdda18ec64ab13750d3c039 data/create/tags/fluids/bottomless/allow.json
|
||||
35133e95f1c8fdd7a1c21afcc231fc0bffefb9a8 data/create/tags/fluids/bottomless/deny.json
|
||||
e191d5f912e05091b3a0b1df17f4c4181e04d96f data/create/tags/fluids/fan_processing_catalysts/blasting.json
|
||||
35133e95f1c8fdd7a1c21afcc231fc0bffefb9a8 data/create/tags/fluids/fan_processing_catalysts/haunting.json
|
||||
35133e95f1c8fdd7a1c21afcc231fc0bffefb9a8 data/create/tags/fluids/fan_processing_catalysts/smoking.json
|
||||
c9ae54a7510073b17edf82f7591e14bdb2c51837 data/create/tags/fluids/fan_processing_catalysts/splashing.json
|
||||
35133e95f1c8fdd7a1c21afcc231fc0bffefb9a8 data/create/tags/items/blaze_burner_fuel/regular.json
|
||||
8ba98bf390a326abeebfd5d84be5f740c935a8b6 data/create/tags/items/blaze_burner_fuel/special.json
|
||||
8b6c0b444b15f7fb2d55b9cbcb68537c1269f877 data/create/tags/items/casing.json
|
||||
|
@ -4195,8 +4204,8 @@ f43cac8216e2a9347e48cf93a43de95dd810ca20 data/create/tags/items/contraption_cont
|
|||
d371dfd35e49a7bef19f59c03e7f4ae20992f03d data/create/tags/items/create_ingots.json
|
||||
910d0f5ccbc4c84b224eca1f1588b1695f41447b data/create/tags/items/crushed_raw_materials.json
|
||||
0fa526e7e742573b603ad26b09526cf724efa1dc data/create/tags/items/deployable_drink.json
|
||||
99d3f12c67bd4c1f14fa9e6cbc1de5ed209ef402 data/create/tags/items/modded_stripped_logs.json
|
||||
b49ad07e47fbb4b12c1d95d72f752e6e6839a815 data/create/tags/items/modded_stripped_wood.json
|
||||
ab45dc78be188d430c71904015b2b034908db64e data/create/tags/items/modded_stripped_logs.json
|
||||
864fb582620b267894ad4016af8f0fd793bac5e8 data/create/tags/items/modded_stripped_wood.json
|
||||
695d75b352fd190b303c724d1aaee9bb786a903b data/create/tags/items/pressurized_air_sources.json
|
||||
2cd3adffd8b151354df137a990dcb97996a665bb data/create/tags/items/sandpaper.json
|
||||
79418bd729cef417b322cef9b491e7ae83317d61 data/create/tags/items/seats.json
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// 1.20.1 2023-07-04T18:31:12.3303171 Create's Advancements
|
||||
// 1.20.1 2023-09-20T19:40:25.3622264 Create's Advancements
|
||||
2661a689fdcf729494f46e3c719f71c62e31582e data/create/advancements/andesite_alloy.json
|
||||
fa16c4afe0496edc3f157858a6e0ff177a1622ff data/create/advancements/andesite_casing.json
|
||||
5a694002d0a663bc869b09d15924a10c43dc522f data/create/advancements/anvil_plough.json
|
||||
|
@ -29,7 +29,7 @@ ac78707d112458c7f771260cf65f0e9bc928d1b6 data/create/advancements/deployer.json
|
|||
48c3af4499797cfb695a235e4527c52c608d40ad data/create/advancements/display_board_0.json
|
||||
24be041d833017d7e7e02a5a92fd04060ea62594 data/create/advancements/display_link.json
|
||||
cc2c729cf82a0c80b4966ac6382984da08429b9d data/create/advancements/diving_suit.json
|
||||
7418171d223567cb52b22f5facef648af04cbae6 data/create/advancements/diving_suit_lava.json
|
||||
e1af547fd148cf9e60c1725ab03545fe3010eac7 data/create/advancements/diving_suit_lava.json
|
||||
4d91e6a7bbf08191d8d1e11943650dfc1dc170e6 data/create/advancements/drain.json
|
||||
dee06f0f78a97a6358b67459d05fb479e5318fe9 data/create/advancements/ejector_maxed.json
|
||||
3300ee54dc1e9d04fd13a11c971e046d9db24e10 data/create/advancements/encased_fan.json
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// 1.20.1 2023-07-04T18:31:12.4130959 Create's Mechanical Crafting Recipes
|
||||
// 1.20.1 2023-09-20T19:40:25.4511802 Create's Mechanical Crafting Recipes
|
||||
f076d64d9f30709bed34775136c9241097b28aa9 data/create/recipes/mechanical_crafting/crushing_wheel.json
|
||||
694dca9dcff246bb7f560b3304fcc244c53217d5 data/create/recipes/mechanical_crafting/extendo_grip.json
|
||||
3b2837b08607c1ca466fa3eb418209b2e55da6ba data/create/recipes/mechanical_crafting/potato_cannon.json
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// 1.20.1 2023-07-04T18:31:12.4081093 Create's Standard Recipes
|
||||
// 1.20.1 2023-09-20T19:40:25.4471912 Create's Standard Recipes
|
||||
a8cc4af26f6c7c45a9eef12e92af1452fe042454 data/create/advancements/recipes/combat/crafting/appliances/netherite_backtank.json
|
||||
2c2639c7b307ee7c7a4e97e5efebf496788998ad data/create/advancements/recipes/combat/crafting/appliances/netherite_backtank_from_netherite.json
|
||||
81dcf0cb1aa99e39bc7d1a386e07cad4cee7d8b9 data/create/advancements/recipes/combat/crafting/appliances/netherite_diving_boots.json
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// 1.20.1 2023-08-25T18:36:29.7642425 Create's Damage Type Tags
|
||||
// 1.20.1 2023-09-20T19:47:44.9018689 Create's Damage Type Tags
|
||||
7884716b2f4bb1330ff215366bb4bab06e4728c2 data/minecraft/tags/damage_type/bypasses_armor.json
|
||||
1fcad1f89265fba8bdb05b03a1dfcc88d7b7a550 data/minecraft/tags/damage_type/is_explosion.json
|
||||
08324c61115b72bb8a6370d7f34d84d9a31afd16 data/minecraft/tags/damage_type/is_fire.json
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// 1.20.1 2023-08-23T16:29:07.6573146 Create's Processing Recipes
|
||||
// 1.20.1 2023-09-20T19:40:25.3652491 Create's Processing Recipes
|
||||
3c94326fb730f68c1e44fe1e2ef09c9db6ffd92b data/create/recipes/compacting/andesite_from_flint.json
|
||||
8d3d5b31f3601b9f681ff710e0545a483a1494c6 data/create/recipes/compacting/blaze_cake.json
|
||||
8bd7f4e3a686ab520b2d55594d2018d0e9a50c91 data/create/recipes/compacting/chocolate.json
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
// 1.20.1 2023-07-04T18:31:12.3492665 Create's Custom Sounds
|
||||
// 1.20.1 2023-09-20T19:40:25.3732177 Create's Custom Sounds
|
||||
043955db25ffe58e7debb9a4f11e41a9571376e6 assets/create/sounds.json
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
// 1.20.1 2023-08-24T21:57:44.7330415 Create's Recipe Serializer Tags
|
||||
// 1.20.1 2023-09-20T19:40:25.4461939 Create's Recipe Serializer Tags
|
||||
0d8718f7383761bc5d7bc45306ed266ebf25dc1d data/create/tags/recipe_serializer/automation_ignore.json
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// 1.20.1 2023-08-25T18:36:29.766244 Create's Generated Registry Entries
|
||||
// 1.20.1 2023-09-20T19:47:44.9028659 Create's Generated Registry Entries
|
||||
030ede1044384c4117ac1e491bf5c78bbd2842f5 data/create/damage_type/crush.json
|
||||
92b0416950ffeb3ba68811e587177c2f8811c2c5 data/create/damage_type/cuckoo_surprise.json
|
||||
d2a4fdb64f4ba817e13a7b20c73fd1ca34b825fc data/create/damage_type/fan_fire.json
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"parent": "create:backtank",
|
||||
"parent": "create:foods",
|
||||
"criteria": {
|
||||
"0": {
|
||||
"conditions": {},
|
||||
|
@ -13,9 +13,9 @@
|
|||
"translate": "advancement.create.diving_suit_lava.desc"
|
||||
},
|
||||
"frame": "goal",
|
||||
"hidden": true,
|
||||
"hidden": false,
|
||||
"icon": {
|
||||
"item": "create:copper_diving_helmet",
|
||||
"item": "create:netherite_diving_helmet",
|
||||
"nbt": "{Damage:0}"
|
||||
},
|
||||
"show_toast": true,
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"values": [
|
||||
"create:blaze_burner"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"values": [
|
||||
"create:lit_blaze_burner",
|
||||
"minecraft:soul_fire",
|
||||
"minecraft:soul_campfire"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"values": [
|
||||
"create:blaze_burner",
|
||||
"create:lit_blaze_burner",
|
||||
"minecraft:fire",
|
||||
"minecraft:campfire"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"values": []
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"values": [
|
||||
"minecraft:blaze"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"values": [
|
||||
"minecraft:lava",
|
||||
"minecraft:flowing_lava"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"values": []
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"values": []
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"values": [
|
||||
"minecraft:water",
|
||||
"minecraft:flowing_water"
|
||||
]
|
||||
}
|
|
@ -288,6 +288,70 @@
|
|||
"id": "blue_skies:stripped_cherry_log",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "environmental:stripped_cherry_log",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "environmental:stripped_willow_log",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "environmental:stripped_wisteria_log",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "atmospheric:stripped_aspen_log",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "atmospheric:stripped_kousa_log",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "atmospheric:stripped_yucca_log",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "atmospheric:stripped_morado_log",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "atmospheric:stripped_rosewood_log",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "atmospheric:stripped_grimwood_log",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "goodending:stripped_muddy_oak_log",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "goodending:stripped_cypress_log",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "biomemakeover:stripped_blighted_balsa_log",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "biomemakeover:stripped_willow_log",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "biomemakeover:stripped_swamp_cypress_log",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "biomemakeover:stripped_ancient_oak_log",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "infernalexp:stripped_luminous_stem",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "byg:stripped_bulbis_stem",
|
||||
"required": false
|
||||
|
|
|
@ -288,6 +288,70 @@
|
|||
"id": "blue_skies:stripped_cherry_wood",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "environmental:stripped_cherry_wood",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "environmental:stripped_willow_wood",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "environmental:stripped_wisteria_wood",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "atmospheric:stripped_aspen_wood",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "atmospheric:stripped_kousa_wood",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "atmospheric:stripped_yucca_wood",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "atmospheric:stripped_morado_wood",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "atmospheric:stripped_rosewood",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "atmospheric:stripped_grimwood",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "goodending:stripped_muddy_oak_wood",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "goodending:stripped_cypress_wood",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "biomemakeover:stripped_blighted_balsa_wood",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "biomemakeover:stripped_willow_wood",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "biomemakeover:stripped_swamp_cypress_wood",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "biomemakeover:stripped_ancient_oak_wood",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "infernalexp:stripped_luminous_hyphae",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"id": "byg:stripped_bulbis_wood",
|
||||
"required": false
|
||||
|
|
|
@ -310,8 +310,10 @@ import net.minecraftforge.common.Tags;
|
|||
import net.minecraftforge.common.util.ForgeSoundType;
|
||||
|
||||
public class AllBlocks {
|
||||
|
||||
static { REGISTRATE.useCreativeTab(AllCreativeModeTabs.MAIN_TAB); }
|
||||
|
||||
static {
|
||||
REGISTRATE.setCreativeTab(AllCreativeModeTabs.BASE_CREATIVE_TAB);
|
||||
}
|
||||
|
||||
// Schematics
|
||||
|
||||
|
@ -339,7 +341,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<SchematicTableBlock> SCHEMATIC_TABLE =
|
||||
REGISTRATE.block("schematic_table", SchematicTableBlock::new)
|
||||
.initialProperties(() -> Blocks.LECTERN)
|
||||
.properties(p -> p.mapColor(MapColor.PODZOL))
|
||||
.properties(p -> p.mapColor(MapColor.PODZOL).forceSolidOn())
|
||||
.transform(axeOrPickaxe())
|
||||
.blockstate((ctx, prov) -> prov.horizontalBlock(ctx.getEntry(), prov.models()
|
||||
.getExistingFile(ctx.getId()), 0))
|
||||
|
@ -350,7 +352,7 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<ShaftBlock> SHAFT = REGISTRATE.block("shaft", ShaftBlock::new)
|
||||
.initialProperties(SharedProperties::stone)
|
||||
.properties(p -> p.mapColor(MapColor.METAL))
|
||||
.properties(p -> p.mapColor(MapColor.METAL).forceSolidOn())
|
||||
.transform(BlockStressDefaults.setNoImpact())
|
||||
.transform(pickaxeOnly())
|
||||
.blockstate(BlockStateGen.axisBlockProvider(false))
|
||||
|
@ -360,8 +362,7 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<CogWheelBlock> COGWHEEL = REGISTRATE.block("cogwheel", CogWheelBlock::small)
|
||||
.initialProperties(SharedProperties::stone)
|
||||
.properties(p -> p.sound(SoundType.WOOD))
|
||||
.properties(p -> p.mapColor(MapColor.DIRT))
|
||||
.properties(p -> p.sound(SoundType.WOOD).mapColor(MapColor.DIRT))
|
||||
.transform(BlockStressDefaults.setNoImpact())
|
||||
.transform(axeOrPickaxe())
|
||||
.blockstate(BlockStateGen.axisBlockProvider(false))
|
||||
|
@ -373,8 +374,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<CogWheelBlock> LARGE_COGWHEEL =
|
||||
REGISTRATE.block("large_cogwheel", CogWheelBlock::large)
|
||||
.initialProperties(SharedProperties::stone)
|
||||
.properties(p -> p.sound(SoundType.WOOD))
|
||||
.properties(p -> p.mapColor(MapColor.DIRT))
|
||||
.properties(p -> p.sound(SoundType.WOOD).mapColor(MapColor.DIRT))
|
||||
.transform(axeOrPickaxe())
|
||||
.transform(BlockStressDefaults.setNoImpact())
|
||||
.blockstate(BlockStateGen.axisBlockProvider(false))
|
||||
|
@ -440,8 +440,7 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<GearboxBlock> GEARBOX = REGISTRATE.block("gearbox", GearboxBlock::new)
|
||||
.initialProperties(SharedProperties::stone)
|
||||
.properties(BlockBehaviour.Properties::noOcclusion)
|
||||
.properties(p -> p.mapColor(MapColor.PODZOL))
|
||||
.properties(p -> p.noOcclusion().mapColor(MapColor.PODZOL))
|
||||
.transform(BlockStressDefaults.setNoImpact())
|
||||
.transform(axeOrPickaxe())
|
||||
.onRegister(CreateRegistrate.connectedTextures(() -> new EncasedCTBehaviour(AllSpriteShifts.ANDESITE_CASING)))
|
||||
|
@ -454,8 +453,7 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<ClutchBlock> CLUTCH = REGISTRATE.block("clutch", ClutchBlock::new)
|
||||
.initialProperties(SharedProperties::stone)
|
||||
.properties(BlockBehaviour.Properties::noOcclusion)
|
||||
.properties(p -> p.mapColor(MapColor.PODZOL))
|
||||
.properties(p -> p.noOcclusion().mapColor(MapColor.PODZOL))
|
||||
.addLayer(() -> RenderType::cutoutMipped)
|
||||
.transform(BlockStressDefaults.setNoImpact())
|
||||
.transform(axeOrPickaxe())
|
||||
|
@ -466,8 +464,7 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<GearshiftBlock> GEARSHIFT = REGISTRATE.block("gearshift", GearshiftBlock::new)
|
||||
.initialProperties(SharedProperties::stone)
|
||||
.properties(BlockBehaviour.Properties::noOcclusion)
|
||||
.properties(p -> p.mapColor(MapColor.PODZOL))
|
||||
.properties(p -> p.noOcclusion().mapColor(MapColor.PODZOL))
|
||||
.addLayer(() -> RenderType::cutoutMipped)
|
||||
.transform(BlockStressDefaults.setNoImpact())
|
||||
.transform(axeOrPickaxe())
|
||||
|
@ -479,8 +476,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<ChainDriveBlock> ENCASED_CHAIN_DRIVE =
|
||||
REGISTRATE.block("encased_chain_drive", ChainDriveBlock::new)
|
||||
.initialProperties(SharedProperties::stone)
|
||||
.properties(BlockBehaviour.Properties::noOcclusion)
|
||||
.properties(p -> p.mapColor(MapColor.PODZOL))
|
||||
.properties(p -> p.noOcclusion().mapColor(MapColor.PODZOL))
|
||||
.transform(BlockStressDefaults.setNoImpact())
|
||||
.transform(axeOrPickaxe())
|
||||
.blockstate((c, p) -> new ChainDriveGenerator((state, suffix) -> p.models()
|
||||
|
@ -492,8 +488,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<ChainGearshiftBlock> ADJUSTABLE_CHAIN_GEARSHIFT =
|
||||
REGISTRATE.block("adjustable_chain_gearshift", ChainGearshiftBlock::new)
|
||||
.initialProperties(SharedProperties::stone)
|
||||
.properties(BlockBehaviour.Properties::noOcclusion)
|
||||
.properties(p -> p.mapColor(MapColor.NETHER))
|
||||
.properties(p -> p.noOcclusion().mapColor(MapColor.NETHER))
|
||||
.transform(BlockStressDefaults.setNoImpact())
|
||||
.transform(axeOrPickaxe())
|
||||
.blockstate((c, p) -> new ChainDriveGenerator((state, suffix) -> {
|
||||
|
@ -524,7 +519,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<CreativeMotorBlock> CREATIVE_MOTOR =
|
||||
REGISTRATE.block("creative_motor", CreativeMotorBlock::new)
|
||||
.initialProperties(SharedProperties::stone)
|
||||
.properties(p -> p.mapColor(MapColor.COLOR_PURPLE))
|
||||
.properties(p -> p.mapColor(MapColor.COLOR_PURPLE).forceSolidOn())
|
||||
.tag(AllBlockTags.SAFE_NBT.tag)
|
||||
.transform(pickaxeOnly())
|
||||
.blockstate(new CreativeMotorGenerator()::generate)
|
||||
|
@ -537,8 +532,7 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<WaterWheelBlock> WATER_WHEEL = REGISTRATE.block("water_wheel", WaterWheelBlock::new)
|
||||
.initialProperties(SharedProperties::wooden)
|
||||
.properties(p -> p.mapColor(MapColor.DIRT))
|
||||
.properties(BlockBehaviour.Properties::noOcclusion)
|
||||
.properties(p -> p.noOcclusion().mapColor(MapColor.DIRT))
|
||||
.transform(axeOrPickaxe())
|
||||
.blockstate(
|
||||
(c, p) -> BlockStateGen.directionalBlockIgnoresWaterlogged(c, p, s -> AssetLookup.partialBaseModel(c, p)))
|
||||
|
@ -552,8 +546,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<LargeWaterWheelBlock> LARGE_WATER_WHEEL =
|
||||
REGISTRATE.block("large_water_wheel", LargeWaterWheelBlock::new)
|
||||
.initialProperties(SharedProperties::wooden)
|
||||
.properties(p -> p.mapColor(MapColor.DIRT))
|
||||
.properties(BlockBehaviour.Properties::noOcclusion)
|
||||
.properties(p -> p.noOcclusion().mapColor(MapColor.DIRT))
|
||||
.transform(axeOrPickaxe())
|
||||
.blockstate((c, p) -> axisBlock(c, p,
|
||||
s -> s.getValue(LargeWaterWheelBlock.EXTENSION) ? AssetLookup.partialBaseModel(c, p, "extension")
|
||||
|
@ -569,8 +562,7 @@ public class AllBlocks {
|
|||
.initialProperties(SharedProperties::wooden)
|
||||
.blockstate((c, p) -> p.getVariantBuilder(c.get())
|
||||
.forAllStatesExcept(BlockStateGen.mapToAir(p), WaterWheelStructuralBlock.FACING))
|
||||
.properties(p -> p.mapColor(MapColor.DIRT))
|
||||
.properties(BlockBehaviour.Properties::noOcclusion)
|
||||
.properties(p -> p.noOcclusion().mapColor(MapColor.DIRT))
|
||||
.transform(axeOrPickaxe())
|
||||
.lang("Large Water Wheel")
|
||||
.register();
|
||||
|
@ -675,8 +667,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<MechanicalPressBlock> MECHANICAL_PRESS =
|
||||
REGISTRATE.block("mechanical_press", MechanicalPressBlock::new)
|
||||
.initialProperties(SharedProperties::stone)
|
||||
.properties(p -> p.mapColor(MapColor.PODZOL))
|
||||
.properties(BlockBehaviour.Properties::noOcclusion)
|
||||
.properties(p -> p.noOcclusion().mapColor(MapColor.PODZOL))
|
||||
.transform(axeOrPickaxe())
|
||||
.blockstate(BlockStateGen.horizontalBlockProvider(true))
|
||||
.transform(BlockStressDefaults.setImpact(8.0))
|
||||
|
@ -687,8 +678,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<MechanicalMixerBlock> MECHANICAL_MIXER =
|
||||
REGISTRATE.block("mechanical_mixer", MechanicalMixerBlock::new)
|
||||
.initialProperties(SharedProperties::stone)
|
||||
.properties(p -> p.mapColor(MapColor.STONE))
|
||||
.properties(BlockBehaviour.Properties::noOcclusion)
|
||||
.properties(p -> p.noOcclusion().mapColor(MapColor.STONE))
|
||||
.transform(axeOrPickaxe())
|
||||
.blockstate((c, p) -> p.simpleBlock(c.getEntry(), AssetLookup.partialBaseModel(c, p)))
|
||||
.addLayer(() -> RenderType::cutoutMipped)
|
||||
|
@ -699,8 +689,7 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<BasinBlock> BASIN = REGISTRATE.block("basin", BasinBlock::new)
|
||||
.initialProperties(SharedProperties::stone)
|
||||
.properties(p -> p.mapColor(MapColor.COLOR_GRAY))
|
||||
.properties(p -> p.sound(SoundType.NETHERITE_BLOCK))
|
||||
.properties(p -> p.mapColor(MapColor.COLOR_GRAY).sound(SoundType.NETHERITE_BLOCK))
|
||||
.transform(pickaxeOnly())
|
||||
.blockstate(new BasinGenerator()::generate)
|
||||
.addLayer(() -> RenderType::cutoutMipped)
|
||||
|
@ -712,11 +701,10 @@ public class AllBlocks {
|
|||
public static final BlockEntry<BlazeBurnerBlock> BLAZE_BURNER =
|
||||
REGISTRATE.block("blaze_burner", BlazeBurnerBlock::new)
|
||||
.initialProperties(SharedProperties::softMetal)
|
||||
.properties(p -> p.mapColor(MapColor.COLOR_GRAY))
|
||||
.properties(p -> p.lightLevel(BlazeBurnerBlock::getLight))
|
||||
.properties(p -> p.mapColor(MapColor.COLOR_GRAY).lightLevel(BlazeBurnerBlock::getLight))
|
||||
.transform(pickaxeOnly())
|
||||
.addLayer(() -> RenderType::cutoutMipped)
|
||||
.tag(AllBlockTags.FAN_TRANSPARENT.tag, AllBlockTags.PASSIVE_BOILER_HEATERS.tag)
|
||||
.tag(AllBlockTags.FAN_PROCESSING_CATALYSTS_BLASTING.tag, AllBlockTags.FAN_PROCESSING_CATALYSTS_SMOKING.tag, AllBlockTags.FAN_TRANSPARENT.tag, AllBlockTags.PASSIVE_BOILER_HEATERS.tag)
|
||||
.loot((lt, block) -> lt.add(block, BlazeBurnerBlock.buildLootTable()))
|
||||
.blockstate((c, p) -> p.simpleBlock(c.getEntry(), AssetLookup.partialBaseModel(c, p)))
|
||||
.onRegister(movementBehaviour(new BlazeBurnerMovementBehaviour()))
|
||||
|
@ -729,11 +717,10 @@ public class AllBlocks {
|
|||
public static final BlockEntry<LitBlazeBurnerBlock> LIT_BLAZE_BURNER =
|
||||
REGISTRATE.block("lit_blaze_burner", LitBlazeBurnerBlock::new)
|
||||
.initialProperties(SharedProperties::softMetal)
|
||||
.properties(p -> p.mapColor(MapColor.COLOR_LIGHT_GRAY))
|
||||
.properties(p -> p.lightLevel(LitBlazeBurnerBlock::getLight))
|
||||
.properties(p -> p.mapColor(MapColor.COLOR_LIGHT_GRAY).lightLevel(LitBlazeBurnerBlock::getLight))
|
||||
.transform(pickaxeOnly())
|
||||
.addLayer(() -> RenderType::cutoutMipped)
|
||||
.tag(AllBlockTags.FAN_TRANSPARENT.tag, AllBlockTags.PASSIVE_BOILER_HEATERS.tag)
|
||||
.tag(AllBlockTags.FAN_PROCESSING_CATALYSTS_HAUNTING.tag, AllBlockTags.FAN_PROCESSING_CATALYSTS_SMOKING.tag, AllBlockTags.FAN_TRANSPARENT.tag, AllBlockTags.PASSIVE_BOILER_HEATERS.tag)
|
||||
.loot((lt, block) -> lt.dropOther(block, AllItems.EMPTY_BLAZE_BURNER.get()))
|
||||
.blockstate((c, p) -> p.getVariantBuilder(c.get())
|
||||
.forAllStates(state -> ConfiguredModel.builder()
|
||||
|
@ -758,8 +745,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<EjectorBlock> WEIGHTED_EJECTOR =
|
||||
REGISTRATE.block("weighted_ejector", EjectorBlock::new)
|
||||
.initialProperties(SharedProperties::stone)
|
||||
.properties(p -> p.mapColor(MapColor.COLOR_GRAY))
|
||||
.properties(BlockBehaviour.Properties::noOcclusion)
|
||||
.properties(p -> p.noOcclusion().mapColor(MapColor.COLOR_GRAY))
|
||||
.transform(axeOrPickaxe())
|
||||
.blockstate((c, p) -> p.horizontalBlock(c.getEntry(), AssetLookup.partialBaseModel(c, p), 180))
|
||||
.transform(BlockStressDefaults.setImpact(2.0))
|
||||
|
@ -769,10 +755,8 @@ public class AllBlocks {
|
|||
.register();
|
||||
|
||||
public static final BlockEntry<ChuteBlock> CHUTE = REGISTRATE.block("chute", ChuteBlock::new)
|
||||
.addLayer(() -> RenderType::cutoutMipped)
|
||||
.initialProperties(SharedProperties::softMetal)
|
||||
.properties(p -> p.mapColor(MapColor.COLOR_GRAY))
|
||||
.properties(p -> p.sound(SoundType.NETHERITE_BLOCK))
|
||||
.properties(p -> p.mapColor(MapColor.COLOR_GRAY).sound(SoundType.NETHERITE_BLOCK))
|
||||
.transform(pickaxeOnly())
|
||||
.addLayer(() -> RenderType::cutoutMipped)
|
||||
.blockstate(new ChuteGenerator()::generate)
|
||||
|
@ -781,12 +765,12 @@ public class AllBlocks {
|
|||
.register();
|
||||
|
||||
public static final BlockEntry<SmartChuteBlock> SMART_CHUTE = REGISTRATE.block("smart_chute", SmartChuteBlock::new)
|
||||
.addLayer(() -> RenderType::cutoutMipped)
|
||||
.initialProperties(SharedProperties::softMetal)
|
||||
.properties(p -> p.mapColor(MapColor.COLOR_GRAY))
|
||||
.properties(p -> p.sound(SoundType.NETHERITE_BLOCK))
|
||||
.properties(p -> p.noOcclusion())
|
||||
.properties(p -> p.isRedstoneConductor((level, pos, state) -> false))
|
||||
.properties(p -> p.mapColor(MapColor.COLOR_GRAY)
|
||||
.sound(SoundType.NETHERITE_BLOCK)
|
||||
.noOcclusion()
|
||||
.isRedstoneConductor((level, pos, state) -> false))
|
||||
.addLayer(() -> RenderType::cutoutMipped)
|
||||
.transform(pickaxeOnly())
|
||||
.blockstate((c, p) -> BlockStateGen.simpleBlock(c, p, AssetLookup.forPowered(c, p)))
|
||||
.item()
|
||||
|
@ -835,6 +819,7 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<FluidPipeBlock> FLUID_PIPE = REGISTRATE.block("fluid_pipe", FluidPipeBlock::new)
|
||||
.initialProperties(SharedProperties::copperMetal)
|
||||
.properties(p -> p.forceSolidOn())
|
||||
.transform(pickaxeOnly())
|
||||
.blockstate(BlockStateGen.pipe())
|
||||
.onRegister(CreateRegistrate.blockModel(() -> PipeAttachmentModel::new))
|
||||
|
@ -845,8 +830,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<EncasedPipeBlock> ENCASED_FLUID_PIPE =
|
||||
REGISTRATE.block("encased_fluid_pipe", p -> new EncasedPipeBlock(p, AllBlocks.COPPER_CASING::get))
|
||||
.initialProperties(SharedProperties::copperMetal)
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_LIGHT_GRAY))
|
||||
.properties(BlockBehaviour.Properties::noOcclusion)
|
||||
.properties(p -> p.noOcclusion().mapColor(MapColor.TERRACOTTA_LIGHT_GRAY))
|
||||
.transform(axeOrPickaxe())
|
||||
.blockstate(BlockStateGen.encasedPipe())
|
||||
.onRegister(CreateRegistrate.connectedTextures(() -> new EncasedCTBehaviour(AllSpriteShifts.COPPER_CASING)))
|
||||
|
@ -860,6 +844,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<GlassFluidPipeBlock> GLASS_FLUID_PIPE =
|
||||
REGISTRATE.block("glass_fluid_pipe", GlassFluidPipeBlock::new)
|
||||
.initialProperties(SharedProperties::copperMetal)
|
||||
.properties(p -> p.forceSolidOn())
|
||||
.addLayer(() -> RenderType::cutoutMipped)
|
||||
.transform(pickaxeOnly())
|
||||
.blockstate((c, p) -> {
|
||||
|
@ -935,8 +920,7 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<FluidTankBlock> FLUID_TANK = REGISTRATE.block("fluid_tank", FluidTankBlock::regular)
|
||||
.initialProperties(SharedProperties::copperMetal)
|
||||
.properties(BlockBehaviour.Properties::noOcclusion)
|
||||
.properties(p -> p.isRedstoneConductor((p1, p2, p3) -> true))
|
||||
.properties(p -> p.noOcclusion().isRedstoneConductor((p1, p2, p3) -> true))
|
||||
.transform(pickaxeOnly())
|
||||
.blockstate(new FluidTankGenerator()::generate)
|
||||
.onRegister(CreateRegistrate.blockModel(() -> FluidTankModel::standard))
|
||||
|
@ -950,8 +934,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<FluidTankBlock> CREATIVE_FLUID_TANK =
|
||||
REGISTRATE.block("creative_fluid_tank", FluidTankBlock::creative)
|
||||
.initialProperties(SharedProperties::copperMetal)
|
||||
.properties(BlockBehaviour.Properties::noOcclusion)
|
||||
.properties(p -> p.mapColor(MapColor.COLOR_PURPLE))
|
||||
.properties(p -> p.noOcclusion().mapColor(MapColor.COLOR_PURPLE))
|
||||
.transform(pickaxeOnly())
|
||||
.tag(AllBlockTags.SAFE_NBT.tag)
|
||||
.blockstate(new FluidTankGenerator("creative_")::generate)
|
||||
|
@ -1030,7 +1013,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<WhistleExtenderBlock> STEAM_WHISTLE_EXTENSION =
|
||||
REGISTRATE.block("steam_whistle_extension", WhistleExtenderBlock::new)
|
||||
.initialProperties(SharedProperties::copperMetal)
|
||||
.properties(p -> p.mapColor(MapColor.GOLD))
|
||||
.properties(p -> p.mapColor(MapColor.GOLD).forceSolidOn())
|
||||
.transform(pickaxeOnly())
|
||||
.blockstate(BlockStateGen.whistleExtender())
|
||||
.register();
|
||||
|
@ -1038,7 +1021,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<PoweredShaftBlock> POWERED_SHAFT =
|
||||
REGISTRATE.block("powered_shaft", PoweredShaftBlock::new)
|
||||
.initialProperties(SharedProperties::stone)
|
||||
.properties(p -> p.mapColor(MapColor.METAL))
|
||||
.properties(p -> p.mapColor(MapColor.METAL).forceSolidOn())
|
||||
.transform(pickaxeOnly())
|
||||
.blockstate(BlockStateGen.axisBlockProvider(false))
|
||||
.loot((lt, block) -> lt.dropOther(block, AllBlocks.SHAFT.get()))
|
||||
|
@ -1065,8 +1048,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<PistonExtensionPoleBlock> PISTON_EXTENSION_POLE =
|
||||
REGISTRATE.block("piston_extension_pole", PistonExtensionPoleBlock::new)
|
||||
.initialProperties(() -> Blocks.PISTON_HEAD)
|
||||
.properties(p -> p.sound(SoundType.SCAFFOLDING))
|
||||
.properties(p -> p.mapColor(MapColor.DIRT))
|
||||
.properties(p -> p.sound(SoundType.SCAFFOLDING).mapColor(MapColor.DIRT).forceSolidOn())
|
||||
.transform(axeOrPickaxe())
|
||||
.blockstate(BlockStateGen.directionalBlockProviderIgnoresWaterlogged(false))
|
||||
.simpleItem()
|
||||
|
@ -1086,8 +1068,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<GantryCarriageBlock> GANTRY_CARRIAGE =
|
||||
REGISTRATE.block("gantry_carriage", GantryCarriageBlock::new)
|
||||
.initialProperties(SharedProperties::stone)
|
||||
.properties(p -> p.mapColor(MapColor.PODZOL))
|
||||
.properties(BlockBehaviour.Properties::noOcclusion)
|
||||
.properties(p -> p.noOcclusion().mapColor(MapColor.PODZOL))
|
||||
.transform(axeOrPickaxe())
|
||||
.blockstate(BlockStateGen.directionalAxisBlockProvider())
|
||||
.item()
|
||||
|
@ -1097,7 +1078,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<GantryShaftBlock> GANTRY_SHAFT =
|
||||
REGISTRATE.block("gantry_shaft", GantryShaftBlock::new)
|
||||
.initialProperties(SharedProperties::stone)
|
||||
.properties(p -> p.mapColor(MapColor.NETHER))
|
||||
.properties(p -> p.mapColor(MapColor.NETHER).forceSolidOn())
|
||||
.transform(axeOrPickaxe())
|
||||
.blockstate((c, p) -> p.directionalBlock(c.get(), s -> {
|
||||
boolean isPowered = s.getValue(GantryShaftBlock.POWERED);
|
||||
|
@ -1192,8 +1173,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<CartAssemblerBlock> CART_ASSEMBLER =
|
||||
REGISTRATE.block("cart_assembler", CartAssemblerBlock::new)
|
||||
.initialProperties(SharedProperties::stone)
|
||||
.properties(p -> p.mapColor(MapColor.COLOR_GRAY))
|
||||
.properties(BlockBehaviour.Properties::noOcclusion)
|
||||
.properties(p -> p.noOcclusion().mapColor(MapColor.COLOR_GRAY))
|
||||
.transform(axeOrPickaxe())
|
||||
.blockstate(BlockStateGen.cartAssembler())
|
||||
.addLayer(() -> RenderType::cutoutMipped)
|
||||
|
@ -1349,8 +1329,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<ElevatorContactBlock> ELEVATOR_CONTACT =
|
||||
REGISTRATE.block("elevator_contact", ElevatorContactBlock::new)
|
||||
.initialProperties(SharedProperties::softMetal)
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_YELLOW))
|
||||
.properties(p -> p.lightLevel(ElevatorContactBlock::getLight))
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_YELLOW).lightLevel(ElevatorContactBlock::getLight))
|
||||
.transform(axeOrPickaxe())
|
||||
.blockstate((c, p) -> p.directionalBlock(c.get(), state -> {
|
||||
Boolean calling = state.getValue(ElevatorContactBlock.CALLING);
|
||||
|
@ -1367,7 +1346,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<HarvesterBlock> MECHANICAL_HARVESTER =
|
||||
REGISTRATE.block("mechanical_harvester", HarvesterBlock::new)
|
||||
.initialProperties(SharedProperties::stone)
|
||||
.properties(p -> p.mapColor(MapColor.METAL))
|
||||
.properties(p -> p.mapColor(MapColor.METAL).forceSolidOn())
|
||||
.transform(axeOrPickaxe())
|
||||
.onRegister(movementBehaviour(new HarvesterMovementBehaviour()))
|
||||
.blockstate(BlockStateGen.horizontalBlockProvider(true))
|
||||
|
@ -1380,7 +1359,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<PloughBlock> MECHANICAL_PLOUGH =
|
||||
REGISTRATE.block("mechanical_plough", PloughBlock::new)
|
||||
.initialProperties(SharedProperties::stone)
|
||||
.properties(p -> p.mapColor(MapColor.COLOR_GRAY))
|
||||
.properties(p -> p.mapColor(MapColor.COLOR_GRAY).forceSolidOn())
|
||||
.transform(axeOrPickaxe())
|
||||
.onRegister(movementBehaviour(new PloughMovementBehaviour()))
|
||||
.blockstate(BlockStateGen.horizontalBlockProvider(false))
|
||||
|
@ -1405,8 +1384,8 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<SailBlock> SAIL_FRAME = REGISTRATE.block("sail_frame", p -> SailBlock.frame(p))
|
||||
.initialProperties(SharedProperties::wooden)
|
||||
.properties(p -> p.mapColor(MapColor.DIRT))
|
||||
.properties(p -> p.sound(SoundType.SCAFFOLDING)
|
||||
.properties(p -> p.mapColor(MapColor.DIRT)
|
||||
.sound(SoundType.SCAFFOLDING)
|
||||
.noOcclusion())
|
||||
.transform(axeOnly())
|
||||
.blockstate(BlockStateGen.directionalBlockProvider(false))
|
||||
|
@ -1419,8 +1398,8 @@ public class AllBlocks {
|
|||
public static final BlockEntry<SailBlock> SAIL =
|
||||
REGISTRATE.block("white_sail", p -> SailBlock.withCanvas(p, DyeColor.WHITE))
|
||||
.initialProperties(SharedProperties::wooden)
|
||||
.properties(p -> p.mapColor(MapColor.SNOW))
|
||||
.properties(p -> p.sound(SoundType.SCAFFOLDING)
|
||||
.properties(p -> p.mapColor(MapColor.SNOW)
|
||||
.sound(SoundType.SCAFFOLDING)
|
||||
.noOcclusion())
|
||||
.transform(axeOnly())
|
||||
.blockstate(BlockStateGen.directionalBlockProvider(false))
|
||||
|
@ -1437,8 +1416,8 @@ public class AllBlocks {
|
|||
String colourName = colour.getSerializedName();
|
||||
return REGISTRATE.block(colourName + "_sail", p -> SailBlock.withCanvas(p, colour))
|
||||
.initialProperties(SharedProperties::wooden)
|
||||
.properties(p -> p.mapColor(colour.getMapColor()))
|
||||
.properties(p -> p.sound(SoundType.SCAFFOLDING)
|
||||
.properties(p -> p.mapColor(colour.getMapColor())
|
||||
.sound(SoundType.SCAFFOLDING)
|
||||
.noOcclusion())
|
||||
.transform(axeOnly())
|
||||
.blockstate((c, p) -> p.directionalBlock(c.get(), p.models()
|
||||
|
@ -1460,8 +1439,7 @@ public class AllBlocks {
|
|||
.register();
|
||||
|
||||
public static final BlockEntry<CasingBlock> COPPER_CASING = REGISTRATE.block("copper_casing", CasingBlock::new)
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_LIGHT_GRAY))
|
||||
.properties(p -> p.sound(SoundType.COPPER))
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_LIGHT_GRAY).sound(SoundType.COPPER))
|
||||
.transform(BuilderTransformers.casing(() -> AllSpriteShifts.COPPER_CASING))
|
||||
.register();
|
||||
|
||||
|
@ -1483,8 +1461,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<MechanicalCrafterBlock> MECHANICAL_CRAFTER =
|
||||
REGISTRATE.block("mechanical_crafter", MechanicalCrafterBlock::new)
|
||||
.initialProperties(SharedProperties::softMetal)
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_YELLOW))
|
||||
.properties(BlockBehaviour.Properties::noOcclusion)
|
||||
.properties(p -> p.noOcclusion().mapColor(MapColor.TERRACOTTA_YELLOW))
|
||||
.transform(axeOrPickaxe())
|
||||
.blockstate(BlockStateGen.horizontalBlockProvider(true))
|
||||
.transform(BlockStressDefaults.setImpact(2.0))
|
||||
|
@ -1509,8 +1486,7 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<FlywheelBlock> FLYWHEEL = REGISTRATE.block("flywheel", FlywheelBlock::new)
|
||||
.initialProperties(SharedProperties::softMetal)
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_YELLOW))
|
||||
.properties(BlockBehaviour.Properties::noOcclusion)
|
||||
.properties(p -> p.noOcclusion().mapColor(MapColor.TERRACOTTA_YELLOW))
|
||||
.transform(axeOrPickaxe())
|
||||
.transform(BlockStressDefaults.setNoImpact())
|
||||
.blockstate(BlockStateGen.axisBlockProvider(true))
|
||||
|
@ -1551,7 +1527,8 @@ public class AllBlocks {
|
|||
.properties(p -> p.mapColor(MapColor.METAL)
|
||||
.strength(0.8F)
|
||||
.sound(SoundType.METAL)
|
||||
.noOcclusion())
|
||||
.noOcclusion()
|
||||
.forceSolidOn())
|
||||
.addLayer(() -> RenderType::cutoutMipped)
|
||||
.transform(pickaxeOnly())
|
||||
.onRegister(CreateRegistrate.blockModel(() -> TrackModel::new))
|
||||
|
@ -1578,15 +1555,13 @@ public class AllBlocks {
|
|||
public static final BlockEntry<CasingBlock> RAILWAY_CASING = REGISTRATE.block("railway_casing", CasingBlock::new)
|
||||
.transform(BuilderTransformers.layeredCasing(() -> AllSpriteShifts.RAILWAY_CASING_SIDE,
|
||||
() -> AllSpriteShifts.RAILWAY_CASING))
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_CYAN))
|
||||
.properties(p -> p.sound(SoundType.NETHERITE_BLOCK))
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_CYAN).sound(SoundType.NETHERITE_BLOCK))
|
||||
.lang("Train Casing")
|
||||
.register();
|
||||
|
||||
public static final BlockEntry<StationBlock> TRACK_STATION = REGISTRATE.block("track_station", StationBlock::new)
|
||||
.initialProperties(SharedProperties::softMetal)
|
||||
.properties(p -> p.mapColor(MapColor.PODZOL))
|
||||
.properties(p -> p.sound(SoundType.NETHERITE_BLOCK))
|
||||
.properties(p -> p.mapColor(MapColor.PODZOL).sound(SoundType.NETHERITE_BLOCK))
|
||||
.transform(pickaxeOnly())
|
||||
.blockstate((c, p) -> p.simpleBlock(c.get(), AssetLookup.partialBaseModel(c, p)))
|
||||
.onRegister(assignDataBehaviour(new StationSummaryDisplaySource(), "station_summary"))
|
||||
|
@ -1598,9 +1573,9 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<SignalBlock> TRACK_SIGNAL = REGISTRATE.block("track_signal", SignalBlock::new)
|
||||
.initialProperties(SharedProperties::softMetal)
|
||||
.properties(p -> p.mapColor(MapColor.PODZOL))
|
||||
.properties(p -> p.noOcclusion())
|
||||
.properties(p -> p.sound(SoundType.NETHERITE_BLOCK))
|
||||
.properties(p -> p.mapColor(MapColor.PODZOL)
|
||||
.noOcclusion()
|
||||
.sound(SoundType.NETHERITE_BLOCK))
|
||||
.transform(pickaxeOnly())
|
||||
.blockstate((c, p) -> p.getVariantBuilder(c.get())
|
||||
.forAllStates(state -> ConfiguredModel.builder()
|
||||
|
@ -1615,9 +1590,9 @@ public class AllBlocks {
|
|||
public static final BlockEntry<TrackObserverBlock> TRACK_OBSERVER =
|
||||
REGISTRATE.block("track_observer", TrackObserverBlock::new)
|
||||
.initialProperties(SharedProperties::softMetal)
|
||||
.properties(p -> p.mapColor(MapColor.PODZOL))
|
||||
.properties(p -> p.noOcclusion())
|
||||
.properties(p -> p.sound(SoundType.NETHERITE_BLOCK))
|
||||
.properties(p -> p.mapColor(MapColor.PODZOL)
|
||||
.noOcclusion()
|
||||
.sound(SoundType.NETHERITE_BLOCK))
|
||||
.blockstate((c, p) -> BlockStateGen.simpleBlock(c, p, AssetLookup.forPowered(c, p)))
|
||||
.transform(pickaxeOnly())
|
||||
.onRegister(assignDataBehaviour(new ObservedTrainNameSource(), "observed_train_name"))
|
||||
|
@ -1640,8 +1615,7 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<ControlsBlock> TRAIN_CONTROLS = REGISTRATE.block("controls", ControlsBlock::new)
|
||||
.initialProperties(SharedProperties::softMetal)
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_BROWN))
|
||||
.properties(p -> p.sound(SoundType.NETHERITE_BLOCK))
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_BROWN).sound(SoundType.NETHERITE_BLOCK))
|
||||
.addLayer(() -> RenderType::cutoutMipped)
|
||||
.transform(pickaxeOnly())
|
||||
.blockstate((c, p) -> p.horizontalBlock(c.get(),
|
||||
|
@ -1656,8 +1630,7 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<ItemVaultBlock> ITEM_VAULT = REGISTRATE.block("item_vault", ItemVaultBlock::new)
|
||||
.initialProperties(SharedProperties::softMetal)
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_BLUE))
|
||||
.properties(p -> p.sound(SoundType.NETHERITE_BLOCK)
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_BLUE).sound(SoundType.NETHERITE_BLOCK)
|
||||
.explosionResistance(1200))
|
||||
.transform(pickaxeOnly())
|
||||
.blockstate((c, p) -> p.getVariantBuilder(c.get())
|
||||
|
@ -1742,8 +1715,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<SmartObserverBlock> SMART_OBSERVER =
|
||||
REGISTRATE.block("content_observer", SmartObserverBlock::new)
|
||||
.initialProperties(SharedProperties::stone)
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_BROWN))
|
||||
.properties(p -> p.noOcclusion())
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_BROWN).noOcclusion())
|
||||
.transform(axeOrPickaxe())
|
||||
.blockstate(new SmartObserverGenerator()::generate)
|
||||
.onRegister(assignDataBehaviour(new ItemCountDisplaySource(), "count_items"))
|
||||
|
@ -1758,8 +1730,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<ThresholdSwitchBlock> THRESHOLD_SWITCH =
|
||||
REGISTRATE.block("stockpile_switch", ThresholdSwitchBlock::new)
|
||||
.initialProperties(SharedProperties::stone)
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_BROWN))
|
||||
.properties(p -> p.noOcclusion())
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_BROWN).noOcclusion())
|
||||
.transform(axeOrPickaxe())
|
||||
.blockstate(new ThresholdSwitchGenerator()::generate)
|
||||
.onRegister(assignDataBehaviour(new FillLevelDisplaySource(), "fill_level"))
|
||||
|
@ -1802,8 +1773,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<NixieTubeBlock> ORANGE_NIXIE_TUBE =
|
||||
REGISTRATE.block("nixie_tube", p -> new NixieTubeBlock(p, DyeColor.ORANGE))
|
||||
.initialProperties(SharedProperties::softMetal)
|
||||
.properties(p -> p.lightLevel($ -> 5))
|
||||
.properties(p -> p.mapColor(DyeColor.ORANGE))
|
||||
.properties(p -> p.lightLevel($ -> 5).mapColor(DyeColor.ORANGE).forceSolidOn())
|
||||
.transform(pickaxeOnly())
|
||||
.blockstate(new NixieTubeGenerator()::generate)
|
||||
.addLayer(() -> RenderType::translucent)
|
||||
|
@ -1817,8 +1787,7 @@ public class AllBlocks {
|
|||
String colourName = colour.getSerializedName();
|
||||
return REGISTRATE.block(colourName + "_nixie_tube", p -> new NixieTubeBlock(p, colour))
|
||||
.initialProperties(SharedProperties::softMetal)
|
||||
.properties(p -> p.mapColor(colour))
|
||||
.properties(p -> p.lightLevel($ -> 5))
|
||||
.properties(p -> p.lightLevel($ -> 5).mapColor(colour).forceSolidOn())
|
||||
.transform(pickaxeOnly())
|
||||
.blockstate(new NixieTubeGenerator()::generate)
|
||||
.loot((p, b) -> p.dropOther(b, ORANGE_NIXIE_TUBE.get()))
|
||||
|
@ -1844,7 +1813,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<RedstoneLinkBlock> REDSTONE_LINK =
|
||||
REGISTRATE.block("redstone_link", RedstoneLinkBlock::new)
|
||||
.initialProperties(SharedProperties::wooden)
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_BROWN))
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_BROWN).forceSolidOn())
|
||||
.transform(axeOrPickaxe())
|
||||
.tag(AllBlockTags.BRITTLE.tag, AllBlockTags.SAFE_NBT.tag)
|
||||
.blockstate(new RedstoneLinkGenerator()::generate)
|
||||
|
@ -1866,6 +1835,7 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<PlacardBlock> PLACARD = REGISTRATE.block("placard", PlacardBlock::new)
|
||||
.initialProperties(SharedProperties::copperMetal)
|
||||
.properties(p -> p.forceSolidOn())
|
||||
.transform(pickaxeOnly())
|
||||
.blockstate((c, p) -> p.horizontalFaceBlock(c.get(), AssetLookup.standardModel(c, p)))
|
||||
.simpleItem()
|
||||
|
@ -1935,14 +1905,14 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<PeculiarBellBlock> PECULIAR_BELL =
|
||||
REGISTRATE.block("peculiar_bell", PeculiarBellBlock::new)
|
||||
.properties(p -> p.mapColor(MapColor.GOLD))
|
||||
.properties(p -> p.mapColor(MapColor.GOLD).forceSolidOn())
|
||||
.transform(BuilderTransformers.bell())
|
||||
.onRegister(movementBehaviour(new BellMovementBehaviour()))
|
||||
.register();
|
||||
|
||||
public static final BlockEntry<HauntedBellBlock> HAUNTED_BELL =
|
||||
REGISTRATE.block("haunted_bell", HauntedBellBlock::new)
|
||||
.properties(p -> p.mapColor(MapColor.SAND))
|
||||
.properties(p -> p.mapColor(MapColor.SAND).forceSolidOn())
|
||||
.transform(BuilderTransformers.bell())
|
||||
.onRegister(movementBehaviour(new HauntedBellMovementBehaviour()))
|
||||
.register();
|
||||
|
@ -1951,8 +1921,7 @@ public class AllBlocks {
|
|||
String colourName = colour.getSerializedName();
|
||||
return REGISTRATE.block(colourName + "_toolbox", p -> new ToolboxBlock(p, colour))
|
||||
.initialProperties(SharedProperties::wooden)
|
||||
.properties(p -> p.sound(SoundType.WOOD))
|
||||
.properties(p -> p.mapColor(colour))
|
||||
.properties(p -> p.sound(SoundType.WOOD).mapColor(colour).forceSolidOn())
|
||||
.addLayer(() -> RenderType::cutoutMipped)
|
||||
.loot((lt, block) -> {
|
||||
Builder builder = LootTable.lootTable();
|
||||
|
@ -1984,6 +1953,7 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<ClipboardBlock> CLIPBOARD = REGISTRATE.block("clipboard", ClipboardBlock::new)
|
||||
.initialProperties(SharedProperties::wooden)
|
||||
.properties(p -> p.forceSolidOn())
|
||||
.transform(axeOrPickaxe())
|
||||
.tag(AllBlockTags.SAFE_NBT.tag)
|
||||
.blockstate((c, p) -> p.horizontalFaceBlock(c.get(),
|
||||
|
@ -1996,8 +1966,10 @@ public class AllBlocks {
|
|||
.register();
|
||||
|
||||
// Materials
|
||||
|
||||
static { REGISTRATE.useCreativeTab(AllCreativeModeTabs.BUILDING_BLOCKS_TAB); }
|
||||
|
||||
static {
|
||||
REGISTRATE.setCreativeTab(AllCreativeModeTabs.PALETTES_CREATIVE_TAB);
|
||||
}
|
||||
|
||||
public static final BlockEntry<MetalLadderBlock> ANDESITE_LADDER =
|
||||
REGISTRATE.block("andesite_ladder", MetalLadderBlock::new)
|
||||
|
@ -2047,10 +2019,9 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<GirderBlock> METAL_GIRDER = REGISTRATE.block("metal_girder", GirderBlock::new)
|
||||
.initialProperties(SharedProperties::softMetal)
|
||||
.blockstate(GirderBlockStateGenerator::blockState)
|
||||
.properties(p -> p.mapColor(MapColor.COLOR_GRAY))
|
||||
.properties(p -> p.sound(SoundType.NETHERITE_BLOCK))
|
||||
.properties(p -> p.mapColor(MapColor.COLOR_GRAY).sound(SoundType.NETHERITE_BLOCK))
|
||||
.transform(pickaxeOnly())
|
||||
.blockstate(GirderBlockStateGenerator::blockState)
|
||||
.onRegister(CreateRegistrate.blockModel(() -> ConnectedGirderModel::new))
|
||||
.item()
|
||||
.transform(customItemModel())
|
||||
|
@ -2059,10 +2030,9 @@ public class AllBlocks {
|
|||
public static final BlockEntry<GirderEncasedShaftBlock> METAL_GIRDER_ENCASED_SHAFT =
|
||||
REGISTRATE.block("metal_girder_encased_shaft", GirderEncasedShaftBlock::new)
|
||||
.initialProperties(SharedProperties::softMetal)
|
||||
.blockstate(GirderBlockStateGenerator::blockStateWithShaft)
|
||||
.properties(p -> p.mapColor(MapColor.COLOR_GRAY))
|
||||
.properties(p -> p.sound(SoundType.NETHERITE_BLOCK))
|
||||
.properties(p -> p.mapColor(MapColor.COLOR_GRAY).sound(SoundType.NETHERITE_BLOCK))
|
||||
.transform(pickaxeOnly())
|
||||
.blockstate(GirderBlockStateGenerator::blockStateWithShaft)
|
||||
.loot((p, b) -> p.add(b, p.createSingleItemTable(METAL_GIRDER.get())
|
||||
.withPool(p.applyExplosionCondition(SHAFT.get(), LootPool.lootPool()
|
||||
.setRolls(ConstantValue.exactly(1.0F))
|
||||
|
@ -2081,6 +2051,7 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<CopycatStepBlock> COPYCAT_STEP =
|
||||
REGISTRATE.block("copycat_step", CopycatStepBlock::new)
|
||||
.properties(p -> p.forceSolidOn())
|
||||
.transform(BuilderTransformers.copycat())
|
||||
.onRegister(CreateRegistrate.blockModel(() -> CopycatStepModel::new))
|
||||
.item()
|
||||
|
@ -2203,8 +2174,8 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<Block> ZINC_ORE = REGISTRATE.block("zinc_ore", Block::new)
|
||||
.initialProperties(() -> Blocks.GOLD_ORE)
|
||||
.properties(p -> p.mapColor(MapColor.METAL))
|
||||
.properties(p -> p.requiresCorrectToolForDrops()
|
||||
.properties(p -> p.mapColor(MapColor.METAL)
|
||||
.requiresCorrectToolForDrops()
|
||||
.sound(SoundType.STONE))
|
||||
.transform(pickaxeOnly())
|
||||
.loot((lt, b) -> lt.add(b,
|
||||
|
@ -2220,8 +2191,8 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<Block> DEEPSLATE_ZINC_ORE = REGISTRATE.block("deepslate_zinc_ore", Block::new)
|
||||
.initialProperties(() -> Blocks.DEEPSLATE_GOLD_ORE)
|
||||
.properties(p -> p.mapColor(MapColor.STONE))
|
||||
.properties(p -> p.requiresCorrectToolForDrops()
|
||||
.properties(p -> p.mapColor(MapColor.STONE)
|
||||
.requiresCorrectToolForDrops()
|
||||
.sound(SoundType.DEEPSLATE))
|
||||
.transform(pickaxeOnly())
|
||||
.loot((lt, b) -> lt.add(b,
|
||||
|
@ -2237,8 +2208,7 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<Block> RAW_ZINC_BLOCK = REGISTRATE.block("raw_zinc_block", Block::new)
|
||||
.initialProperties(() -> Blocks.RAW_GOLD_BLOCK)
|
||||
.properties(p -> p.mapColor(MapColor.GLOW_LICHEN))
|
||||
.properties(p -> p.requiresCorrectToolForDrops())
|
||||
.properties(p -> p.mapColor(MapColor.GLOW_LICHEN).requiresCorrectToolForDrops())
|
||||
.transform(pickaxeOnly())
|
||||
.tag(Tags.Blocks.STORAGE_BLOCKS)
|
||||
.tag(BlockTags.NEEDS_IRON_TOOL)
|
||||
|
@ -2250,8 +2220,7 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<Block> ZINC_BLOCK = REGISTRATE.block("zinc_block", Block::new)
|
||||
.initialProperties(() -> Blocks.IRON_BLOCK)
|
||||
.properties(p -> p.mapColor(MapColor.GLOW_LICHEN))
|
||||
.properties(p -> p.requiresCorrectToolForDrops())
|
||||
.properties(p -> p.mapColor(MapColor.GLOW_LICHEN).requiresCorrectToolForDrops())
|
||||
.transform(pickaxeOnly())
|
||||
.tag(BlockTags.NEEDS_IRON_TOOL)
|
||||
.tag(Tags.Blocks.STORAGE_BLOCKS)
|
||||
|
@ -2264,8 +2233,7 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<Block> ANDESITE_ALLOY_BLOCK = REGISTRATE.block("andesite_alloy_block", Block::new)
|
||||
.initialProperties(() -> Blocks.ANDESITE)
|
||||
.properties(p -> p.mapColor(MapColor.STONE))
|
||||
.properties(p -> p.requiresCorrectToolForDrops())
|
||||
.properties(p -> p.mapColor(MapColor.STONE).requiresCorrectToolForDrops())
|
||||
.transform(pickaxeOnly())
|
||||
.blockstate(simpleCubeAll("andesite_block"))
|
||||
.tag(Tags.Blocks.STORAGE_BLOCKS)
|
||||
|
@ -2277,9 +2245,9 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<Block> INDUSTRIAL_IRON_BLOCK = REGISTRATE.block("industrial_iron_block", Block::new)
|
||||
.initialProperties(SharedProperties::softMetal)
|
||||
.properties(p -> p.mapColor(MapColor.COLOR_GRAY))
|
||||
.properties(p -> p.sound(SoundType.NETHERITE_BLOCK))
|
||||
.properties(p -> p.requiresCorrectToolForDrops())
|
||||
.properties(p -> p.mapColor(MapColor.COLOR_GRAY)
|
||||
.sound(SoundType.NETHERITE_BLOCK)
|
||||
.requiresCorrectToolForDrops())
|
||||
.transform(pickaxeOnly())
|
||||
.blockstate((c, p) -> p.simpleBlock(c.get(), p.models()
|
||||
.cubeColumn(c.getName(), p.modLoc("block/industrial_iron_block"),
|
||||
|
@ -2293,8 +2261,7 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<Block> BRASS_BLOCK = REGISTRATE.block("brass_block", Block::new)
|
||||
.initialProperties(() -> Blocks.IRON_BLOCK)
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_YELLOW))
|
||||
.properties(p -> p.requiresCorrectToolForDrops())
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_YELLOW).requiresCorrectToolForDrops())
|
||||
.transform(pickaxeOnly())
|
||||
.blockstate(simpleCubeAll("brass_block"))
|
||||
.tag(BlockTags.NEEDS_IRON_TOOL)
|
||||
|
@ -2309,12 +2276,12 @@ public class AllBlocks {
|
|||
public static final BlockEntry<ExperienceBlock> EXPERIENCE_BLOCK =
|
||||
REGISTRATE.block("experience_block", ExperienceBlock::new)
|
||||
.initialProperties(SharedProperties::softMetal)
|
||||
.properties(p -> p.mapColor(MapColor.PLANT))
|
||||
.properties(p -> p.sound(new ForgeSoundType(1, .5f, () -> SoundEvents.AMETHYST_BLOCK_BREAK,
|
||||
() -> SoundEvents.AMETHYST_BLOCK_STEP, () -> SoundEvents.AMETHYST_BLOCK_PLACE,
|
||||
() -> SoundEvents.AMETHYST_BLOCK_HIT, () -> SoundEvents.AMETHYST_BLOCK_FALL)))
|
||||
.properties(p -> p.requiresCorrectToolForDrops())
|
||||
.properties(p -> p.lightLevel(s -> 15))
|
||||
.properties(p -> p.mapColor(MapColor.PLANT)
|
||||
.sound(new ForgeSoundType(1, .5f, () -> SoundEvents.AMETHYST_BLOCK_BREAK,
|
||||
() -> SoundEvents.AMETHYST_BLOCK_STEP, () -> SoundEvents.AMETHYST_BLOCK_PLACE,
|
||||
() -> SoundEvents.AMETHYST_BLOCK_HIT, () -> SoundEvents.AMETHYST_BLOCK_FALL))
|
||||
.requiresCorrectToolForDrops()
|
||||
.lightLevel(s -> 15))
|
||||
.blockstate((c, p) -> p.simpleBlock(c.get(), AssetLookup.standardModel(c, p)))
|
||||
.transform(pickaxeOnly())
|
||||
.lang("Block of Experience")
|
||||
|
@ -2343,8 +2310,7 @@ public class AllBlocks {
|
|||
|
||||
public static final BlockEntry<Block> ROSE_QUARTZ_TILES = REGISTRATE.block("rose_quartz_tiles", Block::new)
|
||||
.initialProperties(() -> Blocks.DEEPSLATE)
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_PINK))
|
||||
.properties(p -> p.requiresCorrectToolForDrops())
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_PINK).requiresCorrectToolForDrops())
|
||||
.transform(pickaxeOnly())
|
||||
.blockstate(simpleCubeAll("palettes/rose_quartz_tiles"))
|
||||
.recipe((c, p) -> p.stonecutting(DataIngredient.items(AllItems.POLISHED_ROSE_QUARTZ.get()),
|
||||
|
@ -2355,8 +2321,7 @@ public class AllBlocks {
|
|||
public static final BlockEntry<Block> SMALL_ROSE_QUARTZ_TILES =
|
||||
REGISTRATE.block("small_rose_quartz_tiles", Block::new)
|
||||
.initialProperties(() -> Blocks.DEEPSLATE)
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_PINK))
|
||||
.properties(p -> p.requiresCorrectToolForDrops())
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_PINK).requiresCorrectToolForDrops())
|
||||
.transform(pickaxeOnly())
|
||||
.blockstate(simpleCubeAll("palettes/small_rose_quartz_tiles"))
|
||||
.recipe((c, p) -> p.stonecutting(DataIngredient.items(AllItems.POLISHED_ROSE_QUARTZ.get()),
|
||||
|
|
|
@ -7,13 +7,14 @@ import java.util.Set;
|
|||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||
import org.apache.commons.lang3.mutable.MutableObject;
|
||||
|
||||
import com.simibubi.create.content.contraptions.actors.seat.SeatBlock;
|
||||
import com.simibubi.create.content.decoration.palettes.AllPaletteBlocks;
|
||||
import com.simibubi.create.content.equipment.armor.BacktankUtil;
|
||||
import com.simibubi.create.content.equipment.toolbox.ToolboxBlock;
|
||||
import com.simibubi.create.content.kinetics.crank.ValveHandleBlock;
|
||||
import com.simibubi.create.foundation.data.CreateRegistrate;
|
||||
import com.simibubi.create.foundation.item.TagDependentIngredientItem;
|
||||
import com.tterrag.registrate.util.entry.BlockEntry;
|
||||
import com.tterrag.registrate.util.entry.ItemEntry;
|
||||
|
@ -25,11 +26,11 @@ import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap;
|
|||
import it.unimi.dsi.fastutil.objects.ReferenceArrayList;
|
||||
import it.unimi.dsi.fastutil.objects.ReferenceLinkedOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
|
||||
import net.createmod.catnip.utility.lang.Components;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.entity.ItemRenderer;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.CreativeModeTab;
|
||||
import net.minecraft.world.item.CreativeModeTab.DisplayItemsGenerator;
|
||||
|
@ -53,45 +54,63 @@ import net.minecraftforge.registries.RegistryObject;
|
|||
|
||||
@EventBusSubscriber(bus = Bus.MOD)
|
||||
public class AllCreativeModeTabs {
|
||||
|
||||
private static final DeferredRegister<CreativeModeTab> TAB_REGISTER =
|
||||
private static final DeferredRegister<CreativeModeTab> REGISTER =
|
||||
DeferredRegister.create(Registries.CREATIVE_MODE_TAB, Create.ID);
|
||||
|
||||
public static final RegistryObject<CreativeModeTab> MAIN_TAB = TAB_REGISTER.register("base",
|
||||
public static final RegistryObject<CreativeModeTab> BASE_CREATIVE_TAB = REGISTER.register("base",
|
||||
() -> CreativeModeTab.builder()
|
||||
.title(Component.translatable("itemGroup.create.base"))
|
||||
.title(Components.translatable("itemGroup.create.base"))
|
||||
.withTabsBefore(CreativeModeTabs.SPAWN_EGGS)
|
||||
.icon(() -> AllBlocks.COGWHEEL.asStack())
|
||||
.displayItems(new RegistrateDisplayItemsGenerator(true))
|
||||
.displayItems(new RegistrateDisplayItemsGenerator(true, AllCreativeModeTabs.BASE_CREATIVE_TAB))
|
||||
.build());
|
||||
|
||||
public static final RegistryObject<CreativeModeTab> BUILDING_BLOCKS_TAB = TAB_REGISTER.register("palettes",
|
||||
public static final RegistryObject<CreativeModeTab> PALETTES_CREATIVE_TAB = REGISTER.register("palettes",
|
||||
() -> CreativeModeTab.builder()
|
||||
.title(Component.translatable("itemGroup.create.palettes"))
|
||||
.withTabsBefore(MAIN_TAB.getKey())
|
||||
.title(Components.translatable("itemGroup.create.palettes"))
|
||||
.withTabsBefore(BASE_CREATIVE_TAB.getKey())
|
||||
.icon(() -> AllPaletteBlocks.ORNATE_IRON_WINDOW.asStack())
|
||||
.displayItems(new RegistrateDisplayItemsGenerator(false))
|
||||
.displayItems(new RegistrateDisplayItemsGenerator(false, AllCreativeModeTabs.PALETTES_CREATIVE_TAB))
|
||||
.build());
|
||||
|
||||
|
||||
public static void register(IEventBus modEventBus) {
|
||||
TAB_REGISTER.register(modEventBus);
|
||||
REGISTER.register(modEventBus);
|
||||
}
|
||||
|
||||
public static CreativeModeTab getBaseTab() {
|
||||
return MAIN_TAB.get();
|
||||
}
|
||||
private static class RegistrateDisplayItemsGenerator implements DisplayItemsGenerator {
|
||||
private static final Predicate<Item> IS_ITEM_3D_PREDICATE;
|
||||
|
||||
public static CreativeModeTab getPalettesTab() {
|
||||
return BUILDING_BLOCKS_TAB.get();
|
||||
}
|
||||
|
||||
public static class RegistrateDisplayItemsGenerator implements DisplayItemsGenerator {
|
||||
|
||||
private final boolean mainTab;
|
||||
|
||||
public RegistrateDisplayItemsGenerator(boolean mainTab) {
|
||||
this.mainTab = mainTab;
|
||||
static {
|
||||
MutableObject<Predicate<Item>> isItem3d = new MutableObject<>(item -> false);
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> {
|
||||
isItem3d.setValue(item -> {
|
||||
ItemRenderer itemRenderer = Minecraft.getInstance()
|
||||
.getItemRenderer();
|
||||
BakedModel model = itemRenderer.getModel(new ItemStack(item), null, null, 0);
|
||||
return model.isGui3d();
|
||||
});
|
||||
});
|
||||
IS_ITEM_3D_PREDICATE = isItem3d.getValue();
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
private static Predicate<Item> makeClient3dItemPredicate() {
|
||||
return item -> {
|
||||
ItemRenderer itemRenderer = Minecraft.getInstance()
|
||||
.getItemRenderer();
|
||||
BakedModel model = itemRenderer.getModel(new ItemStack(item), null, null, 0);
|
||||
return model.isGui3d();
|
||||
};
|
||||
}
|
||||
|
||||
private final boolean addItems;
|
||||
private final RegistryObject<CreativeModeTab> tabFilter;
|
||||
|
||||
public RegistrateDisplayItemsGenerator(boolean addItems, RegistryObject<CreativeModeTab> tabFilter) {
|
||||
this.addItems = addItems;
|
||||
this.tabFilter = tabFilter;
|
||||
}
|
||||
|
||||
private static Predicate<Item> makeExclusionPredicate() {
|
||||
Set<Item> exclusions = new ReferenceOpenHashSet<>();
|
||||
|
||||
|
@ -145,22 +164,6 @@ public class AllCreativeModeTabs {
|
|||
|
||||
return exclusions::contains;
|
||||
}
|
||||
|
||||
private static Predicate<Item> make3DPredicate(boolean model3d) {
|
||||
return item -> {
|
||||
MutableBoolean result = new MutableBoolean(false);
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> result.setValue(isItem3d(item) == model3d));
|
||||
return result.getValue();
|
||||
};
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
private static boolean isItem3d(Item item) {
|
||||
ItemRenderer itemRenderer = Minecraft.getInstance()
|
||||
.getItemRenderer();
|
||||
BakedModel model = itemRenderer.getModel(new ItemStack(item), null, null, 0);
|
||||
return model.isGui3d();
|
||||
}
|
||||
|
||||
private static List<ItemOrdering> makeOrderings() {
|
||||
List<ItemOrdering> orderings = new ReferenceArrayList<>();
|
||||
|
@ -253,26 +256,29 @@ public class AllCreativeModeTabs {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void accept(ItemDisplayParameters pParameters, Output output) {
|
||||
public void accept(ItemDisplayParameters parameters, Output output) {
|
||||
Predicate<Item> exclusionPredicate = makeExclusionPredicate();
|
||||
List<ItemOrdering> orderings = makeOrderings();
|
||||
Function<Item, ItemStack> stackFunc = makeStackFunc();
|
||||
Function<Item, TabVisibility> visibilityFunc = makeVisibilityFunc();
|
||||
RegistryObject<CreativeModeTab> tab = mainTab ? MAIN_TAB : BUILDING_BLOCKS_TAB;
|
||||
|
||||
List<Item> items = new LinkedList<>();
|
||||
items.addAll(collectItems(tab, exclusionPredicate.or(make3DPredicate(false))));
|
||||
items.addAll(collectBlocks(tab, exclusionPredicate));
|
||||
items.addAll(collectItems(tab, exclusionPredicate.or(make3DPredicate(true))));
|
||||
if (addItems) {
|
||||
items.addAll(collectItems(exclusionPredicate.or(IS_ITEM_3D_PREDICATE.negate())));
|
||||
}
|
||||
items.addAll(collectBlocks(exclusionPredicate));
|
||||
if (addItems) {
|
||||
items.addAll(collectItems(exclusionPredicate.or(IS_ITEM_3D_PREDICATE)));
|
||||
}
|
||||
|
||||
applyOrderings(items, orderings);
|
||||
outputAll(output, items, stackFunc, visibilityFunc);
|
||||
}
|
||||
|
||||
private List<Item> collectBlocks(RegistryObject<CreativeModeTab> tab, Predicate<Item> exclusionPredicate) {
|
||||
private List<Item> collectBlocks(Predicate<Item> exclusionPredicate) {
|
||||
List<Item> items = new ReferenceArrayList<>();
|
||||
for (RegistryEntry<Block> entry : Create.REGISTRATE.getAll(Registries.BLOCK)) {
|
||||
if (!Create.REGISTRATE.isInCreativeTab(entry, tab))
|
||||
if (!CreateRegistrate.isInCreativeTab(entry, tabFilter))
|
||||
continue;
|
||||
Item item = entry.get()
|
||||
.asItem();
|
||||
|
@ -285,14 +291,10 @@ public class AllCreativeModeTabs {
|
|||
return items;
|
||||
}
|
||||
|
||||
private List<Item> collectItems(RegistryObject<CreativeModeTab> tab, Predicate<Item> exclusionPredicate) {
|
||||
private List<Item> collectItems(Predicate<Item> exclusionPredicate) {
|
||||
List<Item> items = new ReferenceArrayList<>();
|
||||
|
||||
if (!mainTab)
|
||||
return items;
|
||||
|
||||
for (RegistryEntry<Item> entry : Create.REGISTRATE.getAll(Registries.ITEM)) {
|
||||
if (!Create.REGISTRATE.isInCreativeTab(entry, tab))
|
||||
if (!CreateRegistrate.isInCreativeTab(entry, tabFilter))
|
||||
continue;
|
||||
Item item = entry.get();
|
||||
if (item instanceof BlockItem)
|
||||
|
@ -345,4 +347,4 @@ public class AllCreativeModeTabs {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,8 +66,10 @@ import net.minecraft.world.item.Rarity;
|
|||
import net.minecraftforge.common.Tags;
|
||||
|
||||
public class AllItems {
|
||||
|
||||
static { REGISTRATE.useCreativeTab(AllCreativeModeTabs.MAIN_TAB); }
|
||||
|
||||
static {
|
||||
REGISTRATE.setCreativeTab(AllCreativeModeTabs.BASE_CREATIVE_TAB);
|
||||
}
|
||||
|
||||
public static final ItemEntry<Item> WHEAT_FLOUR =
|
||||
taggedIngredient("wheat_flour", forgeItemTag("flour/wheat"), forgeItemTag("flour")),
|
||||
|
|
|
@ -91,6 +91,7 @@ import com.simibubi.create.foundation.networking.SimplePacketBase;
|
|||
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
|
||||
import com.simibubi.create.infrastructure.command.HighlightPacket;
|
||||
import com.simibubi.create.infrastructure.command.SimpleCreateActions;
|
||||
import com.simibubi.create.infrastructure.debugInfo.ServerDebugInfoPacket;
|
||||
|
||||
import net.createmod.catnip.net.ClientboundSimpleActionPacket;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -205,7 +206,7 @@ public enum AllPackets {
|
|||
CONTRAPTION_ACTOR_TOGGLE(ContraptionDisableActorPacket.class, ContraptionDisableActorPacket::new, PLAY_TO_CLIENT),
|
||||
CONTRAPTION_COLLIDER_LOCK(ContraptionColliderLockPacket.class, ContraptionColliderLockPacket::new, PLAY_TO_CLIENT),
|
||||
ATTACHED_COMPUTER(AttachedComputerPacket.class, AttachedComputerPacket::new, PLAY_TO_CLIENT),
|
||||
|
||||
SERVER_DEBUG_INFO(ServerDebugInfoPacket.class, ServerDebugInfoPacket::new, PLAY_TO_CLIENT)
|
||||
;
|
||||
|
||||
static {
|
||||
|
|
|
@ -6,6 +6,7 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
|
@ -319,12 +320,10 @@ public class AllSoundEvents {
|
|||
});
|
||||
}
|
||||
|
||||
public static JsonObject provideLangEntries() {
|
||||
JsonObject object = new JsonObject();
|
||||
public static void provideLang(BiConsumer<String, String> consumer) {
|
||||
for (SoundEntry entry : ALL.values())
|
||||
if (entry.hasSubtitle())
|
||||
object.addProperty(entry.getSubtitleKey(), entry.getSubtitle());
|
||||
return object;
|
||||
consumer.accept(entry.getSubtitleKey(), entry.getSubtitle());
|
||||
}
|
||||
|
||||
public static SoundEntryProvider provider(DataGenerator generator) {
|
||||
|
|
|
@ -78,23 +78,27 @@ public class AllTags {
|
|||
|
||||
BRITTLE,
|
||||
CASING,
|
||||
CONTRAPTION_INVENTORY_DENY,
|
||||
COPYCAT_ALLOW,
|
||||
COPYCAT_DENY,
|
||||
FAN_PROCESSING_CATALYSTS_BLASTING(MOD, "fan_processing_catalysts/blasting"),
|
||||
FAN_PROCESSING_CATALYSTS_HAUNTING(MOD, "fan_processing_catalysts/haunting"),
|
||||
FAN_PROCESSING_CATALYSTS_SMOKING(MOD, "fan_processing_catalysts/smoking"),
|
||||
FAN_PROCESSING_CATALYSTS_SPLASHING(MOD, "fan_processing_catalysts/splashing"),
|
||||
FAN_TRANSPARENT,
|
||||
NON_MOVABLE,
|
||||
GIRDABLE_TRACKS,
|
||||
MOVABLE_EMPTY_COLLIDER,
|
||||
NON_MOVABLE,
|
||||
ORE_OVERRIDE_STONE,
|
||||
PASSIVE_BOILER_HEATERS,
|
||||
SAFE_NBT,
|
||||
SEATS,
|
||||
TOOLBOXES,
|
||||
TRACKS,
|
||||
GIRDABLE_TRACKS,
|
||||
TREE_ATTACHMENTS,
|
||||
VALVE_HANDLES,
|
||||
WINDMILL_SAILS,
|
||||
WRENCH_PICKUP,
|
||||
COPYCAT_ALLOW,
|
||||
COPYCAT_DENY,
|
||||
CONTRAPTION_INVENTORY_DENY,
|
||||
|
||||
RELOCATION_NOT_SUPPORTED(FORGE),
|
||||
WG_STONE(FORGE),
|
||||
|
@ -156,8 +160,10 @@ public class AllTags {
|
|||
BLAZE_BURNER_FUEL_REGULAR(MOD, "blaze_burner_fuel/regular"),
|
||||
BLAZE_BURNER_FUEL_SPECIAL(MOD, "blaze_burner_fuel/special"),
|
||||
CASING,
|
||||
CONTRAPTION_CONTROLLED,
|
||||
CREATE_INGOTS,
|
||||
CRUSHED_RAW_MATERIALS,
|
||||
DEPLOYABLE_DRINK,
|
||||
MODDED_STRIPPED_LOGS,
|
||||
MODDED_STRIPPED_WOOD,
|
||||
PRESSURIZED_AIR_SOURCES,
|
||||
|
@ -169,8 +175,6 @@ public class AllTags {
|
|||
VALVE_HANDLES,
|
||||
VANILLA_STRIPPED_LOGS,
|
||||
VANILLA_STRIPPED_WOOD,
|
||||
DEPLOYABLE_DRINK,
|
||||
CONTRAPTION_CONTROLLED,
|
||||
|
||||
STRIPPED_LOGS(FORGE),
|
||||
STRIPPED_WOOD(FORGE),
|
||||
|
@ -226,6 +230,10 @@ public class AllTags {
|
|||
|
||||
BOTTOMLESS_ALLOW(MOD, "bottomless/allow"),
|
||||
BOTTOMLESS_DENY(MOD, "bottomless/deny"),
|
||||
FAN_PROCESSING_CATALYSTS_BLASTING(MOD, "fan_processing_catalysts/blasting"),
|
||||
FAN_PROCESSING_CATALYSTS_HAUNTING(MOD, "fan_processing_catalysts/haunting"),
|
||||
FAN_PROCESSING_CATALYSTS_SMOKING(MOD, "fan_processing_catalysts/smoking"),
|
||||
FAN_PROCESSING_CATALYSTS_SPLASHING(MOD, "fan_processing_catalysts/splashing"),
|
||||
|
||||
HONEY(FORGE)
|
||||
|
||||
|
@ -275,6 +283,7 @@ public class AllTags {
|
|||
|
||||
public enum AllEntityTags {
|
||||
|
||||
BLAZE_BURNER_CAPTURABLE,
|
||||
IGNORE_SEAT,
|
||||
|
||||
;
|
||||
|
@ -308,9 +317,12 @@ public class AllTags {
|
|||
this.alwaysDatagen = alwaysDatagen;
|
||||
}
|
||||
|
||||
public boolean matches(EntityType<?> type) {
|
||||
return type.is(tag);
|
||||
}
|
||||
|
||||
public boolean matches(Entity entity) {
|
||||
return entity.getType()
|
||||
.is(tag);
|
||||
return matches(entity.getType());
|
||||
}
|
||||
|
||||
private static void init() {}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package com.simibubi.create;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
||||
|
@ -24,43 +23,30 @@ import com.simibubi.create.content.redstone.link.RedstoneLinkNetworkHandler;
|
|||
import com.simibubi.create.content.schematics.ServerSchematicLoader;
|
||||
import com.simibubi.create.content.trains.GlobalRailwayManager;
|
||||
import com.simibubi.create.content.trains.bogey.BogeySizes;
|
||||
import com.simibubi.create.content.trains.track.AllPortalTracks;
|
||||
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
||||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||
import com.simibubi.create.foundation.block.CopperRegistries;
|
||||
import com.simibubi.create.foundation.data.CreateRegistrate;
|
||||
import com.simibubi.create.foundation.data.DamageTypeTagGen;
|
||||
import com.simibubi.create.foundation.data.GeneratedEntriesProvider;
|
||||
import com.simibubi.create.foundation.data.LangMerger;
|
||||
import com.simibubi.create.foundation.data.RecipeSerializerTagGen;
|
||||
import com.simibubi.create.foundation.data.TagGen;
|
||||
import com.simibubi.create.foundation.data.recipe.MechanicalCraftingRecipeGen;
|
||||
import com.simibubi.create.foundation.data.recipe.ProcessingRecipeGen;
|
||||
import com.simibubi.create.foundation.data.recipe.SequencedAssemblyRecipeGen;
|
||||
import com.simibubi.create.foundation.data.recipe.StandardRecipeGen;
|
||||
import com.simibubi.create.foundation.gui.CreateTheme;
|
||||
import com.simibubi.create.foundation.item.ItemDescription;
|
||||
import com.simibubi.create.foundation.item.KineticStats;
|
||||
import com.simibubi.create.foundation.item.TooltipModifier;
|
||||
import com.simibubi.create.foundation.ponder.CreatePonderPlugin;
|
||||
import com.simibubi.create.foundation.utility.AttachedRegistry;
|
||||
import com.simibubi.create.foundation.utility.CreateNBTProcessors;
|
||||
import com.simibubi.create.infrastructure.command.ServerLagger;
|
||||
import com.simibubi.create.infrastructure.config.AllConfigs;
|
||||
import com.simibubi.create.infrastructure.data.CreateDatagen;
|
||||
import com.simibubi.create.infrastructure.worldgen.AllFeatures;
|
||||
import com.simibubi.create.infrastructure.worldgen.AllPlacementModifiers;
|
||||
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.createmod.catnip.utility.lang.LangBuilder;
|
||||
import net.createmod.ponder.foundation.PonderIndex;
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.common.ForgeMod;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.data.event.GatherDataEvent;
|
||||
import net.minecraftforge.eventbus.api.EventPriority;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
|
@ -74,7 +60,7 @@ public class Create {
|
|||
|
||||
public static final String ID = "create";
|
||||
public static final String NAME = "Create";
|
||||
public static final String VERSION = "0.5.1e";
|
||||
public static final String VERSION = "0.6-experimental";
|
||||
|
||||
public static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
|
@ -86,6 +72,10 @@ public class Create {
|
|||
@Deprecated
|
||||
public static final Random RANDOM = new Random();
|
||||
|
||||
/**
|
||||
* <b>Other mods should not use this field!</b> If you are an addon developer, create your own instance of
|
||||
* {@link CreateRegistrate}.
|
||||
*/
|
||||
public static final CreateRegistrate REGISTRATE = CreateRegistrate.create(ID);
|
||||
|
||||
static {
|
||||
|
@ -138,6 +128,7 @@ public class Create {
|
|||
// FIXME: some of these registrations are not thread-safe
|
||||
AllMovementBehaviours.registerDefaults();
|
||||
AllInteractionBehaviours.registerDefaults();
|
||||
AllPortalTracks.registerDefaults();
|
||||
AllDisplayBehaviours.registerDefaults();
|
||||
ContraptionMovementSetting.registerDefaults();
|
||||
AllArmInteractionPointTypes.register();
|
||||
|
@ -153,7 +144,7 @@ public class Create {
|
|||
CopperRegistries.inject();
|
||||
|
||||
modEventBus.addListener(Create::init);
|
||||
modEventBus.addListener(EventPriority.LOW, Create::gatherData);
|
||||
modEventBus.addListener(EventPriority.LOWEST, CreateDatagen::gatherData);
|
||||
modEventBus.addListener(AllSoundEvents::register);
|
||||
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> CreateClient.onCtorClient(modEventBus, forgeEventBus));
|
||||
|
@ -180,36 +171,6 @@ public class Create {
|
|||
});
|
||||
}
|
||||
|
||||
public static void gatherData(GatherDataEvent event) {
|
||||
TagGen.datagen();
|
||||
DataGenerator gen = event.getGenerator();
|
||||
PackOutput output = gen.getPackOutput();
|
||||
CompletableFuture<HolderLookup.Provider> lookupProvider = event.getLookupProvider();
|
||||
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> PonderIndex.addPlugin(new CreatePonderPlugin()));
|
||||
|
||||
gen.addProvider(event.includeClient(), AllSoundEvents.provider(gen));
|
||||
|
||||
GeneratedEntriesProvider generatedEntriesProvider = new GeneratedEntriesProvider(output, lookupProvider);
|
||||
lookupProvider = generatedEntriesProvider.getRegistryProvider();
|
||||
gen.addProvider(event.includeServer(), generatedEntriesProvider);
|
||||
|
||||
gen.addProvider(event.includeServer(), new RecipeSerializerTagGen(output, lookupProvider, event.getExistingFileHelper()));
|
||||
gen.addProvider(event.includeServer(), new DamageTypeTagGen(output, lookupProvider, event.getExistingFileHelper()));
|
||||
gen.addProvider(event.includeServer(), new AllAdvancements(output));
|
||||
gen.addProvider(event.includeServer(), new StandardRecipeGen(output));
|
||||
gen.addProvider(event.includeServer(), new MechanicalCraftingRecipeGen(output));
|
||||
gen.addProvider(event.includeServer(), new SequencedAssemblyRecipeGen(output));
|
||||
|
||||
if (event.includeClient()) {
|
||||
LangMerger.attachToRegistrateProvider(gen, output);
|
||||
}
|
||||
|
||||
if (event.includeServer()) {
|
||||
ProcessingRecipeGen.registerAll(gen, output);
|
||||
}
|
||||
}
|
||||
|
||||
public static LangBuilder lang() {
|
||||
return new LangBuilder(ID);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
package com.simibubi.create.api.event;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraftforge.eventbus.api.Event;
|
||||
|
||||
/**
|
||||
* This Event is fired when two fluids meet in a pipe ({@link Flow})<br>
|
||||
* or when a fluid in a pipe meets with a fluid in the world
|
||||
* ({@link Spill}).<br>
|
||||
* <br>
|
||||
* If it is not null, the event's BlockState will be placed in world after
|
||||
* firing.
|
||||
*/
|
||||
public class PipeCollisionEvent extends Event {
|
||||
|
||||
private final Level level;
|
||||
private final BlockPos pos;
|
||||
protected final Fluid firstFluid, secondFluid;
|
||||
|
||||
@Nullable
|
||||
private BlockState state;
|
||||
|
||||
protected PipeCollisionEvent(Level level, BlockPos pos, Fluid firstFluid, Fluid secondFluid,
|
||||
@Nullable BlockState defaultState) {
|
||||
this.level = level;
|
||||
this.pos = pos;
|
||||
this.firstFluid = firstFluid;
|
||||
this.secondFluid = secondFluid;
|
||||
this.state = defaultState;
|
||||
}
|
||||
|
||||
public Level getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public BlockPos getPos() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public BlockState getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(@Nullable BlockState state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public static class Flow extends PipeCollisionEvent {
|
||||
|
||||
public Flow(Level level, BlockPos pos, Fluid firstFluid, Fluid secondFluid, @Nullable BlockState defaultState) {
|
||||
super(level, pos, firstFluid, secondFluid, defaultState);
|
||||
}
|
||||
|
||||
public Fluid getFirstFluid() {
|
||||
return firstFluid;
|
||||
}
|
||||
|
||||
public Fluid getSecondFluid() {
|
||||
return secondFluid;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Spill extends PipeCollisionEvent {
|
||||
|
||||
public Spill(Level level, BlockPos pos, Fluid worldFluid, Fluid pipeFluid, @Nullable BlockState defaultState) {
|
||||
super(level, pos, worldFluid, pipeFluid, defaultState);
|
||||
}
|
||||
|
||||
public Fluid getWorldFluid() {
|
||||
return firstFluid;
|
||||
}
|
||||
|
||||
public Fluid getPipeFluid() {
|
||||
return secondFluid;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@ import net.minecraftforge.registries.ForgeRegistries;
|
|||
* For compatibility with and without another mod present, we have to define load conditions of the specific code
|
||||
*/
|
||||
public enum Mods {
|
||||
AETHER,
|
||||
COMPUTERCRAFT,
|
||||
CONNECTIVITY,
|
||||
CURIOS,
|
||||
|
|
|
@ -1,5 +1,18 @@
|
|||
package com.simibubi.create.content.contraptions;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang3.mutable.MutableInt;
|
||||
import org.apache.commons.lang3.tuple.MutablePair;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.AllMovementBehaviours;
|
||||
|
@ -24,6 +37,7 @@ import com.simibubi.create.content.trains.entity.Train;
|
|||
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
||||
import com.simibubi.create.foundation.collision.Matrix3d;
|
||||
import com.simibubi.create.foundation.mixin.accessor.ServerLevelAccessor;
|
||||
|
||||
import net.createmod.catnip.utility.VecHelper;
|
||||
import net.createmod.catnip.utility.math.AngleHelper;
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
@ -64,17 +78,6 @@ import net.minecraftforge.entity.IEntityAdditionalSpawnData;
|
|||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.network.NetworkHooks;
|
||||
import net.minecraftforge.network.PacketDistributor;
|
||||
import org.apache.commons.lang3.mutable.MutableInt;
|
||||
import org.apache.commons.lang3.tuple.MutablePair;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class AbstractContraptionEntity extends Entity implements IEntityAdditionalSpawnData {
|
||||
|
||||
|
@ -215,6 +218,9 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
|||
}
|
||||
|
||||
public Vec3 getPassengerPosition(Entity passenger, float partialTicks) {
|
||||
if (contraption == null)
|
||||
return null;
|
||||
|
||||
UUID id = passenger.getUUID();
|
||||
if (passenger instanceof OrientedContraptionEntity) {
|
||||
BlockPos localPos = contraption.getBearingPosOf(id);
|
||||
|
@ -229,6 +235,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
|||
BlockPos seat = contraption.getSeatOf(id);
|
||||
if (seat == null)
|
||||
return null;
|
||||
|
||||
Vec3 transformedVector = toGlobalVector(Vec3.atLowerCornerOf(seat)
|
||||
.add(.5, passenger.getMyRidingOffset() + ySize - .15f, .5), partialTicks)
|
||||
.add(VecHelper.getCenterOf(BlockPos.ZERO))
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
package com.simibubi.create.content.contraptions;
|
||||
|
||||
import static net.createmod.catnip.utility.math.AngleHelper.angleLerp;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.util.transform.TransformStack;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.simibubi.create.AllEntityTypes;
|
||||
|
@ -10,6 +17,7 @@ import com.simibubi.create.content.contraptions.minecart.capability.MinecartCont
|
|||
import com.simibubi.create.content.contraptions.mounted.CartAssemblerBlockEntity.CartMovementMode;
|
||||
import com.simibubi.create.content.contraptions.mounted.MountedContraption;
|
||||
import com.simibubi.create.foundation.item.ItemHelper;
|
||||
|
||||
import net.createmod.catnip.utility.Couple;
|
||||
import net.createmod.catnip.utility.NBTHelper;
|
||||
import net.createmod.catnip.utility.VecHelper;
|
||||
|
@ -41,12 +49,6 @@ import net.minecraftforge.api.distmarker.Dist;
|
|||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static net.createmod.catnip.utility.math.AngleHelper.angleLerp;
|
||||
|
||||
/**
|
||||
* Ex: Minecarts, Couplings <br>
|
||||
* Oriented Contraption Entities can rotate freely around two axes
|
||||
|
@ -567,6 +569,9 @@ public class OrientedContraptionEntity extends AbstractContraptionEntity {
|
|||
private Vec3 getContraptionOffset(float partialTicks, Entity ridingEntity) {
|
||||
AbstractContraptionEntity parent = (AbstractContraptionEntity) ridingEntity;
|
||||
Vec3 passengerPosition = parent.getPassengerPosition(this, partialTicks);
|
||||
if (passengerPosition == null)
|
||||
return Vec3.ZERO;
|
||||
|
||||
double x = passengerPosition.x - Mth.lerp(partialTicks, this.xOld, this.getX());
|
||||
double y = passengerPosition.y - Mth.lerp(partialTicks, this.yOld, this.getY());
|
||||
double z = passengerPosition.z - Mth.lerp(partialTicks, this.zOld, this.getZ());
|
||||
|
|
|
@ -58,7 +58,7 @@ public class PortableStorageInterfaceBlock extends WrenchableDirectionalBlock
|
|||
public BlockState getStateForPlacement(BlockPlaceContext context) {
|
||||
Direction direction = context.getNearestLookingDirection();
|
||||
if (context.getPlayer() != null && context.getPlayer()
|
||||
.isSteppingCarefully())
|
||||
.isShiftKeyDown())
|
||||
direction = direction.getOpposite();
|
||||
return defaultBlockState().setValue(FACING, direction.getOpposite());
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ public class RollerBlockEntity extends SmartBlockEntity {
|
|||
|
||||
protected void acceptSharedValues(int mode, ItemStack filter) {
|
||||
dontPropagate = true;
|
||||
this.filtering.setFilter(filter);
|
||||
this.filtering.setFilter(filter.copy());
|
||||
this.mode.setValue(mode);
|
||||
dontPropagate = false;
|
||||
notifyUpdate();
|
||||
|
|
|
@ -19,7 +19,7 @@ import com.simibubi.create.content.contraptions.render.ActorInstance;
|
|||
import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
|
||||
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher;
|
||||
import com.simibubi.create.content.kinetics.base.BlockBreakingMovementBehaviour;
|
||||
import com.simibubi.create.content.logistics.filter.FilterItem;
|
||||
import com.simibubi.create.content.logistics.filter.FilterItemStack;
|
||||
import com.simibubi.create.content.trains.bogey.StandardBogeyBlock;
|
||||
import com.simibubi.create.content.trains.entity.Carriage;
|
||||
import com.simibubi.create.content.trains.entity.CarriageBogey;
|
||||
|
@ -36,6 +36,7 @@ import com.simibubi.create.foundation.utility.BlockHelper;
|
|||
import com.simibubi.create.infrastructure.config.AllConfigs;
|
||||
|
||||
import net.createmod.catnip.utility.Couple;
|
||||
import net.createmod.catnip.utility.Iterate;
|
||||
import net.createmod.catnip.utility.Pair;
|
||||
import net.createmod.catnip.utility.VecHelper;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
|
@ -102,6 +103,11 @@ public class RollerMovementBehaviour extends BlockBreakingMovementBehaviour {
|
|||
|
||||
@Override
|
||||
public boolean canBreak(Level world, BlockPos breakingPos, BlockState state) {
|
||||
for (Direction side : Iterate.directions)
|
||||
if (world.getBlockState(breakingPos.relative(side))
|
||||
.is(BlockTags.PORTALS))
|
||||
return false;
|
||||
|
||||
return super.canBreak(world, breakingPos, state) && !state.getCollisionShape(world, breakingPos)
|
||||
.isEmpty() && !AllBlocks.TRACK.has(state);
|
||||
}
|
||||
|
@ -188,10 +194,10 @@ public class RollerMovementBehaviour extends BlockBreakingMovementBehaviour {
|
|||
|
||||
int startingY = 1;
|
||||
if (!getStateToPaveWith(context).isAir()) {
|
||||
ItemStack filter = ItemStack.of(context.blockEntityData.getCompound("Filter"));
|
||||
FilterItemStack filter = context.getFilterFromBE();
|
||||
if (!ItemHelper
|
||||
.extract(context.contraption.getSharedInventory(),
|
||||
stack -> FilterItem.test(context.world, stack, filter), 1, true)
|
||||
stack -> filter.test(context.world, stack), 1, true)
|
||||
.isEmpty())
|
||||
startingY = 0;
|
||||
}
|
||||
|
@ -279,8 +285,15 @@ public class RollerMovementBehaviour extends BlockBreakingMovementBehaviour {
|
|||
};
|
||||
rollerScout.travel(train.graph, lengthWiseOffset + 1, steering);
|
||||
|
||||
rollerScout.traversalCallback = (edge, coords) -> TrackPaverV2.pave(heightProfile, train.graph, edge,
|
||||
coords.getFirst(), coords.getSecond());
|
||||
rollerScout.traversalCallback = (edge, coords) -> {
|
||||
if (edge == null)
|
||||
return;
|
||||
if (edge.isInterDimensional())
|
||||
return;
|
||||
if (edge.node1.getLocation().dimension != context.world.dimension())
|
||||
return;
|
||||
TrackPaverV2.pave(heightProfile, train.graph, edge, coords.getFirst(), coords.getSecond());
|
||||
};
|
||||
rollerScout.travel(train.graph, distanceToTravel, steering);
|
||||
|
||||
for (Couple<Integer> entry : heightProfile.keys())
|
||||
|
@ -294,6 +307,9 @@ public class RollerMovementBehaviour extends BlockBreakingMovementBehaviour {
|
|||
BlockState stateToPaveWithAsSlab = getStateToPaveWithAsSlab(context);
|
||||
RollingMode mode = getMode(context);
|
||||
|
||||
if (mode != RollingMode.TUNNEL_PAVE && stateToPaveWith.isAir())
|
||||
return;
|
||||
|
||||
Vec3 directionVec = Vec3.atLowerCornerOf(context.state.getValue(RollerBlock.FACING)
|
||||
.getClockWise()
|
||||
.getNormal());
|
||||
|
@ -457,9 +473,9 @@ public class RollerMovementBehaviour extends BlockBreakingMovementBehaviour {
|
|||
.isEmpty())
|
||||
return PaveResult.FAIL;
|
||||
|
||||
ItemStack filter = ItemStack.of(context.blockEntityData.getCompound("Filter"));
|
||||
FilterItemStack filter = context.getFilterFromBE();
|
||||
ItemStack held = ItemHelper.extract(context.contraption.getSharedInventory(),
|
||||
stack -> FilterItem.test(context.world, stack, filter), 1, false);
|
||||
stack -> filter.test(context.world, stack), 1, false);
|
||||
if (held.isEmpty())
|
||||
return PaveResult.FAIL;
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ public class ControlsBlock extends HorizontalDirectionalBlock implements IWrench
|
|||
Player player = pContext.getPlayer();
|
||||
|
||||
state = state.setValue(FACING, horizontalDirection.getOpposite());
|
||||
if (player != null && player.isSteppingCarefully())
|
||||
if (player != null && player.isShiftKeyDown())
|
||||
state = state.setValue(FACING, horizontalDirection);
|
||||
|
||||
return state;
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.simibubi.create.content.contraptions.behaviour;
|
|||
import java.util.function.UnaryOperator;
|
||||
|
||||
import com.simibubi.create.content.contraptions.Contraption;
|
||||
import com.simibubi.create.content.logistics.filter.FilterItemStack;
|
||||
|
||||
import net.createmod.catnip.utility.VecHelper;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -32,6 +33,8 @@ public class MovementContext {
|
|||
public Contraption contraption;
|
||||
public Object temporaryData;
|
||||
|
||||
private FilterItemStack filter;
|
||||
|
||||
public MovementContext(Level world, StructureBlockInfo info, Contraption contraption) {
|
||||
this.world = world;
|
||||
this.state = info.state();
|
||||
|
@ -47,6 +50,7 @@ public class MovementContext {
|
|||
position = null;
|
||||
data = new CompoundTag();
|
||||
stall = false;
|
||||
filter = null;
|
||||
}
|
||||
|
||||
public float getAnimationSpeed() {
|
||||
|
@ -84,4 +88,10 @@ public class MovementContext {
|
|||
return nbt;
|
||||
}
|
||||
|
||||
public FilterItemStack getFilterFromBE() {
|
||||
if (filter != null)
|
||||
return filter;
|
||||
return filter = FilterItemStack.of(blockEntityData.getCompound("Filter"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.simibubi.create.content.contraptions.elevator;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllPackets;
|
||||
import com.simibubi.create.AllSoundEvents;
|
||||
|
@ -10,6 +12,7 @@ import com.simibubi.create.content.contraptions.pulley.PulleyBlockEntity;
|
|||
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
|
||||
import com.simibubi.create.infrastructure.config.AllConfigs;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
@ -17,8 +20,6 @@ import net.minecraft.util.Mth;
|
|||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ElevatorPulleyBlockEntity extends PulleyBlockEntity {
|
||||
|
||||
private float prevSpeed;
|
||||
|
@ -88,7 +89,7 @@ public class ElevatorPulleyBlockEntity extends PulleyBlockEntity {
|
|||
if (level.isClientSide())
|
||||
targetLevel = ec.clientYTarget;
|
||||
if (!wasArrived && !level.isClientSide()) {
|
||||
triggerContact(ec, targetLevel);
|
||||
triggerContact(ec, targetLevel - ec.contactYOffset);
|
||||
AllSoundEvents.CONTRAPTION_DISASSEMBLE.play(level, null, worldPosition.below((int) offset), 0.75f, 0.8f);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
package com.simibubi.create.content.contraptions.glue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllEntityTypes;
|
||||
import com.simibubi.create.AllItems;
|
||||
|
@ -11,6 +15,7 @@ import com.simibubi.create.content.kinetics.base.DirectionalKineticBlock;
|
|||
import com.simibubi.create.content.schematics.requirement.ISpecialEntityItemRequirement;
|
||||
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
|
||||
import com.simibubi.create.content.schematics.requirement.ItemRequirement.ItemUseType;
|
||||
|
||||
import net.createmod.catnip.utility.Iterate;
|
||||
import net.createmod.catnip.utility.VecHelper;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -50,10 +55,6 @@ import net.minecraft.world.phys.Vec3;
|
|||
import net.minecraftforge.entity.IEntityAdditionalSpawnData;
|
||||
import net.minecraftforge.network.NetworkHooks;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnData, ISpecialEntityItemRequirement {
|
||||
|
||||
public static AABB span(BlockPos startPos, BlockPos endPos) {
|
||||
|
@ -295,9 +296,12 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat
|
|||
return PushReaction.IGNORE;
|
||||
}
|
||||
|
||||
public void setPortalEntrancePos() {
|
||||
portalEntrancePos = blockPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PortalInfo findDimensionEntryPoint(ServerLevel pDestination) {
|
||||
portalEntrancePos = blockPosition();
|
||||
return super.findDimensionEntryPoint(pDestination);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
package com.simibubi.create.content.contraptions.glue;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.simibubi.create.AllPackets;
|
||||
import com.simibubi.create.AllSoundEvents;
|
||||
|
@ -7,6 +11,7 @@ import com.simibubi.create.AllSpecialTextures;
|
|||
import com.simibubi.create.content.contraptions.chassis.AbstractChassisBlock;
|
||||
import com.simibubi.create.foundation.utility.CreateLang;
|
||||
import com.simibubi.create.foundation.utility.RaycastHelper;
|
||||
|
||||
import net.createmod.catnip.CatnipClient;
|
||||
import net.createmod.catnip.utility.lang.Components;
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
@ -25,10 +30,6 @@ import net.minecraft.world.phys.HitResult.Type;
|
|||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.common.ForgeMod;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public class SuperGlueSelectionHandler {
|
||||
|
||||
private static final int PASSIVE = 0x4D9162;
|
||||
|
@ -120,7 +121,7 @@ public class SuperGlueSelectionHandler {
|
|||
return;
|
||||
}
|
||||
|
||||
boolean cancel = player.isSteppingCarefully();
|
||||
boolean cancel = player.isShiftKeyDown();
|
||||
if (cancel && firstPos == null)
|
||||
return;
|
||||
|
||||
|
@ -188,6 +189,8 @@ public class SuperGlueSelectionHandler {
|
|||
|
||||
if (!isGlue(player.getMainHandItem()))
|
||||
return false;
|
||||
if (!player.mayBuild())
|
||||
return false;
|
||||
|
||||
if (attack) {
|
||||
if (selected == null)
|
||||
|
@ -198,7 +201,7 @@ public class SuperGlueSelectionHandler {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (player.isSteppingCarefully()) {
|
||||
if (player.isShiftKeyDown()) {
|
||||
if (firstPos != null) {
|
||||
discard();
|
||||
return true;
|
||||
|
|
|
@ -316,7 +316,7 @@ public abstract class CopycatBlock extends Block implements IBE<CopycatBlockEnti
|
|||
public ItemStack getCloneItemStack(BlockState state, HitResult target, BlockGetter level, BlockPos pos,
|
||||
Player player) {
|
||||
BlockState material = getMaterial(level, pos);
|
||||
if (AllBlocks.COPYCAT_BASE.has(material) || player != null && player.isSteppingCarefully())
|
||||
if (AllBlocks.COPYCAT_BASE.has(material) || player != null && player.isShiftKeyDown())
|
||||
return new ItemStack(this);
|
||||
return material.getCloneItemStack(target, level, pos, player);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package com.simibubi.create.content.decoration.girder;
|
||||
|
||||
import static net.minecraft.world.level.block.FaceAttachedHorizontalDirectionalBlock.FACE;
|
||||
import static net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.AllShapes;
|
||||
|
@ -15,6 +18,7 @@ import com.simibubi.create.content.trains.display.FlapDisplayBlock;
|
|||
import com.simibubi.create.content.trains.track.TrackBlock;
|
||||
import com.simibubi.create.content.trains.track.TrackShape;
|
||||
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
|
||||
|
||||
import net.createmod.catnip.utility.Iterate;
|
||||
import net.createmod.catnip.utility.placement.IPlacementHelper;
|
||||
import net.createmod.catnip.utility.placement.PlacementHelpers;
|
||||
|
@ -60,9 +64,6 @@ import net.minecraft.world.phys.shapes.CollisionContext;
|
|||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
|
||||
import static net.minecraft.world.level.block.FaceAttachedHorizontalDirectionalBlock.FACE;
|
||||
import static net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED;
|
||||
|
||||
public class GirderBlock extends Block implements SimpleWaterloggedBlock, IWrenchable {
|
||||
|
||||
private static final int placementHelperId = PlacementHelpers.register(new GirderPlacementHelper());
|
||||
|
@ -119,7 +120,7 @@ public class GirderBlock extends Block implements SimpleWaterloggedBlock, IWrenc
|
|||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
||||
if (AllItems.WRENCH.isIn(itemInHand) && !pPlayer.isSteppingCarefully()) {
|
||||
if (AllItems.WRENCH.isIn(itemInHand) && !pPlayer.isShiftKeyDown()) {
|
||||
if (GirderWrenchBehavior.handleClick(pLevel, pPos, pState, pHit))
|
||||
return InteractionResult.sidedSuccess(pLevel.isClientSide);
|
||||
return InteractionResult.FAIL;
|
||||
|
|
|
@ -44,7 +44,7 @@ public class GirderWrenchBehavior {
|
|||
Player player = mc.player;
|
||||
ItemStack heldItem = player.getMainHandItem();
|
||||
|
||||
if (player.isSteppingCarefully())
|
||||
if (player.isShiftKeyDown())
|
||||
return;
|
||||
|
||||
if (!AllBlocks.METAL_GIRDER.has(world.getBlockState(pos)))
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
package com.simibubi.create.content.decoration.palettes;
|
||||
|
||||
import static com.simibubi.create.Create.REGISTRATE;
|
||||
import static com.simibubi.create.foundation.data.WindowGen.customWindowBlock;
|
||||
import static com.simibubi.create.foundation.data.WindowGen.customWindowPane;
|
||||
import static com.simibubi.create.foundation.data.WindowGen.framedGlass;
|
||||
import static com.simibubi.create.foundation.data.WindowGen.framedGlassPane;
|
||||
import static com.simibubi.create.foundation.data.WindowGen.woodenWindowBlock;
|
||||
import static com.simibubi.create.foundation.data.WindowGen.woodenWindowPane;
|
||||
|
||||
import com.simibubi.create.AllCreativeModeTabs;
|
||||
import com.simibubi.create.AllSpriteShifts;
|
||||
import com.simibubi.create.Create;
|
||||
|
@ -9,6 +17,7 @@ import com.simibubi.create.foundation.data.BlockStateGen;
|
|||
import com.simibubi.create.foundation.data.WindowGen;
|
||||
import com.tterrag.registrate.util.DataIngredient;
|
||||
import com.tterrag.registrate.util.entry.BlockEntry;
|
||||
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.data.recipes.RecipeCategory;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
@ -20,17 +29,11 @@ import net.minecraft.world.level.block.state.properties.WoodType;
|
|||
import net.minecraft.world.level.material.MapColor;
|
||||
import net.minecraftforge.common.Tags;
|
||||
|
||||
import static com.simibubi.create.Create.REGISTRATE;
|
||||
import static com.simibubi.create.foundation.data.WindowGen.customWindowBlock;
|
||||
import static com.simibubi.create.foundation.data.WindowGen.customWindowPane;
|
||||
import static com.simibubi.create.foundation.data.WindowGen.framedGlass;
|
||||
import static com.simibubi.create.foundation.data.WindowGen.framedGlassPane;
|
||||
import static com.simibubi.create.foundation.data.WindowGen.woodenWindowBlock;
|
||||
import static com.simibubi.create.foundation.data.WindowGen.woodenWindowPane;
|
||||
|
||||
public class AllPaletteBlocks {
|
||||
|
||||
static { REGISTRATE.useCreativeTab(AllCreativeModeTabs.BUILDING_BLOCKS_TAB); }
|
||||
static {
|
||||
REGISTRATE.setCreativeTab(AllCreativeModeTabs.PALETTES_CREATIVE_TAB);
|
||||
}
|
||||
|
||||
// Windows and Glass
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ public class LayeredBlock extends RotatedPillarBlock {
|
|||
.relative(pContext.getClickedFace()
|
||||
.getOpposite()));
|
||||
if (placedOn.getBlock() == this && (pContext.getPlayer() == null || !pContext.getPlayer()
|
||||
.isSteppingCarefully()))
|
||||
.isShiftKeyDown()))
|
||||
stateForPlacement = stateForPlacement.setValue(AXIS, placedOn.getValue(AXIS));
|
||||
return stateForPlacement;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
package com.simibubi.create.content.decoration.palettes;
|
||||
|
||||
import static com.simibubi.create.foundation.data.TagGen.pickaxeOnly;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.foundation.data.CreateRegistrate;
|
||||
import com.tterrag.registrate.builders.BlockBuilder;
|
||||
|
@ -10,6 +15,7 @@ import com.tterrag.registrate.providers.RegistrateRecipeProvider;
|
|||
import com.tterrag.registrate.util.DataIngredient;
|
||||
import com.tterrag.registrate.util.entry.BlockEntry;
|
||||
import com.tterrag.registrate.util.nullness.NonnullType;
|
||||
|
||||
import net.createmod.catnip.utility.lang.Lang;
|
||||
import net.minecraft.data.recipes.RecipeCategory;
|
||||
import net.minecraft.data.recipes.ShapedRecipeBuilder;
|
||||
|
@ -27,11 +33,6 @@ import net.minecraft.world.level.block.WallBlock;
|
|||
import net.minecraft.world.level.block.state.BlockBehaviour.Properties;
|
||||
import net.minecraftforge.client.model.generators.ModelFile;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static com.simibubi.create.foundation.data.TagGen.pickaxeOnly;
|
||||
|
||||
public abstract class PaletteBlockPartial<B extends Block> {
|
||||
|
||||
public static final PaletteBlockPartial<StairBlock> STAIR = new Stairs();
|
||||
|
@ -223,7 +224,7 @@ public abstract class PaletteBlockPartial<B extends Block> {
|
|||
|
||||
@Override
|
||||
protected WallBlock createBlock(Supplier<? extends Block> block) {
|
||||
return new WallBlock(Properties.copy(block.get()));
|
||||
return new WallBlock(Properties.copy(block.get()).forceSolidOn());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -8,6 +8,7 @@ import com.simibubi.create.AllShapes;
|
|||
import com.simibubi.create.AllSoundEvents;
|
||||
import com.simibubi.create.content.equipment.wrench.IWrenchable;
|
||||
import com.simibubi.create.content.logistics.filter.FilterItem;
|
||||
import com.simibubi.create.content.logistics.filter.FilterItemStack;
|
||||
import com.simibubi.create.content.schematics.requirement.ISpecialBlockItemRequirement;
|
||||
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
|
||||
import com.simibubi.create.content.schematics.requirement.ItemRequirement.ItemUseType;
|
||||
|
@ -132,9 +133,9 @@ public class PlacardBlock extends FaceAttachedHorizontalDirectionalBlock
|
|||
return InteractionResult.FAIL;
|
||||
if (pState.getValue(POWERED))
|
||||
return InteractionResult.FAIL;
|
||||
|
||||
boolean test = inBlock.getItem() instanceof FilterItem ? FilterItem.test(pLevel, inHand, inBlock)
|
||||
: ItemHandlerHelper.canItemStacksStack(inHand, inBlock);
|
||||
|
||||
boolean test = inBlock.getItem() instanceof FilterItem ? FilterItemStack.of(inBlock)
|
||||
.test(pLevel, inHand) : ItemHandlerHelper.canItemStacksStack(inHand, inBlock);
|
||||
if (!test) {
|
||||
AllSoundEvents.DENY.play(pLevel, null, pPos, 1, 1);
|
||||
return InteractionResult.SUCCESS;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.simibubi.create.content.equipment.armor;
|
||||
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.AllTags.AllItemTags;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
|
@ -28,13 +28,13 @@ public final class NetheriteDivingHandler {
|
|||
ItemStack to = event.getTo();
|
||||
|
||||
if (slot == EquipmentSlot.HEAD) {
|
||||
if (AllItems.NETHERITE_DIVING_HELMET.isIn(to)) {
|
||||
if (isNetheriteDivingHelmet(to)) {
|
||||
setBit(entity, slot);
|
||||
} else {
|
||||
clearBit(entity, slot);
|
||||
}
|
||||
} else if (slot == EquipmentSlot.CHEST) {
|
||||
if (AllItems.NETHERITE_BACKTANK.isIn(to) && BacktankUtil.hasAirRemaining(to)) {
|
||||
if (isNetheriteBacktank(to) && BacktankUtil.hasAirRemaining(to)) {
|
||||
setBit(entity, slot);
|
||||
} else {
|
||||
clearBit(entity, slot);
|
||||
|
@ -48,6 +48,14 @@ public final class NetheriteDivingHandler {
|
|||
}
|
||||
}
|
||||
|
||||
public static boolean isNetheriteDivingHelmet(ItemStack stack) {
|
||||
return stack.getItem() instanceof DivingHelmetItem && isNetheriteArmor(stack);
|
||||
}
|
||||
|
||||
public static boolean isNetheriteBacktank(ItemStack stack) {
|
||||
return stack.is(AllItemTags.PRESSURIZED_AIR_SOURCES.tag) && isNetheriteArmor(stack);
|
||||
}
|
||||
|
||||
public static boolean isNetheriteArmor(ItemStack stack) {
|
||||
return stack.getItem() instanceof ArmorItem armorItem && armorItem.getMaterial() == ArmorMaterials.NETHERITE;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,24 @@
|
|||
package com.simibubi.create.content.equipment.blueprint;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import com.simibubi.create.AllEntityTypes;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.logistics.filter.FilterItem;
|
||||
import com.simibubi.create.content.logistics.filter.FilterItemStack;
|
||||
import com.simibubi.create.content.schematics.requirement.ISpecialEntityItemRequirement;
|
||||
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
|
||||
import com.simibubi.create.content.schematics.requirement.ItemRequirement.ItemUseType;
|
||||
import com.simibubi.create.foundation.networking.ISyncPersistentData;
|
||||
import com.simibubi.create.foundation.utility.IInteractionChecker;
|
||||
|
||||
import net.createmod.catnip.utility.Couple;
|
||||
import net.createmod.catnip.utility.VecHelper;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -60,13 +70,6 @@ import net.minecraftforge.items.IItemHandlerModifiable;
|
|||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import net.minecraftforge.items.wrapper.InvWrapper;
|
||||
import net.minecraftforge.network.NetworkHooks;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
|
||||
public class BlueprintEntity extends HangingEntity
|
||||
implements IEntityAdditionalSpawnData, ISpecialEntityItemRequirement, ISyncPersistentData, IInteractionChecker {
|
||||
|
@ -363,14 +366,14 @@ public class BlueprintEntity extends HangingEntity
|
|||
boolean success = true;
|
||||
|
||||
Search: for (int i = 0; i < 9; i++) {
|
||||
ItemStack requestedItem = items.getStackInSlot(i);
|
||||
FilterItemStack requestedItem = FilterItemStack.of(items.getStackInSlot(i));
|
||||
if (requestedItem.isEmpty()) {
|
||||
craftingGrid.put(i, ItemStack.EMPTY);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int slot = 0; slot < playerInv.getSlots(); slot++) {
|
||||
if (!FilterItem.test(level(), playerInv.getStackInSlot(slot), requestedItem))
|
||||
if (!requestedItem.test(level(), playerInv.getStackInSlot(slot)))
|
||||
continue;
|
||||
ItemStack currentItem = playerInv.extractItem(slot, 1, false);
|
||||
if (stacksTaken.containsKey(slot))
|
||||
|
|
|
@ -1,14 +1,23 @@
|
|||
package com.simibubi.create.content.equipment.blueprint;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.content.equipment.blueprint.BlueprintEntity.BlueprintCraftingInventory;
|
||||
import com.simibubi.create.content.equipment.blueprint.BlueprintEntity.BlueprintSection;
|
||||
import com.simibubi.create.content.logistics.filter.AttributeFilterMenu.WhitelistMode;
|
||||
import com.simibubi.create.content.logistics.filter.FilterItem;
|
||||
import com.simibubi.create.content.logistics.filter.FilterItemStack;
|
||||
import com.simibubi.create.content.logistics.filter.ItemAttribute;
|
||||
import com.simibubi.create.content.trains.track.TrackPlacement.PlacementInfo;
|
||||
import com.simibubi.create.foundation.gui.AllGuiTextures;
|
||||
|
||||
import net.createmod.catnip.gui.element.GuiGameElement;
|
||||
import net.createmod.catnip.utility.AnimationTickHolder;
|
||||
import net.createmod.catnip.utility.Pair;
|
||||
|
@ -36,13 +45,6 @@ import net.minecraftforge.registries.ForgeRegistries;
|
|||
import net.minecraftforge.registries.tags.ITag;
|
||||
import net.minecraftforge.registries.tags.ITagManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class BlueprintOverlayRenderer {
|
||||
|
||||
public static final IGuiOverlay OVERLAY = BlueprintOverlayRenderer::renderOverlay;
|
||||
|
@ -161,14 +163,14 @@ public class BlueprintOverlayRenderer {
|
|||
newlyMissing.clear();
|
||||
|
||||
Search: for (int i = 0; i < 9; i++) {
|
||||
ItemStack requestedItem = items.getStackInSlot(i);
|
||||
FilterItemStack requestedItem = FilterItemStack.of(items.getStackInSlot(i));
|
||||
if (requestedItem.isEmpty()) {
|
||||
craftingGrid.put(i, ItemStack.EMPTY);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int slot = 0; slot < playerInv.getSlots(); slot++) {
|
||||
if (!FilterItem.test(mc.level, playerInv.getStackInSlot(slot), requestedItem))
|
||||
if (!requestedItem.test(mc.level, playerInv.getStackInSlot(slot)))
|
||||
continue;
|
||||
ItemStack currentItem = playerInv.extractItem(slot, 1, false);
|
||||
craftingGrid.put(i, currentItem);
|
||||
|
@ -177,7 +179,7 @@ public class BlueprintOverlayRenderer {
|
|||
}
|
||||
|
||||
success = false;
|
||||
newlyMissing.add(requestedItem);
|
||||
newlyMissing.add(requestedItem.item());
|
||||
}
|
||||
|
||||
if (success) {
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
package com.simibubi.create.content.equipment.clipboard;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.simibubi.create.AllBlockEntityTypes;
|
||||
import com.simibubi.create.AllShapes;
|
||||
import com.simibubi.create.content.equipment.wrench.IWrenchable;
|
||||
import com.simibubi.create.foundation.block.IBE;
|
||||
import com.simibubi.create.foundation.block.ProperWaterloggedBlock;
|
||||
|
||||
import net.createmod.catnip.gui.ScreenOpener;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -38,8 +41,6 @@ import net.minecraftforge.api.distmarker.OnlyIn;
|
|||
import net.minecraftforge.common.util.FakePlayer;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ClipboardBlock extends FaceAttachedHorizontalDirectionalBlock
|
||||
implements IBE<ClipboardBlockEntity>, IWrenchable, ProperWaterloggedBlock {
|
||||
|
||||
|
@ -85,7 +86,7 @@ public class ClipboardBlock extends FaceAttachedHorizontalDirectionalBlock
|
|||
@Override
|
||||
public InteractionResult use(BlockState pState, Level pLevel, BlockPos pPos, Player pPlayer, InteractionHand pHand,
|
||||
BlockHitResult pHit) {
|
||||
if (pPlayer.isSteppingCarefully()) {
|
||||
if (pPlayer.isShiftKeyDown()) {
|
||||
breakAndCollect(pState, pLevel, pPos, pPlayer);
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ public class ClipboardBlockItem extends BlockItem {
|
|||
Player player = context.getPlayer();
|
||||
if (player == null)
|
||||
return InteractionResult.PASS;
|
||||
if (player.isSteppingCarefully())
|
||||
if (player.isShiftKeyDown())
|
||||
return super.useOn(context);
|
||||
return use(context.getLevel(), player, context.getHand()).getResult();
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ public class ClipboardValueSettingsHandler {
|
|||
Player player = event.getEntity();
|
||||
if (player != null && player.isSpectator())
|
||||
return;
|
||||
if (player.isSteppingCarefully())
|
||||
if (player.isShiftKeyDown())
|
||||
return;
|
||||
if (!(world.getBlockEntity(pos) instanceof SmartBlockEntity smartBE))
|
||||
return;
|
||||
|
|
|
@ -45,7 +45,7 @@ public class WrenchItem extends Item {
|
|||
Block block = state.getBlock();
|
||||
|
||||
if (!(block instanceof IWrenchable)) {
|
||||
if (canWrenchPickup(state))
|
||||
if (player.isShiftKeyDown() && canWrenchPickup(state))
|
||||
return onItemUseOnOther(context);
|
||||
return super.useOn(context);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.content.fluids;
|
||||
|
||||
import com.simibubi.create.AllFluids;
|
||||
import com.simibubi.create.api.event.PipeCollisionEvent;
|
||||
import com.simibubi.create.foundation.advancement.AdvancementBehaviour;
|
||||
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
||||
import com.simibubi.create.foundation.fluid.FluidHelper;
|
||||
|
@ -14,53 +15,84 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.eventbus.api.EventPriority;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
|
||||
@EventBusSubscriber
|
||||
public class FluidReactions {
|
||||
|
||||
public static void handlePipeFlowCollision(Level world, BlockPos pos, FluidStack fluid, FluidStack fluid2) {
|
||||
public static void handlePipeFlowCollision(Level level, BlockPos pos, FluidStack fluid, FluidStack fluid2) {
|
||||
Fluid f1 = fluid.getFluid();
|
||||
Fluid f2 = fluid2.getFluid();
|
||||
|
||||
AdvancementBehaviour.tryAward(world, pos, AllAdvancements.CROSS_STREAMS);
|
||||
BlockHelper.destroyBlock(world, pos, 1);
|
||||
AdvancementBehaviour.tryAward(level, pos, AllAdvancements.CROSS_STREAMS);
|
||||
BlockHelper.destroyBlock(level, pos, 1);
|
||||
|
||||
if (f1 == Fluids.WATER && f2 == Fluids.LAVA || f2 == Fluids.WATER && f1 == Fluids.LAVA)
|
||||
world.setBlockAndUpdate(pos, Blocks.COBBLESTONE.defaultBlockState());
|
||||
else if (f1 == Fluids.LAVA && FluidHelper.hasBlockState(f2)) {
|
||||
BlockState lavaInteraction = AllFluids.getLavaInteraction(FluidHelper.convertToFlowing(f2)
|
||||
.defaultFluidState());
|
||||
if (lavaInteraction != null)
|
||||
world.setBlockAndUpdate(pos, lavaInteraction);
|
||||
PipeCollisionEvent.Flow event = new PipeCollisionEvent.Flow(level, pos, f1, f2, null);
|
||||
MinecraftForge.EVENT_BUS.post(event);
|
||||
if (event.getState() != null)
|
||||
level.setBlockAndUpdate(pos, event.getState());
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void handlePipeFlowCollisionFallback(PipeCollisionEvent.Flow event) {
|
||||
Fluid f1 = event.getFirstFluid();
|
||||
Fluid f2 = event.getSecondFluid();
|
||||
|
||||
if (f1 == Fluids.WATER && f2 == Fluids.LAVA || f2 == Fluids.WATER && f1 == Fluids.LAVA) {
|
||||
event.setState(Blocks.COBBLESTONE.defaultBlockState());
|
||||
} else if (f1 == Fluids.LAVA && FluidHelper.hasBlockState(f2)) {
|
||||
BlockState lavaInteraction = AllFluids.getLavaInteraction(FluidHelper.convertToFlowing(f2).defaultFluidState());
|
||||
if (lavaInteraction != null) {
|
||||
event.setState(lavaInteraction);
|
||||
}
|
||||
} else if (f2 == Fluids.LAVA && FluidHelper.hasBlockState(f1)) {
|
||||
BlockState lavaInteraction = AllFluids.getLavaInteraction(FluidHelper.convertToFlowing(f1)
|
||||
.defaultFluidState());
|
||||
if (lavaInteraction != null)
|
||||
world.setBlockAndUpdate(pos, lavaInteraction);
|
||||
BlockState lavaInteraction = AllFluids.getLavaInteraction(FluidHelper.convertToFlowing(f1).defaultFluidState());
|
||||
if (lavaInteraction != null) {
|
||||
event.setState(lavaInteraction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void handlePipeSpillCollision(Level world, BlockPos pos, Fluid pipeFluid, FluidState worldFluid) {
|
||||
public static void handlePipeSpillCollision(Level level, BlockPos pos, Fluid pipeFluid, FluidState worldFluid) {
|
||||
Fluid pf = FluidHelper.convertToStill(pipeFluid);
|
||||
Fluid wf = worldFluid.getType();
|
||||
if (FluidHelper.isTag(pf, FluidTags.WATER) && wf == Fluids.LAVA)
|
||||
world.setBlockAndUpdate(pos, Blocks.OBSIDIAN.defaultBlockState());
|
||||
else if (pf == Fluids.WATER && wf == Fluids.FLOWING_LAVA)
|
||||
world.setBlockAndUpdate(pos, Blocks.COBBLESTONE.defaultBlockState());
|
||||
else if (pf == Fluids.LAVA && wf == Fluids.WATER)
|
||||
world.setBlockAndUpdate(pos, Blocks.STONE.defaultBlockState());
|
||||
else if (pf == Fluids.LAVA && wf == Fluids.FLOWING_WATER)
|
||||
world.setBlockAndUpdate(pos, Blocks.COBBLESTONE.defaultBlockState());
|
||||
|
||||
PipeCollisionEvent.Spill event = new PipeCollisionEvent.Spill(level, pos, wf, pf, null);
|
||||
MinecraftForge.EVENT_BUS.post(event);
|
||||
if (event.getState() != null) {
|
||||
level.setBlockAndUpdate(pos, event.getState());
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void handlePipeSpillCollisionFallback(PipeCollisionEvent.Spill event) {
|
||||
Fluid pf = event.getPipeFluid();
|
||||
Fluid wf = event.getWorldFluid();
|
||||
|
||||
if (FluidHelper.isTag(pf, FluidTags.WATER) && wf == Fluids.LAVA) {
|
||||
event.setState(Blocks.OBSIDIAN.defaultBlockState());
|
||||
} else if (pf == Fluids.WATER && wf == Fluids.FLOWING_LAVA) {
|
||||
event.setState(Blocks.COBBLESTONE.defaultBlockState());
|
||||
} else if (pf == Fluids.LAVA && wf == Fluids.WATER) {
|
||||
event.setState(Blocks.STONE.defaultBlockState());
|
||||
} else if (pf == Fluids.LAVA && wf == Fluids.FLOWING_WATER) {
|
||||
event.setState(Blocks.COBBLESTONE.defaultBlockState());
|
||||
}
|
||||
|
||||
if (pf == Fluids.LAVA) {
|
||||
BlockState lavaInteraction = AllFluids.getLavaInteraction(worldFluid);
|
||||
if (lavaInteraction != null)
|
||||
world.setBlockAndUpdate(pos, lavaInteraction);
|
||||
BlockState lavaInteraction = AllFluids.getLavaInteraction(wf.defaultFluidState());
|
||||
if (lavaInteraction != null) {
|
||||
event.setState(lavaInteraction);
|
||||
}
|
||||
} else if (wf == Fluids.FLOWING_LAVA && FluidHelper.hasBlockState(pf)) {
|
||||
BlockState lavaInteraction = AllFluids.getLavaInteraction(FluidHelper.convertToFlowing(pf)
|
||||
.defaultFluidState());
|
||||
if (lavaInteraction != null)
|
||||
world.setBlockAndUpdate(pos, lavaInteraction);
|
||||
BlockState lavaInteraction = AllFluids.getLavaInteraction(FluidHelper.convertToFlowing(pf).defaultFluidState());
|
||||
if (lavaInteraction != null) {
|
||||
event.setState(lavaInteraction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -131,7 +131,7 @@ public class PumpBlock extends DirectionalKineticBlock
|
|||
return toPlace;
|
||||
if (bestConnectedDirection.getAxis() == targetDirection.getAxis())
|
||||
return toPlace;
|
||||
if (player.isSteppingCarefully() && bestConnectedDirection.getAxis() != targetDirection.getAxis())
|
||||
if (player.isShiftKeyDown() && bestConnectedDirection.getAxis() != targetDirection.getAxis())
|
||||
return toPlace;
|
||||
|
||||
return toPlace.setValue(FACING, bestConnectedDirection);
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.simibubi.create.AllTags.AllBlockTags;
|
|||
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
|
||||
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock.HeatLevel;
|
||||
import com.simibubi.create.foundation.utility.AttachedRegistry;
|
||||
import com.simibubi.create.foundation.utility.BlockHelper;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
@ -71,7 +72,7 @@ public class BoilerHeaters {
|
|||
});
|
||||
|
||||
registerHeaterProvider((level, pos, state) -> {
|
||||
if (AllBlockTags.PASSIVE_BOILER_HEATERS.matches(state)) {
|
||||
if (AllBlockTags.PASSIVE_BOILER_HEATERS.matches(state) && BlockHelper.isNotUnheated(state)) {
|
||||
return (level1, pos1, state1) -> 0;
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -94,7 +94,7 @@ public class BeltBlockEntity extends KineticBlockEntity {
|
|||
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
|
||||
super.addBehaviours(behaviours);
|
||||
behaviours.add(new DirectBeltInputBehaviour(this).onlyInsertWhen(this::canInsertFrom)
|
||||
.setInsertionHandler(this::tryInsertingFromSide));
|
||||
.setInsertionHandler(this::tryInsertingFromSide).considerOccupiedWhen(this::isOccupied));
|
||||
behaviours.add(new TransportedItemStackHandlerBehaviour(this, this::applyToAllItems)
|
||||
.withStackPlacement(this::getWorldPositionOf));
|
||||
}
|
||||
|
@ -463,6 +463,22 @@ public class BeltBlockEntity extends KineticBlockEntity {
|
|||
return false;
|
||||
return getMovementFacing() != side.getOpposite();
|
||||
}
|
||||
|
||||
private boolean isOccupied(Direction side) {
|
||||
BeltBlockEntity nextBeltController = getControllerBE();
|
||||
if (nextBeltController == null)
|
||||
return true;
|
||||
BeltInventory nextInventory = nextBeltController.getInventory();
|
||||
if (nextInventory == null)
|
||||
return true;
|
||||
if (getSpeed() == 0)
|
||||
return true;
|
||||
if (getMovementFacing() == side.getOpposite())
|
||||
return true;
|
||||
if (!nextInventory.canInsertAtFromSide(index, side))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private ItemStack tryInsertingFromSide(TransportedItemStack transportedStack, Direction side, boolean simulate) {
|
||||
BeltBlockEntity nextBeltController = getControllerBE();
|
||||
|
@ -492,11 +508,7 @@ public class BeltBlockEntity extends KineticBlockEntity {
|
|||
}
|
||||
}
|
||||
|
||||
if (getSpeed() == 0)
|
||||
return inserted;
|
||||
if (getMovementFacing() == side.getOpposite())
|
||||
return inserted;
|
||||
if (!nextInventory.canInsertAtFromSide(index, side))
|
||||
if (isOccupied(side))
|
||||
return inserted;
|
||||
if (simulate)
|
||||
return empty;
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
package com.simibubi.create.content.kinetics.belt;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.simibubi.create.AllTags.AllItemTags;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap;
|
||||
import net.createmod.catnip.utility.VecHelper;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.server.packs.resources.ResourceManagerReloadListener;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
|
@ -16,9 +21,13 @@ import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
|||
|
||||
public class BeltHelper {
|
||||
|
||||
public static Map<Item, Boolean> uprightCache = new Object2BooleanOpenHashMap<>();
|
||||
public static final ResourceManagerReloadListener LISTENER = resourceManager -> uprightCache.clear();
|
||||
|
||||
public static boolean isItemUpright(ItemStack stack) {
|
||||
return stack.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM)
|
||||
.isPresent() || AllItemTags.UPRIGHT_ON_BELT.matches(stack);
|
||||
return uprightCache.computeIfAbsent(stack.getItem(),
|
||||
item -> stack.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM)
|
||||
.isPresent() || AllItemTags.UPRIGHT_ON_BELT.matches(stack));
|
||||
}
|
||||
|
||||
public static BeltBlockEntity getSegmentBE(LevelAccessor world, BlockPos pos) {
|
||||
|
|
|
@ -33,6 +33,7 @@ public class DirectBeltInputBehaviour extends BlockEntityBehaviour {
|
|||
public static final BehaviourType<DirectBeltInputBehaviour> TYPE = new BehaviourType<>();
|
||||
|
||||
private InsertionCallback tryInsert;
|
||||
private OccupiedPredicate isOccupied;
|
||||
private AvailabilityPredicate canInsert;
|
||||
private Supplier<Boolean> supportsBeltFunnels;
|
||||
|
||||
|
@ -40,6 +41,7 @@ public class DirectBeltInputBehaviour extends BlockEntityBehaviour {
|
|||
super(be);
|
||||
tryInsert = this::defaultInsertionCallback;
|
||||
canInsert = d -> true;
|
||||
isOccupied = d -> false;
|
||||
supportsBeltFunnels = () -> false;
|
||||
}
|
||||
|
||||
|
@ -57,6 +59,11 @@ public class DirectBeltInputBehaviour extends BlockEntityBehaviour {
|
|||
canInsert = pred;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DirectBeltInputBehaviour considerOccupiedWhen(OccupiedPredicate pred) {
|
||||
isOccupied = pred;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DirectBeltInputBehaviour setInsertionHandler(InsertionCallback callback) {
|
||||
tryInsert = callback;
|
||||
|
@ -75,6 +82,10 @@ public class DirectBeltInputBehaviour extends BlockEntityBehaviour {
|
|||
return canInsert.test(side);
|
||||
}
|
||||
|
||||
public boolean isOccupied(Direction side) {
|
||||
return isOccupied.test(side);
|
||||
}
|
||||
|
||||
public ItemStack handleInsertion(ItemStack stack, Direction side, boolean simulate) {
|
||||
return handleInsertion(new TransportedItemStack(stack), side, simulate);
|
||||
}
|
||||
|
@ -93,6 +104,11 @@ public class DirectBeltInputBehaviour extends BlockEntityBehaviour {
|
|||
public ItemStack apply(TransportedItemStack stack, Direction side, boolean simulate);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface OccupiedPredicate {
|
||||
public boolean test(Direction side);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface AvailabilityPredicate {
|
||||
public boolean test(Direction side);
|
||||
|
|
|
@ -62,7 +62,9 @@ public class ValveHandleBlock extends HandCrankBlock {
|
|||
|
||||
if (!(blockState.getBlock() instanceof ValveHandleBlock vhb))
|
||||
return;
|
||||
if (AllItems.WRENCH.isIn(player.getItemInHand(event.getHand())) && player.isSteppingCarefully())
|
||||
if (!player.mayBuild())
|
||||
return;
|
||||
if (AllItems.WRENCH.isIn(player.getItemInHand(event.getHand())) && player.isShiftKeyDown())
|
||||
return;
|
||||
|
||||
if (vhb.clicked(level, pos, blockState, player, event.getHand())) {
|
||||
|
@ -90,7 +92,7 @@ public class ValveHandleBlock extends HandCrankBlock {
|
|||
}
|
||||
|
||||
onBlockEntityUse(level, pos,
|
||||
hcbe -> (hcbe instanceof ValveHandleBlockEntity vhbe) && vhbe.activate(player.isSteppingCarefully())
|
||||
hcbe -> (hcbe instanceof ValveHandleBlockEntity vhbe) && vhbe.activate(player.isShiftKeyDown())
|
||||
? InteractionResult.SUCCESS
|
||||
: InteractionResult.PASS);
|
||||
return true;
|
||||
|
|
|
@ -299,9 +299,6 @@ public class DeployerHandler {
|
|||
return;
|
||||
if (useItem == DENY)
|
||||
return;
|
||||
if (item instanceof BlockItem && !(item instanceof CartAssemblerBlockItem)
|
||||
&& !clickedState.canBeReplaced(new BlockPlaceContext(itemusecontext)))
|
||||
return;
|
||||
|
||||
// Reposition fire placement for convenience
|
||||
if (item == Items.FLINT_AND_STEEL) {
|
||||
|
@ -323,6 +320,10 @@ public class DeployerHandler {
|
|||
player.placedTracks = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (item instanceof BlockItem && !(item instanceof CartAssemblerBlockItem)
|
||||
&& !clickedState.canBeReplaced(new BlockPlaceContext(itemusecontext)))
|
||||
return;
|
||||
if (item == Items.ENDER_PEARL)
|
||||
return;
|
||||
if (AllItemTags.DEPLOYABLE_DRINK.matches(item))
|
||||
|
|
|
@ -21,7 +21,7 @@ import com.simibubi.create.content.contraptions.render.ActorInstance;
|
|||
import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
|
||||
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher;
|
||||
import com.simibubi.create.content.kinetics.deployer.DeployerBlockEntity.Mode;
|
||||
import com.simibubi.create.content.logistics.filter.FilterItem;
|
||||
import com.simibubi.create.content.logistics.filter.FilterItemStack;
|
||||
import com.simibubi.create.content.schematics.SchematicInstances;
|
||||
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
|
||||
import com.simibubi.create.content.trains.entity.CarriageContraption;
|
||||
|
@ -80,9 +80,9 @@ public class DeployerMovementBehaviour implements MovementBehaviour {
|
|||
public void activate(MovementContext context, BlockPos pos, DeployerFakePlayer player, Mode mode) {
|
||||
Level world = context.world;
|
||||
|
||||
ItemStack filter = getFilter(context);
|
||||
if (AllItems.SCHEMATIC.isIn(filter))
|
||||
activateAsSchematicPrinter(context, pos, player, world, filter);
|
||||
FilterItemStack filter = context.getFilterFromBE();
|
||||
if (AllItems.SCHEMATIC.isIn(filter.item()))
|
||||
activateAsSchematicPrinter(context, pos, player, world, filter.item());
|
||||
|
||||
Vec3 facingVec = Vec3.atLowerCornerOf(context.state.getValue(DeployerBlock.FACING)
|
||||
.getNormal());
|
||||
|
@ -221,11 +221,11 @@ public class DeployerMovementBehaviour implements MovementBehaviour {
|
|||
return;
|
||||
if (player.getMainHandItem()
|
||||
.isEmpty()) {
|
||||
ItemStack filter = getFilter(context);
|
||||
if (AllItems.SCHEMATIC.isIn(filter))
|
||||
FilterItemStack filter = context.getFilterFromBE();
|
||||
if (AllItems.SCHEMATIC.isIn(filter.item()))
|
||||
return;
|
||||
ItemStack held = ItemHelper.extract(context.contraption.getSharedInventory(),
|
||||
stack -> FilterItem.test(context.world, stack, filter), 1, false);
|
||||
stack -> filter.test(context.world, stack), 1, false);
|
||||
player.setItemInHand(InteractionHand.MAIN_HAND, held);
|
||||
}
|
||||
}
|
||||
|
@ -235,7 +235,7 @@ public class DeployerMovementBehaviour implements MovementBehaviour {
|
|||
if (player == null)
|
||||
return;
|
||||
Inventory inv = player.getInventory();
|
||||
ItemStack filter = getFilter(context);
|
||||
FilterItemStack filter = context.getFilterFromBE();
|
||||
|
||||
for (List<ItemStack> list : Arrays.asList(inv.armor, inv.offhand, inv.items)) {
|
||||
for (int i = 0; i < list.size(); ++i) {
|
||||
|
@ -243,7 +243,7 @@ public class DeployerMovementBehaviour implements MovementBehaviour {
|
|||
if (itemstack.isEmpty())
|
||||
continue;
|
||||
|
||||
if (list == inv.items && i == inv.selected && FilterItem.test(context.world, itemstack, filter))
|
||||
if (list == inv.items && i == inv.selected && filter.test(context.world, itemstack))
|
||||
continue;
|
||||
|
||||
dropItem(context, itemstack);
|
||||
|
@ -277,10 +277,6 @@ public class DeployerMovementBehaviour implements MovementBehaviour {
|
|||
return (DeployerFakePlayer) context.temporaryData;
|
||||
}
|
||||
|
||||
private ItemStack getFilter(MovementContext context) {
|
||||
return ItemStack.of(context.blockEntityData.getCompound("Filter"));
|
||||
}
|
||||
|
||||
private Mode getMode(MovementContext context) {
|
||||
return NBTHelper.readEnum(context.blockEntityData, "Mode", Mode.class);
|
||||
}
|
||||
|
|
|
@ -32,9 +32,7 @@ import net.minecraft.world.entity.player.Player;
|
|||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
|
@ -54,8 +52,6 @@ public class AirCurrent {
|
|||
new ArrayList<>();
|
||||
protected List<Entity> caughtEntities = new ArrayList<>();
|
||||
|
||||
static boolean isClientPlayerInAirCurrent;
|
||||
|
||||
public AirCurrent(IAirCurrentSource source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
@ -64,21 +60,20 @@ public class AirCurrent {
|
|||
if (direction == null)
|
||||
rebuild();
|
||||
Level world = source.getAirCurrentWorld();
|
||||
Direction facing = direction;
|
||||
if (world != null && world.isClientSide) {
|
||||
float offset = pushing ? 0.5f : maxDistance + .5f;
|
||||
Vec3 pos = VecHelper.getCenterOf(source.getAirCurrentPos())
|
||||
.add(Vec3.atLowerCornerOf(facing.getNormal())
|
||||
.add(Vec3.atLowerCornerOf(direction.getNormal())
|
||||
.scale(offset));
|
||||
if (world.random.nextFloat() < AllConfigs.client().fanParticleDensity.get())
|
||||
world.addParticle(new AirFlowParticleData(source.getAirCurrentPos()), pos.x, pos.y, pos.z, 0, 0, 0);
|
||||
}
|
||||
|
||||
tickAffectedEntities(world, facing);
|
||||
tickAffectedEntities(world);
|
||||
tickAffectedHandlers();
|
||||
}
|
||||
|
||||
protected void tickAffectedEntities(Level world, Direction facing) {
|
||||
protected void tickAffectedEntities(Level world) {
|
||||
for (Iterator<Entity> iterator = caughtEntities.iterator(); iterator.hasNext();) {
|
||||
Entity entity = iterator.next();
|
||||
if (!entity.isAlive() || !entity.getBoundingBox()
|
||||
|
@ -87,14 +82,14 @@ public class AirCurrent {
|
|||
continue;
|
||||
}
|
||||
|
||||
Vec3 center = VecHelper.getCenterOf(source.getAirCurrentPos());
|
||||
Vec3i flow = (pushing ? facing : facing.getOpposite()).getNormal();
|
||||
|
||||
float sneakModifier = entity.isShiftKeyDown() ? 4096f : 512f;
|
||||
Vec3i flow = (pushing ? direction : direction.getOpposite()).getNormal();
|
||||
float speed = Math.abs(source.getSpeed());
|
||||
double entityDistance = entity.position()
|
||||
.distanceTo(center);
|
||||
float acceleration = (float) (speed / sneakModifier / (entityDistance / maxDistance));
|
||||
float sneakModifier = entity.isShiftKeyDown() ? 4096f : 512f;
|
||||
double entityDistance = VecHelper.alignedDistanceToFace(entity.position(), source.getAirCurrentPos(), direction);
|
||||
// entityDistanceOld should be removed eventually. Remember that entityDistanceOld cannot be 0 while entityDistance can,
|
||||
// so division by 0 must be avoided.
|
||||
double entityDistanceOld = entity.position().distanceTo(VecHelper.getCenterOf(source.getAirCurrentPos()));
|
||||
float acceleration = (float) (speed / sneakModifier / (entityDistanceOld / maxDistance));
|
||||
Vec3 previousMotion = entity.getDeltaMovement();
|
||||
float maxAcceleration = 5;
|
||||
|
||||
|
@ -110,8 +105,7 @@ public class AirCurrent {
|
|||
if (entity instanceof ServerPlayer)
|
||||
((ServerPlayer) entity).connection.aboveGroundTickCount = 0;
|
||||
|
||||
entityDistance -= .5f;
|
||||
FanProcessingType processingType = getSegmentAt((float) entityDistance);
|
||||
FanProcessingType processingType = getTypeAt((float) entityDistance);
|
||||
|
||||
if (processingType == AllFanProcessingTypes.NONE)
|
||||
continue;
|
||||
|
@ -131,7 +125,33 @@ public class AirCurrent {
|
|||
if (world != null)
|
||||
processingType.affectEntity(entity, world);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isPlayerCreativeFlying(Entity entity) {
|
||||
if (entity instanceof Player) {
|
||||
Player player = (Player) entity;
|
||||
return player.isCreative() && player.getAbilities().flying;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void tickAffectedHandlers() {
|
||||
for (Pair<TransportedItemStackHandlerBehaviour, FanProcessingType> pair : affectedItemHandlers) {
|
||||
TransportedItemStackHandlerBehaviour handler = pair.getKey();
|
||||
Level world = handler.getWorld();
|
||||
FanProcessingType processingType = pair.getRight();
|
||||
|
||||
handler.handleProcessingOnAllItems(transported -> {
|
||||
if (world.isClientSide) {
|
||||
processingType.spawnProcessingParticles(world, handler.getWorldPositionOf(transported));
|
||||
return TransportedResult.doNothing();
|
||||
}
|
||||
TransportedResult applyProcessing = FanProcessing.applyProcessing(transported, world, processingType);
|
||||
if (!applyProcessing.doesNothing() && source instanceof EncasedFanBlockEntity fan)
|
||||
fan.award(AllAdvancements.FAN_PROCESSING);
|
||||
return applyProcessing;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void rebuild() {
|
||||
|
@ -154,32 +174,38 @@ public class AirCurrent {
|
|||
maxDistance = getFlowLimit(world, start, max, facing);
|
||||
|
||||
// Determine segments with transported fluids/gases
|
||||
AirCurrentSegment currentSegment = new AirCurrentSegment();
|
||||
segments.clear();
|
||||
currentSegment.startOffset = 0;
|
||||
AirCurrentSegment currentSegment = null;
|
||||
FanProcessingType type = AllFanProcessingTypes.NONE;
|
||||
|
||||
int limit = (int) (maxDistance + .5f);
|
||||
int searchStart = pushing ? 0 : limit;
|
||||
int searchEnd = pushing ? limit : 0;
|
||||
int limit = getLimit();
|
||||
int searchStart = pushing ? 1 : limit;
|
||||
int searchEnd = pushing ? limit : 1;
|
||||
int searchStep = pushing ? 1 : -1;
|
||||
int toOffset = pushing ? -1 : 0;
|
||||
|
||||
for (int i = searchStart; i * searchStep <= searchEnd * searchStep; i += searchStep) {
|
||||
BlockPos currentPos = start.relative(direction, i);
|
||||
FanProcessingType newType = FanProcessingType.getAt(world, currentPos);
|
||||
if (newType != AllFanProcessingTypes.NONE)
|
||||
if (newType != AllFanProcessingTypes.NONE) {
|
||||
type = newType;
|
||||
if (currentSegment.type != type || currentSegment.startOffset == 0) {
|
||||
currentSegment.endOffset = i;
|
||||
if (currentSegment.startOffset != 0)
|
||||
segments.add(currentSegment);
|
||||
}
|
||||
if (currentSegment == null) {
|
||||
currentSegment = new AirCurrentSegment();
|
||||
currentSegment.startOffset = i;
|
||||
currentSegment.startOffset = i + toOffset;
|
||||
currentSegment.type = type;
|
||||
} else if (currentSegment.type != type) {
|
||||
currentSegment.endOffset = i + toOffset;
|
||||
segments.add(currentSegment);
|
||||
currentSegment = new AirCurrentSegment();
|
||||
currentSegment.startOffset = i + toOffset;
|
||||
currentSegment.type = type;
|
||||
}
|
||||
}
|
||||
currentSegment.endOffset = searchEnd + searchStep;
|
||||
segments.add(currentSegment);
|
||||
if (currentSegment != null) {
|
||||
currentSegment.endOffset = searchEnd + searchStep + toOffset;
|
||||
segments.add(currentSegment);
|
||||
}
|
||||
|
||||
// Build Bounding Box
|
||||
if (maxDistance < 0.25f)
|
||||
|
@ -194,133 +220,152 @@ public class AirCurrent {
|
|||
.move(scale);
|
||||
}
|
||||
}
|
||||
|
||||
findAffectedHandlers();
|
||||
}
|
||||
|
||||
public static float getFlowLimit(Level world, BlockPos start, float max, Direction facing) {
|
||||
Vec3 directionVec = Vec3.atLowerCornerOf(facing.getNormal());
|
||||
Vec3 planeVec = VecHelper.axisAlingedPlaneOf(directionVec);
|
||||
for (int i = 0; i < max; i++) {
|
||||
BlockPos currentPos = start.relative(facing, i + 1);
|
||||
if (!world.isLoaded(currentPos)) {
|
||||
return i;
|
||||
}
|
||||
|
||||
// 4 Rays test for holes in the shapes blocking the flow
|
||||
float offsetDistance = .25f;
|
||||
Vec3[] offsets = new Vec3[] { planeVec.multiply(offsetDistance, offsetDistance, offsetDistance),
|
||||
planeVec.multiply(-offsetDistance, -offsetDistance, offsetDistance),
|
||||
planeVec.multiply(offsetDistance, -offsetDistance, -offsetDistance),
|
||||
planeVec.multiply(-offsetDistance, offsetDistance, -offsetDistance), };
|
||||
|
||||
float limitedDistance = 0;
|
||||
|
||||
// Determine the distance of the air flow
|
||||
Outer: for (int i = 1; i <= max; i++) {
|
||||
BlockPos currentPos = start.relative(facing, i);
|
||||
if (!world.isLoaded(currentPos))
|
||||
break;
|
||||
BlockState state = world.getBlockState(currentPos);
|
||||
BlockState copycatState = CopycatBlock.getMaterial(world, currentPos);
|
||||
if (shouldAlwaysPass(copycatState.isAir() ? state : copycatState))
|
||||
if (shouldAlwaysPass(copycatState.isAir() ? state : copycatState)) {
|
||||
continue;
|
||||
VoxelShape voxelshape = state.getCollisionShape(world, currentPos, CollisionContext.empty());
|
||||
if (voxelshape.isEmpty())
|
||||
continue;
|
||||
if (voxelshape == Shapes.block()) {
|
||||
max = i - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
for (Vec3 offset : offsets) {
|
||||
Vec3 rayStart = VecHelper.getCenterOf(currentPos)
|
||||
.subtract(directionVec.scale(.5f + 1 / 32f))
|
||||
.add(offset);
|
||||
Vec3 rayEnd = rayStart.add(directionVec.scale(1 + 1 / 32f));
|
||||
BlockHitResult blockraytraceresult =
|
||||
world.clipWithInteractionOverride(rayStart, rayEnd, currentPos, voxelshape, state);
|
||||
if (blockraytraceresult == null)
|
||||
continue Outer;
|
||||
|
||||
double distance = i - 1 + blockraytraceresult.getLocation()
|
||||
.distanceTo(rayStart);
|
||||
if (limitedDistance < distance)
|
||||
limitedDistance = (float) distance;
|
||||
VoxelShape shape = state.getCollisionShape(world, currentPos);
|
||||
if (shape.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
max = limitedDistance;
|
||||
break;
|
||||
if (shape == Shapes.block()) {
|
||||
return i;
|
||||
}
|
||||
double shapeDepth = findMaxDepth(shape, facing);
|
||||
if (shapeDepth == Double.POSITIVE_INFINITY) {
|
||||
continue;
|
||||
}
|
||||
return Math.min((float) (i + shapeDepth + 1/32d), max);
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
private static final double[][] DEPTH_TEST_COORDINATES = {
|
||||
{ 0.25, 0.25 },
|
||||
{ 0.25, 0.75 },
|
||||
{ 0.5, 0.5 },
|
||||
{ 0.75, 0.25 },
|
||||
{ 0.75, 0.75 }
|
||||
};
|
||||
|
||||
// Finds the maximum depth of the shape when traveling in the given direction.
|
||||
// The result is always positive.
|
||||
// If there is a hole, the result will be Double.POSITIVE_INFINITY.
|
||||
private static double findMaxDepth(VoxelShape shape, Direction direction) {
|
||||
Direction.Axis axis = direction.getAxis();
|
||||
Direction.AxisDirection axisDirection = direction.getAxisDirection();
|
||||
double maxDepth = 0;
|
||||
|
||||
for (double[] coordinates : DEPTH_TEST_COORDINATES) {
|
||||
double depth;
|
||||
if (axisDirection == Direction.AxisDirection.POSITIVE) {
|
||||
double min = shape.min(axis, coordinates[0], coordinates[1]);
|
||||
if (min == Double.POSITIVE_INFINITY) {
|
||||
return Double.POSITIVE_INFINITY;
|
||||
}
|
||||
depth = min;
|
||||
} else {
|
||||
double max = shape.max(axis, coordinates[0], coordinates[1]);
|
||||
if (max == Double.NEGATIVE_INFINITY) {
|
||||
return Double.POSITIVE_INFINITY;
|
||||
}
|
||||
depth = 1 - max;
|
||||
}
|
||||
|
||||
if (depth > maxDepth) {
|
||||
maxDepth = depth;
|
||||
}
|
||||
}
|
||||
|
||||
return maxDepth;
|
||||
}
|
||||
|
||||
private static boolean shouldAlwaysPass(BlockState state) {
|
||||
return AllTags.AllBlockTags.FAN_TRANSPARENT.matches(state);
|
||||
}
|
||||
|
||||
private int getLimit() {
|
||||
if ((float) (int) maxDistance == maxDistance) {
|
||||
return (int) maxDistance;
|
||||
} else {
|
||||
return (int) maxDistance + 1;
|
||||
}
|
||||
}
|
||||
|
||||
public void findAffectedHandlers() {
|
||||
Level world = source.getAirCurrentWorld();
|
||||
BlockPos start = source.getAirCurrentPos();
|
||||
affectedItemHandlers.clear();
|
||||
int limit = getLimit();
|
||||
for (int i = 1; i <= limit; i++) {
|
||||
FanProcessingType segmentType = getTypeAt(i - 1);
|
||||
for (int offset : Iterate.zeroAndOne) {
|
||||
BlockPos pos = start.relative(direction, i)
|
||||
.below(offset);
|
||||
TransportedItemStackHandlerBehaviour behaviour =
|
||||
BlockEntityBehaviour.get(world, pos, TransportedItemStackHandlerBehaviour.TYPE);
|
||||
if (behaviour != null) {
|
||||
FanProcessingType type = FanProcessingType.getAt(world, pos);
|
||||
if (type == AllFanProcessingTypes.NONE)
|
||||
type = segmentType;
|
||||
affectedItemHandlers.add(Pair.of(behaviour, type));
|
||||
}
|
||||
if (direction.getAxis()
|
||||
.isVertical())
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void findEntities() {
|
||||
caughtEntities.clear();
|
||||
caughtEntities = source.getAirCurrentWorld()
|
||||
.getEntities(null, bounds);
|
||||
}
|
||||
|
||||
public void findAffectedHandlers() {
|
||||
Level world = source.getAirCurrentWorld();
|
||||
BlockPos start = source.getAirCurrentPos();
|
||||
affectedItemHandlers.clear();
|
||||
for (int i = 0; i < maxDistance + 1; i++) {
|
||||
FanProcessingType segmentType = getSegmentAt(i);
|
||||
for (int offset : Iterate.zeroAndOne) {
|
||||
BlockPos pos = start.relative(direction, i)
|
||||
.below(offset);
|
||||
TransportedItemStackHandlerBehaviour behaviour =
|
||||
BlockEntityBehaviour.get(world, pos, TransportedItemStackHandlerBehaviour.TYPE);
|
||||
if (behaviour == null)
|
||||
continue;
|
||||
FanProcessingType type = FanProcessingType.getAt(world, pos);
|
||||
if (type == AllFanProcessingTypes.NONE)
|
||||
type = segmentType;
|
||||
affectedItemHandlers.add(Pair.of(behaviour, type));
|
||||
if (direction.getAxis()
|
||||
.isVertical())
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void tickAffectedHandlers() {
|
||||
for (Pair<TransportedItemStackHandlerBehaviour, FanProcessingType> pair : affectedItemHandlers) {
|
||||
TransportedItemStackHandlerBehaviour handler = pair.getKey();
|
||||
Level world = handler.getWorld();
|
||||
FanProcessingType processingType = pair.getRight();
|
||||
|
||||
handler.handleProcessingOnAllItems(transported -> {
|
||||
if (world.isClientSide) {
|
||||
processingType.spawnProcessingParticles(world, handler.getWorldPositionOf(transported));
|
||||
return TransportedResult.doNothing();
|
||||
public FanProcessingType getTypeAt(float offset) {
|
||||
if (offset >= 0 && offset <= maxDistance) {
|
||||
if (pushing) {
|
||||
for (AirCurrentSegment airCurrentSegment : segments) {
|
||||
if (offset <= airCurrentSegment.endOffset) {
|
||||
return airCurrentSegment.type;
|
||||
}
|
||||
}
|
||||
TransportedResult applyProcessing = FanProcessing.applyProcessing(transported, world, processingType);
|
||||
if (!applyProcessing.doesNothing() && source instanceof EncasedFanBlockEntity fan)
|
||||
fan.award(AllAdvancements.FAN_PROCESSING);
|
||||
return applyProcessing;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean shouldAlwaysPass(BlockState state) {
|
||||
return AllTags.AllBlockTags.FAN_TRANSPARENT.matches(state);
|
||||
}
|
||||
|
||||
public FanProcessingType getSegmentAt(float offset) {
|
||||
for (AirCurrentSegment airCurrentSegment : segments) {
|
||||
if (offset > airCurrentSegment.endOffset && pushing)
|
||||
continue;
|
||||
if (offset < airCurrentSegment.endOffset && !pushing)
|
||||
continue;
|
||||
return airCurrentSegment.type;
|
||||
} else {
|
||||
for (AirCurrentSegment airCurrentSegment : segments) {
|
||||
if (offset >= airCurrentSegment.endOffset) {
|
||||
return airCurrentSegment.type;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return AllFanProcessingTypes.NONE;
|
||||
}
|
||||
|
||||
public static class AirCurrentSegment {
|
||||
FanProcessingType type;
|
||||
int startOffset;
|
||||
int endOffset;
|
||||
private static class AirCurrentSegment {
|
||||
private FanProcessingType type;
|
||||
private int startOffset;
|
||||
private int endOffset;
|
||||
}
|
||||
|
||||
private static boolean isClientPlayerInAirCurrent;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
static AirCurrentSound flyingSound;
|
||||
private static AirCurrentSound flyingSound;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
private static void enableClientPlayerSound(Entity e, float maxVolume) {
|
||||
|
@ -345,7 +390,7 @@ public class AirCurrent {
|
|||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static void tickClientPlayerSounds() {
|
||||
if (!AirCurrent.isClientPlayerInAirCurrent && flyingSound != null)
|
||||
if (!isClientPlayerInAirCurrent && flyingSound != null)
|
||||
if (flyingSound.isFaded())
|
||||
flyingSound.stopSound();
|
||||
else
|
||||
|
@ -353,12 +398,4 @@ public class AirCurrent {
|
|||
isClientPlayerInAirCurrent = false;
|
||||
}
|
||||
|
||||
public static boolean isPlayerCreativeFlying(Entity entity) {
|
||||
if (entity instanceof Player) {
|
||||
Player player = (Player) entity;
|
||||
return player.isCreative() && player.getAbilities().flying;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,9 +34,9 @@ public class AirFlowParticle extends SimpleAnimatedParticle {
|
|||
selectSprite(7);
|
||||
Vec3 offset = VecHelper.offsetRandomly(Vec3.ZERO, random, .25f);
|
||||
this.setPos(x + offset.x, y + offset.y, z + offset.z);
|
||||
this.xo = x;
|
||||
this.yo = y;
|
||||
this.zo = z;
|
||||
this.xo = this.x;
|
||||
this.yo = this.y;
|
||||
this.zo = this.z;
|
||||
setColor(0xEEEEEE);
|
||||
setAlpha(.25f);
|
||||
}
|
||||
|
@ -97,15 +97,13 @@ public class AirFlowParticle extends SimpleAnimatedParticle {
|
|||
this.zd *= 0.7;
|
||||
}
|
||||
this.move(this.xd, this.yd, this.zd);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private FanProcessingType getType(double distance) {
|
||||
if (source.getAirCurrent() == null)
|
||||
return AllFanProcessingTypes.NONE;
|
||||
return source.getAirCurrent().getSegmentAt((float) distance);
|
||||
return source.getAirCurrent().getTypeAt((float) distance);
|
||||
}
|
||||
|
||||
public int getLightColor(float partialTick) {
|
||||
|
@ -124,6 +122,7 @@ public class AirFlowParticle extends SimpleAnimatedParticle {
|
|||
this.spriteSet = animatedSprite;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Particle createParticle(AirFlowParticleData data, ClientLevel worldIn, double x, double y, double z,
|
||||
double xSpeed, double ySpeed, double zSpeed) {
|
||||
BlockEntity be = worldIn.getBlockEntity(new BlockPos(data.posX, data.posY, data.posZ));
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package com.simibubi.create.content.kinetics.fan.processing;
|
||||
|
||||
import static com.simibubi.create.content.processing.burner.BlazeBurnerBlock.getHeatLevelOf;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -10,8 +8,9 @@ import java.util.Optional;
|
|||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllRecipeTypes;
|
||||
import com.simibubi.create.AllTags.AllBlockTags;
|
||||
import com.simibubi.create.AllTags.AllFluidTags;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.kinetics.fan.processing.HauntingRecipe.HauntingWrapper;
|
||||
import com.simibubi.create.content.kinetics.fan.processing.SplashingRecipe.SplashingWrapper;
|
||||
|
@ -48,13 +47,10 @@ import net.minecraft.world.item.crafting.RecipeType;
|
|||
import net.minecraft.world.item.crafting.SmeltingRecipe;
|
||||
import net.minecraft.world.item.crafting.SmokingRecipe;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.CampfireBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import net.minecraftforge.items.wrapper.RecipeWrapper;
|
||||
|
@ -140,9 +136,18 @@ public class AllFanProcessingTypes {
|
|||
|
||||
@Override
|
||||
public boolean isValidAt(Level level, BlockPos pos) {
|
||||
FluidState fluidState = level.getFluidState(pos);
|
||||
if (AllFluidTags.FAN_PROCESSING_CATALYSTS_BLASTING.matches(fluidState)) {
|
||||
return true;
|
||||
}
|
||||
BlockState blockState = level.getBlockState(pos);
|
||||
Block block = blockState.getBlock();
|
||||
return block == Blocks.LAVA || getHeatLevelOf(blockState).isAtLeast(BlazeBurnerBlock.HeatLevel.FADING);
|
||||
if (AllBlockTags.FAN_PROCESSING_CATALYSTS_BLASTING.matches(blockState)) {
|
||||
if (blockState.hasProperty(BlazeBurnerBlock.HEAT_LEVEL) && !blockState.getValue(BlazeBurnerBlock.HEAT_LEVEL).isAtLeast(BlazeBurnerBlock.HeatLevel.FADING)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -233,15 +238,21 @@ public class AllFanProcessingTypes {
|
|||
|
||||
@Override
|
||||
public boolean isValidAt(Level level, BlockPos pos) {
|
||||
FluidState fluidState = level.getFluidState(pos);
|
||||
if (AllFluidTags.FAN_PROCESSING_CATALYSTS_HAUNTING.matches(fluidState)) {
|
||||
return true;
|
||||
}
|
||||
BlockState blockState = level.getBlockState(pos);
|
||||
Block block = blockState.getBlock();
|
||||
return block == Blocks.SOUL_FIRE
|
||||
|| block == Blocks.SOUL_CAMPFIRE && blockState.getOptionalValue(CampfireBlock.LIT)
|
||||
.orElse(false)
|
||||
|| AllBlocks.LIT_BLAZE_BURNER.has(blockState)
|
||||
&& blockState.getOptionalValue(LitBlazeBurnerBlock.FLAME_TYPE)
|
||||
.map(flame -> flame == LitBlazeBurnerBlock.FlameType.SOUL)
|
||||
.orElse(false);
|
||||
if (AllBlockTags.FAN_PROCESSING_CATALYSTS_HAUNTING.matches(blockState)) {
|
||||
if (blockState.is(BlockTags.CAMPFIRES) && blockState.hasProperty(CampfireBlock.LIT) && !blockState.getValue(CampfireBlock.LIT)) {
|
||||
return false;
|
||||
}
|
||||
if (blockState.hasProperty(LitBlazeBurnerBlock.FLAME_TYPE) && blockState.getValue(LitBlazeBurnerBlock.FLAME_TYPE) != LitBlazeBurnerBlock.FlameType.SOUL) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -347,16 +358,24 @@ public class AllFanProcessingTypes {
|
|||
|
||||
@Override
|
||||
public boolean isValidAt(Level level, BlockPos pos) {
|
||||
FluidState fluidState = level.getFluidState(pos);
|
||||
if (AllFluidTags.FAN_PROCESSING_CATALYSTS_SMOKING.matches(fluidState)) {
|
||||
return true;
|
||||
}
|
||||
BlockState blockState = level.getBlockState(pos);
|
||||
Block block = blockState.getBlock();
|
||||
return block == Blocks.FIRE
|
||||
|| blockState.is(BlockTags.CAMPFIRES) && blockState.getOptionalValue(CampfireBlock.LIT)
|
||||
.orElse(false)
|
||||
|| AllBlocks.LIT_BLAZE_BURNER.has(blockState)
|
||||
&& blockState.getOptionalValue(LitBlazeBurnerBlock.FLAME_TYPE)
|
||||
.map(flame -> flame == LitBlazeBurnerBlock.FlameType.REGULAR)
|
||||
.orElse(false)
|
||||
|| getHeatLevelOf(blockState) == BlazeBurnerBlock.HeatLevel.SMOULDERING;
|
||||
if (AllBlockTags.FAN_PROCESSING_CATALYSTS_SMOKING.matches(blockState)) {
|
||||
if (blockState.is(BlockTags.CAMPFIRES) && blockState.hasProperty(CampfireBlock.LIT) && !blockState.getValue(CampfireBlock.LIT)) {
|
||||
return false;
|
||||
}
|
||||
if (blockState.hasProperty(LitBlazeBurnerBlock.FLAME_TYPE) && blockState.getValue(LitBlazeBurnerBlock.FLAME_TYPE) != LitBlazeBurnerBlock.FlameType.REGULAR) {
|
||||
return false;
|
||||
}
|
||||
if (blockState.hasProperty(BlazeBurnerBlock.HEAT_LEVEL) && blockState.getValue(BlazeBurnerBlock.HEAT_LEVEL) != BlazeBurnerBlock.HeatLevel.SMOULDERING) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -420,8 +439,14 @@ public class AllFanProcessingTypes {
|
|||
@Override
|
||||
public boolean isValidAt(Level level, BlockPos pos) {
|
||||
FluidState fluidState = level.getFluidState(pos);
|
||||
Fluid fluid = fluidState.getType();
|
||||
return fluid == Fluids.WATER || fluid == Fluids.FLOWING_WATER;
|
||||
if (AllFluidTags.FAN_PROCESSING_CATALYSTS_SPLASHING.matches(fluidState)) {
|
||||
return true;
|
||||
}
|
||||
BlockState blockState = level.getBlockState(pos);
|
||||
if (AllBlockTags.FAN_PROCESSING_CATALYSTS_SPLASHING.matches(blockState)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,6 +16,8 @@ public class TurntableHandler {
|
|||
Minecraft mc = Minecraft.getInstance();
|
||||
BlockPos pos = mc.player.blockPosition();
|
||||
|
||||
if (mc.gameMode == null)
|
||||
return;
|
||||
if (!AllBlocks.TURNTABLE.has(mc.level.getBlockState(pos)))
|
||||
return;
|
||||
if (!mc.player.onGround())
|
||||
|
|
|
@ -20,6 +20,7 @@ import com.simibubi.create.content.logistics.funnel.FunnelBlock;
|
|||
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
||||
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.VersionedInventoryTrackerBehaviour;
|
||||
import com.simibubi.create.foundation.item.ItemHelper;
|
||||
import com.simibubi.create.foundation.item.ItemHelper.ExtractionCountMode;
|
||||
import com.simibubi.create.foundation.particle.AirParticleData;
|
||||
|
@ -81,6 +82,8 @@ public class ChuteBlockEntity extends SmartBlockEntity implements IHaveGoggleInf
|
|||
int airCurrentUpdateCooldown;
|
||||
int entitySearchCooldown;
|
||||
|
||||
VersionedInventoryTrackerBehaviour invVersionTracker;
|
||||
|
||||
LazyOptional<IItemHandler> capAbove;
|
||||
LazyOptional<IItemHandler> capBelow;
|
||||
|
||||
|
@ -101,6 +104,7 @@ public class ChuteBlockEntity extends SmartBlockEntity implements IHaveGoggleInf
|
|||
@Override
|
||||
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
|
||||
behaviours.add(new DirectBeltInputBehaviour(this).onlyInsertWhen((d) -> canDirectlyInsertCached()));
|
||||
behaviours.add(invVersionTracker = new VersionedInventoryTrackerBehaviour(this));
|
||||
registerAwardables(behaviours, AllAdvancements.CHUTE);
|
||||
}
|
||||
|
||||
|
@ -336,15 +340,20 @@ public class ChuteBlockEntity extends SmartBlockEntity implements IHaveGoggleInf
|
|||
private void handleInput(IItemHandler inv, float startLocation) {
|
||||
if (inv == null)
|
||||
return;
|
||||
if (invVersionTracker.stillWaiting(inv))
|
||||
return;
|
||||
Predicate<ItemStack> canAccept = this::canAcceptItem;
|
||||
int count = getExtractionAmount();
|
||||
ExtractionCountMode mode = getExtractionMode();
|
||||
if (mode == ExtractionCountMode.UPTO || !ItemHelper.extract(inv, canAccept, mode, count, true)
|
||||
.isEmpty()) {
|
||||
ItemStack extracted = ItemHelper.extract(inv, canAccept, mode, count, false);
|
||||
if (!extracted.isEmpty())
|
||||
if (!extracted.isEmpty()) {
|
||||
setItem(extracted, startLocation);
|
||||
return;
|
||||
}
|
||||
}
|
||||
invVersionTracker.awaitNewVersion(inv);
|
||||
}
|
||||
|
||||
private boolean handleDownwardOutput(boolean simulate) {
|
||||
|
@ -359,12 +368,16 @@ public class ChuteBlockEntity extends SmartBlockEntity implements IHaveGoggleInf
|
|||
if (capBelow.isPresent()) {
|
||||
if (level.isClientSide && !isVirtual())
|
||||
return false;
|
||||
ItemStack remainder = ItemHandlerHelper.insertItemStacked(capBelow.orElse(null), item, simulate);
|
||||
IItemHandler inv = capBelow.orElse(null);
|
||||
if (invVersionTracker.stillWaiting(inv))
|
||||
return false;
|
||||
ItemStack remainder = ItemHandlerHelper.insertItemStacked(inv, item, simulate);
|
||||
ItemStack held = getItem();
|
||||
if (!simulate)
|
||||
setItem(remainder, itemPosition.getValue(0));
|
||||
if (remainder.getCount() != held.getCount())
|
||||
return true;
|
||||
invVersionTracker.awaitNewVersion(inv);
|
||||
if (direction == Direction.DOWN)
|
||||
return false;
|
||||
}
|
||||
|
@ -414,10 +427,16 @@ public class ChuteBlockEntity extends SmartBlockEntity implements IHaveGoggleInf
|
|||
if (level.isClientSide && !isVirtual() && !ChuteBlock.isChute(stateAbove))
|
||||
return false;
|
||||
int countBefore = item.getCount();
|
||||
ItemStack remainder = ItemHandlerHelper.insertItemStacked(capAbove.orElse(null), item, simulate);
|
||||
IItemHandler inv = capAbove.orElse(null);
|
||||
if (invVersionTracker.stillWaiting(inv))
|
||||
return false;
|
||||
ItemStack remainder = ItemHandlerHelper.insertItemStacked(inv, item, simulate);
|
||||
if (!simulate)
|
||||
item = remainder;
|
||||
return countBefore != remainder.getCount();
|
||||
if (countBefore != remainder.getCount())
|
||||
return true;
|
||||
invVersionTracker.awaitNewVersion(inv);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -502,6 +521,7 @@ public class ChuteBlockEntity extends SmartBlockEntity implements IHaveGoggleInf
|
|||
public void setItem(ItemStack stack, float insertionPos) {
|
||||
item = stack;
|
||||
itemPosition.startWithValue(insertionPos);
|
||||
invVersionTracker.reset();
|
||||
if (!level.isClientSide) {
|
||||
notifyUpdate();
|
||||
award(AllAdvancements.CHUTE);
|
||||
|
|
|
@ -51,7 +51,8 @@ public class SmartChuteBlockEntity extends ChuteBlockEntity {
|
|||
@Override
|
||||
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
|
||||
behaviours.add(filtering =
|
||||
new FilteringBehaviour(this, new SmartChuteFilterSlotPositioning()).showCountWhen(this::isExtracting));
|
||||
new FilteringBehaviour(this, new SmartChuteFilterSlotPositioning()).showCountWhen(this::isExtracting)
|
||||
.withCallback($ -> invVersionTracker.reset()));
|
||||
super.addBehaviours(behaviours);
|
||||
}
|
||||
|
||||
|
|
|
@ -240,7 +240,7 @@ public class DepotBehaviour extends BlockEntityBehaviour {
|
|||
|
||||
public void addSubBehaviours(List<BlockEntityBehaviour> behaviours) {
|
||||
behaviours.add(new DirectBeltInputBehaviour(blockEntity).allowingBeltFunnels()
|
||||
.setInsertionHandler(this::tryInsertingFromSide));
|
||||
.setInsertionHandler(this::tryInsertingFromSide).considerOccupiedWhen(this::isOccupied));
|
||||
transportedHandler = new TransportedItemStackHandlerBehaviour(blockEntity, this::applyToAllItems)
|
||||
.withStackPlacement(this::getWorldPositionOf);
|
||||
behaviours.add(transportedHandler);
|
||||
|
@ -339,14 +339,20 @@ public class DepotBehaviour extends BlockEntityBehaviour {
|
|||
return lazyItemHandler.cast();
|
||||
}
|
||||
|
||||
private boolean isOccupied(Direction side) {
|
||||
if (!getHeldItemStack().isEmpty() && !canMergeItems())
|
||||
return true;
|
||||
if (!isOutputEmpty() && !canMergeItems())
|
||||
return true;
|
||||
if (!canAcceptItems.get())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private ItemStack tryInsertingFromSide(TransportedItemStack transportedStack, Direction side, boolean simulate) {
|
||||
ItemStack inserted = transportedStack.stack;
|
||||
|
||||
if (!getHeldItemStack().isEmpty() && !canMergeItems())
|
||||
return inserted;
|
||||
if (!isOutputEmpty() && !canMergeItems())
|
||||
return inserted;
|
||||
if (!canAcceptItems.get())
|
||||
if (isOccupied(side))
|
||||
return inserted;
|
||||
|
||||
int size = transportedStack.stack.getCount();
|
||||
|
|
|
@ -8,7 +8,6 @@ import javax.annotation.Nonnull;
|
|||
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.AllKeys;
|
||||
import com.simibubi.create.content.fluids.transfer.GenericItemEmptying;
|
||||
import com.simibubi.create.content.logistics.filter.AttributeFilterMenu.WhitelistMode;
|
||||
import com.simibubi.create.foundation.item.ItemHelper;
|
||||
import com.simibubi.create.foundation.utility.CreateLang;
|
||||
|
@ -34,7 +33,6 @@ import net.minecraft.world.item.context.UseOnContext;
|
|||
import net.minecraft.world.level.Level;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import net.minecraftforge.network.NetworkHooks;
|
||||
|
@ -189,146 +187,7 @@ public class FilterItem extends Item implements MenuProvider {
|
|||
return newInv;
|
||||
}
|
||||
|
||||
public static boolean test(Level world, ItemStack stack, ItemStack filter) {
|
||||
return test(world, stack, filter, false);
|
||||
}
|
||||
|
||||
public static boolean test(Level world, FluidStack stack, ItemStack filter) {
|
||||
return test(world, stack, filter, true);
|
||||
}
|
||||
|
||||
public static boolean test(Level world, ItemStack stack, ItemStack filter, boolean matchNBT) {
|
||||
if (filter.isEmpty())
|
||||
return true;
|
||||
|
||||
if (!(filter.getItem() instanceof FilterItem))
|
||||
return testDirect(filter, stack, matchNBT);
|
||||
|
||||
boolean defaults = !filter.hasTag();
|
||||
|
||||
if (defaults) {
|
||||
return testDirect(filter, stack, matchNBT);
|
||||
}
|
||||
|
||||
if (AllItems.FILTER.get() == filter.getItem()) {
|
||||
ItemStackHandler filterItems = getFilterItems(filter);
|
||||
boolean respectNBT = defaults ? false
|
||||
: filter.getTag()
|
||||
.getBoolean("RespectNBT");
|
||||
boolean blacklist = defaults ? false
|
||||
: filter.getTag()
|
||||
.getBoolean("Blacklist");
|
||||
boolean isEmpty = true;
|
||||
for (int slot = 0; slot < filterItems.getSlots(); slot++) {
|
||||
ItemStack stackInSlot = filterItems.getStackInSlot(slot);
|
||||
if (stackInSlot.isEmpty())
|
||||
continue;
|
||||
isEmpty = false;
|
||||
boolean matches = test(world, stack, stackInSlot, respectNBT);
|
||||
if (matches)
|
||||
return !blacklist;
|
||||
}
|
||||
if (isEmpty) {
|
||||
return testDirect(filter, stack, matchNBT);
|
||||
}
|
||||
return blacklist;
|
||||
}
|
||||
|
||||
if (AllItems.ATTRIBUTE_FILTER.get() == filter.getItem()) {
|
||||
ListTag attributes = defaults ? new ListTag()
|
||||
: filter.getTag()
|
||||
.getList("MatchedAttributes", Tag.TAG_COMPOUND);
|
||||
if (attributes.isEmpty()) {
|
||||
return testDirect(filter, stack, matchNBT);
|
||||
}
|
||||
WhitelistMode whitelistMode = WhitelistMode.values()[defaults ? 0
|
||||
: filter.getTag()
|
||||
.getInt("WhitelistMode")];
|
||||
for (Tag inbt : attributes) {
|
||||
CompoundTag compound = (CompoundTag) inbt;
|
||||
ItemAttribute attribute = ItemAttribute.fromNBT(compound);
|
||||
if (attribute == null)
|
||||
continue;
|
||||
boolean matches = attribute.appliesTo(stack, world) != compound.getBoolean("Inverted");
|
||||
|
||||
if (matches) {
|
||||
switch (whitelistMode) {
|
||||
case BLACKLIST:
|
||||
return false;
|
||||
case WHITELIST_CONJ:
|
||||
continue;
|
||||
case WHITELIST_DISJ:
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
switch (whitelistMode) {
|
||||
case BLACKLIST:
|
||||
continue;
|
||||
case WHITELIST_CONJ:
|
||||
return false;
|
||||
case WHITELIST_DISJ:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (whitelistMode) {
|
||||
case BLACKLIST:
|
||||
return true;
|
||||
case WHITELIST_CONJ:
|
||||
return true;
|
||||
case WHITELIST_DISJ:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean test(Level world, FluidStack stack, ItemStack filter, boolean matchNBT) {
|
||||
if (filter.isEmpty())
|
||||
return true;
|
||||
if (stack.isEmpty())
|
||||
return false;
|
||||
|
||||
if (!(filter.getItem() instanceof FilterItem)) {
|
||||
if (!GenericItemEmptying.canItemBeEmptied(world, filter))
|
||||
return false;
|
||||
FluidStack fluidInFilter = GenericItemEmptying.emptyItem(world, filter, true)
|
||||
.getFirst();
|
||||
if (fluidInFilter == null)
|
||||
return false;
|
||||
if (!matchNBT)
|
||||
return fluidInFilter.getFluid()
|
||||
.isSame(stack.getFluid());
|
||||
boolean fluidEqual = fluidInFilter.isFluidEqual(stack);
|
||||
return fluidEqual;
|
||||
}
|
||||
|
||||
boolean defaults = !filter.hasTag();
|
||||
|
||||
if (AllItems.FILTER.get() == filter.getItem()) {
|
||||
ItemStackHandler filterItems = getFilterItems(filter);
|
||||
boolean respectNBT = defaults ? false
|
||||
: filter.getTag()
|
||||
.getBoolean("RespectNBT");
|
||||
boolean blacklist = defaults ? false
|
||||
: filter.getTag()
|
||||
.getBoolean("Blacklist");
|
||||
for (int slot = 0; slot < filterItems.getSlots(); slot++) {
|
||||
ItemStack stackInSlot = filterItems.getStackInSlot(slot);
|
||||
if (stackInSlot.isEmpty())
|
||||
continue;
|
||||
boolean matches = test(world, stack, stackInSlot, respectNBT);
|
||||
if (matches)
|
||||
return !blacklist;
|
||||
}
|
||||
return blacklist;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean testDirect(ItemStack filter, ItemStack stack, boolean matchNBT) {
|
||||
public static boolean testDirect(ItemStack filter, ItemStack stack, boolean matchNBT) {
|
||||
if (matchNBT) {
|
||||
return ItemHandlerHelper.canItemStacksStack(filter, stack);
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,235 @@
|
|||
package com.simibubi.create.content.logistics.filter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.content.fluids.transfer.GenericItemEmptying;
|
||||
|
||||
import net.createmod.catnip.utility.Pair;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
|
||||
public class FilterItemStack {
|
||||
|
||||
private ItemStack filterItemStack;
|
||||
private boolean fluidExtracted;
|
||||
private FluidStack filterFluidStack;
|
||||
|
||||
public static FilterItemStack of(ItemStack filter) {
|
||||
if (filter.hasTag()) {
|
||||
if (AllItems.FILTER.isIn(filter))
|
||||
return new ListFilterItemStack(filter);
|
||||
if (AllItems.ATTRIBUTE_FILTER.isIn(filter))
|
||||
return new AttributeFilterItemStack(filter);
|
||||
}
|
||||
|
||||
return new FilterItemStack(filter);
|
||||
}
|
||||
|
||||
public static FilterItemStack of(CompoundTag tag) {
|
||||
return of(ItemStack.of(tag));
|
||||
}
|
||||
|
||||
public static FilterItemStack empty() {
|
||||
return of(ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return filterItemStack.isEmpty();
|
||||
}
|
||||
|
||||
public CompoundTag serializeNBT() {
|
||||
return filterItemStack.serializeNBT();
|
||||
}
|
||||
|
||||
public ItemStack item() {
|
||||
return filterItemStack;
|
||||
}
|
||||
|
||||
public FluidStack fluid(Level level) {
|
||||
resolveFluid(level);
|
||||
return filterFluidStack;
|
||||
}
|
||||
|
||||
public boolean isFilterItem() {
|
||||
return filterItemStack.getItem() instanceof FilterItem;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
public boolean test(Level world, ItemStack stack) {
|
||||
return test(world, stack, false);
|
||||
}
|
||||
|
||||
public boolean test(Level world, FluidStack stack) {
|
||||
return test(world, stack, true);
|
||||
}
|
||||
|
||||
public boolean test(Level world, ItemStack stack, boolean matchNBT) {
|
||||
if (isEmpty())
|
||||
return true;
|
||||
return FilterItem.testDirect(filterItemStack, stack, matchNBT);
|
||||
}
|
||||
|
||||
public boolean test(Level world, FluidStack stack, boolean matchNBT) {
|
||||
if (isEmpty())
|
||||
return true;
|
||||
if (stack.isEmpty())
|
||||
return false;
|
||||
|
||||
resolveFluid(world);
|
||||
|
||||
if (filterFluidStack.isEmpty())
|
||||
return false;
|
||||
if (!matchNBT)
|
||||
return filterFluidStack.getFluid()
|
||||
.isSame(stack.getFluid());
|
||||
return filterFluidStack.isFluidEqual(stack);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
private void resolveFluid(Level world) {
|
||||
if (!fluidExtracted) {
|
||||
fluidExtracted = true;
|
||||
if (GenericItemEmptying.canItemBeEmptied(world, filterItemStack))
|
||||
filterFluidStack = GenericItemEmptying.emptyItem(world, filterItemStack, true)
|
||||
.getFirst();
|
||||
}
|
||||
}
|
||||
|
||||
protected FilterItemStack(ItemStack filter) {
|
||||
filterItemStack = filter;
|
||||
filterFluidStack = FluidStack.EMPTY;
|
||||
fluidExtracted = false;
|
||||
}
|
||||
|
||||
public static class ListFilterItemStack extends FilterItemStack {
|
||||
|
||||
public List<FilterItemStack> containedItems;
|
||||
public boolean shouldRespectNBT;
|
||||
public boolean isBlacklist;
|
||||
|
||||
protected ListFilterItemStack(ItemStack filter) {
|
||||
super(filter);
|
||||
boolean defaults = !filter.hasTag();
|
||||
|
||||
containedItems = new ArrayList<>();
|
||||
ItemStackHandler items = FilterItem.getFilterItems(filter);
|
||||
for (int i = 0; i < items.getSlots(); i++) {
|
||||
ItemStack stackInSlot = items.getStackInSlot(i);
|
||||
if (!stackInSlot.isEmpty())
|
||||
containedItems.add(FilterItemStack.of(stackInSlot));
|
||||
}
|
||||
|
||||
shouldRespectNBT = !defaults ? false
|
||||
: filter.getTag()
|
||||
.getBoolean("RespectNBT");
|
||||
isBlacklist = defaults ? false
|
||||
: filter.getTag()
|
||||
.getBoolean("Blacklist");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(Level world, ItemStack stack, boolean matchNBT) {
|
||||
if (containedItems.isEmpty())
|
||||
return super.test(world, stack, matchNBT);
|
||||
for (FilterItemStack filterItemStack : containedItems)
|
||||
if (filterItemStack.test(world, stack, shouldRespectNBT))
|
||||
return !isBlacklist;
|
||||
return isBlacklist;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(Level world, FluidStack stack, boolean matchNBT) {
|
||||
for (FilterItemStack filterItemStack : containedItems)
|
||||
if (filterItemStack.test(world, stack, shouldRespectNBT))
|
||||
return !isBlacklist;
|
||||
return isBlacklist;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class AttributeFilterItemStack extends FilterItemStack {
|
||||
|
||||
public enum WhitelistMode {
|
||||
WHITELIST_DISJ, WHITELIST_CONJ, BLACKLIST;
|
||||
}
|
||||
|
||||
public WhitelistMode whitelistMode;
|
||||
public List<Pair<ItemAttribute, Boolean>> attributeTests;
|
||||
|
||||
protected AttributeFilterItemStack(ItemStack filter) {
|
||||
super(filter);
|
||||
boolean defaults = !filter.hasTag();
|
||||
|
||||
attributeTests = new ArrayList<>();
|
||||
whitelistMode = WhitelistMode.values()[defaults ? 0
|
||||
: filter.getTag()
|
||||
.getInt("WhitelistMode")];
|
||||
|
||||
ListTag attributes = defaults ? new ListTag()
|
||||
: filter.getTag()
|
||||
.getList("MatchedAttributes", Tag.TAG_COMPOUND);
|
||||
for (Tag inbt : attributes) {
|
||||
CompoundTag compound = (CompoundTag) inbt;
|
||||
ItemAttribute attribute = ItemAttribute.fromNBT(compound);
|
||||
if (attribute != null)
|
||||
attributeTests.add(Pair.of(attribute, compound.getBoolean("Inverted")));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(Level world, FluidStack stack, boolean matchNBT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(Level world, ItemStack stack, boolean matchNBT) {
|
||||
if (attributeTests.isEmpty())
|
||||
return super.test(world, stack, matchNBT);
|
||||
for (Pair<ItemAttribute, Boolean> test : attributeTests) {
|
||||
ItemAttribute attribute = test.getFirst();
|
||||
boolean inverted = test.getSecond();
|
||||
boolean matches = attribute.appliesTo(stack, world) != inverted;
|
||||
|
||||
if (matches) {
|
||||
switch (whitelistMode) {
|
||||
case BLACKLIST -> {
|
||||
return false;
|
||||
}
|
||||
case WHITELIST_CONJ -> {
|
||||
continue;
|
||||
}
|
||||
case WHITELIST_DISJ -> {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (whitelistMode) {
|
||||
case BLACKLIST, WHITELIST_DISJ -> {
|
||||
continue;
|
||||
}
|
||||
case WHITELIST_CONJ -> {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return switch (whitelistMode) {
|
||||
case BLACKLIST, WHITELIST_CONJ -> true;
|
||||
case WHITELIST_DISJ -> false;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -3,6 +3,8 @@ package com.simibubi.create.content.logistics.funnel;
|
|||
import java.lang.ref.WeakReference;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||
|
||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllPackets;
|
||||
|
@ -18,6 +20,7 @@ import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
|
|||
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringBehaviour;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.InvManipulationBehaviour;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.VersionedInventoryTrackerBehaviour;
|
||||
import com.simibubi.create.foundation.item.ItemHelper.ExtractionCountMode;
|
||||
import com.simibubi.create.infrastructure.config.AllConfigs;
|
||||
|
||||
|
@ -42,6 +45,7 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering
|
|||
|
||||
private FilteringBehaviour filtering;
|
||||
private InvManipulationBehaviour invManipulation;
|
||||
private VersionedInventoryTrackerBehaviour invVersionTracker;
|
||||
private int extractionCooldown;
|
||||
|
||||
private WeakReference<ItemEntity> lastObserved; // In-world Extractors only
|
||||
|
@ -111,6 +115,9 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering
|
|||
}
|
||||
|
||||
private void activateExtractor() {
|
||||
if (invVersionTracker.stillWaiting(invManipulation))
|
||||
return;
|
||||
|
||||
BlockState blockState = getBlockState();
|
||||
Direction facing = AbstractFunnelBlock.getFunnelFacing(blockState);
|
||||
|
||||
|
@ -140,8 +147,10 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering
|
|||
ExtractionCountMode mode = getModeToExtract();
|
||||
ItemStack stack = invManipulation.simulate()
|
||||
.extract(mode, amountToExtract);
|
||||
if (stack.isEmpty())
|
||||
if (stack.isEmpty()) {
|
||||
invVersionTracker.awaitNewVersion(invManipulation);
|
||||
return;
|
||||
}
|
||||
for (ItemEntity itemEntity : level.getEntitiesOfClass(ItemEntity.class, area)) {
|
||||
lastObserved = new WeakReference<>(itemEntity);
|
||||
return;
|
||||
|
@ -189,6 +198,9 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering
|
|||
}
|
||||
|
||||
private void activateExtractingBeltFunnel() {
|
||||
if (invVersionTracker.stillWaiting(invManipulation))
|
||||
return;
|
||||
|
||||
BlockState blockState = getBlockState();
|
||||
Direction facing = blockState.getValue(BeltFunnelBlock.HORIZONTAL_FACING);
|
||||
DirectBeltInputBehaviour inputBehaviour =
|
||||
|
@ -198,14 +210,24 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering
|
|||
return;
|
||||
if (!inputBehaviour.canInsertFromSide(facing))
|
||||
return;
|
||||
if (inputBehaviour.isOccupied(facing))
|
||||
return;
|
||||
|
||||
int amountToExtract = getAmountToExtract();
|
||||
ExtractionCountMode mode = getModeToExtract();
|
||||
ItemStack stack =
|
||||
invManipulation.extract(mode, amountToExtract, s -> inputBehaviour.handleInsertion(s, facing, true)
|
||||
.isEmpty());
|
||||
if (stack.isEmpty())
|
||||
MutableBoolean deniedByInsertion = new MutableBoolean(false);
|
||||
ItemStack stack = invManipulation.extract(mode, amountToExtract, s -> {
|
||||
ItemStack handleInsertion = inputBehaviour.handleInsertion(s, facing, true);
|
||||
if (handleInsertion.isEmpty())
|
||||
return true;
|
||||
deniedByInsertion.setTrue();
|
||||
return false;
|
||||
});
|
||||
if (stack.isEmpty()) {
|
||||
if (deniedByInsertion.isFalse())
|
||||
invVersionTracker.awaitNewVersion(invManipulation.getInventory());
|
||||
return;
|
||||
}
|
||||
flap(false);
|
||||
onTransfer(stack);
|
||||
inputBehaviour.handleInsertion(stack, facing, false);
|
||||
|
@ -237,12 +259,15 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering
|
|||
new InvManipulationBehaviour(this, (w, p, s) -> new BlockFace(p, AbstractFunnelBlock.getFunnelFacing(s)
|
||||
.getOpposite()));
|
||||
behaviours.add(invManipulation);
|
||||
|
||||
behaviours.add(invVersionTracker = new VersionedInventoryTrackerBehaviour(this));
|
||||
|
||||
filtering = new FilteringBehaviour(this, new FunnelFilterSlotPositioning());
|
||||
filtering.showCountWhen(this::supportsAmountOnFilter);
|
||||
filtering.onlyActiveWhen(this::supportsFiltering);
|
||||
filtering.withCallback($ -> invVersionTracker.reset());
|
||||
behaviours.add(filtering);
|
||||
|
||||
|
||||
behaviours.add(new DirectBeltInputBehaviour(this).onlyInsertWhen(this::supportsDirectBeltInput)
|
||||
.setInsertionHandler(this::handleDirectBeltInput));
|
||||
registerAwardables(behaviours, AllAdvancements.FUNNEL);
|
||||
|
|
|
@ -4,7 +4,7 @@ import java.util.List;
|
|||
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
||||
import com.simibubi.create.content.logistics.filter.FilterItem;
|
||||
import com.simibubi.create.content.logistics.filter.FilterItemStack;
|
||||
import com.simibubi.create.foundation.item.ItemHelper;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -71,14 +71,14 @@ public class FunnelMovementBehaviour implements MovementBehaviour {
|
|||
.isEmpty())
|
||||
return;
|
||||
|
||||
ItemStack filter = getFilter(context);
|
||||
FilterItemStack filter = context.getFilterFromBE();
|
||||
int filterAmount = context.blockEntityData.getInt("FilterAmount");
|
||||
boolean upTo = context.blockEntityData.getBoolean("UpTo");
|
||||
if (filterAmount <= 0)
|
||||
filterAmount = hasFilter ? 64 : 1;
|
||||
|
||||
ItemStack extract = ItemHelper.extract(context.contraption.getSharedInventory(),
|
||||
s -> FilterItem.test(world, s, filter),
|
||||
s -> filter.test(world, s),
|
||||
upTo ? ItemHelper.ExtractionCountMode.UPTO : ItemHelper.ExtractionCountMode.EXACTLY, filterAmount, false);
|
||||
|
||||
if (extract.isEmpty())
|
||||
|
@ -97,13 +97,13 @@ public class FunnelMovementBehaviour implements MovementBehaviour {
|
|||
private void succ(MovementContext context, BlockPos pos) {
|
||||
Level world = context.world;
|
||||
List<ItemEntity> items = world.getEntitiesOfClass(ItemEntity.class, new AABB(pos));
|
||||
ItemStack filter = getFilter(context);
|
||||
FilterItemStack filter = context.getFilterFromBE();
|
||||
|
||||
for (ItemEntity item : items) {
|
||||
if (!item.isAlive())
|
||||
continue;
|
||||
ItemStack toInsert = item.getItem();
|
||||
if (!filter.isEmpty() && !FilterItem.test(context.world, toInsert, filter))
|
||||
if (!filter.test(context.world, toInsert))
|
||||
continue;
|
||||
ItemStack remainder =
|
||||
ItemHandlerHelper.insertItemStacked(context.contraption.getSharedInventory(), toInsert, false);
|
||||
|
@ -124,8 +124,4 @@ public class FunnelMovementBehaviour implements MovementBehaviour {
|
|||
return true;
|
||||
}
|
||||
|
||||
private ItemStack getFilter(MovementContext context) {
|
||||
return hasFilter ? ItemStack.of(context.blockEntityData.getCompound("Filter")) : ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ public class ItemVaultBlock extends Block implements IWrenchable, IBE<ItemVaultB
|
|||
@Override
|
||||
public BlockState getStateForPlacement(BlockPlaceContext pContext) {
|
||||
if (pContext.getPlayer() == null || !pContext.getPlayer()
|
||||
.isSteppingCarefully()) {
|
||||
.isShiftKeyDown()) {
|
||||
BlockState placedOn = pContext.getLevel()
|
||||
.getBlockState(pContext.getClickedPos()
|
||||
.relative(pContext.getClickedFace()
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.simibubi.create.api.connectivity.ConnectivityHandler;
|
|||
import com.simibubi.create.foundation.blockEntity.IMultiBlockEntityContainer;
|
||||
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.VersionedInventoryWrapper;
|
||||
import com.simibubi.create.infrastructure.config.AllConfigs;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -260,8 +261,8 @@ public class ItemVaultBlockEntity extends SmartBlockEntity implements IMultiBloc
|
|||
}
|
||||
}
|
||||
|
||||
CombinedInvWrapper combinedInvWrapper = new CombinedInvWrapper(invs);
|
||||
itemCapability = LazyOptional.of(() -> combinedInvWrapper);
|
||||
IItemHandler itemHandler = new VersionedInventoryWrapper(new CombinedInvWrapper(invs));
|
||||
itemCapability = LazyOptional.of(() -> itemHandler);
|
||||
}
|
||||
|
||||
public static int getMaxLength(int radius) {
|
||||
|
|
|
@ -54,7 +54,7 @@ public class ItemVaultItem extends BlockItem {
|
|||
Player player = ctx.getPlayer();
|
||||
if (player == null)
|
||||
return;
|
||||
if (player.isSteppingCarefully())
|
||||
if (player.isShiftKeyDown())
|
||||
return;
|
||||
Direction face = ctx.getClickedFace();
|
||||
ItemStack stack = ctx.getItemInHand();
|
||||
|
|
|
@ -34,7 +34,7 @@ public class ExperienceNuggetItem extends Item {
|
|||
return InteractionResultHolder.consume(itemInHand);
|
||||
}
|
||||
|
||||
int amountUsed = pPlayer.isSteppingCarefully() ? 1 : itemInHand.getCount();
|
||||
int amountUsed = pPlayer.isShiftKeyDown() ? 1 : itemInHand.getCount();
|
||||
int total = Mth.ceil(3f * amountUsed);
|
||||
int maxOrbs = amountUsed == 1 ? 1 : 5;
|
||||
int valuePer = Math.max(1, 1 + total / maxOrbs);
|
||||
|
|
|
@ -28,6 +28,7 @@ import com.simibubi.create.foundation.blockEntity.behaviour.inventory.InvManipul
|
|||
import com.simibubi.create.foundation.fluid.CombinedTankWrapper;
|
||||
import com.simibubi.create.foundation.item.ItemHelper;
|
||||
import com.simibubi.create.foundation.item.SmartInventory;
|
||||
import com.simibubi.create.foundation.utility.BlockHelper;
|
||||
import com.simibubi.create.foundation.utility.CreateLang;
|
||||
|
||||
import net.createmod.catnip.utility.AnimationTickHolder;
|
||||
|
@ -602,7 +603,7 @@ public class BasinBlockEntity extends SmartBlockEntity implements IHaveGoggleInf
|
|||
public static HeatLevel getHeatLevelOf(BlockState state) {
|
||||
if (state.hasProperty(BlazeBurnerBlock.HEAT_LEVEL))
|
||||
return state.getValue(BlazeBurnerBlock.HEAT_LEVEL);
|
||||
return AllTags.AllBlockTags.PASSIVE_BOILER_HEATERS.matches(state) ? HeatLevel.SMOULDERING : HeatLevel.NONE;
|
||||
return AllTags.AllBlockTags.PASSIVE_BOILER_HEATERS.matches(state) && BlockHelper.isNotUnheated(state) ? HeatLevel.SMOULDERING : HeatLevel.NONE;
|
||||
}
|
||||
|
||||
public Couple<SmartFluidTankBehaviour> getTanks() {
|
||||
|
|
|
@ -3,17 +3,18 @@ package com.simibubi.create.content.processing.burner;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllTags.AllEntityTags;
|
||||
|
||||
import net.createmod.catnip.platform.CatnipServices;
|
||||
import net.createmod.catnip.utility.VecHelper;
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.util.random.WeightedEntry.Wrapper;
|
||||
|
@ -21,7 +22,6 @@ import net.minecraft.world.InteractionHand;
|
|||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.monster.Blaze;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
|
@ -91,11 +91,9 @@ public class BlazeBurnerBlockItem extends BlockItem {
|
|||
possibleSpawns.add(spawner.nextSpawnData);
|
||||
}
|
||||
|
||||
ResourceLocation blazeId = CatnipServices.REGISTRIES.getKeyOrThrow(EntityType.BLAZE);
|
||||
for (SpawnData e : possibleSpawns) {
|
||||
ResourceLocation spawnerEntityId = new ResourceLocation(e.entityToSpawn()
|
||||
.getString("id"));
|
||||
if (!spawnerEntityId.equals(blazeId))
|
||||
Optional<EntityType<?>> optionalEntity = EntityType.by(e.entityToSpawn());
|
||||
if (optionalEntity.isEmpty() || !AllEntityTags.BLAZE_BURNER_CAPTURABLE.matches(optionalEntity.get()))
|
||||
continue;
|
||||
|
||||
spawnCaptureEffects(world, VecHelper.getCenterOf(pos));
|
||||
|
@ -114,7 +112,7 @@ public class BlazeBurnerBlockItem extends BlockItem {
|
|||
InteractionHand hand) {
|
||||
if (hasCapturedBlaze())
|
||||
return InteractionResult.PASS;
|
||||
if (!(entity instanceof Blaze))
|
||||
if (!AllEntityTags.BLAZE_BURNER_CAPTURABLE.matches(entity))
|
||||
return InteractionResult.PASS;
|
||||
|
||||
Level world = player.level();
|
||||
|
|
|
@ -33,12 +33,11 @@ public class AnalogLeverInstance extends BlockEntityInstance<AnalogLeverBlockEnt
|
|||
indicator = mat.getModel(AllPartialModels.ANALOG_LEVER_INDICATOR, blockState)
|
||||
.createInstance();
|
||||
|
||||
transform(indicator);
|
||||
|
||||
AttachFace face = blockState.getValue(AnalogLeverBlock.FACE);
|
||||
rX = face == AttachFace.FLOOR ? 0 : face == AttachFace.WALL ? 90 : 180;
|
||||
rY = AngleHelper.horizontalAngle(blockState.getValue(AnalogLeverBlock.FACING));
|
||||
|
||||
transform(indicator.loadIdentity());
|
||||
animateLever();
|
||||
}
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ public class DisplayLinkBlock extends WrenchableDirectionalBlock implements IBE<
|
|||
BlockHitResult pHit) {
|
||||
if (pPlayer == null)
|
||||
return InteractionResult.PASS;
|
||||
if (pPlayer.isSteppingCarefully())
|
||||
if (pPlayer.isShiftKeyDown())
|
||||
return InteractionResult.PASS;
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT,
|
||||
() -> () -> withBlockEntityDo(pLevel, pPos, be -> this.displayScreen(be, pPlayer)));
|
||||
|
|
|
@ -57,7 +57,7 @@ public class DisplayLinkBlockItem extends BlockItem {
|
|||
if (player == null)
|
||||
return InteractionResult.FAIL;
|
||||
|
||||
if (player.isSteppingCarefully() && stack.hasTag()) {
|
||||
if (player.isShiftKeyDown() && stack.hasTag()) {
|
||||
if (level.isClientSide)
|
||||
return InteractionResult.SUCCESS;
|
||||
player.displayClientMessage(CreateLang.translateDirect("display_link.clear"), true);
|
||||
|
|
|
@ -83,7 +83,7 @@ public class SmartObserverBlock extends DirectedDirectionalBlock implements IBE<
|
|||
if (preferredFacing == null) {
|
||||
Direction facing = context.getNearestLookingDirection();
|
||||
preferredFacing = context.getPlayer() != null && context.getPlayer()
|
||||
.isSteppingCarefully() ? facing : facing.getOpposite();
|
||||
.isShiftKeyDown() ? facing : facing.getOpposite();
|
||||
}
|
||||
|
||||
if (preferredFacing.getAxis() == Axis.Y) {
|
||||
|
@ -101,7 +101,7 @@ public class SmartObserverBlock extends DirectedDirectionalBlock implements IBE<
|
|||
|
||||
@Override
|
||||
public int getSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) {
|
||||
return isSignalSource(blockState) && (side == null || side != blockState.getValue(FACING)
|
||||
return isSignalSource(blockState) && (side == null || side != getTargetDirection(blockState)
|
||||
.getOpposite()) ? 15 : 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringB
|
|||
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.CapManipulationBehaviourBase.InterfaceProvider;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.InvManipulationBehaviour;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.TankManipulationBehaviour;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.VersionedInventoryTrackerBehaviour;
|
||||
|
||||
import net.createmod.catnip.utility.BlockFace;
|
||||
import net.createmod.catnip.utility.Iterate;
|
||||
|
@ -31,6 +32,10 @@ public class SmartObserverBlockEntity extends SmartBlockEntity {
|
|||
private FilteringBehaviour filtering;
|
||||
private InvManipulationBehaviour observedInventory;
|
||||
private TankManipulationBehaviour observedTank;
|
||||
|
||||
private VersionedInventoryTrackerBehaviour invVersionTracker;
|
||||
private boolean sustainSignal;
|
||||
|
||||
public int turnOffTicks = 0;
|
||||
|
||||
public SmartObserverBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||
|
@ -40,7 +45,9 @@ public class SmartObserverBlockEntity extends SmartBlockEntity {
|
|||
|
||||
@Override
|
||||
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
|
||||
behaviours.add(filtering = new FilteringBehaviour(this, new FilteredDetectorFilterSlot(false)));
|
||||
behaviours.add(filtering = new FilteringBehaviour(this, new FilteredDetectorFilterSlot(false))
|
||||
.withCallback($ -> invVersionTracker.reset()));
|
||||
behaviours.add(invVersionTracker = new VersionedInventoryTrackerBehaviour(this));
|
||||
|
||||
InterfaceProvider towardBlockFacing =
|
||||
(w, p, s) -> new BlockFace(p, DirectedDirectionalBlock.getTargetDirection(s));
|
||||
|
@ -105,11 +112,23 @@ public class SmartObserverBlockEntity extends SmartBlockEntity {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!observedInventory.simulate()
|
||||
.extract()
|
||||
.isEmpty()) {
|
||||
activate();
|
||||
return;
|
||||
if (observedInventory.hasInventory()) {
|
||||
boolean skipInv = invVersionTracker.stillWaiting(observedInventory);
|
||||
invVersionTracker.awaitNewVersion(observedInventory);
|
||||
|
||||
if (skipInv && sustainSignal)
|
||||
turnOffTicks = DEFAULT_DELAY;
|
||||
|
||||
if (!skipInv) {
|
||||
sustainSignal = false;
|
||||
if (!observedInventory.simulate()
|
||||
.extract()
|
||||
.isEmpty()) {
|
||||
sustainSignal = true;
|
||||
activate();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!observedTank.simulate()
|
||||
|
|
|
@ -54,7 +54,7 @@ public class ThresholdSwitchBlock extends DirectedDirectionalBlock implements IB
|
|||
|
||||
@Override
|
||||
public boolean canConnectRedstone(BlockState state, BlockGetter world, BlockPos pos, Direction side) {
|
||||
return side != null && side.getOpposite() != state.getValue(FACING);
|
||||
return side != null && side.getOpposite() != getTargetDirection(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -64,7 +64,7 @@ public class ThresholdSwitchBlock extends DirectedDirectionalBlock implements IB
|
|||
|
||||
@Override
|
||||
public int getSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) {
|
||||
if (side == blockState.getValue(FACING)
|
||||
if (side == getTargetDirection(blockState)
|
||||
.getOpposite())
|
||||
return 0;
|
||||
return getBlockEntityOptional(blockAccess, pos).filter(ThresholdSwitchBlockEntity::isPowered)
|
||||
|
@ -121,7 +121,7 @@ public class ThresholdSwitchBlock extends DirectedDirectionalBlock implements IB
|
|||
if (preferredFacing == null) {
|
||||
Direction facing = context.getNearestLookingDirection();
|
||||
preferredFacing = context.getPlayer() != null && context.getPlayer()
|
||||
.isSteppingCarefully() ? facing : facing.getOpposite();
|
||||
.isShiftKeyDown() ? facing : facing.getOpposite();
|
||||
}
|
||||
|
||||
if (preferredFacing.getAxis() == Axis.Y) {
|
||||
|
|
|
@ -12,6 +12,7 @@ import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringB
|
|||
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.CapManipulationBehaviourBase.InterfaceProvider;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.InvManipulationBehaviour;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.TankManipulationBehaviour;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.VersionedInventoryTrackerBehaviour;
|
||||
|
||||
import net.createmod.catnip.utility.BlockFace;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -39,6 +40,7 @@ public class ThresholdSwitchBlockEntity extends SmartBlockEntity {
|
|||
private FilteringBehaviour filtering;
|
||||
private InvManipulationBehaviour observedInventory;
|
||||
private TankManipulationBehaviour observedTank;
|
||||
private VersionedInventoryTrackerBehaviour invVersionTracker;
|
||||
|
||||
public ThresholdSwitchBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||
super(type, pos, state);
|
||||
|
@ -107,18 +109,26 @@ public class ThresholdSwitchBlockEntity extends SmartBlockEntity {
|
|||
|
||||
} else if (observedInventory.hasInventory() || observedTank.hasInventory()) {
|
||||
if (observedInventory.hasInventory()) {
|
||||
|
||||
// Item inventory
|
||||
IItemHandler inv = observedInventory.getInventory();
|
||||
for (int slot = 0; slot < inv.getSlots(); slot++) {
|
||||
ItemStack stackInSlot = inv.getStackInSlot(slot);
|
||||
int space = Math.min(stackInSlot.getMaxStackSize(), inv.getSlotLimit(slot));
|
||||
int count = stackInSlot.getCount();
|
||||
if (space == 0)
|
||||
continue;
|
||||
if (invVersionTracker.stillWaiting(inv)) {
|
||||
occupied = prevLevel;
|
||||
totalSpace = 1f;
|
||||
|
||||
totalSpace += 1;
|
||||
if (filtering.test(stackInSlot))
|
||||
occupied += count * (1f / space);
|
||||
} else {
|
||||
invVersionTracker.awaitNewVersion(inv);
|
||||
for (int slot = 0; slot < inv.getSlots(); slot++) {
|
||||
ItemStack stackInSlot = inv.getStackInSlot(slot);
|
||||
int space = Math.min(stackInSlot.getMaxStackSize(), inv.getSlotLimit(slot));
|
||||
int count = stackInSlot.getCount();
|
||||
if (space == 0)
|
||||
continue;
|
||||
|
||||
totalSpace += 1;
|
||||
if (filtering.test(stackInSlot))
|
||||
occupied += count * (1f / space);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,7 +205,12 @@ public class ThresholdSwitchBlockEntity extends SmartBlockEntity {
|
|||
@Override
|
||||
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
|
||||
behaviours.add(filtering = new FilteringBehaviour(this, new FilteredDetectorFilterSlot(true))
|
||||
.withCallback($ -> this.updateCurrentLevel()));
|
||||
.withCallback($ -> {
|
||||
this.updateCurrentLevel();
|
||||
invVersionTracker.reset();
|
||||
}));
|
||||
|
||||
behaviours.add(invVersionTracker = new VersionedInventoryTrackerBehaviour(this));
|
||||
|
||||
InterfaceProvider towardBlockFacing =
|
||||
(w, p, s) -> new BlockFace(p, DirectedDirectionalBlock.getTargetDirection(s));
|
||||
|
|
|
@ -188,20 +188,19 @@ public class GlobalRailwayManager {
|
|||
if (level.dimension() != Level.OVERWORLD)
|
||||
return;
|
||||
|
||||
for (SignalEdgeGroup group : signalEdgeGroups.values()) {
|
||||
signalEdgeGroups.forEach((id, group) -> {
|
||||
group.trains.clear();
|
||||
group.reserved = null;
|
||||
}
|
||||
});
|
||||
|
||||
for (TrackGraph graph : trackNetworks.values()) {
|
||||
trackNetworks.forEach((id, graph) -> {
|
||||
graph.tickPoints(true);
|
||||
graph.resolveIntersectingEdgeGroups(level);
|
||||
}
|
||||
});
|
||||
|
||||
tickTrains(level);
|
||||
|
||||
for (TrackGraph graph : trackNetworks.values())
|
||||
graph.tickPoints(false);
|
||||
trackNetworks.forEach((id, graph) -> graph.tickPoints(false));
|
||||
|
||||
GlobalTrainDisplayData.updateTick = level.getGameTime() % 100 == 0;
|
||||
if (GlobalTrainDisplayData.updateTick)
|
||||
|
|
|
@ -25,6 +25,7 @@ import com.simibubi.create.content.schematics.requirement.ItemRequirement;
|
|||
import com.simibubi.create.content.trains.entity.Carriage;
|
||||
import com.simibubi.create.content.trains.entity.CarriageBogey;
|
||||
import com.simibubi.create.content.trains.entity.TravellingPoint;
|
||||
import com.simibubi.create.content.trains.graph.TrackEdge;
|
||||
import com.simibubi.create.content.trains.track.TrackMaterial;
|
||||
import com.simibubi.create.foundation.block.IBE;
|
||||
import com.simibubi.create.foundation.block.ProperWaterloggedBlock;
|
||||
|
@ -75,7 +76,10 @@ public abstract class AbstractBogeyBlock<T extends AbstractBogeyBlockEntity> ext
|
|||
public boolean isOnIncompatibleTrack(Carriage carriage, boolean leading) {
|
||||
TravellingPoint point = leading ? carriage.getLeadingPoint() : carriage.getTrailingPoint();
|
||||
CarriageBogey bogey = leading ? carriage.leadingBogey() : carriage.trailingBogey();
|
||||
return point.edge.getTrackMaterial().trackType != getTrackType(bogey.getStyle());
|
||||
TrackEdge currentEdge = point.edge;
|
||||
if (currentEdge == null)
|
||||
return false;
|
||||
return currentEdge.getTrackMaterial().trackType != getTrackType(bogey.getStyle());
|
||||
}
|
||||
|
||||
public Set<TrackMaterial.TrackType> getValidPathfindingTypes(BogeyStyle style) {
|
||||
|
|
|
@ -641,7 +641,7 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
|||
if (lookAhead != null) {
|
||||
if (spaceDown) {
|
||||
carriage.train.manualTick = true;
|
||||
nav.startNavigation(lookAhead, -1, false);
|
||||
nav.startNavigation(nav.findPathTo(lookAhead, -1));
|
||||
carriage.train.manualTick = false;
|
||||
navDistanceTotal = nav.distanceToDestination;
|
||||
return true;
|
||||
|
|
|
@ -304,9 +304,12 @@ public class CarriageSyncData {
|
|||
|
||||
TrackNode initialNode1 = forward ? current.node1 : current.node2;
|
||||
TrackNode initialNode2 = forward ? current.node2 : current.node1;
|
||||
TrackEdge initialEdge = graph.getConnectionsFrom(initialNode1)
|
||||
.get(initialNode2);
|
||||
|
||||
|
||||
Map<TrackNode, TrackEdge> connectionsFromInitial = graph.getConnectionsFrom(initialNode1);
|
||||
if (connectionsFromInitial == null)
|
||||
return -1;
|
||||
|
||||
TrackEdge initialEdge = connectionsFromInitial.get(initialNode2);
|
||||
if (initialEdge == null)
|
||||
return -1; // graph changed
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.apache.commons.lang3.mutable.MutableObject;
|
|||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.trains.entity.TravellingPoint.ITrackSelector;
|
||||
import com.simibubi.create.content.trains.graph.DimensionPalette;
|
||||
import com.simibubi.create.content.trains.graph.DiscoveredPath;
|
||||
import com.simibubi.create.content.trains.graph.EdgeData;
|
||||
import com.simibubi.create.content.trains.graph.EdgePointType;
|
||||
import com.simibubi.create.content.trains.graph.TrackEdge;
|
||||
|
@ -380,15 +381,11 @@ public class Navigation {
|
|||
train.reservedSignalBlocks.clear();
|
||||
}
|
||||
|
||||
public double startNavigation(GlobalStation destination, double maxCost, boolean simulate) {
|
||||
DiscoveredPath pathTo = findPathTo(destination, maxCost);
|
||||
public double startNavigation(DiscoveredPath pathTo) {
|
||||
boolean noneFound = pathTo == null;
|
||||
double distance = noneFound ? -1 : Math.abs(pathTo.distance);
|
||||
double cost = noneFound ? -1 : pathTo.cost;
|
||||
|
||||
if (simulate)
|
||||
return cost;
|
||||
|
||||
distanceToDestination = distance;
|
||||
|
||||
if (noneFound) {
|
||||
|
@ -407,10 +404,10 @@ public class Navigation {
|
|||
train.reservedSignalBlocks.clear();
|
||||
train.navigation.waitingForSignal = null;
|
||||
|
||||
if (this.destination == null && !simulate)
|
||||
if (this.destination == null)
|
||||
distanceStartedAt = distance;
|
||||
|
||||
if (this.destination == destination)
|
||||
if (this.destination == pathTo.destination)
|
||||
return 0;
|
||||
|
||||
if (!train.runtime.paused) {
|
||||
|
@ -435,12 +432,19 @@ public class Navigation {
|
|||
train.status.foundConductor();
|
||||
}
|
||||
|
||||
this.destination = destination;
|
||||
this.destination = pathTo.destination;
|
||||
return cost;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private DiscoveredPath findPathTo(GlobalStation destination, double maxCost) {
|
||||
public DiscoveredPath findPathTo(GlobalStation destination, double maxCost) {
|
||||
ArrayList<GlobalStation> destinations = new ArrayList<>();
|
||||
destinations.add(destination);
|
||||
return findPathTo(destinations, maxCost);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public DiscoveredPath findPathTo(ArrayList<GlobalStation> destinations, double maxCost) {
|
||||
TrackGraph graph = train.graph;
|
||||
if (graph == null)
|
||||
return null;
|
||||
|
@ -460,34 +464,36 @@ public class Navigation {
|
|||
: graph.getConnectionsFrom(initialPoint.node2)
|
||||
.get(initialPoint.node1);
|
||||
|
||||
search(Double.MAX_VALUE, maxCost, forward, (distance, cost, reachedVia, currentEntry, globalStation) -> {
|
||||
if (globalStation != destination)
|
||||
return false;
|
||||
search(Double.MAX_VALUE, maxCost, forward, destinations, (distance, cost, reachedVia, currentEntry, globalStation) -> {
|
||||
for (GlobalStation destination : destinations){
|
||||
if (globalStation == destination) {
|
||||
TrackEdge edge = currentEntry.getSecond();
|
||||
TrackNode node1 = currentEntry.getFirst()
|
||||
.getFirst();
|
||||
TrackNode node2 = currentEntry.getFirst()
|
||||
.getSecond();
|
||||
|
||||
TrackEdge edge = currentEntry.getSecond();
|
||||
TrackNode node1 = currentEntry.getFirst()
|
||||
.getFirst();
|
||||
TrackNode node2 = currentEntry.getFirst()
|
||||
.getSecond();
|
||||
List<Couple<TrackNode>> currentPath = new ArrayList<>();
|
||||
Pair<Boolean, Couple<TrackNode>> backTrack = reachedVia.get(edge);
|
||||
Couple<TrackNode> toReach = Couple.create(node1, node2);
|
||||
TrackEdge edgeReached = edge;
|
||||
while (backTrack != null) {
|
||||
if (edgeReached == initialEdge)
|
||||
break;
|
||||
if (backTrack.getFirst())
|
||||
currentPath.add(0, toReach);
|
||||
toReach = backTrack.getSecond();
|
||||
edgeReached = graph.getConnection(toReach);
|
||||
backTrack = reachedVia.get(edgeReached);
|
||||
}
|
||||
|
||||
List<Couple<TrackNode>> currentPath = new ArrayList<>();
|
||||
Pair<Boolean, Couple<TrackNode>> backTrack = reachedVia.get(edge);
|
||||
Couple<TrackNode> toReach = Couple.create(node1, node2);
|
||||
TrackEdge edgeReached = edge;
|
||||
while (backTrack != null) {
|
||||
if (edgeReached == initialEdge)
|
||||
break;
|
||||
if (backTrack.getFirst())
|
||||
currentPath.add(0, toReach);
|
||||
toReach = backTrack.getSecond();
|
||||
edgeReached = graph.getConnection(toReach);
|
||||
backTrack = reachedVia.get(edgeReached);
|
||||
double position = edge.getLength() - destination.getLocationOn(edge);
|
||||
double distanceToDestination = distance - position;
|
||||
results.set(forward, new DiscoveredPath((forward ? 1 : -1) * distanceToDestination, cost, currentPath, destination));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
double position = edge.getLength() - destination.getLocationOn(edge);
|
||||
double distanceToDestination = distance - position;
|
||||
results.set(forward, new DiscoveredPath((forward ? 1 : -1) * distanceToDestination, cost, currentPath));
|
||||
return true;
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -508,18 +514,6 @@ public class Navigation {
|
|||
return frontBetter ? front : back;
|
||||
}
|
||||
|
||||
public class DiscoveredPath {
|
||||
List<Couple<TrackNode>> path;
|
||||
double distance;
|
||||
double cost;
|
||||
|
||||
public DiscoveredPath(double distance, double cost, List<Couple<TrackNode>> path) {
|
||||
this.distance = distance;
|
||||
this.cost = cost;
|
||||
this.path = path;
|
||||
}
|
||||
}
|
||||
|
||||
public GlobalStation findNearestApproachable(boolean forward) {
|
||||
TrackGraph graph = train.graph;
|
||||
if (graph == null)
|
||||
|
@ -530,7 +524,7 @@ public class Navigation {
|
|||
double minDistance = .75f * (train.speed * train.speed) / (2 * acceleration);
|
||||
double maxDistance = Math.max(32, 1.5f * (train.speed * train.speed) / (2 * acceleration));
|
||||
|
||||
search(maxDistance, forward, (distance, cost, reachedVia, currentEntry, globalStation) -> {
|
||||
search(maxDistance, forward, null, (distance, cost, reachedVia, currentEntry, globalStation) -> {
|
||||
if (distance < minDistance)
|
||||
return false;
|
||||
|
||||
|
@ -548,11 +542,11 @@ public class Navigation {
|
|||
return result.getValue();
|
||||
}
|
||||
|
||||
public void search(double maxDistance, boolean forward, StationTest stationTest) {
|
||||
search(maxDistance, -1, forward, stationTest);
|
||||
public void search(double maxDistance, boolean forward, ArrayList<GlobalStation> destinations, StationTest stationTest) {
|
||||
search(maxDistance, -1, forward, destinations, stationTest);
|
||||
}
|
||||
|
||||
public void search(double maxDistance, double maxCost, boolean forward, StationTest stationTest) {
|
||||
public void search(double maxDistance, double maxCost, boolean forward, ArrayList<GlobalStation> destinations, StationTest stationTest) {
|
||||
TrackGraph graph = train.graph;
|
||||
if (graph == null)
|
||||
return;
|
||||
|
@ -614,10 +608,58 @@ public class Navigation {
|
|||
|
||||
double distanceToNode2 = forward ? initialEdge.getLength() - startingPoint.position : startingPoint.position;
|
||||
|
||||
frontier.add(new FrontierEntry(distanceToNode2, 0, initialNode1, initialNode2, initialEdge));
|
||||
int signalWeight = Mth.clamp(ticksWaitingForSignal * 2, Train.Penalties.RED_SIGNAL, 200);
|
||||
|
||||
Search: while (!frontier.isEmpty()) {
|
||||
// Apply penalties to initial edge
|
||||
int initialPenalty = 0;
|
||||
if (costRelevant)
|
||||
initialPenalty += penalties.getOrDefault(initialEdge, 0);
|
||||
|
||||
EdgeData initialSignalData = initialEdge.getEdgeData();
|
||||
if (initialSignalData.hasPoints()) {
|
||||
for (TrackEdgePoint point : initialSignalData.getPoints()) {
|
||||
if (point.getLocationOn(initialEdge) < initialEdge.getLength() - distanceToNode2)
|
||||
continue;
|
||||
if (costRelevant && distanceToNode2 + initialPenalty > maxCost)
|
||||
return;
|
||||
if (!point.canNavigateVia(initialNode2))
|
||||
return;
|
||||
if (point instanceof SignalBoundary signal) {
|
||||
if (signal.isForcedRed(initialNode2)) {
|
||||
initialPenalty += Train.Penalties.REDSTONE_RED_SIGNAL;
|
||||
continue;
|
||||
}
|
||||
UUID group = signal.getGroup(initialNode2);
|
||||
if (group == null)
|
||||
continue;
|
||||
SignalEdgeGroup signalEdgeGroup = Create.RAILWAYS.signalEdgeGroups.get(group);
|
||||
if (signalEdgeGroup == null)
|
||||
continue;
|
||||
if (signalEdgeGroup.isOccupiedUnless(signal)) {
|
||||
initialPenalty += signalWeight;
|
||||
signalWeight /= 2;
|
||||
}
|
||||
}
|
||||
if (point instanceof GlobalStation station) {
|
||||
Train presentTrain = station.getPresentTrain();
|
||||
boolean isOwnStation = presentTrain == train;
|
||||
if (presentTrain != null && !isOwnStation)
|
||||
initialPenalty += Train.Penalties.STATION_WITH_TRAIN;
|
||||
if (station.canApproachFrom(initialNode2) && stationTest.test(distanceToNode2, distanceToNode2 + initialPenalty, reachedVia,
|
||||
Pair.of(Couple.create(initialNode1, initialNode2), initialEdge), station))
|
||||
return;
|
||||
if (!isOwnStation)
|
||||
initialPenalty += Train.Penalties.STATION;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (costRelevant && distanceToNode2 + initialPenalty > maxCost)
|
||||
return;
|
||||
|
||||
frontier.add(new FrontierEntry(distanceToNode2, initialPenalty, initialNode1, initialNode2, initialEdge));
|
||||
|
||||
while (!frontier.isEmpty()) {
|
||||
FrontierEntry entry = frontier.poll();
|
||||
if (!visited.add(entry.edge))
|
||||
continue;
|
||||
|
@ -632,51 +674,19 @@ public class Navigation {
|
|||
TrackNode node1 = entry.node1;
|
||||
TrackNode node2 = entry.node2;
|
||||
|
||||
if (costRelevant)
|
||||
penalty += penalties.getOrDefault(edge, 0);
|
||||
|
||||
EdgeData signalData = edge.getEdgeData();
|
||||
if (signalData.hasPoints()) {
|
||||
for (TrackEdgePoint point : signalData.getPoints()) {
|
||||
if (node1 == initialNode1 && point.getLocationOn(edge) < edge.getLength() - distanceToNode2)
|
||||
continue;
|
||||
if (costRelevant && distance + penalty > maxCost)
|
||||
continue Search;
|
||||
if (!point.canNavigateVia(node2))
|
||||
continue Search;
|
||||
if (point instanceof SignalBoundary signal) {
|
||||
if (signal.isForcedRed(node2)) {
|
||||
penalty += Train.Penalties.REDSTONE_RED_SIGNAL;
|
||||
continue;
|
||||
if (entry.hasDestination) {
|
||||
EdgeData signalData = edge.getEdgeData();
|
||||
if (signalData.hasPoints()) {
|
||||
for (TrackEdgePoint point : signalData.getPoints()) {
|
||||
if (point instanceof GlobalStation station) {
|
||||
if (station.canApproachFrom(node2) && stationTest.test(distance, penalty, reachedVia,
|
||||
Pair.of(Couple.create(node1, node2), edge), station))
|
||||
return;
|
||||
}
|
||||
UUID group = signal.getGroup(node2);
|
||||
if (group == null)
|
||||
continue;
|
||||
SignalEdgeGroup signalEdgeGroup = Create.RAILWAYS.signalEdgeGroups.get(group);
|
||||
if (signalEdgeGroup == null)
|
||||
continue;
|
||||
if (signalEdgeGroup.isOccupiedUnless(signal)) {
|
||||
penalty += signalWeight;
|
||||
signalWeight /= 2;
|
||||
}
|
||||
}
|
||||
if (point instanceof GlobalStation station) {
|
||||
Train presentTrain = station.getPresentTrain();
|
||||
boolean isOwnStation = presentTrain == train;
|
||||
if (presentTrain != null && !isOwnStation)
|
||||
penalty += Train.Penalties.STATION_WITH_TRAIN;
|
||||
if (station.canApproachFrom(node2) && stationTest.test(distance, distance + penalty, reachedVia,
|
||||
Pair.of(Couple.create(node1, node2), edge), station))
|
||||
return;
|
||||
if (!isOwnStation)
|
||||
penalty += Train.Penalties.STATION;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (costRelevant && distance + penalty > maxCost)
|
||||
continue;
|
||||
|
||||
List<Entry<TrackNode, TrackEdge>> validTargets = new ArrayList<>();
|
||||
Map<TrackNode, TrackEdge> connectionsFrom = graph.getConnectionsFrom(node2);
|
||||
for (Entry<TrackNode, TrackEdge> connection : connectionsFrom.entrySet()) {
|
||||
|
@ -690,15 +700,101 @@ public class Navigation {
|
|||
if (validTargets.isEmpty())
|
||||
continue;
|
||||
|
||||
for (Entry<TrackNode, TrackEdge> target : validTargets) {
|
||||
Search: for (Entry<TrackNode, TrackEdge> target : validTargets) {
|
||||
if (!validTypes.contains(target.getValue().getTrackMaterial().trackType))
|
||||
continue;
|
||||
TrackNode newNode = target.getKey();
|
||||
TrackEdge newEdge = target.getValue();
|
||||
double newDistance = newEdge.getLength() + distance;
|
||||
int newPenalty = penalty;
|
||||
double edgeLength = newEdge.getLength();
|
||||
double newDistance = distance + edgeLength;
|
||||
|
||||
if (costRelevant)
|
||||
newPenalty += penalties.getOrDefault(newEdge, 0);
|
||||
|
||||
// Apply penalty to next connected edge
|
||||
boolean hasDestination = false;
|
||||
EdgeData signalData = newEdge.getEdgeData();
|
||||
if (signalData.hasPoints()) {
|
||||
for (TrackEdgePoint point : signalData.getPoints()) {
|
||||
if (node2 == initialNode1 && point.getLocationOn(newEdge) < edgeLength - distanceToNode2)
|
||||
continue;
|
||||
if (costRelevant && newDistance + newPenalty > maxCost)
|
||||
continue Search;
|
||||
if (!point.canNavigateVia(newNode))
|
||||
continue Search;
|
||||
if (point instanceof SignalBoundary signal) {
|
||||
if (signal.isForcedRed(newNode)) {
|
||||
newPenalty += Train.Penalties.REDSTONE_RED_SIGNAL;
|
||||
continue;
|
||||
}
|
||||
UUID group = signal.getGroup(newNode);
|
||||
if (group == null)
|
||||
continue;
|
||||
SignalEdgeGroup signalEdgeGroup = Create.RAILWAYS.signalEdgeGroups.get(group);
|
||||
if (signalEdgeGroup == null)
|
||||
continue;
|
||||
if (signalEdgeGroup.isOccupiedUnless(signal)) {
|
||||
newPenalty += signalWeight;
|
||||
signalWeight /= 2;
|
||||
}
|
||||
}
|
||||
if (point instanceof GlobalStation station) {
|
||||
Train presentTrain = station.getPresentTrain();
|
||||
boolean isOwnStation = presentTrain == train;
|
||||
if (presentTrain != null && !isOwnStation)
|
||||
newPenalty += Train.Penalties.STATION_WITH_TRAIN;
|
||||
if (station.canApproachFrom(newNode) && stationTest.test(newDistance, newDistance + newPenalty, reachedVia,
|
||||
Pair.of(Couple.create(node2, newNode), newEdge), station)) {
|
||||
hasDestination = true;
|
||||
continue;
|
||||
}
|
||||
if (!isOwnStation)
|
||||
newPenalty += Train.Penalties.STATION;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (costRelevant && newDistance + newPenalty > maxCost)
|
||||
continue;
|
||||
|
||||
double remainingDist = 0;
|
||||
// Calculate remaining distance estimator for next connected edge
|
||||
if (destinations != null && !destinations.isEmpty()) {
|
||||
remainingDist = Double.MAX_VALUE;
|
||||
Vec3 newNodePosition = newNode.getLocation().getLocation();
|
||||
for (GlobalStation destination : destinations) {
|
||||
TrackNodeLocation destinationNode = destination.edgeLocation.getFirst();
|
||||
double dMin = Math.abs(newNodePosition.x - destinationNode.getLocation().x);
|
||||
double dMid = Math.abs(newNodePosition.y - destinationNode.getLocation().y);
|
||||
double dMax = Math.abs(newNodePosition.z - destinationNode.getLocation().z);
|
||||
// Sort distance vector in ascending order
|
||||
double temp;
|
||||
if (dMin > dMid) {
|
||||
temp = dMid;
|
||||
dMid = dMin;
|
||||
dMin = temp;
|
||||
}
|
||||
if (dMin > dMax) {
|
||||
temp = dMax;
|
||||
dMax = dMin;
|
||||
dMin = temp;
|
||||
}
|
||||
if (dMid > dMax) {
|
||||
temp = dMax;
|
||||
dMax = dMid;
|
||||
dMid = temp;
|
||||
}
|
||||
// Octile distance from newNode to station node
|
||||
double currentRemaining = 0.317837245195782 * dMin + 0.414213562373095 * dMid + dMax + destination.position;
|
||||
if (node2.getLocation().equals(destinationNode))
|
||||
currentRemaining -= newEdge.getLength() * 2; // Correct the distance estimator for station edge
|
||||
remainingDist = Math.min(remainingDist, currentRemaining);
|
||||
}
|
||||
}
|
||||
|
||||
reachedVia.putIfAbsent(newEdge, Pair.of(validTargets.size() > 1, Couple.create(node1, node2)));
|
||||
frontier.add(new FrontierEntry(newDistance, newPenalty, node2, newNode, newEdge));
|
||||
frontier.add(new FrontierEntry(newDistance, newPenalty, remainingDist, hasDestination, node2, newNode, newEdge));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -707,6 +803,8 @@ public class Navigation {
|
|||
|
||||
double distance;
|
||||
int penalty;
|
||||
double remaining;
|
||||
boolean hasDestination;
|
||||
TrackNode node1;
|
||||
TrackNode node2;
|
||||
TrackEdge edge;
|
||||
|
@ -714,6 +812,17 @@ public class Navigation {
|
|||
public FrontierEntry(double distance, int penalty, TrackNode node1, TrackNode node2, TrackEdge edge) {
|
||||
this.distance = distance;
|
||||
this.penalty = penalty;
|
||||
this.remaining = 0;
|
||||
this.hasDestination = false;
|
||||
this.node1 = node1;
|
||||
this.node2 = node2;
|
||||
this.edge = edge;
|
||||
}
|
||||
public FrontierEntry(double distance, int penalty, double remaining, boolean hasDestination, TrackNode node1, TrackNode node2, TrackEdge edge) {
|
||||
this.distance = distance;
|
||||
this.penalty = penalty;
|
||||
this.remaining = remaining;
|
||||
this.hasDestination = hasDestination;
|
||||
this.node1 = node1;
|
||||
this.node2 = node2;
|
||||
this.edge = edge;
|
||||
|
@ -721,7 +830,7 @@ public class Navigation {
|
|||
|
||||
@Override
|
||||
public int compareTo(FrontierEntry o) {
|
||||
return Double.compare(distance + penalty, o.distance + o.penalty);
|
||||
return Double.compare(distance + penalty + remaining, o.distance + o.penalty + o.remaining);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,12 +24,13 @@ import com.simibubi.create.AllMovementBehaviours;
|
|||
import com.simibubi.create.AllPackets;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
|
||||
import com.simibubi.create.content.logistics.filter.FilterItem;
|
||||
import com.simibubi.create.content.logistics.filter.FilterItemStack;
|
||||
import com.simibubi.create.content.trains.bogey.AbstractBogeyBlockEntity;
|
||||
import com.simibubi.create.content.trains.entity.Carriage.DimensionalCarriageEntity;
|
||||
import com.simibubi.create.content.trains.entity.TravellingPoint.IEdgePointListener;
|
||||
import com.simibubi.create.content.trains.entity.TravellingPoint.SteerDirection;
|
||||
import com.simibubi.create.content.trains.graph.DimensionPalette;
|
||||
import com.simibubi.create.content.trains.graph.DiscoveredPath;
|
||||
import com.simibubi.create.content.trains.graph.EdgeData;
|
||||
import com.simibubi.create.content.trains.graph.EdgePointType;
|
||||
import com.simibubi.create.content.trains.graph.TrackEdge;
|
||||
|
@ -195,7 +196,7 @@ public class Train {
|
|||
if (observer == null)
|
||||
continue;
|
||||
|
||||
ItemStack filter = observer.getFilter();
|
||||
FilterItemStack filter = observer.getFilter();
|
||||
if (filter.isEmpty()) {
|
||||
observer.keepAlive(this);
|
||||
continue;
|
||||
|
@ -223,7 +224,7 @@ public class Train {
|
|||
ItemStack extractItem = inv.extractItem(slot, 1, true);
|
||||
if (extractItem.isEmpty())
|
||||
continue;
|
||||
shouldActivate |= FilterItem.test(level, extractItem, filter);
|
||||
shouldActivate |= filter.test(level, extractItem);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,7 +236,7 @@ public class Train {
|
|||
FluidStack drain = tank.drain(1, FluidAction.SIMULATE);
|
||||
if (drain.isEmpty())
|
||||
continue;
|
||||
shouldActivate |= FilterItem.test(level, drain, filter);
|
||||
shouldActivate |= filter.test(level, drain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -539,14 +540,12 @@ public class Train {
|
|||
if (!reservedSignalBlocks.isEmpty())
|
||||
return;
|
||||
|
||||
GlobalStation destination = navigation.destination;
|
||||
if (!navigatingManually && fullRefresh) {
|
||||
GlobalStation preferredDestination = runtime.startCurrentInstruction();
|
||||
if (preferredDestination != null)
|
||||
destination = preferredDestination;
|
||||
DiscoveredPath preferredPath = runtime.startCurrentInstruction();
|
||||
if (preferredPath != null){
|
||||
navigation.startNavigation(preferredPath);
|
||||
}
|
||||
}
|
||||
|
||||
navigation.startNavigation(destination, navigatingManually ? -1 : Double.MAX_VALUE, false);
|
||||
}
|
||||
|
||||
private void tickDerailedSlowdown() {
|
||||
|
@ -601,7 +600,7 @@ public class Train {
|
|||
Vec3 start = (speed < 0 ? trailingPoint : leadingPoint).getPosition(graph);
|
||||
Vec3 end = (speed < 0 ? leadingPoint : trailingPoint).getPosition(graph);
|
||||
|
||||
Pair<Train, Vec3> collision = findCollidingTrain(level, start, end, this, dimension);
|
||||
Pair<Train, Vec3> collision = findCollidingTrain(level, start, end, dimension);
|
||||
if (collision == null)
|
||||
return;
|
||||
|
||||
|
@ -617,13 +616,16 @@ public class Train {
|
|||
train.crash();
|
||||
}
|
||||
|
||||
public static Pair<Train, Vec3> findCollidingTrain(Level level, Vec3 start, Vec3 end, Train ignore,
|
||||
ResourceKey<Level> dimension) {
|
||||
for (Train train : Create.RAILWAYS.sided(level).trains.values()) {
|
||||
if (train == ignore)
|
||||
public Pair<Train, Vec3> findCollidingTrain(Level level, Vec3 start, Vec3 end, ResourceKey<Level> dimension) {
|
||||
Vec3 diff = end.subtract(start);
|
||||
double maxDistanceSqr = Math.pow(AllConfigs.server().trains.maxAssemblyLength.get(), 2.0);
|
||||
|
||||
Trains: for (Train train : Create.RAILWAYS.sided(level).trains.values()) {
|
||||
if (train == this)
|
||||
continue;
|
||||
if (train.graph != null && train.graph != graph)
|
||||
continue;
|
||||
|
||||
Vec3 diff = end.subtract(start);
|
||||
Vec3 lastPoint = null;
|
||||
|
||||
for (Carriage otherCarriage : train.carriages) {
|
||||
|
@ -643,6 +645,10 @@ public class Train {
|
|||
|
||||
Vec3 start2 = otherLeading.getPosition(train.graph);
|
||||
Vec3 end2 = otherTrailing.getPosition(train.graph);
|
||||
|
||||
if (Math.min(start2.distanceToSqr(start), end2.distanceToSqr(start)) > maxDistanceSqr)
|
||||
continue Trains;
|
||||
|
||||
if (betweenBits) {
|
||||
end2 = start2;
|
||||
start2 = lastPoint;
|
||||
|
@ -1040,7 +1046,7 @@ public class Train {
|
|||
}
|
||||
|
||||
public static class Penalties {
|
||||
static final int STATION = 200, STATION_WITH_TRAIN = 300;
|
||||
static final int STATION = 50, STATION_WITH_TRAIN = 300;
|
||||
static final int MANUAL_TRAIN = 200, IDLE_TRAIN = 700, ARRIVING_TRAIN = 50, WAITING_TRAIN = 50, ANY_TRAIN = 25,
|
||||
RED_SIGNAL = 25, REDSTONE_RED_SIGNAL = 400;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue