예제 #1
0
 public static void PlayVFX(AIMCritInfo info)
 {
     try {
         ICombatant target = info.target;
         if (target.GameRep == null)
         {
             return;
         }
         MechComponent component = info.component;
         bool          isAmmo = component is AmmunitionBox, isJumpJet = component is Jumpjet, isHeatSink = component.componentDef is HeatSinkDef;
         if (target.team.LocalPlayerControlsTeam)
         {
             AudioEventManager.PlayAudioEvent("audioeventdef_musictriggers_combat", "critical_hit_friendly ", null, null);
         }
         else if (!target.team.IsFriendly(Combat.LocalPlayerTeam))
         {
             AudioEventManager.PlayAudioEvent("audioeventdef_musictriggers_combat", "critical_hit_enemy", null, null);
         }
         if (target.GameRep is MechRepresentation MechRep && !isJumpJet && !isHeatSink && !isAmmo && component.DamageLevel > ComponentDamageLevel.Functional)
         {
             MechRep.PlayComponentCritVFX(info.GetCritLocation());
         }
         if (isAmmo && component.DamageLevel > ComponentDamageLevel.Functional)
         {
             target.GameRep.PlayVFX(info.GetCritLocation(), Combat.Constants.VFXNames.componentDestruction_AmmoExplosion, true, Vector3.zero, true, -1f);
         }
     }                 catch (Exception ex) { Error(ex); }
 }
        public static void Prefix(Turret __instance)
        {
            try
            {
                if (__instance.Combat.IsLoadingFromSave)
                {
                    return;
                }

                var turret = __instance;
                var num    = __instance.allComponents.Select(x => int.Parse(x.uid)).DefaultIfEmpty().Max();
                foreach (var componentRef in turret.TurretDef.Inventory)
                {
                    if (componentRef.ComponentDefType == ComponentType.Weapon)
                    {
                    }
                    else if (componentRef.ComponentDefType == ComponentType.AmmunitionBox)
                    {
                    }
                    else
                    {
                        num++;
                        var component = new MechComponent(turret, turret.Combat, componentRef, num.ToString());
                        turret.allComponents.Add(component);
                    }
                }
            }
            catch (Exception e)
            {
                Control.mod.Logger.LogError(e);
            }
        }
예제 #3
0
        public static int GetEngineModifier(AbstractActor actor)
        {
            int engineMod = 0;

            if (actor.GetTags().Contains("unit_powerarmor"))
            {
                Mod.Log.Debug($"  Actor:{actor.DisplayName}_{actor.GetPilot().Name} is PowerArmor, skipping engine bonus.");
            }
            else
            {
                MechComponent mainEngineComponent = actor?.allComponents?.FirstOrDefault(c => c?.componentDef?.GetComponent <EngineCoreDef>() != null);
                if (mainEngineComponent != null)
                {
                    EngineCoreDef engine  = mainEngineComponent?.componentDef?.GetComponent <EngineCoreDef>();
                    float         tonnage = GetUnitTonnage(actor);
                    engineMod = CalculateEngineModifier(tonnage, engine.Rating);
                    Mod.Log.Debug($"  Actor:{actor.DisplayName}_{actor.GetPilot().Name} with engine rating: {engine?.Rating} has engineMod:{engineMod}");
                }
                else
                {
                    Mod.Log.Info($"  Actor:{actor.DisplayName}_{actor.GetPilot().Name} has no engine - is this expected?");
                }
            }

            return(engineMod);
        }
 public static void CancelCreatedEffects(MechComponent mechComponent, bool performAuraRefresh = true)
 {
     if (mechComponent.DamageLevel >= ComponentDamageLevel.NonFunctional)
     {
         mechComponent.CancelCreatedEffects(performAuraRefresh);
     }
 }
