Skip to content

Commit c6e2ba4

Browse files
committed
Merge branch 'staging'
2 parents 4d53561 + 78cfcf3 commit c6e2ba4

26 files changed

+1615
-374
lines changed

CathodeLib/CathodeLib.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
<PackageId>CathodeLib</PackageId>
1010
<Authors>Matt Filer</Authors>
1111
<Description>Provides support for parsing and writing common Alien: Isolation formats from the Cathode engine.</Description>
12-
<Copyright>Matt Filer 2023</Copyright>
13-
<Version>0.6.0</Version>
12+
<Copyright>Matt Filer 2024</Copyright>
13+
<Version>0.7.0</Version>
1414
<OutputType>Library</OutputType>
15-
<AssemblyVersion>0.6.0.0</AssemblyVersion>
15+
<AssemblyVersion>0.7.0.0</AssemblyVersion>
1616
<FileVersion>0.6.0.0</FileVersion>
1717
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
1818
</PropertyGroup>

CathodeLib/Scripts/CATHODE/AlphaLightLevel.cs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,19 @@ override protected bool LoadInternal()
2020
{
2121
using (BinaryReader reader = new BinaryReader(File.OpenRead(_filepath)))
2222
{
23-
//todo
23+
reader.BaseStream.Position += 8;
24+
25+
//NOTE: these values are always 64/128/256 i think
26+
int count = reader.ReadInt32();
27+
int length = reader.ReadInt32() * 8;
28+
29+
for (int i = 0; i < count; i++)
30+
{
31+
Entries.Add(new Entry()
32+
{
33+
content = reader.ReadBytes(length)
34+
});
35+
}
2436
}
2537
return true;
2638
}
@@ -31,8 +43,13 @@ override protected bool SaveInternal()
3143
{
3244
writer.BaseStream.SetLength(0);
3345
Utilities.WriteString("alph", writer);
34-
35-
//todo
46+
writer.Write(0);
47+
writer.Write(Entries.Count);
48+
writer.Write(Entries.Count);
49+
for (int i = 0; i < Entries.Count; i++)
50+
{
51+
writer.Write(Entries[i].content);
52+
}
3653
}
3754
return true;
3855
}
@@ -41,7 +58,7 @@ override protected bool SaveInternal()
4158
#region STRUCTURES
4259
public class Entry
4360
{
44-
//todo
61+
public byte[] content;
4562
};
4663
#endregion
4764
}

