Esempio n. 1
0
        protected override void Apply(AttributeLoader loader, object wrapperObj)
        {
            if (!(wrapperObj is FactionAttributesWrapper w))
            {
                throw new System.InvalidCastException();
            }

            loader.ApplyPPatch(FactionName, () => w.FactionName);
            loader.ApplyPPatch(ID, () => w.ID);
            loader.ApplyPPatch(VOName, () => w.VOName);
            loader.ApplyPPatch(VOAssetBundle, () => w.VOAssetBundle);
            loader.ApplyPPatch(MusicTrigger, () => w.MusicTrigger);
            loader.ApplyPPatch(ScaleWithDynamicDifficulty, () => w.ScaleWithDynamicDifficulty);

            if (TechTree != null)
            {
                using (loader.logger.BeginScope($"TechTree:"))
                {
                    var w2 = new TechTreeAttributesWrapper(w.TechTree);
                    TechTree.Apply(loader, w2, null);
                    w.TechTree = w2;
                }
            }

            if (GlobalBuffs != null)
            {
                var l = w.GlobalBuffs?.Select(x => new UnitTypeBuffWrapper(x)).ToList() ?? new List <UnitTypeBuffWrapper>();
                loader.ApplyLPatch(GlobalBuffs, l, () => new UnitTypeBuffWrapper(), nameof(UnitTypeBuff));
                w.GlobalBuffs = l.Where(x => x != null).ToArray();
            }
        }
Esempio n. 2
0
        protected override void Apply(AttributeLoader loader, object wrapperObj)
        {
            if (!(wrapperObj is ProjectileAttributesWrapper wrapper))
            {
                throw new System.InvalidCastException();
            }

            loader.ApplyPPatch(DetonationDelay, () => wrapper.DetonationDelay, Fixed64.UnsafeFromDouble);
            loader.ApplyPMultPatch(DetonationDelayMult, () => wrapper.DetonationDelay);

            loader.ApplyPPatch(MissStageIndex, () => wrapper.MissStageIndex);
            loader.ApplyPMultPatch(MissStageIndexMult, () => wrapper.MissStageIndex);

            loader.ApplyPPatch(MinimumMissDistance, () => wrapper.MinimumMissDistance, Fixed64.UnsafeFromDouble);
            loader.ApplyPMultPatch(MinimumMissDistanceMult, () => wrapper.MinimumMissDistance);

            loader.ApplyPPatch(MaximumMissDistance, () => wrapper.MaximumMissDistance, Fixed64.UnsafeFromDouble);
            loader.ApplyPMultPatch(MaximumMissDistanceMult, () => wrapper.MaximumMissDistance);

            loader.ApplyPPatch(ProjectileType, () => wrapper.ProjectileType);

            if (Stages.Count > 0)
            {
                var l = wrapper.Stages?.Select(x => new ProjectileMotionStageWrapper(x)).ToList() ?? new List <ProjectileMotionStageWrapper>();
                loader.ApplyLPatch(Stages, l, () => new ProjectileMotionStageWrapper(), nameof(ProjectileMotionStage));
                wrapper.Stages = l.ToArray();
            }
        }
        protected override void Apply(AttributeLoader loader, object wrapperObj)
        {
            if (!(wrapperObj is PowerSystemAttributesWrapper wrapper))
            {
                throw new System.InvalidCastException();
            }

            loader.ApplyPPatch(StartingPowerLevelIndex, () => wrapper.StartingPowerLevelIndex);
            loader.ApplyPMultPatch(StartingPowerLevelIndexMult, () => wrapper.StartingPowerLevelIndex);

            loader.ApplyPPatch(StartingMaxPowerLevelIndex, () => wrapper.StartingMaxPowerLevelIndex);
            loader.ApplyPMultPatch(StartingMaxPowerLevelIndexMult, () => wrapper.StartingMaxPowerLevelIndex);

            loader.ApplyPPatch(PowerSystemType, () => wrapper.PowerSystemType);

            {
                var l = wrapper.PowerLevels?.Select(x => new PowerLevelAttributesWrapper(x)).ToList() ?? new List <PowerLevelAttributesWrapper>();
                loader.ApplyLPatch(PowerLevels, l, () => new PowerLevelAttributesWrapper(), "PowerLevels");
                wrapper.PowerLevels = l.ToArray();
            }

            if (View != null)
            {
                PowerSystemViewAttributesWrapper powerSystemViewAttributesWrapper = new PowerSystemViewAttributesWrapper(wrapper.View);
                View.Apply(loader, powerSystemViewAttributesWrapper, null);
                wrapper.View = powerSystemViewAttributesWrapper;
            }
        }
