コード例 #1
0
        private void _StopMissile(Mission.Missile item)
        {
            if (_Missiles.ContainsKey(item))
            {
                return;
            }
            item.Stop();
            var spawnedItem = (SpawnedItemEntity)Mission.Current.ActiveMissionObjects.ToList().Last();

            _Missiles.Add(item, new ZaWarudoMissile(item, spawnedItem));
        }
コード例 #2
0
            public static void Stop(this Mission.Missile missile)
            {
                missile.Entity.SetMobility(TaleWorlds.Engine.GameEntity.Mobility.stationary);
                var globalFrame = missile.Entity.GetGlobalFrame();

                globalFrame.rotation.RotateAboutSide((float)(System.Math.PI / 2f));
                var zero = TaleWorlds.Library.Vec3.Zero;

                Mission.Current.HandleMissileCollisionReaction(((MBMissile)missile).Index, MissileCollisionReaction.Stick, globalFrame, missile.ShooterAgent, null, false, System.Convert.ToSByte(-1), null, zero, zero, -1);
                Mission.Current.RemoveMissileAsClient(missile.Index);
                HarmonyLib.Traverse.Create(Mission.Current).Method("RemoveMissileAtIndex", missile.Index).GetValue();
            }
コード例 #3
0
 public void MissileCollisionReaction(Mission.MissileCollisionReaction collisionReaction,
                                      Hero attackerHero, Agent attackerAgent, Agent attachedAgent, sbyte attachedBoneIndex,
                                      bool attachedToShield, MatrixFrame attachLocalFrame, Mission.Missile missile)
 => OnMissileCollision?.Invoke(collisionReaction, attackerHero, attackerAgent, attachedAgent,
                               attachedBoneIndex, attachedToShield, attachLocalFrame, missile);
コード例 #4
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;
            }
        }
コード例 #5
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);
        }
