private void createParticles(float sampleWidthPercent, float sampleHeightPercent) { for (float y = 0; y < frameHeight; y += sampleHeightPercent * (float)(frameHeight)) { for (float x = 0; x < frameWidth; x += sampleWidthPercent * (float)(frameWidth)) { int floorX = (int)Math.Floor(x); int floorY = (int)Math.Floor(y); bool isGray = (Math.Abs((float)(image[floorX + floorY * frameWidth].B - image[floorX + floorY * frameWidth].R)) < 5 && Math.Abs((float)(image[floorX + floorY * frameWidth].B - image[floorX + floorY * frameWidth].G)) < 5f); if (image[floorX + floorY * frameWidth].A > 245 || (image[floorX + floorY * frameWidth].A <= 245f && !isGray)) { double directionAngle = This.Game.rand.NextDouble() * 2 * Math.PI; Vector2 randDirection = new Vector2((float)Math.Cos(directionAngle), (float)Math.Sin(directionAngle) / ParticleEmitter.EllipsePerspectiveModifier); particleEmitter.createParticles(new Vector2(randDirection.X * 25, 105), new Vector2(-randDirection.X * 15, -155), topLeftPosition + new Vector2((deadSprite.Hflip ? frameWidth - floorX : floorX) * scale, floorY * scale), 5, This.Game.rand.Next(600, 800)); } } } }
private void createParticlesLikeFlame(ParticleEmitter emitter, int maxNumToCreate, Vector2 flameOrigin) { Random rand = new Random(This.gameTime.TotalGameTime.Milliseconds); Vector2 position = new Vector2((float)rand.Next(0, 20), (float)rand.Next(0, 20)) + flameOrigin; for (int i = 0; i < maxNumToCreate; i++) { double velocityAngle = rand.NextDouble() * Math.PI * .5 + Math.PI / 4; float velocitySpeed = rand.Next(2, 15); double accelAngle = rand.NextDouble() * Math.PI * .25 + (Math.PI * 3) / 8; float accelSpeed = rand.Next(2, 15); emitter.createParticles(new Vector2((float)Math.Cos(velocityAngle) * velocitySpeed, (float)Math.Sin(velocityAngle) * velocitySpeed), new Vector2((float)Math.Cos(accelAngle) * accelSpeed, (float)Math.Sin(accelAngle) * accelSpeed), position, rand.Next(5, 20), rand.Next(1000, 4500)); } }
private void createParticlesInCircle(ParticleEmitter emitter, int maxNumToCreate, float radius, Vector2 circleOrigin) { Random rand = new Random(This.gameTime.TotalGameTime.Milliseconds); double positionAngle = ((This.gameTime.TotalGameTime.TotalMilliseconds % 8000.0) / 8000.0) * Math.PI * 2; Vector2 position = new Vector2((float)Math.Cos(positionAngle) * radius, (float)Math.Sin(positionAngle) * radius) + circleOrigin; for (int i = 0; i < maxNumToCreate; i++) { double velocityAngle = rand.NextDouble() * Math.PI * 2; float velocitySpeed = rand.Next(2, 15); double accelAngle = rand.NextDouble() * Math.PI * 2; float accelSpeed = rand.Next(2, 15); emitter.createParticles(new Vector2((float)Math.Cos(velocityAngle) * velocitySpeed, (float)Math.Sin(velocityAngle) * velocitySpeed), new Vector2((float)Math.Cos(accelAngle) * accelSpeed, (float)Math.Sin(accelAngle) * accelSpeed), position, rand.Next(5, 20), rand.Next(1000, 4000)); } }
/// <summary> /// Performs Freeze Attack /// </summary> public static IEnumerable<bool> Freeze(Sprite _target, OurSprite attacker, int attackFrame, Element elem = Element.Water) { if (_target == null) { yield return true; } #region Variables Level l = This.Game.CurrentLevel; OurSprite target = (OurSprite)_target; Vector2 initialDirection = attacker.Direction; attacker.State = SpriteState.Attacking; setAnimation(attacker); int FrameCount = attacker.FrameCount(); TimeSpan attackStartTime = This.gameTime.TotalGameTime; List<CollisionObject> collisions = target.GetCollision(); Effect particleEffect = l.GetEffect("ParticleSystem"); Texture2D ice = l.GetTexture("ice"); ParticleEmitter particleEmitterIce = new ParticleEmitter(500, particleEffect, ice); particleEmitterIce.effectTechnique = "FadeAtXPercent"; particleEmitterIce.fadeStartPercent = .98f; particleEmitterIce.blendState = BlendState.Additive; Collision_BoundingCircle c = (particleEmitterIce.collisionObjects.First() as Collision_BoundingCircle); c.Radius = collisions.Count > 0 ? (collisions[0] as Collision_BoundingCircle).Radius + 20 : 100; c.createDrawPoints(); float particleEmitterRadius = c.Radius; #endregion Variables attacker.isAttackAnimDone = false; attacker.Rewind(); if (attacker is Frostbyte.Characters.Mage) { (attacker as Frostbyte.Characters.Mage).attackTier = 3; } #region Shoot Attack while (attacker.Frame < FrameCount) { attacker.isAttackAnimDone = false; if (target.GroundPos != attacker.GroundPos) attacker.Direction = target.GroundPos - particleEmitterIce.GroundPos; attacker.State = SpriteState.Attacking; setAnimation(attacker); FrameCount = attacker.FrameCount(); if (attacker.Frame == attackFrame) { break; } yield return false; } #endregion Shoot Attack #region Generate Freeze bool isAttackAnimDone = false; for (int i = 0; i < 225; i++) { particleEmitterIce.GroundPos = target.GroundPos; // Ice for (int j = 0; j < 3; j++) { double directionAngle = This.Game.rand.NextDouble() * Math.PI; Vector2 randDirection = new Vector2((float)Math.Cos(directionAngle), (float)Math.Sin(directionAngle) / ParticleEmitter.EllipsePerspectiveModifier); particleEmitterIce.createParticles(randDirection * 20, randDirection * 10 - new Vector2(0, 50), particleEmitterIce.GroundPos + randDirection * This.Game.rand.Next(5, (int)particleEmitterRadius), This.Game.rand.Next(5, 20), 600); } // Snow for (int j = 0; j < particleEmitterRadius / 7; j++) { double directionAngle = This.Game.rand.NextDouble() * 2 * Math.PI; Vector2 randDirection = new Vector2((float)Math.Cos(directionAngle), (float)Math.Sin(directionAngle) / ParticleEmitter.EllipsePerspectiveModifier); particleEmitterIce.createParticles(new Vector2(0, 50), new Vector2(10, 40), particleEmitterIce.GroundPos + new Vector2(0, This.Game.rand.Next(-175, -50)) + randDirection * This.Game.rand.Next(0, (int)particleEmitterRadius), 5f, This.Game.rand.Next(500, 800)); } //Freeze Target Slow(target, 0.0f, new TimeSpan(0, 0, 0, 0, 500)); //if the attack frame has passed then allow the attacker to move if (attacker.Frame >= FrameCount - 1) { attacker.isAttackAnimDone = true; isAttackAnimDone = true; } if (!isAttackAnimDone) attacker.isAttackAnimDone = false; yield return false; } while (particleEmitterIce.ActiveParticleCount > 0) yield return false; #endregion Generate Freeze particleEmitterIce.Remove(); l.RemoveSprite(particleEmitterIce); attacker.particleEmitters.Remove(particleEmitterIce); attacker.isAttackAnimDone = true; yield return true; }
/// <summary> /// Performs Earthquake Attack /// </summary> /// <param name="_target">The target for the projectile to attack</param> /// <param name="_attacker">The sprite initiating the attack</param> /// <param name="_baseDamage">The amount of damage to inflict before constant multiplier for weakness</param> /// <param name="_attackFrame">The frame that the attack begins on</param> /// <returns>Returns true when finished</returns> public static IEnumerable<bool> Earthquake(Sprite _target, OurSprite attacker, int baseDamage, int attackFrame, Element elem = Element.Earth) { #region Variables Level l = This.Game.CurrentLevel; OurSprite target = (OurSprite)_target; Vector2 initialDirection = attacker.Direction; attacker.State = SpriteState.Attacking; setAnimation(attacker); int FrameCount = attacker.FrameCount(); TimeSpan attackStartTime = This.gameTime.TotalGameTime; Effect particleEffect = l.GetEffect("ParticleSystem"); Texture2D earthquake = l.GetTexture("earthquake"); ParticleEmitter particleEmitterDust = new ParticleEmitter(500, particleEffect, earthquake); particleEmitterDust.effectTechnique = "NoSpecialEffect"; particleEmitterDust.blendState = BlendState.AlphaBlend; Collision_BoundingCircle c = (particleEmitterDust.collisionObjects.First() as Collision_BoundingCircle); c.Radius = 125; c.createDrawPoints(); Texture2D earthquakeRock = l.GetTexture("Earthquake Rock"); ParticleEmitter particleEmitterRocks = new ParticleEmitter(200, particleEffect, earthquakeRock); particleEmitterRocks.effectTechnique = "NoSpecialEffect"; particleEmitterRocks.blendState = BlendState.AlphaBlend; c = (particleEmitterRocks.collisionObjects.First() as Collision_BoundingCircle); c.Radius = 125; c.createDrawPoints(); //Texture2D earthquakeRock = l.GetTexture("Earthquake Rock"); ParticleEmitter particleEmitterRing = new ParticleEmitter(2000, particleEffect, earthquakeRock); particleEmitterRing.effectTechnique = "FadeAtXPercent"; particleEmitterRing.fadeStartPercent = 0f; particleEmitterRing.blendState = BlendState.Additive; c = (particleEmitterRing.collisionObjects.First() as Collision_BoundingCircle); c.Radius = 125; c.createDrawPoints(); #endregion Variables attacker.isAttackAnimDone = false; attacker.Rewind(); if (attacker is Frostbyte.Characters.Mage) { (attacker as Frostbyte.Characters.Mage).attackTier = 2; } #region Shoot Attack while (attacker.Frame < FrameCount) { attacker.isAttackAnimDone = false; if (target != null && target.GroundPos != attacker.GroundPos) attacker.Direction = target.GroundPos - particleEmitterDust.GroundPos; attacker.State = SpriteState.Attacking; setAnimation(attacker); FrameCount = attacker.FrameCount(); if (attacker.Frame == attackFrame) { break; } yield return false; } #endregion Shoot Attack if (target != null) { particleEmitterDust.GroundPos = target.GroundPos; particleEmitterRocks.GroundPos = target.GroundPos; particleEmitterRing.GroundPos = target.GroundPos; } else { particleEmitterDust.GroundPos = attacker.GroundPos + 300 * initialDirection; particleEmitterRocks.GroundPos = attacker.GroundPos + 300 * initialDirection; particleEmitterRing.GroundPos = attacker.GroundPos + 300 * initialDirection; } #region Generate Earthquake bool isAttackAnimDone = false; if (This.Game.AudioManager.PlaySoundEffect("Effects/Earthquake")) { yield return false; } for (int i = 0; i < 165; i++) { // Shaking Rocks for (int j = 0; j < 1; j++) { double directionAngle = This.Game.rand.NextDouble() * 2 * Math.PI; Vector2 randDirection = new Vector2((float)Math.Cos(directionAngle), (float)Math.Sin(directionAngle) / ParticleEmitter.EllipsePerspectiveModifier); particleEmitterRocks.createParticles(new Vector2(0, -200), new Vector2(0, 800), particleEmitterRocks.GroundPos + randDirection * This.Game.rand.Next(0, 150), 4f, This.Game.rand.Next(100, 400)); } // Dust for (int j = 0; j < 5; j++) { double directionAngle = This.Game.rand.NextDouble() * 2 * Math.PI; Vector2 randDirection = new Vector2((float)Math.Cos(directionAngle), (float)Math.Sin(directionAngle) / ParticleEmitter.EllipsePerspectiveModifier); particleEmitterDust.createParticles(new Vector2(0, -10), new Vector2(0, -5), particleEmitterDust.GroundPos + randDirection * This.Game.rand.Next(0, 150), 35f, This.Game.rand.Next(300, 1200)); } // Ring if ((double)i % 14 == 0) { double startPos = This.Game.rand.Next(0, 50); double maxLength = This.Game.rand.Next(15, 20); for (double j = 0; j < maxLength; j += .15f) { double directionAngle2 = (((j + startPos) % 50) / 50) * 2 * Math.PI; Vector2 circlePoint = new Vector2((float)Math.Cos(directionAngle2), (float)Math.Sin(directionAngle2) / ParticleEmitter.EllipsePerspectiveModifier); particleEmitterRing.createParticles(new Vector2(0, -30), new Vector2(0, -35), particleEmitterRing.GroundPos + circlePoint * 150, 4f, This.Game.rand.Next(1100, 1200)); } } //Deal Damage if (5 - i % 15 == 0 && Collision.CollisionData.Count > 0) { List<Tuple<CollisionObject, WorldObject, CollisionObject>> collidedWith; Collision.CollisionData.TryGetValue(particleEmitterDust, out collidedWith); if (collidedWith != null) { foreach (Tuple<CollisionObject, WorldObject, CollisionObject> detectedCollision in collidedWith) { if (((detectedCollision.Item2 is Enemy) && (attacker is Player)) || ((detectedCollision.Item2 is Player) && (attacker is Enemy))) { //Damage(attacker, (detectedCollision.Item2 as OurSprite), baseDamage); Slow((detectedCollision.Item2 as OurSprite), 0.5f, new TimeSpan(0, 0, 0, 1, 500)); } } } } //if the attack frame has passed then allow the attacker to move if (attacker.Frame >= FrameCount - 1) { attacker.isAttackAnimDone = true; isAttackAnimDone = true; } if (!isAttackAnimDone) attacker.isAttackAnimDone = false; yield return false; } while (particleEmitterDust.ActiveParticleCount > 0 || particleEmitterRocks.ActiveParticleCount > 0 || particleEmitterRing.ActiveParticleCount > 0) yield return false; #endregion Generate Earthquake particleEmitterDust.Remove(); l.RemoveSprite(particleEmitterDust); attacker.particleEmitters.Remove(particleEmitterDust); particleEmitterRocks.Remove(); l.RemoveSprite(particleEmitterRocks); attacker.particleEmitters.Remove(particleEmitterRocks); particleEmitterRing.Remove(); l.RemoveSprite(particleEmitterRing); attacker.particleEmitters.Remove(particleEmitterRing); attacker.isAttackAnimDone = true; yield return true; }
/// <summary> /// Performs Fire Ring Attack /// </summary> /// <param name="_target">The target for the projectile to attack</param> /// <param name="_attacker">The sprite initiating the attack</param> /// <param name="_baseDamage">The amount of damage to inflict before constant multiplier for weakness</param> /// <param name="_attackFrame">The frame that the attack begins on</param> /// <returns>Returns true when finished</returns> public static IEnumerable<bool> FireRing(Sprite _target, OurSprite attacker, int baseDamage, int attackFrame, Element elem = Element.Fire) { #region Variables Level l = This.Game.CurrentLevel; OurSprite target = (OurSprite)_target; Vector2 initialDirection = attacker.Direction; attacker.State = SpriteState.Attacking; setAnimation(attacker); int FrameCount = attacker.FrameCount(); TimeSpan attackStartTime = This.gameTime.TotalGameTime; Effect particleEffect = l.GetEffect("ParticleSystem"); Texture2D fire = l.GetTexture("fireParticle"); ParticleEmitter particleEmitterFire = new ParticleEmitter(4000, particleEffect, l.GetTexture("fire darker")); particleEmitterFire.effectTechnique = "FadeAtXPercent"; particleEmitterFire.fadeStartPercent = .75f; particleEmitterFire.blendState = BlendState.AlphaBlend; particleEmitterFire.ZOrder = 1; Collision_BoundingCircle c = (particleEmitterFire.collisionObjects.First() as Collision_BoundingCircle); c.Radius = 115; c.createDrawPoints(); ParticleEmitter particleEmitterSkywardRing = new ParticleEmitter(4000, particleEffect, fire); particleEmitterSkywardRing.effectTechnique = "FadeAtXPercent"; particleEmitterSkywardRing.blendState = BlendState.Additive; particleEmitterSkywardRing.fadeStartPercent = .8f; particleEmitterSkywardRing.ZOrder = 2; c.Radius = 115; c.createDrawPoints(); Texture2D redfire = l.GetTexture("red fire"); Texture2D smoke = l.GetTexture("smoke"); ParticleEmitter particleEmitterRedFire = new ParticleEmitter(1500, particleEffect, redfire, smoke); particleEmitterRedFire.effectTechnique = "ChangePicAndFadeAtXPercent"; particleEmitterRedFire.blendState = BlendState.AlphaBlend; particleEmitterRedFire.changePicPercent = .2f; particleEmitterRedFire.fadeStartPercent = .9f; particleEmitterRedFire.ZOrder = 3; c = (particleEmitterRedFire.collisionObjects.First() as Collision_BoundingCircle); c.Radius = 115; c.createDrawPoints(); ParticleEmitter particleEmitterDOT = new ParticleEmitter(1500, particleEffect, fire); particleEmitterDOT.effectTechnique = "FadeAtXPercent"; particleEmitterDOT.fadeStartPercent = .98f; particleEmitterDOT.blendState = BlendState.Additive; particleEmitterDOT.ZOrder = 4; c = (particleEmitterDOT.collisionObjects.First() as Collision_BoundingCircle); c.Radius = 115; c.createDrawPoints(); Vector2 collisionOffset = new Vector2(0, 15); Dictionary<OurSprite, TimeSpan> DOT = new Dictionary<OurSprite, TimeSpan>(); #endregion Variables attacker.isAttackAnimDone = false; attacker.Rewind(); if (attacker is Frostbyte.Characters.Mage) { (attacker as Frostbyte.Characters.Mage).attackTier = 2; } #region Shoot Attack while (attacker.Frame < FrameCount) { attacker.isAttackAnimDone = false; if (target != null && target.GroundPos != attacker.GroundPos) attacker.Direction = target.GroundPos - particleEmitterFire.GroundPos; attacker.State = SpriteState.Attacking; setAnimation(attacker); FrameCount = attacker.FrameCount(); if (attacker.Frame == attackFrame) { break; } yield return false; } #endregion Shoot Attack if (target != null) { particleEmitterFire.GroundPos = target.GroundPos - collisionOffset; particleEmitterRedFire.GroundPos = target.GroundPos - collisionOffset; particleEmitterSkywardRing.GroundPos = target.GroundPos - collisionOffset; } else { particleEmitterFire.GroundPos = attacker.GroundPos + 300 * initialDirection - collisionOffset; particleEmitterRedFire.GroundPos = attacker.GroundPos + 300 * initialDirection - collisionOffset; particleEmitterSkywardRing.GroundPos = attacker.GroundPos + 300 * initialDirection - collisionOffset; } #region Generate Fire Ring and Attack bool isAttackAnimDone = false; for (int i = 0; i < 165; i++) { //Skyward Flames if ((double)i % 5 == 0) { for (int j = 0; j < 10; j++) { double directionAngle = This.Game.rand.NextDouble() * 1 * Math.PI + Math.PI * 2; Vector2 randDirection = new Vector2((float)Math.Cos(directionAngle), (float)Math.Sin(directionAngle) / ParticleEmitter.EllipsePerspectiveModifier); Vector2 velocity = new Vector2(This.Game.rand.Next(-10, 10), -100); Vector2 acceleration = new Vector2(This.Game.rand.Next(-10, 10), -200); particleEmitterRedFire.createParticles(velocity, acceleration, particleEmitterRedFire.GroundPos + randDirection * This.Game.rand.Next(0, 140) + collisionOffset, 10f, This.Game.rand.Next(100, 1200)); } } //Circle Firing if ((double)i % 3 == 0) { for (double j = 0; j < 30; j += .3f) { double directionAngle = This.Game.rand.NextDouble() * 2 * Math.PI; Vector2 randDirection = new Vector2((float)Math.Cos(directionAngle), (float)Math.Sin(directionAngle) / ParticleEmitter.EllipsePerspectiveModifier); Vector2 velocity = -randDirection * 100; Vector2 acceleration = -randDirection * 70; particleEmitterFire.createParticles(velocity, acceleration, particleEmitterFire.GroundPos + randDirection * 140 + collisionOffset, 17f, This.Game.rand.Next(100, 1200)); } } //Skyward Ring if ((double)i % 2 == 0) { for (double j = 0; j < 35; j += .3f) { double positionAngle = (((double)i + j % 35.0) / 35.0) * Math.PI * 2; Vector2 position = new Vector2((float)Math.Cos(positionAngle) * 140, (float)Math.Sin(positionAngle) * This.Game.rand.Next(120, 140) / ParticleEmitter.EllipsePerspectiveModifier) + particleEmitterSkywardRing.GroundPos; Vector2 direction = particleEmitterSkywardRing.GroundPos - position; direction.Normalize(); Vector2 velocity = new Vector2(This.Game.rand.Next(-10, 10), -75); Vector2 acceleration = new Vector2(This.Game.rand.Next(-10, 10), -200); particleEmitterSkywardRing.createParticles(velocity, acceleration, position + collisionOffset, This.Game.rand.Next(5, 20), This.Game.rand.Next(400, 600)); } } //Add Enemies to DOT Dictionary if (i % 10 == 0 && Collision.CollisionData.Count > 0) { List<Tuple<CollisionObject, WorldObject, CollisionObject>> collidedWith; Collision.CollisionData.TryGetValue(particleEmitterFire, out collidedWith); if (collidedWith != null) { foreach (Tuple<CollisionObject, WorldObject, CollisionObject> detectedCollision in collidedWith) { if (((detectedCollision.Item2 is Enemy) && (attacker is Player)) || ((detectedCollision.Item2 is Player) && (attacker is Enemy))) { if (!DOT.ContainsKey((OurSprite)detectedCollision.Item2)) DOT.Add((OurSprite)detectedCollision.Item2, new TimeSpan(0, 0, 2) + This.gameTime.TotalGameTime); else DOT[(OurSprite)detectedCollision.Item2] = new TimeSpan(0, 0, 2) + This.gameTime.TotalGameTime; } } } } //Deal Damage, Remove DOT's That Have Timed Out, and Create Particles on Enemies if ((double)i % 18 == 0) { List<OurSprite> removeDOT = new List<OurSprite>(); foreach (KeyValuePair<OurSprite, TimeSpan> dottedTarget in DOT) { Damage(attacker, dottedTarget.Key, baseDamage); if (dottedTarget.Value < This.gameTime.TotalGameTime || !((l as FrostbyteLevel).enemies.Contains(dottedTarget.Key) || (l as FrostbyteLevel).allies.Contains(dottedTarget.Key))) removeDOT.Add(dottedTarget.Key); //Create Particles for (int j = 0; j < 5; j++) { double directionAngle = This.Game.rand.NextDouble() * 2 * Math.PI; Vector2 randDirection = new Vector2((float)Math.Cos(directionAngle), (float)Math.Sin(directionAngle) / ParticleEmitter.EllipsePerspectiveModifier); Vector2 velocity = new Vector2(This.Game.rand.Next(-10, 10), -10); Vector2 acceleration = new Vector2(This.Game.rand.Next(-10, 10), -10); List<CollisionObject> collisionList = dottedTarget.Key.GetCollision(); int radius = (int)(collisionList.Count > 0 ? (collisionList[0] as Collision_BoundingCircle).Radius + 20 : 40); particleEmitterDOT.createParticles(velocity, acceleration, dottedTarget.Key.GroundPos + randDirection * This.Game.rand.Next(0, radius), 10f, This.Game.rand.Next(100, 500)); } } foreach (OurSprite dottedTarget in removeDOT) DOT.Remove(dottedTarget); } //if the attack frame has passed then allow the attacker to move if (attacker.Frame >= FrameCount - 1) { attacker.isAttackAnimDone = true; isAttackAnimDone = true; } if (!isAttackAnimDone) attacker.isAttackAnimDone = false; yield return false; } int count = 0; while (particleEmitterFire.ActiveParticleCount > 0 || particleEmitterRedFire.ActiveParticleCount > 0 || particleEmitterSkywardRing.ActiveParticleCount > 0 || DOT.Count > 0) { if (count % 18 == 0) { //Deal Damage, Remove DOT's That Have Timed Out, and Create Particles on Enemies List<OurSprite> removeDOT = new List<OurSprite>(); foreach (KeyValuePair<OurSprite, TimeSpan> dottedTarget in DOT) { Damage(attacker, dottedTarget.Key, baseDamage); if (dottedTarget.Value < This.gameTime.TotalGameTime || !(l as FrostbyteLevel).enemies.Contains(dottedTarget.Key)) removeDOT.Add(dottedTarget.Key); //Create Particles for (int j = 0; j < 5; j++) { double directionAngle = This.Game.rand.NextDouble() * 2 * Math.PI; Vector2 randDirection = new Vector2((float)Math.Cos(directionAngle), (float)Math.Sin(directionAngle) / ParticleEmitter.EllipsePerspectiveModifier); Vector2 velocity = new Vector2(This.Game.rand.Next(-10, 10), -10); Vector2 acceleration = new Vector2(This.Game.rand.Next(-10, 10), -10); List<CollisionObject> collisionList = dottedTarget.Key.GetCollision(); int radius = (int)(collisionList.Count > 0 ? (collisionList[0] as Collision_BoundingCircle).Radius + 20 : 40); particleEmitterDOT.createParticles(velocity, acceleration, dottedTarget.Key.GroundPos + randDirection * This.Game.rand.Next(0, radius), 10f, This.Game.rand.Next(100, 500)); } } foreach (OurSprite dottedTarget in removeDOT) DOT.Remove(dottedTarget); } count++; yield return false; } #endregion Generate Fire Ring and Attack particleEmitterFire.Remove(); l.RemoveSprite(particleEmitterFire); attacker.particleEmitters.Remove(particleEmitterFire); particleEmitterRedFire.Remove(); l.RemoveSprite(particleEmitterRedFire); attacker.particleEmitters.Remove(particleEmitterRedFire); particleEmitterSkywardRing.Remove(); l.RemoveSprite(particleEmitterSkywardRing); attacker.particleEmitters.Remove(particleEmitterSkywardRing); attacker.isAttackAnimDone = true; yield return true; }
/// <summary> /// Performs Fire Pillar Attack /// </summary> public static IEnumerable<bool> FirePillar(Sprite _target, OurSprite attacker, int baseDamage, int attackFrame, Element elem = Element.Fire) { if (_target == null) { yield return true; } #region Variables Level l = This.Game.CurrentLevel; OurSprite target = (OurSprite)_target; Vector2 initialDirection = attacker.Direction; attacker.State = SpriteState.Attacking; setAnimation(attacker); int FrameCount = attacker.FrameCount(); TimeSpan attackStartTime = This.gameTime.TotalGameTime; List<CollisionObject> collisions = target.GetCollision(); Effect particleEffect = l.GetEffect("ParticleSystem"); Texture2D fire = l.GetTexture("fireParticle"); ParticleEmitter particleEmitterFire = new ParticleEmitter(3000, particleEffect, fire); particleEmitterFire.effectTechnique = "NoSpecialEffect"; particleEmitterFire.blendState = BlendState.Additive; Collision_BoundingCircle c = (particleEmitterFire.collisionObjects.First() as Collision_BoundingCircle); c.Radius = collisions.Count > 0 ? (collisions[0] as Collision_BoundingCircle).Radius + 20 : 100; c.createDrawPoints(); particleEmitterFire.ZOrder = 1; ParticleEmitter particleEmitterGroundFire = new ParticleEmitter(2000, particleEffect, fire); particleEmitterGroundFire.effectTechnique = "FadeAtXPercent"; particleEmitterGroundFire.fadeStartPercent = .6f; particleEmitterGroundFire.blendState = BlendState.Additive; particleEmitterGroundFire.ZOrder = 2; Texture2D maroonfire = l.GetTexture("maroon fire"); ParticleEmitter particleEmitterGroundRedFire = new ParticleEmitter(2000, particleEffect, maroonfire); particleEmitterGroundRedFire.effectTechnique = "NoSpecialEffect"; particleEmitterGroundRedFire.fadeStartPercent = .6f; particleEmitterGroundRedFire.blendState = BlendState.AlphaBlend; particleEmitterGroundRedFire.ZOrder = 3; TimeSpan DOTStart = new TimeSpan(); #endregion Variables attacker.isAttackAnimDone = false; attacker.Rewind(); if (attacker is Frostbyte.Characters.Mage) { (attacker as Frostbyte.Characters.Mage).attackTier = 3; } #region Shoot Attack while (attacker.Frame < FrameCount) { attacker.isAttackAnimDone = false; if (target.GroundPos != attacker.GroundPos) attacker.Direction = target.GroundPos - particleEmitterFire.GroundPos; attacker.State = SpriteState.Attacking; setAnimation(attacker); FrameCount = attacker.FrameCount(); if (attacker.Frame == attackFrame) { break; } yield return false; } #endregion Shoot Attack #region Generate Fire Pillar bool isAttackAnimDone = false; for (int i = 0; i < 165; i++) { particleEmitterFire.GroundPos = target.GroundPos; //Swirl if (i < 100) { for (float j = 0; j < 60.0f; j += 60.0f / 6.0f) { for (float k = i; k < i + 1; k += .1f) { double positionAngle = (((k + j) % 60.0) / 60.0) * Math.PI * 2.0; Vector2 position = new Vector2((float)Math.Cos(positionAngle) * 150.0f * ((float)(100.0f - k) / 100.0f), (float)Math.Sin(positionAngle) * 150.0f * ((float)(100.0f - k) / 100.0f) / ParticleEmitter.EllipsePerspectiveModifier - k * 2.5f) + particleEmitterFire.GroundPos; Vector2 direction = particleEmitterFire.GroundPos - position; Vector2 velocity = direction / .200f; particleEmitterFire.createParticles(velocity, Vector2.Zero, position + direction * (float)This.Game.rand.Next(0, (int)velocity.Length() / 16) / direction.Length(), 12, 150); } j += 60.0f / 6.0f; for (float k = i; k < i + 1; k += .1f) { double positionAngle = (((k + j) % 60.0) / 60.0) * Math.PI * 2.0; Vector2 position = new Vector2((float)Math.Cos(positionAngle) * 150.0f * ((float)(100.0f - k) / 100.0f), (float)Math.Sin(positionAngle) * 150.0f * ((float)(100.0f - k) / 100.0f) / ParticleEmitter.EllipsePerspectiveModifier - k * 2.5f) + particleEmitterFire.GroundPos; Vector2 direction = particleEmitterFire.GroundPos - position; Vector2 velocity = direction / .200f; particleEmitterGroundRedFire.createParticles(velocity, Vector2.Zero, position + direction * (float)This.Game.rand.Next(0, (int)velocity.Length() / 16) / direction.Length(), 12, 150); } } } if (i == 100) { particleEmitterGroundFire.GroundPos = target.GroundPos - new Vector2(0, 250); particleEmitterGroundRedFire.GroundPos = target.GroundPos - new Vector2(0, 250); } //Strike if (i >= 100 && i < 107) { for (int j = 0; j < 20; j++) { double directionAngle = This.Game.rand.NextDouble() * 2 * Math.PI; Vector2 randDirection = new Vector2((float)Math.Cos(directionAngle), (float)Math.Sin(directionAngle)); if (target.GroundPos != particleEmitterGroundFire.GroundPos) { Vector2 direction = target.GroundPos - particleEmitterGroundFire.GroundPos; direction.Normalize(); Vector2 tangent = new Vector2(-direction.Y, direction.X); particleEmitterGroundFire.createParticles(Vector2.Zero, direction * 500 + randDirection * 500, particleEmitterGroundFire.GroundPos + tangent * This.Game.rand.Next(-15, 15), 20, 500); particleEmitterGroundFire.GroundPos += direction; } } for (int j = 0; j < 20; j++) { double directionAngle = This.Game.rand.NextDouble() * 2 * Math.PI; Vector2 randDirection = new Vector2((float)Math.Cos(directionAngle), (float)Math.Sin(directionAngle)); if (target.GroundPos != particleEmitterGroundFire.GroundPos) { Vector2 direction = target.GroundPos - particleEmitterGroundFire.GroundPos; direction.Normalize(); Vector2 tangent = new Vector2(-direction.Y, direction.X); particleEmitterGroundRedFire.createParticles(Vector2.Zero, direction * 500 + randDirection * 500, particleEmitterGroundFire.GroundPos + tangent * This.Game.rand.Next(-15, 15), 20, 300); particleEmitterGroundFire.GroundPos += direction; } } } //Explode if (i >= 108) { for (int j = 0; j < 10; j++) { double directionAngle = This.Game.rand.NextDouble() * Math.PI; Vector2 randDirection = new Vector2((float)Math.Cos(directionAngle), (float)Math.Sin(directionAngle) / ParticleEmitter.EllipsePerspectiveModifier); particleEmitterGroundFire.createParticles(-randDirection * 200, -randDirection * 300 - new Vector2(0, 800), particleEmitterGroundFire.GroundPos + new Vector2(This.Game.rand.Next(-60, 60), 0), 20, 400); } for (int j = 0; j < 10; j++) { double directionAngle = This.Game.rand.NextDouble() * Math.PI; Vector2 randDirection = new Vector2((float)Math.Cos(directionAngle), (float)Math.Sin(directionAngle) / ParticleEmitter.EllipsePerspectiveModifier); particleEmitterGroundRedFire.createParticles(-randDirection * 200, -randDirection * 300 - new Vector2(0, 800), particleEmitterGroundFire.GroundPos + new Vector2(This.Game.rand.Next(-60, 60), 0), 20, 200); } } //Deal Damage if (i == 107) { Damage(attacker, target, baseDamage / 2); DOTStart = This.gameTime.TotalGameTime; } //Draw DOT and deal damage if (i > 107 && i % 18 == 0) { Damage(attacker, target, baseDamage / 35); //Create Particles for (int j = 0; j < 3; j++) { double directionAngle = This.Game.rand.NextDouble() * 2 * Math.PI; Vector2 randDirection = new Vector2((float)Math.Cos(directionAngle), (float)Math.Sin(directionAngle) / ParticleEmitter.EllipsePerspectiveModifier); Vector2 velocity = new Vector2(This.Game.rand.Next(-10, 10), -10); Vector2 acceleration = new Vector2(This.Game.rand.Next(-10, 10), -10); List<CollisionObject> collisionList = target.GetCollision(); int radius = (int)(collisionList.Count > 0 ? (collisionList[0] as Collision_BoundingCircle).Radius + 20 : 40); particleEmitterGroundFire.createParticles(velocity, acceleration, target.GroundPos + randDirection * This.Game.rand.Next(0, radius), 10f, This.Game.rand.Next(400, 800)); } //Create Particles for (int j = 0; j < 3; j++) { double directionAngle = This.Game.rand.NextDouble() * 2 * Math.PI; Vector2 randDirection = new Vector2((float)Math.Cos(directionAngle), (float)Math.Sin(directionAngle) / ParticleEmitter.EllipsePerspectiveModifier); Vector2 velocity = new Vector2(This.Game.rand.Next(-10, 10), -10); Vector2 acceleration = new Vector2(This.Game.rand.Next(-10, 10), -10); List<CollisionObject> collisionList = target.GetCollision(); int radius = (int)(collisionList.Count > 0 ? (collisionList[0] as Collision_BoundingCircle).Radius + 20 : 40); particleEmitterGroundRedFire.createParticles(velocity, acceleration, target.GroundPos + randDirection * This.Game.rand.Next(0, radius), 10f, This.Game.rand.Next(400, 800)); } } //if the attack frame has passed then allow the attacker to move if (attacker.Frame >= FrameCount - 1) { attacker.isAttackAnimDone = true; isAttackAnimDone = true; } if (!isAttackAnimDone) attacker.isAttackAnimDone = false; yield return false; } //continue drawing dot until it is expired for (int i = 0; DOTStart + new TimeSpan(0, 0, 5) > This.gameTime.TotalGameTime && ((l as FrostbyteLevel).enemies.Contains(target) || (l as FrostbyteLevel).allies.Contains(target)); i++) { if (i % 18 == 0) { Damage(attacker, target, baseDamage / 35); //Create Particles for (int j = 0; j < 3; j++) { double directionAngle = This.Game.rand.NextDouble() * 2 * Math.PI; Vector2 randDirection = new Vector2((float)Math.Cos(directionAngle), (float)Math.Sin(directionAngle) / ParticleEmitter.EllipsePerspectiveModifier); Vector2 velocity = new Vector2(This.Game.rand.Next(-10, 10), -10); Vector2 acceleration = new Vector2(This.Game.rand.Next(-10, 10), -10); List<CollisionObject> collisionList = target.GetCollision(); int radius = (int)(collisionList.Count > 0 ? (collisionList[0] as Collision_BoundingCircle).Radius + 20 : 40); particleEmitterGroundFire.createParticles(velocity, acceleration, target.GroundPos + randDirection * This.Game.rand.Next(0, radius), 10f, This.Game.rand.Next(400, 800)); } //Create Particles for (int j = 0; j < 3; j++) { double directionAngle = This.Game.rand.NextDouble() * 2 * Math.PI; Vector2 randDirection = new Vector2((float)Math.Cos(directionAngle), (float)Math.Sin(directionAngle) / ParticleEmitter.EllipsePerspectiveModifier); Vector2 velocity = new Vector2(This.Game.rand.Next(-10, 10), -10); Vector2 acceleration = new Vector2(This.Game.rand.Next(-10, 10), -10); List<CollisionObject> collisionList = target.GetCollision(); int radius = (int)(collisionList.Count > 0 ? (collisionList[0] as Collision_BoundingCircle).Radius + 20 : 40); particleEmitterGroundRedFire.createParticles(velocity, acceleration, target.GroundPos + randDirection * This.Game.rand.Next(0, radius), 10f, This.Game.rand.Next(400, 800)); } } yield return false; } while (particleEmitterFire.ActiveParticleCount > 0 || particleEmitterGroundFire.ActiveParticleCount > 0 || particleEmitterGroundRedFire.ActiveParticleCount > 0) yield return false; #endregion Generate Fire Pillar particleEmitterFire.Remove(); l.RemoveSprite(particleEmitterFire); attacker.particleEmitters.Remove(particleEmitterFire); particleEmitterGroundFire.Remove(); l.RemoveSprite(particleEmitterGroundFire); attacker.particleEmitters.Remove(particleEmitterGroundFire); particleEmitterGroundRedFire.Remove(); l.RemoveSprite(particleEmitterGroundRedFire); attacker.particleEmitters.Remove(particleEmitterGroundRedFire); attacker.isAttackAnimDone = true; yield return true; }
/// <summary> /// Performs Water Push Attack /// </summary> public static IEnumerable<bool> WaterPush(OurSprite attacker, int attackFrame, Element elem = Element.Water) { #region Variables Level l = This.Game.CurrentLevel; attacker.State = SpriteState.Attacking; setAnimation(attacker); int FrameCount = attacker.FrameCount(); TimeSpan attackStartTime = This.gameTime.TotalGameTime; Effect particleEffect = l.GetEffect("ParticleSystem"); Texture2D lightning = l.GetTexture("sparkball"); Texture2D water = l.GetTexture("ice"); ParticleEmitter particleEmitter = new ParticleEmitter(5000, particleEffect, water); particleEmitter.ZOrder = 2; particleEmitter.effectTechnique = "FadeAtXPercent"; particleEmitter.effectTechnique = "FadeAtXPercent"; particleEmitter.fadeStartPercent = .98f; particleEmitter.blendState = BlendState.Additive; (particleEmitter.collisionObjects.First() as Collision_BoundingCircle).Radius = 1; (particleEmitter.collisionObjects.First() as Collision_BoundingCircle).createDrawPoints(); ParticleEmitter particleEmitterDarkBlue = new ParticleEmitter(7000, particleEffect, water); particleEmitterDarkBlue.ZOrder = 1; particleEmitterDarkBlue.effectTechnique = "FadeAtXPercent"; particleEmitterDarkBlue.fadeStartPercent = .9f; particleEmitterDarkBlue.blendState = BlendState.Additive; #endregion Variables attacker.isAttackAnimDone = false; attacker.Rewind(); if (attacker is Frostbyte.Characters.Mage) { (attacker as Frostbyte.Characters.Mage).attackTier = 2; } #region Shoot Attack while (attacker.Frame < FrameCount) { attacker.isAttackAnimDone = false; attacker.State = SpriteState.Attacking; setAnimation(attacker); FrameCount = attacker.FrameCount(); if (attacker.Frame == attackFrame) { break; } yield return false; } #endregion Shoot Attack particleEmitter.GroundPos = attacker.GroundPos; #region Generate Wave bool isAttackAnimDone = false; if (This.Game.AudioManager.PlaySoundEffect("Effects/Lightning_Strike")) { yield return false; } for (int i = 0; i < 275; i++) { (particleEmitter.collisionObjects.First() as Collision_BoundingCircle).Radius = 1 + ((float)i / 185f) * 82f; (particleEmitter.collisionObjects.First() as Collision_BoundingCircle).createDrawPoints(); // Ground Spread if (i < 150) { for (int j = 0; j < 2; j++) { double directionAngle = This.Game.rand.NextDouble() * 2 * Math.PI; Vector2 randDirection = new Vector2((float)Math.Cos(directionAngle), (float)Math.Sin(directionAngle) / ParticleEmitter.EllipsePerspectiveModifier); particleEmitterDarkBlue.createParticles(randDirection * 10, randDirection * 10, particleEmitter.GroundPos + randDirection * This.Game.rand.Next(0, 20), 15, This.Game.rand.Next(3500, 3800)); } } // Ground Spread for (int j = 0; j < 5; j++) { double directionAngle = This.Game.rand.NextDouble() * 2 * Math.PI; Vector2 randDirection = new Vector2((float)Math.Cos(directionAngle), (float)Math.Sin(directionAngle) / ParticleEmitter.EllipsePerspectiveModifier); particleEmitterDarkBlue.createParticles(new Vector2(0, -100), new Vector2(This.Game.rand.Next(-50, 50), -100), particleEmitter.GroundPos + randDirection * (particleEmitter.collisionObjects.First() as Collision_BoundingCircle).Radius, 10, This.Game.rand.Next(800, 1200)); } //Deal Damage int count = 0; if (Collision.CollisionData.Count > 0) { List<Tuple<CollisionObject, WorldObject, CollisionObject>> collidedWith; Collision.CollisionData.TryGetValue(particleEmitter, out collidedWith); if (collidedWith != null) { foreach (Tuple<CollisionObject, WorldObject, CollisionObject> detectedCollision in collidedWith) { if (((detectedCollision.Item2 is Enemy) && (attacker is Player)) || ((detectedCollision.Item2 is Player) && (attacker is Enemy))) { count++; Slow((detectedCollision.Item2 as OurSprite), 0.0f, new TimeSpan(0, 0, 1)); if (count >= 4) break; } } } } //if the attack frame has passed then allow the attacker to move if (attacker.Frame >= FrameCount - 1) { attacker.isAttackAnimDone = true; isAttackAnimDone = true; } if (!isAttackAnimDone) attacker.isAttackAnimDone = false; yield return false; } #endregion Generate Lightning Strike and Ground Spread and Deal Damage while (particleEmitter.ActiveParticleCount > 0 || particleEmitterDarkBlue.ActiveParticleCount > 0) { yield return false; } particleEmitter.Remove(); l.RemoveSprite(particleEmitter); attacker.particleEmitters.Remove(particleEmitter); particleEmitterDarkBlue.Remove(); l.RemoveSprite(particleEmitterDarkBlue); attacker.particleEmitters.Remove(particleEmitterDarkBlue); attacker.isAttackAnimDone = true; yield return true; }
/// <summary> /// Performs Ground Clap Attack /// </summary> /// <param name="_target"></param> /// <param name="attacker"></param> /// <param name="baseDamage"></param> /// <param name="attackFrame"></param> /// <param name="elem"></param> /// <returns></returns> public static IEnumerable<bool> RockShower(Sprite _target, OurSprite attacker, int baseDamage, int attackFrame, Element elem = Element.Earth) { if (_target == null) { yield return true; } #region Variables Level l = This.Game.CurrentLevel; OurSprite target = (OurSprite)_target; Vector2 initialDirection = attacker.Direction; attacker.State = SpriteState.Attacking; setAnimation(attacker); int FrameCount = attacker.FrameCount(); TimeSpan attackStartTime = This.gameTime.TotalGameTime; List<CollisionObject> collisions = target.GetCollision(); Effect particleEffectDust = l.GetEffect("ParticleSystem"); Texture2D earthquake = l.GetTexture("earthquake"); ParticleEmitter particleEmitterDust = new ParticleEmitter(500, particleEffectDust, earthquake); particleEmitterDust.effectTechnique = "NoSpecialEffect"; particleEmitterDust.blendState = BlendState.AlphaBlend; Collision_BoundingCircle c = (particleEmitterDust.collisionObjects.First() as Collision_BoundingCircle); c.Radius = collisions.Count > 0 ? (collisions[0] as Collision_BoundingCircle).Radius + 20 : 100; c.createDrawPoints(); particleEmitterDust.ZOrder = 10; Effect particleEffectRocks = l.GetEffect("ParticleSystem"); Texture2D boulder = l.GetTexture("boulder"); ParticleEmitter particleEmitterRocks = new ParticleEmitter(4000, particleEffectRocks, boulder); particleEmitterRocks.effectTechnique = "NoSpecialEffect"; particleEmitterRocks.blendState = BlendState.AlphaBlend; c = (particleEmitterRocks.collisionObjects.First() as Collision_BoundingCircle); c.Radius = collisions.Count > 0 ? (collisions[0] as Collision_BoundingCircle).Radius + 20 : 100; c.createDrawPoints(); float rockParticleEmitterRadius = c.Radius; particleEmitterRocks.ZOrder = 1; #endregion Variables attacker.isAttackAnimDone = false; attacker.Rewind(); if (attacker is Frostbyte.Characters.Mage) { (attacker as Frostbyte.Characters.Mage).attackTier = 3; } #region Shoot Attack while (attacker.Frame < FrameCount) { attacker.isAttackAnimDone = false; if (target.GroundPos != attacker.GroundPos) attacker.Direction = target.GroundPos - particleEmitterDust.GroundPos; attacker.State = SpriteState.Attacking; setAnimation(attacker); FrameCount = attacker.FrameCount(); if (attacker.Frame == attackFrame) { break; } yield return false; } #endregion Shoot Attack #region Generate Rock Shower bool isAttackAnimDone = false; for (int i = 0; i < 165; i++) { particleEmitterDust.GroundPos = target.GroundPos; particleEmitterRocks.GroundPos = target.GroundPos; // Dust Cloud for (int j = 0; j < rockParticleEmitterRadius / 8; j++) { double directionAngle = This.Game.rand.NextDouble() * 2 * Math.PI; Vector2 randDirection = new Vector2((float)Math.Cos(directionAngle), (float)Math.Sin(directionAngle) / ParticleEmitter.EllipsePerspectiveModifier); particleEmitterDust.createParticles(new Vector2(0, -6), new Vector2(0, -5), particleEmitterDust.GroundPos + new Vector2(0, -175) + randDirection * This.Game.rand.Next(0, (int)(rockParticleEmitterRadius * 1.4f)), 15f, This.Game.rand.Next(300, 1200)); } // Rock Shower for (int j = 0; j < rockParticleEmitterRadius / 8; j++) { double directionAngle = This.Game.rand.NextDouble() * 2 * Math.PI; Vector2 randDirection = new Vector2((float)Math.Cos(directionAngle), (float)Math.Sin(directionAngle) / ParticleEmitter.EllipsePerspectiveModifier); particleEmitterRocks.createParticles(new Vector2(0, 275), new Vector2(10, 50), particleEmitterRocks.GroundPos + new Vector2(0, -175) + randDirection * This.Game.rand.Next(0, (int)rockParticleEmitterRadius), 5f, This.Game.rand.Next(300, 600)); } //Deal Damage if (5 - i % 15 == 0 && Collision.CollisionData.Count > 0) { Damage(attacker, target, baseDamage); Slow(target, 0.5f, new TimeSpan(0, 0, 1)); } //if the attack frame has passed then allow the attacker to move if (attacker.Frame >= FrameCount - 1) { attacker.isAttackAnimDone = true; isAttackAnimDone = true; } if (!isAttackAnimDone) attacker.isAttackAnimDone = false; yield return false; } while (particleEmitterDust.ActiveParticleCount > 0 || particleEmitterRocks.ActiveParticleCount > 0) yield return false; #endregion Generate Rock Shower particleEmitterDust.Remove(); l.RemoveSprite(particleEmitterDust); attacker.particleEmitters.Remove(particleEmitterDust); particleEmitterRocks.Remove(); l.RemoveSprite(particleEmitterRocks); attacker.particleEmitters.Remove(particleEmitterRocks); attacker.isAttackAnimDone = true; yield return true; }
/// <summary> /// Performs Lightning Tiers 2 & 3 Attack /// </summary> /// <param name="_target">The target for the projectile to attack</param> /// <param name="_attacker">The sprite initiating the attack</param> /// <param name="_baseDamage">The amount of damage to inflict before constant multiplier for weakness</param> /// <param name="_attackFrame">The frame that the attack begins on</param> /// <returns>Returns true when finished</returns> public static IEnumerable<bool> LightningStrike(Sprite _target, OurSprite attacker, int baseDamage, int attackFrame, Element elem = Element.Lightning) { #region Variables Level l = This.Game.CurrentLevel; OurSprite target = (OurSprite)_target; Vector2 initialDirection = attacker.Direction; attacker.State = SpriteState.Attacking; setAnimation(attacker); int FrameCount = attacker.FrameCount(); TimeSpan attackStartTime = This.gameTime.TotalGameTime; Effect particleEffect = l.GetEffect("ParticleSystem"); Texture2D lightning = l.GetTexture("sparkball"); ParticleEmitter particleEmitter = new ParticleEmitter(10000, particleEffect, lightning); particleEmitter.ZOrder = int.MaxValue; particleEmitter.effectTechnique = "FadeAtXPercent"; particleEmitter.fadeStartPercent = .98f; particleEmitter.blendState = BlendState.Additive; (particleEmitter.collisionObjects.First() as Collision_BoundingCircle).Radius = 125; (particleEmitter.collisionObjects.First() as Collision_BoundingCircle).createDrawPoints(); Vector2 particleTopPosition; #endregion Variables attacker.isAttackAnimDone = false; attacker.Rewind(); if (attacker is Frostbyte.Characters.Mage) { (attacker as Frostbyte.Characters.Mage).attackTier = 2; } #region Shoot Attack while (attacker.Frame < FrameCount) { attacker.isAttackAnimDone = false; if (target != null && target.GroundPos != attacker.GroundPos) attacker.Direction = target.GroundPos - particleEmitter.GroundPos; attacker.State = SpriteState.Attacking; setAnimation(attacker); FrameCount = attacker.FrameCount(); if (attacker.Frame == attackFrame) { break; } yield return false; } #endregion Shoot Attack if (target != null) { particleEmitter.GroundPos = target.GroundPos; particleTopPosition = new Vector2(target.GroundPos.X, target.GroundPos.Y - 400); } else { particleEmitter.GroundPos = attacker.GroundPos + 300 * initialDirection; particleTopPosition = new Vector2(particleEmitter.GroundPos.X, particleEmitter.GroundPos.Y - 400); } #region Generate Lightning Strike and Ground Spread and Deal Damage bool isAttackAnimDone = false; if (This.Game.AudioManager.PlaySoundEffect("Effects/Lightning_Strike", .8f)) { yield return false; } for (int i = 0; i < 165; i++) { particleTopPosition = new Vector2(particleEmitter.GroundPos.X, particleEmitter.GroundPos.Y - 400); //Generate Start Position Ball for (int j = 0; j < 2; j++) { double directionAngle = This.Game.rand.NextDouble() * 2 * Math.PI; Vector2 randDirection = new Vector2((float)Math.Cos(directionAngle), (float)Math.Sin(directionAngle) / ParticleEmitter.EllipsePerspectiveModifier); particleEmitter.createParticles(randDirection * 30, -randDirection * 3, particleTopPosition, 25f, This.Game.rand.Next(100, 1200)); } // Lightning Strike if (i % 2 == 0) { for (int j = 0; j < 200; j++) { Vector2 directionToTarget = particleEmitter.GroundPos - particleTopPosition; directionToTarget.Normalize(); double directionAngle2 = This.Game.rand.NextDouble() * 2 * Math.PI; Vector2 randDirection2 = new Vector2((float)Math.Cos(directionAngle2), (float)Math.Sin(directionAngle2)); particleTopPosition += directionToTarget * 2 + randDirection2 * 3; particleEmitter.createParticles(Vector2.Zero, Vector2.Zero, particleTopPosition, 8f, 85); } } // Ground Spread for (int j = 0; j < 30; j++) { double directionAngle = This.Game.rand.NextDouble() * 2 * Math.PI; Vector2 randDirection = new Vector2((float)Math.Cos(directionAngle), (float)Math.Sin(directionAngle) / ParticleEmitter.EllipsePerspectiveModifier); particleEmitter.createParticles(randDirection * 170, -randDirection * 90, particleEmitter.GroundPos, 2f, This.Game.rand.Next(400, 1500)); } //Deal Damage int count = 0; if (5 - i % 15 == 0 && Collision.CollisionData.Count > 0) { List<Tuple<CollisionObject, WorldObject, CollisionObject>> collidedWith; Collision.CollisionData.TryGetValue(particleEmitter, out collidedWith); if (collidedWith != null) { foreach (Tuple<CollisionObject, WorldObject, CollisionObject> detectedCollision in collidedWith) { if (((detectedCollision.Item2 is Enemy) && (attacker is Player)) || ((detectedCollision.Item2 is Player) && (attacker is Enemy))) { count++; Damage(attacker, (detectedCollision.Item2 as OurSprite), baseDamage); } if (count >= 4) break; } } } //if the attack frame has passed then allow the attacker to move if (attacker.Frame >= FrameCount - 1) { attacker.isAttackAnimDone = true; isAttackAnimDone = true; } if (!isAttackAnimDone) attacker.isAttackAnimDone = false; yield return false; } #endregion Generate Lightning Strike and Ground Spread and Deal Damage while (particleEmitter.ActiveParticleCount > 0) { yield return false; } particleEmitter.Remove(); l.RemoveSprite(particleEmitter); attacker.particleEmitters.Remove(particleEmitter); attacker.isAttackAnimDone = true; yield return true; }
/// <summary> /// Performs a Lightning strike between two sprites. Collides with anything in the path of the bolt. /// </summary> /// <param name="_target">The target for the projectile to attack</param> /// <param name="_attacker">The sprite initiating the attack</param> /// <param name="_baseDamage">The amount of damage to inflict before constant multiplier for weakness</param> /// <param name="_attackFrame">The frame that the attack begins on</param> /// <returns>Returns true when finished</returns> public static IEnumerable<bool> LightningSpan(Sprite target, OurSprite attacker, int baseDamage, int attackFrame, Element elem=Element.Lightning, AttackRotation rotation=AttackRotation.None) { #region Variables Level l = This.Game.CurrentLevel; Vector2 initialDirection = attacker.Direction; setAnimation(attacker); int FrameCount = attacker.FrameCount(); TimeSpan attackStartTime = This.gameTime.TotalGameTime; Effect particleEffect = l.GetEffect("ParticleSystem"); Texture2D lightning = l.GetTexture("sparkball"); ParticleEmitter particleEmitter = new ParticleEmitter(10000, particleEffect, lightning); particleEmitter.ZOrder = int.MaxValue; particleEmitter.effectTechnique = "FadeAtXPercent"; particleEmitter.fadeStartPercent = .5f; particleEmitter.blendState = BlendState.Additive; particleEmitter.collisionObjects.Clear(); particleEmitter.GroundPos = target.CenterPos; #region Create Lightning Collision Objects int collisionRadius = 20; Vector2 spanDirection = attacker.CenterPos - particleEmitter.GroundPos; spanDirection.Normalize(); for (int x = 0; x < Vector2.Distance(particleEmitter.GroundPos, attacker.CenterPos); x += collisionRadius * 2) { particleEmitter.collisionObjects.Add(new Collision_BoundingCircle(x, x * spanDirection, 1.5f * collisionRadius)); } #endregion Vector2 particleTopPosition; #endregion Variables attacker.isAttackAnimDone = false; attacker.Rewind(); if (attacker is Frostbyte.Characters.Mage) { (attacker as Frostbyte.Characters.Mage).attackTier = 2; } #region Shoot Attack while (attacker.Frame < FrameCount) { attacker.isAttackAnimDone = false; if (target != null && target.CenterPos != attacker.CenterPos) attacker.Direction = target.CenterPos - particleEmitter.CenterPos; attacker.State = SpriteState.Attacking; setAnimation(attacker); FrameCount = attacker.FrameCount(); if (attacker.Frame == attackFrame) { break; } yield return false; } #endregion Shoot Attack if (target != null) { particleEmitter.GroundPos = target.CenterPos; particleTopPosition = new Vector2(target.CenterPos.X, target.CenterPos.Y - 400); } else { particleEmitter.GroundPos = attacker.CenterPos + 300 * initialDirection; particleTopPosition = new Vector2(particleEmitter.CenterPos.X, particleEmitter.CenterPos.Y - 400); } #region Generate Lightning Strike and Deal Damage bool isAttackAnimDone = false; if (This.Game.AudioManager.PlaySoundEffect("Effects/Lightning_Strike", .8f)) { yield return false; } for (int i = 0; i < 165; i++) { particleTopPosition = attacker.CenterPos; if (rotation != AttackRotation.None) { #region Rotate Span float rotateRadius = Vector2.Distance(particleEmitter.GroundPos, particleTopPosition); double angle = Math.Atan2(spanDirection.Y, spanDirection.X); double angleOffset = Math.PI / 2 / 165; if (rotation == AttackRotation.Clockwise) { angle += angleOffset; } else if (rotation == AttackRotation.CounterClockwise) { angle -= angleOffset; } angle = ((angle + 2 * Math.PI) % (2 * Math.PI)) - Math.PI; // Ensure it's between 0 and 2PI particleEmitter.collisionObjects.Clear(); particleEmitter.GroundPos = attacker.CenterPos + rotateRadius * new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle)); spanDirection = attacker.CenterPos - particleEmitter.GroundPos; spanDirection.Normalize(); for (int x = 0; x < rotateRadius; x += collisionRadius * 2) { particleEmitter.collisionObjects.Add(new Collision_BoundingCircle(x, x * spanDirection, 1.5f * collisionRadius)); } #endregion Rotate Span } // Lightning Strike if (i % 13 == 0) { for (int j = 0; j < 200; j++) { Vector2 directionToTarget = particleEmitter.GroundPos - particleTopPosition; directionToTarget.Normalize(); double directionAngle2 = This.Game.rand.NextDouble() * 2 * Math.PI; Vector2 randDirection2 = new Vector2((float)Math.Cos(directionAngle2), (float)Math.Sin(directionAngle2)); particleTopPosition += directionToTarget * 2 + randDirection2 * 3; particleEmitter.createParticles(randDirection2 * 10, -randDirection2 * 20, particleTopPosition, 8f, 600); } } //Deal Damage if (i % 20 == 0 && Collision.CollisionData.Count > 0) { List<Tuple<CollisionObject, WorldObject, CollisionObject>> collidedWith; Collision.CollisionData.TryGetValue(particleEmitter, out collidedWith); if (collidedWith != null) { HashSet<WorldObject> hitObjects = new HashSet<WorldObject>(); foreach (Tuple<CollisionObject, WorldObject, CollisionObject> detectedCollision in collidedWith) { if (((detectedCollision.Item2 is Enemy) && (attacker is Player)) || ((detectedCollision.Item2 is Player) && (attacker is Enemy))) { hitObjects.Add(detectedCollision.Item2); } } foreach (WorldObject obj in hitObjects) { Damage(attacker, (obj as OurSprite), baseDamage); } } } yield return false; } #endregion Generate Lightning Strike and Deal Damage while (particleEmitter.ActiveParticleCount > 0) { #region Rotate Span float rotateRadius = Vector2.Distance(particleEmitter.GroundPos, particleTopPosition); double angle = Math.Atan2(spanDirection.Y, spanDirection.X); double angleOffset = Math.PI / 2 / 165; if (rotation == AttackRotation.Clockwise) { angle += angleOffset; } else if (rotation == AttackRotation.CounterClockwise) { angle -= angleOffset; } angle = ((angle + 2 * Math.PI) % (2 * Math.PI)) - Math.PI; // Ensure it's between 0 and 2PI particleEmitter.collisionObjects.Clear(); particleEmitter.GroundPos = attacker.CenterPos + rotateRadius * new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle)); spanDirection = attacker.CenterPos - particleEmitter.GroundPos; spanDirection.Normalize(); for (int x = 0; x < rotateRadius; x += collisionRadius * 2) { particleEmitter.collisionObjects.Add(new Collision_BoundingCircle(x, x * spanDirection, 1.5f * collisionRadius)); } #endregion Rotate Span yield return false; } //if the attack frame has passed then allow the attacker to move if (attacker.Frame >= FrameCount - 1) { attacker.isAttackAnimDone = true; isAttackAnimDone = true; } if (!isAttackAnimDone) attacker.isAttackAnimDone = false; particleEmitter.Remove(); l.RemoveSprite(particleEmitter); attacker.particleEmitters.Remove(particleEmitter); attacker.isAttackAnimDone = true; yield return true; }