Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Introduce sound_info.json and add everything needed to load it #28

Merged
merged 1 commit into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ allprojects {
}
json {
target "src/**/*.json"
targetExclude "src/**/sound_info.json"
gson()
.indentWithSpaces(2)
.sortByKeys()
Expand Down
29 changes: 27 additions & 2 deletions src/main/java/com/wynnvp/wynncraftvp/ModCore.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package com.wynnvp.wynncraftvp;

import com.wynnvp.wynncraftvp.config.VOWAutoConfig;
import com.wynnvp.wynncraftvp.core.Managers;
import com.wynnvp.wynncraftvp.logging.VowLogger;
import com.wynnvp.wynncraftvp.sound.SoundPlayer;
import com.wynnvp.wynncraftvp.sound.SoundsHandler;
Expand All @@ -21,19 +22,23 @@ public class ModCore implements ModInitializer {
public static final String MODID = "wynnvp";
public static final String NAME = "Wynncraft Voice Project";
public static final String VERSION = "1.8.2";

public static boolean inLiveWynnServer = false;
public static boolean isUsingClothApi = false;

public SoundsHandler soundsHandler;
public static ModCore instance;
public SoundPlayer soundPlayer;
public static final Logger LOGGER = LoggerFactory.getLogger("wynnvp");
public static ChatHandler3 chatHandler;

public static VOWAutoConfig config;

public static ChatHandler3 chatHandler;
public static final Logger LOGGER = LoggerFactory.getLogger(MODID);

@Override
public void onInitialize() {
Managers.initialize();

instance = this;
chatHandler = new ChatHandler3();

Expand All @@ -58,4 +63,24 @@ public void onInitialize() {
chatHandler.onTick();
});
}

public static void error(String msg) {
LOGGER.error(msg);
}

public static void error(String msg, Throwable t) {
LOGGER.error(msg, t);
}

public static void warn(String msg) {
LOGGER.warn(msg);
}

public static void warn(String msg, Throwable t) {
LOGGER.warn(msg, t);
}

public static void info(String msg) {
LOGGER.info(msg);
}
}
23 changes: 23 additions & 0 deletions src/main/java/com/wynnvp/wynncraftvp/core/Manager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright © Team-VoW 2024.
* This file is released under AGPLv3. See LICENSE for full license details.
*/
package com.wynnvp.wynncraftvp.core;

import java.util.List;

/**
* Managers are classes that manage a specific aspect of the mod.
* This can be parsing and handling events from an aspect of Minecraft,
* or holding data that is used throughout the mod.
*/
public abstract class Manager {
/**
* Create a manager with certain dependencies.
* @param dependencies The list of managers that this manager depends on.
* A manager only needs to declare dependency on another manager,
* if it is used during initialization.
* (Dependency does not matter when everything is initialized)
*/
protected Manager(List<Manager> dependencies) {}
}
21 changes: 21 additions & 0 deletions src/main/java/com/wynnvp/wynncraftvp/core/Managers.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright © Team-VoW 2024.
* This file is released under AGPLv3. See LICENSE for full license details.
*/
package com.wynnvp.wynncraftvp.core;

import com.wynnvp.wynncraftvp.managers.json.JsonManager;
import com.wynnvp.wynncraftvp.managers.sound.SoundManager;

