コード例 #1
0
 public MeleeAttackEffector(int weaponStrength,
                            MeleeAttackType attackType = MeleeAttackType.Regular,
                            DamageType damageType      = DamageType.Regular)
 {
     this.weaponStrength = weaponStrength;
     this.attackType     = attackType;
     this.damageType     = damageType;
 }
コード例 #2
0
        static void Postfix(Mech attacker, ICombatant target, ref MeleeAttackType __result)
        {
            MeleeAttack selectedAttack = ModState.GetSelectedAttack(attacker);

            if (selectedAttack != null)
            {
                Mod.Log.Info?.Write($"Forcing melee animation to {selectedAttack.AttackAnimation} for " +
                                    $"attacker: {attacker.DistinctId()} vs. target: {target.DistinctId()}");
                __result = selectedAttack.AttackAnimation;
            }
        }
コード例 #3
0
 public static bool OverrideMeleeModifiers(ref float __result, Mech attacker, ICombatant target, Vector3 targetPosition, MeleeAttackType meleeAttackType)
 {
     try {
         AttackType = meleeAttackType;
         Weapon weapon = (meleeAttackType == MeleeAttackType.DFA) ? attacker.DFAWeapon : attacker.MeleeWeapon;
         SaveStates(attacker, target, weapon);
         __result = SumModifiers(MeleeModifiers);
         return(false);
     } catch (Exception ex) {
         return(Error(new ApplicationException("Error in melee modifier '" + thisModifier + "'", ex)));
     }
 }
コード例 #4
0
 public static bool OverrideMeleeToolTips(CombatHUDWeaponSlot __instance, ICombatant target)
 {
     try {
         CombatHUDWeaponSlot slot = __instance;
         bool isDFA = (bool)contemplatingDFA?.Invoke(slot, new object[] { target });
         AttackType = isDFA ? MeleeAttackType.DFA : MeleeAttackType.Punch;
         SaveStates(HUD.SelectedActor, target, slot.DisplayedWeapon);
         SetToolTips(__instance, MeleeModifiers);
         return(false);
     } catch (Exception ex) {
         return(Error(new ApplicationException("Error in melee modifier '" + thisModifier + "'", ex)));
     }
 }
コード例 #5
0
 static void Prefix(MechMeleeSequence __instance)
 {
     try
     {
         Pilot pilot = __instance.owningActor.GetPilot();
         if (pilot.IsJuggernaut() && Fields.JuggernautCharges)
         {
             Logger.Debug("[MechMeleeSequence_BuildMeleeDirectorSequence_PREFIX] Fields.JuggernautCharges: " + Fields.JuggernautCharges);
             MeleeAttackType selectedMeleeType = (MeleeAttackType)AccessTools.Property(typeof(MechMeleeSequence), "selectedMeleeType").GetValue(__instance, null);
             Logger.Info("[MechMeleeSequence_BuildMeleeDirectorSequence_PREFIX] BEFORE selectedMeleeType: " + selectedMeleeType);
             selectedMeleeType = MeleeAttackType.Charge;
             Logger.Info("[MechMeleeSequence_BuildMeleeDirectorSequence_PREFIX] AFTER selectedMeleeType: " + selectedMeleeType);
         }
     }
     catch (Exception e)
     {
         Logger.Error(e);
     }
 }
コード例 #6
0
        // The default method assumes an absractActor exists, and tries to draw a line of fire. We don't have that, so skip it.
        public static void ResolveSourcelessWeaponDamage(this Mech mech, WeaponHitInfo hitInfo, Weapon weapon, MeleeAttackType meleeAttackType)
        {
            AttackDirector.AttackSequence attackSequence = ModState.Combat.AttackDirector.GetAttackSequence(hitInfo.attackSequenceId);
            float damagePerShot          = weapon.DamagePerShot;
            float structureDamagePerShot = weapon.StructureDamagePerShot;

            LineOfFireLevel lineOfFireLevel = LineOfFireLevel.LOFClear;

            damagePerShot          = mech.GetAdjustedDamage(damagePerShot, weapon.WeaponCategoryValue, mech.occupiedDesignMask, lineOfFireLevel, false);
            structureDamagePerShot = mech.GetAdjustedDamage(structureDamagePerShot, weapon.WeaponCategoryValue, mech.occupiedDesignMask, lineOfFireLevel, false);
            foreach (KeyValuePair <int, float> keyValuePair in hitInfo.ConsolidateCriticalHitInfo(mech.GUID, damagePerShot))
            {
                if (keyValuePair.Key != 0 && keyValuePair.Key != 65536 && (mech.ArmorForLocation(keyValuePair.Key) <= 0f || structureDamagePerShot > 0f))
                {
                    ChassisLocations chassisLocationFromArmorLocation = MechStructureRules.GetChassisLocationFromArmorLocation((ArmorLocation)keyValuePair.Key);
                    if (!mech.IsLocationDestroyed(chassisLocationFromArmorLocation))
                    {
                        Traverse checkForCritT = Traverse.Create(mech).Method("CheckForCrit", new Type[] { typeof(WeaponHitInfo), typeof(ChassisLocations), typeof(Weapon) });
                        checkForCritT.GetValue(new object[] { hitInfo, chassisLocationFromArmorLocation, weapon });
                    }
                }
            }
            if (weapon.HeatDamagePerShot > 0f)
            {
                bool flag = false;
                for (int i = 0; i < hitInfo.numberOfShots; i++)
                {
                    if (hitInfo.DidShotHitTarget(mech.GUID, i) && hitInfo.ShotHitLocation(i) != 0 && hitInfo.ShotHitLocation(i) != 65536)
                    {
                        flag = true;
                        mech.AddExternalHeat(string.Format("Heat Damage from {0}", weapon.Description.Name), (int)weapon.HeatDamagePerShotAdjusted(hitInfo.hitQualities[i]));
                    }
                }
                if (flag && attackSequence != null)
                {
                    attackSequence.FlagAttackDidHeatDamage(mech.GUID);
                }
            }
            float num3 = hitInfo.ConsolidateInstability(mech.GUID, weapon.Instability(), mech.Combat.Constants.ResolutionConstants.GlancingBlowDamageMultiplier,
                                                        mech.Combat.Constants.ResolutionConstants.NormalBlowDamageMultiplier, mech.Combat.Constants.ResolutionConstants.SolidBlowDamageMultiplier);

            num3 *= mech.StatCollection.GetValue <float>("ReceivedInstabilityMultiplier");
            num3 *= mech.EntrenchedMultiplier;
            mech.AddAbsoluteInstability(num3, StabilityChangeSource.Attack, hitInfo.attackerId);
        }
