Esempio n. 1
0
        // WARNING: DUPLICATE OF HBS CODE. THIS IS LIKELY TO BREAK IF HBS CHANGES THE SOURCE FUNCTIONS
        public static float GetSensorsRange(AbstractActor source)
        {
            if (source.StatCollection.ContainsStatistic(ModStats.DisableSensors))
            {
                Mod.Log.Debug?.Write($"Returning minimum sensors range for {CombatantUtils.Label(source)} due to disabled sensors.");
                return(Mod.Config.Sensors.MinimumSensorRange());
            }

            // Add multipliers and absolute bonuses
            EWState ewState = source.GetEWState();

            Mod.Log.Trace?.Write($"  == Sensors Range for for actor:{CombatantUtils.Label(source)}");

            float rawRangeMulti = SensorLockHelper.GetAllSensorRangeMultipliers(source);
            float rangeMulti    = rawRangeMulti + ewState.GetSensorsRangeMulti();

            Mod.Log.Trace?.Write($"    rangeMulti: {rangeMulti} = rawRangeMulti: {rawRangeMulti} + sensorCheckRangeMulti: {ewState.GetSensorsRangeMulti()}");

            float rawRangeMod = SensorLockHelper.GetAllSensorRangeAbsolutes(source);
            float rangeMod    = rawRangeMod * (1 + ewState.GetSensorsRangeMulti());

            Mod.Log.Trace?.Write($"    rangeMod: {rangeMod} = rawRangeMod: {rawRangeMod} + sensorCheckRangeMulti: {ewState.GetSensorsRangeMulti()}");

            float sensorsRange = ewState.GetSensorsBaseRange() * rangeMulti + rangeMod;

            Mod.Log.Trace?.Write($"    sensorsRange: { sensorsRange} = baseRange: {ewState.GetSensorsBaseRange()} * rangeMult: {rangeMulti} + rangeMod: {rangeMod}");

            if (sensorsRange < Mod.Config.Sensors.MinimumSensorRange())
            {
                sensorsRange = Mod.Config.Sensors.MinimumSensorRange();
            }

            return(sensorsRange);
        }
        public static void Postfix(MechComponent __instance, bool __state)
        {
            Mod.Log.Trace?.Write("MC:CCE:post entered.");

            if (__state)
            {
                Mod.Log.Debug?.Write($" Stealth effect was cancelled, parent visibility needs refreshed.");

                EWState parentState = new EWState(__instance.parent);
                PilotableActorRepresentation par = __instance.parent.GameRep as PilotableActorRepresentation;
                if (parentState.HasStealth())
                {
                    VfxHelper.EnableStealthVfx(__instance.parent);
                }
                else
                {
                    VfxHelper.DisableSensorStealthEffect(__instance.parent);
                }

                if (parentState.HasMimetic())
                {
                    VfxHelper.EnableMimeticEffect(__instance.parent);
                }
                else
                {
                    VfxHelper.DisableMimeticEffect(__instance.parent);
                }

                // Force a refresh in case the signature increased due to stealth loss
                // TODO: Make this player hostile only
                List <ICombatant> allLivingCombatants = __instance.parent.Combat.GetAllLivingCombatants();
                __instance.parent.VisibilityCache.UpdateCacheReciprocal(allLivingCombatants);
            }
        }
Esempio n. 3
0
        public static void CalculateMimeticPips(CombatHUDStealthBarPips stealthDisplay, AbstractActor actor, float distanceMoved)
        {
            EWState actorState = new EWState(actor);

            Mod.Log.Trace?.Write($"Calculating mimeticPips for Actor: {CombatantUtils.Label(actor)}");

            int stepsMoved = (int)Math.Ceiling(distanceMoved / 30f);

            Mod.Log.Trace?.Write($"  stepsMoved: {stepsMoved} = distanceMoved: {distanceMoved} / 30");

            // Update # of pips
            int maxPips     = actorState.MaxMimeticPips();
            int currentPips = actorState.CurrentMimeticPips(distanceMoved);

            stealthDisplay.ShowNewActorStealth(currentPips, maxPips);

            // Change colors to reflect maxmimums
            Traverse       pipsT = Traverse.Create(stealthDisplay).Property("Pips");
            List <Graphic> pips  = pipsT.GetValue <List <Graphic> >();

            for (int i = 0; i < pips.Count; i++)
            {
                Graphic g = pips[i];
                if (g.isActiveAndEnabled)
                {
                    //Color pipColor = Color.white;
                    Color pipColor = new Color(50f, 206f, 230f);
                    UIHelpers.SetImageColor(g, pipColor);
                }
            }
        }