예제 #5
0
        internal static bool ProcessLocationalEffectData(ref EffectData effect, MechComponent mechComponent)
        {
            if (effect.effectType == EffectType.StatisticEffect &&
                LocationNaming.IsLocational(effect.Description.Id) &&
                LocationNaming.Create(mechComponent, out var naming))
            {
                var data = effect.ToJSON();
                effect = new EffectData();
                effect.FromJSON(data);

                Control.mod.Logger.LogDebug($"Replacing location in {effect.Description.Id} with {naming.LocationId}");

                effect.statisticData.statName = naming.InterpolateStatisticName(effect.statisticData.statName);

                effect.Description = new BaseDescriptionDef(
                    naming.InterpolateEffectId(effect.Description.Id),
                    naming.InterpolateText(effect.Description.Name),
                    naming.InterpolateText(effect.Description.Details),
                    naming.InterpolateText(effect.Description.Icon)
                    );

                return(true);
            }

            return(false);
        }
예제 #6
0
        internal static int CriticalSlotsHitLinked(this MechComponent mechComponent, int?setHits = null)
        {
            var ce = mechComponent.GetCriticalEffects();

            if (ce == null)
            {
                throw new Exception("should not happen");
            }

            if (!ce.HasLinked)
            {
                throw new Exception("shouldn't really happen too");
            }

            var statisticName = mechComponent.ScopedId(ce.LinkedStatisticName, true);
            var collection    = mechComponent.parent.StatCollection;

            var critStat = collection.GetStatistic(statisticName) ?? collection.AddStatistic(statisticName, 0);

            if (setHits.HasValue)
            {
                critStat.SetValue(setHits.Value);
            }
            return(critStat?.Value <int>() ?? 0);
        }
        static public List <ComponentLocator> GetWeaponComponentLocatorList(Mech m)
        {
            List <ComponentLocator> compLocList = new List <ComponentLocator>();

            foreach (ChassisLocations loc in System.Enum.GetValues(typeof(ChassisLocations)))
            {
                if ((loc == ChassisLocations.All) ||
                    (loc == ChassisLocations.Arms) ||
                    (loc == ChassisLocations.Legs) ||
                    (loc == ChassisLocations.Torso) ||
                    (loc == ChassisLocations.None))
                {
                    continue;
                }

                int inventorySlotsCount = m.MechDef.GetChassisLocationDef(loc).InventorySlots;
                if (inventorySlotsCount == 0)
                {
                    continue;
                }

                for (int slotIndex = 0; slotIndex < inventorySlotsCount; ++slotIndex)
                {
                    MechComponent component = m.GetComponentInSlot(loc, slotIndex);
                    if (component is Weapon)
                    {
                        ComponentLocator compLoc = new ComponentLocator(m, loc, slotIndex);
                        compLocList.Add(compLoc);
                    }
                }
            }
            return(compLocList);
        }
        public static bool ResolveSystemFailureCheck(Mech mech, int heatToCheck, int rootSequenceGUID, float heatCheck)
        {
            bool failedSystemFailureCheck = !CheckHelper.DidCheckPassThreshold(Mod.Config.Heat.SystemFailures, heatToCheck, mech, heatCheck, ModText.FT_Check_System_Failure);

            Mod.Log.Debug?.Write($"  failedSystemFailureCheck: {failedSystemFailureCheck}");
            if (failedSystemFailureCheck)
            {
                Mod.Log.Info?.Write($"-- System Failure check failed, forcing system damage on unit: {CombatantUtils.Label(mech)}");
                List <MechComponent> functionalComponents = new List <MechComponent>();
                foreach (MechComponent mc in mech.allComponents)
                {
                    bool canTarget = mc.IsFunctional;
                    if (mc.mechComponentRef.Is <Flags>(out Flags flagsCC))
                    {
                        if (flagsCC.IsSet(ModStats.ME_IgnoreDamage))
                        {
                            canTarget = false;
                            Mod.Log.Trace?.Write($"    Component: {mc.Name} / {mc.UIName} is marked ignores_damage.");
                        }
                    }
                    if (canTarget)
                    {
                        functionalComponents.Add(mc);
                    }
                }
                MechComponent componentToDamage = functionalComponents.GetRandomElement();
                Mod.Log.Info?.Write($"   Destroying component: {componentToDamage.UIName} from heat damage.");

                WeaponHitInfo fakeHit = new WeaponHitInfo(rootSequenceGUID, -1, -1, -1, string.Empty, string.Empty, -1, null, null, null, null, null, null, null,
                                                          new AttackDirection[] { AttackDirection.None }, null, null, null);
                componentToDamage.DamageComponent(fakeHit, ComponentDamageLevel.Destroyed, true);
            }

            return(failedSystemFailureCheck);
        }
        static Dictionary <ComponentLocator, float> getComponentDictionary(Mech targetMech, ChassisLocations chassisLoc)
        {
            Dictionary <ComponentLocator, float> componentDict = new Dictionary <ComponentLocator, float>();

            int inventorySlotsCount = targetMech.MechDef.GetChassisLocationDef(chassisLoc).InventorySlots;

            if (inventorySlotsCount == 0)
            {
                return(componentDict);
            }

            float slotProbability = 1.0f / inventorySlotsCount;

            for (int slotIndex = 0; slotIndex < inventorySlotsCount; ++slotIndex)
            {
                MechComponent component = targetMech.GetComponentInSlot(chassisLoc, slotIndex);
                if (component != null)
                {
                    ComponentLocator compLoc = new ComponentLocator(targetMech, chassisLoc, slotIndex);
                    componentDict[compLoc] = slotProbability;
                }
            }

            return(componentDict);
        }
