コード例 #1
0
            private static void Prefix(ActorMovementSequence __instance)
            {
                Mod.ActivationLog.Info?.Write($"AMS:OC:PRE entered for actor: {CombatantUtils.Label(__instance?.OwningActor)}");

                // Interleaved - check for visibility to any enemies
                if (!__instance.owningActor.Combat.TurnDirector.IsInterleaved)
                {
                    __instance.owningActor.AutoBrace = true;
                }

                // Movement - check for damage after a sprint, and if so force a piloting check
                if (__instance.OwningMech != null && __instance.isSprinting && __instance.OwningMech.ActuatorDamageMalus() != 0)
                {
                    Mod.Log.Info?.Write($"Actor: {CombatantUtils.Label(__instance.OwningMech)} has actuator damage, forcing piloting check.");
                    float sourceSkillMulti = __instance.OwningMech.PilotCheckMod(Mod.Config.SkillChecks.ModPerPointOfPiloting);
                    float damagePenalty    = __instance.OwningMech.ActuatorDamageMalus() * Mod.Config.SkillChecks.ModPerPointOfPiloting;
                    float checkMod         = sourceSkillMulti + damagePenalty;
                    Mod.Log.Debug?.Write($"  moveSkillMulti:{sourceSkillMulti} - damagePenalty: {damagePenalty} = checkMod: {checkMod}");

                    bool sourcePassed = CheckHelper.DidCheckPassThreshold(Mod.Config.Move.FallAfterRunChance, __instance.OwningMech, checkMod, ModText.FT_Fall_After_Run);
                    if (!sourcePassed)
                    {
                        Mod.Log.Info?.Write($"Source actor: {CombatantUtils.Label(__instance.OwningMech)} failed pilot check after sprinting with actuator damage, forcing fall.");
                        MechHelper.AddFallingSequence(__instance.OwningMech, __instance, ModText.FT_Fall_After_Run);
                    }
                }
            }
コード例 #2
0
ファイル: test.cs プロジェクト: ZPointZ/CBTBMovementCore
        // Token: 0x0600866D RID: 34413 RVA: 0x0022E4D0 File Offset: 0x0022C6D0
        public override bool Invoke(CombatGameState combatGameState)
        {
            InvocationMessage.logger.Log("Invoking a MOVE!");
            AbstractActor abstractActor = combatGameState.FindActorByGUID(this.ActorGUID);

            if (abstractActor == null)
            {
                InvocationMessage.logger.LogError(string.Format("MechMovement.Invoke Actor with GUID {0} not found!", this.ActorGUID));
                return(false);
            }
            ICombatant combatant = null;

            if (!string.IsNullOrEmpty(this.MeleeTargetGUID))
            {
                combatant = combatGameState.FindCombatantByGUID(this.MeleeTargetGUID, false);
                if (combatant == null)
                {
                    InvocationMessage.logger.LogError(string.Format("MechMovement.Invoke ICombatant with GUID {0} not found!", this.MeleeTargetGUID));
                    return(false);
                }
            }
            if (!combatGameState.TurnDirector.IsInterleaved && this.MoveType != MoveType.Sprinting)
            {
                abstractActor.AutoBrace = true;
            }
            ActorMovementSequence stackSequence = new ActorMovementSequence(abstractActor, this.Waypoints, this.FinalOrientation, this.MoveType, combatant, this.AbilityConsumesFiring);

            base.PublishStackSequence(combatGameState.MessageCenter, stackSequence, this);
            return(true);
        }
コード例 #3
0
        public static void Postfix(ActorMovementSequence __instance)
        {
            var traverse = Traverse.Create(__instance);
            var combat   = traverse.Property("Combat").GetValue <CombatGameState>();

            AuraCache.RefreshECMStates(combat.AllActors, EffectTriggerType.Passive);
        }
コード例 #4
0
ファイル: Movement.cs プロジェクト: ZPointZ/CBTBMovementCore
 // Token: 0x060000F6 RID: 246 RVA: 0x00014860 File Offset: 0x00012A60
 private static void Postfix(ActorMovementSequence __instance, ref bool __result)
 {
     if (!__instance.OwningActor.Combat.TurnDirector.IsInterleaved)
     {
         __result = false;
     }
 }