Esempio n. 4
0
        protected override void Apply(AttributeLoader loader, object wrapperObj)
        {
            if (!(wrapperObj is HarvesterAttributesWrapper w))
            {
                throw new System.InvalidCastException();
            }

            loader.ApplyPPatch(SalvageDistance, () => w.SalvageDistance, Fixed64.UnsafeFromDouble);
            loader.ApplyPMultPatch(SalvageDistanceMult, () => w.SalvageDistance);

            loader.ApplyPPatch(MaxDropOffRange, () => w.MaxDropOffRange, Fixed64.UnsafeFromDouble);
            loader.ApplyPMultPatch(MaxDropOffRangeMult, () => w.MaxDropOffRange);

            loader.ApplyPPatch(ClosestResourceControllerHysteresisDistance, () => w.ClosestResourceControllerHysteresisDistance, Fixed64.UnsafeFromDouble);
            loader.ApplyPMultPatch(ClosestResourceControllerHysteresisDistanceMult, () => w.ClosestResourceControllerHysteresisDistance);

            loader.ApplyPPatch(AutoReturnToDepositOnArtifactPickup, () => w.AutoReturnToDepositOnArtifactPickup);

            if (SalvageCycles != null)
            {
                var l = w.SalvageCycles?.Select(x => new SalvageCycleWrapper(x)).ToList() ?? new List <SalvageCycleWrapper>();
                loader.ApplyLPatch(SalvageCycles, l, () => new SalvageCycleWrapper(), nameof(SalvageCycle));
                w.SalvageCycles = l.ToArray();
            }
        }