예제 #10
0
            public static void Postfix(MechComponent __instance, ref Text __result)
            {
                try
                {
                    if (!__instance.IsFunctional || __instance.GetType() != typeof(Weapon))
                    {
                        return;
                    }

                    Weapon weapon = (Weapon)__instance;
                    if (IsJammed(weapon))
                    {
                        string originalUIName = __result.ToString();
                        Color  color          = LazySingletonBehavior <UIManager> .Instance.UIColorRefs.orangeHalf;

                        __result = new Localize.Text($"<color=#{ColorUtility.ToHtmlStringRGBA(color)}>{originalUIName}</color>", new object[] { });

                        //string weaponCaliber = new String(originalUIName.Where(Char.IsDigit).ToArray());
                        //__result = new Localize.Text($"JAMMED <size=75%>(UAC/{weaponCaliber})</size>", new object[] { });
                        //__result.Append(" <size=75%>( JAMMED )</size>", new object[0]);
                        //__result = new Localize.Text("UAC JAMMED", new object[] { });
                    }
                }
                catch (Exception e)
                {
                    Logger.Error(e);
                }
            }
        // crit engine reduces speed
        // destroyed engine destroys CT
        public static bool Prefix(MechComponent __instance, CombatGameState ___combat, WeaponHitInfo hitInfo, ComponentDamageLevel damageLevel, bool applyEffects)
        {
            try
            {
                if (__instance.mechComponentRef.Is <Flags>(out var f) && f.IsSet("ignore_damage"))
                {
                    MechCheckForCritPatch.Message = null;
                    return(false);
                }

                if (!CirticalHitStatesHandler.Shared.ProcessWeaponHit(__instance, ___combat, hitInfo, damageLevel, applyEffects, MechCheckForCritPatch.MessageAdditions))
                {
                    MechCheckForCritPatch.Message = null;
                    return(false);
                }

                if (!EngineCrits.ProcessWeaponHit(__instance, hitInfo, damageLevel, applyEffects, MechCheckForCritPatch.MessageAdditions))
                {
                    MechCheckForCritPatch.Message = null;
                    return(false);
                }
            }
            catch (Exception e)
            {
                Control.mod.Logger.LogError(e);
            }

            return(true);
        }