public final class Managers {
// Managers with no dependencies, kept in alphabetical order
public static final JsonManager Json = new JsonManager();
public static final SoundManager Sound = new SoundManager();

// Managers with dependencies, kept in dependency order (then alphabetical)

// Initialization method for all managers
public static void initialize() {
// no-op, class loading this class will initialize all managers
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright © Team-VoW 2024.
* This file is released under AGPLv3. See LICENSE for full license details.
*/
package com.wynnvp.wynncraftvp.managers.json;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.wynnvp.wynncraftvp.core.Manager;
import com.wynnvp.wynncraftvp.managers.sound.dialogue.DialogueHolder;
import com.wynnvp.wynncraftvp.managers.sound.dialogue.json.DialogueHolderDeserializer;
import java.util.List;

public class JsonManager extends Manager {
public static final Gson GSON = new GsonBuilder()
.registerTypeAdapter(DialogueHolder.class, new DialogueHolderDeserializer())
.enableComplexMapKeySerialization()
.setPrettyPrinting()
.serializeNulls()
.create();

public JsonManager() {
super(List.of());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright © Team-VoW 2024.
* This file is released under AGPLv3. See LICENSE for full license details.
*/
package com.wynnvp.wynncraftvp.managers.sound;

import com.wynnvp.wynncraftvp.ModCore;
import com.wynnvp.wynncraftvp.core.Manager;
import com.wynnvp.wynncraftvp.core.Managers;
import com.wynnvp.wynncraftvp.managers.sound.dialogue.DialogueHolder;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvent;

public class SoundManager extends Manager {
// The path of the file that contains the sound information, currently as a bundled resource
private static final String SOUND_INFO_FILE = "/assets/wynnvp/sound_info.json";

private DialogueHolder dialogueHolder = DialogueHolder.EMPTY;

public SoundManager() {
super(List.of());

// Load the sound info from the json file
loadSounds();

// Register the sounds as sound events
registerSounds();
}

private void loadSounds() {
try (InputStream resourceAsStream = SoundManager.class.getResourceAsStream(SOUND_INFO_FILE)) {
if (resourceAsStream == null) {
ModCore.error("Could not find bundled sound info file, sounds will not be loaded.");
return;
}

DialogueHolder dialogueHolder =
Managers.Json.GSON.fromJson(new InputStreamReader(resourceAsStream), DialogueHolder.class);

if (dialogueHolder == null) {
ModCore.error("Could not load sound info file, sounds will not be loaded.");
return;
}

this.dialogueHolder = dialogueHolder;
ModCore.info("Loaded %d dialogue sounds."
.formatted(dialogueHolder.dialogues().count()));
} catch (Exception e) {
ModCore.error("Error loading sound info file: " + e.getMessage());
}
}

private void registerSounds() {
dialogueHolder.dialogues().forEach(dialogueData -> {
ResourceLocation resourceLocation =
ResourceLocation.fromNamespaceAndPath(ModCore.MODID, dialogueData.dialogueId());
SoundEvent soundEvent = SoundEvent.createVariableRangeEvent(resourceLocation);
Registry.register(BuiltInRegistries.SOUND_EVENT, resourceLocation, soundEvent);
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright © Team-VoW 2024.
* This file is released under AGPLv3. See LICENSE for full license details.
*/
package com.wynnvp.wynncraftvp.managers.sound.dialogue;

import java.util.List;

public record ContextDialogueHolder(List<DialogueData> dialogues) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright © Team-VoW 2024.
* This file is released under AGPLv3. See LICENSE for full license details.
*/
package com.wynnvp.wynncraftvp.managers.sound.dialogue;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.stream.Stream;

public record DialogueContextHolder(LinkedHashMap<String, ContextDialogueHolder> contexts) {
public Stream<DialogueData> dialogues() {
return contexts.values().stream().map(ContextDialogueHolder::dialogues).flatMap(List::stream);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright © Team-VoW 2024.
* This file is released under AGPLv3. See LICENSE for full license details.
*/
package com.wynnvp.wynncraftvp.managers.sound.dialogue;

import java.util.Locale;

/**
* A record to hold all data for a dialogue line.
*
* @param dialogueInfo The unique information about the dialogue
* @param lineInfo The information about the line itself, including the NPC and the line numbers
* @param soundSettings The sound settings for the dialogue
*/
public record DialogueData(
DialogueInfo dialogueInfo, DialogueLineInfo lineInfo, ResolvedDialogueSoundSettings soundSettings) {
/**
* Get the dialogue ID for the dialogue line. This ID is also the file name for the sound file, and the key for the
* sound event.
* @return The dialogue ID
*/
public String dialogueId() {
if (dialogueInfo.fileOverride() != null) {
return dialogueInfo.fileOverride();
}

return ("%s-%s-%s-%d"
.formatted(
dialogueInfo.content(),
dialogueInfo.context(),
lineInfo.npc(),
lineInfo.line().current()))
.toLowerCase(Locale.ROOT);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright © Team-VoW 2024.
* This file is released under AGPLv3. See LICENSE for full license details.
*/
package com.wynnvp.wynncraftvp.managers.sound.dialogue;

import java.util.Optional;
import java.util.TreeMap;
import java.util.stream.Stream;
import org.joml.Vector3f;

public record DialogueHolder(TreeMap<String, DialogueContextHolder> content) {
public static final DialogueHolder EMPTY = new DialogueHolder(new TreeMap<>());

public static final DialogueSoundSettings DEFAULT_SETTINGS = new DialogueSoundSettings() {
@Override
public Optional<Boolean> followPlayer() {
return Optional.of(false);
}

@Override
public Optional<Integer> falloff() {
return Optional.of(0);
}

@Override
public Optional<Vector3f> position() {
return Optional.of(new Vector3f());
}
};

public Stream<DialogueData> dialogues() {
return content.values().stream().flatMap(DialogueContextHolder::dialogues);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright © Team-VoW 2024.
* This file is released under AGPLv3. See LICENSE for full license details.
*/
package com.wynnvp.wynncraftvp.managers.sound.dialogue;

/**
* A record to hold generic information about a dialogue line, which is used to identify the dialogue, making it a key
* for identifying the sound to play.
*
* @param content The content the dialogue is from
* @param context The dialogue context, which identifies the current dialogue (e.g. "caravanCrashed" in tutorial).
* This can also be numbered from 1 to n, in the order the NPC says them
* (mainly used for porting the old names to the new system).
* @param fileOverride The file to use instead of using the default file for the dialogue
*/
public record DialogueInfo(String content, String context, String fileOverride) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright © Team-VoW 2024.
* This file is released under AGPLv3. See LICENSE for full license details.
*/
package com.wynnvp.wynncraftvp.managers.sound.dialogue;

import com.wynnvp.wynncraftvp.utils.type.CappedValue;

/**
* @param npc The NPC the dialogue is from, using the name it appears as text in the game.
* This value is optional and can be null, if the NPC is not known.
* @param line The current/total number of the dialogue in the context.
* (e.g 2/5, if the current dialogue is "[2/5]" in the game)
* This value is optional and can be null, if the line is not specified.
* @param dialogue The voiced dialogue line itself
*/
public record DialogueLineInfo(String npc, CappedValue line, String dialogue) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright © Team-VoW 2024.
* This file is released under AGPLv3. See LICENSE for full license details.
*/
package com.wynnvp.wynncraftvp.managers.sound.dialogue;

import java.util.Optional;
import org.joml.Vector3f;

/**
* An interface for providing sound settings for a dialogue line.
* For more information, see {@link ResolvedDialogueSoundSettings}.
*/
public interface DialogueSoundSettings {
Optional<Boolean> followPlayer();

Optional<Integer> falloff();

Optional<Vector3f> position();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright © Team-VoW 2024.
* This file is released under AGPLv3. See LICENSE for full license details.
*/
package com.wynnvp.wynncraftvp.managers.sound.dialogue;

import org.joml.Vector3f;

/**
* A record to hold the sound settings for a dialogue line.
* This class' fields should match {@link DialogueSoundSettings}.
*
* @param followPlayer Whether the sound should follow the player or not
* @param falloff The falloff of the sound
* @param position The position of the sound
*/
public record ResolvedDialogueSoundSettings(boolean followPlayer, int falloff, Vector3f position) {}
Loading
Loading