Esempio n. 4
0
        public void TestStealthAttackMod_Bonuses_Pinged_ProbeCarrier()
        {
            Mech attacker = TestHelper.BuildTestMech();
            Mech target   = TestHelper.BuildTestMech();

            // Stealth - <signature_modifier>_<details_modifier>_<mediumAttackMod>_<longAttackmod>_<extremeAttackMod>
            target.StatCollection.Set(ModStats.StealthEffect, "0.99_9_1_2_3");

            // Reduce by 3
            target.StatCollection.Set(ModStats.PingedByProbe, 3);

            // Reduce by 2
            attacker.StatCollection.Set(ModStats.ProbeCarrier, 2);

            EWState attackerState = new EWState(attacker);
            EWState targetState   = new EWState(target);

            Weapon weapon = TestHelper.BuildTestWeapon(0, 60, 120, 240, 480);

            Assert.AreEqual(0, targetState.StealthAttackMod(attackerState, weapon, 30));
            Assert.AreEqual(0, targetState.StealthAttackMod(attackerState, weapon, 60));
            Assert.AreEqual(0, targetState.StealthAttackMod(attackerState, weapon, 90));
            Assert.AreEqual(0, targetState.StealthAttackMod(attackerState, weapon, 120));
            Assert.AreEqual(0, targetState.StealthAttackMod(attackerState, weapon, 200));
            Assert.AreEqual(0, targetState.StealthAttackMod(attackerState, weapon, 240));
            Assert.AreEqual(0, targetState.StealthAttackMod(attackerState, weapon, 400));
            Assert.AreEqual(0, targetState.StealthAttackMod(attackerState, weapon, 480));
        }
Esempio n. 5
0
        // WARNING: DUPLICATE OF HBS CODE. THIS IS LIKELY TO BREAK IF HBS CHANGES THE SOURCE FUNCTIONS
        public static float GetTargetSignature(ICombatant target, EWState sourceState)
        {
            if (target == null || (target as AbstractActor) == null)
            {
                return(1f);
            }

            AbstractActor targetActor = target as AbstractActor;
            float         allTargetSignatureModifiers = GetAllTargetSignatureModifiers(targetActor, sourceState);
            float         staticSignature             = 1f * allTargetSignatureModifiers;

            // Add in any design mask boosts
            DesignMaskDef occupiedDesignMask = targetActor.occupiedDesignMask;

            if (occupiedDesignMask != null)
            {
                staticSignature *= occupiedDesignMask.signatureMultiplier;
            }

            if (staticSignature < Mod.Config.Sensors.MinSignature)
            {
                staticSignature = Mod.Config.Sensors.MinSignature;
            }

            return(staticSignature);
        }
Esempio n. 6
0
        // WARNING: DUPLICATE OF HBS CODE. THIS IS LIKELY TO BREAK IF HBS CHANGES THE SOURCE FUNCTIONS
        public static float GetAdjustedSpotterRange(AbstractActor source, ICombatant target)
        {
            float         targetVisibility = 1f;
            AbstractActor targetActor      = target as AbstractActor;

            if (targetActor != null)
            {
                EWState sourceState = source.GetEWState();
                targetVisibility = VisualLockHelper.GetTargetVisibility(targetActor, sourceState);
            }

            float spotterRange = VisualLockHelper.GetSpotterRange(source);

            float modifiedRange = spotterRange * targetVisibility;

            if (modifiedRange < Mod.Config.Vision.MinimumVisionRange())
            {
                modifiedRange = Mod.Config.Vision.MinimumVisionRange();
            }

            // Round up to the nearest full hex
            float normalizedRange = HexUtils.CountHexes(modifiedRange, true) * 30f;

            Mod.Log.Trace?.Write($" -- source:{CombatantUtils.Label(source)} adjusted spotterRange:{normalizedRange}m normalized from:{modifiedRange}m");
            return(normalizedRange);
        }