예제 #12
0
 /*public static bool ShouldAffectThisActor(this AuraCache instance, AbstractActor fromActor, EffectData effect, EffectTriggerType triggerSource) {
  * return (bool)mShouldAffectThisActor.Invoke(instance, new object[] { fromActor, effect, triggerSource });
  * }
  * public static bool AuraConditionsPassed(this AuraCache instance, AbstractActor fromActor, MechComponent auraComponent, EffectData effectData, float distSquared, EffectTriggerType triggerSource) {
  * return (bool)mAuraConditionsPassed.Invoke(instance, new object[] {  fromActor, auraComponent,  effectData,  distSquared,  triggerSource });
  * }*/
 public static bool Prefix(AuraCache __instance, AbstractActor fromActor, MechComponent auraComponent, float distSquared, ref List <EffectData> __result)
 {
     /*AbstractActor Owner = (AbstractActor)FOwner.Invoke(__instance, new object[0] { });
      * List<EffectData> effectDataList = new List<EffectData>();
      * for (int index = 0; index < auraComponent.componentDef.statusEffects.Length; ++index) {
      * if (__instance.ShouldAffectThisActor(fromActor, auraComponent.componentDef.statusEffects[index], EffectTriggerType.Preview) && __instance.AuraConditionsPassed(fromActor, auraComponent, auraComponent.componentDef.statusEffects[index], distSquared, EffectTriggerType.Preview))
      *  effectDataList.Add(auraComponent.componentDef.statusEffects[index]);
      * }
      * ActivatableComponent activatable = auraComponent.componentDef.GetComponent<ActivatableComponent>();
      * if (activatable != null) {
      * if (auraComponent.isActive()) {
      *  for (int index = 0; index < activatable.statusEffects.Length; ++index) {
      *    if (__instance.ShouldAffectThisActor(fromActor, activatable.statusEffects[index], EffectTriggerType.Preview) && __instance.AuraConditionsPassed(fromActor, auraComponent, activatable.statusEffects[index], distSquared, EffectTriggerType.Preview))
      *      effectDataList.Add(activatable.statusEffects[index]);
      *  }
      * } else {
      *  for (int index = 0; index < activatable.offlineStatusEffects.Length; ++index) {
      *    if (__instance.ShouldAffectThisActor(fromActor, activatable.offlineStatusEffects[index], EffectTriggerType.Preview) && __instance.AuraConditionsPassed(fromActor, auraComponent, activatable.offlineStatusEffects[index], distSquared, EffectTriggerType.Preview))
      *      effectDataList.Add(activatable.offlineStatusEffects[index]);
      *  }
      * }
      * }
      * __result = effectDataList;*/
     return(false);
     //Log.LogWrite("AuraCache.PreviewAura prefix owner:" + Owner.DisplayName + ":" + Owner.GUID + " from: " + fromActor.DisplayName + ":" + fromActor.GUID + " component:" + auraComponent.defId + "\n");
 }
예제 #13
0
        private static MechComponent FindAndCritComponent(AIMCritInfo critInfo, float random)
        {
            MechComponent component = critInfo.FindComponentFromRoll(random);

            if (component != null)
            {
                if (DebugLog)
                {
                    Verbo("Play crit SFX and VFX on {0} ({1}) at {2}", component, component.DamageLevel, component.Location);
                }
                PlaySFX(critInfo);
                PlayVFX(critInfo);
                AttackDirector.AttackSequence attackSequence = GetAttackSequence(critInfo.hitInfo);
                attackSequence?.FlagAttackScoredCrit(component as Weapon, component as AmmunitionBox);
                ComponentDamageLevel newDamageLevel = GetDegradedComponentLevel(critInfo);
                if (DebugLog)
                {
                    Verbo("Component damaged to {0}", newDamageLevel);
                }
                try {
                    component.DamageComponent(critInfo.hitInfo, newDamageLevel, true);
                } catch (Exception ex) { Error(ex); }
            }
            return(component);
        }
예제 #14
0
        // crit engine reduces speed
        // destroyed engine destroys CT
        public static bool Prefix(MechComponent __instance, WeaponHitInfo hitInfo, ComponentDamageLevel damageLevel, bool applyEffects)
        {
            try
            {
                if (!EngineCrits.ProcessWeaponHit(__instance, hitInfo, damageLevel, applyEffects, MechCheckForCritPatch.MessageAdditions))
                {
                    MechCheckForCritPatch.Message = null;
                    return(false);
                }

                if (!Structure.ProcessWeaponHit(__instance, hitInfo, damageLevel, applyEffects))
                {
                    MechCheckForCritPatch.Message = null;
                    return(false);
                }

                if (!Armor.ProcessWeaponHit(__instance, hitInfo, damageLevel, applyEffects))
                {
                    MechCheckForCritPatch.Message = null;
                    return(false);
                }
            }
            catch (Exception e)
            {
                Control.mod.Logger.LogError(e);
            }

            return(true);
        }
