public static void Prefix(AttackStackSequence __instance) { IsMoraleAttack = __instance.isMoraleAttack; Mod.Log.Debug($"AttackStackSequence:OnAdded:prefix - Recording IsMoraleAttack: {IsMoraleAttack}"); AbstractActor attacker = __instance.owningActor; ActorInitiative actorInit = ActorInitiativeHolder.GetOrCreate(attacker); MoraleAttackMod = actorInit.calledShotMod; }
public static int CalculateMeleeDelta(ActorInitiative attacker, ActorInitiative target) { // Always return 1 or more int rawDelta = Math.Max(1, attacker.meleeAttackMod - target.meleeDefenseMod); Mod.Log.Debug($"Melee rawDelta:{rawDelta} = (attackerMod:{attacker.meleeAttackMod} - targetMod:{target.meleeDefenseMod})"); int modifiedDelta = Math.Max(1, rawDelta - target.gutsEffectMod); Mod.Log.Debug($"MeleeMod reduced to modifiedDelta:{modifiedDelta} = (rawDelta:{rawDelta} - gutsEffectMod:{target.gutsEffectMod})"); return(modifiedDelta); }
public static void Postfix(Turret __instance, WeaponHitInfo hitInfo, int hitLocation, Weapon weapon, float damageAmount, int hitIndex, DamageType damageType) { if (weapon != null && weapon.Category == WeaponCategory.Melee) { Mod.Log.Debug($"Turret:TakeWeaponDamage:post - Actor:({__instance.DisplayName}_{__instance.GetPilot().Name}) has suffered a melee attack from:{weapon.parent.DisplayName}."); ActorInitiative attacker = ActorInitiativeHolder.GetOrCreate(weapon.parent); ActorInitiative target = ActorInitiativeHolder.GetOrCreate(__instance); int deltaMod = ActorInitiative.CalculateMeleeDelta(attacker, target); target.ResolveMeleeImpact(__instance, deltaMod); } }
public static void Postfix(AbstractActor __instance, string sourceID, int stackItemUID, bool addedBySelf) { if (InvokeIsKnockdown || InvokeIsCalledShot) { Mod.Log.Debug($"AbstractActor:ForceUnitOnePhaseDown:Postfix - executing custom logic."); ActorInitiative actorInit = ActorInitiativeHolder.GetOrCreate(__instance); int penalty = 0; if (InvokeIsKnockdown) { penalty = Math.Max(0, (-1 * Mod.Config.ProneModifier) - actorInit.pilotingEffectMod); } else if (InvokeIsCalledShot) { int randVal = Mod.Random.Next(0, 2); penalty = Math.Max(0, AttackStackSequence_OnAdded.MoraleAttackMod + randVal - actorInit.pilotingEffectMod); Mod.Log.Debug($"AbstractActor:ForceUnitOnePhaseDown:Postfix - moraleAttackMod:{AttackStackSequence_OnAdded.MoraleAttackMod} pilotingEffect:{actorInit.pilotingEffectMod}"); } Mod.Log.Info($"AbstractActor:ForceUnitOnePhaseDown:Postfix modifying Actor:({__instance.DisplayName}_{__instance.GetPilot().Name}) " + $"initiative by {penalty} due to knockdown:{InvokeIsKnockdown} / calledShot:{InvokeIsCalledShot}!"); if (__instance.HasActivatedThisRound || __instance.Initiative >= Mod.MaxPhase) { Mod.Log.Info($"Penalty {penalty} will apply to Actor:({__instance.DisplayName}_{__instance.GetPilot().Name}) on next activation!"); if (InvokeIsCalledShot) { actorInit.deferredCalledShotMod += penalty; } string floatieMsg = InvokeIsKnockdown ? $"GOING DOWN! -{penalty} INITIATIVE NEXT ROUND" : $"CALLED SHOT! -{penalty} INITIATIVE NEXT ROUND"; __instance.Combat.MessageCenter.PublishMessage(new FloatieMessage(__instance.GUID, __instance.GUID, floatieMsg, FloatieMessage.MessageNature.Debuff)); // Reset their initiative on this round __instance.Initiative = PreInvokeInitiative; } else { Mod.Log.Info($"Penalty {penalty} immediately applies to Actor:({__instance.DisplayName}_{__instance.GetPilot().Name}) with init:{PreInvokeInitiative}"); // The prefix call from CompleteKnockdown will have the actual initiative value, do not use the actor initiative __instance.Initiative = PreInvokeInitiative + penalty; if (__instance.Initiative > Mod.MaxPhase) { __instance.Initiative = Mod.MaxPhase; } __instance.Combat.MessageCenter.PublishMessage(new ActorPhaseInfoChanged(__instance.GUID)); string floatieMsg = InvokeIsKnockdown ? $"GOING DOWN! -{penalty} INITIATIVE" : $"CALLED SHOT! -{penalty} INITIATIVE"; __instance.Combat.MessageCenter.PublishMessage(new FloatieMessage(__instance.GUID, __instance.GUID, floatieMsg, FloatieMessage.MessageNature.Debuff)); } } }
public static void Postfix(AbstractActor __instance) { //SkillBasedInit.Logger.Log($"AbstractActor:DeferUnit:"); int reservePenalty = Mod.Random.Next(Mod.Config.ReservedPenaltyBounds[0], Mod.Config.ReservedPenaltyBounds[1]); Mod.Log.Debug($" Deferring Actor:({CombatantHelper.LogLabel(__instance)}) " + $"initiative:{__instance.Initiative} by:{reservePenalty} to:{__instance.Initiative + reservePenalty}"); __instance.Initiative += reservePenalty; if (__instance.Initiative > Mod.MaxPhase) { __instance.Initiative = Mod.MaxPhase; } // Save some part of the reserve surplus as a penalty for the next round ActorInitiative actorInit = ActorInitiativeHolder.GetOrCreate(__instance); actorInit.reservedCount++; Mod.Log.Debug($" Actor:({CombatantHelper.LogLabel(__instance)}) reservedCount incremented to:{actorInit.reservedCount}"); }
public static void Postfix(AbstractActor __instance, string sourceID, int stackItemUID, bool addedBySelf) { if (InvokeIsVigilance) { Mod.Log.Debug($"AbstractActor:ForceUnitOnePhaseUp:Postfix - executing custom logic."); ActorInitiative actorInit = ActorInitiativeHolder.GetOrCreate(__instance); actorInit.deferredVigilanceMod = actorInit.vigilianceMod + Mod.Random.Next(0, 2); Mod.Log.Debug($"AbstractActor:ForceUnitOnePhaseUp:Postfix - actor {__instance.DisplayName}_{__instance.GetPilot().Name} will gain {actorInit.deferredVigilanceMod} init next round."); string floatieMsg = $"VIGILANCE! +{actorInit.vigilianceMod} INITIATIVE NEXT ROUND!"; __instance.Combat.MessageCenter.PublishMessage(new FloatieMessage(__instance.GUID, __instance.GUID, floatieMsg, FloatieMessage.MessageNature.Debuff)); // TODO: Test that this eliminates the portrait remaining activated __instance.Combat.MessageCenter.PublishMessage(new ActorPhaseInfoChanged(__instance.GUID)); // Reset the actor's initiative Mod.Log.Debug($"AbstractActor:ForceUnitOnePhaseUp:Postfix - actor {__instance.DisplayName}_{__instance.GetPilot().Name} init of {__instance.Initiative} being restored to {PreInvokeInitiative}"); __instance.Initiative = PreInvokeInitiative; } }
public static void Postfix(Pilot __instance, int __state, string sourceID, int stackItemUID, int dmg, DamageType damageType, Weapon sourceWeapon, AbstractActor sourceActor) { Mod.Log.Info($"Pilot:InjurePilot:post - Actor:({__instance.ParentActor.DisplayName}_{__instance.Name}) injured with initial bonusHealth:{__state}"); int currentBonus = 0; if (__instance.StatCollection.GetStatistic("BonusHeath") != null) { currentBonus = __instance.StatCollection.GetStatistic("BonusHeath").Value <int>(); } int bonusDelta = __state - currentBonus; int damageTaken = dmg - bonusDelta; Mod.Log.Debug($"Pilot:InjurePilot:post - Actor:({__instance.ParentActor.DisplayName}_{__instance.Name}) lost bonusHealth:{bonusDelta}, while results in damage:{damageTaken} from the attack."); // If the attacker took any damage, apply it if (damageTaken > 0) { AbstractActor parent = __instance.ParentActor; ActorInitiative target = ActorInitiativeHolder.GetOrCreate(parent); int injuryPenalty = target.CalculateInjuryPenalty(damageTaken, __instance.Injuries); if (!parent.HasActivatedThisRound) { // Apply penalty in current round. Remember high init -> higher phase parent.Initiative += injuryPenalty; if (parent.Initiative > Mod.MaxPhase) { parent.Initiative = Mod.MaxPhase; } parent.Combat.MessageCenter.PublishMessage(new ActorPhaseInfoChanged(parent.GUID)); parent.Combat.MessageCenter.PublishMessage(new FloatieMessage(parent.GUID, parent.GUID, $"OUCH! -{injuryPenalty} INITIATIVE", FloatieMessage.MessageNature.Debuff)); } else { // Injuries are cumulative target.deferredInjuryMod += injuryPenalty; parent.Combat.MessageCenter.PublishMessage(new FloatieMessage(parent.GUID, parent.GUID, $"OUCH! -{injuryPenalty} INITIATIVE NEXT ROUND", FloatieMessage.MessageNature.Debuff)); } } }