Esempio n. 7
0
 public static void Postfix()
 {
     if (EWState.InBatchProcess)
     {
         Mod.Log.Error?.Write($"Something has gone wrong in refreshing visibility cache, resetting.");
         EWState.ResetCache();
     }
 }
Esempio n. 8
0
        public void TestTargetSignature_NoModifiers()
        {
            Mech attacker = TestHelper.BuildTestMech();
            Mech target   = TestHelper.BuildTestMech();

            EWState attackerState = new EWState(attacker);
            EWState targetState   = new EWState(target);

            Assert.AreEqual(1.0f, SensorLockHelper.GetTargetSignature(target, attackerState));
        }
Esempio n. 9
0
        private static bool HasNarcBeaconDetection(ICombatant target, EWState sourceState, EWState targetState)
        {
            bool hasDetection = false;

            if (target != null && targetState != null && targetState.IsNarced(sourceState))
            {
                hasDetection = true;
            }
            return(hasDetection);
        }
        public void TestTargetSignature_Stealth_Minus_20pct()
        {
            Mech attacker = TestHelper.BuildTestMech();
            Mech target   = TestHelper.BuildTestMech();

            // Stealth - <signature_modifier>_<details_modifier>_<mediumAttackMod>_<longAttackmod>_<extremeAttackMod>
            target.StatCollection.Set(ModStats.StealthEffect, "0.20_2_1_2_3");

            EWState attackerState = new EWState(attacker);

            Assert.AreEqual(0.8f, SensorLockHelper.GetTargetSignature(target, attackerState));
        }
