public override IEnumerable <TickTimer> Main() { GeneratePrimaryResource(ScriptFormula(17)); // fire projectile normally, or find targets in arc if RuneB Vector3D[] targetDirs; if (Rune_B > 0) { targetDirs = new Vector3D[(int)ScriptFormula(24)]; int takenPos = 0; foreach (Actor actor in GetEnemiesInArcDirection(User.Position, TargetPosition, 75f, ScriptFormula(12)).Actors) { targetDirs[takenPos] = actor.Position; ++takenPos; if (takenPos >= targetDirs.Length) { break; } } // generate any extra positions using generic spread if (takenPos < targetDirs.Length) { PowerMath.GenerateSpreadPositions(User.Position, TargetPosition, 10f, targetDirs.Length - takenPos) .CopyTo(targetDirs, takenPos); } } else { targetDirs = new Vector3D[] { TargetPosition }; } foreach (Vector3D position in targetDirs) { var proj = new Projectile(this, RuneSelect(77569, 153864, 153865, 153866, 153867, 153868), User.Position); proj.Position.Z += 5f; // fix height proj.OnCollision = (hit) => { // hit effect hit.PlayEffectGroup(RuneSelect(77577, 153870, 153872, 153873, 153871, 153869)); if (Rune_B > 0) { WeaponDamage(hit, ScriptFormula(9), DamageType.Poison); } else { AddBuff(hit, new ExplosionBuff()); } proj.Destroy(); }; proj.Launch(position, ScriptFormula(2)); if (Rune_B > 0) { yield return(WaitSeconds(ScriptFormula(13))); } } }
public override IEnumerable <TickTimer> Main() { GeneratePrimaryResource(ScriptFormula(25)); float targetDistance = PowerMath.Distance2D(User.Position, TargetPosition); // create grenade projectiles with shared detonation timer TickTimer timeout = WaitSeconds(ScriptFormula(2)); Projectile[] grenades = new Projectile[Rune_C > 0 ? 1 : 3]; for (int i = 0; i < grenades.Length; ++i) { var projectile = new Projectile(this, Rune_C > 0 ? 212547 : 88244, User.Position); projectile.Timeout = timeout; grenades[i] = projectile; } // generate spread positions with distance-scaled spread amount. float scaledSpreadOffset = Math.Max(targetDistance - ScriptFormula(14), 0f); Vector3D[] projDestinations = PowerMath.GenerateSpreadPositions(User.Position, TargetPosition, ScriptFormula(11) - scaledSpreadOffset, grenades.Length); // launch and bounce grenades yield return(WaitTicks(1)); // helps make bounce timings more consistent float bounceOffset = 1f; float minHeight = ScriptFormula(21); float height = minHeight + ScriptFormula(22); float bouncePercent = 0.7f; // ScriptFormula(23); while (!timeout.TimedOut) { for (int i = 0; i < grenades.Length; ++i) { grenades[i].LaunchArc(PowerMath.TranslateDirection2D(projDestinations[i], User.Position, projDestinations[i], targetDistance * 0.3f * bounceOffset), height, ScriptFormula(20)); } height *= bouncePercent; bounceOffset *= 0.3f; yield return(grenades[0].ArrivalTime); // play "dink dink" grenade bounce sound grenades[0].PlayEffect(Effect.Unknown69); } // damage effects foreach (var grenade in grenades) { var grenadeN = grenade; SpawnEffect(RuneSelect(154027, 154045, 154028, 154044, 154046, 154043), grenade.Position); // poison pool effect if (Rune_A > 0) { var pool = SpawnEffect(154076, grenade.Position, 0, WaitSeconds(ScriptFormula(7))); pool.UpdateDelay = 1f; pool.OnUpdate = () => { WeaponDamage(GetEnemiesInRadius(grenadeN.Position, ScriptFormula(5)), ScriptFormula(6), DamageType.Poison); }; } AttackPayload attack = new AttackPayload(this); attack.Targets = GetEnemiesInRadius(grenade.Position, ScriptFormula(4)); attack.AddWeaponDamage(ScriptFormula(0), Rune_A > 0 ? DamageType.Poison : DamageType.Fire); attack.OnHit = (hitPayload) => { if (Rune_E > 0) { if (Rand.NextDouble() < ScriptFormula(9)) { AddBuff(hitPayload.Target, new DebuffStunned(WaitSeconds(ScriptFormula(10)))); } } if (Rune_C > 0) { Knockback(grenadeN.Position, hitPayload.Target, ScriptFormula(8)); } }; attack.Apply(); } // clusterbomb hits if (Rune_B > 0) { int damagePulses = (int)ScriptFormula(28); for (int pulse = 0; pulse < damagePulses; ++pulse) { yield return(WaitSeconds(ScriptFormula(12) / damagePulses)); foreach (var grenade in grenades) { WeaponDamage(GetEnemiesInRadius(grenade.Position, ScriptFormula(4)), ScriptFormula(0), DamageType.Fire); } } } }