// Token: 0x0600866A RID: 34410 RVA: 0x0022E3D8 File Offset: 0x0022C5D8 public AbstractActorMovementInvocation(AbstractActor actor, bool abilityConsumesFiring) : base(UnityEngine.Random.Range(0, 99999)) { Pathing pathing = actor.Pathing; this.ActorGUID = actor.GUID; this.AbilityConsumesFiring = abilityConsumesFiring; List <WayPoint> collection = ActorMovementSequence.ExtractWaypointsFromPath(actor, pathing.CurrentPath, pathing.ResultDestination, pathing.CurrentMeleeTarget, this.MoveType); this.Waypoints = new List <WayPoint>(collection); this.MoveType = pathing.MoveType; this.FinalOrientation = pathing.ResultAngleAsVector; if (pathing.CurrentMeleeTarget == null) { this.MeleeTargetGUID = string.Empty; return; } this.MeleeTargetGUID = pathing.CurrentMeleeTarget.GUID; }
/* CAC introduces burning effects, which applies heat for each hex you move through, and if you end your turn in a burning hex. * Calculate this heat so we can show it to the player * TODO: Handle unaffected by fire */ public static int CACTerrainHeat(this Mech mech) { float terrainHeat = 0f; // If the unit has been marked as not being affected by fire, skip it entirely if (mech.UnaffectedFire()) { return(0); } if (mech.Pathing.CurrentPath != null && mech.Pathing.CurrentPath.Count > 0) { List <WayPoint> waypointsFromPath = ActorMovementSequence.ExtractWaypointsFromPath( mech, mech.Pathing.CurrentPath, mech.Pathing.ResultDestination, (ICombatant)mech.Pathing.CurrentMeleeTarget, mech.Pathing.MoveType ); List <MapTerrainCellWaypoint> terrainWaypoints = DynamicMapHelper.getVisitedWaypoints(mech.Combat, waypointsFromPath); Mod.HeatLog.Trace?.Write($" Count of waypointsFromPath: {waypointsFromPath.Count} terrainWaypoints: {terrainWaypoints.Count}"); float sumOfCellHeat = 0f; int totalCells = 0; foreach (MapTerrainCellWaypoint cell in terrainWaypoints) { if (cell != null && cell.cell.BurningStrength > 0) { Mod.HeatLog.Trace?.Write($" --Adding {cell.cell.BurningStrength} heat from cell at worldPos: {cell.cell.WorldPos()}"); sumOfCellHeat += cell.cell.BurningStrength; totalCells += 1; } } terrainHeat = totalCells != 0 ? (float)Math.Ceiling(sumOfCellHeat / totalCells) : 0; Mod.HeatLog.Trace?.Write($"TerrainHeat: {terrainHeat} = sumOfHeat: {sumOfCellHeat} / totalCells: {totalCells}"); } else { MapTerrainDataCellEx cell = mech.Combat.MapMetaData.GetCellAt(mech.CurrentPosition) as MapTerrainDataCellEx; if (cell != null && cell.BurningStrength > 0) { Mod.HeatLog.Trace?.Write($"Adding {cell.BurningStrength} heat from current position: {mech.CurrentPosition}"); terrainHeat = cell.BurningStrength; } } return((int)Math.Ceiling(terrainHeat)); }
static void Postfix(SelectionStateMove __instance, ref float __result) { Mod.Log.Trace?.Write("SSM:PSFS - entered."); MeleeAttack selectedAttack = ModState.GetSelectedAttack(__instance.SelectedActor); if (__instance.SelectedActor is Mech selectedMech && selectedAttack != null && __instance.PotentialMeleeTarget != null) { float newStability = selectedMech.CurrentStability + selectedAttack.AttackerInstability; List <WayPoint> waypoints = ActorMovementSequence.ExtractWaypointsFromPath(selectedMech, selectedMech.Pathing.CurrentPath, selectedMech.Pathing.ResultDestination, selectedMech.Pathing.CurrentMeleeTarget, selectedMech.Pathing.MoveType); StabilityChangeSource changeSource = StabilityChangeSource.Moving; if (WayPoint.GetDistFromWaypointList(selectedMech.CurrentPosition, waypoints) < 1f) { changeSource = StabilityChangeSource.RemainingStationary; } float minStability = selectedMech.GetMinStability(changeSource, newStability); Mod.Log.Debug?.Write($"Stability change for {CombatantUtils.Label(selectedMech)} => " + $"current: {selectedMech.CurrentStability} projectedNew: {selectedAttack.AttackerInstability} " + $"totalChange: {newStability} afterDump: {minStability}"); __result = minStability; } }
// Replicates logic from Mech::AdjustedHeatSinkCapacity to allow displaying multiplier public static float DesignMaskHeatMulti(this Mech mech, bool isProjectedHeat) { float capacityMulti = 1f; try { // Check for currently occupied, or future if (isProjectedHeat) { Mod.HeatLog.Trace?.Write("Calculating projected position heat."); if (mech.Pathing != null && mech.Pathing.CurrentPath != null && mech.Pathing.CurrentPath.Count > 0) { // Determine the destination designMask Mod.HeatLog.Trace?.Write($"CurrentPath has: {mech.Pathing.CurrentPath.Count} nodes, using destination path: {mech.Pathing.ResultDestination}"); DesignMaskDef destinationDesignMaskDef = mech?.Combat?.MapMetaData?.GetPriorityDesignMaskAtPos(mech.Pathing.ResultDestination); if (destinationDesignMaskDef != null && !Mathf.Approximately(destinationDesignMaskDef.heatSinkMultiplier, 1f)) { Mod.HeatLog.Trace?.Write($"Destination design mask: {destinationDesignMaskDef?.Description?.Name} has heatSinkMulti: x{destinationDesignMaskDef?.heatSinkMultiplier} "); capacityMulti *= destinationDesignMaskDef.heatSinkMultiplier; } // Check for any cells along the way that will apply the burning sticky effect. // See CustomAmmoCategories\designmask\DesignMaskBurningForest List <WayPoint> waypointsFromPath = ActorMovementSequence.ExtractWaypointsFromPath( mech, mech.Pathing.CurrentPath, mech.Pathing.ResultDestination, (ICombatant)mech.Pathing.CurrentMeleeTarget, mech.Pathing.MoveType ); List <MapTerrainCellWaypoint> terrainWaypoints = DynamicMapHelper.getVisitedWaypoints(mech.Combat, waypointsFromPath); Mod.HeatLog.Trace?.Write($" Count of waypointsFromPath: {waypointsFromPath?.Count} terrainWaypoints: {terrainWaypoints?.Count}"); // This assumes 1) only KMission is using stickyEffects that modify HeatSinkCapacity and 2) it has a stackLimit of 1. Anything else will break this. float stickyModifier = 1f; foreach (MapTerrainCellWaypoint cell in terrainWaypoints) { if (cell != null && cell?.cell?.BurningStrength > 0 && cell?.cell?.mapMetaData?.designMaskDefs != null) { Mod.HeatLog.Trace?.Write($" checking burningCell for designMask."); foreach (DesignMaskDef cellDesignMaskDef in cell?.cell?.mapMetaData?.designMaskDefs?.Values) { Mod.HeatLog.Trace?.Write($" checking designMask for stickyEffects."); if (cellDesignMaskDef.stickyEffect != null && cellDesignMaskDef.stickyEffect?.statisticData != null && cellDesignMaskDef.stickyEffect.statisticData.statName == ModStats.HBS_HeatSinkCapacity) { Mod.HeatLog.Trace?.Write($" found stickyEffects."); stickyModifier = Single.Parse(cellDesignMaskDef.stickyEffect.statisticData.modValue); } } } } if (!Mathf.Approximately(stickyModifier, 1f)) { capacityMulti *= stickyModifier; Mod.HeatLog.Trace?.Write($" capacityMulti: {capacityMulti} after stickyModifier: {stickyModifier}"); } } else { Mod.HeatLog.Trace?.Write($"Current path is null or has 0 count, skipping."); } } else { Mod.HeatLog.Trace?.Write("Calculating current position heat."); if (mech.occupiedDesignMask != null && !Mathf.Approximately(mech.occupiedDesignMask.heatSinkMultiplier, 1f)) { Mod.HeatLog.Trace?.Write($"Multi for currentPos is: {mech?.occupiedDesignMask?.heatSinkMultiplier}"); capacityMulti *= mech.occupiedDesignMask.heatSinkMultiplier; } } if (mech?.Combat?.MapMetaData?.biomeDesignMask != null && !Mathf.Approximately(mech.Combat.MapMetaData.biomeDesignMask.heatSinkMultiplier, 1f)) { Mod.HeatLog.Trace?.Write($"Biome: {mech.Combat.MapMetaData.biomeDesignMask.Id} has heatSinkMulti: x{mech.Combat.MapMetaData.biomeDesignMask.heatSinkMultiplier} "); capacityMulti *= mech.Combat.MapMetaData.biomeDesignMask.heatSinkMultiplier; } } catch (Exception e) { Mod.HeatLog.Error?.Write(e, $"Failed to calculate designMaskHeatMulti due to error: {e}"); } Mod.HeatLog.Trace?.Write($"Calculated capacityMulti: {capacityMulti} x globalHeatSinkMulti: {mech.Combat.Constants.Heat.GlobalHeatSinkMultiplier} "); capacityMulti *= mech.Combat.Constants.Heat.GlobalHeatSinkMultiplier; return(capacityMulti); }