protected void RaiseBallPocketed(BallPocketedEventArgs e)
 {
     if (OnBallPocketed != null)
     {
         OnBallPocketed(this, e);
     }
 }
        protected override void CallOnBallPocketed(BallPocketedEventArgs e)
        {
            RaiseBallPocketed(e);

            if (e.Ball.BallType == BallType.Cue)
            {
                RaisePlayerScratch(new BilliardPlayEventArgs(CurrentPlayer, e.Ball));
                return;
            }

            //WriteableAllBallsInPlay.Remove(e.Ball);

            if (e.Ball.IsDeathBall && !DeathBallShotAllowed(CurrentPlayer))
            {
                RaisePlayerIllegallyPocketDeathBall(new BilliardPlayEventArgs(CurrentPlayer, e.Ball));
                return;
            }

            if (e.Ball.IsDeathBall && (CalledPocket != e.PocketIndex))
            {
                RaisePlayerIllegallyPocketDeathBall(new BilliardPlayEventArgs(CurrentPlayer, e.Ball));
                return;
            }

            if (e.Ball.BallType == BallType.Object)
            {
                RaisePlayerScored(new BilliardPlayEventArgs(CurrentPlayer, e.Ball));
            }
        }
        protected override void CallOnBallPocketed(BallPocketedEventArgs e)
        {
            RaiseBallPocketed(e);

            var args = new BilliardPlayEventArgs(CurrentPlayer, e.Ball);

            if (e.Ball.BallType == BallType.Cue)
            {
                RaisePlayerScratch(args);
                return;
            }

            //WriteableAllBallsInPlay.Remove(e.Ball);

            if (e.Ball.IsDeathBall && !DeathBallShotAllowed(CurrentPlayer))
            {
                if (IsBreak)
                {
                    RaiseBadBreak(args);
                    return;
                }
                RaisePlayerIllegallyPocketDeathBall(args);
                return;
            }

            if (e.Ball.IsDeathBall && CalledPocket != e.PocketIndex)
            {
                RaisePlayerIllegallyPocketDeathBall(args);
                return;
            }

            if (CurrentPlayer.BallAlliance == null)
            {
                var alliances = new List <BallAlliance>(new BallAlliance[] { BallAlliance.Solids, BallAlliance.Stripes });
                CurrentPlayer.BallAlliance = e.Ball.BallAlliance;
                alliances.Remove(e.Ball.BallAlliance);
                OtherPlayer.BallAlliance = alliances[0];

                RaisePlayerScored(args);
                RaiseAllianceDecided(args);
            }

            if (e.Ball.BallAlliance == CurrentPlayer.BallAlliance)
            {
                RaisePlayerScored(args);
            }
            else if (e.Ball.IsDeathBall)
            {
                //  Player pockets the death ball legally in a game where both players share one death ball.
                if (e.Ball.BallAlliance == BallAlliance.Neutral)
                {
                    RaisePlayerScored(args);
                }
                //  Player pockets opponent's death ball in a game where each player has their own death ball.
                else
                {
                    RaisePlayerIllegallyPocketDeathBall(args);
                }
            }
            else
            {
                RaisePlayerScoredForEnemy(args);
            }
        }
 /// <summary>
 /// This must be called every time any ball is pocketed.
 /// </summary>
 /// <param name="e"></param>
 protected abstract void CallOnBallPocketed(BallPocketedEventArgs e);