コード例 #1
0
        /// <summary>
        /// Initializes the list of discovered resources, accounting for both DLC and Vanilla.
        /// </summary>
        private void InitDiscovered()
        {
            Type   baseType;
            object instance;

            // TODO Vanilla/DLC code
            if ((baseType = PPatchTools.GetTypeSafe("DiscoveredResources")) == null)
            {
                // Vanilla
                baseType = PPatchTools.GetTypeSafe(nameof(WorldInventory));
                instance = baseType?.GetProperty("Instance", BindingFlags.Static |
                                                 BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null, null);
            }
            else
            {
                // DLC
                instance = baseType.GetFieldSafe("Instance", true)?.GetValue(null);
            }
#if DEBUG
            PUtil.LogDebug("Using inventory type: " + (baseType?.Name ?? "None"));
#endif
            if (instance != null)
            {
                discovered = baseType.CreateDelegate <ResourceCheckDelegate>(
                    "TryGetDiscoveredResourcesFromTag", instance, typeof(Tag), typeof(
                        HashSet <Tag>).MakeByRefType());
            }
            else
            {
                PUtil.LogWarning("Unable to find discovered resource list, no resources will be available to sweep");
            }
        }
コード例 #2
0
        private static void RoomsExpandedCompat()
        {
            var db            = Db.Get();
            var RoomsExpanded = PPatchTools.GetTypeSafe("RoomsExpanded.RoomTypes_AllModded", "RoomsExpandedMerged");

            if (RoomsExpanded != null)
            {
                PUtil.LogDebug("RoomsExpanded found. Attempt to add compatibility.");
                try
                {
                    AquariumRoom = (RoomType)RoomsExpanded.GetPropertySafe <RoomType>("Aquarium", true)?.GetValue(null, null);
                    if (AquariumRoom != null)
                    {
                        var upgrade_paths = db.RoomTypes.CreaturePen.upgrade_paths.AddToArray(AquariumRoom);
                        Traverse.Create(db.RoomTypes.CreaturePen).Property(nameof(RoomType.upgrade_paths)).SetValue(upgrade_paths);
                        Traverse.Create(AquariumRoom).Property(nameof(RoomType.priority)).SetValue(db.RoomTypes.CreaturePen.priority);
                        RoomsExpandedFound = true;
                    }
                }
                catch (System.Exception e)
                {
                    PUtil.LogExcWarn(e);
                }
            }
            if (RoomsExpandedFound)
            {
                harmony.PatchTranspile(typeof(RanchStation.Instance), nameof(RanchStation.Instance.FindRanchable),
                                       new HarmonyMethod(typeof(RanchStation_Instance_FindRanchable), nameof(RanchStation_Instance_FindRanchable.TranspilerCompat)));
            }
        }
コード例 #3
0
        internal BetterInfoCardsCompat()
        {
            RegisterMethodFunc addConv = null;

            exportMethod = null;
            try {
                addConv = PPatchTools.GetTypeSafe(BIC_NAMESPACE + "ConverterManager",
                                                  BIC_ASSEMBLY)?.Detour <RegisterMethodFunc>("AddConverterReflect");
                var patchType = PPatchTools.GetTypeSafe(BIC_NAMESPACE + "CollectHoverInfo",
                                                        BIC_ASSEMBLY)?.GetNestedType("GetSelectInfo_Patch", BindingFlags.Static |
                                                                                     BindingFlags.Instance | PPatchTools.BASE_FLAGS);
                if (patchType != null)
                {
                    exportMethod = patchType.Detour <ExportMethodFunc>("Export");
                }
            } catch (AmbiguousMatchException e) {
                PUtil.LogWarning("Exception when loading Better Info Cards compatibility:");
                PUtil.LogExcWarn(e);
            } catch (DetourException e) {
                PUtil.LogWarning("Exception when loading Better Info Cards compatibility:");
                PUtil.LogExcWarn(e);
            }
            if (addConv != null && exportMethod != null)
            {
                try {
                    Register(addConv, EXPORT_THERMAL_MASS, ObjectToFloat, SumThermalMass);
                    Register(addConv, EXPORT_HEAT_ENERGY, ObjectToFloat, SumHeatEnergy);
                    PUtil.LogDebug("Registered Better Info Cards status data handlers");
                } catch (Exception e) {
                    PUtil.LogWarning("Exception when registering Better Info Cards compatibility:");
                    PUtil.LogExcWarn(e.GetBaseException());
                }
            }
        }