예제 #15
0
        public static bool CanBeActivated(this MechComponent component)
        {
            ActivatableComponent activatable = component.componentDef.GetComponent <ActivatableComponent>();

            if (component.DamageLevel >= ComponentDamageLevel.Destroyed)
            {
                return(false);
            }
            if (activatable == null)
            {
                return(false);
            }
            ;
            if (activatable.CanBeactivatedManualy == false)
            {
                return(false);
            }
            if (activatable.ChargesCount == -1)
            {
                return(true);
            }
            ;
            if (activatable.ChargesCount > 0)
            {
                if (activatable.ChargesCount <= component.ChargesCount())
                {
                    return(false);
                }
                ;
            }
            ;
            return(true);
        }
예제 #16
0
        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);
            }
        }
예제 #17
0
        public static bool isFailDanger(this MechComponent component)
        {
            ActivatableComponent activatable = component.componentDef.GetComponent <ActivatableComponent>();
            Mech mech = component.parent as Mech;

            if (activatable.FailCrit && component.isExplode())
            {
                return(true);
            }
            ;
            if (mech == null)
            {
                return(false);
            }
            foreach (var Location in activatable.FailDamageLocations)
            {
                if (mech != null)
                {
                    foreach (var lcomp in mech.GetComponentsForLocation(Location, ComponentType.AmmunitionBox))
                    {
                        return(true);
                    }
                }
                if (component.parent.StructureForLocation((int)Location) < activatable.FailISDamage)
                {
                    return(true);
                }
            }
            return(false);
        }
예제 #18
0
 internal static float LogAIMCritChance(float chance, object hitLocation)
 {
     thisCritChance   = chance;
     thisCritLocation = hitLocation.ToString();
     thisCritComp     = null;
     return(chance);
 }
예제 #19
0
        private static TagSet prepareTags(MechComponent target)
        {
            //Control.Log($"Prepating tags for "+target.defId);
            string GUID = target.getCCGUID();
            TagSet tags = null;

            if (CustomCombatTagsHelper.tagsCache.ContainsKey(GUID) == false)
            {
                //Control.Log($" not in cache");
                if (CustomCombatTagsHelper.checkExistance(target.StatCollection, CustomCombatTagsHelper.CCComponentTagsStatName) == false)
                {
                    //Control.Log($" have no statistic value:"+ CustomCombatTagsHelper.CCComponentTagsStatName);
                    tags = new TagSet();
                    tags.AddRange(target.componentDef.ComponentTags);
                }
                else
                {
                    string tags_string = target.StatCollection.GetStatistic(CustomCombatTagsHelper.CCComponentTagsStatName).Value <string>();
                    tags = TagSet.Parse(tags_string);
                    //Control.Log($" have statistic value:" + CustomCombatTagsHelper.CCComponentTagsStatName+":"+tags_string);
                }
                CustomCombatTagsHelper.tagsCache[GUID] = tags;
            }
            else
            {
                //Control.Log($" in cache");
                tags = CustomCombatTagsHelper.tagsCache[GUID];
            }
            return(tags);
        }
예제 #20
0
 public static void RestartPassiveEffects(this MechComponent @this, bool performAuraRefresh)
 {
     if (HeatSinkCapacityStatFeature.Shared.IgnoreShutdown(@this))
     {
         return;
     }
     @this.RestartPassiveEffects(performAuraRefresh);
 }
예제 #21
0
 public static bool setAIRollPassed(this MechComponent component, bool val)
 {
     if (Core.checkExistance(component.StatCollection, AIRollPassStatName) == false)
     {
         component.StatCollection.AddStatistic <bool>(AIRollPassStatName, false);
     }
     return(component.StatCollection.Set <bool>(AIRollPassStatName, val));
 }
예제 #22
0
 public static bool isAIRollPassed(this MechComponent component)
 {
     if (Core.checkExistance(component.StatCollection, AIRollPassStatName) == false)
     {
         component.StatCollection.AddStatistic <bool>(AIRollPassStatName, false);
     }
     return(component.StatCollection.GetStatistic(AIRollPassStatName).Value <bool>());
 }
