protected override void AddContentToWindow(ConsoleWindow window)
        {
            var seg0 = window.Screen.CreateStandardSegment();

            seg0.AddInterpretter(SubjectiveDisplay <bool> .Quick(false, M.m <bool>(x =>
            {
                if (mods.All(y => y.processed))
                {
                    _focus.Do();
                }
                return
                ("The following mods are required by this construct but are not installed on this instance of FtD.\n" +
                 "This popup will automatically close when all mods are either installed or discarded.\n" +
                 "You have to restart FtD in order to apply the newly installed mods.");
            }), ""));

            foreach (var mod in mods)
            {
                window.Screen.CreateHeader(mod.name, new ToolTip("Missing mod"))
                .SetConditionalDisplay(() => !mod.processed);
                var seg1 = window.Screen.CreateStandardSegment();
                seg1.SetConditionalDisplay(() => !mod.processed);

                seg1.AddInterpretter(StringDisplay.Quick(mod.description, "Description of missing mod"));

                var seg2 = window.Screen.CreateStandardHorizontalSegment();
                seg2.SetConditionalDisplay(() => !mod.processed);

                if (!string.IsNullOrWhiteSpace(mod.manifest) &&
                    Uri.TryCreate(mod.manifest, UriKind.Absolute, out var _))
                {
                    seg2.AddInterpretter(Button.Quick("Install mod with FtdModManager", new ToolTip(mod.manifest), () =>
                    {
                        mod.processed = true;
                        ModManagerPlugin.Instance.manager.Install(mod.manifest);
                    }));
                }

                if (!string.IsNullOrWhiteSpace(mod.manifest) &&
                    Uri.TryCreate(mod.link, UriKind.Absolute, out var _))
                {
                    seg2.AddInterpretter(Button.Quick("Open mod page", new ToolTip(mod.link), () =>
                    {
                        Application.OpenURL(mod.link);
                    }));
                }

                seg2.AddInterpretter(Button.Quick("Discard", new ToolTip("Ignore this alert"), () =>
                {
                    mod.processed = true;
                }));
            }
        }