Esempio n. 11
0
        // WARNING: DUPLICATE OF HBS CODE. THIS IS LIKELY TO BREAK IF HBS CHANGES THE SOURCE FUNCTIONS
        public static float GetTargetVisibility(AbstractActor target, EWState sourceState)
        {
            if (target == null)
            {
                return(1f);
            }

            float allTargetVisibilityMultipliers = GetAllTargetVisibilityMultipliers(target, sourceState);
            float allTargetVisibilityAbsolutes   = GetAllTargetVisibilityAbsolutes(target);

            return(1f * allTargetVisibilityMultipliers + allTargetVisibilityAbsolutes);
        }
        public static void Prefix(CombatHUDWeaponPanel __instance, AbstractActor ___displayedActor)
        {
            if (__instance == null || ___displayedActor == null)
            {
                return;
            }
            Mod.Log.Trace?.Write("CHUDWP:RDW - entered.");

            Traverse targetT        = Traverse.Create(__instance).Property("target");
            Traverse hoveredTargetT = Traverse.Create(__instance).Property("hoveredTarget");

            Traverse       HUDT        = Traverse.Create(__instance).Property("HUD");
            CombatHUD      HUD         = HUDT.GetValue <CombatHUD>();
            SelectionState activeState = HUD.SelectionHandler.ActiveState;
            ICombatant     target;

            if (activeState != null && activeState is SelectionStateMove)
            {
                target = hoveredTargetT.GetValue <ICombatant>();
                if (target == null)
                {
                    target = targetT.GetValue <ICombatant>();
                }
            }
            else
            {
                target = targetT.GetValue <ICombatant>();
                if (target == null)
                {
                    target = hoveredTargetT.GetValue <ICombatant>();
                }
            }

            if (target == null)
            {
                return;
            }

            EWState attackerState = new EWState(___displayedActor);

            Mod.Log.Debug?.Write($"Attacker ({CombatantUtils.Label(___displayedActor)} => EWState: {attackerState}");
            bool canSpotTarget = VisualLockHelper.CanSpotTarget(___displayedActor, ___displayedActor.CurrentPosition,
                                                                target, target.CurrentPosition, target.CurrentRotation, ___displayedActor.Combat.LOS);
            SensorScanType sensorScan = SensorLockHelper.CalculateSharedLock(target, ___displayedActor);

            Mod.Log.Debug?.Write($"  canSpotTarget: {canSpotTarget}  sensorScan: {sensorScan}");

            if (target is AbstractActor targetActor)
            {
                EWState targetState = new EWState(targetActor);
                Mod.Log.Debug?.Write($"Target ({CombatantUtils.Label(targetActor)} => EWState: {targetState}");
            }
        }
        public static bool Prefix(SelectionStateFire __instance, ref bool __result, ICombatant combatant)
        {
            Mod.Log.Trace?.Write("SSF:PCC:PRE entered");

            if (__instance != null && combatant != null && combatant is AbstractActor targetActor && __instance.SelectedActor != null)
            {
                CombatGameState Combat           = __instance.SelectedActor.Combat;
                bool            targetIsFriendly = Combat.HostilityMatrix.IsFriendly(combatant.team.GUID, Combat.LocalPlayerTeamGuid);
                if (targetIsFriendly)
                {
                    Mod.Log.Trace?.Write("Friendly target, skipping check");
                    return(true);
                }

                EWState targetState   = new EWState(targetActor);
                EWState attackerState = new EWState(__instance.SelectedActor);

                if (__instance.SelectionType == SelectionType.FireMorale)
                {
                    // Prevents blips from being the targets of called shots
                    VisibilityLevel targetVisibility = __instance.SelectedActor.VisibilityToTargetUnit(targetActor);
                    if (targetVisibility < VisibilityLevel.LOSFull)
                    {
                        Mod.Log.Info?.Write($"Target {CombatantUtils.Label(combatant)} is a blip, cannot be targeted by called shot");
                        __result = false;
                        return(false);
                    }

                    float          distance      = Vector3.Distance(__instance.SelectedActor.CurrentPosition, targetActor.CurrentPosition);
                    bool           hasVisualScan = VisualLockHelper.GetVisualScanRange(__instance.SelectedActor) >= distance;
                    SensorScanType sensorScan    = SensorLockHelper.CalculateSharedLock(targetActor, __instance.SelectedActor);
                    if (sensorScan < SensorScanType.ArmorAndWeaponType && !hasVisualScan)
                    {
                        Mod.Log.Info?.Write($"Target {CombatantUtils.Label(targetActor)} sensor info {sensorScan} is less than SurfaceScan and range:{distance} outside visualScan range, cannot be targeted by called shot");
                        __result = false;
                        return(false);
                    }
                }
                else if (__instance.SelectionType == SelectionType.FireMulti)
                {
                    if (targetState.HasStealth() || targetState.HasMimetic())
                    {
                        Mod.Log.Info?.Write($"Target {CombatantUtils.Label(targetActor)} has stealth, cannot be multi-targeted!");
                        __result = false;
                        return(false);
                    }
                }
            }

            __result = false;
            return(true);
        }
        public void TestStealthSignatureMod()
        {
            Mech attacker = TestHelper.BuildTestMech();
            Mech target   = TestHelper.BuildTestMech();

            // Stealth - <signature_modifier>_<details_modifier>_<mediumAttackMod>_<longAttackmod>_<extremeAttackMod>
            target.StatCollection.Set(ModStats.StealthEffect, "0.20_2_1_2_3");

            EWState attackerState = new EWState(attacker);
            EWState targetState   = new EWState(target);

            Assert.AreEqual(-0.2f, targetState.StealthSignatureMod(attackerState));
        }
Esempio n. 15
0
        public static void Postfix()
        {
            if (EWState.InBatchProcess)
            {
                Mod.Log.Error?.Write($"Something has gone wrong in refreshing visibility cache, resetting.");
                EWState.ResetCache();
            }

            if (AbstractActor_HandleDeath.GateActive)
            {
                Mod.Log.Error?.Write($"Something has gone wrong in handling actor death, resetting VisibilityCacheGate.");
                VisibilityCacheGate.ExitAll();
            }
        }
Esempio n. 16
0
        public void TestTargetSignature_Stealth_20pct()
        {
            Mech attacker = TestHelper.BuildTestMech();
            Mech target   = TestHelper.BuildTestMech();

            Traverse isShutdownT = Traverse.Create(target).Field("_isShutDown");

            isShutdownT.SetValue(true);

            EWState attackerState = new EWState(attacker);
            EWState targetState   = new EWState(target);

            Assert.AreEqual(0.5f, SensorLockHelper.GetTargetSignature(target, attackerState));
        }
Esempio n. 17
0
        public static void Postfix(ref float __result, ICombatant targetUnit)
        {
            Mod.Log.Trace?.Write("MA:GEDFMTW entered");

            if (targetUnit is AbstractActor targetActor)
            {
                EWState targetState = new EWState(targetActor);
                if (targetState.HasStealth() || targetState.HasMimetic())
                {
                    Mod.Log.Debug?.Write($"Target {CombatantUtils.Label(targetUnit)} has stealth, AI cannot multi-attack!");
                    __result = 0f;
                }
            }
        }