コード例 #5
0
ファイル: Movement.cs プロジェクト: ZPointZ/CBTBMovementCore
 // Token: 0x060000F4 RID: 244 RVA: 0x00014618 File Offset: 0x00012818
 private static void Prefix(ActorMovementSequence __instance)
 {
     if (!__instance.owningActor.Combat.TurnDirector.IsInterleaved)
     {
         __instance.owningActor.AutoBrace = true;
     }
 }
コード例 #6
0
            private static void Prefix(ActorMovementSequence __instance)
            {
                Mod.Log.Trace("AMS:OC entered");
                // Interleaved - check for visibility to any enemies
                if (!__instance.owningActor.Combat.TurnDirector.IsInterleaved)
                {
                    if (__instance.owningActor.Combat.LocalPlayerTeam.GetDetectedEnemyUnits().Count > 0)
                    {
                        Mod.Log.Info("AMS:OC TD is not interleaved but enemies are detected - disabling autobrace. ");
                        __instance.owningActor.AutoBrace = false;
                    }
                    else
                    {
                        Mod.Log.Info("AMS:OC TD is not interleaved and no enemies - autobracing ");
                        __instance.owningActor.AutoBrace = true;
                    }
                }

                // Movement - check for damage after a sprint, and if so force a piloting check
                if (__instance.OwningMech != null && __instance.isSprinting && __instance.OwningMech.ActuatorDamageMalus() != 0)
                {
                    Mod.Log.Debug($"Actor: {CombatantUtils.Label(__instance.OwningMech)} has actuator damage, forcing piloting check.");
                    float sourceSkillMulti = __instance.OwningMech.PilotCheckMod(Mod.Config.Move.SkillMulti);
                    bool  sourcePassed     = CheckHelper.DidCheckPassThreshold(Mod.Config.Move.FallAfterRunChance, __instance.OwningMech, sourceSkillMulti, ModConfig.FT_Fall_After_Run);
                    if (!sourcePassed)
                    {
                        Mod.Log.Info($"Source actor: {CombatantUtils.Label(__instance.OwningMech)} failed pilot check after sprinting with actuator damage, forcing fall.");
                        MechHelper.AddFallingSequence(__instance.OwningMech, __instance, ModConfig.FT_Fall_After_Run);
                    }
                }
            }
コード例 #7
0
 private static void Postfix(ActorMovementSequence __instance, ref bool __result)
 {
     Mod.Log.Trace?.Write("AMS:CF:GET entered");
     if (!__instance.OwningActor.Combat.TurnDirector.IsInterleaved)
     {
         // We want to auto-brace, and auto-brace requires that consumesFiring = false. So when no enemies are around, don't consume firing so
         //   that we can auto-brace
         __result = false;
     }
 }
コード例 #8
0
 public static void Postfix(ActorMovementSequence __instance)
 {
     /*if (__instance.owningActor == null) { return; }
      * switch (Core.Settings.auraUpdateFix) {
      * case AuraUpdateFix.Never:
      * case AuraUpdateFix.Position:
      * case AuraUpdateFix.Time:
      *  __instance.owningActor.RemoveAuraUpdateData();
      *  AuraCache.UpdateAurasToActor(__instance.owningActor.Combat.AllActors, __instance.owningActor, __instance.owningActor.CurrentPosition, EffectTriggerType.Passive, false);
      *  break;
      * }*/
 }
コード例 #9
0
ファイル: test.cs プロジェクト: ZPointZ/CBTBMovementCore
        // 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;
        }
