@@ -807,12 +807,12 @@ internal void OnAfterWrite(EndianWriter writer)
807807 /// <summary>
808808 /// The amount of strings in the string table. Usually calculated as (numEntries * 2) + 2.
809809 /// </summary>
810- private uint stringTableCount ;
810+ public uint stringTableCount ;
811811
812812 /// <summary>
813813 /// The size of the string table. Not sure how this is calculated, but the game will fix it itself if it's not right.
814814 /// </summary>
815- private uint stringTableSize ;
815+ public uint stringTableSize ;
816816
817817 private uint externalResourceCount ;
818818
@@ -958,7 +958,7 @@ public void Write(EndianWriter writer)
958958 Symbol . Write ( writer , type ) ;
959959 Symbol . Write ( writer , name ) ;
960960
961- writer . WriteInt32 ( ( entries . Count * 2 ) + 4 ) ;
961+ writer . WriteInt32 ( ( entries . Count + 1 ) * 2 ) ;
962962 writer . WriteUInt32 ( stringTableSize ) ;
963963
964964 if ( revision >= 32 )
@@ -1096,6 +1096,179 @@ public void WriteEntry(EndianWriter writer, DirectoryMeta.Entry entry)
10961096 entry . OnAfterWrite ( writer ) ;
10971097 }
10981098
1099+ /// <summary>
1100+ /// Creates a default-constructed object instance for the given entry type name.
1101+ /// Returns null if the type is not recognized.
1102+ /// </summary>
1103+ public static Object CreateDefaultObject ( string typeName )
1104+ {
1105+ if ( EntryObjectFactories . TryGetValue ( typeName , out var factory ) )
1106+ return factory ( ) ;
1107+ return null ;
1108+ }
1109+
1110+ /// <summary>
1111+ /// Returns a sorted array of all supported entry type names (from EntryReadActions).
1112+ /// </summary>
1113+ public static string [ ] GetSupportedEntryTypes ( )
1114+ {
1115+ var types = EntryReadActions . Keys . ToArray ( ) ;
1116+ Array . Sort ( types , StringComparer . OrdinalIgnoreCase ) ;
1117+ return types ;
1118+ }
1119+
1120+ /// <summary>
1121+ /// Returns a sorted array of all supported directory type names (from DirectoryFactories).
1122+ /// </summary>
1123+ public static string [ ] GetSupportedDirectoryTypes ( )
1124+ {
1125+ var types = DirectoryFactories . Keys . ToArray ( ) ;
1126+ Array . Sort ( types , StringComparer . OrdinalIgnoreCase ) ;
1127+ return types ;
1128+ }
1129+
1130+ /// <summary>
1131+ /// Returns true if the given type name is a directory type (has an entry in DirectoryFactories).
1132+ /// </summary>
1133+ public static bool IsDirectoryType ( string typeName )
1134+ {
1135+ return DirectoryFactories . ContainsKey ( typeName ) ;
1136+ }
1137+
1138+ // factories for constructing various objs
1139+ private static readonly Dictionary < string , Func < Object > > EntryObjectFactories = new Dictionary < string , Func < Object > >
1140+ {
1141+ { "AnimFilter" , ( ) => new RndAnimFilter ( ) } ,
1142+ { "BandButton" , ( ) => new BandButton ( ) } ,
1143+ { "BandCamShot" , ( ) => new BandCamShot ( ) } ,
1144+ { "BandCharDesc" , ( ) => new BandCharDesc ( ) } ,
1145+ { "BandConfiguration" , ( ) => new BandConfiguration ( ) } ,
1146+ { "BandDirector" , ( ) => new BandDirector ( ) } ,
1147+ { "BandFaceDeform" , ( ) => new BandFaceDeform ( ) } ,
1148+ { "BandLabel" , ( ) => new BandLabel ( ) } ,
1149+ { "BandList" , ( ) => new BandList ( ) } ,
1150+ { "BandPlacer" , ( ) => new BandPlacer ( ) } ,
1151+ { "BandScreen" , ( ) => new Object ( ) } ,
1152+ { "BandSongPref" , ( ) => new BandSongPref ( ) } ,
1153+ { "BandSwatch" , ( ) => new BandSwatch ( ) } ,
1154+ { "BustAMoveData" , ( ) => new BustAMoveData ( ) } ,
1155+ { "Cam" , ( ) => new RndCam ( ) } ,
1156+ { "CamShot" , ( ) => new CamShot ( ) } ,
1157+ { "CharClipGroup" , ( ) => new CharClipGroup ( ) } ,
1158+ { "CharCollide" , ( ) => new CharCollide ( ) } ,
1159+ { "CharForeTwist" , ( ) => new CharForeTwist ( ) } ,
1160+ { "CharGuitarString" , ( ) => new CharGuitarString ( ) } ,
1161+ { "CharHair" , ( ) => new CharHair ( ) } ,
1162+ { "CharIKMidi" , ( ) => new CharIKMidi ( ) } ,
1163+ { "CharIKRod" , ( ) => new CharIKRod ( ) } ,
1164+ { "CharInterest" , ( ) => new CharInterest ( ) } ,
1165+ { "CharMeshHide" , ( ) => new CharMeshHide ( ) } ,
1166+ { "CharPosConstraint" , ( ) => new CharPosConstraint ( ) } ,
1167+ { "CharServoBone" , ( ) => new CharServoBone ( ) } ,
1168+ { "CharUpperTwist" , ( ) => new CharUpperTwist ( ) } ,
1169+ { "CharWalk" , ( ) => new CharWalk ( ) } ,
1170+ { "CharWeightSetter" , ( ) => new CharWeightSetter ( ) } ,
1171+ { "CheckboxDisplay" , ( ) => new CheckboxDisplay ( ) } ,
1172+ { "ColorPalette" , ( ) => new ColorPalette ( ) } ,
1173+ { "DancerSequence" , ( ) => new DancerSequence ( ) } ,
1174+ { "Environ" , ( ) => new RndEnviron ( ) } ,
1175+ { "EventTrigger" , ( ) => new EventTrigger ( ) } ,
1176+ { "FileMerger" , ( ) => new FileMerger ( ) } ,
1177+ { "Font" , ( ) => new RndFont ( ) } ,
1178+ { "Fur" , ( ) => new RndFur ( ) } ,
1179+ { "Group" , ( ) => new RndGroup ( ) } ,
1180+ { "View" , ( ) => new RndGroup ( ) } ,
1181+ { "HamBattleData" , ( ) => new HamBattleData ( ) } ,
1182+ { "HamMove" , ( ) => new HamMove ( ) } ,
1183+ { "HamPartyJumpData" , ( ) => new HamPartyJumpData ( ) } ,
1184+ { "HamSupereasyData" , ( ) => new HamSupereasyData ( ) } ,
1185+ { "InlineHelp" , ( ) => new InlineHelp ( ) } ,
1186+ { "InterstitialPanel" , ( ) => new Object ( ) } ,
1187+ { "Light" , ( ) => new RndLight ( ) } ,
1188+ { "Mat" , ( ) => new RndMat ( ) } ,
1189+ { "MatAnim" , ( ) => new RndMatAnim ( ) } ,
1190+ { "Mesh" , ( ) => new RndMesh ( ) } ,
1191+ { "MotionBlur" , ( ) => new RndMotionBlur ( ) } ,
1192+ { "MoveGraph" , ( ) => new MoveGraph ( ) } ,
1193+ { "MsgSource" , ( ) => new Object ( ) } ,
1194+ { "Object" , ( ) => new Object ( ) } ,
1195+ { "OutfitConfig" , ( ) => new OutfitConfig ( ) } ,
1196+ { "P9Director" , ( ) => new P9Director ( ) } ,
1197+ { "ParticleSys" , ( ) => new RndParticleSys ( ) } ,
1198+ { "ParticleSysAnim" , ( ) => new RndParticleSysAnim ( ) } ,
1199+ { "PollAnim" , ( ) => new RndPollAnim ( ) } ,
1200+ { "PostProc" , ( ) => new RndPostProc ( ) } ,
1201+ { "PracticeSection" , ( ) => new PracticeSection ( ) } ,
1202+ { "PropAnim" , ( ) => new RndPropAnim ( ) } ,
1203+ { "RandomGroupSeq" , ( ) => new RandomGroupSeq ( ) } ,
1204+ { "ScreenMask" , ( ) => new RndScreenMask ( ) } ,
1205+ { "Text" , ( ) => new RndText ( ) } ,
1206+ { "Set" , ( ) => new RndSet ( ) } ,
1207+ { "Sfx" , ( ) => new Sfx ( ) } ,
1208+ { "SpotlightDrawer" , ( ) => new SpotlightDrawer ( ) } ,
1209+ { "SynthSample" , ( ) => new SynthSample ( ) } ,
1210+ { "Tex" , ( ) => new RndTex ( ) } ,
1211+ { "TexBlendController" , ( ) => new RndTexBlendController ( ) } ,
1212+ { "TexBlender" , ( ) => new RndTexBlender ( ) } ,
1213+ { "TexMovie" , ( ) => new RndTexMovie ( ) } ,
1214+ { "TrackWidget" , ( ) => new TrackWidget ( ) } ,
1215+ { "TrainerChallenge" , ( ) => new Object ( ) } ,
1216+ { "Trans" , ( ) => new RndTrans ( ) } ,
1217+ { "TransAnim" , ( ) => new RndTransAnim ( ) } ,
1218+ { "TransProxy" , ( ) => new RndTransProxy ( ) } ,
1219+ { "UIButton" , ( ) => new UIButton ( ) } ,
1220+ { "UIColor" , ( ) => new UIColor ( ) } ,
1221+ { "UIComponent" , ( ) => new UIComponent ( ) } ,
1222+ { "UIGuide" , ( ) => new UIGuide ( ) } ,
1223+ { "UILabel" , ( ) => new UILabel ( ) } ,
1224+ { "UIList" , ( ) => new UIList ( ) } ,
1225+ { "UIListArrow" , ( ) => new UIListArrow ( ) } ,
1226+ { "UIListCustom" , ( ) => new UIListCustom ( ) } ,
1227+ { "UIListHighlight" , ( ) => new UIListHighlight ( ) } ,
1228+ { "UIListLabel" , ( ) => new UIListLabel ( ) } ,
1229+ { "UIListMesh" , ( ) => new UIListMesh ( ) } ,
1230+ { "UIListSlot" , ( ) => new UIListSlot ( ) } ,
1231+ { "UIListWidget" , ( ) => new UIListWidget ( ) } ,
1232+ { "UIPanel" , ( ) => new Object ( ) } ,
1233+ { "UIPicture" , ( ) => new UIPicture ( ) } ,
1234+ { "UISlider" , ( ) => new UISlider ( ) } ,
1235+ { "UITrigger" , ( ) => new UITrigger ( ) } ,
1236+ { "Wind" , ( ) => new RndWind ( ) } ,
1237+ { "WorldCrowd" , ( ) => new WorldCrowd ( ) } ,
1238+ { "WorldReflection" , ( ) => new WorldReflection ( ) } ,
1239+ // Directory types (use revision 0 as default)
1240+ { "BandCharacter" , ( ) => new BandCharacter ( 0 ) } ,
1241+ { "BandCrowdMeterDir" , ( ) => new BandCrowdMeterDir ( 0 ) } ,
1242+ { "BandScoreboard" , ( ) => new BandScoreboard ( 0 ) } ,
1243+ { "BandStarDisplay" , ( ) => new BandStarDisplay ( 0 ) } ,
1244+ { "Character" , ( ) => new Character ( 0 ) } ,
1245+ { "CharBoneDir" , ( ) => new CharBoneDir ( 0 ) } ,
1246+ { "CharClipSet" , ( ) => new CharClipSet ( 0 ) } ,
1247+ { "CompositeCharacter" , ( ) => new CompositeCharacter ( 0 ) } ,
1248+ { "CrowdMeterIcon" , ( ) => new BandCrowdMeterIcon ( 0 ) } ,
1249+ { "EndingBonusDir" , ( ) => new RndDir ( 0 ) } ,
1250+ { "GemTrackDir" , ( ) => new GemTrackDir ( 0 ) } ,
1251+ { "MoveDir" , ( ) => new MoveDir ( 0 ) } ,
1252+ { "ObjectDir" , ( ) => new ObjectDir ( 0 ) } ,
1253+ { "OverdriveMeterDir" , ( ) => new OverdriveMeterDir ( 0 ) } ,
1254+ { "OvershellDir" , ( ) => new OvershellDir ( 0 ) } ,
1255+ { "P9Character" , ( ) => new P9Character ( 0 ) } ,
1256+ { "PanelDir" , ( ) => new PanelDir ( 0 ) } ,
1257+ { "PitchArrowDir" , ( ) => new PitchArrowDir ( 0 ) } ,
1258+ { "RndDir" , ( ) => new RndDir ( 0 ) } ,
1259+ { "SkeletonDir" , ( ) => new SkeletonDir ( 0 ) } ,
1260+ { "StreakMeterDir" , ( ) => new StreakMeterDir ( 0 ) } ,
1261+ { "SynthDir" , ( ) => new SynthDir ( 0 ) } ,
1262+ { "TrackDir" , ( ) => new TrackDir ( 0 ) } ,
1263+ { "TrackPanelDir" , ( ) => new TrackPanelDir ( 0 ) } ,
1264+ { "UILabelDir" , ( ) => new UILabelDir ( 0 ) } ,
1265+ { "UIListDir" , ( ) => new UIListDir ( 0 ) } ,
1266+ { "UnisonIcon" , ( ) => new UnisonIcon ( 0 ) } ,
1267+ { "VocalTrackDir" , ( ) => new VocalTrackDir ( 0 ) } ,
1268+ { "WorldDir" , ( ) => new WorldDir ( 0 ) } ,
1269+ { "WorldInstance" , ( ) => new WorldInstance ( 0 ) } ,
1270+ } ;
1271+
10991272 public static DirectoryMeta New ( string type , string name , uint sceneRevision , ushort rootDirRevision )
11001273 {
11011274 DirectoryMeta dir = new DirectoryMeta ( ) ;
0 commit comments