Out of bounds

- Increased distance at which activated whistles can be heard
- Super glue captured by schematics or /c clone now gets cropped to the selected boundary
- Controlled contraptions now save their anchor block position in relative coords
This commit is contained in:
simibubi 2022-05-09 17:23:57 +02:00
parent d3c4613030
commit 520983d5d0
27 changed files with 273 additions and 127 deletions

View file

@ -544,22 +544,22 @@ bf2b0310500213ff853c748c236eb5d01f61658e assets/create/blockstates/yellow_toolbo
7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json 7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json
b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json
875f9aff979888b9d63d6a425cbf544431f1af5a assets/create/lang/en_ud.json 875f9aff979888b9d63d6a425cbf544431f1af5a assets/create/lang/en_ud.json
1ad377f4a615552b93c377ca77d09d9c3cf72056 assets/create/lang/en_us.json c8e4df6292133a1873e4dccb34c00b1e52afcd92 assets/create/lang/en_us.json
52303333ebdc11d4777bebc86200897dbb4a49a6 assets/create/lang/unfinished/de_de.json 3ca43c518fc5c0120b5cf2aaf37cc78f51625fd4 assets/create/lang/unfinished/de_de.json
c523a1dd9f0ea330f529359bb578de3df2bc1458 assets/create/lang/unfinished/es_cl.json 128d3e35cf2d41dacdb54abd8562091f15323a8c assets/create/lang/unfinished/es_cl.json
099f7b1f415189ece3f4601c5934d812ba27ec33 assets/create/lang/unfinished/es_es.json f02d6b15275a22ac665303e6d7181998f408e1a7 assets/create/lang/unfinished/es_es.json
77132328aec11c2d2489eebf7d7b5d6cbeea65c2 assets/create/lang/unfinished/fr_fr.json 02e43d3f9d2527c2cd72f1a5bfe76397b6cfa32f assets/create/lang/unfinished/fr_fr.json
400aedaa547301ac8f35aed1f0e804bba3439a4c assets/create/lang/unfinished/it_it.json 9f0982f15705f8c3f675f9dfac5b68a753ddf97a assets/create/lang/unfinished/it_it.json
47e91eb3f234db0148251fc587dcf4dfcd03cf4d assets/create/lang/unfinished/ja_jp.json 84d0f74256115e505a239ed826b28002fbc67f86 assets/create/lang/unfinished/ja_jp.json
d7b445abbf9189e0c2bb05a49948ec8515f43b76 assets/create/lang/unfinished/ko_kr.json 96dfb6f44098b2a44c4ba6c53ed6f42a4d7811f5 assets/create/lang/unfinished/ko_kr.json
d870830f76c5e268f43af5b53187ac8efecd0a84 assets/create/lang/unfinished/nl_nl.json 5ea64ddc9613b72376220353819a477bf4c6d64d assets/create/lang/unfinished/nl_nl.json
6b3fcb59cec2b318a63dac081f677d90ae3774c6 assets/create/lang/unfinished/pl_pl.json dd81cd81f426833b627831530c77ab3f3655bb39 assets/create/lang/unfinished/pl_pl.json
863971974b1d54b141c7b1d2a725ec1fd073edc6 assets/create/lang/unfinished/pt_br.json 7cdff911043ccc6232932f85825090305ce92426 assets/create/lang/unfinished/pt_br.json
1dec98db8807133fd2060957b35bf506bfad97ab assets/create/lang/unfinished/pt_pt.json ba139e8ea012ed05598ea5bb57ee6ac95693efdd assets/create/lang/unfinished/pt_pt.json
73d43d4434793a145f8a6cba865a3563b674f43b assets/create/lang/unfinished/ro_ro.json 86ac8dc000591768856bbaa873f9d101faddc1cd assets/create/lang/unfinished/ro_ro.json
a07148fa0254c4b9a4a47026f6da8c91f5a718ab assets/create/lang/unfinished/ru_ru.json 14988b8d3a0b97a7c6b49f392d5088fd59a3aaaa assets/create/lang/unfinished/ru_ru.json
39e11d9262999468a4a5b61986aead6a9263c75d assets/create/lang/unfinished/zh_cn.json 99ffa28fe67913dda825628947e5763f0a21ee8a assets/create/lang/unfinished/zh_cn.json
754ad714ec33c27bb1b546fc12798d422beb865b assets/create/lang/unfinished/zh_tw.json 01da3a96eb7aeea75afed38dd1a83321959fcf0a assets/create/lang/unfinished/zh_tw.json
487a511a01b2a4531fb672f917922312db78f958 assets/create/models/block/acacia_window.json 487a511a01b2a4531fb672f917922312db78f958 assets/create/models/block/acacia_window.json
b48060cba1a382f373a05bf0039054053eccf076 assets/create/models/block/acacia_window_pane_noside.json b48060cba1a382f373a05bf0039054053eccf076 assets/create/models/block/acacia_window_pane_noside.json
3066db1bf03cffa1a9c7fbacf47ae586632f4eb3 assets/create/models/block/acacia_window_pane_noside_alt.json 3066db1bf03cffa1a9c7fbacf47ae586632f4eb3 assets/create/models/block/acacia_window_pane_noside_alt.json
@ -2155,7 +2155,7 @@ d080b1b25e5bc8baf5aee68691b08c7f12ece3b0 assets/create/models/item/windmill_bear
866fbb0ce2878a73e0440d1caf6534c8bd7c384f assets/create/models/item/zinc_ingot.json 866fbb0ce2878a73e0440d1caf6534c8bd7c384f assets/create/models/item/zinc_ingot.json
a80fb25a0b655e76be986b5b49fcb0f03461a1ab assets/create/models/item/zinc_nugget.json a80fb25a0b655e76be986b5b49fcb0f03461a1ab assets/create/models/item/zinc_nugget.json
b1689617190c05ef34bd18456b0c7ae09bb3210f assets/create/models/item/zinc_ore.json b1689617190c05ef34bd18456b0c7ae09bb3210f assets/create/models/item/zinc_ore.json
79691595de849f2821595483c6486501581c66cd assets/create/sounds.json 92c34840e05861f7f98aa2f942f9a90370f82cd6 assets/create/sounds.json
0f1b4b980afba9bf2caf583b88e261bba8b10313 data/create/advancements/aesthetics.json 0f1b4b980afba9bf2caf583b88e261bba8b10313 data/create/advancements/aesthetics.json
613e64b44bed959da899fdd54c1cacb227fb33f2 data/create/advancements/andesite_alloy.json 613e64b44bed959da899fdd54c1cacb227fb33f2 data/create/advancements/andesite_alloy.json
81885c6bfb85792c88aaa7c9b70f58832945d31f data/create/advancements/andesite_casing.json 81885c6bfb85792c88aaa7c9b70f58832945d31f data/create/advancements/andesite_casing.json

View file

@ -1590,11 +1590,11 @@
"create.subtitle.wrench_rotate": "Wrench used", "create.subtitle.wrench_rotate": "Wrench used",
"create.subtitle.potato_hit": "Vegetable impacts", "create.subtitle.potato_hit": "Vegetable impacts",
"create.subtitle.saw_activate_wood": "Mechanical Saw activates", "create.subtitle.saw_activate_wood": "Mechanical Saw activates",
"create.subtitle.whistle_high": "Whistling", "create.subtitle.whistle_high": "High whistling",
"create.subtitle.haunted_bell_convert": "Haunted Bell awakens", "create.subtitle.haunted_bell_convert": "Haunted Bell awakens",
"create.subtitle.deny": "Declining boop", "create.subtitle.deny": "Declining boop",
"create.subtitle.controller_click": "Controller clicks", "create.subtitle.controller_click": "Controller clicks",
"create.subtitle.whistle_low": "Whistling", "create.subtitle.whistle_low": "Low whistling",
"create.subtitle.schematicannon_launch_block": "Schematicannon fires", "create.subtitle.schematicannon_launch_block": "Schematicannon fires",
"create.subtitle.copper_armor_equip": "Diving equipment clinks", "create.subtitle.copper_armor_equip": "Diving equipment clinks",
"create.subtitle.controller_take": "Lectern empties", "create.subtitle.controller_take": "Lectern empties",