Example #2
0
        public static void Prefix(ApsTab __instance, AdvCannonFiringPiece ____focus)
        {
            var self           = __instance;
            var focus          = ____focus;
            var ShellRackModel = focus.ShellRackModel;
            var Node           = focus.Node;
            var barrelSystem   = focus.BarrelSystem as CannonMultiBarrelSystem;

            string GetLoaderROF()
            {
                float culmROF = 0;

                if (Node.ShellRacks.Racks.Count > 1)
                {
                    foreach (var thisRack in Node.ShellRacks.Racks)
                    {
                        //Debug.Log("[Walrus Shells Ballistic Madness] Checking For Loaded Shell.");

                        if (thisRack.LoadedShell != null)
                        {
                            //Debug.Log("[Walrus Shells Ballistic Madness] Calculating Load Time.");

                            float loadtime = ShellConstants.LoadTimeForShellVolume(new ShellModel_Propellant(thisRack.LoadedShell).GetTotalVolume());

                            //Debug.Log("[Walrus Shells Ballistic Madness] Is it a beltfed rack?");

                            if (thisRack as BeltFeedShellRackModel != null)
                            {
                                BeltFeedShellRackModel belty = thisRack as BeltFeedShellRackModel;
                                //Debug.Log("[Walrus Shells Ballistic Madness] Doing Beltfed Math?");
                                culmROF += 60 / loadtime / belty.LoadingTimeComplexityModifier / 0.2f;
                            }
                            else
                            {
                                //Debug.Log("[Walrus Shells Ballistic Madness] Is it a standard rack?");

                                if (thisRack as ShellRackModel != null)
                                {
                                    ShellRackModel standardRack = thisRack as ShellRackModel;
                                    //Debug.Log("[Walrus Shells Ballistic Madness] Doing Normal Math?");
                                    culmROF += 60 / loadtime / standardRack.MultipleDirectionsSpeedUpFactor() / standardRack.LoadingTimeComplexityModifier / Rounding.R2(Mathf.Min(1f / Mathf.Sqrt(standardRack.LengthCapacity), 1f));
                                }
                            }
                        }
                    }
                }
                return($"Semi-Stable RoF Estimation: <b>{culmROF:0.##} rounds/min</b>");
            }

            string GetBarrelROF()
            {
                var nextShell = Node.ShellRacks.GetNextShell(false);

                if (nextShell == null)
                {
                    return("Burst RoF: No shell loaded");
                }
                float baseCooldown   = ShellConstants.CooldownTimeFromVolumeOfPropellant(nextShell.Propellant.GetNormalisedVolumeOfPropellant());
                float cooldownFactor = Traverse.Create(barrelSystem).Method("CooldownFactor").GetValue <float>();
                float rof            = 60 / (baseCooldown * cooldownFactor) * barrelSystem.BarrelCount;

                return($"Burst RoF: <b>{rof:0.##} rounds/min</b>");
            }

            string GetRecoilInfo()
            {
                float refresh  = Node.HydraulicRefresh;
                float capacity = Node.HydraulicCapacity;
                float dt       = 60 / focus.Data.MaxFireRatePerMinute;

                var shell = Node.ShellRacks.GetNextShell(false);

                if (shell == null)
                {
                    return("No shell loaded, recoil information unavailable");
                }

                float overclockFactor = Mathf.Max(focus.Data.CooldownOverClock + 1, 1);

                float railReloadTime = focus.RailReloadTime();
                float railFraction   = (railReloadTime < float.PositiveInfinity && railReloadTime > 0)
                    ? Mathf.Clamp01(dt / railReloadTime) : 0;

                float total = overclockFactor * focus.GetRecoilForce(
                    shell.Propellant.GetNormalisedVolumeOfPropellant(),
                    focus.RailgunDraw() * railFraction);

                float reduction = Math.Min(refresh * dt, capacity);
                float actual    = total - reduction;

                return
                    ($"Recoil per shot at current RoF ({dt:0.####}s between shots): {total:0} - {reduction:0} = <b>{actual:0}</b>\n" +
                     $"Maximum recoil reduction is {capacity:0} and recovers {refresh:0.#} per second");
            }

            string GetAmmoInfo()
            {
                var shell = Node.ShellRacks.GetNextShell(false);

                if (shell == null)
                {
                    return("Ammo Consumption: No shell loaded");
                }

                float rof  = focus.Data.MaxFireRatePerMinute / 60;
                float cost = shell.AmmoCost.GetAmmoCost();

                return($"Ammo Consumption: <b>{cost * rof:0} ammo/s</b>");
            }

            //Tuple<float, float> GetReductionForHydraulicLength(int len)
            //{
            //    return new Tuple<float, float>(1250f * len * len, Rounding.R0(10000f * Mathf.Pow(len, 2 / 3f)));
            //}
            //string recoilData = string.Join("\n", new[] { 1, 2, 4, 6, 8 }.Select(x => string.Join(", ", GetReductionForHydraulicLength(x))));

            self.CreateHeader("Rate Of Fire Predictor", new ToolTip(""));
            var seg1 = self.CreateStandardSegment();

            seg1.AddInterpretter(SubjectiveDisplay <AdvCannonFiringPiece> .Quick(focus, M.m <AdvCannonFiringPiece>(x => GetLoaderROF()),
                                                                                 "Prediction of the cannon's actual rate of fire."));

            seg1.AddInterpretter(SubjectiveDisplay <AdvCannonFiringPiece> .Quick(focus, M.m <AdvCannonFiringPiece>(x => GetBarrelROF()),
                                                                                 "The maximum burst RoF of the cannon without overclocking. Based on cooldown time."));

            seg1.AddInterpretter(SubjectiveDisplay <AdvCannonFiringPiece> .Quick(focus, M.m <AdvCannonFiringPiece>(x => GetRecoilInfo()),
                                                                                 "Hydraulic Recoil Absorber data:\n\n" +
                                                                                 "Length	║ Capacity	│ Refresh Rate\n"+
                                                                                 "1m	║ 1250		│ 10000\n"+
                                                                                 "2m	║ 5000		│ 15874\n"+
                                                                                 "4m	║ 20000		│ 25198\n"+
                                                                                 "6m	║ 45000		│ 33019\n"+
                                                                                 "8m	║ 80000		│ 40000"));

            seg1.AddInterpretter(SubjectiveDisplay <AdvCannonFiringPiece> .Quick(focus, M.m <AdvCannonFiringPiece>(x => GetAmmoInfo()),
                                                                                 "The ammunition requirement of the cannon at current RoF."));
        }
