コード例 #1
0
        static public BlockMissionObject DrawFBXMeshMissionObjectAt(Mission mission, Vec3 pos, string filename)
        {
            // if (prefab == null)

            GameEntity prefab = GameEntity.CreateEmpty(mission.Scene, false);


            prefab.EntityFlags |= EntityFlags.DontSaveToScene;

            //prefab.AddMesh(Mesh.GetFromResource("order_arrow_a"), true);

            //   prefab.SetVisibilityExcludeParents(true);

            if (MeshListByFileName.ContainsKey(filename) == false)
            {
                MeshListByFileName.Add(filename, CreateMesh(filename));
            }
            foreach (var mesh in MeshListByFileName[filename])
            {
                prefab.AddMesh(mesh, false);
            }
            prefab.RecomputeBoundingBox();
            PhysicsShape shape = prefab.GetBodyShape();

            // shape.
            prefab.AddPhysics(1000, new Vec3(0, 0, 0), null, new Vec3(), new Vec3(), PhysicsMaterial.GetFromIndex(0), false, 0);

            GameEntity blockEntity = prefab;


            MatrixFrame identity2 = MatrixFrame.Identity;

            identity2.origin    = pos;
            identity2.origin.x += 7.5f;

            identity2.origin.z = 7.5f;
            identity2.rotation.ApplyScaleLocal(1f);
            MatrixFrame frame2 = identity2;

            blockEntity.SetFrame(ref frame2);
            blockEntity.SetVisibilityExcludeParents(true);
            blockEntity.SetAlpha(1f);
            blockEntity.CreateAndAddScriptComponent("BlockMissionObject");

            BlockMissionObject missionObject = blockEntity.GetFirstScriptOfType <BlockMissionObject>();

            mission.AddActiveMissionObject(missionObject);
            return(missionObject);
        }