View file

@ -1591,11 +1591,11 @@
"create.subtitle.wrench_rotate": "UNLOCALIZED: Wrench used", "create.subtitle.wrench_rotate": "UNLOCALIZED: Wrench used",
"create.subtitle.potato_hit": "UNLOCALIZED: Vegetable impacts", "create.subtitle.potato_hit": "UNLOCALIZED: Vegetable impacts",
"create.subtitle.saw_activate_wood": "UNLOCALIZED: Mechanical Saw activates", "create.subtitle.saw_activate_wood": "UNLOCALIZED: Mechanical Saw activates",
"create.subtitle.whistle_high": "UNLOCALIZED: Whistling", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling",
"create.subtitle.haunted_bell_convert": "UNLOCALIZED: Haunted Bell awakens", "create.subtitle.haunted_bell_convert": "UNLOCALIZED: Haunted Bell awakens",
"create.subtitle.deny": "UNLOCALIZED: Declining boop", "create.subtitle.deny": "UNLOCALIZED: Declining boop",
"create.subtitle.controller_click": "UNLOCALIZED: Controller clicks", "create.subtitle.controller_click": "UNLOCALIZED: Controller clicks",
"create.subtitle.whistle_low": "UNLOCALIZED: Whistling", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling",
"create.subtitle.schematicannon_launch_block": "Bauplankanone schießt", "create.subtitle.schematicannon_launch_block": "Bauplankanone schießt",
"create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks", "create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks",
"create.subtitle.controller_take": "UNLOCALIZED: Lectern empties", "create.subtitle.controller_take": "UNLOCALIZED: Lectern empties",

View file

@ -1591,11 +1591,11 @@
"create.subtitle.wrench_rotate": "Llave Inglesa usada", "create.subtitle.wrench_rotate": "Llave Inglesa usada",
"create.subtitle.potato_hit": "Impactos vegetales", "create.subtitle.potato_hit": "Impactos vegetales",
"create.subtitle.saw_activate_wood": "Sierra Mecánica se activa", "create.subtitle.saw_activate_wood": "Sierra Mecánica se activa",
"create.subtitle.whistle_high": "UNLOCALIZED: Whistling", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling",
"create.subtitle.haunted_bell_convert": "Campana Embrujada despierta", "create.subtitle.haunted_bell_convert": "Campana Embrujada despierta",
"create.subtitle.deny": "Boop denegante", "create.subtitle.deny": "Boop denegante",
"create.subtitle.controller_click": "Controlador cliquea", "create.subtitle.controller_click": "Controlador cliquea",
"create.subtitle.whistle_low": "UNLOCALIZED: Whistling", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling",
"create.subtitle.schematicannon_launch_block": "Esquemacañón dispara", "create.subtitle.schematicannon_launch_block": "Esquemacañón dispara",
"create.subtitle.copper_armor_equip": "Equipo de Buceo tintinea", "create.subtitle.copper_armor_equip": "Equipo de Buceo tintinea",
"create.subtitle.controller_take": "Atril se Vacía", "create.subtitle.controller_take": "Atril se Vacía",

View file

@ -1591,11 +1591,11 @@
"create.subtitle.wrench_rotate": "Llave inglesa usada", "create.subtitle.wrench_rotate": "Llave inglesa usada",
"create.subtitle.potato_hit": "Impacto de vegetal", "create.subtitle.potato_hit": "Impacto de vegetal",
"create.subtitle.saw_activate_wood": "Sierra mecánica activada", "create.subtitle.saw_activate_wood": "Sierra mecánica activada",
"create.subtitle.whistle_high": "UNLOCALIZED: Whistling", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling",
"create.subtitle.haunted_bell_convert": "Campana maldita se despierta", "create.subtitle.haunted_bell_convert": "Campana maldita se despierta",
"create.subtitle.deny": "Pitido denegante", "create.subtitle.deny": "Pitido denegante",
"create.subtitle.controller_click": "", "create.subtitle.controller_click": "",
"create.subtitle.whistle_low": "UNLOCALIZED: Whistling", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling",
"create.subtitle.schematicannon_launch_block": "Esquematicañón dispara", "create.subtitle.schematicannon_launch_block": "Esquematicañón dispara",
"create.subtitle.copper_armor_equip": "Equipo de buceo tintinea", "create.subtitle.copper_armor_equip": "Equipo de buceo tintinea",
"create.subtitle.controller_take": "Atril vaciándose", "create.subtitle.controller_take": "Atril vaciándose",

View file

@ -1591,11 +1591,11 @@
"create.subtitle.wrench_rotate": "UNLOCALIZED: Wrench used", "create.subtitle.wrench_rotate": "UNLOCALIZED: Wrench used",
"create.subtitle.potato_hit": "UNLOCALIZED: Vegetable impacts", "create.subtitle.potato_hit": "UNLOCALIZED: Vegetable impacts",
"create.subtitle.saw_activate_wood": "UNLOCALIZED: Mechanical Saw activates", "create.subtitle.saw_activate_wood": "UNLOCALIZED: Mechanical Saw activates",
"create.subtitle.whistle_high": "UNLOCALIZED: Whistling", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling",
"create.subtitle.haunted_bell_convert": "UNLOCALIZED: Haunted Bell awakens", "create.subtitle.haunted_bell_convert": "UNLOCALIZED: Haunted Bell awakens",
"create.subtitle.deny": "UNLOCALIZED: Declining boop", "create.subtitle.deny": "UNLOCALIZED: Declining boop",
"create.subtitle.controller_click": "UNLOCALIZED: Controller clicks", "create.subtitle.controller_click": "UNLOCALIZED: Controller clicks",
"create.subtitle.whistle_low": "UNLOCALIZED: Whistling", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling",
"create.subtitle.schematicannon_launch_block": "Tir de schémacanon", "create.subtitle.schematicannon_launch_block": "Tir de schémacanon",
"create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks", "create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks",
"create.subtitle.controller_take": "UNLOCALIZED: Lectern empties", "create.subtitle.controller_take": "UNLOCALIZED: Lectern empties",

View file

@ -1591,11 +1591,11 @@
"create.subtitle.wrench_rotate": "UNLOCALIZED: Wrench used", "create.subtitle.wrench_rotate": "UNLOCALIZED: Wrench used",
"create.subtitle.potato_hit": "UNLOCALIZED: Vegetable impacts", "create.subtitle.potato_hit": "UNLOCALIZED: Vegetable impacts",
"create.subtitle.saw_activate_wood": "UNLOCALIZED: Mechanical Saw activates", "create.subtitle.saw_activate_wood": "UNLOCALIZED: Mechanical Saw activates",
"create.subtitle.whistle_high": "UNLOCALIZED: Whistling", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling",
"create.subtitle.haunted_bell_convert": "UNLOCALIZED: Haunted Bell awakens", "create.subtitle.haunted_bell_convert": "UNLOCALIZED: Haunted Bell awakens",
"create.subtitle.deny": "UNLOCALIZED: Declining boop", "create.subtitle.deny": "UNLOCALIZED: Declining boop",
"create.subtitle.controller_click": "UNLOCALIZED: Controller clicks", "create.subtitle.controller_click": "UNLOCALIZED: Controller clicks",
"create.subtitle.whistle_low": "UNLOCALIZED: Whistling", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling",
"create.subtitle.schematicannon_launch_block": "Tiri del cannoneschematico", "create.subtitle.schematicannon_launch_block": "Tiri del cannoneschematico",
"create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks", "create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks",
"create.subtitle.controller_take": "UNLOCALIZED: Lectern empties", "create.subtitle.controller_take": "UNLOCALIZED: Lectern empties",

