Example #1
0
        private void RandomizeATBCosts(Dictionary <Ability, int> plando)
        {
            if (Flags.AbilityFlags.ATBCost)
            {
                int variance = Flags.AbilityFlags.ATBCost.Range.Value;
                Flags.AbilityFlags.ATBCost.SetRand();

                RandoCrystarium crystarium           = randomizers.Get <RandoCrystarium>("Crystarium");
                List <string>   startingAbilityNodes = crystarium.crystariums.Values.SelectMany(c => c.DataList).Where(node => node.CPCost == 0 && node.Type == CrystariumType.Ability).Select(node => node.AbilityName).ToList();

                Abilities.abilities.Where(a => a.Role != Role.None).ForEach(aID =>
                {
                    if (abilities.IdList.IndexOf(aID.GetIDs()[0]) > -1)
                    {
                        int max = aID.GetIDs().Where(id => startingAbilityNodes.Contains(id)).Count() > 0 ? 3 : 6;
                        if (aID == Abilities.Attack || aID == Abilities.HandGrenade)
                        {
                            max = 2;
                        }
                        int cost = plando.ContainsKey(aID) ? (plando[aID] * 10) : abilities[aID.GetIDs()[0]].ATBCost;
                        if (cost > 0 && cost < 0xFFFF)
                        {
                            if (!plando.ContainsKey(aID))
                            {
                                cost = RandomNum.RandInt(Math.Max(1, cost / 10 - variance), Math.Min(max, cost / 10 + variance)) * 10;
                            }
                            if (cost == 60)
                            {
                                cost = 0xFFFF;
                            }
                            aID.GetIDs().ForEach(id =>
                            {
                                if (abilities.IdList.IndexOf(id) > -1)
                                {
                                    abilities[id].ATBCost = (ushort)cost;
                                }
                            });
                        }
                    }
                });

                RandomNum.ClearRand();
            }
        }
Example #2
0
        private void RandomizeDebuffs(DataStoreEnemy enemy, Enemy enemyID, int modifier, Dictionary <Enemy, Dictionary <Debuff, int> > plandoDebuffResists)
        {
            RandoCrystarium crystarium = randomizers.Get <RandoCrystarium>("Crystarium");

            float leaderBias = 0.75f, aiBias = 0.90f;

            Dictionary <Debuff, int[]> bounds = ((Debuff[])Enum.GetValues(typeof(Debuff))).ToDictionary(d => d, d => new int[] { 0, 100 });

            int immunities = (int)(((Debuff[])Enum.GetValues(typeof(Debuff))).Where(d => enemy[d] >= 100).Count() + Math.Sign(modifier - 100) * RandomNum.RandInt(0, (int)Math.Round(Math.Sqrt(1.2 * Math.Abs(modifier - 100)))));

            if (enemyID.Type == EnemyType.Eidolon)
            {
                bounds[Debuff.Poison] = new int[] { 100, 100 };
                immunities--;
            }

            if (plandoDebuffResists.ContainsKey(enemyID))
            {
                plandoDebuffResists[enemyID].ForEach(pair => { bounds[pair.Key] = new int[] { pair.Value, pair.Value }; if (pair.Value == 100)
                                                               {
                                                                   immunities--;
                                                               }
                                                     });
            }

            immunities = Math.Max(0, Math.Min(11 - bounds.Values.Where(a => a[0] == 100 && a[1] == 100).Count(), immunities));

            for (int i = 0; i < immunities; i++)
            {
                Debuff d;
                do
                {
                    d = (Debuff)RandomNum.RandInt(0, 10);
                } while (bounds[d][0] == 100 && bounds[d][1] == 100);
                bounds[d] = new int[] { 100, 100 };
            }

            List <Party> partiesUsed = enemyID.Parties.Select(p => GetParty(p)).ToList();

            if (enemyID.ParentData != null && enemyID.ParentData.Parties.Length > 0)
            {
                partiesUsed.AddRange(enemyID.ParentData.Parties);
            }

            Dictionary <Debuff, int> weights = Enumerable.Range((int)Debuff.Deprotect, 11).ToDictionary(i => (Debuff)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).ToList();
                    partyAbilities.Add(p.Members[i], abilities);
                }

                int randomRequiredVulnerable = RandomNum.RandInt(0, p.Members.Length);

                for (int i = 0; i < p.Members.Length; i++)
                {
                    float bias = (i == 0 ? leaderBias : aiBias) / (float)partiesUsed.Count;

                    Ability ability;
                    int     debuffCount = partyAbilities[p.Members[i]].SelectMany(a => a.Debuffs).Distinct().Count();

                    if (debuffCount == 0)
                    {
                        ability = partyAbilities[p.Members[i]][RandomNum.RandInt(0, partyAbilities[p.Members[i]].Count - 1)];
                    }
                    else
                    {
                        List <Debuff> validDebuffs;
                        do
                        {
                            ability      = partyAbilities[p.Members[i]][RandomNum.RandInt(0, partyAbilities[p.Members[i]].Count - 1)];
                            validDebuffs = ability.Debuffs.ToList();
                        } while (validDebuffs.Count == 0);

                        weights.Keys.Where(e => validDebuffs.Contains(e)).ForEach(e =>
                        {
                            if (RandomNum.RandInt(0, 99) < 40)
                            {
                                weights[e] = (int)(weights[e] / bias);
                            }
                            else
                            {
                                weights[e] = (int)(weights[e] * bias);
                            }
                            if (i == randomRequiredVulnerable && bounds[e][1] > 99)
                            {
                                bounds[e][1] = 99;
                            }
                        });
                    }
                }
            }

            if (enemyID.Type == EnemyType.Eidolon)
            {
                bounds[Debuff.Poison] = new int[] { 100, 100 };
            }

            if (plandoDebuffResists.ContainsKey(enemyID))
            {
                plandoDebuffResists[enemyID].ForEach(pair => bounds[pair.Key] = new int[] { pair.Value, pair.Value });
            }

            StatValuesWeighted debuffs = new StatValuesWeighted(weights.Values.ToArray());

            Tuple <int, int>[] debuffBounds = weights.Keys.Select(d => new Tuple <int, int>(bounds[d][0], bounds[d][1])).ToArray();
            debuffs.Randomize(debuffBounds, (int)(debuffs.GetTotalPoints(debuffBounds) * modifier / 100f));

            weights.Keys.ToList().ForEach(d => enemy[d] = (byte)Math.Min(100, debuffs[weights.Keys.ToList().IndexOf(d)]));
        }
Example #3
0
        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)]));
        }