Esempio n. 18
0
        public static float GetAdjustedSensorRange(AbstractActor source, ICombatant target)
        {
            EWState sourceState       = source.GetEWState();
            float   sourceSensorRange = SensorLockHelper.GetSensorsRange(source);
            float   targetSignature   = SensorLockHelper.GetTargetSignature(target, sourceState);
            //LowVisibility.Logger.Debug($"   source:{CombatantUtils.Label(source)} sensorRange:{sourceSensorRange}m vs targetSignature:x{targetSignature}");

            //if (target != null && source.VisibilityToTargetUnit(target) > VisibilityLevel.None) {
            //    // If is sensor lock, add the Hysterisis modifier
            //    signatureModifiedRange += ___Combat.Constants.Visibility.SensorHysteresisAdditive;
            //}

            float modifiedRange = sourceSensorRange * targetSignature;

            return(modifiedRange);
        }
Esempio n. 19
0
        public void TestVisibility_NoEffects()
        {
            Mech attacker = TestHelper.BuildTestMech();
            Mech target   = TestHelper.BuildTestMech();

            attacker.StatCollection.AddStatistic <float>("SpotterDistanceMultiplier", 1f);
            attacker.StatCollection.AddStatistic <float>("SpotterDistanceAbsolute", 0f);

            target.StatCollection.AddStatistic <float>("SpottingVisibilityMultiplier", 1f);
            target.StatCollection.AddStatistic <float>("SpottingVisibilityAbsolute", 0f);

            EWState attackerState = new EWState(attacker);
            EWState targetState   = new EWState(target);

            Assert.AreEqual(1.0f, VisualLockHelper.GetTargetVisibility(target, attackerState));
        }
Esempio n. 20
0
        public static void RedrawFogOfWar(AbstractActor activeActor)
        {
            if (!Mod.Config.FogOfWar.RedrawFogOfWarOnActivation)
            {
                return;
            }

            FogOfWarSystem fowSystem = LazySingletonBehavior <FogOfWarView> .Instance.FowSystem;

            if (fowSystem == null)
            {
                Mod.Log.Error?.Write("FogOfWarSystem could not be found - this should never happen!");
                return;
            }

            Mod.Log.Debug?.Write($"Redrawing FOW for actor: {CombatantUtils.Label(activeActor)}");

            Traverse             viewersT = Traverse.Create(fowSystem).Field("viewers");
            List <AbstractActor> viewers  = viewersT.GetValue <List <AbstractActor> >();

            viewers.Clear();

            // Reset FoW to being unseen
            fowSystem.WipeToValue(Mod.Config.FogOfWar.ShowTerrainThroughFogOfWar ?
                                  FogOfWarState.Surveyed : FogOfWarState.Unknown);

            // Add the actor as a viewer
            fowSystem.AddViewer(activeActor);

            // Check lancemates; if they have vision sharing add them as well
            foreach (string lanceGuid in activeActor?.lance?.unitGuids)
            {
                if (!lanceGuid.Equals(activeActor.GUID))
                {
                    ICombatant lanceMateC = activeActor.Combat.FindCombatantByGUID(lanceGuid);
                    if (lanceMateC is AbstractActor lanceActor)
                    {
                        EWState lanceState = new EWState(lanceActor);
                        if (lanceState.SharesVision())
                        {
                            fowSystem.AddViewer(lanceActor);
                        }
                    }
                }
            }
        }
Esempio n. 21
0
        public static void Reset()
        {
            Mod.Log.Info?.Write($"RESETTING STATE!");
            // Reinitialize state
            MapConfig                = null;
            MoodController           = null;
            LastPlayerActorActivated = null;
            TurnDirectorStarted      = false;
            IsNightVisionMode        = false;

            CheckResults   = new double[ResultsToPrecalcuate];
            CheckResultIdx = 0;

            // Combat state
            Combat = null;
            MarkContainerRefs.Clear();

            EWState.ResetCache();
        }
