public void CheckAndApplyEffect(PhysicalBody other, TimeSpan time)
 {
     if (Exploding && _explodeTimer > TimeSpan.Zero)
     {
         _destroyEffect.TryApply(_destroyPosition, other, time);
         _explodeTimer -= time;
     }
 }
 public void CheckCollisions(GameTime gameTime, PhysicalBody unit)
 {
     foreach (IConsumable item in _slots)
     {
         if (item is ProjectileWeapon)
         {
             (item as ProjectileWeapon).CheckAndApplyCollision(unit, gameTime.ElapsedGameTime);
         }
     }
 }
 public override void CheckAndApplyCollision(PhysicalBody unit, TimeSpan time)
 {
     if (_hookState == HookState.Fired || _hookState == HookState.Retracting)
     {
         if (XnaHelper.RectsCollide(_hookHitRect, unit.HitRect))
         {
             _hookedUnit = unit;
             _hookState = HookState.Attached;
         }
     }
 }
        public override void CheckAndApplyCollision(PhysicalBody unit, TimeSpan time)
        {
            if (!_firing || !unit.Collides)
                return;     //don't check collisions if not firing

            float fireAngle = XnaHelper.RadiansFromVector(_fireDirection);
            if (XnaHelper.RectangleIntersectsArc(unit.HitRect, _owner.Center, _range, fireAngle, _hitArc))
            {
                _tempVector = unit.Center - _owner.Center;
                _tempVector.Normalize();
                unit.ApplyImpact(_force * _tempVector, 1);
                unit.ApplyDamage(_damage);
            }
        }
 /// <summary>
 /// Check if target unit is in range. If so, apply force and damage
 /// </summary>
 /// <param name="effectPos">origin of effect</param>
 /// <param name="target">target unit</param>
 public void TryApply(Vector2 effectPos, PhysicalBody target, TimeSpan time)
 {
     if (utility.XnaHelper.RectangleIntersectsCircle(target.HitRect, effectPos, _radius))
     {
         tempVec.X = target.Position.X - effectPos.X;
         tempVec.Y = target.Position.Y - effectPos.Y;
         Vector2.Normalize(tempVec);
         float factor = Duration == TimeSpan.Zero ? 1 : (float)time.TotalSeconds / (float)Duration.TotalSeconds;
         target.ApplyForce(_force * factor * tempVec);
         target.ApplyDamage((_damage * factor));
         target.ApplyStatus(_statEffects);
     }
 }
        public void CheckAndApplyCollision(PhysicalBody u, TimeSpan time)
        {
            if (!u.Collides)
                return;

            switch (_state)
            {
                case State.Dormant:
                    break;
                case State.Moving:
                    if (u.HitRect.Intersects(_hitRect))
                    {
                        if (_penetration != -1)
                        {
                            _penetration -= 1;
                            if (_penetration <= 0)
                                _state = State.JustHit;
                        }
                        u.ApplyImpact(_velocity, _mass);
                    }
                    _proximityEffect.TryApply(_position, u, time);
                    break;
                case State.JustHit:
                    break;
                case State.ApplyContactEffect:
                    _contactEffect.TryApply(_position, u, time);
                    break;
                case State.ReachedDestination:
                    _destinationEffect.TryApply(_position, u, time);
                    break;
                default:
                    break;
            }
        }
 /// <summary>
 /// Check if weapon is hitting a target, and apply its affects if so
 /// Call during the update loop on each unit
 /// </summary>
 /// <param name="unit"></param>
 public abstract void CheckAndApplyCollision(PhysicalBody unit, TimeSpan time);
        public virtual void CheckAndApplyUnitCollision(PhysicalBody other)
        {
            if (!Collides)
                return;     //don't check collision if unit shouldn't collide
            //special shattered collision detection
            if (_lifeState == LifeState.Shattered)
            {
                tempRec.Width = _hitRect.Width / c_shatterDivisions;
                tempRec.Height = _hitRect.Height / c_shatterDivisions;
                for (int i = 0; i < c_shatterDivisions ; i++)
                    for (int j = 0; j < c_shatterDivisions; j++)
                    {
                        tempRec.X = (int)(_fragments[i,j].Position.X - tempRec.Width / 2);
                        tempRec.Y = (int)(_fragments[i,j].Position.Y - tempRec.Height / 2);
                        if (tempRec.Intersects(other.HitRect))
                        {
                            Vector2 fVel = _fragments[i, j].Velocity;
                            float fMass = (float)Mass / (c_shatterDivisions * c_shatterDivisions);
                            temp = other.Velocity;
                            other._velocity = (other._velocity * (other.Mass - fMass) + 2 * fMass * fVel) /
                                                (fMass + other.Mass);
                            _fragments[i,j].Velocity = (fVel * (fMass - other.Mass) + 2 * other.Mass * temp) /
                                                (fMass + other.Mass);
                        }
                    }
                return; //ignore normal collision detection
            }

            //check if fire should be transferred
            float dist = XnaHelper.DistanceBetweenRects(HitRect, other.HitRect);
            if (dist < FIRE_SPREAD_DISTANCE)
            {
                if (_statusEffects.Fire > other._statusEffects.Fire)
                {
                    StatEffect transfer = new StatEffect() { Fire = FIRE_SPREAD_FACTOR * dist / FIRE_SPREAD_DISTANCE * _statusEffects.Fire };
                    other.ApplyStatus(transfer);
                    ApplyStatus(transfer * -FIRE_SPREAD_LOSS);
                }
            }

            if (XnaHelper.RectsCollide(HitRect, other.HitRect))
            {
                temp = other._velocity; //temp is a static reusable vector

                other._velocity = (other._velocity * (other.Mass - this.Mass) + 2 * this.Mass * this._velocity) /
                                    (this.Mass + other.Mass);
                this._velocity = (this._velocity * (this.Mass - other.Mass) + 2 * other.Mass * temp) /
                                    (this.Mass + other.Mass);
            }
        }
        public override void CheckAndApplyCollision(PhysicalBody unit, TimeSpan time)
        {
            if (!unit.Collides)
                return;

            foreach (Projectile p in _projectiles)
            {
                p.CheckAndApplyCollision(unit, time);
            }
        }
        /// <summary>
        /// Apply Gravity on a unit and eat it if close enough
        /// call on each unit during unit update loop
        /// </summary>
        /// <param name="unit">unit to affect. Should be called after updating unit</param>
        public void ApplyToUnit(PhysicalBody unit, GameTime gameTime)
        {
            float massEaten;
            if (_state != BlackHoleState.Pulling && _state != BlackHoleState.Overdrive)
                return;
            if (_state == BlackHoleState.Pulling)
            {
                unit.ApplyGravity(Gravity, gameTime);
            }
            else if (_state == BlackHoleState.Overdrive)
            {
                unit.FlyToPoint(Position, _overdriveTimer, 2.0f);
            }

            if ((massEaten = unit.EatByBlackHole(Position, _radius)) > 0)
            {
                _capacityUsed += massEaten;
                _particleEffect.IntensityFactor = 1.0f + _capacityUsed / _totalCapacity;
                Gravity.MagnitudeFactor = (1.0f + _capacityUsed / _totalCapacity);
                if (_capacityUsed > _totalCapacity)
                {
                    goOverdrive();
                }
            }
        }
 public void CheckAndApplyCollision(PhysicalBody unit, GameTime gameTime)
 {
     switch (_state)
     {
         case State.Dormant:
             break;
         case State.Appearing:
         case State.Scanning:
             unit.ApplyGravity(_gravity, gameTime);
             break;
         case State.Charging:
             unit.ApplyGravity(_gravity, gameTime);
             if (willCollide(unit.Top, unit.Bottom, unit.Left, unit.Right, gameTime.ElapsedGameTime))
             {
                 unit.ApplyImpact(_velocity, IMPACT_IMPULSE);
                 unit.ApplyDamage(IMPACT_DAMAGE);
                 break;
             }
             break;
     }
 }