コード例 #7
0
        static void Postfix(ToHit __instance, ref float __result, Mech attacker, ICombatant target, Vector3 targetPosition, MeleeAttackType meleeAttackType)
        {
            Mod.Log.Trace?.Write("TH:GAMM entered");

            if (__instance == null)
            {
                return;
            }

            MeleeAttack selectedAttack = ModState.GetSelectedAttack(attacker);

            if (selectedAttack == null)
            {
                return;
            }

            Mod.Log.Debug?.Write("Adding CBTBE modifiers to ToHit");
            int sumMod = 0;

            foreach (KeyValuePair <string, int> kvp in selectedAttack.AttackModifiers)
            {
                string localText = new Text(Mod.LocalizedText.Labels[kvp.Key]).ToString();
                Mod.Log.Debug?.Write($" - Found attack modifier: {localText} = {kvp.Value}, adding to sum modifier");
                sumMod += kvp.Value;
            }

            __result += (float)sumMod;
        }
コード例 #8
0
        public static void CreateImaginaryAttack(Mech attacker, Weapon attackWeapon, ICombatant target, int weaponHitInfoStackItemUID, float[] damageClusters,
                                                 DamageType damageType, MeleeAttackType attackType)
        {
            Mod.Log.Info?.Write($"  Creating imaginary attack for attacker: {attacker.DistinctId()} at position: {attacker?.CurrentPosition} and rot: {attacker?.CurrentRotation}  " +
                                $"vs. target: {target.DistinctId()} at position: {target?.CurrentPosition} and rot: {target?.CurrentRotation}  " +
                                $"using weapon =>  isNull: {attackWeapon == null}  name: {attackWeapon?.Name}  damageType: {damageType}  attackType: {attackType}");

            if (attackWeapon.ammo() == null)
            {
                Mod.Log.Error?.Write($"AMMO is null!");
            }
            if (attackWeapon.mode() == null)
            {
                Mod.Log.Error?.Write($"Mode is null!");
            }
            if (attackWeapon.exDef() == null)
            {
                Mod.Log.Error?.Write($"exDef is null!");
            }

            AttackDirector.AttackSequence attackSequence = target.Combat.AttackDirector.CreateAttackSequence(0, attacker, target,
                                                                                                             attacker.CurrentPosition, attacker.CurrentRotation, 0, new List <Weapon>()
            {
                attackWeapon
            },
                                                                                                             attackType, 0, false
                                                                                                             );

            AttackDirection[] attackDirections = new AttackDirection[damageClusters.Length];
            WeaponHitInfo     hitInfo          = new WeaponHitInfo(0, attackSequence.id, 0, 0, attacker.GUID, target.GUID, 1,
                                                                   null, null, null, null, null, null, null, attackDirections, null, null, null)
            {
                attackerId    = attacker.GUID,
                targetId      = target.GUID,
                numberOfShots = damageClusters.Length,
                stackItemUID  = weaponHitInfoStackItemUID,
                locationRolls = new float[damageClusters.Length],
                hitLocations  = new int[damageClusters.Length],
                hitPositions  = new Vector3[damageClusters.Length],
                hitQualities  = new AttackImpactQuality[damageClusters.Length]
            };

            AttackDirection attackDirection = attacker.Combat.HitLocation.GetAttackDirection(attacker, target);

            Mod.Log.Info?.Write($"  Attack direction is: {attackDirection}");

            int i = 0;

            foreach (int damage in damageClusters)
            {
                // Set hit qualities
                hitInfo.attackDirections[i] = attackDirection;
                hitInfo.hitQualities[i]     = AttackImpactQuality.Solid;
                hitInfo.hitPositions[i]     = attacker.CurrentPosition;

                float adjustedDamage = damage;
                float randomRoll     = (float)Mod.Random.NextDouble();
                if (target is Mech mech)
                {
                    ArmorLocation location =
                        SharedState.Combat.HitLocation.GetHitLocation(attacker.CurrentPosition, mech, randomRoll, ArmorLocation.None, 0f);
                    hitInfo.hitLocations[i] = (int)location;

                    adjustedDamage = mech.GetAdjustedDamageForMelee(damage, attackWeapon.WeaponCategoryValue);
                    Mod.Log.Info?.Write($"  {adjustedDamage} damage to location: {location}");
                    ShowDamageFloatie(mech, location, adjustedDamage, hitInfo.attackerId);
                }
                else if (target is Vehicle vehicle)
                {
                    VehicleChassisLocations location =
                        SharedState.Combat.HitLocation.GetHitLocation(attacker.CurrentPosition, vehicle, randomRoll, VehicleChassisLocations.None, 0f);
                    hitInfo.hitLocations[i] = (int)location;

                    adjustedDamage = vehicle.GetAdjustedDamageForMelee(damage, attackWeapon.WeaponCategoryValue);
                    Mod.Log.Info?.Write($"  {adjustedDamage} damage to location: {location}");
                    ShowDamageFloatie(vehicle, location, adjustedDamage, hitInfo.attackerId);
                }
                else if (target is Turret turret)
                {
                    BuildingLocation location = BuildingLocation.Structure;
                    hitInfo.hitLocations[i] = (int)BuildingLocation.Structure;

                    adjustedDamage = turret.GetAdjustedDamageForMelee(damage, attackWeapon.WeaponCategoryValue);
                    Mod.Log.Info?.Write($"  {adjustedDamage} damage to location: {location}");
                    ShowDamageFloatie(turret, adjustedDamage, hitInfo.attackerId);
                }

                // Make the target take weapon damage
                target.TakeWeaponDamage(hitInfo, hitInfo.hitLocations[i], attackWeapon, adjustedDamage, 0, 0, damageType);

                i++;
            }

            // Cleanup after myself
            target.Combat.AttackDirector.RemoveAttackSequence(attackSequence);
        }