Esempio n. 5
0
        protected override void Apply(AttributeLoader loader, object wrapperObj)
        {
            if (!(wrapperObj is ResearchItemAttributesWrapper wrapper))
            {
                throw new System.InvalidCastException();
            }

            loader.ApplyPPatch(Resource1Cost, () => wrapper.Resource1Cost);
            loader.ApplyPMultPatch(Resource1CostMult, () => wrapper.Resource1Cost);

            loader.ApplyPPatch(Resource2Cost, () => wrapper.Resource2Cost);
            loader.ApplyPMultPatch(Resource2CostMult, () => wrapper.Resource2Cost);

            loader.ApplyPPatch(ResearchTime, () => wrapper.ResearchTime, Fixed64.UnsafeFromDouble);
            loader.ApplyPMultPatch(ResearchTimeMult, () => wrapper.ResearchTime);

            loader.ApplyPPatch(TypeOfResearch, () => wrapper.TypeOfResearch);
            loader.ApplyPPatch(IconSpriteName, () => wrapper.IconSpriteName);
            loader.ApplyPPatch(LocalizedResearchTitleStringID, () => wrapper.LocalizedResearchTitleStringID);
            loader.ApplyPPatch(LocalizedShortDescriptionStringID, () => wrapper.LocalizedShortDescriptionStringID);
            loader.ApplyPPatch(LocalizedLongDescriptionStringID, () => wrapper.LocalizedLongDescriptionStringID);
            loader.ApplyPPatch(Dependencies, () => wrapper.Dependencies);
            loader.ApplyPPatch(ResearchVOCode, () => wrapper.ResearchVOCode);

            if (UnitTypeBuffs != null)
            {
                var l = wrapper.UnitTypeBuffs?.Select(x => new UnitTypeBuffWrapper(x)).ToList() ?? new List <UnitTypeBuffWrapper>();
                loader.ApplyLPatch(UnitTypeBuffs, l, () => new UnitTypeBuffWrapper(), nameof(UnitTypeBuff));
                wrapper.UnitTypeBuffs = l.Where(x => x != null).ToArray();
            }
        }
        protected override void Apply(AttributeLoader loader, object wrapperObj)
        {
            if (!(wrapperObj is PowerShuntAttributesWrapper wrapper))
            {
                throw new System.InvalidCastException();
            }

            loader.ApplyPPatch(PowerLevelChargeTimeSeconds, () => wrapper.PowerLevelChargeTimeSeconds, Fixed64.UnsafeFromDouble);
            loader.ApplyPMultPatch(PowerLevelChargeTimeSecondsMult, () => wrapper.PowerLevelChargeTimeSeconds);

            loader.ApplyPPatch(PowerLevelDrainTimeSeconds, () => wrapper.PowerLevelDrainTimeSeconds, Fixed64.UnsafeFromDouble);
            loader.ApplyPMultPatch(PowerLevelDrainTimeSecondsMult, () => wrapper.PowerLevelDrainTimeSeconds);

            loader.ApplyPPatch(HeatThreshold, () => wrapper.HeatThreshold);
            loader.ApplyPMultPatch(HeatThresholdMult, () => wrapper.HeatThreshold);

            loader.ApplyPPatch(CooldownRate, () => wrapper.CooldownRate);
            loader.ApplyPMultPatch(CooldownRateMult, () => wrapper.CooldownRate);

            loader.ApplyPPatch(OverheatDamage, () => wrapper.OverheatDamage);
            loader.ApplyPMultPatch(OverheatDamageMult, () => wrapper.OverheatDamage);

            loader.ApplyPPatch(NearOverheatWarningMargin, () => wrapper.NearOverheatWarningMargin);
            loader.ApplyPMultPatch(NearOverheatWarningMarginMult, () => wrapper.NearOverheatWarningMargin);

            loader.ApplyPPatch(OverheatReminderPeriod, () => wrapper.OverheatReminderPeriod);
            loader.ApplyPMultPatch(OverheatReminderPeriodMult, () => wrapper.OverheatReminderPeriod);

            {
                var l = wrapper.PowerSystems?.Select(x => new PowerSystemAttributesWrapper(x)).ToList() ?? new List <PowerSystemAttributesWrapper>();
                loader.ApplyLPatch(PowerSystems, l, () => new PowerSystemAttributesWrapper(), "PowerSystems");
                wrapper.PowerSystems = l.ToArray();
            }

            if (ReservePowerPool != null)
            {
                InventoryAttributesWrapper inventoryAttributesWrapper = new InventoryAttributesWrapper(wrapper.ReservePowerPool);
                ReservePowerPool.Apply(loader, inventoryAttributesWrapper, null);
                wrapper.ReservePowerPool = inventoryAttributesWrapper;
            }
            if (OverheatingPool != null)
            {
                InventoryAttributesWrapper inventoryAttributesWrapper = new InventoryAttributesWrapper(wrapper.OverheatingPool);
                OverheatingPool.Apply(loader, inventoryAttributesWrapper, null);
                wrapper.OverheatingPool = inventoryAttributesWrapper;
            }
            if (HeatSystem != null)
            {
                InventoryAttributesWrapper inventoryAttributesWrapper = new InventoryAttributesWrapper(wrapper.HeatSystem);
                HeatSystem.Apply(loader, inventoryAttributesWrapper, null);
                wrapper.HeatSystem = inventoryAttributesWrapper;
            }
            if (View != null)
            {
                PowerShuntViewAttributesWrapper powerShuntViewAttributesWrapper = new PowerShuntViewAttributesWrapper(wrapper.View);
                View.Apply(loader, powerShuntViewAttributesWrapper, null);
                wrapper.View = powerShuntViewAttributesWrapper;
            }
        }
Esempio n. 7
0
        protected override void Apply(AttributeLoader loader, object wrapperObj)
        {
            if (!(wrapperObj is ExperienceAttributesWrapper w))
            {
                throw new System.InvalidCastException();
            }

            {
                var l = w.Levels?.Select(x => new ExperienceLevelAttributesWrapper(x)).ToList() ?? new List <ExperienceLevelAttributesWrapper>();
                loader.ApplyLPatch(Levels, l, () => new ExperienceLevelAttributesWrapper(), nameof(ExperienceLevelAttributes));
                w.Levels = l.ToArray();
            }
        }
Esempio n. 8
0
        protected override void Apply(AttributeLoader loader, object wrapperObj)
        {
            if (!(wrapperObj is TechTreeAttributesWrapper w))
            {
                throw new System.InvalidCastException();
            }

            if (TechTrees != null)
            {
                var l = w.TechTrees?.Select(x => new TechTreeWrapper(x)).ToList() ?? new List <TechTreeWrapper>();
                loader.ApplyLPatch(TechTrees, l, () => new TechTreeWrapper(), nameof(TechTree));
                w.TechTrees = l.ToArray();
            }
        }
