private void GetActorIDByName(string Name, MarkingType markingType) { var combatant = _ffxivPlugin.DataRepository.GetCombatantList().FirstOrDefault(i => i.Name != null && i.ID != 0xE0000000 && i.Name.Equals(Name)); if (combatant == null) { PluginUI.Log($"未能找到{Name}"); return; } //PluginUI.Log($"BNpcID={combatant.BNpcNameID},ActorID={combatant.ID:X},markingType={markingType}"); DoMarkingByActorID(combatant.ID, markingType); }
private PlayerAction GetFreeKickAction(PlayInfo _currentPlay) { PlayerData player = _currentPlay.Attacker; PlayerAction action = PlayerAction.Pass; MarkingType marking = MarkingType.None; Zone zone = _currentPlay.AttackingTeam.GetTeamZone(_currentPlay.Zone); ActionChancePerZoneTable.Actions zoneChance = GameData.Instance.ActionChancePerZone[(int)zone]; float pass = player.GetActionChance(PlayerAction.Pass, zoneChance, marking, zone); float longPass = player.GetActionChance(PlayerAction.LongPass, zoneChance, marking, zone); float cross = player.GetActionChance(PlayerAction.Cross, zoneChance, marking, zone); float shoot = player.GetActionChance(PlayerAction.Shot, zoneChance, marking, zone); if (player.Team.IsStrategyApplicable(zone)) { Team_Strategy teamStrategy = GameData.Instance.TeamStrategies[(int)player.Team.Strategy]; pass *= teamStrategy.PassingChance; cross *= teamStrategy.CrossingChance; shoot *= teamStrategy.ShootingChance; longPass *= teamStrategy.LongPassChance; } float total = pass + longPass + cross + shoot; pass = pass / total; longPass /= total; cross = cross / total; shoot = shoot / total; List <KeyValuePair <PlayerAction, float> > list = new List <KeyValuePair <PlayerAction, float> > { new KeyValuePair <PlayerAction, float>(PlayerAction.Pass, pass), new KeyValuePair <PlayerAction, float>(PlayerAction.LongPass, longPass), new KeyValuePair <PlayerAction, float>(PlayerAction.Cross, cross), new KeyValuePair <PlayerAction, float>(PlayerAction.Shot, shoot) }; float random = Random.Range(0f, 1f); float cumulative = 0f; for (int i = 0; i < list.Count; i++) { cumulative += list[i].Value; if (random < cumulative) { action = list[i].Key; break; } } return(action); }
private void DoMarkingByActorID(uint ActorID, MarkingType markingType) { var combatant = _ffxivPlugin.DataRepository.GetCombatantList().FirstOrDefault(i => i.ID == ActorID); if (combatant == null) { PluginUI.Log($"未能找到{ActorID}"); return; } PluginUI.Log($"ActorID={ActorID:X},markingType={(int)markingType}"); var assemblyLock = Memory.Executor.AssemblyLock; var flag = false; try { Monitor.Enter(assemblyLock, ref flag); _ = Memory.CallInjected64 <char>(Offsets.MarkingFunc, Offsets.MarkingController, markingType, ActorID); } finally { if (flag) { Monitor.Exit(assemblyLock); } } }
private MarkingType GetMarkingType(PlayerData _defender, Zone _zone) { MarkingType type = MarkingType.None; float totalChance = 0f; totalChance = _defender.Prob_Marking; totalChance += (float)_defender.GetAttributeBonus(_defender.Speed) / 100; totalChance += (float)_defender.GetAttributeBonus(_defender.Vision) / 100; Zone zone = Field.Instance.GetTeamZone(_zone, _defender.Team.IsAwayTeam); if (_defender.Team.IsStrategyApplicable(zone)) { totalChance *= _defender.Team.GetStrategy().MarkingChance; } float r = Dice.Roll(20, 1, (int)Dice.RollType.None, Mathf.FloorToInt(totalChance)); if (r >= 20) { type = MarkingType.Steal; _defender.Fatigue -= GameData.Instance.GameModifiers.FatigueHigh * (25 / (float)_defender.Stamina); } else if (r > 10) { type = MarkingType.Close; } else if (r > 3) { type = MarkingType.Distance; } return(type); }
public void Clear() { jLastInactive = 0; mark = MarkingType.Clear; part = null; }
public PlayerAction GetOffensiveAction(PlayInfo _playInfo, bool _headerAvailable) { Zone zone = _playInfo.AttackingTeam.GetTeamZone(_playInfo.Zone); MarkingType _marking = _playInfo.Marking; PlayerData _player = _playInfo.Attacker; float _counterAttack = _playInfo.CounterAttack; float bonus = 0; ActionChancePerZoneTable.Actions zoneChance = GameData.Instance.ActionChancePerZone[(int)zone]; float pass = _player.GetActionChance(PlayerAction.Pass, zoneChance, _marking, zone); float longPass = _player.GetActionChance(PlayerAction.LongPass, zoneChance, _marking, zone); float dribble = _player.GetActionChance(PlayerAction.Dribble, zoneChance, _marking, zone); float cross = _player.GetActionChance(PlayerAction.Cross, zoneChance, _marking, zone); float shoot = _player.GetActionChance(PlayerAction.Shot, zoneChance, _marking, zone); float header = 0f; if (_headerAvailable) { header = _player.GetActionChance(PlayerAction.Header, zoneChance, _marking, zone); } if (_counterAttack > 0) { cross *= 1.5f; longPass *= 1.5f; } if (_player.Zone == Zone.OwnGoal) { dribble = 0; shoot = 0; header = 0; } float sprint = 0f; if (_marking == MarkingType.None) { sprint = dribble * 1.5f;; dribble = 0f; bonus = GetPlayerAttributeBonus(_player.Speed); if (Dice.Roll(20, 1, (int)Dice.RollType.None, Mathf.FloorToInt((sprint * 5) + (bonus / 10))) >= 20) { sprint *= 2f; } } float total = pass + longPass + dribble + cross + shoot + header + sprint; pass /= total; longPass /= total; dribble /= total; cross /= total; shoot /= total; header /= total; sprint /= total; List <KeyValuePair <PlayerAction, float> > list = new List <KeyValuePair <PlayerAction, float> > { new KeyValuePair <PlayerAction, float>(PlayerAction.Pass, pass), new KeyValuePair <PlayerAction, float>(PlayerAction.LongPass, longPass), new KeyValuePair <PlayerAction, float>(PlayerAction.Dribble, dribble), new KeyValuePair <PlayerAction, float>(PlayerAction.Cross, cross), new KeyValuePair <PlayerAction, float>(PlayerAction.Shot, shoot), new KeyValuePair <PlayerAction, float>(PlayerAction.Header, header), new KeyValuePair <PlayerAction, float>(PlayerAction.Sprint, sprint) }; float random = Random.Range(0.00001f, 1f); float cumulative = 0f; PlayerAction action = PlayerAction.None; for (int i = 0; i < list.Count; i++) { cumulative += list[i].Value; if (random < cumulative) { action = list[i].Key; break; } } return(action); }
public PlayInfo ResolveAction(PlayInfo _currentPlay, PlayInfo _lastPlay) { PlayInfo currentPlay = _currentPlay; PlayInfo lastPlay = _lastPlay; MarkingType marking = currentPlay.Marking; PlayerAction offensiveAction = currentPlay.OffensiveAction; if (_lastPlay != null) { if (_lastPlay.OffensiveAction == PlayerAction.Pass || _lastPlay.OffensiveAction == PlayerAction.LongPass || _lastPlay.OffensiveAction == PlayerAction.Cross) { if (CheckOffside(_currentPlay, _lastPlay)) { _currentPlay.Event = MatchEvent.Offside; _currentPlay.IsActionSuccessful = false; return(_currentPlay); } } } currentPlay = GetActionSuccess(currentPlay, lastPlay); if (currentPlay.IsActionSuccessful) { if (offensiveAction == PlayerAction.Shot || offensiveAction == PlayerAction.Header) { currentPlay.Event = MatchEvent.ShotOnGoal; } else { if (currentPlay.Event == MatchEvent.KickOff) { currentPlay.TargetZone = Zone.CM; } else { currentPlay.TargetZone = Field.Instance.GetTargetZone(currentPlay); } switch (currentPlay.OffensiveAction) { case PlayerAction.LongPass: case PlayerAction.Pass: currentPlay.Attacker.MatchStats.Passes++; currentPlay.Attacker.Team.MatchStats.Passes++; break; case PlayerAction.Cross: currentPlay.Attacker.MatchStats.Crosses++; currentPlay.Attacker.Team.MatchStats.Crosses++; if (currentPlay.AttackingTeam.GetTeamZone(currentPlay.TargetZone) == Zone.Box) { currentPlay.Attacker.MatchStats.BoxCrosses++; currentPlay.Attacker.Team.MatchStats.BoxCrosses++; } break; case PlayerAction.Dribble: currentPlay.Attacker.MatchStats.Dribbles++; break; } } } else { currentPlay.TargetZone = currentPlay.Zone; currentPlay.AttackingBonus = 1f; switch (currentPlay.OffensiveAction) { case PlayerAction.Shot: case PlayerAction.Header: currentPlay.Event = MatchEvent.ShotMissed; break; case PlayerAction.LongPass: case PlayerAction.Pass: currentPlay.Attacker.MatchStats.PassesMissed++; currentPlay.Attacker.Team.MatchStats.PassesMissed++; break; case PlayerAction.Cross: currentPlay.Attacker.MatchStats.CrossesMissed++; currentPlay.Attacker.Team.MatchStats.CrossesMissed++; break; case PlayerAction.Dribble: currentPlay.Attacker.MatchStats.DribblesMissed++; break; } if (currentPlay.Event == MatchEvent.Fault) { currentPlay.Defender.MatchStats.Faults++; currentPlay.Defender.Team.MatchStats.Faults++; } else { if (currentPlay.Defender != null) { currentPlay.CounterAttack = CheckCounterAttack(currentPlay.Defender.Team, currentPlay.DefendingTeam.GetTeamZone(currentPlay.Zone)); } } } return(currentPlay); }
public PlayInfo GetActionSuccess(PlayInfo _currentPlay, PlayInfo _lastPlay) { MatchEvent lastEvent = _lastPlay != null ? _lastPlay.Event : MatchEvent.None; PlayerData attacker = _currentPlay.Attacker; PlayerData defender = null; TeamData attackingTeam = _currentPlay.Attacker.Team; TeamData defendingTeam = null; Zone defendingZone = Zone.CM; Zone zone = _currentPlay.Zone; PlayerAction lastAction = PlayerAction.None; bool isLastActionSuccessful = false; MarkingType marking = _currentPlay.Marking; bool isTackling = false; float fault = faultChance; float agilityBonus; if (_currentPlay.Defender != null) { defender = _currentPlay.Defender; defendingTeam = _currentPlay.DefendingTeam; defendingZone = defendingTeam.GetTeamZone(zone); } _currentPlay.AttackFatigueRate = fatigueLow; _currentPlay.DefenseFatigueRate = fatigueLow; _currentPlay.AttackingBonus = 1; //_currentPlay.TargetZone = zone; if (_lastPlay != null) { lastAction = _lastPlay.OffensiveAction; isLastActionSuccessful = _lastPlay.IsActionSuccessful; if (isLastActionSuccessful) { _currentPlay.AttackingBonus = _lastPlay.AttackingBonus; } } //If attacker has no action = fail if (_currentPlay.OffensiveAction == PlayerAction.None) { _currentPlay.IsActionSuccessful = false; return(_currentPlay); } else { _currentPlay = GetOffensiveActionRolls(_currentPlay, _lastPlay); } _currentPlay = playDiceRolls.GetAttackRollResult(_currentPlay); _currentPlay.AttackerRoll *= attacker.FatigueModifier(); if (_currentPlay.AttackerRoll <= 0) { return(_currentPlay); } //Check if tackling is really happening if (defender == null) { isTackling = false; _currentPlay.DefensiveAction = PlayerAction.None; } else { float tackleChance = 0.75f * GameData.Instance.ActionChancePerZone[(int)defendingZone].Tackle * defender.Prob_Tackling; if (marking == MarkingType.Close) { tackleChance *= 1.25f; } if (defender.Team.IsStrategyApplicable(defendingZone)) { tackleChance *= GameData.Instance.TeamStrategies[(int)defender.Team.Strategy].TacklingChance; } isTackling |= tackleChance >= Random.Range(0f, 1f); } if (isTackling) { //Roll dice _currentPlay = playDiceRolls.GetDefenseRollResult(_currentPlay); agilityBonus = (float)defender.GetAttributeBonus(defender.Agility) / 100; agilityBonus *= defender.FatigueModifier(); fault *= (1f - agilityBonus); _currentPlay.DefenderRoll *= defender.FatigueModifier(); _currentPlay.DefenseFatigueRate = fatigueMedium; //Check if tackle resulted in a fault if (fault >= Random.Range(0f, 1f)) { if (_currentPlay.AttackingTeam.GetTeamZone(zone) == Zone.Box) { _currentPlay.Event = MatchEvent.Penalty; } else { _currentPlay.Event = MatchEvent.Fault; } _currentPlay.IsActionSuccessful = false; } else { _currentPlay.IsActionSuccessful = _currentPlay.AttackerRoll > _currentPlay.DefenderRoll; _currentPlay.IsActionDefended = !_currentPlay.IsActionSuccessful; } defender.MatchStats.Tackles++; } else { float difficulty = Random.Range(0f, 1f); float bonus = (float)attacker.GetOverall() / 100; if (bonus > 0) { difficulty -= bonus; } _currentPlay.IsActionSuccessful = _currentPlay.AttackerRoll > difficulty; } if (defender != null) { defender.Fatigue -= _currentPlay.DefenseFatigueRate * (25 / (float)defender.Stamina); } return(_currentPlay); }
public float GetActionChance(PlayerAction _action, ActionChancePerZoneTable.Actions _zoneChance, MarkingType _marking, Zone _zone) { float chance = 0f; float bonus = 0f; Team_Strategy teamStrategy = Team.GetStrategy(); switch (_action) { case PlayerAction.Pass: chance = _zoneChance.Pass * Prob_Pass; bonus = GetAttributeBonus(Passing); if (_marking == MarkingType.Close) { chance *= 2f; } if (Dice.Roll(20, 1, (int)Dice.RollType.None, Mathf.FloorToInt((chance * 5) + (bonus / 10)), 100) >= 20) { chance *= 2f; } if (Team.IsStrategyApplicable(_zone)) { chance *= teamStrategy.PassingChance; } break; case PlayerAction.LongPass: float longPass = _zoneChance.LongPass * Prob_LongPass; bonus = GetAttributeBonus(Mathf.FloorToInt((float)(Passing + Strength) / 2)); if (_marking == MarkingType.Close) { longPass *= 1.75f; } if (Dice.Roll(20, 1, (int)Dice.RollType.None, Mathf.FloorToInt((longPass * 5) + (bonus / 10)), 100) >= 20) { longPass *= 2f; } if (Team.IsStrategyApplicable(_zone)) { chance *= teamStrategy.LongPassChance; } break; case PlayerAction.Dribble: chance = _zoneChance.Dribble * Prob_Dribble; bonus = GetAttributeBonus(Dribbling); if (_marking == MarkingType.Close) { chance *= 0.5f; } else if (_marking == MarkingType.Distance) { chance *= 1.5f; } if (Dice.Roll(20, 1, (int)Dice.RollType.None, Mathf.FloorToInt((chance * 5) + (bonus / 10))) >= 20) { chance *= 2f; } if (Team.IsStrategyApplicable(_zone)) { chance *= teamStrategy.DribblingChance; } break; case PlayerAction.Cross: chance = _zoneChance.Cross * Prob_Crossing; bonus = GetAttributeBonus(Crossing); if (_marking == MarkingType.Close) { chance *= 0.5f; } if (Dice.Roll(20, 1, (int)Dice.RollType.None, Mathf.FloorToInt((chance * 5) + (bonus / 10))) >= 20) { chance *= 2f; } if (Team.IsStrategyApplicable(_zone)) { chance *= teamStrategy.CrossingChance; } break; case PlayerAction.Shot: chance = _zoneChance.Shot * Prob_Shoot; bonus = GetAttributeBonus(Shooting); if (_marking == MarkingType.Close) { chance *= 0.5f; } else if (_marking == MarkingType.None) { chance *= 3f; } if (Dice.Roll(20, 1, (int)Dice.RollType.None, Mathf.FloorToInt((chance * 5) + (bonus / 10))) >= 20) { chance *= 2f; } if (Team.IsStrategyApplicable(_zone)) { chance *= teamStrategy.ShootingChance; } break; case PlayerAction.Header: chance = (_zoneChance.Shot + Prob_Shoot) * 1.5f; bonus = GetAttributeBonus(Heading); if (_marking == MarkingType.Distance) { chance *= 2f; } else if (_marking == MarkingType.None) { chance *= 3f; } if (Dice.Roll(20, 1, (int)Dice.RollType.None, Mathf.FloorToInt((chance * 5) + (bonus / 10))) >= 20) { chance *= 2f; } if (Team.IsStrategyApplicable(_zone)) { chance *= teamStrategy.ShootingChance; } break; } return(chance); }
public void Clear() { jLastInactive = 0; mark = MarkingType.Clear; ductingParts = false; part = null; }