View file

@ -1591,11 +1591,11 @@
"create.subtitle.wrench_rotate": "レンチが使用される", "create.subtitle.wrench_rotate": "レンチが使用される",
"create.subtitle.potato_hit": "野菜の衝撃", "create.subtitle.potato_hit": "野菜の衝撃",
"create.subtitle.saw_activate_wood": "メカニカルソーが動作する", "create.subtitle.saw_activate_wood": "メカニカルソーが動作する",
"create.subtitle.whistle_high": "UNLOCALIZED: Whistling", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling",
"create.subtitle.haunted_bell_convert": "憑りつかれた鐘が目覚める", "create.subtitle.haunted_bell_convert": "憑りつかれた鐘が目覚める",
"create.subtitle.deny": "失敗音", "create.subtitle.deny": "失敗音",
"create.subtitle.controller_click": "コントローラーのカチカチ音", "create.subtitle.controller_click": "コントローラーのカチカチ音",
"create.subtitle.whistle_low": "UNLOCALIZED: Whistling", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling",
"create.subtitle.schematicannon_launch_block": "概略図砲が発射する", "create.subtitle.schematicannon_launch_block": "概略図砲が発射する",
"create.subtitle.copper_armor_equip": "潜水服がチャリンと鳴る", "create.subtitle.copper_armor_equip": "潜水服がチャリンと鳴る",
"create.subtitle.controller_take": "書見台が空になる", "create.subtitle.controller_take": "書見台が空になる",

View file

@ -1591,11 +1591,11 @@
"create.subtitle.wrench_rotate": "렌치를 사용함", "create.subtitle.wrench_rotate": "렌치를 사용함",
"create.subtitle.potato_hit": "채소가 부딫힘", "create.subtitle.potato_hit": "채소가 부딫힘",
"create.subtitle.saw_activate_wood": "톱이 작동함", "create.subtitle.saw_activate_wood": "톱이 작동함",
"create.subtitle.whistle_high": "UNLOCALIZED: Whistling", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling",
"create.subtitle.haunted_bell_convert": "종에 귀신이 들림", "create.subtitle.haunted_bell_convert": "종에 귀신이 들림",
"create.subtitle.deny": "취소음", "create.subtitle.deny": "취소음",
"create.subtitle.controller_click": "조작기를 누름", "create.subtitle.controller_click": "조작기를 누름",
"create.subtitle.whistle_low": "UNLOCALIZED: Whistling", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling",
"create.subtitle.schematicannon_launch_block": "청사진 대포가 발사함", "create.subtitle.schematicannon_launch_block": "청사진 대포가 발사함",
"create.subtitle.copper_armor_equip": "잠수용 장비가 철커덕거림", "create.subtitle.copper_armor_equip": "잠수용 장비가 철커덕거림",
"create.subtitle.controller_take": "독서대가 비워짐", "create.subtitle.controller_take": "독서대가 비워짐",

View file

@ -1591,11 +1591,11 @@
"create.subtitle.wrench_rotate": "UNLOCALIZED: Wrench used", "create.subtitle.wrench_rotate": "UNLOCALIZED: Wrench used",
"create.subtitle.potato_hit": "UNLOCALIZED: Vegetable impacts", "create.subtitle.potato_hit": "UNLOCALIZED: Vegetable impacts",
"create.subtitle.saw_activate_wood": "UNLOCALIZED: Mechanical Saw activates", "create.subtitle.saw_activate_wood": "UNLOCALIZED: Mechanical Saw activates",
"create.subtitle.whistle_high": "UNLOCALIZED: Whistling", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling",
"create.subtitle.haunted_bell_convert": "UNLOCALIZED: Haunted Bell awakens", "create.subtitle.haunted_bell_convert": "UNLOCALIZED: Haunted Bell awakens",
"create.subtitle.deny": "UNLOCALIZED: Declining boop", "create.subtitle.deny": "UNLOCALIZED: Declining boop",
"create.subtitle.controller_click": "UNLOCALIZED: Controller clicks", "create.subtitle.controller_click": "UNLOCALIZED: Controller clicks",
"create.subtitle.whistle_low": "UNLOCALIZED: Whistling", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling",
"create.subtitle.schematicannon_launch_block": "UNLOCALIZED: Schematicannon fires", "create.subtitle.schematicannon_launch_block": "UNLOCALIZED: Schematicannon fires",
"create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks", "create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks",
"create.subtitle.controller_take": "UNLOCALIZED: Lectern empties", "create.subtitle.controller_take": "UNLOCALIZED: Lectern empties",

View file

@ -1591,11 +1591,11 @@
"create.subtitle.wrench_rotate": "Klucz skrzypi", "create.subtitle.wrench_rotate": "Klucz skrzypi",
"create.subtitle.potato_hit": "Warzywo ląduje", "create.subtitle.potato_hit": "Warzywo ląduje",
"create.subtitle.saw_activate_wood": "Mechaniczna piła aktywuje się", "create.subtitle.saw_activate_wood": "Mechaniczna piła aktywuje się",
"create.subtitle.whistle_high": "UNLOCALIZED: Whistling", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling",
"create.subtitle.haunted_bell_convert": "Nawiedzony dzwon budzi się", "create.subtitle.haunted_bell_convert": "Nawiedzony dzwon budzi się",
"create.subtitle.deny": "Dźwięk odmowy", "create.subtitle.deny": "Dźwięk odmowy",
"create.subtitle.controller_click": "Sterownik klika", "create.subtitle.controller_click": "Sterownik klika",
"create.subtitle.whistle_low": "UNLOCALIZED: Whistling", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling",
"create.subtitle.schematicannon_launch_block": "Schematoarmata strzela", "create.subtitle.schematicannon_launch_block": "Schematoarmata strzela",
"create.subtitle.copper_armor_equip": "Sprzęt do nurkowania pobrzękuje", "create.subtitle.copper_armor_equip": "Sprzęt do nurkowania pobrzękuje",
"create.subtitle.controller_take": "Pulpit opróżnia się", "create.subtitle.controller_take": "Pulpit opróżnia się",

View file

@ -1591,11 +1591,11 @@
"create.subtitle.wrench_rotate": "UNLOCALIZED: Wrench used", "create.subtitle.wrench_rotate": "UNLOCALIZED: Wrench used",
"create.subtitle.potato_hit": "UNLOCALIZED: Vegetable impacts", "create.subtitle.potato_hit": "UNLOCALIZED: Vegetable impacts",
"create.subtitle.saw_activate_wood": "UNLOCALIZED: Mechanical Saw activates", "create.subtitle.saw_activate_wood": "UNLOCALIZED: Mechanical Saw activates",
"create.subtitle.whistle_high": "UNLOCALIZED: Whistling", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling",
"create.subtitle.haunted_bell_convert": "UNLOCALIZED: Haunted Bell awakens", "create.subtitle.haunted_bell_convert": "UNLOCALIZED: Haunted Bell awakens",
"create.subtitle.deny": "UNLOCALIZED: Declining boop", "create.subtitle.deny": "UNLOCALIZED: Declining boop",
"create.subtitle.controller_click": "UNLOCALIZED: Controller clicks", "create.subtitle.controller_click": "UNLOCALIZED: Controller clicks",
"create.subtitle.whistle_low": "UNLOCALIZED: Whistling", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling",
"create.subtitle.schematicannon_launch_block": "UNLOCALIZED: Schematicannon fires", "create.subtitle.schematicannon_launch_block": "UNLOCALIZED: Schematicannon fires",
"create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks", "create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks",
"create.subtitle.controller_take": "UNLOCALIZED: Lectern empties", "create.subtitle.controller_take": "UNLOCALIZED: Lectern empties",

