Example #1
0
        /// <summary>
        /// Kicks the penalty kick.
        /// 罚点球
        /// </summary>
        public unsafe override void Start()
        {
            #region 站位回合
            var random = manager.Match;
            // 当前回合加1
            manager.Match.Status.Round++;
            manager.Match.Status.Break(EnumMatchBreakState.PenaltyKick);
            #region 找出罚球人-> 找出离球最近的人
            // 找出罚球人,罚球人为任意球属性最高的球员(不包含守门员)
            IPlayer takeKickPlayer = MatchRule.GetHighestPropertyPlayer(manager, PlayerProperty.FreeKick);
            if (takeKickPlayer == null) // 没有可以罚球的人,跳出逻辑
            {
                return;
            }

            takeKickPlayer.Status.Hasball = true;

            #endregion

            // 罚球人站到球面前
            takeKickPlayer.Status.ForceState(IdleState.Instance);
            takeKickPlayer.MoveTo(point);
            takeKickPlayer.Rotate((manager.Side == Side.Home) ? manager.Match.Pitch.AwayGoal : manager.Match.Pitch.HomeGoal);

            #region 防守方移动至防守位置
            var region = (manager.Side == Side.Home) ? manager.Match.Pitch.AwayPenaltyRegion : manager.Match.Pitch.HomePenaltyRegion;
            foreach (IPlayer p in takeKickPlayer.Manager.Opponent.Players)
            {
                Coordinate coor;
                if (p.Input.AsPosition != Position.Goalkeeper)
                {
                    coor = CloseMove(p.Status.HalfDefault.X, p.Status.HalfDefault.Y);
                }
                else
                {
                    coor = p.Status.Default;
                }

                if (p.Input.AsPosition == Position.Fullback) // 将防守人移动至禁区线上
                {
                    if (region.Start.X == 0)
                    {
                        coor = new Coordinate(region.End.X, coor.Y);
                    }
                    else
                    {
                        coor = new Coordinate(region.Start.X, coor.Y);
                    }
                }

                p.Status.ForceState(IdleState.Instance);
                p.MoveTo(coor);
                p.Rotate(point);
            }
            #endregion

            #region 进攻方除罚球人移动至进攻位置
            foreach (IPlayer p in takeKickPlayer.Manager.Players)
            {
                if (p.ClientId == takeKickPlayer.ClientId)
                {
                    continue;
                }
                if (p.Input.AsPosition == Position.Goalkeeper)
                {
                    p.MoveTo(p.Status.Default);
                    p.Rotate(point);
                    p.Status.ForceState(IdleState.Instance);
                    continue;
                }

                double x = (p.Manager.Side == Side.Home) ? p.Status.HalfDefault.X * 1.6 : p.Status.HalfDefault.X * 1.6 - Defines.Pitch.MAX_WIDTH * 0.6;
                double y = p.Status.HalfDefault.Y;
                y = random.RandomBool() ? y + 5 : y - 5;

                Coordinate coor = CloseMove(x, y);

                p.Status.ForceState(IdleState.Instance);
                p.MoveTo(coor);
                p.Rotate(point);
            }
            #endregion

            #region 防止除罚球人外任何人进入禁区
            foreach (IManager m in manager.Match.Managers)
            {
                foreach (IPlayer player in m.Players)
                {
                    if (player.ClientId == takeKickPlayer.ClientId)
                    {
                        continue;
                    }

                    if (player.Input.AsPosition == Position.Goalkeeper)
                    {
                        continue;
                    }

                    if (region.IsCoordinateInRegion(player.Current))
                    {
                        if (region.Start.X == 0)
                        {
                            player.MoveTo(region.End.X, player.Current.Y);
                        }
                        else
                        {
                            player.MoveTo(region.Start.X, player.Current.Y);
                        }
                    }
                }
            }

            #endregion

            // 停顿时间
            for (int i = 0; i < 4; i++)
            {
                manager.Match.SaveRpt();
                manager.Match.Status.Round++;
                manager.Match.RoundInit();
            }

            #endregion

            #region 开球回合
            takeKickPlayer.Status.ForceState(VolleyShootState.Instance);
            takeKickPlayer.AddFinishingBuff(1);
            takeKickPlayer.Action();

            IPlayer gk = manager.Opponent.GetPlayersByPosition(Position.Goalkeeper)[0];
            gk.QuickDecide();
            gk.Action();
            manager.Match.SaveRpt();
            #endregion
        }
        /// <summary>
        /// Starts a free kick.
        /// </summary>
        public unsafe override void Start()
        {
            #region 站位回合
            var random = manager.Match;
            // 当前回合加1
            manager.Match.Status.Round++;
            manager.Match.RoundInit();
            manager.Match.Status.Break(EnumMatchBreakState.DirectKick);
            // 射门目标
            Coordinate target = (manager.Side == Side.Home) ? manager.Match.Pitch.AwayGoal : manager.Match.Pitch.HomeGoal;
            // 已经移动位置后的球员列表
            List <IPlayer> finArray = new List <IPlayer>(Defines.Match.MAX_PLAYER_COUNT * 2);

            #region  罚球人相关
            // 找出罚球人,罚球人为任意球属性最高的球员(不包含守门员)
            IPlayer takeKickPlayer = MatchRule.GetHighestPropertyPlayer(manager, PlayerProperty.FreeKick);
            if (takeKickPlayer == null) // 如果没有可以罚球的球员,返回
            {
                return;
            }
            takeKickPlayer.Status.Hasball = true;
            finArray.Add(takeKickPlayer);

            // 罚球人站到球面前
            takeKickPlayer.Status.ForceState(IdleState.Instance);
            takeKickPlayer.MoveTo(point);
            takeKickPlayer.Rotate(point);
            #endregion

            #region 找出人墙区
            const int distance   = 20; // 离人墙的距离
            const int pDistance  = 5;  // 人墙间的距离
            const int pDistanceY = 10;

            double xdiff = point.X - target.X;
            double ydiff = point.Y - target.Y;
            if (xdiff == 0)
            {
                xdiff = 1;
            }
            if (ydiff == 0)
            {
                ydiff = 5;                             //ydiff = 1;
            }
            double tDistance = target.Distance(point); // 总距离
            double l         = xdiff / -ydiff;         // 斜率

            double x0 = point.X - xdiff / tDistance * distance;
            double y0 = point.Y - ydiff / tDistance * distance;

            #region 填充人墙坐标
            int wallPlayerCount          = random.RandomBool() ? 2 : 3;
            List <Coordinate> wallPoints = new List <Coordinate>(wallPlayerCount);
            if (wallPlayerCount == 2)
            {
                double x = x0 - pDistance / 2 * xdiff / tDistance;
                double y = y0 + pDistanceY / 2 * ydiff / tDistance;
                wallPoints.Add(new Coordinate(x, y));

                x = x0 + pDistance / 2 * xdiff / tDistance;
                y = y0 - pDistanceY / 2 * ydiff / tDistance;
                wallPoints.Add(new Coordinate(x, y));
            }
            else
            { // wall player count = 3
                double x = x0 - pDistance * xdiff / tDistance;
                double y = y0 + pDistanceY * ydiff / tDistance;
                wallPoints.Add(new Coordinate(x, y));

                x = x0;
                y = y0;
                wallPoints.Add(new Coordinate(x, y));

                x = x0 + pDistance * xdiff / tDistance;
                y = y0 - pDistanceY * ydiff / tDistance;
                wallPoints.Add(new Coordinate(x, y));
            }

            #endregion

            #region 摆人墙

            // 从防守方找出离球最近的人摆人墙
            double *       defenders = stackalloc double[Defines.Match.MAX_PLAYER_COUNT - 1];
            List <IPlayer> array     = new List <IPlayer>(Defines.Match.MAX_PLAYER_COUNT - 1);
            int            length    = 0;
            foreach (var p in manager.Opponent.Players)
            {
                if (p.SkillLock)
                {
                    continue;
                }
                if (p.Input.AsPosition == Position.Goalkeeper ||
                    p.Input.AsPosition == Position.Forward)
                {
                    continue;
                }
                defenders[length] = p.Current.SimpleDistance(point);
                array.Add(p);
                length++;
            }
            int[] indexes = Utility.SortMinDoubleArrayIndexQuick(defenders, length);
            for (int i = 0; i < wallPlayerCount; i++)
            {
                if (i >= array.Count)
                {
                    continue;                   // 修正人墙人数不够引发异常
                }
                Coordinate p = wallPoints[i];
                array[indexes[i]].MoveTo(p);
                finArray.Add(array[indexes[i]]);
            }

            #endregion

            #endregion

            #region 防守方剩余球员站位
            foreach (var p in manager.Opponent.Players)
            {
                if (p.SkillLock)
                {
                    continue;
                }
                if (!finArray.Contains(p))
                {
                    if (p.Input.AsPosition == Position.Goalkeeper)
                    {
                        p.MoveTo(p.Status.Default);
                    }
                    else
                    {
                        p.MoveTo(CloseMove(p.Status.HalfDefault.X, p.Status.HalfDefault.Y));
                    }
                }
                p.Status.ForceState(IdleState.Instance);
                p.Rotate(manager.Match.Football.Current);
            }
            #endregion

            #region 进攻方剩余球员站位
            IPlayer lastMan = manager.Opponent.Status.LastPlayer; // 最后一个防守人
            if (null == lastMan)
            {
                lastMan = FindOutLastDefender();
            }
            foreach (var p in manager.Players)
            {
                if (p.SkillLock)
                {
                    continue;
                }

                if (p.ClientId != takeKickPlayer.ClientId)
                {
                    if (p.Input.AsPosition == Position.Goalkeeper)
                    {
                        p.MoveTo(p.Status.Default);
                    }
                    else
                    {
                        if (p.Input.AsPosition == Position.Forward)
                        {
                            // 前锋挤压阵型
                            int excursion = (manager.Side == Side.Home) ? -random.RandomInt32(0, 10) : random.RandomInt32(0, 10);
                            p.MoveTo(lastMan.Current.X + excursion, p.Status.HalfDefault.Y);
                        }
                        else
                        {
                            // 其余进攻球员
                            double x = (p.Manager.Side == Side.Home) ? p.Status.HalfDefault.X * 1.6 : p.Status.HalfDefault.X * 1.6 - Defines.Pitch.MAX_WIDTH * 0.6;
                            double y = p.Status.HalfDefault.Y;
                            p.MoveTo(CloseMove(x, y));
                        }
                    }
                }
                p.Status.ForceState(IdleState.Instance);
                p.Rotate(manager.Match.Football.Current);
            }

            #endregion

            // 停顿时间
            for (int i = 0; i < 4; i++)
            {
                manager.Match.SaveRpt();
                manager.Match.Status.Round++;
                manager.Match.RoundInit();
            }
            #endregion

            #region 开球回合
            manager.Match.RoundInit();
            takeKickPlayer.Status.ForceState(FreekickShootState.Instance);
            SkillEngine.SkillImpl.SkillFacade.TriggerPlayerSkills(takeKickPlayer, 0, true);
            takeKickPlayer.Action();

            IPlayer gk = manager.Opponent.GetPlayersByPosition(Position.Goalkeeper)[0];
            // gk.Decide();
            gk.QuickDecide();
            gk.Action();

            manager.Match.SaveRpt();
            #endregion
        }