コード例 #10
0
        /* 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));
        }
コード例 #11
0
            public static void Postfix(ActorMovementSequence __instance)
            {
                try
                {
                    //if (__instance.owningActor.team.IsLocalPlayer)
                    if (__instance.owningActor.team.LocalPlayerControlsTeam)
                    {
                        return;
                    }

                    Logger.Debug($"[ActorMovementSequence_OnAdded_POSTFIX] Focus on enemy moving...");

                    CombatGameState ___combatGameState = (CombatGameState)AccessTools.Property(typeof(ActorMovementSequence), "Combat").GetValue(__instance, null);

                    if (___combatGameState.LocalPlayerTeam.CanDetectPosition(__instance.OwningActor.CurrentPosition, __instance.OwningActor))
                    {
                        //CameraSequence cameraSequence = CameraControl.Instance.ShowMovementCam(__instance.OwningActor.CurrentPosition, __instance.FinalPos, __instance);
                        //MultiSequence multiSequence = __instance;
                        //multiSequence.SetCamera(cameraSequence, __instance.MessageIndex);

                        //Quaternion rotation = CameraControl.Instance.CameraRot;
                        //Traverse FrameTwoPoints = Traverse.Create(CameraControl.Instance).Method("FrameTwoPoints", rotation * Vector3.forward, __instance.OwningActor.CurrentPosition, __instance.FinalPos, 0.9f, ___combatGameState.Constants.CameraConstants.MaxHeightAboveTerrain * 0.9f);
                        //Vector3 poi = (Vector3)FrameTwoPoints.GetValue();

                        //Vector3 poi = Vector3.Lerp(__instance.OwningActor.CurrentPosition, __instance.FinalPos, 0.5f);
                        //CameraControl.Instance.SetMovingToGroundPos(poi, 0.95f);

                        // KISS
                        CameraControl.Instance.SetMovingToGroundPos(__instance.OwningActor.CurrentPosition, 0.95f);
                    }
                    else if (___combatGameState.LocalPlayerTeam.CanDetectPosition(__instance.FinalPos, __instance.OwningActor))
                    {
                        CameraControl.Instance.SetMovingToGroundPos(__instance.FinalPos, 0.95f);
                    }
                    else
                    {
                        // Nothing?
                    }
                }
                catch (Exception e)
                {
                    Logger.Error(e);
                }
            }
コード例 #12
0
        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;
            }
        }
コード例 #13
0
            static void Postfix(MechMeleeSequence __instance, ref ActorMovementSequence ___moveSequence)
            {
                try
                {
                    Pilot pilot = __instance.owningActor.GetPilot();
                    if (pilot.IsJuggernaut() && Fields.JuggernautCharges)
                    {
                        Logger.Debug("[MechMeleeSequence_GenerateMeleePath_POSTFIX] Fields.JuggernautCharges: " + Fields.JuggernautCharges);

                        // Setting this prevents the footstep effects from Coils to be displayed when a Juggernauts charges
                        new Traverse(___moveSequence).Property("isSprinting").SetValue(true);
                        ___moveSequence.IgnoreEndSmoothing = true;
                        ___moveSequence.meleeType          = MeleeAttackType.Charge;

                        Logger.Info("[MechMeleeSequence_GenerateMeleePath_POSTFIX] moveSequence.isSprinting: " + ___moveSequence.isSprinting);
                        Logger.Info("[MechMeleeSequence_GenerateMeleePath_POSTFIX] moveSequence.IgnoreEndSmoothing: " + ___moveSequence.IgnoreEndSmoothing);
                        Logger.Info("[MechMeleeSequence_GenerateMeleePath_POSTFIX] moveSequence.meleeType: " + ___moveSequence.meleeType);
                    }
                }
                catch (Exception e)
                {
                    Logger.Error(e);
                }
            }
コード例 #14
0
 public static void Postfix(ActorMovementSequence __instance)
 {
     TurnDamageTracker.hintAttackComplete("ActorMovementSequence:CompleteOrders");
 }
コード例 #15
0
 static void Postfix(ActorMovementSequence __instance)
 {
     Mod.ActivationLog.Info?.Write($"AMS:OC:POST - actor: {CombatantUtils.Label(__instance.OwningActor)} " +
                                   $"autoBrace: {__instance.OwningActor.AutoBrace}  hasFired: {__instance.OwningActor.HasFiredThisRound}  consumesFiring: {__instance.ConsumesFiring}");
 }
コード例 #16
0
        // 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);
        }
コード例 #17
0
 public static void Postfix(ActorMovementSequence __instance)
 {
     AuraCache.RefreshECMStates(__instance.Combat.AllActors, EffectTriggerType.Passive);
 }