/// <summary> /// Handles the Copy decimal info menu-item. /// </summary> /// <param name="sender"><c><see cref="it_Copy_dec"/></c></param> /// <param name="e"></param> void Click_copy_decimal(object sender, EventArgs e) { string info = HenchControl.GetMasterText(); if (!String.IsNullOrEmpty(info)) { Clipboard.SetText(info); } else { Clipboard.Clear(); } }
/// <summary> /// Handles clicking the PathFeat menuitem. /// Intended to add labels from Feat.2da to the 'featLabels' list. /// </summary> /// <param name="sender"><c><see cref="it_pathFeat"/></c></param> /// <param name="e"></param> void Click_pathFeat(object sender, EventArgs e) { if (!it_pathFeat.Checked) { using (var ofd = new OpenFileDialog()) { ofd.AutoUpgradeEnabled = false; // loL fu.net ofd.Title = "Select Feat.2da"; ofd.Filter = "2da files (*.2da)|*.2da|All files (*.*)|*.*"; ofd.FileName = "feat.2da"; string dir = null; string pfe = Path.Combine(Application.StartupPath, RD_LABELS_CFG); if (File.Exists(pfe)) { dir = File.ReadAllText(pfe); if (Directory.Exists(dir)) { ofd.InitialDirectory = dir; } } if (ofd.ShowDialog(this) == DialogResult.OK) { GropeLabels(ofd.FileName, featLabels, it_pathFeat); if (Type != Type2da.None && featLabels.Count != 0) { HenchControl.SetFeatLabelTexts(); } if (dir != null) { dir = Path.GetDirectoryName(ofd.FileName); File.WriteAllText(pfe, dir); } } } } else { it_pathFeat.Checked = false; featLabels.Clear(); if (Type != Type2da.None) { HenchControl.ClearFeatLabelTexts(); } } }
// /// <summary> // /// Invokes and handles the SetCoreAiVersion inputbox via the Edit. // /// </summary> // /// <param name="sender"></param> // /// <param name="e"></param> // /// <remarks>The version is not really the version of the CoreAI. It's // /// the version of the data of each entry. Apparently it can be updated // /// IG (after info-data has already been cached to the module-object) // /// such that that stale data will be bypassed in favor of the new data. // /// But I haven't looked into it thoroughly.</remarks> // void Click_setCoreAiVersion(object sender, EventArgs e) // { // switch (Type) // { // case Type2da.Spells: // SetInfoVersion_spells(); // // it_ApplyGlobal.Enabled = SpellsChanged.Count != 0; // it_GotoChanged.Enabled = SpellsChanged.Count != 0 || SpareChange(); // break; // // case Type2da.Racial: // SetInfoVersion_racial(); // // it_ApplyGlobal.Enabled = RacesChanged.Count != 0; // it_GotoChanged.Enabled = RacesChanged.Count != 0 || SpareChange(); // break; // // case Type2da.Classes: // SetInfoVersion_classes(); // // it_ApplyGlobal.Enabled = ClassesChanged.Count != 0; // it_GotoChanged.Enabled = ClassesChanged.Count != 0 || SpareChange(); // break; // } // } /// <summary> /// IMPORTANT: This is an interim function that forcefully clears the /// InfoVersion bits. InfoVersion is obsolete in TonyAI 2.3+ - the bits /// have been repurposed. /// </summary> /// <param name="sender"><c><see cref="it_ClearCoreAI"/></c></param> /// <param name="e"></param> /// <remarks>This is implemented only to allow a user to pseudo-update /// his/her TonyAI 2.2 Hench*.2das to be compatible with 2.3+. But the /// repurposed bits would still need to be accounted for ....</remarks> void Click_clearCoreAiVersion(object sender, EventArgs e) { string info2da; switch (Type) { case Type2da.Spells: info2da = "SpellInfo"; break; default: info2da = "Flags"; break; } string info = "This clears the bits @ 0xFF000000 on the " + info2da + " page." + Environment.NewLine + Environment.NewLine + "Are you sure you know what you're doing ..."; using (var ib = new infobox(" Alert", info, "yessir", "no")) { if (ib.ShowDialog(this) == DialogResult.OK) { BypassInfoVersion = true; switch (Type) { case Type2da.Spells: SetInfoVersion_spells("0", true); it_ApplyGlobal.Enabled = SpellsChanged.Count != 0; it_GotoChanged.Enabled = SpellsChanged.Count != 0 || hasSpareChange(); break; case Type2da.Racial: SetInfoVersion_racial("0", true); it_ApplyGlobal.Enabled = RacesChanged.Count != 0; it_GotoChanged.Enabled = RacesChanged.Count != 0 || hasSpareChange(); break; case Type2da.Classes: SetInfoVersion_classes("0", true); it_ApplyGlobal.Enabled = ClassesChanged.Count != 0; it_GotoChanged.Enabled = ClassesChanged.Count != 0 || hasSpareChange(); break; } BypassInfoVersion = false; } } HenchControl.SelectResetButton(); }
/// <summary> /// Handles the Copy binary info menu-item. /// </summary> /// <param name="sender"><c><see cref="it_Copy_bin"/></c></param> /// <param name="e"></param> void Click_copy_binary(object sender, EventArgs e) { string info = HenchControl.GetMasterText(); if (!String.IsNullOrEmpty(info)) { info = Convert.ToString(Int32.Parse(info), 2).PadLeft(32, '0'); Clipboard.SetText(info); } else { Clipboard.Clear(); } }
/// <summary> /// Handles the Copy hexadecimal info menu-item. /// </summary> /// <param name="sender"><c><see cref="it_Copy_hex"/></c></param> /// <param name="e"></param> void Click_copy_hexadecimal(object sender, EventArgs e) { string info = HenchControl.GetMasterText(); if (!String.IsNullOrEmpty(info)) { info = Int32.Parse(info).ToString("x8").Insert(0, "0x"); Clipboard.SetText(info); } else { Clipboard.Clear(); } }
/// <summary> /// The TonyAI 2.3+ sets bits of data by reading it directly from /// Spells.2da - such data is no longer stored in HenchSpells.2da. This /// funct clears those bits auto right after HenchSpells.2da loads. /// </summary> /// <remarks>The controls are disabled on the tabpage. /// /// /// Is based on /// <c><see cref="SetInfoVersion_spells()">SetInfoVersion_spells()</see></c>. /// This funct, however, ASSUMES that nothing in the spell-list has /// changed yet; this funct bypasses a bunch of differ-stuff that /// <c>SetInfoVersion_spells()</c> doesn't.</remarks> void UpdateSpellInfo() { Spell spell; SpellChanged spellchanged; int spellinfo0, spellinfo; int total = Spells.Count; for (int id = 0; id != total; ++id) { spell = Spells[id]; spellinfo0 = spell.spellinfo; spellinfo = spellinfo0 & ~(hc.HENCH_SPELL_INFO_CONCENTRATION_FLAG | hc.HENCH_SPELL_INFO_SPELL_LEVEL_MASK); if (spellinfo != spellinfo0) { if (id == Id) { HenchControl.SetMasterText(spellinfo.ToString()); // firing the TextChanged event takes care of it. } else { spellchanged = new SpellChanged(); spellchanged.targetinfo = spell.targetinfo; spellchanged.effectweight = spell.effectweight; spellchanged.effecttypes = spell.effecttypes; spellchanged.damageinfo = spell.damageinfo; spellchanged.savetype = spell.savetype; spellchanged.savedctype = spell.savedctype; spellchanged.spellinfo = spellinfo; SpellsChanged[id] = spellchanged; // check it spell.differ = control_Spells.SpellDiffer(spell, spellchanged); Spells[id] = spell; Tree.Nodes[id].ForeColor = Color.Crimson; } } } }
/// <summary> /// Handles the GlobalApply it. Applies all altered data to their /// <c>structs</c>. /// </summary> /// <param name="sender"> /// <list type="bullet"> /// <item><c><see cref="it_ApplyGlobal"/></c></item> /// <item><c><see cref="it_Save"/></c></item> /// <item><c><see cref="it_Saveas"/></c></item> /// </list></param> /// <param name="e"></param> /// <remarks>See <c><see cref="Click_apply()">Click_apply()</see></c> to /// apply altered data to only the selected <c>struct</c>.</remarks> void Click_applyGlobal(object sender, EventArgs e) { SetTitleText(); // TitleText will be written again (properly) by Write2daFile() if saved. it_ApplyGlobal.Enabled = false; int total; switch (Type) { case Type2da.Spells: { Spell spell; total = Spells.Count; for (int id = 0; id != total; ++id) { spell = Spells[id]; if (spell.differ != control_Spells.bit_clean) { spell.differ = control_Spells.bit_clean; spell.isChanged = true; // this flag will be cleared by Write2daFile() SpellChanged spellchanged = SpellsChanged[id]; spell.spellinfo = spellchanged.spellinfo; spell.targetinfo = spellchanged.targetinfo; spell.effectweight = spellchanged.effectweight; spell.effecttypes = spellchanged.effecttypes; spell.damageinfo = spellchanged.damageinfo; spell.savetype = spellchanged.savetype; spell.savedctype = spellchanged.savedctype; Spells[id] = spell; SpellsChanged.Remove(id); if (id == Id) // is currently selected tree-node { HenchControl.SetResetColor(DefaultForeColor); AfterSelect_node(null, null); // refresh all displayed data for the current spell jic } Tree.Nodes[id].ForeColor = Color.Blue; } } break; } case Type2da.Racial: { Race race; total = Races.Count; for (int id = 0; id != total; ++id) { race = Races[id]; if (race.differ != control_Racial.bit_clean) { race.differ = control_Racial.bit_clean; race.isChanged = true; // this flag will be cleared by Write2daFile() RaceChanged racechanged = RacesChanged[id]; race.flags = racechanged.flags; race.feat1 = racechanged.feat1; race.feat2 = racechanged.feat2; race.feat3 = racechanged.feat3; race.feat4 = racechanged.feat4; race.feat5 = racechanged.feat5; Races[id] = race; RacesChanged.Remove(id); if (id == Id) // is currently selected tree-node { HenchControl.SetResetColor(DefaultForeColor); AfterSelect_node(null, null); // refresh all displayed data for the current race jic } Tree.Nodes[id].ForeColor = Color.Blue; } } break; } case Type2da.Classes: { Class @class; total = Classes.Count; for (int id = 0; id != total; ++id) { @class = Classes[id]; if (@class.differ != control_Classes.bit_clean) { @class.differ = control_Classes.bit_clean; @class.isChanged = true; // this flag will be cleared by Write2daFile() ClassChanged classchanged = ClassesChanged[id]; @class.flags = classchanged.flags; @class.feat1 = classchanged.feat1; @class.feat2 = classchanged.feat2; @class.feat3 = classchanged.feat3; @class.feat4 = classchanged.feat4; @class.feat5 = classchanged.feat5; @class.feat6 = classchanged.feat6; @class.feat7 = classchanged.feat7; @class.feat8 = classchanged.feat8; @class.feat9 = classchanged.feat9; @class.feat10 = classchanged.feat10; @class.feat11 = classchanged.feat11; Classes[id] = @class; ClassesChanged.Remove(id); if (id == Id) // is currently selected tree-node { HenchControl.SetResetColor(DefaultForeColor); AfterSelect_node(null, null); // refresh all displayed data for the current class jic } Tree.Nodes[id].ForeColor = Color.Blue; } } break; } } }
/// <summary> /// This funct is used only for /// <c><see cref="Click_clearCoreAiVersion()">Click_clearCoreAiVersion()</see></c>. /// </summary> /// <param name="str"></param> /// <param name="all"><c>true</c> to apply version to all classes else /// apply to changed classes only</param> /// <remarks>Used to be a helper for <c>Click_setCoreAiVersion()</c>.</remarks> void SetInfoVersion_classes(string str, bool all) { Class @class; ClassChanged classchanged; int classflags0, classflags, differ; bool dirty; int ver = (Int32.Parse(str) << HENCH_SPELL_INFO_VERSION_SHIFT); // the return from the dialog. int total = Classes.Count; for (int id = 0; id != total; ++id) { @class = Classes[id]; if (dirty = ((@class.differ & control_Classes.bit_flags) != 0)) { classflags0 = ClassesChanged[id].flags; } else if (all || @class.isChanged) { classflags0 = @class.flags; } else { continue; // ignore clean class-structs if !all } if ((classflags0 & hc.HENCH_SPELL_INFO_VERSION_MASK) != ver) { if (!BypassInfoVersion) { classflags = ((classflags0 & ~hc.HENCH_SPELL_INFO_VERSION_MASK) | ver); } else { classflags = (classflags0 & ~hc.HENCH_SPELL_INFO_VERSION_MASK); // wipe version info for TonyAI 2.3+ } if (id == Id) { HenchControl.SetMasterText(classflags.ToString()); // firing the TextChanged event takes care of it. } else { if (dirty) { classchanged = ClassesChanged[id]; } else { classchanged = new ClassChanged(); classchanged.feat1 = @class.feat1; classchanged.feat2 = @class.feat2; classchanged.feat3 = @class.feat3; classchanged.feat4 = @class.feat4; classchanged.feat5 = @class.feat5; classchanged.feat6 = @class.feat6; classchanged.feat7 = @class.feat7; classchanged.feat8 = @class.feat8; classchanged.feat9 = @class.feat9; classchanged.feat10 = @class.feat10; classchanged.feat11 = @class.feat11; } classchanged.flags = classflags; // check it differ = control_Classes.ClassDiffer(@class, classchanged); @class.differ = differ; Classes[id] = @class; Color color; if (differ != control_Classes.bit_clean) { ClassesChanged[id] = classchanged; color = Color.Crimson; } else { ClassesChanged.Remove(id); if (@class.isChanged) { color = Color.Blue; } else { color = DefaultForeColor; } } Tree.Nodes[id].ForeColor = color; } } } }
/// <summary> /// This funct is used only for /// <c><see cref="Click_clearCoreAiVersion()">Click_clearCoreAiVersion()</see></c>. /// </summary> /// <param name="str"></param> /// <param name="all"></param> /// <remarks>Used to be a helper for <c>Click_setCoreAiVersion()</c>.</remarks> void SetInfoVersion_spells(string str, bool all) { Spell spell; SpellChanged spellchanged; int spellinfo0, spellinfo, differ; bool dirty; int ver = Int32.Parse(str) << HENCH_SPELL_INFO_VERSION_SHIFT; // the return from the dialog. int total = Spells.Count; for (int id = 0; id != total; ++id) { spell = Spells[id]; if (dirty = ((spell.differ & control_Spells.bit_spellinfo) != 0)) { spellinfo0 = SpellsChanged[id].spellinfo; } else if (all || spell.isChanged) { spellinfo0 = spell.spellinfo; } else { continue; // ignore clean spell-structs if !all } if (spellinfo0 == 0) { continue; // if spellinfo is blank leave it blank } if ((spellinfo0 & ~hc.HENCH_SPELL_INFO_VERSION_MASK) == 0) // force-clear the version if the rest of spellinfo is blank { spellinfo = 0; } else { spellinfo = ((spellinfo0 & ~hc.HENCH_SPELL_INFO_VERSION_MASK) | ver); } if (spellinfo != spellinfo0) { if (id == Id) { HenchControl.SetMasterText(spellinfo.ToString()); // firing the TextChanged event takes care of it. } else { if (dirty) { spellchanged = SpellsChanged[id]; } else { spellchanged = new SpellChanged(); spellchanged.targetinfo = spell.targetinfo; spellchanged.effectweight = spell.effectweight; spellchanged.effecttypes = spell.effecttypes; spellchanged.damageinfo = spell.damageinfo; spellchanged.savetype = spell.savetype; spellchanged.savedctype = spell.savedctype; } spellchanged.spellinfo = spellinfo; // check it differ = control_Spells.SpellDiffer(spell, spellchanged); spell.differ = differ; Spells[id] = spell; Color color; if (differ != control_Spells.bit_clean) { SpellsChanged[id] = spellchanged; color = Color.Crimson; } else { SpellsChanged.Remove(id); if (spell.isChanged) { color = Color.Blue; } else { color = DefaultForeColor; } } Tree.Nodes[id].ForeColor = color; } } } }
/// <summary> /// This funct is used only for /// <c><see cref="Click_clearCoreAiVersion()">Click_clearCoreAiVersion()</see></c>. /// </summary> /// <param name="str"></param> /// <param name="all"></param> /// <remarks>Used to be a helper for <c>Click_setCoreAiVersion()</c>.</remarks> void SetInfoVersion_racial(string str, bool all) { // NOTE: This will iterate through all changed races even // if an invalid version # is input via the dialog since it // inserts the default version even if there is no other // data in the racialflags-int. Race race; RaceChanged racechanged; int racialflags0, racialflags, differ; bool dirty; int ver = (Int32.Parse(str) << HENCH_SPELL_INFO_VERSION_SHIFT); // the return from the dialog. int total = Races.Count; for (int id = 0; id != total; ++id) { race = Races[id]; if (dirty = ((race.differ & control_Racial.bit_flags) != 0)) { racialflags0 = RacesChanged[id].flags; } else if (all || race.isChanged) { racialflags0 = race.flags; } else { continue; // ignore clean racial-structs if !all } if ((racialflags0 & hc.HENCH_SPELL_INFO_VERSION_MASK) != ver) { if (!BypassInfoVersion) { racialflags = ((racialflags0 & ~hc.HENCH_SPELL_INFO_VERSION_MASK) | ver); } else { racialflags = (racialflags0 & ~hc.HENCH_SPELL_INFO_VERSION_MASK); // wipe version info for TonyAI 2.3+ } if (id == Id) { HenchControl.SetMasterText(racialflags.ToString()); // firing the TextChanged event takes care of it. } else { if (dirty) { racechanged = RacesChanged[id]; } else { racechanged = new RaceChanged(); racechanged.feat1 = race.feat1; racechanged.feat2 = race.feat2; racechanged.feat3 = race.feat3; racechanged.feat4 = race.feat4; racechanged.feat5 = race.feat5; } racechanged.flags = racialflags; // check it differ = control_Racial.RaceDiffer(race, racechanged); race.differ = differ; Races[id] = race; Color color; if (differ != control_Racial.bit_clean) { RacesChanged[id] = racechanged; color = Color.Crimson; } else { RacesChanged.Remove(id); if (race.isChanged) { color = Color.Blue; } else { color = DefaultForeColor; } } Tree.Nodes[id].ForeColor = color; } } } }
/* /// <summary> * /// Updates any InfoVersion for the races when the 2da loads. Ensures * /// that racial-flags has a CoreAI version - RacialFlags always has a * /// Version (unlike spellinfo). * /// NOTE: There won't be any RaceChanged structs at this point although * /// this can create such changed-structs - which is the point. * /// </summary> * void InfoVersionLoad_racial() * { * Race race; * * int total = Races.Count; * for (int id = 0; id != total; ++id) * { * race = Races[id]; * if ((race.flags & HENCH_SPELL_INFO_VERSION_MASK) == 0) * { * var racechanged = new RaceChanged(); * * racechanged.feat1 = race.feat1; * racechanged.feat2 = race.feat2; * racechanged.feat3 = race.feat3; * racechanged.feat4 = race.feat4; * racechanged.feat5 = race.feat5; * * racechanged.flags = (race.flags | HENCH_SPELL_INFO_VERSION); // insert the default version # * * RacesChanged[id] = racechanged; * * race.differ = bit_flags; * Races[id] = race; * * Tree.Nodes[id].ForeColor = Color.Crimson; * } * } * * InfoVersionUpdate = * applyGlobal .Enabled = * gotoNextChanged.Enabled = (RacesChanged.Count != 0); * } */ /// <summary> /// Loads a HenchClasses.2da file. /// </summary> /// <param name="rows"></param> /// <remarks>If the file is not a valid HenchClasses.2da then this /// should hopefully throw an exception at the user. If it doesn't all /// bets are off.</remarks> void Load_HenchClasses(string[] rows) { if (HenchControl != null) { HenchControl.Dispose(); // <- also removes the control from its collection } HenchControl = new control_Classes(this); panel2width = HenchControl.Width; // cache that panel2height = HenchControl.Height; // cache that splitContainer.Panel2.Controls.Add(HenchControl); Type = Type2da.Classes; ClearData(); string[] fields; string field; foreach (string row in rows) { if (!String.IsNullOrEmpty(row)) { fields = row.Split(new char[0], StringSplitOptions.RemoveEmptyEntries); int id; if (Int32.TryParse(fields[0], out id)) // is a valid 2da row { var @class = new Class(); @class.id = id; @class.isChanged = false; @class.differ = control_Classes.bit_clean; int col = 0; if (hasLabels && (field = fields[++col]) != stars) { @class.label = field; } else { @class.label = String.Empty; } if ((field = fields[++col]) != stars) { @class.flags = Int32.Parse(field); } else { @class.flags = 0; } if ((field = fields[++col]) != stars) { @class.feat1 = Int32.Parse(field); } else { @class.feat1 = 0; } if ((field = fields[++col]) != stars) { @class.feat2 = Int32.Parse(field); } else { @class.feat2 = 0; } if ((field = fields[++col]) != stars) { @class.feat3 = Int32.Parse(field); } else { @class.feat3 = 0; } if ((field = fields[++col]) != stars) { @class.feat4 = Int32.Parse(field); } else { @class.feat4 = 0; } if ((field = fields[++col]) != stars) { @class.feat5 = Int32.Parse(field); } else { @class.feat5 = 0; } if ((field = fields[++col]) != stars) { @class.feat6 = Int32.Parse(field); } else { @class.feat6 = 0; } if ((field = fields[++col]) != stars) { @class.feat7 = Int32.Parse(field); } else { @class.feat7 = 0; } if ((field = fields[++col]) != stars) { @class.feat8 = Int32.Parse(field); } else { @class.feat8 = 0; } if ((field = fields[++col]) != stars) { @class.feat9 = Int32.Parse(field); } else { @class.feat9 = 0; } if ((field = fields[++col]) != stars) { @class.feat10 = Int32.Parse(field); } else { @class.feat10 = 0; } if ((field = fields[++col]) != stars) { @class.feat11 = Int32.Parse(field); } else { @class.feat11 = 0; } Classes.Add(@class); // class-structs can now be referenced in the 'Classes' list by their } // - Classes[id] } // - HenchClasses.2da row# } // - ClassID (Classes.2da row#) GrowTree(true); // check if any info-version(s) need to be updated in flags-int. // InfoVersionLoad_classes(); bu_Apply.Text = "apply this class\' data"; tree_Highlight.Text = "highlight blank Class flags nodes"; }
/* /// <summary> * /// Updates any InfoVersion for the spells when the 2da loads. Ensures * /// that spell-info does not have a CoreAI version if there's no other * /// data and that it does have a CoreAI version if there is. * /// NOTE: There won't be any SpellChanged structs at this point although * /// this can create such changed-structs - which is the point. * /// </summary> * void InfoVersionLoad_spells() * { * Spell spell; * * int spellinfo, ver; * * int total = Spells.Count; * for (int id = 0; id != total; ++id) * { * spell = Spells[id]; * spellinfo = spell.spellinfo; * * if (spellinfo != 0) * { * ver = (spellinfo & HENCH_SPELL_INFO_VERSION_MASK); * * if (ver == 0) // insert the default spell-version if it doesn't exist * { * ver = HENCH_SPELL_INFO_VERSION; * } * else if (ver == spellinfo) // clear the spell-version if that's the only data in spellinfo * { * ver = 0; * } * else * continue; * * * spellinfo &= ~HENCH_SPELL_INFO_VERSION_MASK; * spellinfo |= ver; * * var spellchanged = new SpellChanged(); * * spellchanged.targetinfo = spell.targetinfo; * spellchanged.effectweight = spell.effectweight; * spellchanged.effecttypes = spell.effecttypes; * spellchanged.damageinfo = spell.damageinfo; * spellchanged.savetype = spell.savetype; * spellchanged.savedctype = spell.savedctype; * * spellchanged.spellinfo = spellinfo; * * SpellsChanged[id] = spellchanged; * * spell.differ = bit_spellinfo; * Spells[id] = spell; * * Tree.Nodes[id].ForeColor = Color.Crimson; * } * } * * InfoVersionUpdate = * applyGlobal .Enabled = * gotoNextChanged.Enabled = (SpellsChanged.Count != 0); * } */ /// <summary> /// Loads a HenchRacial.2da file. /// </summary> /// <param name="rows"></param> /// <remarks>If the file is not a valid HenchRacial.2da then this should /// hopefully throw an exception at the user. If it doesn't all bets are /// off.</remarks> void Load_HenchRacial(string[] rows) { if (HenchControl != null) { HenchControl.Dispose(); // <- also removes the control from its collection } HenchControl = new control_Racial(this); panel2width = HenchControl.Width; // cache that panel2height = HenchControl.Height; // cache that splitContainer.Panel2.Controls.Add(HenchControl); Type = Type2da.Racial; ClearData(); string[] fields; string field; foreach (string row in rows) { if (!String.IsNullOrEmpty(row)) { fields = row.Split(new char[0], StringSplitOptions.RemoveEmptyEntries); int id; if (Int32.TryParse(fields[0], out id)) // is a valid 2da row { var race = new Race(); race.id = id; race.isChanged = false; race.differ = control_Racial.bit_clean; int col = 0; if (hasLabels && (field = fields[++col]) != stars) { race.label = field; } else { race.label = String.Empty; } if ((field = fields[++col]) != stars) { race.flags = Int32.Parse(field); } else { race.flags = 0; } if ((field = fields[++col]) != stars) { race.feat1 = Int32.Parse(field); } else { race.feat1 = 0; } if ((field = fields[++col]) != stars) { race.feat2 = Int32.Parse(field); } else { race.feat2 = 0; } if ((field = fields[++col]) != stars) { race.feat3 = Int32.Parse(field); } else { race.feat3 = 0; } if ((field = fields[++col]) != stars) { race.feat4 = Int32.Parse(field); } else { race.feat4 = 0; } if ((field = fields[++col]) != stars) { race.feat5 = Int32.Parse(field); } else { race.feat5 = 0; } Races.Add(race); // race-structs can now be referenced in the 'Races' list by their } // - Races[id] } // - HenchRacial.2da row# } // - SubRaceID (RacialSubtypes.2da row#) GrowTree(true); // check if any info-version(s) need to be updated in flags-int. // InfoVersionLoad_racial(); bu_Apply.Text = "apply this race\'s data"; tree_Highlight.Text = "highlight blank Racial flags nodes"; }
/// <summary> /// Loads a HenchSpells.2da file. /// </summary> /// <param name="rows"></param> /// <remarks>If the file is not a valid HenchSpells.2da then this should /// hopefully throw an exception at the user. If it doesn't all bets are /// off.</remarks> void Load_HenchSpells(string[] rows) { if (HenchControl != null) { HenchControl.Dispose(); // <- also removes the control from its collection } HenchControl = new control_Spells(this); panel2width = HenchControl.Width; // cache that panel2height = HenchControl.Height; // cache that splitContainer.Panel2.Controls.Add(HenchControl); Type = Type2da.Spells; ClearData(); string[] fields; string field; foreach (string row in rows) { if (!String.IsNullOrEmpty(row)) { fields = row.Split(new char[0], StringSplitOptions.RemoveEmptyEntries); int id; if (Int32.TryParse(fields[0], out id)) // is a valid 2da row { var spell = new Spell(); spell.id = id; spell.isChanged = false; spell.differ = control_Spells.bit_clean; int col = 0; if (hasLabels && (field = fields[++col]) != stars) { spell.label = field; } else { spell.label = String.Empty; } if ((field = fields[++col]) != stars) { spell.spellinfo = Int32.Parse(field); } else { spell.spellinfo = 0; } if ((field = fields[++col]) != stars) { spell.targetinfo = Int32.Parse(field); } else { spell.targetinfo = 0; } if ((field = fields[++col]) != stars) { spell.effectweight = Single.Parse(field); } else { spell.effectweight = 0.0f; } if ((field = fields[++col]) != stars) { spell.effecttypes = Int32.Parse(field); } else { spell.effecttypes = 0; } if ((field = fields[++col]) != stars) { spell.damageinfo = Int32.Parse(field); } else { spell.damageinfo = 0; } if ((field = fields[++col]) != stars) { spell.savetype = Int32.Parse(field); } else { spell.savetype = 0; } if ((field = fields[++col]) != stars) { spell.savedctype = Int32.Parse(field); } else { spell.savedctype = 0; } Spells.Add(spell); // spell-structs can now be referenced in the 'Spells' list by their } // - Spells[id] } // - HenchSpells.2da row# } // - SpellID (Spells.2da row#) GrowTree(true); // check if any info-version(s) need to be updated in spellinfo-int. // InfoVersionLoad_spells(); bu_Apply.Text = "apply this spell\'s data"; tree_Highlight.Text = "highlight blank SpellInfo nodes"; }