Esempio n. 22
0
        public static void Prefix(TurnDirector __instance, int round)
        {
            Mod.Log.Trace?.Write($"TD:BNR entered");
            Mod.Log.Info?.Write($"=== Turn Director is beginning round: {round}");

            // Update the current vision for all allied and friendly units
            foreach (AbstractActor actor in __instance.Combat.AllActors)
            {
                Mod.Log.Info?.Write($" -- Updating actor: {actor.DistinctId()}");

                // If our sensors are offline, re-enable them
                if (actor.StatCollection.ContainsStatistic(ModStats.DisableSensors))
                {
                    if (round >= actor.StatCollection.GetValue <int>(ModStats.DisableSensors))
                    {
                        Mod.Log.Info?.Write($"Re-enabling sensors for {CombatantUtils.Label(actor)}");
                        actor.StatCollection.RemoveStatistic(ModStats.DisableSensors);
                    }
                    else
                    {
                        Mod.Log.Info?.Write($"Actor: {CombatantUtils.Label(actor)} sensors are offline until: {actor.StatCollection.GetValue<int>(ModStats.DisableSensors)}");
                    }
                }

                // Update our sensors check
                ActorHelper.UpdateSensorCheck(actor, true);

                // Print the current state of the actor
                EWState actorState = new EWState(actor);
                Mod.Log.Info?.Write(actorState.ToString());
            }

            // Now that all sensor checks are updated, refresh visiblity for all actors
            foreach (AbstractActor actor in __instance.Combat.AllActors)
            {
                if (actor.TeamId == __instance.Combat.LocalPlayerTeamGuid)
                {
                    actor.VisibilityCache.RebuildCache(actor.Combat.GetAllImporantCombatants());
                    CombatHUDHelper.ForceNameRefresh(actor.Combat);
                }
            }
        }
Esempio n. 23
0
        public void TestVisibility_Shutdown()
        {
            Mech attacker = TestHelper.BuildTestMech();
            Mech target   = TestHelper.BuildTestMech();

            attacker.StatCollection.AddStatistic <float>("SpotterDistanceMultiplier", 1f);
            attacker.StatCollection.AddStatistic <float>("SpotterDistanceAbsolute", 0f);

            target.StatCollection.AddStatistic <float>("SpottingVisibilityMultiplier", 1f);
            target.StatCollection.AddStatistic <float>("SpottingVisibilityAbsolute", 0f);

            Traverse isShutdownT = Traverse.Create(target).Field("_isShutDown");

            isShutdownT.SetValue(true);

            EWState attackerState = new EWState(attacker);
            EWState targetState   = new EWState(target);

            Assert.AreEqual(0.5f, VisualLockHelper.GetTargetVisibility(target, attackerState));
        }
        public static void Prefix(AbstractActor __instance, int stackItemID)
        {
            if (stackItemID == -1 || __instance == null || __instance.HasBegunActivation)
            {
                // For some bloody reason DoneWithActor() invokes OnActivationBegin, EVEN THOUGH IT DOES NOTHING. GAH!
                return;
            }

            // Draw stealth if applicable
            EWState actorState = new EWState(__instance);

            if (actorState.HasStealth())
            {
                Mod.Log.Debug?.Write($"-- Sending message to update stealth");
                StealthChangedMessage message = new StealthChangedMessage(__instance.GUID);
                __instance.Combat.MessageCenter.PublishMessage(message);
            }

            // If friendly, reset the map visibility
            if (__instance.TeamId != __instance.Combat.LocalPlayerTeamGuid &&
                __instance.Combat.HostilityMatrix.IsLocalPlayerFriendly(__instance.TeamId))
            {
                Mod.Log.Info?.Write($"{CombatantUtils.Label(__instance)} IS FRIENDLY, REBUILDING FOG OF WAR");

                if (actorState.HasNightVision() && ModState.GetMapConfig().isDark)
                {
                    Mod.Log.Info?.Write($"Enabling night vision mode.");
                    VfxHelper.EnableNightVisionEffect(__instance);
                }
                else
                {
                    // TODO: This is likely never triggered due to the patch below... remove?
                    if (ModState.IsNightVisionMode)
                    {
                        VfxHelper.DisableNightVisionEffect();
                    }
                }

                VfxHelper.RedrawFogOfWar(__instance);
            }
        }
