internal string CompletionBBCode(CritterType crType, bool partial = false, int columns = 5, bool fonlineRu = false) { string newLine = string.Empty; string tableStart = !fonlineRu ? "[table]" : "[xtable]{tbody}"; string tableEnd = !fonlineRu ? "[/table]" : "{/tbody}[/xtable]"; char tagOpen = !fonlineRu ? '[' : '{'; char tagClose = !fonlineRu ? ']' : '}'; var rawtag = new Func <string, string, string>((id, text) => { string bb = id.Split(new char[] { '=' }, 2)[0]; return('[' + id + ']' + text + "[/" + bb + ']'); }); var tag = new Func <string, string, string>((id, text) => { string bb = id.Split(new char[] { '=' }, 2)[0]; return(tagOpen + id + tagClose + text + tagOpen + '/' + bb + tagClose); }); var td = new Func <string, string>(text => { return(tag("td", text)); }); var tr = new Func <string, string>(text => { return(tag("tr", text)); }); var animComplete = new Func <CritterAnimation, bool>((crAnim) => { foreach (CritterAnimationDir dir in crAnim.Dir) { if (dir == CritterAnimationDir.None) { return(false); } } return(true); }); string result = tableStart + newLine; List <List <string> > groups = new List <List <string> >(); foreach (string groupNameStr in main.ValidAnimationsGroups) { char groupNameChar = groupNameStr[0]; string groupName = main.GetControl(main.AnimGroup + groupNameChar).Text; if (partial && crType[groupNameChar] == null) { continue; } List <string> group = new List <string>(); group.Add(td(rawtag("b", groupName))); List <string> animList = main.ValidAnimations.FindAll(anim => anim.StartsWith(groupNameStr)); foreach (string anim in animList) { string animName = main.GetControl(main.AnimLink + anim).Text; CritterAnimation crAnim = crType[anim]; if (crAnim == null) { group.Add(td(rawtag("color=red", animName))); } else if (animComplete(crAnim)) { group.Add(td(rawtag("color=green", animName))); } else { string[] dirName = { "NE", "E", "SE", "SW", "W", "NW" }; List <string> dirDone = new List <string>(); for (int dir = 0; dir <= 5; dir++) { if (crAnim.Dir[dir] == CritterAnimationDir.None) { continue; } dirDone.Add(dirName[dir]); } animName += " (" + string.Join(",", dirDone.ToArray()) + ")"; group.Add(td(rawtag("color=yellow", animName))); } } groups.Add(group); } int curr = 0; List <string> lines = new List <string>(), rlines = new List <string>(); int linesH = 0; foreach (List <string> group in groups) { if (++curr > columns) { foreach (string line in lines) { result += tr(line) + newLine; } lines.Clear(); curr = 1; linesH = 0; } if (linesH < group.Count) { linesH = group.Count; } if (lines.Count == 0) { lines.AddRange(group); } else { for (int l = 0; l < linesH; l++) { if (l >= lines.Count) { string line = string.Empty; for (int x = 1; x < curr; x++) { line += td(""); } lines.Add(line); } if (l >= group.Count) { group.Add(td("")); } lines[l] += group[l]; } } } foreach (string line in lines) { result += tr(line) + newLine; } result += tableEnd + newLine; return(result); }
internal string CompletionText(CritterType crType, bool part = true) { string result = crType.Name + Environment.NewLine; var groupComplete = new Func <char, bool>((groupName) => { List <string> animList = main.ValidAnimations.FindAll(name => name.StartsWith(groupName.ToString())); foreach (string anim in animList) { CritterAnimation crAnim = crType[anim]; if (crAnim == null || !crAnim.Full) { return(false); } } return(true); }); var animComplete = new Func <CritterAnimation, bool>((crAnim) => { foreach (CritterAnimationDir dir in crAnim.Dir) { if (dir == CritterAnimationDir.None) { return(false); } } return(true); }); List <string> complete = new List <string>(); List <string> partial = new List <string>(); List <string> missing = new List <string>(); bool firstPartial = true; foreach (string groupNameStr in main.ValidAnimationsGroups) { char groupNameChar = groupNameStr[0]; string groupName = main.GetControl(main.AnimGroup + groupNameChar).Text; if (groupComplete(groupNameChar)) { complete.Add(" " + groupName); } else { if (crType[groupNameChar] == null) { if (!part) { missing.Add(" " + groupName); } continue; } if (firstPartial) { firstPartial = false; } else { partial.Add(""); } partial.Add(" " + groupName + ":"); List <CritterAnimation> list = crType.Animations.FindAll(cr => cr.Name.StartsWith(groupNameChar.ToString())); foreach (CritterAnimation crAnim in list) { string animName = " - " + main.GetControl(main.AnimLink + crAnim.Name).Text; if (!animComplete(crAnim)) { string[] dirName = { "NE", "E", "SE", "SW", "W", "NW" }; List <string> dirDone = new List <string>(); for (int dir = 0; dir <= 5; dir++) { if (crAnim.Dir[dir] == CritterAnimationDir.None) { continue; } dirDone.Add(dirName[dir]); } animName += " (" + string.Join(",", dirDone.ToArray()) + ")"; } partial.Add(animName); } } } if (complete.Count > 0) { result += Environment.NewLine; result += "Completed sets:" + Environment.NewLine; foreach (string name in complete) { result += name + Environment.NewLine; } } if (partial.Count > 0) { result += Environment.NewLine; result += "Partial sets:" + Environment.NewLine; foreach (string name in partial) { result += name + Environment.NewLine; } } if (missing.Count > 0) { result += Environment.NewLine; result += "Missing sets:" + Environment.NewLine; foreach (string name in missing) { result += name + Environment.NewLine; } } return(result); }
private void frmChecker_DoWork( object sender, DoWorkEventArgs e ) { BackgroundWorker self = (BackgroundWorker)sender; frmCheckerConfig config = (frmCheckerConfig)e.Argument; List<object> files = new List<object>(); object datafile = null; if( !OpenDatafile( ref datafile, config.Target, config.LoadMode ) ) { self.ReportProgress( (int)ProgressData.ErrorMessage, "Error opening " + config.Target ); return; } switch( config.LoadMode ) { case LoadModeType.Directory: string[] tmpfiles = Directory.GetFiles( config.Target, "*.FR?", SearchOption.TopDirectoryOnly ); foreach( string file in tmpfiles ) { files.Add( Path.GetFileName( file ) ); } break; case LoadModeType.Zip: ZipStorer zip = (ZipStorer)datafile; foreach( ZipStorer.ZipFileEntry entry in zip.ReadCentralDir() ) { if( entry.CompressedSize == 0 ) continue; string filename = entry.FilenameInZip.ToUpper() .Replace( '\\', Path.DirectorySeparatorChar ) .Replace( '/', Path.DirectorySeparatorChar ); if( !filename.StartsWith( ArtCritters ) ) continue; string extmp = Path.GetExtension( filename ); if( extmp.Length != 4 || extmp.Substring( 1, 2 ) != "FR" ) continue; files.Add( entry ); } break; case LoadModeType.Dat: DAT dat = (DAT)datafile; int idx = -1; foreach( DATFile entry in dat.FileList ) { idx++; string filename = entry.Path.ToUpper() .Replace( '\\', Path.DirectorySeparatorChar ) .Replace( '/', Path.DirectorySeparatorChar ); if( !filename.StartsWith( ArtCritters ) ) continue; string extmp = Path.GetExtension( filename ); if( extmp.Length != 4 || extmp.Substring( 1, 2 ) != "FR" ) continue; // DATLib doesn't care about FileIndex, so we have to if( idx == int.MaxValue ) { self.ReportProgress( (int)ProgressData.ErrorMessage, "Too many files" ); CloseDatafile( ref datafile, config.LoadMode ); return; } entry.FileIndex = idx; files.Add( entry ); } break; default: throw new NotSupportedException(); } if( files.Count == 0 ) { self.ReportProgress( (int)ProgressData.ErrorMessage, "No critter animations found" ); CloseDatafile( ref datafile, config.LoadMode ); return; } string baseName = null, animName = null, ext = null; int dir = -1; List<CritterType> crTypesFound = new List<CritterType>(); int currFile = 0, lastPercent = -1, filesCount = files.Count; foreach( object file in files ) { if( self.CancellationPending ) { CloseDatafile( ref datafile, config.LoadMode ); return; } int percent = (++currFile * 100) / filesCount; if( percent != lastPercent ) { lastPercent = percent; self.ReportProgress( percent, "Checking " + config.Target ); } string filename = null; switch( config.LoadMode ) { case LoadModeType.Directory: filename = (string)file; break; case LoadModeType.Zip: ZipStorer.ZipFileEntry zipEntry = (ZipStorer.ZipFileEntry)file; filename = zipEntry.FilenameInZip; break; case LoadModeType.Dat: DATFile datEntry = (DATFile)file; filename = datEntry.FileName; break; default: throw new NotSupportedException(); } if( !ValidNameFRM( filename, ref baseName, ref animName, ref dir, ref ext ) ) continue; CritterType crType = crTypesFound.Find( cr => cr.Name == baseName ); if( crType == null ) { crType = new CritterType( baseName ); crTypesFound.Add( crType ); self.ReportProgress( (int)ProgressData.CritterTypeName, crType.Name ); } if( crType[animName] == null ) { CritterAnimation crAnim = new CritterAnimation( animName ); crType.Animations.Add( crAnim ); } if( ext == "FRM" ) { if( config.FastCheck ) { for( int d = 0; d <= 5; d++ ) { CritterAnimation crAnim = crType[animName]; crAnim.Dir[d] = CritterAnimationDir.Full; if( config.LoadMode == LoadModeType.Zip ) crAnim.ZipData[d] = (ZipStorer.ZipFileEntry)file; else if( config.LoadMode == LoadModeType.Dat ) { DATFile datFile = (DATFile)file; crAnim.DatData[d] = (int)datFile.FileIndex; } } } else // !config.FastCheck { FalloutFRM frm = LoadFRM( datafile, file, config.LoadMode ); for( int d = 0; d <= 5; d++ ) { if( frm != null && frm.GetAnimFrameByDir( d, 1 ) != null ) { CritterAnimation crAnim = crType[animName]; if( crAnim.Dir[d] != CritterAnimationDir.Partial ) crAnim.Dir[d] = CritterAnimationDir.Full; if( config.LoadMode == LoadModeType.Zip ) crAnim.ZipData[d] = (ZipStorer.ZipFileEntry)file; else if( config.LoadMode == LoadModeType.Dat ) crAnim.DatData[d] = (int)((DATFile)file).FileIndex; } } } } else // !ext == "FRM"; { CritterAnimation crAnim = crType[animName]; if( config.FastCheck ) { crAnim.Dir[dir] = CritterAnimationDir.Partial; if( config.LoadMode == LoadModeType.Zip ) crAnim.ZipData[dir] = (ZipStorer.ZipFileEntry)file; else if( config.LoadMode == LoadModeType.Dat ) crAnim.DatData[dir] = (int)((DATFile)file).FileIndex; } else // !config.FastCheck { FalloutFRM frm = LoadFRM( datafile, file, config.LoadMode ); if( frm != null && frm.GetAnimFrameByDir( 0, 1 ) != null ) { crAnim.Dir[dir] = CritterAnimationDir.Partial; if( config.LoadMode == LoadModeType.Zip ) crAnim.ZipData[dir] = (ZipStorer.ZipFileEntry)file; else if( config.LoadMode == LoadModeType.Dat ) crAnim.DatData[dir] = (int)((DATFile)file).FileIndex; } } } object[] data = { baseName, animName, crType[animName] }; self.ReportProgress( (int)ProgressData.CritterAnimation, data ); } currFile = 0; lastPercent = -1; filesCount = crTypesFound.Count; foreach( CritterType crType in crTypesFound ) { int percent = (++currFile * 100) / filesCount; if( percent != lastPercent ) { self.ReportProgress( 100 - percent, "Caching critters preview..." ); } foreach( string anim in ValidAnimations ) { bool found = false; CritterAnimation crAnim = crType[anim]; if( crAnim != null ) { Bitmap[] frm = LoadFRM( datafile, crType, crAnim.Name, config.LoadMode ); if( frm == null ) continue; int[] dirs = { 3, 2, 4, 1, 5, 0 }; foreach( int d in dirs ) { if( frm[d] != null ) { object[] data = { crType.Name, frm[d] }; self.ReportProgress( (int)ProgressData.CritterPreview, data ); found = true; break; } } if( found ) break; } } } CloseDatafile( ref datafile, config.LoadMode ); self.ReportProgress( (int)ProgressData.Finish, config ); }