Example #3
0
        protected override ConsoleWindow BuildInterface(string suggestedName = "")
        {
            var window1 = NewWindow("Mod List", WindowSizing.GetLhs());

            window1.DisplayTextPrompt = false;
            var seg1 = window1.Screen.CreateStandardSegment();

            foreach (var mod in _focus.mods)
            {
                var btn = seg1.AddInterpretter(SubjectiveButton <ModPreferences> .Quick(mod, mod.modName, new ToolTip(mod.basePath, 400), x =>
                {
                    selected = x;
                }));
                btn.Color = M.m <ModPreferences>(x => selected == x ? Color.green : Color.white);
            }


            var window2 = NewWindow("Mod Manager", WindowSizing.GetRhs());

            window2.DisplayTextPrompt = false;


            window2.Screen.CreateHeader("Mod Options", new ToolTip("Options for the selected mod"));
            var seg2 = window2.Screen.CreateStandardSegment();

            seg2.SetConditionalDisplay(() => selected != null);

            seg2.AddInterpretter(SubjectiveDisplay <Manager> .Quick(_focus, M.m <Manager>(
                                                                        x =>
            {
                if (selected.Managed)
                {
                    return("This mod is managed by FtdModManager");
                }
                else
                {
                    return("This mod is <b>not</b> managed by FtdModManager");
                }
            }
                                                                        ), "Information about this mod"));

            var items = Enum.GetNames(typeof(UpdateType)).Select(x => new DropDownMenuAltItem <UpdateType> {
                Name = x, ToolTip = x
            });
            var menu = new DropDownMenuAlt <UpdateType>();

            menu.SetItems(items.ToArray());

            seg2.AddInterpretter(new DropDown <Manager, UpdateType>(_focus, menu,
                                                                    (manager, x) => x == selected.updateType,
                                                                    (manager, x) => _focus.SetUpdateType(selected, x)));

            seg2.AddInterpretter(SubjectiveButton <Manager> .Quick(_focus, "Check update", new ToolTip("Check update"), x =>
            {
                x.CheckUpdate(selected);
            }));

            seg2.AddInterpretter(SubjectiveButton <Manager> .Quick(_focus, "Uninstall", new ToolTip("Uninstall mod"), x =>
            {
                _focus.DetectMods();
                TriggerRebuild();
            }));

            window2.Screen.CreateSpace();

            window2.Screen.CreateHeader("Mod Installation", new ToolTip("Install mod, etc."));
            var seg3 = window2.Screen.CreateStandardSegment();

            seg3.AddInterpretter(SubjectiveButton <Manager> .Quick(_focus, "Install new mod", new ToolTip("Install new mod"),
                                                                   x => preparingInstall = true))
            .SetConditionalDisplayFunction(() => !preparingInstall);

            seg3.AddInterpretter(TextInput <Manager> .Quick(_focus, M.m <Manager>(x => manifestUri), "Install URI",
                                                            new ToolTip("Paste the URI of the modmanifest.json here"), (manager, x) => manifestUri = x))
            .SetConditionalDisplayFunction(() => preparingInstall);

            seg3.AddInterpretter(TextInput <Manager> .Quick(_focus, M.m <Manager>(x => modDir), "Install path (Optional)",
                                                            new ToolTip("The installation directory of the new mod. Leave empty to use default value"), (manager, x) => modDir = x))
            .SetConditionalDisplayFunction(() => preparingInstall);

            var seg4 = window2.Screen.CreateStandardHorizontalSegment();

            seg4.AddInterpretter(SubjectiveButton <Manager> .Quick(_focus, "Install", new ToolTip("Install new mod!"), x =>
            {
                _focus.Install(manifestUri, modDir).ContinueWith(y =>
                {
                    isInstalling     = false;
                    preparingInstall = false;
                    manifestUri      = "";
                    modDir           = "";
                    _focus.DetectMods();
                    TriggerRebuild();
                });
            }))
            .SetConditionalDisplayFunction(() => preparingInstall && !isInstalling);

            seg4.AddInterpretter(SubjectiveButton <Manager> .Quick(_focus, "Cancel", new ToolTip("Cancel mod installation"),
                                                                   x => preparingInstall = false))
            .SetConditionalDisplayFunction(() => preparingInstall && !isInstalling);

            window2.Screen.CreateHeader("Miscellaneous", new ToolTip("Other useful operations"));
            var seg5 = window2.Screen.CreateStandardSegment();

            (seg5.AddInterpretter(SubjectiveButton <Manager> .Quick(_focus, "Restart FtD", new ToolTip("Restart FtD in order to reload mods"),
                                                                    x => _focus.RestartGame()))
             .SetConditionalDisplayFunction(() => !isInstalling) as SubjectiveButton <Manager>)
            .Color = M.m <Manager>(new Color(255 / 255f, 179 / 255f, 179 / 255f));

            //window.Screen.CreateSpace();
            return(window1);
        }