Esempio n. 25
0
        // Records actor selected events to allow id of the last player unit a player selected
        public static void OnActorSelectedMessage(MessageCenterMessage message)
        {
            ActorSelectedMessage actorSelectedMessage = message as ActorSelectedMessage;
            AbstractActor        actor = Combat.FindActorByGUID(actorSelectedMessage.affectedObjectGuid);

            if (actor.team.IsLocalPlayer)
            {
                Mod.Log.Info?.Write($"Updating last activated actor to: ({CombatantUtils.Label(actor)})");
                ModState.LastPlayerActorActivated = actor;

                EWState actorState = new EWState(actor);
                if (actorState.HasNightVision() && ModState.GetMapConfig().isDark)
                {
                    Mod.Log.Info?.Write($"Enabling night vision mode.");
                    VfxHelper.EnableNightVisionEffect(actor);
                }
                else
                {
                    if (ModState.IsNightVisionMode)
                    {
                        VfxHelper.DisableNightVisionEffect();
                    }
                }

                // Refresh the unit's vision
                VfxHelper.RedrawFogOfWar(actor);
                actor.VisibilityCache.RebuildCache(actor.Combat.GetAllImporantCombatants());
                CombatHUDHelper.ForceNameRefresh(actor.Combat);

                // Hack - turn on Vision indicator?
                VisRangeIndicator visRangeIndicator = VisRangeIndicator.Instance;
                visRangeIndicator.SetState(VisRangeIndicator.VisRangeIndicatorState.On);

                // Refresh any CombatHUDMarkDisplays
                foreach (CombatHUDMarkDisplay chudMD in ModState.MarkContainerRefs.Keys)
                {
                    chudMD.RefreshInfo();
                }
            }
        }
Esempio n. 26
0
        public void TestStealthAttackMod_Negatives()
        {
            Mech attacker = TestHelper.BuildTestMech();
            Mech target   = TestHelper.BuildTestMech();

            // Stealth - <signature_modifier>_<details_modifier>_<mediumAttackMod>_<longAttackmod>_<extremeAttackMod>
            target.StatCollection.Set(ModStats.StealthEffect, "0.99_9_-1_-2_-3");

            EWState attackerState = new EWState(attacker);
            EWState targetState   = new EWState(target);

            Weapon weapon = TestHelper.BuildTestWeapon(0, 60, 120, 240, 480);

            Assert.AreEqual(0, targetState.StealthAttackMod(attackerState, weapon, 30));
            Assert.AreEqual(0, targetState.StealthAttackMod(attackerState, weapon, 60));
            Assert.AreEqual(1, targetState.StealthAttackMod(attackerState, weapon, 90));
            Assert.AreEqual(1, targetState.StealthAttackMod(attackerState, weapon, 120));
            Assert.AreEqual(2, targetState.StealthAttackMod(attackerState, weapon, 200));
            Assert.AreEqual(2, targetState.StealthAttackMod(attackerState, weapon, 240));
            Assert.AreEqual(3, targetState.StealthAttackMod(attackerState, weapon, 400));
            Assert.AreEqual(3, targetState.StealthAttackMod(attackerState, weapon, 480));
        }
Esempio n. 27
0
        // WARNING: DUPLICATE OF HBS CODE. THIS IS LIKELY TO BREAK IF HBS CHANGES THE SOURCE FUNCTIONS
        private static float GetAllTargetVisibilityMultipliers(AbstractActor target, EWState sourceState)
        {
            if (target == null)
            {
                return(1f);
            }

            float baseVisMulti                 = 1f;
            float shutdownVisMulti             = (!target.IsShutDown) ? 1f : target.Combat.Constants.Visibility.ShutDownVisibilityModifier;
            float spottingVisibilityMultiplier = target.SpottingVisibilityMultiplier;

            EWState ewState    = target.GetEWState();
            float   mimeticMod = ewState.MimeticVisibilityMod(sourceState);

            float targetVisibility = baseVisMulti * shutdownVisMulti * spottingVisibilityMultiplier * mimeticMod;

            Mod.Log.Trace?.Write($" Actor: {CombatantUtils.Label(target)} has visibility: {targetVisibility} = " +
                                 $"baseVisMulti: {baseVisMulti} * shutdownVisMulti: {shutdownVisMulti} * spottingVisibilityMultiplier: {spottingVisibilityMultiplier} * visionStealthMod: {mimeticMod}");

            return(targetVisibility);
            //return baseVisMulti + shutdownVisMulti + spottingVisibilityMultiplier;
        }
