Пример #1
0
        private Blow CreateBlow(Agent attacker, Agent victim)
        {
            Blow blow = new Blow(attacker.Index);

            blow.VictimBodyPart                 = BoneBodyPartType.None;
            blow.AttackType                     = AgentAttackType.Standard;
            blow.WeaponRecord                   = default(BlowWeaponRecord);
            blow.WeaponRecord.WeaponFlags       = (blow.WeaponRecord.WeaponFlags | (WeaponFlags.AffectsArea | WeaponFlags.Burning));
            blow.MissileRecord.IsValid          = true;
            blow.MissileRecord.CurrentPosition  = blow.Position;
            blow.MissileRecord.MissileItemKind  = 67109974;
            blow.MissileRecord.StartingPosition = blow.Position;
            blow.MissileRecord.WeaponFlags      = blow.WeaponRecord.WeaponFlags;
            blow.StrikeType                     = StrikeType.Invalid;
            blow.DamageType                     = DamageTypes.Blunt;
            blow.NoIgnore                    = false;
            blow.AttackerStunPeriod          = 0;
            blow.DefenderStunPeriod          = 0;
            blow.BlowFlag                    = BlowFlags.ShrugOff;
            blow.BlowFlag                   |= BlowFlags.NoSound;
            blow.Position                    = victim.GetEyeGlobalPosition();
            blow.BoneIndex                   = 0;
            blow.Direction                   = victim.LookDirection;
            blow.SwingDirection              = victim.LookDirection;
            blow.BaseMagnitude               = 0;
            blow.MovementSpeedDamageModifier = 1;
            blow.InflictedDamage             = FireLordConfig.IgnitionDamagePerSecond;
            blow.SelfInflictedDamage         = 0;
            blow.AbsorbedByArmor             = 0;
            blow.DamageCalculated            = true;
            return(blow);
        }
Пример #2
0
        static bool Prefix(Agent __instance, ref Blow b)
        {
            if (InvulnerableSettings.Instance.Enabled == false)
            {
                return(true);
            }
            if (__instance.IsMainAgent)
            {
                if (!b.BlowFlag.HasAnyFlag(BlowFlags.NoSound))
                {
                    Agent agent = (b.OwnerId != -1) ? __instance.Mission.FindAgentWithIndex(b.OwnerId) : __instance;

                    int   soundIndex     = GetSoundIndex(GetWeaponClass(ref b));
                    float forceParameter = GetForceParameter(ref b);
                    SoundEventParameter soundEventParameter = new SoundEventParameter("Force", forceParameter);
                    Mission.Current.MakeSound(soundIndex, b.Position, true, false, -1, -1, ref soundEventParameter);
                    MatrixFrame f       = __instance.Frame;
                    Vec3        dirDist = b.Position - f.origin;
                    Vec3        dir     = dirDist.NormalizedCopy();
                    float       offset  = 0.05f * agent.GetEyeGlobalHeight();
                    f.origin = b.Position + dir * offset;
                    Mission.Current.Scene.CreateBurstParticle(ParticleSystemManager.GetRuntimeIdByName("psys_game_metal_metal_coll"), f);
                    __instance.Mission.AddSoundAlarmFactorToAgents(b.OwnerId, b.Position, 15f);
                }
                return(false);
            }
            return(true);
        }
Пример #3
0
        async Task TestBellMouseMove(MouseEventArgs e)
        {
            // Mouse movement only active when the play button says Play (as opposed to
            // Stop or Wait), and the Play button is not disabled
            // The latter test is needed because when submitting, the play button says Play
            if (e.Buttons == 1 && Screen.PlayLabel == "Play" && Screen.PlayDisabled == false)
            {
                int clientX = Convert.ToInt32(e.ClientX);

                int newGapCumulativeRow;

                if (Blow.IsHandstroke)
                {
                    newGapCumulativeRow = Convert.ToInt32((clientX - Screen.XMargin) / TestSpec.XScale);
                }
                else
                {
                    newGapCumulativeRow = Convert.ToInt32((clientX - Screen.XMargin) / TestSpec.XScale) -
                                          TestSpec.BaseGap;
                }

                int newGap        = Blow.Gap + (newGapCumulativeRow - Blow.GapCumulativeRow);
                int newGapRounded = Convert.ToInt32((double)newGap / Constants.Rounding) * Constants.Rounding;

                if (newGapRounded >= TestSpec.GapMin && newGapRounded <= TestSpec.GapMax &&
                    newGapRounded != Blow.Gap)
                {
                    Blow.UpdateGap(newGapRounded);
                    await Callback.InvokeAsync(CallbackParam.MouseMove);
                }
            }
        }
 public AgentToDie(Agent agent, Blow blow, KillInfo killInfo)
 {
     //IL_0010: Unknown result type (might be due to invalid IL or missing references)
     //IL_0011: Unknown result type (might be due to invalid IL or missing references)
     //IL_0017: Unknown result type (might be due to invalid IL or missing references)
     //IL_0018: Unknown result type (might be due to invalid IL or missing references)
     this.agent    = agent;
     this.blow     = blow;
     this.killInfo = killInfo;
 }
        async Task GapPlusClick()
        {
            int newGap = Blow.Gap + Constants.Rounding;

            if (newGap <= TestSpec.GapMax)
            {
                Blow.UpdateGap(newGap);
                await Callback.InvokeAsync(CallbackParam.GapPlus);
            }
        }
 internal static void CheckToAddHyperarmor(ref Blow b, ref Blow blow)
 {
     if (Global.IsHyperArmorActive())
     {
         b.BlowFlag    |= BlowFlags.ShrugOff;
         blow.BlowFlag |= BlowFlags.ShrugOff;
         InformationManager.DisplayMessage(
             new InformationMessage("Player hyperarmor prevented flinch!", Colors.White));
     }
 }
Пример #7
0
        async Task TestChanged(int value)
        {
            testSpec.SelectedTest = value;
            blow = null;

            if (testSpec.SelectedTest != 0 && testSpec.SelectedTest != -1)
            {
                await Load(testSpec.SelectedTest);
            }
        }
