/// <summary> /// Validate the <see cref="HoldBallState"/> to <see cref="ShootState"/>. /// </summary> /// <param name="player"><see cref="IPlayer"/></param> /// <param name="preview">Preview <see cref="IState"/></param> /// <returns>bool</returns> private static bool ValidateHoldBallToShoot(IPlayer player, IState preview) { // while the ball handler is no need to decide, can't to the shoot if (!player.Status.NeedRedecide) { return(false); } var region = (player.Side == Side.Home) ? player.Match.Pitch.AwayShootRegion : player.Match.Pitch.HomeShootRegion; if (region.IsCoordinateInRegion(player.Current)) { player.AddFinishingBuff(1); return(true); } // while the player is not in the shooting area, can't to shoot if (!player.Status.ShootStatus.ShootRegion.IsCoordinateInRegion(player.Current)) { return(false); } // while the player is in the shooting area, still need a percentage to decide shoot. 1-((射门属性/400))1/4 return(player.Match.RandomPercent() < (1 - Math.Pow(player.PropCore[PlayerProperty.Shooting] / 400, 0.25)) * 100); // return (RandomHelper.GetPercentage() < (1 - Math.Pow(player.CurrProperty[PlayerProperty.Shooting] / 400, 0.25)) * 100); }
/// <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> /// Decides the nex <see cref="IState"/> /// </summary> /// <param name="player">Represents the current <see cref="IPlayer"/>.</param> /// <param name="preview">Represents the preview <see cref="IState"/></param> /// <returns></returns> public override IState QuickDecide(IPlayer player, IState preview) { var match = player.Match; if (player.Status.Hasball == false) { return(OffBallState.Instance); } else { if (player.Status.Holdball == false) { return(ChaceState.Instance); } if (player.Status.NeedRedecide == false) { return(ActionState.Instance); } #region 处理传球来源 int round = player.Match.Status.Round; var subState = player.Status.SubState; EnumSubState subStateVal = subState.GetSubState(round); if (subStateVal == EnumSubState.LongPassAccepting || subStateVal == EnumSubState.ShortPassAccepting) { var passFrom = player.Status.PassStatus.PassFrom; if (null == passFrom) { subState.SetSubState(EnumSubState.None, round); } else { if (subStateVal == EnumSubState.LongPassAccepting) { passFrom.Status.SetDoneState(AI.States.Pass.LongPassState.Instance, SkillEngine.Extern.Enum.EnumDoneStateFlag.Succ); subState.SetSubState(EnumSubState.LongPassAccepted, round + 1); } else if (subStateVal == EnumSubState.ShortPassAccepting) { passFrom.Status.SetDoneState(AI.States.Pass.ShortPassState.Instance, SkillEngine.Extern.Enum.EnumDoneStateFlag.Succ); subState.SetSubState(EnumSubState.None, round); } } } #endregion #region 守门员传球 if (player.Input.AsPosition == Position.Goalkeeper) { return(PassState.Instance); } #endregion #region 验证射门 var shootRegion = (player.Side == Side.Home) ? player.Match.Pitch.AwayShootRegion : player.Match.Pitch.HomeShootRegion; if (shootRegion.IsCoordinateInRegion(player.Current)) { if (subStateVal != EnumSubState.HeadBall) { player.AddFinishingBuff(1); } return(ShootState.Instance); } // while the player is not in the shooting area, can't to shoot if (subStateVal == EnumSubState.HeadBall && player.PropCore.CanHeadShoot(player.Manager.Opponent.Side) || subStateVal != EnumSubState.HeadBall && player.PropCore.CanShoot(player.Manager.Opponent.Side)) { if (match.RandomPercent() < player.PropCore.ShootChooseRate()) { return(ShootState.Instance); } } #endregion if (subStateVal != EnumSubState.HeadBall) { #region 底传中 if (player.Status.IsForceCross) { if (null != player.DecideCrossTarget()) { player.DecideEnd(); return(Pass.LongPassState.Instance); } } #endregion #region 单刀球 if (Decides.Utility.IfSolo(player)) { player.SetTarget(Decides.Utility.GetSoloPosition(player)); return(Dribble.DefaultDribbleState.Instance); } #endregion } #region 验证传球 //region = (player.Side == Side.Home) ? player.Match.Pitch.AwayForcePassRegion : player.Match.Pitch.HomeForcePassRegion; //if (region.IsCoordinateInRegion(player.Current)) //{ // if (RandomHelper.GetPercentage() < 40) // { // return PassState.Instance; // } //} double rawPassRate = 0; if (player.Input.AsPosition == Position.Midfielder || player.Input.AsPosition == Position.Forward) { if (player.PropCore[PlayerProperty.Dribble] - player.PropCore[PlayerProperty.Passing] >= 18) { rawPassRate = 30; } } double passRate = player.PropCore.PassChooseRate(rawPassRate); double dribbleRate = player.PropCore.DribbleChooseRate(); if (dribbleRate >= 100 && passRate < dribbleRate) { passRate = 0; } else if (dribbleRate < 100 && passRate < 100) { passRate = (3 * passRate + 2 * (100 - dribbleRate)) / 5; } if (passRate >= 100 || passRate > 0 && match.RandomPercent() <= passRate) { if (subStateVal == EnumSubState.HeadBall) { if (null != player.DecideShortPassTarget()) { return(Pass.ShortPassState.Instance); } return(DribbleState.Instance); } return(PassState.Instance); } #endregion return(DribbleState.Instance); } }