コード例 #9
0
        static public float EvaluateFirepowerReductionFromAttack(AbstractActor attacker, Vector3 attackerPosition, ICombatant target, Vector3 targetPosition, Quaternion targetRotation, List <Weapon> weapons, MeleeAttackType attackType)
        {
            AbstractActor actor = target as AbstractActor;

            if (actor == null)
            {
                return(0.0f);
            }

            DamageExpectationRecord damageExpectationRecord = EvaluateAttack(attacker, attackerPosition, target, targetPosition, targetRotation, weapons, attackType);

            float dmg = 0.0f;
            List <ComponentLocator> weaponList = GetWeaponComponentLocatorList(actor);

            for (int weaponIndex = 0; weaponIndex < weaponList.Count; ++weaponIndex)
            {
                ComponentLocator compLoc  = weaponList[weaponIndex];
                MechComponent    mechComp = compLoc.GetComponent();
                Weapon           w        = mechComp as Weapon;

                if (w.CanFire)
                {
                    float weaponBaseDamage = w.ShotsWhenFired * w.DamagePerShot;
                    if (w.DamageLevel == ComponentDamageLevel.Functional)
                    {
                        int expDmg = Mathf.RoundToInt(damageExpectationRecord.GetComponentDamageForLocation(compLoc));
                        if (expDmg == 1)
                        {
                            // that's like half damage
                            dmg += weaponBaseDamage * 0.5f;
                        }
                        else if (expDmg > 1)
                        {
                            dmg += weaponBaseDamage;
                        }
                    }
                    else if (w.DamageLevel == ComponentDamageLevel.Penalized)
                    {
                        int expDmg = Mathf.RoundToInt(damageExpectationRecord.GetComponentDamageForLocation(compLoc));
                        if (expDmg >= 1)
                        {
                            dmg += weaponBaseDamage;
                        }
                    }
                }
            }
            return(dmg);
        }
コード例 #10
0
        static public DamageExpectationRecord EvaluateAttack(AbstractActor attacker, Vector3 attackerPosition, ICombatant target, Vector3 targetPosition, Quaternion targetRotation, List <Weapon> weapons, MeleeAttackType attackType)
        {
            // for all weapons in an attack

            // figure out the locations that are likely to be hit
            // use HitTable to figure this out

            // for each location, figure out the chance to
            // - do criticals (without breaching armor?)
            // - breach armor
            // - do structural damage
            // - do component damage (weapons get damaged, then destroyed)
            // - trigger ammo explosion
            // - lose the location
            // - lose sub-locations
            // - kill the mech

            // types.cs ConsolidateCriticalHitInfo
            // Mech.cs CheckForCrit
            // CombatCritChance GetCritChance

            DamageExpectationRecord root = new DamageExpectationRecord();

            for (int weaponIndex = 0; weaponIndex < weapons.Count; ++weaponIndex)
            {
                Weapon w = weapons[weaponIndex];

                // figure out chance to hit the target
                AbstractActor targetActor      = target as AbstractActor;
                bool          targetIsEvasive  = (targetActor != null) && (targetActor.IsEvasive);
                float         toHitProbability = w.GetToHitFromPosition(target, 1, attackerPosition, targetPosition, true, targetIsEvasive);

                DamageExpectationRecord weaponDamageExpectationRecord = new DamageExpectationRecord();
                root.AddChildRecord(toHitProbability, weaponDamageExpectationRecord);

                float expectedDamage = w.ShotsWhenFired * w.DamagePerShotFromPosition(attackType, attackerPosition, target);

                Mech     targetMech     = target as Mech;
                Vehicle  targetVehicle  = target as Vehicle;
                Turret   targetTurret   = target as Turret;
                Building targetBuilding = target as Building;
                if (targetMech != null)
                {
                    evaluateWeaponAttackOnMech(expectedDamage, w, ref weaponDamageExpectationRecord, attackerPosition, targetMech, targetPosition, targetRotation);
                }
                else if (targetVehicle != null)
                {
                    evaluateWeaponAttackOnVehicle(expectedDamage, w, ref weaponDamageExpectationRecord, attackerPosition, targetVehicle, targetPosition, targetRotation);
                }
                else if (targetTurret != null)
                {
                    evaluateWeaponAttackOnTurret(expectedDamage, w, ref weaponDamageExpectationRecord, attackerPosition, targetTurret, targetPosition, targetRotation);
                }
                else if (targetBuilding != null)
                {
                    evaluateWeaponAttackOnBuilding(expectedDamage, w, ref weaponDamageExpectationRecord, attackerPosition, targetBuilding, targetPosition, targetRotation);
                }
            }
            consolidateDamageExpectationRecord(ref root, target);

            return(root);
        }
コード例 #11
0
ファイル: Main.cs プロジェクト: mcb5637/BTX_CAC_Compatibility
        private static float CounterNarc(ToHit tohit, AbstractActor attacker, Weapon wep, ICombatant target, Vector3 apos, Vector3 tpos, LineOfFireLevel lof, MeleeAttackType mat, bool calledshot)
        {
            AbstractActor at = target as AbstractActor;

            if (at != null && at.HasIndirectFireImmunity && at.Combat.EffectManager.GetAllEffectsTargetingWithBaseID(at, "StatusEffect-NARC-IncomingAttBonus").Count > 0)
            {
                return(3);
            }
            return(0);
        }