Пример #8
0
 public static void Prefix(ref Blow b, Agent __instance)
 {
     if (__instance.Character != null)
     {
         float excessiveDamage = (float)b.InflictedDamage - __instance.Health + 1f;
         if (excessiveDamage > 0)
         {
             BasicCharacterObjectCustomMembers.ExcessiveDamages[__instance.Character.Id] = excessiveDamage;
         }
     }
 }
        private void KillAgent(Agent agent)
        {
            bool flag = !GameNetwork.IsClientOrReplay;

            if (flag)
            {
                Blow blow = new Blow(agent.Index);
                blow.DamageType    = DamageTypes.Cut;
                blow.StrikeType    = StrikeType.Swing;
                blow.BoneIndex     = agent.Monster.HeadLookDirectionBoneIndex;
                blow.Position      = agent.Position;
                blow.Position.z    = blow.Position.z + agent.GetEyeGlobalHeight();
                blow.BaseMagnitude = 2000f;
                blow.WeaponRecord.FillWith(null, -1, -1);
                blow.InflictedDamage = 2000;
                Vec3 v     = new Vec3(1f, 0f, 0f, -1f);
                bool flag2 = Mission.Current.InputManager.IsGameKeyDown(2);
                if (flag2)
                {
                    v = new Vec3(-1f, 0f, 0f, -1f);
                }
                else
                {
                    bool flag3 = Mission.Current.InputManager.IsGameKeyDown(3);
                    if (flag3)
                    {
                        v = new Vec3(1f, 0f, 0f, -1f);
                    }
                    else
                    {
                        bool flag4 = Mission.Current.InputManager.IsGameKeyDown(1);
                        if (flag4)
                        {
                            v = new Vec3(0f, -1f, 0f, -1f);
                        }
                        else
                        {
                            bool flag5 = Mission.Current.InputManager.IsGameKeyDown(0);
                            if (flag5)
                            {
                                v = new Vec3(0f, 1f, 0f, -1f);
                            }
                        }
                    }
                }
                blow.SwingDirection = agent.Frame.rotation.TransformToParent(v);
                blow.SwingDirection.Normalize();
                blow.Direction        = blow.SwingDirection;
                blow.DamageCalculated = true;
                agent.RegisterBlow(blow);
            }
        }
 internal static void CheckToAddHyperarmor(Agent agent, ref Blow b, ref Blow blow)
 {
     if (IsHyperArmorActive(agent))
     {
         b.BlowFlag    |= BlowFlags.ShrugOff;
         blow.BlowFlag |= BlowFlags.ShrugOff;
         if (agent == Mission.Current.MainAgent)
         {
             InformationManager.DisplayMessage(
                 new InformationMessage("Player hyperarmor prevented flinch!", Colors.White));
         }
     }
 }
Пример #11
0
        //[HarmonyPrefix]
        //[HarmonyPatch("Die")]
        public static bool DiePreFix(Agent __instance, Blow b, Agent.KillInfo overrideKillInfo = Agent.KillInfo.Invalid)
        {
            if (Main.Enable)
            {
                if (!Main.agentToDice.ContainsKey(__instance))
                {
                    Main.agentToDice.Add(__instance, new AgentToDie(__instance, b, overrideKillInfo));
                }


                return(false);
            }
            return(true);
        }
        internal static void CheckForProjectileFlinch(ref Blow b, ref Blow blow, AttackCollisionData collisionData, Agent victim)
        {
            if (victim != null && b.IsMissile())
            {
                if (collisionData.VictimHitBodyPart != BoneBodyPartType.Head && collisionData.VictimHitBodyPart != BoneBodyPartType.Neck)
                {
                    var projStunThresholdMultiplier = Config.ConfigSettings.ProjectileStunPercentageThreshold / 100;

                    if (b.InflictedDamage < (victim.HealthLimit * projStunThresholdMultiplier))
                    {
                        b.BlowFlag    |= BlowFlags.ShrugOff;
                        blow.BlowFlag |= BlowFlags.ShrugOff;
                    }
                }
            }
        }
Пример #13
0
 private static void DecideWeaponCollisionReactionPostfix(
     Mission __instance,
     Blow registeredBlow,
     ref AttackCollisionData collisionData,
     Agent attacker,
     Agent defender,
     bool isFatalHit,
     bool isShruggedOff,
     ref MeleeCollisionReaction colReaction
     )
 {
     if (SliceLogic.ShouldSliceThrough(collisionData, attacker, defender))
     {
         colReaction = MeleeCollisionReaction.SlicedThrough;
     }
 }
        private static void _RegisterBlow(Agent attacker)
        {
            var blow = new Blow(attacker.Index);

            if (attacker.MountAgent == null)
            {
                blow.BlowFlag = BlowFlags.KnockBack | BlowFlags.KnockDown;
            }
            else
            {
                blow.BlowFlag = BlowFlags.CanDismount;
            }

            blow.InflictedDamage  = 1;
            blow.DamageCalculated = true;
            attacker.RegisterBlow(blow);
        }
        //original method required was a void, but you must return boolean for harmony lib
        internal static bool RegisterBlowPrefix(Mission __instance, Agent attacker, Agent victim, GameEntity realHitEntity, Blow b, ref AttackCollisionData collisionData)
        {
            b.VictimBodyPart = collisionData.VictimHitBodyPart;
            if (!collisionData.AttackBlockedWithShield)
            {
                Blow blow = attacker.CreateBlowFromBlowAsReflection(b);

                if (GCOToolbox.GCOToolbox.MeleeBalance.GCOCheckHyperArmorConfiguration(victim))
                {
                    GCOToolbox.GCOToolbox.MeleeBalance.CheckToAddHyperarmor(victim, ref b, ref blow);
                }
                GCOToolbox.GCOToolbox.ProjectileBalance.CheckForProjectileFlinch(ref b, ref blow, collisionData, victim);

                if (collisionData.IsColliderAgent)
                {
                    if (b.SelfInflictedDamage > 0 && attacker != null && attacker.IsFriendOf(victim))
                    {
                        if (victim.IsMount && attacker.MountAgent != null)
                        {
                            attacker.MountAgent.RegisterBlow(blow);
                        }
                        else
                        {
                            attacker.RegisterBlow(blow);
                        }
                    }
                    victim.RegisterBlow(b);
                }
                else if (collisionData.EntityExists)
                {
                    MissionReversePatches.OnEntityHit(Mission.Current, realHitEntity, attacker, b.InflictedDamage, (DamageTypes)collisionData.DamageType, b.Position, b.SwingDirection, collisionData.AffectorWeaponKind, collisionData.CurrentUsageIndex);

                    if (b.SelfInflictedDamage > 0)
                    {
                        attacker.RegisterBlow(blow);
                    }
                }
            }

            foreach (MissionBehaviour missionBehaviour in Mission.Current.MissionBehaviours)
            {
                missionBehaviour.OnRegisterBlow(attacker, victim, realHitEntity, b, ref collisionData);
            }

            return(false);
        }
