diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index e172e4484..75d5b5836 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -544,22 +544,22 @@ bf2b0310500213ff853c748c236eb5d01f61658e assets/create/blockstates/yellow_toolbo 7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json 875f9aff979888b9d63d6a425cbf544431f1af5a assets/create/lang/en_ud.json -c8e4df6292133a1873e4dccb34c00b1e52afcd92 assets/create/lang/en_us.json -3ca43c518fc5c0120b5cf2aaf37cc78f51625fd4 assets/create/lang/unfinished/de_de.json -128d3e35cf2d41dacdb54abd8562091f15323a8c assets/create/lang/unfinished/es_cl.json -f02d6b15275a22ac665303e6d7181998f408e1a7 assets/create/lang/unfinished/es_es.json -02e43d3f9d2527c2cd72f1a5bfe76397b6cfa32f assets/create/lang/unfinished/fr_fr.json -9f0982f15705f8c3f675f9dfac5b68a753ddf97a assets/create/lang/unfinished/it_it.json -84d0f74256115e505a239ed826b28002fbc67f86 assets/create/lang/unfinished/ja_jp.json -96dfb6f44098b2a44c4ba6c53ed6f42a4d7811f5 assets/create/lang/unfinished/ko_kr.json -5ea64ddc9613b72376220353819a477bf4c6d64d assets/create/lang/unfinished/nl_nl.json -dd81cd81f426833b627831530c77ab3f3655bb39 assets/create/lang/unfinished/pl_pl.json -7cdff911043ccc6232932f85825090305ce92426 assets/create/lang/unfinished/pt_br.json -ba139e8ea012ed05598ea5bb57ee6ac95693efdd assets/create/lang/unfinished/pt_pt.json -86ac8dc000591768856bbaa873f9d101faddc1cd assets/create/lang/unfinished/ro_ro.json -14988b8d3a0b97a7c6b49f392d5088fd59a3aaaa assets/create/lang/unfinished/ru_ru.json -99ffa28fe67913dda825628947e5763f0a21ee8a assets/create/lang/unfinished/zh_cn.json -01da3a96eb7aeea75afed38dd1a83321959fcf0a assets/create/lang/unfinished/zh_tw.json +0a0155981901a175ef3d80376bd12bf6ed87fc40 assets/create/lang/en_us.json +2441d72bd7c3f9bd175a3b7ad6dfd08650244333 assets/create/lang/unfinished/de_de.json +c78d38ed11410f3749b0531faddb47bc864c602e assets/create/lang/unfinished/es_cl.json +3f324c1793d15fc4efee2496ded04ef40a149eef assets/create/lang/unfinished/es_es.json +a75c200cad527244a00e9c8d8044b99ebcb4f434 assets/create/lang/unfinished/fr_fr.json +f8498450f21370fc25144fb02d7f3de644302eae assets/create/lang/unfinished/it_it.json +fb99ffda9c4f753478d69d4a7e672d2934e4eefe assets/create/lang/unfinished/ja_jp.json +c5b3a59940d9d1f31bd333acb05e77a07833f8f7 assets/create/lang/unfinished/ko_kr.json +1a8e15b473cc565d4a0ce6a077ebb21b04436caa assets/create/lang/unfinished/nl_nl.json +a4c4763232172a82d131bdcf9418e8944faa4767 assets/create/lang/unfinished/pl_pl.json +4293a80519e12fe25df446daf66a2c93abde0c29 assets/create/lang/unfinished/pt_br.json +40b6e4ba6fbdc90902288bbf0be9fd65a08d0bce assets/create/lang/unfinished/pt_pt.json +e4a748bfbb60cb7b597921115ce69b45bbfb3d79 assets/create/lang/unfinished/ro_ro.json +5539e89820b997b42e5605202e5c8ba508e80b77 assets/create/lang/unfinished/ru_ru.json +b3f274b8dc40d041733ba10cab527c5130f68bcf assets/create/lang/unfinished/zh_cn.json +5309ae6bd90efd2cf5e8adb730c2d2f4818edf7d 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 @@ -2155,7 +2155,7 @@ d080b1b25e5bc8baf5aee68691b08c7f12ece3b0 assets/create/models/item/windmill_bear 866fbb0ce2878a73e0440d1caf6534c8bd7c384f assets/create/models/item/zinc_ingot.json a80fb25a0b655e76be986b5b49fcb0f03461a1ab assets/create/models/item/zinc_nugget.json b1689617190c05ef34bd18456b0c7ae09bb3210f assets/create/models/item/zinc_ore.json -92c34840e05861f7f98aa2f942f9a90370f82cd6 assets/create/sounds.json +56f5b100aa98b37efb44b85856ff4bfeaa7a89ec assets/create/sounds.json 0f1b4b980afba9bf2caf583b88e261bba8b10313 data/create/advancements/aesthetics.json 613e64b44bed959da899fdd54c1cacb227fb33f2 data/create/advancements/andesite_alloy.json 81885c6bfb85792c88aaa7c9b70f58832945d31f data/create/advancements/andesite_casing.json diff --git a/src/generated/resources/assets/create/lang/en_us.json b/src/generated/resources/assets/create/lang/en_us.json index a8348c037..b4ba24a0e 100644 --- a/src/generated/resources/assets/create/lang/en_us.json +++ b/src/generated/resources/assets/create/lang/en_us.json @@ -1591,7 +1591,10 @@ "create.subtitle.potato_hit": "Vegetable impacts", "create.subtitle.saw_activate_wood": "Mechanical Saw activates", "create.subtitle.whistle_high": "High whistling", + "create.subtitle.whistle_train": "Whistling", "create.subtitle.haunted_bell_convert": "Haunted Bell awakens", + "create.subtitle.whistle_train_high": "High whistling", + "create.subtitle.whistle_train_low": "Low whistling", "create.subtitle.deny": "Declining boop", "create.subtitle.controller_click": "Controller clicks", "create.subtitle.whistle_low": "Low whistling", diff --git a/src/generated/resources/assets/create/lang/unfinished/de_de.json b/src/generated/resources/assets/create/lang/unfinished/de_de.json index ba1bd10d7..9fe22059d 100644 --- a/src/generated/resources/assets/create/lang/unfinished/de_de.json +++ b/src/generated/resources/assets/create/lang/unfinished/de_de.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1534", + "_": "Missing Localizations: 1537", "_": "->------------------------] Game Elements [------------------------<-", @@ -1592,7 +1592,10 @@ "create.subtitle.potato_hit": "UNLOCALIZED: Vegetable impacts", "create.subtitle.saw_activate_wood": "UNLOCALIZED: Mechanical Saw activates", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train": "UNLOCALIZED: Whistling", "create.subtitle.haunted_bell_convert": "UNLOCALIZED: Haunted Bell awakens", + "create.subtitle.whistle_train_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train_low": "UNLOCALIZED: Low whistling", "create.subtitle.deny": "UNLOCALIZED: Declining boop", "create.subtitle.controller_click": "UNLOCALIZED: Controller clicks", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling", diff --git a/src/generated/resources/assets/create/lang/unfinished/es_cl.json b/src/generated/resources/assets/create/lang/unfinished/es_cl.json index cf040cab2..88da16e32 100644 --- a/src/generated/resources/assets/create/lang/unfinished/es_cl.json +++ b/src/generated/resources/assets/create/lang/unfinished/es_cl.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 556", + "_": "Missing Localizations: 559", "_": "->------------------------] Game Elements [------------------------<-", @@ -1592,7 +1592,10 @@ "create.subtitle.potato_hit": "Impactos vegetales", "create.subtitle.saw_activate_wood": "Sierra Mecánica se activa", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train": "UNLOCALIZED: Whistling", "create.subtitle.haunted_bell_convert": "Campana Embrujada despierta", + "create.subtitle.whistle_train_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train_low": "UNLOCALIZED: Low whistling", "create.subtitle.deny": "Boop denegante", "create.subtitle.controller_click": "Controlador cliquea", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling", diff --git a/src/generated/resources/assets/create/lang/unfinished/es_es.json b/src/generated/resources/assets/create/lang/unfinished/es_es.json index afa0eb6c1..cbf678d2a 100644 --- a/src/generated/resources/assets/create/lang/unfinished/es_es.json +++ b/src/generated/resources/assets/create/lang/unfinished/es_es.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 227", + "_": "Missing Localizations: 230", "_": "->------------------------] Game Elements [------------------------<-", @@ -1592,7 +1592,10 @@ "create.subtitle.potato_hit": "Impacto de vegetal", "create.subtitle.saw_activate_wood": "Sierra mecánica activada", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train": "UNLOCALIZED: Whistling", "create.subtitle.haunted_bell_convert": "Campana maldita se despierta", + "create.subtitle.whistle_train_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train_low": "UNLOCALIZED: Low whistling", "create.subtitle.deny": "Pitido denegante", "create.subtitle.controller_click": "", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling", diff --git a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json index 5f5e14a95..13f2cc4e3 100644 --- a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json +++ b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1796", + "_": "Missing Localizations: 1799", "_": "->------------------------] Game Elements [------------------------<-", @@ -1592,7 +1592,10 @@ "create.subtitle.potato_hit": "UNLOCALIZED: Vegetable impacts", "create.subtitle.saw_activate_wood": "UNLOCALIZED: Mechanical Saw activates", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train": "UNLOCALIZED: Whistling", "create.subtitle.haunted_bell_convert": "UNLOCALIZED: Haunted Bell awakens", + "create.subtitle.whistle_train_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train_low": "UNLOCALIZED: Low whistling", "create.subtitle.deny": "UNLOCALIZED: Declining boop", "create.subtitle.controller_click": "UNLOCALIZED: Controller clicks", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling", diff --git a/src/generated/resources/assets/create/lang/unfinished/it_it.json b/src/generated/resources/assets/create/lang/unfinished/it_it.json index f968424c3..df6a738c6 100644 --- a/src/generated/resources/assets/create/lang/unfinished/it_it.json +++ b/src/generated/resources/assets/create/lang/unfinished/it_it.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1485", + "_": "Missing Localizations: 1488", "_": "->------------------------] Game Elements [------------------------<-", @@ -1592,7 +1592,10 @@ "create.subtitle.potato_hit": "UNLOCALIZED: Vegetable impacts", "create.subtitle.saw_activate_wood": "UNLOCALIZED: Mechanical Saw activates", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train": "UNLOCALIZED: Whistling", "create.subtitle.haunted_bell_convert": "UNLOCALIZED: Haunted Bell awakens", + "create.subtitle.whistle_train_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train_low": "UNLOCALIZED: Low whistling", "create.subtitle.deny": "UNLOCALIZED: Declining boop", "create.subtitle.controller_click": "UNLOCALIZED: Controller clicks", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling", diff --git a/src/generated/resources/assets/create/lang/unfinished/ja_jp.json b/src/generated/resources/assets/create/lang/unfinished/ja_jp.json index 97675bda5..dda9a8ef5 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ja_jp.json +++ b/src/generated/resources/assets/create/lang/unfinished/ja_jp.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 222", + "_": "Missing Localizations: 225", "_": "->------------------------] Game Elements [------------------------<-", @@ -1592,7 +1592,10 @@ "create.subtitle.potato_hit": "野菜の衝撃", "create.subtitle.saw_activate_wood": "メカニカルソーが動作する", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train": "UNLOCALIZED: Whistling", "create.subtitle.haunted_bell_convert": "憑りつかれた鐘が目覚める", + "create.subtitle.whistle_train_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train_low": "UNLOCALIZED: Low whistling", "create.subtitle.deny": "失敗音", "create.subtitle.controller_click": "コントローラーのカチカチ音", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling", diff --git a/src/generated/resources/assets/create/lang/unfinished/ko_kr.json b/src/generated/resources/assets/create/lang/unfinished/ko_kr.json index 032930d2f..edb7137fc 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ko_kr.json +++ b/src/generated/resources/assets/create/lang/unfinished/ko_kr.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 222", + "_": "Missing Localizations: 225", "_": "->------------------------] Game Elements [------------------------<-", @@ -1592,7 +1592,10 @@ "create.subtitle.potato_hit": "채소가 부딫힘", "create.subtitle.saw_activate_wood": "톱이 작동함", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train": "UNLOCALIZED: Whistling", "create.subtitle.haunted_bell_convert": "종에 귀신이 들림", + "create.subtitle.whistle_train_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train_low": "UNLOCALIZED: Low whistling", "create.subtitle.deny": "취소음", "create.subtitle.controller_click": "조작기를 누름", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling", diff --git a/src/generated/resources/assets/create/lang/unfinished/nl_nl.json b/src/generated/resources/assets/create/lang/unfinished/nl_nl.json index 2a5ee0564..a714167ff 100644 --- a/src/generated/resources/assets/create/lang/unfinished/nl_nl.json +++ b/src/generated/resources/assets/create/lang/unfinished/nl_nl.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 2148", + "_": "Missing Localizations: 2151", "_": "->------------------------] Game Elements [------------------------<-", @@ -1592,7 +1592,10 @@ "create.subtitle.potato_hit": "UNLOCALIZED: Vegetable impacts", "create.subtitle.saw_activate_wood": "UNLOCALIZED: Mechanical Saw activates", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train": "UNLOCALIZED: Whistling", "create.subtitle.haunted_bell_convert": "UNLOCALIZED: Haunted Bell awakens", + "create.subtitle.whistle_train_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train_low": "UNLOCALIZED: Low whistling", "create.subtitle.deny": "UNLOCALIZED: Declining boop", "create.subtitle.controller_click": "UNLOCALIZED: Controller clicks", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling", diff --git a/src/generated/resources/assets/create/lang/unfinished/pl_pl.json b/src/generated/resources/assets/create/lang/unfinished/pl_pl.json index cfb2fc191..daaed4897 100644 --- a/src/generated/resources/assets/create/lang/unfinished/pl_pl.json +++ b/src/generated/resources/assets/create/lang/unfinished/pl_pl.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 595", + "_": "Missing Localizations: 598", "_": "->------------------------] Game Elements [------------------------<-", @@ -1592,7 +1592,10 @@ "create.subtitle.potato_hit": "Warzywo ląduje", "create.subtitle.saw_activate_wood": "Mechaniczna piła aktywuje się", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train": "UNLOCALIZED: Whistling", "create.subtitle.haunted_bell_convert": "Nawiedzony dzwon budzi się", + "create.subtitle.whistle_train_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train_low": "UNLOCALIZED: Low whistling", "create.subtitle.deny": "Dźwięk odmowy", "create.subtitle.controller_click": "Sterownik klika", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling", diff --git a/src/generated/resources/assets/create/lang/unfinished/pt_br.json b/src/generated/resources/assets/create/lang/unfinished/pt_br.json index 63512bdad..7f26447d9 100644 --- a/src/generated/resources/assets/create/lang/unfinished/pt_br.json +++ b/src/generated/resources/assets/create/lang/unfinished/pt_br.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1396", + "_": "Missing Localizations: 1399", "_": "->------------------------] Game Elements [------------------------<-", @@ -1592,7 +1592,10 @@ "create.subtitle.potato_hit": "UNLOCALIZED: Vegetable impacts", "create.subtitle.saw_activate_wood": "UNLOCALIZED: Mechanical Saw activates", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train": "UNLOCALIZED: Whistling", "create.subtitle.haunted_bell_convert": "UNLOCALIZED: Haunted Bell awakens", + "create.subtitle.whistle_train_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train_low": "UNLOCALIZED: Low whistling", "create.subtitle.deny": "UNLOCALIZED: Declining boop", "create.subtitle.controller_click": "UNLOCALIZED: Controller clicks", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling", diff --git a/src/generated/resources/assets/create/lang/unfinished/pt_pt.json b/src/generated/resources/assets/create/lang/unfinished/pt_pt.json index b67ce3882..24ee64f31 100644 --- a/src/generated/resources/assets/create/lang/unfinished/pt_pt.json +++ b/src/generated/resources/assets/create/lang/unfinished/pt_pt.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1768", + "_": "Missing Localizations: 1771", "_": "->------------------------] Game Elements [------------------------<-", @@ -1592,7 +1592,10 @@ "create.subtitle.potato_hit": "UNLOCALIZED: Vegetable impacts", "create.subtitle.saw_activate_wood": "UNLOCALIZED: Mechanical Saw activates", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train": "UNLOCALIZED: Whistling", "create.subtitle.haunted_bell_convert": "UNLOCALIZED: Haunted Bell awakens", + "create.subtitle.whistle_train_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train_low": "UNLOCALIZED: Low whistling", "create.subtitle.deny": "UNLOCALIZED: Declining boop", "create.subtitle.controller_click": "UNLOCALIZED: Controller clicks", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling", diff --git a/src/generated/resources/assets/create/lang/unfinished/ro_ro.json b/src/generated/resources/assets/create/lang/unfinished/ro_ro.json index 7a0c43bfe..838c56bda 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ro_ro.json +++ b/src/generated/resources/assets/create/lang/unfinished/ro_ro.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 223", + "_": "Missing Localizations: 226", "_": "->------------------------] Game Elements [------------------------<-", @@ -1592,7 +1592,10 @@ "create.subtitle.potato_hit": "Impact de legumă", "create.subtitle.saw_activate_wood": "Ferăstrău Mecanic se activează", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train": "UNLOCALIZED: Whistling", "create.subtitle.haunted_bell_convert": "Clopot Bântuit se trezețte", + "create.subtitle.whistle_train_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train_low": "UNLOCALIZED: Low whistling", "create.subtitle.deny": "Boop de refuz", "create.subtitle.controller_click": "Controlor clickuiește", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling", diff --git a/src/generated/resources/assets/create/lang/unfinished/ru_ru.json b/src/generated/resources/assets/create/lang/unfinished/ru_ru.json index aa5f5b619..ff8631f41 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ru_ru.json +++ b/src/generated/resources/assets/create/lang/unfinished/ru_ru.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 600", + "_": "Missing Localizations: 603", "_": "->------------------------] Game Elements [------------------------<-", @@ -1592,7 +1592,10 @@ "create.subtitle.potato_hit": "Овощ врезается", "create.subtitle.saw_activate_wood": "Активируется механическая пила", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train": "UNLOCALIZED: Whistling", "create.subtitle.haunted_bell_convert": "Призрачный колокол пробуждается", + "create.subtitle.whistle_train_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train_low": "UNLOCALIZED: Low whistling", "create.subtitle.deny": "Отрицательный «Буп»", "create.subtitle.controller_click": "Клики контроллера", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling", diff --git a/src/generated/resources/assets/create/lang/unfinished/zh_cn.json b/src/generated/resources/assets/create/lang/unfinished/zh_cn.json index 4b8a10998..f2973e25f 100644 --- a/src/generated/resources/assets/create/lang/unfinished/zh_cn.json +++ b/src/generated/resources/assets/create/lang/unfinished/zh_cn.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 222", + "_": "Missing Localizations: 225", "_": "->------------------------] Game Elements [------------------------<-", @@ -1592,7 +1592,10 @@ "create.subtitle.potato_hit": "土豆:击中", "create.subtitle.saw_activate_wood": "动力锯:切割", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train": "UNLOCALIZED: Whistling", "create.subtitle.haunted_bell_convert": "奇异钟:转化", + "create.subtitle.whistle_train_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train_low": "UNLOCALIZED: Low whistling", "create.subtitle.deny": "提示声:出错", "create.subtitle.controller_click": "遥控器:按下按钮", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling", diff --git a/src/generated/resources/assets/create/lang/unfinished/zh_tw.json b/src/generated/resources/assets/create/lang/unfinished/zh_tw.json index 66c18c141..9079e4385 100644 --- a/src/generated/resources/assets/create/lang/unfinished/zh_tw.json +++ b/src/generated/resources/assets/create/lang/unfinished/zh_tw.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 614", + "_": "Missing Localizations: 617", "_": "->------------------------] Game Elements [------------------------<-", @@ -1592,7 +1592,10 @@ "create.subtitle.potato_hit": "食物撞擊聲", "create.subtitle.saw_activate_wood": "機械鋸子運作聲", "create.subtitle.whistle_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train": "UNLOCALIZED: Whistling", "create.subtitle.haunted_bell_convert": "靈魂鐘轉化聲", + "create.subtitle.whistle_train_high": "UNLOCALIZED: High whistling", + "create.subtitle.whistle_train_low": "UNLOCALIZED: Low whistling", "create.subtitle.deny": "UNLOCALIZED: Declining boop", "create.subtitle.controller_click": "遙控器按鍵聲", "create.subtitle.whistle_low": "UNLOCALIZED: Low whistling", diff --git a/src/generated/resources/assets/create/sounds.json b/src/generated/resources/assets/create/sounds.json index fd39c82df..e5da11631 100644 --- a/src/generated/resources/assets/create/sounds.json +++ b/src/generated/resources/assets/create/sounds.json @@ -419,6 +419,33 @@ ], "subtitle": "create.subtitle.whistle_low" }, + "whistle_train": { + "sounds": [ + { + "name": "create:whistle_train", + "type": "file" + } + ], + "subtitle": "create.subtitle.whistle_train" + }, + "whistle_train_high": { + "sounds": [ + { + "name": "create:whistle_train_high", + "type": "file" + } + ], + "subtitle": "create.subtitle.whistle_train_high" + }, + "whistle_train_low": { + "sounds": [ + { + "name": "create:whistle_train_low", + "type": "file" + } + ], + "subtitle": "create.subtitle.whistle_train_low" + }, "worldshaper_place": { "sounds": [ { diff --git a/src/main/java/com/simibubi/create/AllSoundEvents.java b/src/main/java/com/simibubi/create/AllSoundEvents.java index 903313641..a5275e6e3 100644 --- a/src/main/java/com/simibubi/create/AllSoundEvents.java +++ b/src/main/java/com/simibubi/create/AllSoundEvents.java @@ -228,7 +228,7 @@ public class AllSoundEvents { .attenuationDistance(64) .build(), - WHISTLE = create("whistle").subtitle("Whistling") + WHISTLE_MEDIUM = create("whistle").subtitle("Whistling") .category(SoundSource.RECORDS) .attenuationDistance(64) .build(), @@ -238,6 +238,18 @@ public class AllSoundEvents { .attenuationDistance(64) .build(), + WHISTLE_TRAIN_HIGH = create("whistle_train_high").subtitle("High whistling") + .category(SoundSource.RECORDS) + .build(), + + WHISTLE_TRAIN_MEDIUM = create("whistle_train").subtitle("Whistling") + .category(SoundSource.RECORDS) + .build(), + + WHISTLE_TRAIN_LOW = create("whistle_train_low").subtitle("Low whistling") + .category(SoundSource.RECORDS) + .build(), + WHISTLE_CHIFF = create("chiff").noSubtitle() .category(SoundSource.RECORDS) .build(), diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/BellMovementBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/BellMovementBehaviour.java index 056929ba4..e521fdfad 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/BellMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/BellMovementBehaviour.java @@ -3,6 +3,7 @@ package com.simibubi.create.content.contraptions.components.actors; import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; import com.simibubi.create.content.curiosities.bell.AbstractBellBlock; +import com.simibubi.create.content.logistics.trains.entity.CarriageContraption; import net.minecraft.core.BlockPos; import net.minecraft.sounds.SoundEvents; @@ -17,6 +18,11 @@ public class BellMovementBehaviour implements MovementBehaviour { public boolean renderAsNormalTileEntity() { return true; } + + @Override + public boolean isActive(MovementContext context) { + return !(context.contraption instanceof CarriageContraption); + } @Override public void onSpeedChanged(MovementContext context, Vec3 oldMotion, Vec3 motion) { @@ -28,7 +34,7 @@ public class BellMovementBehaviour implements MovementBehaviour { @Override public void stopMoving(MovementContext context) { - if (context.position != null) + if (context.position != null && isActive(context)) playSound(context); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerMovementBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerMovementBehaviour.java index 45d47c096..720bc8ae0 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerMovementBehaviour.java @@ -83,8 +83,13 @@ public class DeployerMovementBehaviour implements MovementBehaviour { .getNormal()); facingVec = context.rotation.apply(facingVec); Vec3 vec = context.position.subtract(facingVec.scale(2)); + + float xRot = AbstractContraptionEntity.pitchFromVector(facingVec) - 90; + if (Math.abs(xRot) > 89) + facingVec = context.rotation.apply(new Vec3(0, 0, 1)); + player.setYRot(AbstractContraptionEntity.yawFromVector(facingVec)); - player.setXRot(AbstractContraptionEntity.pitchFromVector(facingVec) - 90); + player.setXRot(xRot); DeployerHandler.activate(player, vec, pos, facingVec, mode); } @@ -105,7 +110,7 @@ public class DeployerMovementBehaviour implements MovementBehaviour { if (schematicWorld == null) return; if (!schematicWorld.getBounds() - .isInside(pos.subtract(schematicWorld.anchor))) + .isInside(pos.subtract(schematicWorld.anchor))) return; BlockState blockState = schematicWorld.getBlockState(pos); ItemRequirement requirement = ItemRequirement.of(blockState, schematicWorld.getBlockEntity(pos)); @@ -121,15 +126,15 @@ public class DeployerMovementBehaviour implements MovementBehaviour { IItemHandler iItemHandler = context.contraption.inventory; for (ItemRequirement.StackRequirement required : requiredItems) { int amountFound = ItemHelper - .extract(iItemHandler, s -> ItemRequirement.validate(required.item, s), ExtractionCountMode.UPTO, - required.item.getCount(), true) - .getCount(); + .extract(iItemHandler, s -> ItemRequirement.validate(required.item, s), ExtractionCountMode.UPTO, + required.item.getCount(), true) + .getCount(); if (amountFound < required.item.getCount()) return; } for (ItemRequirement.StackRequirement required : requiredItems) - ItemHelper.extract(iItemHandler, s -> ItemRequirement.validate(required.item, s), ExtractionCountMode.UPTO, - required.item.getCount(), false); + ItemHelper.extract(iItemHandler, s -> ItemRequirement.validate(required.item, s), + ExtractionCountMode.UPTO, required.item.getCount(), false); } CompoundTag data = null; @@ -183,7 +188,8 @@ public class DeployerMovementBehaviour implements MovementBehaviour { if (player == null) return; - context.tileData.put("Inventory", player.getInventory().save(new ListTag())); + context.tileData.put("Inventory", player.getInventory() + .save(new ListTag())); player.discard(); } @@ -215,8 +221,7 @@ public class DeployerMovementBehaviour implements MovementBehaviour { if (itemstack.isEmpty()) continue; - if (list == inv.items && i == inv.selected - && FilterItem.test(context.world, itemstack, filter)) + if (list == inv.items && i == inv.selected && FilterItem.test(context.world, itemstack, filter)) continue; dropItem(context, itemstack); @@ -237,9 +242,11 @@ public class DeployerMovementBehaviour implements MovementBehaviour { private DeployerFakePlayer getPlayer(MovementContext context) { if (!(context.temporaryData instanceof DeployerFakePlayer) && context.world instanceof ServerLevel) { DeployerFakePlayer deployerFakePlayer = new DeployerFakePlayer((ServerLevel) context.world); - deployerFakePlayer.getInventory().load(context.tileData.getList("Inventory", Tag.TAG_COMPOUND)); + deployerFakePlayer.getInventory() + .load(context.tileData.getList("Inventory", Tag.TAG_COMPOUND)); if (context.data.contains("HeldItem")) - deployerFakePlayer.setItemInHand(InteractionHand.MAIN_HAND, ItemStack.of(context.data.getCompound("HeldItem"))); + deployerFakePlayer.setItemInHand(InteractionHand.MAIN_HAND, + ItemStack.of(context.data.getCompound("HeldItem"))); context.tileData.remove("Inventory"); context.temporaryData = deployerFakePlayer; } @@ -257,7 +264,7 @@ public class DeployerMovementBehaviour implements MovementBehaviour { @Override public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld, ContraptionMatrices matrices, MultiBufferSource buffers) { - if (!Backend.isOn()) + if (!Backend.isOn()) DeployerRenderer.renderInContraption(context, renderWorld, matrices, buffers); } @@ -268,7 +275,8 @@ public class DeployerMovementBehaviour implements MovementBehaviour { @Nullable @Override - public ActorInstance createInstance(MaterialManager materialManager, VirtualRenderWorld simulationWorld, MovementContext context) { + public ActorInstance createInstance(MaterialManager materialManager, VirtualRenderWorld simulationWorld, + MovementContext context) { return new DeployerActorInstance(materialManager, simulationWorld, context); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/steam/whistle/WhistleSoundInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/steam/whistle/WhistleSoundInstance.java index 8908a378a..0a91e3340 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/steam/whistle/WhistleSoundInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/steam/whistle/WhistleSoundInstance.java @@ -1,6 +1,6 @@ package com.simibubi.create.content.contraptions.components.steam.whistle; -import static com.simibubi.create.AllSoundEvents.WHISTLE; +import static com.simibubi.create.AllSoundEvents.WHISTLE_MEDIUM; import static com.simibubi.create.AllSoundEvents.WHISTLE_HIGH; import static com.simibubi.create.AllSoundEvents.WHISTLE_LOW; @@ -18,7 +18,7 @@ public class WhistleSoundInstance extends AbstractTickableSoundInstance { private WhistleSize size; public WhistleSoundInstance(WhistleSize size, BlockPos worldPosition) { - super((size == WhistleSize.SMALL ? WHISTLE_HIGH : size == WhistleSize.MEDIUM ? WHISTLE : WHISTLE_LOW) + super((size == WhistleSize.SMALL ? WHISTLE_HIGH : size == WhistleSize.MEDIUM ? WHISTLE_MEDIUM : WHISTLE_LOW) .getMainEvent(), SoundSource.RECORDS); this.size = size; looping = true; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/BlockMovementChecks.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/BlockMovementChecks.java index b65997686..970dba444 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/BlockMovementChecks.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/BlockMovementChecks.java @@ -11,6 +11,8 @@ import com.simibubi.create.content.contraptions.components.actors.PloughBlock; import com.simibubi.create.content.contraptions.components.actors.PortableStorageInterfaceBlock; import com.simibubi.create.content.contraptions.components.crank.HandCrankBlock; import com.simibubi.create.content.contraptions.components.fan.NozzleBlock; +import com.simibubi.create.content.contraptions.components.steam.whistle.WhistleBlock; +import com.simibubi.create.content.contraptions.components.steam.whistle.WhistleExtenderBlock; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.ClockworkBearingBlock; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.ClockworkBearingTileEntity; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.MechanicalBearingBlock; @@ -146,8 +148,7 @@ public class BlockMovementChecks { /** * Attached blocks will move if blocks they are attached to are moved */ - public static boolean isBlockAttachedTowards(BlockState state, Level world, BlockPos pos, - Direction direction) { + public static boolean isBlockAttachedTowards(BlockState state, Level world, BlockPos pos, Direction direction) { for (AttachedCheck check : ATTACHED_CHECKS) { CheckResult result = check.isBlockAttachedTowards(state, world, pos, direction); if (result != CheckResult.PASS) { @@ -179,10 +180,10 @@ public class BlockMovementChecks { if (state.getBlock() instanceof FenceGateBlock) return true; if (state.getMaterial() - .isReplaceable()) + .isReplaceable()) return false; if (state.getCollisionShape(world, pos) - .isEmpty()) + .isEmpty()) return false; return true; } @@ -258,11 +259,15 @@ public class BlockMovementChecks { return true; if (block instanceof WoolCarpetBlock) return true; + if (block instanceof WhistleBlock) + return true; + if (block instanceof WhistleExtenderBlock) + return true; return AllBlockTags.BRITTLE.matches(state); } private static boolean isBlockAttachedTowardsFallback(BlockState state, Level world, BlockPos pos, - Direction direction) { + Direction direction) { Block block = state.getBlock(); if (block instanceof LadderBlock) return state.getValue(LadderBlock.FACING) == direction.getOpposite(); @@ -331,18 +336,23 @@ public class BlockMovementChecks { } if (state.getBlock() instanceof SailBlock) return direction.getAxis() != state.getValue(SailBlock.FACING) - .getAxis(); + .getAxis(); if (state.getBlock() instanceof FluidTankBlock) return FluidTankConnectivityHandler.isConnected(world, pos, pos.relative(direction)); if (state.getBlock() instanceof ItemVaultBlock) return ItemVaultConnectivityHandler.isConnected(world, pos, pos.relative(direction)); if (AllBlocks.STICKER.has(state) && state.getValue(StickerBlock.EXTENDED)) { return direction == state.getValue(StickerBlock.FACING) - && !isNotSupportive(world.getBlockState(pos.relative(direction)), direction.getOpposite()); + && !isNotSupportive(world.getBlockState(pos.relative(direction)), direction.getOpposite()); } if (block instanceof IBogeyBlock bogey) return bogey.getStickySurfaces(world, pos, state) .contains(direction); + if (block instanceof WhistleBlock) + return direction == (state.getValue(WhistleBlock.WALL) ? state.getValue(WhistleBlock.FACING) + : Direction.DOWN); + if (block instanceof WhistleExtenderBlock) + return direction == Direction.DOWN; return false; } @@ -355,7 +365,7 @@ public class BlockMovementChecks { return state.getValue(HarvesterBlock.FACING) == facing; if (AllBlocks.MECHANICAL_PLOUGH.has(state)) return state.getValue(PloughBlock.FACING) == facing; - + if (AllBlocks.CART_ASSEMBLER.has(state)) return Direction.DOWN == facing; if (AllBlocks.MECHANICAL_SAW.has(state)) @@ -373,10 +383,10 @@ public class BlockMovementChecks { .getAxis(); if (AllBlocks.PISTON_EXTENSION_POLE.has(state)) return facing.getAxis() != state.getValue(BlockStateProperties.FACING) - .getAxis(); + .getAxis(); if (AllBlocks.MECHANICAL_PISTON_HEAD.has(state)) return facing.getAxis() != state.getValue(BlockStateProperties.FACING) - .getAxis(); + .getAxis(); if (AllBlocks.STICKER.has(state) && !state.getValue(StickerBlock.EXTENDED)) return facing == state.getValue(StickerBlock.FACING); return isBrittle(state); @@ -415,13 +425,12 @@ public class BlockMovementChecks { public CheckResult isNotSupportive(BlockState state, Direction direction); } - public static interface AllChecks extends MovementNecessaryCheck, MovementAllowedCheck, BrittleCheck, AttachedCheck, NotSupportiveCheck { + public static interface AllChecks + extends MovementNecessaryCheck, MovementAllowedCheck, BrittleCheck, AttachedCheck, NotSupportiveCheck { } public static enum CheckResult { - SUCCESS, - FAIL, - PASS; + SUCCESS, FAIL, PASS; public Boolean toBoolean() { return this == PASS ? null : (this == SUCCESS ? true : false); diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/ArrivalSoundQueue.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/ArrivalSoundQueue.java new file mode 100644 index 000000000..ceb24a635 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/ArrivalSoundQueue.java @@ -0,0 +1,133 @@ +package com.simibubi.create.content.logistics.trains.entity; + +import java.util.ArrayList; +import java.util.HashMap; + +import javax.annotation.Nullable; + +import com.google.common.collect.Multimap; +import com.google.common.collect.Multimaps; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllSoundEvents; +import com.simibubi.create.content.contraptions.components.steam.whistle.WhistleBlock; +import com.simibubi.create.content.contraptions.components.steam.whistle.WhistleBlock.WhistleSize; +import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; +import com.simibubi.create.foundation.utility.NBTHelper; + +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.nbt.Tag; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.level.block.BellBlock; +import net.minecraft.world.level.block.NoteBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo; + +public class ArrivalSoundQueue { + + public int offset; + int min, max; + Multimap sources; + + public ArrivalSoundQueue() { + sources = Multimaps.newMultimap(new HashMap<>(), ArrayList::new); + min = Integer.MAX_VALUE; + max = Integer.MIN_VALUE; + } + + @Nullable + public Integer firstTick() { + return sources.isEmpty() ? null : min + offset; + } + + @Nullable + public Integer lastTick() { + return sources.isEmpty() ? null : max + offset; + } + + public boolean tick(CarriageContraptionEntity entity, int tick, boolean backwards) { + tick = tick - offset; + if (!sources.containsKey(tick)) + return backwards ? tick > min : tick < max; + Contraption contraption = entity.getContraption(); + for (BlockPos blockPos : sources.get(tick)) + play(entity, contraption.getBlocks() + .get(blockPos)); + return backwards ? tick > min : tick < max; + } + + public void serialize(CompoundTag tagIn) { + CompoundTag tag = new CompoundTag(); + tag.putInt("Offset", offset); + tag.put("Sources", NBTHelper.writeCompoundList(sources.entries(), e -> { + CompoundTag c = new CompoundTag(); + c.putInt("Tick", e.getKey()); + c.put("Pos", NbtUtils.writeBlockPos(e.getValue())); + return c; + })); + tagIn.put("SoundQueue", tag); + } + + public void deserialize(CompoundTag tagIn) { + CompoundTag tag = tagIn.getCompound("SoundQueue"); + offset = tag.getInt("Offset"); + NBTHelper.iterateCompoundList(tag.getList("Sources", Tag.TAG_COMPOUND), + c -> add(c.getInt("Tick"), NbtUtils.readBlockPos(c.getCompound("Pos")))); + } + + public void add(int offset, BlockPos localPos) { + sources.put(offset, localPos); + min = Math.min(offset, min); + max = Math.max(offset, max); + } + + public static boolean isPlayable(BlockState state) { + if (state.getBlock() instanceof BellBlock) + return true; + if (state.getBlock() instanceof NoteBlock) + return true; + if (state.getBlock() instanceof WhistleBlock) + return true; + return false; + } + + public static void play(CarriageContraptionEntity entity, StructureBlockInfo info) { + if (info == null) + return; + BlockState state = info.state; + + if (state.getBlock() instanceof BellBlock) { + if (AllBlocks.HAUNTED_BELL.has(state)) + playSimple(entity, AllSoundEvents.HAUNTED_BELL_USE.getMainEvent(), 1, 1); + else + playSimple(entity, SoundEvents.BELL_BLOCK, 1, 1); + } + + if (state.getBlock()instanceof NoteBlock nb) { + float f = (float) Math.pow(2, (state.getValue(NoteBlock.NOTE) - 12) / 12.0); + playSimple(entity, state.getValue(NoteBlock.INSTRUMENT) + .getSoundEvent(), 1, f); + } + + if (state.getBlock() instanceof WhistleBlock && info.nbt != null) { + int pitch = info.nbt.getInt("Pitch"); + float f = (float) Math.pow(2, (pitch - 12) / 12.0); + WhistleSize size = state.getValue(WhistleBlock.SIZE); + playSimple(entity, (size == WhistleSize.LARGE ? AllSoundEvents.WHISTLE_TRAIN_LOW + : size == WhistleSize.MEDIUM ? AllSoundEvents.WHISTLE_TRAIN_MEDIUM : AllSoundEvents.WHISTLE_TRAIN_HIGH) + .getMainEvent(), + 1, f); + playSimple(entity, AllSoundEvents.WHISTLE_CHIFF.getMainEvent(), .75f, + size == WhistleSize.SMALL ? f + .75f : f); + } + + } + + private static void playSimple(CarriageContraptionEntity entity, SoundEvent event, float volume, float pitch) { + entity.level.playSound(null, entity, event, SoundSource.NEUTRAL, 5 * volume, pitch); + } + +} diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/Carriage.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/Carriage.java index e47ecdd3e..818ac2972 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/Carriage.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/Carriage.java @@ -36,6 +36,7 @@ public class Carriage { public Train train; public int id; public boolean blocked; + public boolean stalled; public Couple presentConductors; public int bogeySpacing; @@ -50,6 +51,7 @@ public class Carriage { // client public boolean pointsInitialised; + static final int FIRST = 0, MIDDLE = 1, LAST = 2, BOTH = 3; public Carriage(CarriageBogey bogey1, @Nullable CarriageBogey bogey2, int bogeySpacing) { @@ -284,6 +286,7 @@ public class Carriage { tag.putInt("Spacing", bogeySpacing); tag.putBoolean("FrontConductor", presentConductors.getFirst()); tag.putBoolean("BackConductor", presentConductors.getSecond()); + tag.putBoolean("Stalled", stalled); CarriageContraptionEntity entity = this.entity.get(); if (entity != null) @@ -303,6 +306,7 @@ public class Carriage { Carriage carriage = new Carriage(bogey1, bogey2, tag.getInt("Spacing")); + carriage.stalled = tag.getBoolean("Stalled"); carriage.presentConductors = Couple.create(tag.getBoolean("FrontConductor"), tag.getBoolean("BackConductor")); carriage.serialisedEntity = tag.getCompound("Entity") .copy(); diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraption.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraption.java index 276f5e296..967b081c4 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraption.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraption.java @@ -21,6 +21,7 @@ import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.NBTHelper; +import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -42,6 +43,7 @@ public class CarriageContraption extends Contraption { private boolean backwardControls; public Couple blazeBurnerConductors; public Map> conductorSeats; + public ArrivalSoundQueue soundQueue; // during assembly only private int bogeys; @@ -53,6 +55,11 @@ public class CarriageContraption extends Contraption { conductorSeats = new HashMap<>(); assembledBlazeBurners = new ArrayList<>(); blazeBurnerConductors = Couple.create(false, false); + soundQueue = new ArrivalSoundQueue(); + } + + public void setSoundQueueOffset(int offset) { + soundQueue.offset = offset; } public CarriageContraption(Direction assemblyDirection) { @@ -106,6 +113,13 @@ public class CarriageContraption extends Contraption { protected Pair capture(Level world, BlockPos pos) { BlockState blockState = world.getBlockState(pos); + if (ArrivalSoundQueue.isPlayable(blockState)) { + int anchorCoord = VecHelper.getCoordinate(anchor, assemblyDirection.getAxis()); + int posCoord = VecHelper.getCoordinate(pos, assemblyDirection.getAxis()); + soundQueue.add((posCoord - anchorCoord) * assemblyDirection.getAxisDirection() + .getStep(), toLocalPos(pos)); + } + if (blockState.getBlock() instanceof IBogeyBlock) { bogeys++; if (bogeys == 2) @@ -151,6 +165,7 @@ public class CarriageContraption extends Contraption { return compoundTag; }); tag.put("ConductorSeats", list); + soundQueue.serialize(tag); return tag; } @@ -165,6 +180,7 @@ public class CarriageContraption extends Contraption { NBTHelper.iterateCompoundList(nbt.getList("ConductorSeats", Tag.TAG_COMPOUND), c -> conductorSeats.put(NbtUtils.readBlockPos(c.getCompound("Pos")), Couple.create(c.getBoolean("Forward"), c.getBoolean("Backward")))); + soundQueue.deserialize(nbt); super.readNBT(world, nbt, spawnData); } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraptionEntity.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraptionEntity.java index d53682631..fe9c8ad80 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraptionEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraptionEntity.java @@ -2,19 +2,18 @@ package com.simibubi.create.content.logistics.trains.entity; import java.lang.ref.WeakReference; import java.util.Collection; +import java.util.List; import java.util.Optional; import java.util.UUID; import javax.annotation.Nullable; -import org.apache.commons.lang3.tuple.MutablePair; - import com.google.common.base.Strings; +import com.jozufozu.flywheel.repack.joml.Math; import com.simibubi.create.AllEntityDataSerializers; import com.simibubi.create.AllEntityTypes; import com.simibubi.create.Create; import com.simibubi.create.CreateClient; -import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; 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.TrackGraph; @@ -65,10 +64,15 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity { public boolean leftTickingChunks; public boolean firstPositionUpdate; + private boolean arrivalSoundPlaying; + private boolean arrivalSoundReversed; + private int arrivalSoundTicks; + public CarriageContraptionEntity(EntityType type, Level world) { super(type, world); validForRender = false; firstPositionUpdate = true; + arrivalSoundTicks = Integer.MIN_VALUE; } @Override @@ -167,15 +171,13 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity { } tickActors(); - contraption.stalled = false; - for (MutablePair pair : contraption.getActors()) { - MovementContext context = pair.right; - context.stall = false; - } + boolean isStalled = isStalled(); + carriage.stalled = isStalled; CarriageSyncData carriageData = getCarriageData(); if (!level.isClientSide) { + entityData.set(SCHEDULED, carriage.train.runtime.getSchedule() != null); boolean shouldCarriageSyncThisTick = carriage.train.shouldCarriageSyncThisTick(level.getGameTime(), getType().updateInterval()); @@ -184,6 +186,18 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity { entityData.set(CARRIAGE_DATA, carriageData); carriageData.setDirty(false); } + + Navigation navigation = carriage.train.navigation; + if (navigation.announceArrival && Math.abs(navigation.distanceToDestination) < 60 + && carriageIndex == (carriage.train.speed < 0 ? carriage.train.carriages.size() - 1 : 0)) { + navigation.announceArrival = false; + arrivalSoundPlaying = true; + arrivalSoundReversed = carriage.train.speed < 0; + arrivalSoundTicks = Integer.MIN_VALUE; + } + + if (arrivalSoundPlaying) + tickArrivalSound(cc); return; } @@ -223,6 +237,59 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity { validForRender = true; } + private void tickArrivalSound(CarriageContraption cc) { + List carriages = carriage.train.carriages; + + if (arrivalSoundTicks == Integer.MIN_VALUE) { + int carriageCount = carriages.size(); + Integer tick = null; + + for (int index = 0; index < carriageCount; index++) { + int i = arrivalSoundReversed ? carriageCount - 1 - index : index; + Carriage carriage = carriages.get(i); + CarriageContraptionEntity entity = carriage.entity.get(); + if (entity == null || !(entity.contraption instanceof CarriageContraption otherCC)) + break; + tick = arrivalSoundReversed ? otherCC.soundQueue.lastTick() : otherCC.soundQueue.firstTick(); + if (tick != null) + break; + } + + if (tick == null) { + arrivalSoundPlaying = false; + return; + } + + arrivalSoundTicks = tick; + } + + if (tickCount % 2 == 0) + return; + + boolean keepTicking = false; + for (Carriage c : carriages) { + CarriageContraptionEntity entity = c.entity.get(); + if (entity == null || !(entity.contraption instanceof CarriageContraption otherCC)) + continue; + keepTicking |= otherCC.soundQueue.tick(entity, arrivalSoundTicks, arrivalSoundReversed); + } + + if (!keepTicking) { + arrivalSoundPlaying = false; + return; + } + + arrivalSoundTicks += arrivalSoundReversed ? -1 : 1; + } + + @Override + public void tickActors() { + super.tickActors(); + } + + @Override + protected void handleStallInformation(float x, float y, float z, float angle) {} + Vec3 derailParticleOffset = VecHelper.offsetRandomly(Vec3.ZERO, Create.RANDOM, 1.5f) .multiply(1, .25f, 1); @@ -308,7 +375,7 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity { train.navigation.waitingForSignal = null; return true; } - + @Override public Component getDisplayName() { if (carriage == null) diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/Navigation.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/Navigation.java index 886d1bd31..f5a9ae325 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/Navigation.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/Navigation.java @@ -17,6 +17,7 @@ import javax.annotation.Nullable; import org.apache.commons.lang3.mutable.MutableDouble; import org.apache.commons.lang3.mutable.MutableObject; +import com.jozufozu.flywheel.repack.joml.Math; import com.simibubi.create.Create; import com.simibubi.create.content.logistics.trains.TrackEdge; import com.simibubi.create.content.logistics.trains.TrackGraph; @@ -52,6 +53,7 @@ public class Navigation { public double distanceToDestination; public double distanceStartedAt; public boolean destinationBehindTrain; + public boolean announceArrival; List> currentPath; private TravellingPoint signalScout; @@ -366,6 +368,9 @@ public class Navigation { cancelNavigation(); return -1; } + + if (Math.abs(distanceToDestination) > 100) + announceArrival = true; currentPath = pathTo.path; destinationBehindTrain = pathTo.distance < 0; @@ -676,6 +681,7 @@ public class Navigation { tag.putDouble("DistanceToDestination", distanceToDestination); tag.putDouble("DistanceStartedAt", distanceStartedAt); tag.putBoolean("BehindTrain", destinationBehindTrain); + tag.putBoolean("AnnounceArrival", announceArrival); tag.put("Path", NBTHelper.writeCompoundList(currentPath, c -> { CompoundTag nbt = new CompoundTag(); nbt.put("Nodes", c.map(TrackNode::getLocation) @@ -703,6 +709,7 @@ public class Navigation { distanceToDestination = tag.getDouble("DistanceToDestination"); distanceStartedAt = tag.getDouble("DistanceStartedAt"); destinationBehindTrain = tag.getBoolean("BehindTrain"); + announceArrival = tag.getBoolean("AnnounceArrival"); currentPath.clear(); NBTHelper.iterateCompoundList(tag.getList("Path", Tag.TAG_COMPOUND), c -> currentPath.add(Couple diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/Train.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/Train.java index f3be96ef6..2d487785c 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/Train.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/Train.java @@ -181,6 +181,10 @@ public class Train { stress[i - 1] = target - actual; } previousCarriage = carriage; + if (carriage.stalled) { + distance = 0; + speed = 0; + } } // positive stress: carriages should move apart @@ -532,7 +536,6 @@ public class Train { navigation.cancelNavigation(); forEachTravellingPoint(tp -> migratingPoints.add(new TrainMigration(tp))); graph = null; - syncTrackGraphChanges(); } public void forEachTravellingPoint(Consumer callback) { @@ -613,14 +616,13 @@ public class Train { if (derailed) status.successfulMigration(); derailed = false; - if (runtime.getSchedule() != null) { - if (runtime.state == State.IN_TRANSIT) - runtime.state = State.PRE_TRANSIT; - } + if (runtime.getSchedule() != null && runtime.state == State.IN_TRANSIT) + runtime.state = State.PRE_TRANSIT; GlobalStation currentStation = getCurrentStation(); if (currentStation != null) currentStation.reserveFor(this); updateSignalBlocks = true; + migrationCooldown = 0; syncTrackGraphChanges(); return; } @@ -722,7 +724,7 @@ public class Train { while (current != null) { prev = current; d = current.getLocationOn(edge); - current = signalData.next(EdgePointType.SIGNAL, d); + current = signalData.next(EdgePointType.SIGNAL, d); } if (prev != null) { UUID group = prev.getGroup(node2); diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/AbstractStationScreen.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/AbstractStationScreen.java index 8333b48f2..3e80a5fe2 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/AbstractStationScreen.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/AbstractStationScreen.java @@ -65,6 +65,7 @@ public abstract class AbstractStationScreen extends AbstractSimiScreen { Carriage carriage = carriages.get(i); w += icon.getIconWidth(carriage.bogeySpacing) + 1; } + return w; } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/AssemblyScreen.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/AssemblyScreen.java index bdc5ccdaa..2c090f5bd 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/AssemblyScreen.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/AssemblyScreen.java @@ -153,7 +153,10 @@ public class AssemblyScreen extends AbstractStationScreen { TrainIconType icon = train.icon; int offset = 0; - int position = background.width / 2 - getTrainIconWidth(train) / 2; + int trainIconWidth = getTrainIconWidth(train); + int position = background.width / 2 - trainIconWidth / 2; + if (trainIconWidth > 130) + position -= trainIconWidth - 130; boolean frontConductor = false; boolean backConductor = false; diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationScreen.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationScreen.java index 1de347dfa..8f5bebad5 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationScreen.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationScreen.java @@ -116,7 +116,7 @@ public class StationScreen extends AbstractStationScreen { .length()); trainNameBox.setHighlightPos(trainNameBox.getCursorPosition()); } - + super.tick(); updateAssemblyTooltip(te.edgePoint.isOnCurve() ? "no_assembly_curve" @@ -154,6 +154,8 @@ public class StationScreen extends AbstractStationScreen { int trainIconWidth = getTrainIconWidth(imminentTrain); int targetPos = background.width / 2 - trainIconWidth / 2; + if (trainIconWidth > 130) + targetPos -= trainIconWidth - 130; float f = (float) (imminentTrain.navigation.distanceToDestination / 15f); if (trainPresent()) f = 0; @@ -164,6 +166,8 @@ public class StationScreen extends AbstractStationScreen { int trainIconWidth = getTrainIconWidth(train); int targetPos = background.width / 2 - trainIconWidth / 2; + if (trainIconWidth > 130) + targetPos -= trainIconWidth - 130; if (leavingAnimation > 0) { disassembleTrainButton.active = false; diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationTileEntity.java index 6d62c1a0f..9a43e7613 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationTileEntity.java @@ -33,6 +33,7 @@ import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePoi import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBehaviour; import com.simibubi.create.content.logistics.trains.management.schedule.Schedule; import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleItem; +import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; @@ -311,8 +312,8 @@ public class StationTileEntity extends SmartTileEntity { BlockPos bogeyOffset = new BlockPos(track.getUpNormal(level, targetPosition, trackState)); - int MAX_LENGTH = 48; - int MAX_BOGEY_COUNT = 20; + int MAX_LENGTH = AllConfigs.SERVER.trains.maxAssemblyLength.get(); + int MAX_BOGEY_COUNT = AllConfigs.SERVER.trains.maxBogeyCount.get(); int bogeyIndex = 0; int maxBogeyCount = MAX_BOGEY_COUNT; @@ -324,10 +325,14 @@ public class StationTileEntity extends SmartTileEntity { Arrays.fill(bogeyTypes, null); for (int i = 0; i < MAX_LENGTH; i++) { - if (i == MAX_LENGTH - 1 || !track.trackEquals(trackState, level.getBlockState(currentPos))) { + if (i == MAX_LENGTH - 1) { assemblyLength = i; break; } + if (!track.trackEquals(trackState, level.getBlockState(currentPos))) { + assemblyLength = Math.max(0, i - 1); + break; + } BlockState potentialBogeyState = level.getBlockState(bogeyOffset.offset(currentPos)); if (potentialBogeyState.getBlock()instanceof IBogeyBlock bogey && bogeyIndex < bogeyLocations.length) { @@ -510,9 +515,10 @@ public class StationTileEntity extends SmartTileEntity { BlockPos bogeyPosOffset = trackPosition.offset(bogeyOffset); try { - boolean success = contraption.assemble(level, - bogeyPosOffset.relative(assemblyDirection, bogeyLocations[bogeyIndex] + 1)); + int offset = bogeyLocations[bogeyIndex] + 1; + boolean success = contraption.assemble(level, bogeyPosOffset.relative(assemblyDirection, offset)); atLeastOneForwardControls |= contraption.hasForwardControls(); + contraption.setSoundQueueOffset(offset); if (!success) { exception(new AssemblyException(Lang.translate("train_assembly.nothing_attached", bogeyIndex + 1)), -1); diff --git a/src/main/java/com/simibubi/create/foundation/config/CTrains.java b/src/main/java/com/simibubi/create/foundation/config/CTrains.java index bc3e8f97d..f30b31e97 100644 --- a/src/main/java/com/simibubi/create/foundation/config/CTrains.java +++ b/src/main/java/com/simibubi/create/foundation/config/CTrains.java @@ -7,6 +7,8 @@ public class CTrains extends ConfigBase { public final ConfigFloat trainTurningTopSpeed = f(18, 0, "trainTurningTopSpeed", Comments.mps, Comments.trainTurningTopSpeed); public final ConfigFloat trainAcceleration = f(4, 0, "trainAcceleration", Comments.acc, Comments.trainAcceleration); + public final ConfigInt maxAssemblyLength = i(128, 5, "maxAssemblyLength", Comments.maxAssemblyLength); + public final ConfigInt maxBogeyCount = i(20, 1, "maxBogeyCount", Comments.maxBogeyCount); @Override public String getName() { @@ -32,6 +34,8 @@ public class CTrains extends ConfigBase { static String trainTurningTopSpeed = "The top speed of Trains during a turn."; static String trainAcceleration = "The acceleration of any assembled Train."; static String trainsCauseDamage = "Whether moving Trains can hurt colliding mobs and players."; + static String maxAssemblyLength = "Maximum length of a Train Stations' assembly track."; + static String maxBogeyCount = "Maximum amount of bogeys assembled as a single Train."; } } diff --git a/src/main/resources/assets/create/sounds/whistle_low_old.ogg b/src/main/resources/assets/create/sounds/whistle_low_old.ogg deleted file mode 100644 index 32c065f03..000000000 Binary files a/src/main/resources/assets/create/sounds/whistle_low_old.ogg and /dev/null differ diff --git a/src/main/resources/assets/create/sounds/whistle_train.ogg b/src/main/resources/assets/create/sounds/whistle_train.ogg new file mode 100644 index 000000000..d2e62ec6c Binary files /dev/null and b/src/main/resources/assets/create/sounds/whistle_train.ogg differ diff --git a/src/main/resources/assets/create/sounds/whistle_train_high.ogg b/src/main/resources/assets/create/sounds/whistle_train_high.ogg new file mode 100644 index 000000000..fca799761 Binary files /dev/null and b/src/main/resources/assets/create/sounds/whistle_train_high.ogg differ diff --git a/src/main/resources/assets/create/sounds/whistle_train_low.ogg b/src/main/resources/assets/create/sounds/whistle_train_low.ogg new file mode 100644 index 000000000..379275e87 Binary files /dev/null and b/src/main/resources/assets/create/sounds/whistle_train_low.ogg differ