コード例 #4
0
        internal static void AfterDbInit()
        {
            // Assets are now loaded, so create pip icon
            var    pip    = Assets.GetAnim("squirrel_kanim");
            Sprite sprite = null;

            if (pip != null)
            {
                sprite = Def.GetUISpriteFromMultiObjectAnim(pip);
            }
            if (sprite == null)
            {
                // Pip anim is somehow missing?
                sprite = Assets.GetSprite("overlay_farming");
            }
            Assets.Sprites.Add(PipPlantOverlayStrings.OVERLAY_ICON, sprite);
            // SPPR fixes the symmetry rule
            bool ruleFix = PPatchTools.GetTypeSafe("MightyVincent.Patches",
                                                   "SimplerPipPlantRule") != null;

            if (ruleFix)
            {
                PUtil.LogDebug("Detected Simpler Pip Plant Overlay, adjusting radius");
            }
            PipPlantOverlayTests.SymmetricalRadius = ruleFix;
        }
コード例 #5
0
            internal static MethodBase TargetMethod()
            {
                // Target HoverTextHelper in DLC, and WorldInspector in vanilla
                // TODO Vanilla/DLC code
                var type = PPatchTools.GetTypeSafe("HoverTextHelper");

                if (type == null)
                {
                    type = PPatchTools.GetTypeSafe("WorldInspector");
                }
                return(type?.GetMethodSafe(METHOD, true, typeof(int)));
            }
コード例 #6
0
        private static void LagooPatch()
        {
            var BaseLagooConfig = PPatchTools.GetTypeSafe("Lagoo.BaseLagooConfig", "LagooMerged");

            if (BaseLagooConfig != null)
            {
                PUtil.LogDebug("'Lagoo' found, trying to apply a compatibility patch.");

                var postfix = new HarmonyMethod(typeof(BaseSquirrelConfig_BaseSquirrel), nameof(BaseSquirrelConfig_BaseSquirrel.Postfix));
                harmonyInstance.Patch(BaseLagooConfig, "BaseLagoo", null, postfix);

                var transpiler = new HarmonyMethod(typeof(BaseSquirrelConfig_BaseSquirrel), nameof(BaseSquirrelConfig_BaseSquirrel.Transpiler));
                harmonyInstance.PatchTranspile(BaseLagooConfig, "BaseLagoo", transpiler);
            }
        }
コード例 #7
0
        public static void PostPatch(HarmonyInstance instance)
        {
            var steamMod = PPatchTools.GetTypeSafe("KMod.Steam");

            if (steamMod != null)
            {
#if DEBUG
                PUtil.LogDebug("Transpiling Steam.UpdateMods()");
#endif
                // Transpile UpdateMods only for Steam versions (not EGS)
                instance.Patch(steamMod.GetMethodSafe("UpdateMods", false, PPatchTools.
                                                      AnyArguments), transpiler: new HarmonyMethod(typeof(StockBugsPatches),
                                                                                                   nameof(TranspileUpdateMods)));
                instance.Patch(typeof(MainMenu).GetMethodSafe("Update", false), postfix:
                               new HarmonyMethod(typeof(StockBugsPatches), nameof(PostfixMenuUpdate)));
            }
        }