Esempio n. 9
0
        protected override void Apply(AttributeLoader loader, object wrapperObj)
        {
            if (!(wrapperObj is TechTreeWrapper w))
            {
                throw new System.InvalidCastException();
            }

            if (Tiers != null)
            {
                var l = w.Tiers?.Select(x => new TechTreeTierWrapper(x)).ToList() ?? new List <TechTreeTierWrapper>();
                loader.ApplyLPatch(Tiers, l, () => new TechTreeTierWrapper(), nameof(TechTreeTier));
                w.Tiers = l.ToArray();
            }

            if (Upgrades != null)
            {
                var l = w.Upgrades?.Select(x => new TechUpgradeWrapper(x)).ToList() ?? new List <TechUpgradeWrapper>();
                loader.ApplyLPatch(Upgrades, l, () => new TechUpgradeWrapper(), nameof(TechUpgrade));
                w.Upgrades = l.ToArray();
            }

            loader.ApplyPPatch(TechTreeName, () => w.TechTreeName);
            loader.ApplyPPatch(IconSpriteName, () => w.IconSpriteName);
        }
Esempio n. 10
0
        protected override void Apply(AttributeLoader loader, object wrapperObjj)
        {
            if (!(wrapperObjj is RelicAttributesWrapper wrapper))
            {
                throw new System.InvalidCastException();
            }

            loader.ApplyPPatch(CollectibleType, () => wrapper.CollectibleType);
            loader.ApplyPPatch(DetonationWeaponTypeID, () => wrapper.DetonationWeaponTypeID);

            {
                var l = new AttributeBuffSetWrapper(wrapper.BuffsWhileHolding);
                loader.ApplyLPatch(BuffsWhileHolding, l.Buffs, () => new AttributeBuffWrapper(), nameof(AttributeBuff));
                wrapper.BuffsWhileHolding = l;
            }
        }
Esempio n. 11
0
        protected override void Apply(AttributeLoader loader, object wrapperObj)
        {
            if (!(wrapperObj is ExperienceLevelAttributesWrapper w))
            {
                throw new System.InvalidCastException();
            }

            loader.ApplyPPatch(RequiredExperience, () => w.RequiredExperience);
            loader.ApplyPMultPatch(RequiredExperienceMult, () => w.RequiredExperience);

            loader.ApplyPPatch(BuffTooltipLocID, () => w.BuffTooltipLocID);

            {
                var l = new AttributeBuffSetWrapper(w.Buff);
                loader.ApplyLPatch(Buff, l.Buffs, () => new AttributeBuffWrapper(), nameof(AttributeBuff));
                w.Buff = l;
            }
        }