コード例 #6
0
        internal static bool GetAttackCollisionResultsPrefix(ref Mission __instance, bool isHorseArcher, Mission.Missile missile, Agent attackerAgent, Agent victimAgent, GameEntity hitObject, float momentumRemaining, ref AttackCollisionData attackCollisionData, bool crushedThrough, bool cancelDamage, out WeaponComponentData shieldOnBack)
        {
            bool  flag             = attackerAgent == null;
            bool  flag2            = victimAgent == null;
            float armorAmountFloat = 0f;

            if (!flag2)
            {
                armorAmountFloat = victimAgent.GetBaseArmorEffectivenessForBodyPart(attackCollisionData.VictimHitBodyPart);
            }
            shieldOnBack = null;
            if (!flag2 && (victimAgent.GetAgentFlags() & AgentFlag.CanWieldWeapon) != AgentFlag.None)
            {
                EquipmentIndex wieldedItemIndex = victimAgent.GetWieldedItemIndex(Agent.HandIndex.OffHand);
                victimAgent.GetWieldedItemIndex(Agent.HandIndex.OffHand);
                for (int i = 0; i < 4; i++)
                {
                    WeaponComponentData currentUsageItem = victimAgent.Equipment[i].CurrentUsageItem;
                    if (i != (int)wieldedItemIndex && currentUsageItem != null && currentUsageItem.IsShield)
                    {
                        shieldOnBack = currentUsageItem;
                        break;
                    }
                }
            }
            MissionWeapon victimShield = default(MissionWeapon);

            if (!flag2 && (victimAgent.GetAgentFlags() & AgentFlag.CanWieldWeapon) != AgentFlag.None)
            {
                EquipmentIndex wieldedItemIndex2 = victimAgent.GetWieldedItemIndex(Agent.HandIndex.OffHand);
                if (wieldedItemIndex2 != EquipmentIndex.None)
                {
                    victimShield = victimAgent.Equipment[wieldedItemIndex2];
                }
            }
            Vec3 attackerAgentMountMovementDirection = default(Vec3);

            if (!flag && attackerAgent.HasMount)
            {
                attackerAgentMountMovementDirection = attackerAgent.MountAgent.GetMovementDirection();
            }
            Vec3 victimAgentMountMovementDirection = default(Vec3);

            if (!flag2 && victimAgent.HasMount)
            {
                victimAgentMountMovementDirection = victimAgent.MountAgent.GetMovementDirection();
            }
            bool                  flag3 = attackerAgent == victimAgent;
            ItemObject            itemFromWeaponKind    = ItemObject.GetItemFromWeaponKind(attackCollisionData.AffectorWeaponKind);
            int                   weaponAttachBoneIndex = (int)((itemFromWeaponKind != null && !flag && attackerAgent.IsHuman) ? attackerAgent.Monster.GetBoneToAttachForItem(itemFromWeaponKind) : -1);
            DestructableComponent destructableComponent = (hitObject != null) ? hitObject.GetFirstScriptOfTypeInFamily <DestructableComponent>() : null;
            bool                  flag4;

            if (!flag3 && (flag2 || !victimAgent.IsFriendOf(attackerAgent)))
            {
                if (destructableComponent != null)
                {
                    BattleSideEnum battleSide     = destructableComponent.BattleSide;
                    Team           team           = attackerAgent.Team;
                    BattleSideEnum?battleSideEnum = (team != null) ? new BattleSideEnum?(team.Side) : null;
                    flag4 = (battleSide == battleSideEnum.GetValueOrDefault() & battleSideEnum != null);
                }
                else
                {
                    flag4 = false;
                }
            }
            else
            {
                flag4 = true;
            }
            bool          isFriendlyFire = flag4;
            MissionWeapon offHandItem    = default(MissionWeapon);

            if (!flag && (attackerAgent.GetAgentFlags() & AgentFlag.CanWieldWeapon) != AgentFlag.None)
            {
                EquipmentIndex wieldedItemIndex3 = attackerAgent.GetWieldedItemIndex(Agent.HandIndex.OffHand);
                if (wieldedItemIndex3 != EquipmentIndex.None)
                {
                    offHandItem = attackerAgent.Equipment[wieldedItemIndex3];
                }
            }
            bool                 isHeadShot = attackCollisionData.VictimHitBodyPart == BoneBodyPartType.Head;
            float                victimAgentAbsorbedDamageRatio = 0f;
            float                num = 0f;
            float                victimMovementDirectionAsAngle = 0f;
            float                victimAgentScale            = 0f;
            float                victimAgentWeight           = 0f;
            float                victimAgentTotalEncumbrance = 0f;
            float                combatDifficultyMultiplier  = 1f;
            AgentFlag            victimAgentFlag             = AgentFlag.CanAttack;
            bool                 isVictimAgentLeftStance     = false;
            bool                 doesVictimHaveMountAgent    = false;
            bool                 isVictimAgentMine           = false;
            bool                 flag5 = false;
            bool                 isVictimAgentRiderAgentIsMine         = false;
            bool                 isVictimAgentMount                    = false;
            bool                 isVictimAgentHuman                    = false;
            bool                 isVictimRiderAgentSameAsAttackerAgent = false;
            BasicCharacterObject victimAgentCharacter                  = new BasicCharacterObject();
            Vec2                 victimAgentMovementVelocity           = default(Vec2);
            Vec3                 victimAgentPosition                   = default(Vec3);
            Vec3                 victimAgentVelocity                   = default(Vec3);
            string               victimAgentName = string.Empty;

            if (!flag2)
            {
                isVictimAgentMount = victimAgent.IsMount;
                isVictimAgentMine  = victimAgent.IsMine;
                bool isMainAgent = victimAgent.IsMainAgent;
                isVictimAgentHuman       = victimAgent.IsHuman;
                isVictimAgentLeftStance  = victimAgent.GetIsLeftStance();
                doesVictimHaveMountAgent = victimAgent.HasMount;
                flag5 = (victimAgent.RiderAgent != null);
                isVictimRiderAgentSameAsAttackerAgent = (!flag5 && victimAgent.RiderAgent == attackerAgent);
                victimAgentAbsorbedDamageRatio        = victimAgent.Monster.AbsorbedDamageRatio;
                num = victimAgent.GetDamageMultiplierForBone(attackCollisionData.CollisionBoneIndex, (DamageTypes)attackCollisionData.DamageType);
                if (!attackCollisionData.IsMissile && (sbyte)attackCollisionData.DamageType == 1)
                {
                    num = (1f + num) * 0.5f;
                }
                victimMovementDirectionAsAngle = victimAgent.MovementDirectionAsAngle;
                victimAgentScale            = victimAgent.AgentScale;
                victimAgentWeight           = (float)victimAgent.Monster.Weight;
                victimAgentTotalEncumbrance = victimAgent.GetTotalEncumbrance();
                combatDifficultyMultiplier  = __instance.GetDamageMultiplierOfCombatDifficulty(victimAgent);
                string name = victimAgent.Name;
                victimAgentName               = (((name != null) ? name.ToString() : null) ?? string.Empty);
                victimAgentMovementVelocity   = victimAgent.MovementVelocity;
                victimAgentVelocity           = victimAgent.Velocity;
                victimAgentPosition           = victimAgent.Position;
                victimAgentFlag               = victimAgent.GetAgentFlags();
                victimAgentCharacter          = victimAgent.Character;
                isVictimAgentRiderAgentIsMine = (flag5 && victimAgent.RiderAgent.IsMine);
                if (victimAgent.MountAgent != null)
                {
                    Vec2 movementVelocity = victimAgent.MountAgent.MovementVelocity;
                }
            }
            float attackerMovementDirectionAsAngle       = 0f;
            float attackerAgentMountChargeDamageProperty = 0f;
            bool  doesAttackerHaveMountAgent             = false;
            bool  isAttackerAgentMine = false;
            bool  flag6 = false;
            bool  isAttackerAgentRiderAgentIsMine = false;
            bool  isAttackerAgentMount            = false;
            bool  isAttackerAgentHuman            = false;
            bool  flag7 = false;
            bool  isAttackerAgentCharging               = false;
            Vec2  attackerAgentMovementVelocity         = default(Vec2);
            BasicCharacterObject attackerAgentCharacter = new BasicCharacterObject();
            Vec3 attackerAgentMovementDirection         = default(Vec3);
            Vec3 attackerAgentVelocity            = default(Vec3);
            Vec3 attackerAgentCurrentWeaponOffset = default(Vec3);
            bool isAttackerAIControlled           = false;

            if (!flag)
            {
                doesAttackerHaveMountAgent = attackerAgent.HasMount;
                bool isMainAgent2 = attackerAgent.IsMainAgent;
                isAttackerAgentMine  = attackerAgent.IsMine;
                isAttackerAgentMount = attackerAgent.IsMount;
                isAttackerAgentHuman = attackerAgent.IsHuman;
                flag7 = attackerAgent.IsActive();
                isAttackerAgentCharging = attackerAgent.IsCharging;
                flag6 = (attackerAgent.RiderAgent != null);
                isAttackerAIControlled                 = attackerAgent.IsAIControlled;
                attackerMovementDirectionAsAngle       = attackerAgent.MovementDirectionAsAngle;
                attackerAgentMountChargeDamageProperty = attackerAgent.GetAgentDrivenPropertyValue(DrivenProperty.MountChargeDamage);
                attackerAgentMovementVelocity          = attackerAgent.MovementVelocity;
                attackerAgentMovementDirection         = attackerAgent.GetMovementDirection();
                attackerAgentVelocity = attackerAgent.Velocity;
                if (flag7)
                {
                    attackerAgentCurrentWeaponOffset = attackerAgent.GetCurWeaponOffset();
                }
                attackerAgentCharacter = attackerAgent.Character;
                if (flag6)
                {
                    isAttackerAgentRiderAgentIsMine = attackerAgent.RiderAgent.IsMine;
                }
                if (attackerAgent.MountAgent != null)
                {
                    Vec2 movementVelocity2 = attackerAgent.MountAgent.MovementVelocity;
                }
            }
            bool canGiveDamageToAgentShield = true;

            if (!flag3)
            {
                canGiveDamageToAgentShield = Extensions.CanGiveDamageToAgentShield(attackerAgent, victimAgent);
            }
            CombatLogData combatLog;


            GetAttackCollisionResults(missile, isHorseArcher, armorAmountFloat, shieldOnBack, victimAgentFlag, victimAgentAbsorbedDamageRatio, num, combatDifficultyMultiplier, victimShield, canGiveDamageToAgentShield, isVictimAgentLeftStance, isFriendlyFire, doesAttackerHaveMountAgent, doesVictimHaveMountAgent, attackerAgentMovementVelocity, attackerAgentMountMovementDirection, attackerMovementDirectionAsAngle, victimAgentMovementVelocity, victimAgentMountMovementDirection, victimMovementDirectionAsAngle, flag3, isAttackerAgentMine, flag6, isAttackerAgentRiderAgentIsMine, isAttackerAgentMount, isVictimAgentMine, flag5, isVictimAgentRiderAgentIsMine, isVictimAgentMount, flag, isAttackerAIControlled, attackerAgentCharacter, victimAgentCharacter, attackerAgentMovementDirection, attackerAgentVelocity, attackerAgentMountChargeDamageProperty, attackerAgentCurrentWeaponOffset, isAttackerAgentHuman, flag7, isAttackerAgentCharging, flag2, victimAgentScale, victimAgentWeight, victimAgentTotalEncumbrance, isVictimAgentHuman, victimAgentVelocity, victimAgentPosition, weaponAttachBoneIndex, offHandItem, isHeadShot, crushedThrough, isVictimRiderAgentSameAsAttackerAgent, momentumRemaining, ref attackCollisionData, cancelDamage, victimAgentName, out combatLog);
            combatLog.BodyPartHit    = attackCollisionData.VictimHitBodyPart;
            combatLog.IsFatalDamage  = (victimAgent != null && victimAgent.Health - (float)attackCollisionData.InflictedDamage <= 0f);
            combatLog.IsVictimEntity = (hitObject != null);

            Extensions.PrintAttackCollisionResults(attackerAgent, victimAgent, hitObject, attackCollisionData, combatLog, cancelDamage);

            return(false);
        }