Esempio n. 28
0
        public void TestMimetic_Visibility_DecayThreeStep()
        {
            Mech attacker = TestHelper.BuildTestMech();
            Mech target   = TestHelper.BuildTestMech();

            target.CurrentPosition = new Vector3(180f, 0, 0);
            Traverse previousPositionT = Traverse.Create(target).Field("previousPosition");

            previousPositionT.SetValue(new Vector3(0f, 0f, 0f));

            attacker.StatCollection.AddStatistic <float>("SpotterDistanceMultiplier", 1f);
            attacker.StatCollection.AddStatistic <float>("SpotterDistanceAbsolute", 0f);

            target.StatCollection.AddStatistic <float>("SpottingVisibilityMultiplier", 1f);
            target.StatCollection.AddStatistic <float>("SpottingVisibilityAbsolute", 0f);
            target.StatCollection.Set(ModStats.MimeticEffect, "4_0.10_1_2");

            EWState attackerState = new EWState(attacker);
            EWState targetState   = new EWState(target);

            Assert.AreEqual(0.9f, VisualLockHelper.GetTargetVisibility(target, attackerState), 0.001);
        }
Esempio n. 29
0
        public void TestMimetic_AttackMod_DecayOneStep_FractionalAtkMod()
        {
            Mech attacker = TestHelper.BuildTestMech();
            Mech target   = TestHelper.BuildTestMech();

            target.CurrentPosition = new Vector3(90f, 0, 0);
            Traverse previousPositionT = Traverse.Create(target).Field("previousPosition");

            previousPositionT.SetValue(new Vector3(0f, 0f, 0f));

            attacker.StatCollection.AddStatistic <float>("SpotterDistanceMultiplier", 1f);
            attacker.StatCollection.AddStatistic <float>("SpotterDistanceAbsolute", 0f);

            target.StatCollection.AddStatistic <float>("SpottingVisibilityMultiplier", 1f);
            target.StatCollection.AddStatistic <float>("SpottingVisibilityAbsolute", 0f);
            target.StatCollection.Set(ModStats.MimeticEffect, "4_0.10_0.5_2");

            EWState attackerState = new EWState(attacker);
            EWState targetState   = new EWState(target);

            Assert.AreEqual(2, targetState.MimeticAttackMod(attackerState));
        }
Esempio n. 30
0
        // WARNING: DUPLICATE OF HBS CODE. THIS IS LIKELY TO BREAK IF HBS CHANGES THE SOURCE FUNCTIONS
        private static float GetAllTargetSignatureModifiers(AbstractActor target, EWState sourceState)
        {
            if (target == null)
            {
                return(1f);
            }

            float shutdownMod = (!target.IsShutDown) ? 1f : target.Combat.Constants.Visibility.ShutDownSignatureModifier;

            float chassisSignature = target.StatCollection.GetValue <float>(ModStats.HBS_SensorSignatureModifier);

            if (chassisSignature == 0f)
            {
                chassisSignature = 1.0f;                         // Fix until redbat fixes this
            }
            EWState ewState      = target.GetEWState();
            float   ecmShieldMod = ewState.ECMSignatureMod(sourceState);
            float   stealthMod   = ewState.StealthSignatureMod(sourceState);
            float   narcMod      = ewState.NarcSignatureMod(sourceState);
            float   tagMod       = ewState.TagSignatureMod(sourceState);

            float signatureMods   = (1.0f + stealthMod) * (1.0f + ecmShieldMod) * (1.0f + narcMod) * (1.0f + tagMod);
            float targetSignature = chassisSignature * shutdownMod * signatureMods;

            Mod.Log.Trace?.Write($" Actor: {CombatantUtils.Label(target)} has signature: {targetSignature} = " +
                                 $"rawSignature: {chassisSignature} x shutdown: {shutdownMod}" +
                                 $" x (1.0 + ecmShield: {ecmShieldMod})" +
                                 $" x (1.0 + stealthMod: {stealthMod})" +
                                 $" x (1.0 + narc: {narcMod})" +
                                 $" x (1.0 + tag: {tagMod})");

            if (targetSignature < Mod.Config.Sensors.MinSignature)
            {
                targetSignature = Mod.Config.Sensors.MinSignature;
            }

            return(targetSignature);
        }