private int GetBoundValue(ElementalRes res, bool nextHighest = false) { if (nextHighest) { return((res == ElementalRes.Absorb ? GetBoundValue(res) + 100 : GetBoundValue(res + 1)) - 1); } switch (res) { case ElementalRes.Weakness: return(0); case ElementalRes.Normal: default: return(200); case ElementalRes.Halved: return(525); case ElementalRes.Resistant: return(600); case ElementalRes.Immune: return(650); case ElementalRes.Absorb: return(700); } }
private ElementalRes GetBoundRes(int value) { for (ElementalRes res = ElementalRes.Weakness; res <= ElementalRes.Absorb; res++) { if (value >= GetBoundValue(res) && value <= GetBoundValue(res, true)) { return(res); } } return(ElementalRes.Normal); }
private byte fromElemRes(ElementalRes res) { if (res == ElementalRes.Weakness) { return(1); } if (res == ElementalRes.Normal) { return(0); } return((byte)res); }
private void RandomizeElements(DataStoreEnemy enemy, Enemy enemyID, int modifier, Dictionary <Enemy, Dictionary <Element, ElementalRes> > plandoElementResists) { RandoCrystarium crystarium = randomizers.Get <RandoCrystarium>("Crystarium"); float leaderBias = 0.75f, aiBias = 0.90f; Dictionary <Element, ElementalRes[]> bounds = new Dictionary <Element, ElementalRes[]>(); bounds.Add(Element.Fire, new ElementalRes[] { ElementalRes.Weakness, ElementalRes.Absorb }); bounds.Add(Element.Ice, new ElementalRes[] { ElementalRes.Weakness, ElementalRes.Absorb }); bounds.Add(Element.Thunder, new ElementalRes[] { ElementalRes.Weakness, ElementalRes.Absorb }); bounds.Add(Element.Water, new ElementalRes[] { ElementalRes.Weakness, ElementalRes.Absorb }); bounds.Add(Element.Wind, new ElementalRes[] { ElementalRes.Weakness, ElementalRes.Absorb }); bounds.Add(Element.Earth, new ElementalRes[] { ElementalRes.Weakness, ElementalRes.Absorb }); bounds.Add(Element.Physical, new ElementalRes[] { ElementalRes.Weakness, ElementalRes.Immune }); bounds.Add(Element.Magical, new ElementalRes[] { ElementalRes.Weakness, ElementalRes.Immune }); if (enemyID.ElementProperty == ElementProperty.Bomb) { ((Element[])Enum.GetValues(typeof(Element))).Where(e => enemy[e] == ElementalRes.Absorb).ForEach(e => bounds[e] = new ElementalRes[] { ElementalRes.Absorb, ElementalRes.Absorb }); } if (plandoElementResists.ContainsKey(enemyID)) { plandoElementResists[enemyID].ForEach(pair => bounds[pair.Key] = new ElementalRes[] { pair.Value, pair.Value }); } bool isArmored = enemy.PhysicalRes >= ElementalRes.Resistant && enemy.MagicRes >= ElementalRes.Resistant; ElementalRes possibleMax = isArmored ? ElementalRes.Resistant : ElementalRes.Halved; List <Party> partiesUsed = enemyID.Parties.Select(p => GetParty(p)).ToList(); if (enemyID.ParentData != null && enemyID.ParentData.Parties.Length > 0) { partiesUsed.AddRange(enemyID.ParentData.Parties.Select(p => GetParty(p)).ToList()); } Dictionary <Element, int> typeWeights = Enumerable.Range((int)Element.Physical, 2).ToDictionary(i => (Element)i, i => 10000); Dictionary <Element, int> elementWeights = Enumerable.Range((int)Element.Fire, 6).ToDictionary(i => (Element)i, i => 10000); foreach (Party p in partiesUsed) { Dictionary <Member, List <Ability> > partyAbilities = new Dictionary <Member, List <Ability> >(); for (int i = 0; i < p.Members.Length; i++) { List <Ability> abilities = p.Members[i].GetAbilitiesAvailable(p.MaxStage, crystarium.crystariums[p.Members[i].Character.ToString().ToLower()], i == 0 || p.LeaderSwap, enemyID.ElementProperty == ElementProperty.Skytank).Where(a => a.Elements.Length > 0).SkipWhile(a => (enemyID.ElementProperty == ElementProperty.Bomb ? (a.Elements.Where(e => bounds[e][0] == ElementalRes.Absorb && bounds[e][1] == ElementalRes.Absorb).Count() > 0) : false)).ToList(); partyAbilities.Add(p.Members[i], abilities); } if (enemyID.ElementProperty == ElementProperty.Bomb && partyAbilities.Values.SelectMany(l => l).Count() == 0) { ((Element[])Enum.GetValues(typeof(Element))).Where(e => enemy[e] == ElementalRes.Absorb).ForEach(e => bounds[e] = new ElementalRes[] { ElementalRes.Halved, ElementalRes.Halved }); } List <Ability> physical, magic; physical = partyAbilities.Values.SelectMany(l => l).Where(a => a.Elements.Contains(Element.Physical)).ToList(); magic = partyAbilities.Values.SelectMany(l => l).Where(a => a.Elements.Contains(Element.Magical)).ToList(); if (physical.Count > 0 && magic.Count == 0 && bounds[Element.Physical][1] > possibleMax) { bounds[Element.Physical][1] = possibleMax; } else if (physical.Count == 0 && magic.Count > 0 && bounds[Element.Magical][1] > possibleMax) { bounds[Element.Magical][1] = possibleMax; } int randomRequiredVulnerable = RandomNum.RandInt(0, p.Members.Length); for (int i = 0; i < p.Members.Length; i++) { if (partyAbilities[p.Members[i]].Count == 0) { continue; } float bias = (i == 0 ? leaderBias : aiBias) / (float)partiesUsed.Count; Ability ability; int elementCount = partyAbilities[p.Members[i]].SelectMany(a => GetElementsOnAbility(a, partyAbilities.Values.SelectMany(l => l).ToList())).Distinct().Count(); if (elementCount == 0) { ability = partyAbilities[p.Members[i]][RandomNum.RandInt(0, partyAbilities[p.Members[i]].Count - 1)]; } else { List <Element> validElements; do { ability = partyAbilities[p.Members[i]][RandomNum.RandInt(0, partyAbilities[p.Members[i]].Count - 1)]; validElements = GetElementsOnAbility(ability, partyAbilities.Values.SelectMany(l => l).ToList()).ToList(); } while (validElements.Count == 0); elementWeights.Keys.Where(e => validElements.Contains(e)).ForEach(e => { if (RandomNum.RandInt(0, 99) < 40) { elementWeights[e] = (int)(elementWeights[e] / bias); } else { elementWeights[e] = (int)(elementWeights[e] * bias); } if (i == randomRequiredVulnerable && bounds[e][1] > possibleMax) { bounds[e][1] = possibleMax; } }); } typeWeights.Keys.Where(e => ability.Elements.Contains(e)).ForEach(e => { float typeBias = bias * (e == Element.Physical ? 0.45f : 1); if (RandomNum.RandInt(0, 99) < 40) { typeWeights[e] = (int)(typeWeights[e] / Math.Pow(typeBias, 0.1)); } else { typeWeights[e] = (int)(typeWeights[e] * Math.Pow(typeBias, 0.1)); } if (i == randomRequiredVulnerable && bounds[e][1] > possibleMax) { bounds[e][1] = possibleMax; } }); } } if (plandoElementResists.ContainsKey(enemyID)) { plandoElementResists[enemyID].ForEach(pair => bounds[pair.Key] = new ElementalRes[] { pair.Value, pair.Value }); } StatValuesWeighted types = new StatValuesWeighted(typeWeights.Values.ToArray()); StatValuesWeighted elements = new StatValuesWeighted(elementWeights.Values.ToArray()); Tuple <int, int>[] typeBounds = typeWeights.Keys.Select(e => GetElemBounds(bounds[e])).ToArray(); types.Randomize(typeBounds, (int)(types.GetTotalPoints(typeBounds) * modifier / 100f)); Tuple <int, int>[] elementBounds = elementWeights.Keys.Select(e => GetElemBounds(bounds[e])).ToArray(); elements.Randomize(elementBounds, (int)(elements.GetTotalPoints(elementBounds) * modifier / 100f)); typeWeights.Keys.ToList().ForEach(e => enemy[e] = GetBoundRes(types[typeWeights.Keys.ToList().IndexOf(e)])); elementWeights.Keys.ToList().ForEach(e => enemy[e] = GetBoundRes(elements[elementWeights.Keys.ToList().IndexOf(e)])); }