コード例 #12
0
            public static void Postfix(Mech __instance, WeaponHitInfo hitInfo, Weapon weapon, MeleeAttackType meleeAttackType)
            {
                Mod.Log.Trace("M:RWD entered.");

                AttackDirector.AttackSequence attackSequence = __instance.Combat.AttackDirector.GetAttackSequence(hitInfo.attackSequenceId);
                AbstractActor actor = __instance.Combat.FindActorByGUID(hitInfo.targetId);

                if (actor is Mech target)
                {
                    CombatResolutionConstantsDef crcd = __instance.Combat.Constants.ResolutionConstants;
                    float stabilityDamage             = hitInfo.ConsolidateInstability(hitInfo.targetId, weapon.Instability(),
                                                                                       crcd.GlancingBlowDamageMultiplier, crcd.NormalBlowDamageMultiplier, crcd.SolidBlowDamageMultiplier);

                    stabilityDamage *= __instance.StatCollection.GetValue <float>("ReceivedInstabilityMultiplier");
                    stabilityDamage *= __instance.EntrenchedMultiplier;

                    Mod.Log.Debug($" == Checking Piloting Stability");
                    Mod.Log.Debug($"   target:{CombatantHelper.LogLabel(target)} isMech:{(actor is Mech)} IsDead:{target.IsDead} IsUnsteady:{target.IsUnsteady} IsOrWillBeProne:{target.IsOrWillBeProne}");
                    Mod.Log.Debug($"   weapon stability damage:{stabilityDamage}");

                    if (stabilityDamage > 0 && !target.IsDead && target.IsUnsteady && !target.IsOrWillBeProne)
                    {
                        float skillBonus = (float)target.SkillPiloting / __instance.Combat.Constants.PilotingConstants.PilotingDivisor;

                        float skillRoll  = __instance.Combat.NetworkRandom.Float();
                        float skillTotal = skillRoll + skillBonus;

                        Mod.Log.Debug($" Skill check -> bonus: {skillBonus}  roll: {skillRoll}  rollTotal: {skillTotal}  target:{Mod.Config.PilotStabilityCheck}");

                        if (skillTotal < Mod.Config.PilotStabilityCheck)
                        {
                            Mod.Log.Debug(string.Format(" Skill Check Failed! Flagging for Knockdown"));
                            bool showMessage = !target.IsFlaggedForKnockdown;

                            target.FlagForKnockdown();
                            if (Mod.Config.ShowAllStabilityRolls || showMessage)
                            {
                                target.Combat.MessageCenter.PublishMessage(new AddSequenceToStackMessage(new ShowActorInfoSequence(target, $"Stability Check: Failed!", FloatieMessage.MessageNature.Debuff, true)));
                            }
                        }
                        else
                        {
                            Mod.Log.Debug(string.Format(" Skill Check Succeeded!"));
                            if (Mod.Config.ShowAllStabilityRolls)
                            {
                                target.Combat.MessageCenter.PublishMessage(new AddSequenceToStackMessage(new ShowActorInfoSequence(target, $"Stability Check: Passed!", FloatieMessage.MessageNature.Buff, true)));
                            }
                        }
                    }
                    else
                    {
                        Mod.Log.Debug($"  target has no stability damage, is not unsteady, or is dead or prone - skipping");
                    }
                }
            }
コード例 #13
0
    public override void OnInspectorGUI()
    {
//        base.OnInspectorGUI();
        _actionSetting = (EnemyActionSetting)target;

        EditorGUILayout.BeginVertical();

        EditorGUILayout.LabelField("General settings:", EditorStyles.boldLabel);

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Action type:");
        EnemyActionType newType = (EnemyActionType)_enemyActionType.enumValueIndex;

        newType = (EnemyActionType)EditorGUILayout.EnumPopup(newType);
        _enemyActionType.enumValueIndex = (int)newType;
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        _damage.intValue = Mathf.Max(EditorGUILayout.IntField(new GUIContent("Damage:"), _damage.intValue), 5);
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        _rate.floatValue = Mathf.Max(EditorGUILayout.FloatField(new GUIContent("Attack rate:"), _rate.floatValue), 3);
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Max attack angle:");
        _maxAngle.intValue = EditorGUILayout.IntSlider(_maxAngle.intValue, 0, 40);
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Max distance for attack:");
        _maxDistance.intValue = EditorGUILayout.IntSlider(_maxDistance.intValue, 0, 30);
        EditorGUILayout.EndHorizontal();

        if (_actionSetting.actionType == EnemyActionType.DISTANCE)
        {
            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Distance attack settings:", EditorStyles.boldLabel);

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Distance attack type:");
            DistanceAttackType distance = (DistanceAttackType)_distanceAttackType.enumValueIndex;
            distance = (DistanceAttackType)EditorGUILayout.EnumPopup(distance);
            _distanceAttackType.enumValueIndex = (int)distance;
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Attack calculation type:");
            AttackCalculationType calculationType = (AttackCalculationType)_attackCalculationType.enumValueIndex;
            calculationType = (AttackCalculationType)EditorGUILayout.EnumPopup(calculationType);
            _attackCalculationType.enumValueIndex = (int)calculationType;
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PropertyField(_projectilePrefab, new GUIContent("Projectile prefab:"));
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.Slider(_projectileSpeed, 0, 50, new GUIContent("Projectile speed: "));
            EditorGUILayout.EndHorizontal();

            if (_actionSetting.distanceAttackType == DistanceAttackType.TRIPLE)
            {
                EditorGUILayout.Space();
                EditorGUILayout.LabelField("Triple attack settings:", EditorStyles.boldLabel);

                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.Slider(_angleTriple, 0, 30, new GUIContent("Projectile triple angle: "));
                EditorGUILayout.EndHorizontal();
            }
            else if (_actionSetting.distanceAttackType == DistanceAttackType.MACHINE_GUN)
            {
                EditorGUILayout.Space();
                EditorGUILayout.LabelField("Machine gun attack settings:", EditorStyles.boldLabel);

                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("Max offset for attack:");
                _offset.floatValue = EditorGUILayout.FloatField(_offset.floatValue);
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("Rate in milliseconds:");
                _machineGunRate.intValue = EditorGUILayout.IntField(_machineGunRate.intValue);
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("Magazine amount:");
                _magazineAmount.intValue = EditorGUILayout.IntField(_magazineAmount.intValue);
                EditorGUILayout.EndHorizontal();
            }
        }
        else
        {
            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Melee attack settings:", EditorStyles.boldLabel);

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Melee type:");
            MeleeAttackType melee = (MeleeAttackType)_meleeAttackType.enumValueIndex;
            melee = (MeleeAttackType)EditorGUILayout.EnumPopup(melee);
            _meleeAttackType.enumValueIndex = (int)melee;
            EditorGUILayout.EndHorizontal();

            if (_actionSetting.meleeAttackType == MeleeAttackType.EXPLOSION)
            {
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("Time to explosion:");
                _timeToExplode.intValue = EditorGUILayout.IntSlider(_timeToExplode.intValue, 0, 5);
                EditorGUILayout.EndHorizontal();
            }
        }

        EditorGUILayout.EndVertical();
        serializedObject.ApplyModifiedProperties();
    }
