public void SetRemaining(List <DataStoreCrystarium> list) { foreach (string name in CharNames) { DataStoreWDB <DataStoreCrystarium, DataStoreIDCrystarium> crystarium = crystariums[name]; foreach (DataStoreCrystarium c in list) { if (!(c.Type == CrystariumType.HP || c.Type == CrystariumType.Strength || c.Type == CrystariumType.Magic)) { int stage = c.Stage; List <DataStoreCrystarium> others; do { others = new CrystariumType[] { CrystariumType.HP, CrystariumType.Strength, CrystariumType.Magic }.SelectMany(t => crystarium.DataList.Where(o => o.Role == c.Role && o.Stage == stage && o.Type == t)).ToList(); stage--; } while (others.Count == 0 && stage > 0); if (others.Count > 0) { DataStoreCrystarium other = others[RandomNum.RandInt(0, others.Count - 1)]; c.Type = other.Type; c.Value = other.Value; } else { c.Type = new CrystariumType[] { CrystariumType.HP, CrystariumType.Strength, CrystariumType.Magic }[RandomNum.RandInt(0, 2)]; c.Value = 1; } } } } }
public void RandomizeCPCosts() { Flags.CrystariumFlags.RandCP.SetRand(); foreach (string name in CharNames) { foreach (Role role in Enum.GetValues(typeof(Role))) { if (role == Role.None) { continue; } List <DataStoreIDCrystarium> roleCrysts = crystariums[name].IdList.Where(id => !id.ID.StartsWith("!") && crystariums[name][id.ID].CPCost > 0 && crystariums[name][id.ID].Role == role).ToList(); for (int stage = 1; stage <= 10; stage++) { List <DataStoreIDCrystarium> crysts = roleCrysts.Where(id => crystariums[name][id.ID].Stage == stage).ToList(); int[] weights = crysts.Select(id => { DataStoreCrystarium c = crystariums[name][id.ID]; int val = 10000; if (Flags.CrystariumFlags.RandCP.ExtraSelected && (c.Type == CrystariumType.Ability || c.Type == CrystariumType.Accessory || c.Type == CrystariumType.ATBLevel || c.Type == CrystariumType.RoleLevel)) { val = (int)(val * 2); } if (id.SubNode > 0) { val = (int)(val * 1.5); } return(val); }).ToArray(); StatValuesWeighted cpCosts = new StatValuesWeighted(weights); Tuple <int, int>[] bounds = Enumerable.Range(0, crysts.Count).Select(i => new Tuple <int, int>(1, Int32.MaxValue)).ToArray(); cpCosts.Randomize(bounds, crysts.Select(id => (long)crystariums[name][id.ID].CPCost).Sum()); for (int i = 0; i < crysts.Count; i++) { crystariums[name][crysts[i].ID].CPCost = (uint)cpCosts[i]; } } } } RandomNum.ClearRand(); }
public void ReloadData(FormMain main) { dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None; dataTable.Clear(); Dictionary <string, DataStoreWDB <DataStoreCrystarium, DataStoreIDCrystarium> > crystariums = new Dictionary <string, DataStoreWDB <DataStoreCrystarium, DataStoreIDCrystarium> >(); Dictionary <string, Dictionary <DataStoreIDCrystarium, string> > displayNames = new Dictionary <string, Dictionary <DataStoreIDCrystarium, string> >(); Dictionary <string, List <DataStoreIDCrystarium> > sorted = new Dictionary <string, List <DataStoreIDCrystarium> >(); foreach (string name in RandoCrystarium.CharNames) { DataStoreWDB <DataStoreCrystarium, DataStoreIDCrystarium> cryst = new DataStoreWDB <DataStoreCrystarium, DataStoreIDCrystarium>(); cryst.LoadData(File.ReadAllBytes($"{main.RandoPath}\\original\\db\\crystal\\crystal_{name}.wdb")); crystariums.Add(name, cryst); displayNames.Add(name, Crystarium.GetDisplayNames(cryst)); List <DataStoreIDCrystarium> sortedList = cryst.IdList.Where(s => !s.ID.StartsWith("!")).ToList(); sortedList.Sort((a, b) => a.CompareTo(b)); sorted.Add(name, sortedList); } crystariums.Keys.ForEach(k => sorted[k].ForEach(s => AddEntry(s, k, crystariums[k][s.ID].Role.ToString(), displayNames[k][s]))); foreach (DataRow row in dataTable.Rows) { DataStoreCrystarium cryst = crystariums[row.Field <string>(1)][row.Field <string>(0)]; string name; if (cryst.Type == CrystariumType.Accessory) { name = "Accessory"; } else if (cryst.Type == CrystariumType.ATBLevel) { name = "ATB Level"; } else if (cryst.Type == CrystariumType.RoleLevel) { name = "Role Level"; } else if (cryst.Type == CrystariumType.Ability) { Ability ability = Abilities.abilities.Find(a => a.GetIDs().Contains(cryst.AbilityName)); if (ability == null) { name = cryst.AbilityName; } else { name = ability.Name; } } else { name = $"{cryst.Type} +{cryst.Value}"; } name += $" ({cryst.CPCost} CP)"; row.SetField <string>(5, name); } dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; }
public void RandomizeAbilities(Dictionary <string, Dictionary <string, Tuple <CrystariumType, Ability, int> > > plando) { foreach (string name in CharNames) { DataStoreWDB <DataStoreCrystarium, DataStoreIDCrystarium> crystarium = crystariums[name]; ShuffleTechniques(plando, name, crystarium); List <Tiered <Ability> > added = new List <Tiered <Ability> >(); List <Ability> obtained = new List <Ability>(); Dictionary <Role, List <int> > startingNodes = new Dictionary <Role, List <int> >(); for (int r = 1; r <= 6; r++) { List <int> startingNodeList = new List <int>(); Role role = (Role)r; if (Flags.CrystariumFlags.NewAbilities) { Flags.CrystariumFlags.NewAbilities.SetRand(); List <int> abilityNodes = new List <int>(); for (int i = 0; i < crystarium.DataList.Count; i++) { DataStoreCrystarium c = crystarium.DataList[i]; if (c.Role == role && c.Type == CrystariumType.Ability && (!plando[name].Keys.Select(k => crystarium[k]).Contains(c) || string.IsNullOrEmpty(c.AbilityName))) { abilityNodes.Add(i); } } abilityNodes.Sort((a, b) => crystarium.DataList[a].Stage.CompareTo(crystarium.DataList[b].Stage)); List <Tiered <Ability> > starting = TieredAbilities.manager.list.Where( t => t.Items.Where(a => a.Role == role && !a.Special && a.Starting && a.HasCharacter(Abilities.GetCharID(name))).Count() > 0 && !added.Contains(t)).ToList(); int maxStage = 1; for (int i = 0; i < abilityNodes.Count; i++) { DataStoreCrystarium cryst = crystarium.DataList[abilityNodes[i]]; if (cryst.Stage < maxStage) { throw new Exception("Went down in stage!"); } maxStage = cryst.Stage; Ability orig = Abilities.GetAbility(name, cryst); if (orig != null && orig.Special) { continue; } if (cryst.CPCost == 0 || (!primaryRoles[name].Contains(role) && cryst.Stage == 1)) { int newI; Ability ability; do { newI = RandomNum.RandInt(0, starting.Count - 1); ability = Flags.CrystariumFlags.NewAbilities.ExtraSelected ? TieredAbilities.GetNoDep(starting[newI]) : TieredAbilities.Get(starting[newI], obtained); } while (ability == null); cryst.AbilityName = ability.GetAbility(Abilities.GetCharID(name)); obtained.Add(ability); added.Add(starting[newI]); starting.RemoveAt(newI); startingNodeList.Add(abilityNodes[i]); abilityNodes.RemoveAt(i); break; } } maxStage = 1; startingNodes.Add(role, startingNodeList); RandomNum.ClearRand(); } } for (int r = 1; r <= 6; r++) { Role role = (Role)r; int maxStage = 1; if (Flags.CrystariumFlags.NewAbilities) { Flags.CrystariumFlags.NewAbilities.SetRand(); List <int> abilityNodes = new List <int>(); for (int i = 0; i < crystarium.DataList.Count; i++) { DataStoreCrystarium c = crystarium.DataList[i]; if (c.Role == role && c.Type == CrystariumType.Ability && !startingNodes[role].Contains(i) && c.CPCost == 0 && (!plando[name].Keys.Select(k => crystarium[k]).Contains(c) || string.IsNullOrEmpty(c.AbilityName))) { abilityNodes.Add(i); } } abilityNodes.Sort((a, b) => crystarium.DataList[a].Stage.CompareTo(crystarium.DataList[b].Stage)); List <Tiered <Ability> > rest = TieredAbilities.manager.list.Where( t => t.Items.Where(a => a.Role == role && !a.Special && a.HasCharacter(Abilities.GetCharID(name))).Count() > 0 && !added.Contains(t)).ToList(); for (int i = 0; i < abilityNodes.Count; i++) { DataStoreCrystarium cryst = crystarium.DataList[abilityNodes[i]]; if (cryst.Stage < maxStage) { throw new Exception("Went down in stage!"); } maxStage = cryst.Stage; Ability orig = Abilities.GetAbility(name, cryst); if (orig != null && orig.Special) { continue; } int newI; Ability ability; do { newI = RandomNum.RandInt(0, rest.Count - 1); ability = Flags.CrystariumFlags.NewAbilities.ExtraSelected ? TieredAbilities.GetNoDep(rest[newI]) : TieredAbilities.Get(rest[newI], obtained); } while (ability == null); cryst.AbilityName = ability.GetAbility(Abilities.GetCharID(name)); obtained.Add(ability); added.Add(rest[newI]); rest.RemoveAt(newI); startingNodes[role].Add(i); } RandomNum.ClearRand(); } } for (int r = 1; r <= 6; r++) { Role role = (Role)r; int maxStage = 1; if (Flags.CrystariumFlags.NewAbilities.FlagEnabled) { Flags.CrystariumFlags.NewAbilities.SetRand(); List <int> abilityNodes = new List <int>(); for (int i = 0; i < crystarium.DataList.Count; i++) { DataStoreCrystarium c = crystarium.DataList[i]; if (c.Role == role && c.Type == CrystariumType.Ability && !startingNodes[role].Contains(i) && c.CPCost > 0 && (!plando[name].Keys.Select(k => crystarium[k]).Contains(c) || string.IsNullOrEmpty(c.AbilityName))) { abilityNodes.Add(i); } } abilityNodes.Sort((a, b) => crystarium.DataList[a].Stage.CompareTo(crystarium.DataList[b].Stage)); List <Tiered <Ability> > rest = TieredAbilities.manager.list.Where( t => t.Items.Where(a => (a.Role == role || Flags.CrystariumFlags.NewAbilities.ExtraSelected) && !a.Special && a.HasCharacter(Abilities.GetCharID(name))).Count() > 0 && !added.Contains(t)).ToList(); for (int i = 0; i < abilityNodes.Count; i++) { DataStoreCrystarium cryst = crystarium.DataList[abilityNodes[i]]; if (cryst.Stage < maxStage) { throw new Exception("Went down in stage!"); } maxStage = cryst.Stage; Ability orig = Abilities.GetAbility(name, cryst); if (orig != null && orig.Special) { continue; } int newI; Ability ability; do { newI = RandomNum.RandInt(0, rest.Count - 1); ability = Flags.CrystariumFlags.NewAbilities.ExtraSelected ? TieredAbilities.GetNoDep(rest[newI]) : TieredAbilities.Get(rest[newI], obtained); } while (ability == null); cryst.AbilityName = ability.GetAbility(Abilities.GetCharID(name)); obtained.Add(ability); added.Add(rest[newI]); rest.RemoveAt(newI); } RandomNum.ClearRand(); } } ShuffleAnyRole(plando, name, crystarium); } }
public override void Randomize(BackgroundWorker backgroundWorker) { Dictionary <int, Dictionary <CrystariumType, List <int> > > statAverages = new Dictionary <int, Dictionary <CrystariumType, List <int> > >(); if (Flags.CrystariumFlags.RandStats) { statAverages = GetStatAverages(); } Dictionary <string, Dictionary <Role, List <Ability> > > nodes = GetNodeAbilities(); Dictionary <string, Dictionary <string, Tuple <CrystariumType, Ability, int> > > plando = CharNames.ToDictionary(c => c, c => new Dictionary <string, Tuple <CrystariumType, Ability, int> >()); if (Flags.CrystariumFlags.ShuffleNodes) { plando = main.crystariumPlando1.GetNodes(); PlaceNodes(plando, nodes); } backgroundWorker.ReportProgress(10); if (Flags.CrystariumFlags.RandStats) { RandomizeStats(plando, statAverages); } backgroundWorker.ReportProgress(20); backgroundWorker.ReportProgress(40); RandomizeAbilities(plando); foreach (string name in CharNames) { foreach (DataStoreIDCrystarium id in crystariums[name].IdList.Where(id => !id.ID.StartsWith("!"))) { DataStoreCrystarium c = crystariums[name][id.ID]; if (c.Type == CrystariumType.Unknown) { throw new Exception($"{name.Substring(0, 1).ToUpper() + name.Substring(1)} {c.Role} Stage {c.Stage} Node {Crystarium.GetDisplayNames(crystariums[name])[id]} is invalid."); } } } backgroundWorker.ReportProgress(70); if (Flags.CrystariumFlags.RandCP) { RandomizeCPCosts(); } if (Tweaks.Boosts.HalfSecondaryCPCost) { ApplyHalfCPCosts(); } if (Tweaks.Boosts.ScaledCPCost) { ApplyScaledCPCosts(); } if (Flags.CrystariumFlags.RandCP) { ApplyPlandoCPCosts(); } backgroundWorker.ReportProgress(100); }
public void PlaceNodes(Dictionary <string, Dictionary <string, Tuple <CrystariumType, Ability, int> > > plando, Dictionary <string, Dictionary <Role, List <Ability> > > nodes) { Flags.CrystariumFlags.ShuffleNodes.SetRand(); foreach (string name in CharNames) { Dictionary <Role, int> origAbilityCounts = Enumerable.Range(1, 6).ToDictionary(i => (Role)i, i => nodes[name][(Role)i].Count); List <DataStoreCrystarium> unknowns = crystariums[name].DataList.Where(c => c.CPCost > 0 && (c.Stage > 1 || primaryRoles[name].Contains(c.Role))).ToList(); foreach (string id in plando[name].Keys) { DataStoreCrystarium cryst = crystariums[name][id]; if (plando[name][id].Item1 == CrystariumType.Ability) { cryst.Type = CrystariumType.Ability; if (plando[name][id].Item2 != null) { cryst.AbilityName = plando[name][id].Item2.GetAbility(Abilities.GetCharID(name)); nodes.Values.ForEach(d => d.Values.ForEach(l => l.RemoveAll(a => a == plando[name][id].Item2))); } else { cryst.AbilityName = ""; } } else { cryst.Type = plando[name][id].Item1; cryst.Value = (ushort)plando[name][id].Item3; } unknowns.Remove(cryst); } List <DataStoreCrystarium> possible; for (Role role = (Role)1; role <= (Role)6; role++) { possible = crystariums[name].IdList.Where( id => !id.ID.StartsWith("!") && !plando[name].Keys.Contains(id.ID)).Select(id => crystariums[name][id.ID]).Where( c => c.Role == role && c.CPCost > 0 && (c.Stage > 1 || primaryRoles[name].Contains(role)) && unknowns.Contains(c)).ToList(); if (possible.Count == 0) { break; } int abilityCount = crystariums[name].DataList.Where(c => c.Role == role && c.Type == CrystariumType.Ability && !unknowns.Contains(c) && (c.Stage > 1 || primaryRoles[name].Contains(role))).Count(); for (int i = 0; i < origAbilityCounts[role] - abilityCount; i++) { if (possible.Count == 0) { break; } int select = RandomNum.RandInt(0, possible.Count - 1); possible[select].Type = CrystariumType.Ability; possible[select].AbilityName = nodes[name][role][i].GetAbility(Abilities.GetCharID(name)); unknowns.Remove(possible[select]); possible.RemoveAt(select); } int roleLevelCount = crystariums[name].DataList.Where(c => c.Role == role && c.Type == CrystariumType.RoleLevel && !unknowns.Contains(c)).Count(); for (int i = 0; i < 4 - roleLevelCount; i++) { if (possible.Count == 0) { break; } int select = RandomNum.RandInt(0, possible.Count - 1); possible[select].Type = CrystariumType.RoleLevel; unknowns.Remove(possible[select]); possible.RemoveAt(select); } } possible = crystariums[name].IdList.Where( id => !id.ID.StartsWith("!") && !plando[name].Keys.Contains(id.ID)).Select(id => crystariums[name][id.ID]).Where( c => c.CPCost > 0 && (c.Stage > 1 || primaryRoles[name].Contains(c.Role)) && unknowns.Contains(c)).ToList(); int atbLevelCount = crystariums[name].DataList.Where(c => c.Type == CrystariumType.ATBLevel && !unknowns.Contains(c)).Count(); if (atbLevelCount == 0 && possible.Count > 0) { int select = RandomNum.RandInt(0, possible.Count - 1); possible[select].Type = CrystariumType.ATBLevel; unknowns.Remove(possible[select]); possible.RemoveAt(select); } int accessoryCount = crystariums[name].DataList.Where(c => c.Type == CrystariumType.Accessory && !unknowns.Contains(c)).Count(); for (int i = 0; i < 3 - accessoryCount; i++) { if (possible.Count == 0) { break; } int select = RandomNum.RandInt(0, possible.Count - 1); possible[select].Type = CrystariumType.Accessory; unknowns.Remove(possible[select]); possible.RemoveAt(select); } SetRemaining(unknowns); } foreach (string name in CharNames) { for (Role role = (Role)1; role <= (Role)6; role++) { for (int stage = 1; stage <= 10; stage++) { List <DataStoreCrystarium> shuffle = crystariums[name].IdList.Where( id => !id.ID.StartsWith("!") && !plando[name].Keys.Contains(id.ID)).Select(id => crystariums[name][id.ID]).Where( c => c.Role == role && c.Stage == stage && c.CPCost > 0 && (c.Stage > 1 || primaryRoles[name].Contains(role))).ToList(); shuffle.Shuffle((a, b) => a.SwapStatsAbilities(b)); } } } RandomNum.ClearRand(); }
public void RandomizeStats(Dictionary <string, Dictionary <string, Tuple <CrystariumType, Ability, int> > > plando, Dictionary <int, Dictionary <CrystariumType, List <int> > > statAverages) { Flags.CrystariumFlags.RandStats.SetRand(); foreach (string name in CharNames) { DataStoreWDB <DataStoreCrystarium, DataStoreIDCrystarium> crystarium = crystariums[name]; Dictionary <int, Dictionary <Role, int> > nodeCounts = new Dictionary <int, Dictionary <Role, int> >(); for (int stage = 1; stage <= 10; stage++) { Dictionary <Role, int> stageDict = new Dictionary <Role, int>(); foreach (Role role in Enum.GetValues(typeof(Role))) { stageDict.Add(role, crystarium.DataList.Where( c => c.Stage == stage && c.Role == role && (c.Type == CrystariumType.HP || c.Type == CrystariumType.Strength || c.Type == CrystariumType.Magic)) .Count()); } nodeCounts.Add(stage, stageDict); } foreach (DataStoreCrystarium c in crystarium.DataList) { if ((c.Type == CrystariumType.Unknown || c.Type == CrystariumType.HP || c.Type == CrystariumType.Strength || c.Type == CrystariumType.Magic) && !plando[name].Keys.Select(k => crystarium[k]).Contains(c)) { c.Type = RandomNum.SelectRandomWeighted( new CrystariumType[] { CrystariumType.HP, CrystariumType.Strength, CrystariumType.Magic }.ToList(), t => Math.Max(1, (int)Math.Pow( t == CrystariumType.HP ? (charMults[name][0] * roleMults[c.Role][0]) : ( t == CrystariumType.Strength ? (charMults[name][1] * roleMults[c.Role][1]) : (charMults[name][2] * roleMults[c.Role][2])), 1 / 1.5d))); if (Tweaks.Challenges.Stats1StageBehind && c.Stage == 1) { c.Value = 0; continue; } int stage = c.Stage + (Tweaks.Challenges.Stats1StageBehind ? -1 : 0); int avgValue = (int)Math.Ceiling(statAverages[c.Stage][c.Type][0] * Math.Pow(1.1, stage * 0.07 + 0.1 + (stage == 10 ? 1.8 : 0))); if (stage == 10 && c.Type == CrystariumType.HP) { avgValue = (int)Math.Ceiling(avgValue * 1.8); } if (primaryRoles[name].Contains(c.Role)) { //avgValue = (int)Math.Ceiling(avgValue * (5 * Math.Exp(-0.5d * nodeCounts[c.Stage][c.Role]) + 1)); } else { avgValue = (int)Math.Ceiling(Math.Log(avgValue, 3) * Math.Pow(avgValue, 0.4)); } if (name != "fang" && c.CPCost == 0) { avgValue = (int)Math.Floor(avgValue * 2.8d); } if (c.Type == CrystariumType.HP) { avgValue = (int)Math.Ceiling(avgValue * 0.9); } if (c.Type == CrystariumType.HP) { c.Value = (ushort)Math.Round(Math.Max(1, (float)avgValue * (float)charMults[name][0] * (float)roleMults[c.Role][0] / 10000f)); } if (c.Type == CrystariumType.Strength) { c.Value = (ushort)Math.Round(Math.Max(1, (float)avgValue * (float)charMults[name][1] * (float)roleMults[c.Role][1] / 10000f)); } if (c.Type == CrystariumType.Magic) { c.Value = (ushort)Math.Round(Math.Max(1, (float)avgValue * (float)charMults[name][2] * (float)roleMults[c.Role][2] / 10000f)); } } } foreach (Role role in Enum.GetValues(typeof(Role))) { List <DataStoreCrystarium> list = crystarium.DataList.Where( c => (c.Type == CrystariumType.HP || c.Type == CrystariumType.Strength || c.Type == CrystariumType.Magic) && c.Role == role && !plando[name].Keys.Select(k => crystarium[k]).Contains(c)).ToList(); for (int i = 0; i < list.Count() / 2; i++) { DataStoreCrystarium c = list[RandomNum.RandInt(0, list.Count - 1)]; int count = list.Where(c2 => c.Type == c2.Type).Count(); float mult = RandomNum.RandInt(100, 100 + (int)Math.Sqrt(Math.Max(0, (count - 1)) * 20)) / 100f; list.ForEach(cr => { if (c.Type == cr.Type && c.Stage == cr.Stage && cr.Value > 0) { cr.Value = (ushort)Math.Max(1, Math.Ceiling(cr == c ? (cr.Value * mult) : (cr.Value / Math.Pow(mult, 1 / 2.2f) - 1))); } }); if (c.Value > 0) { c.Value = (ushort)Math.Max(1, (int)c.Value); } } } } RandomNum.ClearRand(); }