Пример #16
0
        async Task Load(int id)
        {
            // Get a test from the API
            AVTestData aVTestData = await TJBarnesService.GetHttpClient()
                                    .GetFromJsonAsync <AVTestData>("api/avtests/" + id.ToString());

            // Use the Deserializer method of the JsonSerializer class (in the System.Text.Json namespace) to create
            // a BlowCore object
            BlowCore blowCore = JsonSerializer.Deserialize <BlowCore>(aVTestData.AVTestSpec);

            // Now create a Blow object from the BlowCore object
            blow = new Blow();
            blow.LoadBlow(blowCore);

            blow.BellColor = Constants.UnstruckTestBellColor;

            testSpec.ShowGaps = false;
            StateHasChanged();
        }
Пример #17
0
        private static void MakeDead(Agent victim, Agent attacker)
        {
            Blow blow = new Blow();

            blow.AttackType      = AgentAttackType.Standard;
            blow.DamageType      = DamageTypes.Cut;
            blow.StrikeType      = StrikeType.Swing;
            blow.InflictedDamage = 1000;
            blow.BoneIndex       = victim.Monster.HeadLookDirectionBoneIndex;
            blow.BaseMagnitude   = 1000;
            blow.Position        = victim.Position;
            blow.Position.z      = victim.GetEyeGlobalHeight();
            blow.WeaponRecord.FillWith(null, -1, -1);
            blow.SwingDirection = new Vec3(attacker.MovementVelocity * -1, 0, -1);
            blow.SwingDirection.Normalize();
            blow.Direction        = blow.SwingDirection;
            blow.DamageCalculated = true;
            victim.RegisterBlow(blow);
        }
Пример #18
0
        /// <summary>
        /// Applies multipliers according to configuration file.
        /// </summary>
        /// <param name="tickDamage"></param>
        /// <param name="b"></param>
        /// <param name="collisionData"></param>
        /// <param name="config"></param>
        /// <returns></returns>
        public static double ApplyMultipliers(this double tickDamage, Blow b, AttackCollisionData collisionData, Config config)
        {
            if (b.DamageType == DamageTypes.Cut)
            {
                tickDamage *= 1 + config.CutMultiplier;
            }
            if (b.DamageType == DamageTypes.Blunt)
            {
                tickDamage *= 1 + config.BluntMultiplier;
            }
            if (b.DamageType == DamageTypes.Pierce)
            {
                tickDamage *= 1 + config.PierceMultiplier;
            }
            if (b.DamageType == DamageTypes.Invalid)
            {
                tickDamage *= 1 + config.InvalidMultiplier;
            }

            if (collisionData.VictimHitBodyPart == BoneBodyPartType.Neck)
            {
                tickDamage *= 1 + config.BodyMultipliers.Neck.Mult;
            }
            if (collisionData.VictimHitBodyPart == BoneBodyPartType.Head)
            {
                tickDamage *= 1 + config.BodyMultipliers.Head.Mult;
            }
            if (collisionData.VictimHitBodyPart == BoneBodyPartType.BipedalArmLeft || collisionData.VictimHitBodyPart == BoneBodyPartType.BipedalArmRight)
            {
                tickDamage *= 1 + config.BodyMultipliers.Arms.Mult;
            }
            if (collisionData.VictimHitBodyPart == BoneBodyPartType.BipedalLegs)
            {
                tickDamage *= 1 + config.BodyMultipliers.Legs.Mult;
            }
            if (collisionData.VictimHitBodyPart == BoneBodyPartType.ShoulderLeft || collisionData.VictimHitBodyPart == BoneBodyPartType.ShoulderRight)
            {
                tickDamage *= 1 + config.BodyMultipliers.Shoulders.Mult;
            }

            return(tickDamage);
        }
Пример #19
0
        private Blow CreateBlow(
            Agent affectedAgent,
            HumanBone impactedBone,
            Agent affectorAgent,
            WeaponComponentData weapon,
            MatrixFrame weaponTipFrame
            )
        {
            var blow = new Blow
            {
                Position        = weaponTipFrame.origin,
                Direction       = weaponTipFrame.rotation.u,
                AttackType      = AgentAttackType.Standard,
                InflictedDamage = (int)((weapon.ThrustDamage * affectedAgent.Velocity.Length) + (weapon.ThrustDamage * affectorAgent.Velocity.Length)),
                DamageType      = DamageTypes.Pierce,
                VictimBodyPart  = affectedAgent.AgentVisuals.GetBoneTypeDataList()[(int)impactedBone].BodyPartType,
                BaseMagnitude   = 1.0f,
                StrikeType      = StrikeType.Thrust,
            };

            return(blow);
        }
