-
Notifications
You must be signed in to change notification settings - Fork 322
Expand file tree
/
Copy pathUndertaleVariable.cs
More file actions
105 lines (89 loc) · 3.02 KB
/
UndertaleVariable.cs
File metadata and controls
105 lines (89 loc) · 3.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
using System;
using Underanalyzer;
namespace UndertaleModLib.Models;
/// <summary>
/// A variable entry in a GameMaker data file.
/// </summary>
[PropertyChanged.AddINotifyPropertyChangedInterface]
public class UndertaleVariable : UndertaleNamedResource, ISearchable, UndertaleInstruction.IReferencedObject, IDisposable, IGMVariable
{
/// The name of the Variable.
public UndertaleString Name { get; set; }
/// <summary>
/// The type of the variable.
/// </summary>
public UndertaleInstruction.InstanceType InstanceType { get; set; }
/// <summary>
/// TODO: some id?
/// </summary>
public int VarID { get; set; }
/// <inheritdoc />
public uint Occurrences { get; set; }
/// <inheritdoc />
public UndertaleInstruction FirstAddress { get; set; }
/// <inheritdoc />
public int NameStringID { get; set; }
/// <summary>
/// OBSOLETE. This variable is now located at <see cref="NameStringID"/>.
/// </summary>
[Obsolete("This variable has been renamed to NameStringID.")]
public int UnknownChainEndingValue { get => NameStringID; set => NameStringID = value; }
/// <inheritdoc />
public void Serialize(UndertaleWriter writer)
{
writer.WriteUndertaleString(Name);
if (writer.undertaleData.GeneralInfo?.BytecodeVersion >= 15)
{
writer.Write((int)InstanceType);
writer.Write(VarID);
}
writer.Write(Occurrences);
if (Occurrences > 0)
writer.Write(writer.GetAddressForUndertaleObject(FirstAddress));
else
writer.Write(-1);
}
/// <inheritdoc />
public void Unserialize(UndertaleReader reader)
{
Name = reader.ReadUndertaleString();
if (reader.undertaleData.GeneralInfo?.BytecodeVersion >= 15)
{
InstanceType = (UndertaleInstruction.InstanceType)reader.ReadInt32();
VarID = reader.ReadInt32();
}
Occurrences = reader.ReadUInt32();
if (Occurrences > 0)
{
FirstAddress = reader.ReadUndertaleObjectPointer<UndertaleInstruction>();
UndertaleInstruction.ParseReferenceChain(reader, this);
}
else
{
if (reader.ReadInt32() != -1)
throw new Exception("Variable with no occurrences, but still has a first occurrence address");
FirstAddress = null;
}
}
/// <inheritdoc />
public override string ToString()
{
return Name?.Content != null ? Name.Content : "<NULL_VAR_NAME>";
}
/// <inheritdoc/>
public void Dispose()
{
GC.SuppressFinalize(this);
Name = null;
FirstAddress = null;
}
/// <inheritdoc />
public bool SearchMatches(string filter)
{
return Name?.SearchMatches(filter) ?? false;
}
// Underanalyzer implementations
IGMString IGMVariable.Name => Name;
IGMInstruction.InstanceType IGMVariable.InstanceType => (IGMInstruction.InstanceType)InstanceType;
int IGMVariable.VariableID => VarID;
}