View file

@ -1591,11 +1591,11 @@
"create.subtitle.wrench_rotate": "UNLOCALIZED: Wrench used", "create.subtitle.wrench_rotate": "UNLOCALIZED: Wrench used",
"create.subtitle.potato_hit": "UNLOCALIZED: Vegetable impacts", "create.subtitle.potato_hit": "UNLOCALIZED: Vegetable impacts",
"create.subtitle.saw_activate_wood": "UNLOCALIZED: Mechanical Saw activates", "create.subtitle.saw_activate_wood": "UNLOCALIZED: Mechanical Saw activates",
"create.subtitle.whistle_high": "UNLOCALIZED: Whistling", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling",
"create.subtitle.haunted_bell_convert": "UNLOCALIZED: Haunted Bell awakens", "create.subtitle.haunted_bell_convert": "UNLOCALIZED: Haunted Bell awakens",
"create.subtitle.deny": "UNLOCALIZED: Declining boop", "create.subtitle.deny": "UNLOCALIZED: Declining boop",
"create.subtitle.controller_click": "UNLOCALIZED: Controller clicks", "create.subtitle.controller_click": "UNLOCALIZED: Controller clicks",
"create.subtitle.whistle_low": "UNLOCALIZED: Whistling", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling",
"create.subtitle.schematicannon_launch_block": "UNLOCALIZED: Schematicannon fires", "create.subtitle.schematicannon_launch_block": "UNLOCALIZED: Schematicannon fires",
"create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks", "create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks",
"create.subtitle.controller_take": "UNLOCALIZED: Lectern empties", "create.subtitle.controller_take": "UNLOCALIZED: Lectern empties",

View file

@ -1591,11 +1591,11 @@
"create.subtitle.wrench_rotate": "Cheie folosită", "create.subtitle.wrench_rotate": "Cheie folosită",
"create.subtitle.potato_hit": "Impact de legumă", "create.subtitle.potato_hit": "Impact de legumă",
"create.subtitle.saw_activate_wood": "Ferăstrău Mecanic se activează", "create.subtitle.saw_activate_wood": "Ferăstrău Mecanic se activează",
"create.subtitle.whistle_high": "UNLOCALIZED: Whistling", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling",
"create.subtitle.haunted_bell_convert": "Clopot Bântuit se trezețte", "create.subtitle.haunted_bell_convert": "Clopot Bântuit se trezețte",
"create.subtitle.deny": "Boop de refuz", "create.subtitle.deny": "Boop de refuz",
"create.subtitle.controller_click": "Controlor clickuiește", "create.subtitle.controller_click": "Controlor clickuiește",
"create.subtitle.whistle_low": "UNLOCALIZED: Whistling", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling",
"create.subtitle.schematicannon_launch_block": "Tun de Schemă trage", "create.subtitle.schematicannon_launch_block": "Tun de Schemă trage",
"create.subtitle.copper_armor_equip": "Echipament de scufundare ciocăne", "create.subtitle.copper_armor_equip": "Echipament de scufundare ciocăne",
"create.subtitle.controller_take": "Pupitru se golește", "create.subtitle.controller_take": "Pupitru se golește",

View file

@ -1591,11 +1591,11 @@
"create.subtitle.wrench_rotate": "Использован гаечный ключ", "create.subtitle.wrench_rotate": "Использован гаечный ключ",
"create.subtitle.potato_hit": "Овощ врезается", "create.subtitle.potato_hit": "Овощ врезается",
"create.subtitle.saw_activate_wood": "Активируется механическая пила", "create.subtitle.saw_activate_wood": "Активируется механическая пила",
"create.subtitle.whistle_high": "UNLOCALIZED: Whistling", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling",
"create.subtitle.haunted_bell_convert": "Призрачный колокол пробуждается", "create.subtitle.haunted_bell_convert": "Призрачный колокол пробуждается",
"create.subtitle.deny": "Отрицательный «Буп»", "create.subtitle.deny": "Отрицательный «Буп»",
"create.subtitle.controller_click": "Клики контроллера", "create.subtitle.controller_click": "Клики контроллера",
"create.subtitle.whistle_low": "UNLOCALIZED: Whistling", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling",
"create.subtitle.schematicannon_launch_block": "Выстрелы схематичной пушки", "create.subtitle.schematicannon_launch_block": "Выстрелы схематичной пушки",
"create.subtitle.copper_armor_equip": "Позвякивание снаряжения для дайвинга", "create.subtitle.copper_armor_equip": "Позвякивание снаряжения для дайвинга",
"create.subtitle.controller_take": "Кафедра опустошается", "create.subtitle.controller_take": "Кафедра опустошается",

View file

@ -1591,11 +1591,11 @@
"create.subtitle.wrench_rotate": "扳手:拧动", "create.subtitle.wrench_rotate": "扳手:拧动",
"create.subtitle.potato_hit": "土豆:击中", "create.subtitle.potato_hit": "土豆:击中",
"create.subtitle.saw_activate_wood": "动力锯:切割", "create.subtitle.saw_activate_wood": "动力锯:切割",
"create.subtitle.whistle_high": "UNLOCALIZED: Whistling", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling",
"create.subtitle.haunted_bell_convert": "奇异钟:转化", "create.subtitle.haunted_bell_convert": "奇异钟:转化",
"create.subtitle.deny": "提示声:出错", "create.subtitle.deny": "提示声:出错",
"create.subtitle.controller_click": "遥控器:按下按钮", "create.subtitle.controller_click": "遥控器:按下按钮",
"create.subtitle.whistle_low": "UNLOCALIZED: Whistling", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling",
"create.subtitle.schematicannon_launch_block": "蓝图加农炮:发射", "create.subtitle.schematicannon_launch_block": "蓝图加农炮:发射",
"create.subtitle.copper_armor_equip": "潜水装备:铿锵", "create.subtitle.copper_armor_equip": "潜水装备:铿锵",
"create.subtitle.controller_take": "讲台:取走物品", "create.subtitle.controller_take": "讲台:取走物品",

View file

@ -1591,11 +1591,11 @@
"create.subtitle.wrench_rotate": "UNLOCALIZED: Wrench used", "create.subtitle.wrench_rotate": "UNLOCALIZED: Wrench used",
"create.subtitle.potato_hit": "食物撞擊聲", "create.subtitle.potato_hit": "食物撞擊聲",
"create.subtitle.saw_activate_wood": "機械鋸子運作聲", "create.subtitle.saw_activate_wood": "機械鋸子運作聲",
"create.subtitle.whistle_high": "UNLOCALIZED: Whistling", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling",
"create.subtitle.haunted_bell_convert": "靈魂鐘轉化聲", "create.subtitle.haunted_bell_convert": "靈魂鐘轉化聲",
"create.subtitle.deny": "UNLOCALIZED: Declining boop", "create.subtitle.deny": "UNLOCALIZED: Declining boop",
"create.subtitle.controller_click": "遙控器按鍵聲", "create.subtitle.controller_click": "遙控器按鍵聲",
"create.subtitle.whistle_low": "UNLOCALIZED: Whistling", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling",
"create.subtitle.schematicannon_launch_block": "藍圖大炮發射", "create.subtitle.schematicannon_launch_block": "藍圖大炮發射",
"create.subtitle.copper_armor_equip": "潛水裝裝備聲", "create.subtitle.copper_armor_equip": "潛水裝裝備聲",
"create.subtitle.controller_take": "拿下遙控器", "create.subtitle.controller_take": "拿下遙控器",