Esempio n. 12
0
        protected override void Apply(AttributeLoader loader, object wrapperObj)
        {
            if (!(wrapperObj is UnitTypeBuffWrapper wrapper))
            {
                throw new System.InvalidCastException();
            }

            loader.ApplyPPatch(UnitType, () => wrapper.UnitType);
            loader.ApplyPPatch(UseAsPrefix, () => wrapper.UseAsPrefix);
            loader.ApplyPPatch(UnitClass, () => wrapper.UnitClass);
            loader.ApplyPPatch(ClassOperator, () => wrapper.ClassOperator);

            if (BuffSet != null)
            {
                var l = wrapper.BuffSet != null ? new AttributeBuffSetWrapper(wrapper.BuffSet) : new AttributeBuffSetWrapper();
                loader.ApplyLPatch(BuffSet, l.Buffs, () => new AttributeBuffWrapper(), nameof(AttributeBuffSet));
                wrapper.BuffSet = l;
            }
        }
        protected override void Apply(AttributeLoader loader, object wrapperbj)
        {
            if (!(wrapperbj is StatusEffectAttributesWrapper w))
            {
                throw new System.InvalidCastException();
            }

            loader.ApplyPPatch(Duration, () => w.Duration, Fixed64.UnsafeFromDouble);
            loader.ApplyPMultPatch(DurationMult, () => w.Duration);

            loader.ApplyPPatch(MaxStacks, () => w.MaxStacks);
            loader.ApplyPMultPatch(MaxStacksMult, () => w.MaxStacks);

            loader.ApplyPPatch(Lifetime, () => w.Lifetime);
            loader.ApplyPPatch(WeaponFireTriggerEndEvent, () => w.WeaponFireTriggerEndEvent);
            loader.ApplyPPatch(StackingBehaviour, () => w.StackingBehaviour);

            if (BuffsToApplyToTarget != null)
            {
                var l = w.BuffsToApplyToTarget?.Select(x => new UnitTypeBuffWrapper(x)).ToList() ?? new List <UnitTypeBuffWrapper>();
                loader.ApplyLPatch(BuffsToApplyToTarget, l, () => new UnitTypeBuffWrapper(), "BuffsToApplyToTarget");
                w.BuffsToApplyToTarget = l.ToArray();
            }

            if (UnitTypeBuffsToApply != null)
            {
                var l = w.UnitTypeBuffsToApply?.Select(x => new UnitTypeBuffWrapper(x)).ToList() ?? new List <UnitTypeBuffWrapper>();
                loader.ApplyLPatch(UnitTypeBuffsToApply, l, () => new UnitTypeBuffWrapper(), "UnitTypeBuffsToApply");
                w.UnitTypeBuffsToApply = l.ToArray();
            }

            if (Modifiers != null)
            {
                var wrapperModifiers = w.Modifiers?.ToList() ?? new List <ModifierAttributes>();

                var parsed = new Dictionary <int, ModifierAttributesPatch>();

                foreach (var kvp in Modifiers)
                {
                    if (!int.TryParse(kvp.Key, out var index))
                    {
                        loader.logger.Log($"ERROR: Non-integer key: {kvp.Key}");
                        break;
                    }

                    parsed[index] = kvp.Value;
                }

                var toRemove = new Stack <int>();

                foreach (var kvp in parsed.OrderBy(p => p.Key))
                {
                    var index        = kvp.Key;
                    var elementPatch = kvp.Value;

                    using (loader.logger.BeginScope($"Modifiers: {index}"))
                    {
                        var remove = elementPatch.Remove;

                        ModifierAttributes newValue;

                        if (index < wrapperModifiers.Count())
                        {
                            if (remove)
                            {
                                loader.logger.Log("(removed)");
                                toRemove.Push(index);
                                continue;
                            }

                            newValue = wrapperModifiers[index];
                        }
                        else if (index >= wrapperModifiers.Count())
                        {
                            if (remove)
                            {
                                loader.logger.Log("WARNING: Remove flag set for non-existent entry");
                                continue;
                            }

                            loader.logger.BeginScope("(created)").Dispose();

                            newValue = new ModifierAttributes();
                        }
                        else                         // if (index > wrapperModifiers.Count)
                        {
                            loader.logger.Log("ERROR: Non-consecutive index");
                            continue;
                        }

                        loader.ApplyPRefPatch(elementPatch.ModifierType, ref newValue.ModifierType, "ModifierType");
                        loader.ApplyPRefPatch(elementPatch.EnableWeapon_WeaponID, ref newValue.EnableWeaponAttributes.WeaponID, "EnableWeapon_WeaponID");
                        loader.ApplyPRefPatch(elementPatch.SwapFromWeaponID, ref newValue.SwapWeaponAttributes.SwapFromWeaponID, "SwapFromWeaponID");
                        loader.ApplyPRefPatch(elementPatch.SwapToWeaponID, ref newValue.SwapWeaponAttributes.SwapToWeaponID, "SwapToWeaponID");

                        if (elementPatch.HealthOverTimeAttributes != null)
                        {
                            using (loader.logger.BeginScope("HealthOverTimeAttributes:"))
                            {
                                loader.ApplyPRefPatch(elementPatch.HealthOverTimeAttributes.ID, ref newValue.HealthOverTimeAttributes.ID, "ID");
                                loader.ApplyPRefPatch(elementPatch.HealthOverTimeAttributes.Amount, ref newValue.HealthOverTimeAttributes.Amount, "Amount");
                                loader.ApplyPRefPatch(elementPatch.HealthOverTimeAttributes.MSTickDuration, ref newValue.HealthOverTimeAttributes.MSTickDuration, "MSTickDuration");
                                loader.ApplyPRefPatch(elementPatch.HealthOverTimeAttributes.DamageType, ref newValue.HealthOverTimeAttributes.DamageType, "DamageType");
                            }
                        }

                        if (index < wrapperModifiers.Count)
                        {
                            wrapperModifiers[index] = newValue;
                        }
                        else
                        {
                            wrapperModifiers.Add(newValue);
                        }
                    }
                }

                foreach (var v in toRemove)
                {
                    wrapperModifiers.RemoveAt(v);
                }

                w.Modifiers = wrapperModifiers.ToArray();
            }
        }