コード例 #2
0
        public static void GetAttackCollisionResults(Mission.Missile missile, bool isHorseArcher, float armorAmountFloat, WeaponComponentData shieldOnBack, AgentFlag victimAgentFlag, float victimAgentAbsorbedDamageRatio, float damageMultiplierOfBone, float combatDifficultyMultiplier, MissionWeapon victimShield, bool canGiveDamageToAgentShield, bool isVictimAgentLeftStance, bool isFriendlyFire, bool doesAttackerHaveMountAgent, bool doesVictimHaveMountAgent, Vec2 attackerAgentMovementVelocity, Vec3 attackerAgentMountMovementDirection, float attackerMovementDirectionAsAngle, Vec2 victimAgentMovementVelocity, Vec3 victimAgentMountMovementDirection, float victimMovementDirectionAsAngle, bool isVictimAgentSameWithAttackerAgent, bool isAttackerAgentMine, bool isAttackerAgentHasRiderAgent, bool isAttackerAgentRiderAgentIsMine, bool isAttackerAgentMount, bool isVictimAgentMine, bool isVictimAgentHasRiderAgent, bool isVictimAgentRiderAgentIsMine, bool isVictimAgentMount, bool isAttackerAgentNull, bool isAttackerAIControlled, BasicCharacterObject attackerAgentCharacter, BasicCharacterObject victimAgentCharacter, Vec3 attackerAgentMovementDirection, Vec3 attackerAgentVelocity, float attackerAgentMountChargeDamageProperty, Vec3 attackerAgentCurrentWeaponOffset, bool isAttackerAgentHuman, bool isAttackerAgentActive, bool isAttackerAgentCharging, bool isVictimAgentNull, float victimAgentScale, float victimAgentWeight, float victimAgentTotalEncumbrance, bool isVictimAgentHuman, Vec3 victimAgentVelocity, Vec3 victimAgentPosition, int weaponAttachBoneIndex, MissionWeapon offHandItem, bool isHeadShot, bool crushedThrough, bool IsVictimRiderAgentSameAsAttackerAgent, float momentumRemaining, ref AttackCollisionData attackCollisionData, bool cancelDamage, string victimAgentName, out CombatLogData combatLog)
        {
            float distance = 0f;

            if (attackCollisionData.IsMissile)
            {
                distance = (attackCollisionData.MissileStartingPosition - attackCollisionData.CollisionGlobalPosition).Length;
            }
            combatLog = new CombatLogData(isVictimAgentSameWithAttackerAgent, isAttackerAgentHuman, isAttackerAgentMine, isAttackerAgentHasRiderAgent, isAttackerAgentRiderAgentIsMine, isAttackerAgentMount, isVictimAgentHuman, isVictimAgentMine, false, isVictimAgentHasRiderAgent, isVictimAgentRiderAgentIsMine, isVictimAgentMount, false, IsVictimRiderAgentSameAsAttackerAgent, false, false, distance);
            ItemObject          itemFromWeaponKind  = ItemObject.GetItemFromWeaponKind(attackCollisionData.AffectorWeaponKind);
            WeaponComponentData weaponComponentData = (itemFromWeaponKind != null) ? itemFromWeaponKind.GetWeaponWithUsageIndex(attackCollisionData.CurrentUsageIndex) : null;
            bool flag = Extensions.HitWithAnotherBone(ref attackCollisionData, weaponAttachBoneIndex);
            Vec3 agentVelocityContribution  = Extensions.GetAgentVelocityContribution(doesAttackerHaveMountAgent, attackerAgentMovementVelocity, attackerAgentMountMovementDirection, attackerMovementDirectionAsAngle);
            Vec3 agentVelocityContribution2 = Extensions.GetAgentVelocityContribution(doesVictimHaveMountAgent, victimAgentMovementVelocity, victimAgentMountMovementDirection, victimMovementDirectionAsAngle);

            if (attackCollisionData.IsColliderAgent)
            {
                combatLog.IsRangedAttack = attackCollisionData.IsMissile;
                combatLog.HitSpeed       = (attackCollisionData.IsMissile ? (agentVelocityContribution2 - attackCollisionData.MissileVelocity).Length : (agentVelocityContribution - agentVelocityContribution2).Length);
            }
            float baseMagnitude;
            int   speedBonus;

            Mission.ComputeBlowMagnitude(ref attackCollisionData, doesVictimHaveMountAgent, weaponComponentData, isAttackerAgentNull, attackerAgentCharacter, attackerAgentMovementDirection, attackerAgentVelocity, attackerAgentMountChargeDamageProperty, attackerAgentCurrentWeaponOffset, isAttackerAgentHuman, isAttackerAgentActive, isAttackerAgentCharging, isVictimAgentNull, victimAgentScale, victimAgentWeight, victimAgentTotalEncumbrance, isVictimAgentHuman, victimAgentVelocity, victimAgentPosition, momentumRemaining, cancelDamage, flag, attackCollisionData.MissileTotalDamage, agentVelocityContribution, agentVelocityContribution2, out attackCollisionData.BaseMagnitude, out baseMagnitude, out attackCollisionData.MovementSpeedDamageModifier, out speedBonus);
            DamageTypes damageType = (itemFromWeaponKind == null || flag || attackCollisionData.IsAlternativeAttack || attackCollisionData.IsFallDamage || attackCollisionData.IsHorseCharge) ? DamageTypes.Blunt : ((DamageTypes)attackCollisionData.DamageType);

            combatLog.DamageType = damageType;
            if (!attackCollisionData.IsColliderAgent && attackCollisionData.EntityExists)
            {
                string name         = PhysicsMaterial.GetFromIndex(attackCollisionData.PhysicsMaterialIndex).Name;
                bool   isWoodenBody = name == "wood" || name == "wood_weapon" || name == "wood_shield";
                attackCollisionData.BaseMagnitude  *= Extensions.GetEntityDamageMultiplier(isAttackerAgentCharging, weaponComponentData, damageType, isWoodenBody);
                attackCollisionData.InflictedDamage = MBMath.ClampInt((int)attackCollisionData.BaseMagnitude, 0, 2000);
                combatLog.InflictedDamage           = attackCollisionData.InflictedDamage;
            }
            int num = 0;

            if (attackCollisionData.IsColliderAgent && !isVictimAgentNull)
            {
                if (attackCollisionData.IsAlternativeAttack)
                {
                    baseMagnitude = attackCollisionData.BaseMagnitude;
                }
                if (attackCollisionData.AttackBlockedWithShield)
                {
                    Mission.ComputeBlowDamageOnShield(isAttackerAgentNull, isAttackerAgentActive, isAttackerAgentCharging, canGiveDamageToAgentShield, isVictimAgentLeftStance, victimShield, ref attackCollisionData, weaponComponentData, attackCollisionData.BaseMagnitude);
                    attackCollisionData.AbsorbedByArmor = attackCollisionData.InflictedDamage;
                }
                else
                {
                    Mission.ComputeBlowDamage(armorAmountFloat, shieldOnBack, victimAgentFlag, victimAgentAbsorbedDamageRatio, damageMultiplierOfBone, combatDifficultyMultiplier, damageType, baseMagnitude, attackCollisionData.CollisionGlobalPosition, itemFromWeaponKind, attackCollisionData.AttackBlockedWithShield, attackCollisionData.CollidedWithShieldOnBack, speedBonus, cancelDamage, attackCollisionData.IsFallDamage, out attackCollisionData.InflictedDamage, out attackCollisionData.AbsorbedByArmor, out num);
                }



                GCOToolbox.GCOToolbox.ProjectileBalance.ApplyProjectileArmorResistance(armorAmountFloat, ref attackCollisionData, missile, isHorseArcher);


                combatLog.InflictedDamage = attackCollisionData.InflictedDamage;
                combatLog.AbsorbedDamage  = attackCollisionData.AbsorbedByArmor;

                //combatLog.AttackProgress = attackCollisionData.AttackProgress;
                //issionGameModels.Current.AgentApplyDamageModel.CalculateDamage(attackerAgentCharacter, victimAgentCharacter, offHandItem, isHeadShot, isVictimAgentMount, isVictimAgentHuman, doesAttackerHaveMountAgent, isVictimAgentNull, isAttackerAgentHuman, attackCollisionData, weaponComponentData);
                //combatLog.ExtraDamage = attackCollisionData.InflictedDamage - combatLog.InflictedDamage;
            }
            if (!attackCollisionData.IsFallDamage && isFriendlyFire && !isAttackerAIControlled && GameNetwork.IsSessionActive)
            {
                int num2 = attackCollisionData.IsMissile ? MultiplayerOptions.OptionType.FriendlyFireDamageRangedSelfPercent.GetIntValue(MultiplayerOptions.MultiplayerOptionsAccessMode.CurrentMapOptions) : MultiplayerOptions.OptionType.FriendlyFireDamageMeleeSelfPercent.GetIntValue(MultiplayerOptions.MultiplayerOptionsAccessMode.CurrentMapOptions);
                attackCollisionData.SelfInflictedDamage = MBMath.Round((float)attackCollisionData.InflictedDamage * ((float)num2 * 0.01f));
                int num3 = attackCollisionData.IsMissile ? MultiplayerOptions.OptionType.FriendlyFireDamageRangedFriendPercent.GetIntValue(MultiplayerOptions.MultiplayerOptionsAccessMode.CurrentMapOptions) : MultiplayerOptions.OptionType.FriendlyFireDamageMeleeFriendPercent.GetIntValue(MultiplayerOptions.MultiplayerOptionsAccessMode.CurrentMapOptions);
                attackCollisionData.InflictedDamage = MBMath.Round((float)attackCollisionData.InflictedDamage * ((float)num3 * 0.01f));
                if (isVictimAgentMount && !doesAttackerHaveMountAgent)
                {
                    attackCollisionData.InflictedDamage = MBMath.Round((float)attackCollisionData.InflictedDamage * 0.1f);
                }
                combatLog.InflictedDamage = attackCollisionData.InflictedDamage;
                combatLog.IsFriendlyFire  = true;
            }
            if (attackCollisionData.AttackBlockedWithShield && attackCollisionData.InflictedDamage > 0 && (int)victimShield.HitPoints - attackCollisionData.InflictedDamage <= 0)
            {
                attackCollisionData.IsShieldBroken = true;
            }
        }
コード例 #3
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);
        }
コード例 #4
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);
        }