/// <summary> /// There are two components to the drawing. The first is the data model /// which is represented by a single PlayFrame. /// /// The second is a visual overlay indicating what the user is current /// doing. /// /// This function takes the frame and 'applies' the overlay to it by /// creating a deep copy and then moving/adding items as required by /// the overlay. For this to work we need to be able to uniquely /// reference items in a playmodel by an id (as their refs change on a /// deep copy). /// </summary> /// <param name="frame"></param> /// <param name="overlay"></param> /// <param name="converter"></param> /// <returns></returns> private static PlayFrame AdjustFrameForOverlay(PlayFrame frame, VisualOverlay overlay, PitchScreenCoordConverter converter) { // Take a deep copy of the frame so that we can adjust it based on what // visual overlay is required. PlayFrame adjustableFrame = frame.Clone(); PointF pitchCoords = converter.screenToPitchCoords(overlay.MouseLocation); // First move any players who need to be. if (overlay.SelectedPlayer != null) { Player movedPlayer = adjustableFrame.GetPlayerById(overlay.SelectedPlayer.UniqueId); if (movedPlayer != null) { adjustableFrame.PlayerMovement[movedPlayer][0].FinalPosition = pitchCoords; } else { adjustableFrame.AddPlayer(overlay.SelectedPlayer, pitchCoords); } } // Either a new cut is being drawn or a cut is being moved. if (overlay.CutStart != null) { if (overlay.DrawingNewCut) { Player cuttingPlayer = adjustableFrame.GetPlayerById(overlay.CutStart.Player.UniqueId); adjustableFrame.PlayerMovement[cuttingPlayer].Add( new LinearMovement(pitchCoords, 100, cuttingPlayer)); } else { LinearMovement movedCut = adjustableFrame.GetCutById(overlay.CutStart.UniqueId); adjustableFrame.ReplaceCut(movedCut, pitchCoords); } } // Check if the user is drawing the disc movement at the moment. if (overlay.DrawingDiscMovement) { adjustableFrame.DiscFrameMovement.AbsoluteFlightPath = pitchCoords; adjustableFrame.DiscFrameMovement.HasMoved = true; } if (overlay.MovingDiscControlPoint) { adjustableFrame.DiscFrameMovement.ControlPoint = pitchCoords; } // If there is a trigger being moved then the selected trigger must have // it's position updated. if (overlay.SelectedTrigger != null) { CutRatio closestCutPoint = adjustableFrame.GetClosestCutPoint(pitchCoords, sPitchLength, overlay.SelectedTrigger.AffectedPlayer); if (closestCutPoint != null) { Trigger adjustedTrigger = adjustableFrame.GetTriggerById(overlay.SelectedTrigger.UniqueId); if (adjustedTrigger != null) { adjustedTrigger.CausingCutRatio = closestCutPoint; } } } else if (overlay.PlacingTrigger) { adjustableFrame.MaybeCreateTrigger(pitchCoords, sPitchLength, overlay.TriggerPlayer); } return adjustableFrame; }