Пример #20
0
 public static void DecideAgentKnockedByBlow(
     ref Agent attacker,
     ref Agent victim,
     ref AttackCollisionData collisionData,
     ref WeaponComponentData attackerWeapon,
     ref bool isInitialBlowShrugOff,
     ref Blow blow)
 {
     try
     {
         if (attacker.IsPlayer() &&
             BannerlordCheatsSettings.Instance?.AlwaysKnockDown == true)
         {
             blow.BlowFlag &= ~BlowFlags.ShrugOff;
             blow.BlowFlag |= BlowFlags.KnockDown;
         }
     }
     catch (Exception e)
     {
         SubModule.LogError(e, typeof(AlwaysKnockDown));
     }
 }
Пример #21
0
            public BleedingComponent(Agent victim, Agent attacker, double tickDamage, Blow b, Config config, Mission mission, SPKillFeedVM hitFeed) : base(victim)
            {
                _victim     = victim;
                _attacker   = attacker;
                _b          = b;
                _config     = config;
                _mission    = mission;
                _tickDamage = tickDamage;
                _bandaged   = false;
                _hitFeed    = hitFeed;

                _dropRate = 0.8f;
                _timer    = new System.Timers.Timer()
                {
                    Interval  = _config.SecondsBetweenTicks * 1000,
                    AutoReset = false
                };

                _enabled = true;

                DealBleedingDamage();
            }
 public static void DecideWeaponCollisionReaction(
     ref Blow registeredBlow,
     ref AttackCollisionData collisionData,
     ref Agent attacker,
     ref Agent defender,
     ref MissionWeapon attackerWeapon,
     ref bool isFatalHit,
     ref bool isShruggedOff,
     ref MeleeCollisionReaction colReaction)
 {
     try
     {
         if (attacker.IsPlayer() &&
             BannerlordCheatsSettings.Instance?.SliceThroughEveryone == true)
         {
             colReaction = MeleeCollisionReaction.SlicedThrough;
         }
     }
     catch (Exception e)
     {
         SubModule.LogError(e, typeof(SliceThroughEveryoneWeapon));
     }
 }
Пример #23
0
        void Create()
        {
            blow = new Blow();
            blow.CreateRandomBlow();

            blow.Gap = 700;
            blow.GapCumulativeRow = blow.Gap;
            blow.GapCumulative    = blow.Gap;
            blow.GapStr           = blow.Gap.ToString();

            Random rand = new Random();

            blow.AltGap = rand.Next(400, 701);

            if (blow.AltGap > 550)
            {
                blow.AltGap += 300;
            }

            // Round
            blow.AltGap = Convert.ToInt32((double)blow.AltGap / Constants.Rounding) * Constants.Rounding;

            blow.BellColor = Constants.UnstruckTestBellColor;
        }
Пример #24
0
        public override void OnRegisterBlow(Agent attacker, Agent victim, GameEntity realHitEntity, Blow b, ref AttackCollisionData collisionData)
        {
            if (attacker == null || victim == null)
            {
                return;
            }
            if (attacker == victim)
            {
                return;
            }

            bool isPlayerAttacker;

            if (IsValidAttacker(attacker, out isPlayerAttacker) && IsValidVictim(victim))
            {
                var attackDir = attacker.AttackDirection;
                //Wanted to do arms as well, but currently not possible. Will have to wait until we can add custom meshes and skeletons
                if (collisionData.VictimHitBodyPart == BoneBodyPartType.Head && (attackDir == Agent.UsageDirection.AttackRight ||
                                                                                 attackDir == Agent.UsageDirection.AttackLeft) && b.DamageType == DamageTypes.Cut)
                {
                    DismemberAgent(victim, attacker, BodyPart.Head, isPlayerAttacker);
                }
                //else if (attackDir == Agent.UsageDirection.AttackRight && (collisionData.VictimHitBodyPart == BoneBodyPartType.BipedalArmLeft || collisionData.VictimHitBodyPart == BoneBodyPartType.ShoulderLeft))
                //    DismemberAgent(victim, BodyPart.LeftArm);
                //else if (attackDir == Agent.UsageDirection.AttackLeft && (collisionData.VictimHitBodyPart == BoneBodyPartType.ShoulderRight || collisionData.VictimHitBodyPart == BoneBodyPartType.BipedalArmRight))
                //    DismemberAgent(victim, BodyPart.RightArm);
            }
            else if (IsValidAttacker(attacker, out isPlayerAttacker) && victim.Health <= 0 && victim.Character == null)
            {
                DismemberAgent(victim, attacker, BodyPart.Head, false);
            }
        }
