From 4fa752b24cb58e576d03176445017d18f009ce46 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Wed, 22 Mar 2023 14:03:20 +0800 Subject: [PATCH] update SFX, handle missing JSON deck definition - add button_press, coins_drop, take_shard sfx - update music timing - adjust secondary audio volume - adjust flipprocess prior to its sfx - handle crash for missing deck/json definition --- .../adventure/player/AdventurePlayer.java | 6 ++ .../src/forge/adventure/scene/DuelScene.java | 2 +- .../forge/adventure/scene/NewGameScene.java | 4 +- .../forge/adventure/scene/RewardScene.java | 16 +++-- .../forge/adventure/scene/SaveLoadScene.java | 3 + .../src/forge/adventure/scene/StartScene.java | 2 + .../src/forge/adventure/stage/GameHUD.java | 61 +++++++++++++++--- .../src/forge/adventure/util/CardUtil.java | 4 +- .../src/forge/adventure/util/Controls.java | 10 +++ .../src/forge/adventure/util/RewardActor.java | 2 +- forge-gui/res/sound/button_press.mp3 | Bin 0 -> 1560 bytes forge-gui/res/sound/coins_drop.mp3 | Bin 0 -> 11760 bytes forge-gui/res/sound/take_shard.mp3 | Bin 0 -> 9984 bytes .../java/forge/sound/SoundEffectType.java | 5 +- 14 files changed, 94 insertions(+), 21 deletions(-) create mode 100644 forge-gui/res/sound/button_press.mp3 create mode 100644 forge-gui/res/sound/coins_drop.mp3 create mode 100644 forge-gui/res/sound/take_shard.mp3 diff --git a/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java b/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java index 98e47c52a3f..0ad4640b8c1 100644 --- a/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java +++ b/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java @@ -18,6 +18,8 @@ import forge.deck.DeckProxy; import forge.deck.DeckSection; import forge.item.InventoryItem; import forge.item.PaperCard; +import forge.sound.SoundEffectType; +import forge.sound.SoundSystem; import forge.util.ItemPool; import java.io.Serializable; @@ -516,6 +518,8 @@ public class AdventurePlayer implements Serializable, SaveFileContent { public void takeGold(int price) { gold -= price; onGoldChangeList.emit(); + //play sfx + SoundSystem.instance.play(SoundEffectType.CoinsDrop, false); } public void addShards(int number) { takeShards(-number); @@ -523,6 +527,8 @@ public class AdventurePlayer implements Serializable, SaveFileContent { public void takeShards(int number) { shards -= number; onShardsChangeList.emit(); + //play sfx + SoundSystem.instance.play(SoundEffectType.TakeShard, false); } public void setShards(int number) { diff --git a/forge-gui-mobile/src/forge/adventure/scene/DuelScene.java b/forge-gui-mobile/src/forge/adventure/scene/DuelScene.java index 687b4d1a9fb..0d916192653 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/DuelScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/DuelScene.java @@ -201,7 +201,7 @@ public class DuelScene extends ForgeScene { @Override public void enter() { - GameHUD.getInstance().stopAudio(); + GameHUD.getInstance().unloadAudio(); Set appliedVariants = new HashSet<>(); appliedVariants.add(GameType.Constructed); AdventurePlayer advPlayer = Current.player(); diff --git a/forge-gui-mobile/src/forge/adventure/scene/NewGameScene.java b/forge-gui-mobile/src/forge/adventure/scene/NewGameScene.java index ae0238cdf80..a386d174feb 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/NewGameScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/NewGameScene.java @@ -24,6 +24,7 @@ import forge.localinstance.properties.ForgePreferences; import forge.model.FModel; import forge.player.GamePlayerUtil; import forge.screens.TransitionScreen; +import forge.sound.SoundSystem; import forge.util.NameGenerator; import java.util.Random; @@ -190,7 +191,7 @@ public class NewGameScene extends UIScene { } Runnable runnable = () -> { started = false; - FModel.getPreferences().setPref(ForgePreferences.FPref.UI_ENABLE_MUSIC, false); + //FModel.getPreferences().setPref(ForgePreferences.FPref.UI_ENABLE_MUSIC, false); WorldSave.generateNewWorld(selectedName.getText(), gender.getCurrentIndex() == 0, race.getCurrentIndex(), @@ -200,6 +201,7 @@ public class NewGameScene extends UIScene { modes.get(mode.getCurrentIndex()), colorId.getCurrentIndex(), editionIds[starterEdition.getCurrentIndex()], 0);//maybe replace with enum GamePlayerUtil.getGuiPlayer().setName(selectedName.getText()); + SoundSystem.instance.changeBackgroundTrack(); Forge.switchScene(GameScene.instance()); }; Forge.setTransitionScreen(new TransitionScreen(runnable, null, false, true, "Generating World...")); diff --git a/forge-gui-mobile/src/forge/adventure/scene/RewardScene.java b/forge-gui-mobile/src/forge/adventure/scene/RewardScene.java index b7b5557c0d6..ede0fa74539 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/RewardScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/RewardScene.java @@ -146,13 +146,15 @@ public class RewardScene extends UIScene { showLootOrDone(); return true; } - switch (type) { - case Shop: - doneButton.setText(Forge.getLocalizer().getMessage("lblLeave")); - break; - case Loot: - doneButton.setText(Forge.getLocalizer().getMessage("lblDone")); - break; + if (type != null) { + switch (type) { + case Shop: + doneButton.setText(Forge.getLocalizer().getMessage("lblLeave")); + break; + case Loot: + doneButton.setText(Forge.getLocalizer().getMessage("lblDone")); + break; + } } shown = false; clearGenerated(); diff --git a/forge-gui-mobile/src/forge/adventure/scene/SaveLoadScene.java b/forge-gui-mobile/src/forge/adventure/scene/SaveLoadScene.java index cbb7ad68221..751058629f9 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/SaveLoadScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/SaveLoadScene.java @@ -21,6 +21,7 @@ import forge.adventure.util.Current; import forge.adventure.world.WorldSave; import forge.adventure.world.WorldSaveHeader; import forge.screens.TransitionScreen; +import forge.sound.SoundSystem; import forge.util.TextUtil; import java.io.File; @@ -217,6 +218,7 @@ public class SaveLoadScene extends UIScene { try { Forge.setTransitionScreen(new TransitionScreen(() -> { if (WorldSave.load(currentSlot)) { + SoundSystem.instance.changeBackgroundTrack(); Forge.switchScene(GameScene.instance()); } else { Forge.clearTransitionScreen(); @@ -236,6 +238,7 @@ public class SaveLoadScene extends UIScene { Current.player().updateDifficulty(Config.instance().getConfigData().difficulties[difficulty.getSelectedIndex()]); Current.player().setWorldPosY((int) (WorldSave.getCurrentSave().getWorld().getData().playerStartPosY * WorldSave.getCurrentSave().getWorld().getData().height * WorldSave.getCurrentSave().getWorld().getTileSize())); Current.player().setWorldPosX((int) (WorldSave.getCurrentSave().getWorld().getData().playerStartPosX * WorldSave.getCurrentSave().getWorld().getData().width * WorldSave.getCurrentSave().getWorld().getTileSize())); + SoundSystem.instance.changeBackgroundTrack(); Forge.switchScene(GameScene.instance()); } else { Forge.clearTransitionScreen(); diff --git a/forge-gui-mobile/src/forge/adventure/scene/StartScene.java b/forge-gui-mobile/src/forge/adventure/scene/StartScene.java index 543b812c223..a2fb1445ed4 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/StartScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/StartScene.java @@ -10,6 +10,7 @@ import forge.adventure.util.Config; import forge.adventure.util.Controls; import forge.adventure.world.WorldSave; import forge.screens.TransitionScreen; +import forge.sound.SoundSystem; /** * First scene after the splash screen @@ -81,6 +82,7 @@ public class StartScene extends UIScene { try { Forge.setTransitionScreen(new TransitionScreen(() -> { if (WorldSave.load(WorldSave.filenameToSlot(lastActiveSave))) { + SoundSystem.instance.changeBackgroundTrack(); Forge.switchScene(GameScene.instance()); } else { Forge.clearTransitionScreen(); diff --git a/forge-gui-mobile/src/forge/adventure/stage/GameHUD.java b/forge-gui-mobile/src/forge/adventure/stage/GameHUD.java index 10861a02376..022fc4ea62d 100644 --- a/forge-gui-mobile/src/forge/adventure/stage/GameHUD.java +++ b/forge-gui-mobile/src/forge/adventure/stage/GameHUD.java @@ -35,6 +35,8 @@ import forge.adventure.world.WorldSave; import forge.deck.Deck; import forge.gui.FThreads; import forge.gui.GuiBase; +import forge.localinstance.properties.ForgePreferences; +import forge.model.FModel; import forge.sound.MusicPlaylist; import forge.sound.SoundSystem; import org.apache.commons.lang3.tuple.Pair; @@ -311,7 +313,7 @@ public class GameHUD extends Stage { SoundSystem.instance.pause(); playAudio(); } else { - stopAudio(); + unloadAudio(); SoundSystem.instance.resume(); // resume World BGM } } @@ -337,26 +339,63 @@ public class GameHUD extends Stage { if (audio != null) { audio.getRight().setLooping(true); audio.getRight().play(); + audio.getRight().setVolume(FModel.getPreferences().getPrefInt(ForgePreferences.FPref.UI_VOL_MUSIC)/100f); } } - public void fadeAudio(float v) { + public void fadeAudio(float value) { if (audio != null) { - audio.getRight().setVolume(v); + audio.getRight().setVolume((FModel.getPreferences().getPrefInt(ForgePreferences.FPref.UI_VOL_MUSIC)*value)/100f); } } - public void stopAudio() { - if (audio != null) { - audio.getRight().stop(); + float fade = 1f; + void fadeIn() { + if (fade >= 1f) + return; + for (int i = 10; i > 1; i--) { + float delay = i * 0.1f; + Timer.schedule(new Timer.Task() { + @Override + public void run() { + fade += 0.1f; + if (fade > 1f) + fade = 1f; + fadeAudio(fade); + } + }, delay); } } + void fadeOut() { + for (int i = 10; i > 1; i--) { + float delay = i * 0.1f; + Timer.schedule(new Timer.Task() { + @Override + public void run() { + fade -= 0.1f; + if (fade < 0.1f) + fade = 0.1f; + fadeAudio(fade); + } + }, delay); + } + } + + public void unloadAudio() { + if (audio != null) { + audio.getRight().setOnCompletionListener(null); + audio.getRight().stop(); + Forge.getAssets().manager().unload(audio.getLeft().path()); + } + audio = null; + currentAudioPlaylist = null; + } private MusicPlaylist currentAudioPlaylist = null; private void setAudio(MusicPlaylist playlist) { if (playlist.equals(currentAudioPlaylist)) return; - stopAudio(); + unloadAudio(); audio = getMusic(playlist); } @@ -399,6 +438,12 @@ public class GameHUD extends Stage { showDialog(); } + public void pauseMusic() { + if (audio != null) { + audio.getRight().pause(); + } + SoundSystem.instance.pause(); + } private void exitDungeonCallback() { hideDialog(true); } @@ -656,8 +701,6 @@ public class GameHUD extends Stage { } } - float fade = 1f; - void changeBGM(MusicPlaylist playlist) { if (!playlist.equals(SoundSystem.instance.getCurrentPlaylist())) { SoundSystem.instance.setBackgroundMusic(playlist); diff --git a/forge-gui-mobile/src/forge/adventure/util/CardUtil.java b/forge-gui-mobile/src/forge/adventure/util/CardUtil.java index 108fa1f2927..1aceb7abb97 100644 --- a/forge-gui-mobile/src/forge/adventure/util/CardUtil.java +++ b/forge-gui-mobile/src/forge/adventure/util/CardUtil.java @@ -648,7 +648,9 @@ public class CardUtil { FileHandle handle = Config.instance().getFile(path); if (handle.exists()) return generateDeck(json.fromJson(GeneratedDeckData.class, handle), starterEdition, discourageDuplicates); - return null; + Deck deck = DeckgenUtil.getRandomOrPreconOrThemeDeck(colors, true, false, true); + System.err.println("Error loading JSON: " + handle.path() + "\nGenerating random deck: "+deck.getName()); + return deck; } diff --git a/forge-gui-mobile/src/forge/adventure/util/Controls.java b/forge-gui-mobile/src/forge/adventure/util/Controls.java index be813e19a87..ebc99cd67b2 100644 --- a/forge-gui-mobile/src/forge/adventure/util/Controls.java +++ b/forge-gui-mobile/src/forge/adventure/util/Controls.java @@ -27,6 +27,8 @@ import com.github.tommyettinger.textra.TypingLabel; import forge.Forge; import forge.adventure.player.AdventurePlayer; import forge.card.ColorSet; +import forge.sound.SoundEffectType; +import forge.sound.SoundSystem; import java.util.function.Function; @@ -52,6 +54,13 @@ public class Controls { static class TextButtonFix extends TextraButton { public TextButtonFix(@Null String text) { super(text == null ? "NULL" : text, Controls.getSkin(), Controls.getTextraFont()); + addListener(new ClickListener(){ + @Override + public void clicked(InputEvent event, float x, float y) { + super.clicked(event, x, y); + SoundSystem.instance.play(SoundEffectType.ButtonPress, false); + } + }); } @Override @@ -74,6 +83,7 @@ public class Controls { getTextraLabel().setWidth(getTextraLabel().layout.getWidth() + (getTextraLabel().style != null && getTextraLabel().style.background != null ? getTextraLabel().style.background.getLeftWidth() + getTextraLabel().style.background.getRightWidth() : 0.0F)); layout(); } + } static public TextraButton newTextButton(String text) { diff --git a/forge-gui-mobile/src/forge/adventure/util/RewardActor.java b/forge-gui-mobile/src/forge/adventure/util/RewardActor.java index 018f4afe026..71ae37acca7 100644 --- a/forge-gui-mobile/src/forge/adventure/util/RewardActor.java +++ b/forge-gui-mobile/src/forge/adventure/util/RewardActor.java @@ -611,7 +611,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb super.act(delta); if (clicked) { if (flipProcess < 1) - flipProcess += delta * 1.5; + flipProcess += delta * 2.4; else flipProcess = 1; diff --git a/forge-gui/res/sound/button_press.mp3 b/forge-gui/res/sound/button_press.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..c85aaa0a801efc92ea9e01e81d02004a932afbf3 GIT binary patch literal 1560 zcmezWd&&_8bP$o5mkt!;2V!;x1~v(X3=}X41*|~<2T{Q_6!01a{6_&myF`2(eO-<9 z3=IreX26^zs-VK;*vP=R1mq5D?OO+662pZ4|9c5A{0}fN{sVeQL8ke+SPKJd6TAI? z1!kUAL9D7u3=;f0k||pZo+SN0%(BLC>4WKt4=zflFz<1qvvJbOu6~ZtOJA3s2sp?pCiK6(IUw7rgMZExhE5GO!$V@rd^)eSTIrd% zm6?1vx#-es(I>834OciA_AzYM5;!#5sHI0hWl_-ey)$*iZ|R5a6}}ihb?t%xuAjiL z|JmsCWlc@WlqV;)>@tgJI5D^LKvu`y2~F!?#Xo6bm0i zi`3%mX_|HAwq=&+DxEv6T5y9_5ersMbYNKG$?n8+Fv-B&W_C6(7V>FoZ(P7iqM69b(alGeqXql_Z>$dL~Whc4&`w9N2W5!CWhV9JcCXlf|og3N!`cxZyIEwjp@ l1%eG4BEYha5(Clng3Q0g49nLH4EDgx!-A%U5-zRH2LPz-3oQTu literal 0 HcmV?d00001 diff --git a/forge-gui/res/sound/coins_drop.mp3 b/forge-gui/res/sound/coins_drop.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..44dbd60e00add196162fbbb45b7c3495f29d344a GIT binary patch literal 11760 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 S|GOjm*TVk?^XI=*|9=7UOPa9& literal 0 HcmV?d00001 diff --git a/forge-gui/res/sound/take_shard.mp3 b/forge-gui/res/sound/take_shard.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..14e6b85b38509ab08ae0ac706acc1ff1c7e01d50 GIT binary patch literal 9984 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