예제 #23
0
        public static void playDestroySound(this MechComponent component)
        {
            ActivatableComponent activatable = component.componentDef.GetComponent <ActivatableComponent>();

            if (activatable != null)
            {
                activatable.playDestroySound(component.parent.GameRep.audioObject);
            }
        }
예제 #24
0
        private float getHeatMult(MechComponent mechComponent)
        {
            if (mechComponent.componentDef.Is <HeatSinkingCost>(out var costFactor))
            {
                return(costFactor.HeatUpkeepMult);
            }

            return(1f);
        }
예제 #25
0
        public VFXObjects(MechComponent p)
        {
            this.parent = p;
            ActivatableComponent activatable = this.parent.componentDef.GetComponent <ActivatableComponent>();

            if (activatable != null)
            {
                GameObject parentObject = p.parent.GameRep.gameObject;
                Weapon     weapon       = p as Weapon;
                if (weapon != null)
                {
                    if (weapon.weaponRep != null)
                    {
                        parentObject = weapon.weaponRep.gameObject;
                    }
                }
                Log.LogWrite(p.defId + " is activatable \n");
                if (activatable.presistantVFX.isInited)
                {
                    try {
                        Log.LogWrite(p.defId + " spawning " + activatable.presistantVFX.VFXPrefab + " \n");
                        presitantObject = new ObjectSpawnDataSelf(activatable.presistantVFX.VFXPrefab, parentObject,
                                                                  new Vector3(activatable.presistantVFX.VFXOffsetX, activatable.presistantVFX.VFXOffsetY, activatable.presistantVFX.VFXOffsetZ),
                                                                  new Vector3(activatable.presistantVFX.VFXScaleX, activatable.presistantVFX.VFXScaleY, activatable.presistantVFX.VFXScaleZ), true, false);
                        presitantObject.SpawnSelf(parent.parent.Combat);
                    } catch (Exception e) {
                        Log.LogWrite(" Fail to spawn vfx " + e.ToString() + "\n");
                    }
                }
                else
                {
                    presitantObject = null;
                }
                if (activatable.activateVFX.isInited)
                {
                    Log.LogWrite(p.defId + " spawning " + activatable.activateVFX.VFXPrefab + " \n");
                    activateObject = new ObjectSpawnDataSelf(activatable.activateVFX.VFXPrefab, parentObject,
                                                             new Vector3(activatable.activateVFX.VFXOffsetX, activatable.activateVFX.VFXOffsetY, activatable.activateVFX.VFXOffsetZ),
                                                             new Vector3(activatable.activateVFX.VFXScaleX, activatable.activateVFX.VFXScaleY, activatable.activateVFX.VFXScaleZ), true, false);
                }
                else
                {
                    activateObject = null;
                }
                if (activatable.destroyedVFX.isInited)
                {
                    Log.LogWrite(p.defId + " spawning " + activatable.destroyedVFX.VFXPrefab + " \n");
                    destroyedObject = new ObjectSpawnDataSelf(activatable.destroyedVFX.VFXPrefab, parentObject,
                                                              new Vector3(activatable.destroyedVFX.VFXOffsetX, activatable.destroyedVFX.VFXOffsetY, activatable.destroyedVFX.VFXOffsetZ),
                                                              new Vector3(activatable.destroyedVFX.VFXScaleX, activatable.destroyedVFX.VFXScaleY, activatable.destroyedVFX.VFXScaleZ), true, false);
                }
                else
                {
                    destroyedObject = null;
                }
            }
        }
예제 #26
0
    public static int OverrideLocation(this MechComponent component)
    {
        if (component.componentDef.IsIgnoreDamage())
        {
            return(0);
        }

        return(component.Location);
    }
 private static void SetDamageLevel(MechComponent mechComponent, WeaponHitInfo hitInfo, ComponentDamageLevel damageLevel)
 {
     mechComponent.StatCollection.ModifyStat(
         hitInfo.attackerId,
         hitInfo.stackItemUID,
         "DamageLevel",
         StatCollection.StatOperation.Set,
         damageLevel);
 }
