using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using I2.Loc;
using Microsoft.CodeAnalysis;
using PerfectRandom.Sulfur.Core;
using PerfectRandom.Sulfur.Core.Items;
using PerfectRandom.Sulfur.Core.Stats;
using PerfectRandom.Sulfur.Core.UI.ItemDescription;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace SulfurWeaponStats
{
internal static class FireCycle
{
internal static string Text(WeaponSO so, float rpm)
{
float num = 60f / rpm;
bool actionLimited = false;
if ((Object)(object)so != (Object)null && so.rpm > 0 && ReloadData.Table.TryGetValue(((Object)so).name, out var value) && value.Cycle > 0f)
{
float num2 = value.Cycle * (float)so.rpm / rpm;
if (num2 > num + 0.0005f)
{
num = num2;
actionLimited = true;
}
}
return Strings.FireIntervalValue(num.ToString("0.000"), rpm.ToString("0"), actionLimited);
}
}
internal static class ModifierText
{
internal const float BulletBaseMass = 3f;
internal static readonly MethodInfo AddAttribute = AccessTools.Method(typeof(ItemDescription), "AddAttribute", (Type[])null, (Type[])null);
private static readonly FieldRef<ItemDescription, ItemDefinition> ItemDefRef = AccessTools.FieldRefAccess<ItemDescription, ItemDefinition>("itemDefinition");
private static bool _errorLogged;
internal static ItemDefinition CurrentItem(ItemDescription desc)
{
return ItemDefRef.Invoke(desc);
}
internal static void LogOnce(Exception e)
{
if (!_errorLogged)
{
_errorLogged = true;
Plugin.Log.LogError((object)("Failed to rewrite modifier text: " + e));
}
}
internal static string Label(ItemAttributes attr)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
string result = default(string);
if (LocalizationManager.TryGetTranslation($"ItemAttributes/{attr}_itemDescription", ref result, true, 0, true, false, (GameObject)null, (string)null, true))
{
return result;
}
return AssetAccess.GetAsset(attr)?.itemDescriptionName;
}
internal static bool IsSimplifiedText(ItemAttributes attr, string text)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
ItemAttribute asset = AssetAccess.GetAsset(attr);
if ((Object)(object)asset == (Object)null)
{
return false;
}
string text3 = default(string);
string text2 = (LocalizationManager.TryGetTranslation($"ItemAttributes/{attr}_simplifiedIncrease", ref text3, true, 0, true, false, (GameObject)null, (string)null, true) ? text3 : asset.simplifiedIncreaseString);
string text5 = default(string);
string text4 = (LocalizationManager.TryGetTranslation($"ItemAttributes/{attr}_simplifiedDecrease", ref text5, true, 0, true, false, (GameObject)null, (string)null, true) ? text5 : asset.simplifiedDecreaseString);
if (!(text == text2))
{
return text == text4;
}
return true;
}
internal static IEnumerable<ItemModifierContainer> Modifiers(ItemDefinition def)
{
if ((Object)(object)def == (Object)null)
{
yield break;
}
if (((EnchantmentId)(ref def.appliesEnchantment)).IsValid)
{
EnchantmentDefinition asset = AssetAccess.GetAsset(def.appliesEnchantment);
if ((Object)(object)asset != (Object)null && asset.modifiersApplied != null)
{
foreach (ItemModifierContainer item in asset.modifiersApplied)
{
yield return item;
}
}
}
if (def.modifiersOnAttachToItem == null)
{
yield break;
}
foreach (ItemModifierContainer item2 in def.modifiersOnAttachToItem)
{
yield return item2;
}
}
internal static bool TryGetFlat(ItemDefinition def, ItemAttributes attr, out float value)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Invalid comparison between Unknown and I4
value = 0f;
bool result = false;
foreach (ItemModifierContainer item in Modifiers(def))
{
if (item.attribute == attr && (int)item.modType == 100)
{
value += item.value;
result = true;
}
}
return result;
}
internal static string ForceText(float force)
{
return Strings.MuzzleVelocityFactor((1f + force).ToString("0.##"));
}
}
[HarmonyPatch(typeof(ItemDescription), "AddAttribute")]
internal static class ModifierAttributePatch
{
private static void Prefix(ItemDescription __instance, ref string key, ref string value)
{
try
{
ItemDefinition val = ModifierText.CurrentItem(__instance);
if (!((Object)(object)val == (Object)null) && !(val is WeaponSO) && !string.IsNullOrEmpty(key))
{
if (key == ModifierText.Label((ItemAttributes)41) && value != null && value.StartsWith("x") && float.TryParse(value.Substring(1), NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
{
float num = 3f / (3f + result);
key = Strings.BulletMass;
value = Strings.BulletMassValue(result.ToString("+0.##;-0.##"), num.ToString("0.##"));
}
else if (key == ModifierText.Label((ItemAttributes)61))
{
value += Strings.SameTrajectory;
}
}
}
catch (Exception e)
{
ModifierText.LogOnce(e);
}
}
}
[HarmonyPatch(typeof(ItemDescription), "AddDescriptionText")]
internal static class ModifierDescriptionPatch
{
private static void Prefix(ItemDescription __instance, ref string descriptionText)
{
try
{
ItemDefinition val = ModifierText.CurrentItem(__instance);
if (!((Object)(object)val == (Object)null) && !(val is WeaponSO) && !string.IsNullOrEmpty(descriptionText))
{
float value2;
if (ModifierText.IsSimplifiedText((ItemAttributes)65, descriptionText) && ModifierText.TryGetFlat(val, (ItemAttributes)65, out var value))
{
descriptionText = Strings.DragLine(value.ToString("+0.##;-0.##"), (0f - value).ToString("+0.##;-0.##"));
}
else if (ModifierText.IsSimplifiedText((ItemAttributes)60, descriptionText) && ModifierText.TryGetFlat(val, (ItemAttributes)60, out value2))
{
descriptionText = ModifierText.ForceText(value2);
}
}
}
catch (Exception e)
{
ModifierText.LogOnce(e);
}
}
}
[HarmonyPatch(typeof(ItemDescription), "AddFlavorText")]
internal static class HiddenForcePatch
{
private static void Prefix(ItemDescription __instance, ItemDefinition item, ref int childIndex)
{
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: Invalid comparison between Unknown and I4
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Invalid comparison between Unknown and I4
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Invalid comparison between Unknown and I4
try
{
if ((Object)(object)item == (Object)null || item is WeaponSO || !((EnchantmentId)(ref item.appliesEnchantment)).IsValid || ModifierText.AddAttribute == null)
{
return;
}
ItemAttribute asset = AssetAccess.GetAsset((ItemAttributes)60);
if ((Object)(object)asset == (Object)null || asset.showInItemDescription)
{
return;
}
EnchantmentDefinition asset2 = AssetAccess.GetAsset(item.appliesEnchantment);
if ((Object)(object)asset2 == (Object)null || asset2.modifiersApplied == null)
{
return;
}
float num = 0f;
bool flag = false;
bool flag2 = false;
foreach (ItemModifierContainer item2 in asset2.modifiersApplied)
{
if ((int)item2.attribute == 39)
{
flag2 = true;
}
if ((int)item2.attribute == 60 && (int)item2.modType == 100)
{
num += item2.value;
flag = true;
}
}
if (!(!flag || flag2))
{
object[] array = new object[5]
{
Strings.MuzzleVelocity,
childIndex,
"x" + (1f + num).ToString("0.##"),
"",
false
};
ModifierText.AddAttribute.Invoke(__instance, array);
childIndex = (int)array[1];
}
}
catch (Exception e)
{
ModifierText.LogOnce(e);
}
}
}
[BepInPlugin("ericszh.sulfur.weaponstats", "Weapon Stats Plus", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
public const string Guid = "ericszh.sulfur.weaponstats";
public const string Name = "Weapon Stats Plus";
public const string Version = "1.0.0";
internal static ManualLogSource Log;
private void Awake()
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
Strings.Language = ((BaseUnityPlugin)this).Config.Bind<Strings.LanguageMode>("General", "Language", Strings.LanguageMode.Auto, "Tooltip language. Auto follows the game language (Chinese if the game is in Chinese, otherwise English).");
new Harmony("ericszh.sulfur.weaponstats").PatchAll();
Log.LogInfo((object)"Weapon Stats Plus 1.0.0 loaded.");
}
}
[HarmonyPatch(typeof(ItemDescription), "AddDurability")]
internal static class AddDurabilityPatch
{
private const float Gravity = 20f;
private const float SpeedCap = 200f;
private const float DropDistance = 50f;
private const float LandingHeight = 1.5f;
private static readonly Dictionary<string, float> ChargeTime = new Dictionary<string, float> { { "Weapon_D4RT", 0.75f } };
private static readonly MethodInfo AddAttribute = AccessTools.Method(typeof(ItemDescription), "AddAttribute", (Type[])null, (Type[])null);
private static bool _errorLogged;
private static void Prefix(ItemDescription __instance, InventoryItem item, ref int childIndex)
{
try
{
if (!((Object)(object)item == (Object)null) && !(AddAttribute == null))
{
WeaponSO weaponDefinition = item.weaponDefinition;
ItemStats stats = item.stats;
if (!((Object)(object)weaponDefinition == (Object)null) && stats != null && !weaponDefinition.IsMelee && !weaponDefinition.IsThrowable)
{
AddHiddenRpmInterval(__instance, weaponDefinition, stats, ref childIndex);
AddCharge(__instance, weaponDefinition, stats, ref childIndex);
AddRecoil(__instance, item, stats, ref childIndex);
AddBallistics(__instance, weaponDefinition, stats, ref childIndex);
AddReload(__instance, weaponDefinition, stats, ref childIndex);
}
}
}
catch (Exception ex)
{
if (!_errorLogged)
{
_errorLogged = true;
Plugin.Log.LogError((object)("Failed to add weapon stats: " + ex));
}
}
}
private static void Add(ItemDescription desc, string key, string value, ref int childIndex)
{
object[] array = new object[5] { key, childIndex, value, "", false };
AddAttribute.Invoke(desc, array);
childIndex = (int)array[1];
}
private static string Mult(float m)
{
if (!(Mathf.Abs(m - 1f) > 0.001f))
{
return "";
}
return $" (x{m:0.##})";
}
private static void AddHiddenRpmInterval(ItemDescription desc, WeaponSO so, ItemStats st, ref int childIndex)
{
if (so.hideRpm && so.firesByTrigger)
{
float attribute = st.GetAttribute((ItemAttributes)56);
if (!(attribute <= 0f))
{
Add(desc, Strings.FireInterval, FireCycle.Text(so, attribute), ref childIndex);
}
}
}
private static void AddCharge(ItemDescription desc, WeaponSO so, ItemStats st, ref int childIndex)
{
if (ChargeTime.TryGetValue(((Object)so).name, out var value) && so.rpm > 0)
{
float attribute = st.GetAttribute((ItemAttributes)56);
if (!(attribute <= 0f))
{
float num = value / Mathf.Clamp(attribute / (float)so.rpm, 0.01f, 10f);
float num2 = num + 60f / attribute;
Add(desc, Strings.Charge, Strings.ChargeCycle(num.ToString("0.00"), num2.ToString("0.00")), ref childIndex);
}
}
}
private static void AddRecoil(ItemDescription desc, InventoryItem item, ItemStats st, ref int childIndex)
{
float attribute = st.GetAttribute((ItemAttributes)19);
float num = Mathf.Clamp(attribute * item.KickPower, 0f, 999f);
Add(desc, Strings.Recoil, num.ToString("0.##") + Mult(attribute), ref childIndex);
}
private static void AddBallistics(ItemDescription desc, WeaponSO so, ItemStats st, ref int childIndex)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Invalid comparison between Unknown and I4
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
if (st.GetAttribute((ItemAttributes)113) > 0f)
{
Add(desc, Strings.BulletSpeed, Strings.Beam, ref childIndex);
return;
}
if ((int)so.projectileType == 4 || st.GetAttribute((ItemAttributes)39) > 0f)
{
Add(desc, Strings.BulletSpeed, Strings.Rocket, ref childIndex);
return;
}
ProjectileDefinition asset = AssetAccess.GetAsset(so.projectileType);
if ((Object)(object)asset == (Object)null)
{
return;
}
float num = asset.mass + st.GetAttribute((ItemAttributes)41);
if (num <= 0f)
{
return;
}
float num2 = so.bulletSpeed * (1f + st.GetAttribute((ItemAttributes)60)) / num;
float num3 = Mathf.Min(num2, 200f);
float num4 = Mathf.Clamp(st.GetAttribute((ItemAttributes)61), 0.01f, 10f);
bool flag = st.GetAttribute((ItemAttributes)62) > 0f;
string value = ((num2 > 200f) ? $"{num2:0} m/s ({Strings.CappedAt} {200f:0})" : $"{num2:0} m/s");
Add(desc, Strings.MuzzleVelocity, value, ref childIndex);
Add(desc, Strings.BulletSpeed, flag ? Strings.Hitscan : $"{num3 * num4:0} m/s", ref childIndex);
if (!(num3 <= 0.01f))
{
float num5 = 20f * asset.gravityFactor * st.GetAttribute((ItemAttributes)102);
if (!(num5 <= 0f))
{
float drag = Mathf.Max(0f, asset.drag + st.GetAttribute((ItemAttributes)65));
float? num6 = DropAtDistance(num3, drag, num5, 50f);
string value2 = ((!num6.HasValue) ? "-" : ((num6.Value > 99f) ? ">99 m" : $"{num6.Value:0.0} m"));
Add(desc, Strings.DropAt(50f), value2, ref childIndex);
float num7 = DistanceAtDrop(num3, drag, num5, 1.5f);
Add(desc, Strings.Landing(1.5f), $"{num7:0} m", ref childIndex);
}
}
}
private static float? DropAtDistance(float v0, float drag, float g, float distance)
{
if (drag < 0.0001f)
{
float num = distance / v0;
return 0.5f * g * num * num;
}
float num2 = distance * drag / v0;
if (num2 >= 1f)
{
return null;
}
float num3 = (0f - Mathf.Log(1f - num2)) / drag;
return g / drag * (num3 - distance / v0);
}
private static float DistanceAtDrop(float v0, float drag, float g, float height)
{
if (drag < 0.0001f)
{
return v0 * Mathf.Sqrt(2f * height / g);
}
float num = 0f;
float num2 = height * drag / g + 1f / drag;
for (int i = 0; i < 60; i++)
{
float num3 = 0.5f * (num + num2);
if (g / drag * (num3 - (1f - Mathf.Exp((0f - drag) * num3)) / drag) < height)
{
num = num3;
}
else
{
num2 = num3;
}
}
return v0 * (1f - Mathf.Exp((0f - drag) * num)) / drag;
}
private static void AddReload(ItemDescription desc, WeaponSO so, ItemStats st, ref int childIndex)
{
if (!ReloadData.Table.TryGetValue(((Object)so).name, out var value))
{
return;
}
float num = Mathf.Clamp(st.GetAttribute((ItemAttributes)55), 0.01f, 10f);
string text = Mult(num);
switch (value.Kind)
{
case 1:
{
float num4 = value.Empty / num;
float num5 = ((value.Partial > 0f) ? value.Partial : value.Empty) / num;
string text3 = $"{num5:0.00} s";
if (value.EmptyLoaded < value.Mag)
{
text3 += Strings.EmptyPartialLoad(num4.ToString("0.00"), value.EmptyLoaded);
}
else if (Mathf.Abs(num4 - num5) > 0.05f)
{
text3 += Strings.Empty(num4.ToString("0.00"));
}
Add(desc, Strings.Reload, text3 + text, ref childIndex);
break;
}
case 2:
{
string text2 = Strings.ShellLoad((value.PerShell > 1) ? Strings.PerClip(value.PerShell) : Strings.PerRound, (value.Shell / num).ToString("0.00"), (value.Empty / num).ToString("0.0"));
Add(desc, Strings.Loading, text2 + text, ref childIndex);
break;
}
case 3:
{
float num2 = value.Fixed + value.ShellEvent / num;
float num3 = value.Fixed + value.Empty / num;
Add(desc, Strings.Loading, Strings.HoldLoad(num2.ToString("0.00"), value.Mag, num3.ToString("0.0")) + text, ref childIndex);
break;
}
}
}
}
internal readonly struct R
{
public readonly int Kind;
public readonly float Empty;
public readonly int EmptyLoaded;
public readonly float Partial;
public readonly float Start;
public readonly float Shell;
public readonly float ShellEvent;
public readonly int PerShell;
public readonly float Fixed;
public readonly int Mag;
public readonly float Cycle;
public R(int kind, float empty, int emptyLoaded, float partial, float start, float shell, float shellEvent, int perShell, float fixedPart, int mag, float cycle)
{
Kind = kind;
Empty = empty;
EmptyLoaded = emptyLoaded;
Partial = partial;
Start = start;
Shell = shell;
ShellEvent = shellEvent;
PerShell = perShell;
Fixed = fixedPart;
Mag = mag;
Cycle = cycle;
}
}
internal static class ReloadData
{
public static readonly Dictionary<string, R> Table = new Dictionary<string, R>
{
{
"Weapon_Arbiter2",
new R(1, 3.1f, 3, 3.1f, 0f, 0f, 0f, 0, 0f, 3, 0f)
},
{
"Weapon_Augusta",
new R(1, 3.117f, 6, 2.717f, 0f, 0f, 0f, 0, 0f, 6, 0.233f)
},
{
"Weapon_Balthazar",
new R(1, 3.233f, 4, 3.233f, 0f, 0f, 0f, 0, 0f, 4, 0f)
},
{
"Weapon_Beck",
new R(1, 2.35f, 26, 1.967f, 0f, 0f, 0f, 0, 0f, 26, 0f)
},
{
"Weapon_Blackwater",
new R(1, 3.6f, 8, 2.917f, 0f, 0f, 0f, 0, 0f, 12, 0f)
},
{
"Weapon_Breacher8",
new R(3, 4.433f, 8, 0f, 0f, 0.55f, 0.367f, 0, 0.833f, 8, 0f)
},
{
"Weapon_Bronco",
new R(2, 6.263f, 10, 0f, 0.833f, 0.583f, 0.183f, 1, 0f, 10, 0f)
},
{
"Weapon_CYB47",
new R(1, 2.983f, 47, 2.983f, 0f, 0f, 0f, 0, 0f, 47, 0f)
},
{
"Weapon_Catacoil",
new R(1, 2.517f, 30, 2.517f, 0f, 0f, 0f, 0, 0f, 30, 0f)
},
{
"Weapon_Cavalier",
new R(1, 2.233f, 30, 1.717f, 0f, 0f, 0f, 0, 0f, 30, 0f)
},
{
"Weapon_Chat-Pardeur98",
new R(1, 4.383f, 20, 4.383f, 0f, 0f, 0f, 0, 0f, 20, 0.167f)
},
{
"Weapon_ChimeraRapid",
new R(1, 3.217f, 22, 2.25f, 0f, 0f, 0f, 0, 0f, 22, 0f)
},
{
"Weapon_Corpsemaker",
new R(1, 2.3f, 30, 1.55f, 0f, 0f, 0f, 0, 0f, 30, 0f)
},
{
"Weapon_D4RT",
new R(1, 1.133f, 1, 1.133f, 0f, 0f, 0f, 0, 0f, 1, 0f)
},
{
"Weapon_DeathStar",
new R(1, 3.267f, 15, 0f, 0f, 0f, 0f, 0, 0f, 15, 0f)
},
{
"Weapon_DeathsToll",
new R(2, 1.649f, 4, 0f, 0.5f, 0.333f, 0.15f, 1, 0f, 4, 0f)
},
{
"Weapon_Dirk",
new R(1, 2.85f, 7, 2.65f, 0f, 0f, 0f, 0, 0f, 7, 0f)
},
{
"Weapon_Dolphin99",
new R(1, 2.033f, 5, 3.25f, 0f, 0f, 0f, 0, 0f, 5, 2.6f)
},
{
"Weapon_Drifter9",
new R(1, 2.167f, 20, 2.167f, 0f, 0f, 0f, 0, 0f, 20, 0f)
},
{
"Weapon_Duhar",
new R(1, 2.567f, 40, 2.567f, 0f, 0f, 0f, 0, 0f, 40, 0f)
},
{
"Weapon_Farsight",
new R(1, 3.117f, 8, 2.583f, 0f, 0f, 0f, 0, 0f, 8, 0.217f)
},
{
"Weapon_Ferryman",
new R(1, 4.35f, 20, 3.617f, 0f, 0f, 0f, 0, 0f, 20, 0f)
},
{
"Weapon_FlickerZip",
new R(1, 2.733f, 5, 0f, 0f, 0f, 0f, 0, 0f, 5, 0f)
},
{
"Weapon_Flock",
new R(1, 2.983f, 10, 2.567f, 0f, 0f, 0f, 0, 0f, 10, 0f)
},
{
"Weapon_Gravekeeper",
new R(1, 1.933f, 7, 1.8f, 0f, 0f, 0f, 0, 0f, 7, 0f)
},
{
"Weapon_HellnBack",
new R(1, 2.95f, 14, 2.717f, 0f, 0f, 0f, 0, 0f, 14, 0f)
},
{
"Weapon_ImpalaGravita",
new R(1, 2.8f, 8, 2.8f, 0f, 0f, 0f, 0, 0f, 8, 0.75f)
},
{
"Weapon_KleinBauer",
new R(1, 3.2f, 138, 2.717f, 0f, 0f, 0f, 0, 0f, 138, 0f)
},
{
"Weapon_Knop",
new R(1, 1f, 1, 1f, 0f, 0f, 0f, 0, 0f, 1, 0.283f)
},
{
"Weapon_LilyOfTheNight",
new R(1, 3.867f, 70, 3.033f, 0f, 0f, 0f, 0, 0f, 70, 0f)
},
{
"Weapon_Longboy",
new R(2, 3.183f, 6, 0f, 1.1f, 0.5f, 0.317f, 1, 0f, 6, 0f)
},
{
"Weapon_M11Ramshack",
new R(1, 2.367f, 30, 1.917f, 0f, 0f, 0f, 0, 0f, 30, 0f)
},
{
"Weapon_Majordome",
new R(2, 4.748f, 6, 0f, 1f, 0.533f, 0.217f, 1, 0f, 6, 0f)
},
{
"Weapon_Mario",
new R(1, 2.6f, 2, 2.2f, 0f, 0f, 0f, 0, 0f, 2, 0.25f)
},
{
"Weapon_Mossman",
new R(2, 4.5f, 6, 0f, 0.667f, 0.5f, 0.267f, 1, 0f, 6, 1.217f)
},
{
"Weapon_Mowlock",
new R(1, 3.633f, 20, 2.533f, 0f, 0f, 0f, 0, 0f, 20, 0f)
},
{
"Weapon_NeuraxisF22",
new R(2, 34.817f, 100, 0f, 0.1f, 0.333f, 0.133f, 1, 0f, 100, 0f)
},
{
"Weapon_PalehorseTopclipper",
new R(1, 2.25f, 7, 2.25f, 0f, 0f, 0f, 0, 0f, 7, 0.917f)
},
{
"Weapon_PierreFusil",
new R(1, 1.983f, 6, 1.983f, 0f, 0f, 0f, 0, 0f, 6, 0.333f)
},
{
"Weapon_PloikaC",
new R(1, 2.65f, 40, 1.65f, 0f, 0f, 0f, 0, 0f, 40, 0f)
},
{
"Weapon_RamshackOld_NOT_USED",
new R(1, 2.583f, 30, 1.683f, 0f, 0f, 0f, 0, 0f, 30, 0f)
},
{
"Weapon_Rektor",
new R(1, 5.55f, 100, 5.55f, 0f, 0f, 0f, 0, 0f, 100, 0f)
},
{
"Weapon_Rokua",
new R(1, 2.25f, 5, 2.25f, 0f, 0f, 0f, 0, 0f, 5, 1.283f)
},
{
"Weapon_Salamander",
new R(1, 2.783f, 8, 2.15f, 0f, 0f, 0f, 0, 0f, 8, 0f)
},
{
"Weapon_Snut38",
new R(1, 3f, 6, 3f, 0f, 0f, 0f, 0, 0f, 6, 0f)
},
{
"Weapon_Socom9",
new R(1, 1.85f, 12, 1.417f, 0f, 0f, 0f, 0, 0f, 12, 0f)
},
{
"Weapon_SocomACR",
new R(1, 3.567f, 42, 3f, 0f, 0f, 0f, 0, 0f, 42, 0f)
},
{
"Weapon_Songbird",
new R(1, 3.167f, 40, 2.433f, 0f, 0f, 0f, 0, 0f, 40, 0f)
},
{
"Weapon_StarAndWitness",
new R(1, 3.267f, 30, 1.917f, 0f, 0f, 0f, 0, 0f, 30, 0f)
},
{
"Weapon_TailorMarksman",
new R(1, 4.2f, 8, 3.733f, 0f, 0f, 0f, 0, 0f, 8, 0f)
},
{
"Weapon_Termite",
new R(2, 9f, 30, 0f, 0.5f, 0.75f, 0.35f, 3, 0f, 30, 0f)
},
{
"Weapon_TerrierURB",
new R(1, 2.817f, 14, 2.2f, 0f, 0f, 0f, 0, 0f, 14, 0f)
},
{
"Weapon_Typhoon",
new R(1, 2.9f, 20, 2.9f, 0f, 0f, 0f, 0, 0f, 20, 0f)
},
{
"Weapon_Unknown",
new R(1, 2.85f, 10, 2.85f, 0f, 0f, 0f, 0, 0f, 10, 0f)
},
{
"Weapon_Valet",
new R(1, 2.4f, 24, 1.933f, 0f, 0f, 0f, 0, 0f, 24, 0f)
},
{
"Weapon_Vrede",
new R(1, 2.567f, 30, 1.817f, 0f, 0f, 0f, 0, 0f, 30, 0f)
},
{
"Weapon_Warpig",
new R(1, 3.9f, 55, 2.9f, 0f, 0f, 0f, 0, 0f, 55, 0f)
},
{
"Weapon_Wingman",
new R(1, 3.933f, 18, 1.833f, 0f, 0f, 0f, 0, 0f, 18, 0f)
},
{
"Weapon_WyattPulsar",
new R(1, 2.15f, 18, 2.15f, 0f, 0f, 0f, 0, 0f, 18, 0f)
}
};
}
[HarmonyPatch(typeof(ItemDescription), "AddAttribute")]
internal static class RpmLinePatch
{
private static void Prefix(ItemDescription __instance, ref string key, ref string value, ref bool skipSeparator)
{
string value2 = Traverse.Create((object)__instance).Field("localizedTextsCache").Field("Label_RPM")
.GetValue<string>();
if (!string.IsNullOrEmpty(value2) && !(value != value2) && int.TryParse(key, out var result) && result > 0)
{
key = Strings.FireInterval;
ItemDefinition obj = ModifierText.CurrentItem(__instance);
value = FireCycle.Text((WeaponSO)(object)((obj is WeaponSO) ? obj : null), result);
skipSeparator = false;
}
}
}
internal static class Strings
{
internal enum LanguageMode
{
Auto,
English,
Chinese
}
internal static ConfigEntry<LanguageMode> Language;
private static bool Zh
{
get
{
switch (Language?.Value ?? LanguageMode.Auto)
{
case LanguageMode.English:
return false;
case LanguageMode.Chinese:
return true;
default:
{
string currentLanguageCode = LocalizationManager.CurrentLanguageCode;
if (!string.IsNullOrEmpty(currentLanguageCode))
{
return currentLanguageCode.StartsWith("zh");
}
return false;
}
}
}
}
public static string Recoil => T("后坐力", "Recoil");
public static string MuzzleVelocity => T("出膛速度", "Muzzle velocity");
public static string BulletSpeed => T("弹速", "Bullet speed");
public static string Beam => T("光束", "Beam");
public static string Hitscan => T("射线, 瞬间命中", "Hitscan (railgun)");
public static string Rocket => T("火箭", "Rocket");
public static string BulletMass => T("子弹质量", "Bullet mass");
public static string SameTrajectory => T(" (弹道不变)", " (same trajectory)");
public static string Reload => T("换弹", "Reload");
public static string Loading => T("装填", "Loading");
public static string PerRound => T("每发", "per round");
public static string FireInterval => T("射击间隔", "Fire interval");
public static string CappedAt => T("上限", "capped at");
public static string Charge => T("蓄力", "Charge");
private static string T(string zh, string en)
{
if (!Zh)
{
return en;
}
return zh;
}
public static string DropAt(float meters)
{
return T($"{meters:0} m 下坠", $"Drop at {meters:0} m");
}
public static string Landing(float height)
{
return T($"平射落地 ({height:0.#} m 高)", $"Flat shot lands ({height:0.#} m high)");
}
public static string BulletMassValue(string mass, string factor)
{
return T(mass + " (普通子弹出膛速度 x" + factor + ")", mass + " (regular bullets: muzzle velocity x" + factor + ")");
}
public static string DragLine(string drag, string perMeter)
{
return T("空气阻力 " + drag + ": 每飞 1 m 速度 " + perMeter + " m/s", "Drag " + drag + ": " + perMeter + " m/s speed per metre flown");
}
public static string MuzzleVelocityFactor(string factor)
{
return T("出膛速度 x" + factor, "Muzzle velocity x" + factor);
}
public static string EmptyPartialLoad(string seconds, int rounds)
{
return T($" (打空 {seconds} s, 只装 {rounds} 发)", $" (empty {seconds} s, loads {rounds} only)");
}
public static string Empty(string seconds)
{
return T(" (打空 " + seconds + " s)", " (empty " + seconds + " s)");
}
public static string PerClip(int rounds)
{
return T($"每组{rounds}发", $"per {rounds}-round clip");
}
public static string ShellLoad(string unit, string per, string full)
{
return T(unit + " " + per + " s, 空到满 " + full + " s", per + " s " + unit + ", empty to full " + full + " s");
}
public static string HoldLoad(string first, int mag, string full)
{
return T($"首发 {first} s, 满 {mag} 发 {full} s", $"first round {first} s, full {mag} rounds {full} s");
}
public static string FireIntervalValue(string seconds, string rpm, bool actionLimited)
{
if (!actionLimited)
{
return seconds + " s (" + rpm + " RPM)";
}
return T(seconds + " s (" + rpm + " RPM, 受动作限制)", seconds + " s (" + rpm + " RPM, action-limited)");
}
public static string ChargeCycle(string charge, string cycle)
{
return T(charge + " s, 每发循环 " + cycle + " s", charge + " s, full cycle " + cycle + " s");
}
}
}