diff --git a/src/ZoneCode/Game/IW4/IW4_Commands.txt b/src/ZoneCode/Game/IW4/IW4_Commands.txt index 20368a74..d74c8e32 100644 --- a/src/ZoneCode/Game/IW4/IW4_Commands.txt +++ b/src/ZoneCode/Game/IW4/IW4_Commands.txt @@ -199,6 +199,7 @@ set condition surfs never; // XModelSurfs use XModelSurfs; +set block XFILE_BLOCK_VIRTUAL; set string name; set count surfs XModelLodInfo::numsurfs; // No this is not a mistake. This is how the game does it. diff --git a/src/ZoneCodeGenerator/Domain/Information/StructureInformation.cs b/src/ZoneCodeGenerator/Domain/Information/StructureInformation.cs index 15210f6b..015dda6c 100644 --- a/src/ZoneCodeGenerator/Domain/Information/StructureInformation.cs +++ b/src/ZoneCodeGenerator/Domain/Information/StructureInformation.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using ZoneCodeGenerator.Domain.FastFileStructure; using ZoneCodeGenerator.Generating.Computations; namespace ZoneCodeGenerator.Domain.Information @@ -28,6 +29,7 @@ namespace ZoneCodeGenerator.Domain.Information public bool ReferenceFromNonDefaultNormalBlockExists { get; set; } public CustomAction PostLoadAction { get; set; } + public FastFileBlock Block { get; set; } public bool IsLeaf { get; set; } diff --git a/src/ZoneCodeGenerator/Generating/Templates/ZoneLoad.stg b/src/ZoneCodeGenerator/Generating/Templates/ZoneLoad.stg index 4ccf7845..805b8421 100644 --- a/src/ZoneCodeGenerator/Generating/Templates/ZoneLoad.stg +++ b/src/ZoneCodeGenerator/Generating/Templates/ZoneLoad.stg @@ -263,12 +263,15 @@ void $LoaderClassName(context.Asset)$::Load_$structure.Type.Name$(const bool atS $else$ assert(atStreamStart);$\\$ $endif$ - $if(structure.IsAsset)$ + $if(structure.Block)$ + + m_stream->PushBlock($structure.Block.Name$);$\\$ + $elseif(structure.IsAsset)$ m_stream->PushBlock($context.DefaultNormalBlock.Name$);$\\$ $endif$ $structure.OrderedMembers:{member | $LoadMemberIfNeedsTreatment(context, structure, member)$}$ - $if(structure.IsAsset)$ + $if(structure.Block || structure.IsAsset)$ m_stream->PopBlock(); $endif$ diff --git a/src/ZoneCodeGenerator/Parsing/CommandFile/Tests/TestSetBlock.cs b/src/ZoneCodeGenerator/Parsing/CommandFile/Tests/TestSetBlock.cs index f8359fe2..74288e35 100644 --- a/src/ZoneCodeGenerator/Parsing/CommandFile/Tests/TestSetBlock.cs +++ b/src/ZoneCodeGenerator/Parsing/CommandFile/Tests/TestSetBlock.cs @@ -1,10 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; -using ZoneCodeGenerator.Domain; -using ZoneCodeGenerator.Domain.FastFileStructure; using ZoneCodeGenerator.Domain.Information; using ZoneCodeGenerator.Parsing.Matching; using ZoneCodeGenerator.Parsing.Matching.Matchers; @@ -21,8 +17,11 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests { new MatcherLiteral("set"), new MatcherLiteral("block"), - new MatcherTypename().WithName(TokenTypeName), - new MatcherName().WithName(TokenBlockEnumEntry), + new MatcherGroupOr(new MatcherGroupAnd( + new MatcherTypename().WithName(TokenTypeName), + new MatcherName().WithName(TokenBlockEnumEntry) + ), + new MatcherName().WithName(TokenBlockEnumEntry)), new MatcherLiteral(";") }; @@ -33,35 +32,52 @@ namespace ZoneCodeGenerator.Parsing.CommandFile.Tests protected override void ProcessMatch(ICommandParserState state) { var typeName = NextMatch(TokenTypeName); - var typeNameParts = typeName.Split(new[] {"::"}, StringSplitOptions.None); - if (state.DataTypeInUse != null && - state.GetMembersFromParts(typeNameParts, state.DataTypeInUse, out var memberList)) + StructureInformation typeInfo; + List memberList; + + if (typeName != null) { - // Do nothing - } - else if (state.GetTypenameAndMembersFromParts(typeNameParts, out _, out memberList)) - { - // Do nothing + var typeNameParts = typeName.Split(new[] { "::" }, StringSplitOptions.None); + if (state.DataTypeInUse != null && + state.GetMembersFromParts(typeNameParts, state.DataTypeInUse, out memberList)) + { + typeInfo = state.DataTypeInUse; + } + else if (state.GetTypenameAndMembersFromParts(typeNameParts, out typeInfo, out memberList)) + { + // Do nothing + } + else + { + throw new TestFailedException($"Could not find type '{typeName}'."); + } } else { - throw new TestFailedException($"Could not find type '{typeName}'."); - } + typeInfo = state.DataTypeInUse; + memberList = new List(); - if (!memberList.Any()) - { - throw new TestFailedException("Must specify a member and not a type when setting a block."); + if(typeInfo == null) + throw new TestFailedException("Must specify a type or member."); } - var member = memberList.Last(); - var blockName = NextMatch(TokenBlockEnumEntry); var block = state.FastFileBlocks .FirstOrDefault(fastFileBlock => fastFileBlock.Name.Equals(blockName)); - member.Block = - block ?? throw new TestFailedException($"Could not find fastfile block with name '{blockName}'"); + if (block == null) + throw new TestFailedException($"Could not find fastfile block with name '{blockName}'"); + + if (memberList.Any()) + { + var member = memberList.Last(); + member.Block = block; + } + else + { + typeInfo.Block = block; + } } } } \ No newline at end of file