コード例 #14
0
        public override void Deserialize( GenericReader reader )
        {
            base.Deserialize( reader );

            int version = reader.ReadInt();

            int test = 0;

            if (version > 57)
            {
                m_Orders = new List<OrderInfo>();
                int orderCount = reader.ReadInt();
                for (int i = 0; i < orderCount; i++)
                {
                    OrderInfo newOrder = new OrderInfo("", 1, 1, this);
                    OrderInfo.Deserialize(reader, newOrder);
                    m_Orders.Add(newOrder);
                }
            }

            if (version > 55)
            {
                m_Deadly = reader.ReadInt();
            }

            if (version > 54)
            {
                m_Nation = (Nation)reader.ReadInt();
                m_Government = (GovernmentEntity)reader.ReadItem();
                m_Organization = (CustomGuildStone)reader.ReadItem();
            }

            if( version > 53 )
                m_AuraType = (AuraType)reader.ReadInt();

            if( version > 52 )
                m_CustomBreathType = (CustomBreathType)reader.ReadInt();

            if( version > 51 )
                m_ManeuverResistance = reader.ReadInt();

            if( version > 50 )
            {
                m_CantInterrupt = reader.ReadBool();
                m_CantParry = reader.ReadBool();
                m_HasNoCorpse = reader.ReadBool();
            }

            if( version > 49 )
            {
                int count = reader.ReadInt();

                for( int i = 0; i < count; i++ )
                    m_SecondaryWikiConfigs.Add( reader.ReadString() );

                count = reader.ReadInt();

                for( int i = 0; i < count; i++ )
                {
                    XMLEventType eventType = (XMLEventType)reader.ReadInt();
                    List<string> list = new List<string>();
                    int codeCount = reader.ReadInt();

                    for( int a = 0; a < codeCount; a++ )
                        list.Add( reader.ReadString() );

                    m_XMLEventsDatabase.Add( eventType, list );
                }
            }

            if( version > 48 )
                m_RangedAttackType = (RangedAttackType)reader.ReadInt();

            if( version > 47 )
                m_CustomSkinnableParts = reader.ReadStrongItemList();

            if( version > 46 )
            {
                m_NoWoundedMovePenalty = reader.ReadBool();
                m_MeleeAttackType = (MeleeAttackType)reader.ReadInt();
            }

            if( version > 45 )
                m_WikiConfig = reader.ReadString();

            if( version > 44 )
            {
                m_Technique = reader.ReadString();
                m_TechniqueLevel = reader.ReadInt();
            }

            if( version > 43 )
                m_StableTicket = reader.ReadItem();

            if( version > 41 )
                m_StabledOwner = reader.ReadMobile();

            if( version > 40 )
                m_ReceivedNewLoot = reader.ReadBool();

            if( version > 39 )
            {
                m_TimeOfDeath = reader.ReadDeltaTime();

                if( reader.ReadBool() )
                    BeginRess( reader.ReadDeltaTime() - DateTime.Now, this.Corpse );

                m_Lives = reader.ReadInt();
            }

            if( version > 38 )
                m_ReleaseTime = reader.ReadDateTime();

            if( version > 37 )
                m_MarkedForTermination = reader.ReadBool();

            if( version > 36 )
            {
                m_FavouriteStance = reader.ReadString();
                m_FavouriteManeuver = reader.ReadString();
            }

            if( version > 34 )
                m_CombatStyles = new CombatStyles( reader );

            if( version > 32 )
                m_Feats = new Feats( reader, true );

            if( version > 33 )
                m_FixedScales = reader.ReadBool();

            if( version > 31 )
            {
                m_NoDeathCondition = reader.ReadBool();
                m_NoDeath = reader.ReadBool();
                m_NoDeathMsg = reader.ReadString();
                m_NoDeathSound = reader.ReadInt();
            }

            if( version > 30 )
                this.Frozen = reader.ReadBool();

            if( version > 27 )
            {
                m_VanishTime = reader.ReadDateTime();
                m_VanishEmote = reader.ReadString();
            }

            m_CreatureGroup = (CreatureGroup)reader.ReadInt();

            if( version < 29 )
            {
                test = reader.ReadInt();
                m_IsSneaky = test > 0;
            }

            else
                m_IsSneaky = reader.ReadBool();

            if( version < 29 )
            {
                test = reader.ReadInt();
                m_TakesLifeOnKill = test > 0;
            }

            else
                m_TakesLifeOnKill = reader.ReadBool();

            m_Description = reader.ReadString();

            m_Intimidated = reader.ReadInt();

            if( version < 29 )
            {
                test = reader.ReadInt();
                m_IsHuntingHound = test > 0;
            }

            else
                m_IsHuntingHound = reader.ReadBool();

            m_XPScale = reader.ReadInt();

            m_StatScale = reader.ReadInt();

            m_SkillScale = reader.ReadInt();

            m_Level = reader.ReadInt();

            m_XP = reader.ReadInt();

            m_NextLevel = reader.ReadInt();

            if( version < 29 )
            {
                test = reader.ReadInt();
                m_Warned = test > 0;
            }

            else
                m_Warned = reader.ReadBool();

            m_WarningTime = reader.ReadDateTime();

            m_BribingTime = reader.ReadDateTime();

            m_EmployerFeatLevel = reader.ReadInt();

            m_TargetsName = reader.ReadString();

            m_Employer = reader.ReadMobile();

            m_HiringTime = reader.ReadDateTime();

            if( version < 29 )
            {
                test = reader.ReadInt();
                m_Bribed = test > 0;
            }

            else
                m_Bribed = reader.ReadBool();

            m_LastSeen = reader.ReadDateTime();

            if( version < 29 )
            {
                test = reader.ReadInt();
                m_CanBeInformant = test > 0;
            }

            else
                m_CanBeInformant = reader.ReadBool();

            m_CurrentAI = (AIType)reader.ReadInt();
            m_DefaultAI = (AIType)reader.ReadInt();

            m_iRangePerception = reader.ReadInt();
            m_iRangeFight = reader.ReadInt();

            m_iTeam = reader.ReadInt();

            m_dActiveSpeed = reader.ReadDouble();
            m_dPassiveSpeed = reader.ReadDouble();
            m_dCurrentSpeed = reader.ReadDouble();

            if ( m_iRangePerception == OldRangePerception )
                m_iRangePerception = DefaultRangePerception;

            m_pHome.X = reader.ReadInt();
            m_pHome.Y = reader.ReadInt();
            m_pHome.Z = reader.ReadInt();

            if ( version >= 1 )
            {
                m_iRangeHome = reader.ReadInt();

                int i, iCount;

                iCount = reader.ReadInt();
                for ( i=0; i< iCount; i++ )
                {
                    string str = reader.ReadString();
                    Type type = Type.GetType( str );

                    if ( type != null )
                    {
                        m_arSpellAttack.Add( type );
                    }
                }

                iCount = reader.ReadInt();
                for ( i=0; i< iCount; i++ )
                {
                    string str = reader.ReadString();
                    Type type = Type.GetType( str );

                    if ( type != null )
                    {
                        m_arSpellDefense.Add( type );
                    }
                }
            }
            else
            {
                m_iRangeHome = 0;
            }

            if ( version >= 2 )
            {
                m_FightMode = ( FightMode )reader.ReadInt();

                m_bControlled = reader.ReadBool();
                m_ControlMaster = reader.ReadMobile();
                m_ControlTarget = reader.ReadMobile();
                m_ControlDest = reader.ReadPoint3D();
                m_ControlOrder = (OrderType) reader.ReadInt();

                m_dMinTameSkill = reader.ReadDouble();

                if ( version < 9 )
                    reader.ReadDouble();

                m_bTamable = reader.ReadBool();
                m_bSummoned = reader.ReadBool();

                if ( m_bSummoned )
                {
                    m_SummonEnd = reader.ReadDeltaTime();
                    new UnsummonTimer( m_ControlMaster, this, m_SummonEnd - DateTime.Now ).Start();
                }

                m_iControlSlots = reader.ReadInt();
            }
            else
            {
                m_FightMode = FightMode.Closest;

                m_bControlled = false;
                m_ControlMaster = null;
                m_ControlTarget = null;
                m_ControlOrder = OrderType.None;
            }

            if ( version >= 3 )
                m_Loyalty = reader.ReadInt();
            else
                m_Loyalty = MaxLoyalty; // Wonderfully Happy

            if ( version >= 4 )
                m_CurrentWayPoint = reader.ReadItem() as WayPoint;

            if ( version >= 5 )
                m_SummonMaster = reader.ReadMobile();

            if ( version >= 6 )
            {
                //m_HitsMax = reader.ReadInt();
                //m_StamMax = reader.ReadInt();
                //m_ManaMax = reader.ReadInt();
                m_DamageMin = reader.ReadInt();
                m_DamageMax = reader.ReadInt();
            }

            if ( version >= 7 )
            {
                m_PhysicalResistance = reader.ReadInt();
                m_PhysicalDamage = reader.ReadInt();

                m_FireResistance = reader.ReadInt();
                m_FireDamage = reader.ReadInt();

                m_ColdResistance = reader.ReadInt();
                m_ColdDamage = reader.ReadInt();

                m_PoisonResistance = reader.ReadInt();
                m_PoisonDamage = reader.ReadInt();

                m_EnergyResistance = reader.ReadInt();
                m_EnergyDamage = reader.ReadInt();
            }

            if ( version >= 8 )
                m_Owners = reader.ReadStrongMobileList();
            else
                m_Owners = new List<Mobile>();

            if ( version >= 10 )
            {
                m_IsDeadPet = reader.ReadBool();
                m_IsBonded = reader.ReadBool();
                m_BondingBegin = reader.ReadDateTime();
                m_OwnerAbandonTime = reader.ReadDateTime();
            }

            if ( version >= 11 )
                m_HasGeneratedLoot = reader.ReadBool();
            else
                m_HasGeneratedLoot = true;

            if ( version >= 12 )
                m_Paragon = reader.ReadBool();
            else
                m_Paragon = false;

            if ( version >= 13 && reader.ReadBool() )
                m_Friends = reader.ReadStrongMobileList();
            else if ( version < 13 && m_ControlOrder >= OrderType.Unfriend )
                ++m_ControlOrder;

            if ( version < 16 )
                Loyalty *= 10;

            double activeSpeed = m_dActiveSpeed;
            double passiveSpeed = m_dPassiveSpeed;

            SpeedInfo.GetSpeeds( this, ref activeSpeed, ref passiveSpeed );

            bool isStandardActive = false;
            for ( int i = 0; !isStandardActive && i < m_StandardActiveSpeeds.Length; ++i )
                isStandardActive = ( m_dActiveSpeed == m_StandardActiveSpeeds[i] );

            bool isStandardPassive = false;
            for ( int i = 0; !isStandardPassive && i < m_StandardPassiveSpeeds.Length; ++i )
                isStandardPassive = ( m_dPassiveSpeed == m_StandardPassiveSpeeds[i] );

            if ( isStandardActive && m_dCurrentSpeed == m_dActiveSpeed )
                m_dCurrentSpeed = activeSpeed;
            else if ( isStandardPassive && m_dCurrentSpeed == m_dPassiveSpeed )
                m_dCurrentSpeed = passiveSpeed;

            if ( isStandardActive && !m_Paragon )
                m_dActiveSpeed = activeSpeed;

            if ( isStandardPassive && !m_Paragon )
                m_dPassiveSpeed = passiveSpeed;

            if ( version >= 14 )
            {
                m_RemoveIfUntamed = reader.ReadBool();
                m_RemoveStep = reader.ReadInt();
            }

            if( version <= 14 && m_Paragon && Hue == 0x31 )
            {
                Hue = Paragon.Hue; //Paragon hue fixed, should now be 0x501.
            }

            m_BluntResistance = reader.ReadInt();
            m_BluntDamage = reader.ReadInt();
            m_SlashingResistance = reader.ReadInt();
            m_SlashingDamage = reader.ReadInt();
            m_PiercingResistance = reader.ReadInt();
            m_PiercingDamage = reader.ReadInt();

            CheckStatTimers();

            Timer.DelayCall( TimeSpan.FromSeconds( 5 ), new TimerCallback( WaitToChangeAI ) );

            AddFollowers();

            if ( IsAnimatedDead )
                Spells.Necromancy.AnimateDeadSpell.Register( m_SummonMaster, this );

            if( this.Level < 1 )
                this.Level = 1;

            if( this.Blessed && this.Alive )
                this.CanBeInformant = true;

            m_Intimidated = 0;

            if( !( this is Mercenary ) && version < 34 && this.Level > 1 )
            {
                int bonus = this.Level / 2;
                int rest = this.Level % 2;

                this.DamageMax += bonus + rest;
                this.DamageMin += bonus;
            }

            LevelSystem.FixStatsAndSkills( this );

            m_Deserialized = true;
        }
