mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-27 23:47:38 +01:00
Manual Steering
- Trains can now travel backwards through the graph - Controls are now a requirement for assembly - Double-endedness now depends on two opposite controls blocks anywhere on the train - Players can now manually control trains via a mounted controls block
This commit is contained in:
parent
478d891a04
commit
0a931a77ef
44 changed files with 1123 additions and 364 deletions
|
@ -536,21 +536,21 @@ bf2b0310500213ff853c748c236eb5d01f61658e assets/create/blockstates/yellow_toolbo
|
|||
7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json
|
||||
b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json
|
||||
9ffe5b3f8a39fa3c3a97a3c534bd82402177e82e assets/create/lang/en_ud.json
|
||||
a95bf9617620bb8b5fb82fe0e56e46bd336b278f assets/create/lang/en_us.json
|
||||
b0115c492677dab858488cef73f2fd8eb6917868 assets/create/lang/unfinished/de_de.json
|
||||
5165ae65abf3e3708a2546c4a90d1e73955358e0 assets/create/lang/unfinished/es_cl.json
|
||||
052b77a7f53c2bff190db58d0c5cdd0fd46b0aa4 assets/create/lang/unfinished/es_es.json
|
||||
33485bc349947338aef69f05cf23df3254c30b02 assets/create/lang/unfinished/fr_fr.json
|
||||
f5effa80964b2a6afd5e4cc31de0658ab5f3ee4e assets/create/lang/unfinished/it_it.json
|
||||
14db37211e03d9e8322d1f692c17325be405b4ff assets/create/lang/unfinished/ja_jp.json
|
||||
fc1d89b9f72db1030d4dc11c73a58d8e9f20fc21 assets/create/lang/unfinished/ko_kr.json
|
||||
3acc03de9c0e411d1d935464e8cd66c3745ad2d2 assets/create/lang/unfinished/nl_nl.json
|
||||
23eaf81707d5d67816a3f035b9eee5b48e601624 assets/create/lang/unfinished/pl_pl.json
|
||||
0a626a20150c4246ef5a956d7853424a95254222 assets/create/lang/unfinished/pt_br.json
|
||||
4fd404306e795407325d17d9a68a3e6f5bbaf475 assets/create/lang/unfinished/pt_pt.json
|
||||
74a3fec14772a0575debe0ec93f43d45cb556542 assets/create/lang/unfinished/ru_ru.json
|
||||
f9f56931ea5cae9fecf7bf5f4f323cdbe1101f75 assets/create/lang/unfinished/zh_cn.json
|
||||
1c5669a3109edbd448623a38e8b1c653f1a312c5 assets/create/lang/unfinished/zh_tw.json
|
||||
9dc50a1957cac1967adba6a02f2708f5a82915b6 assets/create/lang/en_us.json
|
||||
60e216704dc824ae189af3927ae06e4c70e53478 assets/create/lang/unfinished/de_de.json
|
||||
c2faed3f8cdc2616dc03d6c9cf6dafd9084c3e14 assets/create/lang/unfinished/es_cl.json
|
||||
f9632799fdf6278d0b0c0a2bff40df099745b076 assets/create/lang/unfinished/es_es.json
|
||||
1d7af6b083679766bb542cf61fc6a835983a055c assets/create/lang/unfinished/fr_fr.json
|
||||
4942f180ef3758a1449108331943e0fa75e1a29b assets/create/lang/unfinished/it_it.json
|
||||
3249596dacdf06bc727676a5cc8acf85742054d0 assets/create/lang/unfinished/ja_jp.json
|
||||
ef7601ee26fdaf0356fe5400bc4f230ccb87eea8 assets/create/lang/unfinished/ko_kr.json
|
||||
6d3914298d06db106d91299729f39cf5406f6768 assets/create/lang/unfinished/nl_nl.json
|
||||
e21bd53612d2e82e9214b94fd6d2d110377089c1 assets/create/lang/unfinished/pl_pl.json
|
||||
56b4b8f892bf4442ac2f5140dc97273d1dfe2f27 assets/create/lang/unfinished/pt_br.json
|
||||
63690bcfce50698d81562fe6cff1d0701a13e23d assets/create/lang/unfinished/pt_pt.json
|
||||
dfa8dc43216673feac87a2a49d08fd8cc9b1d9f2 assets/create/lang/unfinished/ru_ru.json
|
||||
dd18a29b4a76752ea033569ebbb07014e9aa3ab0 assets/create/lang/unfinished/zh_cn.json
|
||||
0b67d5808e2665b5c0414a103b730508e17e01f6 assets/create/lang/unfinished/zh_tw.json
|
||||
487a511a01b2a4531fb672f917922312db78f958 assets/create/models/block/acacia_window.json
|
||||
b48060cba1a382f373a05bf0039054053eccf076 assets/create/models/block/acacia_window_pane_noside.json
|
||||
3066db1bf03cffa1a9c7fbacf47ae586632f4eb3 assets/create/models/block/acacia_window_pane_noside_alt.json
|
||||
|
@ -2135,7 +2135,7 @@ d080b1b25e5bc8baf5aee68691b08c7f12ece3b0 assets/create/models/item/windmill_bear
|
|||
a80fb25a0b655e76be986b5b49fcb0f03461a1ab assets/create/models/item/zinc_nugget.json
|
||||
b1689617190c05ef34bd18456b0c7ae09bb3210f assets/create/models/item/zinc_ore.json
|
||||
5049f72c327a88f175f6f9425909e098fc711100 assets/create/sounds.json
|
||||
5d0cc4c0255dc241e61c173b31ddca70c88d08e4 data/create/advancements/aesthetics.json
|
||||
0f1b4b980afba9bf2caf583b88e261bba8b10313 data/create/advancements/aesthetics.json
|
||||
613e64b44bed959da899fdd54c1cacb227fb33f2 data/create/advancements/andesite_alloy.json
|
||||
81885c6bfb85792c88aaa7c9b70f58832945d31f data/create/advancements/andesite_casing.json
|
||||
83c046bd200623933545c9e4326f782fb02c87fa data/create/advancements/arm_blaze_burner.json
|
||||
|
|
|
@ -1398,6 +1398,8 @@
|
|||
"create.train_assembly.not_connected_in_order": "Bogeys are not connected in order",
|
||||
"create.train_assembly.single_bogey_carriage": "This Bogey type cannot support a carriage on its own",
|
||||
"create.train_assembly.nothing_attached": "No structure attached to Bogey %1$s",
|
||||
"create.train_assembly.no_controls": "At least one forward-facing controls block needs to be mounted on the train",
|
||||
"create.train_assembly.sideways_controls": "A mounted controls block is facing sideways",
|
||||
|
||||
"create.track_target.set": "Targeted track selected",
|
||||
"create.track_target.success": "Successfully bound to targeted track",
|
||||
|
@ -1410,10 +1412,14 @@
|
|||
"create.train.relocate": "Click a Track to Relocate %1$s to. Sneak-Click to abort",
|
||||
"create.train.relocate.abort": "Relocation aborted",
|
||||
"create.train.relocate.success": "Relocation successful",
|
||||
"create.train.relocate.valid": "Can be relocated here, Click to Confirm",
|
||||
"create.train.relocate.valid": "Can relocate to here, Click to Confirm",
|
||||
"create.train.relocate.invalid": "Cannot relocate Train to this Track",
|
||||
"create.train.relocate.too_far": "Cannot relocate Train this far away",
|
||||
|
||||
"create.contraption.controls.start_controlling": "Now controlling: %1$s",
|
||||
"create.contraption.controls.stop_controlling": "Stopped controlling contraption",
|
||||
"create.contraption.controls.approach_station": "Hold %1$s to approach %2$s",
|
||||
|
||||
"create.gui.config.overlay1": "Hi :)",
|
||||
"create.gui.config.overlay2": "This is a sample overlay",
|
||||
"create.gui.config.overlay3": "Click or drag with your mouse",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 1422",
|
||||
"_": "Missing Localizations: 1427",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1399,6 +1399,8 @@
|
|||
"create.train_assembly.not_connected_in_order": "UNLOCALIZED: Bogeys are not connected in order",
|
||||
"create.train_assembly.single_bogey_carriage": "UNLOCALIZED: This Bogey type cannot support a carriage on its own",
|
||||
"create.train_assembly.nothing_attached": "UNLOCALIZED: No structure attached to Bogey %1$s",
|
||||
"create.train_assembly.no_controls": "UNLOCALIZED: At least one forward-facing controls block needs to be mounted on the train",
|
||||
"create.train_assembly.sideways_controls": "UNLOCALIZED: A mounted controls block is facing sideways",
|
||||
|
||||
"create.track_target.set": "UNLOCALIZED: Targeted track selected",
|
||||
"create.track_target.success": "UNLOCALIZED: Successfully bound to targeted track",
|
||||
|
@ -1411,10 +1413,14 @@
|
|||
"create.train.relocate": "UNLOCALIZED: Click a Track to Relocate %1$s to. Sneak-Click to abort",
|
||||
"create.train.relocate.abort": "UNLOCALIZED: Relocation aborted",
|
||||
"create.train.relocate.success": "UNLOCALIZED: Relocation successful",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can be relocated here, Click to Confirm",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can relocate to here, Click to Confirm",
|
||||
"create.train.relocate.invalid": "UNLOCALIZED: Cannot relocate Train to this Track",
|
||||
"create.train.relocate.too_far": "UNLOCALIZED: Cannot relocate Train this far away",
|
||||
|
||||
"create.contraption.controls.start_controlling": "UNLOCALIZED: Now controlling: %1$s",
|
||||
"create.contraption.controls.stop_controlling": "UNLOCALIZED: Stopped controlling contraption",
|
||||
"create.contraption.controls.approach_station": "UNLOCALIZED: Hold %1$s to approach %2$s",
|
||||
|
||||
"create.gui.config.overlay1": "Hi :)",
|
||||
"create.gui.config.overlay2": "Dies ist ein Beispiel Overlay",
|
||||
"create.gui.config.overlay3": "Klicke oder ziehe mit deiner Maus",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 433",
|
||||
"_": "Missing Localizations: 438",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1399,6 +1399,8 @@
|
|||
"create.train_assembly.not_connected_in_order": "UNLOCALIZED: Bogeys are not connected in order",
|
||||
"create.train_assembly.single_bogey_carriage": "UNLOCALIZED: This Bogey type cannot support a carriage on its own",
|
||||
"create.train_assembly.nothing_attached": "UNLOCALIZED: No structure attached to Bogey %1$s",
|
||||
"create.train_assembly.no_controls": "UNLOCALIZED: At least one forward-facing controls block needs to be mounted on the train",
|
||||
"create.train_assembly.sideways_controls": "UNLOCALIZED: A mounted controls block is facing sideways",
|
||||
|
||||
"create.track_target.set": "UNLOCALIZED: Targeted track selected",
|
||||
"create.track_target.success": "UNLOCALIZED: Successfully bound to targeted track",
|
||||
|
@ -1411,10 +1413,14 @@
|
|||
"create.train.relocate": "UNLOCALIZED: Click a Track to Relocate %1$s to. Sneak-Click to abort",
|
||||
"create.train.relocate.abort": "UNLOCALIZED: Relocation aborted",
|
||||
"create.train.relocate.success": "UNLOCALIZED: Relocation successful",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can be relocated here, Click to Confirm",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can relocate to here, Click to Confirm",
|
||||
"create.train.relocate.invalid": "UNLOCALIZED: Cannot relocate Train to this Track",
|
||||
"create.train.relocate.too_far": "UNLOCALIZED: Cannot relocate Train this far away",
|
||||
|
||||
"create.contraption.controls.start_controlling": "UNLOCALIZED: Now controlling: %1$s",
|
||||
"create.contraption.controls.stop_controlling": "UNLOCALIZED: Stopped controlling contraption",
|
||||
"create.contraption.controls.approach_station": "UNLOCALIZED: Hold %1$s to approach %2$s",
|
||||
|
||||
"create.gui.config.overlay1": "Hola :)",
|
||||
"create.gui.config.overlay2": "Este es un overlay de ejemplo",
|
||||
"create.gui.config.overlay3": "Haz clic o arrastra con el mouse",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 433",
|
||||
"_": "Missing Localizations: 438",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1399,6 +1399,8 @@
|
|||
"create.train_assembly.not_connected_in_order": "UNLOCALIZED: Bogeys are not connected in order",
|
||||
"create.train_assembly.single_bogey_carriage": "UNLOCALIZED: This Bogey type cannot support a carriage on its own",
|
||||
"create.train_assembly.nothing_attached": "UNLOCALIZED: No structure attached to Bogey %1$s",
|
||||
"create.train_assembly.no_controls": "UNLOCALIZED: At least one forward-facing controls block needs to be mounted on the train",
|
||||
"create.train_assembly.sideways_controls": "UNLOCALIZED: A mounted controls block is facing sideways",
|
||||
|
||||
"create.track_target.set": "UNLOCALIZED: Targeted track selected",
|
||||
"create.track_target.success": "UNLOCALIZED: Successfully bound to targeted track",
|
||||
|
@ -1411,10 +1413,14 @@
|
|||
"create.train.relocate": "UNLOCALIZED: Click a Track to Relocate %1$s to. Sneak-Click to abort",
|
||||
"create.train.relocate.abort": "UNLOCALIZED: Relocation aborted",
|
||||
"create.train.relocate.success": "UNLOCALIZED: Relocation successful",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can be relocated here, Click to Confirm",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can relocate to here, Click to Confirm",
|
||||
"create.train.relocate.invalid": "UNLOCALIZED: Cannot relocate Train to this Track",
|
||||
"create.train.relocate.too_far": "UNLOCALIZED: Cannot relocate Train this far away",
|
||||
|
||||
"create.contraption.controls.start_controlling": "UNLOCALIZED: Now controlling: %1$s",
|
||||
"create.contraption.controls.stop_controlling": "UNLOCALIZED: Stopped controlling contraption",
|
||||
"create.contraption.controls.approach_station": "UNLOCALIZED: Hold %1$s to approach %2$s",
|
||||
|
||||
"create.gui.config.overlay1": "Hola :)",
|
||||
"create.gui.config.overlay2": "Esta es una muestra de la superposición",
|
||||
"create.gui.config.overlay3": "Haga clic o arrastre con el ratón",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 1684",
|
||||
"_": "Missing Localizations: 1689",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1399,6 +1399,8 @@
|
|||
"create.train_assembly.not_connected_in_order": "UNLOCALIZED: Bogeys are not connected in order",
|
||||
"create.train_assembly.single_bogey_carriage": "UNLOCALIZED: This Bogey type cannot support a carriage on its own",
|
||||
"create.train_assembly.nothing_attached": "UNLOCALIZED: No structure attached to Bogey %1$s",
|
||||
"create.train_assembly.no_controls": "UNLOCALIZED: At least one forward-facing controls block needs to be mounted on the train",
|
||||
"create.train_assembly.sideways_controls": "UNLOCALIZED: A mounted controls block is facing sideways",
|
||||
|
||||
"create.track_target.set": "UNLOCALIZED: Targeted track selected",
|
||||
"create.track_target.success": "UNLOCALIZED: Successfully bound to targeted track",
|
||||
|
@ -1411,10 +1413,14 @@
|
|||
"create.train.relocate": "UNLOCALIZED: Click a Track to Relocate %1$s to. Sneak-Click to abort",
|
||||
"create.train.relocate.abort": "UNLOCALIZED: Relocation aborted",
|
||||
"create.train.relocate.success": "UNLOCALIZED: Relocation successful",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can be relocated here, Click to Confirm",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can relocate to here, Click to Confirm",
|
||||
"create.train.relocate.invalid": "UNLOCALIZED: Cannot relocate Train to this Track",
|
||||
"create.train.relocate.too_far": "UNLOCALIZED: Cannot relocate Train this far away",
|
||||
|
||||
"create.contraption.controls.start_controlling": "UNLOCALIZED: Now controlling: %1$s",
|
||||
"create.contraption.controls.stop_controlling": "UNLOCALIZED: Stopped controlling contraption",
|
||||
"create.contraption.controls.approach_station": "UNLOCALIZED: Hold %1$s to approach %2$s",
|
||||
|
||||
"create.gui.config.overlay1": "UNLOCALIZED: Hi :)",
|
||||
"create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay",
|
||||
"create.gui.config.overlay3": "UNLOCALIZED: Click or drag with your mouse",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 1373",
|
||||
"_": "Missing Localizations: 1378",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1399,6 +1399,8 @@
|
|||
"create.train_assembly.not_connected_in_order": "UNLOCALIZED: Bogeys are not connected in order",
|
||||
"create.train_assembly.single_bogey_carriage": "UNLOCALIZED: This Bogey type cannot support a carriage on its own",
|
||||
"create.train_assembly.nothing_attached": "UNLOCALIZED: No structure attached to Bogey %1$s",
|
||||
"create.train_assembly.no_controls": "UNLOCALIZED: At least one forward-facing controls block needs to be mounted on the train",
|
||||
"create.train_assembly.sideways_controls": "UNLOCALIZED: A mounted controls block is facing sideways",
|
||||
|
||||
"create.track_target.set": "UNLOCALIZED: Targeted track selected",
|
||||
"create.track_target.success": "UNLOCALIZED: Successfully bound to targeted track",
|
||||
|
@ -1411,10 +1413,14 @@
|
|||
"create.train.relocate": "UNLOCALIZED: Click a Track to Relocate %1$s to. Sneak-Click to abort",
|
||||
"create.train.relocate.abort": "UNLOCALIZED: Relocation aborted",
|
||||
"create.train.relocate.success": "UNLOCALIZED: Relocation successful",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can be relocated here, Click to Confirm",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can relocate to here, Click to Confirm",
|
||||
"create.train.relocate.invalid": "UNLOCALIZED: Cannot relocate Train to this Track",
|
||||
"create.train.relocate.too_far": "UNLOCALIZED: Cannot relocate Train this far away",
|
||||
|
||||
"create.contraption.controls.start_controlling": "UNLOCALIZED: Now controlling: %1$s",
|
||||
"create.contraption.controls.stop_controlling": "UNLOCALIZED: Stopped controlling contraption",
|
||||
"create.contraption.controls.approach_station": "UNLOCALIZED: Hold %1$s to approach %2$s",
|
||||
|
||||
"create.gui.config.overlay1": "Ciao :)",
|
||||
"create.gui.config.overlay2": "Questo overlay è di esempio",
|
||||
"create.gui.config.overlay3": "Cliccalo o trascinalo col mouse",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 103",
|
||||
"_": "Missing Localizations: 108",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1399,6 +1399,8 @@
|
|||
"create.train_assembly.not_connected_in_order": "UNLOCALIZED: Bogeys are not connected in order",
|
||||
"create.train_assembly.single_bogey_carriage": "UNLOCALIZED: This Bogey type cannot support a carriage on its own",
|
||||
"create.train_assembly.nothing_attached": "UNLOCALIZED: No structure attached to Bogey %1$s",
|
||||
"create.train_assembly.no_controls": "UNLOCALIZED: At least one forward-facing controls block needs to be mounted on the train",
|
||||
"create.train_assembly.sideways_controls": "UNLOCALIZED: A mounted controls block is facing sideways",
|
||||
|
||||
"create.track_target.set": "UNLOCALIZED: Targeted track selected",
|
||||
"create.track_target.success": "UNLOCALIZED: Successfully bound to targeted track",
|
||||
|
@ -1411,10 +1413,14 @@
|
|||
"create.train.relocate": "UNLOCALIZED: Click a Track to Relocate %1$s to. Sneak-Click to abort",
|
||||
"create.train.relocate.abort": "UNLOCALIZED: Relocation aborted",
|
||||
"create.train.relocate.success": "UNLOCALIZED: Relocation successful",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can be relocated here, Click to Confirm",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can relocate to here, Click to Confirm",
|
||||
"create.train.relocate.invalid": "UNLOCALIZED: Cannot relocate Train to this Track",
|
||||
"create.train.relocate.too_far": "UNLOCALIZED: Cannot relocate Train this far away",
|
||||
|
||||
"create.contraption.controls.start_controlling": "UNLOCALIZED: Now controlling: %1$s",
|
||||
"create.contraption.controls.stop_controlling": "UNLOCALIZED: Stopped controlling contraption",
|
||||
"create.contraption.controls.approach_station": "UNLOCALIZED: Hold %1$s to approach %2$s",
|
||||
|
||||
"create.gui.config.overlay1": "やぁ(・∀・)",
|
||||
"create.gui.config.overlay2": "これはオーバーレイのサンプルです",
|
||||
"create.gui.config.overlay3": "マウスでクリックまたはドラッグしてください",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 105",
|
||||
"_": "Missing Localizations: 110",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1399,6 +1399,8 @@
|
|||
"create.train_assembly.not_connected_in_order": "UNLOCALIZED: Bogeys are not connected in order",
|
||||
"create.train_assembly.single_bogey_carriage": "UNLOCALIZED: This Bogey type cannot support a carriage on its own",
|
||||
"create.train_assembly.nothing_attached": "UNLOCALIZED: No structure attached to Bogey %1$s",
|
||||
"create.train_assembly.no_controls": "UNLOCALIZED: At least one forward-facing controls block needs to be mounted on the train",
|
||||
"create.train_assembly.sideways_controls": "UNLOCALIZED: A mounted controls block is facing sideways",
|
||||
|
||||
"create.track_target.set": "UNLOCALIZED: Targeted track selected",
|
||||
"create.track_target.success": "UNLOCALIZED: Successfully bound to targeted track",
|
||||
|
@ -1411,10 +1413,14 @@
|
|||
"create.train.relocate": "UNLOCALIZED: Click a Track to Relocate %1$s to. Sneak-Click to abort",
|
||||
"create.train.relocate.abort": "UNLOCALIZED: Relocation aborted",
|
||||
"create.train.relocate.success": "UNLOCALIZED: Relocation successful",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can be relocated here, Click to Confirm",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can relocate to here, Click to Confirm",
|
||||
"create.train.relocate.invalid": "UNLOCALIZED: Cannot relocate Train to this Track",
|
||||
"create.train.relocate.too_far": "UNLOCALIZED: Cannot relocate Train this far away",
|
||||
|
||||
"create.contraption.controls.start_controlling": "UNLOCALIZED: Now controlling: %1$s",
|
||||
"create.contraption.controls.stop_controlling": "UNLOCALIZED: Stopped controlling contraption",
|
||||
"create.contraption.controls.approach_station": "UNLOCALIZED: Hold %1$s to approach %2$s",
|
||||
|
||||
"create.gui.config.overlay1": "Hi :)",
|
||||
"create.gui.config.overlay2": "This is a sample overlay",
|
||||
"create.gui.config.overlay3": "Click or drag with your mouse",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 2037",
|
||||
"_": "Missing Localizations: 2042",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1399,6 +1399,8 @@
|
|||
"create.train_assembly.not_connected_in_order": "UNLOCALIZED: Bogeys are not connected in order",
|
||||
"create.train_assembly.single_bogey_carriage": "UNLOCALIZED: This Bogey type cannot support a carriage on its own",
|
||||
"create.train_assembly.nothing_attached": "UNLOCALIZED: No structure attached to Bogey %1$s",
|
||||
"create.train_assembly.no_controls": "UNLOCALIZED: At least one forward-facing controls block needs to be mounted on the train",
|
||||
"create.train_assembly.sideways_controls": "UNLOCALIZED: A mounted controls block is facing sideways",
|
||||
|
||||
"create.track_target.set": "UNLOCALIZED: Targeted track selected",
|
||||
"create.track_target.success": "UNLOCALIZED: Successfully bound to targeted track",
|
||||
|
@ -1411,10 +1413,14 @@
|
|||
"create.train.relocate": "UNLOCALIZED: Click a Track to Relocate %1$s to. Sneak-Click to abort",
|
||||
"create.train.relocate.abort": "UNLOCALIZED: Relocation aborted",
|
||||
"create.train.relocate.success": "UNLOCALIZED: Relocation successful",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can be relocated here, Click to Confirm",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can relocate to here, Click to Confirm",
|
||||
"create.train.relocate.invalid": "UNLOCALIZED: Cannot relocate Train to this Track",
|
||||
"create.train.relocate.too_far": "UNLOCALIZED: Cannot relocate Train this far away",
|
||||
|
||||
"create.contraption.controls.start_controlling": "UNLOCALIZED: Now controlling: %1$s",
|
||||
"create.contraption.controls.stop_controlling": "UNLOCALIZED: Stopped controlling contraption",
|
||||
"create.contraption.controls.approach_station": "UNLOCALIZED: Hold %1$s to approach %2$s",
|
||||
|
||||
"create.gui.config.overlay1": "UNLOCALIZED: Hi :)",
|
||||
"create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay",
|
||||
"create.gui.config.overlay3": "UNLOCALIZED: Click or drag with your mouse",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 472",
|
||||
"_": "Missing Localizations: 477",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1399,6 +1399,8 @@
|
|||
"create.train_assembly.not_connected_in_order": "UNLOCALIZED: Bogeys are not connected in order",
|
||||
"create.train_assembly.single_bogey_carriage": "UNLOCALIZED: This Bogey type cannot support a carriage on its own",
|
||||
"create.train_assembly.nothing_attached": "UNLOCALIZED: No structure attached to Bogey %1$s",
|
||||
"create.train_assembly.no_controls": "UNLOCALIZED: At least one forward-facing controls block needs to be mounted on the train",
|
||||
"create.train_assembly.sideways_controls": "UNLOCALIZED: A mounted controls block is facing sideways",
|
||||
|
||||
"create.track_target.set": "UNLOCALIZED: Targeted track selected",
|
||||
"create.track_target.success": "UNLOCALIZED: Successfully bound to targeted track",
|
||||
|
@ -1411,10 +1413,14 @@
|
|||
"create.train.relocate": "UNLOCALIZED: Click a Track to Relocate %1$s to. Sneak-Click to abort",
|
||||
"create.train.relocate.abort": "UNLOCALIZED: Relocation aborted",
|
||||
"create.train.relocate.success": "UNLOCALIZED: Relocation successful",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can be relocated here, Click to Confirm",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can relocate to here, Click to Confirm",
|
||||
"create.train.relocate.invalid": "UNLOCALIZED: Cannot relocate Train to this Track",
|
||||
"create.train.relocate.too_far": "UNLOCALIZED: Cannot relocate Train this far away",
|
||||
|
||||
"create.contraption.controls.start_controlling": "UNLOCALIZED: Now controlling: %1$s",
|
||||
"create.contraption.controls.stop_controlling": "UNLOCALIZED: Stopped controlling contraption",
|
||||
"create.contraption.controls.approach_station": "UNLOCALIZED: Hold %1$s to approach %2$s",
|
||||
|
||||
"create.gui.config.overlay1": "Cześć :)",
|
||||
"create.gui.config.overlay2": "To jest przykładowa nakładka",
|
||||
"create.gui.config.overlay3": "Kliknij lub przeciągnij myszką",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 1656",
|
||||
"_": "Missing Localizations: 1661",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1399,6 +1399,8 @@
|
|||
"create.train_assembly.not_connected_in_order": "UNLOCALIZED: Bogeys are not connected in order",
|
||||
"create.train_assembly.single_bogey_carriage": "UNLOCALIZED: This Bogey type cannot support a carriage on its own",
|
||||
"create.train_assembly.nothing_attached": "UNLOCALIZED: No structure attached to Bogey %1$s",
|
||||
"create.train_assembly.no_controls": "UNLOCALIZED: At least one forward-facing controls block needs to be mounted on the train",
|
||||
"create.train_assembly.sideways_controls": "UNLOCALIZED: A mounted controls block is facing sideways",
|
||||
|
||||
"create.track_target.set": "UNLOCALIZED: Targeted track selected",
|
||||
"create.track_target.success": "UNLOCALIZED: Successfully bound to targeted track",
|
||||
|
@ -1411,10 +1413,14 @@
|
|||
"create.train.relocate": "UNLOCALIZED: Click a Track to Relocate %1$s to. Sneak-Click to abort",
|
||||
"create.train.relocate.abort": "UNLOCALIZED: Relocation aborted",
|
||||
"create.train.relocate.success": "UNLOCALIZED: Relocation successful",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can be relocated here, Click to Confirm",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can relocate to here, Click to Confirm",
|
||||
"create.train.relocate.invalid": "UNLOCALIZED: Cannot relocate Train to this Track",
|
||||
"create.train.relocate.too_far": "UNLOCALIZED: Cannot relocate Train this far away",
|
||||
|
||||
"create.contraption.controls.start_controlling": "UNLOCALIZED: Now controlling: %1$s",
|
||||
"create.contraption.controls.stop_controlling": "UNLOCALIZED: Stopped controlling contraption",
|
||||
"create.contraption.controls.approach_station": "UNLOCALIZED: Hold %1$s to approach %2$s",
|
||||
|
||||
"create.gui.config.overlay1": "UNLOCALIZED: Hi :)",
|
||||
"create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay",
|
||||
"create.gui.config.overlay3": "UNLOCALIZED: Click or drag with your mouse",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 1656",
|
||||
"_": "Missing Localizations: 1661",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1399,6 +1399,8 @@
|
|||
"create.train_assembly.not_connected_in_order": "UNLOCALIZED: Bogeys are not connected in order",
|
||||
"create.train_assembly.single_bogey_carriage": "UNLOCALIZED: This Bogey type cannot support a carriage on its own",
|
||||
"create.train_assembly.nothing_attached": "UNLOCALIZED: No structure attached to Bogey %1$s",
|
||||
"create.train_assembly.no_controls": "UNLOCALIZED: At least one forward-facing controls block needs to be mounted on the train",
|
||||
"create.train_assembly.sideways_controls": "UNLOCALIZED: A mounted controls block is facing sideways",
|
||||
|
||||
"create.track_target.set": "UNLOCALIZED: Targeted track selected",
|
||||
"create.track_target.success": "UNLOCALIZED: Successfully bound to targeted track",
|
||||
|
@ -1411,10 +1413,14 @@
|
|||
"create.train.relocate": "UNLOCALIZED: Click a Track to Relocate %1$s to. Sneak-Click to abort",
|
||||
"create.train.relocate.abort": "UNLOCALIZED: Relocation aborted",
|
||||
"create.train.relocate.success": "UNLOCALIZED: Relocation successful",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can be relocated here, Click to Confirm",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can relocate to here, Click to Confirm",
|
||||
"create.train.relocate.invalid": "UNLOCALIZED: Cannot relocate Train to this Track",
|
||||
"create.train.relocate.too_far": "UNLOCALIZED: Cannot relocate Train this far away",
|
||||
|
||||
"create.contraption.controls.start_controlling": "UNLOCALIZED: Now controlling: %1$s",
|
||||
"create.contraption.controls.stop_controlling": "UNLOCALIZED: Stopped controlling contraption",
|
||||
"create.contraption.controls.approach_station": "UNLOCALIZED: Hold %1$s to approach %2$s",
|
||||
|
||||
"create.gui.config.overlay1": "UNLOCALIZED: Hi :)",
|
||||
"create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay",
|
||||
"create.gui.config.overlay3": "UNLOCALIZED: Click or drag with your mouse",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 477",
|
||||
"_": "Missing Localizations: 482",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1399,6 +1399,8 @@
|
|||
"create.train_assembly.not_connected_in_order": "UNLOCALIZED: Bogeys are not connected in order",
|
||||
"create.train_assembly.single_bogey_carriage": "UNLOCALIZED: This Bogey type cannot support a carriage on its own",
|
||||
"create.train_assembly.nothing_attached": "UNLOCALIZED: No structure attached to Bogey %1$s",
|
||||
"create.train_assembly.no_controls": "UNLOCALIZED: At least one forward-facing controls block needs to be mounted on the train",
|
||||
"create.train_assembly.sideways_controls": "UNLOCALIZED: A mounted controls block is facing sideways",
|
||||
|
||||
"create.track_target.set": "UNLOCALIZED: Targeted track selected",
|
||||
"create.track_target.success": "UNLOCALIZED: Successfully bound to targeted track",
|
||||
|
@ -1411,10 +1413,14 @@
|
|||
"create.train.relocate": "UNLOCALIZED: Click a Track to Relocate %1$s to. Sneak-Click to abort",
|
||||
"create.train.relocate.abort": "UNLOCALIZED: Relocation aborted",
|
||||
"create.train.relocate.success": "UNLOCALIZED: Relocation successful",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can be relocated here, Click to Confirm",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can relocate to here, Click to Confirm",
|
||||
"create.train.relocate.invalid": "UNLOCALIZED: Cannot relocate Train to this Track",
|
||||
"create.train.relocate.too_far": "UNLOCALIZED: Cannot relocate Train this far away",
|
||||
|
||||
"create.contraption.controls.start_controlling": "UNLOCALIZED: Now controlling: %1$s",
|
||||
"create.contraption.controls.stop_controlling": "UNLOCALIZED: Stopped controlling contraption",
|
||||
"create.contraption.controls.approach_station": "UNLOCALIZED: Hold %1$s to approach %2$s",
|
||||
|
||||
"create.gui.config.overlay1": "Привет :)",
|
||||
"create.gui.config.overlay2": "Это образец оверлея",
|
||||
"create.gui.config.overlay3": "Кликни и тащи с помощью мыши",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 103",
|
||||
"_": "Missing Localizations: 108",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1399,6 +1399,8 @@
|
|||
"create.train_assembly.not_connected_in_order": "UNLOCALIZED: Bogeys are not connected in order",
|
||||
"create.train_assembly.single_bogey_carriage": "UNLOCALIZED: This Bogey type cannot support a carriage on its own",
|
||||
"create.train_assembly.nothing_attached": "UNLOCALIZED: No structure attached to Bogey %1$s",
|
||||
"create.train_assembly.no_controls": "UNLOCALIZED: At least one forward-facing controls block needs to be mounted on the train",
|
||||
"create.train_assembly.sideways_controls": "UNLOCALIZED: A mounted controls block is facing sideways",
|
||||
|
||||
"create.track_target.set": "UNLOCALIZED: Targeted track selected",
|
||||
"create.track_target.success": "UNLOCALIZED: Successfully bound to targeted track",
|
||||
|
@ -1411,10 +1413,14 @@
|
|||
"create.train.relocate": "UNLOCALIZED: Click a Track to Relocate %1$s to. Sneak-Click to abort",
|
||||
"create.train.relocate.abort": "UNLOCALIZED: Relocation aborted",
|
||||
"create.train.relocate.success": "UNLOCALIZED: Relocation successful",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can be relocated here, Click to Confirm",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can relocate to here, Click to Confirm",
|
||||
"create.train.relocate.invalid": "UNLOCALIZED: Cannot relocate Train to this Track",
|
||||
"create.train.relocate.too_far": "UNLOCALIZED: Cannot relocate Train this far away",
|
||||
|
||||
"create.contraption.controls.start_controlling": "UNLOCALIZED: Now controlling: %1$s",
|
||||
"create.contraption.controls.stop_controlling": "UNLOCALIZED: Stopped controlling contraption",
|
||||
"create.contraption.controls.approach_station": "UNLOCALIZED: Hold %1$s to approach %2$s",
|
||||
|
||||
"create.gui.config.overlay1": "Hi :)",
|
||||
"create.gui.config.overlay2": "这是一个实例层",
|
||||
"create.gui.config.overlay3": "点击拖拽你的鼠标",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 491",
|
||||
"_": "Missing Localizations: 496",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1399,6 +1399,8 @@
|
|||
"create.train_assembly.not_connected_in_order": "UNLOCALIZED: Bogeys are not connected in order",
|
||||
"create.train_assembly.single_bogey_carriage": "UNLOCALIZED: This Bogey type cannot support a carriage on its own",
|
||||
"create.train_assembly.nothing_attached": "UNLOCALIZED: No structure attached to Bogey %1$s",
|
||||
"create.train_assembly.no_controls": "UNLOCALIZED: At least one forward-facing controls block needs to be mounted on the train",
|
||||
"create.train_assembly.sideways_controls": "UNLOCALIZED: A mounted controls block is facing sideways",
|
||||
|
||||
"create.track_target.set": "UNLOCALIZED: Targeted track selected",
|
||||
"create.track_target.success": "UNLOCALIZED: Successfully bound to targeted track",
|
||||
|
@ -1411,10 +1413,14 @@
|
|||
"create.train.relocate": "UNLOCALIZED: Click a Track to Relocate %1$s to. Sneak-Click to abort",
|
||||
"create.train.relocate.abort": "UNLOCALIZED: Relocation aborted",
|
||||
"create.train.relocate.success": "UNLOCALIZED: Relocation successful",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can be relocated here, Click to Confirm",
|
||||
"create.train.relocate.valid": "UNLOCALIZED: Can relocate to here, Click to Confirm",
|
||||
"create.train.relocate.invalid": "UNLOCALIZED: Cannot relocate Train to this Track",
|
||||
"create.train.relocate.too_far": "UNLOCALIZED: Cannot relocate Train this far away",
|
||||
|
||||
"create.contraption.controls.start_controlling": "UNLOCALIZED: Now controlling: %1$s",
|
||||
"create.contraption.controls.stop_controlling": "UNLOCALIZED: Stopped controlling contraption",
|
||||
"create.contraption.controls.approach_station": "UNLOCALIZED: Hold %1$s to approach %2$s",
|
||||
|
||||
"create.gui.config.overlay1": "嗨 :)",
|
||||
"create.gui.config.overlay2": "這是一個實例層",
|
||||
"create.gui.config.overlay3": "點擊拖拽你的滑鼠",
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
"trigger": "create:bracket_apply",
|
||||
"conditions": {
|
||||
"accepted_entries": [
|
||||
"create:large_cogwheel",
|
||||
"create:cogwheel"
|
||||
"create:cogwheel",
|
||||
"create:large_cogwheel"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
|
|
@ -11,6 +11,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Mov
|
|||
import com.simibubi.create.content.contraptions.components.structureMovement.interaction.DoorMovingInteraction;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.interaction.LeverMovingInteraction;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.interaction.TrapdoorMovingInteraction;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls.ControlsInteractionBehaviour;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
@ -49,6 +50,7 @@ public class AllInteractionBehaviours {
|
|||
static void register() {
|
||||
addInteractionBehaviour(Blocks.LEVER.getRegistryName(), LeverMovingInteraction::new);
|
||||
addInteractionBehaviour(AllBlocks.DEPLOYER.getId(), DeployerMovingInteraction::new);
|
||||
addInteractionBehaviour(AllBlocks.CONTROLS.getId(), ControlsInteractionBehaviour::new);
|
||||
|
||||
// TODO: Scan registry for instanceof (-> modded door support)
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ public class AllShapes {
|
|||
|
||||
STATION = shape(0, 0, 0, 16, 5, 16).add(2, 4, 0, 14, 16, 4)
|
||||
.forHorizontal(NORTH),
|
||||
CONTROLS = shape(0, 0, 4, 16, 8, 16).add(0, 0, 6, 16, 14, 16)
|
||||
CONTROLS = shape(0, 0, 4, 16, 4, 16).add(0, 0, 6, 16, 14, 16)
|
||||
.forHorizontal(NORTH)
|
||||
|
||||
;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -31,6 +32,7 @@ import net.minecraft.core.Direction;
|
|||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtIo;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.syncher.EntityDataAccessor;
|
||||
import net.minecraft.network.syncher.EntityDataSerializers;
|
||||
|
@ -161,6 +163,20 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
|||
.size();
|
||||
}
|
||||
|
||||
public Component getContraptionName() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
public boolean startControlling(BlockPos controlsLocalPos) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean control(BlockPos controlsLocalPos, Collection<Integer> heldControls, Player player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void stopControlling(BlockPos controlsLocalPos) {}
|
||||
|
||||
public boolean handlePlayerInteraction(Player player, BlockPos localPos, Direction side,
|
||||
InteractionHand interactionHand) {
|
||||
int indexOfSeat = contraption.getSeats()
|
||||
|
@ -168,7 +184,9 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
|||
if (indexOfSeat == -1)
|
||||
return contraption.interactors.containsKey(localPos) && contraption.interactors.get(localPos)
|
||||
.handlePlayerInteraction(player, interactionHand, localPos, this);
|
||||
|
||||
if (player.isPassenger())
|
||||
return false;
|
||||
|
||||
// Eject potential existing passenger
|
||||
Entity toDismount = null;
|
||||
for (Entry<UUID, Integer> entry : contraption.getSeatMapping()
|
||||
|
@ -223,7 +241,9 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
|||
return;
|
||||
}
|
||||
|
||||
collidingEntities.entrySet().removeIf(e -> e.getValue().incrementAndGet() > 3);
|
||||
collidingEntities.entrySet()
|
||||
.removeIf(e -> e.getValue()
|
||||
.incrementAndGet() > 3);
|
||||
|
||||
xo = getX();
|
||||
yo = getY();
|
||||
|
@ -441,7 +461,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
|||
return;
|
||||
if (contraption == null)
|
||||
return;
|
||||
|
||||
|
||||
StructureTransform transform = makeStructureTransform();
|
||||
AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> this),
|
||||
new ContraptionDisassemblyPacket(this.getId(), transform));
|
||||
|
|
|
@ -13,8 +13,8 @@ import com.simibubi.create.content.logistics.trains.entity.TrainRelocator;
|
|||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
import com.simibubi.create.foundation.utility.RaycastHelper;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.foundation.utility.RaycastHelper.PredicateTraceResult;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
|
@ -74,8 +74,6 @@ public class ContraptionHandlerClient {
|
|||
|
||||
if (player == null)
|
||||
return;
|
||||
if (player.isPassenger())
|
||||
return;
|
||||
if (mc.level == null)
|
||||
return;
|
||||
if (!event.isUseItem())
|
||||
|
@ -84,7 +82,7 @@ public class ContraptionHandlerClient {
|
|||
Couple<Vec3> rayInputs = getRayInputs(player);
|
||||
Vec3 origin = rayInputs.getFirst();
|
||||
Vec3 target = rayInputs.getSecond();
|
||||
AABB aabb = new AABB(origin, target);
|
||||
AABB aabb = new AABB(origin, target).inflate(4);
|
||||
List<AbstractContraptionEntity> intersectingContraptions =
|
||||
mc.level.getEntitiesOfClass(AbstractContraptionEntity.class, aabb);
|
||||
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import com.mojang.blaze3d.platform.InputConstants;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
|
||||
import com.simibubi.create.foundation.utility.ControlsUtil;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.client.KeyMapping;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
||||
public class ControlsHandler {
|
||||
|
||||
public static Collection<Integer> currentlyPressed = new HashSet<>();
|
||||
|
||||
public static int PACKET_RATE = 5;
|
||||
static int packetCooldown;
|
||||
|
||||
static WeakReference<AbstractContraptionEntity> entityRef = new WeakReference<>(null);
|
||||
static BlockPos controlsPos;
|
||||
|
||||
public static void controllerClicked(AbstractContraptionEntity entity, BlockPos controllerLocalPos) {
|
||||
AbstractContraptionEntity prevEntity = entityRef.get();
|
||||
if (prevEntity != null) {
|
||||
stopControlling();
|
||||
if (prevEntity == entity)
|
||||
return;
|
||||
}
|
||||
if (!entity.startControlling(controllerLocalPos))
|
||||
return;
|
||||
entityRef = new WeakReference<AbstractContraptionEntity>(entity);
|
||||
controlsPos = controllerLocalPos;
|
||||
Minecraft.getInstance().player.displayClientMessage(
|
||||
Lang.translate("contraption.controls.start_controlling", entity.getContraptionName()), true);
|
||||
}
|
||||
|
||||
public static void stopControlling() {
|
||||
AbstractContraptionEntity abstractContraptionEntity = entityRef.get();
|
||||
if (abstractContraptionEntity != null)
|
||||
abstractContraptionEntity.stopControlling(controlsPos);
|
||||
ControlsUtil.getControls()
|
||||
.forEach(kb -> kb.setDown(ControlsUtil.isActuallyPressed(kb)));
|
||||
packetCooldown = 0;
|
||||
entityRef = new WeakReference<>(null);
|
||||
controlsPos = null;
|
||||
// if (!currentlyPressed.isEmpty())
|
||||
// AllPackets.channel.sendToServer(new LinkedControllerInputPacket(currentlyPressed, false));
|
||||
currentlyPressed.clear();
|
||||
Minecraft.getInstance().player.displayClientMessage(Lang.translate("contraption.controls.stop_controlling"),
|
||||
true);
|
||||
}
|
||||
|
||||
public static void tick() {
|
||||
AbstractContraptionEntity entity = entityRef.get();
|
||||
if (entity == null)
|
||||
return;
|
||||
if (packetCooldown > 0)
|
||||
packetCooldown--;
|
||||
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
LocalPlayer player = mc.player;
|
||||
|
||||
if (player.isSpectator()) {
|
||||
stopControlling();
|
||||
return;
|
||||
}
|
||||
if (InputConstants.isKeyDown(mc.getWindow()
|
||||
.getWindow(), GLFW.GLFW_KEY_ESCAPE)) {
|
||||
stopControlling();
|
||||
return;
|
||||
}
|
||||
if (!entity.toGlobalVector(VecHelper.getCenterOf(controlsPos), 1)
|
||||
.closerThan(player.position(), 10)) {
|
||||
stopControlling();
|
||||
return;
|
||||
}
|
||||
|
||||
Vector<KeyMapping> controls = ControlsUtil.getControls();
|
||||
Collection<Integer> pressedKeys = new HashSet<>();
|
||||
for (int i = 0; i < controls.size(); i++) {
|
||||
if (ControlsUtil.isActuallyPressed(controls.get(i)))
|
||||
pressedKeys.add(i);
|
||||
}
|
||||
|
||||
Collection<Integer> newKeys = new HashSet<>(pressedKeys);
|
||||
Collection<Integer> releasedKeys = currentlyPressed;
|
||||
newKeys.removeAll(releasedKeys);
|
||||
releasedKeys.removeAll(pressedKeys);
|
||||
|
||||
// Released Keys
|
||||
if (!releasedKeys.isEmpty()) {
|
||||
// AllPackets.channel.sendToServer(new LinkedControllerInputPacket(releasedKeys, false, lecternPos));
|
||||
// AllSoundEvents.CONTROLLER_CLICK.playAt(player.level, player.blockPosition(), 1f, .5f, true);
|
||||
}
|
||||
|
||||
// Newly Pressed Keys
|
||||
if (!newKeys.isEmpty()) {
|
||||
if (newKeys.contains(Integer.valueOf(5))) {
|
||||
stopControlling();
|
||||
return;
|
||||
}
|
||||
|
||||
// AllPackets.channel.sendToServer(new LinkedControllerInputPacket(newKeys, true, lecternPos));
|
||||
// packetCooldown = PACKET_RATE;
|
||||
// AllSoundEvents.CONTROLLER_CLICK.playAt(player.level, player.blockPosition(), 1f, .75f, true);
|
||||
}
|
||||
|
||||
// Keepalive Pressed Keys
|
||||
if (packetCooldown == 0) {
|
||||
// if (!pressedKeys.isEmpty()) {
|
||||
// AllPackets.channel.sendToServer(new LinkedControllerInputPacket(pressedKeys, true, lecternPos));
|
||||
// packetCooldown = PACKET_RATE;
|
||||
// }
|
||||
}
|
||||
|
||||
// TODO do this server side
|
||||
if (!entity.control(controlsPos, pressedKeys, player)) {
|
||||
stopControlling();
|
||||
return;
|
||||
}
|
||||
|
||||
currentlyPressed = pressedKeys;
|
||||
controls.forEach(kb -> kb.setDown(false));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls;
|
||||
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.MovingInteractionBehaviour;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
|
||||
public class ControlsInteractionBehaviour extends MovingInteractionBehaviour {
|
||||
|
||||
@Override
|
||||
public boolean handlePlayerInteraction(Player player, InteractionHand activeHand, BlockPos localPos,
|
||||
AbstractContraptionEntity contraptionEntity) {
|
||||
if (player.level.isClientSide)
|
||||
ControlsHandler.controllerClicked(contraptionEntity, localPos);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,9 +1,16 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionMatrices;
|
||||
import com.simibubi.create.content.logistics.trains.entity.Carriage;
|
||||
import com.simibubi.create.content.logistics.trains.entity.CarriageContraptionEntity;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
|
||||
import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser;
|
||||
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
|
@ -11,11 +18,38 @@ import net.minecraftforge.api.distmarker.OnlyIn;
|
|||
|
||||
public class ControlsMovementBehaviour extends MovementBehaviour {
|
||||
|
||||
// TODO: this is specific to Carriage Contraptions - need to move this behaviour
|
||||
// there
|
||||
LerpedFloat steering = LerpedFloat.linear();
|
||||
LerpedFloat speed = LerpedFloat.linear();
|
||||
LerpedFloat equipAnimation = LerpedFloat.linear();
|
||||
|
||||
@Override
|
||||
public void tick(MovementContext context) {
|
||||
steering.tickChaser();
|
||||
speed.tickChaser();
|
||||
equipAnimation.tickChaser();
|
||||
super.tick(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld,
|
||||
ContraptionMatrices matrices, MultiBufferSource buffer) {
|
||||
ControlsRenderer.render(context, renderWorld, matrices, buffer);
|
||||
if (ControlsHandler.entityRef.get() == context.contraption.entity && ControlsHandler.controlsPos != null
|
||||
&& ControlsHandler.controlsPos.equals(context.localPos)) {
|
||||
Collection<Integer> pressed = ControlsHandler.currentlyPressed;
|
||||
equipAnimation.chase(1, .2f, Chaser.EXP);
|
||||
steering.chase((pressed.contains(3) ? 1 : 0) + (pressed.contains(2) ? -1 : 0), 0.2f, Chaser.EXP);
|
||||
if (context.contraption.entity instanceof CarriageContraptionEntity car) {
|
||||
Carriage carriage = car.getCarriage();
|
||||
speed.chase(Math.abs(carriage.train.speed), 0.2f, Chaser.EXP);
|
||||
}
|
||||
} else
|
||||
equipAnimation.chase(0, .2f, Chaser.EXP);
|
||||
float pt = AnimationTickHolder.getPartialTicks(context.world);
|
||||
ControlsRenderer.render(context, renderWorld, matrices, buffer, equipAnimation.getValue(pt), speed.getValue(pt),
|
||||
steering.getValue(pt));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls;
|
||||
|
||||
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
|
||||
import com.jozufozu.flywheel.util.transform.MatrixTransformStack;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.simibubi.create.AllBlockPartials;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionMatrices;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
||||
|
@ -16,38 +17,43 @@ import net.minecraft.client.renderer.RenderType;
|
|||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class ControlsRenderer {
|
||||
|
||||
public static void render(MovementContext context, VirtualRenderWorld renderWorld, ContraptionMatrices matrices,
|
||||
MultiBufferSource buffer) {
|
||||
MultiBufferSource buffer, float equipAnimation, float firstLever, float secondLever) {
|
||||
BlockState state = context.state;
|
||||
Direction facing = state.getValue(ControlsBlock.FACING);
|
||||
|
||||
SuperByteBuffer cover = CachedBufferer.partial(AllBlockPartials.TRAIN_CONTROLS_COVER, state);
|
||||
float hAngle = 180 + AngleHelper.horizontalAngle(facing);
|
||||
cover.transform(matrices.getModel())
|
||||
PoseStack ms = matrices.getModel();
|
||||
cover.transform(ms)
|
||||
.centre()
|
||||
.rotateY(hAngle)
|
||||
.unCentre()
|
||||
.light(matrices.getWorld(), ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld))
|
||||
.renderInto(matrices.getViewProjection(), buffer.getBuffer(RenderType.solid()));
|
||||
|
||||
double yOffset = Mth.lerp(equipAnimation * equipAnimation, -0.15f, 0.05f);
|
||||
|
||||
for (boolean first : Iterate.trueAndFalse) {
|
||||
AbstractContraptionEntity entity = context.contraption.entity;
|
||||
double motion = entity.position()
|
||||
.distanceTo(new Vec3(entity.xo, entity.yo, entity.zo));
|
||||
float vAngle = (float) Mth.clamp(first ? motion * 45 : 0, -45, 45);
|
||||
float vAngle = (float) Mth.clamp(first ? firstLever * 70 - 25 : secondLever * 15, -45, 45);
|
||||
SuperByteBuffer lever = CachedBufferer.partial(AllBlockPartials.TRAIN_CONTROLS_LEVER, state);
|
||||
lever.transform(matrices.getModel())
|
||||
.centre()
|
||||
ms.pushPose();
|
||||
new MatrixTransformStack(ms).centre()
|
||||
.rotateY(hAngle)
|
||||
.rotateX(vAngle)
|
||||
.translate(0, 0, 4 / 16f)
|
||||
.rotateX(vAngle - 45)
|
||||
.translate(0, yOffset, 0)
|
||||
.rotateX(45)
|
||||
.unCentre()
|
||||
.translate(first ? 0 : 6 / 16f, 0, 0)
|
||||
.translate(0, -2 / 16f, -3 / 16f)
|
||||
.translate(first ? 0 : 6 / 16f, 0, 0);
|
||||
lever.transform(ms)
|
||||
.light(matrices.getWorld(), ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld))
|
||||
.renderInto(matrices.getViewProjection(), buffer.getBuffer(RenderType.solid()));
|
||||
ms.popPose();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,12 +18,12 @@ import com.simibubi.create.foundation.item.TooltipHelper;
|
|||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.linked.LinkBehaviour;
|
||||
import com.simibubi.create.foundation.utility.ControlsUtil;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.KeyMapping;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.Options;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -43,24 +43,8 @@ public class LinkedControllerClientHandler {
|
|||
public static Collection<Integer> currentlyPressed = new HashSet<>();
|
||||
private static BlockPos lecternPos;
|
||||
private static BlockPos selectedLocation = BlockPos.ZERO;
|
||||
private static Vector<KeyMapping> controls;
|
||||
|
||||
private static int packetCooldown;
|
||||
|
||||
public static Vector<KeyMapping> getControls() {
|
||||
if (controls == null) {
|
||||
Options gameSettings = Minecraft.getInstance().options;
|
||||
controls = new Vector<>(6);
|
||||
controls.add(gameSettings.keyUp);
|
||||
controls.add(gameSettings.keyDown);
|
||||
controls.add(gameSettings.keyLeft);
|
||||
controls.add(gameSettings.keyRight);
|
||||
controls.add(gameSettings.keyJump);
|
||||
controls.add(gameSettings.keyShift);
|
||||
}
|
||||
return controls;
|
||||
}
|
||||
|
||||
public static void toggleBindMode(BlockPos location) {
|
||||
if (MODE == Mode.IDLE) {
|
||||
MODE = Mode.BIND;
|
||||
|
@ -100,7 +84,7 @@ public class LinkedControllerClientHandler {
|
|||
}
|
||||
|
||||
protected static void onReset() {
|
||||
getControls().forEach(kb -> kb.setDown(isActuallyPressed(kb)));
|
||||
ControlsUtil.getControls().forEach(kb -> kb.setDown(ControlsUtil.isActuallyPressed(kb)));
|
||||
packetCooldown = 0;
|
||||
selectedLocation = BlockPos.ZERO;
|
||||
|
||||
|
@ -115,14 +99,6 @@ public class LinkedControllerClientHandler {
|
|||
LinkedControllerItemRenderer.resetButtons();
|
||||
}
|
||||
|
||||
protected static boolean isActuallyPressed(KeyMapping kb) {
|
||||
return InputConstants.isKeyDown(Minecraft.getInstance()
|
||||
.getWindow()
|
||||
.getWindow(),
|
||||
kb.getKey()
|
||||
.getValue());
|
||||
}
|
||||
|
||||
public static void tick() {
|
||||
LinkedControllerItemRenderer.tick();
|
||||
|
||||
|
@ -169,10 +145,10 @@ public class LinkedControllerClientHandler {
|
|||
return;
|
||||
}
|
||||
|
||||
Vector<KeyMapping> controls = getControls();
|
||||
Vector<KeyMapping> controls = ControlsUtil.getControls();
|
||||
Collection<Integer> pressedKeys = new HashSet<>();
|
||||
for (int i = 0; i < controls.size(); i++) {
|
||||
if (isActuallyPressed(controls.get(i)))
|
||||
if (ControlsUtil.isActuallyPressed(controls.get(i)))
|
||||
pressedKeys.add(i);
|
||||
}
|
||||
|
||||
|
@ -240,7 +216,7 @@ public class LinkedControllerClientHandler {
|
|||
tooltipScreen.init(mc, width1, height1);
|
||||
|
||||
Object[] keys = new Object[6];
|
||||
Vector<KeyMapping> controls = getControls();
|
||||
Vector<KeyMapping> controls = ControlsUtil.getControls();
|
||||
for (int i = 0; i < controls.size(); i++) {
|
||||
KeyMapping keyBinding = controls.get(i);
|
||||
keys[i] = keyBinding.getTranslatedKeyMessage()
|
||||
|
|
|
@ -13,6 +13,7 @@ import com.simibubi.create.foundation.gui.AllIcons;
|
|||
import com.simibubi.create.foundation.gui.container.AbstractSimiContainerScreen;
|
||||
import com.simibubi.create.foundation.gui.element.GuiGameElement;
|
||||
import com.simibubi.create.foundation.gui.widget.IconButton;
|
||||
import com.simibubi.create.foundation.utility.ControlsUtil;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
|
||||
import net.minecraft.ChatFormatting;
|
||||
|
@ -112,7 +113,7 @@ public class LinkedControllerScreen extends AbstractSimiContainerScreen<LinkedCo
|
|||
return list;
|
||||
list.add(Lang
|
||||
.createTranslationTextComponent("linked_controller.frequency_slot_" + ((slot % 2) + 1),
|
||||
LinkedControllerClientHandler.getControls()
|
||||
ControlsUtil.getControls()
|
||||
.get(slot / 2)
|
||||
.getTranslatedKeyMessage()
|
||||
.getString())
|
||||
|
|
|
@ -43,7 +43,7 @@ public class Carriage {
|
|||
this.bogeys = Couple.create(bogey1, bogey2);
|
||||
this.entity = new WeakReference<>(null);
|
||||
this.id = netIdGenerator.incrementAndGet();
|
||||
|
||||
|
||||
bogey1.carriage = this;
|
||||
if (bogey2 != null)
|
||||
bogey2.carriage = this;
|
||||
|
@ -59,7 +59,8 @@ public class Carriage {
|
|||
}
|
||||
|
||||
public double travel(Level level, TrackGraph graph, double distance,
|
||||
@Nullable Function<TravellingPoint, ITrackSelector> control) {
|
||||
Function<TravellingPoint, ITrackSelector> forwardControl,
|
||||
Function<TravellingPoint, ITrackSelector> backwardControl) {
|
||||
Vec3 leadingAnchor = leadingBogey().anchorPosition;
|
||||
Vec3 trailingAnchor = trailingBogey().anchorPosition;
|
||||
boolean onTwoBogeys = isOnTwoBogeys();
|
||||
|
@ -86,14 +87,20 @@ public class Carriage {
|
|||
|
||||
bogey.points.forEachWithContext((point, first) -> {
|
||||
TravellingPoint prevPoint = previous.getValue();
|
||||
ITrackSelector trackSelector =
|
||||
prevPoint == null ? control == null ? point.random() : control.apply(point)
|
||||
: point.follow(prevPoint);
|
||||
TravellingPoint nextPoint = first ? bogey.points.getSecond()
|
||||
: firstBogey && onTwoBogeys ? bogeys.getSecond().points.getFirst() : null;
|
||||
|
||||
double correction = bogeyStress * (first ? leadingPointModifier : trailingPointModifier);
|
||||
double toMove = distanceMoved.getValue();
|
||||
double moved = point.travel(graph, toMove, trackSelector);
|
||||
point.travel(graph, correction + bogeyCorrection, trackSelector);
|
||||
|
||||
ITrackSelector frontTrackSelector =
|
||||
prevPoint == null ? forwardControl.apply(point) : point.follow(prevPoint);
|
||||
ITrackSelector backTrackSelector =
|
||||
nextPoint == null ? backwardControl.apply(point) : point.follow(nextPoint);
|
||||
|
||||
double moved = point.travel(graph, toMove, toMove > 0 ? frontTrackSelector : backTrackSelector);
|
||||
point.travel(graph, correction + bogeyCorrection,
|
||||
correction + bogeyCorrection > 0 ? frontTrackSelector : backTrackSelector);
|
||||
blocked |= point.blocked;
|
||||
|
||||
distanceMoved.setValue(moved);
|
||||
|
@ -201,9 +208,9 @@ public class Carriage {
|
|||
|
||||
public Vec3 leadingCouplingAnchor;
|
||||
public Vec3 trailingCouplingAnchor;
|
||||
|
||||
|
||||
int derailAngle;
|
||||
|
||||
|
||||
public CarriageBogey(IBogeyBlock type, TravellingPoint point, TravellingPoint point2) {
|
||||
this.type = type;
|
||||
points = Couple.create(point, point2);
|
||||
|
@ -223,11 +230,11 @@ public class Carriage {
|
|||
double diffZ = positionVec.z - coupledVec.z;
|
||||
float yRot = AngleHelper.deg(Mth.atan2(diffZ, diffX)) + 90;
|
||||
float xRot = AngleHelper.deg(Math.atan2(diffY, Math.sqrt(diffX * diffX + diffZ * diffZ)));
|
||||
|
||||
|
||||
if (carriage.train.derailed)
|
||||
yRot += derailAngle;
|
||||
|
||||
wheelAngle.setValue((wheelAngle.getValue() - angleDiff) % 360);
|
||||
|
||||
wheelAngle.setValue((wheelAngle.getValue() - angleDiff * Math.signum(carriage.train.speed)) % 360);
|
||||
pitch.setValue(xRot);
|
||||
yaw.setValue(-yRot);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Con
|
|||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionLighter;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionType;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.NonStationaryLighter;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls.ControlsBlock;
|
||||
import com.simibubi.create.content.logistics.trains.IBogeyBlock;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||
|
@ -24,7 +25,10 @@ public class CarriageContraption extends Contraption {
|
|||
|
||||
private Direction assemblyDirection;
|
||||
|
||||
private boolean controls;
|
||||
private boolean forwardControls;
|
||||
private boolean backwardControls;
|
||||
private boolean sidewaysControls;
|
||||
|
||||
private int bogeys;
|
||||
private BlockPos secondBogeyPos;
|
||||
|
||||
|
@ -48,6 +52,8 @@ public class CarriageContraption extends Contraption {
|
|||
return false;
|
||||
if (bogeys > 2)
|
||||
throw new AssemblyException(Lang.translate("train_assembly.too_many_bogeys", bogeys));
|
||||
if (sidewaysControls)
|
||||
throw new AssemblyException(Lang.translate("train_assembly.sideways_controls"));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -67,8 +73,15 @@ public class CarriageContraption extends Contraption {
|
|||
return Pair.of(new StructureBlockInfo(pos, blockState, null), null);
|
||||
}
|
||||
|
||||
if (AllBlocks.CONTROLS.has(blockState))
|
||||
controls = true;
|
||||
if (AllBlocks.CONTROLS.has(blockState)) {
|
||||
Direction facing = blockState.getValue(ControlsBlock.FACING);
|
||||
if (facing.getAxis() != assemblyDirection.getAxis())
|
||||
sidewaysControls = true;
|
||||
else if (facing == assemblyDirection)
|
||||
forwardControls = true;
|
||||
else
|
||||
backwardControls = true;
|
||||
}
|
||||
|
||||
return super.capture(world, pos);
|
||||
}
|
||||
|
@ -79,7 +92,8 @@ public class CarriageContraption extends Contraption {
|
|||
NBTHelper.writeEnum(tag, "AssemblyDirection", getAssemblyDirection());
|
||||
if (spawnPacket)
|
||||
tag.putInt("CarriageId", carriage.id);
|
||||
tag.putBoolean("Controls", hasControls());
|
||||
tag.putBoolean("FrontControls", forwardControls);
|
||||
tag.putBoolean("BackControls", backwardControls);
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
@ -88,7 +102,8 @@ public class CarriageContraption extends Contraption {
|
|||
assemblyDirection = NBTHelper.readEnum(nbt, "AssemblyDirection", Direction.class);
|
||||
if (spawnData)
|
||||
temporaryCarriageIdHolder = nbt.getInt("CarriageId");
|
||||
controls = nbt.getBoolean("Controls");
|
||||
forwardControls = nbt.getBoolean("FrontControls");
|
||||
backwardControls = nbt.getBoolean("BackControls");
|
||||
super.readNBT(world, nbt, spawnData);
|
||||
}
|
||||
|
||||
|
@ -120,8 +135,12 @@ public class CarriageContraption extends Contraption {
|
|||
return carriage;
|
||||
}
|
||||
|
||||
public boolean hasControls() {
|
||||
return controls;
|
||||
public boolean hasForwardControls() {
|
||||
return forwardControls;
|
||||
}
|
||||
|
||||
public boolean hasBackwardControls() {
|
||||
return backwardControls;
|
||||
}
|
||||
|
||||
public BlockPos getSecondBogeyPos() {
|
||||
|
|
|
@ -1,14 +1,34 @@
|
|||
package com.simibubi.create.content.logistics.trains.entity;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.simibubi.create.AllEntityTypes;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.OrientedContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls.ControlsBlock;
|
||||
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.SteerDirection;
|
||||
import com.simibubi.create.content.logistics.trains.management.GlobalStation;
|
||||
import com.simibubi.create.foundation.utility.Color;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.TextComponent;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
|
||||
public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
||||
|
||||
|
@ -30,16 +50,158 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
|||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getContraptionName() {
|
||||
Carriage carriage = getCarriage();
|
||||
if (carriage != null)
|
||||
return carriage.train.name;
|
||||
Component contraptionName = super.getContraptionName();
|
||||
return contraptionName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startControlling(BlockPos controlsLocalPos) {
|
||||
Carriage carriage = getCarriage();
|
||||
if (carriage == null)
|
||||
return false;
|
||||
if (carriage.train.derailed)
|
||||
return false;
|
||||
|
||||
Train train = carriage.train;
|
||||
if (train.runtime.getSchedule() != null && !train.runtime.paused)
|
||||
train.status.manualControls();
|
||||
train.navigation.cancelNavigation();
|
||||
train.runtime.paused = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
double navDistanceTotal = 0;
|
||||
|
||||
@Override
|
||||
public boolean control(BlockPos controlsLocalPos, Collection<Integer> heldControls, Player player) {
|
||||
Carriage carriage = getCarriage();
|
||||
if (carriage == null)
|
||||
return false;
|
||||
if (carriage.train.derailed)
|
||||
return false;
|
||||
|
||||
StructureBlockInfo info = contraption.getBlocks()
|
||||
.get(controlsLocalPos);
|
||||
Direction initialOrientation = getInitialOrientation().getCounterClockWise();
|
||||
boolean inverted = false;
|
||||
if (info != null && info.state.hasProperty(ControlsBlock.FACING))
|
||||
inverted = !info.state.getValue(ControlsBlock.FACING)
|
||||
.equals(initialOrientation);
|
||||
|
||||
int targetSpeed = 0;
|
||||
if (heldControls.contains(0))
|
||||
targetSpeed++;
|
||||
if (heldControls.contains(1))
|
||||
targetSpeed--;
|
||||
|
||||
int targetSteer = 0;
|
||||
if (heldControls.contains(2))
|
||||
targetSteer++;
|
||||
if (heldControls.contains(3))
|
||||
targetSteer--;
|
||||
|
||||
if (inverted) {
|
||||
targetSpeed *= -1;
|
||||
// targetSteer *= -1;
|
||||
}
|
||||
|
||||
boolean spaceDown = heldControls.contains(4);
|
||||
GlobalStation currentStation = carriage.train.getCurrentStation();
|
||||
if (currentStation != null && spaceDown) {
|
||||
player.displayClientMessage(new TextComponent("<i> Arrived at ").withStyle(ChatFormatting.GREEN)
|
||||
.append(new TextComponent(currentStation.name).withStyle(ChatFormatting.WHITE)), true);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (currentStation != null && targetSpeed != 0) {
|
||||
stationMessage = false;
|
||||
player.displayClientMessage(new TextComponent("<i> Departing from ").withStyle(ChatFormatting.YELLOW)
|
||||
.append(new TextComponent(currentStation.name).withStyle(ChatFormatting.WHITE)), true);
|
||||
}
|
||||
|
||||
if (currentStation == null && targetSpeed >= 0) {
|
||||
Navigation nav = carriage.train.navigation;
|
||||
if (nav.destination != null) {
|
||||
if (!spaceDown)
|
||||
nav.cancelNavigation();
|
||||
if (spaceDown) {
|
||||
double f = (nav.distanceToDestination / navDistanceTotal);
|
||||
int progress = (int) (Mth.clamp(1 - ((1 - f) * (1 - f)), 0, 1) * 30);
|
||||
boolean arrived = progress == 0;
|
||||
TextComponent whiteComponent =
|
||||
new TextComponent(Strings.repeat("|", progress) + (arrived ? " ->" : " <-"));
|
||||
TextComponent greenComponent =
|
||||
new TextComponent((arrived ? "<- " : "-> ") + Strings.repeat("|", 30 - progress));
|
||||
int mixedColor = Color.mixColors(0xff_91EA44, 0xff_FFC244, progress / 30f);
|
||||
int targetColor = arrived ? 0xff_91EA44 : 0xff_ffffff;
|
||||
player.displayClientMessage(greenComponent.withStyle(st -> st.withColor(mixedColor))
|
||||
.append(whiteComponent.withStyle(st -> st.withColor(targetColor))), true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
GlobalStation lookAhead = nav.findNearestApproachable();
|
||||
if (lookAhead != null) {
|
||||
if (spaceDown) {
|
||||
nav.startNavigation(lookAhead, false);
|
||||
navDistanceTotal = nav.distanceToDestination;
|
||||
return true;
|
||||
}
|
||||
if (level.isClientSide)
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> displayApproachStationMessage(lookAhead));
|
||||
} else {
|
||||
if (level.isClientSide)
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> this::cleanUpApproachStationMessage);
|
||||
}
|
||||
}
|
||||
|
||||
carriage.train.manualSteer =
|
||||
targetSteer < 0 ? SteerDirection.RIGHT : targetSteer > 0 ? SteerDirection.LEFT : SteerDirection.NONE;
|
||||
carriage.train.targetSpeed = Train.topSpeed * targetSpeed;
|
||||
if (inverted ^ targetSpeed < 0)
|
||||
carriage.train.targetSpeed /= 8;
|
||||
boolean counteringAcceleration = Math.abs(Math.signum(targetSpeed) - Math.signum(carriage.train.speed)) > 1.5f;
|
||||
carriage.train.manualTick = true;
|
||||
carriage.train.approachTargetSpeed(counteringAcceleration ? 2 : 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean stationMessage = false;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
private void displayApproachStationMessage(GlobalStation station) {
|
||||
Minecraft instance = Minecraft.getInstance();
|
||||
instance.player.displayClientMessage(Lang.translate("contraption.controls.approach_station",
|
||||
instance.options.keyJump.getTranslatedKeyMessage(), station.name), true);
|
||||
stationMessage = true;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
private void cleanUpApproachStationMessage() {
|
||||
if (!stationMessage)
|
||||
return;
|
||||
Minecraft instance = Minecraft.getInstance();
|
||||
instance.player.displayClientMessage(new TextComponent(""), true);
|
||||
stationMessage = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tickContraption() {
|
||||
if (!(contraption instanceof CarriageContraption))
|
||||
return;
|
||||
int id = ((CarriageContraption) contraption).temporaryCarriageIdHolder;
|
||||
Carriage carriage = Create.RAILWAYS.carriageById.get(id); // TODO: thread breach
|
||||
Carriage carriage = getCarriage();
|
||||
if (carriage == null) {
|
||||
discard();
|
||||
return;
|
||||
}
|
||||
|
||||
tickActors();
|
||||
|
||||
if (!level.isClientSide)
|
||||
return;
|
||||
|
||||
|
@ -61,6 +223,12 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
|||
|
||||
}
|
||||
|
||||
public Carriage getCarriage() {
|
||||
int id = ((CarriageContraption) contraption).temporaryCarriageIdHolder;
|
||||
Carriage carriage = Create.RAILWAYS.carriageById.get(id); // TODO: thread breach
|
||||
return carriage;
|
||||
}
|
||||
|
||||
Vec3 derailParticleOffset = VecHelper.offsetRandomly(Vec3.ZERO, Create.RANDOM, 1.5f)
|
||||
.multiply(1, .25f, 1);
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.simibubi.create.content.logistics.trains.entity;
|
|||
|
||||
import com.jozufozu.flywheel.util.transform.MatrixTransformStack;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionEntityRenderer;
|
||||
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
|
@ -29,8 +28,7 @@ public class CarriageContraptionEntityRenderer extends ContraptionEntityRenderer
|
|||
MultiBufferSource buffers, int overlay) {
|
||||
super.render(entity, yaw, partialTicks, ms, buffers, overlay);
|
||||
|
||||
int id = ((CarriageContraption) entity.getContraption()).temporaryCarriageIdHolder;
|
||||
Carriage carriage = Create.RAILWAYS.carriageById.get(id);
|
||||
Carriage carriage = entity.getCarriage();
|
||||
if (carriage == null)
|
||||
return;
|
||||
|
||||
|
|
|
@ -8,6 +8,9 @@ import java.util.Map;
|
|||
import java.util.Map.Entry;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiPredicate;
|
||||
|
||||
import org.apache.commons.lang3.mutable.MutableObject;
|
||||
|
||||
import com.simibubi.create.content.logistics.trains.TrackEdge;
|
||||
import com.simibubi.create.content.logistics.trains.TrackGraph;
|
||||
|
@ -18,7 +21,6 @@ import com.simibubi.create.content.logistics.trains.management.GlobalStation;
|
|||
import com.simibubi.create.foundation.utility.Couple;
|
||||
import com.simibubi.create.foundation.utility.Pair;
|
||||
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
|
@ -64,15 +66,7 @@ public class Navigation {
|
|||
|
||||
double brakingDistance = (train.speed * train.speed) / (2 * Train.acceleration);
|
||||
train.targetSpeed = distanceToDestination > brakingDistance ? Train.topSpeed : 0;
|
||||
|
||||
if (Mth.equal(train.targetSpeed, train.speed))
|
||||
return;
|
||||
|
||||
if (train.speed < train.targetSpeed)
|
||||
train.speed = Math.min(train.speed + Train.acceleration, train.targetSpeed);
|
||||
else if (train.speed > train.targetSpeed)
|
||||
train.speed = Math.max(train.speed - Train.acceleration, train.targetSpeed);
|
||||
|
||||
train.approachTargetSpeed(1);
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
|
@ -80,17 +74,20 @@ public class Navigation {
|
|||
}
|
||||
|
||||
public ITrackSelector control(TravellingPoint mp) {
|
||||
return (graph, list) -> {
|
||||
if (destination == null)
|
||||
return mp.steer(train.manualSteer, new Vec3(0, 1, 0));
|
||||
return (graph, pair) -> {
|
||||
if (!currentPath.isEmpty()) {
|
||||
TrackEdge target = currentPath.get(0);
|
||||
for (Entry<TrackNode, TrackEdge> entry : list) {
|
||||
for (Entry<TrackNode, TrackEdge> entry : pair.getSecond()) {
|
||||
if (entry.getValue() == target) {
|
||||
currentPath.remove(0);
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
return list.get(0);
|
||||
return pair.getSecond()
|
||||
.get(0);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -122,7 +119,7 @@ public class Navigation {
|
|||
if (this.destination == destination)
|
||||
return 0;
|
||||
|
||||
train.leave();
|
||||
train.leaveStation();
|
||||
this.destination = destination;
|
||||
return distanceToDestination;
|
||||
}
|
||||
|
@ -130,19 +127,103 @@ public class Navigation {
|
|||
private Pair<Double, List<TrackEdge>> findPathTo(GlobalStation destination) {
|
||||
TrackGraph graph = train.graph;
|
||||
List<TrackEdge> path = new ArrayList<>();
|
||||
double distanceToDestination = 0;
|
||||
|
||||
if (graph == null)
|
||||
return Pair.of(-1d, path);
|
||||
|
||||
Couple<TrackNodeLocation> target = destination.edgeLocation;
|
||||
PriorityQueue<Pair<Double, Pair<Couple<TrackNode>, TrackEdge>>> frontier =
|
||||
new PriorityQueue<>((p1, p2) -> Double.compare(p1.getFirst(), p2.getFirst()));
|
||||
TravellingPoint leadingPoint = train.carriages.get(0)
|
||||
.getLeadingPoint();
|
||||
TrackEdge initialEdge = leadingPoint.edge;
|
||||
|
||||
MutableObject<Pair<Double, List<TrackEdge>>> result = new MutableObject<>(Pair.of(-1d, path));
|
||||
|
||||
search((reachedVia, poll) -> {
|
||||
double distance = poll.getFirst();
|
||||
Pair<Couple<TrackNode>, TrackEdge> currentEntry = poll.getSecond();
|
||||
TrackEdge edge = currentEntry.getSecond();
|
||||
TrackNode node1 = currentEntry.getFirst()
|
||||
.getFirst();
|
||||
TrackNode node2 = currentEntry.getFirst()
|
||||
.getSecond();
|
||||
|
||||
TrackNodeLocation loc1 = node1.getLocation();
|
||||
TrackNodeLocation loc2 = node2.getLocation();
|
||||
if (!loc1.equals(target.getFirst()) || !loc2.equals(target.getSecond()))
|
||||
return false;
|
||||
|
||||
Pair<Boolean, TrackEdge> backTrack = reachedVia.get(edge);
|
||||
TrackEdge toReach = edge;
|
||||
while (backTrack != null && toReach != initialEdge) {
|
||||
if (backTrack.getFirst())
|
||||
path.add(0, toReach);
|
||||
toReach = backTrack.getSecond();
|
||||
backTrack = reachedVia.get(backTrack.getSecond());
|
||||
}
|
||||
|
||||
double distanceToDestination = distance;
|
||||
double position = edge.getLength(node1, node2) - destination.position;
|
||||
distanceToDestination -= position;
|
||||
result.setValue(Pair.of(distanceToDestination, path));
|
||||
return true;
|
||||
}, Double.MAX_VALUE);
|
||||
|
||||
return result.getValue();
|
||||
}
|
||||
|
||||
public GlobalStation findNearestApproachable() {
|
||||
TrackGraph graph = train.graph;
|
||||
if (graph == null)
|
||||
return null;
|
||||
|
||||
MutableObject<GlobalStation> result = new MutableObject<>(null);
|
||||
double minDistance = .75f * (train.speed * train.speed) / (2 * Train.acceleration);
|
||||
double maxDistance = Math.max(32, 1.5f * (train.speed * train.speed) / (2 * Train.acceleration));
|
||||
|
||||
search((reachedVia, poll) -> {
|
||||
double distance = poll.getFirst();
|
||||
if (distance < minDistance)
|
||||
return false;
|
||||
|
||||
Pair<Couple<TrackNode>, TrackEdge> currentEntry = poll.getSecond();
|
||||
TrackEdge edge = currentEntry.getSecond();
|
||||
TrackNode node1 = currentEntry.getFirst()
|
||||
.getFirst();
|
||||
TrackNode node2 = currentEntry.getFirst()
|
||||
.getSecond();
|
||||
|
||||
for (GlobalStation globalStation : graph.getStations()) {
|
||||
Couple<TrackNodeLocation> target = globalStation.edgeLocation;
|
||||
TrackNodeLocation loc1 = node1.getLocation();
|
||||
TrackNodeLocation loc2 = node2.getLocation();
|
||||
if (!loc1.equals(target.getFirst()) || !loc2.equals(target.getSecond()))
|
||||
continue;
|
||||
double position = edge.getLength(node1, node2) - globalStation.position;
|
||||
if (distance - position < minDistance)
|
||||
continue;
|
||||
result.setValue(globalStation);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}, maxDistance);
|
||||
|
||||
return result.getValue();
|
||||
}
|
||||
|
||||
public void search(
|
||||
BiPredicate<Map<TrackEdge, Pair<Boolean, TrackEdge>>, Pair<Double, Pair<Couple<TrackNode>, TrackEdge>>> condition,
|
||||
double maxDistance) {
|
||||
TrackGraph graph = train.graph;
|
||||
if (graph == null)
|
||||
return;
|
||||
|
||||
TravellingPoint leadingPoint = train.carriages.get(0)
|
||||
.getLeadingPoint();
|
||||
Set<TrackEdge> visited = new HashSet<>();
|
||||
Map<TrackEdge, Pair<Boolean, TrackEdge>> reachedVia = new IdentityHashMap<>();
|
||||
PriorityQueue<Pair<Double, Pair<Couple<TrackNode>, TrackEdge>>> frontier =
|
||||
new PriorityQueue<>((p1, p2) -> Double.compare(p1.getFirst(), p2.getFirst()));
|
||||
|
||||
TrackEdge initialEdge = leadingPoint.edge;
|
||||
TrackNode initialNode1 = leadingPoint.node1;
|
||||
|
@ -153,39 +234,19 @@ public class Navigation {
|
|||
while (!frontier.isEmpty()) {
|
||||
Pair<Double, Pair<Couple<TrackNode>, TrackEdge>> poll = frontier.poll();
|
||||
double distance = poll.getFirst();
|
||||
if (distance > maxDistance)
|
||||
continue;
|
||||
|
||||
Pair<Couple<TrackNode>, TrackEdge> currentEntry = poll.getSecond();
|
||||
List<Entry<TrackNode, TrackEdge>> validTargets = new ArrayList<>();
|
||||
TrackEdge edge = currentEntry.getSecond();
|
||||
TrackNode node1 = currentEntry.getFirst()
|
||||
.getFirst();
|
||||
TrackNode node2 = currentEntry.getFirst()
|
||||
.getSecond();
|
||||
if (condition.test(reachedVia, poll))
|
||||
return;
|
||||
|
||||
TrackNodeLocation loc1 = node1.getLocation();
|
||||
TrackNodeLocation loc2 = node2.getLocation();
|
||||
boolean enteringBackward = loc2.equals(target.getFirst()) && loc1.equals(target.getSecond());
|
||||
boolean enteringForward = loc1.equals(target.getFirst()) && loc2.equals(target.getSecond());
|
||||
|
||||
if (enteringForward || train.doubleEnded && enteringBackward) {
|
||||
Pair<Boolean, TrackEdge> backTrack = reachedVia.get(edge);
|
||||
TrackEdge toReach = edge;
|
||||
while (backTrack != null && toReach != initialEdge) {
|
||||
if (backTrack.getFirst())
|
||||
path.add(0, toReach);
|
||||
toReach = backTrack.getSecond();
|
||||
backTrack = reachedVia.get(backTrack.getSecond());
|
||||
}
|
||||
|
||||
distanceToDestination = distance;
|
||||
double position = destination.position;
|
||||
if (enteringForward)
|
||||
position = edge.getLength(node1, node2) - position;
|
||||
else
|
||||
distanceToDestination += train.getTotalLength() + 2;
|
||||
distanceToDestination -= position;
|
||||
return Pair.of(distanceToDestination, path);
|
||||
}
|
||||
|
||||
List<Entry<TrackNode, TrackEdge>> validTargets = new ArrayList<>();
|
||||
for (Entry<TrackNode, TrackEdge> entry : graph.getConnectionsFrom(node2)
|
||||
.entrySet()) {
|
||||
TrackNode newNode = entry.getKey();
|
||||
|
@ -210,8 +271,6 @@ public class Navigation {
|
|||
Pair.of(Couple.create(node2, newNode), newEdge)));
|
||||
}
|
||||
}
|
||||
|
||||
return Pair.of(-1d, path);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import com.simibubi.create.CreateClient;
|
|||
import com.simibubi.create.content.logistics.trains.TrackGraph;
|
||||
import com.simibubi.create.content.logistics.trains.TrackNode;
|
||||
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.ITrackSelector;
|
||||
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.SteerDirection;
|
||||
import com.simibubi.create.content.logistics.trains.management.GlobalStation;
|
||||
import com.simibubi.create.content.logistics.trains.management.GraphLocation;
|
||||
import com.simibubi.create.content.logistics.trains.management.ScheduleRuntime;
|
||||
|
@ -56,6 +57,9 @@ public class Train {
|
|||
public Component name;
|
||||
public TrainStatus status;
|
||||
|
||||
public SteerDirection manualSteer;
|
||||
public boolean manualTick;
|
||||
|
||||
public UUID currentStation;
|
||||
|
||||
public boolean heldForAssembly;
|
||||
|
@ -85,12 +89,14 @@ public class Train {
|
|||
Create.RAILWAYS.carriageById.put(c.id, c);
|
||||
});
|
||||
|
||||
doubleEnded = carriages.size() > 1 && carriages.get(carriages.size() - 1).contraption.hasControls();
|
||||
doubleEnded = carriages.stream()
|
||||
.anyMatch(c -> c.contraption.hasBackwardControls());
|
||||
navigation = new Navigation(this, graph);
|
||||
runtime = new ScheduleRuntime(this);
|
||||
heldForAssembly = true;
|
||||
migratingPoints = new ArrayList<>();
|
||||
currentStation = null;
|
||||
manualSteer = SteerDirection.NONE;
|
||||
}
|
||||
|
||||
public void tick(Level level) {
|
||||
|
@ -105,11 +111,13 @@ public class Train {
|
|||
runtime.tick(level);
|
||||
navigation.tick(level);
|
||||
|
||||
if (navigation.destination == null && speed > 0) {
|
||||
speed -= acceleration;
|
||||
if (speed <= 0)
|
||||
speed = 0;
|
||||
if (!manualTick && navigation.destination == null && speed != 0) {
|
||||
if (speed > 0)
|
||||
speed = Math.max(speed - acceleration, 0);
|
||||
else
|
||||
speed = Math.min(speed + acceleration, 0);
|
||||
}
|
||||
manualTick = false;
|
||||
|
||||
if (derailed) {
|
||||
speed /= 3f;
|
||||
|
@ -145,12 +153,20 @@ public class Train {
|
|||
for (int i = 0; i < carriages.size(); i++) {
|
||||
double leadingStress = i == 0 ? 0 : stress[i - 1] * leadingModifier;
|
||||
double trailingStress = i == stress.length ? 0 : stress[i] * trailingModifier;
|
||||
|
||||
Carriage carriage = carriages.get(i);
|
||||
TravellingPoint toFollow = previous;
|
||||
Function<TravellingPoint, ITrackSelector> control =
|
||||
previous == null ? navigation::control : mp -> mp.follow(toFollow);
|
||||
double actualDistance = carriage.travel(level, graph, distance + leadingStress + trailingStress, control);
|
||||
|
||||
TravellingPoint toFollowForward = previous;
|
||||
TravellingPoint toFollowBackward = i == carriages.size() - 1 ? null
|
||||
: carriages.get(i + 1)
|
||||
.getLeadingPoint();
|
||||
|
||||
Function<TravellingPoint, ITrackSelector> forwardControl =
|
||||
toFollowForward == null ? navigation::control : mp -> mp.follow(toFollowForward);
|
||||
Function<TravellingPoint, ITrackSelector> backwardControl =
|
||||
toFollowBackward == null ? navigation::control : mp -> mp.follow(toFollowBackward);
|
||||
|
||||
double actualDistance = carriage.travel(level, graph, distance + leadingStress + trailingStress,
|
||||
forwardControl, backwardControl);
|
||||
blocked |= carriage.blocked;
|
||||
|
||||
if (i == 0) {
|
||||
|
@ -165,7 +181,7 @@ public class Train {
|
|||
navigation.cancelNavigation();
|
||||
runtime.tick(level);
|
||||
status.endOfTrack();
|
||||
} else if (speed > 0)
|
||||
} else if (speed != 0)
|
||||
status.trackOK();
|
||||
|
||||
if (navigation.destination != null) {
|
||||
|
@ -376,7 +392,7 @@ public class Train {
|
|||
return length;
|
||||
}
|
||||
|
||||
public void leave() {
|
||||
public void leaveStation() {
|
||||
GlobalStation currentStation = getCurrentStation();
|
||||
if (currentStation == null)
|
||||
return;
|
||||
|
@ -411,4 +427,15 @@ public class Train {
|
|||
}
|
||||
}
|
||||
|
||||
public void approachTargetSpeed(float accelerationMod) {
|
||||
if (Mth.equal(targetSpeed, speed))
|
||||
return;
|
||||
if (manualTick)
|
||||
leaveStation();
|
||||
if (speed < targetSpeed)
|
||||
speed = Math.min(speed + Train.acceleration * accelerationMod, targetSpeed);
|
||||
else if (speed > targetSpeed)
|
||||
speed = Math.max(speed - Train.acceleration * accelerationMod, targetSpeed);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -188,7 +188,7 @@ public class TrainRelocator {
|
|||
});
|
||||
|
||||
train.status.successfulMigration();
|
||||
train.leave();
|
||||
train.leaveStation();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -293,8 +293,7 @@ public class TrainRelocator {
|
|||
private static Train getTrainFromEntity(CarriageContraptionEntity carriageContraptionEntity) {
|
||||
if (carriageContraptionEntity == null)
|
||||
return null;
|
||||
int id = ((CarriageContraption) carriageContraptionEntity.getContraption()).temporaryCarriageIdHolder;
|
||||
Carriage carriage = Create.RAILWAYS.carriageById.get(id); // TODO: thread breach
|
||||
Carriage carriage = carriageContraptionEntity.getCarriage();
|
||||
if (carriage == null)
|
||||
return null;
|
||||
return carriage.train;
|
||||
|
|
|
@ -36,6 +36,10 @@ public class TrainStatus {
|
|||
displayInformation("Navigation succeeded", true);
|
||||
navigation = false;
|
||||
}
|
||||
|
||||
public void manualControls() {
|
||||
displayInformation("Schedule paused for manual controls", true);
|
||||
}
|
||||
|
||||
public void failedMigration() {
|
||||
if (track)
|
||||
|
|
|
@ -13,6 +13,7 @@ import com.simibubi.create.content.logistics.trains.TrackEdge;
|
|||
import com.simibubi.create.content.logistics.trains.TrackGraph;
|
||||
import com.simibubi.create.content.logistics.trains.TrackNode;
|
||||
import com.simibubi.create.content.logistics.trains.management.GraphLocation;
|
||||
import com.simibubi.create.foundation.utility.Pair;
|
||||
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
|
@ -34,7 +35,7 @@ public class TravellingPoint {
|
|||
}
|
||||
|
||||
public static interface ITrackSelector
|
||||
extends BiFunction<TrackGraph, List<Entry<TrackNode, TrackEdge>>, Entry<TrackNode, TrackEdge>> {
|
||||
extends BiFunction<TrackGraph, Pair<Boolean, List<Entry<TrackNode, TrackEdge>>>, Entry<TrackNode, TrackEdge>> {
|
||||
};
|
||||
|
||||
public TravellingPoint(TrackNode node1, TrackNode node2, TrackEdge edge, double position) {
|
||||
|
@ -45,15 +46,20 @@ public class TravellingPoint {
|
|||
}
|
||||
|
||||
public ITrackSelector random() {
|
||||
return (graph, validTargets) -> validTargets.get(Create.RANDOM.nextInt(validTargets.size()));
|
||||
return (graph, pair) -> pair.getSecond()
|
||||
.get(Create.RANDOM.nextInt(pair.getSecond()
|
||||
.size()));
|
||||
}
|
||||
|
||||
public ITrackSelector follow(TravellingPoint other) {
|
||||
return (graph, validTargets) -> {
|
||||
TrackNode target = other.node1;
|
||||
return (graph, pair) -> {
|
||||
List<Entry<TrackNode, TrackEdge>> validTargets = pair.getSecond();
|
||||
boolean forward = pair.getFirst();
|
||||
TrackNode target = forward ? other.node1 : other.node2;
|
||||
TrackNode secondary = forward ? other.node2 : other.node1;
|
||||
|
||||
for (Entry<TrackNode, TrackEdge> entry : validTargets)
|
||||
if (entry.getKey() == target || entry.getKey() == other.node2)
|
||||
if (entry.getKey() == target || entry.getKey() == secondary)
|
||||
return entry;
|
||||
|
||||
Vector<List<Entry<TrackNode, TrackEdge>>> frontiers = new Vector<>(validTargets.size());
|
||||
|
@ -99,7 +105,9 @@ public class TravellingPoint {
|
|||
}
|
||||
|
||||
public ITrackSelector steer(SteerDirection direction, Vec3 upNormal) {
|
||||
return (graph, validTargets) -> {
|
||||
return (graph, pair) -> {
|
||||
List<Entry<TrackNode, TrackEdge>> validTargets = pair.getSecond();
|
||||
boolean forward = pair.getFirst();
|
||||
double closest = Double.MAX_VALUE;
|
||||
Entry<TrackNode, TrackEdge> best = null;
|
||||
|
||||
|
@ -108,7 +116,7 @@ public class TravellingPoint {
|
|||
Vec3 entryTrajectory = entry.getValue()
|
||||
.getDirection(node2, entry.getKey(), true);
|
||||
Vec3 normal = trajectory.cross(upNormal);
|
||||
double dot = normal.dot(entryTrajectory);
|
||||
double dot = normal.dot(entryTrajectory) * (forward ? 1 : -1);
|
||||
double diff = Math.abs(direction.targetDot - dot);
|
||||
if (diff > closest)
|
||||
continue;
|
||||
|
@ -136,43 +144,86 @@ public class TravellingPoint {
|
|||
double currentT = position / edgeLength;
|
||||
double incrementT = edge.incrementT(node1, node2, currentT, distance);
|
||||
position = incrementT * edgeLength;
|
||||
|
||||
List<Entry<TrackNode, TrackEdge>> validTargets = new ArrayList<>();
|
||||
while (position > edgeLength) {
|
||||
validTargets.clear();
|
||||
|
||||
for (Entry<TrackNode, TrackEdge> entry : graph.getConnectionsFrom(node2)
|
||||
.entrySet()) {
|
||||
TrackNode newNode = entry.getKey();
|
||||
if (newNode == node1)
|
||||
continue;
|
||||
if (distance > 0) {
|
||||
// Moving forward
|
||||
while (position > edgeLength) {
|
||||
validTargets.clear();
|
||||
|
||||
TrackEdge newEdge = entry.getValue();
|
||||
Vec3 currentDirection = edge.getDirection(node1, node2, false);
|
||||
Vec3 newDirection = newEdge.getDirection(node2, newNode, true);
|
||||
if (currentDirection.dot(newDirection) < 0)
|
||||
continue;
|
||||
for (Entry<TrackNode, TrackEdge> entry : graph.getConnectionsFrom(node2)
|
||||
.entrySet()) {
|
||||
TrackNode newNode = entry.getKey();
|
||||
if (newNode == node1)
|
||||
continue;
|
||||
|
||||
validTargets.add(entry);
|
||||
TrackEdge newEdge = entry.getValue();
|
||||
Vec3 currentDirection = edge.getDirection(node1, node2, false);
|
||||
Vec3 newDirection = newEdge.getDirection(node2, newNode, true);
|
||||
if (currentDirection.dot(newDirection) < 0)
|
||||
continue;
|
||||
|
||||
validTargets.add(entry);
|
||||
}
|
||||
|
||||
if (validTargets.isEmpty()) {
|
||||
traveled -= position - edgeLength;
|
||||
position = edgeLength;
|
||||
blocked = true;
|
||||
break;
|
||||
}
|
||||
|
||||
Entry<TrackNode, TrackEdge> entry = validTargets.size() == 1 ? validTargets.get(0)
|
||||
: trackSelector.apply(graph, Pair.of(true, validTargets));
|
||||
|
||||
node1 = node2;
|
||||
node2 = entry.getKey();
|
||||
edge = entry.getValue();
|
||||
position -= edgeLength;
|
||||
edgeLength = edge.getLength(node1, node2);
|
||||
}
|
||||
|
||||
if (validTargets.isEmpty()) {
|
||||
traveled -= position - edgeLength;
|
||||
position = edgeLength;
|
||||
blocked = true;
|
||||
break;
|
||||
} else {
|
||||
// Moving backwards
|
||||
while (position < 0) {
|
||||
validTargets.clear();
|
||||
|
||||
for (Entry<TrackNode, TrackEdge> entry : graph.getConnectionsFrom(node1)
|
||||
.entrySet()) {
|
||||
TrackNode newNode = entry.getKey();
|
||||
if (newNode == node2)
|
||||
continue;
|
||||
|
||||
TrackEdge newEdge = graph.getConnectionsFrom(newNode)
|
||||
.get(node1);
|
||||
Vec3 currentDirection = edge.getDirection(node1, node2, true);
|
||||
Vec3 newDirection = newEdge.getDirection(newNode, node1, false);
|
||||
if (currentDirection.dot(newDirection) < 0)
|
||||
continue;
|
||||
|
||||
validTargets.add(entry);
|
||||
}
|
||||
|
||||
if (validTargets.isEmpty()) {
|
||||
traveled -= position;
|
||||
position = 0;
|
||||
blocked = true;
|
||||
break;
|
||||
}
|
||||
|
||||
Entry<TrackNode, TrackEdge> entry = validTargets.size() == 1 ? validTargets.get(0)
|
||||
: trackSelector.apply(graph, Pair.of(false, validTargets));
|
||||
|
||||
node2 = node1;
|
||||
node1 = entry.getKey();
|
||||
edge = graph.getConnectionsFrom(node1)
|
||||
.get(node2);
|
||||
edgeLength = edge.getLength(node1, node2);
|
||||
position += edgeLength;
|
||||
}
|
||||
|
||||
Entry<TrackNode, TrackEdge> entry =
|
||||
validTargets.size() == 1 ? validTargets.get(0) : trackSelector.apply(graph, validTargets);
|
||||
|
||||
node1 = node2;
|
||||
node2 = entry.getKey();
|
||||
edge = entry.getValue();
|
||||
position -= edgeLength;
|
||||
edgeLength = edge.getLength(node1, node2);
|
||||
}
|
||||
|
||||
|
||||
return traveled;
|
||||
}
|
||||
|
||||
|
|
|
@ -414,6 +414,7 @@ public class StationTileEntity extends SmartTileEntity {
|
|||
List<CarriageContraption> contraptions = new ArrayList<>();
|
||||
List<Carriage> carriages = new ArrayList<>();
|
||||
List<Integer> spacing = new ArrayList<>();
|
||||
boolean atLeastOneForwardControls = false;
|
||||
|
||||
for (int bogeyIndex = 0; bogeyIndex < bogeyCount; bogeyIndex++) {
|
||||
int pointIndex = bogeyIndex * 2;
|
||||
|
@ -425,6 +426,7 @@ public class StationTileEntity extends SmartTileEntity {
|
|||
try {
|
||||
boolean success = contraption.assemble(level,
|
||||
bogeyPosOffset.relative(assemblyDirection, bogeyLocations[bogeyIndex] + 1));
|
||||
atLeastOneForwardControls |= contraption.hasForwardControls();
|
||||
if (!success) {
|
||||
exception(new AssemblyException(Lang.translate("train_assembly.nothing_attached", bogeyIndex + 1)),
|
||||
-1);
|
||||
|
@ -467,6 +469,11 @@ public class StationTileEntity extends SmartTileEntity {
|
|||
carriages.add(carriage);
|
||||
}
|
||||
|
||||
if (!atLeastOneForwardControls) {
|
||||
exception(new AssemblyException(Lang.translate("train_assembly.no_controls")), -1);
|
||||
return;
|
||||
}
|
||||
|
||||
for (CarriageContraption contraption : contraptions) {
|
||||
contraption.removeBlocksFromWorld(level, BlockPos.ZERO);
|
||||
contraption.expandBoundsAroundAxis(Axis.Y);
|
||||
|
|
|
@ -15,6 +15,7 @@ import com.simibubi.create.content.contraptions.components.fan.AirCurrent;
|
|||
import com.simibubi.create.content.contraptions.components.flywheel.engine.EngineBlock;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionHandler;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.chassis.ChassisRangeDisplay;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls.ControlsHandler;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.train.CouplingHandlerClient;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.train.CouplingPhysics;
|
||||
|
@ -105,6 +106,7 @@ public class ClientEvents {
|
|||
Level world = Minecraft.getInstance().level;
|
||||
if (event.phase == Phase.START) {
|
||||
LinkedControllerClientHandler.tick();
|
||||
ControlsHandler.tick();
|
||||
AirCurrent.tickClientPlayerSounds();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package com.simibubi.create.foundation.utility;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import com.mojang.blaze3d.platform.InputConstants;
|
||||
|
||||
import net.minecraft.client.KeyMapping;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.Options;
|
||||
|
||||
public class ControlsUtil {
|
||||
|
||||
private static Vector<KeyMapping> standardControls;
|
||||
|
||||
public static Vector<KeyMapping> getControls() {
|
||||
if (standardControls == null) {
|
||||
Options gameSettings = Minecraft.getInstance().options;
|
||||
standardControls = new Vector<>(6);
|
||||
standardControls.add(gameSettings.keyUp);
|
||||
standardControls.add(gameSettings.keyDown);
|
||||
standardControls.add(gameSettings.keyLeft);
|
||||
standardControls.add(gameSettings.keyRight);
|
||||
standardControls.add(gameSettings.keyJump);
|
||||
standardControls.add(gameSettings.keyShift);
|
||||
}
|
||||
return standardControls;
|
||||
}
|
||||
|
||||
public static boolean isActuallyPressed(KeyMapping kb) {
|
||||
return InputConstants.isKeyDown(Minecraft.getInstance()
|
||||
.getWindow()
|
||||
.getWindow(),
|
||||
kb.getKey()
|
||||
.getValue());
|
||||
}
|
||||
|
||||
}
|
|
@ -627,6 +627,8 @@
|
|||
"create.train_assembly.not_connected_in_order": "Bogeys are not connected in order",
|
||||
"create.train_assembly.single_bogey_carriage": "This Bogey type cannot support a carriage on its own",
|
||||
"create.train_assembly.nothing_attached": "No structure attached to Bogey %1$s",
|
||||
"create.train_assembly.no_controls": "At least one forward-facing controls block needs to be mounted on the train",
|
||||
"create.train_assembly.sideways_controls": "A mounted controls block is facing sideways",
|
||||
|
||||
"create.track_target.set": "Targeted track selected",
|
||||
"create.track_target.success": "Successfully bound to targeted track",
|
||||
|
@ -643,6 +645,10 @@
|
|||
"create.train.relocate.invalid": "Cannot relocate Train to this Track",
|
||||
"create.train.relocate.too_far": "Cannot relocate Train this far away",
|
||||
|
||||
"create.contraption.controls.start_controlling": "Now controlling: %1$s",
|
||||
"create.contraption.controls.stop_controlling": "Stopped controlling contraption",
|
||||
"create.contraption.controls.approach_station": "Hold %1$s to approach %2$s",
|
||||
|
||||
"create.gui.config.overlay1": "Hi :)",
|
||||
"create.gui.config.overlay2": "This is a sample overlay",
|
||||
"create.gui.config.overlay3": "Click or drag with your mouse",
|
||||
|
|
|
@ -3,32 +3,53 @@
|
|||
"texture_size": [32, 32],
|
||||
"textures": {
|
||||
"0": "create:block/brass_casing_belt",
|
||||
"1": "create:block/brass_block",
|
||||
"3": "create:block/brass_funnel_plating",
|
||||
"4": "create:block/blaze_burner_side",
|
||||
"5": "create:block/blaze_heater_brazier",
|
||||
"particle": "create:block/brass_casing"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [0, 0, 4],
|
||||
"to": [16, 8, 16],
|
||||
"to": [16, 4, 8],
|
||||
"faces": {
|
||||
"north": {"uv": [8, 8.5, 16, 12.5], "texture": "#0"},
|
||||
"east": {"uv": [8, 8.5, 14, 12.5], "texture": "#0"},
|
||||
"south": {"uv": [8, 8.5, 16, 12.5], "texture": "#0"},
|
||||
"west": {"uv": [10, 8.5, 16, 12.5], "texture": "#0"},
|
||||
"up": {"uv": [9, 1, 15, 9], "rotation": 90, "texture": "#3"},
|
||||
"down": {"uv": [0, 2, 16, 14], "texture": "#1"}
|
||||
"north": {"uv": [12, 0, 16, 16], "rotation": 90, "texture": "#4"},
|
||||
"east": {"uv": [12, 0, 16, 4], "rotation": 90, "texture": "#4"},
|
||||
"west": {"uv": [12, 12, 16, 16], "rotation": 90, "texture": "#4"},
|
||||
"up": {"uv": [8, 0, 16, 2], "texture": "#5"},
|
||||
"down": {"uv": [6, 8, 8, 16], "rotation": 90, "texture": "#5"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [0, 8, 6],
|
||||
"from": [0, 0, 8],
|
||||
"to": [8, 6, 16],
|
||||
"faces": {
|
||||
"north": {"uv": [2, 5, 6, 8], "texture": "#5"},
|
||||
"south": {"uv": [2, 5, 6, 8], "texture": "#5"},
|
||||
"west": {"uv": [2, 5, 6, 8], "texture": "#5"},
|
||||
"down": {"uv": [0, 8, 4, 11], "texture": "#5"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [8, 0, 8],
|
||||
"to": [16, 6, 16],
|
||||
"faces": {
|
||||
"north": {"uv": [2, 5, 6, 8], "texture": "#5"},
|
||||
"east": {"uv": [2, 5, 6, 8], "texture": "#5"},
|
||||
"south": {"uv": [2, 5, 6, 8], "texture": "#5"},
|
||||
"down": {"uv": [4, 8, 8, 11], "texture": "#5"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [0, 6, 6],
|
||||
"to": [16, 14, 16],
|
||||
"faces": {
|
||||
"north": {"uv": [11, 1, 14, 9], "rotation": 90, "texture": "#3"},
|
||||
"east": {"uv": [7, 0, 16, 6], "texture": "#1"},
|
||||
"south": {"uv": [2, 0, 14, 6], "texture": "#1"},
|
||||
"west": {"uv": [0, 0, 10, 6], "texture": "#1"},
|
||||
"up": {"uv": [9, 1, 14, 9], "rotation": 270, "texture": "#3"}
|
||||
"north": {"uv": [10, 1, 14, 9], "rotation": 270, "texture": "#3"},
|
||||
"east": {"uv": [3, 0, 8, 4], "texture": "#0"},
|
||||
"south": {"uv": [8, 0, 16, 4], "texture": "#0"},
|
||||
"west": {"uv": [0, 0, 5, 4], "texture": "#0"},
|
||||
"up": {"uv": [9, 1, 14, 9], "rotation": 270, "texture": "#3"},
|
||||
"down": {"uv": [10, 1, 15, 9], "rotation": 270, "texture": "#3"}
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@ -37,7 +58,7 @@
|
|||
"name": "closed",
|
||||
"origin": [0, 0, 0],
|
||||
"color": 0,
|
||||
"children": [0, 1]
|
||||
"children": [0, 1, 2, 3]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -6,59 +6,88 @@
|
|||
"1": "create:block/brass_block",
|
||||
"2": "create:block/brass_funnel_back",
|
||||
"3": "create:block/brass_funnel_plating",
|
||||
"5": "create:block/blaze_burner_side",
|
||||
"6": "create:block/blaze_heater_brazier",
|
||||
"particle": "create:block/brass_casing"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [0, 0, 4],
|
||||
"to": [16, 8, 16],
|
||||
"faces": {
|
||||
"north": {"uv": [8, 8.5, 16, 12.5], "texture": "#0"},
|
||||
"east": {"uv": [8, 8.5, 14, 12.5], "texture": "#0"},
|
||||
"south": {"uv": [8, 8.5, 16, 12.5], "texture": "#0"},
|
||||
"west": {"uv": [10, 8.5, 16, 12.5], "texture": "#0"},
|
||||
"up": {"uv": [9, 1, 15, 9], "rotation": 90, "texture": "#3"},
|
||||
"down": {"uv": [0, 2, 16, 14], "texture": "#1"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [14, 8, 6],
|
||||
"from": [14, 6, 6],
|
||||
"to": [16, 14, 16],
|
||||
"faces": {
|
||||
"north": {"uv": [11, 8, 14, 9], "rotation": 90, "texture": "#3"},
|
||||
"east": {"uv": [7, 0, 16, 6], "texture": "#1"},
|
||||
"south": {"uv": [11, 0, 13, 6], "texture": "#1"},
|
||||
"north": {"uv": [10, 8, 14, 9], "rotation": 90, "texture": "#3"},
|
||||
"east": {"uv": [7, 0, 16, 8], "texture": "#particle"},
|
||||
"south": {"uv": [15, 0, 16, 4], "texture": "#0"},
|
||||
"west": {"uv": [0, 0, 10, 6], "texture": "#1"},
|
||||
"up": {"uv": [9, 8, 14, 9], "rotation": 270, "texture": "#3"}
|
||||
"up": {"uv": [9, 8, 14, 9], "rotation": 270, "texture": "#3"},
|
||||
"down": {"uv": [10, 8, 15, 9], "rotation": 270, "texture": "#3"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [2, 8, 14],
|
||||
"from": [2, 6, 14],
|
||||
"to": [14, 14, 16],
|
||||
"faces": {
|
||||
"north": {"uv": [2, 0, 14, 6], "texture": "#1"},
|
||||
"south": {"uv": [3, 0, 12, 6], "texture": "#1"},
|
||||
"south": {"uv": [9, 0, 15, 4], "texture": "#0"},
|
||||
"up": {"uv": [10, 1, 14, 2], "rotation": 180, "texture": "#3"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [0, 8, 6],
|
||||
"from": [0, 6, 6],
|
||||
"to": [2, 14, 16],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [16, 0, 0]},
|
||||
"faces": {
|
||||
"north": {"uv": [11, 9, 14, 8], "rotation": 90, "texture": "#3"},
|
||||
"north": {"uv": [10, 9, 14, 8], "rotation": 90, "texture": "#3"},
|
||||
"east": {"uv": [10, 0, 0, 6], "texture": "#1"},
|
||||
"south": {"uv": [4, 0, 2, 6], "texture": "#1"},
|
||||
"west": {"uv": [16, 0, 7, 6], "texture": "#1"},
|
||||
"up": {"uv": [9, 9, 14, 8], "rotation": 270, "texture": "#3"}
|
||||
"south": {"uv": [9, 0, 8, 4], "texture": "#0"},
|
||||
"west": {"uv": [16, 0, 7, 8], "texture": "#particle"},
|
||||
"up": {"uv": [9, 9, 14, 8], "rotation": 270, "texture": "#3"},
|
||||
"down": {"uv": [10, 9, 15, 8], "rotation": 270, "texture": "#3"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [2, 8, 7],
|
||||
"from": [2, 6, 7],
|
||||
"to": [14, 13, 14],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 8, 2.5, 14], "rotation": 270, "texture": "#2"},
|
||||
"up": {"uv": [2.5, 8, 6, 14], "rotation": 90, "texture": "#2"}
|
||||
"north": {"uv": [0, 8, 3.5, 14], "rotation": 270, "texture": "#2"},
|
||||
"up": {"uv": [2.5, 8, 6, 14], "rotation": 90, "texture": "#2"},
|
||||
"down": {"uv": [2.5, 8, 6, 14], "rotation": 90, "texture": "#2"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [0, 0, 8],
|
||||
"to": [8, 6, 16],
|
||||
"faces": {
|
||||
"north": {"uv": [2, 5, 6, 8], "texture": "#6"},
|
||||
"east": {"uv": [0, 0, 0, 0], "texture": "#6"},
|
||||
"south": {"uv": [2, 5, 6, 8], "texture": "#6"},
|
||||
"west": {"uv": [2, 5, 6, 8], "texture": "#6"},
|
||||
"up": {"uv": [0, 0, 0, 0], "texture": "#6"},
|
||||
"down": {"uv": [0, 8, 4, 11], "texture": "#6"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [8, 0, 8],
|
||||
"to": [16, 6, 16],
|
||||
"faces": {
|
||||
"north": {"uv": [2, 5, 6, 8], "texture": "#6"},
|
||||
"east": {"uv": [2, 5, 6, 8], "texture": "#6"},
|
||||
"south": {"uv": [2, 5, 6, 8], "texture": "#6"},
|
||||
"west": {"uv": [0, 0, 0, 0], "texture": "#6"},
|
||||
"up": {"uv": [0, 0, 0, 0], "texture": "#6"},
|
||||
"down": {"uv": [4, 8, 8, 11], "texture": "#6"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [0, 0, 4],
|
||||
"to": [16, 4, 8],
|
||||
"faces": {
|
||||
"north": {"uv": [12, 0, 16, 16], "rotation": 90, "texture": "#5"},
|
||||
"east": {"uv": [12, 0, 16, 4], "rotation": 90, "texture": "#5"},
|
||||
"south": {"uv": [0, 0, 0, 0], "rotation": 90, "texture": "#6"},
|
||||
"west": {"uv": [12, 12, 16, 16], "rotation": 90, "texture": "#5"},
|
||||
"up": {"uv": [8, 0, 16, 2], "texture": "#6"},
|
||||
"down": {"uv": [6, 8, 8, 16], "rotation": 90, "texture": "#6"}
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@ -67,7 +96,10 @@
|
|||
"name": "open",
|
||||
"origin": [0, 0, 0],
|
||||
"color": 0,
|
||||
"children": [0, 1, 2, 3, 4]
|
||||
}
|
||||
"children": [0, 1, 2, 3]
|
||||
},
|
||||
4,
|
||||
5,
|
||||
6
|
||||
]
|
||||
}
|
|
@ -7,85 +7,12 @@
|
|||
"2": "create:block/brass_funnel_back",
|
||||
"3": "create:block/brass_funnel_plating",
|
||||
"5": "block/lever",
|
||||
"7": "create:block/chute"
|
||||
"6": "create:block/blaze_heater_brazier",
|
||||
"7": "create:block/chute",
|
||||
"1_5": "create:block/blaze_burner_side",
|
||||
"particle": "create:block/brass_casing"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [0, 0, 4],
|
||||
"to": [16, 8, 16],
|
||||
"faces": {
|
||||
"north": {"uv": [8, 8.5, 16, 12.5], "texture": "#0"},
|
||||
"east": {"uv": [8, 8.5, 14, 12.5], "texture": "#0"},
|
||||
"south": {"uv": [8, 8.5, 16, 12.5], "texture": "#0"},
|
||||
"west": {"uv": [10, 8.5, 16, 12.5], "texture": "#0"},
|
||||
"up": {"uv": [9, 1, 15, 9], "rotation": 90, "texture": "#3"},
|
||||
"down": {"uv": [0, 2, 16, 14], "texture": "#1"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [14, 8, 6],
|
||||
"to": [16, 14, 16],
|
||||
"faces": {
|
||||
"north": {"uv": [11, 8, 14, 9], "rotation": 90, "texture": "#3"},
|
||||
"east": {"uv": [7, 0, 16, 6], "texture": "#1"},
|
||||
"south": {"uv": [11, 0, 13, 6], "texture": "#1"},
|
||||
"west": {"uv": [0, 0, 10, 6], "texture": "#1"},
|
||||
"up": {"uv": [9, 8, 14, 9], "rotation": 270, "texture": "#3"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [2, 8, 14],
|
||||
"to": [14, 14, 16],
|
||||
"faces": {
|
||||
"north": {"uv": [2, 0, 14, 6], "texture": "#1"},
|
||||
"south": {"uv": [3, 0, 12, 6], "texture": "#1"},
|
||||
"up": {"uv": [10, 1, 14, 2], "rotation": 180, "texture": "#3"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [0, 8, 6],
|
||||
"to": [2, 14, 16],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [16, 0, 0]},
|
||||
"faces": {
|
||||
"north": {"uv": [11, 9, 14, 8], "rotation": 90, "texture": "#3"},
|
||||
"east": {"uv": [10, 0, 0, 6], "texture": "#1"},
|
||||
"south": {"uv": [4, 0, 2, 6], "texture": "#1"},
|
||||
"west": {"uv": [16, 0, 7, 6], "texture": "#1"},
|
||||
"up": {"uv": [9, 9, 14, 8], "rotation": 270, "texture": "#3"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [2, 8, 7],
|
||||
"to": [14, 13, 14],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 8, 2.5, 14], "rotation": 270, "texture": "#2"},
|
||||
"up": {"uv": [2.5, 8, 6, 14], "rotation": 90, "texture": "#2"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [6, 7.25, 6.75],
|
||||
"to": [10, 13.25, 14.75],
|
||||
"faces": {
|
||||
"north": {"uv": [10.5, 6, 13.5, 8], "rotation": 270, "texture": "#7"},
|
||||
"up": {"uv": [10, 6, 14, 8], "rotation": 90, "texture": "#7"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [0, 7.25, 6.75],
|
||||
"to": [4, 13.25, 14.75],
|
||||
"faces": {
|
||||
"north": {"uv": [10.5, 6, 13.5, 8], "rotation": 270, "texture": "#7"},
|
||||
"up": {"uv": [10, 6, 14, 8], "rotation": 90, "texture": "#7"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [12, 7.25, 6.75],
|
||||
"to": [16, 13.25, 14.75],
|
||||
"faces": {
|
||||
"north": {"uv": [10.5, 6, 13.5, 8], "rotation": 270, "texture": "#7"},
|
||||
"up": {"uv": [10, 6, 14, 8], "rotation": 90, "texture": "#7"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [4, 9, -1],
|
||||
"to": [6, 11, 9],
|
||||
|
@ -109,6 +36,109 @@
|
|||
"up": {"uv": [7, 6, 9, 16], "texture": "#5"},
|
||||
"down": {"uv": [7, 6, 9, 16], "rotation": 180, "texture": "#5"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [14, 6, 6],
|
||||
"to": [16, 14, 16],
|
||||
"faces": {
|
||||
"north": {"uv": [10, 8, 14, 9], "rotation": 90, "texture": "#3"},
|
||||
"east": {"uv": [7, 0, 16, 8], "texture": "#particle"},
|
||||
"south": {"uv": [15, 0, 16, 4], "texture": "#0"},
|
||||
"west": {"uv": [0, 0, 10, 6], "texture": "#1"},
|
||||
"up": {"uv": [9, 8, 14, 9], "rotation": 270, "texture": "#3"},
|
||||
"down": {"uv": [10, 8, 15, 9], "rotation": 270, "texture": "#3"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [2, 6, 14],
|
||||
"to": [14, 14, 16],
|
||||
"faces": {
|
||||
"north": {"uv": [2, 0, 14, 6], "texture": "#1"},
|
||||
"south": {"uv": [9, 0, 15, 4], "texture": "#0"},
|
||||
"up": {"uv": [10, 1, 14, 2], "rotation": 180, "texture": "#3"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [0, 6, 6],
|
||||
"to": [2, 14, 16],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [16, 0, 0]},
|
||||
"faces": {
|
||||
"north": {"uv": [10, 9, 14, 8], "rotation": 90, "texture": "#3"},
|
||||
"east": {"uv": [10, 0, 0, 6], "texture": "#1"},
|
||||
"south": {"uv": [9, 0, 8, 4], "texture": "#0"},
|
||||
"west": {"uv": [16, 0, 7, 8], "texture": "#particle"},
|
||||
"up": {"uv": [9, 9, 14, 8], "rotation": 270, "texture": "#3"},
|
||||
"down": {"uv": [10, 9, 15, 8], "rotation": 270, "texture": "#3"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [2, 6, 7],
|
||||
"to": [14, 13, 14],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 8, 3.5, 14], "rotation": 270, "texture": "#2"},
|
||||
"up": {"uv": [2.5, 8, 6, 14], "rotation": 90, "texture": "#2"},
|
||||
"down": {"uv": [2.5, 8, 6, 14], "rotation": 90, "texture": "#2"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [0, 0, 8],
|
||||
"to": [8, 6, 16],
|
||||
"faces": {
|
||||
"north": {"uv": [2, 5, 6, 8], "texture": "#6"},
|
||||
"east": {"uv": [0, 0, 0, 0], "texture": "#6"},
|
||||
"south": {"uv": [2, 5, 6, 8], "texture": "#6"},
|
||||
"west": {"uv": [2, 5, 6, 8], "texture": "#6"},
|
||||
"up": {"uv": [0, 0, 0, 0], "texture": "#6"},
|
||||
"down": {"uv": [0, 8, 4, 11], "texture": "#6"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [8, 0, 8],
|
||||
"to": [16, 6, 16],
|
||||
"faces": {
|
||||
"north": {"uv": [2, 5, 6, 8], "texture": "#6"},
|
||||
"east": {"uv": [2, 5, 6, 8], "texture": "#6"},
|
||||
"south": {"uv": [2, 5, 6, 8], "texture": "#6"},
|
||||
"west": {"uv": [0, 0, 0, 0], "texture": "#6"},
|
||||
"up": {"uv": [0, 0, 0, 0], "texture": "#6"},
|
||||
"down": {"uv": [4, 8, 8, 11], "texture": "#6"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [0, 0, 4],
|
||||
"to": [16, 4, 8],
|
||||
"faces": {
|
||||
"north": {"uv": [12, 0, 16, 16], "rotation": 90, "texture": "#1_5"},
|
||||
"east": {"uv": [12, 0, 16, 4], "rotation": 90, "texture": "#1_5"},
|
||||
"south": {"uv": [0, 0, 0, 0], "rotation": 90, "texture": "#6"},
|
||||
"west": {"uv": [12, 12, 16, 16], "rotation": 90, "texture": "#1_5"},
|
||||
"up": {"uv": [8, 0, 16, 2], "texture": "#6"},
|
||||
"down": {"uv": [6, 8, 8, 16], "rotation": 90, "texture": "#6"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [6, 6.25, 6.75],
|
||||
"to": [10, 13.25, 14.75],
|
||||
"faces": {
|
||||
"north": {"uv": [8.5, 1, 12, 3], "rotation": 270, "texture": "#7"},
|
||||
"up": {"uv": [8.5, 1, 12.5, 3], "rotation": 270, "texture": "#7"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [0, 6.25, 6.75],
|
||||
"to": [4, 13.25, 14.75],
|
||||
"faces": {
|
||||
"north": {"uv": [12, 1, 15.5, 3], "rotation": 90, "texture": "#7"},
|
||||
"up": {"uv": [11.5, 1, 15.5, 3], "rotation": 90, "texture": "#7"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [12, 6.25, 6.75],
|
||||
"to": [16, 13.25, 14.75],
|
||||
"faces": {
|
||||
"north": {"uv": [12, 1, 15.5, 3], "rotation": 90, "texture": "#7"},
|
||||
"up": {"uv": [11.5, 1, 15.5, 3], "rotation": 90, "texture": "#7"}
|
||||
}
|
||||
}
|
||||
],
|
||||
"display": {
|
||||
|
@ -148,28 +178,38 @@
|
|||
},
|
||||
"groups": [
|
||||
{
|
||||
"name": "open",
|
||||
"origin": [0, 0, 0],
|
||||
"name": "lever",
|
||||
"origin": [8, 8, 8],
|
||||
"color": 0,
|
||||
"children": [0, 1, 2, 3, 4]
|
||||
"children": [0]
|
||||
},
|
||||
{
|
||||
"name": "lever",
|
||||
"origin": [8, 8, 8],
|
||||
"color": 0,
|
||||
"children": [1]
|
||||
},
|
||||
{
|
||||
"name": "block_open",
|
||||
"origin": [8, 8, 8],
|
||||
"color": 0,
|
||||
"children": [
|
||||
{
|
||||
"name": "open",
|
||||
"origin": [0, 0, 0],
|
||||
"color": 0,
|
||||
"children": [2, 3, 4, 5]
|
||||
},
|
||||
6,
|
||||
7,
|
||||
8
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "cover",
|
||||
"origin": [8, 8, 8],
|
||||
"color": 0,
|
||||
"children": [5, 6, 7]
|
||||
},
|
||||
{
|
||||
"name": "lever",
|
||||
"origin": [8, 8, 8],
|
||||
"color": 0,
|
||||
"children": [8]
|
||||
},
|
||||
{
|
||||
"name": "lever",
|
||||
"origin": [8, 8, 8],
|
||||
"color": 0,
|
||||
"children": [9]
|
||||
"children": [9, 10, 11]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -6,27 +6,27 @@
|
|||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [6, 7.25, 6.75],
|
||||
"from": [6, 6.25, 6.75],
|
||||
"to": [10, 13.25, 14.75],
|
||||
"faces": {
|
||||
"north": {"uv": [10.5, 6, 13.5, 8], "rotation": 270, "texture": "#7"},
|
||||
"up": {"uv": [10, 6, 14, 8], "rotation": 90, "texture": "#7"}
|
||||
"north": {"uv": [8.5, 1, 12, 3], "rotation": 270, "texture": "#7"},
|
||||
"up": {"uv": [8.5, 1, 12.5, 3], "rotation": 270, "texture": "#7"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [0, 7.25, 6.75],
|
||||
"from": [0, 6.25, 6.75],
|
||||
"to": [4, 13.25, 14.75],
|
||||
"faces": {
|
||||
"north": {"uv": [10.5, 6, 13.5, 8], "rotation": 270, "texture": "#7"},
|
||||
"up": {"uv": [10, 6, 14, 8], "rotation": 90, "texture": "#7"}
|
||||
"north": {"uv": [12, 1, 15.5, 3], "rotation": 90, "texture": "#7"},
|
||||
"up": {"uv": [11.5, 1, 15.5, 3], "rotation": 90, "texture": "#7"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [12, 7.25, 6.75],
|
||||
"from": [12, 6.25, 6.75],
|
||||
"to": [16, 13.25, 14.75],
|
||||
"faces": {
|
||||
"north": {"uv": [10.5, 6, 13.5, 8], "rotation": 270, "texture": "#7"},
|
||||
"up": {"uv": [10, 6, 14, 8], "rotation": 90, "texture": "#7"}
|
||||
"north": {"uv": [12, 1, 15.5, 3], "rotation": 90, "texture": "#7"},
|
||||
"up": {"uv": [11.5, 1, 15.5, 3], "rotation": 90, "texture": "#7"}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
Loading…
Reference in a new issue