From 56f4cd524df890885a17315acd8d28b433c6c41c Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Sat, 7 May 2022 17:04:52 +0200 Subject: [PATCH] Choo Choo, Part II - Whistles animate and play a test sound when powered --- src/generated/resources/.cache/cache | 34 ++++---- .../resources/assets/create/lang/en_us.json | 1 + .../assets/create/lang/unfinished/de_de.json | 3 +- .../assets/create/lang/unfinished/es_cl.json | 3 +- .../assets/create/lang/unfinished/es_es.json | 3 +- .../assets/create/lang/unfinished/fr_fr.json | 3 +- .../assets/create/lang/unfinished/it_it.json | 3 +- .../assets/create/lang/unfinished/ja_jp.json | 3 +- .../assets/create/lang/unfinished/ko_kr.json | 3 +- .../assets/create/lang/unfinished/nl_nl.json | 3 +- .../assets/create/lang/unfinished/pl_pl.json | 3 +- .../assets/create/lang/unfinished/pt_br.json | 3 +- .../assets/create/lang/unfinished/pt_pt.json | 3 +- .../assets/create/lang/unfinished/ro_ro.json | 3 +- .../assets/create/lang/unfinished/ru_ru.json | 3 +- .../assets/create/lang/unfinished/zh_cn.json | 3 +- .../assets/create/lang/unfinished/zh_tw.json | 3 +- .../resources/assets/create/sounds.json | 6 ++ .../com/simibubi/create/AllSoundEvents.java | 4 + .../steam/whistle/WhistleRenderer.java | 9 +- .../steam/whistle/WhistleSoundInstance.java | 60 ++++++++++++++ .../steam/whistle/WhistleTileEntity.java | 77 +++++++++++++++++- .../assets/create/sounds/whistle.ogg | Bin 0 -> 27395 bytes 23 files changed, 201 insertions(+), 35 deletions(-) create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/steam/whistle/WhistleSoundInstance.java create mode 100644 src/main/resources/assets/create/sounds/whistle.ogg diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index 06dfa4fe4..113719636 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 -9920f89987afa7a5a534f913f930affb5fadaa33 assets/create/lang/en_us.json -13c213be9595e8fe1ad165a14cdd0ec16a092204 assets/create/lang/unfinished/de_de.json -687b9acd091e4222219057ac647402aab2f05ca2 assets/create/lang/unfinished/es_cl.json -20984bb318badfb2a49d1a5467de0aef5fa4a14f assets/create/lang/unfinished/es_es.json -3ef90285ab19e24ff80354849a253a5caf5062f4 assets/create/lang/unfinished/fr_fr.json -af40251171a29093bb6d4f99172af15a734a47f7 assets/create/lang/unfinished/it_it.json -98304b8aebf8db14d0a764140f2e4703bbcffb29 assets/create/lang/unfinished/ja_jp.json -4d7f1ba7e3ced59666d9113577d2e20af54d00ef assets/create/lang/unfinished/ko_kr.json -3530e4d047cf4a654a95d069d874ac73306cbac3 assets/create/lang/unfinished/nl_nl.json -3a82a8398f74ece7d5f6440613fecc14d7056b30 assets/create/lang/unfinished/pl_pl.json -5723fa37dbdd24e31bfd14f71586f67e3a23047f assets/create/lang/unfinished/pt_br.json -f394d6ff13e89051f7582a789ab1cf81905620b4 assets/create/lang/unfinished/pt_pt.json -01ccdd4a7c1beaa84cc6bdc7cd0cc912440fb0c7 assets/create/lang/unfinished/ro_ro.json -d0b58764408454fc6df71e0a340e210c0bc5f70b assets/create/lang/unfinished/ru_ru.json -bf4a93e64419cdacf1636e1a283086e33f853bf5 assets/create/lang/unfinished/zh_cn.json -6a615c911ea01faac6c52f58e98904aef5660dc5 assets/create/lang/unfinished/zh_tw.json +97c53a163e253dd1a8933a0ace74b9654d893587 assets/create/lang/en_us.json +12311e1c34d28139bbf8d7da53a116e066be6b9e assets/create/lang/unfinished/de_de.json +c63ceb535bf91819590021a3889dcd86cf529923 assets/create/lang/unfinished/es_cl.json +6862db283b26fbdcd901939e6c4b60641711a410 assets/create/lang/unfinished/es_es.json +1e66f6f48c7cebe998dcf9611cb41d3616444df6 assets/create/lang/unfinished/fr_fr.json +3fcccff2e2aa3029e260c5b521db927a99528658 assets/create/lang/unfinished/it_it.json +1b514b1cd75ea524b38ec1da48fdaa535827fcb4 assets/create/lang/unfinished/ja_jp.json +5b6f470baf2fef6252530fe88cc58530b948b44c assets/create/lang/unfinished/ko_kr.json +952e931c4d99d0c42c59ebc8f292d00cadd853dd assets/create/lang/unfinished/nl_nl.json +6c892826366d463b52a0cd2d2eeff00f6289346a assets/create/lang/unfinished/pl_pl.json +df275e393b8e8930d1863955d5563e49638d48c0 assets/create/lang/unfinished/pt_br.json +582a9e4d94df44f283103024781395791569dd4d assets/create/lang/unfinished/pt_pt.json +a114cdc8701e158bbb1ddbd90aa6b3a6615e1ca6 assets/create/lang/unfinished/ro_ro.json +4be727c1026bd66dce98518eb851de127eadab51 assets/create/lang/unfinished/ru_ru.json +e09205abffde3d10717284de6e405bb17c59b902 assets/create/lang/unfinished/zh_cn.json +e1f9d9ce9d4835fb69151af2908c3359c696d481 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 -5049f72c327a88f175f6f9425909e098fc711100 assets/create/sounds.json +8b9dcd869179ac21a800b11693db6bb8cdd479a9 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 c9b5432fb..c6c9561ac 100644 --- a/src/generated/resources/assets/create/lang/en_us.json +++ b/src/generated/resources/assets/create/lang/en_us.json @@ -1584,6 +1584,7 @@ "create.subtitle.cranking": "Hand Crank turns", "create.subtitle.wrench_remove": "Component breaks", "create.subtitle.sanding_short": "Sanding noises", + "create.subtitle.whistle": "Whistling", "create.subtitle.cogs": "Cogwheels rumble", "create.subtitle.slime_added": "Slime squishes", "create.subtitle.wrench_rotate": "Wrench used", 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 4f63971ec..6597d08c9 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: 1531", + "_": "Missing Localizations: 1532", "_": "->------------------------] Game Elements [------------------------<-", @@ -1585,6 +1585,7 @@ "create.subtitle.cranking": "UNLOCALIZED: Hand Crank turns", "create.subtitle.wrench_remove": "UNLOCALIZED: Component breaks", "create.subtitle.sanding_short": "UNLOCALIZED: Sanding noises", + "create.subtitle.whistle": "UNLOCALIZED: Whistling", "create.subtitle.cogs": "UNLOCALIZED: Cogwheels rumble", "create.subtitle.slime_added": "Schleim matscht", "create.subtitle.wrench_rotate": "UNLOCALIZED: Wrench used", 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 461e2323d..0b9b8ec2e 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: 553", + "_": "Missing Localizations: 554", "_": "->------------------------] Game Elements [------------------------<-", @@ -1585,6 +1585,7 @@ "create.subtitle.cranking": "Manivela gira", "create.subtitle.wrench_remove": "Componente se rompe", "create.subtitle.sanding_short": "UNLOCALIZED: Sanding noises", + "create.subtitle.whistle": "UNLOCALIZED: Whistling", "create.subtitle.cogs": "Engranajes suenan", "create.subtitle.slime_added": "Slime chapotea", "create.subtitle.wrench_rotate": "Llave Inglesa usada", 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 08b467612..9b70aa047 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: 224", + "_": "Missing Localizations: 225", "_": "->------------------------] Game Elements [------------------------<-", @@ -1585,6 +1585,7 @@ "create.subtitle.cranking": "Manivela gira", "create.subtitle.wrench_remove": "Componente se rompe", "create.subtitle.sanding_short": "Lijando", + "create.subtitle.whistle": "UNLOCALIZED: Whistling", "create.subtitle.cogs": "Engranajes retumban", "create.subtitle.slime_added": "Pegamento chapotea", "create.subtitle.wrench_rotate": "Llave inglesa usada", 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 33f322bf5..ad31e31e1 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: 1793", + "_": "Missing Localizations: 1794", "_": "->------------------------] Game Elements [------------------------<-", @@ -1585,6 +1585,7 @@ "create.subtitle.cranking": "UNLOCALIZED: Hand Crank turns", "create.subtitle.wrench_remove": "UNLOCALIZED: Component breaks", "create.subtitle.sanding_short": "UNLOCALIZED: Sanding noises", + "create.subtitle.whistle": "UNLOCALIZED: Whistling", "create.subtitle.cogs": "UNLOCALIZED: Cogwheels rumble", "create.subtitle.slime_added": "Bruit de slime", "create.subtitle.wrench_rotate": "UNLOCALIZED: Wrench used", 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 d245ff753..31f5c8647 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: 1482", + "_": "Missing Localizations: 1483", "_": "->------------------------] Game Elements [------------------------<-", @@ -1585,6 +1585,7 @@ "create.subtitle.cranking": "UNLOCALIZED: Hand Crank turns", "create.subtitle.wrench_remove": "UNLOCALIZED: Component breaks", "create.subtitle.sanding_short": "UNLOCALIZED: Sanding noises", + "create.subtitle.whistle": "UNLOCALIZED: Whistling", "create.subtitle.cogs": "UNLOCALIZED: Cogwheels rumble", "create.subtitle.slime_added": "Slime schiacciato", "create.subtitle.wrench_rotate": "UNLOCALIZED: Wrench used", 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 e99833cd2..70b86a2af 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: 219", + "_": "Missing Localizations: 220", "_": "->------------------------] Game Elements [------------------------<-", @@ -1585,6 +1585,7 @@ "create.subtitle.cranking": "ハンドクランクが回る", "create.subtitle.wrench_remove": "機械を壊す", "create.subtitle.sanding_short": "研磨音", + "create.subtitle.whistle": "UNLOCALIZED: Whistling", "create.subtitle.cogs": "歯車がゴロゴロと鳴る", "create.subtitle.slime_added": "スライムがぐしゃっとつぶれる", "create.subtitle.wrench_rotate": "レンチが使用される", 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 213f16703..42b9c414b 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: 219", + "_": "Missing Localizations: 220", "_": "->------------------------] Game Elements [------------------------<-", @@ -1585,6 +1585,7 @@ "create.subtitle.cranking": "크랭크가 돌아감", "create.subtitle.wrench_remove": "장치가 부숴짐", "create.subtitle.sanding_short": "사포를 사용함", + "create.subtitle.whistle": "UNLOCALIZED: Whistling", "create.subtitle.cogs": "톱니바퀴가 돌아감", "create.subtitle.slime_added": "슬라임이 철퍽거림", "create.subtitle.wrench_rotate": "렌치를 사용함", 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 e6cdaba7b..061a24a54 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: 2145", + "_": "Missing Localizations: 2146", "_": "->------------------------] Game Elements [------------------------<-", @@ -1585,6 +1585,7 @@ "create.subtitle.cranking": "UNLOCALIZED: Hand Crank turns", "create.subtitle.wrench_remove": "UNLOCALIZED: Component breaks", "create.subtitle.sanding_short": "UNLOCALIZED: Sanding noises", + "create.subtitle.whistle": "UNLOCALIZED: Whistling", "create.subtitle.cogs": "UNLOCALIZED: Cogwheels rumble", "create.subtitle.slime_added": "UNLOCALIZED: Slime squishes", "create.subtitle.wrench_rotate": "UNLOCALIZED: Wrench used", 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 b360388a0..68b353145 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: 592", + "_": "Missing Localizations: 593", "_": "->------------------------] Game Elements [------------------------<-", @@ -1585,6 +1585,7 @@ "create.subtitle.cranking": "Ręczna korba obraca się", "create.subtitle.wrench_remove": "Komponent niszczy się", "create.subtitle.sanding_short": "UNLOCALIZED: Sanding noises", + "create.subtitle.whistle": "UNLOCALIZED: Whistling", "create.subtitle.cogs": "Koła zębate terkoczą", "create.subtitle.slime_added": "Szlam plaska", "create.subtitle.wrench_rotate": "Klucz skrzypi", 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 8f5aaa384..a4048f31a 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: 1393", + "_": "Missing Localizations: 1394", "_": "->------------------------] Game Elements [------------------------<-", @@ -1585,6 +1585,7 @@ "create.subtitle.cranking": "UNLOCALIZED: Hand Crank turns", "create.subtitle.wrench_remove": "UNLOCALIZED: Component breaks", "create.subtitle.sanding_short": "UNLOCALIZED: Sanding noises", + "create.subtitle.whistle": "UNLOCALIZED: Whistling", "create.subtitle.cogs": "UNLOCALIZED: Cogwheels rumble", "create.subtitle.slime_added": "UNLOCALIZED: Slime squishes", "create.subtitle.wrench_rotate": "UNLOCALIZED: Wrench used", 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 69709281c..4ac0cb547 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: 1765", + "_": "Missing Localizations: 1766", "_": "->------------------------] Game Elements [------------------------<-", @@ -1585,6 +1585,7 @@ "create.subtitle.cranking": "UNLOCALIZED: Hand Crank turns", "create.subtitle.wrench_remove": "UNLOCALIZED: Component breaks", "create.subtitle.sanding_short": "UNLOCALIZED: Sanding noises", + "create.subtitle.whistle": "UNLOCALIZED: Whistling", "create.subtitle.cogs": "UNLOCALIZED: Cogwheels rumble", "create.subtitle.slime_added": "UNLOCALIZED: Slime squishes", "create.subtitle.wrench_rotate": "UNLOCALIZED: Wrench used", 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 f1007e046..457e7dadd 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: 220", + "_": "Missing Localizations: 221", "_": "->------------------------] Game Elements [------------------------<-", @@ -1585,6 +1585,7 @@ "create.subtitle.cranking": "Manivelă se rotește", "create.subtitle.wrench_remove": "Component se sparge", "create.subtitle.sanding_short": "Sunete de șlefuit", + "create.subtitle.whistle": "UNLOCALIZED: Whistling", "create.subtitle.cogs": "Roți Dințate vuie", "create.subtitle.slime_added": "Mâzgă zdrobește", "create.subtitle.wrench_rotate": "Cheie folosită", 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 7348818a6..3a5f9b6ba 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: 597", + "_": "Missing Localizations: 598", "_": "->------------------------] Game Elements [------------------------<-", @@ -1585,6 +1585,7 @@ "create.subtitle.cranking": "Вращается рукоятка", "create.subtitle.wrench_remove": "Компонент ломается", "create.subtitle.sanding_short": "UNLOCALIZED: Sanding noises", + "create.subtitle.whistle": "UNLOCALIZED: Whistling", "create.subtitle.cogs": "Шестерни грохочут", "create.subtitle.slime_added": "Намазывание слизи", "create.subtitle.wrench_rotate": "Использован гаечный ключ", 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 038e3fe70..852e411de 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: 219", + "_": "Missing Localizations: 220", "_": "->------------------------] Game Elements [------------------------<-", @@ -1585,6 +1585,7 @@ "create.subtitle.cranking": "手摇曲柄:转动", "create.subtitle.wrench_remove": "组件:被破坏", "create.subtitle.sanding_short": "打磨噪音", + "create.subtitle.whistle": "UNLOCALIZED: Whistling", "create.subtitle.cogs": "齿轮:嘎吱作响", "create.subtitle.slime_added": "粘液:挤碎声", "create.subtitle.wrench_rotate": "扳手:拧动", 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 0cf8de35c..cab13a0c7 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: 611", + "_": "Missing Localizations: 612", "_": "->------------------------] Game Elements [------------------------<-", @@ -1585,6 +1585,7 @@ "create.subtitle.cranking": "手搖把手轉動聲", "create.subtitle.wrench_remove": "零件移除聲", "create.subtitle.sanding_short": "UNLOCALIZED: Sanding noises", + "create.subtitle.whistle": "UNLOCALIZED: Whistling", "create.subtitle.cogs": "齒輪隆隆聲", "create.subtitle.slime_added": "黏液擠壓", "create.subtitle.wrench_rotate": "UNLOCALIZED: Wrench used", diff --git a/src/generated/resources/assets/create/sounds.json b/src/generated/resources/assets/create/sounds.json index c755c2668..848130795 100644 --- a/src/generated/resources/assets/create/sounds.json +++ b/src/generated/resources/assets/create/sounds.json @@ -359,6 +359,12 @@ ], "subtitle": "create.subtitle.slime_added" }, + "whistle": { + "sounds": [ + "create:whistle" + ], + "subtitle": "create.subtitle.whistle" + }, "worldshaper_place": { "sounds": [ { diff --git a/src/main/java/com/simibubi/create/AllSoundEvents.java b/src/main/java/com/simibubi/create/AllSoundEvents.java index 314e2c814..435e62960 100644 --- a/src/main/java/com/simibubi/create/AllSoundEvents.java +++ b/src/main/java/com/simibubi/create/AllSoundEvents.java @@ -223,6 +223,10 @@ public class AllSoundEvents { .category(SoundSource.BLOCKS) .build(), + WHISTLE = create("whistle").subtitle("Whistling") + .category(SoundSource.RECORDS) + .build(), + HAUNTED_BELL_CONVERT = create("haunted_bell_convert").subtitle("Haunted Bell awakens") .category(SoundSource.BLOCKS) .build(), diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/steam/whistle/WhistleRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/steam/whistle/WhistleRenderer.java index 45edc082e..1aafc8d7b 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/steam/whistle/WhistleRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/steam/whistle/WhistleRenderer.java @@ -7,11 +7,13 @@ import com.simibubi.create.content.contraptions.components.steam.whistle.Whistle import com.simibubi.create.foundation.render.CachedBufferer; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.AnimationTickHolder; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.core.Direction; +import net.minecraft.util.Mth; import net.minecraft.world.level.block.state.BlockState; public class WhistleRenderer extends SafeTileEntityRenderer { @@ -31,7 +33,12 @@ public class WhistleRenderer extends SafeTileEntityRenderer { PartialModel mouth = size == WhistleSize.LARGE ? AllBlockPartials.WHISTLE_MOUTH_LARGE : size == WhistleSize.MEDIUM ? AllBlockPartials.WHISTLE_MOUTH_MEDIUM : AllBlockPartials.WHISTLE_MOUTH_SMALL; - float offset = 0; + float offset = te.animation.getValue(partialTicks); + if (te.animation.getChaseTarget() > 0 && te.animation.getValue() > 0.5f) { + float wiggleProgress = (AnimationTickHolder.getTicks(te.getLevel()) + partialTicks) / 8f; + offset -= Math.sin(wiggleProgress * (2 * Mth.PI) * (4 - size.ordinal())) / 16f; + } + CachedBufferer.partial(mouth, blockState) .centre() .rotateY(AngleHelper.horizontalAngle(direction)) 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 new file mode 100644 index 000000000..614e9df10 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/steam/whistle/WhistleSoundInstance.java @@ -0,0 +1,60 @@ +package com.simibubi.create.content.contraptions.components.steam.whistle; + +import com.simibubi.create.AllSoundEvents; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.sounds.AbstractTickableSoundInstance; +import net.minecraft.core.BlockPos; +import net.minecraft.sounds.SoundSource; +import net.minecraft.util.Mth; +import net.minecraft.world.phys.Vec3; + +public class WhistleSoundInstance extends AbstractTickableSoundInstance { + + private boolean active; + private int keepAlive; + + public WhistleSoundInstance(BlockPos worldPosition) { + super(AllSoundEvents.WHISTLE.getMainEvent(), SoundSource.RECORDS); + looping = true; + active = true; + volume = 0.05f; + delay = 0; + keepAlive(); + Vec3 v = Vec3.atCenterOf(worldPosition); + x = v.x; + y = v.y; + z = v.z; + } + + public void fadeOut() { + this.active = false; + } + + public void keepAlive() { + keepAlive = 2; + } + + public void setPitch(float pitch) { + this.pitch = pitch; + } + + @Override + public void tick() { + Vec3 eyePosition = Minecraft.getInstance().cameraEntity.getEyePosition(); + float maxVolume = (float) Mth.clamp((30 - eyePosition.distanceTo(new Vec3(x, y, z))) / 30, 0, 1); + if (active) { + volume = Math.min(1, volume + .25f); + volume = Math.min(volume, maxVolume); + keepAlive--; + if (keepAlive == 0) + fadeOut(); + return; + } + volume = Math.max(0, volume - .25f); + volume = Math.min(volume, maxVolume); + if (volume == 0) + stop(); + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/steam/whistle/WhistleTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/steam/whistle/WhistleTileEntity.java index 9c8bb9d52..fd1261862 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/steam/whistle/WhistleTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/steam/whistle/WhistleTileEntity.java @@ -1,26 +1,40 @@ package com.simibubi.create.content.contraptions.components.steam.whistle; +import java.lang.ref.WeakReference; import java.util.List; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.components.steam.whistle.WhistleExtenderBlock.WhistleExtenderShape; +import com.simibubi.create.content.contraptions.fluids.tank.FluidTankConnectivityHandler; +import com.simibubi.create.content.contraptions.fluids.tank.FluidTankTileEntity; import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; +import com.simibubi.create.foundation.utility.animation.LerpedFloat; +import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser; +import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TextComponent; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.fml.DistExecutor; public class WhistleTileEntity extends SmartTileEntity implements IHaveGoggleInformation { - protected int pitch = 0; + public WeakReference source; + public LerpedFloat animation; + protected int pitch; public WhistleTileEntity(BlockEntityType type, BlockPos pos, BlockState state) { super(type, pos, state); + source = new WeakReference<>(null); + animation = LerpedFloat.linear(); } @Override @@ -44,6 +58,20 @@ public class WhistleTileEntity extends SmartTileEntity implements IHaveGoggleInf notifyUpdate(); } + @Override + public void tick() { + super.tick(); + if (!level.isClientSide()) + return; + + FluidTankTileEntity tank = getTank(); + boolean powered = isPowered() && tank != null && tank.boiler.isActive() + && tank.boiler.getEngineEfficiency(tank.getTotalTankSize()) > 0; + animation.chase(powered ? 1 : 0, powered ? .5f : .4f, powered ? Chaser.EXP : Chaser.LINEAR); + animation.tickChaser(); + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> this.tickAudio(powered)); + } + @Override protected void write(CompoundTag tag, boolean clientPacket) { tag.putInt("Pitch", pitch); @@ -58,8 +86,53 @@ public class WhistleTileEntity extends SmartTileEntity implements IHaveGoggleInf @Override public boolean addToGoggleTooltip(List tooltip, boolean isPlayerSneaking) { - tooltip.add(new TextComponent(spacing + "Pitch: " + pitch)); + String[] pitches = "F#;F;E;D#;D;C#;C;B;A#;A;G#;G".split(";"); + tooltip.add(new TextComponent(spacing + "Pitch: " + pitches[pitch % pitches.length])); return true; } + protected boolean isPowered() { + return getBlockState().getOptionalValue(WhistleBlock.POWERED) + .orElse(false); + } + + @OnlyIn(Dist.CLIENT) + protected WhistleSoundInstance soundInstance; + + @OnlyIn(Dist.CLIENT) + protected void tickAudio(boolean powered) { + if (!powered) { + if (soundInstance != null) { + soundInstance.fadeOut(); + soundInstance = null; + } + return; + } + + if (soundInstance == null || soundInstance.isStopped()) + Minecraft.getInstance() + .getSoundManager() + .play(soundInstance = new WhistleSoundInstance(worldPosition)); + + float f = (float) Math.pow(2.0D, (double) ((24 - pitch) - 12) / 12.0D); + soundInstance.keepAlive(); + soundInstance.setPitch(f); + } + + public FluidTankTileEntity getTank() { + FluidTankTileEntity tank = source.get(); + if (tank == null || tank.isRemoved()) { + if (tank != null) + source = new WeakReference<>(null); + Direction facing = WhistleBlock.getAttachedDirection(getBlockState()); + FluidTankTileEntity anyTankAt = + FluidTankConnectivityHandler.anyTankAt(level, worldPosition.relative(facing)); + if (anyTankAt != null) + source = new WeakReference<>(tank = anyTankAt); + } + if (tank == null) + return null; + return tank.getControllerTE(); + } + } diff --git a/src/main/resources/assets/create/sounds/whistle.ogg b/src/main/resources/assets/create/sounds/whistle.ogg new file mode 100644 index 0000000000000000000000000000000000000000..78a6dd51e235a32f58c8e77b7bf6881a3571909a GIT binary patch literal 27395 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