Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of TonySoprano v0.11.0
plugins/TonySoprano/TonySoprano.dll
Decompiled 7 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using EntityStates; using EntityStates.AI.Walker; using EntityStates.Commando.CommandoWeapon; using Microsoft.CodeAnalysis; using On.RoR2; using R2API; using R2API.Networking; using R2API.Networking.Interfaces; using R2API.Utils; using RoR2; using RoR2.CharacterAI; using RoR2.ConVar; using RoR2.Skills; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("TonySoprano")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.11.0.0")] [assembly: AssemblyInformationalVersion("0.11.0")] [assembly: AssemblyProduct("TonySoprano")] [assembly: AssemblyTitle("TonySoprano")] [assembly: AssemblyVersion("0.11.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 TonySoprano { internal sealed class CrewCopyLedger { private readonly Dictionary<int, List<int>> roles = new Dictionary<int, List<int>>(); internal int Count(int item) { if (!roles.TryGetValue(item, out List<int> value)) { return 0; } return value.Count; } internal void Granted(int item, int role) { if (!roles.TryGetValue(item, out List<int> value)) { value = (roles[item] = new List<int>()); } value.Add(role); } internal int RemoveLast(int item) { List<int> list = roles[item]; int index = list.Count - 1; int result = list[index]; list.RemoveAt(index); if (list.Count == 0) { roles.Remove(item); } return result; } } internal sealed class CrewInventorySnapshot { private readonly Dictionary<int, int> items = new Dictionary<int, int>(); internal IEnumerable<KeyValuePair<int, int>> Items => items; internal IEnumerable<KeyValuePair<int, int>> MissingFrom(Func<int, int> count) { foreach (KeyValuePair<int, int> item in items) { int num = item.Value - count(item.Key); if (num > 0) { yield return new KeyValuePair<int, int>(item.Key, num); } } } internal void Capture(IEnumerable<KeyValuePair<int, int>> current) { items.Clear(); foreach (KeyValuePair<int, int> item in current) { if (item.Value > 0) { items[item.Key] = item.Value; } } } } internal static class FoodBalance { internal static float DamageBonus(int stacks) { return 0.05f * (float)stacks; } internal static float BarrierFraction(int stacks) { return 0.15f; } internal static float HealthAfterCost(float health, float fullHealth, int stacks) { return Math.Max(0f, health - fullHealth * CostFraction(stacks)); } internal static float CostFraction(int stacks) { return (float)(0.01 * Math.Pow(2.0, stacks)); } } internal static class GoonAbilities { internal static IEnumerable<CharacterBody> NearbyCrew(CharacterBody caster) { CharacterMaster owner = SopranoCrew.Owner(caster); if (!Object.op_Implicit((Object)(object)owner)) { yield break; } foreach (CharacterBody readOnlyInstances in CharacterBody.readOnlyInstancesList) { SopranoIdentity sopranoIdentity = (Object.op_Implicit((Object)(object)readOnlyInstances) ? ((Component)readOnlyInstances).GetComponent<SopranoIdentity>() : null); if (Object.op_Implicit((Object)(object)sopranoIdentity) && !sopranoIdentity.IsTony && Object.op_Implicit((Object)(object)readOnlyInstances.healthComponent) && readOnlyInstances.healthComponent.alive && !((Object)(object)SopranoCrew.Owner(readOnlyInstances) != (Object)(object)owner)) { Vector3 val = readOnlyInstances.corePosition - caster.corePosition; if (((Vector3)(ref val)).sqrMagnitude <= 400f) { yield return readOnlyInstances; } } } } internal static CharacterBody? HealTarget(CharacterBody caster, bool special) { return (from b in NearbyCrew(caster) where GoonBalance.HealingReady(b.healthComponent.health / Mathf.Max(1f, b.healthComponent.fullHealth), special) orderby b.healthComponent.health / Mathf.Max(1f, b.healthComponent.fullHealth) select b).FirstOrDefault(); } internal static bool CanUse(CharacterBody body, Type state) { SopranoIdentity sopranoIdentity = (Object.op_Implicit((Object)(object)body) ? ((Component)body).GetComponent<SopranoIdentity>() : null); if (!Object.op_Implicit((Object)(object)sopranoIdentity) || sopranoIdentity.IsTony || !body.healthComponent.alive || !Object.op_Implicit((Object)(object)SopranoCrew.Owner(body))) { return false; } if (state == typeof(TakeABreather) || state == typeof(BingsHospitality)) { if (sopranoIdentity.role == 1) { return Object.op_Implicit((Object)(object)HealTarget(body, state == typeof(BingsHospitality))); } return false; } if (state == typeof(TriggerHappy) || state == typeof(LooseCannon)) { if (sopranoIdentity.role != 2) { return false; } } else { if (!(state == typeof(WatchYourStep)) && !(state == typeof(OnThePayroll))) { return false; } if (sopranoIdentity.role != 0) { return false; } } return GoonTargeting.CanAttack(body, state == typeof(TriggerHappy) || state == typeof(WatchYourStep)); } } public sealed class GoonSkillDef : SkillDef { public override bool IsReady(GenericSkill slot) { if (Object.op_Implicit((Object)(object)slot.characterBody) && GoonAbilities.CanUse(slot.characterBody, ((SerializableEntityStateType)(ref base.activationState)).stateType)) { return ((SkillDef)this).IsReady(slot); } return false; } public override bool CanExecute(GenericSkill slot) { if (Object.op_Implicit((Object)(object)slot.characterBody) && GoonAbilities.CanUse(slot.characterBody, ((SerializableEntityStateType)(ref base.activationState)).stateType)) { return ((SkillDef)this).CanExecute(slot); } return false; } } public abstract class GoonAbilityState : BaseState { protected virtual float Duration => 0.3f; public override void FixedUpdate() { ((EntityState)this).FixedUpdate(); if (((EntityState)this).isAuthority && ((EntityState)this).fixedAge >= Duration) { ((EntityState)this).outer.SetNextStateToMain(); } } public override InterruptPriority GetMinimumInterruptPriority() { return (InterruptPriority)2; } } public abstract class GoonPistolAbility : GoonAbilityState { [CompilerGenerated] private static class <>O { public static HitCallback <0>__SlowHit; } protected void Shoot(int pistol, bool slow = false) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Expected O, but got Unknown //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Expected O, but got Unknown if (NetworkServer.active && !GoonTargeting.CanAttack(((EntityState)this).characterBody, requireAim: true)) { return; } Ray aimRay = ((BaseState)this).GetAimRay(); ((BaseState)this).StartAimMode(aimRay, 3f, false); bool flag = pistol % 2 == 0; string text = (flag ? "MuzzleLeft" : "MuzzleRight"); ((EntityState)this).PlayAnimation(flag ? "Gesture Additive, Left" : "Gesture Additive, Right", flag ? "FirePistol, Left" : "FirePistol, Right"); Util.PlaySound(FirePistol2.firePistolSoundString, ((EntityState)this).gameObject); GameObject muzzleEffectPrefab = FirePistol2.muzzleEffectPrefab; if (Object.op_Implicit((Object)(object)muzzleEffectPrefab)) { EffectManager.SimpleMuzzleFlash(muzzleEffectPrefab, ((EntityState)this).gameObject, text, false); } if (!((EntityState)this).isAuthority) { return; } BulletAttack val = new BulletAttack { owner = ((EntityState)this).gameObject, weapon = ((EntityState)this).gameObject, origin = ((Ray)(ref aimRay)).origin, aimVector = ((Ray)(ref aimRay)).direction, damage = ((BaseState)this).damageStat * FirePistol2.damageCoefficient, bulletCount = 1u, isCrit = ((BaseState)this).RollCrit(), force = FirePistol2.force, minSpread = 0f, maxSpread = ((EntityState)this).characterBody.spreadBloomAngle, radius = 0.1f, smartCollision = true, procCoefficient = 1f, muzzleName = text, trajectoryAimAssistMultiplier = FirePistol2.trajectoryAimAssistMultiplier, tracerEffectPrefab = FirePistol2.tracerEffectPrefab, hitEffectPrefab = FirePistol2.hitEffectPrefab }; if (slow) { object obj = <>O.<0>__SlowHit; if (obj == null) { HitCallback val2 = SlowHit; <>O.<0>__SlowHit = val2; obj = (object)val2; } val.hitCallback = (HitCallback)obj; } val.Fire(); ((EntityState)this).characterBody.AddSpreadBloom(FirePistol2.spreadBloomValue); } private static bool SlowHit(BulletAttack bullet, ref BulletHit hit) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) bool result = BulletAttack.defaultHitCallback.Invoke(bullet, ref hit); HurtBox hitHurtBox = hit.hitHurtBox; CharacterBody val = ((Object.op_Implicit((Object)(object)hitHurtBox) && Object.op_Implicit((Object)(object)hitHurtBox.healthComponent)) ? hitHurtBox.healthComponent.body : null); if (NetworkServer.active && Object.op_Implicit((Object)(object)val) && val.healthComponent.alive && Object.op_Implicit((Object)(object)bullet.owner)) { TeamMask unprotectedTeams = TeamMask.GetUnprotectedTeams(TeamComponent.GetObjectTeam(bullet.owner)); if (((TeamMask)(ref unprotectedTeams)).HasTeam(val.teamComponent.teamIndex)) { val.AddTimedBuff(SopranoCombat.GoonSlow, 4f); } } return result; } } public sealed class TriggerHappy : GoonPistolAbility { private int fired; private float interval; protected override float Duration => 6f * interval; public override void OnEnter() { ((BaseState)this).OnEnter(); interval = 0.1f / Mathf.Max(0.01f, ((BaseState)this).attackSpeedStat); Shoot(fired++); } public override void FixedUpdate() { while (fired < 6 && ((EntityState)this).fixedAge >= (float)fired * interval) { Shoot(fired++); } base.FixedUpdate(); } } public sealed class WatchYourStep : GoonPistolAbility { public override void OnEnter() { ((BaseState)this).OnEnter(); Shoot(0, slow: true); } } public sealed class LooseCannon : GoonAbilityState { public override void OnEnter() { ((BaseState)this).OnEnter(); if (NetworkServer.active) { ((EntityState)this).characterBody.AddTimedBuff(SopranoCombat.LooseCannonBuff, 6f); } } } public sealed class OnThePayroll : GoonAbilityState { public override void OnEnter() { ((BaseState)this).OnEnter(); if (NetworkServer.active) { CharacterMaster val = SopranoCrew.Owner(((EntityState)this).characterBody); if (Object.op_Implicit((Object)(object)val)) { val.GiveMoney((uint)GoonBalance.Payroll(Random.value)); } } } } public sealed class TakeABreather : GoonAbilityState { public override void OnEnter() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) ((BaseState)this).OnEnter(); if (NetworkServer.active) { CharacterBody val = GoonAbilities.HealTarget(((EntityState)this).characterBody, special: false); if (Object.op_Implicit((Object)(object)val)) { val.healthComponent.HealFraction(0.1f, default(ProcChainMask)); } } } } public sealed class BingsHospitality : GoonAbilityState { public override void OnEnter() { ((BaseState)this).OnEnter(); if (NetworkServer.active) { (((EntityState)this).GetComponent<GoonHospitality>() ?? ((EntityState)this).gameObject.AddComponent<GoonHospitality>()).Begin(); } } } public sealed class GoonHospitality : MonoBehaviour { private CharacterBody body; private float nextTick; private int ticks; internal void Begin() { body = ((Component)this).GetComponent<CharacterBody>(); nextTick = Time.fixedTime + 1f; ticks = 6; } private void FixedUpdate() { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active || !Object.op_Implicit((Object)(object)body) || !body.healthComponent.alive || ticks <= 0) { return; } while (ticks > 0 && Time.fixedTime >= nextTick) { foreach (CharacterBody item in GoonAbilities.NearbyCrew(body)) { item.healthComponent.HealFraction(0.03f, default(ProcChainMask)); } ticks--; nextTick += 1f; } } } internal static class GoonBalance { internal const float HealRange = 20f; internal const int BurstShots = 6; internal const float BurstInterval = 0.1f; internal static bool TargetInRange(float distanceSquared) { if (distanceSquared > 0.0001f) { return distanceSquared <= 6400f; } return false; } internal static bool AimAligned(float dot) { return dot >= 0.9659258f; } internal static int Payroll(float roll) { double num = Math.Max(0f, Math.Min(1f, roll)); return 1 + Math.Min(99, (int)(100.0 * num * num * num)); } internal static bool HealingReady(float fraction, bool special) { return fraction < (special ? 0.5f : 0.8f); } } internal sealed class GoonRespawnTimers { internal const float Delay = 15f; private readonly float?[] readyAt = new float?[3]; internal void Died(int role, float now) { if (!readyAt[role].HasValue) { readyAt[role] = now + 15f; } } internal bool Ready(int role, float now) { if (readyAt[role].HasValue) { return now >= readyAt[role].Value; } return false; } internal void Alive(int role) { readyAt[role] = null; } } internal static class GoonTargeting { internal static bool CanAttack(CharacterBody body, bool requireAim) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.master) || !body.healthComponent.alive) { return false; } BaseAI component = ((Component)body.master).GetComponent<BaseAI>(); CharacterBody val = (Object.op_Implicit((Object)(object)component) ? component.currentEnemy.characterBody : null); if (Object.op_Implicit((Object)(object)val) && val.healthComponent.alive) { TeamMask unprotectedTeams = TeamMask.GetUnprotectedTeams(body.teamComponent.teamIndex); if (((TeamMask)(ref unprotectedTeams)).HasTeam(val.teamComponent.teamIndex)) { Vector3 val2 = val.corePosition - body.aimOrigin; if (!GoonBalance.TargetInRange(((Vector3)(ref val2)).sqrMagnitude) || Physics.Linecast(body.aimOrigin, val.corePosition, LayerMask.op_Implicit(((LayerIndex)(ref LayerIndex.world)).mask))) { return false; } if (!requireAim) { return true; } InputBankTest component2 = ((Component)body).GetComponent<InputBankTest>(); if (Object.op_Implicit((Object)(object)component2)) { Vector3 aimDirection = component2.aimDirection; return GoonBalance.AimAligned(Vector3.Dot(((Vector3)(ref aimDirection)).normalized, ((Vector3)(ref val2)).normalized)); } return false; } } return false; } } internal static class MarkBalance { internal static int CappedStacks(int stacks) { return Math.Max(0, Math.Min(100, stacks)); } internal static float ScaledFraction(int stacks) { return (float)(1.0 - Math.Pow(0.99, CappedStacks(stacks))); } internal static float ProcChance(int stacks) { if (stacks > 0) { return Math.Min(100L, 9L + (long)stacks); } return 0f; } internal static uint CurrencyReward(int stacks) { return (uint)Math.Max(0, stacks); } } internal sealed class BossScrapLedger { private readonly HashSet<(int boss, int owner)> rewarded = new HashSet<(int, int)>(); internal bool Claim(int boss, int owner) { return rewarded.Add((boss, owner)); } internal void Clear() { rewarded.Clear(); } } internal sealed class MarkLedger { internal readonly struct Entry { internal readonly int Owner; internal readonly int Team; internal readonly int Stacks; internal readonly bool Shakedown; internal readonly bool Area; internal readonly float Expires; internal Entry(int owner, int team, int stacks, bool shakedown, bool area, float expires) { Owner = owner; Team = team; Stacks = stacks; Shakedown = shakedown; Area = area; Expires = expires; } } private readonly List<Entry> entries = new List<Entry>(); internal void SetNormal(int owner, int team, int stacks, bool shakedown) { RemoveNormal(owner); entries.Add(new Entry(owner, team, Math.Max(1, stacks), shakedown, area: false, float.PositiveInfinity)); } internal void AddArea(int owner, int team, int stacks, bool shakedown, float expires) { entries.Add(new Entry(owner, team, Math.Max(1, stacks), shakedown, area: true, expires)); } internal void RemoveNormal(int owner) { entries.RemoveAll((Entry e) => e.Owner == owner && !e.Area); } internal void Prune(float now) { entries.RemoveAll((Entry e) => e.Expires <= now); } internal int Count(int team, bool shakedown, float now) { return entries.Where((Entry e) => e.Team == team && e.Shakedown == shakedown && e.Expires > now).Sum((Entry e) => e.Stacks); } internal int Total(bool shakedown, float now) { return entries.Where((Entry e) => e.Shakedown == shakedown && e.Expires > now).Sum((Entry e) => e.Stacks); } internal IEnumerable<int> CurrencyOwners(int team, float now) { return (from e in entries where e.Team == team && e.Shakedown && e.Expires > now select e.Owner).Distinct(); } } internal static class NativeVoice { [StructLayout(LayoutKind.Sequential, Pack = 2)] private struct Format { public ushort Tag; public ushort Channels; public uint Rate; public uint BytesPerSecond; public ushort Alignment; public ushort Bits; public ushort Extra; } private struct Header { public IntPtr Data; public uint Length; public uint Recorded; public UIntPtr User; public uint Flags; public uint Loops; public IntPtr Next; public UIntPtr Reserved; } private sealed class Playback { private sealed class Slot { internal IntPtr Data; internal IntPtr Head; internal bool Prepared; } private readonly byte[] pcm; private readonly Slot[] slots = new Slot[2] { new Slot(), new Slot() }; private IntPtr device; private int position; private bool paused; private bool closing; private static readonly uint HeaderSize = (uint)Marshal.SizeOf<Header>(); internal Playback(byte[] pcm) { this.pcm = pcm; } internal void Open() { Format format = new Format { Tag = 1, Channels = 1, Rate = 48000u, BytesPerSecond = 96000u, Alignment = 2, Bits = 16 }; Check(waveOutOpen(out device, uint.MaxValue, ref format, IntPtr.Zero, IntPtr.Zero, 0u), "waveOutOpen"); Slot[] array = slots; foreach (Slot slot in array) { slot.Data = Marshal.AllocHGlobal(9600); slot.Head = Marshal.AllocHGlobal((int)HeaderSize); Queue(slot); } } private void Queue(Slot slot) { int num = Math.Min(9600, pcm.Length - position); if (num != 0) { float num2 = Volume("volume_master") * Volume("volume_sfx"); byte[] array = new byte[num]; for (int i = 0; i < num; i += 2) { short num3 = (short)Mathf.Clamp(Mathf.RoundToInt((float)(short)(pcm[position + i] | (pcm[position + i + 1] << 8)) * num2), -32768, 32767); array[i] = (byte)num3; array[i + 1] = (byte)(num3 >> 8); } Marshal.Copy(array, 0, slot.Data, num); position += num; Marshal.StructureToPtr(new Header { Data = slot.Data, Length = (uint)num }, slot.Head, fDeleteOld: false); Check(waveOutPrepareHeader(device, slot.Head, HeaderSize), "prepare voice buffer"); slot.Prepared = true; Check(waveOutWrite(device, slot.Head, HeaderSize), "write voice buffer"); } } internal bool Tick() { if (closing) { return true; } bool flag = Time.timeScale == 0f; if (flag != paused) { Check(flag ? waveOutPause(device) : waveOutRestart(device), "voice pause"); paused = flag; } bool flag2 = false; Slot[] array = slots; foreach (Slot slot in array) { if (slot.Prepared && (Marshal.PtrToStructure<Header>(slot.Head).Flags & 1) != 0) { Check(waveOutUnprepareHeader(device, slot.Head, HeaderSize), "unprepare voice buffer"); slot.Prepared = false; } if (!slot.Prepared) { Queue(slot); } flag2 |= slot.Prepared; } if (position >= pcm.Length) { return !flag2; } return false; } internal bool Close() { closing = true; Slot[] array; if (device != IntPtr.Zero) { if (waveOutReset(device) != 0) { return false; } array = slots; foreach (Slot slot in array) { if (slot.Prepared) { if (waveOutUnprepareHeader(device, slot.Head, HeaderSize) != 0) { return false; } slot.Prepared = false; } } if (waveOutClose(device) != 0) { return false; } device = IntPtr.Zero; } array = slots; foreach (Slot slot2 in array) { if (slot2.Head != IntPtr.Zero) { Marshal.FreeHGlobal(slot2.Head); slot2.Head = IntPtr.Zero; } if (slot2.Data != IntPtr.Zero) { Marshal.FreeHGlobal(slot2.Data); slot2.Data = IntPtr.Zero; } } return true; } } private static Playback? active; internal static bool Busy => active != null; [DllImport("winmm.dll")] private static extern uint waveOutOpen(out IntPtr device, uint index, ref Format format, IntPtr callback, IntPtr instance, uint flags); [DllImport("winmm.dll")] private static extern uint waveOutPrepareHeader(IntPtr device, IntPtr header, uint size); [DllImport("winmm.dll")] private static extern uint waveOutWrite(IntPtr device, IntPtr header, uint size); [DllImport("winmm.dll")] private static extern uint waveOutUnprepareHeader(IntPtr device, IntPtr header, uint size); [DllImport("winmm.dll")] private static extern uint waveOutReset(IntPtr device); [DllImport("winmm.dll")] private static extern uint waveOutClose(IntPtr device); [DllImport("winmm.dll")] private static extern uint waveOutPause(IntPtr device); [DllImport("winmm.dll")] private static extern uint waveOutRestart(IntPtr device); internal static void Play(string path) { if (active != null) { return; } Playback playback = (active = new Playback(ReadPcm(path))); try { playback.Open(); } catch { Stop(); throw; } } internal static void Tick() { if (active == null) { return; } try { if (active.Tick()) { Stop(); } } catch (Exception ex) { Plugin.VoiceLog("Voice output failed: " + ex.Message); Stop(); } } internal static void Stop() { if (active != null && active.Close()) { active = null; } } private static byte[] ReadPcm(string path) { using BinaryReader binaryReader = new BinaryReader(File.OpenRead(path)); if (new string(binaryReader.ReadChars(4)) != "RIFF") { throw new InvalidDataException("Invalid voice RIFF"); } binaryReader.ReadUInt32(); if (new string(binaryReader.ReadChars(4)) != "WAVE") { throw new InvalidDataException("Invalid voice WAVE"); } bool flag = false; while (binaryReader.BaseStream.Position + 8 <= binaryReader.BaseStream.Length) { string text = new string(binaryReader.ReadChars(4)); int num = binaryReader.ReadInt32(); long num2 = binaryReader.BaseStream.Position + num; if (num < 0 || num2 > binaryReader.BaseStream.Length) { throw new InvalidDataException("Truncated voice WAV"); } if (text == "fmt ") { ushort num3 = binaryReader.ReadUInt16(); int num4 = binaryReader.ReadUInt16(); int num5 = binaryReader.ReadInt32(); binaryReader.ReadInt32(); binaryReader.ReadUInt16(); int num6 = binaryReader.ReadUInt16(); flag = num3 == 1 && num4 == 1 && num5 == 48000 && num6 == 16; } else if (text == "data") { if (!flag || num % 2 != 0) { throw new InvalidDataException("Voice must be mono 48kHz PCM16"); } return binaryReader.ReadBytes(num); } binaryReader.BaseStream.Position = num2 + (num & 1); } throw new InvalidDataException("Missing voice PCM"); } private static float Volume(string name) { Console instance = Console.instance; object s; if (!Object.op_Implicit((Object)(object)instance)) { s = null; } else { BaseConVar obj = instance.FindConVar(name); s = ((obj != null) ? obj.GetString() : null); } if (!float.TryParse((string?)s, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return 1f; } return Mathf.Clamp01(result / 100f); } private static void Check(uint code, string operation) { if (code != 0) { throw new IOException(operation + ": MMRESULT " + code); } } } [BepInPlugin("local.tonysoprano.survivor", "Tony Soprano", "0.11.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { private GameObject bodyPrefab; private SurvivorDef survivor; private bool gameplayRegistered; private bool voiceRegistered; private static Plugin? instance; internal static void VoiceLog(string message) { Plugin? plugin = instance; if (plugin != null) { ((BaseUnityPlugin)plugin).Logger.LogWarning((object)message); } } private static T Load<T>(string address) where T : Object { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) return Addressables.LoadAssetAsync<T>((object)address).WaitForCompletion(); } private void Awake() { //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) instance = this; try { TonyAssets.Load(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "assets"), Load<Shader>("RoR2/Base/Shaders/HGStandard.shader")); SopranoVoice.Initialize(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "assets")); voiceRegistered = true; SurvivorDef obj = Load<SurvivorDef>("RoR2/Base/Commando/Commando.asset"); bodyPrefab = PrefabAPI.InstantiateClone(Load<GameObject>("RoR2/Base/Commando/CommandoBody.prefab"), "TonySopranoBody"); CharacterBody component = bodyPrefab.GetComponent<CharacterBody>(); component.baseNameToken = "TONY_NAME"; component.subtitleNameToken = "TONY_SUBTITLE"; component.portraitIcon = (Texture)(object)TonyAssets.Portrait; bodyPrefab.AddComponent<SopranoIdentity>(); SopranoCombat.Register(TonyAssets.Icon("secondary"), TonyAssets.Icon("special"), TonyAssets.Icon("utility")); gameplayRegistered = true; SopranoSkills.RegisterStates(); SopranoSkills.Register(bodyPrefab, goon: false); Material val = Object.Instantiate<Material>(Load<Material>("RoR2/Base/Commando/matCommandoDualies.mat")); val.shader = Load<Shader>("RoR2/Base/Shaders/HGStandard.shader"); GameObject gunModel = Load<GameObject>("RoR2/Base/Commando/mdlCommandoDualies.fbx"); TonyVisual.Attach(bodyPrefab, val, gunModel); TonySkin.Configure(bodyPrefab); GameObject val2 = PrefabAPI.InstantiateClone(obj.displayPrefab, "TonySopranoDisplay", false); TonyVisual.Attach(val2, val, gunModel); TonySkin.Configure(val2, bodyPrefab.GetComponentInChildren<ModelSkinController>(true).skins[0]); GameObject obj2 = PrefabAPI.InstantiateClone(Load<GameObject>("RoR2/Base/Commando/CommandoMonsterMaster.prefab"), "TonySopranoMonsterMaster"); obj2.GetComponent<CharacterMaster>().bodyPrefab = bodyPrefab; SopranoCrew.ConfigureAI(obj2, goon: false); RegisterGoons(val, gunModel); survivor = ScriptableObject.CreateInstance<SurvivorDef>(); survivor.cachedName = "TonySoprano"; survivor.bodyPrefab = bodyPrefab; survivor.displayPrefab = val2; survivor.displayNameToken = "TONY_NAME"; survivor.descriptionToken = "TONY_DESC"; survivor.outroFlavorToken = "TONY_OUTRO"; survivor.mainEndingEscapeFailureFlavorToken = "TONY_FAILURE"; survivor.primaryColor = new Color(0.4f, 0.31f, 0.23f); survivor.desiredSortPosition = 51f; LanguageAPI.Add("TONY_NAME", "Tony Soprano"); LanguageAPI.Add("TONY_SUBTITLE", "Waste Management Consultant"); LanguageAPI.Add("TONY_DESC", "The Don of New Jersey fights alongside Paulie, Silvio, and Christopher.\n\nChoose Waste Management for pistols and scrap, or Made Men to command your own crew. Mark targets with Shot Caller or Shakedown, charge with Varsity Athlete, and eat Gabagool or become The Don of New Jersey.\n\n<size=80%>Models: Skessler, Cuba, Stellar, and Ibradude; The Sopranos: Road to Respect.</size>"); RegisterLanguage(); LanguageAPI.Add("TONY_OUTRO", "...and so he left, with unfinished business."); LanguageAPI.Add("TONY_FAILURE", "...and so he vanished, before the music stopped."); ContentAddition.AddBody(bodyPrefab); ContentAddition.AddMaster(obj2); ContentAddition.AddSurvivorDef(survivor); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(CheckCatalog)); Run.onRunStartGlobal += SopranoCrew.StartRun; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Tony Soprano 0.11.0 registered: direct Shakedown payouts, diminishing mark scaling, and boss scrap rewards."); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Tony Soprano could not register: " + ex)); } } private void RegisterGoons(Material gunMaterial, GameObject gunModel) { string[] array = new string[3] { "Paulie", "Silvio", "Christopher" }; SopranoCrew.MasterPrefabs = (GameObject[])(object)new GameObject[3]; for (int i = 0; i < array.Length; i++) { GameObject val = PrefabAPI.InstantiateClone(Load<GameObject>("RoR2/Base/Commando/CommandoBody.prefab"), "Soprano" + array[i] + "Body"); val.AddComponent<SopranoIdentity>().role = i; CharacterBody component = val.GetComponent<CharacterBody>(); component.baseNameToken = "SOPRANO_" + array[i].ToUpperInvariant(); CharacterBody component2 = bodyPrefab.GetComponent<CharacterBody>(); component.baseDamage = component2.baseDamage; component.levelDamage = component2.levelDamage; component.baseAttackSpeed = component2.baseAttackSpeed; component.levelAttackSpeed = component2.levelAttackSpeed; component.baseMaxHealth = component2.baseMaxHealth; component.levelMaxHealth = component2.levelMaxHealth; component.baseRegen = component2.baseRegen; component.levelRegen = component2.levelRegen; component.baseMoveSpeed = component2.baseMoveSpeed; component.levelMoveSpeed = component2.levelMoveSpeed; component.baseArmor = component2.baseArmor; component.levelArmor = component2.levelArmor; component.baseCrit = component2.baseCrit; component.levelCrit = component2.levelCrit; component.subtitleNameToken = "TONY_GOON_SUBTITLE"; component.portraitIcon = (Texture)(object)TonyAssets.Goons[i].Portrait; TonyVisual.Attach(val, gunMaterial, gunModel, TonyAssets.Goons[i]); TonySkin.Configure(val); SopranoSkills.Register(val, goon: true); GameObject val2 = PrefabAPI.InstantiateClone(Load<GameObject>("RoR2/Base/Commando/CommandoMonsterMaster.prefab"), "Soprano" + array[i] + "Master"); val2.GetComponent<CharacterMaster>().bodyPrefab = val; SopranoCrew.ConfigureAI(val2); SopranoCrew.MasterPrefabs[i] = val2; ContentAddition.AddBody(val); ContentAddition.AddMaster(val2); LanguageAPI.Add(component.baseNameToken, array[i]); } } private static void RegisterLanguage() { LanguageAPI.Add("TONY_PASSIVE", "Waste Management Consultant"); LanguageAPI.Add("TONY_PASSIVE_DESC", "Waste Management turns scrap into stats. Made Men gives you a personal crew that shares one-third of your stat gains. Secondary marks last until death or replacement; casts apply maximum-charge stacks. Allied marks stack. Diminishing scaling caps at 100 stacks (63.4%)."); LanguageAPI.Add("TONY_PRIMARY", "Waste Management"); LanguageAPI.Add("TONY_PRIMARY_DESC", "Fire alternating pistols. Scrap increases health, damage, regeneration, speed, armor, and crit. Kills have a 5% scrap chance; completed boss fights guarantee scrap."); LanguageAPI.Add("TONY_PRIMARY2", "Made Men"); LanguageAPI.Add("TONY_PRIMARY2_DESC", "Command Paulie, Silvio, and Christopher. Cycle Follow, Hold, and Free Roam. Keep your items; Goons get category copies with effects but no item stats. Dead Goons return after 15s and keep their items."); LanguageAPI.Add("TONY_SECONDARY", "Shot Caller"); LanguageAPI.Add("TONY_SECONDARY_DESC", "Mark an enemy for <style=cIsDamage>10% more allied damage per stack</style> and execution below <style=cIsDamage>1% health</style>, increasing with diminishing stacks. Your Goons focus it. No cooldown."); LanguageAPI.Add("TONY_SECONDARY2", "Shakedown"); LanguageAPI.Add("TONY_SECONDARY2_DESC", "Mark an enemy. Allied hits add <style=cIsDamage>1% of the richest marking Tony's money</style>, increasing with diminishing stacks. Hits have a 10% chance to pay the attacker $1; each extra stack adds 1% chance and $1. Goon payouts go to Tony. No cooldown."); LanguageAPI.Add("TONY_UTILITY", "Varsity Athlete"); LanguageAPI.Add("TONY_UTILITY_DESC", "Charge for <style=cIsDamage>300% damage</style>, stunning and knocking enemies back. Gain 100 armor briefly. 6s cooldown."); LanguageAPI.Add("TONY_SPECIAL", "Gabagool"); LanguageAPI.Add("TONY_SPECIAL_DESC", "Gain <style=cIsHealing>15% maximum health as barrier</style> and a 30s stack giving you and your Goons <style=cIsDamage>5% more damage</style>. First pay 2%, 4%, 8%... maximum health as stacks grow. Can kill you. 5s cooldown."); LanguageAPI.Add("TONY_SPECIAL2", "The Don Of New Jersey"); LanguageAPI.Add("TONY_SPECIAL2_DESC", "Apply your Secondary mark to <style=cIsDamage>all enemies</style> for 30s. Recasts stack. Fully heal living allied Goons. 120s cooldown."); LanguageAPI.Add("GOON_TRIGGER_HAPPY", "Trigger Happy"); LanguageAPI.Add("GOON_TRIGGER_HAPPY_DESC", "Fire six rapid pistol shots. 8s cooldown."); LanguageAPI.Add("GOON_LOOSE_CANNON", "Loose Cannon"); LanguageAPI.Add("GOON_LOOSE_CANNON_DESC", "Deal 50% more damage for 6s. 30s cooldown."); LanguageAPI.Add("GOON_WATCH_STEP", "Watch Your Step"); LanguageAPI.Add("GOON_WATCH_STEP_DESC", "Shoot an enemy, slowing it by 60% for 4s. 10s cooldown."); LanguageAPI.Add("GOON_PAYROLL", "On The Payroll"); LanguageAPI.Add("GOON_PAYROLL_DESC", "Give Tony $1–100, favoring smaller payouts. 30s cooldown."); LanguageAPI.Add("GOON_BREATHER", "Take a Breather"); LanguageAPI.Add("GOON_BREATHER_DESC", "Heal a nearby injured Goon for 10% maximum health. 10s cooldown."); LanguageAPI.Add("GOON_HOSPITALITY", "The Bing's Hospitality"); LanguageAPI.Add("GOON_HOSPITALITY_DESC", "Heal nearby Goons for 3% maximum health each second for 6s. 40s cooldown."); LanguageAPI.Add("TONY_GOON_SUBTITLE", "Soprano Crew"); } private void CheckCatalog() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) ((BaseUnityPlugin)this).Logger.LogInfo((object)("Tony catalog check: body=" + ((object)BodyCatalog.FindBodyIndex(bodyPrefab)/*cast due to .constrained prefix*/).ToString() + "; survivor=" + ((object)survivor.survivorIndex/*cast due to .constrained prefix*/).ToString())); } private void Update() { NativeVoice.Tick(); } private void OnDestroy() { RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(CheckCatalog)); Run.onRunStartGlobal -= SopranoCrew.StartRun; if (gameplayRegistered) { SopranoCombat.Unregister(); } if (voiceRegistered) { SopranoVoice.Shutdown(); } instance = null; } } internal readonly struct RarityBonus { internal readonly float Health; internal readonly float Damage; internal readonly float Regen; internal readonly float Speed; internal readonly float Armor; internal readonly float Crit; internal RarityBonus(float health, float damage, float regen, float speed, float armor, float crit) { Health = health; Damage = damage; Regen = regen; Speed = speed; Armor = armor; Crit = crit; } internal static RarityBonus For(int rarity) { float num = rarity switch { 3 => 6, 2 => 10, 1 => 3, _ => (rarity == 0) ? 1 : 0, }; return new RarityBonus(6f * num, 0.6f * num, 0.12f * num, 0.07f * num, 0.5f * num, num); } } internal static class ReworkBalance { internal static float Inherit(float current, float baseline) { return Math.Max(0f, current - baseline) / 3f; } internal static int ScrapRarity(float roll) { if (!(roll < 0.8f)) { if (!(roll < 0.96f)) { if (!(roll < 0.99f)) { return 3; } return 2; } return 1; } return 0; } internal static int ChooseRole(bool utility, bool healing, bool damage, int paulie, int silvio, int christopher) { int result = -1; int num = int.MaxValue; if (utility && paulie < num) { result = 0; num = paulie; } if (healing && silvio < num) { result = 1; num = silvio; } if (damage && christopher < num) { result = 2; } return result; } } public sealed class SopranoIdentity : MonoBehaviour { public int role = -1; private float nextStats; internal bool IsTony => role < 0; private void FixedUpdate() { if (!(Time.fixedTime < nextStats) && Object.op_Implicit((Object)(object)Run.instance)) { nextStats = Time.fixedTime + 0.5f; CharacterBody component = ((Component)this).GetComponent<CharacterBody>(); if (!IsTony || (Object.op_Implicit((Object)(object)component.master) && SopranoCrew.HasMadeMen(component.master))) { component.MarkAllStatsDirty(); } } } } public sealed class SopranoMark : MonoBehaviour { internal readonly MarkLedger Ledger = new MarkLedger(); private CharacterBody body; private void Awake() { body = ((Component)this).GetComponent<CharacterBody>(); } private void FixedUpdate() { if (NetworkServer.active) { Ledger.Prune(Time.fixedTime); Refresh(); } } internal void Refresh() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)body)) { body.SetBuffCount(SopranoCombat.CalledMark.buffIndex, Ledger.Total(shakedown: false, Time.fixedTime)); body.SetBuffCount(SopranoCombat.ShakedownBuff.buffIndex, Ledger.Total(shakedown: true, Time.fixedTime)); } } } public sealed class SopranoMarkVisual : MonoBehaviour { private Renderer[]? renderers; internal IEnumerable<Renderer> Renderers() { if (renderers == null) { CharacterBody component = ((Component)this).GetComponent<CharacterBody>(); Transform val = (Object.op_Implicit((Object)(object)component.modelLocator) ? component.modelLocator.modelTransform : null); renderers = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponentsInChildren<Renderer>() : Array.Empty<Renderer>()); } return renderers; } } internal static class SopranoCombat { [CompilerGenerated] private static class <>O { public static hook_TakeDamage <0>__TakeDamage; public static Action<DamageReport> <1>__DamageDealt; public static Action<DamageReport> <2>__Death; public static StatHookEventHandler <3>__Stats; public static Action<OutlineHighlight> <4>__Highlight; } internal static BuffDef CalledMark = null; internal static BuffDef ChargeArmor = null; internal static BuffDef GabagoolBuff = null; internal static BuffDef ShakedownBuff = null; internal static BuffDef LooseCannonBuff = null; internal static BuffDef GoonSlow = null; private static readonly Dictionary<int, SopranoMark> normalTargets = new Dictionary<int, SopranoMark>(); private static readonly Dictionary<int, CharacterMaster> owners = new Dictionary<int, CharacterMaster>(); internal static void Register(Sprite markIcon, Sprite foodIcon, Sprite chargeIcon) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Expected O, but got Unknown //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Expected O, but got Unknown CalledMark = Buff("SopranoCalledTarget", Color.red, markIcon, debuff: true, stack: true); ChargeArmor = Buff("SopranoChargeArmor", new Color(0.6f, 0.75f, 1f), chargeIcon, debuff: false, stack: false); GabagoolBuff = Buff("SopranoGabagool", new Color(0.4f, 1f, 0.3f), foodIcon, debuff: false, stack: true); ShakedownBuff = Buff("SopranoShakedown", new Color(1f, 0.75f, 0.15f), TonyAssets.Icon("secondary2"), debuff: true, stack: true); LooseCannonBuff = Buff("SopranoLooseCannon", new Color(1f, 0.4f, 0.15f), TonyAssets.Icon("primary"), debuff: false, stack: false); GoonSlow = Buff("SopranoWatchYourStep", new Color(0.5f, 0.7f, 1f), TonyAssets.Icon("pauliestep"), debuff: true, stack: false); SopranoItems.Register(); object obj = <>O.<0>__TakeDamage; if (obj == null) { hook_TakeDamage val = TakeDamage; <>O.<0>__TakeDamage = val; obj = (object)val; } HealthComponent.TakeDamage += (hook_TakeDamage)obj; GlobalEventManager.onServerDamageDealt += DamageDealt; GlobalEventManager.onCharacterDeathGlobal += Death; object obj2 = <>O.<3>__Stats; if (obj2 == null) { StatHookEventHandler val2 = Stats; <>O.<3>__Stats = val2; obj2 = (object)val2; } RecalculateStatsAPI.GetStatCoefficients += (StatHookEventHandler)obj2; OutlineHighlight.onPreRenderOutlineHighlight = (Action<OutlineHighlight>)Delegate.Combine(OutlineHighlight.onPreRenderOutlineHighlight, new Action<OutlineHighlight>(Highlight)); OutlineHighlight.AddPreRenderHighlightRequest((Object)(object)CalledMark); } private static BuffDef Buff(string name, Color color, Sprite icon, bool debuff, bool stack) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) BuffDef obj = ScriptableObject.CreateInstance<BuffDef>(); ((Object)obj).name = name; obj.buffColor = color; obj.iconSprite = icon; obj.isDebuff = debuff; obj.canStack = stack; ContentAddition.AddBuffDef(obj); return obj; } internal static bool Mark(CharacterBody caller, CharacterBody victim, bool shakedown, bool area = false) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected I4, but got Unknown if (!NetworkServer.active || !Object.op_Implicit((Object)(object)caller.master) || !Object.op_Implicit((Object)(object)victim) || !victim.healthComponent.alive) { return false; } int instanceID = ((Object)caller.master).GetInstanceID(); int team = (int)caller.teamComponent.teamIndex; int stacks = Math.Max(1, caller.skillLocator.secondary.maxStock); SopranoMark sopranoMark = ((Component)victim).GetComponent<SopranoMark>() ?? ((Component)victim).gameObject.AddComponent<SopranoMark>(); owners[instanceID] = caller.master; if (area) { sopranoMark.Ledger.AddArea(instanceID, team, stacks, shakedown, Time.fixedTime + 30f); } else { if (normalTargets.TryGetValue(instanceID, out SopranoMark value) && Object.op_Implicit((Object)(object)value)) { value.Ledger.RemoveNormal(instanceID); value.Refresh(); } normalTargets[instanceID] = sopranoMark; sopranoMark.Ledger.SetNormal(instanceID, team, stacks, shakedown); SopranoCrew.CallTarget(caller, victim); } sopranoMark.Refresh(); if (!shakedown) { TryExecute(victim, caller); } return true; } internal static void ClearRun() { normalTargets.Clear(); owners.Clear(); SopranoItems.ClearRun(); } private static void TakeDamage(orig_TakeDamage orig, HealthComponent victim, DamageInfo info) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected I4, but got Unknown if (NetworkServer.active && !info.rejected && info.damage > 0f && Object.op_Implicit((Object)(object)info.attacker) && Object.op_Implicit((Object)(object)victim.body)) { CharacterBody component = info.attacker.GetComponent<CharacterBody>(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.teamComponent) && component.teamComponent.teamIndex != victim.body.teamComponent.teamIndex) { SopranoMark component2 = ((Component)victim.body).GetComponent<SopranoMark>(); int team = (int)component.teamComponent.teamIndex; if (Object.op_Implicit((Object)(object)component2)) { int stacks = component2.Ledger.Count(team, shakedown: true, Time.fixedTime); uint num = 0u; foreach (int item in component2.Ledger.CurrencyOwners(team, Time.fixedTime)) { if (owners.TryGetValue(item, out CharacterMaster value) && Object.op_Implicit((Object)(object)value)) { num = Math.Max(num, value.money); } } info.damage += (float)num * MarkBalance.ScaledFraction(stacks); info.damage *= 1f + 0.1f * (float)component2.Ledger.Count(team, shakedown: false, Time.fixedTime); } SopranoIdentity component3 = ((Component)component).GetComponent<SopranoIdentity>(); if (component3 != null && component3.role == 2 && component.HasBuff(LooseCannonBuff)) { info.damage *= 1.5f; } SopranoIdentity component4 = ((Component)component).GetComponent<SopranoIdentity>(); if (Object.op_Implicit((Object)(object)component4)) { CharacterBody val = (CharacterBody)(component4.IsTony ? ((object)component) : ((object)SopranoCrew.Leader(component))); if (Object.op_Implicit((Object)(object)val)) { info.damage *= 1f + FoodBalance.DamageBonus(val.GetBuffCount(GabagoolBuff)); } } } } orig.Invoke(victim, info); } private static void DamageDealt(DamageReport report) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected I4, but got Unknown if (!NetworkServer.active || report.damageInfo.rejected || report.damageDealt <= 0f || !Object.op_Implicit((Object)(object)report.attackerBody) || !Object.op_Implicit((Object)(object)report.victimBody) || report.isFriendlyFire) { return; } CharacterBody victimBody = report.victimBody; SopranoMark component = ((Component)victimBody).GetComponent<SopranoMark>(); if (Object.op_Implicit((Object)(object)component)) { int team = (int)report.attackerTeamIndex; int num = component.Ledger.Count(team, shakedown: true, Time.fixedTime); CharacterMaster val = CurrencyRecipient(report.attackerMaster); if (num > 0 && Object.op_Implicit((Object)(object)val) && Util.CheckRoll(MarkBalance.ProcChance(num), val)) { val.GiveMoney(MarkBalance.CurrencyReward(num)); } TryExecute(victimBody, report.attackerBody); } } internal static CharacterMaster? CurrencyRecipient(CharacterMaster attacker) { HashSet<int> hashSet = new HashSet<int>(); CharacterMaster val = attacker; while (Object.op_Implicit((Object)(object)val) && hashSet.Add(((Object)val).GetInstanceID())) { if (Object.op_Implicit((Object)(object)val.playerCharacterMasterController)) { return val; } val = (Object.op_Implicit((Object)(object)val.minionOwnership) ? val.minionOwnership.ownerMaster : null); } return null; } private static void TryExecute(CharacterBody victim, CharacterBody attacker) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected I4, but got Unknown //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) SopranoMark component = ((Component)victim).GetComponent<SopranoMark>(); if (Object.op_Implicit((Object)(object)component) && victim.healthComponent.alive) { int num = component.Ledger.Count((int)attacker.teamComponent.teamIndex, shakedown: false, Time.fixedTime); if (num > 0 && !((Enum)victim.bodyFlags).HasFlag((Enum)(object)(BodyFlags)16) && victim.healthComponent.health <= victim.healthComponent.fullHealth * MarkBalance.ScaledFraction(num)) { victim.healthComponent.Suicide(((Component)attacker).gameObject, ((Component)attacker).gameObject, DamageTypeCombo.op_Implicit((DamageType)0)); } } } private static void Death(DamageReport report) { if (NetworkServer.active) { SopranoItems.OnKill(report); if (Object.op_Implicit((Object)(object)report.victimBody)) { SopranoCrew.ClearDeadTarget(report.victimBody); } } } private static void Stats(CharacterBody body, StatHookEventArgs args) { if (body.HasBuff(ChargeArmor)) { args.armorAdd += 100f; } if (body.HasBuff(GoonSlow)) { args.moveSpeedTotalMult *= 0.4f; } } private static void Highlight(OutlineHighlight outline) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) foreach (CharacterBody readOnlyInstances in CharacterBody.readOnlyInstancesList) { if (!Object.op_Implicit((Object)(object)readOnlyInstances) || !readOnlyInstances.healthComponent.alive) { continue; } bool flag = readOnlyInstances.HasBuff(CalledMark); bool flag2 = readOnlyInstances.HasBuff(ShakedownBuff); if (!flag && !flag2) { continue; } foreach (Renderer item in (((Component)readOnlyInstances).GetComponent<SopranoMarkVisual>() ?? ((Component)readOnlyInstances).gameObject.AddComponent<SopranoMarkVisual>()).Renderers()) { if (Object.op_Implicit((Object)(object)item) && item.enabled) { outline.AddHighlight(item, (Color)(flag ? Color.red : new Color(1f, 0.75f, 0.15f))); } } } } internal static void Unregister() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown object obj = <>O.<0>__TakeDamage; if (obj == null) { hook_TakeDamage val = TakeDamage; <>O.<0>__TakeDamage = val; obj = (object)val; } HealthComponent.TakeDamage -= (hook_TakeDamage)obj; GlobalEventManager.onServerDamageDealt -= DamageDealt; GlobalEventManager.onCharacterDeathGlobal -= Death; object obj2 = <>O.<3>__Stats; if (obj2 == null) { StatHookEventHandler val2 = Stats; <>O.<3>__Stats = val2; obj2 = (object)val2; } RecalculateStatsAPI.GetStatCoefficients -= (StatHookEventHandler)obj2; SopranoItems.Unregister(); OutlineHighlight.onPreRenderOutlineHighlight = (Action<OutlineHighlight>)Delegate.Remove(OutlineHighlight.onPreRenderOutlineHighlight, new Action<OutlineHighlight>(Highlight)); OutlineHighlight.ReleasePreRenderHighlightRequest((Object)(object)CalledMark); ClearRun(); } } public sealed class SopranoCrew : MonoBehaviour { internal sealed class Crew { internal CharacterMaster Owner; internal readonly CharacterMaster[] Members = (CharacterMaster[])(object)new CharacterMaster[3]; internal CharacterBody? Focus; internal int Mode; internal Stage? SpawnStage; internal readonly GoonRespawnTimers Respawns = new GoonRespawnTimers(); internal readonly CrewCopyLedger Copies = new CrewCopyLedger(); internal readonly CrewInventorySnapshot[] Inventories = new CrewInventorySnapshot[3] { new CrewInventorySnapshot(), new CrewInventorySnapshot(), new CrewInventorySnapshot() }; } private readonly Dictionary<int, Crew> crews = new Dictionary<int, Crew>(); private float timer; private bool restoringInventories; internal static SopranoCrew? Instance; internal static GameObject[] MasterPrefabs; private void Awake() { Instance = this; GlobalEventManager.onCharacterDeathGlobal += GoonDied; Inventory.onInventoryChangedGlobal += InventoryChanged; Stage.onServerStageComplete += SaveStage; } private void InventoryChanged(Inventory inventory) { if (!NetworkServer.active || restoringInventories || (Object.op_Implicit((Object)(object)Stage.instance) && Stage.instance.completed)) { return; } foreach (Crew value in crews.Values) { if (!((Object)(object)value.SpawnStage == (Object)(object)Stage.instance)) { continue; } for (int i = 0; i < 3; i++) { if (Object.op_Implicit((Object)(object)value.Members[i]) && (Object)(object)value.Members[i].inventory == (Object)(object)inventory) { SaveInventory(value, i); } } } } private static void SaveInventory(Crew crew, int role) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) CharacterMaster member = crew.Members[role]; if (Object.op_Implicit((Object)(object)member) && Object.op_Implicit((Object)(object)member.inventory)) { crew.Inventories[role].Capture(((IEnumerable<ItemIndex>)(object)ItemCatalog.allItems).Select((ItemIndex index) => new KeyValuePair<int, int>((int)index, member.inventory.GetItemCountPermanent(index)))); } } private void SaveStage(Stage stage) { if (!NetworkServer.active) { return; } foreach (Crew value in crews.Values) { for (int i = 0; i < 3; i++) { SaveInventory(value, i); } } } private void RestoreInventory(Crew crew, int role, CharacterMaster member) { restoringInventories = true; try { foreach (KeyValuePair<int, int> item in crew.Inventories[role].MissingFrom((int index) => member.inventory.GetItemCountPermanent((ItemIndex)index))) { member.inventory.GiveItemPermanent((ItemIndex)item.Key, item.Value); } } finally { restoringInventories = false; } } private void GoonDied(DamageReport report) { if (!NetworkServer.active || !Object.op_Implicit((Object)(object)report.victimBody)) { return; } SopranoIdentity component = ((Component)report.victimBody).GetComponent<SopranoIdentity>(); if (Object.op_Implicit((Object)(object)component) && !component.IsTony) { CharacterMaster val = Owner(report.victimBody); Crew crew = (Object.op_Implicit((Object)(object)val) ? ForOwner(val) : null); if (crew != null && component.role >= 0 && component.role < 3 && (Object)(object)crew.Members[component.role] == (Object)(object)report.victimMaster) { crew.Respawns.Died(component.role, Time.fixedTime); } } } internal static void StartRun(Run run) { if (NetworkServer.active) { SopranoEconomy.ClearRun(); SopranoVoice.BeginRun(); ((Component)run).gameObject.AddComponent<SopranoCrew>(); } } internal static bool HasMadeMen(CharacterMaster master) { //IL_0095: Unknown result type (might be due to invalid IL or missing references) CharacterBody body = master.GetBody(); GenericSkill val = ((!Object.op_Implicit((Object)(object)body)) ? null : ((Component)body).GetComponent<SkillLocator>()?.primary); if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.skillDef)) { return ((SerializableEntityStateType)(ref val.skillDef.activationState)).stateType == typeof(MadeMen); } if (!Object.op_Implicit((Object)(object)master.bodyPrefab)) { return false; } Variant[] variants = master.bodyPrefab.GetComponent<SkillLocator>().primary.skillFamily.variants; uint skillVariant = master.loadout.bodyLoadoutManager.GetSkillVariant(BodyCatalog.FindBodyIndex(master.bodyPrefab), 0); if (skillVariant < variants.Length) { return ((SerializableEntityStateType)(ref variants[skillVariant].skillDef.activationState)).stateType == typeof(MadeMen); } return false; } internal static CharacterMaster? Owner(CharacterBody goon) { if (!Object.op_Implicit((Object)(object)goon.master) || !Object.op_Implicit((Object)(object)goon.master.minionOwnership)) { return null; } return goon.master.minionOwnership.ownerMaster; } internal static CharacterBody? Leader(CharacterBody goon) { CharacterMaster val = Owner(goon); CharacterBody val2 = (Object.op_Implicit((Object)(object)val) ? val.GetBody() : null); if (!Object.op_Implicit((Object)(object)val2) || !val2.healthComponent.alive) { return null; } return val2; } internal static Crew? ForOwner(CharacterMaster owner, bool create = false) { if (!Object.op_Implicit((Object)(object)Instance) || !Object.op_Implicit((Object)(object)owner)) { return null; } if (Instance.crews.TryGetValue(((Object)owner).GetInstanceID(), out Crew value)) { return value; } if (!create || !NetworkServer.active || !HasMadeMen(owner)) { return null; } value = new Crew { Owner = owner }; Instance.crews[((Object)owner).GetInstanceID()] = value; Instance.EnsureMembers(value); return value; } internal static IEnumerable<CharacterMaster> OwnedMembers(CharacterMaster owner) { return CharacterMaster.readOnlyInstancesList.Where(delegate(CharacterMaster m) { if (Object.op_Implicit((Object)(object)m) && Object.op_Implicit((Object)(object)m.bodyPrefab)) { SopranoIdentity component = m.bodyPrefab.GetComponent<SopranoIdentity>(); if (component != null && !component.IsTony && Object.op_Implicit((Object)(object)m.minionOwnership)) { return (Object)(object)m.minionOwnership.ownerMaster == (Object)(object)owner; } } return false; }); } internal static CharacterBody? Target(CharacterBody goon) { CharacterMaster val = Owner(goon); Crew crew = (Object.op_Implicit((Object)(object)val) ? ForOwner(val) : null); if (crew == null || !Object.op_Implicit((Object)(object)crew.Focus) || !crew.Focus.healthComponent.alive) { return null; } return crew.Focus; } internal static void CallTarget(CharacterBody caller, CharacterBody victim) { Crew crew = ForOwner(caller.master, create: true); if (crew != null) { crew.Focus = victim; } } internal static void ClearDeadTarget(CharacterBody victim) { if (!Object.op_Implicit((Object)(object)Instance)) { return; } foreach (Crew value in Instance.crews.Values) { if ((Object)(object)value.Focus == (Object)(object)victim) { value.Focus = null; } } } internal static void Cycle(CharacterBody caller) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown if (!NetworkServer.active) { return; } Crew crew = ForOwner(caller.master, create: true); if (crew == null) { return; } crew.Mode = (crew.Mode + 1) % 3; CharacterMaster[] members = crew.Members; foreach (CharacterMaster val in members) { GoonAI goonAI = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<GoonAI>() : null); if (Object.op_Implicit((Object)(object)goonAI)) { goonAI.SetMode(crew.Mode); } } SimpleChatMessage val2 = new SimpleChatMessage(); val2.baseToken = Util.GetBestBodyName(((Component)caller).gameObject) + ": crew " + (new string[3] { "following", "holding position", "free roaming" })[crew.Mode] + "."; Chat.SendBroadcastChat((ChatMessageBase)(object)val2); } internal static void HealLiving(CharacterBody caller) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active) { return; } foreach (CharacterBody readOnlyInstances in CharacterBody.readOnlyInstancesList) { SopranoIdentity sopranoIdentity = (Object.op_Implicit((Object)(object)readOnlyInstances) ? ((Component)readOnlyInstances).GetComponent<SopranoIdentity>() : null); if (Object.op_Implicit((Object)(object)sopranoIdentity) && !sopranoIdentity.IsTony && readOnlyInstances.teamComponent.teamIndex == caller.teamComponent.teamIndex && readOnlyInstances.healthComponent.alive) { readOnlyInstances.healthComponent.HealFraction(1f, default(ProcChainMask)); } } } private void EnsureMembers(Crew crew) { //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) CharacterBody val = (Object.op_Implicit((Object)(object)crew.Owner) ? crew.Owner.GetBody() : null); if (!Object.op_Implicit((Object)(object)val) || !val.healthComponent.alive || !Object.op_Implicit((Object)(object)Stage.instance)) { return; } bool flag = (Object)(object)crew.SpawnStage != (Object)(object)Stage.instance; int i; for (i = 0; i < 3; i++) { CharacterMaster member = crew.Members[i]; if (!Object.op_Implicit((Object)(object)member)) { Vector3 position = SpawnPosition(val, i); member = (crew.Members[i] = new MasterSummon { masterPrefab = MasterPrefabs[i], summonerBodyObject = ((Component)val).gameObject, teamIndexOverride = val.teamComponent.teamIndex, ignoreTeamMemberLimit = true, position = position, rotation = ((Component)val).gameObject.transform.rotation, useAmbientLevel = false, inventoryToCopy = null, propogateMinionOwnership = false, preSpawnSetupCallback = delegate(CharacterMaster m) { m.destroyOnBodyDeath = false; m.minionOwnership.SetOwner(crew.Owner); RestoreInventory(crew, i, m); } }.Perform()); } else { if (flag) { bool num = crew.Inventories[i].Items.Any((KeyValuePair<int, int> p) => p.Value > 0 && Object.op_Implicit((Object)(object)ItemCatalog.GetItemDef((ItemIndex)p.Key)) && !ItemCatalog.GetItemDef((ItemIndex)p.Key).hidden); bool flag2 = !((IEnumerable<ItemIndex>)(object)ItemCatalog.allItems).Any(delegate(ItemIndex index) { //IL_0000: 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) ItemDef itemDef = ItemCatalog.GetItemDef(index); return Object.op_Implicit((Object)(object)itemDef) && !itemDef.hidden && member.inventory.GetItemCountPermanent(index) > 0; }); if (num && flag2) { RestoreInventory(crew, i, member); } } CharacterBody body = member.GetBody(); if (Object.op_Implicit((Object)(object)body) && body.healthComponent.alive) { crew.Respawns.Alive(i); if (flag) { TeleportNear(body, val); } } else { crew.Respawns.Died(i, Time.fixedTime); if (flag || crew.Respawns.Ready(i, Time.fixedTime)) { CharacterBody val2 = member.Respawn(SpawnPosition(val, i), ((Component)val).gameObject.transform.rotation, false); if (Object.op_Implicit((Object)(object)val2) && val2.healthComponent.alive) { crew.Respawns.Alive(i); GoonAI component = ((Component)member).GetComponent<GoonAI>(); if (Object.op_Implicit((Object)(object)component)) { component.SetMode((!flag) ? crew.Mode : 0); } } } } } if (Object.op_Implicit((Object)(object)member)) { member.minionOwnership.SetOwner(crew.Owner); GoonAI component2 = ((Component)member).GetComponent<GoonAI>(); if (Object.op_Implicit((Object)(object)component2) && flag) { component2.SetMode(0); } } } if (flag) { crew.Mode = 0; } crew.SpawnStage = Stage.instance; } private static Vector3 SpawnPosition(CharacterBody leader, int index) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) Vector3 val = leader.footPosition + Quaternion.Euler(0f, (float)(index * 120), 0f) * Vector3.forward * 3f; RaycastHit val2 = default(RaycastHit); if (Physics.Raycast(val + Vector3.up * 8f, Vector3.down, ref val2, 20f, LayerMask.op_Implicit(((LayerIndex)(ref LayerIndex.world)).mask))) { val = ((RaycastHit)(ref val2)).point + Vector3.up * 0.1f; } return val; } private void FixedUpdate() { //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active || !Object.op_Implicit((Object)(object)Run.instance) || !Object.op_Implicit((Object)(object)Stage.instance)) { return; } SopranoVoice.TickServer(); if (Stage.instance.completed) { return; } timer -= Time.fixedDeltaTime; if (timer > 0f) { return; } timer = 0.5f; CharacterMaster[] array = CharacterMaster.readOnlyInstancesList.Where(delegate(CharacterMaster m) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 if (Object.op_Implicit((Object)(object)m) && (int)m.teamIndex == 1 && Object.op_Implicit((Object)(object)m.bodyPrefab)) { SopranoIdentity component = m.bodyPrefab.GetComponent<SopranoIdentity>(); if (component != null && component.IsTony) { return HasMadeMen(m); } } return false; }).ToArray().Concat(from c in crews.Values where Object.op_Implicit((Object)(object)c.Owner) select c.Owner) .Distinct() .ToArray(); foreach (CharacterMaster val in array) { Crew crew = ForOwner(val, create: true); if (crew == null) { continue; } CharacterBody body = val.GetBody(); if (Object.op_Implicit((Object)(object)body) && body.healthComponent.alive && !HasMadeMen(val)) { continue; } EnsureMembers(crew); CharacterBody body2 = val.GetBody(); if (!Object.op_Implicit((Object)(object)body2) || !body2.healthComponent.alive) { continue; } SopranoItems.SyncCopies(crew); body2.MarkAllStatsDirty(); CharacterMaster[] members = crew.Members; foreach (CharacterMaster val2 in members) { CharacterBody val3 = (Object.op_Implicit((Object)(object)val2) ? val2.GetBody() : null); if (!Object.op_Implicit((Object)(object)val3) || !val3.healthComponent.alive) { continue; } val3.MarkAllStatsDirty(); if (!Stage.instance.completed) { SaveInventory(crew, Array.IndexOf(crew.Members, val2)); } if (crew.Mode == 0) { Vector3 val4 = val3.corePosition - body2.corePosition; if (((Vector3)(ref val4)).sqrMagnitude > 1600f) { TeleportNear(val3, body2); } } } } int[] array2 = crews.Keys.ToArray(); foreach (int key in array2) { Crew crew2 = crews[key]; CharacterBody val5 = (Object.op_Implicit((Object)(object)crew2.Owner) ? crew2.Owner.GetBody() : null); bool flag = Object.op_Implicit((Object)(object)val5) && ((Component)val5).gameObject.activeInHierarchy && val5.healthComponent.alive && Object.op_Implicit((Object)(object)val5.skillLocator) && Object.op_Implicit((Object)(object)val5.skillLocator.primary) && Object.op_Implicit((Object)(object)val5.skillLocator.primary.skillDef) && !HasMadeMen(crew2.Owner); if (!Object.op_Implicit((Object)(object)crew2.Owner) || flag) { array = crew2.Members; for (int num2 = 0; num2 < array.Length; num2++) { DestroyMaster(array[num2]); } crews.Remove(key); } } DistractEnemies(); } private void DistractEnemies() { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Invalid comparison between Unknown and I4 //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) CharacterBody[] source = (from m in crews.Values.SelectMany((Crew c) => c.Members) where Object.op_Implicit((Object)(object)m) select m.GetBody() into b where Object.op_Implicit((Object)(object)b) && b.healthComponent.alive select b).ToArray(); foreach (CharacterMaster readOnlyInstances in CharacterMaster.readOnlyInstancesList) { if (!Object.op_Implicit((Object)(object)readOnlyInstances) || (int)readOnlyInstances.teamIndex == 1) { continue; } TeamMask unprotectedTeams = TeamMask.GetUnprotectedTeams(readOnlyInstances.teamIndex); if (!((TeamMask)(ref unprotectedTeams)).HasTeam((TeamIndex)1)) { continue; } BaseAI[] components = ((Component)readOnlyInstances).GetComponents<BaseAI>(); foreach (BaseAI ai in components) { if (!Object.op_Implicit((Object)(object)ai.body) || !ai.body.healthComponent.alive) { continue; } CharacterBody characterBody = ai.currentEnemy.characterBody; SopranoIdentity sopranoIdentity = (Object.op_Implicit((Object)(object)characterBody) ? ((Component)characterBody).GetComponent<SopranoIdentity>() : null); if (!Object.op_Implicit((Object)(object)characterBody) || Object.op_Implicit((Object)(object)sopranoIdentity)) { CharacterBody val = source.Where(delegate(CharacterBody b) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) Vector3 val2 = b.corePosition - ai.body.corePosition; return ((Vector3)(ref val2)).sqrMagnitude <= 3600f && ai.HasLOS(b.corePosition); }).OrderBy(delegate(CharacterBody b) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) Vector3 val2 = b.corePosition - ai.body.corePosition; return ((Vector3)(ref val2)).sqrMagnitude; }).FirstOrDefault(); if (Object.op_Implicit((Object)(object)val)) { ai.currentEnemy.gameObject = ((Component)val).gameObject; ai.currentEnemy.Update(); ai.enemyAttention = 5f; } } } } } private static void TeleportNear(CharacterBody body, CharacterBody leader) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Run.instance.FindSafeTeleportPosition(body, ((Component)leader).gameObject.transform, 2f, 5f); TeleportHelper.TeleportBody(body, val); CharacterMotor component = ((Component)body).GetComponent<CharacterMotor>(); if (Object.op_Implicit((Object)(object)component)) { component.velocity = Vector3.zero; component.rootMotion = Vector3.zero; component.moveDirection = Vector3.zero; } Rigidbody[] componentsInChildren = ((Component)body).GetComponentsInChildren<Rigidbody>(); foreach (Rigidbody obj in componentsInChildren) { obj.velocity = Vector3.zero; obj.angularVelocity = Vector3.zero; } EntityStateMachine[] components = ((Component)body).GetComponents<EntityStateMachine>(); foreach (EntityStateMachine val2 in components) { if (val2.state is VarsityAthlete) { val2.SetNextStateToMain(); } } InputBankTest component2 = ((Component)body).GetComponent<InputBankTest>(); if (Object.op_Implicit((Object)(object)component2)) { component2.moveVector = Vector3.zero; } } private static void DestroyMaster(CharacterMaster? master) { if (Object.op_Implicit((Object)(object)master) && NetworkServer.active) { GameObject bodyObject = master.GetBodyObject(); if (Object.op_Implicit((Object)(object)bodyObject)) { NetworkServer.Destroy(bodyObject); } NetworkServer.Destroy(((Component)master).gameObject); } } private void OnDestroy() { Inventory.onInventoryChangedGlobal -= InventoryChanged; Stage.onServerStageComplete -= SaveStage; GlobalEventManager.onCharacterDeathGlobal -= GoonDied; if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } foreach (Crew value in crews.Values) { CharacterMaster[] members = value.Members; for (int i = 0; i < members.Length; i++) { DestroyMaster(members[i]); } } } internal static void ConfigureAI(GameObject master, bool goon = true) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0387: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Unknown result type (might be due to invalid IL or missing references) AISkillDriver[] components = master.GetComponents<AISkillDriver>(); for (int i = 0; i < components.Length; i++) { Object.DestroyImmediate((Object)(object)components[i]); } AISkillDriver val = Driver(master, "VarsityAthlete", (SkillSlot)2, 0f, 8f, los: true); val.activationRequiresAimConfirmation = true; AISkillDriver val2 = Driver(master, "WasteManagement", (SkillSlot)0, 0f, 80f, los: true); val2.movementType = (MovementType)0; AISkillDriver val3 = Driver(master, "PursueEnemy", (SkillSlot)(-1), 0f, float.PositiveInfinity, los: false); val3.buttonPressType = (ButtonPressType)1; AISkillDriver val4 = Driver(master, "FollowTheDon", (SkillSlot)(-1), goon ? 3f : 10f, float.PositiveInfinity, los: false); val4.moveTargetType = (TargetType)2; val4.aimType = (AimType)1; val4.selectionRequiresAimTarget = false; val4.buttonPressType = (ButtonPressType)1; val4.shouldSprint = goon; List<AISkillDriver> list = new List<AISkillDriver> { val, val2, val3, val4 }; if (goon) { components = (AISkillDriver[])(object)new AISkillDriver[3] { val, val2, val3 }; foreach (AISkillDriver obj in components) { obj.moveTargetType = (TargetType)2; obj.movementType = (MovementType)1; obj.minDistance = 0f; obj.maxDistance = float.PositiveInfinity; obj.shouldSprint = true; } val.selectionRequiresTargetLoS = false; val.activationRequiresTargetLoS = false; val2.selectionRequiresTargetLoS = false; val2.activationRequiresTargetLoS = false; val2.activationRequiresAimTargetLoS = true; val2.activationRequiresAimConfirmation = true; AISkillDriver val5 = Driver(master, "StayNearTheDon", (SkillSlot)(-1), 0f, 3f, los: false); val5.moveTargetType = (TargetType)2; val5.aimType = (AimType)0; val5.movementType = (MovementType)0; val5.selectionRequiresAimTarget = false; val5.buttonPressType = (ButtonPressType)1; list.Add(val5); } if (!goon) { AISkillDriver val6 = Driver(master, "Gabagool", (SkillSlot)3, 0f, float.PositiveInfinity, los: false); val6.maxUserHealthFraction = 0.8f; val6.selectionRequiresAimTarget = false; val6.moveTargetType = (TargetType)2; val6.movementType = (MovementType)0; val6.aimType = (AimType)0; list.Insert(0, val6); AISkillDriver val7 = Driver(master, "ShotCaller", (SkillSlot)1, 0f, 120f, los: true); val7.maxTimesSelected = 1; list.Insert(1, val7); master.AddComponent<SopranoCloneAI>(); } if (goon) { int role = master.GetComponent<CharacterMaster>().bodyPrefab.GetComponent<SopranoIdentity>().role; AISkillDriver val8 = Driver(master, "GoonSecondary", (SkillSlot)1, 0f, float.PositiveInfinity, los: false); AISkillDriver val9 = Driver(master, "GoonSpecial", (SkillSlot)3, 0f, float.PositiveInfinity, los: false); components = (AISkillDriver[])(object)new AISkillDriver[2] { val8, val9 }; foreach (AISkillDriver val10 in components) { val10.moveTargetType = (TargetType)2; val10.movementType = (MovementType)1; val10.shouldSprint = true; val10.selectionRequiresAimTarget = role != 1 && (Object)(object)val10 == (Object)(object)val8; val10.aimType = (AimType)(val10.selectionRequiresAimTarget ? 2 : 0); val10.activationRequiresAimTargetLoS = val10.selectionRequiresAimTarget; val10.activationRequiresAimConfirmation = val10.selectionRequiresAimTarget; val10.buttonPressType = (ButtonPressType)0; } list.Insert(0, val8); list.Insert(0, val9); } BaseAI component = master.GetComponent<BaseAI>(); component.ReplaceSkillDrivers(list.ToArray()); component.copyLeaderTarget = false; component.neverRetaliateFriendlies = true; component.fullVision = true; component.prioritizePlayers = false; component.aimVectorDampTime = 0.05f; component.aimVectorMaxSpeed = 720f; component.scanState = new SerializableEntityStateType(typeof(LookBusy)); if (goon) { master.AddComponent<GoonAI>(); master.AddComponent<GoonPersistence>(); } } private static AISkillDriver Driver(GameObject master, string name, SkillSlot slot, float min, float max, bool los) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) AISkillDriver obj = master.AddComponent<AISkillDriver>(); obj.customName = name; obj.skillSlot = slot; obj.requireSkillReady = (int)slot != -1; obj.minDistance = min; obj.maxDistance = max; obj.moveTargetType = (TargetType)0; obj.aimType = (AimType)2; obj.movementType = (MovementType)1; obj.selectionRequiresAimTarget = true; obj.selectionRequiresTargetLoS = los; obj.activationRequiresTargetLoS = los; obj.buttonPressType = (ButtonPressType)0; obj.driverUpdateTimerOverride = 0.1f; return obj; } } [DefaultExecutionOrder(-9000)] public sealed class SopranoCloneAI : MonoBehaviour { private BaseAI ai; private AISkillDriver call; private CharacterBody? lastTarget; private void Start() { ai = ((Component)this).GetComponent<BaseAI>(); call = ((Component)this).GetComponents<AISkillDriver>().First((AISkillDriver d) => d.customName == "ShotCaller"); } private void FixedUpdate() { if (NetworkServer.active && Object.op_Implicit((Object)(object)ai) && Object.op_Implicit((Object)(object)call)) { CharacterBody characterBody = ai.currentEnemy.characterBody; call.maxTimesSelected = 1; if ((Object)(object)characterBody != (Object)(object)lastTarget) { lastTarget = characterBody; call.timesSelected = 0; } } } } [DefaultExecutionOrder(-9000)] public sealed class GoonAI : MonoBehaviour { private BaseAI ai; private AISkillDriver[] drivers = Array.Empty<AISkillDriver>(); private GameObject? anchor; private int mode; private void Awake() { ai = ((Component)this).GetComponent<BaseAI>(); drivers = ((Component)this).GetComponents<AISkillDriver>(); } internal void SetMode(int value) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown mode = value; if (mode == 1 && Object.op_Implicit((Object)(object)ai.body)) { if (!Object.op_Implicit((Object)(object)anchor)) { anchor = new GameObject("SopranoHoldPosition"); } anchor.transform.position = ai.body.footPosition; } } internal Vector3 MoveDirection() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)ai.body)) { return Vector3.zero; } ? val; if (mode != 1 || !Object.op_Implicit((Object)(object)anchor)) { if (mode != 2 || !Object.op_Implicit((Object)(object)ai.currentEnemy.characterBody)) { CharacterBody? obj = SopranoCrew.Leader(ai.body); val = ((obj != null) ? obj.footPosition : ai.body.footPosition); } else { val = ai.currentEnemy.characterBody.corePosition; } } else { val = anchor.transform.position; } Vector3 val2 = (Vector3)val - ai.body.footPosition; val2.y = 0f; if (!(((Vector3)(ref val2)).sqrMagnitude > 9f)) { return Vector3.zero; } return ((Vector3)(ref val2)).normalized; } private void FixedUpdate() { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active || !Object.op_Implicit((Object)(object)ai) || !Object.op_Implicit((Object)(object)ai.body)) { return; } CharacterBody val = SopranoCrew.Leader(ai.body); if (mode == 1 && Object.op_Implicit((Object)(object)anchor)) { ai.leader.gameObject = anchor; } else if (Object.op_Implicit((Object)(object)val)) { ai.leader.gameObject = ((Component)val).gameObject; } ai.leader.Update(); bool flag = MoveDirection() == Vector3.zero; AISkillDriver[] array = drivers; foreach (AISkillDriver val2 in array) { if (val2.customName == "VarsityAthlete" || val2.customName == "WasteManagement" || val2.customName == "PursueEnemy" || val2.customName == "GoonSecondary" || val2.customName == "GoonSpecial") { val2.moveTargetType = (TargetType)((mode != 2) ? 2 : 0); val2.movementType = (MovementType)(!(mode != 2 && flag)); } if (val2.customName == "FollowTheDon") { val2.minDistance = ((mode == 2) ? float.PositiveInfinity : 3f); } } CharacterBody val3 = SopranoCrew.Target(ai.body); if (Object.op_Implicit((Object)(object)val3)) { ai.currentEnemy.gameObject = ((Component)val3).gameObject; ai.currentEnemy.Update(); ai.enemyAttention = 5f; return; } if (Object.op_Implicit((Object)(object)ai.currentEnemy.healthComponent) && !ai.currentEnemy.healthComponent.alive) { ai.currentEnemy.Reset(); } ai.ForceAcquireNearestEnemyIfNoCurrentEnemy(); } private void OnDestroy() { if (Object.op_Implicit((Object)(object)anchor)) { Object.Destroy((Object)(object)anchor); } } } public sealed class GoonPersistence : MonoBehaviour { private void Awake() { Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } } internal static class SopranoEconomy { internal static void ClearRun() { SopranoCombat.ClearRun(); } internal static void Eat(CharacterBody body) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active && body.healthComponent.alive) { body.AddTimedBuffDontRefreshDuration(SopranoCombat.GabagoolBuff, 30f, int.MaxValue); int buffCount = body.GetBuffCount(SopranoCombat.GabagoolBuff); SopranoVoice.TryPlay(body, "EatingFood"); HealthComponent healthComponent = body.healthComponent; float num = FoodBalance.HealthAfterCost(healthComponent.health, healthComponent.fullHealth, buffCount); if (num <= 0f) { healthComponent.Suicide((GameObject)null, (GameObject)null, DamageTypeCombo.op_Implicit((DamageType)262210)); } else { healthComponent.Networkhealth = num; } if (healthComponent.alive) { healthComponent.AddBarrier(healthComponent.fullHealth * FoodBalance.BarrierFraction(buffCount)); } } } } internal static class SopranoItems { [CompilerGenerated] private static class <>O { public static hook_GetItemCountEffective_ItemIndex <0>__StatCount; public static hook_RecalculateStats <1>__Recalculate; public static StatHookEventHandler <2>__Stats; public static Action<BossGroup> <3>__BossDefeated; } [ThreadStatic] private static CharacterBody? calculating; private static readonly BossScrapLedger BossRewards = new BossScrapLedger(); internal static void Register() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown object obj = <>O.<0>__StatCount; if (obj == null) { hook_GetItemCountEffective_ItemIndex val = StatCount; <>O.<0>__StatCount = val; obj = (object)val; } Inventory.GetItemCountEffective_ItemIndex += (hook_GetItemCountEffective_ItemIndex)obj; object obj2 = <>O.<1>__Recalculate; if (obj2 == null) { hook_RecalculateStats val2 = Recalculate; <>O.<1>__Recalculate = val2; obj2 = (object)val2; } CharacterBody.RecalculateStats += (hook_RecalculateStats)obj2; object obj3 = <>O.<2>__Stats; if (obj3 == null) { StatHookEventHandler val3 = Stats; <>O.<2>__Stats = val3; obj3 = (object)val3; } RecalculateStatsAPI.GetStatCoefficients += (StatHookEventHandler)obj3; BossGroup.onBossGroupDefeatedServer += BossDefeated; } internal static void Unregister() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown object obj = <>O.<0>__StatCount; if (obj == null) { hook_GetItemCountEffective_ItemIndex val = StatCount; <>O.<0>__StatCount = val; obj = (object)val; } Inventory.GetItemCountEffective_ItemIndex -= (hook_GetItemCountEffective_ItemIndex)obj; object obj2 = <>O.<1>__Recalculate; if (obj2 == null) { hook_RecalculateStats val2 = Recalculate; <>O.<1>__Recalculate = val2; obj2 = (object)val2; } CharacterBody.RecalculateStats -= (hook_Reca