Skip to content

Commit

Permalink
Merge branch 'mcc'
Browse files Browse the repository at this point in the history
  • Loading branch information
unk-1 committed Jul 13, 2024
2 parents 612730c + cfdb53d commit 5af8a36
Show file tree
Hide file tree
Showing 31 changed files with 4,851 additions and 5,147 deletions.
27 changes: 14 additions & 13 deletions TagTool/Ai/AiGlobalsDatum.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@

namespace TagTool.Ai
{
[TagStructure(Size = 0x1B0, MaxVersion = CacheVersion.Halo3Retail)]
[TagStructure(Size = 0x1B0, MaxVersion = CacheVersion.Halo3Retail, Platform = CachePlatform.Original)]
[TagStructure(Size = 0xE4, MaxVersion = CacheVersion.Halo3Retail, Platform = CachePlatform.MCC)]
[TagStructure(Size = 0x144, MinVersion = CacheVersion.Halo3ODST, MaxVersion = CacheVersion.HaloOnline700123)]
[TagStructure(Size = 0x1B0, MinVersion = CacheVersion.HaloReach)]
public class AiGlobalsDatum : TagStructure
Expand All @@ -17,36 +18,36 @@ public class AiGlobalsDatum : TagStructure
public float AiInPlayerVehicleOnAiWeaponDamageScale; // [0,1] Global scale on weapon damage made by AI in a vehicle with the player on other AI
public float DangerBroadlyFacing;

[TagField(MaxVersion = CacheVersion.Halo3Retail, Length = 4, Flags = TagFieldFlags.Padding)]
[TagField(MaxVersion = CacheVersion.Halo3Retail, Length = 4, Flags = TagFieldFlags.Padding, Platform = CachePlatform.Original)]
public byte[] Padding;

public float DangerShootingNear;

[TagField(MaxVersion = CacheVersion.Halo3Retail, Length = 4, Flags = TagFieldFlags.Padding)]
[TagField(MaxVersion = CacheVersion.Halo3Retail, Length = 4, Flags = TagFieldFlags.Padding, Platform = CachePlatform.Original)]
public byte[] Padding1;

public float DangerShootingAt;

[TagField(MaxVersion = CacheVersion.Halo3Retail, Length = 4, Flags = TagFieldFlags.Padding)]
[TagField(MaxVersion = CacheVersion.Halo3Retail, Length = 4, Flags = TagFieldFlags.Padding, Platform = CachePlatform.Original)]
public byte[] Padding2;

public float DangerExtremelyClose;

[TagField(MaxVersion = CacheVersion.Halo3Retail, Length = 4, Flags = TagFieldFlags.Padding)]
[TagField(MaxVersion = CacheVersion.Halo3Retail, Length = 4, Flags = TagFieldFlags.Padding, Platform = CachePlatform.Original)]
public byte[] Padding3;

public float DangerShieldDamage;
public float DangerExtendedShieldDamage;
public float DangerBodyDamage;
public float DangerExtendedBodyDamage;

[TagField(MaxVersion = CacheVersion.Halo3Retail, Length = 48, Flags = TagFieldFlags.Padding)]
[TagField(MaxVersion = CacheVersion.Halo3Retail, Length = 48, Flags = TagFieldFlags.Padding, Platform = CachePlatform.Original)]
public byte[] Padding4;

public CachedTag GlobalDialogue;
public StringId DefaultMissionDialogueSoundEffect;

[TagField(MaxVersion = CacheVersion.Halo3Retail, Length = 20, Flags = TagFieldFlags.Padding)]
[TagField(MaxVersion = CacheVersion.Halo3Retail, Length = 20, Flags = TagFieldFlags.Padding, Platform = CachePlatform.Original)]
public byte[] Padding5;

public float JumpDown; // wu/tick
Expand All @@ -56,7 +57,7 @@ public class AiGlobalsDatum : TagStructure
public float JumpStorey; // wu/tick
public float JumpTower; // wu/tick

[TagField(MinVersion = CacheVersion.HaloReach, Length = 0x4, Flags = TagFieldFlags.Padding)]
[TagField(MinVersion = CacheVersion.HaloReach, Length = 0x4, Flags = TagFieldFlags.Padding, Platform = CachePlatform.Original)]
public byte[] ReachPadding;

public float MaxJumpDownHeightDown; // wu
Expand All @@ -66,14 +67,14 @@ public class AiGlobalsDatum : TagStructure
public float MaxJumpDownHeightStorey; // wu
public float MaxJumpDownHeightTower; // wu

[TagField(MinVersion = CacheVersion.HaloReach, Length = 0x4, Flags = TagFieldFlags.Padding)]
[TagField(MinVersion = CacheVersion.HaloReach, Length = 0x4, Flags = TagFieldFlags.Padding, Platform = CachePlatform.Original)]
public byte[] ReachPadding1;

public Bounds<float> HoistStep;
public Bounds<float> HoistCrouch;
public Bounds<float> HoistStand;

[TagField(MaxVersion = CacheVersion.Halo3Retail, Length = 24, Flags = TagFieldFlags.Padding)]
[TagField(MaxVersion = CacheVersion.Halo3Retail, Length = 24, Flags = TagFieldFlags.Padding, Platform = CachePlatform.Original)]
public byte[] Padding6;

public Bounds<float> VaultStep; // wus
Expand All @@ -86,12 +87,12 @@ public class AiGlobalsDatum : TagStructure
[TagField(MinVersion = CacheVersion.Halo3ODST)]
public PathfindingSearchRangeStruct PathfindingSearchRanges;

[TagField(Flags = TagFieldFlags.Padding, Length = 48, MaxVersion = CacheVersion.Halo3Retail)]
[TagField(Flags = TagFieldFlags.Padding, Length = 48, MaxVersion = CacheVersion.Halo3Retail, Platform = CachePlatform.Original)]
public byte[] Padding7;

public List<GravemindPropertyBlock> GravemindProperties;

[TagField(Flags = TagFieldFlags.Padding, Length = 48, MaxVersion = CacheVersion.Halo3Retail)]
[TagField(Flags = TagFieldFlags.Padding, Length = 48, MaxVersion = CacheVersion.Halo3Retail, Platform = CachePlatform.Original)]
public byte[] Padding8;

public float ScaryTargetThreshold; // A target of this scariness is offically considered scary (by combat dialogue, etc.)
Expand Down Expand Up @@ -170,7 +171,7 @@ public class AiGlobalsDatum : TagStructure
[TagField(MinVersion = CacheVersion.HaloReach)]
public Bounds<short> SearchPatternCellsPerShellRange;

[TagField(MinVersion = CacheVersion.HaloReach, Length = 0x2, Flags = TagFieldFlags.Padding)]
[TagField(MinVersion = CacheVersion.HaloReach, Length = 0x2, Flags = TagFieldFlags.Padding, Platform = CachePlatform.Original)]
public byte[] ReachPadding2;

[TagStructure(Size = 0xC)]
Expand Down
4 changes: 3 additions & 1 deletion TagTool/Ai/CharacterPreSearchProperties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@

namespace TagTool.Ai
{
[TagStructure(Size = 0x28)]
[TagStructure(Size = 0x28, Platform = Cache.CachePlatform.Original)]
[TagStructure(Size = 0x24, Platform = Cache.CachePlatform.MCC)]
public class CharacterPreSearchProperties : TagStructure
{
public CharacterPreSearchFlags Flags;
public Bounds<float> MinimumPreSearchTime; // If the min presearch time expires and the target is (actually) outside the min-certainty radius, presearch turns off (seconds)
public Bounds<float> MaximumPreSearchTime; // Presearch turns off after the given time (seconds)
public float MinimumCertaintyRadius;
[TagField(Platform = Cache.CachePlatform.Original)]
public float DEPRECATED;
public Bounds<float> MinimumSuppressingTime; // if the min suppressing time expires and the target is outside the min-certainty radius, suppressing fire turns off
public short MaxSuppressCount; // the maximum number of guys allowed to be suppressing at one time
Expand Down
21 changes: 13 additions & 8 deletions TagTool/Audio/FMOD/FMODSoundCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,32 @@ namespace TagTool.Audio
{
public class FMODSoundCache
{
public DirectoryInfo Directory;
public List<DirectoryInfo> Directories;
public List<FMODSoundBank> LoadedBanks;

public FMODSoundCache(DirectoryInfo directory)
public FMODSoundCache(List<DirectoryInfo> directories)
{
Directory = directory;
Directories = directories;
LoadedBanks = new List<FMODSoundBank>();

LoadBanks();
}

private void LoadBanks()
{
LoadBank("sfx.fsb");
LoadBank("english.fsb");
foreach(var directory in Directories)
{
foreach (var file in directory.EnumerateFiles())
{
if (file.Extension == ".fsb")
LoadBank(file);
}
}
}

private void LoadBank(string name)
private void LoadBank(FileInfo file)
{
var bankFile = new FileInfo(Path.Combine(Directory.FullName, name));
LoadedBanks.Add(new FMODSoundBank(FMODTagTool.System, bankFile));
LoadedBanks.Add(new FMODSoundBank(FMODTagTool.System, file));
}

public int FindSound(uint hash, out FMODSoundBank outBank)
Expand Down
6 changes: 6 additions & 0 deletions TagTool/Audio/FMOD/FMODSoundIndex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using TagTool.Cache;
using TagTool.Commands.Common;
using TagTool.IO;
using TagTool.Serialization;
using TagTool.Tags;
Expand Down Expand Up @@ -46,6 +47,11 @@ private void Load(Stream stream)
while (!reader.EOF)
{
var info = deserializer.Deserialize<FMODSoundInfo>(dataContext);
if(HashLookup.ContainsKey(info.Hash))
{
index++;
continue;
}
HashLookup.Add(info.Hash, index);
Sounds.Add(info);
index++;
Expand Down
8 changes: 5 additions & 3 deletions TagTool/Audio/SoundConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using TagTool.Audio.Converter;
using TagTool.Cache;
using TagTool.Commands;
using TagTool.Commands.Common;
using TagTool.Common;
using TagTool.IO;
using TagTool.Tags.Definitions;
Expand Down Expand Up @@ -204,10 +205,9 @@ public static BlamSound ConvertGen3Sound(GameCache cache, SoundCacheFileGestalt
if (cache.Platform == CachePlatform.MCC)
{
var gen3Cache = (GameCacheGen3)cache;
if (!gen3Cache.FMODSoundCacheDirectory.Exists)
throw new DirectoryNotFoundException($"FMOD sound banks directory not found \"{gen3Cache.FMODSoundCacheDirectory.FullName}\"");

blamSound = GetSoundBankData(cache, soundGestalt, gen3Cache.FMODSoundCache, sound, pitchRangeIndex, permutationIndex);
if(blamSound == null)
throw new Exception($"Failed to find sound {tagName} permutation {permutationIndex} in FMOD sound cache!");
var waveFile = new WAVFile(blamSound.Data, TagTool.Audio.Encoding.GetChannelCount(blamSound.Encoding), blamSound.SampleRate.GetSampleRateHz());
using (var output = new EndianWriter(File.Create(WAVFileName)))
waveFile.Write(output);
Expand Down Expand Up @@ -295,6 +295,8 @@ public static BlamSound GetSoundBankData(GameCache cache, SoundCacheFileGestalt
int permutationGestaltIndex = soundGestalt.GetFirstPermutationIndex(pitchRangeGestaltIndex, cache.Platform) + permutationIndex;
var permutation = soundGestalt.GetPermutation(permutationGestaltIndex);
byte[] permutationData = fmodSoundCache.ExtractSound(permutation.FsbSoundHash);
if (permutationData == null)
return null;
// TODO: update the rest of tagtool to handle pcm32
permutationData = ConvertToPCM16(permutationData);
var blamSound = new BlamSound(sound, permutationGestaltIndex, permutationData, cache.Version, soundGestalt);
Expand Down
2 changes: 1 addition & 1 deletion TagTool/BlamFile/MapVariantGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ private VariantObjectDatum CreateDefaultPlacement()
private bool ObjectIsEarlyMover(CachedTag tag)
{
var obje = _cache.Deserialize(_cacheStream, tag) as GameObject;
return obje.ObjectFlags.HasFlag(ObjectDefinitionFlags.EarlyMoverLocalizedPhysics);
return obje.ObjectFlags.Flags.HasFlag(ObjectFlags.EarlyMoverLocalizedPhysics);
}

public bool ObjectIsForgeable(CachedTag tag)
Expand Down
31 changes: 22 additions & 9 deletions TagTool/Cache/Gen3/GameCacheGen3.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class GameCacheGen3 : GameCache
public TagCacheGen3 TagCacheGen3;
public ResourceCacheGen3 ResourceCacheGen3;

public DirectoryInfo FMODSoundCacheDirectory;
public List<DirectoryInfo> FMODSoundCacheDirectories = new List<DirectoryInfo>();
public FMODSoundCache FMODSoundCache;

public override TagCache TagCache => TagCacheGen3;
Expand Down Expand Up @@ -129,21 +129,34 @@ public GameCacheGen3(MapFile mapFile, FileInfo file)

if(Platform == CachePlatform.MCC)
{
var game = Version.ToString().ToLower().Replace("retail", "");

//check if this is a mod
if (CacheFile.Directory.FullName.Contains("steamapps\\workshop\\content"))
{
string root = CacheFile.Directory.FullName.Split(new string[] { "workshop" }, StringSplitOptions.None)[0];
string game = "halo3";

if (Version != CacheVersion.Halo3Retail)
game = Version.ToString();

FMODSoundCacheDirectory = new DirectoryInfo(Path.Combine(root, "common\\Halo The Master Chief Collection", game, "fmod\\pc"));
DirectoryInfo mainDirectory = new DirectoryInfo(Path.Combine(root, "common\\Halo The Master Chief Collection", game, "fmod\\pc"));
if (mainDirectory.Exists)
FMODSoundCacheDirectories.Add(mainDirectory);
else
new TagToolWarning("Failed to find main mcc sound banks!");
}

DirectoryInfo localDirectory = new DirectoryInfo(Path.Combine(CacheFile.Directory.FullName, "..", "fmod\\pc"));
if (localDirectory.Exists)
FMODSoundCacheDirectories.Add(localDirectory);
else
FMODSoundCacheDirectory = new DirectoryInfo(Path.Combine(CacheFile.Directory.FullName, @"..\fmod\pc"));
{
localDirectory = new DirectoryInfo(Path.Combine(CacheFile.Directory.FullName, "..", game, "fmod\\pc"));
if (localDirectory.Exists)
FMODSoundCacheDirectories.Add(localDirectory);
}

if (FMODSoundCacheDirectories.Count == 0)
new TagToolWarning("Failed to load any FMOD sound banks!");

if(FMODSoundCacheDirectory.Exists)
FMODSoundCache = new FMODSoundCache(FMODSoundCacheDirectory);
FMODSoundCache = new FMODSoundCache(FMODSoundCacheDirectories);
}
}

Expand Down
10 changes: 5 additions & 5 deletions TagTool/Cache/Gen3/StringIdResolverHalo3MCC.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ namespace TagTool.Cache
public class StringIdResolverHalo3MCC : StringIdResolver
{
// These values were figured out through trial-and-error
private static readonly int[] SetOffsets = { 0xD4F, 0x4C4, 0xB3E, 0xBD0, 0xC26, 0xC36, 0xC82, 0xCBB, 0xCCF, 0xCDC };
private const int SetMin = 0x4C4; // Mininum index that goes in a set
private static readonly int[] SetOffsets = { 0xD24, 0x499, 0xB13, 0xBA5, 0xBFB, 0xC0B, 0xC57, 0xC90, 0xCA4, 0xCB1 };
private const int SetMin = 0x499; // Mininum index that goes in a set
private const int SetMax = 0xFFFF; // Maximum index that goes in a set (Not in Halo 3?)

public StringIdResolverHalo3MCC()
{
LengthBits = 8;
SetBits = 8;
IndexBits = 16;
LengthBits = 7;
SetBits = 6;
IndexBits = 19;
}

public override int GetMinSetStringIndex()
Expand Down
2 changes: 1 addition & 1 deletion TagTool/Cache/Gen3/TagCacheGen3.cs
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ public TagCacheGen3(EndianReader reader, MapFile baseMapFile, StringTableGen3 st
}

newReader.SeekTo(stringOffsets[i]);
Instances[i].Name = newReader.ReadNullTerminatedString();
Instances[i].Name = newReader.ReadNullTerminatedString().Replace(' ', '_');
}
}

Expand Down
Loading

0 comments on commit 5af8a36

Please sign in to comment.