Пример #25
0
        internal static bool MissileHitCallbackPrefix(ref bool __result, ref Mission __instance, out int hitParticleIndex, ref AttackCollisionData collisionData, int missileIndex, Vec3 missileStartingPosition, Vec3 missilePosition, Vec3 missileAngularVelocity, Vec3 movementVelocity, MatrixFrame attachGlobalFrame, MatrixFrame affectedShieldGlobalFrame, int numDamagedAgents, Agent attacker, Agent victim, GameEntity hitEntity)
        {
            var _missiles = MissionAccessTools.Get_missiles(ref __instance);

            Mission.Missile missile = _missiles[missileIndex];

            bool isHorseArcher = GCOToolbox.GCOToolbox.ProjectileBalance.CheckForHorseArcher(victim);
            bool makesRear     = GCOToolbox.GCOToolbox.ProjectileBalance.ApplyHorseCrippleLogic(victim, collisionData.VictimHitBodyPart);

            WeaponFlags         weaponFlags1      = missile.Weapon.CurrentUsageItem.WeaponFlags;
            float               momentumRemaining = 1f;
            WeaponComponentData shieldOnBack      = (WeaponComponentData)null;

            if (collisionData.AttackBlockedWithShield && weaponFlags1.HasAnyFlag <WeaponFlags>(WeaponFlags.CanPenetrateShield))
            {
                GetAttackCollisionResultsPrefix(ref __instance, isHorseArcher, missile, attacker, victim, hitEntity, momentumRemaining, ref collisionData, false, false, out shieldOnBack);
                EquipmentIndex wieldedItemIndex = victim.GetWieldedItemIndex(Agent.HandIndex.OffHand);
                if ((double)collisionData.InflictedDamage > (double)ManagedParameters.Instance.GetManagedParameter(ManagedParametersEnum.ShieldPenetrationOffset) + (double)ManagedParameters.Instance.GetManagedParameter(ManagedParametersEnum.ShieldPenetrationFactor) * (double)victim.Equipment[wieldedItemIndex].GetShieldArmorForCurrentUsage())
                {
                    AttackCollisionData.UpdateDataForShieldPenetration(ref collisionData);
                    momentumRemaining *= (float)(0.400000005960464 + (double)MBRandom.RandomFloat * 0.200000002980232);
                }
            }
            hitParticleIndex = -1;
            bool            flag1             = !GameNetwork.IsSessionActive;
            bool            missileHasPhysics = collisionData.MissileHasPhysics;
            PhysicsMaterial fromIndex         = PhysicsMaterial.GetFromIndex(collisionData.PhysicsMaterialIndex);
            int             num1  = fromIndex.IsValid ? (int)fromIndex.GetFlags() : 0;
            bool            flag2 = (weaponFlags1 & WeaponFlags.AmmoSticksWhenShot) > (WeaponFlags)0;
            bool            flag3 = (num1 & 1) == 0;
            bool            flag4 = (uint)(num1 & 8) > 0U;
            MissionObject   attachedMissionObject = (MissionObject)null;

            if (victim == null && (NativeObject)hitEntity != (NativeObject)null)
            {
                GameEntity gameEntity = hitEntity;
                do
                {
                    attachedMissionObject = gameEntity.GetFirstScriptOfType <MissionObject>();
                    gameEntity            = gameEntity.Parent;
                }while (attachedMissionObject == null && (NativeObject)gameEntity != (NativeObject)null);
                hitEntity = attachedMissionObject?.GameEntity;
            }
            Mission.MissileCollisionReaction collisionReaction1 = !flag4 ? (!weaponFlags1.HasAnyFlag <WeaponFlags>(WeaponFlags.Burning) ? (!flag3 || !flag2 ? Mission.MissileCollisionReaction.BounceBack : Mission.MissileCollisionReaction.Stick) : Mission.MissileCollisionReaction.BecomeInvisible) : Mission.MissileCollisionReaction.PassThrough;
            bool isCanceled = false;

            Mission.MissileCollisionReaction collisionReaction2;
            if (collisionData.MissileGoneUnderWater)
            {
                collisionReaction2 = Mission.MissileCollisionReaction.BecomeInvisible;
                hitParticleIndex   = 0;
            }
            else if (victim == null)
            {
                if ((NativeObject)hitEntity != (NativeObject)null)
                {
                    GetAttackCollisionResultsPrefix(ref __instance, isHorseArcher, missile, attacker, victim, hitEntity, momentumRemaining, ref collisionData, false, false, out shieldOnBack);
                    Blow missileBlow = __instance.CreateMissileBlow(attacker, ref collisionData, missile, missilePosition, missileStartingPosition);
                    __instance.RegisterBlow(attacker, (Agent)null, hitEntity, missileBlow, ref collisionData);
                }
                collisionReaction2 = collisionReaction1;
                hitParticleIndex   = 0;
            }
            else if (collisionData.AttackBlockedWithShield)
            {
                GetAttackCollisionResultsPrefix(ref __instance, isHorseArcher, missile, attacker, victim, hitEntity, momentumRemaining, ref collisionData, false, false, out shieldOnBack);
                collisionReaction2 = collisionData.IsShieldBroken ? Mission.MissileCollisionReaction.BecomeInvisible : collisionReaction1;
                hitParticleIndex   = 0;
            }
            else
            {
                if (attacker != null && attacker.IsFriendOf(victim))
                {
                    if (!missileHasPhysics)
                    {
                        if (flag1)
                        {
                            if (attacker.Controller == Agent.ControllerType.AI)
                            {
                                isCanceled = true;
                            }
                        }
                        else if (MultiplayerOptions.OptionType.FriendlyFireDamageRangedFriendPercent.GetIntValue(MultiplayerOptions.MultiplayerOptionsAccessMode.CurrentMapOptions) <= 0 && MultiplayerOptions.OptionType.FriendlyFireDamageRangedSelfPercent.GetIntValue(MultiplayerOptions.MultiplayerOptionsAccessMode.CurrentMapOptions) <= 0 || __instance.Mode == MissionMode.Duel)
                        {
                            isCanceled = true;
                        }
                    }
                }
                else if (victim.IsHuman && !attacker.IsEnemyOf(victim))
                {
                    isCanceled = true;
                }
                else if (flag1 && attacker != null && (attacker.Controller == Agent.ControllerType.AI && victim.RiderAgent != null) && attacker.IsFriendOf(victim.RiderAgent))
                {
                    isCanceled = true;
                }
                if (isCanceled)
                {
                    if (flag1 && attacker == Agent.Main && attacker.IsFriendOf(victim))
                    {
                        InformationManager.DisplayMessage(new InformationMessage(GameTexts.FindText("ui_you_hit_a_friendly_troop", (string)null).ToString(), Color.ConvertStringToColor("#D65252FF")));
                    }
                    collisionReaction2 = Mission.MissileCollisionReaction.BecomeInvisible;
                }
                else
                {
                    bool flag5 = (weaponFlags1 & WeaponFlags.MultiplePenetration) > (WeaponFlags)0;
                    GetAttackCollisionResultsPrefix(ref __instance, isHorseArcher, missile, attacker, victim, (GameEntity)null, momentumRemaining, ref collisionData, false, false, out shieldOnBack);
                    Blow missileBlow = __instance.CreateMissileBlow(attacker, ref collisionData, missile, missilePosition, missileStartingPosition);
                    if (makesRear)
                    {
                        missileBlow.BlowFlag = BlowFlags.MakesRear;
                    }

                    if (!collisionData.CollidedWithShieldOnBack & flag5 && numDamagedAgents > 0)
                    {
                        missileBlow.InflictedDamage     /= numDamagedAgents;
                        missileBlow.SelfInflictedDamage /= numDamagedAgents;
                    }
                    float managedParameter1 = ManagedParameters.Instance.GetManagedParameter(missileBlow.DamageType != DamageTypes.Cut ? (missileBlow.DamageType != DamageTypes.Pierce ? ManagedParametersEnum.DamageInterruptAttackThresholdBlunt : ManagedParametersEnum.DamageInterruptAttackThresholdPierce) : ManagedParametersEnum.DamageInterruptAttackThresholdCut);
                    if ((double)collisionData.InflictedDamage <= (double)managedParameter1)
                    {
                        missileBlow.BlowFlag |= BlowFlags.ShrugOff;
                    }
                    if (victim.State == AgentState.Active)
                    {
                        __instance.RegisterBlow(attacker, victim, (GameEntity)null, missileBlow, ref collisionData);
                    }
                    hitParticleIndex = ParticleSystemManager.GetRuntimeIdByName("psys_game_blood_sword_enter");
                    if (flag5 && numDamagedAgents < 3)
                    {
                        collisionReaction2 = Mission.MissileCollisionReaction.PassThrough;
                    }
                    else
                    {
                        collisionReaction2 = collisionReaction1;
                        if (collisionReaction1 == Mission.MissileCollisionReaction.Stick && !collisionData.CollidedWithShieldOnBack)
                        {
                            bool flag6 = __instance.CombatType == Mission.MissionCombatType.Combat;
                            if (flag6)
                            {
                                bool flag7 = victim.IsHuman && collisionData.VictimHitBodyPart == BoneBodyPartType.Head;
                                flag6 = victim.State != AgentState.Active || !flag7;
                            }
                            if (flag6)
                            {
                                float managedParameter2 = ManagedParameters.Instance.GetManagedParameter(ManagedParametersEnum.MissileMinimumDamageToStick);
                                float num2 = 2f * managedParameter2;
                                if (!GameNetwork.IsClientOrReplay && (double)missileBlow.InflictedDamage < (double)managedParameter2 && (double)missileBlow.AbsorbedByArmor > (double)num2)
                                {
                                    collisionReaction2 = Mission.MissileCollisionReaction.BounceBack;
                                }
                            }
                            else
                            {
                                collisionReaction2 = Mission.MissileCollisionReaction.BecomeInvisible;
                            }
                        }
                    }
                }
            }
            if (collisionData.CollidedWithShieldOnBack && shieldOnBack != null && (victim != null && victim.IsMainAgent))
            {
                InformationManager.DisplayMessage(new InformationMessage(GameTexts.FindText("ui_hit_shield_on_back", (string)null).ToString(), Color.ConvertStringToColor("#FFFFFFFF")));
            }
            MatrixFrame attachLocalFrame;

            if (!collisionData.MissileHasPhysics && !collisionData.MissileGoneUnderWater)
            {
                bool shouldMissilePenetrate = collisionReaction2 == Mission.MissileCollisionReaction.Stick;
                attachLocalFrame = __instance.CalculateAttachedLocalFrame(ref attachGlobalFrame, collisionData, missile.Weapon.CurrentUsageItem, victim, hitEntity, movementVelocity, missileAngularVelocity, affectedShieldGlobalFrame, shouldMissilePenetrate);
            }
            else
            {
                attachLocalFrame      = attachGlobalFrame;
                attachedMissionObject = (MissionObject)null;
            }
            Vec3 velocity        = Vec3.Zero;
            Vec3 angularVelocity = Vec3.Zero;

            if (collisionReaction2 == Mission.MissileCollisionReaction.BounceBack)
            {
                WeaponFlags weaponFlags2 = weaponFlags1 & WeaponFlags.AmmoBreakOnBounceBackMask;
                if (weaponFlags2 == WeaponFlags.AmmoCanBreakOnBounceBack && (double)collisionData.MissileVelocity.Length > (double)ManagedParameters.Instance.GetManagedParameter(ManagedParametersEnum.BreakableProjectileMinimumBreakSpeed) || weaponFlags2 == WeaponFlags.AmmoBreaksOnBounceBack)
                {
                    collisionReaction2 = Mission.MissileCollisionReaction.BecomeInvisible;
                    hitParticleIndex   = ParticleSystemManager.GetRuntimeIdByName("psys_game_broken_arrow");
                }
                else
                {
                    missile.CalculateBounceBackVelocity(missileAngularVelocity, collisionData, out velocity, out angularVelocity);
                }
            }
            __instance.HandleMissileCollisionReaction(missileIndex, collisionReaction2, attachLocalFrame, attacker, victim, collisionData.AttackBlockedWithShield, collisionData.CollisionBoneIndex, attachedMissionObject, velocity, angularVelocity, -1);
            foreach (MissionBehaviour missionBehaviour in __instance.MissionBehaviours)
            {
                missionBehaviour.OnMissileHit(attacker, victim, isCanceled);
            }
            __result = collisionReaction2 != Mission.MissileCollisionReaction.PassThrough;

            return(false);
        }