View file

@ -10,13 +10,19 @@
}, },
"chiff": { "chiff": {
"sounds": [ "sounds": [
"create:chiff" {
"name": "create:chiff",
"type": "file"
}
], ],
"subtitle": "create.subtitle.chiff" "subtitle": "create.subtitle.chiff"
}, },
"cogs": { "cogs": {
"sounds": [ "sounds": [
"create:cogs" {
"name": "create:cogs",
"type": "file"
}
], ],
"subtitle": "create.subtitle.cogs" "subtitle": "create.subtitle.cogs"
}, },
@ -205,19 +211,28 @@
}, },
"fwoomp": { "fwoomp": {
"sounds": [ "sounds": [
"create:fwoomp" {
"name": "create:fwoomp",
"type": "file"
}
], ],
"subtitle": "create.subtitle.fwoomp" "subtitle": "create.subtitle.fwoomp"
}, },
"haunted_bell_convert": { "haunted_bell_convert": {
"sounds": [ "sounds": [
"create:haunted_bell_convert" {
"name": "create:haunted_bell_convert",
"type": "file"
}
], ],
"subtitle": "create.subtitle.haunted_bell_convert" "subtitle": "create.subtitle.haunted_bell_convert"
}, },
"haunted_bell_use": { "haunted_bell_use": {
"sounds": [ "sounds": [
"create:haunted_bell_use" {
"name": "create:haunted_bell_use",
"type": "file"
}
], ],
"subtitle": "create.subtitle.haunted_bell_use" "subtitle": "create.subtitle.haunted_bell_use"
}, },
@ -300,14 +315,23 @@
}, },
"sanding_long": { "sanding_long": {
"sounds": [ "sounds": [
"create:sanding_long" {
"name": "create:sanding_long",
"type": "file"
}
], ],
"subtitle": "create.subtitle.sanding_long" "subtitle": "create.subtitle.sanding_long"
}, },
"sanding_short": { "sanding_short": {
"sounds": [ "sounds": [
"create:sanding_short", {
"create:sanding_short_1" "name": "create:sanding_short",
"type": "file"
},
{
"name": "create:sanding_short_1",
"type": "file"
}
], ],
"subtitle": "create.subtitle.sanding_short" "subtitle": "create.subtitle.sanding_short"
}, },
@ -367,19 +391,31 @@
}, },
"whistle": { "whistle": {
"sounds": [ "sounds": [
"create:whistle" {
"name": "create:whistle",
"type": "file",
"attenuation_distance": 64
}
], ],
"subtitle": "create.subtitle.whistle" "subtitle": "create.subtitle.whistle"
}, },
"whistle_high": { "whistle_high": {
"sounds": [ "sounds": [
"create:whistle_high" {
"name": "create:whistle_high",
"type": "file",
"attenuation_distance": 64
}
], ],
"subtitle": "create.subtitle.whistle_high" "subtitle": "create.subtitle.whistle_high"
}, },
"whistle_low": { "whistle_low": {
"sounds": [ "sounds": [
"create:whistle_low" {
"name": "create:whistle_low",
"type": "file",
"attenuation_distance": 64
}
], ],
"subtitle": "create.subtitle.whistle_low" "subtitle": "create.subtitle.whistle_low"
}, },

View file

