using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Runtime.CompilerServices; using EntityStates; using EntityStates.Railgunner.Scope; using HG; using RoR2.Audio; using RoR2.Items; using RoR2.Navigation; using RoR2.Networking; using RoR2.PostProcessing; using RoR2.Projectile; using RoR2.Skills; using Unity; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.Serialization; namespace RoR2; [DisallowMultipleComponent] [RequireComponent(typeof(TeamComponent))] [RequireComponent(typeof(SkillLocator))] public class CharacterBody : NetworkBehaviour, ILifeBehavior, IDisplayNameProvider, IOnTakeDamageServerReceiver, IOnKilledOtherServerReceiver { public static class CommonAssets { public static SkillDef lunarUtilityReplacementSkillDef; public static SkillDef lunarPrimaryReplacementSkillDef; public static SkillDef lunarSecondaryReplacementSkillDef; public static SkillDef lunarSpecialReplacementSkillDef; public static NetworkSoundEventDef nullifiedBuffAppliedSound; public static NetworkSoundEventDef pulverizeBuildupBuffAppliedSound; public static NetworkSoundEventDef[] procCritAttackSpeedSounds; public static GameObject thornExplosionEffect; public static GameObject teleportOnLowHealthVFX; public static GameObject teleportOnLowHealthExplosion; public static GameObject teleportOnLowHealthExplosionNova; public static GameObject prayerBeadEffect; public static GameObject goldOnStageStartEffect; public static void Load() { LegacyResourcesAPI.LoadAsyncCallback("NetworkSoundEventDefs/nseNullifiedBuffApplied", delegate(NetworkSoundEventDef asset) { nullifiedBuffAppliedSound = asset; }); LegacyResourcesAPI.LoadAsyncCallback("NetworkSoundEventDefs/nsePulverizeBuildupBuffApplied", delegate(NetworkSoundEventDef asset) { pulverizeBuildupBuffAppliedSound = asset; }); procCritAttackSpeedSounds = new NetworkSoundEventDef[3]; LegacyResourcesAPI.LoadAsyncCallback("NetworkSoundEventDefs/nseProcCritAttackSpeed1", delegate(NetworkSoundEventDef asset) { procCritAttackSpeedSounds[0] = asset; }); LegacyResourcesAPI.LoadAsyncCallback("NetworkSoundEventDefs/nseProcCritAttackSpeed2", delegate(NetworkSoundEventDef asset) { procCritAttackSpeedSounds[1] = asset; }); LegacyResourcesAPI.LoadAsyncCallback("NetworkSoundEventDefs/nseProcCritAttackSpeed3", delegate(NetworkSoundEventDef asset) { procCritAttackSpeedSounds[2] = asset; }); AsyncOperationHandle asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/Effects/NoxiousThornExplosion"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { thornExplosionEffect = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/Effects/TeleportOnLowHealthVFX"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { teleportOnLowHealthVFX = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/Effects/TeleportOnLowHealthExplosion"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { teleportOnLowHealthExplosion = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/Effects/VagrantNovaExplosion"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { teleportOnLowHealthExplosionNova = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/Effects/ExtraStatsOnLevelUpScrapEffect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { prayerBeadEffect = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/Effects/GoldOnStageStartCoinGain"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { goldOnStageStartEffect = x.Result; }; SkillCatalog.skillsDefined.CallWhenAvailable(delegate { lunarUtilityReplacementSkillDef = SkillCatalog.GetSkillDef(SkillCatalog.FindSkillIndexByName("LunarUtilityReplacement")); lunarPrimaryReplacementSkillDef = SkillCatalog.GetSkillDef(SkillCatalog.FindSkillIndexByName("LunarPrimaryReplacement")); lunarSecondaryReplacementSkillDef = SkillCatalog.GetSkillDef(SkillCatalog.FindSkillIndexByName("LunarSecondaryReplacement")); lunarSpecialReplacementSkillDef = SkillCatalog.GetSkillDef(SkillCatalog.FindSkillIndexByName("LunarDetonatorSpecialReplacement")); }); } } private class TimedBuff { public BuffIndex buffIndex; public float timer; } public delegate void JumpDelegate(); [Flags] public enum BodyFlags : uint { None = 0u, IgnoreFallDamage = 1u, Mechanical = 2u, Masterless = 4u, ImmuneToGoo = 8u, ImmuneToExecutes = 0x10u, SprintAnyDirection = 0x20u, ResistantToAOE = 0x40u, HasBackstabPassive = 0x80u, HasBackstabImmunity = 0x100u, OverheatImmune = 0x200u, Void = 0x400u, ImmuneToVoidDeath = 0x800u, IgnoreItemUpdates = 0x1000u, Devotion = 0x2000u, IgnoreKnockback = 0x4000u, ImmuneToLava = 0x8000u } private struct ItemAvailability { public int helfireCount; public bool hasFireTrail; public bool hasAffixLunar; public bool hasAffixPoison; } [Serializable] public struct NetworkItemBehaviorData { public int intItemValue; public float floatValue; public ItemIndex itemIndex { get { return (ItemIndex)intItemValue; } set { intItemValue = (int)value; } } public NetworkItemBehaviorData(ItemIndex _index, float _floatValue) { intItemValue = (int)_index; floatValue = _floatValue; } public NetworkItemBehaviorData(int _index, float _floatVal) { intItemValue = _index; floatValue = _floatVal; } } public class ItemBehavior : MonoBehaviour { public CharacterBody body; public int stack; } public class AffixHauntedBehavior : ItemBehavior { private GameObject affixHauntedWard; private void FixedUpdate() { if (!NetworkServer.active) { return; } bool flag = stack > 0; if ((bool)affixHauntedWard != flag) { if (flag) { affixHauntedWard = UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load("Prefabs/NetworkedObjects/AffixHauntedWard")); affixHauntedWard.GetComponent().teamIndex = body.teamComponent.teamIndex; affixHauntedWard.GetComponent().Networkradius = 30f + body.radius; affixHauntedWard.GetComponent().AttachToGameObjectAndSpawn(body.gameObject); } else { UnityEngine.Object.Destroy(affixHauntedWard); affixHauntedWard = null; } } } private void OnDisable() { if ((bool)affixHauntedWard) { UnityEngine.Object.Destroy(affixHauntedWard); } } } public class QuestVolatileBatteryBehaviorServer : ItemBehavior { private NetworkedBodyAttachment attachment; private void Start() { attachment = UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load("Prefabs/NetworkedObjects/QuestVolatileBatteryAttachment")).GetComponent(); attachment.AttachToGameObjectAndSpawn(body.gameObject); } private void OnDestroy() { if ((bool)attachment) { UnityEngine.Object.Destroy(attachment.gameObject); attachment = null; } } } public class TimeBubbleItemBehaviorServer : ItemBehavior { private void OnDestroy() { if ((bool)body.timeBubbleWardInstance) { UnityEngine.Object.Destroy(body.timeBubbleWardInstance); } } } public class ElementalRingsBehavior : ItemBehavior { private void OnDisable() { if ((bool)body) { if (body.HasBuff(RoR2Content.Buffs.ElementalRingsReady)) { body.RemoveBuff(RoR2Content.Buffs.ElementalRingsReady); } if (body.HasBuff(RoR2Content.Buffs.ElementalRingsCooldown)) { body.RemoveBuff(RoR2Content.Buffs.ElementalRingsCooldown); } } } private void FixedUpdate() { bool flag = body.HasBuff(RoR2Content.Buffs.ElementalRingsCooldown); bool flag2 = body.HasBuff(RoR2Content.Buffs.ElementalRingsReady); if (!flag && !flag2) { body.AddBuff(RoR2Content.Buffs.ElementalRingsReady); } if (flag2 && flag) { body.RemoveBuff(RoR2Content.Buffs.ElementalRingsReady); } } } public class AffixEchoBehavior : ItemBehavior { private DeployableMinionSpawner echoSpawner1; private DeployableMinionSpawner echoSpawner2; private CharacterSpawnCard spawnCard; private List spawnedEchoes = new List(); private void FixedUpdate() { spawnCard.nodeGraphType = (body.isFlying ? MapNodeGroup.GraphType.Air : MapNodeGroup.GraphType.Ground); } private void Awake() { base.enabled = false; } private void OnEnable() { MasterCatalog.MasterIndex masterIndex = MasterCatalog.FindAiMasterIndexForBody(body.bodyIndex); spawnCard = ScriptableObject.CreateInstance(); spawnCard.prefab = MasterCatalog.GetMasterPrefab(masterIndex); spawnCard.inventoryToCopy = body.inventory; spawnCard.equipmentToGrant = new EquipmentDef[1]; spawnCard.itemsToGrant = new ItemCountPair[1] { new ItemCountPair { itemDef = RoR2Content.Items.SummonedEcho, count = 1 } }; CreateSpawners(); } private void OnDisable() { UnityEngine.Object.Destroy(spawnCard); spawnCard = null; for (int num = spawnedEchoes.Count - 1; num >= 0; num--) { if ((bool)spawnedEchoes[num]) { spawnedEchoes[num].TrueKill(); } } DestroySpawners(); } private void CreateSpawners() { Xoroshiro128Plus rng = new Xoroshiro128Plus(Run.instance.seed ^ (ulong)GetInstanceID()); CreateSpawner(ref echoSpawner1, DeployableSlot.RoboBallRedBuddy, spawnCard); CreateSpawner(ref echoSpawner2, DeployableSlot.RoboBallGreenBuddy, spawnCard); void CreateSpawner(ref DeployableMinionSpawner buddySpawner, DeployableSlot deployableSlot, SpawnCard spawnCard) { buddySpawner = new DeployableMinionSpawner(body.master, deployableSlot, rng) { respawnInterval = 30f, spawnCard = spawnCard }; buddySpawner.onMinionSpawnedServer += OnMinionSpawnedServer; } } private void DestroySpawners() { echoSpawner1?.Dispose(); echoSpawner1 = null; echoSpawner2?.Dispose(); echoSpawner2 = null; } private void OnMinionSpawnedServer(SpawnCard.SpawnResult spawnResult) { GameObject spawnedInstance = spawnResult.spawnedInstance; if (!spawnedInstance) { return; } CharacterMaster spawnedMaster = spawnedInstance.GetComponent(); if ((bool)spawnedMaster) { spawnedEchoes.Add(spawnedMaster); OnDestroyCallback.AddCallback(spawnedMaster.gameObject, delegate { spawnedEchoes.Remove(spawnedMaster); }); } } } private static class AssetReferences { public static GameObject engiShieldTempEffectPrefab; public static GameObject bucklerShieldTempEffectPrefab; public static GameObject slowDownTimeTempEffectPrefab; public static GameObject crippleEffectPrefab; public static GameObject tonicBuffEffectPrefab; public static GameObject weakTempEffectPrefab; public static GameObject energizedTempEffectPrefab; public static GameObject barrierTempEffectPrefab; public static GameObject nullifyStack1EffectPrefab; public static GameObject nullifyStack2EffectPrefab; public static GameObject nullifyStack3EffectPrefab; public static GameObject regenBoostEffectPrefab; public static GameObject elephantDefenseEffectPrefab; public static GameObject healingDisabledEffectPrefab; public static GameObject noCooldownEffectPrefab; public static GameObject doppelgangerEffectPrefab; public static GameObject deathmarkEffectPrefab; public static GameObject crocoRegenEffectPrefab; public static GameObject mercExposeEffectPrefab; public static GameObject lifestealOnHitEffectPrefab; public static GameObject teamWarCryEffectPrefab; public static GameObject randomDamageEffectPrefab; public static GameObject lunarGolemShieldEffectPrefab; public static GameObject warbannerEffectPrefab; public static GameObject teslaFieldEffectPrefab; public static GameObject lunarSecondaryRootEffectPrefab; public static GameObject lunarDetonatorEffectPrefab; public static GameObject fruitingEffectPrefab; public static GameObject mushroomVoidTempEffectPrefab; public static GameObject bearVoidTempEffectPrefab; public static GameObject outOfCombatArmorEffectPrefab; public static GameObject voidFogMildEffectPrefab; public static GameObject voidFogStrongEffectPrefab; public static GameObject voidJailerSlowEffectPrefab; public static GameObject voidRaidcrabWardWipeFogEffectPrefab; public static GameObject aurelioniteBlessingEffectInstance; public static GameObject permanentDebuffEffectPrefab; public static void Resolve() { AsyncOperationHandle asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/EngiShield"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { engiShieldTempEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/BucklerDefense"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { bucklerShieldTempEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/SlowDownTime"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { slowDownTimeTempEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/CrippleEffect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { crippleEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/TonicBuffEffect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { tonicBuffEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/WeakEffect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { weakTempEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/EnergizedEffect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { energizedTempEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/BarrierEffect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { barrierTempEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/RegenBoostEffect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { regenBoostEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/ElephantDefense"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { elephantDefenseEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/HealingDisabledEffect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { healingDisabledEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/NoCooldownEffect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { noCooldownEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/DoppelgangerEffect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { doppelgangerEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/NullifyStack1Effect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { nullifyStack1EffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/NullifyStack2Effect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { nullifyStack2EffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/NullifyStack3Effect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { nullifyStack3EffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/DeathMarkEffect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { deathmarkEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/CrocoRegenEffect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { crocoRegenEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/MercExposeEffect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { mercExposeEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/LifeStealOnHitAura"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { lifestealOnHitEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/TeamWarCryAura"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { teamWarCryEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/LunarDefense"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { lunarGolemShieldEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/RandomDamageBuffEffect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { randomDamageEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/WarbannerBuffEffect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { warbannerEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/TeslaFieldBuffEffect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { teslaFieldEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/LunarSecondaryRootEffect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { lunarSecondaryRootEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/LunarDetonatorEffect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { lunarDetonatorEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/FruitingEffect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { fruitingEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/MushroomVoidEffect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { mushroomVoidTempEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/BearVoidEffect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { bearVoidTempEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/VoidFogMildEffect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { voidFogMildEffectPrefab = x.Result; }; asyncOperationHandle = LegacyResourcesAPI.LoadAsync("Prefabs/TemporaryVisualEffects/VoidFogStrongEffect"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { voidFogStrongEffectPrefab = x.Result; }; asyncOperationHandle = Addressables.LoadAssetAsync("RoR2/DLC1/VoidRaidCrab/VoidRaidCrabWardWipeFogEffect.prefab"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { voidRaidcrabWardWipeFogEffectPrefab = x.Result; }; asyncOperationHandle = Addressables.LoadAssetAsync("RoR2/DLC1/OutOfCombatArmor/OutOfCombatArmorEffect.prefab"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { outOfCombatArmorEffectPrefab = x.Result; }; asyncOperationHandle = Addressables.LoadAssetAsync("RoR2/DLC1/VoidJailer/VoidJailerTetherDebuff.prefab"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { voidJailerSlowEffectPrefab = x.Result; }; asyncOperationHandle = Addressables.LoadAssetAsync("RoR2/DLC2/Elites/EliteAurelionite/AffixAurelioniteArmorBubble.prefab"); asyncOperationHandle.Completed += delegate(AsyncOperationHandle x) { aurelioniteBlessingEffectInstance = x.Result; }; } } private class ConstructTurretMessage : MessageBase { public GameObject builder; public Vector3 position; public Quaternion rotation; public MasterCatalog.NetworkMasterIndex turretMasterIndex; public override void Serialize(NetworkWriter writer) { writer.Write(builder); writer.Write(position); writer.Write(rotation); GeneratedNetworkCode._WriteNetworkMasterIndex_MasterCatalog(writer, turretMasterIndex); } public override void Deserialize(NetworkReader reader) { builder = reader.ReadGameObject(); position = reader.ReadVector3(); rotation = reader.ReadQuaternion(); turretMasterIndex = GeneratedNetworkCode._ReadNetworkMasterIndex_MasterCatalog(reader); } } private class DelayedDamageInfo { public DamageInfo halfDamage = new DamageInfo(); public float timeUntilDamage = 3f; } public class TeleportOnLowHealthBehavior : ItemBehavior { private CharacterBody characterBody; private bool hasActivated; private bool hasItem; private bool hasBuff; private bool hasCooldown; private void Start() { if (!hasActivated) { characterBody = GetComponent(); characterBody.RemoveBuff(DLC2Content.Buffs.TeleportOnLowHealth); characterBody.RemoveOldestTimedBuff(DLC2Content.Buffs.TeleportOnLowHealthCooldown); characterBody.RemoveBuff(DLC2Content.Buffs.TeleportOnLowHealthCooldown); characterBody.AddBuff(DLC2Content.Buffs.TeleportOnLowHealth); characterBody.hasTeleported = false; hasActivated = true; } } private void Update() { hasItem = characterBody.inventory.GetItemCount(DLC2Content.Items.TeleportOnLowHealth) > 0; hasBuff = characterBody.HasBuff(DLC2Content.Buffs.TeleportOnLowHealth); hasCooldown = characterBody.HasBuff(DLC2Content.Buffs.TeleportOnLowHealthCooldown); if (!hasItem) { if (hasBuff) { characterBody.RemoveBuff(DLC2Content.Buffs.TeleportOnLowHealth); } if (hasCooldown) { characterBody.RemoveBuff(DLC2Content.Buffs.TeleportOnLowHealthCooldown); } } else if (!hasBuff && !hasCooldown && characterBody.hasTeleported) { characterBody.AddBuff(DLC2Content.Buffs.TeleportOnLowHealth); characterBody.hasTeleported = false; } } private void OnDisable() { characterBody.RemoveBuff(DLC2Content.Buffs.TeleportOnLowHealth); characterBody.RemoveOldestTimedBuff(DLC2Content.Buffs.TeleportOnLowHealthCooldown); characterBody.RemoveBuff(DLC2Content.Buffs.TeleportOnLowHealthCooldown); } } public class DelayedDamageBehavior : ItemBehavior { private CharacterBody characterBody; private bool hasActivated; private bool hasItem; private bool hasBuff; private bool hasCooldown; private void Start() { if (!hasActivated) { characterBody = GetComponent(); hasActivated = true; } } private void Update() { hasItem = characterBody.inventory.GetItemCount(DLC2Content.Items.DelayedDamage) > 0; hasBuff = characterBody.HasBuff(DLC2Content.Buffs.DelayedDamageBuff); hasCooldown = characterBody.HasBuff(DLC2Content.Buffs.DelayedDamageBuff); if (!hasItem) { if (hasBuff) { characterBody.RemoveBuff(DLC2Content.Buffs.DelayedDamageBuff); characterBody.RemoveOldestTimedBuff(DLC2Content.Buffs.DelayedDamageBuff); } if (hasCooldown) { characterBody.RemoveBuff(DLC2Content.Buffs.DelayedDamageBuff); characterBody.RemoveOldestTimedBuff(DLC2Content.Buffs.DelayedDamageBuff); characterBody.RemoveBuff(DLC2Content.Buffs.DelayedDamageDebuff); } } } } public class MeteorAttackOnHighDamageBehavior : ItemBehavior { private CharacterBody characterBody; private bool hasActivated; private void FixedUpdate() { if (!hasActivated) { characterBody = GetComponent(); hasActivated = true; } if (characterBody.runicLensMeteorReady) { characterBody.runicLensStartTime = Run.instance.time; if (characterBody.runicLensStartTime >= characterBody.runicLensImpactTime && characterBody.runicLensMeteorReady) { characterBody.detonateRunicLensMeteor(); characterBody.runicLensMeteorReady = false; } } } } [Serializable] public class CharacterBodyUnityEvent : UnityEvent { } [HideInInspector] [Tooltip("This is assigned to the prefab automatically by BodyCatalog at runtime. Do not set this value manually.")] public BodyIndex bodyIndex = BodyIndex.None; public bool CharacterIsVisible; [Tooltip("How much the combat director paid for this character. If this enemy is culled, then we refund the combat director for the cost it paid to spawn us.")] public float cost = -1f; public bool dontCull; [Tooltip("The baseline importance for this character. 0 is standard, elites get a +2 modifier, bosses get +10, players get +5000. Characters of low importance are culled in some circumstances.")] public int BaseImportance; [Tooltip("The dynamically calculated level of importance for this enemy.")] public int Importance = -1; public bool inLava; [Tooltip("The language token to use as the base name of this character.")] public string baseNameToken; public string subtitleNameToken; private BuffIndex[] activeBuffsList; private int activeBuffsListCount; private int[] buffs; private int eliteBuffCount; private List timedBuffs = new List(); [NonSerialized] public int pendingTonicAfflictionCount; public JumpDelegate onJump; private int previousMultiKillBuffCount; private GameObject warCryEffectInstance; [EnumMask(typeof(BodyFlags))] public BodyFlags bodyFlags; private NetworkInstanceId masterObjectId; private GameObject _masterObject; private CharacterMaster _master; private bool linkedToMaster; private bool disablingHurtBoxes; private EquipmentIndex previousEquipmentIndex = EquipmentIndex.None; private new Transform transform; private SfxLocator sfxLocator; public float lavaCooldown = 0.2f; private float lavaTimer; private ItemAvailability itemAvailability; private static List instancesList; public static readonly ReadOnlyCollection readOnlyInstancesList; private bool _isSprinting; private const float outOfCombatDelay = 5f; private const float outOfDangerDelay = 7f; private float outOfCombatStopwatch; private float outOfDangerStopwatch; private bool _outOfDanger = true; private Vector3 previousPosition; private const float notMovingWait = 1f; private float notMovingStopwatch; public bool rootMotionInMainState; public float mainRootSpeed; public float baseMaxHealth; public float baseRegen; public float baseMaxShield; public float baseMoveSpeed; public float baseAcceleration; public float baseJumpPower; public float baseDamage; public float baseAttackSpeed; public float baseCrit; public float baseArmor; public float baseVisionDistance = float.PositiveInfinity; public int baseJumpCount = 1; public float sprintingSpeedMultiplier = 1.45f; public bool autoCalculateLevelStats; public float levelMaxHealth; public float levelRegen; public float levelMaxShield; public float levelMoveSpeed; public float levelJumpPower; public float levelDamage; public float levelAttackSpeed; public float levelCrit; public float levelArmor; private float m_surfaceSpeedBoost; private bool statsDirty; private int currentHealthLevel; private int oldHealthLevel; private float damageFromRecalculateStats; private int numberOfKills; private bool canCleanInventory = true; public int extraSecondaryFromSkill; public int extraSpecialFromSkill; private GameObject lowerHealthHigherDamageSteam; [HideInInspector] public LowerHealthHigherDamageEffectUpdater lowerHealthHigherDamageEffectUpdater; private bool boostAllStatsTimerStarted; private bool boostAllStatsCoolDownTimerStarted; private float boostAllStatsTimer; private float boostAllStatsTriggerTimer = 5f; private float boostAllStatsCoolDownTriggerTimer = 10f; private float boostAllStatsCoolDownStartTimer; private float boostAllStatsCoolDownTimer; private float boostAllStatsStartTimer; private float boostAllStatsTriggerChance; public bool canBoostAllStats; private float boostAllStatsDefaultTriggerChance = 0.25f; private float boostAllStatsTriggerIncrease = 0.1f; private float boostAllStatsMultiplier = 0.2f; private int extraStatsOnLevelUpCountModifier; [HideInInspector] public IncreaseDamageOnMultiKillItemDisplayUpdater increaseDamageOnMultiKillItemDisplayUpdater; private bool lowerPricedChestsActive; private bool canPurchaseLoweredPricedChests; public bool allSkillsDisabled; private ScreenDamageCalculatorDisabledSkills screenDamageSkillsDisabled; private int oldComboMeter; public bool isTeleporting; public int solitudeLevelCount; private float aimTimer; private const uint masterDirtyBit = 1u; private const uint buffsDirtyBit = 2u; private const uint outOfCombatBit = 4u; private const uint outOfDangerBit = 8u; private const uint sprintingBit = 16u; private const uint allDirtyBits = 31u; public Action OnNetworkItemBehaviorUpdate; private HelfireController helfireController; private float helfireLifetime; private DamageTrail fireTrail; public bool wasLucky; private const float poisonballAngle = 25f; private const float poisonballDamageCoefficient = 1f; private const float poisonballRefreshTime = 6f; private float poisonballTimer; private const float lunarMissileDamageCoefficient = 0.3f; private const float lunarMissileRefreshTime = 10f; private const float lunarMissileDelayBetweenShots = 0.1f; private float lunarMissileRechargeTimer = 10f; private float lunarMissileTimerBetweenShots; private int remainingMissilesToFire; private GameObject lunarMissilePrefab; private GameObject timeBubbleWardInstance; private TemporaryVisualEffect engiShieldTempEffectInstance; private TemporaryVisualEffect bucklerShieldTempEffectInstance; private TemporaryVisualEffect slowDownTimeTempEffectInstance; private TemporaryVisualEffect crippleEffectInstance; private TemporaryVisualEffect tonicBuffEffectInstance; private TemporaryVisualEffect weakTempEffectInstance; private TemporaryVisualEffect energizedTempEffectInstance; private TemporaryVisualEffect barrierTempEffectInstance; private TemporaryVisualEffect nullifyStack1EffectInstance; private TemporaryVisualEffect nullifyStack2EffectInstance; private TemporaryVisualEffect nullifyStack3EffectInstance; private TemporaryVisualEffect regenBoostEffectInstance; private TemporaryVisualEffect elephantDefenseEffectInstance; private TemporaryVisualEffect healingDisabledEffectInstance; private TemporaryVisualEffect noCooldownEffectInstance; private TemporaryVisualEffect doppelgangerEffectInstance; private TemporaryVisualEffect deathmarkEffectInstance; private TemporaryVisualEffect crocoRegenEffectInstance; private TemporaryVisualEffect mercExposeEffectInstance; private TemporaryVisualEffect lifestealOnHitEffectInstance; private TemporaryVisualEffect teamWarCryEffectInstance; private TemporaryVisualEffect randomDamageEffectInstance; private TemporaryVisualEffect lunarGolemShieldEffectInstance; private TemporaryVisualEffect warbannerEffectInstance; private TemporaryVisualEffect teslaFieldEffectInstance; private TemporaryVisualEffect lunarSecondaryRootEffectInstance; private TemporaryVisualEffect lunarDetonatorEffectInstance; private TemporaryVisualEffect fruitingEffectInstance; private TemporaryVisualEffect mushroomVoidTempEffectInstance; private TemporaryVisualEffect bearVoidTempEffectInstance; private TemporaryVisualEffect outOfCombatArmorEffectInstance; private TemporaryVisualEffect voidFogMildEffectInstance; private TemporaryVisualEffect voidFogStrongEffectInstance; private TemporaryVisualEffect voidJailerSlowEffectInstance; private TemporaryVisualEffect voidRaidcrabWardWipeFogEffectInstance; private TemporaryVisualEffect aurelioniteBlessingEffectInstance; [Tooltip("How long it takes for spread bloom to reset from full.")] public float spreadBloomDecayTime = 0.45f; [Tooltip("The spread bloom interpretation curve.")] public AnimationCurve spreadBloomCurve; private float spreadBloomInternal; [FormerlySerializedAs("crosshairPrefab")] [SerializeField] [Tooltip("The crosshair prefab used for this body.")] private GameObject _defaultCrosshairPrefab; [HideInInspector] public bool hideCrosshair; private const float multiKillMaxInterval = 1f; private float multiKillTimer; private const int multiKillThresholdForWarcry = 4; private const float increasedDamageMultiKillMaxInterval = 5f; private float increasedDamageKillTimer; private int oldKillcount; private const int multiKillThresholdForIncreasedDamage = 5; private int secondarySkillStacks; [HideInInspector] public IncreasePrimaryDamageEffectUpdater increasePrimaryDamageEffectUpdater; private float delayedDamageRefreshTime = 10f; private float secondHalfOfDamageTime = 3f; private int oldDelayedDamageCount; private bool halfDamageReady; private float halfDamageTimer; public bool protectFromOneShot; private DamageInfo secondHalfOfDamage; private List incomingDamageList = new List(); public bool hasTeleported; private Vector3 runicLensPosition; private EffectData runicLensEffectData = new EffectData(); private DamageInfo runicLensDamageInfo = new DamageInfo(); private float runicLensDamage; private float runicLensBlastForce; private float runicLensBlastRadius; private float runicLensStartTime; private float runicLensImpactTime; public bool runicLensMeteorReady; private bool hasStackableDebuff; private bool tamperedHeartActive; private float tamperedHeartRegenBonus; private float tamperedHeartMSpeedBonus; private float tamperedHeartDamageBonus; private float tamperedHeartAttackSpeedBonus; private float tamperedHeartArmorBonus; [Tooltip("The child transform to be used as the aiming origin.")] public Transform aimOriginTransform; [Tooltip("The hull size to use when pathfinding for this object.")] public HullClassification hullClassification; [Tooltip("The icon displayed for ally healthbars")] public Texture portraitIcon; [Tooltip("The main color of the body. Currently only used in the logbook.")] public Color bodyColor = Color.clear; [Tooltip("By default, players and enemies are assigned to either PlayerBody or EnemyBody, based on team. But some enemies (Gups) want a specific layer - this will skip that assignment.")] public bool doNotReassignToTeamBasedCollisionLayer; [FormerlySerializedAs("isBoss")] [Tooltip("Whether or not this is a boss for dropping items on death.")] public bool isChampion; public VehicleSeat currentVehicle; [Tooltip("The pod prefab to use for handling this character's first-time spawn animation.")] public GameObject preferredPodPrefab; [Tooltip("The preferred state to use for handling the character's first-time spawn animation. Only used with no preferred pod prefab.")] public SerializableEntityStateType preferredInitialStateType = new SerializableEntityStateType(typeof(Uninitialized)); public uint skinIndex; public string customKillTotalStatName; public Transform overrideCoreTransform; private static int kCmdCmdAddTimedBuff; private static int kCmdCmdSetInLava; private static int kCmdCmdUpdateSprint; private static int kCmdCmdOnSkillActivated; private static int kCmdCmdTransmitItemBehavior; private static int kRpcRpcTransmitItemBehavior; private static int kCmdCmdSpawnDelayedDamageEffect; private static int kRpcRpcTeleportCharacterToSafety; private static int kRpcRpcBark; private static int kCmdCmdRequestVehicleEjection; private static int kRpcRpcUsePreferredInitialStateType; public CharacterMaster master { get { if (!masterObject) { return null; } return _master; } } public Inventory inventory { get; private set; } public bool isPlayerControlled { get; private set; } public float executeEliteHealthFraction { get; private set; } public GameObject masterObject { get { if (!_masterObject) { if (NetworkServer.active) { _masterObject = NetworkServer.FindLocalObject(masterObjectId); } else if (NetworkClient.active) { _masterObject = ClientScene.FindLocalObject(masterObjectId); } _master = (_masterObject ? _masterObject.GetComponent() : null); if ((bool)_master) { PlayerCharacterMasterController component = _masterObject.GetComponent(); isPlayerControlled = component; if ((bool)inventory) { inventory.onInventoryChanged -= OnInventoryChanged; } inventory = _master.inventory; if ((bool)inventory) { inventory.onInventoryChanged += OnInventoryChanged; OnInventoryChanged(); } statsDirty = true; } } return _masterObject; } set { masterObjectId = value.GetComponent().netId; statsDirty = true; } } public Rigidbody rigidbody { get; private set; } public NetworkIdentity networkIdentity { get; private set; } public CharacterMotor characterMotor { get; private set; } public CharacterDirection characterDirection { get; private set; } public TeamComponent teamComponent { get; private set; } public HealthComponent healthComponent { get; private set; } public EquipmentSlot equipmentSlot { get; private set; } public InputBankTest inputBank { get; private set; } public SkillLocator skillLocator { get; private set; } public ModelLocator modelLocator { get; private set; } public HurtBoxGroup hurtBoxGroup { get; private set; } public HurtBox mainHurtBox { get; private set; } public Transform coreTransform { get; private set; } public bool hasEffectiveAuthority { get; private set; } public bool isSprinting { get { return _isSprinting; } set { if (_isSprinting != value) { _isSprinting = value; RecalculateStats(); if (value) { OnSprintStart(); } else { OnSprintStop(); } if (NetworkServer.active) { SetDirtyBit(16u); } else if (hasEffectiveAuthority) { CallCmdUpdateSprint(value); } } } } public bool outOfCombat { get; private set; } = true; public bool outOfDanger { get { return _outOfDanger; } private set { if (_outOfDanger != value) { _outOfDanger = value; OnOutOfDangerChanged(); } } } public float experience { get; private set; } public float level { get; private set; } public float maxHealth { get; private set; } public float maxBarrier { get; private set; } public float barrierDecayRate { get; private set; } public float regen { get; private set; } public float maxShield { get; private set; } public float moveSpeed { get; private set; } public float acceleration { get; private set; } public float surfaceSpeedBoost { get { return m_surfaceSpeedBoost; } set { if (!Mathf.Approximately(m_surfaceSpeedBoost, value)) { m_surfaceSpeedBoost = value; RecalculateStats(); } } } public float jumpPower { get; private set; } public int maxJumpCount { get; private set; } public float maxJumpHeight { get; private set; } public float damage { get; private set; } public float attackSpeed { get; private set; } public float crit { get; private set; } public float critMultiplier { get; private set; } public float bleedChance { get; private set; } public float armor { get; private set; } public float visionDistance { get; private set; } public float critHeal { get; private set; } public float cursePenalty { get; private set; } public bool hasOneShotProtection { get; private set; } public bool isGlass { get; private set; } public float oneShotProtectionFraction { get; private set; } public bool canPerformBackstab { get; private set; } public bool canReceiveBackstab { get; private set; } public float maxBonusHealth { get; private set; } public bool shouldAim { get { if (aimTimer > 0f) { return !isSprinting; } return false; } } public int killCountServer { get; private set; } public float bestFitRadius => Mathf.Max(radius, characterMotor ? characterMotor.capsuleHeight : 1f); public float bestFitActualRadius => Mathf.Max(radius, characterMotor ? (characterMotor.capsuleHeight * 0.5f) : 1f); public bool hasCloakBuff { get { if (!HasBuff(RoR2Content.Buffs.Cloak)) { return HasBuff(RoR2Content.Buffs.AffixHauntedRecipient); } return true; } } public float spreadBloomAngle => spreadBloomCurve.Evaluate(spreadBloomInternal); public GameObject defaultCrosshairPrefab => _defaultCrosshairPrefab; public int multiKillCount { get; private set; } public int increasedDamageKillCount { get; private set; } public int increasedDamageKillCountBuff { get; private set; } public float luminousShotDamage { get; private set; } public bool luminousShotReady { get; private set; } public Vector3 corePosition { get { if (!coreTransform) { return transform.position; } return coreTransform.position; } } public Vector3 footPosition { get { Vector3 position = transform.position; if ((bool)characterMotor) { position.y -= characterMotor.capsuleHeight * 0.5f; } return position; } } public float radius { get; private set; } public Vector3 aimOrigin { get { if (!aimOriginTransform) { return corePosition; } return aimOriginTransform.position; } } public bool isElite { get; private set; } public bool isBoss { get { if ((bool)master) { return master.isBoss; } return false; } } public bool isFlying { get { if ((bool)characterMotor) { return characterMotor.isFlying; } return true; } } public Run.FixedTimeStamp localStartTime { get; private set; } = Run.FixedTimeStamp.positiveInfinity; public bool isEquipmentActivationAllowed { get { if ((bool)currentVehicle) { return currentVehicle.isEquipmentActivationAllowed; } return true; } } public event Action onInventoryChanged; public event Action onSkillActivatedServer; public event Action onSkillActivatedAuthority; public static event Action onBodyAwakeGlobal; public static event Action onBodyDestroyGlobal; public static event Action onBodyStartGlobal; public static event Action onBodyInventoryChangedGlobal; [MethodImpl(MethodImplOptions.AggressiveInlining)] public CharacterBody GetBody() { return this; } public void DebugDrawLine(Vector3 start, Vector3 end, Color color) { Debug.DrawLine(start, end, color, 5f); } [InitDuringStartup] private static void LoadCommonAssets() { CommonAssets.Load(); } public string GetDisplayName() { return Language.GetString(baseNameToken); } public string GetSubtitle() { return Language.GetString(subtitleNameToken); } public string GetUserName() { string text = ""; if ((bool)master) { PlayerCharacterMasterController component = master.GetComponent(); if ((bool)component) { text = component.GetDisplayName(); } } if (string.IsNullOrEmpty(text)) { text = GetDisplayName(); } return text; } public string GetColoredUserName() { Color32 color = new Color32(127, 127, 127, byte.MaxValue); string text = null; if ((bool)master) { PlayerCharacterMasterController component = master.GetComponent(); if ((bool)component) { GameObject networkUserObject = component.networkUserObject; if ((bool)networkUserObject) { NetworkUser component2 = networkUserObject.GetComponent(); if ((bool)component2) { color = component2.userColor; text = component2.userName; } } } } if (text == null) { text = GetDisplayName(); } return Util.GenerateColoredString(text, color); } [Server] private void WriteBuffs(NetworkWriter writer) { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::WriteBuffs(UnityEngine.Networking.NetworkWriter)' called on client"); return; } writer.Write((byte)activeBuffsListCount); for (int i = 0; i < activeBuffsListCount; i++) { BuffIndex buffIndex = activeBuffsList[i]; BuffDef buffDef = BuffCatalog.GetBuffDef(buffIndex); writer.WriteBuffIndex(buffIndex); if (buffDef.canStack) { writer.WritePackedUInt32((uint)buffs[(int)buffIndex]); } } } [Client] private void ReadBuffs(NetworkReader reader) { if (!NetworkClient.active) { Debug.LogWarning("[Client] function 'System.Void RoR2.CharacterBody::ReadBuffs(UnityEngine.Networking.NetworkReader)' called on server"); return; } if (activeBuffsList == null) { Debug.LogError("Trying to ReadBuffs, but our activeBuffsList is null"); return; } int activeBuffsIndexToCheck = 0; int num = reader.ReadByte(); BuffIndex buffIndex = BuffIndex.None; for (int i = 0; i < num; i++) { BuffIndex buffIndex2 = reader.ReadBuffIndex(); BuffDef buffDef = BuffCatalog.GetBuffDef(buffIndex2); if (buffDef != null) { int num2 = 1; if (buffDef.canStack) { num2 = (int)reader.ReadPackedUInt32(); } if (num2 > 0 && !NetworkServer.active) { ZeroBuffIndexRange(buffIndex + 1, buffIndex2); SetBuffCount(buffIndex2, num2); } buffIndex = buffIndex2; } else { Debug.LogErrorFormat("No BuffDef for index {0}. body={1}, netID={2}", buffIndex2, base.gameObject, base.netId); } } if (!NetworkServer.active) { ZeroBuffIndexRange(buffIndex + 1, (BuffIndex)BuffCatalog.buffCount); } void ZeroBuffIndexRange(BuffIndex start, BuffIndex end) { while (activeBuffsIndexToCheck < activeBuffsListCount) { BuffIndex buffIndex3 = activeBuffsList[activeBuffsIndexToCheck]; if (end <= buffIndex3) { break; } int num3; if (start <= buffIndex3) { SetBuffCount(buffIndex3, 0); num3 = activeBuffsIndexToCheck - 1; activeBuffsIndexToCheck = num3; } num3 = activeBuffsIndexToCheck + 1; activeBuffsIndexToCheck = num3; } } } [Server] public void AddBuff(BuffIndex buffType) { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::AddBuff(RoR2.BuffIndex)' called on client"); } else if (buffType != BuffIndex.None) { SetBuffCount(buffType, buffs[(int)buffType] + 1); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] [Server] public void AddBuff(BuffDef buffDef) { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::AddBuff(RoR2.BuffDef)' called on client"); } else { AddBuff(buffDef?.buffIndex ?? BuffIndex.None); } } [Server] public void RemoveBuff(BuffIndex buffType) { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::RemoveBuff(RoR2.BuffIndex)' called on client"); } else { if (buffType == BuffIndex.None) { return; } SetBuffCount(buffType, buffs[(int)buffType] - 1); if (buffType == RoR2Content.Buffs.MedkitHeal.buffIndex) { if (GetBuffCount(RoR2Content.Buffs.MedkitHeal.buffIndex) == 0) { int itemCount = inventory.GetItemCount(RoR2Content.Items.Medkit); float num = 20f; float num2 = maxHealth * 0.05f * (float)itemCount; healthComponent.Heal(num + num2, default(ProcChainMask)); EffectData effectData = new EffectData { origin = transform.position }; effectData.SetNetworkedObjectReference(base.gameObject); EffectManager.SpawnEffect(LegacyResourcesAPI.Load("Prefabs/Effects/MedkitHealEffect"), effectData, transmit: true); } } else if (buffType == RoR2Content.Buffs.TonicBuff.buffIndex) { if ((bool)inventory && GetBuffCount(RoR2Content.Buffs.TonicBuff) == 0 && pendingTonicAfflictionCount > 0) { inventory.GiveItem(RoR2Content.Items.TonicAffliction, pendingTonicAfflictionCount); PickupIndex pickupIndex = PickupCatalog.FindPickupIndex(RoR2Content.Items.TonicAffliction.itemIndex); GenericPickupController.SendPickupMessage(master, pickupIndex); pendingTonicAfflictionCount = 0; } } else if (buffType == DLC2Content.Buffs.SoulCost.buffIndex) { cursePenalty -= 0.1f * (float)GetBuffCount(DLC2Content.Buffs.SoulCost); } } } [MethodImpl(MethodImplOptions.AggressiveInlining)] [Server] public void RemoveBuff(BuffDef buffDef) { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::RemoveBuff(RoR2.BuffDef)' called on client"); } else { RemoveBuff(buffDef?.buffIndex ?? BuffIndex.None); } } public void SetBuffCount(BuffIndex buffType, int newCount) { newCount = Mathf.Max(newCount, 0); ref int reference = ref buffs[(int)buffType]; if (newCount == reference) { return; } int num = reference; reference = newCount; BuffDef buffDef = BuffCatalog.GetBuffDef(buffType); bool flag = true; if (!buffDef.canStack) { flag = num == 0 != (newCount == 0); } if (flag) { if (newCount == 0) { ArrayUtils.ArrayRemoveAt(activeBuffsList, ref activeBuffsListCount, Array.IndexOf(activeBuffsList, buffType)); OnBuffFinalStackLost(buffDef); } else if (num == 0) { int i; for (i = 0; i < activeBuffsListCount && buffType >= activeBuffsList[i]; i++) { } ArrayUtils.ArrayInsert(ref activeBuffsList, ref activeBuffsListCount, i, in buffType); OnBuffFirstStackGained(buffDef); } if (NetworkServer.active) { SetDirtyBit(2u); } } statsDirty = true; if (NetworkClient.active) { OnClientBuffsChanged(); } UpdateItemAvailability(); } private void OnBuffFirstStackGained(BuffDef buffDef) { if (buffDef.isElite) { eliteBuffCount++; } if (buffDef == RoR2Content.Buffs.Intangible) { UpdateHurtBoxesEnabled(); } else if (buffDef == RoR2Content.Buffs.WarCryBuff) { if (HasBuff(RoR2Content.Buffs.TeamWarCry)) { ClearTimedBuffs(RoR2Content.Buffs.TeamWarCry); } } else if (buffDef == RoR2Content.Buffs.TeamWarCry) { if (HasBuff(RoR2Content.Buffs.WarCryBuff)) { ClearTimedBuffs(RoR2Content.Buffs.WarCryBuff); } } else if (buffDef == RoR2Content.Buffs.AffixEcho && NetworkServer.active) { AddItemBehavior(1); } } private void OnBuffFinalStackLost(BuffDef buffDef) { if (buffDef.isElite) { eliteBuffCount--; } if (buffDef.buffIndex == RoR2Content.Buffs.Intangible.buffIndex) { UpdateHurtBoxesEnabled(); } else if (buffDef == RoR2Content.Buffs.AffixEcho && NetworkServer.active) { AddItemBehavior(0); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int GetBuffCount(BuffIndex buffType) { return ArrayUtils.GetSafe(buffs, (int)buffType); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int GetBuffCount(BuffDef buffDef) { return GetBuffCount(buffDef?.buffIndex ?? BuffIndex.None); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool HasBuff(BuffIndex buffType) { return GetBuffCount(buffType) > 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool HasBuff(BuffDef buffDef) { return HasBuff(buffDef?.buffIndex ?? BuffIndex.None); } public void AddTimedBuffAuthority(BuffIndex buffType, float duration) { if (NetworkServer.active) { AddTimedBuff(buffType, duration); } else { CallCmdAddTimedBuff(buffType, duration); } } [Command] public void CmdAddTimedBuff(BuffIndex buffType, float duration) { AddTimedBuff(buffType, duration); } [Server] public void AddTimedBuff(BuffDef buffDef, float duration, int maxStacks) { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::AddTimedBuff(RoR2.BuffDef,System.Single,System.Int32)' called on client"); } else { if (ImmuneToDebuffBehavior.OverrideDebuff(buffDef, this)) { return; } if (GetBuffCount(buffDef) < maxStacks) { AddTimedBuff(buffDef, duration); return; } int num = -1; float num2 = duration; for (int i = 0; i < timedBuffs.Count; i++) { if (timedBuffs[i].buffIndex == buffDef.buffIndex && timedBuffs[i].timer < num2) { num = i; num2 = timedBuffs[i].timer; } } if (num >= 0) { timedBuffs[num].timer = duration; } } } [Server] public void AddTimedBuff(BuffDef buffDef, float duration) { BuffIndex buffType; if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::AddTimedBuff(RoR2.BuffDef,System.Single)' called on client"); } else { if ((object)buffDef == null || ImmuneToDebuffBehavior.OverrideDebuff(buffDef, this)) { return; } buffType = buffDef.buffIndex; if (buffType == BuffIndex.None) { return; } if (buffDef == RoR2Content.Buffs.AttackSpeedOnCrit) { int num = (inventory ? inventory.GetItemCount(RoR2Content.Items.AttackSpeedOnCrit) : 0); int num2 = 1 + num * 2; int num3 = 0; int num4 = -1; float num5 = 999f; for (int i = 0; i < timedBuffs.Count; i++) { if (timedBuffs[i].buffIndex == buffType) { num3++; if (timedBuffs[i].timer < num5) { num4 = i; num5 = timedBuffs[i].timer; } } } if (num3 < num2) { timedBuffs.Add(new TimedBuff { buffIndex = buffType, timer = duration }); AddBuff(buffType); ChildLocator component = modelLocator.modelTransform.GetComponent(); if ((bool)component) { Transform obj = component.FindChild("HandL"); Transform transform = component.FindChild("HandR"); GameObject effectPrefab = LegacyResourcesAPI.Load("Prefabs/Effects/WolfProcEffect"); if ((bool)obj) { EffectManager.SimpleMuzzleFlash(effectPrefab, base.gameObject, "HandL", transmit: true); } if ((bool)transform) { EffectManager.SimpleMuzzleFlash(effectPrefab, base.gameObject, "HandR", transmit: true); } } } else if (num4 > -1) { timedBuffs[num4].timer = duration; } EntitySoundManager.EmitSoundServer(CommonAssets.procCritAttackSpeedSounds[Mathf.Min(CommonAssets.procCritAttackSpeedSounds.Length - 1, num3)].index, networkIdentity); } else if (buffDef == RoR2Content.Buffs.BeetleJuice) { if (RefreshStacks() < 10) { timedBuffs.Add(new TimedBuff { buffIndex = buffType, timer = duration }); AddBuff(buffType); } } else if (buffDef == RoR2Content.Buffs.NullifyStack) { if (HasBuff(RoR2Content.Buffs.Nullified)) { return; } int num6 = 0; for (int j = 0; j < timedBuffs.Count; j++) { if (timedBuffs[j].buffIndex == buffType) { num6++; if (timedBuffs[j].timer < duration) { timedBuffs[j].timer = duration; } } } if (num6 < 2) { timedBuffs.Add(new TimedBuff { buffIndex = buffType, timer = duration }); AddBuff(buffType); } else { ClearTimedBuffs(RoR2Content.Buffs.NullifyStack.buffIndex); AddTimedBuff(RoR2Content.Buffs.Nullified.buffIndex, 3f); } } else if (buffDef == RoR2Content.Buffs.AffixHauntedRecipient) { if (!HasBuff(RoR2Content.Buffs.AffixHaunted)) { DefaultBehavior(); } } else if (buffDef == DLC2Content.Buffs.EliteBeadCorruption) { if (!HasBuff(DLC2Content.Buffs.EliteBead)) { DefaultBehavior(); } } else if (buffDef == RoR2Content.Buffs.LunarDetonationCharge) { RefreshStacks(); DefaultBehavior(); } else if (buffDef == RoR2Content.Buffs.Overheat) { RefreshStacks(); DefaultBehavior(); } else if (buffDef == DLC2Content.Buffs.BoostAllStatsBuff) { RefreshStacks(); DefaultBehavior(); } else { DefaultBehavior(); } } void DefaultBehavior() { bool flag = false; if (!buffDef.canStack) { for (int k = 0; k < timedBuffs.Count; k++) { if (timedBuffs[k].buffIndex == buffType) { flag = true; timedBuffs[k].timer = Mathf.Max(timedBuffs[k].timer, duration); break; } } } if (!flag) { timedBuffs.Add(new TimedBuff { buffIndex = buffType, timer = duration }); AddBuff(buffType); } if ((bool)buffDef.startSfx) { EntitySoundManager.EmitSoundServer(buffDef.startSfx.index, networkIdentity); } } int RefreshStacks() { int num7 = 0; for (int l = 0; l < timedBuffs.Count; l++) { TimedBuff timedBuff = timedBuffs[l]; if (timedBuff.buffIndex == buffType) { num7++; if (timedBuff.timer < duration) { timedBuff.timer = duration; } } } return num7; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] [Server] public void AddTimedBuff(BuffIndex buffIndex, float duration) { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::AddTimedBuff(RoR2.BuffIndex,System.Single)' called on client"); } else { AddTimedBuff(BuffCatalog.GetBuffDef(buffIndex), duration); } } [Server] public void ClearTimedBuffs(BuffIndex buffType) { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::ClearTimedBuffs(RoR2.BuffIndex)' called on client"); return; } for (int num = timedBuffs.Count - 1; num >= 0; num--) { TimedBuff timedBuff = timedBuffs[num]; if (timedBuff.buffIndex == buffType) { timedBuffs.RemoveAt(num); RemoveBuff(timedBuff.buffIndex); } } } [MethodImpl(MethodImplOptions.AggressiveInlining)] [Server] public void ClearTimedBuffs(BuffDef buffDef) { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::ClearTimedBuffs(RoR2.BuffDef)' called on client"); } else { ClearTimedBuffs(buffDef?.buffIndex ?? BuffIndex.None); } } [Server] public void RemoveOldestTimedBuff(BuffIndex buffType) { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::RemoveOldestTimedBuff(RoR2.BuffIndex)' called on client"); return; } float num = float.NegativeInfinity; int num2 = -1; for (int num3 = timedBuffs.Count - 1; num3 >= 0; num3--) { TimedBuff timedBuff = timedBuffs[num3]; if (timedBuff.buffIndex == buffType && num < timedBuff.timer) { num = timedBuff.timer; num2 = num3; } } if (num2 > 0) { timedBuffs.RemoveAt(num2); RemoveBuff(buffType); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] [Server] public void RemoveOldestTimedBuff(BuffDef buffDef) { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::RemoveOldestTimedBuff(RoR2.BuffDef)' called on client"); } else { RemoveOldestTimedBuff(buffDef?.buffIndex ?? BuffIndex.None); } } [Server] private void UpdateBuffs(float deltaTime) { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::UpdateBuffs(System.Single)' called on client"); return; } for (int num = timedBuffs.Count - 1; num >= 0; num--) { TimedBuff timedBuff = timedBuffs[num]; timedBuff.timer -= deltaTime; if (timedBuff.timer <= 0f) { timedBuffs.RemoveAt(num); RemoveBuff(timedBuff.buffIndex); } } } [Client] private void OnClientBuffsChanged() { if (!NetworkClient.active) { Debug.LogWarning("[Client] function 'System.Void RoR2.CharacterBody::OnClientBuffsChanged()' called on server"); return; } bool num = HasBuff(RoR2Content.Buffs.WarCryBuff); if (!num && (bool)warCryEffectInstance) { UnityEngine.Object.Destroy(warCryEffectInstance); } if (num && !warCryEffectInstance) { Transform transform = (mainHurtBox ? mainHurtBox.transform : this.transform); if ((bool)transform) { warCryEffectInstance = UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load("Prefabs/Effects/WarCryEffect"), transform.position, Quaternion.identity, transform); } } if ((bool)inventory && inventory.GetItemCount(DLC2Content.Items.IncreaseDamageOnMultiKill) > 0) { int buffCount = GetBuffCount(DLC2Content.Buffs.IncreaseDamageBuff); if ((bool)increaseDamageOnMultiKillItemDisplayUpdater) { increaseDamageOnMultiKillItemDisplayUpdater.UpdateKillCounterText(buffCount); } if (previousMultiKillBuffCount < buffCount) { Util.PlaySound("Play_item_proc_increaseDamageMultiKill", base.gameObject); } previousMultiKillBuffCount = buffCount; } } public NetworkInstanceId GetMasterObjectId() { return masterObjectId; } private void GetSelectedCharacterType() { } private void UpdateHurtBoxesEnabled() { bool flag = ((bool)inventory && inventory.GetItemCount(RoR2Content.Items.Ghost) > 0) || HasBuff(RoR2Content.Buffs.Intangible); if (flag == disablingHurtBoxes) { return; } if ((bool)hurtBoxGroup) { if (flag) { HurtBoxGroup obj = hurtBoxGroup; int hurtBoxesDeactivatorCounter = obj.hurtBoxesDeactivatorCounter + 1; obj.hurtBoxesDeactivatorCounter = hurtBoxesDeactivatorCounter; } else { HurtBoxGroup obj2 = hurtBoxGroup; int hurtBoxesDeactivatorCounter = obj2.hurtBoxesDeactivatorCounter - 1; obj2.hurtBoxesDeactivatorCounter = hurtBoxesDeactivatorCounter; } } disablingHurtBoxes = flag; } private void OnInventoryChanged() { EquipmentIndex currentEquipmentIndex = inventory.currentEquipmentIndex; if (currentEquipmentIndex != previousEquipmentIndex) { EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(previousEquipmentIndex); EquipmentDef equipmentDef2 = EquipmentCatalog.GetEquipmentDef(currentEquipmentIndex); if (equipmentDef != null) { OnEquipmentLost(equipmentDef); } if (equipmentDef2 != null) { OnEquipmentGained(equipmentDef2); } previousEquipmentIndex = currentEquipmentIndex; } statsDirty = true; UpdateHurtBoxesEnabled(); AddItemBehavior(HasBuff(RoR2Content.Buffs.AffixHaunted) ? 1 : 0); AddItemBehavior(HasBuff(DLC1Content.Buffs.EliteEarth) ? 1 : 0); AddItemBehavior(HasBuff(DLC1Content.Buffs.EliteVoid) ? 1 : 0); AddItemBehavior(HasBuff(DLC2Content.Buffs.EliteBead) ? 1 : 0); AddItemBehavior(HasBuff(DLC2Content.Buffs.EliteAurelionite) ? 1 : 0); if (NetworkServer.active) { AddItemBehavior((inventory.GetEquipment(inventory.activeEquipmentSlot).equipmentDef == RoR2Content.Equipment.QuestVolatileBattery) ? 1 : 0); AddItemBehavior(inventory.GetItemCount(RoR2Content.Items.IceRing) + inventory.GetItemCount(RoR2Content.Items.FireRing)); AddItemBehavior(inventory.GetItemCount(DLC1Content.Items.ElementalRingVoid)); AddItemBehavior(inventory.GetItemCount(DLC1Content.Items.OutOfCombatArmor)); AddItemBehavior(inventory.GetItemCount(DLC1Content.Items.PrimarySkillShuriken)); AddItemBehavior(inventory.GetItemCount(DLC1Content.Items.MushroomVoid)); AddItemBehavior(inventory.GetItemCount(DLC1Content.Items.BearVoid)); AddItemBehavior(inventory.GetItemCount(DLC1Content.Items.LunarSun)); AddItemBehavior(inventory.GetItemCount(DLC1Content.Items.VoidMegaCrabItem)); AddItemBehavior(inventory.GetItemCount(DLC1Content.Items.DroneWeapons)); AddItemBehavior(inventory.GetItemCount(DLC1Content.Items.DroneWeaponsBoost)); AddItemBehavior(inventory.GetItemCount(DLC2Content.Items.MeteorAttackOnHighDamage)); AddItemBehavior(inventory.GetItemCount(DLC2Content.Items.TeleportOnLowHealth)); } executeEliteHealthFraction = Util.ConvertAmplificationPercentageIntoReductionPercentage(13f * (float)inventory.GetItemCount(RoR2Content.Items.ExecuteLowHealthElite)) / 100f; if ((bool)skillLocator) { ReplaceSkillIfItemPresent(skillLocator.primary, RoR2Content.Items.LunarPrimaryReplacement.itemIndex, CommonAssets.lunarPrimaryReplacementSkillDef); ReplaceSkillIfItemPresent(skillLocator.secondary, RoR2Content.Items.LunarSecondaryReplacement.itemIndex, CommonAssets.lunarSecondaryReplacementSkillDef); ReplaceSkillIfItemPresent(skillLocator.special, RoR2Content.Items.LunarSpecialReplacement.itemIndex, CommonAssets.lunarSpecialReplacementSkillDef); ReplaceSkillIfItemPresent(skillLocator.utility, RoR2Content.Items.LunarUtilityReplacement.itemIndex, CommonAssets.lunarUtilityReplacementSkillDef); } this.onInventoryChanged?.Invoke(); CharacterBody.onBodyInventoryChangedGlobal?.Invoke(this); UpdateItemAvailability(); } private void ReplaceSkillIfItemPresent(GenericSkill skill, ItemIndex itemIndex, SkillDef skillDef) { if ((bool)skill) { if (inventory.GetItemCount(itemIndex) > 0 && (bool)skillDef) { skill.SetSkillOverride(this, skillDef, GenericSkill.SkillOverridePriority.Replacement); } else { skill.UnsetSkillOverride(this, skillDef, GenericSkill.SkillOverridePriority.Replacement); } } } private void OnEquipmentLost(EquipmentDef equipmentDef) { if (NetworkServer.active && (object)equipmentDef.passiveBuffDef != null) { RemoveBuff(equipmentDef.passiveBuffDef); } } private void OnEquipmentGained(EquipmentDef equipmentDef) { if (NetworkServer.active && (object)equipmentDef.passiveBuffDef != null) { AddBuff(equipmentDef.passiveBuffDef); } } private void UpdateMasterLink() { if (!linkedToMaster && (bool)master && (bool)master) { master.OnBodyStart(this); linkedToMaster = true; skinIndex = master.loadout.bodyLoadoutManager.GetSkinIndex(bodyIndex); } } public static void Init() { AssetReferences.Resolve(); } private void Awake() { transform = base.transform; rigidbody = GetComponent(); networkIdentity = GetComponent(); teamComponent = GetComponent(); healthComponent = GetComponent(); equipmentSlot = GetComponent(); skillLocator = GetComponent(); modelLocator = GetComponent(); characterMotor = GetComponent(); characterDirection = GetComponent(); inputBank = GetComponent(); sfxLocator = GetComponent(); activeBuffsList = BuffCatalog.GetPerBuffBuffer(); buffs = BuffCatalog.GetPerBuffBuffer(); if ((bool)modelLocator) { modelLocator.onModelChanged += OnModelChanged; OnModelChanged(modelLocator.modelTransform); } radius = 1f; CapsuleCollider component = GetComponent(); if ((bool)component) { radius = component.radius; } else { SphereCollider component2 = GetComponent(); if ((bool)component2) { radius = component2.radius; } } try { CharacterBody.onBodyAwakeGlobal?.Invoke(this); } catch (Exception message) { Debug.LogError(message); } } private void OnModelChanged(Transform modelTransform) { hurtBoxGroup = null; mainHurtBox = null; coreTransform = transform; if ((bool)modelTransform) { hurtBoxGroup = modelTransform.GetComponent(); if ((bool)hurtBoxGroup) { mainHurtBox = hurtBoxGroup.mainHurtBox; if ((bool)mainHurtBox) { coreTransform = mainHurtBox.transform; } } } if ((bool)overrideCoreTransform) { coreTransform = overrideCoreTransform; } } private void Start() { UpdateAuthority(); localStartTime = Run.FixedTimeStamp.now; bool num = (bodyFlags & BodyFlags.Masterless) != 0; outOfCombatStopwatch = float.PositiveInfinity; outOfDangerStopwatch = float.PositiveInfinity; notMovingStopwatch = 0f; if (NetworkServer.active) { outOfCombat = true; outOfDanger = true; } RecalculateStats(); UpdateMasterLink(); if (num) { healthComponent.Networkhealth = maxHealth; } if ((bool)sfxLocator && healthComponent.alive) { Util.PlaySound(sfxLocator.aliveLoopStart, base.gameObject); } if (!doNotReassignToTeamBasedCollisionLayer) { base.gameObject.layer = LayerIndex.GetAppropriateLayerForTeam(teamComponent.teamIndex); if (characterMotor != null) { characterMotor.Motor.RebuildCollidableLayers(); } } CharacterBody.onBodyStartGlobal?.Invoke(this); if ((bool)master && NetworkServer.active) { if (master.devotionInventoryPrefab == null) { _ = master.isDevotedMinion; } if (isPlayerControlled && (bool)master.devotionInventoryPrefab) { _ = master.devotionInventoryPrefab != null; } int num2 = ((inventory != null) ? inventory.GetItemCount(DLC2Content.Items.GoldOnStageStart) : 0); if (num2 > 0) { TransmitItemBehavior(new NetworkItemBehaviorData(DLC2Content.Items.GoldOnStageStart.itemIndex, 0f)); uint difficultyScaledCost = (uint)Run.instance.GetDifficultyScaledCost((int)(50f + level * 1.5f * (float)num2)); master.GiveMoney(difficultyScaledCost); } } } public void Update() { float deltaTime = Time.deltaTime; outOfCombatStopwatch += deltaTime; outOfDangerStopwatch += deltaTime; aimTimer = Mathf.Max(aimTimer - deltaTime, 0f); UpdateOutOfCombatAndDanger(); UpdateSpreadBloom(deltaTime); DoItemUpdates(deltaTime); UpdateNotMoving(deltaTime); HandleLavaDamage(deltaTime); } private void UpdateNotMoving(float deltaTime) { if (NetworkServer.active) { Vector3 position = transform.position; float num = 0.1f * deltaTime; if ((position - previousPosition).sqrMagnitude <= num * num) { notMovingStopwatch += deltaTime; } else { notMovingStopwatch = 0f; } previousPosition = position; } } private void DoItemUpdates(float deltaTime) { if ((bodyFlags & BodyFlags.IgnoreItemUpdates) == 0) { if (NetworkServer.active) { UpdateMultiKill(deltaTime); UpdateHelfire(deltaTime); UpdateAffixPoison(deltaTime); UpdateAffixLunar(deltaTime); UpdateLowerHealthHigherDamage(); UpdateDelayedDamage(deltaTime); UpdateSecondHalfOfDamage(deltaTime); } UpdateFireTrail(); } } private void UpdateOutOfCombatAndDanger() { bool active = NetworkServer.active; bool flag = outOfCombat; bool flag2 = flag; if (active || hasEffectiveAuthority) { flag2 = outOfCombatStopwatch >= 5f; if (outOfCombat != flag2) { if (NetworkServer.active) { SetDirtyBit(4u); } outOfCombat = flag2; statsDirty = true; } } if (active) { bool flag3 = outOfDangerStopwatch >= 7f; bool flag4 = outOfDanger; bool flag5 = flag && flag4; bool num = flag2 && flag3; if (outOfDanger != flag3) { SetDirtyBit(8u); outOfDanger = flag3; statsDirty = true; } if (num && !flag5) { OnOutOfCombatAndDangerServer(); } } } [Command] public void CmdSetInLava(bool b) { inLava = b; } public void SetInLava(bool b) { if (inLava != b) { if (!NetworkServer.active && base.hasAuthority) { CallCmdSetInLava(b); } inLava = b; } } public void InflictLavaDamage() { DamageInfo damageInfo = new DamageInfo(); damageInfo.damage = 10f; if (isChampion || isBoss) { damageInfo.damage = healthComponent.fullCombinedHealth / 100f; } else if (teamComponent.teamIndex == TeamIndex.Monster || teamComponent.teamIndex == TeamIndex.Void) { damageInfo.damage = healthComponent.fullCombinedHealth / 50f; } else { damageInfo.damage = healthComponent.fullCombinedHealth / 10f; } damageInfo.damageType = DamageType.IgniteOnHit; damageInfo.position = footPosition; healthComponent.TakeDamage(damageInfo); } public void HandleLavaDamage(float deltaTime) { bool flag = (bodyFlags & BodyFlags.ImmuneToLava) != 0; if (inLava && NetworkServer.active) { lavaTimer -= deltaTime; if (lavaTimer <= 0f && !flag) { InflictLavaDamage(); lavaTimer = lavaCooldown; } } else { lavaTimer = 0f; } } private void UpdateItemAvailability() { if ((bool)inventory) { itemAvailability.helfireCount = inventory.GetItemCount(JunkContent.Items.BurnNearby); } itemAvailability.hasFireTrail = HasBuff(RoR2Content.Buffs.AffixRed); itemAvailability.hasAffixLunar = HasBuff(RoR2Content.Buffs.AffixLunar); itemAvailability.hasAffixPoison = HasBuff(RoR2Content.Buffs.AffixPoison); } public void FixedUpdate() { float fixedDeltaTime = Time.fixedDeltaTime; bool flag = (bodyFlags & BodyFlags.IgnoreItemUpdates) == 0; if (NetworkServer.active) { if (flag) { UpdateBuffs(fixedDeltaTime); } UpdateOutOfCombatAndDanger(); } if (statsDirty) { RecalculateStats(); } } public void OnDeathStart() { base.enabled = false; if ((bool)sfxLocator) { Util.PlaySound(sfxLocator.aliveLoopStop, base.gameObject); } if (NetworkServer.active && (bool)currentVehicle) { currentVehicle.EjectPassenger(base.gameObject); } if ((bool)master) { master.OnBodyDeath(this); } ModelLocator component = GetComponent(); if (!component) { return; } Transform modelTransform = component.modelTransform; if ((bool)modelTransform) { CharacterModel component2 = modelTransform.GetComponent(); if ((bool)component2) { component2.OnDeath(); } } } public void OnTakeDamageServer(DamageReport damageReport) { if (damageReport.damageDealt > 0f) { outOfDangerStopwatch = 0f; } if ((bool)master) { master.OnBodyDamaged(damageReport); } } public void OnSkillActivated(GenericSkill skill) { if (skill.isCombatSkill) { outOfCombatStopwatch = 0f; } if (hasEffectiveAuthority) { this.onSkillActivatedAuthority?.Invoke(skill); } if (NetworkServer.active) { this.onSkillActivatedServer?.Invoke(skill); if (inventory.GetItemCount(DLC2Content.Items.IncreasePrimaryDamage) <= 0) { return; } if (bodyIndex == BodyCatalog.SpecialCases.RailGunner()) { if ((object)skillLocator.primary == skill) { if (GetBuffCount(DLC2Content.Buffs.IncreasePrimaryDamageBuff) > 0 && !BaseScopeState.inScope) { luminousShotReady = true; } } else { luminousShotReady = false; } if ((object)skillLocator.primary == skill && BaseScopeState.inScope) { AddIncreasePrimaryDamageStack(); } } else { if (!skill.skillDef.autoHandleLuminousShot) { return; } if ((object)skillLocator.secondary == skill) { AddIncreasePrimaryDamageStack(); } else if ((object)skillLocator.primary == skill) { if (GetBuffCount(DLC2Content.Buffs.IncreasePrimaryDamageBuff) > 0) { luminousShotReady = true; } else { luminousShotReady = false; } } } } else { CallCmdOnSkillActivated((sbyte)skillLocator.FindSkillSlot(skill)); } } public void OnDestroy() { try { CharacterBody.onBodyDestroyGlobal?.Invoke(this); } catch (Exception message) { Debug.LogError(message); } if ((bool)sfxLocator) { Util.PlaySound(sfxLocator.aliveLoopStop, base.gameObject); } if ((object)modelLocator != null) { modelLocator.onModelChanged -= OnModelChanged; } if ((bool)inventory) { inventory.onInventoryChanged -= OnInventoryChanged; } if ((bool)master) { master.OnBodyDestroyed(this); } } public float GetNormalizedThreatValue() { if ((bool)Run.instance) { return (master ? ((float)master.money) : 0f) * Run.instance.oneOverCompensatedDifficultyCoefficientSquared; } return 0f; } private void OnEnable() { instancesList.Add(this); } private void OnDisable() { instancesList.Remove(this); } private void OnValidate() { if (autoCalculateLevelStats) { PerformAutoCalculateLevelStats(); } if (!Application.isPlaying && bodyIndex != BodyIndex.None) { bodyIndex = BodyIndex.None; } } private void UpdateAuthority() { hasEffectiveAuthority = Util.HasEffectiveAuthority(base.gameObject); } public override void OnStartAuthority() { UpdateAuthority(); } public override void OnStopAuthority() { UpdateAuthority(); } private void OnSprintStart() { if ((bool)sfxLocator) { Util.PlaySound(sfxLocator.sprintLoopStart, base.gameObject); } } private void OnSprintStop() { if ((bool)sfxLocator) { Util.PlaySound(sfxLocator.sprintLoopStop, base.gameObject); } } [Command] private void CmdUpdateSprint(bool newIsSprinting) { isSprinting = newIsSprinting; } [Command] private void CmdOnSkillActivated(sbyte skillIndex) { OnSkillActivated(skillLocator.GetSkill((SkillSlot)skillIndex)); } private void OnOutOfDangerChanged() { if (outOfDanger && healthComponent.shield != healthComponent.fullShield) { Util.PlaySound("Play_item_proc_personal_shield_recharge", base.gameObject); } } [Server] private void OnOutOfCombatAndDangerServer() { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::OnOutOfCombatAndDangerServer()' called on client"); } } [Server] public bool GetNotMoving() { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Boolean RoR2.CharacterBody::GetNotMoving()' called on client"); return false; } return notMovingStopwatch >= 1f; } public void PerformAutoCalculateLevelStats() { levelMaxHealth = Mathf.Round(baseMaxHealth * 0.3f); levelMaxShield = Mathf.Round(baseMaxShield * 0.3f); levelRegen = baseRegen * 0.2f; levelMoveSpeed = 0f; levelJumpPower = 0f; levelDamage = baseDamage * 0.2f; levelAttackSpeed = 0f; levelCrit = 0f; levelArmor = 0f; } public void MarkAllStatsDirty() { statsDirty = true; } private void UpdateLowerHealthHigherDamageVFX() { if ((bool)lowerHealthHigherDamageSteam) { ParticleSystem.EmissionModule emission = lowerHealthHigherDamageSteam.GetComponent().emission; emission.rateOverTime = 35f; } } public void UpdateLowerHealthHigherDamage() { if (!inventory) { return; } int itemCount = inventory.GetItemCount(DLC2Content.Items.LowerHealthHigherDamage); if (NetworkServer.active) { if (itemCount > 0) { if ((bool)inventory && healthComponent.health > 0f && teamComponent.teamIndex == TeamIndex.Player) { float normalizedHealth = healthComponent.GetNormalizedHealth(); if ((double)normalizedHealth <= 0.5 && !HasBuff(DLC2Content.Buffs.LowerHealthHigherDamageBuff)) { AddBuff(DLC2Content.Buffs.LowerHealthHigherDamageBuff); Util.PlaySound("Play_item_proc_lowerHealthHigherDamage_proc", base.gameObject); TransmitItemBehavior(new NetworkItemBehaviorData(DLC2Content.Items.LowerHealthHigherDamage.itemIndex, 1f)); } else if (HasBuff(DLC2Content.Buffs.LowerHealthHigherDamageBuff) && (double)normalizedHealth > 0.5) { RemoveBuff(DLC2Content.Buffs.LowerHealthHigherDamageBuff); TransmitItemBehavior(new NetworkItemBehaviorData(DLC2Content.Items.LowerHealthHigherDamage.itemIndex, 0f)); } } } else if (HasBuff(DLC2Content.Buffs.LowerHealthHigherDamageBuff)) { RemoveBuff(DLC2Content.Buffs.LowerHealthHigherDamageBuff); TransmitItemBehavior(new NetworkItemBehaviorData(DLC2Content.Items.LowerHealthHigherDamage.itemIndex, 0f)); } } else if (itemCount == 0 && HasBuff(DLC2Content.Buffs.LowerHealthHigherDamageBuff) && healthComponent.health > 0f && teamComponent.teamIndex == TeamIndex.Player && (double)healthComponent.GetNormalizedHealth() > 0.5) { RemoveBuff(DLC2Content.Buffs.LowerHealthHigherDamageBuff); TransmitItemBehavior(new NetworkItemBehaviorData(DLC2Content.Items.LowerHealthHigherDamage.itemIndex, 0f)); } } private void SetBoostAllStatsStartTimer(float t) { if (!boostAllStatsTimerStarted) { boostAllStatsStartTimer = t; boostAllStatsTimer = boostAllStatsStartTimer; boostAllStatsTimerStarted = true; } } private void SetBoostAllStatsCoolDownTimer(float t) { if (boostAllStatsCoolDownTimerStarted) { boostAllStatsCoolDownStartTimer = t; boostAllStatsCoolDownTimer = boostAllStatsCoolDownStartTimer; } } private float CalculateBoostAllStatsTriggerChance(int i) { boostAllStatsTriggerChance = boostAllStatsDefaultTriggerChance + boostAllStatsTriggerIncrease * (float)(i - 1); if ((double)boostAllStatsTriggerChance >= 0.5) { boostAllStatsTriggerChance = 0.5f; } return boostAllStatsTriggerChance; } private void UpdateBoostAllStatsTimer(float t) { if (!NetworkServer.active || !inventory) { return; } int itemCount = inventory.GetItemCount(DLC2Content.Items.BoostAllStats); if (!boostAllStatsCoolDownTimerStarted && itemCount > 0) { SetBoostAllStatsStartTimer(t); boostAllStatsTimer += t; if (boostAllStatsTimer >= boostAllStatsStartTimer + boostAllStatsTriggerTimer) { if (RoR2Application.rng.RangeFloat(0f, 1f) <= CalculateBoostAllStatsTriggerChance(inventory.GetItemCount(DLC2Content.Items.BoostAllStats))) { AddBuff(DLC2Content.Buffs.BoostAllStatsBuff); RecalculateStats(); boostAllStatsTimerStarted = false; boostAllStatsCoolDownTimerStarted = true; SetBoostAllStatsCoolDownTimer(t); } else { boostAllStatsTimerStarted = false; boostAllStatsCoolDownTimerStarted = false; } } } else if (boostAllStatsCoolDownTimerStarted) { boostAllStatsCoolDownTimer += t; if (boostAllStatsCoolDownTimer >= boostAllStatsStartTimer + boostAllStatsCoolDownTriggerTimer) { RemoveBuff(DLC2Content.Buffs.BoostAllStatsBuff); RecalculateStats(); boostAllStatsCoolDownTimerStarted = false; } } } public void RecalculateStats() { if (!Run.instance) { return; } float num = level; TeamManager.instance.GetTeamExperience(teamComponent.teamIndex); float num2 = TeamManager.instance.GetTeamLevel(teamComponent.teamIndex); int num3 = 0; int num4 = 0; int num5 = 0; int num6 = 0; int num7 = 0; int num8 = 0; int num9 = 0; int num10 = 0; int num11 = 0; int num12 = 0; int num13 = 0; int num14 = 0; int num15 = 0; int num16 = 0; int num17 = 0; int num18 = 0; int num19 = 0; int num20 = 0; int num21 = 0; int num22 = 0; int num23 = 0; int num24 = 0; int num25 = 0; int num26 = 0; int num27 = 0; int num28 = 0; int num29 = 0; int num30 = 0; int num31 = 0; int num32 = 0; int num33 = 0; int num34 = 0; int num35 = 0; int num36 = 0; int num37 = 0; int num38 = 0; int num39 = 0; int num40 = 0; int num41 = 0; int num42 = 0; int num43 = 0; int num44 = 0; int num45 = 0; int num46 = 0; int num47 = 0; int num48 = 0; int num49 = 0; int num50 = 0; EquipmentIndex equipmentIndex = EquipmentIndex.None; uint num51 = 0u; int num52 = 0; int num53 = 0; int num54 = 0; int num55 = 0; if ((bool)inventory) { num3 = inventory.GetItemCount(RoR2Content.Items.LevelBonus); num4 = inventory.GetItemCount(RoR2Content.Items.Infusion); num5 = inventory.GetItemCount(RoR2Content.Items.HealWhileSafe); num6 = inventory.GetItemCount(RoR2Content.Items.PersonalShield); num7 = inventory.GetItemCount(RoR2Content.Items.Hoof); num8 = inventory.GetItemCount(RoR2Content.Items.SprintOutOfCombat); num9 = inventory.GetItemCount(RoR2Content.Items.Feather); num10 = inventory.GetItemCount(RoR2Content.Items.Syringe); num11 = inventory.GetItemCount(RoR2Content.Items.CritGlasses); num12 = inventory.GetItemCount(RoR2Content.Items.AttackSpeedOnCrit); num13 = inventory.GetItemCount(JunkContent.Items.CooldownOnCrit); num14 = inventory.GetItemCount(RoR2Content.Items.HealOnCrit); num15 = inventory.GetItemCount(RoR2Content.Items.ShieldOnly); num16 = inventory.GetItemCount(RoR2Content.Items.AlienHead); num17 = inventory.GetItemCount(RoR2Content.Items.Knurl); num18 = inventory.GetItemCount(RoR2Content.Items.BoostHp); num19 = inventory.GetItemCount(JunkContent.Items.CritHeal); num20 = inventory.GetItemCount(RoR2Content.Items.SprintBonus); num21 = inventory.GetItemCount(RoR2Content.Items.SecondarySkillMagazine); num23 = inventory.GetItemCount(RoR2Content.Items.SprintArmor); num24 = inventory.GetItemCount(RoR2Content.Items.UtilitySkillMagazine); num25 = inventory.GetItemCount(RoR2Content.Items.HealthDecay); num27 = inventory.GetItemCount(RoR2Content.Items.TonicAffliction); num28 = inventory.GetItemCount(RoR2Content.Items.LunarDagger); num26 = inventory.GetItemCount(RoR2Content.Items.DrizzlePlayerHelper); num29 = inventory.GetItemCount(RoR2Content.Items.MonsoonPlayerHelper); num30 = inventory.GetItemCount(RoR2Content.Items.Pearl); num31 = inventory.GetItemCount(RoR2Content.Items.ShinyPearl); num32 = inventory.GetItemCount(RoR2Content.Items.InvadingDoppelganger); num33 = inventory.GetItemCount(RoR2Content.Items.CutHp); num34 = inventory.GetItemCount(RoR2Content.Items.BoostAttackSpeed); num35 = inventory.GetItemCount(RoR2Content.Items.BleedOnHitAndExplode); num36 = inventory.GetItemCount(RoR2Content.Items.LunarBadLuck); num37 = inventory.GetItemCount(RoR2Content.Items.FlatHealth); num38 = inventory.GetItemCount(RoR2Content.Items.TeamSizeDamageBonus); num39 = inventory.GetItemCount(RoR2Content.Items.SummonedEcho); num40 = inventory.GetItemCount(RoR2Content.Items.UseAmbientLevel); num22 = inventory.GetItemCount(DLC1Content.Items.EquipmentMagazineVoid); num44 = inventory.GetItemCount(DLC1Content.Items.HalfAttackSpeedHalfCooldowns); num45 = inventory.GetItemCount(DLC1Content.Items.HalfSpeedDoubleHealth); num41 = inventory.GetItemCount(RoR2Content.Items.BleedOnHit); num42 = inventory.GetItemCount(DLC1Content.Items.AttackSpeedAndMoveSpeed); num43 = inventory.GetItemCount(DLC1Content.Items.CritDamage); num46 = inventory.GetItemCount(DLC1Content.Items.ConvertCritChanceToCritDamage); num47 = inventory.GetItemCount(DLC1Content.Items.DroneWeaponsBoost); num48 = inventory.GetItemCount(DLC1Content.Items.MissileVoid); equipmentIndex = inventory.currentEquipmentIndex; num51 = inventory.infusionBonus; num49 = ((equipmentIndex == DLC1Content.Equipment.EliteVoidEquipment.equipmentIndex) ? 1 : 0); num50 = inventory.GetItemCount(DLC1Content.Items.OutOfCombatArmor); inventory.GetItemCount(DLC1Content.Items.VoidmanPassiveItem); num52 = inventory.GetItemCount(DLC2Content.Items.LowerHealthHigherDamage); num53 = inventory.GetItemCount(DLC2Content.Items.BoostAllStats); inventory.GetItemCount(DLC2Content.Items.TeleportOnLowHealth); num54 = inventory.GetItemCount(DLC2Content.Items.IncreaseDamageOnMultiKill); inventory.GetItemCount(DLC2Content.Items.GoldOnStageStart); num55 = inventory.GetItemCount(DLC2Content.Items.ExtraStatsOnLevelUp); } level = num2; if (num40 > 0) { level = Math.Max(level, Run.instance.ambientLevelFloor); } level += num3; EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(equipmentIndex); float num56 = level - 1f; isElite = eliteBuffCount > 0; bool flag = HasBuff(RoR2Content.Buffs.TonicBuff); bool num57 = HasBuff(RoR2Content.Buffs.Entangle); bool flag2 = HasBuff(RoR2Content.Buffs.Nullified); bool flag3 = HasBuff(RoR2Content.Buffs.LunarSecondaryRoot); bool flag4 = teamComponent.teamIndex == TeamIndex.Player && RunArtifactManager.instance.IsArtifactEnabled(RoR2Content.Artifacts.glassArtifactDef); bool num58 = num15 > 0 || HasBuff(RoR2Content.Buffs.AffixLunar); bool flag5 = (object)equipmentDef != null && (object)equipmentDef == JunkContent.Equipment.EliteYellowEquipment; hasOneShotProtection = isPlayerControlled; int buffCount = GetBuffCount(RoR2Content.Buffs.BeetleJuice); int buffCount2 = GetBuffCount(DLC2Content.Buffs.RevitalizeBuff); isGlass = flag4 || num28 > 0; canPerformBackstab = (bodyFlags & BodyFlags.HasBackstabPassive) == BodyFlags.HasBackstabPassive; canReceiveBackstab = (bodyFlags & BodyFlags.HasBackstabImmunity) != BodyFlags.HasBackstabImmunity; float num59 = maxHealth; float num60 = maxShield; if (num55 > extraStatsOnLevelUpCountModifier && num55 > 0) { extraStatsOnLevelUpCountModifier = num55; } if (num55 < extraStatsOnLevelUpCountModifier && (bool)inventory) { UnityEngine.Object.Instantiate(CommonAssets.prayerBeadEffect, base.gameObject.transform.position, Quaternion.identity).transform.parent = base.gameObject.transform; extraStatsOnLevelUpCountModifier -= num55; float beadAppliedHealth = inventory.beadAppliedHealth; prayerBeadCalculateAppliedStats(levelMaxHealth); prayerBeadCalculateAppliedStats(levelMaxShield); prayerBeadCalculateAppliedStats(levelRegen); prayerBeadCalculateAppliedStats(levelDamage); extraStatsOnLevelUpCountModifier = num55; if (HasBuff(DLC2Content.Buffs.ExtraStatsOnLevelUpBuff)) { SetBuffCount(DLC2Content.Buffs.ExtraStatsOnLevelUpBuff.buffIndex, 0); bool gainedStats = inventory.beadAppliedHealth > beadAppliedHealth; master.OnBeadReset(gainedStats); } } HandleDisableAllSkillsDebuff(); float num61 = baseMaxHealth + levelMaxHealth * num56; if (teamComponent.teamIndex == TeamIndex.Player && (bool)inventory && inventory.beadAppliedHealth > 0f) { num61 += inventory.beadAppliedHealth; } float num62 = 1f; num62 += (float)num18 * 0.1f; num62 += (float)(num30 + num31) * 0.1f; num62 += (float)buffCount2 * 0.07f; num62 += (float)num49 * 0.5f; num62 += (float)num45 * 1f; if (num4 > 0) { num61 += (float)num51; } num61 += (float)num37 * 25f; num61 += (float)num17 * 40f; num61 *= num62; num61 /= (float)(num33 + 1); if (num32 > 0) { num61 *= 10f; } if (num39 > 0) { num61 *= 0.1f; } maxHealth = num61; float num63 = baseMaxShield + levelMaxShield * num56; if (teamComponent.teamIndex == TeamIndex.Player && (bool)inventory && inventory.beadAppliedShield > 0f) { num63 += inventory.beadAppliedShield; } num63 += (float)num6 * 0.08f * maxHealth; if (HasBuff(RoR2Content.Buffs.EngiShield)) { num63 += maxHealth * 1f; } if (HasBuff(JunkContent.Buffs.EngiTeamShield)) { num63 += maxHealth * 0.5f; } if (num48 > 0) { num63 += maxHealth * 0.1f; } if (num58) { num63 += maxHealth * (1.5f + (float)(num15 - 1) * 0.25f); maxHealth = 1f; } if (HasBuff(RoR2Content.Buffs.AffixBlue)) { float num64 = maxHealth * 0.5f; maxHealth -= num64; num63 += maxHealth; } maxShield = num63; float num65 = baseRegen + levelRegen * num56; if (teamComponent.teamIndex == TeamIndex.Player && (bool)inventory && inventory.beadAppliedRegen > 0f) { num65 += inventory.beadAppliedRegen; } float num66 = 1f + num56 * 0.2f; float num67 = (float)num17 * 1.6f * num66; float num68 = ((outOfDanger && num5 > 0) ? (3f * (float)num5) : 0f) * num66; float num69 = (HasBuff(JunkContent.Buffs.MeatRegenBoost) ? 2f : 0f) * num66; float num70 = (float)GetBuffCount(RoR2Content.Buffs.CrocoRegen) * maxHealth * 0.1f; float num71 = (float)num31 * 0.1f * num66; float num72 = (float)buffCount2 * 0.07f * num66; float num73 = 1f; if (num26 > 0) { num73 += 0.5f; } if (num29 > 0) { num73 -= 0.4f; } float num74 = (num65 + num67 + num68 + num69 + num71 + num72) * num73; if (HasBuff(RoR2Content.Buffs.OnFire) || HasBuff(DLC1Content.Buffs.StrongerBurn)) { num74 = Mathf.Min(0f, num74); } num74 += num70; if (num58) { num74 = Mathf.Max(num74, 0f); } if (num25 > 0) { num74 = Mathf.Min(num74, 0f) - maxHealth / cursePenalty / (float)num25; } if (tamperedHeartActive) { num74 += tamperedHeartRegenBonus; } if (HasBuff(DLC2Content.Buffs.HealAndReviveRegenBuff)) { num74 += num74 * 0.5f; } regen = num74; float num75 = baseMoveSpeed + levelMoveSpeed * num56; num75 += surfaceSpeedBoost; float num76 = 1f; if (flag5) { num75 += 2f; } if (isSprinting) { num75 *= sprintingSpeedMultiplier; } num76 += (float)num7 * 0.14f; num76 += (float)num42 * 0.07f; num76 += (float)num31 * 0.1f; num76 += (float)buffCount2 * 0.07f; num76 += 0.25f * (float)GetBuffCount(DLC1Content.Buffs.KillMoveSpeed); if (teamComponent.teamIndex == TeamIndex.Monster && Run.instance.selectedDifficulty >= DifficultyIndex.Eclipse4) { num76 += 0.4f; } if (isSprinting && num20 > 0) { num76 += 0.25f * (float)num20 / sprintingSpeedMultiplier; } if (num8 > 0 && HasBuff(RoR2Content.Buffs.WhipBoost)) { num76 += (float)num8 * 0.3f; } if (num39 > 0) { num76 += 0.66f; } if (HasBuff(RoR2Content.Buffs.BugWings)) { num76 += 0.2f; } if (HasBuff(RoR2Content.Buffs.Warbanner)) { num76 += 0.3f; } if (HasBuff(JunkContent.Buffs.EnrageAncientWisp)) { num76 += 0.4f; } if (HasBuff(RoR2Content.Buffs.CloakSpeed)) { num76 += 0.4f; } if (HasBuff(RoR2Content.Buffs.WarCryBuff) || HasBuff(RoR2Content.Buffs.TeamWarCry)) { num76 += 0.5f; } if (HasBuff(JunkContent.Buffs.EngiTeamShield)) { num76 += 0.3f; } if (HasBuff(RoR2Content.Buffs.AffixLunar)) { num76 += 0.3f; } if (tamperedHeartActive) { num75 += num75 * tamperedHeartMSpeedBonus; } float num77 = 1f; if (HasBuff(RoR2Content.Buffs.Slow50)) { num77 += 0.5f; } if (HasBuff(RoR2Content.Buffs.Slow60)) { num77 += 0.6f; } if (HasBuff(RoR2Content.Buffs.Slow80)) { num77 += 0.8f; } if (HasBuff(RoR2Content.Buffs.ClayGoo)) { num77 += 0.5f; } if (HasBuff(JunkContent.Buffs.Slow30)) { num77 += 0.3f; } if (HasBuff(RoR2Content.Buffs.Cripple)) { num77 += 1f; } if (HasBuff(DLC1Content.Buffs.JailerSlow)) { num77 += 1f; } num77 += (float)num45 * 1f; num75 *= num76 / num77; if (buffCount > 0) { num75 *= 1f - 0.05f * (float)buffCount; } moveSpeed = num75; acceleration = ((baseMoveSpeed == 0f) ? 0f : (moveSpeed / baseMoveSpeed * baseAcceleration)); if (num57 || flag2 || flag3) { moveSpeed = 0f; acceleration = 80f; } float num78 = baseJumpPower + levelJumpPower * num56; jumpPower = num78; maxJumpHeight = Trajectory.CalculateApex(jumpPower); maxJumpCount = baseJumpCount + num9; oneShotProtectionFraction = 0.1f; float num79 = baseDamage + levelDamage * num56; if (teamComponent.teamIndex == TeamIndex.Player && (bool)inventory && inventory.beadAppliedDamage > 0f) { num79 += inventory.beadAppliedDamage; } float num80 = 1f; int num81 = (inventory ? inventory.GetItemCount(RoR2Content.Items.BoostDamage) : 0); if (num81 > 0) { num80 += (float)num81 * 0.1f; } if (num38 > 0) { int num82 = Math.Max(TeamComponent.GetTeamMembers(teamComponent.teamIndex).Count - 1, 0); num80 += (float)(num82 * num38) * 1f; } if (buffCount > 0) { num80 -= 0.05f * (float)buffCount; } if (HasBuff(JunkContent.Buffs.GoldEmpowered)) { num80 += 1f; } if (HasBuff(RoR2Content.Buffs.PowerBuff)) { num80 += 0.5f; } num80 += (float)num31 * 0.1f; num80 += (float)buffCount2 * 0.07f; num80 += Mathf.Pow(2f, num28) - 1f; num80 -= (float)num49 * 0.3f; num79 *= num80; if (num32 > 0) { num79 *= 0.04f; } if (flag4) { num79 *= 5f; } damage = num79; damageFromRecalculateStats = damage; if (HasBuff(DLC2Content.Buffs.LowerHealthHigherDamageBuff)) { damage += baseDamage * (float)currentHealthLevel * 0.1f * (float)num52 * 0.5f; } _ = tamperedHeartActive; if (HasBuff(DLC2Content.Buffs.IncreaseDamageBuff)) { int buffCount3 = GetBuffCount(DLC2Content.Buffs.IncreaseDamageBuff); float num83 = 0f; if (buffCount3 >= 2) { num83 = (float)(buffCount3 * (buffCount3 + num54 * 5)) * 0.01f; } else if (buffCount3 == 1) { num83 = (float)(1 + num54 * 5) * 0.01f; } damage += baseDamage * num83; if (oldComboMeter < buffCount3) { oldComboMeter = buffCount3; } } float num84 = baseAttackSpeed + levelAttackSpeed * num56; float num85 = 1f; num85 += (float)num34 * 0.1f; num85 += (float)num10 * 0.15f; num85 += (float)num42 * 0.075f; num85 += (float)num47 * 0.5f; if (flag5) { num85 += 0.5f; } num85 += (float)GetBuffCount(RoR2Content.Buffs.AttackSpeedOnCrit) * 0.12f; if (HasBuff(RoR2Content.Buffs.Warbanner)) { num85 += 0.3f; } if (HasBuff(RoR2Content.Buffs.Energized)) { num85 += 0.7f; } if (HasBuff(RoR2Content.Buffs.WarCryBuff) || HasBuff(RoR2Content.Buffs.TeamWarCry)) { num85 += 1f; } num85 += (float)num31 * 0.1f; num85 += (float)buffCount2 * 0.07f; num85 /= (float)(num44 + 1); num85 = Mathf.Max(num85, 0.1f); num84 *= num85; if (buffCount > 0) { num84 *= 1f - 0.05f * (float)buffCount; } if (tamperedHeartActive) { num84 += num84 * tamperedHeartAttackSpeedBonus; } attackSpeed = num84; critMultiplier = 2f + 1f * (float)num43; float num86 = baseCrit + levelCrit * num56; num86 += (float)num11 * 10f; if (num12 > 0) { num86 += 5f; } if (num35 > 0) { num86 += 5f; } if (num13 > 0) { num86 += 5f; } if (num14 > 0) { num86 += 5f; } if (num19 > 0) { num86 += 5f; } if (HasBuff(RoR2Content.Buffs.FullCrit)) { num86 += 100f; } num86 += (float)num31 * 10f; num86 += (float)buffCount2 * 7f; if (num46 == 0) { crit = num86; } else { critMultiplier += num86 * 0.01f; crit = 0f; } armor = baseArmor + levelArmor * num56; armor *= 1f + 0.1f * (float)num31; armor *= 1f + 0.07f * (float)buffCount2; armor += (float)num26 * 70f; armor += (HasBuff(RoR2Content.Buffs.ArmorBoost) ? 200f : 0f); armor += (HasBuff(RoR2Content.Buffs.SmallArmorBoost) ? 100f : 0f); armor += (HasBuff(DLC1Content.Buffs.OutOfCombatArmorBuff) ? (100f * (float)num50) : 0f); armor += (HasBuff(RoR2Content.Buffs.ElephantArmorBoost) ? 500f : 0f); armor += (HasBuff(DLC1Content.Buffs.VoidSurvivorCorruptMode) ? 100f : 0f); armor += (HasBuff(DLC2Content.Buffs.AurelioniteBlessing) ? (60f + 0.1f * (float)master.money) : 0f); if (HasBuff(RoR2Content.Buffs.Cripple)) { armor -= 20f; } if (HasBuff(RoR2Content.Buffs.Pulverized)) { armor -= 60f; } if (isSprinting && num23 > 0) { armor += num23 * 30; } if (tamperedHeartActive) { armor += tamperedHeartArmorBonus; } int buffCount4 = GetBuffCount(DLC1Content.Buffs.PermanentDebuff); armor -= (float)buffCount4 * 2f; float num87 = 0f; if (num36 > 0) { num87 += 2f + 1f * (float)(num36 - 1); } float num88 = 1f; if (HasBuff(JunkContent.Buffs.GoldEmpowered)) { num88 *= 0.25f; } for (int i = 0; i < num16; i++) { num88 *= 0.75f; } for (int j = 0; j < num44; j++) { num88 *= 0.5f; } for (int k = 0; k < num47; k++) { num88 *= 0.5f; } if (teamComponent.teamIndex == TeamIndex.Monster && Run.instance.selectedDifficulty >= DifficultyIndex.Eclipse7) { num88 *= 0.5f; } if (HasBuff(RoR2Content.Buffs.NoCooldowns)) { num88 = 0f; } if ((bool)skillLocator.primary) { skillLocator.primary.cooldownScale = num88; skillLocator.primary.flatCooldownReduction = num87; } if ((bool)skillLocator.secondaryBonusStockSkill) { skillLocator.secondaryBonusStockSkill.cooldownScale = num88; skillLocator.secondaryBonusStockSkill.SetBonusStockFromBody(num21 + extraSecondaryFromSkill); skillLocator.secondaryBonusStockSkill.flatCooldownReduction = num87; } if ((bool)skillLocator.utilityBonusStockSkill) { float num89 = num88; if (num24 > 0) { num89 *= 2f / 3f; } skillLocator.utilityBonusStockSkill.cooldownScale = num89; skillLocator.utilityBonusStockSkill.flatCooldownReduction = num87; skillLocator.utilityBonusStockSkill.SetBonusStockFromBody(num24 * 2); } if ((bool)skillLocator.specialBonusStockSkill) { skillLocator.specialBonusStockSkill.cooldownScale = num88; if (num22 > 0) { skillLocator.specialBonusStockSkill.cooldownScale *= 0.67f; } skillLocator.specialBonusStockSkill.flatCooldownReduction = num87; skillLocator.specialBonusStockSkill.SetBonusStockFromBody(num22 + extraSpecialFromSkill); } critHeal = 0f; if (num19 > 0) { float num90 = crit; crit /= num19 + 1; critHeal = num90 - crit; } cursePenalty = 1f; if (num28 > 0) { cursePenalty = Mathf.Pow(2f, num28); } if (flag4) { cursePenalty *= 10f; } int buffCount5 = GetBuffCount(RoR2Content.Buffs.PermanentCurse); if (buffCount5 > 0) { cursePenalty += (float)buffCount5 * 0.01f; } if (HasBuff(RoR2Content.Buffs.Weak)) { armor -= 30f; damage *= 0.6f; moveSpeed *= 0.6f; } if (HasBuff(DLC2Content.Buffs.lunarruin)) { moveSpeed *= 0.8f; } if (flag) { maxHealth *= 1.5f; maxShield *= 1.5f; attackSpeed *= 1.7f; moveSpeed *= 1.3f; armor += 20f; damage *= 2f; regen *= 4f; } if (HasBuff(DLC2Content.Buffs.BoostAllStatsBuff)) { float num91 = (float)num53 * boostAllStatsMultiplier; _ = maxHealth; _ = moveSpeed; _ = damage; _ = attackSpeed; _ = crit; _ = regen; maxHealth += maxHealth * num91; moveSpeed += moveSpeed * num91; damage += damage * num91; attackSpeed += attackSpeed * num91; crit += crit * num91; regen += regen * num91; } maxBonusHealth = maxHealth; if (num27 > 0 && !flag) { float num92 = Mathf.Pow(0.95f, num27); attackSpeed *= num92; moveSpeed *= num92; damage *= num92; regen *= num92; cursePenalty += 0.1f * (float)num27; } if (HasBuff(DLC2Content.Buffs.SoulCost)) { cursePenalty += 0.1f * (float)GetBuffCount(DLC2Content.Buffs.SoulCost); } maxHealth /= cursePenalty; maxShield /= cursePenalty; oneShotProtectionFraction = Mathf.Max(0f, oneShotProtectionFraction - (1f - 1f / cursePenalty)); maxBarrier = maxHealth + maxShield; barrierDecayRate = maxBarrier / 30f; if (NetworkServer.active) { float num93 = maxHealth - num59; float num94 = maxShield - num60; if (num93 > 0f) { healthComponent.Heal(num93, default(ProcChainMask), nonRegen: false); } else if (healthComponent.health > maxHealth) { healthComponent.Networkhealth = Mathf.Max(healthComponent.health + num93, maxHealth); } if (num94 > 0f) { healthComponent.RechargeShield(num94); } else if (healthComponent.shield > maxShield) { healthComponent.Networkshield = Mathf.Max(healthComponent.shield + num94, maxShield); } } bleedChance = 10f * (float)num41; visionDistance = baseVisionDistance; if (HasBuff(DLC1Content.Buffs.Blinded)) { visionDistance = Mathf.Min(visionDistance, 15f); } if (level != num) { OnCalculatedLevelChanged(num, level); } int num95 = 0; if (num53 > 0 && !HasBuff(DLC2Content.Buffs.BoostAllStatsBuff)) { BuffIndex[] nonHiddenBuffIndices = BuffCatalog.nonHiddenBuffIndices; foreach (BuffIndex buffIndex in nonHiddenBuffIndices) { if (HasBuff(buffIndex) && buffIndex != DLC2Content.Buffs.BoostAllStatsBuff.buffIndex && !BuffCatalog.ignoreGrowthNectarIndices.Contains(buffIndex)) { num95++; if (num95 >= 5 && !HasBuff(DLC2Content.Buffs.BoostAllStatsBuff)) { AddTimedBuff(DLC2Content.Buffs.BoostAllStatsBuff, 5f); } } } } UpdateAllTemporaryVisualEffects(); statsDirty = false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void HandleDisableAllSkillsDebuff() { bool flag = HasBuff(DLC2Content.Buffs.DisableAllSkills); if (flag != allSkillsDisabled) { if (flag) { HandleSkillDisableState(_disable: true); allSkillsDisabled = true; } else { HandleSkillDisableState(_disable: false); allSkillsDisabled = false; } } void HandleSkillDisableState(bool _disable) { if (base.hasAuthority) { SkillDef skillDef = LegacyResourcesAPI.Load("Skills/DisabledSkills"); if (!skillDef) { Debug.LogWarning("Could not find disabledSkill for DisableAllSkills."); } else if (_disable) { skillLocator.primary.SetSkillOverride(this, skillDef, GenericSkill.SkillOverridePriority.Contextual); skillLocator.secondary.SetSkillOverride(this, skillDef, GenericSkill.SkillOverridePriority.Contextual); skillLocator.utility.SetSkillOverride(this, skillDef, GenericSkill.SkillOverridePriority.Contextual); skillLocator.special.SetSkillOverride(this, skillDef, GenericSkill.SkillOverridePriority.Contextual); inventory.SetEquipmentDisabled(_active: true); Util.PlaySound("Play_env_meridian_primeDevestator_debuff", base.gameObject); screenDamageSkillsDisabled = new ScreenDamageCalculatorDisabledSkills(); healthComponent.screenDamageCalculator = screenDamageSkillsDisabled; } else { skillLocator.primary.UnsetSkillOverride(this, skillDef, GenericSkill.SkillOverridePriority.Contextual); skillLocator.secondary.UnsetSkillOverride(this, skillDef, GenericSkill.SkillOverridePriority.Contextual); skillLocator.utility.UnsetSkillOverride(this, skillDef, GenericSkill.SkillOverridePriority.Contextual); skillLocator.special.UnsetSkillOverride(this, skillDef, GenericSkill.SkillOverridePriority.Contextual); inventory.SetEquipmentDisabled(_active: false); if (screenDamageSkillsDisabled != null) { if (healthComponent.screenDamageCalculator == screenDamageSkillsDisabled) { healthComponent.screenDamageCalculator = null; } screenDamageSkillsDisabled.End(); } } } } } public void OnTeamLevelChanged() { statsDirty = true; } private void OnCalculatedLevelChanged(float oldLevel, float newLevel) { if (newLevel > oldLevel) { int num = Mathf.FloorToInt(oldLevel); if (Mathf.FloorToInt(newLevel) > num && num != 0) { OnLevelUp(); } } } private void OnLevelUp() { GlobalEventManager.OnCharacterLevelUp(this); if (inventory.GetItemCount(DLC2Content.Items.OnLevelUpFreeUnlock) > 0) { solitudeLevelCount++; AddFreeChestBuff(); Util.PlaySound("Play_item_proc_onLevelUpFreeUnlock_activate", base.gameObject); } } public void SetAimTimer(float duration) { aimTimer = duration; } public override void OnDeserialize(NetworkReader reader, bool initialState) { byte num = reader.ReadByte(); if (((uint)num & (true ? 1u : 0u)) != 0) { NetworkInstanceId networkInstanceId = reader.ReadNetworkId(); if (networkInstanceId != masterObjectId) { masterObjectId = networkInstanceId; statsDirty = true; } } if ((num & 2u) != 0) { ReadBuffs(reader); } if ((num & 4u) != 0) { bool flag = reader.ReadBoolean(); if (!hasEffectiveAuthority && flag != outOfCombat) { outOfCombat = flag; statsDirty = true; } } if ((num & 8u) != 0) { bool flag2 = reader.ReadBoolean(); if (flag2 != outOfDanger) { outOfDanger = flag2; statsDirty = true; } } if ((num & 0x10u) != 0) { bool flag3 = reader.ReadBoolean(); if (flag3 != isSprinting && !hasEffectiveAuthority) { statsDirty = true; isSprinting = flag3; } } } public override bool OnSerialize(NetworkWriter writer, bool initialState) { uint num = base.syncVarDirtyBits; if (initialState) { num = 31u; } bool num2 = (num & 1) != 0; bool flag = (num & 2) != 0; bool flag2 = (num & 4) != 0; bool flag3 = (num & 8) != 0; bool flag4 = (num & 0x10) != 0; writer.Write((byte)num); if (num2) { writer.Write(masterObjectId); } if (flag) { WriteBuffs(writer); } if (flag2) { writer.Write(outOfCombat); } if (flag3) { writer.Write(outOfDanger); } if (flag4) { writer.Write(isSprinting); } if (!initialState) { return num != 0; } return false; } public void TransmitItemBehavior(NetworkItemBehaviorData itemBehaviorData) { if (!NetworkServer.active) { InternalTransmitItemBehavior(itemBehaviorData); CallCmdTransmitItemBehavior(itemBehaviorData); } else { ServerTransmitItemBehavior(itemBehaviorData); } } [Server] private void ServerTransmitItemBehavior(NetworkItemBehaviorData itemBehaviorData) { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::ServerTransmitItemBehavior(RoR2.CharacterBody/NetworkItemBehaviorData)' called on client"); return; } CallRpcTransmitItemBehavior(itemBehaviorData); InternalTransmitItemBehavior(itemBehaviorData); } [Command] private void CmdTransmitItemBehavior(NetworkItemBehaviorData itemBehaviorData) { ServerTransmitItemBehavior(itemBehaviorData); } [ClientRpc(channel = 1)] private void RpcTransmitItemBehavior(NetworkItemBehaviorData itemBehaviorData) { if (!NetworkServer.active) { InternalTransmitItemBehavior(itemBehaviorData); } } private void InternalTransmitItemBehavior(NetworkItemBehaviorData itemBehaviorData) { OnNetworkItemBehaviorUpdate?.Invoke(itemBehaviorData); } public T AddItemBehavior(int stack) where T : ItemBehavior { T val = GetComponent(); if (stack > 0) { if (!val) { val = base.gameObject.AddComponent(); val.body = this; val.enabled = true; } val.stack = stack; return val; } if ((bool)val) { UnityEngine.Object.Destroy(val); } return null; } public void HandleOnKillEffectsServer(DamageReport damageReport) { int num = killCountServer + 1; killCountServer = num; AddMultiKill(1); } public void OnKilledOtherServer(DamageReport damageReport) { } public void AddHelfireDuration(float duration) { helfireLifetime = duration; } [Server] private void UpdateHelfire(float deltaTime) { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::UpdateHelfire(System.Single)' called on client"); return; } helfireLifetime -= deltaTime; bool flag = false; if ((bool)inventory) { flag = itemAvailability.helfireCount > 0 || helfireLifetime > 0f; } if ((bool)helfireController != flag) { if (flag) { helfireController = UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load("Prefabs/NetworkedObjects/HelfireController")).GetComponent(); helfireController.networkedBodyAttachment.AttachToGameObjectAndSpawn(base.gameObject); } else { UnityEngine.Object.Destroy(helfireController.gameObject); helfireController = null; } } } private void UpdateFireTrail() { bool hasFireTrail = itemAvailability.hasFireTrail; if (hasFireTrail != (bool)fireTrail) { if (hasFireTrail) { fireTrail = UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load("Prefabs/FireTrail"), transform).GetComponent(); fireTrail.transform.position = footPosition; fireTrail.owner = base.gameObject; fireTrail.radius *= radius; } else { UnityEngine.Object.Destroy(fireTrail.gameObject); fireTrail = null; } } if ((bool)fireTrail) { fireTrail.damagePerSecond = damage * 1.5f; } } private void UpdateAffixPoison(float deltaTime) { if (!itemAvailability.hasAffixPoison) { return; } poisonballTimer += deltaTime; if (poisonballTimer >= 6f) { int num = 3 + (int)radius; poisonballTimer = 0f; Vector3 up = Vector3.up; float num2 = 360f / (float)num; Vector3 normalized = Vector3.ProjectOnPlane(transform.forward, up).normalized; Vector3 vector = Vector3.RotateTowards(up, normalized, 0.43633232f, float.PositiveInfinity); for (int i = 0; i < num; i++) { Vector3 forward = Quaternion.AngleAxis(num2 * (float)i, up) * vector; ProjectileManager.instance.FireProjectile(LegacyResourcesAPI.Load("Prefabs/Projectiles/PoisonOrbProjectile"), corePosition, Util.QuaternionSafeLookRotation(forward), base.gameObject, damage * 1f, 0f, Util.CheckRoll(crit, master)); } } } private void UpdateAffixLunar(float deltaTime) { if (!outOfCombat && itemAvailability.hasAffixLunar) { lunarMissileRechargeTimer += deltaTime; lunarMissileTimerBetweenShots += deltaTime; int num = 4; if (!lunarMissilePrefab) { lunarMissilePrefab = LegacyResourcesAPI.Load("Prefabs/Projectiles/LunarMissileProjectile"); } if (lunarMissileRechargeTimer >= 10f) { lunarMissileRechargeTimer = 0f; remainingMissilesToFire += num; } if (remainingMissilesToFire > 0 && lunarMissileTimerBetweenShots > 0.1f) { lunarMissileTimerBetweenShots = 0f; Vector3 vector = (inputBank ? inputBank.aimDirection : transform.forward); float num2 = 180f / (float)num; float num3 = 3f + (float)(int)radius * 1f; float num4 = damage * 0.3f; Quaternion rotation = Util.QuaternionSafeLookRotation(vector); Vector3 vector2 = Quaternion.AngleAxis((float)(remainingMissilesToFire - 1) * num2 - num2 * (float)(num - 1) / 2f, vector) * Vector3.up * num3; Vector3 position = aimOrigin + vector2; FireProjectileInfo fireProjectileInfo = default(FireProjectileInfo); fireProjectileInfo.projectilePrefab = lunarMissilePrefab; fireProjectileInfo.position = position; fireProjectileInfo.rotation = rotation; fireProjectileInfo.owner = base.gameObject; fireProjectileInfo.damage = num4; fireProjectileInfo.crit = Util.CheckRoll(crit, master); fireProjectileInfo.force = 200f; FireProjectileInfo fireProjectileInfo2 = fireProjectileInfo; ProjectileManager.instance.FireProjectile(fireProjectileInfo2); remainingMissilesToFire--; } } } private void UpdateAllTemporaryVisualEffects() { int buffCount = GetBuffCount(RoR2Content.Buffs.NullifyStack); UpdateSingleTemporaryVisualEffect(ref engiShieldTempEffectInstance, AssetReferences.engiShieldTempEffectPrefab, bestFitRadius, healthComponent.shield > 0f && HasBuff(RoR2Content.Buffs.EngiShield)); ref TemporaryVisualEffect tempEffect = ref bucklerShieldTempEffectInstance; GameObject bucklerShieldTempEffectPrefab = AssetReferences.bucklerShieldTempEffectPrefab; float effectRadius = radius; int active; if (isSprinting) { Inventory obj = inventory; active = (((object)obj != null && obj.GetItemCount(RoR2Content.Items.SprintArmor) > 0) ? 1 : 0); } else { active = 0; } UpdateSingleTemporaryVisualEffect(ref tempEffect, bucklerShieldTempEffectPrefab, effectRadius, (byte)active != 0); UpdateSingleTemporaryVisualEffect(ref slowDownTimeTempEffectInstance, AssetReferences.slowDownTimeTempEffectPrefab, radius, HasBuff(RoR2Content.Buffs.Slow60)); UpdateSingleTemporaryVisualEffect(ref crippleEffectInstance, AssetReferences.crippleEffectPrefab, radius, HasBuff(RoR2Content.Buffs.Cripple)); UpdateSingleTemporaryVisualEffect(ref tonicBuffEffectInstance, AssetReferences.tonicBuffEffectPrefab, radius, HasBuff(RoR2Content.Buffs.TonicBuff)); UpdateSingleTemporaryVisualEffect(ref weakTempEffectInstance, AssetReferences.weakTempEffectPrefab, radius, HasBuff(RoR2Content.Buffs.Weak)); UpdateSingleTemporaryVisualEffect(ref energizedTempEffectInstance, AssetReferences.energizedTempEffectPrefab, radius, HasBuff(RoR2Content.Buffs.Energized)); UpdateSingleTemporaryVisualEffect(ref barrierTempEffectInstance, AssetReferences.barrierTempEffectPrefab, bestFitRadius, healthComponent.barrier > 0f); UpdateSingleTemporaryVisualEffect(ref regenBoostEffectInstance, AssetReferences.regenBoostEffectPrefab, bestFitRadius, HasBuff(JunkContent.Buffs.MeatRegenBoost)); UpdateSingleTemporaryVisualEffect(ref elephantDefenseEffectInstance, AssetReferences.elephantDefenseEffectPrefab, radius, HasBuff(RoR2Content.Buffs.ElephantArmorBoost)); UpdateSingleTemporaryVisualEffect(ref healingDisabledEffectInstance, AssetReferences.healingDisabledEffectPrefab, radius, HasBuff(RoR2Content.Buffs.HealingDisabled)); UpdateSingleTemporaryVisualEffect(ref noCooldownEffectInstance, AssetReferences.noCooldownEffectPrefab, radius, HasBuff(RoR2Content.Buffs.NoCooldowns), "Head"); ref TemporaryVisualEffect tempEffect2 = ref doppelgangerEffectInstance; GameObject doppelgangerEffectPrefab = AssetReferences.doppelgangerEffectPrefab; float effectRadius2 = radius; Inventory obj2 = inventory; UpdateSingleTemporaryVisualEffect(ref tempEffect2, doppelgangerEffectPrefab, effectRadius2, (object)obj2 != null && obj2.GetItemCount(RoR2Content.Items.InvadingDoppelganger) > 0, "Head"); UpdateSingleTemporaryVisualEffect(ref nullifyStack1EffectInstance, AssetReferences.nullifyStack1EffectPrefab, radius, buffCount == 1); UpdateSingleTemporaryVisualEffect(ref nullifyStack2EffectInstance, AssetReferences.nullifyStack2EffectPrefab, radius, buffCount == 2); UpdateSingleTemporaryVisualEffect(ref nullifyStack3EffectInstance, AssetReferences.nullifyStack3EffectPrefab, radius, HasBuff(RoR2Content.Buffs.Nullified)); UpdateSingleTemporaryVisualEffect(ref deathmarkEffectInstance, AssetReferences.deathmarkEffectPrefab, radius, HasBuff(RoR2Content.Buffs.DeathMark)); UpdateSingleTemporaryVisualEffect(ref crocoRegenEffectInstance, AssetReferences.crocoRegenEffectPrefab, bestFitRadius, HasBuff(RoR2Content.Buffs.CrocoRegen)); UpdateSingleTemporaryVisualEffect(ref mercExposeEffectInstance, AssetReferences.mercExposeEffectPrefab, radius, HasBuff(RoR2Content.Buffs.MercExpose)); UpdateSingleTemporaryVisualEffect(ref lifestealOnHitEffectInstance, AssetReferences.lifestealOnHitEffectPrefab, bestFitRadius, HasBuff(RoR2Content.Buffs.LifeSteal)); UpdateSingleTemporaryVisualEffect(ref teamWarCryEffectInstance, AssetReferences.teamWarCryEffectPrefab, bestFitRadius, HasBuff(RoR2Content.Buffs.TeamWarCry), "HeadCenter"); UpdateSingleTemporaryVisualEffect(ref lunarGolemShieldEffectInstance, AssetReferences.lunarGolemShieldEffectPrefab, bestFitRadius, HasBuff(RoR2Content.Buffs.LunarShell)); UpdateSingleTemporaryVisualEffect(ref randomDamageEffectInstance, AssetReferences.randomDamageEffectPrefab, radius, HasBuff(RoR2Content.Buffs.PowerBuff)); UpdateSingleTemporaryVisualEffect(ref warbannerEffectInstance, AssetReferences.warbannerEffectPrefab, radius, HasBuff(RoR2Content.Buffs.Warbanner)); UpdateSingleTemporaryVisualEffect(ref teslaFieldEffectInstance, AssetReferences.teslaFieldEffectPrefab, bestFitRadius, HasBuff(RoR2Content.Buffs.TeslaField)); UpdateSingleTemporaryVisualEffect(ref lunarSecondaryRootEffectInstance, AssetReferences.lunarSecondaryRootEffectPrefab, radius, HasBuff(RoR2Content.Buffs.LunarSecondaryRoot)); UpdateSingleTemporaryVisualEffect(ref lunarDetonatorEffectInstance, AssetReferences.lunarDetonatorEffectPrefab, radius, HasBuff(RoR2Content.Buffs.LunarDetonationCharge)); UpdateSingleTemporaryVisualEffect(ref fruitingEffectInstance, AssetReferences.fruitingEffectPrefab, radius, HasBuff(RoR2Content.Buffs.Fruiting)); UpdateSingleTemporaryVisualEffect(ref mushroomVoidTempEffectInstance, AssetReferences.mushroomVoidTempEffectPrefab, radius, HasBuff(DLC1Content.Buffs.MushroomVoidActive)); UpdateSingleTemporaryVisualEffect(ref bearVoidTempEffectInstance, AssetReferences.bearVoidTempEffectPrefab, radius, HasBuff(DLC1Content.Buffs.BearVoidReady)); UpdateSingleTemporaryVisualEffect(ref outOfCombatArmorEffectInstance, AssetReferences.outOfCombatArmorEffectPrefab, radius, HasBuff(DLC1Content.Buffs.OutOfCombatArmorBuff)); UpdateSingleTemporaryVisualEffect(ref voidFogMildEffectInstance, AssetReferences.voidFogMildEffectPrefab, radius, HasBuff(RoR2Content.Buffs.VoidFogMild)); UpdateSingleTemporaryVisualEffect(ref voidFogStrongEffectInstance, AssetReferences.voidFogStrongEffectPrefab, radius, HasBuff(RoR2Content.Buffs.VoidFogStrong)); UpdateSingleTemporaryVisualEffect(ref voidRaidcrabWardWipeFogEffectInstance, AssetReferences.voidRaidcrabWardWipeFogEffectPrefab, radius, HasBuff(DLC1Content.Buffs.VoidRaidCrabWardWipeFog)); UpdateSingleTemporaryVisualEffect(ref voidJailerSlowEffectInstance, AssetReferences.voidJailerSlowEffectPrefab, radius, HasBuff(DLC1Content.Buffs.JailerSlow)); UpdateSingleTemporaryVisualEffect(ref aurelioniteBlessingEffectInstance, AssetReferences.aurelioniteBlessingEffectInstance, bestFitActualRadius, HasBuff(DLC2Content.Buffs.AurelioniteBlessing), "Pelvis"); if ((bool)mushroomVoidTempEffectInstance && !HasBuff(DLC1Content.Buffs.MushroomVoidActive)) { UnityEngine.Object.Destroy(mushroomVoidTempEffectInstance.gameObject); } } private void UpdateSingleTemporaryVisualEffect(ref TemporaryVisualEffect tempEffect, string resourceString, float effectRadius, bool active, string childLocatorOverride = "") { bool flag = tempEffect != null; if (flag == active) { return; } if (active) { if (flag) { return; } GameObject gameObject = UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load(resourceString), corePosition, Quaternion.identity); tempEffect = gameObject.GetComponent(); tempEffect.parentTransform = coreTransform; tempEffect.visualState = TemporaryVisualEffect.VisualState.Enter; tempEffect.healthComponent = healthComponent; tempEffect.radius = effectRadius; LocalCameraEffect component = gameObject.GetComponent(); if ((bool)component) { component.targetCharacter = base.gameObject; } if (string.IsNullOrEmpty(childLocatorOverride)) { return; } ChildLocator childLocator = modelLocator?.modelTransform?.GetComponent(); if ((bool)childLocator) { Transform transform = childLocator.FindChild(childLocatorOverride); if ((bool)transform) { tempEffect.parentTransform = transform; } } } else if ((bool)tempEffect) { tempEffect.visualState = TemporaryVisualEffect.VisualState.Exit; } } private void UpdateSingleTemporaryVisualEffect(ref TemporaryVisualEffect tempEffect, GameObject tempEffectPrefab, float effectRadius, bool active, string childLocatorOverride = "") { bool flag = tempEffect != null; if (flag == active) { return; } if (active) { if (flag) { return; } if ((bool)tempEffectPrefab) { GameObject gameObject = UnityEngine.Object.Instantiate(tempEffectPrefab, corePosition, Quaternion.identity); tempEffect = gameObject.GetComponent(); tempEffect.parentTransform = coreTransform; tempEffect.visualState = TemporaryVisualEffect.VisualState.Enter; tempEffect.healthComponent = healthComponent; tempEffect.radius = effectRadius; LocalCameraEffect component = gameObject.GetComponent(); if ((bool)component) { component.targetCharacter = base.gameObject; } if (string.IsNullOrEmpty(childLocatorOverride)) { return; } ChildLocator childLocator = modelLocator?.modelTransform?.GetComponent(); if ((bool)childLocator) { Transform transform = childLocator.FindChild(childLocatorOverride); if ((bool)transform) { tempEffect.parentTransform = transform; } } } else { Debug.LogError("Can't instantiate null temporary visual effect"); } } else if ((bool)tempEffect) { tempEffect.visualState = TemporaryVisualEffect.VisualState.Exit; } } public VisibilityLevel GetVisibilityLevel(CharacterBody observer) { return GetVisibilityLevel(observer ? observer.teamComponent.teamIndex : TeamIndex.None); } public VisibilityLevel GetVisibilityLevel(TeamIndex observerTeam) { if (!hasCloakBuff) { return VisibilityLevel.Visible; } if (teamComponent.teamIndex != observerTeam) { return VisibilityLevel.Cloaked; } return VisibilityLevel.Revealed; } public void AddSpreadBloom(float value) { spreadBloomInternal = Mathf.Min(spreadBloomInternal + value, 1f); } public void SetSpreadBloom(float value, bool canOnlyIncreaseBloom = true) { if (canOnlyIncreaseBloom) { spreadBloomInternal = Mathf.Clamp(value, spreadBloomInternal, 1f); } else { spreadBloomInternal = Mathf.Min(value, 1f); } } private void UpdateSpreadBloom(float dt) { float num = 1f / spreadBloomDecayTime; spreadBloomInternal = Mathf.Max(spreadBloomInternal - num * dt, 0f); } [Client] public void SendConstructTurret(CharacterBody builder, Vector3 position, Quaternion rotation, MasterCatalog.MasterIndex masterIndex) { if (!NetworkClient.active) { Debug.LogWarning("[Client] function 'System.Void RoR2.CharacterBody::SendConstructTurret(RoR2.CharacterBody,UnityEngine.Vector3,UnityEngine.Quaternion,RoR2.MasterCatalog/MasterIndex)' called on server"); return; } ConstructTurretMessage msg = new ConstructTurretMessage { builder = builder.gameObject, position = position, rotation = rotation, turretMasterIndex = masterIndex }; ClientScene.readyConnection.Send(62, msg); } [NetworkMessageHandler(msgType = 62, server = true)] private static void HandleConstructTurret(NetworkMessage netMsg) { ConstructTurretMessage constructTurretMessage = netMsg.ReadMessage(); if (!constructTurretMessage.builder) { return; } CharacterBody component = constructTurretMessage.builder.GetComponent(); if ((bool)component) { CharacterMaster characterMaster = component.master; if ((bool)characterMaster) { CharacterMaster characterMaster2 = new MasterSummon { masterPrefab = MasterCatalog.GetMasterPrefab(constructTurretMessage.turretMasterIndex), position = constructTurretMessage.position, rotation = constructTurretMessage.rotation, summonerBodyObject = component.gameObject, ignoreTeamMemberLimit = true, inventoryToCopy = characterMaster.inventory }.Perform(); Deployable deployable = characterMaster2.gameObject.AddComponent(); deployable.onUndeploy = new UnityEvent(); deployable.onUndeploy.AddListener(characterMaster2.TrueKill); characterMaster.AddDeployable(deployable, DeployableSlot.EngiTurret); } } } public void AddIncreasedDamageMultiKillTime() { increasedDamageKillTimer = 5f; } [Server] public void AddMultiKill(int kills) { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::AddMultiKill(System.Int32)' called on client"); return; } multiKillTimer = 1f; multiKillCount += kills; int num = (inventory ? inventory.GetItemCount(RoR2Content.Items.WarCryOnMultiKill) : 0); if (num > 0 && multiKillCount >= 4) { AddTimedBuff(RoR2Content.Buffs.WarCryBuff, 2f + 4f * (float)num); } increasedDamageKillTimer = 5f; increasedDamageKillCount += kills; increasedDamageKillCountBuff += kills; if ((((bool)inventory && inventory.GetItemCount(DLC2Content.Items.IncreaseDamageOnMultiKill) != 0) ? 1 : 0) > (false ? 1 : 0)) { if (increasedDamageKillCountBuff >= 5) { AddBuff(DLC2Content.Buffs.IncreaseDamageBuff); EffectManager.SpawnEffect(LegacyResourcesAPI.Load("Prefabs/Effects/IncreaseDamageOnMultiKillVFX"), new EffectData { origin = base.gameObject.transform.position }, transmit: true); increasedDamageKillCountBuff = 0; } if (increasedDamageKillCount > oldKillcount) { oldKillcount = increasedDamageKillCount; } } } [Server] private void UpdateMultiKill(float deltaTime) { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::UpdateMultiKill(System.Single)' called on client"); return; } multiKillTimer -= deltaTime; if (multiKillTimer <= 0f) { multiKillTimer = 0f; multiKillCount = 0; } increasedDamageKillTimer -= deltaTime; if (increasedDamageKillTimer <= 0f) { increasedDamageKillTimer = 0f; increasedDamageKillCount = 0; increasedDamageKillCountBuff = 0; oldKillcount = 0; oldComboMeter = 0; if (HasBuff(DLC2Content.Buffs.IncreaseDamageBuff)) { RemoveBuff(DLC2Content.Buffs.IncreaseDamageBuff); } } } public void AddIncreasePrimaryDamageStack() { int buffCount = GetBuffCount(DLC2Content.Buffs.IncreasePrimaryDamageBuff); int itemCount = inventory.GetItemCount(DLC2Content.Items.IncreasePrimaryDamage); int num = 4 + itemCount; if (buffCount < num) { AddBuff(DLC2Content.Buffs.IncreasePrimaryDamageBuff); } buffCount = GetBuffCount(DLC2Content.Buffs.IncreasePrimaryDamageBuff); TransmitItemBehavior(new NetworkItemBehaviorData(DLC2Content.Items.IncreasePrimaryDamage.itemIndex, buffCount)); float num2 = baseDamage + levelDamage * (level - 1f); luminousShotDamage = num2 * (1.25f + 0.25f * (float)itemCount) * (float)buffCount; } public void IncreasePrimaryDamageReset() { if (GetBuffCount(DLC2Content.Buffs.IncreasePrimaryDamageBuff) > 0) { SetBuffCount(DLC2Content.Buffs.IncreasePrimaryDamageBuff.buffIndex, 0); TransmitItemBehavior(new NetworkItemBehaviorData(DLC2Content.Items.IncreasePrimaryDamage.itemIndex, 0f)); } luminousShotReady = false; } [Server] private void UpdateDelayedDamage(float deltaTime) { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::UpdateDelayedDamage(System.Single)' called on client"); return; } int num = (inventory ? inventory.GetItemCount(DLC2Content.Items.DelayedDamage) : 0); if (num > 0) { int buffCount = GetBuffCount(DLC2Content.Buffs.DelayedDamageBuff); if (oldDelayedDamageCount < num) { int num2 = num - oldDelayedDamageCount; for (int i = 0; i < num2; i++) { AddBuff(DLC2Content.Buffs.DelayedDamageBuff); } oldDelayedDamageCount = num; } else if (oldDelayedDamageCount > num) { oldDelayedDamageCount = num; } if (buffCount < num) { delayedDamageRefreshTime -= deltaTime; if (delayedDamageRefreshTime <= 0f) { AddBuff(DLC2Content.Buffs.DelayedDamageBuff); delayedDamageRefreshTime = 10f; } } } else { delayedDamageRefreshTime = 10f; oldDelayedDamageCount = 0; RemoveBuff(DLC2Content.Buffs.DelayedDamageBuff); RemoveBuff(DLC2Content.Buffs.DelayedDamageDebuff); RemoveOldestTimedBuff(DLC2Content.Buffs.DelayedDamageDebuff); } } public void SpawnDelayedDamageEffect() { if (NetworkServer.active) { ServerSpawnDelayedDamageEffect(); } else { CallCmdSpawnDelayedDamageEffect(); } } [Server] private void ServerSpawnDelayedDamageEffect() { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::ServerSpawnDelayedDamageEffect()' called on client"); } else { UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load("Prefabs/Effects/DelayedDamageIndicator"), mainHurtBox ? mainHurtBox.transform.position : transform.position, Quaternion.identity, mainHurtBox ? mainHurtBox.transform : transform); } } [Command] private void CmdSpawnDelayedDamageEffect() { ServerSpawnDelayedDamageEffect(); } public void SecondHalfOfDelayedDamage(DamageInfo halfDamage) { RemoveBuff(DLC2Content.Buffs.DelayedDamageBuff); AddBuff(DLC2Content.Buffs.DelayedDamageDebuff); TransmitItemBehavior(new NetworkItemBehaviorData(DLC2Content.Items.DelayedDamage.itemIndex, 0f)); DelayedDamageInfo delayedDamageInfo = new DelayedDamageInfo(); delayedDamageInfo.halfDamage = halfDamage; incomingDamageList.Add(delayedDamageInfo); if (incomingDamageList.Count == 0) { halfDamageReady = false; } else { halfDamageReady = true; } } [Server] private void UpdateSecondHalfOfDamage(float deltaTime) { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::UpdateSecondHalfOfDamage(System.Single)' called on client"); } else { if (!halfDamageReady) { return; } for (int i = 0; i < incomingDamageList.Count; i++) { DelayedDamageInfo delayedDamageInfo = incomingDamageList[i]; DamageInfo halfDamage = delayedDamageInfo.halfDamage; halfDamage.position = GetBody().corePosition; if (protectFromOneShot) { halfDamage.damageType = DamageType.NonLethal; } delayedDamageInfo.timeUntilDamage -= deltaTime; if (delayedDamageInfo.timeUntilDamage <= 0f) { Util.PlaySound("Play_item_proc_delayedDamage_2ndHit", base.gameObject); healthComponent.TakeDamage(halfDamage); RemoveBuff(DLC2Content.Buffs.DelayedDamageDebuff); incomingDamageList.RemoveAt(i); protectFromOneShot = false; } } } } [ClientRpc] public void RpcTeleportCharacterToSafety() { if (!hasEffectiveAuthority) { return; } Transform transform = modelLocator?.modelTransform; if (!(transform == null)) { CharacterModel component = transform.GetComponent(); Vector3 position = coreTransform.position; int itemCount = inventory.GetItemCount(DLC2Content.Items.TeleportOnLowHealth); BlastAttack blastAttack = new BlastAttack(); blastAttack.attacker = base.gameObject; blastAttack.baseDamage = damage * ((float)itemCount * 3.5f); blastAttack.baseForce = 2000f; blastAttack.bonusForce = Vector3.zero; blastAttack.attackerFiltering = AttackerFiltering.NeverHitSelf; blastAttack.crit = RollCrit(); blastAttack.damageColorIndex = DamageColorIndex.Item; blastAttack.damageType = DamageType.Generic; blastAttack.falloffModel = BlastAttack.FalloffModel.None; blastAttack.inflictor = base.gameObject; blastAttack.position = position; blastAttack.procChainMask = default(ProcChainMask); blastAttack.procCoefficient = 1f; blastAttack.radius = 25f; blastAttack.losType = BlastAttack.LoSType.None; blastAttack.teamIndex = TeamIndex.Player; blastAttack.Fire(); EffectManager.SpawnEffect(CommonAssets.teleportOnLowHealthExplosion, new EffectData { origin = position, scale = 50f, rotation = Quaternion.identity }, transmit: true); Util.PlaySound("Play_item_proc_teleportOnLowHealth", base.gameObject); NodeGraph nodeGraph = SceneInfo.instance.GetNodeGraph(MapNodeGroup.GraphType.Ground); List source = nodeGraph.FindNodesInRange(corePosition, 100f, 200f, HullMask.Human); nodeGraph.GetNodePosition(source.First(), out var position2); TeleportHelper.TeleportBody(this, position2); TeleportOutController.AddTPOutEffect(component, 1f, 0f, 1f); EffectManager.SpawnEffect(CommonAssets.teleportOnLowHealthVFX, new EffectData { origin = this.transform.position, rotation = Quaternion.identity }, transmit: true); Vector3 normalized = (position - position2).normalized; if ((bool)characterDirection) { characterDirection.forward = normalized; } if ((bool)master && (bool)master.playerCharacterMasterController) { master.playerCharacterMasterController.RedirectCamera(Quaternion.LookRotation(normalized).eulerAngles); } } } private void prayerBeadCalculateAppliedStats(float levelStat) { if (teamComponent.teamIndex == TeamIndex.Player) { float num = (float)GetBuffCount(DLC2Content.Buffs.ExtraStatsOnLevelUpBuff) * levelStat * (0.2f + 0.05f * (float)(inventory.GetItemCount(DLC2Content.Items.ExtraStatsOnLevelUp) - 1)); if (levelStat == levelMaxHealth) { _ = inventory.beadAppliedHealth; inventory.beadAppliedHealth += num; } else if (levelStat == levelMaxShield) { _ = inventory.beadAppliedShield; inventory.beadAppliedShield += num; } else if (levelStat == levelRegen) { _ = inventory.beadAppliedRegen; inventory.beadAppliedRegen += num; } else if (levelStat == levelDamage) { _ = inventory.beadAppliedDamage; inventory.beadAppliedDamage += num; } } } [HideInInspector] public void runicLensUpdateVariables(float damage, Vector3 position, DamageInfo damageInfo, float blastForce, float blastRadius) { runicLensPosition = position; runicLensImpactTime = Run.instance.time + 2f; runicLensMeteorReady = true; runicLensDamage = damage; runicLensDamageInfo = damageInfo; runicLensBlastForce = blastForce; runicLensBlastRadius = blastRadius; } public void detonateRunicLensMeteor() { GameObject gameObject = LegacyResourcesAPI.Load("Prefabs/Effects/ImpactEffects/RunicMeteorStrikeImpact"); Util.PlaySound("Play_item_proc_meteorAttackOnHighDamage_impact", base.gameObject); EffectData effectData = new EffectData { origin = runicLensPosition }; EffectManager.SpawnEffect(gameObject, effectData, transmit: true); BlastAttack blastAttack = new BlastAttack(); blastAttack.falloffModel = BlastAttack.FalloffModel.None; blastAttack.inflictor = gameObject; blastAttack.baseDamage = runicLensDamage; blastAttack.baseForce = runicLensBlastForce; blastAttack.attackerFiltering = AttackerFiltering.Default; blastAttack.crit = runicLensDamageInfo.crit; blastAttack.attacker = runicLensDamageInfo.attacker; blastAttack.bonusForce = Vector3.zero; blastAttack.damageColorIndex = DamageColorIndex.Item; blastAttack.position = runicLensPosition; blastAttack.procChainMask = default(ProcChainMask); blastAttack.procCoefficient = 0.5f; blastAttack.teamIndex = TeamIndex.Player; blastAttack.radius = runicLensBlastRadius; blastAttack.Fire(); } public void TriggerEnemyDebuffs(DamageInfo damageInfo) { SphereSearch sphereSearch = new SphereSearch(); List list = CollectionPool>.RentCollection(); sphereSearch.mask = LayerIndex.entityPrecise.mask; sphereSearch.origin = base.gameObject.transform.position; sphereSearch.radius = 30f; sphereSearch.queryTriggerInteraction = QueryTriggerInteraction.UseGlobal; sphereSearch.RefreshCandidates(); sphereSearch.FilterCandidatesByHurtBoxTeam(TeamMask.GetEnemyTeams(teamComponent.teamIndex)); sphereSearch.OrderCandidatesByDistance(); sphereSearch.FilterCandidatesByDistinctHurtBoxEntities(); sphereSearch.GetHurtBoxes(list); sphereSearch.ClearCandidates(); EffectManager.SpawnEffect(CommonAssets.thornExplosionEffect, new EffectData { origin = coreTransform.position, scale = 60f, rotation = Quaternion.identity }, transmit: true); Util.PlaySound("Play_item_proc_triggerEnemyDebuffs", base.gameObject); for (int i = 0; i < list.Count; i++) { HurtBox hurtBox = list[i]; if (!hurtBox || !hurtBox.healthComponent || !hurtBox.healthComponent.alive) { continue; } CharacterBody body = hurtBox.healthComponent.body; int itemCount = inventory.GetItemCount(DLC2Content.Items.TriggerEnemyDebuffs); int num = 1; if (!body.hasStackableDebuff) { DotController.InflictDot(body.gameObject, damageInfo.attacker, DotController.DotIndex.Bleed, 3f * damageInfo.procCoefficient); continue; } int buffCount = body.GetBuffCount(RoR2Content.Buffs.OnFire); if (buffCount > 0) { float num2 = 0.5f; int num3 = num * itemCount; InflictDotInfo inflictDotInfo = default(InflictDotInfo); inflictDotInfo.attackerObject = damageInfo.attacker; inflictDotInfo.victimObject = body.gameObject; inflictDotInfo.totalDamage = damageInfo.damage * num2; inflictDotInfo.damageMultiplier = 1f; inflictDotInfo.dotIndex = DotController.DotIndex.Burn; InflictDotInfo inflictDotInfo2 = inflictDotInfo; for (int j = 0; j < num3; j++) { DotController.InflictDot(ref inflictDotInfo2); } } buffCount = body.GetBuffCount(RoR2Content.Buffs.BeetleJuice); if (buffCount > 0) { int newCount = buffCount + num * itemCount; body.SetBuffCount(RoR2Content.Buffs.BeetleJuice.buffIndex, newCount); } buffCount = body.GetBuffCount(RoR2Content.Buffs.NullifyStack); if (buffCount > 0) { int newCount2 = buffCount + num * itemCount; body.SetBuffCount(RoR2Content.Buffs.NullifyStack.buffIndex, newCount2); } buffCount = body.GetBuffCount(RoR2Content.Buffs.Bleeding); if (buffCount > 0) { int num4 = num * itemCount; for (int k = 0; k < num4; k++) { DotController.InflictDot(body.gameObject, damageInfo.attacker, DotController.DotIndex.Bleed, 3f * damageInfo.procCoefficient); } } buffCount = body.GetBuffCount(RoR2Content.Buffs.SuperBleed); if (buffCount > 0) { int num5 = num * itemCount; for (int l = 0; l < num5; l++) { DotController.InflictDot(body.gameObject, damageInfo.attacker, DotController.DotIndex.SuperBleed, 15f * damageInfo.procCoefficient); } } buffCount = body.GetBuffCount(RoR2Content.Buffs.Blight); if (buffCount > 0) { int num6 = num * itemCount; for (int m = 0; m < num6; m++) { DotController.InflictDot(body.gameObject, damageInfo.attacker, DotController.DotIndex.Blight, 5f * damageInfo.procCoefficient); } } buffCount = body.GetBuffCount(RoR2Content.Buffs.Overheat); if (buffCount > 0) { int newCount3 = buffCount + num * itemCount; body.SetBuffCount(RoR2Content.Buffs.Overheat.buffIndex, newCount3); } buffCount = body.GetBuffCount(RoR2Content.Buffs.PulverizeBuildup); if (buffCount > 0) { int newCount4 = buffCount + num * itemCount; body.SetBuffCount(RoR2Content.Buffs.PulverizeBuildup.buffIndex, newCount4); } buffCount = body.GetBuffCount(DLC1Content.Buffs.StrongerBurn); if (buffCount > 0) { int num7 = num * itemCount; for (int n = 0; n < num7; n++) { DotController.InflictDot(body.gameObject, damageInfo.attacker, DotController.DotIndex.StrongerBurn, 3f * damageInfo.procCoefficient); } } buffCount = body.GetBuffCount(DLC1Content.Buffs.Fracture); if (buffCount > 0) { int num8 = num * itemCount; DotController.DotDef dotDef = DotController.GetDotDef(DotController.DotIndex.Fracture); for (int num9 = 0; num9 < num8; num9++) { DotController.InflictDot(body.gameObject, damageInfo.attacker, DotController.DotIndex.Fracture, dotDef.interval); } } buffCount = body.GetBuffCount(DLC1Content.Buffs.PermanentDebuff); if (buffCount > 0) { int newCount5 = buffCount + num * itemCount; body.SetBuffCount(DLC1Content.Buffs.PermanentDebuff.buffIndex, newCount5); } buffCount = body.GetBuffCount(DLC2Content.Buffs.lunarruin); if (buffCount > 0) { int num10 = buffCount + num * itemCount; body.SetBuffCount(DLC2Content.Buffs.lunarruin.buffIndex, num10); for (int num11 = 0; num11 < num10; num11++) { DotController.InflictDot(body.gameObject, damageInfo.attacker, DotController.DotIndex.LunarRuin, 5f); } } } } private void IncreaseStunPierceDamage(int kills) { } public void ApplyTamperedHeartPassive(float heartRegen, float heartMSpeed, float heartDamage, float armor, float attackSpeed) { tamperedHeartActive = true; tamperedHeartRegenBonus = heartRegen; tamperedHeartMSpeedBonus = heartMSpeed; tamperedHeartDamageBonus = heartDamage; tamperedHeartAttackSpeedBonus = attackSpeed; tamperedHeartArmorBonus = armor; } public void AddFreeChestBuff() { int itemCount = inventory.GetItemCount(DLC2Content.Items.OnLevelUpFreeUnlock); for (int i = 0; i < itemCount; i++) { AddBuff(DLC2Content.Buffs.FreeUnlocks.buffIndex); } } [ClientRpc] public void RpcBark() { if ((bool)sfxLocator) { Util.PlaySound(sfxLocator.barkSound, base.gameObject); } } [Command] public void CmdRequestVehicleEjection() { if ((bool)currentVehicle) { currentVehicle.EjectPassenger(base.gameObject); } } public bool RollCrit() { if ((bool)master) { return Util.CheckRoll(crit, master); } return false; } public bool IsCullable() { if (!dontCull && Importance - TeamComponent.GetTeamAverageImportance(teamComponent) < 3 && teamComponent.teamIndex != TeamIndex.Player && !isBoss) { return TeamComponent.GetTeamMembers(TeamIndex.Monster).Count >= 10; } return false; } public bool IsActivelyCullable() { if (!isBoss) { if (!NearAnyPlayers(75f)) { return !CharacterIsVisible; } return false; } return false; } public bool NearAnyPlayers(float checkRadius) { float num = checkRadius * checkRadius; foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances) { if ((bool)instance.master && (bool)instance.master.GetBody() && (transform.position - instance.master.GetBody().transform.position).sqrMagnitude < num) { return true; } } return false; } [ClientRpc] private void RpcUsePreferredInitialStateType() { if (hasEffectiveAuthority) { SetBodyStateToPreferredInitialState(); } } public void SetBodyStateToPreferredInitialState() { if (!hasEffectiveAuthority) { if (NetworkServer.active) { CallRpcUsePreferredInitialStateType(); } return; } Type stateType = preferredInitialStateType.stateType; if (!(stateType == null) && !(stateType == typeof(Uninitialized))) { EntityStateMachine.FindByCustomName(base.gameObject, "Body")?.SetState(EntityStateCatalog.InstantiateState(stateType)); } } [Server] public void SetLoadoutServer(Loadout loadout) { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.CharacterBody::SetLoadoutServer(RoR2.Loadout)' called on client"); } else { skillLocator.ApplyLoadoutServer(loadout, bodyIndex); } } static CharacterBody() { instancesList = new List(); readOnlyInstancesList = new ReadOnlyCollection(instancesList); kCmdCmdAddTimedBuff = -160178508; NetworkBehaviour.RegisterCommandDelegate(typeof(CharacterBody), kCmdCmdAddTimedBuff, InvokeCmdCmdAddTimedBuff); kCmdCmdSetInLava = 234733148; NetworkBehaviour.RegisterCommandDelegate(typeof(CharacterBody), kCmdCmdSetInLava, InvokeCmdCmdSetInLava); kCmdCmdUpdateSprint = -1006016914; NetworkBehaviour.RegisterCommandDelegate(typeof(CharacterBody), kCmdCmdUpdateSprint, InvokeCmdCmdUpdateSprint); kCmdCmdOnSkillActivated = 384138986; NetworkBehaviour.RegisterCommandDelegate(typeof(CharacterBody), kCmdCmdOnSkillActivated, InvokeCmdCmdOnSkillActivated); kCmdCmdTransmitItemBehavior = 394448000; NetworkBehaviour.RegisterCommandDelegate(typeof(CharacterBody), kCmdCmdTransmitItemBehavior, InvokeCmdCmdTransmitItemBehavior); kCmdCmdSpawnDelayedDamageEffect = 1860577938; NetworkBehaviour.RegisterCommandDelegate(typeof(CharacterBody), kCmdCmdSpawnDelayedDamageEffect, InvokeCmdCmdSpawnDelayedDamageEffect); kCmdCmdRequestVehicleEjection = 1803737791; NetworkBehaviour.RegisterCommandDelegate(typeof(CharacterBody), kCmdCmdRequestVehicleEjection, InvokeCmdCmdRequestVehicleEjection); kRpcRpcTransmitItemBehavior = -729896618; NetworkBehaviour.RegisterRpcDelegate(typeof(CharacterBody), kRpcRpcTransmitItemBehavior, InvokeRpcRpcTransmitItemBehavior); kRpcRpcTeleportCharacterToSafety = -245876694; NetworkBehaviour.RegisterRpcDelegate(typeof(CharacterBody), kRpcRpcTeleportCharacterToSafety, InvokeRpcRpcTeleportCharacterToSafety); kRpcRpcBark = -76716871; NetworkBehaviour.RegisterRpcDelegate(typeof(CharacterBody), kRpcRpcBark, InvokeRpcRpcBark); kRpcRpcUsePreferredInitialStateType = 638695010; NetworkBehaviour.RegisterRpcDelegate(typeof(CharacterBody), kRpcRpcUsePreferredInitialStateType, InvokeRpcRpcUsePreferredInitialStateType); NetworkCRC.RegisterBehaviour("CharacterBody", 0); } private void UNetVersion() { } protected static void InvokeCmdCmdAddTimedBuff(NetworkBehaviour obj, NetworkReader reader) { if (!NetworkServer.active) { Debug.LogError("Command CmdAddTimedBuff called on client."); } else { ((CharacterBody)obj).CmdAddTimedBuff((BuffIndex)reader.ReadInt32(), reader.ReadSingle()); } } protected static void InvokeCmdCmdSetInLava(NetworkBehaviour obj, NetworkReader reader) { if (!NetworkServer.active) { Debug.LogError("Command CmdSetInLava called on client."); } else { ((CharacterBody)obj).CmdSetInLava(reader.ReadBoolean()); } } protected static void InvokeCmdCmdUpdateSprint(NetworkBehaviour obj, NetworkReader reader) { if (!NetworkServer.active) { Debug.LogError("Command CmdUpdateSprint called on client."); } else { ((CharacterBody)obj).CmdUpdateSprint(reader.ReadBoolean()); } } protected static void InvokeCmdCmdOnSkillActivated(NetworkBehaviour obj, NetworkReader reader) { if (!NetworkServer.active) { Debug.LogError("Command CmdOnSkillActivated called on client."); } else { ((CharacterBody)obj).CmdOnSkillActivated((sbyte)reader.ReadPackedUInt32()); } } protected static void InvokeCmdCmdTransmitItemBehavior(NetworkBehaviour obj, NetworkReader reader) { if (!NetworkServer.active) { Debug.LogError("Command CmdTransmitItemBehavior called on client."); } else { ((CharacterBody)obj).CmdTransmitItemBehavior(GeneratedNetworkCode._ReadNetworkItemBehaviorData_CharacterBody(reader)); } } protected static void InvokeCmdCmdSpawnDelayedDamageEffect(NetworkBehaviour obj, NetworkReader reader) { if (!NetworkServer.active) { Debug.LogError("Command CmdSpawnDelayedDamageEffect called on client."); } else { ((CharacterBody)obj).CmdSpawnDelayedDamageEffect(); } } protected static void InvokeCmdCmdRequestVehicleEjection(NetworkBehaviour obj, NetworkReader reader) { if (!NetworkServer.active) { Debug.LogError("Command CmdRequestVehicleEjection called on client."); } else { ((CharacterBody)obj).CmdRequestVehicleEjection(); } } public void CallCmdAddTimedBuff(BuffIndex buffType, float duration) { if (!NetworkClient.active) { Debug.LogError("Command function CmdAddTimedBuff called on server."); return; } if (base.isServer) { CmdAddTimedBuff(buffType, duration); return; } NetworkWriter networkWriter = new NetworkWriter(); networkWriter.Write((short)0); networkWriter.Write((short)5); networkWriter.WritePackedUInt32((uint)kCmdCmdAddTimedBuff); networkWriter.Write(GetComponent().netId); networkWriter.Write((int)buffType); networkWriter.Write(duration); SendCommandInternal(networkWriter, 0, "CmdAddTimedBuff"); } public void CallCmdSetInLava(bool b) { if (!NetworkClient.active) { Debug.LogError("Command function CmdSetInLava called on server."); return; } if (base.isServer) { CmdSetInLava(b); return; } NetworkWriter networkWriter = new NetworkWriter(); networkWriter.Write((short)0); networkWriter.Write((short)5); networkWriter.WritePackedUInt32((uint)kCmdCmdSetInLava); networkWriter.Write(GetComponent().netId); networkWriter.Write(b); SendCommandInternal(networkWriter, 0, "CmdSetInLava"); } public void CallCmdUpdateSprint(bool newIsSprinting) { if (!NetworkClient.active) { Debug.LogError("Command function CmdUpdateSprint called on server."); return; } if (base.isServer) { CmdUpdateSprint(newIsSprinting); return; } NetworkWriter networkWriter = new NetworkWriter(); networkWriter.Write((short)0); networkWriter.Write((short)5); networkWriter.WritePackedUInt32((uint)kCmdCmdUpdateSprint); networkWriter.Write(GetComponent().netId); networkWriter.Write(newIsSprinting); SendCommandInternal(networkWriter, 0, "CmdUpdateSprint"); } public void CallCmdOnSkillActivated(sbyte skillIndex) { if (!NetworkClient.active) { Debug.LogError("Command function CmdOnSkillActivated called on server."); return; } if (base.isServer) { CmdOnSkillActivated(skillIndex); return; } NetworkWriter networkWriter = new NetworkWriter(); networkWriter.Write((short)0); networkWriter.Write((short)5); networkWriter.WritePackedUInt32((uint)kCmdCmdOnSkillActivated); networkWriter.Write(GetComponent().netId); networkWriter.WritePackedUInt32((uint)skillIndex); SendCommandInternal(networkWriter, 0, "CmdOnSkillActivated"); } public void CallCmdTransmitItemBehavior(NetworkItemBehaviorData itemBehaviorData) { if (!NetworkClient.active) { Debug.LogError("Command function CmdTransmitItemBehavior called on server."); return; } if (base.isServer) { CmdTransmitItemBehavior(itemBehaviorData); return; } NetworkWriter networkWriter = new NetworkWriter(); networkWriter.Write((short)0); networkWriter.Write((short)5); networkWriter.WritePackedUInt32((uint)kCmdCmdTransmitItemBehavior); networkWriter.Write(GetComponent().netId); GeneratedNetworkCode._WriteNetworkItemBehaviorData_CharacterBody(networkWriter, itemBehaviorData); SendCommandInternal(networkWriter, 0, "CmdTransmitItemBehavior"); } public void CallCmdSpawnDelayedDamageEffect() { if (!NetworkClient.active) { Debug.LogError("Command function CmdSpawnDelayedDamageEffect called on server."); return; } if (base.isServer) { CmdSpawnDelayedDamageEffect(); return; } NetworkWriter networkWriter = new NetworkWriter(); networkWriter.Write((short)0); networkWriter.Write((short)5); networkWriter.WritePackedUInt32((uint)kCmdCmdSpawnDelayedDamageEffect); networkWriter.Write(GetComponent().netId); SendCommandInternal(networkWriter, 0, "CmdSpawnDelayedDamageEffect"); } public void CallCmdRequestVehicleEjection() { if (!NetworkClient.active) { Debug.LogError("Command function CmdRequestVehicleEjection called on server."); return; } if (base.isServer) { CmdRequestVehicleEjection(); return; } NetworkWriter networkWriter = new NetworkWriter(); networkWriter.Write((short)0); networkWriter.Write((short)5); networkWriter.WritePackedUInt32((uint)kCmdCmdRequestVehicleEjection); networkWriter.Write(GetComponent().netId); SendCommandInternal(networkWriter, 0, "CmdRequestVehicleEjection"); } protected static void InvokeRpcRpcTransmitItemBehavior(NetworkBehaviour obj, NetworkReader reader) { if (!NetworkClient.active) { Debug.LogError("RPC RpcTransmitItemBehavior called on server."); } else { ((CharacterBody)obj).RpcTransmitItemBehavior(GeneratedNetworkCode._ReadNetworkItemBehaviorData_CharacterBody(reader)); } } protected static void InvokeRpcRpcTeleportCharacterToSafety(NetworkBehaviour obj, NetworkReader reader) { if (!NetworkClient.active) { Debug.LogError("RPC RpcTeleportCharacterToSafety called on server."); } else { ((CharacterBody)obj).RpcTeleportCharacterToSafety(); } } protected static void InvokeRpcRpcBark(NetworkBehaviour obj, NetworkReader reader) { if (!NetworkClient.active) { Debug.LogError("RPC RpcBark called on server."); } else { ((CharacterBody)obj).RpcBark(); } } protected static void InvokeRpcRpcUsePreferredInitialStateType(NetworkBehaviour obj, NetworkReader reader) { if (!NetworkClient.active) { Debug.LogError("RPC RpcUsePreferredInitialStateType called on server."); } else { ((CharacterBody)obj).RpcUsePreferredInitialStateType(); } } public void CallRpcTransmitItemBehavior(NetworkItemBehaviorData itemBehaviorData) { if (!NetworkServer.active) { Debug.LogError("RPC Function RpcTransmitItemBehavior called on client."); return; } NetworkWriter networkWriter = new NetworkWriter(); networkWriter.Write((short)0); networkWriter.Write((short)2); networkWriter.WritePackedUInt32((uint)kRpcRpcTransmitItemBehavior); networkWriter.Write(GetComponent().netId); GeneratedNetworkCode._WriteNetworkItemBehaviorData_CharacterBody(networkWriter, itemBehaviorData); SendRPCInternal(networkWriter, 1, "RpcTransmitItemBehavior"); } public void CallRpcTeleportCharacterToSafety() { if (!NetworkServer.active) { Debug.LogError("RPC Function RpcTeleportCharacterToSafety called on client."); return; } NetworkWriter networkWriter = new NetworkWriter(); networkWriter.Write((short)0); networkWriter.Write((short)2); networkWriter.WritePackedUInt32((uint)kRpcRpcTeleportCharacterToSafety); networkWriter.Write(GetComponent().netId); SendRPCInternal(networkWriter, 0, "RpcTeleportCharacterToSafety"); } public void CallRpcBark() { if (!NetworkServer.active) { Debug.LogError("RPC Function RpcBark called on client."); return; } NetworkWriter networkWriter = new NetworkWriter(); networkWriter.Write((short)0); networkWriter.Write((short)2); networkWriter.WritePackedUInt32((uint)kRpcRpcBark); networkWriter.Write(GetComponent().netId); SendRPCInternal(networkWriter, 0, "RpcBark"); } public void CallRpcUsePreferredInitialStateType() { if (!NetworkServer.active) { Debug.LogError("RPC Function RpcUsePreferredInitialStateType called on client."); return; } NetworkWriter networkWriter = new NetworkWriter(); networkWriter.Write((short)0); networkWriter.Write((short)2); networkWriter.WritePackedUInt32((uint)kRpcRpcUsePreferredInitialStateType); networkWriter.Write(GetComponent().netId); SendRPCInternal(networkWriter, 0, "RpcUsePreferredInitialStateType"); } public override void PreStartClient() { } }