Now you can make real gameplay mods for Torment: Tides of Numenara. Includes example cheat mod. Last updated 6/11/2017 06:00 UTC, v1.0.1.4.
Update for TidesLoaderSounds. Adds "enablesoundevent [identifier]" and "disablesoundevent [identifier]". Starts with PLAY_TTON_SFX_INSPIRINGPRESENCE_FETTLE_LOOP disabled out of the box. Source code in description (read more).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using JetBrains.Annotations;
using TidesLoader;
using UnityEngine;
using Wwise.Internal;
namespace TidesLoaderSounds {
public class SoundCommands : MonoBehaviour {
public static GameObject LoadObject;
public static readonly HashSet<uint> DisabledSoundEvents = new HashSet<uint>() {
(uint)Events.PLAY_TTON_SFX_INSPIRINGPRESENCE_FETTLE_LOOP
};
[UsedImplicitly]
public static void OnTidesLoaderLoad() {
var commands = new Dictionary<string, Action<string[]>> {
{"stopsounds", StopSoundsCommand},
{"stopsoundevent", StopSoundEventCommand},
{"listsoundevents", ListSoundEventsCommand },
{"disablesoundevent", DisableSoundEventCommand },
{"enablesoundevent", EnableSoundEventCommand },
};
foreach (var command in commands) {
TidesLoaderConsole.Commands.Add(command);
}
var obj = new GameObject();
obj.AddComponent<SoundCommands>();
LoadObject = obj;
DontDestroyOnLoad(obj);
obj.GetComponent<SoundCommands>()
.InvokeRepeating("StopDisabledSoundEvents", 0, 3);
}
[UsedImplicitly]
public void StopDisabledSoundEvents() {
var regdGameObjIds = typeof(AkSoundEngine).InvokeMember("RegisteredGameObjects",
BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Static,
null, null, new object[0]) as HashSet<int>;
if (regdGameObjIds == null) return;
var regdGameObjs = FindObjectsOfType<GameObject>()
.Where(gameObj => regdGameObjIds.Contains(gameObj.GetInstanceID()));
foreach (var gameObj in regdGameObjs) {
var numIds = 0u;
var playingIds = new uint[0];
if (AkSoundEngine.GetPlayingIDsFromGameObject(gameObj, ref numIds, playingIds) != AKRESULT.AK_Success || numIds == 0)
continue;
playingIds = new uint[numIds];
if (AkSoundEngine.GetPlayingIDsFromGameObject(gameObj, ref numIds, playingIds) != AKRESULT.AK_Success)
continue;
foreach (var playingId in playingIds) {
var eventId = AkSoundEngine.GetEventIDFromPlayingID(playingId);
foreach (var stopEventId in DisabledSoundEvents) {
if (stopEventId != eventId)
continue;
AkSoundEngine.StopPlayingID(playingId);
}
}
}
}
public static void StopSoundsCommand(string[] inputArgs) {
AkSoundEngine.StopAll();
TidesLoaderConsole.Notify("Active sounds stopped");
}
public static void DisableSoundEventCommand(string[] inputArgs) {
if (inputArgs.Length != 2) {
TidesLoaderConsole.Notify("First argument must be the number or identifier indicating the event to stop sounds for");
return;
}
uint disableEventId;
if (!uint.TryParse(inputArgs[1], out disableEventId)) {
try {
disableEventId = (uint)Enum.Parse(typeof(Events), inputArgs[1], true);
}
catch {
TidesLoaderConsole.Notify($"Event {inputArgs[1]} not found");
return;
}
TidesLoaderConsole.Notify(
DisabledSoundEvents.Add(disableEventId)
? $"Event {inputArgs[1]} sound disabled"
: $"Event {inputArgs[1]} sound already disabled");
}
}
public static void EnableSoundEventCommand(string[] inputArgs) {
if (inputArgs.Length != 2) {
TidesLoaderConsole.Notify("First argument must be the number or identifier indicating the event to stop sounds for");
return;
}
uint disableEventId;
if (!uint.TryParse(inputArgs[1], out disableEventId)) {
try {
disableEventId = (uint)Enum.Parse(typeof(Events), inputArgs[1], true);
}
catch {
TidesLoaderConsole.Notify($"Event {inputArgs[1]} not found");
return;
}
TidesLoaderConsole.Notify(
DisabledSoundEvents.Remove(disableEventId)
? $"Event {inputArgs[1]} sound not disabled"
: $"Event {inputArgs[1]} enabled");
}
}
public static void ListSoundEventsCommand(string[] inputArgs) {
var events = new HashSet<Events>();
var regdGameObjIds = typeof(AkSoundEngine).InvokeMember("RegisteredGameObjects",
BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Static,
null, null, new object[0]) as HashSet<int>;
if (regdGameObjIds != null) {
var regdGameObjs = FindObjectsOfType<GameObject>()
.Where(gameObj => regdGameObjIds.Contains(gameObj.GetInstanceID()));
foreach (var gameObj in regdGameObjs) {
var numIds = 0u;
var playingIds = new uint[0];
if (AkSoundEngine.GetPlayingIDsFromGameObject(gameObj, ref numIds, playingIds) != AKRESULT.AK_Success || numIds == 0)
continue;
playingIds = new uint[numIds];
if (AkSoundEngine.GetPlayingIDsFromGameObject(gameObj, ref numIds, playingIds) != AKRESULT.AK_Success)
continue;
foreach (var playingId in playingIds) {
var eventId = AkSoundEngine.GetEventIDFromPlayingID(playingId);
events.Add((Events)(int)eventId);
}
}
}
TidesLoaderConsole.Notify(string.Join(", ", events.Select(e => Enum.GetName(typeof(Events), e)).ToArray()));
}
public static void StopSoundEventCommand(string[] inputArgs) {
if (inputArgs.Length != 2) {
TidesLoaderConsole.Notify("First argument must be the number or identifier indicating the event to stop sounds for");
return;
}
uint stoppedSoundsCount = 0;
uint stopEventId;
if (!uint.TryParse(inputArgs[1], out stopEventId)) {
try {
stopEventId = (uint)Enum.Parse(typeof(Events), inputArgs[1], true);
}
catch {
TidesLoaderConsole.Notify($"Event {inputArgs[1]} not found");
return;
}
}
var regdGameObjIds = typeof(AkSoundEngine).InvokeMember("RegisteredGameObjects",
BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Static,
null, null, new object[0]) as HashSet<int>;
if (regdGameObjIds != null) {
var regdGameObjs = UnityEngine.Object.FindObjectsOfType<GameObject>()
.Where(gameObj => regdGameObjIds.Contains(gameObj.GetInstanceID()));
foreach (var gameObj in regdGameObjs) {
var numIds = 0u;
var playingIds = new uint[0];
if (AkSoundEngine.GetPlayingIDsFromGameObject(gameObj, ref numIds, playingIds) != AKRESULT.AK_Success || numIds == 0)
continue;
playingIds = new uint[numIds];
if (AkSoundEngine.GetPlayingIDsFromGameObject(gameObj, ref numIds, playingIds) != AKRESULT.AK_Success)
continue;
foreach (var playingId in playingIds) {
var eventId = AkSoundEngine.GetEventIDFromPlayingID(playingId);
if (stopEventId != eventId)
continue;
AkSoundEngine.StopPlayingID(playingId);
//AkSoundEngine.DynamicSequenceClose(playingId);
++stoppedSoundsCount;
}
}
}
TidesLoaderConsole.Notify($"{stoppedSoundsCount} sounds for event {inputArgs[1]} stopped");
}
}
}