@ -223,16 +223,19 @@ public class AllSoundEvents {
.category(SoundSource.BLOCKS) .category(SoundSource.BLOCKS)
.build(), .build(),
WHISTLE_HIGH = create("whistle_high").subtitle("Whistling") WHISTLE_HIGH = create("whistle_high").subtitle("High whistling")
.category(SoundSource.RECORDS) .category(SoundSource.RECORDS)
.attenuationDistance(64)
.build(), .build(),
WHISTLE = create("whistle").subtitle("Whistling") WHISTLE = create("whistle").subtitle("Whistling")
.category(SoundSource.RECORDS) .category(SoundSource.RECORDS)
.attenuationDistance(64)
.build(), .build(),
WHISTLE_LOW = create("whistle_low").subtitle("Whistling") WHISTLE_LOW = create("whistle_low").subtitle("Low whistling")
.category(SoundSource.RECORDS) .category(SoundSource.RECORDS)
.attenuationDistance(64)
.build(), .build(),
WHISTLE_CHIFF = create("chiff").noSubtitle() WHISTLE_CHIFF = create("chiff").noSubtitle()
@ -342,6 +345,7 @@ public class AllSoundEvents {
protected SoundSource category = SoundSource.BLOCKS; protected SoundSource category = SoundSource.BLOCKS;
protected List<Pair<SoundEvent, Couple<Float>>> wrappedEvents; protected List<Pair<SoundEvent, Couple<Float>>> wrappedEvents;
protected List<ResourceLocation> variants; protected List<ResourceLocation> variants;
protected int attenuationDistance;
public SoundEntryBuilder(ResourceLocation id) { public SoundEntryBuilder(ResourceLocation id) {
wrappedEvents = new ArrayList<>(); wrappedEvents = new ArrayList<>();
@ -354,6 +358,11 @@ public class AllSoundEvents {
return this; return this;
} }
public SoundEntryBuilder attenuationDistance(int distance) {
this.attenuationDistance = distance;
return this;
}
public SoundEntryBuilder noSubtitle() { public SoundEntryBuilder noSubtitle() {
this.subtitle = null; this.subtitle = null;
return this; return this;
@ -383,7 +392,8 @@ public class AllSoundEvents {
} }
public SoundEntry build() { public SoundEntry build() {
SoundEntry entry = wrappedEvents.isEmpty() ? new CustomSoundEntry(id, variants, subtitle, category) SoundEntry entry =
wrappedEvents.isEmpty() ? new CustomSoundEntry(id, variants, subtitle, category, attenuationDistance)
: new WrappedSoundEntry(id, subtitle, wrappedEvents, category); : new WrappedSoundEntry(id, subtitle, wrappedEvents, category);
entries.put(entry.getId(), entry); entries.put(entry.getId(), entry);
return entry; return entry;
@ -550,11 +560,13 @@ public class AllSoundEvents {
protected List<ResourceLocation> variants; protected List<ResourceLocation> variants;
protected SoundEvent event; protected SoundEvent event;
protected int attenuationDistance;
public CustomSoundEntry(ResourceLocation id, List<ResourceLocation> variants, String subtitle, public CustomSoundEntry(ResourceLocation id, List<ResourceLocation> variants, String subtitle,
SoundSource category) { SoundSource category, int attenuationDistance) {
super(id, subtitle, category); super(id, subtitle, category);
this.variants = variants; this.variants = variants;
this.attenuationDistance = attenuationDistance;
} }
@Override @Override
@ -577,9 +589,20 @@ public class AllSoundEvents {
JsonObject entry = new JsonObject(); JsonObject entry = new JsonObject();
JsonArray list = new JsonArray(); JsonArray list = new JsonArray();
list.add(id.toString()); JsonObject s = new JsonObject();
s.addProperty("name", id.toString());
s.addProperty("type", "file");
if (attenuationDistance != 0)
s.addProperty("attenuation_distance", attenuationDistance);
list.add(s);
for (ResourceLocation variant : variants) { for (ResourceLocation variant : variants) {
list.add(variant.toString()); s = new JsonObject();
s.addProperty("name", variant.toString());
s.addProperty("type", "file");
if (attenuationDistance != 0)
s.addProperty("attenuation_distance", attenuationDistance);
list.add(s);
} }
entry.add("sounds", list); entry.add("sounds", list);

View file

@ -1,13 +1,14 @@
package com.simibubi.create.content.contraptions.components.steam.whistle; package com.simibubi.create.content.contraptions.components.steam.whistle;
import com.simibubi.create.AllSoundEvents; import static com.simibubi.create.AllSoundEvents.WHISTLE;
import static com.simibubi.create.AllSoundEvents.WHISTLE_HIGH;
import static com.simibubi.create.AllSoundEvents.WHISTLE_LOW;
import com.simibubi.create.content.contraptions.components.steam.whistle.WhistleBlock.WhistleSize; import com.simibubi.create.content.contraptions.components.steam.whistle.WhistleBlock.WhistleSize;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.sounds.AbstractTickableSoundInstance; import net.minecraft.client.resources.sounds.AbstractTickableSoundInstance;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.sounds.SoundSource; import net.minecraft.sounds.SoundSource;
import net.minecraft.util.Mth;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
public class WhistleSoundInstance extends AbstractTickableSoundInstance { public class WhistleSoundInstance extends AbstractTickableSoundInstance {
@ -17,10 +18,8 @@ public class WhistleSoundInstance extends AbstractTickableSoundInstance {
private WhistleSize size; private WhistleSize size;
public WhistleSoundInstance(WhistleSize size, BlockPos worldPosition) { public WhistleSoundInstance(WhistleSize size, BlockPos worldPosition) {
super( super((size == WhistleSize.SMALL ? WHISTLE_HIGH : size == WhistleSize.MEDIUM ? WHISTLE : WHISTLE_LOW)
(size == WhistleSize.SMALL ? AllSoundEvents.WHISTLE_HIGH .getMainEvent(), SoundSource.RECORDS);
: size == WhistleSize.MEDIUM ? AllSoundEvents.WHISTLE : AllSoundEvents.WHISTLE_LOW).getMainEvent(),
SoundSource.RECORDS);
this.size = size; this.size = size;
looping = true; looping = true;
active = true; active = true;
@ -51,11 +50,8 @@ public class WhistleSoundInstance extends AbstractTickableSoundInstance {
@Override @Override
public void tick() { public void tick() {
Vec3 eyePosition = Minecraft.getInstance().cameraEntity.getEyePosition();
float maxVolume = (float) Mth.clamp((30 - eyePosition.distanceTo(new Vec3(x, y, z))) / 30, 0, .75f);
if (active) { if (active) {
volume = Math.min(1, volume + .25f); volume = Math.min(1, volume + .25f);
volume = Math.min(volume, maxVolume);
keepAlive--; keepAlive--;
if (keepAlive == 0) if (keepAlive == 0)
fadeOut(); fadeOut();
@ -63,7 +59,6 @@ public class WhistleSoundInstance extends AbstractTickableSoundInstance {
} }
volume = Math.max(0, volume - .25f); volume = Math.max(0, volume - .25f);
volume = Math.min(volume, maxVolume);
if (volume == 0) if (volume == 0)
stop(); stop();
} }

View file

@ -25,6 +25,7 @@ import net.minecraft.core.Direction.Axis;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent; import net.minecraft.network.chat.TextComponent;
import net.minecraft.util.Mth;
import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
@ -123,13 +124,15 @@ public class WhistleTileEntity extends SmartTileEntity implements IHaveGoggleInf
float f = (float) Math.pow(2, -pitch / 12.0); float f = (float) Math.pow(2, -pitch / 12.0);
boolean particle = level.getGameTime() % 8 == 0; boolean particle = level.getGameTime() % 8 == 0;
Vec3 eyePosition = Minecraft.getInstance().cameraEntity.getEyePosition();
float maxVolume = (float) Mth.clamp((64 - eyePosition.distanceTo(Vec3.atCenterOf(worldPosition))) / 64, 0, 1);
if (soundInstance == null || soundInstance.isStopped() || soundInstance.getOctave() != size) { if (soundInstance == null || soundInstance.isStopped() || soundInstance.getOctave() != size) {
Minecraft.getInstance() Minecraft.getInstance()
.getSoundManager() .getSoundManager()
.play(soundInstance = new WhistleSoundInstance(size, worldPosition)); .play(soundInstance = new WhistleSoundInstance(size, worldPosition));
AllSoundEvents.WHISTLE_CHIFF.playAt(level, worldPosition, 0.25f, size == WhistleSize.SMALL ? f + .75f : f, AllSoundEvents.WHISTLE_CHIFF.playAt(level, worldPosition, maxVolume * .175f,
true); size == WhistleSize.SMALL ? f + .75f : f, false);
particle = true; particle = true;
} }

View file

@ -68,7 +68,11 @@ public class ControlledContraptionEntity extends AbstractContraptionEntity {
@Override @Override
protected void readAdditional(CompoundTag compound, boolean spawnPacket) { protected void readAdditional(CompoundTag compound, boolean spawnPacket) {
super.readAdditional(compound, spawnPacket); super.readAdditional(compound, spawnPacket);
if (compound.contains("Controller")) // legacy
controllerPos = NbtUtils.readBlockPos(compound.getCompound("Controller")); controllerPos = NbtUtils.readBlockPos(compound.getCompound("Controller"));
else
controllerPos = NbtUtils.readBlockPos(compound.getCompound("ControllerRelative"))
.offset(blockPosition());
if (compound.contains("Axis")) if (compound.contains("Axis"))
rotationAxis = NBTHelper.readEnum(compound, "Axis", Axis.class); rotationAxis = NBTHelper.readEnum(compound, "Axis", Axis.class);
angle = compound.getFloat("Angle"); angle = compound.getFloat("Angle");
@ -77,7 +81,7 @@ public class ControlledContraptionEntity extends AbstractContraptionEntity {
@Override @Override
protected void writeAdditional(CompoundTag compound, boolean spawnPacket) { protected void writeAdditional(CompoundTag compound, boolean spawnPacket) {
super.writeAdditional(compound, spawnPacket); super.writeAdditional(compound, spawnPacket);
compound.put("Controller", NbtUtils.writeBlockPos(controllerPos)); compound.put("ControllerRelative", NbtUtils.writeBlockPos(controllerPos.subtract(blockPosition())));
if (rotationAxis != null) if (rotationAxis != null)
NBTHelper.writeEnum(compound, "Axis", rotationAxis); NBTHelper.writeEnum(compound, "Axis", rotationAxis);
compound.putFloat("Angle", angle); compound.putFloat("Angle", angle);
@ -168,7 +172,8 @@ public class ControlledContraptionEntity extends AbstractContraptionEntity {
return false; return false;
if (!VecHelper.onSameAxis(blockInfo.pos, BlockPos.ZERO, facing.getAxis())) if (!VecHelper.onSameAxis(blockInfo.pos, BlockPos.ZERO, facing.getAxis()))
return false; return false;
context.motion = Vec3.atLowerCornerOf(facing.getNormal()).scale(angleDelta / 360.0); context.motion = Vec3.atLowerCornerOf(facing.getNormal())
.scale(angleDelta / 360.0);
context.relativeMotion = context.motion; context.relativeMotion = context.motion;
int timer = context.data.getInt("StationaryTimer"); int timer = context.data.getInt("StationaryTimer");
if (timer > 0) { if (timer > 0) {

View file

@ -1,5 +1,7 @@
package com.simibubi.create.content.contraptions.components.structureMovement.glue; package com.simibubi.create.content.contraptions.components.structureMovement.glue;
import java.util.ArrayList;
import java.util.List;
import java.util.Set; import java.util.Set;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
@ -26,6 +28,7 @@ import net.minecraft.nbt.Tag;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.Packet;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Mth;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResult;
import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.damagesource.DamageSource;
@ -72,6 +75,20 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat
return false; return false;
} }
public static List<SuperGlueEntity> collectCropped(Level level, AABB bb) {
List<SuperGlueEntity> glue = new ArrayList<>();
for (SuperGlueEntity glueEntity : level.getEntitiesOfClass(SuperGlueEntity.class, bb)) {
AABB glueBox = glueEntity.getBoundingBox();
AABB intersect = bb.intersect(glueBox);
if (intersect.getXsize() * intersect.getYsize() * intersect.getZsize() == 0)
continue;
if (Mth.equal(intersect.getSize(), 1))
continue;
glue.add(new SuperGlueEntity(level, intersect));
}
return glue;
}
public SuperGlueEntity(EntityType<?> type, Level world) { public SuperGlueEntity(EntityType<?> type, Level world) {
super(type, world); super(type, world);
} }
@ -148,10 +165,11 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat
@Override @Override
public void setPos(double x, double y, double z) { public void setPos(double x, double y, double z) {
AABB bb = getBoundingBox();
setPosRaw(x, y, z); setPosRaw(x, y, z);
getBoundingBox().move(getBoundingBox().getCenter() Vec3 center = bb.getCenter();
.scale(-1) setBoundingBox(bb.move(-center.x, -bb.minY, -center.z)
.add(x, y, z)); .move(x, y, z));
} }
@Override @Override

View file

@ -35,6 +35,7 @@ import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import net.minecraft.world.phys.AABB;
public class ServerSchematicLoader { public class ServerSchematicLoader {
@ -89,8 +90,10 @@ public class ServerSchematicLoader {
} }
public void handleNewUpload(ServerPlayer player, String schematic, long size, BlockPos pos) { public void handleNewUpload(ServerPlayer player, String schematic, long size, BlockPos pos) {
String playerPath = getSchematicPath() + "/" + player.getGameProfile().getName(); String playerPath = getSchematicPath() + "/" + player.getGameProfile()
String playerSchematicId = player.getGameProfile().getName() + "/" + schematic; .getName();
String playerSchematicId = player.getGameProfile()
.getName() + "/" + schematic;
FilesHelper.createFolderIfMissing(playerPath); FilesHelper.createFolderIfMissing(playerPath);
// Unsupported Format // Unsupported Format
@ -99,9 +102,12 @@ public class ServerSchematicLoader {
return; return;
} }
Path playerSchematicsPath = Paths.get(getSchematicPath(), player.getGameProfile().getName()).toAbsolutePath(); Path playerSchematicsPath = Paths.get(getSchematicPath(), player.getGameProfile()
.getName())
.toAbsolutePath();
Path uploadPath = playerSchematicsPath.resolve(schematic).normalize(); Path uploadPath = playerSchematicsPath.resolve(schematic)
.normalize();
if (!uploadPath.startsWith(playerSchematicsPath)) { if (!uploadPath.startsWith(playerSchematicsPath)) {
Create.LOGGER.warn("Attempted Schematic Upload with directory escape: {}", playerSchematicId); Create.LOGGER.warn("Attempted Schematic Upload with directory escape: {}", playerSchematicId);
return; return;
@ -171,7 +177,8 @@ public class ServerSchematicLoader {
} }
public void handleWriteRequest(ServerPlayer player, String schematic, byte[] data) { public void handleWriteRequest(ServerPlayer player, String schematic, byte[] data) {
String playerSchematicId = player.getGameProfile().getName() + "/" + schematic; String playerSchematicId = player.getGameProfile()
.getName() + "/" + schematic;
if (activeUploads.containsKey(playerSchematicId)) { if (activeUploads.containsKey(playerSchematicId)) {
SchematicUploadEntry entry = activeUploads.get(playerSchematicId); SchematicUploadEntry entry = activeUploads.get(playerSchematicId);
@ -241,7 +248,8 @@ public class ServerSchematicLoader {
} }
public void handleFinishedUpload(ServerPlayer player, String schematic) { public void handleFinishedUpload(ServerPlayer player, String schematic) {
String playerSchematicId = player.getGameProfile().getName() + "/" + schematic; String playerSchematicId = player.getGameProfile()
.getName() + "/" + schematic;
if (activeUploads.containsKey(playerSchematicId)) { if (activeUploads.containsKey(playerSchematicId)) {
try { try {
@ -262,7 +270,8 @@ public class ServerSchematicLoader {
if (table == null) if (table == null)
return; return;
table.finishUpload(); table.finishUpload();
table.inventory.setStackInSlot(1, SchematicItem.create(schematic, player.getGameProfile().getName())); table.inventory.setStackInSlot(1, SchematicItem.create(schematic, player.getGameProfile()
.getName()));
} catch (IOException e) { } catch (IOException e) {
Create.LOGGER.error("Exception Thrown when finishing Upload: " + playerSchematicId); Create.LOGGER.error("Exception Thrown when finishing Upload: " + playerSchematicId);
@ -273,8 +282,10 @@ public class ServerSchematicLoader {
public void handleInstantSchematic(ServerPlayer player, String schematic, Level world, BlockPos pos, public void handleInstantSchematic(ServerPlayer player, String schematic, Level world, BlockPos pos,
BlockPos bounds) { BlockPos bounds) {
String playerPath = getSchematicPath() + "/" + player.getGameProfile().getName(); String playerPath = getSchematicPath() + "/" + player.getGameProfile()
String playerSchematicId = player.getGameProfile().getName() + "/" + schematic; .getName();
String playerSchematicId = player.getGameProfile()
.getName() + "/" + schematic;
FilesHelper.createFolderIfMissing(playerPath); FilesHelper.createFolderIfMissing(playerPath);
// Unsupported Format // Unsupported Format
@ -283,9 +294,11 @@ public class ServerSchematicLoader {
return; return;
} }
Path schematicPath = Paths.get(getSchematicPath()).toAbsolutePath(); Path schematicPath = Paths.get(getSchematicPath())
.toAbsolutePath();
Path path = schematicPath.resolve(playerSchematicId).normalize(); Path path = schematicPath.resolve(playerSchematicId)
.normalize();
if (!path.startsWith(schematicPath)) { if (!path.startsWith(schematicPath)) {
Create.LOGGER.warn("Attempted Schematic Upload with directory escape: {}", playerSchematicId); Create.LOGGER.warn("Attempted Schematic Upload with directory escape: {}", playerSchematicId);
return; return;
@ -321,8 +334,10 @@ public class ServerSchematicLoader {
try (OutputStream outputStream = Files.newOutputStream(path)) { try (OutputStream outputStream = Files.newOutputStream(path)) {
CompoundTag nbttagcompound = t.save(new CompoundTag()); CompoundTag nbttagcompound = t.save(new CompoundTag());
SchematicAndQuillItem.replaceStructureVoidWithAir(nbttagcompound); SchematicAndQuillItem.replaceStructureVoidWithAir(nbttagcompound);
SchematicAndQuillItem.clampGlueBoxes(world, new AABB(pos, pos.offset(bounds)), nbttagcompound);
NbtIo.writeCompressed(nbttagcompound, outputStream); NbtIo.writeCompressed(nbttagcompound, outputStream);
player.setItemInHand(InteractionHand.MAIN_HAND, SchematicItem.create(schematic, player.getGameProfile().getName())); player.setItemInHand(InteractionHand.MAIN_HAND, SchematicItem.create(schematic, player.getGameProfile()
.getName()));
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();

View file

@ -39,6 +39,7 @@ import net.minecraft.util.Mth;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.levelgen.structure.BoundingBox; import net.minecraft.world.level.levelgen.structure.BoundingBox;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
@ -190,8 +191,7 @@ public class SchematicAndQuillHandler {
if (secondPos == null) { if (secondPos == null) {
if (firstPos == null) if (firstPos == null)
return selectedPos == null ? null : new AABB(selectedPos); return selectedPos == null ? null : new AABB(selectedPos);
return selectedPos == null ? new AABB(firstPos) return selectedPos == null ? new AABB(firstPos) : new AABB(firstPos, selectedPos).expandTowards(1, 1, 1);
: new AABB(firstPos, selectedPos).expandTowards(1, 1, 1);
} }
return new AABB(firstPos, secondPos).expandTowards(1, 1, 1); return new AABB(firstPos, secondPos).expandTowards(1, 1, 1);
} }
@ -210,8 +210,9 @@ public class SchematicAndQuillHandler {
BoundingBox bb = BoundingBox.fromCorners(firstPos, secondPos); BoundingBox bb = BoundingBox.fromCorners(firstPos, secondPos);
BlockPos origin = new BlockPos(bb.minX(), bb.minY(), bb.minZ()); BlockPos origin = new BlockPos(bb.minX(), bb.minY(), bb.minZ());
BlockPos bounds = new BlockPos(bb.getXSpan(), bb.getYSpan(), bb.getZSpan()); BlockPos bounds = new BlockPos(bb.getXSpan(), bb.getYSpan(), bb.getZSpan());
Level level = Minecraft.getInstance().level;
t.fillFromWorld(Minecraft.getInstance().level, origin, bounds, true, Blocks.AIR); t.fillFromWorld(level, origin, bounds, true, Blocks.AIR);
if (string.isEmpty()) if (string.isEmpty())
string = Lang.translate("schematicAndQuill.fallbackName") string = Lang.translate("schematicAndQuill.fallbackName")
@ -228,6 +229,7 @@ public class SchematicAndQuillHandler {
outputStream = Files.newOutputStream(path, StandardOpenOption.CREATE); outputStream = Files.newOutputStream(path, StandardOpenOption.CREATE);
CompoundTag nbttagcompound = t.save(new CompoundTag()); CompoundTag nbttagcompound = t.save(new CompoundTag());
SchematicAndQuillItem.replaceStructureVoidWithAir(nbttagcompound); SchematicAndQuillItem.replaceStructureVoidWithAir(nbttagcompound);
SchematicAndQuillItem.clampGlueBoxes(level, new AABB(origin, origin.offset(bounds)), nbttagcompound);
NbtIo.writeCompressed(nbttagcompound, outputStream); NbtIo.writeCompressed(nbttagcompound, outputStream);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();

View file

@ -1,10 +1,23 @@
package com.simibubi.create.content.schematics.item; package com.simibubi.create.content.schematics.item;
import java.util.Iterator;
import com.simibubi.create.AllEntityTypes;
import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity;
import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.NBTHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.DoubleTag;
import net.minecraft.nbt.IntTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.Tag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class SchematicAndQuillItem extends Item { public class SchematicAndQuillItem extends Item {
@ -26,4 +39,48 @@ public class SchematicAndQuillItem extends Item {
}); });
} }
public static void clampGlueBoxes(Level level, AABB aabb, CompoundTag nbt) {
ListTag listtag = nbt.getList("entities", 10)
.copy();
for (Iterator<Tag> iterator = listtag.iterator(); iterator.hasNext();) {
Tag tag = iterator.next();
if (!(tag instanceof CompoundTag compoundtag))
continue;
if (compoundtag.contains("nbt") && new ResourceLocation(compoundtag.getCompound("nbt")
.getString("id")).equals(AllEntityTypes.SUPER_GLUE.getId())) {
iterator.remove();
}
}
for (SuperGlueEntity entity : SuperGlueEntity.collectCropped(level, aabb)) {
Vec3 vec3 = new Vec3(entity.getX() - aabb.minX, entity.getY() - aabb.minY, entity.getZ() - aabb.minZ);
CompoundTag compoundtag = new CompoundTag();
entity.save(compoundtag);
BlockPos blockpos = new BlockPos(vec3);
CompoundTag entityTag = new CompoundTag();
entityTag.put("pos", newDoubleList(vec3.x, vec3.y, vec3.z));
entityTag.put("blockPos", newIntegerList(blockpos.getX(), blockpos.getY(), blockpos.getZ()));
entityTag.put("nbt", compoundtag.copy());
listtag.add(entityTag);
}
nbt.put("entities", listtag);
}
private static ListTag newIntegerList(int... pValues) {
ListTag listtag = new ListTag();
for (int i : pValues)
listtag.add(IntTag.valueOf(i));
return listtag;
}
private static ListTag newDoubleList(double... pValues) {
ListTag listtag = new ListTag();
for (double d0 : pValues)
listtag.add(DoubleTag.valueOf(d0));
return listtag;
}
} }

View file

@ -8,13 +8,11 @@ import com.mojang.brigadier.builder.ArgumentBuilder;
import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType; import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType;
import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity; import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity;
import com.simibubi.create.foundation.utility.Pair;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands; import net.minecraft.commands.Commands;
import net.minecraft.commands.arguments.coordinates.BlockPosArgument; import net.minecraft.commands.arguments.coordinates.BlockPosArgument;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.TextComponent; import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.network.chat.TranslatableComponent;
@ -27,6 +25,7 @@ import net.minecraft.world.level.block.state.pattern.BlockInWorld;
import net.minecraft.world.level.levelgen.structure.BoundingBox; import net.minecraft.world.level.levelgen.structure.BoundingBox;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class CloneCommand { public class CloneCommand {
@ -89,22 +88,15 @@ public class CloneCommand {
private static int cloneGlue(BoundingBox sourceArea, ServerLevel world, BlockPos diffToTarget) { private static int cloneGlue(BoundingBox sourceArea, ServerLevel world, BlockPos diffToTarget) {
int gluePastes = 0; int gluePastes = 0;
List<SuperGlueEntity> glue = world.getEntitiesOfClass(SuperGlueEntity.class, AABB.of(sourceArea)); AABB bb = new AABB(sourceArea.minX(), sourceArea.minY(), sourceArea.minZ(), sourceArea.maxX() + 1,
List<Pair<BlockPos, Direction>> newGlue = Lists.newArrayList(); sourceArea.maxY() + 1, sourceArea.maxZ() + 1);
for (SuperGlueEntity g : SuperGlueEntity.collectCropped(world, bb)) {
g.setPos(g.position()
.add(Vec3.atLowerCornerOf(diffToTarget)));
world.addFreshEntity(g);
gluePastes++;
}
// for (SuperGlueEntity g : glue) {TODO
// BlockPos pos = g.getHangingPosition();
// Direction direction = g.getFacingDirection();
// newGlue.add(Pair.of(pos.offset(diffToTarget), direction));
// }
//
// for (Pair<BlockPos, Direction> p : newGlue) {
// SuperGlueEntity g = new SuperGlueEntity(world, p.getFirst(), p.getSecond());
// if (g.onValidSurface()) {
// world.addFreshEntity(g);
// gluePastes++;
// }
// }
return gluePastes; return gluePastes;
} }