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); }
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); }
public static void Postfix(PilotableActorRepresentation __instance, VisibilityLevel newLevel) { try { Log.LogWrite("PilotableActorRepresentation.OnPlayerVisibilityChanged " + __instance.parentCombatant.DisplayName + " " + newLevel + "\n"); if (__instance.parentActor == null) { Log.LogWrite(" are you f*****g seriously?? parentActor is null\n", true); return; } foreach (MechComponent component in __instance.parentActor.allComponents) { try { ActivatableComponent activatable = component.componentDef.GetComponent <ActivatableComponent>(); if (activatable == null) { continue; } ; if ((activatable.activateVFXOutOfLOSHide == false) && (activatable.presistantVFXOutOfLOSHide == false)) { continue; } if (activatable.activateVFXOutOfLOSHide == true) { ObjectSpawnDataSelf activeVFX = component.ActivateVFX(); if (activeVFX != null) { if (newLevel != VisibilityLevel.LOSFull) { activeVFX.Hide(); } else { activeVFX.Show(); } } } if (activatable.presistantVFXOutOfLOSHide == true) { ObjectSpawnDataSelf presistantVFX = component.PresitantVFX(); if (presistantVFX != null) { if (newLevel != VisibilityLevel.LOSFull) { presistantVFX.Hide(); } else { presistantVFX.Show(); } } } } catch (Exception e) { Log.LogWrite(e.ToString() + "\n", true); } } }catch (Exception e) { Log.LogWrite(e.ToString() + "\n", true); } }
public static bool Prefix(CombatGameState __instance) { RepairHelper.Clear(); HashSet <string> clearComponents = new HashSet <string>(); foreach (var avfx in ComponentVFXHelper.componentsVFXObjects) { clearComponents.Add(avfx.Key); } foreach (var compGUID in clearComponents) { if (ComponentVFXHelper.componentsVFXObjects.ContainsKey(compGUID)) { ComponentVFXHelper.componentsVFXObjects[compGUID].Clean(); } } ComponentVFXHelper.componentsVFXObjects.Clear(); CAEAuraHelper.ClearBubbles(); CombatHUDWeaponPanelExHelper.Clear(); CombatHUDEquipmentPanel.Clear(); ActivatableComponent.Clear(); CombatHUDEquipmentSlotEx.Clear(); CombatHUDEquipmentPanel.Clear(); //DamageHelpers.DamageHelper.Clear(); return(true); }
public static void playDestroySound(this MechComponent component) { ActivatableComponent activatable = component.componentDef.GetComponent <ActivatableComponent>(); if (activatable != null) { activatable.playDestroySound(component.parent.GameRep.audioObject); } }
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; } } }
public static void Postfix(MechComponent __instance, WeaponHitInfo hitInfo, ComponentDamageLevel damageLevel, bool applyEffects) { try { Log.Debug?.TWL(0, "MechComponent.DamageComponent Postfix " + __instance.defId + " DamageLevel:" + __instance.DamageLevel + "/" + damageLevel); if ((__instance.DamageLevel >= ComponentDamageLevel.Destroyed) || (damageLevel >= ComponentDamageLevel.Destroyed)) { Statistic isCAEDestroyed = __instance.StatCollection.GetStatistic("CAEDestroyed"); if (isCAEDestroyed == null) { isCAEDestroyed = __instance.StatCollection.AddStatistic("CAEDestroyed", false); } if (isCAEDestroyed.Value <bool>() == false) { isCAEDestroyed.SetValue(true); Log.Debug?.WL(1, "really destroyed at first time"); ActivatableComponent activatable = __instance.componentDef.GetComponent <ActivatableComponent>(); if (activatable == null) { Log.Debug?.WL(1, "not activatable"); return; } ObjectSpawnDataSelf VFX = __instance.PresitantVFX(); if (VFX != null) { VFX.CleanupSelf(); } ; VFX = __instance.ActivateVFX(); if (VFX != null) { VFX.CleanupSelf(); } ; VFX = __instance.DestroyedVFX(); if (VFX != null) { VFX.SpawnSelf(__instance.parent.Combat); } ; if (activatable.ExplodeOnDamage) { __instance.AoEExplodeComponent(); } ; __instance.playDestroySound(); } else { Log.Debug?.WL(1, "not a really destroyed"); } __instance.UpdateAuras(); } } catch (Exception e) { Log.Debug?.TWL(0, e.ToString(), true); } }
public static void LinkageActivate(this MechComponent component, bool isInital) { ActivatableComponent activatable = component.componentDef.GetComponent <ActivatableComponent>(); if (activatable == null) { return; } Log.Debug?.TWL(0, "LinkageActivate " + component.defId); foreach (string toActivateBtn in activatable.Linkage.OnActivate.Activate) { Log.Debug?.WL(1, "searching " + toActivateBtn); foreach (MechComponent CompToActivate in component.parent.allComponents) { ActivatableComponent tactivatable = CompToActivate.componentDef.GetComponent <ActivatableComponent>(); if (tactivatable == null) { continue; } //if (tactivatable.CanBeactivatedManualy == false) { continue; }; if (tactivatable.ButtonName != toActivateBtn) { continue; } if (ActivatableComponent.isComponentActivated(CompToActivate) == true) { continue; } ; ActivatableComponent.activateComponent(CompToActivate, true, isInital); } } foreach (string toActivateBtn in activatable.Linkage.OnActivate.Deactivate) { foreach (MechComponent CompToDeactivate in component.parent.allComponents) { ActivatableComponent tactivatable = CompToDeactivate.componentDef.GetComponent <ActivatableComponent>(); if (tactivatable == null) { continue; } //if (tactivatable.CanBeactivatedManualy == false) { continue; }; if (tactivatable.ButtonName != toActivateBtn) { continue; } if (ActivatableComponent.isComponentActivated(CompToDeactivate) == false) { continue; } ; ActivatableComponent.deactivateComponent(CompToDeactivate); } } }
public static void CommitCAEDamageData(this AbstractActor unit) { Log.Debug?.Write("CommitDamageData " + unit.DisplayName + ":" + unit.GUID + "\n"); if (DamagedStructureLocationsThisTurn.ContainsKey(unit) == false) { DamagedStructureLocationsThisTurn.Add(unit, new HashSet <int>()); } HashSet <int> dmsLocations = DamagedStructureLocationsThisTurn[unit]; Log.Debug?.Write(" DamagedLocations:"); foreach (int Location in dmsLocations) { Log.Debug?.Write(" " + Location); } ; Log.Debug?.Write("\n"); foreach (MechComponent component in unit.allComponents) { if (component.IsFunctional == false) { continue; } ActivatableComponent activatable = component.componentDef.GetComponent <ActivatableComponent>(); if (activatable == null) { continue; } ; Log.Debug?.Write(" " + component.defId + ":" + activatable.Repair.repairTrigger + ":" + component.Location + "\n"); if (activatable.Repair.repairTrigger.AtEndOfTurn == true) { if (activatable.Repair.repairTrigger.OnDamage == RepairDamageTrigger.None) { activatable.Repair.Repair(component, true); } else if (activatable.Repair.repairTrigger.OnDamage == RepairDamageTrigger.AllUnit) { if (dmsLocations.Count > 0) { activatable.Repair.Repair(component, true); } } else if (activatable.Repair.repairTrigger.OnDamage == RepairDamageTrigger.InstalledLocation) { if (dmsLocations.Contains(component.Location)) { activatable.Repair.Repair(component, true); } } } } unit.ClearDamageData(); }
public ComponentsMenu(AbstractActor unit) { SelectedComponent = 0; components = new List <MechComponent>(); componentsStates = new Dictionary <MechComponent, string>(); popup = null; foreach (MechComponent component in unit.allComponents) { ActivatableComponent activatable = component.componentDef.GetComponent <ActivatableComponent>(); if (activatable != null) { components.Add(component); } ; } }
public static float FailChance(this MechComponent component) { ActivatableComponent activatable = component.componentDef.GetComponent <ActivatableComponent>(); if (activatable == null) { return(0f); } ; if (activatable.AlwaysFail) { return(1f); } ; return(ActivatableComponent.getEffectiveComponentFailChance(component)); }
/*static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { * Log.LogWrite("AuraCache.UpdateAura transpliter\n"); * List<CodeInstruction> result = instructions.ToList(); * MethodInfo get_statusEffects = AccessTools.Property(typeof(MechComponentDef), "statusEffects").GetGetMethod(false); * if (get_statusEffects != null) { * Log.LogWrite(" source method found\n"); * } else { * return result; * } * MethodInfo replacementMethod = AccessTools.Method(typeof(AuraCache_UpdateAura), nameof(get_statusEffects)); * if (replacementMethod != null) { * Log.LogWrite("target method found\n"); * } else { * return result; * } * do { * int methodCallIndex = result.FindIndex(instruction => instruction.opcode == OpCodes.Callvirt && instruction.operand == get_statusEffects); * if (methodCallIndex >= 0) { * Log.LogWrite("methodCallIndex found " + methodCallIndex + "\n"); * } else { * break; * } * result[methodCallIndex].operand = replacementMethod; * for (int thisIndex = methodCallIndex - 1; thisIndex > 0; --thisIndex) { * Log.LogWrite(" result[" + thisIndex + "].opcode = " + result[thisIndex].opcode + "\n"); * if (result[thisIndex].opcode == OpCodes.Callvirt) { * result[thisIndex].opcode = OpCodes.Nop; * result[thisIndex].operand = null; * Log.LogWrite(" def opcode changed to component\n"); * break; * } * } * } while (true); * Log.LogWrite("result:\n"); * for(int t = 0; t < result.Count; ++t) { * Log.LogWrite(" "+t + "\t" + result[t].opcode + "\t" + (result[t].operand == null ? "null" : result[t].operand) + "\n"); * } * return result; * }*/ public static EffectData[] get_statusEffects(this MechComponent component) { //if (component == null) { return new EffectData[0] { }; }; //Log.LogWrite("AuraCache_UpdateAura.get_statusEffects(" + component.defId + ")\n"); ActivatableComponent activatable = component.componentDef.GetComponent <ActivatableComponent>(); if (activatable == null) { //Log.LogWrite(" not activatable:" + component.componentDef.statusEffects.Length + "\n"); return(component.componentDef.statusEffects); } else { //Log.LogWrite(" activatable:"+activatable.allEffects.Length+"\n"); return(activatable.allEffects); } }
public static void Postfix(MechComponent __instance, WeaponHitInfo hitInfo, ComponentDamageLevel damageLevel, bool applyEffects, ref bool __state) { if (__state) { ActivatableComponent activatable = __instance.componentDef.GetComponent <ActivatableComponent>(); if (activatable == null) { Log.LogWrite(" not activatable\n"); return; } ObjectSpawnDataSelf VFX = __instance.PresitantVFX(); if (VFX != null) { VFX.CleanupSelf(); } ; VFX = __instance.ActivateVFX(); if (VFX != null) { VFX.CleanupSelf(); } ; VFX = __instance.DestroyedVFX(); if (VFX != null) { VFX.SpawnSelf(__instance.parent.Combat); } ; if (activatable.ExplodeOnDamage) { __instance.AoEExplodeComponent(); } ; __instance.playDestroySound(); } else { Log.LogWrite(" no additional processing\n"); } __instance.UpdateAuras(); }
public override void OnPointerClick(PointerEventData data) { Log.Debug?.Write("OnPointerClick called." + data.position + "\n"); if (dataline.error) { return; } if (dataline.manual == false) { return; } if (dataline.component != null) { Log.Debug?.Write("Toggle activatable " + dataline.component.defId + "\n"); ActivatableComponent.toggleComponentActivation(dataline.component); } if (ActivatebleDialogHelper.popup != null) { Log.Debug?.Write("Aborting popup\n"); ActivatebleDialogHelper.popup.Pool(false); } //line.SetText(dataline.ToString(false)); }
public static void AIActivatableProc(AbstractActor unit) { try { if (unit.IsDead) { return; } if (unit.TeamId == unit.Combat.LocalPlayerTeamGuid) { Log.Debug?.Write(" not AI\n"); return; } HashSet <MechComponent> extreamlyUsefull = new HashSet <MechComponent>(); HashSet <MechComponent> Usefull = new HashSet <MechComponent>(); var AITime = System.Diagnostics.Stopwatch.StartNew(); // the code that you want to measure comes here var elapsedMs = AITime.ElapsedMilliseconds; int isVisibleTargets = 0; float offenceCoeff = 0f; float deffenceCoeff = 0f; unit.TargetsCalc(ref isVisibleTargets, ref offenceCoeff, ref deffenceCoeff); Mech mech = unit as Mech; float heatCoeff = 0f; float overheatCoeff = 0f; if (mech != null) { heatCoeff = mech.CurrentHeat / mech.OverheatLevel; overheatCoeff = mech.CurrentHeatAsRatio; } Log.Debug?.Write("AI activatable coeffs:" + unit.DisplayName + ":" + unit.GUID + "\n"); Log.Debug?.Write(" visible targets:" + isVisibleTargets + "\n"); Log.Debug?.Write(" offenceCoeff:" + offenceCoeff + "\n"); Log.Debug?.Write(" deffenceCoeff:" + deffenceCoeff + "\n"); Log.Debug?.Write(" heatCoeff:" + heatCoeff + "\n"); Log.Debug?.Write(" overheatCoeff:" + overheatCoeff + "\n"); bool isAnyLocationExposed = unit.IsAnyStructureExposed; Log.Debug?.Write(" isAnyLocationExposed:" + isAnyLocationExposed + "\n"); Log.Debug?.Write("Components:\n"); foreach (MechComponent component in unit.allComponents) { Log.Debug?.Write(" " + component.defId + "\n"); if (component.CanBeActivated() == false) { Log.Debug?.Write(" can't be activated\n"); continue; } ; if (component.isSensors()) { Log.Debug?.Write(" sensors\n"); if (isVisibleTargets == 0) { if (isAnyLocationExposed == false) { Log.Debug?.Write(" no visible targets. Sensors are extreamly usefull to detect them\n"); extreamlyUsefull.Add(component); } } else if (isVisibleTargets < 2) { if (isAnyLocationExposed == false) { Log.Debug?.Write(" low visible visible targets count. Sensors are usefull to detect additional targets\n"); Usefull.Add(component); } } } if (component.isCool()) { if (heatCoeff > Core.Settings.AIHeatCoeffCoeff) { Log.Debug?.Write(" cooling component and i'm heated. Usefull\n"); Usefull.Add(component); } if (overheatCoeff > Core.Settings.AIOverheatCoeffCoeff) { Log.Debug?.Write(" cooling component and i'm close to overheat. Very usefull\n"); extreamlyUsefull.Add(component); } } if (component.isSpeed()) { if (isAnyLocationExposed) { Log.Debug?.Write(" speed and i'm damaged. Need to flee. Very usefull\n"); extreamlyUsefull.Add(component); } else if (isVisibleTargets == 0) { Log.Debug?.Write(" speed and no visible targets. Need to find usefull\n"); Usefull.Add(component); } } if (component.isOffence()) { if ((isVisibleTargets > 1) && (isAnyLocationExposed)) { Log.Debug?.Write(" offence and i see target and damaged. Very usefull\n"); extreamlyUsefull.Add(component); } else if (offenceCoeff > Core.Settings.AIOffenceUsefullCoeff) { Log.Debug?.Write(" offence and i can make much damage. Very usefull\n"); extreamlyUsefull.Add(component); } else if (offenceCoeff > Core.Epsilon) { Log.Debug?.Write(" offence and i can make some damage. Usefull\n"); Usefull.Add(component); } } if (component.isDefence()) { if ((isVisibleTargets > 1) && (isAnyLocationExposed)) { Log.Debug?.Write(" defence and i see target and damaged. Very usefull\n"); extreamlyUsefull.Add(component); } else if (deffenceCoeff > Core.Settings.AIDefenceUsefullCoeff) { Log.Debug?.Write(" defence and i can suffer much damage. Very usefull\n"); extreamlyUsefull.Add(component); } else if (deffenceCoeff > Core.Epsilon) { Log.Debug?.Write(" defence and i suffer make some damage. Usefull\n"); Usefull.Add(component); } } } HashSet <MechComponent> stepDownComponents = new HashSet <MechComponent>(); foreach (MechComponent component in extreamlyUsefull) { if (component.isHeat()) { if (heatCoeff > Core.Settings.AIHeatCoeffCoeff) { Log.Debug?.Write(component.defId + " very usefull. But i'm heated\n"); stepDownComponents.Add(component); } else if (overheatCoeff > Core.Settings.AIOverheatCoeffCoeff) { Log.Debug?.Write(component.defId + " very usefull. But i'm overheated\n"); stepDownComponents.Add(component); } } } foreach (MechComponent component in stepDownComponents) { extreamlyUsefull.Remove(component); Usefull.Add(component); } Log.Debug?.Write("Activation:\n"); foreach (MechComponent component in unit.allComponents) { Log.Debug?.Write(" " + component.defId + "\n"); bool needToBeActivated = false; if (extreamlyUsefull.Contains(component)) { Log.Debug?.Write(" very usefull\n"); if (component.isFailDanger() == false) { Log.Debug?.Write(" not danger\n"); needToBeActivated = true; } else { Log.Debug?.Write(" FailChance:" + component.FailChance() + "\n"); if ((component.isDamaged() == false) || (isAnyLocationExposed == true)) { if (component.FailChance() < Core.Settings.AIComponentExtreamlyUsefulModifyer) { needToBeActivated = true; Log.Debug?.Write(" not big danger. Can be activated\n"); } } else { Log.Debug?.Write(" component is damaged and have no exposed locations. Danger level increase\n"); if (component.FailChance() < Core.Settings.AIComponentUsefullModifyer) { needToBeActivated = true; Log.Debug?.Write(" not big danger. Can be activated\n"); } } } } if (Usefull.Contains(component)) { Log.Debug?.Write(" usefull\n"); if (component.isFailDanger() == false) { Log.Debug?.Write(" not danger\n"); needToBeActivated = true; } else { Log.Debug?.Write(" FailChance:" + component.FailChance() + "\n"); if ((component.isDamaged() == false) || (isAnyLocationExposed == true)) { if (component.FailChance() < Core.Settings.AIComponentUsefullModifyer) { needToBeActivated = true; Log.Debug?.Write(" not big danger. Can be activated\n"); } } else { Log.Debug?.Write(" component is damaged and have no exposed locations. Danger level increase will not activate.\n"); } } } if (needToBeActivated) { if (ActivatableComponent.isComponentActivated(component)) { Log.Debug?.Write(" already active\n"); if (unit.AICheatRoll()) { bool isSuccess = ActivatableComponent.rollFail(component, false, true); if (isSuccess == false) { Log.Debug?.Write(" deactivating due to high possible fail\n"); ActivatableComponent.deactivateComponent(component); } else { component.setAIRollPassed(true); } } } else { Log.Debug?.Write(" activating\n"); if (unit.AICheatRoll()) { bool isSuccess = ActivatableComponent.rollFail(component, false, true); if (isSuccess == false) { Log.Debug?.Write(" not activate due to high possible fail\n"); } else { component.setAIRollPassed(true); ActivatableComponent.activateComponent(component, false, false); } } else { ActivatableComponent.activateComponent(component, false, false); } } } else { if (ActivatableComponent.isComponentActivated(component)) { Log.Debug?.Write(" not active\n"); } else { Log.Debug?.Write(" deactivating\n"); ActivatableComponent.deactivateComponent(component); } } } AITime.Stop(); Log.Debug?.Write("AI activatable time:" + AITime.ElapsedMilliseconds + " msec\n"); } catch (Exception e) { Log.WriteCritical("AI activatable exception:" + e.ToString() + "\n"); } }
public static void CritComponentInLocations(this AbstractActor target, ActivatableComponent activatable, MechComponent component) { List <MechComponent> components = new List <MechComponent>(); Mech mech = target as Mech; Vehicle vehicle = target as Vehicle; Turret turret = target as Turret; HashSet <int> affectedLocation = new HashSet <int>(); if (mech != null) { if (mech.FakeVehicle() == false) { foreach (ChassisLocations loc in activatable.FailCritLocations) { LocationDef locDef = mech.MechDef.Chassis.GetLocationDef(loc); if ((locDef.InternalStructure <= 1.0f) && (locDef.MaxArmor == 0f)) { continue; } affectedLocation.Add((int)loc); } } else { foreach (VehicleChassisLocations vloc in activatable.FailCritVehicleLocations) { ChassisLocations loc = vloc.FakeVehicleLocation(); LocationDef locDef = mech.MechDef.Chassis.GetLocationDef(loc); if ((locDef.InternalStructure <= 1.0f) && (locDef.MaxArmor <= 0f)) { continue; } affectedLocation.Add((int)loc); } } } else if (vehicle != null) { foreach (VehicleChassisLocations vloc in activatable.FailCritVehicleLocations) { VehicleLocationDef locDef = vehicle.VehicleDef.Chassis.GetLocationDef(vloc); if ((locDef.InternalStructure <= 1.0f) && (locDef.MaxArmor <= 0f)) { continue; } affectedLocation.Add((int)vloc); } } else if (turret != null) { affectedLocation.Add((int)BuildingLocation.Structure); } if (activatable.FailDamageToInstalledLocation) { affectedLocation.Add(component.Location); } HashSet <string> excludeTags = new HashSet <string>(); HashSet <string> onlyTags = new HashSet <string>(); foreach (string tag in activatable.FailCritExcludeComponentsTags) { excludeTags.Add(tag); } foreach (string tag in activatable.FailCritOnlyComponentsTags) { onlyTags.Add(tag); } Log.Debug?.TWL(0, "CritComponentsInLocations:" + target.DisplayName); foreach (int loc in affectedLocation) { List <MechComponent> locComps = target.GetComponentsInLocation(loc, excludeTags, onlyTags); components.AddRange(locComps); } for (int t = 0; t < components.Count; ++t) { Log.Debug?.WL(1, "[" + t + "]" + components[t].defId + " location:" + components[t].Location); } int slotRoll = Random.Range(0, components.Count); MechComponent critComp = components[slotRoll]; WeaponHitInfo fakeHit = new WeaponHitInfo(-1, -1, -1, -1, target.GUID, target.GUID, 1, null, null, null, null, null, null, null, null, null, null, null); fakeHit.toHitRolls = new float[1] { 1.0f }; fakeHit.locationRolls = new float[1] { 1.0f }; fakeHit.dodgeRolls = new float[1] { 0.0f }; fakeHit.dodgeSuccesses = new bool[1] { false }; fakeHit.hitLocations = new int[1] { critComp.Location }; fakeHit.hitVariance = new int[1] { 0 }; fakeHit.hitQualities = new AttackImpactQuality[1] { AttackImpactQuality.Solid }; fakeHit.attackDirections = new AttackDirection[1] { AttackDirection.FromArtillery }; fakeHit.hitPositions = new Vector3[1] { target.GameRep.GetHitPosition(critComp.Location) }; fakeHit.secondaryTargetIds = new string[1] { null }; fakeHit.secondaryHitLocations = new int[1] { 0 }; critComp.CritComponent(ref fakeHit); }
public static float FailChance(this MechComponent component) { return(ActivatableComponent.getEffectiveComponentFailChance(component)); }
public static void ArmorDamage(this AbstractActor target, ActivatableComponent activatable, MechComponent component) { Mech mech = target as Mech; Vehicle vehicle = target as Vehicle; Turret turret = target as Turret; HashSet <int> affectedLocation = new HashSet <int>(); if (mech != null) { if (mech.FakeVehicle() == false) { foreach (ChassisLocations loc in activatable.FailCritLocations) { LocationDef locDef = mech.MechDef.Chassis.GetLocationDef(loc); if ((locDef.InternalStructure <= 1.0f) && (locDef.MaxArmor == 0f)) { continue; } affectedLocation.Add((int)loc); } } else { foreach (VehicleChassisLocations vloc in activatable.FailCritVehicleLocations) { ChassisLocations loc = vloc.FakeVehicleLocation(); LocationDef locDef = mech.MechDef.Chassis.GetLocationDef(loc); if ((locDef.InternalStructure <= 1.0f) && (locDef.MaxArmor <= 0f)) { continue; } affectedLocation.Add((int)loc); } } } else if (vehicle != null) { foreach (VehicleChassisLocations vloc in activatable.FailCritVehicleLocations) { VehicleLocationDef locDef = vehicle.VehicleDef.Chassis.GetLocationDef(vloc); if ((locDef.InternalStructure <= 1.0f) && (locDef.MaxArmor <= 0f)) { continue; } affectedLocation.Add((int)vloc); } } else if (turret != null) { affectedLocation.Add((int)BuildingLocation.Structure); } if (activatable.FailDamageToInstalledLocation) { affectedLocation.Add(component.Location); } HashSet <string> excludeTags = new HashSet <string>(); HashSet <string> onlyTags = new HashSet <string>(); foreach (string tag in activatable.FailCritExcludeComponentsTags) { excludeTags.Add(tag); } foreach (string tag in activatable.FailCritOnlyComponentsTags) { onlyTags.Add(tag); } target.ArmorDamage(affectedLocation.ToList(), activatable.FailArmorDamage, activatable.FailCrit, excludeTags, onlyTags); }
public static int ChargesCount(this MechComponent component) { return(ActivatableComponent.getChargesCount(component)); }
public VFXObjects(MechComponent p) { this.parent = p; this.explodeObject = null; 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.Debug?.Write(p.defId + " is activatable \n"); //PilotableActorRepresentation rep = parent.parent.GameRep as PilotableActorRepresentation; if (activatable.presistantVFX.isInited) { try { Log.Debug?.Write(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); //if(rep != null) { // if (activatable.presistantVFXOutOfLOSHide == true) { // if (rep.VisibleToPlayer == false) { presitantObject.Hide(); } // } //} } catch (Exception e) { Log.Debug?.Write(" Fail to spawn vfx " + e.ToString() + "\n"); } } else { presitantObject = null; } if (activatable.activateVFX.isInited) { Log.Debug?.Write(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.Debug?.Write(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; } } }
public static void AoEExplodeComponent(this MechComponent component) { ActivatableComponent activatable = component.componentDef.GetComponent <ActivatableComponent>(); if (activatable == null) { return; } if (component.parent == null) { return; } if (activatable.Explosion.Damage <= Core.Epsilon) { return; } if (activatable.Explosion.Range <= Core.Epsilon) { return; } List <AoEComponentExplosionRecord> AoEDamage = new List <AoEComponentExplosionRecord>(); foreach (ICombatant target in component.parent.Combat.GetAllLivingCombatants()) { if (target.GUID == component.parent.GUID) { continue; } ; float distance = Vector3.Distance(target.CurrentPosition, component.parent.CurrentPosition); if (distance > activatable.Explosion.Range) { continue; } ; float HeatDamage = activatable.Explosion.Heat * (activatable.Explosion.Range - distance) / activatable.Explosion.Range; float Damage = activatable.Explosion.Damage * (activatable.Explosion.Range - distance) / activatable.Explosion.Range; float StabDamage = activatable.Explosion.Stability * (activatable.Explosion.Range - distance) / activatable.Explosion.Range; Mech mech = target as Mech; Vehicle vehicle = target as Vehicle; if (mech == null) { Damage += HeatDamage; } ; List <int> hitLocations = null; Dictionary <int, float> AOELocationDict = null; if (mech != null) { hitLocations = component.parent.Combat.HitLocation.GetPossibleHitLocations(component.parent.CurrentPosition, mech); if (AoEComponentExplodeHelper.MechHitLocations == null) { AoEComponentExplodeHelper.InitHitLocationsAOE(); } ; AOELocationDict = AoEComponentExplodeHelper.MechHitLocations; int HeadIndex = hitLocations.IndexOf((int)ArmorLocation.Head); if ((HeadIndex >= 0) && (HeadIndex < hitLocations.Count)) { hitLocations.RemoveAt(HeadIndex); } ; } else if (target is Vehicle) { hitLocations = component.parent.Combat.HitLocation.GetPossibleHitLocations(component.parent.CurrentPosition, target as Vehicle); if (AoEComponentExplodeHelper.VehicleLocations == null) { AoEComponentExplodeHelper.InitHitLocationsAOE(); } ; AOELocationDict = AoEComponentExplodeHelper.VehicleLocations; } else { hitLocations = new List <int>() { 1 }; if (AoEComponentExplodeHelper.OtherLocations == null) { AoEComponentExplodeHelper.InitHitLocationsAOE(); } ; AOELocationDict = AoEComponentExplodeHelper.OtherLocations; } float fullLocationDamage = 0.0f; foreach (int hitLocation in hitLocations) { if (AOELocationDict.ContainsKey(hitLocation)) { fullLocationDamage += AOELocationDict[hitLocation]; } else { fullLocationDamage += 100f; } } Log.LogWrite(" hitLocations: "); foreach (int hitLocation in hitLocations) { Log.LogWrite(" " + hitLocation); } Log.LogWrite("\n"); Log.LogWrite(" full location damage coeff " + fullLocationDamage + "\n"); AoEComponentExplosionRecord AoERecord = new AoEComponentExplosionRecord(target); AoERecord.HeatDamage = HeatDamage; AoERecord.StabDamage = StabDamage; foreach (int hitLocation in hitLocations) { float currentDamageCoeff = 100f; if (AOELocationDict.ContainsKey(hitLocation)) { currentDamageCoeff = AOELocationDict[hitLocation]; } currentDamageCoeff /= fullLocationDamage; float CurrentLocationDamage = Damage * currentDamageCoeff; if (AoERecord.hitRecords.ContainsKey(hitLocation)) { AoERecord.hitRecords[hitLocation].Damage += CurrentLocationDamage; } else { Vector3 pos = target.getImpactPositionSimple(component.parent, component.parent.CurrentPosition, hitLocation); AoERecord.hitRecords[hitLocation] = new AoEComponentExplosionHitRecord(pos, CurrentLocationDamage); } Log.LogWrite(" location " + hitLocation + " damage " + AoERecord.hitRecords[hitLocation].Damage + "\n"); } AoEDamage.Add(AoERecord); } Log.LogWrite("AoE Damage result:\n"); Weapon fakeWeapon = new Weapon(); fakeWeapon.parent = component.parent; typeof(MechComponent).GetProperty("componentDef", BindingFlags.Instance | BindingFlags.Public).GetSetMethod(true).Invoke(fakeWeapon, new object[1] { (object)component.componentDef }); var fakeHit = new WeaponHitInfo(-1, -1, -1, -1, component.parent.GUID, component.parent.GUID, -1, null, null, null, null, null, null, new AttackImpactQuality[1] { AttackImpactQuality.Solid }, new AttackDirection[1] { AttackDirection.FromArtillery }, null, null, null); for (int index = 0; index < AoEDamage.Count; ++index) { Log.LogWrite(" " + AoEDamage[index].target.DisplayName + ":" + AoEDamage[index].target.GUID + "\n"); Log.LogWrite(" Heat:" + AoEDamage[index].HeatDamage + "\n"); Log.LogWrite(" Instability:" + AoEDamage[index].StabDamage + "\n"); fakeHit.targetId = AoEDamage[index].target.GUID; foreach (var AOEHitRecord in AoEDamage[index].hitRecords) { Log.LogWrite(" location:" + AOEHitRecord.Key + " pos:" + AOEHitRecord.Value.hitPosition + " dmg:" + AOEHitRecord.Value.Damage + "\n"); float LocArmor = AoEDamage[index].target.ArmorForLocation(AOEHitRecord.Key); if ((double)LocArmor < (double)AOEHitRecord.Value.Damage) { component.parent.Combat.MessageCenter.PublishMessage((MessageCenterMessage) new FloatieMessage(component.parent.GUID, AoEDamage[index].target.GUID, new Text("{0}", new object[1] { (object)(int)Mathf.Max(1f, AOEHitRecord.Value.Damage) }), component.parent.Combat.Constants.CombatUIConstants.floatieSizeMedium, FloatieMessage.MessageNature.StructureDamage, AOEHitRecord.Value.hitPosition.x, AOEHitRecord.Value.hitPosition.y, AOEHitRecord.Value.hitPosition.z)); } else { component.parent.Combat.MessageCenter.PublishMessage((MessageCenterMessage) new FloatieMessage(component.parent.GUID, AoEDamage[index].target.GUID, new Text("{0}", new object[1] { (object)(int)Mathf.Max(1f, AOEHitRecord.Value.Damage) }), component.parent.Combat.Constants.CombatUIConstants.floatieSizeMedium, FloatieMessage.MessageNature.ArmorDamage, AOEHitRecord.Value.hitPosition.x, AOEHitRecord.Value.hitPosition.y, AOEHitRecord.Value.hitPosition.z)); } AoEDamage[index].target.TakeWeaponDamage(fakeHit, AOEHitRecord.Key, fakeWeapon, AOEHitRecord.Value.Damage, 0, DamageType.AmmoExplosion); } AoEDamage[index].target.HandleDeath(component.parent.GUID); Mech mech = AoEDamage[index].target as Mech; if (mech != null) { if (AoEDamage[index].HeatDamage > Core.Epsilon) { mech.AddExternalHeat("AoE Component explosion", Mathf.RoundToInt(AoEDamage[index].HeatDamage)); mech.GenerateAndPublishHeatSequence(-1, true, false, component.parent.GUID); } if (AoEDamage[index].StabDamage > Core.Epsilon) { mech.AddAbsoluteInstability(AoEDamage[index].StabDamage, StabilityChangeSource.Effect, component.parent.GUID); } mech.HandleKnockdown(-1, component.parent.GUID, Vector2.one, (SequenceFinished)null); } } }
public static bool isActive(this MechComponent component) { return(ActivatableComponent.isComponentActivated(component)); }
public static void AurasActivateOnline(this ActivatableComponent activatable, MechComponent component) { }
public string BuildText() { StringBuilder builder = new StringBuilder(); for (int index = 0; index < components.Count; ++index) { if (index != 0) { builder.Append("\n"); } ; if (index == SelectedComponent) { builder.Append("->"); } MechComponent component = components[index]; builder.Append(component.UIName); if (component.IsFunctional == false) { builder.Append(" !__/CAE.NonFunctional/__!"); continue; } if (component.DamageLevel >= ComponentDamageLevel.Penalized) { builder.Append(" !__/CAE.Damaged/__!"); } if (ActivatableComponent.isOutOfCharges(components[index])) { builder.Append(" !__/CAE.OutOfCharges/__!"); continue; } ActivatableComponent activatable = component.componentDef.GetComponent <ActivatableComponent>(); if (activatable.ChargesCount != 0) { if (activatable.ChargesCount > 0) { builder.Append(" __/CAE.CHARGES/__:" + ActivatableComponent.getChargesCount(component)); } } if (ActivatableComponent.isComponentActivated(component)) { builder.Append(" " + activatable.ActivationMessage + " "); if (activatable.CanBeactivatedManualy == false) { if (component.parent is Mech) { float neededHeat = (activatable.AutoDeactivateOverheatLevel > CustomActivatableEquipment.Core.Epsilon) ? activatable.AutoDeactivateOverheatLevel * (float)(component.parent as Mech).OverheatLevel : activatable.AutoDeactivateOnHeat; builder.Append("__/CAE.HEAT/__:" + (component.parent as Mech).CurrentHeat + "/" + neededHeat); } } } else { builder.Append(" " + activatable.DeactivationMessage + " "); if (activatable.AutoActivateOnHeat > CustomActivatableEquipment.Core.Epsilon) { if (component.parent is Mech) { float neededHeat = (activatable.AutoActivateOnOverheatLevel > CustomActivatableEquipment.Core.Epsilon) ? activatable.AutoActivateOnOverheatLevel * (float)(component.parent as Mech).OverheatLevel : activatable.AutoActivateOnHeat; builder.Append("__/CAE.HEAT/__:" + (component.parent as Mech).CurrentHeat + "/" + neededHeat); } } } float failChance = ActivatableComponent.getEffectiveComponentFailChance(component); if (failChance > Core.Epsilon) { builder.Append(" __/CAE.FAIL/__:" + Math.Round(failChance * 100f) + "%"); } } return(builder.ToString()); }