Пример #1
0
        private static void SetupM3InNXMHandler(string nxmIniPath)
        {
            DuplicatingIni ini      = DuplicatingIni.LoadIni(nxmIniPath);
            var            handlers = ini.GetOrAddSection("handlers");
            var            numCurrentHandlersStr = handlers.GetValue("size")?.Value;

            int.TryParse(numCurrentHandlersStr, out var numCurrentHandlers);

            // Find if M3 has been registered for me/me2/me3
            bool updated = false;

            for (int i = 1; i <= numCurrentHandlers; i++)
            {
                var games = handlers.GetValue($@"{i}\games");
                if (games == null)
                {
                    // ???
                    // Is ini configured incorrectly?
                    Log.Warning(@"NXMHandler ini appears to be configured incorrectly");
                }
                else
                {
                    if (games.Value == "other")
                    {
                        Log.Information(@"Updating 'other' in nxmhandler");
                        // We need to update this one
                        handlers.SetSingleEntry($@"{i}\executable", App.ExecutableLocation.Replace("\\", "\\\\"));
                        handlers.SetSingleEntry($@"{i}\arguments", "--nxmlink");
                        updated = true;
                    }
                }
            }

            if (!updated)
            {
                // Add ours
                Log.Warning(@"Adding section 'other' in nxmhandler");
                numCurrentHandlers++;
                handlers.SetSingleEntry($@"size", numCurrentHandlers);
                handlers.SetSingleEntry($@"{numCurrentHandlers}\games", "other");
                handlers.SetSingleEntry($@"{numCurrentHandlers}\executable",
                                        App.ExecutableLocation.Replace("\\", "\\\\"));
                handlers.SetSingleEntry($@"{numCurrentHandlers}\arguments", "--nxmlink");
            }

            File.WriteAllText(nxmIniPath, ini.ToString());
            Log.Information(@"Finished configuring nxmhandler");
            // Register nxm protocol
        }