コード例 #7
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);
        }
コード例 #8
0
        public override void OnMissileCollisionReaction(Mission.MissileCollisionReaction collisionReaction, Agent attacker, Agent victim, sbyte attachedBoneIndex)
        {
            if (!_fireArrowEnabled)
            {
                return;
            }

            Dictionary <Mission.Missile, ParticleSystem> existMissiles = new Dictionary <Mission.Missile, ParticleSystem>();

            foreach (Mission.Missile missile in Mission.Current.Missiles)
            {
                if (_missileParticles.ContainsKey(missile))
                {
                    existMissiles.Add(missile, _missileParticles[missile]);
                    _missileParticles.Remove(missile);
                }
            }
            foreach (KeyValuePair <Mission.Missile, ParticleSystem> item in _missileParticles)
            {
                Mission.Missile missile = item.Key;
                Light           light   = missile.Entity.GetLight();

                //击中敌人箭矢必须熄灭,因为插在Agent身上的箭的粒子效果是无法显示的
                if (victim != null)
                {
                    missile.Entity.RemoveAllParticleSystems();
                    if (light != null)
                    {
                        missile.Entity.RemoveComponent(light);
                    }
                }
                else
                {
                    ParticleSystem particle   = item.Value;
                    MatrixFrame    localFrame = particle.GetLocalFrame().Elevate(0.6f);
                    particle.SetLocalFrame(ref localFrame);
                    if (light != null)
                    {
                        light.Frame     = light.Frame.Elevate(0.15f);
                        light.Intensity = FireLordConfig.FireArrowLightIntensity;
                    }

                    ArrowFireData fireData = new ArrowFireData();

                    localFrame = new MatrixFrame(Mat3.Identity, new Vec3(0, 0, 0)).Elevate(0.6f);
                    fireData.bigFireParticle = ParticleSystem.CreateParticleSystemAttachedToEntity("psys_campfire", missile.Entity, ref localFrame);
                    fireData.timer           = new MissionTimer(FireLordConfig.StickedArrowsBurningTime / 2);
                    fireData.missile         = missile;
                    _hitArrowFires.Add(fireData);
                }

                if (FireLordConfig.IgniteTargetWithFireArrow && victim != null && victim.IsHuman)
                {
                    if (AgentFireDatas.ContainsKey(victim))
                    {
                        AgentFireData fireData = AgentFireDatas[victim];
                        if (!fireData.isBurning)
                        {
                            fireData.firebar += FireLordConfig.IgnitionPerFireArrow;
                            fireData.attacker = attacker;
                        }
                    }
                    else
                    {
                        AgentFireData fireData = new AgentFireData();
                        fireData.firebar += FireLordConfig.IgnitionPerFireArrow;
                        fireData.attacker = attacker;
                        AgentFireDatas.Add(victim, fireData);
                    }
                }
            }
            _missileParticles = existMissiles;
        }
