internal static TeamAIOverrideDef TryOverrideTeamAI(AITeam team) { var aiOverride = TeamAIOverrideDef.SelectOverride(team, TeamAIOverrides) as TeamAIOverrideDef; if (aiOverride == null) { return(null); } if (TeamToAIOverride.ContainsKey(team)) { if (TeamToAIOverride[team] == aiOverride) { return(TeamToAIOverride[team]); } ResetTeamAI(team); } HBSLog?.Log($"Overriding AI on team {team.Name} with {aiOverride.Name}"); TeamToAIOverride[team] = aiOverride; return(TeamToAIOverride[team]); }
public static void TryRecalculateCurrentUnit(AITeam team) { if (!Main.TeamToAIOverride.ContainsKey(team)) { return; } var teamAIOverride = Main.TeamToAIOverride[team]; if (teamAIOverride.TurnOrderFactorWeights.Count == 0) { return; } // can't do simple thing and just reprocess the activation // because reasons? locks AI after they act after pause // AIPause.CurrentAITeam.TurnActorProcessActivation(); var teamTraverse = Traverse.Create(team); var newUnit = teamTraverse.Method("selectCurrentUnit").GetValue <AbstractActor>(); teamTraverse.Field("currentUnit").SetValue(newUnit); // side effects of TurnActorProcessActivation teamTraverse.Method("UpdateAloneStatus", newUnit).GetValue(); AIRoleAssignment.AssignRoleToUnit(newUnit, team.units); }
public static void Postfix(AITeam __instance) { Mod.Log.Trace?.Write("AIU:CDT:Post"); foreach (KeyValuePair <Lance, AbstractActor> kvp in __instance.DesignatedTargetForLance) { Mod.Log.Info?.Write($"Lance: {kvp.Key.DisplayName} has designedTarget: {CombatantUtils.Label(kvp.Value)}"); } }
private static void OnPause(AITeam team) { Main.HBSLog?.Log($"AIDebugPause -- Paused on {_interceptedInvocationMessage.GetType().Name}"); IsPaused = true; CurrentAITeam = team; InvocationVisual.ShowFor(team.Combat, _interceptedInvocationMessage); InfluenceMapVisual.Show(); }
public static bool Prefix(AITeam __instance, Lance lance, List <AbstractActor> lanceUnits, List <AbstractActor> hostileUnits) { var target = LanceDesignatedTargetOverride.TryGetDesignatedTarget(__instance, lanceUnits, hostileUnits); if (target != null) { __instance.DesignatedTargetForLance[lance] = target; } return(false); }
public static bool Prefix(AITeam __instance, AbstractActor unit, OrderInfo order, ref InvocationMessage __result) { var invocation = InvocationFromOrderOverride.TryCreateInvocation(unit, order); if (invocation == null) { return(true); } __result = invocation; return(false); }
public AIObject(AIRoleType r, Vector3 p, bool isBot) : base() { _team = null; _isBot = isBot; if (r == AIRoleType.TeamLeader) { //r = AIRoleType.Infantry; _isLeader = true; } _role = r; Status = AIMovementStatus.Walk; Position = p; }
private static void cycleAISelection() { List <AbstractActor> allUnits = Combat.AllActors; List <AbstractActor> aiUnits = new List <AbstractActor>(); for (int unitIndex = 0; unitIndex < allUnits.Count; ++unitIndex) { AbstractActor unit = allUnits[unitIndex]; AITeam aiTeam = unit.team as AITeam; if (aiTeam != null && aiTeam.ThinksOnThisMachine) { aiUnits.Add(unit); } } if (aiUnits.Count == 0) { SelectedAIUnit = null; return; } if (SelectedAIUnit == null) { SelectedAIUnit = aiUnits[0]; return; } int index = aiUnits.FindIndex(x => x == SelectedAIUnit); if (index == -1) { SelectedAIUnit = aiUnits[0]; return; } index++; if (index == aiUnits.Count) { SelectedAIUnit = null; return; } SelectedAIUnit = aiUnits[index]; return; }
// CLONE OF HBS CODE - LIKELY BRITTLE! public static bool ShouldUnitUseInspire(AbstractActor unit) { float num = AIUtil.CalcMaxInspirationDelta(unit, true); AITeam aiteam = unit.team as AITeam; if (aiteam == null || !unit.CanBeInspired) { return(false); } if (num < AIHelper.GetBehaviorVariableValue(unit.BehaviorTree, BehaviorVariableName.Float_MinimumInspirationDamage).FloatVal) { return(false); } float num2 = 1f - aiteam.GetInspirationWindow(); return(num > aiteam.GetInspirationTargetDamage() * num2); }
public static bool Prefix(AITeam __instance, List <AbstractActor> unusedUnits, ref AbstractActor __result) { try { if (!__instance.CanEntireEnemyTeamBeGhosted()) { __result = null; return(false); } AbstractActor result = (AbstractActor)null; float minDistance = float.MaxValue; for (int index1 = 0; index1 < unusedUnits.Count; ++index1) { AbstractActor unusedUnit = unusedUnits[index1]; List <AbstractActor> enemies = AIUtil.HostilesToUnit(unusedUnit); AuraBubble sensors = unusedUnit.sensorAura(); if (sensors == null) { continue; } ; for (int index2 = 0; index2 < enemies.Count; ++index2) { AbstractActor enemy = enemies[index2]; if (enemy.HasECMAbilityInstalled) { float floatVal = unusedUnit.BehaviorTree.GetBehaviorVariableValue(BehaviorVariableName.Float_SignalInWeapRngWhenEnemyGhostedWithinMoveDistance).FloatVal; float maxMoveDist = Mathf.Lerp(unusedUnit.MaxWalkDistance, unusedUnit.MaxSprintDistance, floatVal); float range = sensors.collider.radius; float needMoveDist = Vector3.Distance(unusedUnit.CurrentPosition, enemy.CurrentPosition) - range; if ((double)needMoveDist <= (double)maxMoveDist && (double)needMoveDist < (double)minDistance) { result = unusedUnit; minDistance = needMoveDist; } } } } __result = result; return(false); }catch (Exception e) { Log.WriteCritical(e.ToString() + "\n"); __result = null; return(false); } }
public static void Postfix(AITeam __instance, ref InvocationMessage __result) { if (__result == null || _injectedThisCall) { _injectedThisCall = false; return; } // the ai has decided to do something, if we're pausing the AI, // we want to skip this invocation and inject it on the next think // after we hit the key shortcut var skipThisInvocation = AIPause.OnAIInvocation(__instance, __result); if (skipThisInvocation) { __result = null; } }
public static bool OnAIThink(AITeam team) { if (!Main.Settings.ShouldPauseAI) { return(false); } // don't pause if the current unit has already activated this round var currentUnit = Traverse.Create(team).Field("currentUnit").GetValue <AbstractActor>(); if (currentUnit.HasActivatedThisRound) { return(false); } // don't pause if pending invocations (we want to only pause before new invocation) var pendingInvocations = Traverse.Create(team).Field("pendingInvocations").GetValue <List <InvocationMessage> >(); if (pendingInvocations != null && pendingInvocations.Count > 0) { return(false); } // don't pause if we don't have an intercepted message if (_interceptedInvocationMessage == null) { return(false); } // unpause when press the keys if (Input.GetKey(KeyCode.LeftControl) && Input.GetKeyDown(KeyCode.RightArrow)) { OnUnpause(); return(false); } if (!IsPaused) { OnPause(team); } return(true); }
public static bool Prefix(AITeam __instance, ref AbstractActor __result) { var teamAIOverride = Main.TryOverrideTeamAI(__instance); if (teamAIOverride == null) { return(true); } var nextUnit = TurnOrderOverride.TryOverrideCurrentUnit(__instance.GetUnusedUnitsForCurrentPhase(), teamAIOverride); if (nextUnit == null) { return(true); } __result = nextUnit; Main.TryOverrideUnitAI(__result); return(false); }
public static bool OnAIInvocation(AITeam aiTeam, InvocationMessage invocation) { if (!Main.Settings.ShouldPauseAI) { return(false); } if (invocation is EjectInvocation) { return(false); } if (invocation is InspireActorInvocation) { return(false); } _interceptedInvocationMessage = invocation; return(true); }
public static bool Prefix(AITeam __instance, ref InvocationMessage __result, ref float ___planningStartTime) { // if shouldPauseAI is on at all, we should never fail to get invocation because of time if (Main.Settings.ShouldPauseAI) { ___planningStartTime = __instance.Combat.BattleTechGame.Time; } var inject = AIPause.TryGetMessageInject(); if (inject == null) { return(true); } // abort the call and force the return to be the previously skipped // invocation message that we got in the postfix __result = inject; _injectedThisCall = true; return(false); }
public static AbstractActor FilterEnemyUnitsToDesignatedTarget(AITeam aiteam, Lance attackerLance, List <ICombatant> enemyUnits) { AbstractActor designatedTarget = null; if (aiteam != null && aiteam.DesignatedTargetForLance.ContainsKey(attackerLance)) { designatedTarget = aiteam.DesignatedTargetForLance[attackerLance]; if (designatedTarget != null && !designatedTarget.IsDead) { for (int i = 0; i < enemyUnits.Count; i++) { if (enemyUnits[i] == designatedTarget) { designatedTarget = enemyUnits[i] as AbstractActor; break; } } } } return(designatedTarget); }
internal static void ResetTeamAI(AITeam team) { HBSLog?.Log($"Resetting AI for team {team.Name}"); }
public static bool CanEntireEnemyTeamBeGhosted(this AITeam instance) { return(CanEntireEnemyTeamBeGhostedInvoker(instance)); }
public void SelectTeam(AITeamType team) { ClearSelect(); foreach (AITeam t in _teams) { if(t.TeamType == team) _selectedTeam = t; } foreach (AIObject aiobj in _aiobjects) { if (aiobj.Team == _selectedTeam) { aiobj.Selected = true; if (aiobj.IsLeader) { _selectedObject = aiobj; aiobj.Selected = true; } } } }
protected override async void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); Window.Current.CoreWindow.KeyUp += Menu_KeyUp; //zoomer = new ShowAllPositions(GameHolder.ActualWidth, GameHolder.ActualHeight, fieldDimensions); //rge = new RenderGameEvents(GameArea, Fps, LeftScore, RightScore, zoomer, frame, fieldDimensions); //if (lockCurser.Thing) //{ // Window.Current.CoreWindow.PointerPosition = new Windows.Foundation.Point( // (Window.Current.CoreWindow.Bounds.Left + Window.Current.CoreWindow.Bounds.Right) / 2.0, // (Window.Current.CoreWindow.Bounds.Top + Window.Current.CoreWindow.Bounds.Bottom) / 2.0); // Window.Current.CoreWindow.PointerCursor = null; //} //else //{ // Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.Arrow, 0); //} var gameInfo = (GameInfo)e.Parameter; var gameName = gameInfo.gameName; game = new Game2(); var teamSize = 5; var ourTeam = new Guid[teamSize].Select(x => Guid.NewGuid()).ToArray(); //zoomer = new MouseZoomer(GameHolder.ActualWidth, GameHolder.ActualHeight, fieldDimensions, (GameState gs)=> { // return gs.players.Where(x => x.Key == ourTeam[0]).Select(x => x.Value.PlayerBody.Position) // .Union(new[] { gs.GameBall.Posistion }) // .ToArray(); //}); // this blocks like a mofo // we don't want anything to get a peice of the main thread while we are setting up try { //if (gameInfo.controlScheme == ControlScheme.MouseAndKeyboard) //{ // var body = ourTeam.First(); // var inputs = new MouseKeyboardInputs(lockCurser, body); // await inputs.Init(); // await CreatePlayer(body, inputs, new byte[3] { 0x88, 0x00, 0xff }); //} //foreach (var body in ourTeam)//.Skip(1) //{ // var inputs = new AIInputs(game.gameState, body, ourTeam.Except(new Guid[] { body }).ToArray(), fieldDimensions, false); // await inputs.Init(); // await CreatePlayer(body, inputs, new byte[3] { 0x00, 0x00, 0xff }); //} //https://stackoverflow.com/questions/48997243/uwp-gamepad-gamepads-is-empty-even-though-a-controller-is-connected //var x = 0; //while (x < 10) //{ // var db = Gamepad.Gamepads.Count; // Task.Delay(100).Wait(); // x++; //} //var gps = Gamepad.Gamepads.ToArray(); //foreach (var (gamePad, key) in gps.Zip(ourTeam.Take(gps.Length), (x, y) => (x, y))) //{ // var body = key;// Guid.NewGuid(); // var inputs = CreateController(gamePad, body); // inputs.Init().Wait(); // CreatePlayer(body, inputs).Wait(); //} var body = ourTeam.First(); var inputs = new MouseKeyboardInputs(lockCurser, body); await inputs.Init(); await CreatePlayer(body, inputs, new byte[3] { 0x88, 0x00, 0xff }); { var team = new AITeam(game.gameState, ourTeam, fieldDimensions, false); foreach (var(key, input) in team.GetPlayers().Skip(1 /*gps.Length*/)) { input.Init().Wait(); CreatePlayer(key, input, new byte[3] { 0x00, 0x00, 0xff }).Wait(); } } var theirTeam = new Guid[teamSize].Select(x => Guid.NewGuid()).ToArray(); { var team = new AITeam(game.gameState, theirTeam, fieldDimensions, true); foreach (var(key, input) in team.GetPlayers()) { input.Init().Wait(); CreatePlayer(key, input, new byte[3] { 0xff, 0x00, 0x00 }).Wait(); } } } catch (Exception ex) { await OnDisconnect(ex); } var ourBody = localPlayers.Read().First().LocalId; zoomerLeft = new Zoomer(CanvasLeft.ActualWidth, CanvasLeft.ActualHeight, ourBody, .0025); zoomerRight = new Zoomer(CanvasRight.ActualWidth, CanvasRight.ActualHeight, ourBody, .01); //renderGameState = new RenderGameState(GameArea, zoomer, LeftScore, RightScore); renderGameStateLeft = new RenderGameState2(/*Canvas,*/ zoomerLeft, LeftScore, RightScore); renderGameStateRight = new RenderGameState2(/*Canvas,*/ zoomerRight, LeftScore, RightScore); Task.Run(async() => { try { MainLoop(); } catch (Exception ex) { await OnDisconnect(ex); } }); }
// TODO: make this more moddable from TeamAIOverride public static AbstractActor TryGetDesignatedTarget(AITeam team, List <AbstractActor> lanceUnits, List <AbstractActor> hostileUnits) { if (!Main.TeamToAIOverride.ContainsKey(team) || !Main.TeamToAIOverride[team].DesignateTargets) { return(null); } if (lanceUnits.Count <= 1 || hostileUnits.Count <= 1) { return(null); } var hostileToNumLof = new Dictionary <ICombatant, int>(); foreach (var hostile in hostileUnits) { var numLof = 0; foreach (var unit in lanceUnits) { var weapon = unit.GetLongestRangeWeapon(false); if (weapon != null && unit.HasLOSToTargetUnit(hostile) && unit.HasLOFToTargetUnit(hostile, weapon)) { numLof++; } } hostileToNumLof[hostile] = numLof; } // get the target that has the most LOF from this lance var maxLof = hostileToNumLof.Values.Max(); var maxLofHostiles = hostileToNumLof.Where(h => h.Value == maxLof).Select(h => h.Key).ToArray(); if (maxLofHostiles.Length == 1) { var target = maxLofHostiles[0] as AbstractActor; Main.HBSLog?.Log($"Selecting highest LOS/LOF ({maxLof}) target {target?.UnitName} with pilot {target?.GetPilot()?.Name}"); return(target); } // if there are multiple targets with the same LOF number, use the closest ICombatant closest = null; var closestDistance = float.MaxValue; foreach (var hostile in maxLofHostiles) { foreach (var unit in lanceUnits) { var distance = Vector3.Distance(hostile.CurrentPosition, unit.CurrentPosition); if (!(distance < closestDistance)) { continue; } closest = hostile; closestDistance = distance; } } var closestTarget = closest as AbstractActor; Main.HBSLog?.Log($"Selecting closest highest LOS/LOF ({maxLof}) target {closestTarget?.UnitName} with pilot {closestTarget?.GetPilot()?.Name}"); return(closest as AbstractActor); }
public static bool Prefix(AITeam __instance) { return(!AIPause.OnAIThink(__instance)); }
public void ClearSelect() { foreach (AIObject aiobj in _aiobjects) aiobj.Selected = false; _selectedObject = null; _selectedTeam = null; }
public void CreateTeam(AITeamType type, Color color, int numInfantry, int numSniper, int numSupport, Vector3 position, bool areBots) { AITeam team = new AITeam(type, color); team.Add(new AIObject(AIRoleType.TeamLeader, position, areBots)); for (int i = 0; i < numInfantry; i++) team.Add(new AIObject(AIRoleType.Infantry, position, areBots)); for (int i = 0; i < numSniper; i++) team.Add(new AIObject(AIRoleType.Sniper, position, areBots)); for (int i = 0; i < numSupport; i++) team.Add(new AIObject(AIRoleType.Support, position, areBots)); _teams.Add(team); }
public void Select(AIObject item) { ClearSelect(); _selectedObject = item; _selectedTeam = item.Team; item.Selected = true; }
public static void Postfix(AITeam __instance, ref AbstractActor __result) { Main.TryOverrideUnitAI(__result); }
public void AddAITeam(AITeam team) { Debug.Assert(!aiTeams.Contains(team)); aiTeams.Add(team); }