public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime) { bool isGlobalUpdate = msg.ReadBoolean(); if (isGlobalUpdate) { foreach (LevelWall levelWall in ExtraWalls) { if (levelWall.Body.BodyType == BodyType.Static) { continue; } Vector2 bodyPos = new Vector2( msg.ReadSingle(), msg.ReadSingle()); levelWall.MoveState = msg.ReadRangedSingle(0.0f, MathHelper.TwoPi, 16); DestructibleLevelWall destructibleWall = levelWall as DestructibleLevelWall; if (Vector2.DistanceSquared(bodyPos, levelWall.Body.Position) > 0.5f && (destructibleWall == null || !destructibleWall.Destroyed)) { levelWall.Body.SetTransformIgnoreContacts(ref bodyPos, levelWall.Body.Rotation); } } } else { int index = msg.ReadUInt16(); byte damageByte = msg.ReadByte(); if (index < ExtraWalls.Count && ExtraWalls[index] is DestructibleLevelWall destructibleWall) { destructibleWall.SetDamage(destructibleWall.MaxHealth * damageByte / 255.0f); } } }
private void CreateFragments() { #if CLIENT SoundPlayer.PlaySound("icebreak", WorldPosition); #endif //generate initial triangles (one triangle from each edge to the center of the cell) List <List <Vector2> > triangles = new List <List <Vector2> >(); foreach (var cell in Cells) { foreach (GraphEdge edge in cell.Edges) { List <Vector2> triangleVerts = new List <Vector2> { edge.Point1 + cell.Translation, edge.Point2 + cell.Translation, cell.Center }; triangles.Add(triangleVerts); } } //split triangles that have edges more than 1000 units long Pair <int, int> longestEdge = new Pair <int, int>(-1, -1); float longestEdgeLength = 0.0f; do { longestEdge.First = -1; longestEdge.Second = -1; longestEdgeLength = 0.0f; for (int i = 0; i < triangles.Count; i++) { for (int edge = 0; edge < 3; edge++) { float edgeLength = Vector2.Distance(triangles[i][edge], triangles[i][(edge + 1) % 3]); if (edgeLength > longestEdgeLength) { longestEdge.First = i; longestEdge.Second = edge; longestEdgeLength = edgeLength; } } } if (longestEdgeLength < 1000.0f) { break; } Vector2 p0 = triangles[longestEdge.First][longestEdge.Second]; Vector2 p1 = triangles[longestEdge.First][(longestEdge.Second + 1) % 3]; Vector2 p2 = triangles[longestEdge.First][(longestEdge.Second + 2) % 3]; triangles[longestEdge.First] = new List <Vector2> { p0, (p0 + p1) / 2, p2 }; triangles.Add(new List <Vector2> { (p0 + p1) / 2, p1, p2 }); } while (triangles.Count < 32); //generate fragments foreach (var triangle in triangles) { Vector2 triangleCenter = (triangle[0] + triangle[1] + triangle[2]) / 3; triangle[0] -= triangleCenter; triangle[1] -= triangleCenter; triangle[2] -= triangleCenter; Vector2 simTriangleCenter = ConvertUnits.ToSimUnits(triangleCenter); DestructibleLevelWall fragment = new DestructibleLevelWall(triangle, Color.White, Level.Loaded, giftWrap: true); fragment.Damage = fragment.MaxHealth; fragment.Body.Position = simTriangleCenter; fragment.Body.BodyType = BodyType.Dynamic; fragment.Body.FixedRotation = false; fragment.Body.LinearDamping = Rand.Range(0.2f, 0.3f); fragment.Body.AngularDamping = Rand.Range(0.1f, 0.2f); fragment.Body.GravityScale = 0.1f; fragment.Body.Mass *= 10.0f; fragment.Body.CollisionCategories = Physics.CollisionNone; fragment.Body.CollidesWith = Physics.CollisionWall; fragment.FadeOutDuration = 20.0f; Vector2 bodyDiff = simTriangleCenter - Body.Position; fragment.Body.LinearVelocity = (bodyDiff + Rand.Vector(0.5f)).ClampLength(15.0f); fragment.Body.AngularVelocity = Rand.Range(-0.5f, 0.5f);// MathHelper.Clamp(-bodyDiff.X * 0.1f, -0.5f, 0.5f); Level.Loaded.UnsyncedExtraWalls.Add(fragment); #if CLIENT for (int i = 0; i < 20; i++) { int startEdgeIndex = Rand.Int(3); Vector2 pos1 = triangle[startEdgeIndex]; Vector2 pos2 = triangle[(startEdgeIndex + 1) % 3]; var particle = GameMain.ParticleManager.CreateParticle("iceshards", triangleCenter + Vector2.Lerp(pos1, pos2, Rand.Range(0.0f, 1.0f)), Rand.Vector(Rand.Range(50.0f, 1000.0f)) + fragment.Body.LinearVelocity * 100.0f); if (particle != null) { particle.Size *= Rand.Range(1.0f, 5.0f); } } #endif } }