コード例 #9
0
 internal static Blow CreateMissileBlow(this Mission __instance, Agent attackerAgent, ref AttackCollisionData collisionData, Mission.Missile missile, Vec3 missilePosition, Vec3 missileStartingPosition)
 {
     throw new NotImplementedException("Need to patch first");
 }
コード例 #10
0
            internal static void ApplyProjectileArmorResistance(float finputArmor, ref AttackCollisionData collisionData, Mission.Missile missile, bool isHorseArcher)
            {
                int  inputArmor = (int)finputArmor;
                bool multiplierHeadOrNeckShot = collisionData.VictimHitBodyPart == BoneBodyPartType.Head || collisionData.VictimHitBodyPart == BoneBodyPartType.Neck;

                var type = missile.Weapon.CurrentUsageItem.WeaponClass;

                switch (type)
                {
                case WeaponClass.Arrow:
                    ApplyArrowArmorPen(ref collisionData, inputArmor, multiplierHeadOrNeckShot);
                    break;

                case WeaponClass.Bolt:
                    ApplyBoltArmorPen(ref collisionData, inputArmor, multiplierHeadOrNeckShot);
                    break;

                case WeaponClass.ThrowingAxe:
                    ApplyThrowableArmorPen(ref collisionData, inputArmor, multiplierHeadOrNeckShot);
                    break;

                case WeaponClass.ThrowingKnife:
                    ApplyThrowableArmorPen(ref collisionData, inputArmor, multiplierHeadOrNeckShot);
                    break;

                case WeaponClass.Javelin:
                    ApplyThrowableArmorPen(ref collisionData, inputArmor, multiplierHeadOrNeckShot);
                    break;

                default:
                    break;
                }

                if (isHorseArcher)
                {
                    collisionData.InflictedDamage *= 2;
                }
            }