예제 #28
0
        internal static bool ProcessWeaponHit(MechComponent mechComponent, WeaponHitInfo hitInfo, ComponentDamageLevel damageLevel, bool applyEffects)
        {
            if (mechComponent.componentDef.IsStructure())
            {
                return(false);
            }

            return(true);
        }
예제 #29
0
        public static void PublishComponentState(MechComponent mechComponent)
        {
            if (mechComponent.DamageLevel == ComponentDamageLevel.Penalized)
            {
                var critMessage = new Text("{0} CRIT", mechComponent.UIName);

                var ce = mechComponent.GetCriticalEffects();
                if (ce?.CritFloatieMessage != null)
                {
                    if (ce.CritFloatieMessage == "")
                    {
                        return;
                    }
                    critMessage = new Text(ce.CritFloatieMessage);
                }
                mechComponent.PublishMessage(
                    critMessage,
                    FloatieMessage.MessageNature.CriticalHit
                    );
            }
            else if (mechComponent.DamageLevel == ComponentDamageLevel.Destroyed)
            {
                // dont show destroyed if a mech is known to be incapacitated
                var actor = mechComponent.parent;
                if (actor.IsDead || actor.IsFlaggedForDeath)
                {
                    return;
                }

                // dont show destroyed if a whole section was destroyed, counters spam
                //if (actor is Mech mech)
                //{
                //    var location = mechComponent.mechComponentRef.MountedLocation;
                //    var mechLocationDestroyed = mech.IsLocationDestroyed(location);
                //    if (mechLocationDestroyed)
                //    {
                //        return;
                //    }
                //}

                var destroyedMessage = new Text("{0} DESTROYED", mechComponent.UIName);
                var ce = mechComponent.GetCriticalEffects();
                if (ce?.DestroyedFloatieMessage != null)
                {
                    if (ce.DestroyedFloatieMessage == "")
                    {
                        return;
                    }
                    destroyedMessage = new Text(ce.DestroyedFloatieMessage);
                }
                mechComponent.PublishMessage(
                    destroyedMessage,
                    FloatieMessage.MessageNature.ComponentDestroyed
                    );
            }
        }
예제 #30
0
        public static bool CheckForCrit(AIMCritInfo info, int hitLocation, bool logCrit)
        {
            try {
                if (info?.weapon == null)
                {
                    return(true);
                }
                info.SetHitLocation(hitLocation);
                AbstractActor target = info.target;
                if (SkipCritingDeadMech && IsBeatingDeadMech(target))
                {
                    return(false);
                }
                float chance = info.GetCritChance();
                for (int i = 1; chance > 0; i++)
                {
                    float critRoll = Combat.NetworkRandom.Float(); // If use original code AttackDirector.GetRandomFromCache( info.hitInfo, 2 ), may run out of rolls
                    if (DebugLog)
                    {
                        Verbo("Crit {3} roll {0} <= chance {1}? {2}", critRoll, chance, critRoll <= chance, i);
                    }
                    if (i == 1)
                    {
                        AttackLog.LogAIMCritRoll(critRoll);
                    }
                    if (critRoll > chance)
                    {
                        break;
                    }
                    float slotRoll = Combat.NetworkRandom.Float();
                    if (AttackLog.thisCritComp == null)
                    {
                        AttackLog.LogAIMSlotRoll(slotRoll);
                    }
                    MechComponent component = FindAndCritComponent(info, slotRoll);
                    if (i > 1)
                    {
                        Verbo("Crit x{0} on location {1} of {2} by {3}. Roll {4} <= Chance {5}. Crit'ed {6}",
                              i, component?.Location ?? hitLocation, info.target, info.weapon, critRoll, chance, component?.UIName.ToString() ?? "(None)");
                    }
                    if (logCrit)
                    {
                        AttackLog.LogCritResult(target, info.weapon);
                        logCrit = false;
                    }
                    if (!Settings.MultipleCrits)
                    {
                        break;
                    }
                    chance -= critRoll;
                }
                PostCheckForCrit(info, logCrit);
            }                 catch (Exception ex) { Error(ex); }

            return(false);
        }