コード例 #8
0
        public override BuildingDef CreateBuildingDef()
        {
            var def = ThermalInterfacePlate.CreateDef();

            // Is "Drywall Hides Pipes" installed? If so, hide pipes with this too
            if (PPatchTools.GetTypeSafe("DrywallHidesPipes.DrywallPatch") != null)
            {
                def.SceneLayer = Grid.SceneLayer.LogicGatesFront;
            }
            // Is "Faster Drywall & Plate Construction" installed? If so, reduce
            // construction time by 5x
            if (PPatchTools.GetTypeSafe("Patches.ExteriorWallAdjust") != null)
            {
                def.ConstructionTime = 6.0f;
            }
            return(def);
        }
コード例 #9
0
        internal static void SetupTooltips()
        {
            var options = POptions.ReadSettings <ThermalTooltipsOptions>() ??
                          new ThermalTooltipsOptions();

            // Check for DisplayAllTemps
            if (PPatchTools.GetTypeSafe("DisplayAllTemps.State", "DisplayAllTemps") !=
                null)
            {
                // Let Display All Temps take over display (ironically setting AllUnits
                // to FALSE) since it patches GetFormattedTemperature
                PUtil.LogDebug("DisplayAllTemps compatibility activated");
                options.AllUnits = false;
            }
            TooltipInstance = new ExtendedThermalTooltip(options, bicCompat);
            PUtil.LogDebug("Created ExtendedThermalTooltip");
        }
コード例 #10
0
 /// <summary>
 /// Patches Text Mesh Pro input fields to fix a variety of bugs. Should be used before
 /// any Text Mesh Pro objects are created.
 /// </summary>
 public static void Patch()
 {
     lock (patchLock) {
         if (!patchChecked)
         {
             var tmpType = PPatchTools.GetTypeSafe("TMPro.TMP_InputField");
             if (tmpType != null)
             {
                 try {
                     InputFieldPatches(tmpType);
                 } catch (Exception) {
                     PUtil.LogWarning("Unable to patch TextMeshPro bug, text fields may display improperly inside scroll areas");
                 }
             }
             patchChecked = true;
         }
     }
 }
コード例 #11
0
        /// <summary>
        /// Fixes the race condition in Steam.UpdateMods.
        /// </summary>
        /// <param name="instance">The Harmony instance to use for patching.</param>
        private void FixModUpdateRace(Harmony instance)
        {
            var          steamMod = PPatchTools.GetTypeSafe("KMod.Steam");
            const string BUG_KEY  = "Bugs.ModUpdateRace";

            if (steamMod != null && !PRegistry.GetData <bool>(BUG_KEY))
            {
                // Transpile UpdateMods only for Steam versions (not EGS)
#if DEBUG
                PUtil.LogDebug("Transpiling Steam.UpdateMods()");
#endif
                PRegistry.PutData(BUG_KEY, true);
                instance.Patch(steamMod.GetMethodSafe("UpdateMods", false, PPatchTools.
                                                      AnyArguments), transpiler: new HarmonyMethod(typeof(StockBugsPatches),
                                                                                                   nameof(TranspileUpdateMods)));
                instance.Patch(typeof(MainMenu).GetMethodSafe("OnSpawn", false), postfix:
                               new HarmonyMethod(typeof(StockBugsPatches), nameof(PostfixMenuSpawn)));
            }
        }