Пример #2
0
        private static void RandomizeWeaponIni(DuplicatingIni vanillaFile, DuplicatingIni randomizerIni)
        {
            foreach (var section in vanillaFile.Sections)
            {
                var sectionsplit = section.Header.Split('.').ToList();
                if (sectionsplit.Count > 1)
                {
                    var objectname = sectionsplit[1];
                    if (objectname.StartsWith("SFXWeapon_") || objectname.StartsWith("SFXHeavyWeapon_"))
                    {
                        //We can randomize this section of the ini.
                        Debug.WriteLine($"Randomizing weapon {objectname}");
                        var outSection = randomizerIni.GetOrAddSection(section.Header);
                        foreach (var entry in section.Entries)
                        {
                            if (KeysToNotRandomize.Contains(entry.Key, StringComparer.InvariantCultureIgnoreCase))
                            {
                                continue; // Do not touch this key
                            }
                            if (entry.HasValue)
                            {
                                // if (entry.Key == "Damage") Debugger.Break();
                                string value = entry.Value;

                                //range check
                                if (value.StartsWith("("))
                                {
                                    value = value.Substring(0, value.IndexOf(')') + 1); //trim off trash on end (like ; comment )
                                    var p = StringStructParser.GetCommaSplitValues(value);
                                    if (p.Count == 2)
                                    {
                                        try
                                        {
                                            bool  isInt    = false;
                                            float x        = 0;
                                            float y        = 0;
                                            bool  isZeroed = false;
                                            if (int.TryParse(p["X"].TrimEnd('f'), out var intX) && int.TryParse(p["Y"].TrimEnd('f'), out var intY))
                                            {
                                                //integers
                                                if (intX < 0 && intY < 0)
                                                {
                                                    Debug.WriteLine($" BELOW ZERO INT: {entry.Key} for {objectname}: {entry.RawText}");
                                                }

                                                bool validValue = false;
                                                for (int i = 0; i < 10; i++)
                                                {
                                                    bool isMaxMin = intX > intY;
                                                    //bool isMinMax = intY < intX;
                                                    isZeroed = intX == 0 && intY == 0;
                                                    if (isZeroed)
                                                    {
                                                        validValue = true;
                                                        break;
                                                    }
                                                    ;  //skip
                                                    bool isSame       = intX == intY;
                                                    bool belowzeroInt = intX < 0 || intY < 0;
                                                    bool abovezeroInt = intX > 0 || intY > 0;

                                                    int Max = isMaxMin ? intX : intY;
                                                    int Min = isMaxMin ? intY : intX;

                                                    int range = Max - Min;
                                                    if (range == 0)
                                                    {
                                                        range = Max;
                                                    }
                                                    if (range == 0)
                                                    {
                                                        Debug.WriteLine("Range still 0");
                                                    }
                                                    int rangeExtension = range / 2; //50%

                                                    int newMin = Math.Max(0, ThreadSafeRandom.Next(Min - rangeExtension, Min + rangeExtension));
                                                    int newMax = ThreadSafeRandom.Next(Max - rangeExtension, Max + rangeExtension);
                                                    intX = isMaxMin ? newMax : newMin;
                                                    intY = isMaxMin ? newMin : newMax; //might need to check zeros
                                                                                       //if (entry.Key.Contains("MagSize")) Debugger.Break();

                                                    if (intX != 0 || intY != 0)
                                                    {
                                                        x = intX;
                                                        y = intY;
                                                        if (isSame)
                                                        {
                                                            x = intY;
                                                        }
                                                        if (!belowzeroInt && (x <= 0 || y <= 0))
                                                        {
                                                            continue; //not valid. Redo this loop
                                                        }
                                                        if (abovezeroInt && (x <= 0 || y <= 0))
                                                        {
                                                            continue; //not valid. Redo this loop
                                                        }

                                                        validValue = true;
                                                        break; //break loop
                                                    }
                                                }

                                                if (!validValue)
                                                {
                                                    Debug.WriteLine($"Failed rerolls: {entry.Key} for {objectname}: {entry.RawText}");
                                                }
                                            }
                                            else
                                            {
                                                //if (section.Header.Contains("SFXWeapon_GethShotgun")) Debugger.Break();

                                                //floats
                                                //Fix error in bioware's coalesced file
                                                if (p["X"] == "0.65.0f")
                                                {
                                                    p["X"] = "0.65f";
                                                }
                                                float floatx         = float.Parse(p["X"].TrimEnd('f'));
                                                float floaty         = float.Parse(p["Y"].TrimEnd('f'));
                                                bool  belowzeroFloat = false;
                                                if (floatx < 0 || floaty < 0)
                                                {
                                                    Debug.WriteLine($" BELOW ZERO FLOAT: {entry.Key} for {objectname}: {entry.RawText}");
                                                    belowzeroFloat = true;
                                                }

                                                bool isMaxMin = floatx > floaty;
                                                bool isMinMax = floatx < floaty;
                                                bool isSame   = floatx == floaty;
                                                isZeroed = floatx == 0 && floaty == 0;
                                                if (isZeroed)
                                                {
                                                    continue;
                                                }
                                                ;  //skip

                                                float Max = isMaxMin ? floatx : floaty;
                                                float Min = isMaxMin ? floaty : floatx;

                                                float range = Max - Min;
                                                if (range == 0)
                                                {
                                                    range = 0.1f * Max;
                                                }
                                                float rangeExtension = range * .5f; //50%
                                                if (ThreadSafeRandom.Next(10) == 0)
                                                {
                                                    rangeExtension = range * 15f; // Extreme
                                                }


                                                float newMin = Math.Max(0, ThreadSafeRandom.NextFloat(Min - rangeExtension, Min + rangeExtension));
                                                float newMax = ThreadSafeRandom.NextFloat(Max - rangeExtension, Max + rangeExtension);
                                                if (!belowzeroFloat)
                                                {
                                                    //ensure they don't fall below 0
                                                    if (newMin < 0)
                                                    {
                                                        newMin = Math.Max(newMin, Min / 2);
                                                    }

                                                    if (newMax < 0)
                                                    {
                                                        newMax = Math.Max(newMax, Max / 2);
                                                    }

                                                    //i have no idea what i'm doing
                                                }
                                                floatx = isMaxMin ? newMax : newMin;
                                                floaty = isMaxMin ? newMin : newMax; //might need to check zeros
                                                x      = floatx;
                                                y      = floaty;
                                                if (isSame)
                                                {
                                                    x = y;
                                                }
                                            }

                                            if (isZeroed)
                                            {
                                                continue; //skip
                                            }

                                            // Write out the new value
                                            outSection.SetSingleEntry(entry.Key, $"(X={x},Y={y})");
                                        }
                                        catch (Exception e)
                                        {
                                            Log.Error($"Cannot randomize weapon stat {objectname} {entry.Key}: {e.Message}");
                                        }
                                    }
                                }
                                else
                                {
                                    //Debug.WriteLine(entry.Key);
                                    var initialValue = entry.Value.ToString();
                                    var isInt        = int.TryParse(entry.Value, out var valueInt);
                                    var isFloat      = float.TryParse(entry.Value, out var valueFloat);
                                    switch (entry.Key)
                                    {
                                    case "BurstRounds":
                                    {
                                        var burstMax = valueInt * 2;
                                        entry.Value = (ThreadSafeRandom.Next(burstMax) + 1).ToString();
                                    }
                                    break;

                                    case "RateOfFireAI":
                                    case "DamageAI":
                                    {
                                        entry.Value = ThreadSafeRandom.NextFloat(.1, 2).ToString(CultureInfo.InvariantCulture);
                                    }
                                    break;

                                    case "RecoilInterpSpeed":
                                    case "RecoilFadeSpeed":
                                    case "RecoilZoomFadeSpeed":
                                    case "RecoilYawScale":
                                    case "RecoilYawFrequency":
                                    case "RecoilYawNoise":
                                    case "DamageHench":
                                    case "BurstRefireTime":
                                    case "ZoomAccFirePenalty":
                                    case "ZoomAccFireInterpSpeed":
                                    case "FirstHitDamage":
                                    case "SecondHitDamage":
                                    case "ThirdHitDamage":
                                    {
                                        entry.Value = ThreadSafeRandom.NextFloat(valueFloat / 2, valueFloat * 1.5).ToString(CultureInfo.InvariantCulture);
                                    }
                                    break;

                                    case "bIsAutomatic":
                                    {
                                        var curValue = bool.Parse(entry.Value);
                                        entry.Value = ThreadSafeRandom.Next(5) == 0 ? (!curValue).ToString() : entry.Value.ToString();
                                    }
                                    break;

                                    case "MinRefireTime":
                                    {
                                        entry.Value = ThreadSafeRandom.NextFloat(0.01, 1).ToString();
                                    }
                                    break;

                                    case "AccFirePenalty":
                                    case "AccFireInterpSpeed":
                                    {
                                        entry.Value = ThreadSafeRandom.NextFloat(0, valueFloat * 1.75).ToString(CultureInfo.InvariantCulture);
                                    }
                                    break;

                                    case "AmmoPerShot":
                                    {
                                        if (ThreadSafeRandom.Next(10) == 0)
                                        {
                                            entry.Value = "2";
                                        }
                                        // Otherwise do not change
                                    }
                                    break;

                                    case "AIBurstRefireTimeMin":
                                        entry.Value = ThreadSafeRandom.NextFloat(0, 2).ToString(CultureInfo.InvariantCulture);
                                        break;

                                    case "AIBurstRefireTimeMax":
                                        entry.Value = ThreadSafeRandom.NextFloat(1, 5).ToString(CultureInfo.InvariantCulture);
                                        break;

                                    case "MaxSpareAmmo":
                                        entry.Value = ThreadSafeRandom.Next(valueInt / 10, valueInt * 2).ToString(CultureInfo.InvariantCulture);
                                        break;

                                    default:
                                        Debug.WriteLine($"Undone key: {entry.Key}");
                                        break;
                                    }

                                    if (entry.Value != initialValue)
                                    {
                                        outSection.SetSingleEntry(entry.Key, entry.Value);
                                    }
                                }
                            }
                        }

                        // whats this do?
                        //if (section.Entries.All(x => x.Key != "Damage"))
                        //{
                        //    float X = ThreadSafeRandom.NextFloat(2, 7);
                        //    float Y = ThreadSafeRandom.NextFloat(2, 7);
                        //    section.Entries.Add(new DuplicatingIni.IniEntry($"Damage=(X={X},Y={Y})"));
                        //}
                    }
                }
            }
        }