Пример #26
0
        public override void OnRegisterBlow(Agent attacker, Agent victim, GameEntity realHitEntity, Blow b,
                                            ref AttackCollisionData collisionData)
        {
            base.OnRegisterBlow(attacker, victim, realHitEntity, b, ref collisionData);
            if (victim.IsHero)
            {
                // Hero hero = ((CharacterObject) victim.Character).HeroObject;
                // InformationManager.DisplayMessage(new InformationMessage(hero.Name.ToString() + " found as hero"));

                InformationManager.DisplayMessage(
                    new InformationMessage(
                        "On Register blow: " +
                        attacker.Name +
                        " hit " +
                        victim.Name +
                        " with " +
                        HeroHealth[victim].ToString() + " health remaining after " +
                        b.InflictedDamage.ToString() + " damage was inflicted and " +
                        b.AbsorbedByArmor.ToString() + " damage absorbed by armor" // b.VictimBodyPart. + " "

                        ));
                if (victim.Health == 0)
                {
                    InformationManager.DisplayMessage(
                        new InformationMessage(
                            attacker.Name + " finished " +
                            victim.Name + " with " +
                            HeroHealth[victim].ToString() + " health remaining after " +
                            b.InflictedDamage.ToString() + " damage was inflicted and " +
                            b.AbsorbedByArmor.ToString() + " damage absorbed by armor"

                            ));
                    var excess_damage = b.InflictedDamage - HeroHealth[victim];
                    excess_damage = excess_damage * excess_damage;
                    var random_roll            = rand.NextDouble();
                    var wound_threshold        = .25;
                    var death_threshold        = .1;
                    var body_part_multiplier   = 1.0;
                    var damage_scaler          = .0015;
                    var damage_type_multiplier = 1.0;
                    switch (b.DamageType)
                    {
                    case DamageTypes.Blunt:
                        damage_type_multiplier = .5;
                        break;

                    case DamageTypes.Cut:
                        damage_type_multiplier = .75;
                        break;

                    case DamageTypes.Pierce:
                        damage_type_multiplier = 1.0;
                        break;

                    default:
                        damage_type_multiplier = .4;
                        break;
                    }
                    switch (b.VictimBodyPart)
                    {
                    case BoneBodyPartType.Head:
                        body_part_multiplier = 1.0;
                        break;

                    case BoneBodyPartType.Neck:
                        body_part_multiplier = .9;
                        break;

                    case BoneBodyPartType.Chest:
                        body_part_multiplier = .5;
                        break;

                    case BoneBodyPartType.Abdomen:
                        body_part_multiplier = .3;
                        break;

                    case BoneBodyPartType.ShoulderLeft:
                        body_part_multiplier = .2;
                        break;

                    case BoneBodyPartType.ShoulderRight:
                        body_part_multiplier = .2;
                        break;

                    case BoneBodyPartType.BipedalLegs:
                        body_part_multiplier = .1;
                        break;

                    case BoneBodyPartType.BipedalArmLeft:
                        body_part_multiplier = .1;
                        break;

                    case BoneBodyPartType.BipedalArmRight:
                        body_part_multiplier = .1;
                        break;

                    default:
                        body_part_multiplier = 0.0;
                        break;
                    }
                    InformationManager.DisplayMessage(new InformationMessage(random_roll.ToString() + " was random roll"));

                    if (excess_damage * damage_scaler * body_part_multiplier * damage_type_multiplier * death_threshold
                        > random_roll)
                    {
                        InformationManager.DisplayMessage(new InformationMessage(victim.Name + " has been killed"));
                        InformationManager.DisplayMessage(new InformationMessage("Excess Damage " + excess_damage.ToString() +
                                                                                 " Damage Scaler " + damage_scaler +
                                                                                 " body part " + body_part_multiplier +
                                                                                 " damage type " + damage_type_multiplier));
                        InformationManager.DisplayMessage(new InformationMessage("Chance of death was " + (excess_damage * damage_scaler * body_part_multiplier * damage_type_multiplier * death_threshold).ToString()));
                        // Hero hero = ((CharacterObject) victim.Character).HeroObject;
                        // InformationManager.DisplayMessage(new InformationMessage(hero.Name.ToString() + " found as hero"));

                        // KillCharacterAction.ApplyByBattle((Hero)victim.Character., true);
                        // MBObjectManager.Instance.GetObject<Hero>(victim.Character.StringId).Name.ToString();
                    }
                    else if (excess_damage * damage_scaler * body_part_multiplier * damage_type_multiplier * wound_threshold
                             > random_roll)
                    {
                        InformationManager.DisplayMessage(new InformationMessage(victim.Name + " has been wounded"));
                        InformationManager.DisplayMessage(new InformationMessage("Excess Damage " + excess_damage.ToString() +
                                                                                 " Damage Scaler " + damage_scaler +
                                                                                 " body part " + body_part_multiplier +
                                                                                 " damage type " + damage_type_multiplier));
                        InformationManager.DisplayMessage(new InformationMessage("Chance of wound was " + (excess_damage * damage_scaler * body_part_multiplier * damage_type_multiplier * wound_threshold).ToString()));
                    }
                }
                HeroHealth[victim] = victim.Health;
            }
        }