コード例 #15
0
        public static float GetRangeModifier(ToHit instance, AbstractActor attacker, Weapon weapon, ICombatant target, Vector3 attackPosition, Vector3 targetPosition, LineOfFireLevel lofLevel, MeleeAttackType meleeAttackType, bool isCalledShot)
        {
            if (attacker.EncounterTags.ContainsAny(Core.Settings._C3NetworkEncounterTags) == false)
            {
                return(ToHitModifiersHelper.GetRangeModifier(instance, attacker, weapon, target, attackPosition, targetPosition, lofLevel, meleeAttackType, isCalledShot));
            }
            float   realDist           = Vector3.Distance(attackPosition, targetPosition);
            float   distance           = realDist;
            float   distMod            = 0f;
            float   minRange           = weapon.MinRange;
            float   shortRange         = weapon.ShortRange;
            float   medRange           = weapon.MediumRange;
            float   longRange          = weapon.LongRange;
            float   maxRange           = weapon.MaxRange;
            Vector3 alternateAttackPos = GetC3CachedPos(attacker, target);

            if (alternateAttackPos != Vector3.zero)
            {
                float alternateDist = Vector3.Distance(alternateAttackPos, targetPosition);
                if (alternateDist < realDist)
                {
                    if (alternateDist < minRange)
                    {
                        distance = minRange;
                    }
                    else
                    {
                        distance = alternateDist;
                    }
                }
            }
            if (distance < minRange)
            {
                distMod = weapon.parent.MinRangeAccMod();
                //Log.LogWrite(" minRange ");
            }
            else
            if (distance < shortRange)
            {
                distMod = weapon.parent.ShortRangeAccMod();
                //Log.LogWrite(" shortRange ");
            }
            else
            if (distance < medRange)
            {
                distMod = weapon.parent.MediumRangeAccMod();
                //Log.LogWrite(" medRange ");
            }
            else
            if (distance < longRange)
            {
                distMod = weapon.parent.LongRangeRangeAccMod();
                //Log.LogWrite(" longRange ");
            }
            else
            if (distance < maxRange)
            {
                distMod = weapon.parent.ExtraLongRangeAccMod();
                //Log.LogWrite(" extraRange ");
            }
            ;
            //return distMod;
            return(distMod + instance.GetRangeModifierForDist(weapon, distance));
        }
