private IEnumerator SpawnEnemyList(EnemyWaveItem enemyWaveItem, float delayBetween) { spawnCoroutinesRunning++; if (enemyWaveItem.startDelay > 0) { spawnWarnings[enemyWaveItem.spawnerIndex].AddTimeInfo(new SpawnWarning.TimeInfo(enemyWaveItem.startDelay, currentWave)); } yield return(new WaitForSeconds(enemyWaveItem.startDelay)); Dictionary <BonusType, StatBonus> bonuses = new Dictionary <BonusType, StatBonus>(); RarityType rarity = enemyWaveItem.enemyRarity; if (isSurvivalBattle) { int totalWaveCount = survivalLoopCount * Waves.Count + (currentWave + 1); StatBonus healthBonus = new StatBonus(); healthBonus.AddBonus(ModifyType.MULTIPLY, 15 * survivalLoopCount); bonuses.Add(BonusType.MAX_HEALTH, healthBonus); StatBonus damageBonus = new StatBonus(); damageBonus.AddBonus(ModifyType.MULTIPLY, 15 * survivalLoopCount); bonuses.Add(BonusType.GLOBAL_DAMAGE, damageBonus); } foreach (string affixName in enemyWaveItem.bonusProperties) { AffixBase affixBase = ResourceManager.Instance.GetAffixBase(affixName, AffixType.MONSTERMOD); foreach (AffixBonusProperty prop in affixBase.affixBonuses) { StatBonus bonus; if (bonuses.ContainsKey(prop.bonusType)) { bonus = bonuses[prop.bonusType]; } else { bonus = new StatBonus(); bonuses.Add(prop.bonusType, bonus); } bonus.AddBonus(prop.modifyType, prop.minValue); } } for (int j = 0; j < enemyWaveItem.enemyCount; j++) { int rarityMod = 0; if (survivalLoopCount > 0 && rarity < RarityType.RARE) { float rarityBoostIncrement = 0.05f; if (rarity == RarityType.NORMAL) { rarityBoostIncrement = 0.08f; } float totalRarityBoostChance = survivalLoopCount * rarityBoostIncrement; if (Random.Range(0, 1f) < totalRarityBoostChance) { rarityMod++; if (rarity == RarityType.NORMAL && totalRarityBoostChance > 1f && Random.Range(0, 1f) < (1f - totalRarityBoostChance)) { rarityMod++; } } } SpawnEnemy(enemyWaveItem, bonuses, rarity + rarityMod); yield return(new WaitForSeconds(delayBetween)); } spawnCoroutinesRunning--; yield break; }
public Dictionary <ElementType, float> ScaleSecondaryDamageValue(Actor target, Dictionary <ElementType, MinMaxRange> baseDamage, IEnumerable <GroupType> effectTags) { HashSet <GroupType> targetTypes = target.GetActorTagsAsTarget(); Dictionary <BonusType, StatBonus> whenHitBonusDict = new Dictionary <BonusType, StatBonus>(); int[] minDamage = new int[7]; int[] maxDamage = new int[7]; int[] convertedMinDamage = new int[7]; int[] convertedMaxDamage = new int[7]; float[] conversions = new float[7]; HashSet <GroupType> tagsToUse = new HashSet <GroupType>(effectTags); tagsToUse.UnionWith(GetActorTagsAndDataTags()); foreach (TriggeredEffect triggeredEffect in Data.TriggeredEffects[TriggerType.WHEN_HITTING]) { if (targetTypes.Contains(triggeredEffect.BaseEffect.restriction) && triggeredEffect.RollTriggerChance()) { if (whenHitBonusDict.ContainsKey(triggeredEffect.BaseEffect.statBonusType)) { whenHitBonusDict[triggeredEffect.BaseEffect.statBonusType].AddBonus(triggeredEffect.BaseEffect.statModifyType, triggeredEffect.Value); } else { StatBonus bonus = new StatBonus(); bonus.AddBonus(triggeredEffect.BaseEffect.statModifyType, triggeredEffect.Value); whenHitBonusDict.Add(triggeredEffect.BaseEffect.statBonusType, bonus); } } } foreach (ElementType elementType in Enum.GetValues(typeof(ElementType))) { if (!baseDamage.ContainsKey(elementType)) { baseDamage[elementType] = new MinMaxRange(); } minDamage[(int)elementType] = baseDamage[elementType].min; maxDamage[(int)elementType] = baseDamage[elementType].max; HashSet <BonusType> minTypes = new HashSet <BonusType>(); HashSet <BonusType> maxTypes = new HashSet <BonusType>(); HashSet <BonusType> multiTypes = new HashSet <BonusType>(); Helpers.GetGlobalAndFlatDamageTypes(elementType, tagsToUse, minTypes, maxTypes, multiTypes); multiTypes.UnionWith(Helpers.GetMultiplierTypes(AbilityType.NON_ABILITY, elementType)); StatBonus minBonus = Data.GetMultiStatBonus(tagsToUse, minTypes.ToArray()); StatBonus maxBonus = Data.GetMultiStatBonus(tagsToUse, maxTypes.ToArray()); StatBonus multiBonus = new StatBonus(); foreach (KeyValuePair <BonusType, StatBonus> keyValue in whenHitBonusDict) { if (minTypes.Contains(keyValue.Key)) { minBonus.AddBonuses(keyValue.Value); } else if (maxTypes.Contains(keyValue.Key)) { maxBonus.AddBonuses(keyValue.Value); } else if (multiTypes.Contains(keyValue.Key)) { multiBonus.AddBonuses(keyValue.Value); } } HashSet <BonusType> availableConversions = Data.BonusesIntersection(null, Helpers.GetConversionTypes(elementType)); if (availableConversions.Count > 0) { Array.Clear(conversions, 0, 7); ActorAbility.GetElementConversionValues(Data, tagsToUse, availableConversions, conversions, null); MinMaxRange baseRange = ActorAbility.CalculateDamageConversion(Data, convertedMinDamage, convertedMaxDamage, tagsToUse, baseDamage[elementType], conversions, elementType, multiTypes, minBonus, maxBonus, multiBonus); minDamage[(int)elementType] = baseRange.min; maxDamage[(int)elementType] = baseRange.max; } else { Data.GetMultiStatBonus(multiBonus, null, tagsToUse, multiTypes.ToArray()); minDamage[(int)elementType] = (int)Math.Max(multiBonus.CalculateStat(baseDamage[elementType].min + minBonus.CalculateStat(0f)), 0); maxDamage[(int)elementType] = (int)Math.Max(multiBonus.CalculateStat(baseDamage[elementType].max + maxBonus.CalculateStat(0f)), 0); } } float critChance = Data.GetMultiStatBonus(tagsToUse, BonusType.GLOBAL_CRITICAL_CHANCE).CalculateStat(0f); bool isCrit = UnityEngine.Random.Range(0f, 100f) < critChance; Dictionary <ElementType, float> returnDict = new Dictionary <ElementType, float>(); foreach (ElementType elementType in Enum.GetValues(typeof(ElementType))) { float damage = UnityEngine.Random.Range(minDamage[(int)elementType] + convertedMinDamage[(int)elementType], maxDamage[(int)elementType] + convertedMaxDamage[(int)elementType] + 1); if (isCrit) { damage *= 1 + (Data.GetMultiStatBonus(tagsToUse, BonusType.GLOBAL_CRITICAL_DAMAGE).CalculateStat(50) / 100f); } returnDict.Add(elementType, damage); } return(returnDict); }