Пример #27
0
        private static float GetForceParameter(ref Blow b)
        {
            float res = 1f;

            return(res);
        }
Пример #28
0
 public override void OnRegisterBlow(Agent attacker, Agent victim, GameEntity realHitEntity, Blow b, ref AttackCollisionData collisionData, in MissionWeapon attackerWeapon)
Пример #29
0
        static bool Prefix(Mission __instance, ref bool __result, out int hitParticleIndex, ref AttackCollisionData collisionData,
                           Vec3 missileStartingPosition, Vec3 missilePosition, Vec3 missileAngularVelocity, Vec3 movementVelocity,
                           MatrixFrame attachGlobalFrame, MatrixFrame affectedShieldGlobalFrame, int numDamagedAgents, Agent attacker, Agent victim,
                           GameEntity hitEntity)
        {
            hitParticleIndex = -1;
            if (InvulnerableSettings.Instance.Enabled == false)
            {
                return(true);
            }
            if (victim == Agent.Main)
            {
                FieldInfo           missileField        = AccessTools.Field(typeof(Mission), "_missiles");
                var                 missiles            = (Dictionary <int, Mission.Missile>)missileField.GetValue(__instance);
                Mission.Missile     missile             = missiles[collisionData.AffectorWeaponSlotOrMissileIndex];
                MissionWeapon       weapon              = missile.Weapon;
                WeaponFlags         weaponFlags         = missile.Weapon.CurrentUsageItem.WeaponFlags;
                float               num                 = 1f;
                WeaponComponentData weaponComponentData = null;
                if (collisionData.AttackBlockedWithShield && weaponFlags.HasAnyFlag(WeaponFlags.CanPenetrateShield))
                {
                    return(true);    // Use original code
                }
                hitParticleIndex = -1;
                Mission.MissileCollisionReaction missileCollisionReaction = Mission.MissileCollisionReaction.BounceBack;
                bool            flag = !GameNetwork.IsSessionActive;
                bool            missileHasPhysics = collisionData.MissileHasPhysics;
                PhysicsMaterial fromIndex         = PhysicsMaterial.GetFromIndex(collisionData.PhysicsMaterialIndex);
                object          obj   = fromIndex.IsValid ? fromIndex.GetFlags() : PhysicsMaterialFlags.None;
                bool            flag2 = (weaponFlags & WeaponFlags.AmmoSticksWhenShot) > (WeaponFlags)0UL;
                object          obj2  = obj;
                bool            flag5 = false;
                if (collisionData.MissileGoneUnderWater)
                {
                    return(true);
                }
                else if (collisionData.AttackBlockedWithShield)
                {
                    return(true);
                }
                else
                {
                    // Friendly control
                    if (attacker != null && attacker.IsFriendOf(victim))
                    {
                        if (!missileHasPhysics)
                        {
                            if (flag)
                            {
                                if (attacker.Controller == Agent.ControllerType.AI)
                                {
                                    flag5 = true;
                                }
                            }
                            else if ((MultiplayerOptions.OptionType.FriendlyFireDamageRangedFriendPercent.GetIntValue(MultiplayerOptions.MultiplayerOptionsAccessMode.CurrentMapOptions) <= 0 && MultiplayerOptions.OptionType.FriendlyFireDamageRangedSelfPercent.GetIntValue(MultiplayerOptions.MultiplayerOptionsAccessMode.CurrentMapOptions) <= 0) || __instance.Mode == MissionMode.Duel)
                            {
                                flag5 = true;
                            }
                        }
                    }
                    else if (victim.IsHuman && !attacker.IsEnemyOf(victim))
                    {
                        flag5 = true;
                    }
                    else if (flag && attacker != null && attacker.Controller == Agent.ControllerType.AI && victim.RiderAgent != null && attacker.IsFriendOf(victim.RiderAgent))
                    {
                        flag5 = true;
                    }

                    if (flag5)
                    {
                        missileCollisionReaction = Mission.MissileCollisionReaction.BecomeInvisible;
                    }
                    else
                    {
                        // even weapons with multiple penetration can't penetrate me.
                        //bool flag6 = (weaponFlags & WeaponFlags.MultiplePenetration) > (WeaponFlags)0UL;
                        //if (flag6)
                        //{
                        //    return true;    // Use original code
                        //}

                        MethodInfo getAttackCollisionResultsMethod = typeof(Mission).GetMethod("GetAttackCollisionResults", BindingFlags.NonPublic | BindingFlags.Instance);
                        getAttackCollisionResultsMethod.Invoke(__instance, new object[] {
                            attacker, victim, null, num, collisionData, weapon, false, false, false, weaponComponentData
                        });
                        Blow blow = CreateMissileBlow(attacker, collisionData, weapon, missilePosition, missileStartingPosition);
                        blow.BlowFlag |= BlowFlags.ShrugOff;    // Any attack is so neglectable to our hero
                        if (victim.State == AgentState.Active)
                        {
                            MethodInfo registerBlowMethod = AccessTools.Method("Mission:RegisterBlow");
                            registerBlowMethod.Invoke(__instance, new object[] { attacker, victim, null, blow, collisionData, weapon });
                            //__instance.RegisterBlow(attacker, victim, null, blow, ref collisionData);
                        }
                    }
                }
                MatrixFrame attachLocalFrame;
                attachLocalFrame = attachGlobalFrame;


                // Any missile bounces back
                WeaponFlags weaponFlags2 = weaponFlags & WeaponFlags.AmmoBreakOnBounceBackMask;
                Vec3        zero         = Vec3.Zero;
                Vec3        zero2        = Vec3.Zero;
                if ((weaponFlags2 == WeaponFlags.AmmoCanBreakOnBounceBack &&
                     collisionData.MissileVelocity.Length >
                     ManagedParameters.Instance.GetManagedParameter(ManagedParametersEnum.BreakableProjectileMinimumBreakSpeed)) ||
                    weaponFlags2 == WeaponFlags.AmmoBreaksOnBounceBack)
                {
                    if (collisionData.MissileTotalDamage > InvulnerableSettings.Instance.ArrowBreakingThres)
                    {
                        missileCollisionReaction = Mission.MissileCollisionReaction.BecomeInvisible;
                        Mission.Current.Scene.CreateBurstParticle(ParticleSystemManager.GetRuntimeIdByName("psys_game_broken_arrow"), attachLocalFrame);
                    }
                    else
                    {
                        hitParticleIndex = ParticleSystemManager.GetRuntimeIdByName("psys_game_broken_arrow");  // For some reason, setting this doesn't work
                    }
                }
                else
                {
                    missile.CalculateBounceBackVelocity(missileAngularVelocity, collisionData, out zero, out zero2);
                    Mission.Current.Scene.CreateBurstParticle(ParticleSystemManager.GetRuntimeIdByName("psys_game_missile_metal_coll"), attachLocalFrame);
                }
                __instance.HandleMissileCollisionReaction(collisionData.AffectorWeaponSlotOrMissileIndex, missileCollisionReaction, attachLocalFrame,
                                                          attacker, null, collisionData.AttackBlockedWithShield, collisionData.CollisionBoneIndex, null, zero, zero2, -1);
                foreach (MissionBehaviour missionBehaviour in __instance.MissionBehaviours)
                {
                    missionBehaviour.OnMissileHit(attacker, null, flag5);
                }

                __result = true;
                return(false);
            }
            return(true);
        }
Пример #30
0
 private static WeaponClass GetWeaponClass(ref Blow b)
 {
     return(b.WeaponRecord.WeaponClass);
 }