コード例 #16
0
        public static string GetRangeModifierName(ToHit instance, AbstractActor attacker, Weapon w, ICombatant target, Vector3 attackPosition, Vector3 targetPosition, LineOfFireLevel lofLevel, MeleeAttackType meleeAttackType, bool isCalledShot, int modifier)
        {
            if (attacker.EncounterTags.ContainsAny(Core.Settings._C3NetworkEncounterTags) == false)
            {
                if (modifier == 0)
                {
                    return(string.Empty);
                }
                return(ToHitModifiersHelper.GetRangeModifierName(instance, attacker, w, target, attackPosition, targetPosition, lofLevel, meleeAttackType, isCalledShot));
            }
            float   real_range         = Vector3.Distance(attackPosition, targetPosition);
            float   range              = real_range;
            float   MinRange           = w.MinRange;
            float   ShortRange         = w.ShortRange;
            float   MediumRange        = w.MediumRange;
            float   LongRange          = w.LongRange;
            float   MaxRange           = w.MaxRange;
            string  c3_prefix          = string.Empty;
            Vector3 alternateAttackPos = GetC3CachedPos(attacker, target);

            if (alternateAttackPos != Vector3.zero)
            {
                float alternateDist = Vector3.Distance(alternateAttackPos, targetPosition);
                //Log.Debug?.TWL(0, "GetRangeModifierName "+attacker.PilotableActorDef.ChassisID+" weapon:"+w.defId+" target:"+target.PilotableActorDef.ChassisID+" real_dist:"+ real_range+" alt dist:"+ alternateDist+" max range:"+MaxRange+" modifier:"+modifier);
                if ((alternateDist < real_range) && (alternateDist < MaxRange))
                {
                    c3_prefix = "(C3)";
                    if (alternateDist < MinRange)
                    {
                        range = MinRange;
                    }
                    else
                    {
                        range = alternateDist;
                    }
                }
            }
            if (string.IsNullOrEmpty(c3_prefix))
            {
                if (modifier == 0)
                {
                    return(string.Empty);
                }
            }
            if (range < MinRange)
            {
                return(c3_prefix + "__/AIM.MIN_RANGE/__ (<" + MinRange + "m)");
            }
            if (range < ShortRange)
            {
                return(c3_prefix + "__/AIM.SHORT_RANGE/__" + SmartRange(MinRange, range, ShortRange));
            }
            if (range < MediumRange)
            {
                return(c3_prefix + "__/AIM.MED_RANGE/__" + SmartRange(ShortRange, range, MediumRange));
            }
            if (range < LongRange)
            {
                return(c3_prefix + "__/AIM.LONG_RANGE/__" + SmartRange(MediumRange, range, LongRange));
            }
            if (range < MaxRange)
            {
                return(c3_prefix + "__/AIM.MAX_RANGE/__" + SmartRange(LongRange, range, MaxRange));
            }
            return(c3_prefix + "__/AIM.OUT_OF_RANGE/__ (>" + MaxRange + "m)");
        }