CathodeLib/Scripts/CATHODE/CharacterAccessorySets.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ override protected bool LoadInternal()
2525
for (int i = 0; i < entryCount; i++)
2626
{
2727
Entry entry = new Entry();
28-
entry.character = Utilities.Consume<CommandsEntityReference>(reader);
28+
entry.character = Utilities.Consume<EntityHandle>(reader);
2929

3030
entry.shirt_composite = Utilities.Consume<ShortGuid>(reader);
3131
entry.trousers_composite = Utilities.Consume<ShortGuid>(reader);
@@ -112,7 +112,7 @@ override protected bool SaveInternal()
112112
#region STRUCTURES
113113
public class Entry
114114
{
115-
public CommandsEntityReference character = new CommandsEntityReference();
115+
public EntityHandle character = new EntityHandle();
116116

117117
public ShortGuid shirt_composite = ShortGuid.Invalid;
118118
public ShortGuid trousers_composite = ShortGuid.Invalid;

CathodeLib/Scripts/CATHODE/CollisionMaps.cs

Lines changed: 125 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System;
44
using System.Collections.Generic;
55
using System.IO;
6+
using System.Linq;
67
using System.Runtime.InteropServices;
78

89
namespace CATHODE
@@ -19,45 +20,117 @@ public CollisionMaps(string path) : base(path) { }
1920
#region FILE_IO
2021
override protected bool LoadInternal()
2122
{
23+
int minUnk1 = 0;
24+
int minUnk2 = 0;
25+
int minColIn = 0;
26+
27+
List<int> flags = new List<int>();
28+
Dictionary<string, List<string>> dictest = new Dictionary<string, List<string>>();
29+
2230
using (BinaryReader reader = new BinaryReader(File.OpenRead(_filepath)))
2331
{
24-
//It seems typically in this file at the start there are a bunch of empty entries, and then there are a bunch of unresolvable ones, and then a bunch that can be resolved.
32+
//The way this works:
33+
// - First 18 entries are empty
34+
// - Next set of entries are all the COLLISION_MAPPING resources referenced by COMMANDS.PAK (hence they have no composite_instance_id, as the composites aren't instanced - but they do have entity_ids)
35+
// - There are then a few entries that have composite_instance_ids set but I can't resolve them - perhaps these are things from GLOBAL?
36+
// - Then there's all the instanced entities with resolvable composite_instance_ids
2537

2638
reader.BaseStream.Position = 4;
2739
int entryCount = reader.ReadInt32();
2840
for (int i = 0; i < entryCount; i++)
2941
{
3042
Entry entry = new Entry();
31-
entry.unk0 = reader.ReadInt32(); //flag?
32-
entry.Unknown1_ = reader.ReadInt32(); //some sort of index ?
33-
entry.ID = Utilities.Consume<ShortGuid>(reader);
34-
entry.entity = Utilities.Consume<CommandsEntityReference>(reader);
35-
entry.Unknown2_ = reader.ReadInt32(); //Is sometimes -1 and other times a small positive integer. Is this tree node parent?
36-
entry.CollisionHKXEntryIndex = reader.ReadInt16();
37-
entry.Unknown3_ = reader.ReadInt16(); //Most of the time it is -1.
38-
entry.MVRZoneIDThing = reader.ReadInt32();
43+
44+
entry.UnknownFlag = reader.ReadInt32(); //NOTE: if you filter by this value, all the UnknownIndex1s increment, UnknownIndex2s/collision_index don't increment but are grouped by -1s and non -1s,
45+
46+
//todo: compare flag value across levels
47+
48+
entry.UnknownIndex1= reader.ReadInt32();
49+
entry.id = Utilities.Consume<ShortGuid>(reader);
50+
entry.entity = Utilities.Consume<EntityHandle>(reader);
51+
entry.UnknownIndex2 = reader.ReadInt32();
52+
entry.collision_index = reader.ReadInt16();
53+
entry.UnknownValue = reader.ReadInt16();
54+
entry.zone_id = Utilities.Consume<ShortGuid>(reader);
3955
reader.BaseStream.Position += 16;
4056
Entries.Add(entry);
57+
58+
if (minUnk1 < entry.UnknownIndex1)
59+
minUnk1 = entry.UnknownIndex1;
60+
if (minUnk2 < entry.UnknownIndex2)
61+
minUnk2 = entry.UnknownIndex2;
62+
if (minColIn < entry.collision_index)
63+
minColIn = entry.collision_index;
64+
65+
if (!flags.Contains(entry.UnknownFlag))
66+
flags.Add(entry.UnknownFlag);
67+
68+
if (entry.collision_index != -1 && entry.UnknownIndex1 == -1 && entry.UnknownIndex2 == -1 && entry.UnknownValue == -1)
69+
{
70+
string sdfsdf = "";
71+
}
72+
73+
if (entry.UnknownIndex1 == -1 && entry.UnknownIndex2 == -1 && entry.UnknownValue == -1)
74+
{
75+
string sdfsdf = "";
76+
}
77+
78+
string flagBin = BitConverter.ToString(BitConverter.GetBytes(entry.UnknownFlag));
79+
if (!dictest.ContainsKey(flagBin))
80+
dictest.Add(flagBin, new List<string>());
81+
82+
dictest[flagBin].Add(entry.UnknownIndex1 + " -> " + entry.UnknownIndex2 + " -> " + entry.collision_index);
83+
84+
//if (entry.UnknownFlag == -1073737335)
85+
// Console.WriteLine(entry.UnknownIndex1);
86+
87+
//if (entry.UnknownFlag == 4429)
88+
// Console.WriteLine(entry.UnknownIndex1);
89+
90+
//if (entry.UnknownFlag == -1073737405)
91+
// Console.WriteLine(entry.UnknownIndex1);
92+
93+
//Console.WriteLine(entry.UnknownFlag + " -> " + entry.UnknownIndex1 + " -> " + entry.UnknownIndex2 + " -> " + entry.collision_index + " -> " + entry.UnknownValue);
4194
}
4295
}
96+
97+
4398
return true;
4499
}
45100

46101
override protected bool SaveInternal()
47102
{
103+
//composite_instance_id defo has something to do with the ordering as all the zeros are first
104+
105+
106+
//Entries = Entries.OrderBy(o => o.entity.entity_id.ToUInt32() + o.id.ToUInt32()).ThenBy(o => o.entity.composite_instance_id.ToUInt32()).ThenBy(o => o.zone_id.ToUInt32()).ToList();
107+
48108
using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(_filepath)))
49109
{
50110
writer.BaseStream.SetLength(0);
51-
writer.Write(Entries.Count * 80);
111+
writer.Write((Entries.Count) * 48);
52112
writer.Write(Entries.Count);
113+
53114
for (int i = 0; i < Entries.Count; i++)
54115
{
55-
writer.Write(Entries[i].Unknown1_);
56-
Utilities.Write<ShortGuid>(writer, Entries[i].ID);
57-
Utilities.Write<CommandsEntityReference>(writer, Entries[i].entity);
58-
writer.Write(Entries[i].CollisionHKXEntryIndex);
59-
writer.Write(Entries[i].Unknown3_);
60-
writer.Write(Entries[i].MVRZoneIDThing);
116+
//writer.Write(-268427008);
117+
//writer.Write(-1);
118+
119+
writer.Write(Entries[i].UnknownFlag);
120+
writer.Write(Entries[i].UnknownIndex1);
121+
122+
Utilities.Write<ShortGuid>(writer, Entries[i].id);
123+
Utilities.Write<EntityHandle>(writer, Entries[i].entity);
124+
125+
writer.Write(-1);
126+
//writer.Write(Entries[i].UnknownIndex2);
127+
128+
writer.Write((Int16)Entries[i].collision_index);
129+
130+
writer.Write((short)-1);
131+
//writer.Write((Int16)Entries[i].UnknownValue);
132+
133+
Utilities.Write<ShortGuid>(writer, Entries[i].zone_id);
61134
writer.Write(new byte[16]);
62135
}
63136
}
@@ -68,19 +141,47 @@ override protected bool SaveInternal()
68141
#region STRUCTURES
69142
public class Entry
70143
{
71-
public int unk0 = 0; //flags?
72-
public int Unknown1_ = -1; // Is this tree node id?
144+
public ShortGuid id = ShortGuid.Invalid; //This is the name of the entity hashed via ShortGuid
145+
public EntityHandle entity = new EntityHandle();
146+
public ShortGuid zone_id = ShortGuid.Invalid; //this maps the entity to a zone ID. interestingly, this seems to be the point of truth for the zone rendering
73147

74-
public ShortGuid ID = ShortGuid.Invalid; //This is the name of the entity hashed via ShortGuid, as a result, we can't resolve a lot of them. Does the game care about the value? I doubt it. We definitely don't.
148+
public int collision_index = -1; //maps to havok hkx entry
75149

76-
public CommandsEntityReference entity = new CommandsEntityReference();
150+
public int UnknownFlag = 0;
151+
public int UnknownIndex1 = -1;
152+
public int UnknownIndex2 = -1;
153+
public int UnknownValue = -1;
77154

78-
public int Unknown2_= -1; // NOTE: Is sometimes -1 and other times a small positive integer. Is this tree node parent?
155+
public static bool operator ==(Entry x, Entry y)
156+
{
157+
if (ReferenceEquals(x, null)) return ReferenceEquals(y, null);
158+
if (ReferenceEquals(y, null)) return ReferenceEquals(x, null);
159+
if (x.id != y.id) return false;
160+
if (x.zone_id != y.zone_id) return false;
161+
if (x.entity != y.entity) return false;
162+
return true;
163+
}
164+
public static bool operator !=(Entry x, Entry y)
165+
{
166+
return !(x == y);
167+
}
79168

80-
public Int16 CollisionHKXEntryIndex = -1; // NOTE: Most of the time is a positive integer, sometimes -1.
169+
public override bool Equals(object obj)
170+
{
171+
return obj is Entry entry &&
172+
EqualityComparer<ShortGuid>.Default.Equals(id, entry.id) &&
173+
EqualityComparer<EntityHandle>.Default.Equals(entity, entry.entity) &&
174+
EqualityComparer<ShortGuid>.Default.Equals(zone_id, entry.zone_id);
175+
}
81176

82-
public Int16 Unknown3_ = -1; // NOTE: Most of the time it is -1.
83-
public int MVRZoneIDThing = 0; // NOTE: This is CollisionMapThingIDs[0] from alien_mvr_entry
177+
public override int GetHashCode()
178+
{
179+
int hashCode = 1001543423;
180+
hashCode = hashCode * -1521134295 + id.GetHashCode();
181+
hashCode = hashCode * -1521134295 + EqualityComparer<EntityHandle>.Default.GetHashCode(entity);
182+
hashCode = hashCode * -1521134295 + zone_id.GetHashCode();
183+
return hashCode;
184+
}
84185
};
85186
#endregion
86187
}

0 commit comments

Comments
 (0)