public void Kill(ICombatant attacker) { RemoveEdges(); this.transform.parent.GetComponent<MeshMalware>().RemoveNode(this); ActiveSubroutines.RemoveVirus(this); SelfDestruct(); }
// Use this for initialization public void FireTorpedo(ICombatant target) { StartCoroutine(SelfDestruct()); this.liveFire = true; this.target = target; this.targetObj = target.gameObject; }
public void Fire(ICombatant attacker, Vector3 target, float duration, float lagPenalty, float radius = 60f) { this.firing = true; this.radius = radius; this.sender = attacker; BombLerp = new HarmonicUtils.LerpContext(duration) { From = this.transform.position, To = target }; ExplosionRoot.SetActive(false); ShellRoot.SetActive(true); }
public virtual bool DoAttack(ICombatant target, AttackType type = AttackType.Kill) { if (target.Defenseless || RollDice(this.KillChance)) { if (target.TrySave(this)) { target.DoOnBlock(this); } else { switch (type) { case AttackType.Freeze: target.Freeze(this); if (target is Combatant) (target as Combatant).AddEffect(this.FreezeEffect.Clone()); break; case AttackType.Lag: target.Lag(this); if (target is Combatant) (target as Combatant).AddEffect(this.LagEffect.Clone()); break; default: //this reads backwards //it's actually "kill the target, this is who killed the target" target.Kill(this); break; } } return true; } return false; }
//[HarmonyBefore(new string[] { "Sheepy.BattleTechMod.AttackImprovementMod" })] private static void Postfix(ToHit __instance, ref string __result, AbstractActor attacker, Weapon weapon, ICombatant target, Vector3 attackPosition, Vector3 targetPosition, LineOfFireLevel lofLevel, bool isCalledShot) { //Mod.Log.Debug?.Write($"Getting modifier descriptions for attacker:{CombatantUtils.Label(attacker)} " + // $"using weapon:{weapon.Name} vs target:{CombatantUtils.Label(target)}"); //AbstractActor targetActor = target as AbstractActor; //if (__instance != null && attacker != null && weapon != null && target != null && targetActor != null) { // float distance = Vector3.Distance(attackPosition, targetPosition); // EWState attackerState = new EWState(attacker); // EWState targetState = new EWState(targetActor); // // Vision modifiers // int zoomVisionMod = attackerState.GetZoomVisionAttackMod(weapon, distance); // int heatVisionMod = attackerState.GetHeatVisionAttackMod(targetActor, distance, weapon); // int mimeticMod = targetState.MimeticAttackMod(attackerState); // bool canSpotTarget = VisualLockHelper.CanSpotTarget(attacker, attacker.CurrentPosition, target, target.CurrentPosition, target.CurrentRotation, attacker.Combat.LOS); // // Sensor modifiers // SensorScanType sensorScan = SensorLockHelper.CalculateSharedLock(targetActor, attacker); // int ecmShieldMod = targetState.ECMAttackMod(attackerState); // int stealthMod = targetState.StealthAttackMod(attackerState, weapon, distance); // int narcMod = targetState.NarcAttackMod(attackerState); // int tagMod = targetState.TagAttackMod(attackerState); // if (Mod.Config.Attack.NoSensorInfoPenalty > (ecmShieldMod + stealthMod + narcMod + tagMod)) { sensorScan = SensorScanType.NoInfo; } // if (sensorScan == SensorScanType.NoInfo && !canSpotTarget) { // string localText = new Localize.Text(Mod.Config.LocalizedText[ModConfig.LT_ATTACK_FIRING_BLIND]).ToString(); // __result = string.Format("{0}{1} {2:+#;-#}; ", __result, localText, Mod.Config.Attack.BlindFirePenalty); // } else { // if (!canSpotTarget) { // string localText = new Localize.Text(Mod.Config.LocalizedText[ModConfig.LT_ATTACK_NO_VISUALS]).ToString(); // __result = string.Format("{0}{1} {2:+#;-#}; ", __result, localText, Mod.Config.Attack.NoVisualsPenalty); // } else { // if (zoomVisionMod != 0) { // string localText = new Localize.Text(Mod.Config.LocalizedText[ModConfig.LT_ATTACK_ZOOM_VISION]).ToString(); // __result = string.Format("{0}{1} {2:+#;-#}; ", __result, localText, zoomVisionMod); // } // if (heatVisionMod != 0) { // string localText = new Localize.Text(Mod.Config.LocalizedText[ModConfig.LT_ATTACK_HEAT_VISION]).ToString(); // __result = string.Format("{0}{1} {2:+#;-#}; ", __result, localText, heatVisionMod); // } // if (mimeticMod != 0) { // string localText = new Localize.Text(Mod.Config.LocalizedText[ModConfig.LT_ATTACK_MIMETIC]).ToString(); // __result = string.Format("{0}{1} {2:+#;-#}; ", __result, localText, mimeticMod); // } // } // if (sensorScan == SensorScanType.NoInfo) { // string localText = new Localize.Text(Mod.Config.LocalizedText[ModConfig.LT_ATTACK_NO_SENSORS]).ToString(); // __result = string.Format("{0}{1} {2:+#;-#}; ", __result, localText, Mod.Config.Attack.NoSensorInfoPenalty); // } else { // if (ecmShieldMod != 0) { // string localText = new Localize.Text(Mod.Config.LocalizedText[ModConfig.LT_ATTACK_ECM_SHEILD]).ToString(); // __result = string.Format("{0}{1} {2:+#;-#}; ", __result, localText, ecmShieldMod); // } // if (stealthMod != 0) { // string localText = new Localize.Text(Mod.Config.LocalizedText[ModConfig.LT_ATTACK_STEALTH]).ToString(); // __result = string.Format("{0}{1} {2:+#;-#}; ", __result, localText, stealthMod); // } // if (ecmShieldMod != 0) { // string localText = new Localize.Text(Mod.Config.LocalizedText[ModConfig.LT_ATTACK_NARCED]).ToString(); // __result = string.Format("{0}{1} {2:+#;-#}; ", __result, localText, narcMod); // } // if (stealthMod != 0) { // string localText = new Localize.Text(Mod.Config.LocalizedText[ModConfig.LT_ATTACK_TAGGED]).ToString(); // __result = string.Format("{0}{1} {2:+#;-#}; ", __result, localText, tagMod); // } // } // } //} }
public static int MagicalDamage(int bd, int power, ICombatant ee) { return (power * (512 - ee.Def) * bd) / (16 * 512); }
public void EquipCombatant(ICombatant combatant) { combatant.EquipWeapon(new CatapultStone()); }
public abstract ICombatBuffProvider GetBuffProvider(ICombatant attacker, ICombatant defender);
public abstract void Execute(ICombatant combatant);
public CombatantDestroyedEvent(IBattle battle, ICombatant combatant, IntVector2 position) : base(battle, combatant, position, position) { }
private void StubEquipCombatant(ICombatant combatant) { combatant.EquipWeapon(this.stubWeapon); }
public virtual bool TrySave(ICombatant attacker) { return RollDice(this.BlockChance); }
public void Lag(ICombatant attacker) { Popup.Create(this.transform.position + Vector3.up * 4, null, Popup.Popups.Lag, (this is Subroutine)); }
public virtual void Kill(ICombatant attacker) { if (this.Info.Reboots > 0) { this.Info.Reboots -= 1; this.DoOnReboot(); } else { this.DoOnKilled(attacker); } }
public virtual void DoOnKilled(ICombatant attacker) { throw new NotImplementedException(); }
public virtual void DoOnBlock(ICombatant attacker) { Popup.Create(this.transform.position + Vector3.up * 4, null, Popup.Popups.Block, (this is Subroutine)); }
public static void Postfix(AbstractActor attackerUnit, Vector3 attackPosition, ICombatant targetUnit, Vector3 targetPosition, bool targetIsEvasive, Weapon weapon, int numTargets, ref float __result) { if (__result > CustomAmmoCategories.Epsilon) { float forbiddenRange = CustomAmmoCategories.getWeaponForbiddenRange(weapon); if (forbiddenRange > (double)CustomAmmoCategories.Epsilon) { float ActualRange = Vector3.Distance(attackPosition, targetPosition); if (ActualRange < forbiddenRange) { __result = 0.0f; } } } }
public static void Postfix(ToHit __instance, AbstractActor attacker, Weapon weapon, ICombatant target, Vector3 attackPosition, Vector3 targetPosition, LineOfFireLevel lofLevel, bool isCalledShot, ref string __result) { string str = string.Empty; bool flag = lofLevel < LineOfFireLevel.LOFObstructed && (CustomAmmoCategories.getIndirectFireCapable(weapon)); float weaponDirectFireModifier = CustomAmmoCategories.getDirectFireModifier(weapon); if (flag == false) { //CustomAmmoCategoriesLog.Log.LogWrite(attacker.DisplayName + " has LOS on " + target.DisplayName + ". Apply DirectFireModifier " + weaponDirectFireModifier + "\n"); if (!NvMath.FloatIsNearZero(weaponDirectFireModifier)) { __result = string.Format("{0}WEAPON-DIRECT-FIRE {1:+#;-#}; ", (object)__result, (object)(int)weaponDirectFireModifier); } } CombatGameState combat = (CombatGameState)typeof(ToHit).GetField("combat", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); return; }
public bool TrySave(ICombatant attacker) { return false; }
private static MessageCenterMessage GetCritMessage(ICombatant unit, string message, object arg, FloatieMessage.MessageNature type) { return(new AddSequenceToStackMessage(new ShowActorInfoSequence(unit, new Text(message, new object[] { arg }), type, true))); }
public bool DoAttack(ICombatant target, AttackType type) { return false; }
private static void Postfix(ToHit __instance, ref string __result, AbstractActor attacker, Weapon weapon, ICombatant target, Vector3 attackPosition, Vector3 targetPosition, LineOfFireLevel lofLevel, bool isCalledShot) { Mod.Log.Trace("TH:GAMD entered"); if (attacker.HasMovedThisRound && attacker.JumpedLastRound) { __result = string.Format("{0}JUMPED {1:+#;-#}; ", __result, Mod.Config.ToHitSelfJumped); } }
public void DoOnBlock(ICombatant attacker) { //noop }
public abstract SkillForecast ComputeForecast(ICombatant attacker, ICombatant defender);
public void DoOnSave(ICombatant attacker) { }
public static int Sadness(int dam, ICombatant ee) { if (ee.Sadness) dam = dam * 7 / 10; return dam; }
public void Freeze(ICombatant attacker) { }
public override void DoOnKilled(ICombatant attacker) { OnVirusDead(); }
protected abstract void TickEffect(ICombatant stat_entity);
protected override void Remove(ICombatant stat_entity) { StopCoroutine(tick_routines[stat_entity][0]); tick_routines[stat_entity].RemoveAt(0); }
public static void UpdateWeaponDamage(CombatHUDWeaponSlot __instance, ICombatant target) { try { Weapon weapon = __instance.DisplayedWeapon; if (weapon == null || weapon.Category == WeaponCategory.Melee || !weapon.CanFire) { return; } string text = null; if (ShowingStabilityDamage) { if (!__instance.WeaponText.text.Contains(HeatPrefix)) { __instance.WeaponText.text += FormatHeat(weapon.HeatGenerated); } float dmg = weapon.Instability(); if (Settings.ShowReducedWeaponDamage && target is AbstractActor actor) { dmg *= actor.StatCollection.GetValue <float>("ReceivedInstabilityMultiplier") * actor.EntrenchedMultiplier; } AddToTotalDamage(dmg, __instance); text = FormatStabilityDamage(dmg); } else { if (__instance.WeaponText.text.Contains(HeatPrefix)) { __instance.WeaponText.text = weapon.UIName.ToString(); } if (ActiveState is SelectionStateFireMulti multi && __instance.TargetIndex < 0) { return; } float raw = weapon.DamagePerShotAdjusted(), dmg = raw; // damage displayed by vanilla if (target != null) { AbstractActor owner = weapon.parent; Vector2 position = (owner.HasMovedThisRound ? null : ActiveState?.PreviewPos) ?? owner.CurrentPosition; dmg = weapon.DamagePerShotFromPosition(MeleeAttackType.NotSet, position, target); // damage with all masks and reductions factored //Info( "{0} {1} => {2} {3} {4}, Dir {5}", owner.CurrentPosition, position, target, target.CurrentPosition, target.CurrentRotation, Combat.HitLocation.GetAttackDirection( position, target ) ); if (WeaponRealizerDamageModifiers != null) { dmg = (float)WeaponRealizerDamageModifiers.Invoke(null, new object[] { weapon.parent, target, weapon, dmg, false }); } } AddToTotalDamage(dmg, __instance); if (target == null || Math.Abs(raw - dmg) < 0.01) { return; } text = ((int)dmg).ToString(); } if (weapon.HeatDamagePerShot > 0) { text = string.Format(HUD.WeaponPanel.HeatFormatString, text, Mathf.RoundToInt(weapon.HeatDamagePerShot)); } if (weapon.ShotsWhenFired > 1) { text = string.Format("{0}</color> (x{1})", text, weapon.ShotsWhenFired); } __instance.DamageText.text = text; } catch (Exception ex) { Error(ex); } }
public void Reset() { _hitp = 0; _noSplit = false; _mpTurbo = 0; _hpAbsorb = false; _mpAbsorb = false; _quadraMagic = false; _addedCut = 0; _addedSteal = false; _longRange = false; _type = AttackType.None; _performer = null; _target = null; _actionTimer = new Timer(2000, 0, false); }
public void Lag(ICombatant attacker) { }
public void Apply(ICombatant combatant) { }
public override void AcceptDamage(ICombatant attacker, int delta) { _hp -= delta; if (_hp < 0) _hp = 0; if (_hp == 0) _death = true; }
public static void Postfix(ToHit __instance, AbstractActor attacker, Weapon weapon, ICombatant target, Vector3 attackPosition, Vector3 targetPosition, LineOfFireLevel lofLevel, bool isCalledShot, ref float __result) { bool flag = lofLevel < LineOfFireLevel.LOFObstructed && (CustomAmmoCategories.getIndirectFireCapable(weapon)); float num = __result; if (flag == false) { //float directFireModifier = CustomAmmoCategories.getDirectFireModifier(weapon); //CustomAmmoCategoriesLog.Log.LogWrite(attacker.DisplayName+" has LOS on "+target.DisplayName+ ". Apply DirectFireModifier "+directFireModifier+"\n"); num += CustomAmmoCategories.getDirectFireModifier(weapon); } CombatGameState combat = (CombatGameState)typeof(ToHit).GetField("combat", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); if ((double)num < 0.0 && !combat.Constants.ResolutionConstants.AllowTotalNegativeModifier) { num = 0.0f; } __result = num; return; }
public void SetEnemy(ICombatant enemyIn) { enemy = enemyIn; }
private static void Postfix(ToHit __instance, ref float __result, AbstractActor attacker, Weapon weapon, ICombatant target, Vector3 attackPosition, Vector3 targetPosition, LineOfFireLevel lofLevel, bool isCalledShot) { if (attacker.HasMovedThisRound && attacker.JumpedLastRound) { __result = __result + (float)CBTMovement.Settings.ToHitSelfJumped; } }
/// <summary> /// Grabs the combatants that fit the specified criteria /// </summary> /// <param name="rHunter">Transform who is searching for the combatants</param> /// <param name="rSeekOrigin">Combat origin of the hunter</param> /// <param name="rFilter">Filters we'll use to limit which combatants are returned</param> /// <param name="rCombatantHits">List of CombatantHit values who are the combatants</param> /// <param name="rIgnore">Transform that we won't consider a target (typically the character)</param> /// <returns>Count of combatants returned</returns> public static int QueryCombatTargets(Transform rSeeker, Vector3 rSeekOrigin, CombatFilter rFilter, List <CombatTarget> rCombatTargets, Transform rIgnore) { if (rSeeker == null) { return(0); } if (rCombatTargets == null) { return(0); } #if OOTII_PROFILE com.ootii.Utilities.Profiler.Start(rSeeker.name + ".QueryCombatTargets"); #endif Collider[] lHitColliders; rCombatTargets.Clear(); int lHitCount = RaycastExt.SafeOverlapSphere(rSeekOrigin, rFilter.MaxDistance, out lHitColliders, rFilter.Layers, rIgnore); for (int i = 0; i < lHitCount; i++) { GameObject lGameObject = lHitColliders[i].gameObject; // Don't count the ignore if (lGameObject.transform == rSeeker) { continue; } if (lGameObject.transform == rIgnore) { continue; } // Determine if the combatant has the appropriate tag if (rFilter.Tag != null && rFilter.Tag.Length > 0) { if (!lGameObject.CompareTag(rFilter.Tag)) { continue; } } // We only care about combatants we'll enage with ICombatant lCombatant = null; Transform lHitTransform = lHitColliders[i].transform; while (lHitTransform != null) { lCombatant = lGameObject.GetComponent <ICombatant>(); if (lCombatant != null) { break; } lHitTransform = lHitTransform.parent; } if (rFilter.RequireCombatant && lCombatant == null) { continue; } // Determine if the combatant is within range Vector3 lClosestPoint = Vector3.zero; ActorController lActorController = lGameObject.GetComponent <ActorController>(); if (lActorController != null) { lClosestPoint = lActorController.ClosestPoint(rSeekOrigin); } else { lClosestPoint = GeometryExt.ClosestPoint(rSeekOrigin, lHitColliders[i]); } // If we have an invalid point, stop if (lClosestPoint == Vector3Ext.Null) { continue; } // Determine if the point is in range bool lIsValid = true; Vector3 lToClosestPoint = lClosestPoint - rSeekOrigin; float lDistance = lToClosestPoint.magnitude; if (rFilter.MinDistance > 0f && lDistance < rFilter.MinDistance) { lIsValid = false; } if (rFilter.MaxDistance > 0f && lDistance > rFilter.MaxDistance) { lIsValid = false; } // Ensure we're not ontop of the combatant. In that case, it's probably the ground Vector3 lDirection = lToClosestPoint.normalized; if (lDirection == -rSeeker.up) { lIsValid = false; } // Check if we're within the field of view float lHAngle = Vector3Ext.HorizontalAngleTo(rSeeker.forward, lDirection, rSeeker.up); if (rFilter.HorizontalFOA > 0f && Mathf.Abs(lHAngle) > rFilter.HorizontalFOA * 0.5f) { lIsValid = false; } float lVAngle = Vector3Ext.HorizontalAngleTo(rSeeker.forward, lDirection, rSeeker.right); if (rFilter.VerticalFOA > 0f && Mathf.Abs(lVAngle) > rFilter.VerticalFOA * 0.5f) { lIsValid = false; } // This is an odd test, but we have to do it. If the closest point of a sphere is out of the FOA, it may // be that the top of the sphere is in the FOA. So, we'll grab the top of the sphere and test it. if (!lIsValid && lCombatant != null && lHitColliders[i] is SphereCollider) { lIsValid = true; SphereCollider lSphereCollider = lHitColliders[i] as SphereCollider; lClosestPoint = lCombatant.Transform.position + (lCombatant.Transform.rotation * (lSphereCollider.center + (Vector3.up * lSphereCollider.radius))); lToClosestPoint = lClosestPoint - rSeekOrigin; lDistance = lToClosestPoint.magnitude; if (rFilter.MinDistance > 0f && lDistance < rFilter.MinDistance) { lIsValid = false; } if (rFilter.MaxDistance > 0f && lDistance > rFilter.MaxDistance) { lIsValid = false; } // Ensure we're not ontop of the combatant. In that case, it's probably the ground lDirection = lToClosestPoint.normalized; if (lDirection == -rSeeker.up) { lIsValid = false; } // Check if we're within the field of view lHAngle = Vector3Ext.HorizontalAngleTo(rSeeker.forward, lDirection, rSeeker.up); if (rFilter.HorizontalFOA > 0f && Mathf.Abs(lHAngle) > rFilter.HorizontalFOA * 0.5f) { lIsValid = false; } lVAngle = Vector3Ext.HorizontalAngleTo(rSeeker.forward, lDirection, rSeeker.right); if (rFilter.VerticalFOA > 0f && Mathf.Abs(lVAngle) > rFilter.VerticalFOA * 0.5f) { lIsValid = false; } } if (mShowDebug) { GraphicsManager.DrawPoint(rSeekOrigin, Color.white, null, 2f); GraphicsManager.DrawPoint(lClosestPoint, Color.red, null, 2f); } if (lIsValid) { // Add the combatant to our list CombatTarget lTargetInfo = new CombatTarget(); lTargetInfo.SeekOrigin = rSeekOrigin; lTargetInfo.Collider = lHitColliders[i]; lTargetInfo.Combatant = lCombatant; lTargetInfo.ClosestPoint = lClosestPoint; lTargetInfo.Distance = lDistance; lTargetInfo.Direction = lDirection; lTargetInfo.HorizontalAngle = lHAngle; lTargetInfo.VerticalAngle = lVAngle; rCombatTargets.Add(lTargetInfo); } } // Sort the combatants by distance if (rCombatTargets.Count > 1) { rCombatTargets.Sort((rLeft, rRight) => rLeft.Distance.CompareTo(rRight.Distance)); // We also want to remove duplicates for (int i = 0; i < rCombatTargets.Count; i++) { Transform lTarget = rCombatTargets[i].Collider.transform; if (rCombatTargets[i].Combatant != null) { lTarget = rCombatTargets[i].Combatant.Transform; } // Check if there's a duplicate and remove it for (int j = rCombatTargets.Count - 1; j > i && j > 0; j--) { Transform lNextTarget = rCombatTargets[j].Collider.transform; if (rCombatTargets[j].Combatant != null) { lNextTarget = rCombatTargets[j].Combatant.Transform; } if (lNextTarget == lTarget) { rCombatTargets.RemoveAt(j); } } } } #if OOTII_PROFILE float lTime = Utilities.Profiler.Stop(rSeeker.name + ".QueryCombatTargets"); //Utilities.Debug.Log.FileWrite(rSeeker.name + ".QueryCombatTargets time:" + lTime.ToString("f5") + "ms"); #endif // Finally, return the count return(rCombatTargets.Count); }
public HitChance(ICombatant initiator, ICombatant defender) : base(initiator, defender) { Type = StatType.HitChance; }
protected abstract void Apply(ICombatant stat_entity);
public void TakeTurn(ICombatant enemy, Range range) { if (Ammo > 1) { if (range.CurrentDistance > 320)//If outside normal range use movement to close { MoveRelativeEnemy(320, range); } if (range.CurrentDistance > 320)//If outside max range use action to dash { MoveRelativeEnemy(320, range); } else//Else Attack { Ammo -= 2; Dice diceroll; if (range.CurrentDistance > 120)//Disadvantage for range { diceroll = new List <Dice> { new Dice(20), new Dice(20) }.OrderBy(x => x.Result).First(); if (enemy.DoesAttackHit(diceroll, 6)) { enemy.CurrentHP -= AttackDamage(); if (diceroll.Result == 20) { enemy.CurrentHP -= AttackDamage(); } } diceroll = new List <Dice> { new Dice(20), new Dice(20) }.OrderBy(x => x.Result).First(); if (enemy.DoesAttackHit(diceroll, 6)) { enemy.CurrentHP -= AttackDamage(); if (diceroll.Result == 20) { enemy.CurrentHP -= AttackDamage(); } } } else { diceroll = new Dice(20); if (enemy.DoesAttackHit(diceroll, 6)) { enemy.CurrentHP -= AttackDamage(); if (diceroll.Result == 20) { enemy.CurrentHP -= AttackDamage(); } } diceroll = new Dice(20); if (enemy.DoesAttackHit(diceroll, 6)) { enemy.CurrentHP -= AttackDamage(); if (diceroll.Result == 20) { enemy.CurrentHP -= AttackDamage(); } } } } } else { range.CurrentDistance += 60; //If we are out of ammo leg it! } }
public void RemoveFrom(ICombatant stat_entity) { Remove(stat_entity); }
private static void Postfix(ToHit __instance, ref float __result, AbstractActor attacker, Weapon weapon, ICombatant target, Vector3 attackPosition, Vector3 targetPosition, LineOfFireLevel lofLevel, bool isCalledShot) { Mod.Log.Trace("TH:GAM entered"); if (attacker.HasMovedThisRound && attacker.JumpedLastRound) { __result = __result + (float)Mod.Config.ToHitSelfJumped; } }
protected abstract void Remove(ICombatant stat_entity);
protected abstract void OnKill(Player p, ICombatant killed);
public override void Execute(ICombatant entity) { entity.AnimatorUpdater.StartCoroutine(ExecuteAttack(entity)); }
public abstract SkillEffects ComputeResult(ICombatant attacker, ICombatant defener, IRandomizer randomizer);
bool CanAttack(ICombatant combatant) { return(combatant != null && combatant.attack > 0 && combatant.remainingAttacks > 0); }
public static float GetKillChance(this ICombatant attacker, ICombatant target) { return attacker.KillChance / 100f * target.BlockChance / 100f; }
public bool CanAttack(ICombatant combatant) { return(function(combatant)); }
public static int PhysicalBase(ICombatant er) { return er.Atk + ((er.Atk + er.Level) / 32) * (er.Atk * er.Level / 32); }
static bool Prefix( ref Vector3 position, ref Quaternion rotation, ref bool isPositionLocked, ref AbstractActor selectedActor, ref ICombatant target, ref bool usingMultifire, ref bool isLocked, ref bool isMelee, WeaponRangeIndicators __instance) { CombatHUD HUD = (CombatHUD)ReflectionHelper.GetPrivateProperty(__instance, "HUD"); if (__instance.DEBUG_showLOSLines) { DEBUG_LOSLineDrawer debugDrawer = (DEBUG_LOSLineDrawer)ReflectionHelper.InvokePrivateMethode(__instance, "GetDebugDrawer", new object[] { }); debugDrawer.DrawLines(selectedActor, HUD.SelectionHandler.ActiveState, target); } LineRenderer line = (LineRenderer)ReflectionHelper.InvokePrivateMethode(__instance, "getLine", new object[] { }); Vector3 vector = Vector3.Lerp(position, position + selectedActor.HighestLOSPosition, __instance.sourceLaserDestRatio); Vector3 vector2 = Vector3.Lerp(target.CurrentPosition, target.TargetPosition, __instance.targetLaserDestRatio); AbstractActor targetActor = target as AbstractActor; // melee if (isMelee) { line.startWidth = __instance.LOSWidthBegin; line.endWidth = __instance.LOSWidthEnd; line.material = __instance.MaterialInRange; line.startColor = __instance.LOSLockedTarget; line.endColor = __instance.LOSLockedTarget; line.positionCount = 2; line.SetPosition(0, vector); Vector3 vector3 = vector - vector2; vector3.Normalize(); vector3 *= __instance.LineEndOffset; vector2 += vector3; line.SetPosition(1, vector2); ReflectionHelper.InvokePrivateMethode(__instance, "SetEnemyTargetable", new object[] { target, true }); List <AbstractActor> allActors = selectedActor.Combat.AllActors; allActors.Remove(selectedActor); allActors.Remove(targetActor); PathNode pathNode = default(PathNode); Vector3 attackPosition = default(Vector3); float num = default(float); selectedActor.Pathing.GetMeleeDestination(targetActor, allActors, out pathNode, out attackPosition, out num); HUD.InWorldMgr.ShowAttackDirection(HUD.SelectedActor, targetActor, HUD.Combat.HitLocation.GetAttackDirection(attackPosition, target), vector2.y, MeleeAttackType.Punch, 0); } // not melee else { FiringPreviewManager.PreviewInfo previewInfo = HUD.SelectionHandler.ActiveState.FiringPreview.GetPreviewInfo(target); if (previewInfo.availability == FiringPreviewManager.TargetAvailability.NotSet) { Debug.LogError("Error - trying to draw line with no FiringPreviewManager availability!"); } // why is the bad case first. just dump out of the f*****g method, doug else { bool flag = HUD.SelectionHandler.ActiveState.SelectionType != SelectionType.Sprint || HUD.SelectedActor.CanShootAfterSprinting; bool flag2 = !isPositionLocked && previewInfo.availability != FiringPreviewManager.TargetAvailability.BeyondMaxRange && previewInfo.availability != FiringPreviewManager.TargetAvailability.BeyondRotation; if (flag && (previewInfo.IsCurrentlyAvailable || flag2)) { // multiple targets, even if only one selected if (usingMultifire) { if (target == HUD.SelectedTarget) { LineRenderer lineRenderer = line; Color color2 = lineRenderer.startColor = (line.endColor = __instance.LOSMultiTargetKBSelection); } else if (isLocked) { LineRenderer lineRenderer2 = line; Color color2 = lineRenderer2.startColor = (line.endColor = __instance.LOSLockedTarget); } else { LineRenderer lineRenderer3 = line; Color color2 = lineRenderer3.startColor = (line.endColor = __instance.LOSUnlockedTarget); } } // normal shot else { float shotQuality = (float)ReflectionHelper.InvokePrivateMethode(__instance, "GetShotQuality", new object[] { selectedActor, position, rotation, target }); Color color5 = Color.Lerp(Color.clear, __instance.LOSInRange, shotQuality); LineRenderer lineRenderer4 = line; Color color2 = lineRenderer4.startColor = line.endColor = color5; } line.material = __instance.MaterialInRange; // straight line shot if (previewInfo.HasLOF) { // LOF unobstructed line.positionCount = 2; line.SetPosition(0, vector); Vector3 vector4 = vector - vector2; vector4.Normalize(); vector4 *= __instance.LineEndOffset; vector2 += vector4; if (previewInfo.LOFLevel == LineOfFireLevel.LOFClear) { // ??? if (target == HUD.SelectionHandler.ActiveState.FacingEnemy) { Logger.Debug("LOF facing"); if (ModSettings.Direct.Active) { float shotQuality = (float)ReflectionHelper.InvokePrivateMethode(__instance, "GetShotQuality", new object[] { selectedActor, position, rotation, target }); line.material.color = Color.white; line.endColor = line.startColor = Color.Lerp(Color.clear, ModSettings.Direct.Color, shotQuality); } line.startWidth = __instance.LOSWidthBegin * __instance.LOSWidthFacingTargetMultiplier; line.endWidth = __instance.LOSWidthEnd * __instance.LOSWidthFacingTargetMultiplier; } else { // enemy in firing arc and have shot if (ModSettings.Direct.Active) { float shotQuality = (float)ReflectionHelper.InvokePrivateMethode(__instance, "GetShotQuality", new object[] { selectedActor, position, rotation, target }); line.material.color = Color.white; line.endColor = line.startColor = Color.Lerp(Color.clear, ModSettings.Direct.Color, shotQuality); // PoC follows for a very high contrast line to help color blind players // line.endColor = line.startColor = Color.black; // LineRenderer line8080 = // (LineRenderer)ReflectionHelper.InvokePrivateMethode(__instance, "getLine", // new object[] { }); // line8080.positionCount = 2; // line8080.SetPosition(0, vector); // line8080.material = __instance.MaterialOutOfRange; // line8080.endColor = line8080.startColor = Color.white; // line8080.material.color = Color.white; // line8080.startWidth = line8080.endWidth = ModSettings.Direct.Thickness * 1.5f; // line8080.SetPosition(1, vector2); if (ModSettings.Direct.Dashed) { line.material = __instance.MaterialOutOfRange; line.material.color = line.endColor; } } line.startWidth = line.endWidth = ModSettings.Direct.Thickness; } line.SetPosition(1, vector2); } // LOF obstructed else { if (target == HUD.SelectionHandler.ActiveState.FacingEnemy) { line.startWidth = __instance.LOSWidthBegin * __instance.LOSWidthFacingTargetMultiplier; line.endWidth = __instance.LOSWidthBegin * __instance.LOSWidthFacingTargetMultiplier; } else { line.startWidth = __instance.LOSWidthBegin; line.endWidth = __instance.LOSWidthBegin; } Vector3 collisionPoint = previewInfo.collisionPoint; collisionPoint = Vector3.Project(collisionPoint - vector, vector2 - vector) + vector; line.SetPosition(1, collisionPoint); if (ModSettings.ObstructedAttackerSide.Active) { line.material.color = Color.white; line.startColor = line.endColor = ModSettings.ObstructedAttackerSide.Color; line.startWidth = line.endWidth = ModSettings.ObstructedAttackerSide.Thickness; if (ModSettings.ObstructedAttackerSide.Dashed) { line.material = __instance.MaterialOutOfRange; line.material.color = line.endColor; } } LineRenderer line2 = (LineRenderer)ReflectionHelper.InvokePrivateMethode(__instance, "getLine", new object[] { }); line2.positionCount = 2; line2.material = __instance.MaterialInRange; if (ModSettings.ObstructedTargetSide.Active) { line2.material.color = Color.white; line2.startColor = line2.endColor = ModSettings.ObstructedTargetSide.Color; line2.startWidth = line2.endWidth = ModSettings.ObstructedTargetSide.Thickness; if (ModSettings.ObstructedTargetSide.Dashed) { line2.material = __instance.MaterialOutOfRange; line2.material.color = line2.endColor; } } else { line2.startColor = line2.endColor = __instance.LOSBlocked; line2.startWidth = line2.endWidth = __instance.LOSWidthBlocked; } line2.SetPosition(0, collisionPoint); line2.SetPosition(1, vector2); GameObject coverIcon = (GameObject)ReflectionHelper.InvokePrivateMethode(__instance, "getCoverIcon", new object[] { }); if (!coverIcon.activeSelf) { coverIcon.SetActive(true); } coverIcon.transform.position = collisionPoint; } } // arc shot else { if (ModSettings.Indirect.Active) { float shotQuality = (float)ReflectionHelper.InvokePrivateMethode(__instance, "GetShotQuality", new object[] { selectedActor, position, rotation, target }); Color color6 = Color.Lerp( Color.clear, ModSettings.Indirect.Color, shotQuality); if (ModSettings.Indirect.Dashed) { line.material = __instance.MaterialOutOfRange; line.material.color = color6; line.startWidth = line.endWidth = ModSettings.Indirect.Thickness; } else { line.material.color = Color.white; line.endColor = line.startColor = color6; } } Vector3[] pointsForArc = WeaponRangeIndicators.GetPointsForArc(18, 30f, vector, vector2); line.positionCount = 18; line.SetPositions(pointsForArc); } ReflectionHelper.InvokePrivateMethode(__instance, "SetEnemyTargetable", new object[] { target, true }); if (targetActor != null) { HUD.InWorldMgr.ShowAttackDirection(HUD.SelectedActor, targetActor, HUD.Combat.HitLocation.GetAttackDirection(position, target), vector2.y, MeleeAttackType.NotSet, HUD.InWorldMgr.NumWeaponsTargeting(target)); } } // sprinted and can't shoot or out of rotation/weapon range else { line.positionCount = 2; line.SetPosition(0, vector); line.SetPosition(1, vector2); LineRenderer lineRenderer6 = line; Color color2 = lineRenderer6.startColor = (line.endColor = __instance.LOSOutOfRange); line.material = __instance.MaterialOutOfRange; ReflectionHelper.InvokePrivateMethode(__instance, "SetEnemyTargetable", new object[] { target, false }); } } } return(false); }
public static int MagicalBase(ICombatant er) { return 6 * (er.Mat + er.Level); }
private static void Postfix(ToHit __instance, ref float __result, AbstractActor attacker, Weapon weapon, ICombatant target, Vector3 attackPosition, Vector3 targetPosition, LineOfFireLevel lofLevel) { //Mod.Log.Debug?.Write($"Getting modifiers for attacker:{CombatantUtils.Label(attacker)} " + // $"using weapon:{weapon.Name} vs target:{CombatantUtils.Label(target)} with initial result:{__result}"); AbstractActor targetActor = target as AbstractActor; if (__instance != null && attacker != null && targetActor != null) { float distance = Vector3.Distance(attackPosition, targetPosition); // Cache these EWState attackerState = new EWState(attacker); EWState targetState = new EWState(targetActor); // If we can't see the target, apply the No Visuals penalty bool canSpotTarget = VisualLockHelper.CanSpotTarget(attacker, attacker.CurrentPosition, target, target.CurrentPosition, target.CurrentRotation, attacker.Combat.LOS); int mimeticMod = targetState.MimeticAttackMod(attackerState); int eyeballAttackMod = canSpotTarget ? mimeticMod : Mod.Config.Attack.NoVisualsPenalty; // Zoom applies independently of visibility (request from Harkonnen) int zoomVisionMod = attackerState.GetZoomVisionAttackMod(weapon, distance); int zoomAttackMod = attackerState.HasZoomVisionToTarget(weapon, distance, lofLevel) ? zoomVisionMod - mimeticMod : Mod.Config.Attack.NoVisualsPenalty; bool hasVisualAttack = (eyeballAttackMod < Mod.Config.Attack.NoVisualsPenalty || zoomAttackMod < Mod.Config.Attack.NoVisualsPenalty); // Sensor attack bucket. Sensors always fallback, so roll everything up and cap int narcAttackMod = targetState.NarcAttackMod(attackerState); int tagAttackMod = targetState.TagAttackMod(attackerState); int ecmShieldAttackMod = targetState.ECMAttackMod(attackerState); int stealthAttackMod = targetState.StealthAttackMod(attackerState, weapon, distance); bool hasSensorAttack = SensorLockHelper.CalculateSharedLock(targetActor, attacker) > SensorScanType.NoInfo; int sensorsAttackMod = Mod.Config.Attack.NoSensorsPenalty; if (hasSensorAttack) { sensorsAttackMod = 0; sensorsAttackMod -= narcAttackMod; sensorsAttackMod -= tagAttackMod; sensorsAttackMod += ecmShieldAttackMod; sensorsAttackMod += stealthAttackMod; } if (sensorsAttackMod > Mod.Config.Attack.NoSensorsPenalty) { sensorsAttackMod = Mod.Config.Attack.NoSensorsPenalty; hasSensorAttack = false; } // Check firing blind if (!hasVisualAttack && !hasSensorAttack) { __result += Mod.Config.Attack.FiringBlindPenalty; } else { __result += (zoomAttackMod < eyeballAttackMod) ? zoomAttackMod : eyeballAttackMod; if (attackerState.HasHeatVisionToTarget(weapon, distance)) { __result += attackerState.GetHeatVisionAttackMod(targetActor, distance, weapon); } __result += sensorsAttackMod; } } }
public override void DoOnKilled(ICombatant attacker) { this.Die(); }
public abstract void AcceptDamage(ICombatant attacker, int delta);