/// <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 }