mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-03-04 06:44:40 +01:00
Merge branch 'mc1.20.1/feature-dev' into mc1.21.1/dev
# Conflicts: # src/main/java/com/simibubi/create/AllPackets.java # src/main/java/com/simibubi/create/content/contraptions/MountedStorage.java # src/main/java/com/simibubi/create/content/contraptions/MountedStorageManager.java # src/main/java/com/simibubi/create/content/logistics/box/PackageItem.java # src/main/java/com/simibubi/create/content/logistics/depot/DepotBlockEntity.java # src/main/java/com/simibubi/create/content/logistics/packagePort/frogport/FrogportVisual.java # src/main/java/com/simibubi/create/content/trains/schedule/destination/ScheduleInstruction.java # src/main/java/com/simibubi/create/foundation/render/AllInstanceTypes.java
This commit is contained in:
commit
b6ab33db9c
52 changed files with 1663 additions and 359 deletions
|
@ -1,4 +1,4 @@
|
|||
// 1.20.1 2025-01-08T12:42:08.2186069 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 2025-01-11T18:12:51.5905299 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
|
||||
|
@ -642,8 +642,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
|
||||
c1d7b1f496afa2f971078caf90f20255292d760b assets/create/lang/en_ud.json
|
||||
ce3c58e8401db1c42f3e1187bec1343fbf15009e assets/create/lang/en_us.json
|
||||
913f3794fb772a0736ae66dff722b3c468bcde79 assets/create/lang/en_ud.json
|
||||
1f6031cb19932ad54d645fbca1f2773385dd47ed 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
|
||||
|
|
|
@ -1692,6 +1692,12 @@
|
|||
"create.ponder.cart_assembler_rails.text_2": "pǝɹǝʍoԀ s,ʇı ןıʇun ǝɔɐןd uı pןǝɥ ǝq ןןıʍ sʇɹɐɔ ǝɥʇ 'ןıɐᴚ ɹǝןןoɹʇuoƆ ɹo pǝɹǝʍoԀ uo uǝɥM",
|
||||
"create.ponder.cart_assembler_rails.text_3": "ɹoɥɔuɐ ǝɥʇ sɐ pǝsn ǝq uɐɔ sʇɹɐɔǝuıW ɟo sǝdʎʇ ɹǝɥʇO",
|
||||
"create.ponder.cart_assembler_rails.text_4": "sǝıɹoʇuǝʌuı pǝɥɔɐʇʇɐ ʎuɐ ɯoɹɟ ןǝnɟ buıןןnd 'pǝɹǝʍod sǝʌןǝsɯǝɥʇ dǝǝʞ ןןıʍ sʇɹɐƆ ǝɔɐuɹnℲ",
|
||||
"create.ponder.chain_conveyor.header": "sɹoʎǝʌuoƆ uıɐɥƆ buısn ǝɔɹoɟ ןɐuoıʇɐʇoɹ buıʎɐןǝᴚ",
|
||||
"create.ponder.chain_conveyor.text_1": "ɯǝɥʇ ʇɔǝuuoɔ oʇ suıɐɥɔ ɥʇıʍ sɹoʎǝʌuoɔ oʍʇ ʞɔıןɔ-ʇɥbıᴚ",
|
||||
"create.ponder.chain_conveyor.text_2": "˙˙ʎןqıxǝןɟ ʎɹǝʌ ɹǝɥʇo ɥɔɐǝ oʇ ɹǝʍod ןɐuoıʇɐʇoɹ ʎɐןǝɹ ǝsǝɥ⟘",
|
||||
"create.ponder.chain_conveyor.text_3": "ɯǝɥʇ ʍoןǝq ɹo ǝʌoqɐ sʇɟɐɥs oʇ ʇɔǝuuoɔ puɐ˙˙",
|
||||
"create.ponder.chain_conveyor.text_4": "uıɐɥɔ ǝɥʇ uo buıןןǝʌɐɹʇ ʇɹɐʇs oʇ ɥɔuǝɹʍ ɐ buıpןoɥ ʞɔıןɔ-ʇɥbıᴚ",
|
||||
"create.ponder.chain_conveyor.text_5": "ʇı ʍoןןoɟ oʇ uıɐɥɔ ɐ spɹɐʍoʇ ǝɔɐɟ 'uoıʇɔunظ ɐ ʇⱯ",
|
||||
"create.ponder.chain_drive.header": "sǝʌıɹᗡ uıɐɥƆ ɥʇıʍ ǝɔɹoɟ ןɐuoıʇɐʇoɹ buıʎɐןǝᴚ",
|
||||
"create.ponder.chain_drive.text_1": "ʍoɹ ɐ uı ɹǝɥʇo ɥɔɐǝ oʇ uoıʇɐʇoɹ ʎɐןǝɹ sǝʌıɹᗡ uıɐɥƆ",
|
||||
"create.ponder.chain_drive.text_2": "uoıʇɔǝɹıp ǝɯɐs ǝɥʇ uı ǝʇɐʇoɹ ןןıʍ sıɥʇ ǝʞıן pǝʇɔǝuuoɔ sʇɟɐɥs ןןⱯ",
|
||||
|
@ -2124,6 +2130,46 @@
|
|||
"create.ponder.nixie_tube.text_1": "ɥʇbuǝɹʇs ןɐubıs ǝɥʇ ʎɐןdsıp ןןıʍ sǝqn⟘ ǝıxıN 'ǝuoʇspǝᴚ ʎq pǝɹǝʍod uǝɥM",
|
||||
"create.ponder.nixie_tube.text_2": "pǝʎɐןdsıp ǝq uɐɔ ʇxǝʇ ɯoʇsnɔ 'spɹɐoqdıןƆ uǝʇʇıɹʍ buıs∩",
|
||||
"create.ponder.nixie_tube.text_3": "ɹnoןoɔ ʎɐןdsıp ɹıǝɥʇ ǝbuɐɥɔ oʇ ǝʎᗡ ɥʇıʍ ʞɔıןƆ-ʇɥbıᴚ",
|
||||
"create.ponder.package_frogport.header": "sʇɹodboɹℲ ɥʇıʍ sǝbɐʞɔɐd buıʇɹodsuɐɹ⟘",
|
||||
"create.ponder.package_frogport.text_1": "ʎqɹɐǝu ʇɹodboɹℲ ǝɥʇ ǝɔɐןd puɐ ɹoʎǝʌuoƆ uıɐɥƆ ɐ ʞɔıןɔ-ʇɥbıᴚ",
|
||||
"create.ponder.package_frogport.text_10": "ʞɹoʍʇǝu uıɐɥɔ ǝɥʇ uo boɹɟ buıɥɔʇɐɯ ɐ oʇ ɥʇɐd ɹıǝɥʇ puıɟ sǝbɐʞɔɐԀ",
|
||||
"create.ponder.package_frogport.text_11": "ɹǝʇǝԀ",
|
||||
"create.ponder.package_frogport.text_12": "ɹǝʇǝԀ →",
|
||||
"create.ponder.package_frogport.text_13": "ɯǝɥʇ ʍoןǝq sǝıɹoʇuǝʌuı ɥʇıʍ ǝɔɐɟɹǝʇuı ʎןʇɔǝɹıp uɐɔ sʇɹodboɹℲ",
|
||||
"create.ponder.package_frogport.text_14": "ʎןʇɔǝɹıp pǝddıɥs puɐ pǝʞɔɐd ǝq uɐɔ sɯǝʇı 'sɹǝbɐʞɔɐd ɥʇıʍ sʞɹoʍ sıɥ⟘",
|
||||
"create.ponder.package_frogport.text_15": "ʇɹǝqןⱯ",
|
||||
"create.ponder.package_frogport.text_16": "ɹǝʇǝԀ",
|
||||
"create.ponder.package_frogport.text_17": ",ɹǝʇǝԀ, oʇ sǝbɐʞɔɐd sǝssǝɹppⱯ",
|
||||
"create.ponder.package_frogport.text_18": "ssǝɹppɐ ɹıǝɥʇ ʇɔǝןןoɔ oʇ pɹɐoqdıןɔ ɐ ɥʇıʍ sʇɹodboɹℲ ʞɔıןɔ-ʇɥbıᴚ",
|
||||
"create.ponder.package_frogport.text_19": "sI∩ ɹǝɥʇo uı sʇnduı ssǝɹppɐ ǝʇǝןdɯoɔ-oʇnɐ dןǝɥ uɐɔ sǝɯɐu pǝʇɔǝןןoɔ ɥʇıʍ spɹɐoqdıןƆ",
|
||||
"create.ponder.package_frogport.text_2": "I∩ ʎɹoʇuǝʌuı ɹıǝɥʇ uı ǝɯɐu ɐ uǝʌıb ǝq uɐɔ ʎǝɥ⟘",
|
||||
"create.ponder.package_frogport.text_3": "˙˙ǝɯɐu ʇuǝɹǝɟɟıp ɐ oʇ pǝssǝɹppɐ sı ǝbɐʞɔɐd ɐ ɟI",
|
||||
"create.ponder.package_frogport.text_4": "ʇɹǝqןⱯ",
|
||||
"create.ponder.package_frogport.text_5": "ɹǝʇǝԀ →",
|
||||
"create.ponder.package_frogport.text_6": "ɹoʎǝʌuoɔ ǝɥʇ uo ǝbɐʞɔɐd ǝɥʇ ǝɔɐןd ןןıʍ ʇɹodboɹℲ ǝɥʇ˙˙",
|
||||
"create.ponder.package_frogport.text_7": "uoıʇɐuıʇsǝp pıןɐʌ ou ǝʌɐɥ ʎǝɥʇ ɟı ǝɔɐןd uı uıds sǝbɐʞɔɐԀ",
|
||||
"create.ponder.package_frogport.text_8": "ʞɹoʍʇǝu uıɐɥɔ ǝɥʇ uo ǝɹǝɥʍʎuɐ pǝppɐ ǝq uɐɔ sʇɹodboɹℲ ǝɹoW",
|
||||
"create.ponder.package_frogport.text_9": "ɹǝʇǝԀ",
|
||||
"create.ponder.packager.header": "sǝbɐʞɔɐd buıddɐɹʍun puɐ buıʇɐǝɹƆ",
|
||||
"create.ponder.packager.text_1": "ʇǝbɹɐʇ pןnoɥs ʎǝɥʇ ʎɹoʇuǝʌuı ǝɥʇ oʇ ʇxǝu sɹǝbɐʞɔɐd ǝɔɐןԀ",
|
||||
"create.ponder.packager.text_2": "ǝbɐʞɔɐd ɐ oʇuı ʎɹoʇuǝʌuı ǝɥʇ ɯoɹɟ sɯǝʇı ʞɔɐd ןןıʍ ʇı 'ɹǝʍod ǝuoʇspǝɹ uǝʌı⅁",
|
||||
"create.ponder.packager.text_3": "ɯǝʇı ɹǝɥʇo ʎuɐ ǝʞıן pǝʇɹodsuɐɹʇ puɐ dn pǝʞɔıd ǝq uɐɔ ǝsǝɥ⟘",
|
||||
"create.ponder.packager.text_4": "ʎɹoʇuǝʌuı ǝɥʇ oʇuı sʇuǝʇuoɔ ǝɥʇ buıʞɔɐdun 'pǝʎoɹʇsǝp ǝq ןןıʍ pǝʇɹǝsuı sǝbɐʞɔɐԀ",
|
||||
"create.ponder.packager.text_5": "ןןnℲ",
|
||||
"create.ponder.packager.text_6": "ʞɔɐdun ʎןןnɟ ʇouuɐɔ ʎǝɥʇ sǝbɐʞɔɐd ʇdǝɔɔɐ ʇou ןןıʍ sɹǝbɐʞɔɐԀ",
|
||||
"create.ponder.packager_address.header": "ssǝɹppɐ uɐ ɥʇıʍ sǝbɐʞɔɐd buıʇnoᴚ",
|
||||
"create.ponder.packager_address.text_1": "ǝsnoɥǝɹɐM",
|
||||
"create.ponder.packager_address.text_10": "ʇןǝq ɐ oʇuo ʇɥbıɐɹʇs sǝbɐʞɔɐd dɐɹʍun uɐɔ sʍɐs ןɐɔıuɐɥɔǝɯ 'ssǝuʇɔɐdɯoɔ ɹoℲ",
|
||||
"create.ponder.packager_address.text_11": "sǝıʇıןıqɐdɐɔ buıʇnoɹ ǝbɐʞɔɐd ǝʌɐɥ sǝxoqʇsoԀ puɐ sʇɹodboɹℲ 'sɹǝʇןıɟ ǝsoɥʇ ɯoɹɟ ǝpısⱯ",
|
||||
"create.ponder.packager_address.text_12": "ɹnoıʌɐɥǝq ɹıǝɥʇ ʇnoqɐ ǝɹoɯ ʇno puıɟ oʇ ɯǝɥʇ ʇɔǝdsuI",
|
||||
"create.ponder.packager_address.text_2": "˙˙ɹǝbɐʞɔɐd ɐ uo pǝɔɐןd sı ubıs ɐ uǝɥM",
|
||||
"create.ponder.packager_address.text_3": "ǝsnoɥǝɹɐM →",
|
||||
"create.ponder.packager_address.text_4": "ssǝɹppɐ ɹıǝɥʇ sɐ ʇxǝʇ ɟo ǝuıן uǝʇʇıɹʍ ǝɥʇ ʎɹɹɐɔ ןןıʍ sǝbɐʞɔɐd pǝʇɐǝɹƆ",
|
||||
"create.ponder.packager_address.text_5": "ssǝɹppɐ ɹıǝɥʇ uo pǝsɐq sǝbɐʞɔɐd ǝʇnoɹ sɹǝʇןıɟ ǝbɐʞɔɐԀ",
|
||||
"create.ponder.packager_address.text_6": "ǝsnoɥǝɹɐM →",
|
||||
"create.ponder.packager_address.text_7": "ʎɹoʇɔɐℲ",
|
||||
"create.ponder.packager_address.text_8": "ʎɹoʇɔɐℲ →",
|
||||
"create.ponder.packager_address.text_9": "ʎɹoʇɔɐℲ",
|
||||
"create.ponder.piston_pole.header": "sǝןoԀ uoısuǝʇxƎ uoʇsıԀ",
|
||||
"create.ponder.piston_pole.text_1": "ǝʌoɯ ʇouuɐɔ uoʇsıԀ ןɐɔıuɐɥɔǝW ɐ 'sǝןoԀ pǝɥɔɐʇʇɐ ʇnoɥʇıM",
|
||||
"create.ponder.piston_pole.text_2": "ǝbuɐᴚ uoısuǝʇxƎ ǝɥʇ sǝuıɯɹǝʇǝp ʞɔɐq sʇı ʇɐ pǝppɐ ǝןod ɟo ɥʇbuǝꞀ ǝɥ⟘",
|
||||
|
@ -2596,6 +2642,10 @@
|
|||
"create.schedule.condition.unloaded.status": "pɐoןun ʞunɥɔ ɹoɟ buıʇıɐM",
|
||||
"create.schedule.condition_type": ":ɹǝʇɟɐ/ɟı ǝnuıʇuoƆ",
|
||||
"create.schedule.continued": "pǝɯnsǝɹ ǝןnpǝɥɔS",
|
||||
"create.schedule.instruction.address_filter_edit_box": "ssǝɹppⱯ sıɥʇ ɥʇıʍ sǝbɐʞɔɐԀ ǝʌǝıɹʇǝᴚ",
|
||||
"create.schedule.instruction.address_filter_edit_box_1": "pɹɐɔpןıʍ ʇxǝʇ ɐ sɐ * ǝs∩",
|
||||
"create.schedule.instruction.address_filter_edit_box_2": "ʇı ʇɔǝןןoɔ oʇ ǝɹǝɥʍʎuɐ ǝʇɐbıʌɐu ʎɐɯ uıɐɹ⟘",
|
||||
"create.schedule.instruction.address_filter_edit_box_3": "uɹnʇǝɹ ʇı ǝʞɐɯ oʇ uoıʇɔnɹʇsuı ɹǝɥʇouɐ ppⱯ",
|
||||
"create.schedule.instruction.destination": "uoıʇɐʇS oʇ ןǝʌɐɹ⟘",
|
||||
"create.schedule.instruction.destination.summary": ":doʇS ʇxǝN",
|
||||
"create.schedule.instruction.editor": "ɹoʇıpƎ uoıʇɔnɹʇsuI",
|
||||
|
@ -2606,6 +2656,14 @@
|
|||
"create.schedule.instruction.name_edit_box": "ǝןʇı⟘ ǝןnpǝɥɔS",
|
||||
"create.schedule.instruction.name_edit_box_1": "sʎɐןdsıp uo uʍoɥs ʇxǝʇ sʇɔǝɟɟⱯ",
|
||||
"create.schedule.instruction.name_edit_box_2": "ǝɯɐu s,uoıʇɐuıʇsǝp ʇxǝu oʇ sʇןnɐɟǝᗡ",
|
||||
"create.schedule.instruction.package_delivery": "ǝbɐʞɔɐԀ ɹǝʌıןǝᗡ",
|
||||
"create.schedule.instruction.package_delivery.summary": "obɹɐɔ uı ǝbɐʞɔɐd ʇsɹıɟ ɹǝʌıןǝᗡ",
|
||||
"create.schedule.instruction.package_delivery.summary_1": "ɥʇıʍ uoıʇɐʇs ǝɥʇ oʇ sǝʌıɹᗡ",
|
||||
"create.schedule.instruction.package_delivery.summary_2": "xoqʇsod ʇɔǝɹɹoɔ ǝɥʇ",
|
||||
"create.schedule.instruction.package_retrieval": "ǝbɐʞɔɐԀ ǝʌǝıɹʇǝᴚ",
|
||||
"create.schedule.instruction.package_retrieval.summary": ":oʇ pǝssǝɹppɐ ǝbɐʞɔɐd ɐ ɥɔʇǝℲ",
|
||||
"create.schedule.instruction.package_retrieval.summary_1": "ɥʇıʍ xoqʇsod ɐ oʇ sǝʌıɹᗡ",
|
||||
"create.schedule.instruction.package_retrieval.summary_2": "ǝbɐʞɔɐd pǝɹǝʌıןǝpun uɐ",
|
||||
"create.schedule.instruction.rename": "ǝןʇı⟘ ǝןnpǝɥɔS ǝʇɐpd∩",
|
||||
"create.schedule.instruction.rename.summary": ":ǝןʇı⟘ ʍǝN",
|
||||
"create.schedule.instruction.throttle": "pǝǝdS xɐW ʇıɯıꞀ",
|
||||
|
|
|
@ -1692,6 +1692,12 @@
|
|||
"create.ponder.cart_assembler_rails.text_2": "When on Powered or Controller Rail, the carts will be held in place until it's Powered",
|
||||
"create.ponder.cart_assembler_rails.text_3": "Other types of Minecarts can be used as the anchor",
|
||||
"create.ponder.cart_assembler_rails.text_4": "Furnace Carts will keep themselves powered, pulling fuel from any attached inventories",
|
||||
"create.ponder.chain_conveyor.header": "Relaying rotational force using Chain Conveyors",
|
||||
"create.ponder.chain_conveyor.text_1": "Right-click two conveyors with chains to connect them",
|
||||
"create.ponder.chain_conveyor.text_2": "These relay rotational power to each other very flexibly..",
|
||||
"create.ponder.chain_conveyor.text_3": "..and connect to shafts above or below them",
|
||||
"create.ponder.chain_conveyor.text_4": "Right-click holding a wrench to start travelling on the chain",
|
||||
"create.ponder.chain_conveyor.text_5": "At a junction, face towards a chain to follow it",
|
||||
"create.ponder.chain_drive.header": "Relaying rotational force with Chain Drives",
|
||||
"create.ponder.chain_drive.text_1": "Chain Drives relay rotation to each other in a row",
|
||||
"create.ponder.chain_drive.text_2": "All shafts connected like this will rotate in the same direction",
|
||||
|
@ -2124,6 +2130,46 @@
|
|||
"create.ponder.nixie_tube.text_1": "When powered by Redstone, Nixie Tubes will display the signal strength",
|
||||
"create.ponder.nixie_tube.text_2": "Using written Clipboards, custom text can be displayed",
|
||||
"create.ponder.nixie_tube.text_3": "Right-Click with Dye to change their display colour",
|
||||
"create.ponder.package_frogport.header": "Transporting packages with Frogports",
|
||||
"create.ponder.package_frogport.text_1": "Right-click a Chain Conveyor and place the Frogport nearby",
|
||||
"create.ponder.package_frogport.text_10": "Packages find their path to a matching frog on the chain network",
|
||||
"create.ponder.package_frogport.text_11": "Peter",
|
||||
"create.ponder.package_frogport.text_12": "→ Peter",
|
||||
"create.ponder.package_frogport.text_13": "Frogports can directly interface with inventories below them",
|
||||
"create.ponder.package_frogport.text_14": "This works with packagers, items can be packed and shipped directly",
|
||||
"create.ponder.package_frogport.text_15": "Albert",
|
||||
"create.ponder.package_frogport.text_16": "Peter",
|
||||
"create.ponder.package_frogport.text_17": "Addresses packages to 'Peter'",
|
||||
"create.ponder.package_frogport.text_18": "Right-click Frogports with a clipboard to collect their address",
|
||||
"create.ponder.package_frogport.text_19": "Clipboards with collected names can help auto-complete address inputs in other UIs",
|
||||
"create.ponder.package_frogport.text_2": "They can be given a name in their inventory UI",
|
||||
"create.ponder.package_frogport.text_3": "If a package is addressed to a different name..",
|
||||
"create.ponder.package_frogport.text_4": "Albert",
|
||||
"create.ponder.package_frogport.text_5": "→ Peter",
|
||||
"create.ponder.package_frogport.text_6": "..the Frogport will place the package on the conveyor",
|
||||
"create.ponder.package_frogport.text_7": "Packages spin in place if they have no valid destination",
|
||||
"create.ponder.package_frogport.text_8": "More Frogports can be added anywhere on the chain network",
|
||||
"create.ponder.package_frogport.text_9": "Peter",
|
||||
"create.ponder.packager.header": "Creating and unwrapping packages",
|
||||
"create.ponder.packager.text_1": "Place packagers next to the inventory they should target",
|
||||
"create.ponder.packager.text_2": "Given redstone power, it will pack items from the inventory into a package",
|
||||
"create.ponder.packager.text_3": "These can be picked up and transported like any other item",
|
||||
"create.ponder.packager.text_4": "Packages inserted will be destroyed, unpacking the contents into the inventory",
|
||||
"create.ponder.packager.text_5": "Full",
|
||||
"create.ponder.packager.text_6": "Packagers will not accept packages they cannot fully unpack",
|
||||
"create.ponder.packager_address.header": "Routing packages with an address",
|
||||
"create.ponder.packager_address.text_1": "Warehouse",
|
||||
"create.ponder.packager_address.text_10": "For compactness, mechanical saws can unwrap packages straight onto a belt",
|
||||
"create.ponder.packager_address.text_11": "Aside from those filters, Frogports and Postboxes have package routing capabilities",
|
||||
"create.ponder.packager_address.text_12": "Inspect them to find out more about their behaviour",
|
||||
"create.ponder.packager_address.text_2": "When a sign is placed on a packager..",
|
||||
"create.ponder.packager_address.text_3": "→ Warehouse",
|
||||
"create.ponder.packager_address.text_4": "Created packages will carry the written line of text as their address",
|
||||
"create.ponder.packager_address.text_5": "Package filters route packages based on their address",
|
||||
"create.ponder.packager_address.text_6": "→ Warehouse",
|
||||
"create.ponder.packager_address.text_7": "Factory",
|
||||
"create.ponder.packager_address.text_8": "→ Factory",
|
||||
"create.ponder.packager_address.text_9": "Factory",
|
||||
"create.ponder.piston_pole.header": "Piston Extension Poles",
|
||||
"create.ponder.piston_pole.text_1": "Without attached Poles, a Mechanical Piston cannot move",
|
||||
"create.ponder.piston_pole.text_2": "The Length of pole added at its back determines the Extension Range",
|
||||
|
@ -2596,6 +2642,10 @@
|
|||
"create.schedule.condition.unloaded.status": "Waiting for chunk unload",
|
||||
"create.schedule.condition_type": "Continue if/after:",
|
||||
"create.schedule.continued": "Schedule resumed",
|
||||
"create.schedule.instruction.address_filter_edit_box": "Retrieve Packages with this Address",
|
||||
"create.schedule.instruction.address_filter_edit_box_1": "Use * as a text wildcard",
|
||||
"create.schedule.instruction.address_filter_edit_box_2": "Train may navigate anywhere to collect it",
|
||||
"create.schedule.instruction.address_filter_edit_box_3": "Add another instruction to make it return",
|
||||
"create.schedule.instruction.destination": "Travel to Station",
|
||||
"create.schedule.instruction.destination.summary": "Next Stop:",
|
||||
"create.schedule.instruction.editor": "Instruction Editor",
|
||||
|
@ -2606,6 +2656,14 @@
|
|||
"create.schedule.instruction.name_edit_box": "Schedule Title",
|
||||
"create.schedule.instruction.name_edit_box_1": "Affects text shown on displays",
|
||||
"create.schedule.instruction.name_edit_box_2": "Defaults to next destination's name",
|
||||
"create.schedule.instruction.package_delivery": "Deliver Package",
|
||||
"create.schedule.instruction.package_delivery.summary": "Deliver first package in cargo",
|
||||
"create.schedule.instruction.package_delivery.summary_1": "Drives to the station with",
|
||||
"create.schedule.instruction.package_delivery.summary_2": "the correct postbox",
|
||||
"create.schedule.instruction.package_retrieval": "Retrieve Package",
|
||||
"create.schedule.instruction.package_retrieval.summary": "Fetch a package addressed to:",
|
||||
"create.schedule.instruction.package_retrieval.summary_1": "Drives to a postbox with",
|
||||
"create.schedule.instruction.package_retrieval.summary_2": "an undelivered package",
|
||||
"create.schedule.instruction.rename": "Update Schedule Title",
|
||||
"create.schedule.instruction.rename.summary": "New Title:",
|
||||
"create.schedule.instruction.throttle": "Limit Max Speed",
|
||||
|
|
|
@ -169,6 +169,7 @@ import com.simibubi.create.content.logistics.crate.CreativeCrateBlock;
|
|||
import com.simibubi.create.content.logistics.depot.DepotBlock;
|
||||
import com.simibubi.create.content.logistics.depot.EjectorBlock;
|
||||
import com.simibubi.create.content.logistics.depot.EjectorItem;
|
||||
import com.simibubi.create.content.logistics.depot.MountedDepotInteractionBehaviour;
|
||||
import com.simibubi.create.content.logistics.factoryBoard.FactoryPanelBlock;
|
||||
import com.simibubi.create.content.logistics.factoryBoard.FactoryPanelBlockItem;
|
||||
import com.simibubi.create.content.logistics.factoryBoard.FactoryPanelModel;
|
||||
|
@ -796,6 +797,7 @@ public class AllBlocks {
|
|||
.transform(axeOrPickaxe())
|
||||
.blockstate((c, p) -> p.simpleBlock(c.getEntry(), AssetLookup.partialBaseModel(c, p)))
|
||||
.onRegister(assignDataBehaviour(new ItemNameDisplaySource(), "combine_item_names"))
|
||||
.onRegister(interactionBehaviour(new MountedDepotInteractionBehaviour()))
|
||||
.item()
|
||||
.transform(customItemModel("_", "block"))
|
||||
.register();
|
||||
|
|
|
@ -27,6 +27,7 @@ import com.simibubi.create.content.contraptions.minecart.capability.MinecartCont
|
|||
import com.simibubi.create.content.contraptions.sync.ClientMotionPacket;
|
||||
import com.simibubi.create.content.contraptions.sync.ContraptionFluidPacket;
|
||||
import com.simibubi.create.content.contraptions.sync.ContraptionInteractionPacket;
|
||||
import com.simibubi.create.content.contraptions.sync.ContraptionItemPacket;
|
||||
import com.simibubi.create.content.contraptions.sync.ContraptionSeatMappingPacket;
|
||||
import com.simibubi.create.content.contraptions.sync.LimbSwingUpdatePacket;
|
||||
import com.simibubi.create.content.contraptions.wrench.RadialWrenchMenuSubmitPacket;
|
||||
|
@ -201,6 +202,7 @@ public enum AllPackets implements BasePacketPayload.PacketTypeProvider {
|
|||
MINECART_CONTROLLER(MinecartControllerUpdatePacket.class, MinecartControllerUpdatePacket.STREAM_CODEC),
|
||||
FLUID_SPLASH(FluidSplashPacket.class, FluidSplashPacket.STREAM_CODEC),
|
||||
CONTRAPTION_FLUID(ContraptionFluidPacket.class, ContraptionFluidPacket.STREAM_CODEC),
|
||||
CONTRAPTION_ITEM(ContraptionItemPacket.class, ContraptionItemPacket.STREAM_CODEC),
|
||||
GANTRY_UPDATE(GantryContraptionUpdatePacket.class, GantryContraptionUpdatePacket.STREAM_CODEC),
|
||||
BLOCK_HIGHLIGHT(HighlightPacket.class, HighlightPacket.STREAM_CODEC),
|
||||
TUNNEL_FLAP(TunnelFlapPacket.class, TunnelFlapPacket.STREAM_CODEC),
|
||||
|
|
|
@ -1467,6 +1467,10 @@ public abstract class Contraption {
|
|||
public IFluidHandler getSharedFluidTanks() {
|
||||
return storage.getFluids();
|
||||
}
|
||||
|
||||
public MountedStorageManager getStorageManager() {
|
||||
return storage;
|
||||
}
|
||||
|
||||
public RenderedBlocks getRenderedBlocks() {
|
||||
return new RenderedBlocks(pos -> {
|
||||
|
@ -1493,6 +1497,10 @@ public abstract class Contraption {
|
|||
public void handleContraptionFluidPacket(BlockPos localPos, FluidStack containedFluid) {
|
||||
storage.updateContainedFluid(localPos, containedFluid);
|
||||
}
|
||||
|
||||
public void handleContraptionItemPacket(BlockPos localPos, List<ItemStack> containedItems) {
|
||||
storage.updateContainedItem(localPos, containedItems);
|
||||
}
|
||||
|
||||
public static class ContraptionInvWrapper extends CombinedInvWrapper {
|
||||
protected final boolean isExternal;
|
||||
|
|
|
@ -1,20 +1,29 @@
|
|||
package com.simibubi.create.content.contraptions;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllBlockEntityTypes;
|
||||
import com.simibubi.create.AllTags.AllBlockTags;
|
||||
import com.simibubi.create.content.contraptions.sync.ContraptionItemPacket;
|
||||
import com.simibubi.create.content.equipment.toolbox.ToolboxInventory;
|
||||
import com.simibubi.create.content.kinetics.belt.transport.TransportedItemStack;
|
||||
import com.simibubi.create.content.kinetics.crafter.MechanicalCrafterBlockEntity;
|
||||
import com.simibubi.create.content.logistics.crate.BottomlessItemHandler;
|
||||
import com.simibubi.create.content.logistics.depot.DepotBehaviour;
|
||||
import com.simibubi.create.content.logistics.depot.DepotBlockEntity;
|
||||
import com.simibubi.create.content.logistics.vault.ItemVaultBlockEntity;
|
||||
import com.simibubi.create.content.processing.recipe.ProcessingInventory;
|
||||
|
||||
import net.createmod.catnip.platform.CatnipServices;
|
||||
import net.createmod.catnip.utility.NBTHelper;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.ContainerHelper;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BarrelBlockEntity;
|
||||
|
@ -22,6 +31,7 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
|||
import net.minecraft.world.level.block.entity.ChestBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||
import net.neoforged.neoforge.items.IItemHandler;
|
||||
import net.neoforged.neoforge.items.IItemHandlerModifiable;
|
||||
|
@ -35,7 +45,10 @@ public class MountedStorage {
|
|||
boolean noFuel;
|
||||
boolean valid;
|
||||
|
||||
private BlockEntity blockEntity;
|
||||
private int packetCooldown = 0;
|
||||
private boolean sendPacket = false;
|
||||
|
||||
BlockEntity blockEntity;
|
||||
|
||||
public static boolean canUseAsStorage(BlockEntity be) {
|
||||
if (be == null)
|
||||
|
@ -52,10 +65,12 @@ public class MountedStorage {
|
|||
return true;
|
||||
if (be instanceof ItemVaultBlockEntity)
|
||||
return true;
|
||||
if (be instanceof DepotBlockEntity)
|
||||
return true;
|
||||
|
||||
try {
|
||||
IItemHandler capability = be.getLevel().getCapability(Capabilities.ItemHandler.BLOCK, be.getBlockPos(), null);
|
||||
if (capability instanceof ItemStackHandler)
|
||||
net.neoforged.neoforge.items.IItemHandler capability = be.getLevel().getCapability(Capabilities.ItemHandler.BLOCK, be.getBlockPos(), null);
|
||||
if (capability instanceof net.neoforged.neoforge.items.ItemStackHandler)
|
||||
return !(capability instanceof ProcessingInventory);
|
||||
return canUseModdedInventory(be, capability);
|
||||
} catch (Exception e) {
|
||||
|
@ -64,7 +79,7 @@ public class MountedStorage {
|
|||
}
|
||||
|
||||
public static boolean canUseModdedInventory(BlockEntity be, IItemHandler handler) {
|
||||
if (!(handler instanceof IItemHandlerModifiable))
|
||||
if (!(handler instanceof net.neoforged.neoforge.items.IItemHandlerModifiable))
|
||||
return false;
|
||||
BlockState blockState = be.getBlockState();
|
||||
if (AllBlockTags.CONTRAPTION_INVENTORY_DENY.matches(blockState))
|
||||
|
@ -88,9 +103,17 @@ public class MountedStorage {
|
|||
Level level = blockEntity.getLevel();
|
||||
|
||||
valid = false;
|
||||
sendPacket = false;
|
||||
if (blockEntity == null)
|
||||
return;
|
||||
|
||||
if (blockEntity instanceof DepotBlockEntity depot) {
|
||||
handler = new SyncedMountedItemStackHandler(1);
|
||||
handler.setStackInSlot(0, depot.getHeldItem());
|
||||
valid = true;
|
||||
return;
|
||||
}
|
||||
|
||||
RegistryAccess registryAccess = level.registryAccess();
|
||||
|
||||
if (blockEntity instanceof ChestBlockEntity) {
|
||||
|
@ -107,7 +130,7 @@ public class MountedStorage {
|
|||
return;
|
||||
}
|
||||
|
||||
IItemHandler beHandler = level.getCapability(Capabilities.ItemHandler.BLOCK, blockEntity.getBlockPos(), null, blockEntity, null);
|
||||
net.neoforged.neoforge.items.IItemHandler beHandler = level.getCapability(Capabilities.ItemHandler.BLOCK, blockEntity.getBlockPos(), null, blockEntity, null);
|
||||
if (beHandler == null || beHandler == dummyHandler)
|
||||
return;
|
||||
|
||||
|
@ -144,6 +167,13 @@ public class MountedStorage {
|
|||
if (handler instanceof BottomlessItemHandler)
|
||||
return;
|
||||
|
||||
if (be instanceof DepotBlockEntity depot) {
|
||||
if (handler.getSlots() > 0)
|
||||
depot.getBehaviour(DepotBehaviour.TYPE)
|
||||
.setCenteredHeldItem(new TransportedItemStack(handler.getStackInSlot(0)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (be instanceof ChestBlockEntity) {
|
||||
RegistryAccess registryAccess = be.getLevel().registryAccess();
|
||||
|
||||
|
@ -162,14 +192,35 @@ public class MountedStorage {
|
|||
return;
|
||||
}
|
||||
|
||||
IItemHandler capability = be.getLevel().getCapability(Capabilities.ItemHandler.BLOCK, be.getBlockPos(), null);
|
||||
if (!(capability instanceof IItemHandlerModifiable inv))
|
||||
net.neoforged.neoforge.items.IItemHandler capability = be.getLevel().getCapability(Capabilities.ItemHandler.BLOCK, be.getBlockPos(), null);
|
||||
if (!(capability instanceof net.neoforged.neoforge.items.IItemHandlerModifiable inv))
|
||||
return;
|
||||
|
||||
for (int slot = 0; slot < Math.min(inv.getSlots(), handler.getSlots()); slot++)
|
||||
inv.setStackInSlot(slot, handler.getStackInSlot(slot));
|
||||
}
|
||||
|
||||
public void tick(Entity entity, BlockPos pos, boolean isRemote) {
|
||||
if (isRemote)
|
||||
return;
|
||||
if (packetCooldown > 0) {
|
||||
packetCooldown--;
|
||||
return;
|
||||
}
|
||||
if (sendPacket) {
|
||||
sendPacket = false;
|
||||
CatnipServices.NETWORK.sendToClientsTrackingEntity(entity, new ContraptionItemPacket(entity.getId(), pos, handler));
|
||||
packetCooldown = 8;
|
||||
}
|
||||
}
|
||||
|
||||
public void updateItems(List<ItemStack> containedItems) {
|
||||
for (int i = 0; i < Math.min(containedItems.size(), handler.getSlots()); i++)
|
||||
handler.setStackInSlot(i, containedItems.get(i));
|
||||
if (blockEntity instanceof DepotBlockEntity depot)
|
||||
depot.setHeldItem(handler.getStackInSlot(0));
|
||||
}
|
||||
|
||||
public IItemHandlerModifiable getItemHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
@ -183,6 +234,9 @@ public class MountedStorage {
|
|||
NBTHelper.putMarker(tag, "NoFuel");
|
||||
if (handler instanceof ToolboxInventory)
|
||||
NBTHelper.putMarker(tag, "Toolbox");
|
||||
if (needsSync())
|
||||
NBTHelper.putMarker(tag, "Synced");
|
||||
|
||||
if (!(handler instanceof BottomlessItemHandler))
|
||||
return tag;
|
||||
|
||||
|
@ -198,6 +252,8 @@ public class MountedStorage {
|
|||
return storage;
|
||||
if (nbt.contains("Toolbox"))
|
||||
storage.handler = new ToolboxInventory(null);
|
||||
if (nbt.contains("Synced"))
|
||||
storage.handler = storage.new SyncedMountedItemStackHandler(1);
|
||||
|
||||
storage.valid = true;
|
||||
storage.noFuel = nbt.contains("NoFuel");
|
||||
|
@ -220,4 +276,21 @@ public class MountedStorage {
|
|||
return !noFuel;
|
||||
}
|
||||
|
||||
public boolean needsSync() {
|
||||
return handler instanceof SyncedMountedItemStackHandler;
|
||||
}
|
||||
|
||||
public class SyncedMountedItemStackHandler extends ItemStackHandler {
|
||||
|
||||
public SyncedMountedItemStackHandler(int i) {
|
||||
super(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onContentsChanged(int slot) {
|
||||
sendPacket = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,12 +5,14 @@ import java.util.Arrays;
|
|||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.TreeMap;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.simibubi.create.content.contraptions.Contraption.ContraptionInvWrapper;
|
||||
import com.simibubi.create.content.fluids.tank.FluidTankBlockEntity;
|
||||
import com.simibubi.create.content.logistics.depot.DepotBlockEntity;
|
||||
import com.simibubi.create.foundation.fluid.CombinedTankWrapper;
|
||||
|
||||
import net.createmod.catnip.utility.NBTHelper;
|
||||
|
@ -54,7 +56,9 @@ public class MountedStorageManager {
|
|||
}
|
||||
|
||||
public void entityTick(AbstractContraptionEntity entity) {
|
||||
fluidStorage.forEach((pos, mfs) -> mfs.tick(entity, pos, entity.level().isClientSide));
|
||||
boolean isClientSide = entity.level().isClientSide;
|
||||
storage.forEach((pos, mfs) -> mfs.tick(entity, pos, isClientSide));
|
||||
fluidStorage.forEach((pos, mfs) -> mfs.tick(entity, pos, isClientSide));
|
||||
}
|
||||
|
||||
public void createHandlers() {
|
||||
|
@ -100,7 +104,7 @@ public class MountedStorageManager {
|
|||
.put(NbtUtils.readBlockPos(c, "Pos").orElseThrow(), MountedFluidStorage.deserialize(c.getCompound("Data"), registries)));
|
||||
|
||||
if (clientPacket && presentBlockEntities != null)
|
||||
bindTanks(presentBlockEntities);
|
||||
bindTanksAndDepots(presentBlockEntities);
|
||||
|
||||
List<IItemHandlerModifiable> handlers = new ArrayList<>();
|
||||
List<IItemHandlerModifiable> fuelHandlers = new ArrayList<>();
|
||||
|
@ -119,33 +123,41 @@ public class MountedStorageManager {
|
|||
.toList());
|
||||
}
|
||||
|
||||
public void bindTanks(Map<BlockPos, BlockEntity> presentBlockEntities) {
|
||||
fluidStorage.forEach((pos, mfs) -> {
|
||||
BlockEntity blockEntity = presentBlockEntities.get(pos);
|
||||
if (!(blockEntity instanceof FluidTankBlockEntity))
|
||||
public void bindTanksAndDepots(Map<BlockPos, BlockEntity> presentBlockEntities) {
|
||||
for (Entry<BlockPos, MountedStorage> entry : storage.entrySet()) {
|
||||
BlockEntity blockEntity = presentBlockEntities.get(entry.getKey());
|
||||
if (!(blockEntity instanceof DepotBlockEntity depot))
|
||||
return;
|
||||
depot.setHeldItem(entry.getValue().handler.getStackInSlot(0));
|
||||
entry.getValue().blockEntity = depot;
|
||||
}
|
||||
for (Entry<BlockPos, MountedFluidStorage> entry : fluidStorage.entrySet()) {
|
||||
BlockEntity blockEntity = presentBlockEntities.get(entry.getKey());
|
||||
if (!(blockEntity instanceof FluidTankBlockEntity tank))
|
||||
return;
|
||||
FluidTankBlockEntity tank = (FluidTankBlockEntity) blockEntity;
|
||||
IFluidTank tankInventory = tank.getTankInventory();
|
||||
MountedFluidStorage mfs = entry.getValue();
|
||||
if (tankInventory instanceof FluidTank)
|
||||
((FluidTank) tankInventory).setFluid(mfs.tank.getFluid());
|
||||
tank.getFluidLevel()
|
||||
.startWithValue(tank.getFillState());
|
||||
mfs.assignBlockEntity(tank);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void write(CompoundTag nbt, HolderLookup.Provider registries, boolean clientPacket) {
|
||||
ListTag storageNBT = new ListTag();
|
||||
if (!clientPacket)
|
||||
for (BlockPos pos : storage.keySet()) {
|
||||
CompoundTag c = new CompoundTag();
|
||||
MountedStorage mountedStorage = storage.get(pos);
|
||||
if (!mountedStorage.isValid())
|
||||
continue;
|
||||
c.put("Pos", NbtUtils.writeBlockPos(pos));
|
||||
c.put("Data", mountedStorage.serialize(registries));
|
||||
storageNBT.add(c);
|
||||
}
|
||||
for (BlockPos pos : storage.keySet()) {
|
||||
CompoundTag c = new CompoundTag();
|
||||
MountedStorage mountedStorage = storage.get(pos);
|
||||
if (!mountedStorage.isValid())
|
||||
continue;
|
||||
if (clientPacket && !mountedStorage.needsSync())
|
||||
continue;
|
||||
c.put("Pos", NbtUtils.writeBlockPos(pos));
|
||||
c.put("Data", mountedStorage.serialize(registries));
|
||||
storageNBT.add(c);
|
||||
}
|
||||
|
||||
ListTag fluidStorageNBT = new ListTag();
|
||||
for (BlockPos pos : fluidStorage.keySet()) {
|
||||
|
@ -197,6 +209,12 @@ public class MountedStorageManager {
|
|||
mountedFluidStorage.updateFluid(containedFluid);
|
||||
}
|
||||
|
||||
public void updateContainedItem(BlockPos localPos, List<ItemStack> containedItems) {
|
||||
MountedStorage mountedStorage = storage.get(localPos);
|
||||
if (mountedStorage != null)
|
||||
mountedStorage.updateItems(containedItems);
|
||||
}
|
||||
|
||||
public void attachExternal(IItemHandlerModifiable externalStorage) {
|
||||
inventory = new ContraptionInvWrapper(externalStorage, inventory);
|
||||
fuelInventory = new ContraptionInvWrapper(externalStorage, fuelInventory);
|
||||
|
@ -214,6 +232,14 @@ public class MountedStorageManager {
|
|||
return fluidInventory;
|
||||
}
|
||||
|
||||
public Map<BlockPos, MountedStorage> getMountedItemStorage() {
|
||||
return storage;
|
||||
}
|
||||
|
||||
public Map<BlockPos, MountedFluidStorage> getMountedFluidStorage() {
|
||||
return fluidStorage;
|
||||
}
|
||||
|
||||
public boolean handlePlayerStorageInteraction(Contraption contraption, Player player, BlockPos localPos) {
|
||||
if (player.level().isClientSide()) {
|
||||
BlockEntity localBE = contraption.presentBlockEntities.get(localPos);
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
package com.simibubi.create.content.contraptions.sync;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllPackets;
|
||||
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
|
||||
|
||||
import net.createmod.catnip.codecs.stream.CatnipStreamCodecBuilders;
|
||||
import net.createmod.catnip.net.base.ClientboundPacketPayload;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
import net.neoforged.neoforge.items.ItemStackHandler;
|
||||
|
||||
public record ContraptionItemPacket(int entityId, BlockPos localPos, List<ItemStack> containedItems) implements ClientboundPacketPayload {
|
||||
public static StreamCodec<RegistryFriendlyByteBuf, ContraptionItemPacket> STREAM_CODEC = StreamCodec.composite(
|
||||
ByteBufCodecs.INT, ContraptionItemPacket::entityId,
|
||||
BlockPos.STREAM_CODEC, ContraptionItemPacket::localPos,
|
||||
CatnipStreamCodecBuilders.list(ItemStack.STREAM_CODEC), ContraptionItemPacket::containedItems,
|
||||
ContraptionItemPacket::new
|
||||
);
|
||||
|
||||
public ContraptionItemPacket(int entityId, BlockPos localPos, ItemStackHandler handler) {
|
||||
this(entityId, localPos, convert(handler));
|
||||
}
|
||||
|
||||
private static List<ItemStack> convert(ItemStackHandler handler) {
|
||||
List<ItemStack> list = new ArrayList<>(handler.getSlots());
|
||||
for (int i = 0; i < handler.getSlots(); i++)
|
||||
list.add(handler.getStackInSlot(i));
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketTypeProvider getTypeProvider() {
|
||||
return AllPackets.CONTRAPTION_ITEM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(LocalPlayer player) {
|
||||
Entity entityByID = Minecraft.getInstance().level.getEntity(entityId);
|
||||
if (!(entityByID instanceof AbstractContraptionEntity contraptionEntity))
|
||||
return;
|
||||
contraptionEntity.getContraption().handleContraptionItemPacket(localPos, containedItems);
|
||||
}
|
||||
}
|
|
@ -6,9 +6,9 @@ import com.simibubi.create.content.kinetics.simpleRelays.ShaftBlock;
|
|||
|
||||
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
|
||||
import dev.engine_room.flywheel.lib.visual.AbstractBlockEntityVisual;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Direction.Axis;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public abstract class KineticBlockEntityVisual<T extends KineticBlockEntity> extends AbstractBlockEntityVisual<T> {
|
||||
|
@ -32,7 +32,7 @@ public abstract class KineticBlockEntityVisual<T extends KineticBlockEntity> ext
|
|||
protected final void updateRotation(RotatingInstance instance, Direction.Axis axis, float speed) {
|
||||
instance.setRotationAxis(axis)
|
||||
.setRotationOffset(getRotationOffset(axis))
|
||||
.setRotationalSpeed(speed)
|
||||
.setRotationalSpeed(speed * RotatingInstance.SPEED_MULTIPLIER)
|
||||
.setColor(blockEntity)
|
||||
.setChanged();
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ public abstract class KineticBlockEntityVisual<T extends KineticBlockEntity> ext
|
|||
|
||||
protected final RotatingInstance setup(RotatingInstance key, Direction.Axis axis, float speed) {
|
||||
key.setRotationAxis(axis)
|
||||
.setRotationalSpeed(speed)
|
||||
.setRotationalSpeed(speed * RotatingInstance.SPEED_MULTIPLIER)
|
||||
.setRotationOffset(getRotationOffset(axis))
|
||||
.setColor(blockEntity)
|
||||
.setPosition(getVisualPosition())
|
||||
|
@ -76,7 +76,7 @@ public abstract class KineticBlockEntityVisual<T extends KineticBlockEntity> ext
|
|||
return shaft(rotationAxis());
|
||||
}
|
||||
|
||||
public static float rotationOffset(BlockState state, Axis axis, BlockPos pos) {
|
||||
public static float rotationOffset(BlockState state, Axis axis, Vec3i pos) {
|
||||
if (shouldOffset(axis, pos)) {
|
||||
return 22.5f;
|
||||
} else {
|
||||
|
@ -84,7 +84,7 @@ public abstract class KineticBlockEntityVisual<T extends KineticBlockEntity> ext
|
|||
}
|
||||
}
|
||||
|
||||
public static boolean shouldOffset(Axis axis, BlockPos pos) {
|
||||
public static boolean shouldOffset(Axis axis, Vec3i pos) {
|
||||
// Sum the components of the other 2 axes.
|
||||
int x = (axis == Axis.X) ? 0 : pos.getX();
|
||||
int y = (axis == Axis.Y) ? 0 : pos.getY();
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
package com.simibubi.create.content.kinetics.base;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import dev.engine_room.flywheel.api.instance.InstanceHandle;
|
||||
import dev.engine_room.flywheel.api.instance.InstanceType;
|
||||
import dev.engine_room.flywheel.lib.instance.ColoredLitInstance;
|
||||
import net.createmod.catnip.utility.theme.Color;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
||||
public class KineticInstance extends ColoredLitInstance {
|
||||
public float x;
|
||||
public float y;
|
||||
public float z;
|
||||
public float rotationalSpeed;
|
||||
public float rotationOffset;
|
||||
|
||||
protected KineticInstance(InstanceType<? extends KineticInstance> type, InstanceHandle handle) {
|
||||
super(type, handle);
|
||||
}
|
||||
|
||||
public KineticInstance setPosition(BlockPos pos) {
|
||||
return setPosition(pos.getX(), pos.getY(), pos.getZ());
|
||||
}
|
||||
|
||||
public KineticInstance setPosition(Vector3f pos) {
|
||||
return setPosition(pos.x(), pos.y(), pos.z());
|
||||
}
|
||||
|
||||
public KineticInstance setPosition(float x, float y, float z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public KineticInstance nudge(float x, float y, float z) {
|
||||
this.x += x;
|
||||
this.y += y;
|
||||
this.z += z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public KineticInstance setColor(KineticBlockEntity blockEntity) {
|
||||
colorRgb(colorFromBE(blockEntity));
|
||||
return this;
|
||||
}
|
||||
|
||||
public KineticInstance setColor(Color c) {
|
||||
color(c.getRed(), c.getGreen(), c.getBlue());
|
||||
return this;
|
||||
}
|
||||
|
||||
public KineticInstance setRotationalSpeed(float rotationalSpeed) {
|
||||
this.rotationalSpeed = rotationalSpeed;
|
||||
return this;
|
||||
}
|
||||
|
||||
public KineticInstance setRotationOffset(float rotationOffset) {
|
||||
this.rotationOffset = rotationOffset;
|
||||
return this;
|
||||
}
|
||||
|
||||
public static int colorFromBE(KineticBlockEntity be) {
|
||||
if (be.hasNetwork())
|
||||
return Color.generateFromLong(be.network).getRGB();
|
||||
return 0xFFFFFF;
|
||||
}
|
||||
}
|
|
@ -1,20 +1,48 @@
|
|||
package com.simibubi.create.content.kinetics.base;
|
||||
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import dev.engine_room.flywheel.api.instance.InstanceHandle;
|
||||
import dev.engine_room.flywheel.api.instance.InstanceType;
|
||||
import dev.engine_room.flywheel.lib.instance.ColoredLitInstance;
|
||||
import net.createmod.catnip.utility.theme.Color;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Vec3i;
|
||||
|
||||
public class RotatingInstance extends ColoredLitInstance {
|
||||
public static final float SPEED_MULTIPLIER = 6;
|
||||
|
||||
public class RotatingInstance extends KineticInstance {
|
||||
public byte rotationAxisX;
|
||||
public byte rotationAxisY;
|
||||
public byte rotationAxisZ;
|
||||
public float x;
|
||||
public float y;
|
||||
public float z;
|
||||
/**
|
||||
* Speed in degrees per second
|
||||
*/
|
||||
public float rotationalSpeed;
|
||||
/**
|
||||
* Offset in degrees
|
||||
*/
|
||||
public float rotationOffset;
|
||||
|
||||
public RotatingInstance(InstanceType<? extends KineticInstance> type, InstanceHandle handle) {
|
||||
/**
|
||||
* Base rotation of the instance, applied before kinetic rotation
|
||||
*/
|
||||
public final Quaternionf rotation = new Quaternionf();
|
||||
|
||||
public RotatingInstance(InstanceType<? extends RotatingInstance> type, InstanceHandle handle) {
|
||||
super(type, handle);
|
||||
}
|
||||
|
||||
public static int colorFromBE(KineticBlockEntity be) {
|
||||
if (be.hasNetwork())
|
||||
return Color.generateFromLong(be.network).getRGB();
|
||||
return 0xFFFFFF;
|
||||
}
|
||||
|
||||
public RotatingInstance setRotationAxis(Direction.Axis axis) {
|
||||
Direction orientation = Direction.get(Direction.AxisDirection.POSITIVE, axis);
|
||||
return setRotationAxis(orientation.step());
|
||||
|
@ -31,4 +59,45 @@ public class RotatingInstance extends KineticInstance {
|
|||
return this;
|
||||
}
|
||||
|
||||
public RotatingInstance setPosition(Vec3i pos) {
|
||||
return setPosition(pos.getX(), pos.getY(), pos.getZ());
|
||||
}
|
||||
|
||||
public RotatingInstance setPosition(Vector3f pos) {
|
||||
return setPosition(pos.x(), pos.y(), pos.z());
|
||||
}
|
||||
|
||||
public RotatingInstance setPosition(float x, float y, float z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RotatingInstance nudge(float x, float y, float z) {
|
||||
this.x += x;
|
||||
this.y += y;
|
||||
this.z += z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RotatingInstance setColor(KineticBlockEntity blockEntity) {
|
||||
colorRgb(colorFromBE(blockEntity));
|
||||
return this;
|
||||
}
|
||||
|
||||
public RotatingInstance setColor(Color c) {
|
||||
color(c.getRed(), c.getGreen(), c.getBlue());
|
||||
return this;
|
||||
}
|
||||
|
||||
public RotatingInstance setRotationalSpeed(float rotationalSpeed) {
|
||||
this.rotationalSpeed = rotationalSpeed;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RotatingInstance setRotationOffset(float rotationOffset) {
|
||||
this.rotationOffset = rotationOffset;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ import org.joml.Quaternionf;
|
|||
|
||||
import com.simibubi.create.AllPartialModels;
|
||||
import com.simibubi.create.content.kinetics.base.KineticBlockEntityVisual;
|
||||
import com.simibubi.create.content.kinetics.base.KineticInstance;
|
||||
import com.simibubi.create.content.kinetics.base.RotatingInstance;
|
||||
import com.simibubi.create.content.processing.burner.ScrollInstance;
|
||||
import com.simibubi.create.foundation.render.AllInstanceTypes;
|
||||
|
@ -158,7 +157,7 @@ public class BeltVisual extends KineticBlockEntityVisual<BeltBlockEntity> {
|
|||
.rotation(q)
|
||||
.speed(0, speed * MAGIC_SCROLL_MULTIPLIER)
|
||||
.offset(0, bottom ? SCROLL_OFFSET_BOTTOM : SCROLL_OFFSET_OTHERWISE)
|
||||
.colorRgb(KineticInstance.colorFromBE(blockEntity))
|
||||
.colorRgb(RotatingInstance.colorFromBE(blockEntity))
|
||||
.setChanged();
|
||||
|
||||
return key;
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
package com.simibubi.create.content.kinetics.drill;
|
||||
|
||||
import org.joml.Quaternionf;
|
||||
|
||||
import com.simibubi.create.AllPartialModels;
|
||||
import com.simibubi.create.content.contraptions.actors.ActorInstance;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
||||
import com.simibubi.create.content.contraptions.render.ActorVisual;
|
||||
import com.simibubi.create.content.kinetics.base.RotatingInstance;
|
||||
import com.simibubi.create.foundation.render.AllInstanceTypes;
|
||||
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
|
||||
|
||||
|
@ -19,7 +17,7 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||
|
||||
public class DrillActorVisual extends ActorVisual {
|
||||
|
||||
ActorInstance drillHead;
|
||||
RotatingInstance drillHead;
|
||||
private final Direction facing;
|
||||
|
||||
public DrillActorVisual(VisualizationContext visualizationContext, VirtualRenderWorld contraption, MovementContext context) {
|
||||
|
@ -38,21 +36,22 @@ public class DrillActorVisual extends ActorVisual {
|
|||
else
|
||||
eulerY = facing.toYRot() + ((axis == Direction.Axis.X) ? 180 : 0);
|
||||
|
||||
drillHead = instancerProvider.instancer(AllInstanceTypes.ACTOR, Models.partial(AllPartialModels.DRILL_HEAD))
|
||||
drillHead = instancerProvider.instancer(AllInstanceTypes.ROTATING, Models.partial(AllPartialModels.DRILL_HEAD))
|
||||
.createInstance();
|
||||
|
||||
drillHead.rotation.rotationXYZ(eulerX * Mth.DEG_TO_RAD, eulerY * Mth.DEG_TO_RAD, 0);
|
||||
|
||||
drillHead.setPosition(context.localPos)
|
||||
.setBlockLight(localBlockLight())
|
||||
.setRotationOffset(0)
|
||||
.setRotationAxis(0, 0, 1)
|
||||
.setLocalRotation(new Quaternionf().rotationXYZ(eulerX * Mth.DEG_TO_RAD, eulerY * Mth.DEG_TO_RAD, 0))
|
||||
.setSpeed(getSpeed(facing))
|
||||
.setChanged();
|
||||
.setRotationOffset(0)
|
||||
.setRotationAxis(0, 0, 1)
|
||||
.setRotationalSpeed(getSpeed(facing))
|
||||
.light(localBlockLight(), 0)
|
||||
.setChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginFrame() {
|
||||
drillHead.setSpeed(getSpeed(facing))
|
||||
drillHead.setRotationalSpeed(getSpeed(facing))
|
||||
.setChanged();
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ public class GearboxVisual extends KineticBlockEntityVisual<GearboxBlockEntity>
|
|||
.createInstance();
|
||||
|
||||
key.setRotationAxis(axis)
|
||||
.setRotationalSpeed(getSpeed(direction))
|
||||
.setRotationalSpeed(getSpeed(direction) * RotatingInstance.SPEED_MULTIPLIER)
|
||||
.setRotationOffset(getRotationOffset(axis)).setColor(blockEntity)
|
||||
.setPosition(getVisualPosition())
|
||||
.light(blockLight, skyLight)
|
||||
|
|
|
@ -60,7 +60,7 @@ public class MixerVisual extends EncasedCogVisual implements SimpleDynamicVisual
|
|||
|
||||
mixerHead.setPosition(getVisualPosition())
|
||||
.nudge(0, -renderedHeadOffset, 0)
|
||||
.setRotationalSpeed(speed * 2)
|
||||
.setRotationalSpeed(speed * 2 * RotatingInstance.SPEED_MULTIPLIER)
|
||||
.setChanged();
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import com.simibubi.create.content.logistics.chute.ChuteBlock;
|
|||
import net.createmod.catnip.platform.CatnipServices;
|
||||
import net.createmod.catnip.utility.VecHelper;
|
||||
import net.createmod.catnip.utility.math.AngleHelper;
|
||||
import net.createmod.ponder.api.level.PonderLevel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
@ -164,6 +165,13 @@ public class PackageEntity extends LivingEntity implements IEntityWithComplexSpa
|
|||
verifyInitialEntity();
|
||||
originalEntity = null;
|
||||
}
|
||||
|
||||
if (level() instanceof PonderLevel) {
|
||||
setDeltaMovement(getDeltaMovement().add(0, -0.06, 0));
|
||||
if (position().y < 0.125)
|
||||
discard();
|
||||
}
|
||||
|
||||
insertionDelay = Math.min(insertionDelay + 1, 30);
|
||||
super.tick();
|
||||
|
||||
|
|
|
@ -188,7 +188,7 @@ public class PackageItem extends Item {
|
|||
super.appendHoverText(stack, tooltipContext, tooltipComponents, tooltipFlag);
|
||||
|
||||
if (stack.has(AllDataComponents.PACKAGE_ADDRESS))
|
||||
tooltipComponents.add(Components.literal("-> " + stack.get(AllDataComponents.PACKAGE_ADDRESS))
|
||||
tooltipComponents.add(Components.literal("\u2192 " + stack.get(AllDataComponents.PACKAGE_ADDRESS))
|
||||
.withStyle(ChatFormatting.GOLD));
|
||||
|
||||
/*
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.simibubi.create.content.logistics.depot;
|
|||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllBlockEntityTypes;
|
||||
import com.simibubi.create.content.kinetics.belt.transport.TransportedItemStack;
|
||||
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
|
||||
|
||||
|
@ -38,4 +39,12 @@ public class DepotBlockEntity extends SmartBlockEntity {
|
|||
public ItemStack getHeldItem() {
|
||||
return depotBehaviour.getHeldItemStack();
|
||||
}
|
||||
|
||||
public void setHeldItem(ItemStack item) {
|
||||
TransportedItemStack newStack = new TransportedItemStack(item);
|
||||
if (depotBehaviour.heldItem != null)
|
||||
newStack.angle = depotBehaviour.heldItem.angle;
|
||||
depotBehaviour.setHeldItem(newStack);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
package com.simibubi.create.content.logistics.depot;
|
||||
|
||||
import com.simibubi.create.AllSoundEvents;
|
||||
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.MountedStorage;
|
||||
import com.simibubi.create.content.contraptions.MountedStorageManager;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovingInteractionBehaviour;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import net.neoforged.neoforge.items.IItemHandlerModifiable;
|
||||
|
||||
public class MountedDepotInteractionBehaviour extends MovingInteractionBehaviour {
|
||||
|
||||
@Override
|
||||
public boolean handlePlayerInteraction(Player player, InteractionHand activeHand, BlockPos localPos,
|
||||
AbstractContraptionEntity contraptionEntity) {
|
||||
ItemStack itemInHand = player.getItemInHand(activeHand);
|
||||
if (activeHand == InteractionHand.OFF_HAND)
|
||||
return false;
|
||||
if (player.level().isClientSide)
|
||||
return true;
|
||||
|
||||
MountedStorageManager storageManager = contraptionEntity.getContraption()
|
||||
.getStorageManager();
|
||||
if (storageManager == null)
|
||||
return false;
|
||||
|
||||
MountedStorage mountedStorage = storageManager.getMountedItemStorage()
|
||||
.get(localPos);
|
||||
if (mountedStorage == null)
|
||||
return false;
|
||||
|
||||
IItemHandlerModifiable itemHandler = mountedStorage.getItemHandler();
|
||||
ItemStack itemOnDepot = itemHandler.getStackInSlot(0);
|
||||
|
||||
if (itemOnDepot.isEmpty() && itemInHand.isEmpty())
|
||||
return true;
|
||||
|
||||
itemHandler.setStackInSlot(0, itemInHand.copy());
|
||||
player.setItemInHand(activeHand, itemOnDepot.copy());
|
||||
AllSoundEvents.DEPOT_PLOP.playOnServer(player.level(),
|
||||
BlockPos.containing(contraptionEntity.toGlobalVector(Vec3.atCenterOf(localPos), 0)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -3,6 +3,7 @@ package com.simibubi.create.content.logistics.packagePort.frogport;
|
|||
import java.util.function.Consumer;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Matrix4f;
|
||||
|
||||
import com.simibubi.create.AllPartialModels;
|
||||
|
||||
|
@ -26,6 +27,12 @@ public class FrogportVisual extends AbstractBlockEntityVisual<FrogportBlockEntit
|
|||
private final TransformedInstance rig;
|
||||
private final TransformedInstance box;
|
||||
|
||||
private final Matrix4f basePose = new Matrix4f();
|
||||
private float lastYaw = Float.NaN;
|
||||
private float lastHeadPitch = Float.NaN;
|
||||
private float lastTonguePitch = Float.NaN;
|
||||
private float lastTongueLength = Float.NaN;
|
||||
|
||||
public FrogportVisual(VisualizationContext ctx, FrogportBlockEntity blockEntity, float partialTick) {
|
||||
super(ctx, blockEntity, partialTick);
|
||||
|
||||
|
@ -112,40 +119,55 @@ public class FrogportVisual extends AbstractBlockEntityVisual<FrogportBlockEntit
|
|||
float anticipation = blockEntity.anticipationProgress.getValue(partialTicks);
|
||||
headPitchModifier =
|
||||
anticipation > 0 ? (float) Math.max(0, 1 - Math.pow((anticipation * 1.25) * 2 - 1, 4)) : 0;
|
||||
rig.handle()
|
||||
.setVisible(false);
|
||||
box.handle()
|
||||
.setVisible(false);
|
||||
}
|
||||
|
||||
headPitch *= headPitchModifier;
|
||||
|
||||
headPitch = Math.max(headPitch, blockEntity.manualOpenAnimationProgress.getValue(partialTicks) * 60);
|
||||
tongueLength = Math.max(tongueLength, blockEntity.manualOpenAnimationProgress.getValue(partialTicks) * 0.25f);
|
||||
if (yaw != lastYaw) {
|
||||
body.setIdentityTransform()
|
||||
.translate(getVisualPosition())
|
||||
.center()
|
||||
.rotateYDegrees(yaw)
|
||||
.uncenter()
|
||||
.setChanged();
|
||||
|
||||
body.setIdentityTransform()
|
||||
.translate(getVisualPosition())
|
||||
.center()
|
||||
.rotateYDegrees(yaw)
|
||||
.uncenter()
|
||||
.setChanged();
|
||||
// Save the base pose to avoid recalculating it twice every frame
|
||||
basePose.set(body.pose)
|
||||
.translate(8 / 16f, 10 / 16f, 11 / 16f);
|
||||
|
||||
head.setIdentityTransform()
|
||||
.translate(getVisualPosition())
|
||||
.center()
|
||||
.rotateYDegrees(yaw)
|
||||
.uncenter()
|
||||
.translate(8 / 16f, 10 / 16f, 11 / 16f)
|
||||
.rotateXDegrees(headPitch)
|
||||
.translateBack(8 / 16f, 10 / 16f, 11 / 16f)
|
||||
.setChanged();
|
||||
// I'm not entirely sure that yaw ever changes
|
||||
lastYaw = yaw;
|
||||
|
||||
tongue.setIdentityTransform()
|
||||
.translate(getVisualPosition())
|
||||
.center()
|
||||
.rotateYDegrees(yaw)
|
||||
.uncenter()
|
||||
.translate(8 / 16f, 10 / 16f, 11 / 16f)
|
||||
.rotateXDegrees(tonguePitch)
|
||||
.scale(1f, 1f, tongueLength / (7 / 16f))
|
||||
.translateBack(8 / 16f, 10 / 16f, 11 / 16f)
|
||||
.setChanged();
|
||||
// Force the head and tongue to update
|
||||
lastTonguePitch = Float.NaN;
|
||||
lastHeadPitch = Float.NaN;
|
||||
}
|
||||
|
||||
if (headPitch != lastHeadPitch) {
|
||||
head.setTransform(basePose)
|
||||
.rotateXDegrees(headPitch)
|
||||
.translateBack(8 / 16f, 10 / 16f, 11 / 16f)
|
||||
.setChanged();
|
||||
|
||||
lastHeadPitch = headPitch;
|
||||
}
|
||||
|
||||
if (tonguePitch != lastTonguePitch || tongueLength != lastTongueLength) {
|
||||
tongue.setTransform(basePose)
|
||||
.rotateXDegrees(tonguePitch)
|
||||
.scale(1f, 1f, tongueLength / (7 / 16f))
|
||||
.translateBack(8 / 16f, 10 / 16f, 11 / 16f)
|
||||
.setChanged();
|
||||
|
||||
lastTonguePitch = tonguePitch;
|
||||
lastTongueLength = tongueLength;
|
||||
}
|
||||
}
|
||||
|
||||
private void renderPackage(Vec3 diff, float scale, float itemDistance) {
|
||||
|
|
|
@ -334,6 +334,11 @@ public class CarriageContraption extends Contraption {
|
|||
public void handleContraptionFluidPacket(BlockPos localPos, FluidStack containedFluid) {
|
||||
storage.updateContainedFluid(localPos, containedFluid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MountedStorageManager getStorageManager() {
|
||||
return storageProxy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tickStorage(AbstractContraptionEntity entity) {
|
||||
|
|
|
@ -44,6 +44,13 @@ public class TrainStatus {
|
|||
displayInformation("no_match", false, filter);
|
||||
navigation = true;
|
||||
}
|
||||
|
||||
public void failedPackageNoTarget(String address) {
|
||||
if (navigation)
|
||||
return;
|
||||
displayInformation("no_package_target", false, address);
|
||||
navigation = true;
|
||||
}
|
||||
|
||||
public void successfulNavigation() {
|
||||
if (!navigation)
|
||||
|
|
|
@ -17,7 +17,9 @@ import com.simibubi.create.content.trains.schedule.condition.StationUnloadedCond
|
|||
import com.simibubi.create.content.trains.schedule.condition.TimeOfDayCondition;
|
||||
import com.simibubi.create.content.trains.schedule.destination.ChangeThrottleInstruction;
|
||||
import com.simibubi.create.content.trains.schedule.destination.ChangeTitleInstruction;
|
||||
import com.simibubi.create.content.trains.schedule.destination.DeliverPackagesInstruction;
|
||||
import com.simibubi.create.content.trains.schedule.destination.DestinationInstruction;
|
||||
import com.simibubi.create.content.trains.schedule.destination.FetchPackagesInstruction;
|
||||
import com.simibubi.create.content.trains.schedule.destination.ScheduleInstruction;
|
||||
|
||||
import net.createmod.catnip.utility.NBTHelper;
|
||||
|
@ -49,6 +51,8 @@ public class Schedule {
|
|||
|
||||
static {
|
||||
registerInstruction("destination", DestinationInstruction::new);
|
||||
registerInstruction("package_delivery", DeliverPackagesInstruction::new);
|
||||
registerInstruction("package_retrieval", FetchPackagesInstruction::new);
|
||||
registerInstruction("rename", ChangeTitleInstruction::new);
|
||||
registerInstruction("throttle", ChangeThrottleInstruction::new);
|
||||
registerCondition("delay", ScheduledDelay::new);
|
||||
|
|
|
@ -4,7 +4,6 @@ import java.util.ArrayList;
|
|||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
import com.simibubi.create.AllDataComponents;
|
||||
import com.simibubi.create.AllItems;
|
||||
|
@ -12,10 +11,8 @@ import com.simibubi.create.content.trains.display.GlobalTrainDisplayData.TrainDe
|
|||
import com.simibubi.create.content.trains.entity.Carriage;
|
||||
import com.simibubi.create.content.trains.entity.Train;
|
||||
import com.simibubi.create.content.trains.graph.DiscoveredPath;
|
||||
import com.simibubi.create.content.trains.graph.EdgePointType;
|
||||
import com.simibubi.create.content.trains.schedule.condition.ScheduleWaitCondition;
|
||||
import com.simibubi.create.content.trains.schedule.condition.ScheduledDelay;
|
||||
import com.simibubi.create.content.trains.schedule.destination.ChangeThrottleInstruction;
|
||||
import com.simibubi.create.content.trains.schedule.destination.ChangeTitleInstruction;
|
||||
import com.simibubi.create.content.trains.schedule.destination.DestinationInstruction;
|
||||
import com.simibubi.create.content.trains.schedule.destination.ScheduleInstruction;
|
||||
|
@ -40,30 +37,35 @@ public class ScheduleRuntime {
|
|||
PRE_TRANSIT, IN_TRANSIT, POST_TRANSIT
|
||||
}
|
||||
|
||||
Train train;
|
||||
Schedule schedule;
|
||||
public Train train;
|
||||
public Schedule schedule;
|
||||
|
||||
public boolean isAutoSchedule;
|
||||
public boolean paused;
|
||||
public boolean completed;
|
||||
public int currentEntry;
|
||||
public State state;
|
||||
|
||||
public List<Integer> conditionProgress;
|
||||
public List<CompoundTag> conditionContext;
|
||||
public String currentTitle;
|
||||
|
||||
static final int INTERVAL = 40;
|
||||
int cooldown;
|
||||
List<Integer> conditionProgress;
|
||||
List<CompoundTag> conditionContext;
|
||||
String currentTitle;
|
||||
|
||||
int ticksInTransit;
|
||||
List<Integer> predictionTicks;
|
||||
public int ticksInTransit;
|
||||
public List<Integer> predictionTicks;
|
||||
|
||||
public boolean displayLinkUpdateRequested;
|
||||
|
||||
private static final int INTERVAL = 40;
|
||||
private int cooldown;
|
||||
|
||||
public ScheduleRuntime(Train train) {
|
||||
this.train = train;
|
||||
reset();
|
||||
}
|
||||
|
||||
public void startCooldown() {
|
||||
cooldown = INTERVAL;
|
||||
}
|
||||
|
||||
public void destinationReached() {
|
||||
if (state != State.IN_TRANSIT)
|
||||
|
@ -144,7 +146,15 @@ public class ScheduleRuntime {
|
|||
}
|
||||
|
||||
public void tickConditions(Level level) {
|
||||
List<List<ScheduleWaitCondition>> conditions = schedule.entries.get(currentEntry).conditions;
|
||||
ScheduleEntry entry = schedule.entries.get(currentEntry);
|
||||
List<List<ScheduleWaitCondition>> conditions = entry.conditions;
|
||||
|
||||
if (!entry.instruction.supportsConditions()) {
|
||||
state = State.PRE_TRANSIT;
|
||||
currentEntry++;
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < conditions.size(); i++) {
|
||||
List<ScheduleWaitCondition> list = conditions.get(i);
|
||||
int progress = conditionProgress.get(i);
|
||||
|
@ -175,55 +185,7 @@ public class ScheduleRuntime {
|
|||
public DiscoveredPath startCurrentInstruction() {
|
||||
ScheduleEntry entry = schedule.entries.get(currentEntry);
|
||||
ScheduleInstruction instruction = entry.instruction;
|
||||
|
||||
if (instruction instanceof DestinationInstruction destination) {
|
||||
String regex = destination.getFilterForRegex();
|
||||
boolean anyMatch = false;
|
||||
ArrayList<GlobalStation> validStations = new ArrayList<>();
|
||||
|
||||
if (!train.hasForwardConductor() && !train.hasBackwardConductor()) {
|
||||
train.status.missingConductor();
|
||||
cooldown = INTERVAL;
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
for (GlobalStation globalStation : train.graph.getPoints(EdgePointType.STATION)) {
|
||||
if (!globalStation.name.matches(regex))
|
||||
continue;
|
||||
anyMatch = true;
|
||||
validStations.add(globalStation);
|
||||
}
|
||||
} catch (PatternSyntaxException ignored) {}
|
||||
|
||||
DiscoveredPath best = train.navigation.findPathTo(validStations, Double.MAX_VALUE);
|
||||
if (best == null) {
|
||||
if (anyMatch)
|
||||
train.status.failedNavigation();
|
||||
else
|
||||
train.status.failedNavigationNoTarget(destination.getFilter());
|
||||
cooldown = INTERVAL;
|
||||
return null;
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
if (instruction instanceof ChangeTitleInstruction title) {
|
||||
currentTitle = title.getScheduleTitle();
|
||||
state = State.PRE_TRANSIT;
|
||||
currentEntry++;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (instruction instanceof ChangeThrottleInstruction throttle) {
|
||||
train.throttle = throttle.getThrottle();
|
||||
state = State.PRE_TRANSIT;
|
||||
currentEntry++;
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
return instruction.start(this);
|
||||
}
|
||||
|
||||
public void setSchedule(Schedule schedule, boolean auto) {
|
||||
|
|
|
@ -58,6 +58,7 @@ import net.minecraft.network.chat.Component;
|
|||
import net.minecraft.util.FormattedCharSequence;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
@ -989,8 +990,15 @@ public class ScheduleScreen extends AbstractSimiContainerScreen<ScheduleMenu> im
|
|||
|
||||
for (int i = 0; i < Math.max(1, rendered.slotsTargeted()); i++) {
|
||||
List<Component> secondLineTooltip = rendered.getSecondLineTooltip(i);
|
||||
if (secondLineTooltip == null || (hoveredSlot != menu.getSlot(36 + i) || !hoveredSlot.getItem()
|
||||
.isEmpty()))
|
||||
if (secondLineTooltip == null)
|
||||
continue;
|
||||
Slot slot = menu.getSlot(36 + i);
|
||||
if (slot == null || !slot.getItem()
|
||||
.isEmpty())
|
||||
continue;
|
||||
if (mouseX < leftPos + slot.x || mouseX > leftPos + slot.x + 18)
|
||||
continue;
|
||||
if (mouseY < topPos + slot.y || mouseY > topPos + slot.y + 18)
|
||||
continue;
|
||||
renderActionTooltip(graphics, secondLineTooltip, mouseX, mouseY);
|
||||
}
|
||||
|
|
|
@ -2,9 +2,14 @@ package com.simibubi.create.content.trains.schedule.destination;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.trains.graph.DiscoveredPath;
|
||||
import com.simibubi.create.content.trains.schedule.ScheduleRuntime;
|
||||
import com.simibubi.create.content.trains.schedule.ScheduleRuntime.State;
|
||||
import com.simibubi.create.foundation.gui.ModularGuiLineBuilder;
|
||||
import com.simibubi.create.foundation.utility.CreateLang;
|
||||
|
||||
|
@ -83,4 +88,13 @@ public class ChangeThrottleInstruction extends ScheduleInstruction {
|
|||
.withStyle(ChatFormatting.GRAY));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public DiscoveredPath start(ScheduleRuntime runtime) {
|
||||
runtime.train.throttle = getThrottle();
|
||||
runtime.state = State.PRE_TRANSIT;
|
||||
runtime.currentEntry++;
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,8 +2,13 @@ package com.simibubi.create.content.trains.schedule.destination;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.trains.graph.DiscoveredPath;
|
||||
import com.simibubi.create.content.trains.schedule.ScheduleRuntime;
|
||||
import com.simibubi.create.content.trains.schedule.ScheduleRuntime.State;
|
||||
import com.simibubi.create.foundation.utility.CreateLang;
|
||||
|
||||
import net.createmod.catnip.utility.Pair;
|
||||
|
@ -53,4 +58,13 @@ public class ChangeTitleInstruction extends TextScheduleInstruction {
|
|||
.withStyle(ChatFormatting.DARK_GRAY));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public DiscoveredPath start(ScheduleRuntime runtime) {
|
||||
runtime.currentTitle = getScheduleTitle();
|
||||
runtime.state = State.PRE_TRANSIT;
|
||||
runtime.currentEntry++;
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
package com.simibubi.create.content.trains.schedule.destination;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.logistics.box.PackageItem;
|
||||
import com.simibubi.create.content.trains.entity.Carriage;
|
||||
import com.simibubi.create.content.trains.entity.Train;
|
||||
import com.simibubi.create.content.trains.graph.DiscoveredPath;
|
||||
import com.simibubi.create.content.trains.graph.EdgePointType;
|
||||
import com.simibubi.create.content.trains.schedule.ScheduleRuntime;
|
||||
import com.simibubi.create.content.trains.schedule.ScheduleRuntime.State;
|
||||
import com.simibubi.create.content.trains.station.GlobalStation;
|
||||
import com.simibubi.create.content.trains.station.GlobalStation.GlobalPackagePort;
|
||||
import com.simibubi.create.foundation.utility.CreateLang;
|
||||
|
||||
import net.createmod.catnip.utility.Pair;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.DyeColor;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
import net.neoforged.neoforge.items.IItemHandlerModifiable;
|
||||
|
||||
public class DeliverPackagesInstruction extends ScheduleInstruction {
|
||||
|
||||
@Override
|
||||
public Pair<ItemStack, Component> getSummary() {
|
||||
return Pair.of(getSecondLineIcon(), CreateLang.translateDirect("schedule.instruction.package_delivery"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getSecondLineIcon() {
|
||||
return AllBlocks.PACKAGE_POSTBOXES.get(DyeColor.WHITE)
|
||||
.asStack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Component> getTitleAs(String type) {
|
||||
return ImmutableList.of(CreateLang.translate("schedule.instruction.package_delivery.summary")
|
||||
.style(ChatFormatting.GOLD)
|
||||
.component(),
|
||||
CreateLang.translateDirect("schedule.instruction.package_delivery.summary_1")
|
||||
.withStyle(ChatFormatting.GRAY),
|
||||
CreateLang.translateDirect("schedule.instruction.package_delivery.summary_2")
|
||||
.withStyle(ChatFormatting.GRAY));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getId() {
|
||||
return Create.asResource("package_delivery");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsConditions() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public DiscoveredPath start(ScheduleRuntime runtime) {
|
||||
boolean anyMatch = false;
|
||||
String firstPackage = null;
|
||||
ArrayList<GlobalStation> validStations = new ArrayList<>();
|
||||
Train train = runtime.train;
|
||||
|
||||
if (!train.hasForwardConductor() && !train.hasBackwardConductor()) {
|
||||
train.status.missingConductor();
|
||||
runtime.startCooldown();
|
||||
return null;
|
||||
}
|
||||
|
||||
for (Carriage carriage : train.carriages) {
|
||||
IItemHandlerModifiable carriageInventory = carriage.storage.getItems();
|
||||
if (carriageInventory == null)
|
||||
continue;
|
||||
|
||||
// Export to station
|
||||
for (int slot = 0; slot < carriageInventory.getSlots(); slot++) {
|
||||
ItemStack stack = carriageInventory.getStackInSlot(slot);
|
||||
if (!PackageItem.isPackage(stack))
|
||||
continue;
|
||||
if (firstPackage == null)
|
||||
firstPackage = PackageItem.getAddress(stack);
|
||||
for (GlobalStation globalStation : train.graph.getPoints(EdgePointType.STATION)) {
|
||||
for (Entry<BlockPos, GlobalPackagePort> port : globalStation.connectedPorts.entrySet()) {
|
||||
if (!PackageItem.matchAddress(stack, port.getValue().address))
|
||||
continue;
|
||||
anyMatch = true;
|
||||
validStations.add(globalStation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (validStations.isEmpty()) {
|
||||
if (firstPackage != null) {
|
||||
train.status.failedPackageNoTarget(firstPackage);
|
||||
runtime.startCooldown();
|
||||
} else {
|
||||
runtime.state = State.PRE_TRANSIT;
|
||||
runtime.currentEntry++;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
DiscoveredPath best = train.navigation.findPathTo(validStations, Double.MAX_VALUE);
|
||||
if (best == null) {
|
||||
if (anyMatch)
|
||||
train.status.failedNavigation();
|
||||
runtime.startCooldown();
|
||||
return null;
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,12 +1,21 @@
|
|||
package com.simibubi.create.content.trains.schedule.destination;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.trains.entity.Train;
|
||||
import com.simibubi.create.content.trains.graph.DiscoveredPath;
|
||||
import com.simibubi.create.content.trains.graph.EdgePointType;
|
||||
import com.simibubi.create.content.trains.schedule.ScheduleRuntime;
|
||||
import com.simibubi.create.content.trains.station.GlobalStation;
|
||||
import com.simibubi.create.foundation.utility.CreateLang;
|
||||
|
||||
import net.createmod.catnip.utility.Pair;
|
||||
|
@ -69,4 +78,40 @@ public class DestinationInstruction extends TextScheduleInstruction {
|
|||
box.setFilter(s -> StringUtils.countMatches(s, '*') <= 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public DiscoveredPath start(ScheduleRuntime runtime) {
|
||||
String regex = getFilterForRegex();
|
||||
boolean anyMatch = false;
|
||||
ArrayList<GlobalStation> validStations = new ArrayList<>();
|
||||
Train train = runtime.train;
|
||||
|
||||
if (!train.hasForwardConductor() && !train.hasBackwardConductor()) {
|
||||
train.status.missingConductor();
|
||||
runtime.startCooldown();
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
for (GlobalStation globalStation : train.graph.getPoints(EdgePointType.STATION)) {
|
||||
if (!globalStation.name.matches(regex))
|
||||
continue;
|
||||
anyMatch = true;
|
||||
validStations.add(globalStation);
|
||||
}
|
||||
} catch (PatternSyntaxException ignored) {}
|
||||
|
||||
DiscoveredPath best = train.navigation.findPathTo(validStations, Double.MAX_VALUE);
|
||||
if (best == null) {
|
||||
if (anyMatch)
|
||||
train.status.failedNavigation();
|
||||
else
|
||||
train.status.failedNavigationNoTarget(getFilter());
|
||||
runtime.startCooldown();
|
||||
return null;
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
package com.simibubi.create.content.trains.schedule.destination;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.logistics.box.PackageItem;
|
||||
import com.simibubi.create.content.logistics.box.PackageStyles;
|
||||
import com.simibubi.create.content.logistics.packagePort.postbox.PostboxBlockEntity;
|
||||
import com.simibubi.create.content.trains.entity.Carriage;
|
||||
import com.simibubi.create.content.trains.entity.CarriageContraptionEntity;
|
||||
import com.simibubi.create.content.trains.entity.Train;
|
||||
import com.simibubi.create.content.trains.graph.DiscoveredPath;
|
||||
import com.simibubi.create.content.trains.graph.EdgePointType;
|
||||
import com.simibubi.create.content.trains.schedule.ScheduleRuntime;
|
||||
import com.simibubi.create.content.trains.schedule.ScheduleRuntime.State;
|
||||
import com.simibubi.create.content.trains.station.GlobalStation;
|
||||
import com.simibubi.create.content.trains.station.GlobalStation.GlobalPackagePort;
|
||||
import com.simibubi.create.foundation.utility.CreateLang;
|
||||
|
||||
import net.createmod.catnip.utility.Pair;
|
||||
import net.createmod.catnip.utility.lang.Components;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.gui.components.EditBox;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
import net.neoforged.neoforge.items.IItemHandlerModifiable;
|
||||
|
||||
public class FetchPackagesInstruction extends TextScheduleInstruction {
|
||||
|
||||
@Override
|
||||
public Pair<ItemStack, Component> getSummary() {
|
||||
return Pair.of(getSecondLineIcon(), CreateLang.translateDirect("schedule.instruction.package_retrieval"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Component> getTitleAs(String type) {
|
||||
return ImmutableList.of(CreateLang.translate("schedule.instruction.package_retrieval.summary")
|
||||
.style(ChatFormatting.GOLD)
|
||||
.component(), CreateLang.translateDirect("generic.in_quotes", Components.literal(getLabelText())),
|
||||
CreateLang.translateDirect("schedule.instruction.package_retrieval.summary_1")
|
||||
.withStyle(ChatFormatting.GRAY),
|
||||
CreateLang.translateDirect("schedule.instruction.package_retrieval.summary_2")
|
||||
.withStyle(ChatFormatting.GRAY));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getSecondLineIcon() {
|
||||
return PackageStyles.getDefaultBox();
|
||||
}
|
||||
|
||||
public String getFilter() {
|
||||
return getLabelText();
|
||||
}
|
||||
|
||||
public String getFilterForRegex() {
|
||||
String filter = getFilter();
|
||||
if (filter.isBlank())
|
||||
return filter;
|
||||
return "\\Q" + filter.replace("*", "\\E.*\\Q") + "\\E";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Component> getSecondLineTooltip(int slot) {
|
||||
return ImmutableList.of(CreateLang.translateDirect("schedule.instruction.address_filter_edit_box"),
|
||||
CreateLang.translateDirect("schedule.instruction.address_filter_edit_box_1")
|
||||
.withStyle(ChatFormatting.GRAY),
|
||||
CreateLang.translateDirect("schedule.instruction.address_filter_edit_box_2")
|
||||
.withStyle(ChatFormatting.DARK_GRAY),
|
||||
CreateLang.translateDirect("schedule.instruction.address_filter_edit_box_3")
|
||||
.withStyle(ChatFormatting.DARK_GRAY));
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
protected void modifyEditBox(EditBox box) {
|
||||
box.setFilter(s -> StringUtils.countMatches(s, '*') <= 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getId() {
|
||||
return Create.asResource("package_retrieval");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsConditions() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DiscoveredPath start(ScheduleRuntime runtime) {
|
||||
String regex = getFilterForRegex();
|
||||
boolean anyMatch = false;
|
||||
ArrayList<GlobalStation> validStations = new ArrayList<>();
|
||||
Train train = runtime.train;
|
||||
|
||||
if (!train.hasForwardConductor() && !train.hasBackwardConductor()) {
|
||||
train.status.missingConductor();
|
||||
runtime.startCooldown();
|
||||
return null;
|
||||
}
|
||||
|
||||
Level level = null;
|
||||
for (Carriage carriage : train.carriages) {
|
||||
if (level == null) {
|
||||
CarriageContraptionEntity entity = carriage.anyAvailableEntity();
|
||||
if (entity != null && entity.level() instanceof ServerLevel sl)
|
||||
level = sl;
|
||||
}
|
||||
}
|
||||
|
||||
for (GlobalStation globalStation : train.graph.getPoints(EdgePointType.STATION)) {
|
||||
for (Entry<BlockPos, GlobalPackagePort> entry : globalStation.connectedPorts.entrySet()) {
|
||||
GlobalPackagePort port = entry.getValue();
|
||||
BlockPos pos = entry.getKey();
|
||||
|
||||
IItemHandlerModifiable postboxInventory = port.offlineBuffer;
|
||||
if (level != null && level.isLoaded(pos)
|
||||
&& level.getBlockEntity(pos) instanceof PostboxBlockEntity ppbe) {
|
||||
postboxInventory = ppbe.inventory;
|
||||
}
|
||||
|
||||
for (int slot = 0; slot < postboxInventory.getSlots(); slot++) {
|
||||
ItemStack stack = postboxInventory.getStackInSlot(slot);
|
||||
if (!PackageItem.isPackage(stack))
|
||||
continue;
|
||||
if (PackageItem.matchAddress(stack, port.address))
|
||||
continue;
|
||||
try {
|
||||
if (!PackageItem.getAddress(stack)
|
||||
.matches(regex))
|
||||
continue;
|
||||
anyMatch = true;
|
||||
validStations.add(globalStation);
|
||||
} catch (PatternSyntaxException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (validStations.isEmpty()) {
|
||||
runtime.startCooldown();
|
||||
runtime.state = State.PRE_TRANSIT;
|
||||
runtime.currentEntry++;
|
||||
return null;
|
||||
}
|
||||
|
||||
DiscoveredPath best = train.navigation.findPathTo(validStations, Double.MAX_VALUE);
|
||||
if (best == null) {
|
||||
if (anyMatch)
|
||||
train.status.failedNavigation();
|
||||
runtime.startCooldown();
|
||||
return null;
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
}
|
|
@ -3,8 +3,11 @@ package com.simibubi.create.content.trains.schedule.destination;
|
|||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.trains.graph.DiscoveredPath;
|
||||
import com.simibubi.create.content.trains.schedule.Schedule;
|
||||
import com.simibubi.create.content.trains.schedule.ScheduleDataEntry;
|
||||
|
||||
import com.simibubi.create.content.trains.schedule.ScheduleRuntime;
|
||||
import com.simibubi.create.infrastructure.codec.CreateStreamCodecs;
|
||||
|
||||
import net.createmod.catnip.utility.Pair;
|
||||
|
@ -14,6 +17,8 @@ import net.minecraft.network.RegistryFriendlyByteBuf;
|
|||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class ScheduleInstruction extends ScheduleDataEntry {
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, ScheduleInstruction> STREAM_CODEC = CreateStreamCodecs.ofLegacyNbtWithRegistries(
|
||||
ScheduleInstruction::write, ScheduleInstruction::fromTag
|
||||
|
@ -21,6 +26,9 @@ public abstract class ScheduleInstruction extends ScheduleDataEntry {
|
|||
|
||||
public abstract boolean supportsConditions();
|
||||
|
||||
@Nullable
|
||||
public abstract DiscoveredPath start(ScheduleRuntime runtime);
|
||||
|
||||
public final CompoundTag write(HolderLookup.Provider registries) {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
CompoundTag dataCopy = data.copy();
|
||||
|
|
|
@ -187,6 +187,37 @@ public class GlobalStation extends SingleBlockEntityEdgePoint {
|
|||
if (carriageInventory == null)
|
||||
continue;
|
||||
|
||||
// Import from station
|
||||
for (Entry<BlockPos, GlobalPackagePort> entry : connectedPorts.entrySet()) {
|
||||
GlobalPackagePort port = entry.getValue();
|
||||
BlockPos pos = entry.getKey();
|
||||
PostboxBlockEntity box = null;
|
||||
|
||||
IItemHandlerModifiable postboxInventory = port.offlineBuffer;
|
||||
if (level != null && level.isLoaded(pos)
|
||||
&& level.getBlockEntity(pos) instanceof PostboxBlockEntity ppbe) {
|
||||
postboxInventory = ppbe.inventory;
|
||||
box = ppbe;
|
||||
}
|
||||
|
||||
for (int slot = 0; slot < postboxInventory.getSlots(); slot++) {
|
||||
ItemStack stack = postboxInventory.getStackInSlot(slot);
|
||||
if (!PackageItem.isPackage(stack))
|
||||
continue;
|
||||
if (PackageItem.matchAddress(stack, port.address))
|
||||
continue;
|
||||
|
||||
ItemStack result = ItemHandlerHelper.insertItemStacked(carriageInventory, stack, false);
|
||||
if (!result.isEmpty())
|
||||
continue;
|
||||
|
||||
postboxInventory.setStackInSlot(slot, ItemStack.EMPTY);
|
||||
Create.RAILWAYS.markTracksDirty();
|
||||
if (box != null)
|
||||
box.spawnParticles();
|
||||
}
|
||||
}
|
||||
|
||||
// Export to station
|
||||
for (int slot = 0; slot < carriageInventory.getSlots(); slot++) {
|
||||
ItemStack stack = carriageInventory.getStackInSlot(slot);
|
||||
|
@ -221,37 +252,6 @@ public class GlobalStation extends SingleBlockEntityEdgePoint {
|
|||
}
|
||||
}
|
||||
|
||||
// Import from station
|
||||
for (Entry<BlockPos, GlobalPackagePort> entry : connectedPorts.entrySet()) {
|
||||
GlobalPackagePort port = entry.getValue();
|
||||
BlockPos pos = entry.getKey();
|
||||
PostboxBlockEntity box = null;
|
||||
|
||||
IItemHandlerModifiable postboxInventory = port.offlineBuffer;
|
||||
if (level != null && level.isLoaded(pos)
|
||||
&& level.getBlockEntity(pos) instanceof PostboxBlockEntity ppbe) {
|
||||
postboxInventory = ppbe.inventory;
|
||||
box = ppbe;
|
||||
}
|
||||
|
||||
for (int slot = 0; slot < postboxInventory.getSlots(); slot++) {
|
||||
ItemStack stack = postboxInventory.getStackInSlot(slot);
|
||||
if (!PackageItem.isPackage(stack))
|
||||
continue;
|
||||
if (PackageItem.matchAddress(stack, port.address))
|
||||
continue;
|
||||
|
||||
ItemStack result = ItemHandlerHelper.insertItemStacked(carriageInventory, stack, false);
|
||||
if (!result.isEmpty())
|
||||
continue;
|
||||
|
||||
postboxInventory.setStackInSlot(slot, ItemStack.EMPTY);
|
||||
Create.RAILWAYS.markTracksDirty();
|
||||
if (box != null)
|
||||
box.spawnParticles();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.simibubi.create.foundation.blockEntity;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
@ -19,6 +18,7 @@ import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour
|
|||
import com.simibubi.create.foundation.utility.IInteractionChecker;
|
||||
import com.simibubi.create.api.schematic.nbt.IPartialSafeNBT;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Reference2ObjectArrayMap;
|
||||
import net.createmod.ponder.api.VirtualBlockEntity;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
|
@ -32,7 +32,7 @@ import net.neoforged.neoforge.common.NeoForge;
|
|||
public abstract class SmartBlockEntity extends CachedRenderBBBlockEntity
|
||||
implements IPartialSafeNBT, IInteractionChecker, ISpecialBlockEntityItemRequirement, VirtualBlockEntity {
|
||||
|
||||
private final Map<BehaviourType<?>, BlockEntityBehaviour> behaviours = new HashMap<>();
|
||||
private final Map<BehaviourType<?>, BlockEntityBehaviour> behaviours = new Reference2ObjectArrayMap<>();
|
||||
private boolean initialized = false;
|
||||
private boolean firstNbtRead = true;
|
||||
protected int lazyTickRate;
|
||||
|
|
|
@ -7,7 +7,6 @@ import net.neoforged.api.distmarker.OnlyIn;
|
|||
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import com.simibubi.create.content.contraptions.actors.ActorInstance;
|
||||
import com.simibubi.create.content.kinetics.base.RotatingInstance;
|
||||
import com.simibubi.create.content.processing.burner.ScrollInstance;
|
||||
|
||||
|
@ -27,6 +26,7 @@ public class AllInstanceTypes {
|
|||
.vector("color", FloatRepr.NORMALIZED_UNSIGNED_BYTE, 4)
|
||||
.vector("light", IntegerRepr.SHORT, 2)
|
||||
.vector("overlay", IntegerRepr.SHORT, 2)
|
||||
.vector("rotation", FloatRepr.FLOAT, 4)
|
||||
.vector("pos", FloatRepr.FLOAT, 3)
|
||||
.scalar("speed", FloatRepr.FLOAT)
|
||||
.scalar("offset", FloatRepr.FLOAT)
|
||||
|
@ -39,14 +39,15 @@ public class AllInstanceTypes {
|
|||
MemoryUtil.memPutByte(ptr + 3, instance.alpha);
|
||||
ExtraMemoryOps.put2x16(ptr + 4, instance.light);
|
||||
ExtraMemoryOps.put2x16(ptr + 8, instance.overlay);
|
||||
MemoryUtil.memPutFloat(ptr + 12, instance.x);
|
||||
MemoryUtil.memPutFloat(ptr + 16, instance.y);
|
||||
MemoryUtil.memPutFloat(ptr + 20, instance.z);
|
||||
MemoryUtil.memPutFloat(ptr + 24, instance.rotationalSpeed);
|
||||
MemoryUtil.memPutFloat(ptr + 28, instance.rotationOffset);
|
||||
MemoryUtil.memPutByte(ptr + 32, instance.rotationAxisX);
|
||||
MemoryUtil.memPutByte(ptr + 33, instance.rotationAxisY);
|
||||
MemoryUtil.memPutByte(ptr + 34, instance.rotationAxisZ);
|
||||
ExtraMemoryOps.putQuaternionf(ptr + 12, instance.rotation);
|
||||
MemoryUtil.memPutFloat(ptr + 28, instance.x);
|
||||
MemoryUtil.memPutFloat(ptr + 32, instance.y);
|
||||
MemoryUtil.memPutFloat(ptr + 36, instance.z);
|
||||
MemoryUtil.memPutFloat(ptr + 40, instance.rotationalSpeed);
|
||||
MemoryUtil.memPutFloat(ptr + 44, instance.rotationOffset);
|
||||
MemoryUtil.memPutByte(ptr + 48, instance.rotationAxisX);
|
||||
MemoryUtil.memPutByte(ptr + 49, instance.rotationAxisY);
|
||||
MemoryUtil.memPutByte(ptr + 50, instance.rotationAxisZ);
|
||||
})
|
||||
.build();
|
||||
|
||||
|
@ -86,36 +87,6 @@ public class AllInstanceTypes {
|
|||
})
|
||||
.build();
|
||||
|
||||
public static final InstanceType<ActorInstance> ACTOR = SimpleInstanceType.builder(ActorInstance::new)
|
||||
.cullShader(asResource("instance/cull/actor.glsl"))
|
||||
.vertexShader(asResource("instance/actor.vert"))
|
||||
.layout(LayoutBuilder.create()
|
||||
.vector("pos", FloatRepr.FLOAT, 3)
|
||||
.vector("light", IntegerRepr.SHORT, 2)
|
||||
.scalar("offset", FloatRepr.FLOAT)
|
||||
.vector("axis", FloatRepr.NORMALIZED_BYTE, 3)
|
||||
.vector("rotation", FloatRepr.FLOAT, 4)
|
||||
.vector("rotationCenter", FloatRepr.NORMALIZED_BYTE, 3)
|
||||
.scalar("speed", FloatRepr.FLOAT)
|
||||
.build())
|
||||
.writer((ptr, instance) -> {
|
||||
MemoryUtil.memPutFloat(ptr, instance.x);
|
||||
MemoryUtil.memPutFloat(ptr + 4, instance.y);
|
||||
MemoryUtil.memPutFloat(ptr + 8, instance.z);
|
||||
MemoryUtil.memPutShort(ptr + 12, instance.blockLight);
|
||||
MemoryUtil.memPutShort(ptr + 14, instance.skyLight);
|
||||
MemoryUtil.memPutFloat(ptr + 16, instance.rotationOffset);
|
||||
MemoryUtil.memPutByte(ptr + 20, instance.rotationAxisX);
|
||||
MemoryUtil.memPutByte(ptr + 21, instance.rotationAxisY);
|
||||
MemoryUtil.memPutByte(ptr + 22, instance.rotationAxisZ);
|
||||
ExtraMemoryOps.putQuaternionf(ptr + 24, instance.rotation);
|
||||
MemoryUtil.memPutByte(ptr + 40, instance.rotationCenterX);
|
||||
MemoryUtil.memPutByte(ptr + 41, instance.rotationCenterY);
|
||||
MemoryUtil.memPutByte(ptr + 42, instance.rotationCenterZ);
|
||||
MemoryUtil.memPutFloat(ptr + 44, instance.speed);
|
||||
})
|
||||
.build();
|
||||
|
||||
public static void init() {
|
||||
// noop
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ import com.simibubi.create.infrastructure.ponder.scenes.DisplayScenes;
|
|||
import com.simibubi.create.infrastructure.ponder.scenes.EjectorScenes;
|
||||
import com.simibubi.create.infrastructure.ponder.scenes.ElevatorScenes;
|
||||
import com.simibubi.create.infrastructure.ponder.scenes.FanScenes;
|
||||
import com.simibubi.create.infrastructure.ponder.scenes.FrogAndConveyorScenes;
|
||||
import com.simibubi.create.infrastructure.ponder.scenes.FunnelScenes;
|
||||
import com.simibubi.create.infrastructure.ponder.scenes.GantryScenes;
|
||||
import com.simibubi.create.infrastructure.ponder.scenes.ItemVaultScenes;
|
||||
|
@ -42,6 +41,8 @@ import com.simibubi.create.infrastructure.ponder.scenes.fluid.HosePulleyScenes;
|
|||
import com.simibubi.create.infrastructure.ponder.scenes.fluid.PipeScenes;
|
||||
import com.simibubi.create.infrastructure.ponder.scenes.fluid.PumpScenes;
|
||||
import com.simibubi.create.infrastructure.ponder.scenes.fluid.SpoutScenes;
|
||||
import com.simibubi.create.infrastructure.ponder.scenes.highLogistics.FrogAndConveyorScenes;
|
||||
import com.simibubi.create.infrastructure.ponder.scenes.highLogistics.PackagerScenes;
|
||||
import com.simibubi.create.infrastructure.ponder.scenes.trains.TrackObserverScenes;
|
||||
import com.simibubi.create.infrastructure.ponder.scenes.trains.TrackScenes;
|
||||
import com.simibubi.create.infrastructure.ponder.scenes.trains.TrainScenes;
|
||||
|
@ -351,10 +352,13 @@ public class AllCreatePonderScenes {
|
|||
|
||||
// Hilo
|
||||
HELPER.forComponents(AllBlocks.CHAIN_CONVEYOR)
|
||||
.addStoryBoard("chain_conveyor", FrogAndConveyorScenes::conveyor);
|
||||
.addStoryBoard("high_logistics/chain_conveyor", FrogAndConveyorScenes::conveyor);
|
||||
HELPER.forComponents(AllBlocks.PACKAGE_FROGPORT)
|
||||
.addStoryBoard("package_frogport", FrogAndConveyorScenes::frogPort);
|
||||
|
||||
.addStoryBoard("high_logistics/package_frogport", FrogAndConveyorScenes::frogPort);
|
||||
HELPER.forComponents(AllBlocks.PACKAGER)
|
||||
.addStoryBoard("high_logistics/packager", PackagerScenes::packager)
|
||||
.addStoryBoard("high_logistics/packager_address", PackagerScenes::packagerAddress);
|
||||
|
||||
// Trains
|
||||
HELPER.forComponents(TrackMaterial.allBlocks()
|
||||
.stream()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package com.simibubi.create.infrastructure.ponder.scenes;
|
||||
package com.simibubi.create.infrastructure.ponder.scenes.highLogistics;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.function.Supplier;
|
||||
|
@ -564,10 +564,19 @@ public class FrogAndConveyorScenes {
|
|||
scene.world()
|
||||
.multiplyKineticSpeed(util.select()
|
||||
.fromTo(9, 0, 1, 5, 1, 0), 1 / 32f);
|
||||
scene.idle(5);
|
||||
|
||||
scene.overlay()
|
||||
.showText(75)
|
||||
.showText(60)
|
||||
.attachKeyFrame()
|
||||
.text("If a package is addressed to a different name..")
|
||||
.pointAt(util.vector()
|
||||
.topOf(5, 0, 3))
|
||||
.placeNearTarget();
|
||||
|
||||
scene.idle(70);
|
||||
|
||||
scene.overlay()
|
||||
.showText(40)
|
||||
.colored(PonderPalette.BLUE)
|
||||
.text("Albert")
|
||||
.pointAt(util.vector()
|
||||
|
@ -575,24 +584,15 @@ public class FrogAndConveyorScenes {
|
|||
.placeNearTarget();
|
||||
scene.idle(5);
|
||||
scene.overlay()
|
||||
.showText(70)
|
||||
.showText(40)
|
||||
.colored(PonderPalette.OUTPUT)
|
||||
.text("Peter")
|
||||
.text("\u2192 Peter")
|
||||
.pointAt(util.vector()
|
||||
.centerOf(util.grid()
|
||||
.at(5, 2, 0)))
|
||||
.placeNearTarget();
|
||||
scene.idle(30);
|
||||
|
||||
scene.overlay()
|
||||
.showText(80)
|
||||
.attachKeyFrame()
|
||||
.text("If a package is addressed to a different name..")
|
||||
.pointAt(util.vector()
|
||||
.topOf(5, 0, 3))
|
||||
.placeNearTarget();
|
||||
|
||||
scene.idle(60);
|
||||
scene.idle(50);
|
||||
|
||||
scene.world()
|
||||
.multiplyKineticSpeed(util.select()
|
||||
|
@ -712,7 +712,7 @@ public class FrogAndConveyorScenes {
|
|||
scene.overlay()
|
||||
.showText(55)
|
||||
.colored(PonderPalette.OUTPUT)
|
||||
.text("Peter")
|
||||
.text("\u2192 Peter")
|
||||
.pointAt(util.vector()
|
||||
.centerOf(util.grid()
|
||||
.at(0, 2, 5)))
|
||||
|
@ -775,7 +775,7 @@ public class FrogAndConveyorScenes {
|
|||
scene.world()
|
||||
.showIndependentSection(fromPackager, Direction.WEST);
|
||||
ElementLink<WorldSectionElement> toPackagerE = scene.world()
|
||||
.showIndependentSection(toPackager, Direction.WEST);
|
||||
.showIndependentSection(toPackager, Direction.EAST);
|
||||
scene.world()
|
||||
.moveSection(toPackagerE, util.vector()
|
||||
.of(0, 0, 1), 0);
|
||||
|
@ -849,14 +849,8 @@ public class FrogAndConveyorScenes {
|
|||
.fromTo(5, 1, 2, 6, 1, 1));
|
||||
scene.idle(5);
|
||||
|
||||
scene.world()
|
||||
.modifyBlockEntity(util.grid()
|
||||
.at(5, 1, 2), PackagerBlockEntity.class, be -> {
|
||||
be.animationTicks = PackagerBlockEntity.CYCLE;
|
||||
be.animationInward = false;
|
||||
be.heldBox = box;
|
||||
});
|
||||
|
||||
PonderHilo.packagerCreate(scene, util.grid()
|
||||
.at(5, 1, 2), box);
|
||||
scene.idle(30);
|
||||
|
||||
scene.world()
|
||||
|
@ -873,15 +867,10 @@ public class FrogAndConveyorScenes {
|
|||
.modifyBlockEntity(conv2, ChainConveyorBlockEntity.class, be -> boxTransfer(conv1, conv2, be));
|
||||
scene.idle(50);
|
||||
|
||||
scene.world()
|
||||
.modifyBlockEntity(util.grid()
|
||||
.at(2, 1, 4), PackagerBlockEntity.class, be -> {
|
||||
be.animationTicks = PackagerBlockEntity.CYCLE;
|
||||
be.animationInward = true;
|
||||
be.previouslyUnwrapped = box;
|
||||
});
|
||||
|
||||
PonderHilo.packagerUnpack(scene, util.grid()
|
||||
.at(2, 1, 4), box);
|
||||
scene.idle(20);
|
||||
|
||||
scene.overlay()
|
||||
.showControls(util.vector()
|
||||
.blockSurface(util.grid()
|
|
@ -0,0 +1,569 @@
|
|||
package com.simibubi.create.infrastructure.ponder.scenes.highLogistics;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.content.logistics.box.PackageItem;
|
||||
import com.simibubi.create.content.logistics.box.PackageStyles;
|
||||
import com.simibubi.create.foundation.ponder.CreateSceneBuilder;
|
||||
|
||||
import net.createmod.catnip.utility.Pointing;
|
||||
import net.createmod.ponder.api.PonderPalette;
|
||||
import net.createmod.ponder.api.element.ElementLink;
|
||||
import net.createmod.ponder.api.element.WorldSectionElement;
|
||||
import net.createmod.ponder.api.scene.SceneBuilder;
|
||||
import net.createmod.ponder.api.scene.SceneBuildingUtil;
|
||||
import net.createmod.ponder.api.scene.Selection;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
|
||||
public class PackagerScenes {
|
||||
|
||||
public static void packager(SceneBuilder builder, SceneBuildingUtil util) {
|
||||
CreateSceneBuilder scene = new CreateSceneBuilder(builder);
|
||||
scene.title("packager", "Creating and unwrapping packages");
|
||||
scene.configureBasePlate(0, 0, 7);
|
||||
scene.showBasePlate();
|
||||
|
||||
Selection chest1 = util.select()
|
||||
.fromTo(5, 2, 3, 5, 2, 4);
|
||||
BlockPos funnel1 = util.grid()
|
||||
.at(4, 2, 2);
|
||||
BlockPos funnel2 = util.grid()
|
||||
.at(1, 2, 2);
|
||||
Selection funnel1S = util.select()
|
||||
.position(funnel1);
|
||||
Selection funnel2S = util.select()
|
||||
.position(funnel2);
|
||||
BlockPos packager1 = util.grid()
|
||||
.at(5, 2, 2);
|
||||
BlockPos packager2 = util.grid()
|
||||
.at(1, 2, 3);
|
||||
Selection packager1S = util.select()
|
||||
.position(packager1);
|
||||
Selection packager2S = util.select()
|
||||
.position(packager2);
|
||||
Selection largeCog = util.select()
|
||||
.position(7, 0, 3);
|
||||
Selection cogNBelt = util.select()
|
||||
.fromTo(6, 1, 2, 0, 1, 2)
|
||||
.add(util.select()
|
||||
.position(6, 1, 3));
|
||||
BlockPos lever = util.grid()
|
||||
.at(5, 3, 2);
|
||||
Selection scaff1 = util.select()
|
||||
.fromTo(5, 1, 3, 5, 1, 4);
|
||||
Selection scaff2 = util.select()
|
||||
.fromTo(1, 1, 3, 1, 1, 4);
|
||||
scene.idle(5);
|
||||
|
||||
ElementLink<WorldSectionElement> chestL = scene.world()
|
||||
.showIndependentSection(chest1, Direction.DOWN);
|
||||
scene.world()
|
||||
.moveSection(chestL, util.vector()
|
||||
.of(-2, -1, 0), 0);
|
||||
scene.idle(10);
|
||||
ElementLink<WorldSectionElement> packagerL = scene.world()
|
||||
.showIndependentSection(packager1S, Direction.SOUTH);
|
||||
scene.world()
|
||||
.moveSection(packagerL, util.vector()
|
||||
.of(-2, -1, 0), 0);
|
||||
scene.idle(20);
|
||||
|
||||
ItemStack dirt = new ItemStack(Items.DIRT);
|
||||
scene.overlay()
|
||||
.showControls(util.vector()
|
||||
.of(2.5, 3, 2.5), Pointing.DOWN, 40)
|
||||
.withItem(dirt);
|
||||
scene.idle(20);
|
||||
|
||||
scene.overlay()
|
||||
.showText(80)
|
||||
.text("Place packagers next to the inventory they should target")
|
||||
.attachKeyFrame()
|
||||
.placeNearTarget()
|
||||
.pointAt(util.vector()
|
||||
.of(2, 2.5, 2.5));
|
||||
scene.idle(60);
|
||||
|
||||
ElementLink<WorldSectionElement> leverL = scene.world()
|
||||
.showIndependentSection(util.select()
|
||||
.position(lever), Direction.DOWN);
|
||||
scene.world()
|
||||
.moveSection(leverL, util.vector()
|
||||
.of(-2, -1, 0), 0);
|
||||
scene.idle(30);
|
||||
|
||||
scene.world()
|
||||
.toggleRedstonePower(util.select()
|
||||
.fromTo(lever, packager1));
|
||||
scene.effects()
|
||||
.indicateRedstone(lever.west(2)
|
||||
.below());
|
||||
|
||||
scene.idle(10);
|
||||
ItemStack box = PackageStyles.getDefaultBox()
|
||||
.copy();
|
||||
PackageItem.addAddress(box, "Warehouse");
|
||||
PonderHilo.packagerCreate(scene, packager1, box);
|
||||
scene.idle(30);
|
||||
|
||||
scene.overlay()
|
||||
.showText(80)
|
||||
.text("Given redstone power, it will pack items from the inventory into a package")
|
||||
.attachKeyFrame()
|
||||
.placeNearTarget()
|
||||
.pointAt(util.vector()
|
||||
.blockSurface(util.grid()
|
||||
.at(3, 1, 2), Direction.UP));
|
||||
scene.idle(30);
|
||||
|
||||
scene.idle(80);
|
||||
|
||||
scene.world()
|
||||
.moveSection(leverL, util.vector()
|
||||
.of(2, 1, 0), 10);
|
||||
scene.world()
|
||||
.moveSection(packagerL, util.vector()
|
||||
.of(2, 1, 0), 10);
|
||||
scene.world()
|
||||
.moveSection(chestL, util.vector()
|
||||
.of(2, 1, 0), 10);
|
||||
scene.world()
|
||||
.showSection(scaff1, Direction.UP);
|
||||
scene.idle(10);
|
||||
scene.world()
|
||||
.showSection(largeCog, Direction.UP);
|
||||
scene.world()
|
||||
.showSection(cogNBelt, Direction.SOUTH);
|
||||
scene.idle(10);
|
||||
scene.world()
|
||||
.showSection(funnel1S, Direction.DOWN);
|
||||
scene.idle(15);
|
||||
scene.world()
|
||||
.createItemOnBelt(util.grid()
|
||||
.at(4, 1, 2), Direction.EAST, box);
|
||||
PonderHilo.packagerClear(scene, packager1);
|
||||
scene.idle(20);
|
||||
scene.world()
|
||||
.toggleRedstonePower(util.select()
|
||||
.fromTo(5, 2, 2, 5, 3, 2));
|
||||
scene.idle(10);
|
||||
|
||||
scene.world()
|
||||
.multiplyKineticSpeed(util.select()
|
||||
.everywhere(), 1 / 16f);
|
||||
|
||||
scene.overlay()
|
||||
.showText(70)
|
||||
.text("These can be picked up and transported like any other item")
|
||||
.attachKeyFrame()
|
||||
.placeNearTarget()
|
||||
.pointAt(util.vector()
|
||||
.blockSurface(util.grid()
|
||||
.at(3, 2, 2), Direction.EAST));
|
||||
|
||||
scene.idle(80);
|
||||
scene.world()
|
||||
.multiplyKineticSpeed(util.select()
|
||||
.everywhere(), 16f);
|
||||
scene.idle(10);
|
||||
|
||||
scene.world()
|
||||
.showSection(scaff2, Direction.DOWN);
|
||||
scene.idle(5);
|
||||
scene.world()
|
||||
.showSection(packager2S, Direction.DOWN);
|
||||
scene.world()
|
||||
.showSection(util.select()
|
||||
.position(1, 2, 4), Direction.DOWN);
|
||||
scene.idle(10);
|
||||
scene.world()
|
||||
.showSection(funnel2S, Direction.SOUTH);
|
||||
scene.rotateCameraY(-15);
|
||||
scene.idle(40);
|
||||
|
||||
scene.world()
|
||||
.removeItemsFromBelt(util.grid()
|
||||
.at(1, 1, 2));
|
||||
scene.world()
|
||||
.flapFunnel(util.grid()
|
||||
.at(1, 2, 2), false);
|
||||
PonderHilo.packagerUnpack(scene, packager2, box);
|
||||
|
||||
scene.idle(20);
|
||||
scene.overlay()
|
||||
.showControls(util.vector()
|
||||
.topOf(util.grid()
|
||||
.at(1, 2, 4)),
|
||||
Pointing.DOWN, 40)
|
||||
.withItem(dirt);
|
||||
scene.idle(20);
|
||||
|
||||
scene.overlay()
|
||||
.showText(90)
|
||||
.text("Packages inserted will be destroyed, unpacking the contents into the inventory")
|
||||
.attachKeyFrame()
|
||||
.placeNearTarget()
|
||||
.pointAt(util.vector()
|
||||
.blockSurface(util.grid()
|
||||
.at(1, 2, 3), Direction.WEST));
|
||||
scene.idle(100);
|
||||
|
||||
scene.world()
|
||||
.toggleRedstonePower(util.select()
|
||||
.fromTo(5, 2, 2, 5, 3, 2));
|
||||
scene.effects()
|
||||
.indicateRedstone(util.grid()
|
||||
.at(5, 3, 2));
|
||||
PonderHilo.packagerCreate(scene, packager1, box);
|
||||
scene.idle(25);
|
||||
|
||||
scene.world()
|
||||
.createItemOnBelt(util.grid()
|
||||
.at(4, 1, 2), Direction.EAST, box);
|
||||
PonderHilo.packagerClear(scene, packager1);
|
||||
scene.idle(30);
|
||||
|
||||
scene.overlay()
|
||||
.showText(60)
|
||||
.text("Full")
|
||||
.colored(PonderPalette.RED)
|
||||
.placeNearTarget()
|
||||
.pointAt(util.vector()
|
||||
.topOf(util.grid()
|
||||
.at(1, 2, 4)));
|
||||
scene.idle(80);
|
||||
|
||||
scene.overlay()
|
||||
.showOutlineWithText(util.select()
|
||||
.fromTo(1, 2, 3, 1, 2, 4), 90)
|
||||
.text("Packagers will not accept packages they cannot fully unpack")
|
||||
.colored(PonderPalette.RED)
|
||||
.placeNearTarget()
|
||||
.attachKeyFrame()
|
||||
.pointAt(util.vector()
|
||||
.blockSurface(util.grid()
|
||||
.at(1, 2, 3), Direction.WEST));
|
||||
scene.idle(40);
|
||||
|
||||
PonderHilo.packageHopsOffBelt(scene, util.grid()
|
||||
.at(0, 1, 2), Direction.WEST);
|
||||
scene.idle(40);
|
||||
|
||||
}
|
||||
|
||||
public static void packagerAddress(SceneBuilder builder, SceneBuildingUtil util) {
|
||||
CreateSceneBuilder scene = new CreateSceneBuilder(builder);
|
||||
scene.title("packager_address", "Routing packages with an address");
|
||||
scene.configureBasePlate(0, 0, 9);
|
||||
scene.scaleSceneView(.875f);
|
||||
scene.showBasePlate();
|
||||
|
||||
Selection frogport = util.select()
|
||||
.position(7, 1, 1);
|
||||
Selection postbox = util.select()
|
||||
.fromTo(6, 1, 2, 6, 2, 2);
|
||||
Selection northBelt = util.select()
|
||||
.fromTo(3, 1, 3, 4, 1, 0);
|
||||
Selection initialKinetics = util.select()
|
||||
.fromTo(3, 1, 5, 3, 1, 9);
|
||||
Selection largeCog = util.select()
|
||||
.position(2, 0, 9);
|
||||
Selection saw = util.select()
|
||||
.fromTo(2, 1, 5, 0, 1, 4);
|
||||
Selection eastBelt = util.select()
|
||||
.fromTo(3, 1, 4, 8, 1, 4);
|
||||
Selection tunnelS = util.select()
|
||||
.position(4, 2, 4);
|
||||
Selection chest = util.select()
|
||||
.fromTo(7, 2, 8, 7, 2, 7);
|
||||
Selection scaffold = util.select()
|
||||
.fromTo(7, 1, 8, 7, 1, 7);
|
||||
BlockPos packager = util.grid()
|
||||
.at(7, 2, 6);
|
||||
Selection packagerAndLever = util.select()
|
||||
.fromTo(7, 2, 6, 7, 3, 6);
|
||||
Selection packagerBelt = util.select()
|
||||
.fromTo(7, 1, 6, 4, 1, 6);
|
||||
BlockPos funnel = util.grid()
|
||||
.at(6, 2, 6);
|
||||
Selection signS = util.select()
|
||||
.position(7, 2, 5);
|
||||
|
||||
scene.idle(10);
|
||||
ElementLink<WorldSectionElement> chestL = scene.world()
|
||||
.showIndependentSection(chest, Direction.DOWN);
|
||||
scene.world()
|
||||
.moveSection(chestL, util.vector()
|
||||
.of(-2, -1, -2), 0);
|
||||
scene.idle(5);
|
||||
scene.world()
|
||||
.showSectionAndMerge(packagerAndLever, Direction.SOUTH, chestL);
|
||||
scene.idle(20);
|
||||
|
||||
scene.world()
|
||||
.showSectionAndMerge(signS, Direction.SOUTH, chestL);
|
||||
scene.idle(15);
|
||||
|
||||
scene.overlay()
|
||||
.showText(40)
|
||||
.text("Warehouse")
|
||||
.colored(PonderPalette.OUTPUT)
|
||||
.placeNearTarget()
|
||||
.pointAt(util.vector()
|
||||
.blockSurface(util.grid()
|
||||
.at(5, 1, 4), Direction.NORTH)
|
||||
.add(-0.5, 0, 0));
|
||||
scene.idle(50);
|
||||
|
||||
scene.overlay()
|
||||
.showText(60)
|
||||
.text("When a sign is placed on a packager..")
|
||||
.attachKeyFrame()
|
||||
.placeNearTarget()
|
||||
.pointAt(util.vector()
|
||||
.blockSurface(util.grid()
|
||||
.at(5, 1, 4), Direction.NORTH)
|
||||
.add(-0.5, 0, 0));
|
||||
scene.idle(50);
|
||||
|
||||
scene.world()
|
||||
.toggleRedstonePower(packagerAndLever);
|
||||
scene.effects()
|
||||
.indicateRedstone(util.grid()
|
||||
.at(5, 1, 4));
|
||||
ItemStack box = PackageStyles.getDefaultBox()
|
||||
.copy();
|
||||
PonderHilo.packagerCreate(scene, packager, box);
|
||||
|
||||
scene.idle(20);
|
||||
scene.world()
|
||||
.moveSection(chestL, util.vector()
|
||||
.of(0, 1, 0), 10);
|
||||
scene.idle(10);
|
||||
scene.world()
|
||||
.showSectionAndMerge(scaffold, Direction.NORTH, chestL);
|
||||
scene.world()
|
||||
.showSection(largeCog, Direction.UP);
|
||||
scene.world()
|
||||
.showSection(initialKinetics, Direction.NORTH);
|
||||
scene.world()
|
||||
.showSectionAndMerge(packagerBelt, Direction.SOUTH, chestL);
|
||||
scene.idle(5);
|
||||
scene.world()
|
||||
.showSectionAndMerge(util.select()
|
||||
.position(funnel), Direction.DOWN, chestL);
|
||||
scene.idle(15);
|
||||
|
||||
PonderHilo.packagerClear(scene, packager);
|
||||
scene.world()
|
||||
.createItemOnBelt(util.grid()
|
||||
.at(6, 1, 6), Direction.EAST, box);
|
||||
scene.idle(20);
|
||||
|
||||
scene.world()
|
||||
.multiplyKineticSpeed(util.select()
|
||||
.everywhere(), 1 / 32f);
|
||||
scene.overlay()
|
||||
.showText(40)
|
||||
.text("\u2192 Warehouse")
|
||||
.colored(PonderPalette.OUTPUT)
|
||||
.placeNearTarget()
|
||||
.pointAt(util.vector()
|
||||
.blockSurface(util.grid()
|
||||
.at(3, 2, 4), Direction.NORTH));
|
||||
scene.idle(50);
|
||||
|
||||
scene.overlay()
|
||||
.showText(100)
|
||||
.text("Created packages will carry the written line of text as their address")
|
||||
.attachKeyFrame()
|
||||
.placeNearTarget()
|
||||
.pointAt(util.vector()
|
||||
.blockSurface(util.grid()
|
||||
.at(3, 2, 4), Direction.NORTH)
|
||||
.add(-0.5, 0, 0));
|
||||
scene.idle(120);
|
||||
|
||||
scene.world()
|
||||
.hideIndependentSection(chestL, Direction.NORTH);
|
||||
scene.idle(15);
|
||||
scene.world()
|
||||
.removeItemsFromBelt(util.grid()
|
||||
.at(5, 1, 6));
|
||||
scene.world()
|
||||
.removeItemsFromBelt(util.grid()
|
||||
.at(4, 1, 6));
|
||||
scene.idle(15);
|
||||
|
||||
scene.world()
|
||||
.showSection(eastBelt, Direction.WEST);
|
||||
scene.idle(5);
|
||||
scene.world()
|
||||
.showSection(tunnelS, Direction.DOWN);
|
||||
scene.idle(5);
|
||||
scene.world()
|
||||
.showSection(saw, Direction.EAST);
|
||||
scene.idle(5);
|
||||
scene.world()
|
||||
.showSection(northBelt, Direction.SOUTH);
|
||||
scene.rotateCameraY(-15);
|
||||
scene.idle(15);
|
||||
|
||||
scene.overlay()
|
||||
.showControls(util.vector()
|
||||
.of(4, 2.825, 4.5), Pointing.DOWN, 60)
|
||||
.withItem(AllItems.PACKAGE_FILTER.asStack());
|
||||
scene.idle(10);
|
||||
scene.overlay()
|
||||
.showFilterSlotInput(util.vector()
|
||||
.of(4.1, 2.825, 4.5), 50);
|
||||
scene.idle(30);
|
||||
|
||||
scene.overlay()
|
||||
.showText(70)
|
||||
.text("Package filters route packages based on their address")
|
||||
.attachKeyFrame()
|
||||
.placeNearTarget()
|
||||
.pointAt(util.vector()
|
||||
.of(4, 2.825, 4.5));
|
||||
scene.idle(70);
|
||||
|
||||
ItemStack warehouseBox = PackageStyles.getDefaultBox()
|
||||
.copy();
|
||||
ItemStack factoryBox = PackageItem.containing(List.of(new ItemStack(Items.IRON_INGOT)));
|
||||
PackageItem.addAddress(warehouseBox, "Warehouse");
|
||||
PackageItem.addAddress(factoryBox, "Factory");
|
||||
|
||||
scene.world()
|
||||
.createItemOnBelt(util.grid()
|
||||
.at(6, 1, 4), Direction.EAST, warehouseBox);
|
||||
scene.idle(10);
|
||||
|
||||
scene.overlay()
|
||||
.showText(50)
|
||||
.text("\u2192 Warehouse")
|
||||
.colored(PonderPalette.OUTPUT)
|
||||
.placeNearTarget()
|
||||
.pointAt(util.vector()
|
||||
.blockSurface(util.grid()
|
||||
.at(7, 2, 4), Direction.WEST));
|
||||
scene.overlay()
|
||||
.showText(50)
|
||||
.colored(PonderPalette.BLUE)
|
||||
.text("Factory")
|
||||
.placeNearTarget()
|
||||
.pointAt(util.vector()
|
||||
.of(4, 2.825, 4.5));
|
||||
scene.idle(60);
|
||||
|
||||
scene.world()
|
||||
.multiplyKineticSpeed(util.select()
|
||||
.everywhere(), 32f);
|
||||
|
||||
scene.idle(60);
|
||||
|
||||
scene.world()
|
||||
.createItemOnBelt(util.grid()
|
||||
.at(6, 1, 4), Direction.EAST, factoryBox);
|
||||
scene.world()
|
||||
.multiplyKineticSpeed(util.select()
|
||||
.everywhere(), 1 / 32f);
|
||||
scene.idle(10);
|
||||
|
||||
scene.overlay()
|
||||
.showText(50)
|
||||
.text("\u2192 Factory")
|
||||
.colored(PonderPalette.OUTPUT)
|
||||
.placeNearTarget()
|
||||
.pointAt(util.vector()
|
||||
.blockSurface(util.grid()
|
||||
.at(7, 2, 4), Direction.WEST));
|
||||
scene.overlay()
|
||||
.showText(50)
|
||||
.colored(PonderPalette.BLUE)
|
||||
.text("Factory")
|
||||
.placeNearTarget()
|
||||
.pointAt(util.vector()
|
||||
.of(4, 2.825, 4.5));
|
||||
scene.idle(60);
|
||||
|
||||
scene.world()
|
||||
.multiplyKineticSpeed(util.select()
|
||||
.everywhere(), 32f);
|
||||
|
||||
scene.idle(40);
|
||||
PonderHilo.packageHopsOffBelt(scene, util.grid()
|
||||
.at(4, 1, 0), Direction.NORTH);
|
||||
scene.idle(40);
|
||||
scene.world()
|
||||
.multiplyKineticSpeed(util.select()
|
||||
.everywhere(), 1 / 32f);
|
||||
scene.overlay()
|
||||
.showText(100)
|
||||
.text("For compactness, mechanical saws can unwrap packages straight onto a belt")
|
||||
.attachKeyFrame()
|
||||
.placeNearTarget()
|
||||
.pointAt(util.vector()
|
||||
.topOf(util.grid()
|
||||
.at(2, 1, 4)));
|
||||
scene.idle(110);
|
||||
|
||||
scene.world()
|
||||
.multiplyKineticSpeed(util.select()
|
||||
.everywhere(), 32f);
|
||||
|
||||
scene.idle(20);
|
||||
scene.world()
|
||||
.hideSection(eastBelt, Direction.EAST);
|
||||
scene.idle(5);
|
||||
scene.world()
|
||||
.hideSection(tunnelS, Direction.UP);
|
||||
scene.idle(5);
|
||||
scene.world()
|
||||
.hideSection(saw, Direction.WEST);
|
||||
scene.idle(5);
|
||||
scene.world()
|
||||
.hideSection(initialKinetics, Direction.UP);
|
||||
scene.world()
|
||||
.hideSection(largeCog, Direction.DOWN);
|
||||
scene.world()
|
||||
.hideSection(northBelt, Direction.NORTH);
|
||||
scene.rotateCameraY(15);
|
||||
scene.idle(15);
|
||||
|
||||
ElementLink<WorldSectionElement> extrasL = scene.world()
|
||||
.showIndependentSection(postbox, Direction.DOWN);
|
||||
scene.world()
|
||||
.moveSection(extrasL, util.vector()
|
||||
.of(-3, 0, 2), 0);
|
||||
scene.idle(5);
|
||||
scene.world()
|
||||
.showSectionAndMerge(frogport, Direction.DOWN, extrasL);
|
||||
scene.idle(20);
|
||||
|
||||
scene.overlay()
|
||||
.showText(100)
|
||||
.text("Aside from those filters, Frogports and Postboxes have package routing capabilities")
|
||||
.attachKeyFrame()
|
||||
.placeNearTarget()
|
||||
.pointAt(util.vector()
|
||||
.blockSurface(util.grid()
|
||||
.at(3, 2, 4), Direction.NORTH));
|
||||
scene.idle(110);
|
||||
|
||||
scene.overlay()
|
||||
.showText(80)
|
||||
.text("Inspect them to find out more about their behaviour")
|
||||
.placeNearTarget()
|
||||
.pointAt(util.vector()
|
||||
.blockSurface(util.grid()
|
||||
.at(3, 2, 4), Direction.NORTH));
|
||||
scene.idle(90);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package com.simibubi.create.infrastructure.ponder.scenes.highLogistics;
|
||||
|
||||
import com.simibubi.create.content.logistics.box.PackageEntity;
|
||||
import com.simibubi.create.content.logistics.box.PackageStyles;
|
||||
import com.simibubi.create.content.logistics.packager.PackagerBlockEntity;
|
||||
import com.simibubi.create.foundation.ponder.CreateSceneBuilder;
|
||||
|
||||
import net.createmod.ponder.api.element.ElementLink;
|
||||
import net.createmod.ponder.api.element.EntityElement;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class PonderHilo {
|
||||
|
||||
public static void packagerCreate(CreateSceneBuilder scene, BlockPos pos, ItemStack box) {
|
||||
scene.world()
|
||||
.modifyBlockEntity(pos, PackagerBlockEntity.class, be -> {
|
||||
be.animationTicks = PackagerBlockEntity.CYCLE;
|
||||
be.animationInward = false;
|
||||
be.heldBox = box;
|
||||
});
|
||||
}
|
||||
|
||||
public static void packagerUnpack(CreateSceneBuilder scene, BlockPos pos, ItemStack box) {
|
||||
scene.world()
|
||||
.modifyBlockEntity(pos, PackagerBlockEntity.class, be -> {
|
||||
be.animationTicks = PackagerBlockEntity.CYCLE;
|
||||
be.animationInward = true;
|
||||
be.previouslyUnwrapped = box;
|
||||
});
|
||||
}
|
||||
|
||||
public static void packagerClear(CreateSceneBuilder scene, BlockPos pos) {
|
||||
scene.world()
|
||||
.modifyBlockEntity(pos, PackagerBlockEntity.class, be -> be.heldBox = ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
public static ElementLink<EntityElement> packageHopsOffBelt(CreateSceneBuilder scene, BlockPos beltPos,
|
||||
Direction side) {
|
||||
scene.world()
|
||||
.removeItemsFromBelt(beltPos);
|
||||
return scene.world()
|
||||
.createEntity(l -> {
|
||||
PackageEntity packageEntity = new PackageEntity(l, beltPos.getX() + 0.5 + side.getStepX() * 0.25,
|
||||
beltPos.getY() + 0.875, beltPos.getZ() + 0.5 + side.getStepZ() * 0.25);
|
||||
packageEntity.setDeltaMovement(new Vec3(side.getStepX(), 0.5f, side.getStepZ()).scale(0.25f));
|
||||
packageEntity.box = PackageStyles.getDefaultBox();
|
||||
return packageEntity;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
#include "flywheel:util/matrix.glsl"
|
||||
#include "flywheel:util/quaternion.glsl"
|
||||
|
||||
void flw_instanceVertex(in FlwInstance instance) {
|
||||
float degrees = instance.offset + flw_renderSeconds * instance.speed;
|
||||
|
||||
vec4 kineticRot = quaternionDegrees(instance.axis, degrees);
|
||||
vec3 rotated = rotateByQuaternion(flw_vertexPos.xyz - instance.rotationCenter, kineticRot) + instance.rotationCenter;
|
||||
|
||||
flw_vertexPos.xyz = rotateByQuaternion(rotated - .5, instance.rotation) + instance.pos + .5;
|
||||
flw_vertexNormal = rotateByQuaternion(rotateByQuaternion(flw_vertexNormal, kineticRot), instance.rotation);
|
||||
flw_vertexLight = max(vec2(instance.light) / 256., flw_vertexLight);
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
void flw_transformBoundingSphere(in FlwInstance instance, inout vec3 center, inout float radius) {
|
||||
// The instance will spin about the rotation center, so we need to expand the radius to account for that
|
||||
float extraForKinetic = length(center - instance.rotationCenter);
|
||||
float extraForModel = length(center - 0.5);
|
||||
|
||||
radius += extraForKinetic + extraForModel;
|
||||
center += instance.pos;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
void flw_transformBoundingSphere(in FlwInstance instance, inout vec3 center, inout float radius) {
|
||||
// The instance will spin about (0.5, 0.5, 0.5), so we need to expand the radius to account for that
|
||||
// The instance will spin about the rotation center, so we need to expand the radius to account for that
|
||||
radius += length(center - 0.5);
|
||||
center += instance.pos;
|
||||
}
|
||||
|
|
|
@ -1,21 +1,15 @@
|
|||
#include "flywheel:util/matrix.glsl"
|
||||
|
||||
const float uTime = 0.;
|
||||
|
||||
mat3 kineticRotation(float offset, float speed, vec3 axis) {
|
||||
float degrees = offset + flw_renderTicks * speed * 3./10.;
|
||||
return rotationDegrees(axis, degrees);
|
||||
}
|
||||
#include "flywheel:util/quaternion.glsl"
|
||||
|
||||
void flw_instanceVertex(in FlwInstance instance) {
|
||||
mat3 spin = kineticRotation(instance.offset, instance.speed, instance.axis);
|
||||
float degrees = instance.offset + flw_renderSeconds * instance.speed;
|
||||
|
||||
vec3 worldPos = spin * (flw_vertexPos.xyz - .5);
|
||||
flw_vertexPos.xyz = worldPos.xyz + instance.pos + .5;
|
||||
vec4 kineticRot = quaternionDegrees(instance.axis, degrees);
|
||||
vec3 rotated = rotateByQuaternion(flw_vertexPos.xyz - .5, instance.rotation);
|
||||
|
||||
flw_vertexNormal = spin * flw_vertexNormal;
|
||||
flw_vertexOverlay = instance.overlay;
|
||||
flw_vertexPos.xyz = rotateByQuaternion(rotated, kineticRot) + instance.pos + .5;
|
||||
flw_vertexNormal = rotateByQuaternion(rotateByQuaternion(flw_vertexNormal, instance.rotation), kineticRot);
|
||||
flw_vertexLight = max(vec2(instance.light) / 256., flw_vertexLight);
|
||||
flw_vertexOverlay = instance.overlay;
|
||||
|
||||
#if defined(DEBUG_RAINBOW)
|
||||
flw_vertexColor = instance.color;
|
||||
|
|
|
@ -790,6 +790,20 @@
|
|||
"create.schedule.instruction.throttle.summary": "Change Max Speed to %1$s",
|
||||
"create.schedule.instruction.throttle_edit_box": "Throttle",
|
||||
"create.schedule.instruction.throttle_edit_box_1": "Affects the top speed of the Train",
|
||||
|
||||
"create.schedule.instruction.package_delivery": "Deliver Package",
|
||||
"create.schedule.instruction.package_delivery.summary": "Deliver first package in cargo",
|
||||
"create.schedule.instruction.package_delivery.summary_1": "Drives to the station with",
|
||||
"create.schedule.instruction.package_delivery.summary_2": "the correct postbox",
|
||||
|
||||
"create.schedule.instruction.package_retrieval": "Retrieve Package",
|
||||
"create.schedule.instruction.package_retrieval.summary": "Fetch a package addressed to:",
|
||||
"create.schedule.instruction.package_retrieval.summary_1": "Drives to a postbox with",
|
||||
"create.schedule.instruction.package_retrieval.summary_2": "an undelivered package",
|
||||
"create.schedule.instruction.address_filter_edit_box": "Retrieve Packages with this Address",
|
||||
"create.schedule.instruction.address_filter_edit_box_1": "Use * as a text wildcard",
|
||||
"create.schedule.instruction.address_filter_edit_box_2": "Train may navigate anywhere to collect it",
|
||||
"create.schedule.instruction.address_filter_edit_box_3": "Add another instruction to make it return",
|
||||
|
||||
"create.schedule.condition_type": "Continue if/after:",
|
||||
"create.schedule.condition.editor": "Condition Editor",
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 1,003 B |
Binary file not shown.
Before Width: | Height: | Size: 981 B After Width: | Height: | Size: 952 B |
|
@ -24,10 +24,6 @@
|
|||
"type": "single",
|
||||
"resource": "create:entity/blueprint_small"
|
||||
},
|
||||
{
|
||||
"type": "single",
|
||||
"resource": "create:entity/display_cloth"
|
||||
},
|
||||
{
|
||||
"type": "single",
|
||||
"resource": "create:entity/coupling"
|
||||
|
|
Loading…
Add table
Reference in a new issue