internal void Die(bool callPartsChanged = true) { Health = 0; MyState = State.DESTROYED; Color = Aircraft.ControlledByPlayer ? CCColor3B.DarkGray : PlaneToDeathColor(((PlayLayer)Layer).CurrentPlaneColor); // reduce your mass (half it for now) for (int i = 0; i < MassPoints.Length; i++) { MassPoints[i].Mass /= 2; } // add a special destruction circle cloud that will follow you if (!DamageCloudTailNodes.Any()) { var dctNode = new DamageCloudTailNode(0, CCPoint.Zero); dctNode.AutoAddClouds = false; DamageCloudTailNodes.Add(dctNode); } var destructionCircleCloud = new CircleCloud(PositionWorldspace, 0, CCColor4B.White, true, (ContentSize.Width + ContentSize.Height) * GetTotalScale() + 100f, 5f); destructionCircleCloud.FollowTarget = this; DamageCloudTailNodes.First().AddCloud(destructionCircleCloud); // also kill all parts that are mounted to you foreach (var part in MountedParts) { part.Die(false); } if (callPartsChanged) { Aircraft.PartsChanged(deathPossible: true); } }
internal void ReactToHit(float damage, CCPoint collisionPos) { const float MAX_DISTANCE_FROM_COLLISION = 200f; float maxDistanceFromCollision = ((ContentSize.Width + ContentSize.Height) / 4) * GetTotalScale(); if (maxDistanceFromCollision > MAX_DISTANCE_FROM_COLLISION) { maxDistanceFromCollision = MAX_DISTANCE_FROM_COLLISION; } // generate a random point near the collisionPos // and show an effect there Random rng = new Random(); for (int tries = 0; tries < 5; tries++) { CCPoint randomPoint = Constants.RandomPointNear(collisionPos, maxDistanceFromCollision, rng); //CCPoint randomPoint = collisionPos; if (Collisions.CollidePositionPolygon(randomPoint, this) || tries == 4) // check whether the random point is inside the collision polygon { CCPoint relativePosition = randomPoint - PositionWorldspace; relativePosition = CCPoint.RotateByAngle(relativePosition, CCPoint.Zero, -Constants.CCDegreesToMathRadians(TotalRotation)); // react differently depending upon how damaged you now are float refSize = DamageToReferenceSize(damage); var damageTail = new DamageCloudTailNode(refSize, relativePosition); if (Aircraft.SelectedPower != PowerUp.PowerType.SHIELD) { if (Health / MaxHealth > 0.7f) { damageTail.AutoAddClouds = false; } if (Health / MaxHealth < 0.5f) { var planeColor = ((PlayLayer)Layer).CurrentPlaneColor; var baseFlameColor = new CCColor4B((byte)rng.Next(0, 256), 0, 0); var h = (new SKColor(planeColor.R, planeColor.G, planeColor.B)).Hue; damageTail.CloudColor = Constants.MoveHue(baseFlameColor, h); } damageTail.CloudLifeTime += (refSize - 8f) * 0.1f; } else { damageTail.AutoAddClouds = false; } DamageCloudTailNodes.Add(damageTail); break; } } // shake! if (Aircraft.ControlledByPlayer && Aircraft.SelectedPower != PowerUp.PowerType.SHIELD) { // the shake amount depends on the damage, but mostly on how the damage relates to the max health float baseRefSize = DamageToReferenceSize(damage, 10f); float specialBonus = 0f; float healthFactor = damage / MaxHealth; if (healthFactor > 1) { healthFactor = 1; } if (Health <= 0) { baseRefSize *= (1 + TotalParts.Count()) * 0.8f; specialBonus += (float)Math.Sqrt(TotalMaxHealth) * 3; } float shakeAmount = baseRefSize * 10 * healthFactor + specialBonus; ((PlayLayer)Layer).AddScreenShake(shakeAmount, shakeAmount); } }