コード例 #12
0
        internal BetterInfoCardsCompat()
        {
            MethodInfo addConv = null;

            exportMethod = null;
            try {
                addConv = PPatchTools.GetTypeSafe(BIC_NAMESPACE + "ConverterManager",
                                                  BIC_ASSEMBLY)?.GetMethodSafe("AddConverter", true, PPatchTools.
                                                                               AnyArguments);
                var patchType = PPatchTools.GetTypeSafe(BIC_NAMESPACE + "CollectHoverInfo",
                                                        BIC_ASSEMBLY)?.GetNestedType("GetSelectInfo_Patch", BindingFlags.Static |
                                                                                     BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
                if (patchType != null)
                {
                    exportMethod = patchType.CreateStaticDelegate <ExportMethodFunc>("Export",
                                                                                     typeof(string), typeof(object));
                }
            } catch (TargetInvocationException e) {
                PUtil.LogWarning("Exception when loading Better Info Cards compatibility:");
                PUtil.LogExcWarn(e?.GetBaseException() ?? e);
            } catch (AmbiguousMatchException e) {
                PUtil.LogWarning("Exception when loading Better Info Cards compatibility:");
                PUtil.LogExcWarn(e);
            }
            if (addConv != null && exportMethod != null)
            {
                // Delegates are much faster at runtime
                registerMethod = addConv;
                try {
                    Register(EXPORT_THERMAL_MASS, ObjectToFloat, SumThermalMass);
                    Register(EXPORT_HEAT_ENERGY, ObjectToFloat, SumHeatEnergy);
                    PUtil.LogDebug("Registered Better Info Cards status data handlers");
                } catch (TargetInvocationException e) {
                    PUtil.LogWarning("Exception when registering Better Info Cards compatibility:");
                    PUtil.LogExcWarn(e?.GetBaseException() ?? e);
                }
            }
            else
            {
                registerMethod = null;
            }
        }
コード例 #13
0
        /// <summary>
        /// Checks for compatibility and applies fast fetch manager updates only if Efficient
        /// Supply is not enabled.
        /// </summary>
        /// <param name="harmony">The Harmony instance to use for patching.</param>
        private static void CheckFetchCompat(Harmony harmony)
        {
            if (PPatchTools.GetTypeSafe("PeterHan.EfficientFetch.EfficientFetchManager") ==
                null)
            {
                PathPatches.AsyncBrainGroupUpdater.AllowFastListSwap = true;
                harmony.Patch(typeof(FetchManager.FetchablesByPrefabId),
                              nameof(FetchManager.FetchablesByPrefabId.UpdatePickups),
                              prefix: new HarmonyMethod(typeof(GamePatches.FetchManagerFastUpdate),
                                                        nameof(GamePatches.FetchManagerFastUpdate.BeforeUpdatePickups)));
#if DEBUG
                PUtil.LogDebug("Patched FetchManager for fast pickup updates");
#endif
            }
            else
            {
                PUtil.LogWarning("Disabling fast pickup updates: Efficient Supply active");
                PathPatches.AsyncBrainGroupUpdater.AllowFastListSwap = false;
            }
        }
コード例 #14
0
        /// <summary>
        /// Attempts to also patch the Decor Reimagined implementation of DecorProvider.
        /// Refresh.
        /// </summary>
        /// <param name="harmony">The Harmony instance to use for patching.</param>
        internal static void ApplyPatch(Harmony harmony)
        {
            var patchMethod = new HarmonyMethod(typeof(DecorProviderRefreshFix), nameof(
                                                    TranspileRefresh));
            var targetMethod = PPatchTools.GetTypeSafe(
                "ReimaginationTeam.DecorRework.DecorSplatNew", "DecorReimagined")?.
                               GetMethodSafe("RefreshDecor", false, PPatchTools.AnyArguments);

            if (targetMethod != null)
            {
                PUtil.LogDebug("Patching Decor Reimagined for DecorProvider.RefreshDecor");
                harmony.Patch(targetMethod, transpiler: patchMethod);
            }
            PUtil.LogDebug("Patching DecorProvider.Refresh");
            harmony.Patch(typeof(DecorProvider).GetMethodSafe(nameof(DecorProvider.Refresh),
                                                              false, PPatchTools.AnyArguments), transpiler: patchMethod);
            harmony.Patch(typeof(RoomProber), nameof(RoomProber.Sim1000ms), prefix:
                          new HarmonyMethod(typeof(DecorProviderRefreshFix), nameof(PrefixRoomProbe)));
            ROOMS_PENDING.Clear();
        }
コード例 #15
0
        public override void OnLoad(Harmony harmony)
        {
            IsMono = PPatchTools.GetTypeSafe("Mono.Runtime") != null;
            base.OnLoad(harmony);
            PUtil.InitLibrary();
#if DEBUG
            SpamObjectsHandler.PrepareSpamHandler(new PLib.PatchManager.PPatchManager(harmony));
#endif
            var inst = ExtendedTagBits.Instance;
            // Force these tags into the efficient lower bits
            foreach (var tag in FORCE_LOWER_BITS)
            {
                inst.ManifestFlagIndex(tag);
            }
            FetchManager.disallowedTagMask = TagBitOps.Not(FetchManager.disallowedTagBits);
            PDetours.DetourField <FetchAreaChore.StatesInstance, TagBits>(
                "s_transientDeliveryMask").Set(null, TagBitOps.Not(new TagBits(new Tag[] {
                GameTags.Garbage, GameTags.Creatures.Deliverable
            })));
            new PVersionCheck().Register(this, new SteamVersionChecker());
        }
コード例 #16
0
 public override void OnAllModsLoaded(Harmony harmony, IReadOnlyList <Mod> mods)
 {
     base.OnAllModsLoaded(harmony, mods);
     // Manual patch in the rewritten FetchManager.UpdatePickups only if Efficient
     // Supply is not enabled
     if (FastTrackOptions.Instance.FastUpdatePickups)
     {
         if (PPatchTools.GetTypeSafe("PeterHan.EfficientFetch.EfficientFetchManager") ==
             null)
         {
             harmony.Patch(typeof(FetchManager.FetchablesByPrefabId),
                           nameof(FetchManager.FetchablesByPrefabId.UpdatePickups),
                           prefix: new HarmonyMethod(typeof(FetchManagerFastUpdate),
                                                     nameof(FetchManagerFastUpdate.Prefix)));
             PUtil.LogDebug("Patched FetchManager for fast pickup updates");
         }
         else
         {
             PUtil.LogWarning("Disabling fast pickup updates: Efficient Supply active");
         }
     }
 }
コード例 #17
0
        /// <summary>
        /// Checks to see if the conditions for a method running are met.
        /// </summary>
        /// <param name="assemblyName">The assembly name that must be present, or null if none is required.</param>
        /// <param name="typeName">The type full name that must be present, or null if none is required.</param>
        /// <param name="requiredType">The type that was required, if typeName was not null or empty.</param>
        /// <returns>true if the requirements are met, or false otherwise.</returns>
        internal static bool CheckConditions(string assemblyName, string typeName,
                                             out Type requiredType)
        {
            bool ok = false, emptyType = string.IsNullOrEmpty(typeName);

            if (string.IsNullOrEmpty(assemblyName))
            {
                if (emptyType)
                {
                    requiredType = null;
                    ok           = true;
                }
                else
                {
                    requiredType = PPatchTools.GetTypeSafe(typeName);
                    ok           = requiredType != null;
                }
            }
            else if (emptyType)
            {
                requiredType = null;
                // Search for assembly only, by name
                foreach (var candidate in AppDomain.CurrentDomain.GetAssemblies())
                {
                    if (candidate.GetName().Name == assemblyName)
                    {
                        ok = true;
                        break;
                    }
                }
            }
            else
            {
                requiredType = PPatchTools.GetTypeSafe(typeName, assemblyName);
                ok           = requiredType != null;
            }
            return(ok);
        }
コード例 #18
0
ファイル: DebugUtils.cs プロジェクト: pether-pg/ONIMods
        /// <summary>
        /// Finds the type for the given name using the method that Unity/Mono uses to report
        /// types internally.
        /// </summary>
        /// <param name="typeName">The type name.</param>
        /// <returns>The types for each type name, or null if no type could be resolved.</returns>
        internal static Type GetTypeByUnityName(this string typeName)
        {
            Type type = null;

            if (!string.IsNullOrEmpty(typeName) && !SHORTHAND_TYPES.TryGetValue(typeName,
                                                                                out type))
            {
                // Generic type?
                var match = GENERIC_TYPE.Match(typeName);
                if (match.Success)
                {
                    var parameters = match.Groups[2].Value.Split(',');
                    int nParams    = parameters.Length;
                    // Convert parameters to types
                    var paramTypes = new Type[nParams];
                    for (int i = 0; i < nParams; i++)
                    {
                        paramTypes[i] = parameters[i].GetTypeByUnityName();
                    }
                    // Genericize it
                    var baseType = PPatchTools.GetTypeSafe(RemoveBacktick(match.Groups[1].
                                                                          Value));
                    if (baseType != null && baseType.IsGenericTypeDefinition)
                    {
                        type = baseType.MakeGenericType(paramTypes);
                    }
                    else
                    {
                        type = baseType;
                    }
                }
                else
                {
                    type = PPatchTools.GetTypeSafe(RemoveBacktick(typeName));
                }
            }
            return(type);
        }
コード例 #19
0
        /// <summary>
        /// Enumerates a list of methods and resolves their types. This method handles
        /// constructors as well.
        ///
        /// This method is very slow. Only execute when necessary.
        /// </summary>
        /// <param name="specs">The methods to look up.</param>
        /// <returns>The resolved methods or constructors.</returns>
        private static IEnumerable <MethodBase> CreateMethodList(ICollection <string> specs)
        {
            var methods = new List <MethodBase>(specs.Count);

            foreach (string mSpec in specs)
            {
                int index = mSpec.IndexOf(':');
                if (index > 0)
                {
                    string[]   types  = mSpec.Substring(0, index).Split('+');
                    int        n      = types.Length;
                    MethodBase result = null;
                    // Resolve the type, descending by '+' if needed
                    var type = PPatchTools.GetTypeSafe(types[0]);
                    for (int i = 1; i < n && type != null; i++)
                    {
                        type = type.GetNestedType(types[i], BindingFlags.NonPublic |
                                                  BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
                    }
                    // Access constructor or method
                    if (type == null)
                    {
                        PUtil.LogWarning("Unable to find type: " + mSpec);
                    }
                    else
                    {
                        result = LookupMethod(type, mSpec.Substring(index + 1));
                    }
                    if (result != null)
                    {
                        methods.Add(result);
                    }
                }
            }
            return(methods);
        }
コード例 #20
0
 internal static void TestAdvancedFilter()
 {
     AdvancedFilterEnabled = PPatchTools.GetTypeSafe(
         "AdvancedFilterMenu.AdvancedFiltrationAssets", "AdvancedFilterMenu") != null;
 }
コード例 #21
0
 public static void PrePatch(HarmonyInstance _)
 {
     IsMono = PPatchTools.GetTypeSafe("Mono.Runtime") != null;
 }
コード例 #22
0
        internal static void Init()
        {
            var db = Db.Get();

            // тюнингуем и актифируем комнату
            // подхватывать максимальный размер комнаты из тюнинга
            int maxRoomSize = TuningData <RoomProber.Tuning> .Get().maxRoomSize;

            var MAXIMUM_SIZE_MAX = new RoomConstraints.Constraint(
                building_criteria: null,
                room_criteria: (Room room) => room.cavity.numCells <= maxRoomSize,
                times_required: 1,
                name: string.Format(ROOMS.CRITERIA.MAXIMUM_SIZE.NAME, maxRoomSize),
                description: string.Format(ROOMS.CRITERIA.MAXIMUM_SIZE.DESCRIPTION, maxRoomSize),
                stomp_in_conflict: null);

            var additional_constraints = db.RoomTypes.MachineShop.additional_constraints;

            for (int i = 0; i < additional_constraints.Length; i++)
            {
                if (additional_constraints[i] == RoomConstraints.MAXIMUM_SIZE_96)
                {
                    additional_constraints[i] = MAXIMUM_SIZE_MAX;
                    break;
                }
            }

            db.RoomTypes.Add(db.RoomTypes.MachineShop);

            // детектим "Rooms Expanded". модифицируем "мастерскую" чтобы она могла быть обгрейднутна до "кухни"
            var RoomsExpanded = PPatchTools.GetTypeSafe("RoomsExpanded.RoomTypes_AllModded", "RoomsExpandedMerged");

            if (RoomsExpanded != null)
            {
                PUtil.LogDebug("RoomsExpanded found. Attempt to add compatibility.");
                try
                {
                    KitchenRoom = (RoomType)RoomsExpanded.GetPropertySafe <RoomType>("KitchenRoom", true)?.GetValue(null, null);
                    if (KitchenRoom != null)
                    {
                        var upgrade_paths = db.RoomTypes.MachineShop.upgrade_paths.AddToArray(KitchenRoom);
                        Traverse.Create(db.RoomTypes.MachineShop).Property(nameof(RoomType.upgrade_paths)).SetValue(upgrade_paths);
                        Traverse.Create(db.RoomTypes.MachineShop).Property(nameof(RoomType.priority)).SetValue(KitchenRoom.priority);
                        KitchenBuildingTag = "KitchenBuildingTag".ToTag();
                        RoomsExpandedFound = true;
                    }
                }
                catch (System.Exception e)
                {
                    PUtil.LogExcWarn(e);
                }
            }

            // добавляем перк для работы на станции
            CanMachineTinker = db.SkillPerks.Add(new SimpleSkillPerk(
                                                     id: REQUIRED_ROLE_PERK,
                                                     description: STRINGS.PERK_CAN_MACHINE_TINKER.DESCRIPTION));
            db.Skills.Technicals1.perks.Add(CanMachineTinker);

            // добавляем модификаторы и эффекты
            string text        = DUPLICANTS.MODIFIERS.MACHINETINKER.NAME;
            string description = STRINGS.DUPLICANTS.MODIFIERS.MACHINETINKER.TOOLTIP;

            CraftingSpeed = db.Attributes.Add(new Attribute(
                                                  id: CRAFTING_SPEED_MODIFIER_NAME,
                                                  is_trainable: false,
                                                  show_in_ui: Attribute.Display.General,
                                                  is_profession: false,
                                                  base_value: BASE_SPEED_VALUE));
            CraftingSpeed.SetFormatter(new PercentAttributeFormatter());

            MachinerySpeedModifier = new AttributeModifier(
                attribute_id: MACHINERY_SPEED_MODIFIER_NAME,
                value: MACHINERY_SPEED_MODIFIER,
                description: text,
                is_readonly: false);
            CraftingSpeedModifier = new AttributeModifier(
                attribute_id: CRAFTING_SPEED_MODIFIER_NAME,
                value: CRAFTING_SPEED_MODIFIER,
                description: text,
                is_readonly: false);

            MachineTinkerEffect = db.effects.Add(new Effect(
                                                     id: MACHINE_TINKER_EFFECT_NAME,
                                                     name: text,
                                                     description: description,
                                                     duration: MACHINE_TINKER_EFFECT_DURATION * Constants.SECONDS_PER_CYCLE,
                                                     show_in_ui: true,
                                                     trigger_floating_text: true,
                                                     is_bad: false));
            MachineTinkerEffect.Add(MachinerySpeedModifier);
            MachineTinkerEffect.Add(CraftingSpeedModifier);

            MachineTinkerEffectDuration = db.AttributeConverters.Create(
                id: "MachineTinkerEffectDuration",
                name: "Engie's Jerry Rig Effect Duration",
                description: STRINGS.DUPLICANTS.ATTRIBUTES.MACHINERY.MACHINE_TINKER_EFFECT_MODIFIER,
                attribute: db.Attributes.Machinery,
                multiplier: MACHINE_TINKER_EFFECT_DURATION_PER_SKILL,
                base_value: 0,
                formatter: new ToPercentAttributeFormatter(1f, GameUtil.TimeSlice.None),
                available_dlcs: DlcManager.AVAILABLE_ALL_VERSIONS);
        }
コード例 #23
0
 /// <summary>
 /// Finds the private class and method to patch.
 /// </summary>
 internal static MethodBase TargetMethod()
 {
     return(PPatchTools.GetTypeSafe("ClearableManager")?.GetMethodSafe(
                nameof(ChoreProvider.CollectChores), false, PPatchTools.AnyArguments));
 }
コード例 #24
0
        /// <summary>
        /// Adds more items to the spawner list, including geysers, artifacts, and POI items.
        /// </summary>
        /// <param name="instance">The sandbox tool menu to modify.</param>
        private static void AddToSpawnerMenu(SandboxToolParameterMenu instance)
        {
            // Transpiling it is possible (and a bit faster) but way more brittle
            var selector = instance.entitySelector;
            var filters  = ListPool <SearchFilter, SandboxToolParameterMenu> .Allocate();

            filters.AddRange(selector.filters);
            // POI Props
            filters.Add(new SearchFilter(SandboxToolsStrings.FILTER_POIPROPS,
                                         (entity) => {
                var prefab = entity as KPrefabID;
                bool ok    = prefab != null;
                if (ok)
                {
                    string name = prefab.PrefabTag.Name;
                    // Include anti-entropy thermo nullifier and neural vacillator
                    // Vacillator's ID is private, we have to make do
                    ok = (name.StartsWith("Prop") && name.Length > 4 && char.IsUpper(
                              name, 4)) || name == MassiveHeatSinkConfig.ID ||
                         name == "GeneShuffler";
                }
                return(ok);
            }, null, Def.GetUISprite(Assets.GetPrefab("PropLadder"))));
            // Artifacts
            filters.Add(new SearchFilter(SandboxToolsStrings.FILTER_ARTIFACTS,
                                         (entity) => {
                var prefab = entity as KPrefabID;
                bool ok    = prefab != null;
                if (ok)
                {
                    ok = prefab.PrefabTag.Name.StartsWith("artifact_");
                }
                return(ok);
            }, null, Def.GetUISprite(Assets.GetPrefab("artifact_eggrock"))));
            // Geysers
            filters.Add(new SearchFilter(SandboxToolsStrings.FILTER_GEYSERS,
                                         (entity) => {
                var prefab = entity as KPrefabID;
                return(prefab != null && (prefab.GetComponent <Geyser>() != null || prefab.
                                          PrefabTag.Name == "OilWell"));
            }, null, Def.GetUISprite(Assets.GetPrefab("GeyserGeneric_slush_water"))));
            // TODO Vanilla/DLC code
            if (PPatchTools.GetTypeSafe("FullereneCometConfig") == null)
            {
                // Update the special filter to add other comet types
                foreach (var filter in filters)
                {
                    if (filter.Name == STRINGS.UI.SANDBOXTOOLS.FILTERS.ENTITIES.SPECIAL)
                    {
                        var oldCondition = filter.condition;
                        filter.condition = (entity) => {
                            var prefab = entity as KPrefabID;
                            return((prefab != null && prefab.GetComponent <Comet>() != null) ||
                                   oldCondition.Invoke(entity));
                        };
                    }
                }
            }
            // Add matching assets
            var options = ListPool <object, SandboxToolParameterMenu> .Allocate();

            foreach (var prefab in Assets.Prefabs)
            {
                foreach (var filter in filters)
                {
                    if (filter.condition(prefab))
                    {
                        options.Add(prefab);
                        break;
                    }
                }
            }
#if DEBUG
            PUtil.LogDebug("Added {0:D} options to spawn menu".F(options.Count));
#endif
            selector.options = options.ToArray();
            selector.filters = filters.ToArray();
            options.Recycle();
            filters.Recycle();
        }