コード例 #17
0
 public static float GetToHitFromPosition(Weapon weapon, AttackDetails details, MeleeAttackType meleeAttackType)
 {
     return(SharedState.Combat.ToHit.GetToHitChance(attacker: details.Attacker, weapon: weapon, target: details.Target,
                                                    attackPosition: details.AttackPosition, targetPosition: details.TargetPosition,
                                                    numTargets: 1, meleeAttackType: meleeAttackType, isMoraleAttack: false));
 }
コード例 #18
0
        private static void Postfix(Mech __instance, WeaponHitInfo hitInfo, Weapon weapon, MeleeAttackType meleeAttackType)
        {
            AttackDirector.AttackSequence attackSequence = __instance.Combat.AttackDirector.GetAttackSequence(hitInfo.attackSequenceId);
            AbstractActor actor = __instance.Combat.FindActorByGUID(hitInfo.targetId);

            if (actor is Mech)
            {
                Mech target = actor as Mech;

                float stabilityDamage = hitInfo.ConsolidateInstability(weapon.Instability(), __instance.Combat.Constants.ResolutionConstants.GlancingBlowDamageMultiplier, __instance.Combat.Constants.ResolutionConstants.NormalBlowDamageMultiplier, __instance.Combat.Constants.ResolutionConstants.SolidBlowDamageMultiplier);
                stabilityDamage *= __instance.StatCollection.GetValue <float>("ReceivedInstabilityMultiplier");
                stabilityDamage *= __instance.EntrenchedMultiplier;

                if (AttackDirector.attackLogger.IsLogEnabled)
                {
                    AttackDirector.attackLogger.Log("[CBTPiloting] Checking Piloting Stability");
                    AttackDirector.attackLogger.Log(string.Format("[CBTPiloting] Is Mech: {0}", (actor is Mech)));
                    AttackDirector.attackLogger.Log(string.Format("[CBTPiloting] Weapon Stab Dmg: {0}", stabilityDamage));
                    AttackDirector.attackLogger.Log(string.Format("[CBTPiloting] Target Dead: {0}", target.IsDead));
                    AttackDirector.attackLogger.Log(string.Format("[CBTPiloting] Target Unsteady: {0}", target.IsUnsteady));
                    AttackDirector.attackLogger.Log(string.Format("[CBTPiloting] Target IsOrWillBeProne: {0}", target.IsOrWillBeProne));
                }

                if (stabilityDamage > 0 && !target.IsDead && target.IsUnsteady && !target.IsOrWillBeProne)
                {
                    float skillBonus = (float)target.SkillPiloting / __instance.Combat.Constants.PilotingConstants.PilotingDivisor;

                    float skillRoll  = __instance.Combat.NetworkRandom.Float();
                    float skillTotal = skillRoll + skillBonus;

                    if (AttackDirector.attackLogger.IsLogEnabled)
                    {
                        AttackDirector.attackLogger.Log(string.Format("[CBTPiloting] Skill Bonus: {0}", skillBonus));
                        AttackDirector.attackLogger.Log(string.Format("[CBTPiloting] Skill Roll: {0}", skillRoll));
                        AttackDirector.attackLogger.Log(string.Format("[CBTPiloting] Skill Roll Total: {0}", skillTotal));
                        AttackDirector.attackLogger.Log(string.Format("[CBTPiloting] Skill Target: {0}", CBTPiloting.Settings.PilotStabilityCheck));
                    }

                    if (skillTotal < CBTPiloting.Settings.PilotStabilityCheck)
                    {
                        if (AttackDirector.attackLogger.IsLogEnabled)
                        {
                            AttackDirector.attackLogger.Log(string.Format("[CBTPiloting] Skill Check Failed! Flagging for Knockdown"));
                        }

                        target.FlagForKnockdown();
                        target.Combat.MessageCenter.PublishMessage(new AddSequenceToStackMessage(new ShowActorInfoSequence(target, $"Stability Check: Failed!", FloatieMessage.MessageNature.Debuff, true)));
                    }
                    else
                    {
                        if (AttackDirector.attackLogger.IsLogEnabled)
                        {
                            AttackDirector.attackLogger.Log(string.Format("[CBTPiloting] Skill Check Succeeded!"));
                        }

                        target.Combat.MessageCenter.PublishMessage(new AddSequenceToStackMessage(new ShowActorInfoSequence(target, $"Stability Check: Passed!", FloatieMessage.MessageNature.Buff, true)));
                    }
                }
            }
        }
コード例 #19
0
            public static void Postfix(Mech __instance, WeaponHitInfo hitInfo, Weapon weapon, MeleeAttackType meleeAttackType)
            {
                Mod.Log.Trace("M:RWD entered.");

                AttackDirector.AttackSequence attackSequence = __instance.Combat.AttackDirector.GetAttackSequence(hitInfo.attackSequenceId);
                AbstractActor target = __instance.Combat.FindActorByGUID(hitInfo.targetId);

                if (target is Mech targetMech)
                {
                    // Feature: Piloting Skill Check from instability
                    // TODO: Let instability represent this?
                    CombatResolutionConstantsDef crcd = target.Combat.Constants.ResolutionConstants;
                    float stabilityDamage             = hitInfo.ConsolidateInstability(hitInfo.targetId, weapon.Instability(),
                                                                                       crcd.GlancingBlowDamageMultiplier, crcd.NormalBlowDamageMultiplier, crcd.SolidBlowDamageMultiplier);
                    stabilityDamage *= __instance.StatCollection.GetValue <float>("ReceivedInstabilityMultiplier");
                    stabilityDamage *= __instance.EntrenchedMultiplier;
                    MechHelper.PilotCheckOnInstabilityDamage(targetMech, stabilityDamage);
                }
            }