Esempio n. 14
0
        protected override void Apply(AttributeLoader loader, object wrapperObj)
        {
            if (!(wrapperObj is WeaponAttributesWrapper w))
            {
                throw new System.InvalidCastException();
            }

            loader.ApplyPPatch(TracerSpeed, () => w.TracerSpeed, Fixed64.UnsafeFromDouble);
            loader.ApplyPMultPatch(TracerSpeedMult, () => w.TracerSpeed);

            loader.ApplyPPatch(TracerLength, () => w.TracerLength, Fixed64.UnsafeFromDouble);
            loader.ApplyPMultPatch(TracerLengthMult, () => w.TracerLength);

            loader.ApplyPPatch(BaseDamagePerRound, () => w.BaseDamagePerRound, Fixed64.UnsafeFromDouble);
            loader.ApplyPMultPatch(BaseDamagePerRoundMult, () => w.BaseDamagePerRound);

            loader.ApplyPPatch(BaseWreckDamagePerRound, () => w.BaseWreckDamagePerRound, Fixed64.UnsafeFromDouble);
            loader.ApplyPMultPatch(BaseWreckDamagePerRoundMult, () => w.BaseWreckDamagePerRound);

            loader.ApplyPPatch(FiringRecoil, () => w.FiringRecoil);
            loader.ApplyPMultPatch(FiringRecoilMult, () => w.FiringRecoil);

            loader.ApplyPPatch(WindUpTimeMS, () => w.WindUpTimeMS);
            loader.ApplyPMultPatch(WindUpTimeMSMult, () => w.WindUpTimeMS);

            loader.ApplyPPatch(RateOfFire, () => w.RateOfFire);
            loader.ApplyPMultPatch(RateOfFireMult, () => w.RateOfFire);

            loader.ApplyPPatch(NumberOfBursts, () => w.NumberOfBursts);
            loader.ApplyPMultPatch(NumberOfBurstsMult, () => w.NumberOfBursts);

            loader.ApplyPPatch(DamagePacketsPerShot, () => w.DamagePacketsPerShot);
            loader.ApplyPMultPatch(DamagePacketsPerShotMult, () => w.DamagePacketsPerShot);

            loader.ApplyPPatch(BurstPeriodMinTimeMS, () => w.BurstPeriodMinTimeMS);
            loader.ApplyPMultPatch(BurstPeriodMinTimeMSMult, () => w.BurstPeriodMinTimeMS);

            loader.ApplyPPatch(BurstPeriodMaxTimeMS, () => w.BurstPeriodMaxTimeMS);
            loader.ApplyPMultPatch(BurstPeriodMaxTimeMSMult, () => w.BurstPeriodMaxTimeMS);

            loader.ApplyPPatch(CooldownTimeMS, () => w.CooldownTimeMS);
            loader.ApplyPMultPatch(CooldownTimeMSMult, () => w.CooldownTimeMS);

            loader.ApplyPPatch(WindDownTimeMS, () => w.WindDownTimeMS);
            loader.ApplyPMultPatch(WindDownTimeMSMult, () => w.WindDownTimeMS);

            loader.ApplyPPatch(ReloadTimeMS, () => w.ReloadTimeMS);
            loader.ApplyPMultPatch(ReloadTimeMSMult, () => w.ReloadTimeMS);

            loader.ApplyPPatch(AreaOfEffectRadius, () => w.AreaOfEffectRadius, Fixed64.UnsafeFromDouble);
            loader.ApplyPMultPatch(AreaOfEffectRadiusMult, () => w.AreaOfEffectRadius);

            loader.ApplyPPatch(FriendlyFireDamageScalar, () => w.FriendlyFireDamageScalar, Fixed64.UnsafeFromDouble);
            loader.ApplyPMultPatch(FriendlyFireDamageScalarMult, () => w.FriendlyFireDamageScalar);

            loader.ApplyPPatch(WeaponOwnerFriendlyFireDamageScalar, () => w.WeaponOwnerFriendlyFireDamageScalar, Fixed64.UnsafeFromDouble);
            loader.ApplyPMultPatch(WeaponOwnerFriendlyFireDamageScalarMult, () => w.WeaponOwnerFriendlyFireDamageScalar);

            loader.ApplyPPatch(ExcludeFromAutoTargetAcquisition, () => w.ExcludeFromAutoTargetAcquisition);
            loader.ApplyPPatch(ExcludeFromAutoFire, () => w.ExcludeFromAutoFire);
            loader.ApplyPPatch(ExcludeFromHeightAdvantage, () => w.ExcludeFromHeightAdvantage);
            loader.ApplyPPatch(DamageType, () => w.DamageType);
            loader.ApplyPPatch(IsTracer, () => w.IsTracer);
            loader.ApplyPPatch(LineOfSightRequired, () => w.LineOfSightRequired);
            loader.ApplyPPatch(LeadsTarget, () => w.LeadsTarget);
            loader.ApplyPPatch(KillSkipsUnitDeathSequence, () => w.KillSkipsUnitDeathSequence);
            loader.ApplyPPatch(RevealTriggers, () => w.RevealTriggers);
            loader.ApplyPPatch(UnitStatusAttackingTriggers, () => w.UnitStatusAttackingTriggers);
            loader.ApplyPPatch(TargetStyle, () => w.TargetStyle);
            loader.ApplyPPatch(ActiveStatusEffectsIndex, () => w.ActiveStatusEffectsIndex);

            if (Modifiers != null)
            {
                var l = w.Modifiers?.Select(x => new WeaponModifierInfoWrapper(x)).ToList() ?? new List <WeaponModifierInfoWrapper>();
                loader.ApplyLPatch(Modifiers, l, () => new WeaponModifierInfoWrapper(), nameof(WeaponModifierInfo));
                w.Modifiers = l.ToArray();
            }

            loader.ApplyPPatch(AreaOfEffectFalloffType, () => w.AreaOfEffectFalloffType);
            loader.ApplyPPatch(ExcludeWeaponOwnerFromAreaOfEffect, () => w.ExcludeWeaponOwnerFromAreaOfEffect);

            if (Turret != null)
            {
                using (loader.logger.BeginScope($"Turret:"))
                {
                    var w2 = new TurretAttributesWrapper(w.Turret);
                    Turret.Apply(loader, w2, null);
                    w.Turret = w2;
                }
            }

            ApplyRangeAttributes(loader, WeaponRange.Short, RangeAttributesShort, w);
            ApplyRangeAttributes(loader, WeaponRange.Medium, RangeAttributesMedium, w);
            ApplyRangeAttributes(loader, WeaponRange.Long, RangeAttributesLong, w);

            loader.ApplyPPatch(ProjectileEntityTypeToSpawn, () => w.ProjectileEntityTypeToSpawn);
            loader.ApplyPPatch(StatusEffectsTargetAlignment, () => w.StatusEffectsTargetAlignment);
            loader.ApplyPPatch(StatusEffectsExcludeTargetType, () => w.StatusEffectsExcludeTargetType);

            if (StatusEffectsSets != null)
            {
                var l = w.StatusEffectsSets?.Select(x => new StatusEffectsSetAttributesWrapper(x)).ToList() ?? new List <StatusEffectsSetAttributesWrapper>();
                loader.ApplyLPatch(StatusEffectsSets, l, () => new StatusEffectsSetAttributesWrapper(), nameof(StatusEffectsSetAttributes));
                w.StatusEffectsSets = l.Where(x => x != null).ToArray();
            }

            if (TargetPrioritizationAttributes != null)
            {
                using (loader.logger.BeginScope($"TargetPrioritizationAttributes:"))
                {
                    var w2 = new TargetPriorizationAttributesWrapper(w.TargetPriorizationAttributes);
                    TargetPrioritizationAttributes.Apply(loader, w2, null);
                    w.TargetPriorizationAttributes = w2;
                }
            }

            if (EntityTypesToSpawnOnImpact != null)
            {
                var l = w.EntityTypesToSpawnOnImpact?.Select(x => new EntityTypeToSpawnAttributesWrapper(x)).ToList() ?? new List <EntityTypeToSpawnAttributesWrapper>();
                loader.ApplyLPatch(EntityTypesToSpawnOnImpact, l, () => new EntityTypeToSpawnAttributesWrapper(), nameof(EntityTypeToSpawnAttributes));
                w.EntityTypesToSpawnOnImpact = l.Where(x => x != null).ToArray();
            }

            if (OutputDPS == true)
            {
                OutputWeaponDPS(loader, w);
            }
        }