public void CheckAndApplyUnitCollision(PhysicalUnit 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 / ICE_DIVISIONS; tempRec.Height = _hitRect.Height / ICE_DIVISIONS; for (int i = 0; i < ICE_DIVISIONS; i++) { for (int j = 0; j < ICE_DIVISIONS; 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 / (ICE_DIVISIONS * ICE_DIVISIONS); 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); } }