diff --git a/src/ZoneCode/Game/T6/T6_Commands.txt b/src/ZoneCode/Game/T6/T6_Commands.txt index ea487a89..bb47feb9 100644 --- a/src/ZoneCode/Game/T6/T6_Commands.txt +++ b/src/ZoneCode/Game/T6/T6_Commands.txt @@ -136,10 +136,10 @@ set count quat 1; // XAnimPartTrans use XAnimPartTrans; set condition u::frames size > 0; -set condition XAnimParts::deltaPart::trans::u::frames::indices::_1 numframes < 256; -set count u::frames::indices::_1 size + 1; -set count u::frames::indices::_2 size + 1; -set condition u::frames::frames::_1 smallTrans == true; +set condition u::frames::indices::_1 XAnimParts::numframes < 256; +set arraysize u::frames::indices::_1 size + 1; +set arraysize u::frames::indices::_2 size + 1; +set condition u::frames::frames::_1 smallTrans; set count u::frames::frames::_1 size + 1; set count u::frames::frames::_2 size + 1; @@ -151,9 +151,9 @@ reorder XAnimPartTransFrames: // XAnimDeltaPartQuat2 use XAnimDeltaPartQuat2; set condition u::frames size > 0; -set condition XAnimParts::deltaPart::quat2::u::frames::indices::_1 numframes < 256; -set count u::frames::indices::_1 size + 1; -set count u::frames::indices::_2 size + 1; +set condition u::frames::indices::_1 XAnimParts::numframes < 256; +set arraysize u::frames::indices::_1 size + 1; +set arraysize u::frames::indices::_2 size + 1; set count u::frames::frames size + 1; // XAnimDeltaPartQuatDataFrames2 @@ -164,9 +164,9 @@ reorder XAnimDeltaPartQuatDataFrames2: // XAnimDeltaPartQuat use XAnimDeltaPartQuat; set condition u::frames size > 0; -set condition XAnimParts::deltaPart::quat::u::frames::indices::_1 numframes < 256; -set count u::frames::indices::_1 size + 1; -set count u::frames::indices::_2 size + 1; +set condition u::frames::indices::_1 XAnimParts::numframes < 256; +set arraysize u::frames::indices::_1 size + 1; +set arraysize u::frames::indices::_2 size + 1; set count u::frames::frames size + 1; // ========================================= diff --git a/src/ZoneCodeGenerator/Domain/ReferenceTypeArray.cs b/src/ZoneCodeGenerator/Domain/ReferenceTypeArray.cs index ef7983c1..b4bf5d16 100644 --- a/src/ZoneCodeGenerator/Domain/ReferenceTypeArray.cs +++ b/src/ZoneCodeGenerator/Domain/ReferenceTypeArray.cs @@ -1,12 +1,17 @@ -namespace ZoneCodeGenerator.Domain +using ZoneCodeGenerator.Domain.Evaluation; + +namespace ZoneCodeGenerator.Domain { class ReferenceTypeArray : ReferenceType { public int ArraySize { get; } + public IEvaluation DynamicSize { get; set; } + public ReferenceTypeArray(int arraySize) { ArraySize = arraySize; + DynamicSize = null; } } } diff --git a/src/ZoneCodeGenerator/Parsing/CommandFile/Impl/CommandParserState.cs b/src/ZoneCodeGenerator/Parsing/CommandFile/Impl/CommandParserState.cs index 9fb7d280..b56fb4ec 100644 --- a/src/ZoneCodeGenerator/Parsing/CommandFile/Impl/CommandParserState.cs +++ b/src/ZoneCodeGenerator/Parsing/CommandFile/Impl/CommandParserState.cs @@ -14,6 +14,7 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Impl class CommandParserState : ICommandParserState { private static readonly ITokenTest[] tests = { + new TestArraySize(), new TestAsset(), new TestBlock(), new TestCondition(), diff --git a/src/ZoneCodeGenerator/Parsing/CommandFile/Tests/TestArraySize.cs b/src/ZoneCodeGenerator/Parsing/CommandFile/Tests/TestArraySize.cs new file mode 100644 index 00000000..16b03dcc --- /dev/null +++ b/src/ZoneCodeGenerator/Parsing/CommandFile/Tests/TestArraySize.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using ZoneCodeGenerator.Domain; +using ZoneCodeGenerator.Domain.Information; +using ZoneCodeGenerator.Parsing.Matching; +using ZoneCodeGenerator.Parsing.Matching.Matchers; +using ZoneCodeGenerator.Parsing.Testing; + +namespace ZoneCodeGenerator.Parsing.CommandFile.Tests +{ + class TestArraySize : TestWithEvaluation + { + private StructureInformation referencedType; + private const string TypeNameToken = "typeName"; + + // set count ; + private static readonly TokenMatcher[] matchers = + { + new MatcherLiteral("set"), + new MatcherLiteral("arraysize"), + new MatcherTypename().WithName(TypeNameToken), + new MatcherWithTag(TagEvaluation), + new MatcherLiteral(";") + }; + + public TestArraySize() : base(matchers) + { + + } + + protected override void ProcessMatch(ICommandParserState state) + { + var typeName = NextMatch(TypeNameToken); + var typeNameParts = typeName.Split(new[] { "::" }, StringSplitOptions.None); + if (state.DataTypeInUse != null + && state.GetMembersFromParts(typeNameParts, state.DataTypeInUse, out var typeMembers)) + { + referencedType = state.DataTypeInUse; + } + else if (state.GetTypenameAndMembersFromParts(typeNameParts, out referencedType, out typeMembers)) + { + // Do nothing + } + else + { + throw new TestFailedException($"Could not find type/members '{typeName}'"); + } + + if (typeMembers == null + || !typeMembers.Any()) + { + throw new TestFailedException("Can only set array size for members and not for types."); + } + + if (!NextTag().Equals(TagEvaluation)) + throw new Exception("Expected first array size tag to be a calculation statement"); + + var evaluation = ProcessEvaluation(state); + + var referencedMember = typeMembers.Last(); + var reference = referencedMember.Member.VariableType.References.OfType() + .FirstOrDefault(); + + if (reference != null) + reference.DynamicSize = evaluation; + else + throw new TestFailedException( + $"Member '{referencedMember.Member.Name}' of type '{referencedMember.Member.VariableType.Type.FullName}' cannot have its array size set due to it not having an array reference"); + } + + protected override IEnumerable GetUsedTypes(ICommandParserState state) + { + if (state.DataTypeInUse != null + && state.DataTypeInUse != referencedType) + { + return new[] { state.DataTypeInUse, referencedType }; + } + + return new[] { referencedType }; + } + } +} \ No newline at end of file