Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of YoureInjured v1.4.1
YoureInjured.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("0.0.0.0")] namespace YoureInjured; [BepInPlugin("com.marccunningham.youreinjured", "You're Injured", "1.5.0")] [BepInProcess("valheim.exe")] public sealed class YoureInjuredPlugin : BaseUnityPlugin { private enum HudResizeHandle { None, TopLeft, TopRight, BottomLeft, BottomRight } private enum HitSoundKind { None, Axe, Sword, Arrow } public const string PluginGuid = "com.marccunningham.youreinjured"; public const string PluginName = "You're Injured"; public const string PluginVersion = "1.5.0"; private const float MinimumValue = 0f; private const float MaximumValue = 100f; private const float TickIntervalSeconds = 1f; private const float SaveIntervalSeconds = 5f; private const float MinimumHealthLeft = 1f; private const float InjuryPanelHeight = 150f; private const float InjuryPanelMinimumBottomMargin = 12f; private const int LiquidBloodTextureSize = 192; private const int LiquidBloodTextureVariantCount = 7; private const float CompactHudReferenceWidth = 2048f; private const float CompactHudReferenceHeight = 1152f; private const float CompactInjuryReferenceLeft = 248f; private const float CompactInjuryReferenceBottom = 30f; private const float CompactInjuryReferenceWidth = 220f; private const float CompactInjuryReferenceHeight = 80f; private const string ZdoHead = "YoureInjured_Head"; private const string ZdoTorso = "YoureInjured_Torso"; private const string ZdoLeftArm = "YoureInjured_LeftArm"; private const string ZdoRightArm = "YoureInjured_RightArm"; private const string ZdoLeftLeg = "YoureInjured_LeftLeg"; private const string ZdoRightLeg = "YoureInjured_RightLeg"; private const string ZdoBleeding = "YoureInjured_Bleeding"; private const string ZdoInfection = "YoureInjured_Infection"; private const string ZdoInfectionRisk = "YoureInjured_InfectionRisk"; internal static YoureInjuredPlugin Instance; private ConfigEntry<bool> modEnabled; private ConfigEntry<KeyCode> treatmentKey; private ConfigEntry<KeyCode> diagnosticKey; private ConfigEntry<KeyCode> sessionToggleKey; private ConfigEntry<string> difficultyPreset; private ConfigEntry<string> lastAppliedDifficultyPreset; private ConfigEntry<float> minimumStaminaRegenMultiplier; private ConfigEntry<bool> showHud; private ConfigEntry<bool> hideHudWithCtrlF3; private ConfigEntry<bool> useCompactSurvivalHud; private ConfigEntry<KeyCode> hudLayoutEditorKey; private ConfigEntry<float> compactHudXNormalized; private ConfigEntry<float> compactHudYNormalized; private ConfigEntry<float> compactHudWidthNormalized; private ConfigEntry<float> compactHudHeightNormalized; private ConfigEntry<bool> useSafeHudLayout; private ConfigEntry<float> hudPanelLeft; private ConfigEntry<float> hudPanelBottomOffset; private ConfigEntry<bool> stackBelowTemperatureHud; private ConfigEntry<bool> autoLiftTemperatureHudForInjuryPanel; private ConfigEntry<float> temperatureHudGapPixels; private ConfigEntry<float> temperatureHudFallbackLeft; private ConfigEntry<float> temperatureHudFallbackBottomOffset; private ConfigEntry<bool> verboseLogging; private ConfigEntry<float> minimumDamageForInjury; private ConfigEntry<float> injuryPerHealthLost; private ConfigEntry<float> fallInjuryMultiplier; private ConfigEntry<float> physicalBleedingThreshold; private ConfigEntry<float> bleedingPerHealthLost; private ConfigEntry<float> brokenBoneThreshold; private ConfigEntry<float> bleedingDamageAt100PerSecond; private ConfigEntry<float> naturalClottingPerSecond; private ConfigEntry<float> infectionRiskPerSecond; private ConfigEntry<float> wetInfectionRiskMultiplier; private ConfigEntry<float> infectionOnsetSeverity; private ConfigEntry<float> infectionGrowthPerSecond; private ConfigEntry<float> infectionRecoveryInBedPerSecond; private ConfigEntry<float> infectionDamageAt100PerSecond; private ConfigEntry<bool> enableSwimmingRinse; private ConfigEntry<float> swimmingRinseRequiredSeconds; private ConfigEntry<float> shelterRecoveryPerSecond; private ConfigEntry<float> bedRecoveryMultiplier; private ConfigEntry<float> recoveryStillSpeedLimit; private ConfigEntry<float> brokenLegRunPenalty; private ConfigEntry<float> legInjuryRunPenalty; private ConfigEntry<float> armInjuryAttackStaminaPenalty; private ConfigEntry<float> brokenArmAttackStaminaPenalty; private ConfigEntry<float> legInjuryRunStaminaPenalty; private ConfigEntry<float> headTorsoStaminaRegenPenalty; private ConfigEntry<float> infectionStaminaRegenPenalty; private ConfigEntry<float> legInjuryJumpStaminaPenalty; private ConfigEntry<string> bandageItemSharedName; private ConfigEntry<int> bandageItemCost; private ConfigEntry<float> bandageBleedingReduction; private ConfigEntry<float> bandageInfectionRiskReduction; private ConfigEntry<float> bandageInfectionReduction; private ConfigEntry<float> bandageWoundRelief; private ConfigEntry<float> treatmentCooldownSeconds; private ConfigEntry<bool> enableBleedingVisuals; private ConfigEntry<bool> spawnBloodFromSharpHits; private ConfigEntry<bool> enableBleedingTrail; private ConfigEntry<float> visibleBloodMinimumHealthLoss; private ConfigEntry<float> trailMinimumBleeding; private ConfigEntry<float> walkingTrailIntervalSeconds; private ConfigEntry<float> runningTrailIntervalSeconds; private ConfigEntry<float> groundBloodLifetimeSeconds; private ConfigEntry<int> maximumGroundBloodSplats; private ConfigEntry<int> maximumHitBloodDroplets; private ConfigEntry<float> bloodDropletGravity; private ConfigEntry<float> bloodSplatMinimumSize; private ConfigEntry<float> bloodSplatMaximumSize; private ConfigEntry<float> bloodLiquidSpreadSeconds; private ConfigEntry<bool> enableHitImpactSprites; private ConfigEntry<bool> cameraSafeHitSprites; private ConfigEntry<float> hitImpactSpriteLifetime; private ConfigEntry<float> hitImpactSpriteMaximumSize; private ConfigEntry<int> maximumImpactSpriteTextures; private ConfigEntry<bool> enableHitAudio; private ConfigEntry<float> hitAudioVolume; private ConfigEntry<float> hitAudioCooldownSeconds; private ConfigEntry<string> axeHitAudioFile; private ConfigEntry<string> swordHitAudioFile; private ConfigEntry<string> arrowHitAudioFile; private ConfigEntry<bool> enableBandageAudio; private ConfigEntry<float> bandageAudioVolume; private ConfigEntry<string> bandageAudioFile; private Harmony harmony; private readonly InjuryState state = new InjuryState(); private GUIStyle injuryHeaderStyle; private GUIStyle injuryDetailStyle; private GUIStyle compactInjuryHeaderStyle; private GUIStyle compactInjuryDetailStyle; private bool hudLayoutEditorActive; private bool hudLayoutDragging; private HudResizeHandle hudResizeHandle; private Vector2 hudEditStartMouse; private Rect hudEditStartRect; private CursorLockMode hudPreviousCursorLockMode; private bool hudPreviousCursorVisible; private bool hudCursorStateCaptured; private bool hudHiddenByCtrlF3; private bool runtimeEnabled = true; private bool stateLoaded; private float tickTimer; private float saveTimer; private float treatmentCooldown; private int localDamageHookCalls; private int injuryEventsRecorded; private float lastDetectedHealthLoss; private HitType lastDetectedHitType; private readonly List<GroundBloodSplat> activeGroundBlood = new List<GroundBloodSplat>(); private Transform bloodVisualRoot; private Material bloodDropMaterial; private Material[] bloodLiquidMaterials; private Texture2D[] bloodLiquidTextures; private float bleedingTrailTimer; private float swimmingRinseTimer; private int hitBloodAttempts; private int trailBloodAttempts; private int hitBloodDropletsSpawned; private int trailBloodDropletsSpawned; private int groundBloodSplatsSpawned; private int directTrailSplatsSpawned; private int groundProbeSuccesses; private int groundProbeFailures; private int dropletFallbackLandings; private string pluginDirectory; private readonly List<Texture2D> impactSpriteTextures = new List<Texture2D>(); private readonly List<Material> impactSpriteMaterials = new List<Material>(); private readonly List<Texture2D> dripSpriteTextures = new List<Texture2D>(); private readonly List<Material> dripSpriteMaterials = new List<Material>(); private Component hitAudioSource; private object axeHitAudioClip; private object swordHitAudioClip; private object arrowHitAudioClip; private object bandageAudioClip; private float bleedDripTimer; private float nextAllowedRecognizedHitAudioTime; private void Awake() { //IL_0e99: Unknown result type (might be due to invalid IL or missing references) //IL_0ea3: Expected O, but got Unknown Instance = this; pluginDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Set false to disable the entire injury system, including wounds, penalties, treatment and injury HUD."); treatmentKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "UseBandageKey", (KeyCode)103, "Press this key to use a bandage material and treat wounds. Change it if G conflicts with another mod."); diagnosticKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "DiagnosticKey", (KeyCode)283, "Writes the current injury state to BepInEx/LogOutput.log."); sessionToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "SessionToggleKey", (KeyCode)284, "Emergency session toggle. This pauses or resumes injury effects without removing the DLL."); difficultyPreset = ((BaseUnityPlugin)this).Config.Bind<string>("Difficulty", "Preset", "Normal", "Choose Easy, Normal, Hard, or Extreme. Change this setting, then restart Valheim to apply that mod's matching survival balance."); lastAppliedDifficultyPreset = ((BaseUnityPlugin)this).Config.Bind<string>("Difficulty", "LastAppliedPreset", "Normal", "Internal preset tracking. Leave this alone; it records the last difficulty preset applied."); minimumStaminaRegenMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Difficulty", "MinimumStaminaRegenMultiplier", 0.82f, "Safety floor for this mod's own injury and infection stamina-regeneration penalty. It prevents wounds from combining with other Scavengers penalties into a no-escape state."); showHud = ((BaseUnityPlugin)this).Config.Bind<bool>("HUD", "ShowInjuryPanel", true, "Set false to hide only the Injuries HUD while injury calculations and treatment continue running."); hideHudWithCtrlF3 = ((BaseUnityPlugin)this).Config.Bind<bool>("HUD", "HideHudWithCtrlF3", true, "When enabled, Ctrl+F3 hides or restores this mod's HUD along with Valheim's HUD toggle. The injury system keeps running."); useCompactSurvivalHud = ((BaseUnityPlugin)this).Config.Bind<bool>("HUD", "UseCompactSurvivalHud", true, "Places the injury panel beneath the Body Temp panel, under Nourishment and directly left of the Tired meter."); hudLayoutEditorKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("HUD Layout Editor", "ToggleInjuriesLayoutEditorKey", (KeyCode)111, "Press O to enter or leave Injuries HUD layout mode. In layout mode, drag the panel and drag a gold corner handle to resize it."); compactHudXNormalized = ((BaseUnityPlugin)this).Config.Bind<float>("HUD Layout", "CompactInjuriesXNormalized", 0.12109375f, "Saved left position of the compact Injuries panel as a fraction of screen width."); compactHudYNormalized = ((BaseUnityPlugin)this).Config.Bind<float>("HUD Layout", "CompactInjuriesYNormalized", 0.9045139f, "Saved top position of the compact Injuries panel as a fraction of screen height."); compactHudWidthNormalized = ((BaseUnityPlugin)this).Config.Bind<float>("HUD Layout", "CompactInjuriesWidthNormalized", 0.107421875f, "Saved width of the compact Injuries panel as a fraction of screen width."); compactHudHeightNormalized = ((BaseUnityPlugin)this).Config.Bind<float>("HUD Layout", "CompactInjuriesHeightNormalized", 5f / 72f, "Saved height of the compact Injuries panel as a fraction of screen height."); useSafeHudLayout = ((BaseUnityPlugin)this).Config.Bind<bool>("HUD", "UseSafeLayout", true, "Uses the fixed stacked layout beneath the temperature gauge. It automatically keeps enough room for the full injury panel."); hudPanelLeft = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "PanelLeftPixels", 392f, "Manual panel left edge in pixels when UseSafeLayout is false."); hudPanelBottomOffset = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "PanelBottomOffsetPixels", 18f, "Manual clearance from the bottom of the screen in pixels when UseSafeLayout is false."); stackBelowTemperatureHud = ((BaseUnityPlugin)this).Config.Bind<bool>("HUD", "StackDirectlyBelowTemperatureBar", true, "Keeps the injury panel directly below You're Cold's temperature bar, with an even gap. This is enabled by default so the two survival panels remain aligned."); autoLiftTemperatureHudForInjuryPanel = ((BaseUnityPlugin)this).Config.Bind<bool>("HUD", "AutoLiftTemperatureHudForInjuryPanel", true, "Moves the temperature panel upward only when needed so the larger injury panel can remain directly beneath it without clipping off the bottom of the screen."); temperatureHudGapPixels = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "TemperatureHudGapPixels", 12f, "Even vertical gap between the bottom of the temperature panel and the top of the larger injury panel."); temperatureHudFallbackLeft = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "TemperatureHudFallbackLeftPixels", 460f, "Fallback temperature-panel left edge used only when You're Cold is not currently loaded."); temperatureHudFallbackBottomOffset = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "TemperatureHudFallbackBottomOffsetPixels", 330f, "Fallback temperature-panel bottom offset used only when You're Cold is not currently loaded."); verboseLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "VerboseLogging", false, "Writes injury update details to LogOutput.log every tick. Keep disabled unless testing."); minimumDamageForInjury = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "MinimumHealthLossForInjury", 1f, "Actual health loss required before a hit can create an injury. V1.0.3 defaults to 1 so ordinary enemy hits are visible during testing."); injuryPerHealthLost = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "InjuryPointsPerHealthLost", 1.4f, "Injury points applied for each point of health actually lost after armour and resistances."); fallInjuryMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "FallInjuryMultiplier", 1.25f, "Extra injury multiplier for fall damage. Fall injuries are applied to both legs."); physicalBleedingThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "PhysicalDamageForBleeding", 8f, "Actual health loss required before slash or pierce damage can cause bleeding."); bleedingPerHealthLost = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "BleedingPointsPerHealthLost", 1.5f, "Bleeding points applied per health lost beyond the bleeding threshold."); brokenBoneThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "BrokenBoneThreshold", 78f, "An arm or leg at or above this injury value is treated as broken."); bleedingDamageAt100PerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("Bleeding", "DamageAt100BleedingPerSecond", 0.24f, "Health lost each second at 100 bleeding. Bleeding will not reduce health below 1 in V1."); naturalClottingPerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("Bleeding", "NaturalClottingPerSecond", 0.06f, "Bleeding naturally decreases this much per second. Bandages are much faster."); infectionRiskPerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("Infection", "RiskGainPerSecond", 0.1f, "Infection risk gained per second from untreated serious wounds."); wetInfectionRiskMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Infection", "WetRiskMultiplier", 2f, "Multiplier applied to infection risk while Wet."); infectionOnsetSeverity = ((BaseUnityPlugin)this).Config.Bind<float>("Infection", "OnsetSeverity", 25f, "Infection severity created when infection risk reaches 100."); infectionGrowthPerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("Infection", "GrowthPerSecond", 0.04f, "How quickly an untreated infection worsens outside a bed."); infectionRecoveryInBedPerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("Infection", "RecoveryInBedPerSecond", 0.14f, "How quickly infection improves while sheltered in bed with no active bleeding."); infectionDamageAt100PerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("Infection", "DamageAt100InfectionPerSecond", 0.12f, "Health lost each second at 100 infection. Infection will not reduce health below 1 in V1."); enableSwimmingRinse = ((BaseUnityPlugin)this).Config.Bind<bool>("Infection", "EnableColdWaterRinse", true, "Allows one continuous minute of swimming to rinse infection risk from a closed, non-infected wound. It does not cure an established infection and cannot be used while actively bleeding."); swimmingRinseRequiredSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Infection", "ColdWaterRinseSeconds", 60f, "Continuous swimming time required to clear infection risk from a closed wound. Leaving the water resets the rinse timer."); shelterRecoveryPerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("Recovery", "ShelterRecoveryPerSecond", 0.045f, "Injury points recovered per second while sheltered and still, with no bleeding or infection."); bedRecoveryMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Recovery", "BedRecoveryMultiplier", 4.5f, "Recovery multiplier while resting in bed."); recoveryStillSpeedLimit = ((BaseUnityPlugin)this).Config.Bind<float>("Recovery", "StillSpeedLimit", 0.25f, "Maximum movement speed that counts as resting for sheltered recovery."); brokenLegRunPenalty = ((BaseUnityPlugin)this).Config.Bind<float>("Penalties", "BrokenLegRunPenalty", 0.18f, "Speed penalty per broken leg. Two broken legs are capped so movement remains possible."); legInjuryRunPenalty = ((BaseUnityPlugin)this).Config.Bind<float>("Penalties", "LegInjuryRunPenaltyAt100", 0.22f, "Maximum speed penalty from non-broken leg injuries."); armInjuryAttackStaminaPenalty = ((BaseUnityPlugin)this).Config.Bind<float>("Penalties", "ArmInjuryAttackStaminaPenaltyAt100", 0.28f, "Maximum extra attack stamina cost from arm injuries."); brokenArmAttackStaminaPenalty = ((BaseUnityPlugin)this).Config.Bind<float>("Penalties", "BrokenArmAttackStaminaPenalty", 0.15f, "Extra attack stamina cost per broken arm."); legInjuryRunStaminaPenalty = ((BaseUnityPlugin)this).Config.Bind<float>("Penalties", "LegInjuryRunStaminaPenaltyAt100", 0.22f, "Maximum extra run stamina drain from leg injuries."); headTorsoStaminaRegenPenalty = ((BaseUnityPlugin)this).Config.Bind<float>("Penalties", "HeadTorsoStaminaRegenPenaltyAt100", 0.22f, "Maximum stamina regeneration reduction from head and torso injuries."); infectionStaminaRegenPenalty = ((BaseUnityPlugin)this).Config.Bind<float>("Penalties", "InfectionStaminaRegenPenaltyAt100", 0.18f, "Maximum stamina regeneration reduction from infection."); legInjuryJumpStaminaPenalty = ((BaseUnityPlugin)this).Config.Bind<float>("Penalties", "LegInjuryJumpStaminaPenaltyAt100", 0.2f, "Maximum extra jump stamina cost from leg injuries."); bandageItemSharedName = ((BaseUnityPlugin)this).Config.Bind<string>("Bandages", "BandageItemSharedName", "$item_leatherscraps", "Valheim shared item name consumed as a bandage. Default is Leather Scraps, so treatment is available from the early game. This is a material-based bandage system in V1, not a new custom item prefab."); bandageItemCost = ((BaseUnityPlugin)this).Config.Bind<int>("Bandages", "BandageItemCost", 1, "How many bandage material items are consumed per treatment."); bandageBleedingReduction = ((BaseUnityPlugin)this).Config.Bind<float>("Bandages", "BleedingReduction", 60f, "Bleeding removed by one treatment."); bandageInfectionRiskReduction = ((BaseUnityPlugin)this).Config.Bind<float>("Bandages", "InfectionRiskReduction", 40f, "Infection risk removed by one treatment."); bandageInfectionReduction = ((BaseUnityPlugin)this).Config.Bind<float>("Bandages", "InfectionReduction", 5f, "Existing infection reduced by one treatment. Sleeping while sheltered is the main recovery method."); bandageWoundRelief = ((BaseUnityPlugin)this).Config.Bind<float>("Bandages", "WoundRelief", 7f, "Small injury reduction applied to each body part by one treatment. Bandages do not immediately fix broken bones."); treatmentCooldownSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Bandages", "TreatmentCooldownSeconds", 1f, "Prevents accidental repeated bandage use from one key press."); enableBleedingVisuals = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual Bleeding", "Enabled", true, "Creates local visual blood droplets and glossy two-minute ground splats for the player when wounded. It does not alter damage, terrain, saves or networking."); spawnBloodFromSharpHits = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual Bleeding", "SpawnBloodFromSharpHits", true, "Spawns a small blood burst from qualifying slash or pierce hits, even before a wound becomes severe enough to leave a trail."); enableBleedingTrail = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual Bleeding", "EnableBleedingTrail", true, "Leaves intermittent drops while walking or running with meaningful active bleeding."); visibleBloodMinimumHealthLoss = ((BaseUnityPlugin)this).Config.Bind<float>("Visual Bleeding", "MinimumHealthLossForVisibleBlood", 2f, "Health loss required from slash or pierce damage before a visible hit blood burst is created."); trailMinimumBleeding = ((BaseUnityPlugin)this).Config.Bind<float>("Visual Bleeding", "MinimumBleedingForTrail", 5f, "Bleeding severity required before movement leaves a visible trail."); walkingTrailIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Visual Bleeding", "WalkingTrailIntervalSeconds", 0.82f, "Time between trail drops while walking. The default leaves a clearly readable but safe blood trail."); runningTrailIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Visual Bleeding", "RunningTrailIntervalSeconds", 0.44f, "Time between trail drops while running."); groundBloodLifetimeSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Visual Bleeding", "GroundBloodLifetimeSeconds", 120f, "How long landed blood remains visible on the ground. Default is two minutes and the final fade only begins in the last twelve seconds."); maximumGroundBloodSplats = ((BaseUnityPlugin)this).Config.Bind<int>("Visual Bleeding", "MaximumGroundBloodSplats", 240, "Safety cap for active ground blood visuals. The oldest splat is removed when this limit is reached."); maximumHitBloodDroplets = ((BaseUnityPlugin)this).Config.Bind<int>("Visual Bleeding", "MaximumHitBloodDroplets", 14, "Maximum droplets produced by one strong slash, axe or arrow hit."); bloodDropletGravity = ((BaseUnityPlugin)this).Config.Bind<float>("Visual Bleeding", "DropletGravity", 14f, "Downward acceleration for visual blood droplets. Slightly above real gravity keeps the fall readable in-game."); bloodSplatMinimumSize = ((BaseUnityPlugin)this).Config.Bind<float>("Visual Bleeding", "GroundSplatMinimumSize", 0.17f, "Smallest ground blood splat diameter in metres."); bloodSplatMaximumSize = ((BaseUnityPlugin)this).Config.Bind<float>("Visual Bleeding", "GroundSplatMaximumSize", 0.52f, "Largest ground blood splat diameter in metres."); bloodLiquidSpreadSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Visual Bleeding", "BloodLiquidSpreadSeconds", 0.65f, "Seconds for a fresh blood splat to settle and spread across the ground. Short but visible, so blood feels liquid rather than stamped on."); enableHitImpactSprites = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual Bleeding", "EnableHitImpactSprites", false, "Optional world-space hit burst using supplied blood-spray frames. Disabled by default because the player-hit burst is not needed and can read like a red screen flash."); cameraSafeHitSprites = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual Bleeding", "CameraSafeHitSprites", true, "Skips a hit-sprite if the wound is too close to the gameplay camera, preventing a red full-screen blink."); hitImpactSpriteLifetime = ((BaseUnityPlugin)this).Config.Bind<float>("Visual Bleeding", "HitImpactSpriteLifetimeSeconds", 0.14f, "How long the small sprite-based blood burst remains visible."); hitImpactSpriteMaximumSize = ((BaseUnityPlugin)this).Config.Bind<float>("Visual Bleeding", "HitImpactSpriteMaximumSize", 0.38f, "Largest world-space size of a hit blood-spray sprite."); maximumImpactSpriteTextures = ((BaseUnityPlugin)this).Config.Bind<int>("Visual Bleeding", "MaximumImpactSpriteTextures", 4, "Maximum number of supplied blood-spray textures loaded from assets/bleeding/impact_frames."); enableHitAudio = ((BaseUnityPlugin)this).Config.Bind<bool>("Hit Audio", "Enabled", true, "Plays one local hit sound for qualifying player hits. Axe, sword, and arrow MP3 files are loaded externally beside the DLL."); hitAudioVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Hit Audio", "Volume", 0.65f, "Volume for externally loaded hit sounds."); hitAudioCooldownSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Hit Audio", "RecognizedHitSoundCooldownSeconds", 0.18f, "Minimum gap between correctly recognized axe, sword or arrow hit sounds. This prevents duplicate sounds from a single combat event."); axeHitAudioFile = ((BaseUnityPlugin)this).Config.Bind<string>("Hit Audio", "AxeHitFile", "axe_hit.mp3", "MP3 filename expected in assets/audio beside the You're Injured DLL."); swordHitAudioFile = ((BaseUnityPlugin)this).Config.Bind<string>("Hit Audio", "SwordHitFile", "sword_hit.mp3", "MP3 filename expected in assets/audio beside the You're Injured DLL."); arrowHitAudioFile = ((BaseUnityPlugin)this).Config.Bind<string>("Hit Audio", "ArrowHitFile", "arrow_hit.mp3", "MP3 filename expected in assets/audio beside the You're Injured DLL."); enableBandageAudio = ((BaseUnityPlugin)this).Config.Bind<bool>("Bandage Audio", "Enabled", true, "Plays the supplied cloth-wrap sound only after a bandage is successfully applied and its material is consumed."); bandageAudioVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Bandage Audio", "Volume", 0.68f, "Volume for the externally loaded bandage-wrap sound."); bandageAudioFile = ((BaseUnityPlugin)this).Config.Bind<string>("Bandage Audio", "BandageWrapFile", "bandage wrap.mp3", "MP3 filename expected in assets/audio beside the You're Injured DLL."); if (string.Equals(bandageItemSharedName.Value, "$item_linen", StringComparison.Ordinal)) { bandageItemSharedName.Value = "$item_leatherscraps"; } if (Mathf.Abs(minimumDamageForInjury.Value - 5f) < 0.01f) { minimumDamageForInjury.Value = 1f; } if (Mathf.Abs(hudPanelLeft.Value - 460f) < 0.01f || Mathf.Abs(hudPanelLeft.Value - 417f) < 0.01f || Mathf.Abs(hudPanelLeft.Value - 406f) < 0.01f) { hudPanelLeft.Value = 392f; } if (Mathf.Abs(hudPanelBottomOffset.Value - 165f) < 0.01f || Mathf.Abs(hudPanelBottomOffset.Value - 170f) < 0.01f || Mathf.Abs(hudPanelBottomOffset.Value - 140f) < 0.01f || Mathf.Abs(hudPanelBottomOffset.Value - 100f) < 0.01f) { hudPanelBottomOffset.Value = 18f; } if (Mathf.Abs(walkingTrailIntervalSeconds.Value - 1.35f) < 0.01f) { walkingTrailIntervalSeconds.Value = 0.82f; } if (Mathf.Abs(runningTrailIntervalSeconds.Value - 0.68f) < 0.01f) { runningTrailIntervalSeconds.Value = 0.44f; } if (maximumGroundBloodSplats.Value == 160) { maximumGroundBloodSplats.Value = 240; } if (maximumHitBloodDroplets.Value == 5) { maximumHitBloodDroplets.Value = 14; } if (Mathf.Abs(bloodSplatMinimumSize.Value - 0.11f) < 0.01f) { bloodSplatMinimumSize.Value = 0.17f; } if (Mathf.Abs(bloodSplatMaximumSize.Value - 0.28f) < 0.01f) { bloodSplatMaximumSize.Value = 0.52f; } ((BaseUnityPlugin)this).Config.Save(); MigrateLegacyDefaultsToNormal(); ApplyDifficultyPresetIfChanged(); LoadExternalImpactSprites(); ((MonoBehaviour)this).StartCoroutine(LoadHitAudioFiles()); harmony = new Harmony("com.marccunningham.youreinjured"); harmony.PatchAll(typeof(YoureInjuredPlugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"You're Injured 1.5.0 loaded. G uses Leather Scraps as bandage material, F2 logs diagnostics, and F3 toggles injury effects for this session. V1.3.5 adds a heavier directional wound spray, larger persistent blood pools, and strict weapon-recognized hit audio."); } private void MigrateLegacyDefaultsToNormal() { if (Mathf.Abs(injuryPerHealthLost.Value - 1.6f) < 0.001f && Mathf.Abs(fallInjuryMultiplier.Value - 1.4f) < 0.001f && Mathf.Abs(bleedingPerHealthLost.Value - 1.8f) < 0.001f && Mathf.Abs(brokenBoneThreshold.Value - 75f) < 0.001f && Mathf.Abs(headTorsoStaminaRegenPenalty.Value - 0.35f) < 0.001f && Mathf.Abs(infectionStaminaRegenPenalty.Value - 0.3f) < 0.001f) { ApplyDifficultyPreset("Normal"); ((BaseUnityPlugin)this).Config.Save(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"You're Injured: migrated untouched legacy injury defaults to the balanced Normal preset."); } } private void ApplyDifficultyPresetIfChanged() { string text = NormalizeDifficultyPreset(difficultyPreset.Value); if (!string.Equals(difficultyPreset.Value, text, StringComparison.OrdinalIgnoreCase)) { difficultyPreset.Value = text; } if (!string.Equals(lastAppliedDifficultyPreset.Value, text, StringComparison.OrdinalIgnoreCase)) { ApplyDifficultyPreset(text); lastAppliedDifficultyPreset.Value = text; ((BaseUnityPlugin)this).Config.Save(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("You're Injured: applied " + text + " difficulty preset.")); } } private static string NormalizeDifficultyPreset(string value) { if (string.Equals(value, "Easy", StringComparison.OrdinalIgnoreCase)) { return "Easy"; } if (string.Equals(value, "Hard", StringComparison.OrdinalIgnoreCase)) { return "Hard"; } if (string.Equals(value, "Extreme", StringComparison.OrdinalIgnoreCase)) { return "Extreme"; } return "Normal"; } private void ApplyDifficultyPreset(string preset) { switch (preset) { case "Easy": injuryPerHealthLost.Value = 1f; fallInjuryMultiplier.Value = 1.1f; bleedingPerHealthLost.Value = 1.1f; brokenBoneThreshold.Value = 85f; bleedingDamageAt100PerSecond.Value = 0.16f; naturalClottingPerSecond.Value = 0.08f; infectionRiskPerSecond.Value = 0.07f; wetInfectionRiskMultiplier.Value = 1.7f; infectionGrowthPerSecond.Value = 0.025f; infectionRecoveryInBedPerSecond.Value = 0.18f; infectionDamageAt100PerSecond.Value = 0.09f; shelterRecoveryPerSecond.Value = 0.06f; bedRecoveryMultiplier.Value = 5f; brokenLegRunPenalty.Value = 0.14f; legInjuryRunPenalty.Value = 0.16f; legInjuryRunStaminaPenalty.Value = 0.16f; headTorsoStaminaRegenPenalty.Value = 0.16f; infectionStaminaRegenPenalty.Value = 0.12f; minimumStaminaRegenMultiplier.Value = 0.9f; bandageBleedingReduction.Value = 68f; bandageInfectionRiskReduction.Value = 48f; bandageInfectionReduction.Value = 7f; bandageWoundRelief.Value = 9f; break; case "Hard": injuryPerHealthLost.Value = 1.85f; fallInjuryMultiplier.Value = 1.55f; bleedingPerHealthLost.Value = 2f; brokenBoneThreshold.Value = 70f; bleedingDamageAt100PerSecond.Value = 0.34f; naturalClottingPerSecond.Value = 0.035f; infectionRiskPerSecond.Value = 0.15f; wetInfectionRiskMultiplier.Value = 3f; infectionGrowthPerSecond.Value = 0.07f; infectionRecoveryInBedPerSecond.Value = 0.09f; infectionDamageAt100PerSecond.Value = 0.22f; shelterRecoveryPerSecond.Value = 0.025f; bedRecoveryMultiplier.Value = 3f; brokenLegRunPenalty.Value = 0.25f; legInjuryRunPenalty.Value = 0.34f; legInjuryRunStaminaPenalty.Value = 0.34f; headTorsoStaminaRegenPenalty.Value = 0.32f; infectionStaminaRegenPenalty.Value = 0.28f; minimumStaminaRegenMultiplier.Value = 0.75f; bandageBleedingReduction.Value = 48f; bandageInfectionRiskReduction.Value = 30f; bandageInfectionReduction.Value = 3f; bandageWoundRelief.Value = 4f; break; case "Extreme": injuryPerHealthLost.Value = 2.3f; fallInjuryMultiplier.Value = 1.8f; bleedingPerHealthLost.Value = 2.4f; brokenBoneThreshold.Value = 65f; bleedingDamageAt100PerSecond.Value = 0.42f; naturalClottingPerSecond.Value = 0.025f; infectionRiskPerSecond.Value = 0.2f; wetInfectionRiskMultiplier.Value = 3.6f; infectionGrowthPerSecond.Value = 0.095f; infectionRecoveryInBedPerSecond.Value = 0.065f; infectionDamageAt100PerSecond.Value = 0.3f; shelterRecoveryPerSecond.Value = 0.018f; bedRecoveryMultiplier.Value = 2.4f; brokenLegRunPenalty.Value = 0.3f; legInjuryRunPenalty.Value = 0.4f; legInjuryRunStaminaPenalty.Value = 0.4f; headTorsoStaminaRegenPenalty.Value = 0.38f; infectionStaminaRegenPenalty.Value = 0.34f; minimumStaminaRegenMultiplier.Value = 0.68f; bandageBleedingReduction.Value = 38f; bandageInfectionRiskReduction.Value = 22f; bandageInfectionReduction.Value = 2f; bandageWoundRelief.Value = 3f; break; default: injuryPerHealthLost.Value = 1.4f; fallInjuryMultiplier.Value = 1.25f; bleedingPerHealthLost.Value = 1.5f; brokenBoneThreshold.Value = 78f; bleedingDamageAt100PerSecond.Value = 0.24f; naturalClottingPerSecond.Value = 0.06f; infectionRiskPerSecond.Value = 0.1f; wetInfectionRiskMultiplier.Value = 2f; infectionGrowthPerSecond.Value = 0.04f; infectionRecoveryInBedPerSecond.Value = 0.14f; infectionDamageAt100PerSecond.Value = 0.12f; shelterRecoveryPerSecond.Value = 0.045f; bedRecoveryMultiplier.Value = 4.5f; brokenLegRunPenalty.Value = 0.18f; legInjuryRunPenalty.Value = 0.22f; legInjuryRunStaminaPenalty.Value = 0.22f; headTorsoStaminaRegenPenalty.Value = 0.22f; infectionStaminaRegenPenalty.Value = 0.18f; minimumStaminaRegenMultiplier.Value = 0.82f; bandageBleedingReduction.Value = 60f; bandageInfectionRiskReduction.Value = 40f; bandageInfectionReduction.Value = 5f; bandageWoundRelief.Value = 7f; break; } } private void OnDestroy() { RestoreHudCursor(); if (harmony != null) { harmony.UnpatchSelf(); } DestroyBloodVisuals(); if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } private void Update() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) if (TryToggleHudWithCtrlF3()) { return; } if (hudLayoutEditorActive && (!showHud.Value || IsHudHiddenByCtrlF3())) { CloseHudLayoutEditorForHiddenHud(); } if (Input.GetKeyDown(hudLayoutEditorKey.Value) && showHud.Value && !IsHudHiddenByCtrlF3()) { ToggleHudLayoutEditor(); } if (Input.GetKeyDown(diagnosticKey.Value)) { WriteDiagnostic(); } if (Input.GetKeyDown(sessionToggleKey.Value)) { runtimeEnabled = !runtimeEnabled; ShowMessage("You're Injured: " + (runtimeEnabled ? "ON" : "OFF")); } if (!runtimeEnabled || !modEnabled.Value) { return; } Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { EnsureStateLoaded(localPlayer); if (Input.GetKeyDown(treatmentKey.Value)) { TryUseBandage(localPlayer); } float deltaTime = Time.deltaTime; treatmentCooldown = Mathf.Max(0f, treatmentCooldown - deltaTime); UpdateBleedingTrail(localPlayer, deltaTime); UpdateBleedingDrips(localPlayer, deltaTime); tickTimer += deltaTime; saveTimer += deltaTime; if (tickTimer >= 1f) { float elapsedSeconds = Mathf.Min(tickTimer, 3f); tickTimer = 0f; TickInjuries(localPlayer, elapsedSeconds); } if (saveTimer >= 5f) { saveTimer = 0f; SaveState(localPlayer); } } } internal bool IsActiveFor(Player player) { if (runtimeEnabled && modEnabled.Value && (Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)Player.m_localPlayer) { return stateLoaded; } return false; } internal float GetRunSpeedMultiplier() { float threshold = Mathf.Clamp(brokenBoneThreshold.Value, 1f, 100f); float num = state.GetAverageLegInjury() / 100f; float num2 = 1f - num * Mathf.Clamp01(legInjuryRunPenalty.Value); if (state.IsBroken(Limb.LeftLeg, threshold)) { num2 -= Mathf.Clamp01(brokenLegRunPenalty.Value); } if (state.IsBroken(Limb.RightLeg, threshold)) { num2 -= Mathf.Clamp01(brokenLegRunPenalty.Value); } return Mathf.Clamp(num2, 0.3f, 1f); } internal float GetAttackStaminaMultiplier() { float threshold = Mathf.Clamp(brokenBoneThreshold.Value, 1f, 100f); float num = state.GetAverageArmInjury() / 100f; float num2 = 1f + num * Mathf.Max(0f, armInjuryAttackStaminaPenalty.Value); if (state.IsBroken(Limb.LeftArm, threshold)) { num2 += Mathf.Max(0f, brokenArmAttackStaminaPenalty.Value); } if (state.IsBroken(Limb.RightArm, threshold)) { num2 += Mathf.Max(0f, brokenArmAttackStaminaPenalty.Value); } return Mathf.Max(1f, num2); } internal float GetRunStaminaMultiplier() { float num = state.GetAverageLegInjury() / 100f; return Mathf.Max(1f, 1f + num * Mathf.Max(0f, legInjuryRunStaminaPenalty.Value)); } internal float GetJumpStaminaMultiplier() { float num = state.GetAverageLegInjury() / 100f; return Mathf.Max(1f, 1f + num * Mathf.Max(0f, legInjuryJumpStaminaPenalty.Value)); } internal float GetStaminaRegenMultiplier() { float num = (state.Head + state.Torso) / 200f * Mathf.Clamp01(headTorsoStaminaRegenPenalty.Value); float num2 = state.Infection / 100f * Mathf.Clamp01(infectionStaminaRegenPenalty.Value); float num3 = Mathf.Clamp(minimumStaminaRegenMultiplier.Value, 0.1f, 1f); return Mathf.Clamp(1f - num - num2, num3, 1f); } internal void RecordAppliedDamage(Player player, HitData hit, float healthBefore) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Invalid comparison between Unknown and I4 if (!IsActiveFor(player) || hit == null) { return; } float num = Mathf.Max(0f, healthBefore - ((Character)player).GetHealth()); localDamageHookCalls++; lastDetectedHealthLoss = num; lastDetectedHitType = hit.m_hitType; if (verboseLogging.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Damage hook: health loss=" + num.ToString("0.0") + ", type=" + ((object)Unsafe.As<HitType, HitType>(ref hit.m_hitType)/*cast due to .constrained prefix*/).ToString() + ", threshold=" + minimumDamageForInjury.Value.ToString("0.0"))); } if (!(num < Mathf.Max(0f, minimumDamageForInjury.Value)) && !ShouldIgnoreInjuryHit(hit.m_hitType)) { float num2 = num * Mathf.Max(0f, injuryPerHealthLost.Value); if ((int)hit.m_hitType == 3) { num2 *= Mathf.Max(0f, fallInjuryMultiplier.Value); state.Add(Limb.LeftLeg, num2 * 0.5f); state.Add(Limb.RightLeg, num2 * 0.5f); } else { state.Add(ResolveHitLimb(player, hit), num2); } float bleedingAdded = ApplyBleedingFromHit(hit, num); state.ClampAll(); TrySpawnHitBlood(player, hit, num, bleedingAdded); TryPlayHitAudio(hit); injuryEventsRecorded++; SaveState(player); ShowMessage(BuildDamageMessage(num)); if (verboseLogging.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Applied damage " + num.ToString("0.0") + ", hitType=" + ((object)Unsafe.As<HitType, HitType>(ref hit.m_hitType)/*cast due to .constrained prefix*/).ToString() + ", injuries=" + state.ToDiagnosticText())); } } } private void TickInjuries(Player player, float elapsedSeconds) { if (((Character)player).IsDead()) { state.Bleeding = 0f; return; } ProcessBleeding(player, elapsedSeconds); ProcessInfection(player, elapsedSeconds); ProcessRecovery(player, elapsedSeconds); state.ClampAll(); if (verboseLogging.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Tick: " + state.ToDiagnosticText())); } } private void ProcessBleeding(Player player, float elapsedSeconds) { if (!(state.Bleeding <= 0f)) { float healthLoss = state.Bleeding / 100f * Mathf.Max(0f, bleedingDamageAt100PerSecond.Value) * elapsedSeconds; ApplyNonLethalHealthLoss(player, healthLoss); float num = Mathf.Max(0f, naturalClottingPerSecond.Value) * elapsedSeconds; if (player.InShelter() && !IsWet(player)) { num *= 2f; } state.Bleeding = Mathf.Max(0f, state.Bleeding - num); } } private void ProcessInfection(Player player, float elapsedSeconds) { bool flag = IsWet(player); bool flag2 = state.Bleeding >= 5f || state.GetAverageLimbInjury() >= 35f || state.Torso >= 35f; bool flag3 = UpdateColdWaterRinse(player, elapsedSeconds); if (flag2 && state.Infection <= 0f && !flag3) { float num = Mathf.Max(0f, infectionRiskPerSecond.Value) * elapsedSeconds; if (flag) { num *= Mathf.Max(1f, wetInfectionRiskMultiplier.Value); } if (player.InShelter()) { num *= 0.5f; } state.InfectionRisk += num; if (state.InfectionRisk >= 100f) { state.InfectionRisk = 0f; state.Infection = Mathf.Max(state.Infection, Mathf.Clamp(infectionOnsetSeverity.Value, 1f, 100f)); ShowMessage("An untreated wound has become infected."); } } else if (!flag2 && state.Infection <= 0f) { state.InfectionRisk = Mathf.Max(0f, state.InfectionRisk - elapsedSeconds * 0.25f); } if (!(state.Infection <= 0f)) { if (((Character)player).InBed() && player.InShelter() && !flag && state.Bleeding <= 0.01f) { state.Infection = Mathf.Max(0f, state.Infection - Mathf.Max(0f, infectionRecoveryInBedPerSecond.Value) * elapsedSeconds); return; } state.Infection += Mathf.Max(0f, infectionGrowthPerSecond.Value) * elapsedSeconds; float healthLoss = state.Infection / 100f * Mathf.Max(0f, infectionDamageAt100PerSecond.Value) * elapsedSeconds; ApplyNonLethalHealthLoss(player, healthLoss); } } private bool UpdateColdWaterRinse(Player player, float elapsedSeconds) { if (!enableSwimmingRinse.Value || (Object)(object)player == (Object)null || state.Infection > 0.01f) { swimmingRinseTimer = 0f; return false; } if (!((Character)player).IsSwimming() || !(state.Bleeding <= 0.01f) || !(state.InfectionRisk > 0.01f)) { swimmingRinseTimer = 0f; return false; } swimmingRinseTimer += elapsedSeconds; if (swimmingRinseTimer >= Mathf.Max(1f, swimmingRinseRequiredSeconds.Value)) { state.InfectionRisk = 0f; swimmingRinseTimer = 0f; ShowMessage("Cold water has rinsed the infection risk. Dry off and bandage the wound."); return false; } return true; } private void ProcessRecovery(Player player, float elapsedSeconds) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) if (state.Bleeding > 0.01f || state.Infection > 0.01f || IsWet(player) || !player.InShelter()) { return; } bool flag = ((Character)player).InBed(); Vector3 velocity = ((Character)player).GetVelocity(); bool flag2 = ((Vector3)(ref velocity)).magnitude <= Mathf.Max(0.01f, recoveryStillSpeedLimit.Value); if (flag || flag2) { float num = Mathf.Max(0f, shelterRecoveryPerSecond.Value) * elapsedSeconds; if (flag) { num *= Mathf.Max(1f, bedRecoveryMultiplier.Value); } state.ReduceAllInjuries(num); } } private float ApplyBleedingFromHit(HitData hit, float actualHealthLoss) { if (Mathf.Max(0f, hit.m_damage.m_slash) + Mathf.Max(0f, hit.m_damage.m_pierce) + Mathf.Max(0f, hit.m_damage.m_chop) <= 0f || actualHealthLoss < Mathf.Max(0f, physicalBleedingThreshold.Value)) { return 0f; } float num = (actualHealthLoss - Mathf.Max(0f, physicalBleedingThreshold.Value)) * Mathf.Max(0f, bleedingPerHealthLost.Value); state.Bleeding += num; return num; } private void UpdateBleedingTrail(Player player, float deltaSeconds) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) if (!enableBleedingVisuals.Value || !enableBleedingTrail.Value || (Object)(object)player == (Object)null || ((Character)player).IsSwimming()) { bleedingTrailTimer = 0f; return; } if (state.Bleeding < Mathf.Max(0f, trailMinimumBleeding.Value)) { bleedingTrailTimer = 0f; return; } Vector3 velocity = ((Character)player).GetVelocity(); velocity.y = 0f; if (((Vector3)(ref velocity)).sqrMagnitude <= 0.1f) { return; } float num = (((Character)player).IsRunning() ? Mathf.Max(0.1f, runningTrailIntervalSeconds.Value) : Mathf.Max(0.1f, walkingTrailIntervalSeconds.Value)); bleedingTrailTimer += deltaSeconds; if (!(bleedingTrailTimer < num)) { bleedingTrailTimer = 0f; trailBloodAttempts++; Vector3 val = ((Character)player).GetCenterPoint() - Vector3.up * 0.18f; Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(Random.Range(-0.12f, 0.12f), 0f, Random.Range(-0.12f, 0.12f)); bool flag = TryPlaceBloodOnGround(player, val + val2, trailDrop: true); if (flag) { directTrailSplatsSpawned++; } SpawnBloodDroplet(((Component)player).transform, val + val2, val2 * 1.25f + Vector3.up * 0.35f, 0.04f, 0.72f, trailDrop: false, !flag); trailBloodDropletsSpawned++; } } private void UpdateBleedingDrips(Player player, float deltaSeconds) { //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) if (!enableBleedingVisuals.Value || (Object)(object)player == (Object)null || ((Character)player).IsSwimming() || state.Bleeding <= 0.01f) { bleedDripTimer = 0f; return; } float num = Mathf.InverseLerp(0f, 100f, state.Bleeding); float num2 = Mathf.Lerp(0.72f, 0.4f, num); bleedDripTimer += deltaSeconds; if (bleedDripTimer < num2) { return; } bleedDripTimer = 0f; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(Random.Range(-0.13f, 0.13f), 0f, Random.Range(-0.13f, 0.13f)); Vector3 val2 = ((Character)player).GetCenterPoint() - Vector3.up * Random.Range(0.16f, 0.42f) + val; Vector3 velocity = ((Character)player).GetVelocity(); velocity.y = 0f; bool flag = TryPlaceBloodOnGround(player, val2, trailDrop: true); if (flag) { directTrailSplatsSpawned++; } if (num >= 0.45f) { Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(Random.Range(-0.2f, 0.2f), 0f, Random.Range(-0.2f, 0.2f)); if (TryPlaceBloodOnGround(player, val2 + val3, trailDrop: true)) { directTrailSplatsSpawned++; } } SpawnBloodDroplet(((Component)player).transform, val2, velocity * 0.16f + val * 0.7f + Vector3.up * Random.Range(0.08f, 0.26f), Mathf.Lerp(0.045f, 0.07f, num), 1.5f, trailDrop: true, !flag); trailBloodDropletsSpawned++; } private void TrySpawnHitBlood(Player player, HitData hit, float actualHealthLoss, float bleedingAdded) { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) if (!enableBleedingVisuals.Value || !spawnBloodFromSharpHits.Value || (Object)(object)player == (Object)null || hit == null || Mathf.Max(0f, hit.m_damage.m_slash) + Mathf.Max(0f, hit.m_damage.m_pierce) + Mathf.Max(0f, hit.m_damage.m_chop) <= 0f || actualHealthLoss < Mathf.Max(0f, visibleBloodMinimumHealthLoss.Value)) { return; } hitBloodAttempts++; Vector3 val = ResolvePlayerImpactPoint(player, hit); Vector3 val2 = ResolveOutwardBloodDirection(player, hit, val); float num = Mathf.Clamp01((actualHealthLoss - visibleBloodMinimumHealthLoss.Value) / 12f); bool flag = actualHealthLoss >= 6f || bleedingAdded > 0.01f; int num2 = Mathf.Clamp(maximumHitBloodDroplets.Value, 4, 22); int num3 = 5 + Mathf.RoundToInt(Mathf.Lerp(2f, (float)num2 - 5f, num)); if (bleedingAdded > 0.01f) { num3 += 2; } if (flag) { num3 += 2; } num3 = Mathf.Clamp(num3, 5, num2); TryPlaceBloodOnGround(player, val + val2 * Random.Range(0.25f, 0.48f), trailDrop: false); if (flag) { Vector3 val3 = Vector3.Cross(Vector3.up, val2); Vector3 normalized = ((Vector3)(ref val3)).normalized; TryPlaceBloodOnGround(player, val + val2 * Random.Range(0.42f, 0.72f) + normalized * Random.Range(-0.22f, 0.22f), trailDrop: false); } SpawnHitImpactSprite(val, val2, num); for (int i = 0; i < num3; i++) { float num4 = (flag ? 0.72f : 0.52f); Vector3 val4 = val2 + new Vector3(Random.Range(0f - num4, num4), Random.Range(-0.05f, 0.32f), Random.Range(0f - num4, num4)); if (((Vector3)(ref val4)).sqrMagnitude < 0.01f) { val4 = ((Component)player).transform.forward; } ((Vector3)(ref val4)).Normalize(); float num5 = (flag ? Random.Range(2.7f, 5.1f) : Random.Range(2f, 4f)); Vector3 initialVelocity = val4 * num5 + Vector3.up * Random.Range(1.7f, flag ? 3.85f : 3.1f); float size = (flag ? Random.Range(0.04f, 0.082f) : Random.Range(0.034f, 0.066f)); SpawnBloodDroplet(((Component)player).transform, val, initialVelocity, size, 1.8f, trailDrop: false, createSplatWhenLanding: true); hitBloodDropletsSpawned++; } } private static Vector3 ResolvePlayerImpactPoint(Player player, HitData hit) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) Vector3 centerPoint = ((Character)player).GetCenterPoint(); Vector3 val = hit?.m_point ?? Vector3.zero; if (!(((Vector3)(ref val)).sqrMagnitude < 0.0001f)) { Vector3 val2 = val - centerPoint; if (!(((Vector3)(ref val2)).sqrMagnitude > 9f)) { goto IL_003e; } } val = centerPoint; goto IL_003e; IL_003e: return val + Vector3.up * 0.035f; } private static Vector3 ResolveOutwardBloodDirection(Player player, HitData hit, Vector3 impactPoint) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) Vector3 val = hit?.m_dir ?? Vector3.zero; if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = ((Component)player).transform.forward; } ((Vector3)(ref val)).Normalize(); Vector3 val2 = impactPoint - ((Character)player).GetCenterPoint(); val2.y *= 0.55f; if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f) { val2 = val; } else { ((Vector3)(ref val2)).Normalize(); if (Vector3.Dot(val2, val) < 0f) { val2 = -val2; } } Vector3 val3 = val * 0.78f + val2 * 0.32f + Vector3.up * 0.08f; if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f) { val3 = ((Component)player).transform.forward; } val3.y = Mathf.Clamp(val3.y, -0.1f, 0.38f); return ((Vector3)(ref val3)).normalized; } private void SpawnHitImpactSprite(Vector3 source, Vector3 direction, float severity) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) if (!enableHitImpactSprites.Value || impactSpriteMaterials.Count == 0) { return; } EnsureBloodVisualRoot(); Camera main = Camera.main; if (cameraSafeHitSprites.Value && (Object)(object)main != (Object)null) { Vector3 val = source - ((Component)main).transform.position; if (((Vector3)(ref val)).sqrMagnitude < 0.48f) { return; } } GameObject obj = GameObject.CreatePrimitive((PrimitiveType)5); ((Object)obj).name = "YoureInjured_HitBloodSprite"; obj.transform.SetParent(bloodVisualRoot, true); obj.transform.position = source + direction * 0.045f; obj.transform.localScale = Vector3.one * Mathf.Lerp(0.2f, Mathf.Max(0.2f, hitImpactSpriteMaximumSize.Value), severity); Collider component = obj.GetComponent<Collider>(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } Renderer component2 = obj.GetComponent<Renderer>(); if ((Object)(object)component2 != (Object)null) { component2.sharedMaterial = impactSpriteMaterials[Random.Range(0, impactSpriteMaterials.Count)]; component2.shadowCastingMode = (ShadowCastingMode)0; component2.receiveShadows = false; } obj.AddComponent<BloodImpactSprite>().Initialize(direction * Mathf.Lerp(0.45f, 1.1f, severity), Mathf.Clamp(hitImpactSpriteLifetime.Value, 0.06f, 0.3f), component2); } private void SpawnBloodDroplet(Transform owner, Vector3 source, Vector3 initialVelocity, float size, float lifetime, bool trailDrop, bool createSplatWhenLanding) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) if (enableBleedingVisuals.Value) { EnsureBloodVisualRoot(); bool flag = trailDrop && dripSpriteMaterials.Count > 0; GameObject val = GameObject.CreatePrimitive((PrimitiveType)(flag ? 5 : 0)); ((Object)val).name = (flag ? "YoureInjured_BloodDripSprite" : "YoureInjured_BloodDroplet"); val.transform.SetParent(bloodVisualRoot, true); val.transform.position = source; val.transform.localScale = (Vector3)(flag ? new Vector3(Mathf.Max(0.026f, size * 2.5f), Mathf.Max(0.026f, size * 2.5f), 1f) : (Vector3.one * Mathf.Max(0.018f, size))); Camera main = Camera.main; if (flag && (Object)(object)main != (Object)null) { val.transform.rotation = ((Component)main).transform.rotation; } Collider component = val.GetComponent<Collider>(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } Renderer component2 = val.GetComponent<Renderer>(); if ((Object)(object)component2 != (Object)null) { component2.sharedMaterial = (flag ? dripSpriteMaterials[Random.Range(0, dripSpriteMaterials.Count)] : GetBloodDropMaterial()); component2.shadowCastingMode = (ShadowCastingMode)0; component2.receiveShadows = false; } val.AddComponent<BloodDroplet>().Initialize(this, owner, initialVelocity, Mathf.Max(0.2f, lifetime), Mathf.Max(1f, bloodDropletGravity.Value), trailDrop, createSplatWhenLanding); } } internal void LandBloodDroplet(Vector3 point, Vector3 normal, bool trailDrop) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (!(normal.y < 0.18f)) { CreateGroundBloodSplat(point, ((Vector3)(ref normal)).normalized, trailDrop); } } internal bool TryLandBloodAtFallback(Transform owner, Vector3 source, bool trailDrop) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)owner == (Object)null || (Object)(object)owner != (Object)(object)((Component)localPlayer).transform) { return false; } bool num = TryPlaceBloodOnGround(localPlayer, source, trailDrop); if (num) { dropletFallbackLandings++; } return num; } private bool TryPlaceBloodOnGround(Player player, Vector3 source, bool trailDrop) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (!TryFindGroundBelow(player, source, out var point, out var normal)) { groundProbeFailures++; return false; } groundProbeSuccesses++; CreateGroundBloodSplat(point, normal, trailDrop); return true; } private bool TryFindGroundBelow(Player player, Vector3 source, out Vector3 point, out Vector3 normal) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) point = Vector3.zero; normal = Vector3.up; if ((Object)(object)player == (Object)null) { return false; } RaycastHit[] array = Physics.RaycastAll(source + Vector3.up * 1.8f, Vector3.down, 7f, -1, (QueryTriggerInteraction)1); float num = float.MaxValue; Vector3 val; for (int i = 0; i < array.Length; i++) { Collider collider = ((RaycastHit)(ref array[i])).collider; if (!((Object)(object)collider == (Object)null) && !((Component)collider).transform.IsChildOf(((Component)player).transform) && !(((RaycastHit)(ref array[i])).normal.y < 0.18f) && !(((RaycastHit)(ref array[i])).distance >= num)) { num = ((RaycastHit)(ref array[i])).distance; point = ((RaycastHit)(ref array[i])).point; val = ((RaycastHit)(ref array[i])).normal; normal = ((Vector3)(ref val)).normalized; } } if (num < float.MaxValue) { return true; } Collider lastGroundCollider = ((Character)player).GetLastGroundCollider(); Vector3 lastGroundNormal = ((Character)player).GetLastGroundNormal(); if ((Object)(object)lastGroundCollider != (Object)null && lastGroundNormal.y >= 0.18f) { Vector3 val2 = lastGroundCollider.ClosestPoint(((Component)player).transform.position + Vector3.up * 0.3f); val = val2 - ((Component)player).transform.position; if (((Vector3)(ref val)).sqrMagnitude <= 36f) { point = val2; normal = ((Vector3)(ref lastGroundNormal)).normalized; return true; } } return false; } private void CreateGroundBloodSplat(Vector3 point, Vector3 normal, bool trailDrop) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) if (!enableBleedingVisuals.Value) { return; } CleanupDeadBloodSplats(); int num = Mathf.Max(10, maximumGroundBloodSplats.Value); while (activeGroundBlood.Count >= num) { GroundBloodSplat groundBloodSplat = activeGroundBlood[0]; activeGroundBlood.RemoveAt(0); if ((Object)(object)groundBloodSplat != (Object)null) { Object.Destroy((Object)(object)((Component)groundBloodSplat).gameObject); } } EnsureBloodVisualRoot(); GameObject val = new GameObject("YoureInjured_LiquidGroundBlood"); val.transform.SetParent(bloodVisualRoot, true); val.transform.position = point + normal * 0.011f; val.transform.rotation = Quaternion.FromToRotation(Vector3.up, normal); float num2 = Mathf.Max(0.03f, bloodSplatMinimumSize.Value); float num3 = Mathf.Max(num2, bloodSplatMaximumSize.Value); float num4 = (trailDrop ? Random.Range(Mathf.Lerp(num2, num3, 0.25f), Mathf.Lerp(num2, num3, 0.76f)) : Random.Range(Mathf.Lerp(num2, num3, 0.5f), num3)); float aspect = (trailDrop ? Random.Range(0.55f, 2.25f) : Random.Range(0.72f, 1.95f)); float yaw = Random.Range(0f, 360f); List<Mesh> list = new List<Mesh>(); CreateBloodDecalMesh(val.transform, "YoureInjured_LiquidBloodPool", Vector3.zero, num4, aspect, yaw, 4, 0f, GetBloodLiquidMaterial(Random.Range(0, 7)), list); int num5 = (trailDrop ? Random.Range(1, 4) : Random.Range(2, 5)); for (int i = 0; i < num5; i++) { float num6 = Random.Range(0f, (float)Math.PI * 2f); Vector3 val2 = new Vector3(Mathf.Cos(num6), 0f, Mathf.Sin(num6)); float num7 = num4 * Random.Range(0.48f, trailDrop ? 0.82f : 1.2f); Vector3 localPosition = val2 * num7 + Vector3.up * 0.0015f; CreateBloodDecalMesh(val.transform, "YoureInjured_LiquidBloodDrop", localPosition, num4 * Random.Range(0.11f, 0.28f), Random.Range(0.5f, 1.75f), Random.Range(0f, 360f), 4, 0f, GetBloodLiquidMaterial(Random.Range(0, 7)), list); } GroundBloodSplat groundBloodSplat2 = val.AddComponent<GroundBloodSplat>(); groundBloodSplat2.Initialize(this, Mathf.Max(5f, groundBloodLifetimeSeconds.Value), Mathf.Clamp(bloodLiquidSpreadSeconds.Value, 0.1f, 2f), list); activeGroundBlood.Add(groundBloodSplat2); groundBloodSplatsSpawned++; } private static void CreateBloodDecalMesh(Transform parent, string name, Vector3 localPosition, float diameter, float aspect, float yaw, int edgeCount, float irregularity, Material material, List<Mesh> ownedMeshes) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); val.transform.localPosition = localPosition; val.transform.localRotation = Quaternion.AngleAxis(yaw, Vector3.up); val.transform.localScale = new Vector3(Mathf.Max(0.01f, diameter * aspect), 1f, Mathf.Max(0.01f, diameter / Mathf.Max(0.05f, aspect))); MeshFilter val2 = val.AddComponent<MeshFilter>(); MeshRenderer obj = val.AddComponent<MeshRenderer>(); Mesh item = (val2.sharedMesh = BuildIrregularBloodMesh(edgeCount, irregularity)); ((Renderer)obj).sharedMaterial = material; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; ownedMeshes?.Add(item); } private static Mesh BuildIrregularBloodMesh(int requestedEdgeCount, float irregularity) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Expected O, but got Unknown Vector3[] vertices = (Vector3[])(object)new Vector3[4] { new Vector3(-0.5f, 0f, -0.5f), new Vector3(-0.5f, 0f, 0.5f), new Vector3(0.5f, 0f, 0.5f), new Vector3(0.5f, 0f, -0.5f) }; Vector3[] normals = (Vector3[])(object)new Vector3[4] { Vector3.up, Vector3.up, Vector3.up, Vector3.up }; Vector2[] uv = (Vector2[])(object)new Vector2[4] { new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(1f, 0f) }; int[] triangles = new int[6] { 0, 1, 2, 0, 2, 3 }; Mesh val = new Mesh { name = "YoureInjured_LiquidBloodDecalQuad", vertices = vertices, normals = normals, uv = uv, triangles = triangles }; val.RecalculateBounds(); return val; } internal void UnregisterGroundBlood(GroundBloodSplat splat) { activeGroundBlood.Remove(splat); } private void CleanupDeadBloodSplats() { for (int num = activeGroundBlood.Count - 1; num >= 0; num--) { if ((Object)(object)activeGroundBlood[num] == (Object)null) { activeGroundBlood.RemoveAt(num); } } } private void EnsureBloodVisualRoot() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown if (!((Object)(object)bloodVisualRoot != (Object)null)) { GameObject val = new GameObject("YoureInjured_BloodVisuals"); bloodVisualRoot = val.transform; } } private void LoadExternalImpactSprites() { string text = Path.Combine(pluginDirectory ?? string.Empty, "assets", "bleeding", "impact_frames"); if (!Directory.Exists(text)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Injured: no impact-sprite folder found at " + text + ". Hit droplets will still work.")); return; } string[] files; try { files = Directory.GetFiles(text, "*.png", SearchOption.TopDirectoryOnly); Array.Sort(files, (IComparer<string>?)StringComparer.OrdinalIgnoreCase); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Injured: could not enumerate impact sprite files. " + ex.Message)); return; } int num = Mathf.Clamp(maximumImpactSpriteTextures.Value, 1, 12); for (int i = 0; i < files.Length; i++) { if (impactSpriteTextures.Count >= num) { break; } if (!InjuryAssetLoader.TryLoadAlphaMaskPng(files[i], out var texture, out var error)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Injured: skipped impact sprite " + Path.GetFileName(files[i]) + ". " + error)); continue; } ((Object)texture).name = "YoureInjured_ImpactSprite_" + Path.GetFileNameWithoutExtension(files[i]); impactSpriteTextures.Add(texture); impactSpriteMaterials.Add(CreateImpactSpriteMaterial(texture)); } string path = Path.Combine(pluginDirectory ?? string.Empty, "assets", "bleeding", "drip_frames"); if (Directory.Exists(path)) { try { string[] files2 = Directory.GetFiles(path, "*.png", SearchOption.TopDirectoryOnly); Array.Sort(files2, (IComparer<string>?)StringComparer.OrdinalIgnoreCase); for (int j = 0; j < files2.Length; j++) { if (dripSpriteTextures.Count >= 4) { break; } if (!InjuryAssetLoader.TryLoadAlphaMaskPng(files2[j], out var texture2, out var error2)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Injured: skipped drip sprite " + Path.GetFileName(files2[j]) + ". " + error2)); continue; } ((Object)texture2).name = "YoureInjured_DripSprite_" + Path.GetFileNameWithoutExtension(files2[j]); dripSpriteTextures.Add(texture2); dripSpriteMaterials.Add(CreateImpactSpriteMaterial(texture2)); } } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Injured: could not enumerate drip sprite files. " + ex2.Message)); } } if (impactSpriteMaterials.Count > 0 || dripSpriteMaterials.Count > 0) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("You're Injured: loaded " + impactSpriteMaterials.Count + " camera-safe impact sprites and " + dripSpriteMaterials.Count + " falling drip sprites.")); } } private static Material CreateImpactSpriteMaterial(Texture2D texture) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) Shader val = Shader.Find("Unlit/Transparent"); if ((Object)(object)val == (Object)null) { val = Shader.Find("Sprites/Default"); } if ((Object)(object)val == (Object)null) { val = Shader.Find("Legacy Shaders/Transparent/Diffuse"); } Material val2 = new Material(val); val2.mainTexture = (Texture)(object)texture; if (val2.HasProperty("_Color")) { val2.SetColor("_Color", new Color(0.4f, 0.01f, 0.016f, 0.78f)); } val2.renderQueue = 3002; return val2; } private IEnumerator LoadHitAudioFiles() { yield return ((MonoBehaviour)this).StartCoroutine(LoadExternalMp3(Path.Combine(pluginDirectory ?? string.Empty, "assets", "audio", axeHitAudioFile.Value.Trim()), delegate(object clip) { axeHitAudioClip = clip; }, "axe hit")); yield return ((MonoBehaviour)this).StartCoroutine(LoadExternalMp3(Path.Combine(pluginDirectory ?? string.Empty, "assets", "audio", swordHitAudioFile.Value.Trim()), delegate(object clip) { swordHitAudioClip = clip; }, "sword hit")); yield return ((MonoBehaviour)this).StartCoroutine(LoadExternalMp3(Path.Combine(pluginDirectory ?? string.Empty, "assets", "audio", arrowHitAudioFile.Value.Trim()), delegate(object clip) { arrowHitAudioClip = clip; }, "arrow hit")); yield return ((MonoBehaviour)this).StartCoroutine(LoadExternalMp3(Path.Combine(pluginDirectory ?? string.Empty, "assets", "audio", bandageAudioFile.Value.Trim()), delegate(object clip) { bandageAudioClip = clip; }, "bandage wrap")); } private IEnumerator LoadExternalMp3(string path, Action<object> onLoaded, string label) { object request; object operation; if (string.IsNullOrEmpty(path) || !File.Exists(path)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Injured: " + label + " audio file was not found at " + path)); } else if (TryBeginExternalMp3Request(path, label, out request, out operation)) { yield return operation; CompleteExternalMp3Request(request, onLoaded, label); } } private bool TryBeginExternalMp3Request(string path, string label, out object request, out object operation) { request = null; operation = null; try { Type type = FindRuntimeType("UnityEngine.Networking.UnityWebRequestMultimedia"); if (type == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Injured: UnityWebRequestMultimedia was unavailable; could not load " + label + " audio.")); return false; } MethodInfo methodInfo = null; MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public); foreach (MethodInfo methodInfo2 in methods) { if (methodInfo2.Name == "GetAudioClip" && methodInfo2.GetParameters().Length == 2) { methodInfo = methodInfo2; break; } } if (methodInfo == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Injured: no compatible GetAudioClip method was found for " + label + " audio.")); return false; } object obj = Enum.Parse(methodInfo.GetParameters()[1].ParameterType, "MPEG"); request = methodInfo.Invoke(null, new object[2] { new Uri(path).AbsoluteUri, obj }); if (request == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Injured: could not create the request for " + label + " audio.")); return false; } MethodInfo method = request.GetType().GetMethod("SendWebRequest", Type.EmptyTypes); if (method == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Injured: no SendWebRequest method was found for " + label + " audio.")); DisposeRequest(request); request = null; return false; } operation = method.Invoke(request, null); if (operation == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Injured: SendWebRequest returned no operation for " + label + " audio.")); DisposeRequest(request); request = null; return false; } return true; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Injured: could not start loading " + label + " audio. " + ex.Message)); DisposeRequest(request); request = null; operation = null; return false; } } private void CompleteExternalMp3Request(object request, Action<object> onLoaded, string label) { try { if (request == null) { return; } PropertyInfo property = request.GetType().GetProperty("error", BindingFlags.Instance | BindingFlags.Public); string text = ((property != null) ? (property.GetValue(request, null) as string) : null); if (!string.IsNullOrEmpty(text)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Injured: failed to load " + label + " audio. " + text)); return; } PropertyInfo property2 = request.GetType().GetProperty("downloadHandler", BindingFlags.Instance | BindingFlags.Public); object obj = ((property2 != null) ? property2.GetValue(request, null) : null); PropertyInfo propertyInfo = obj?.GetType().GetProperty("audioClip", BindingFlags.Instance | BindingFlags.Public); object obj2 = ((propertyInfo != null) ? propertyInfo.GetValue(obj, null) : null); if (obj2 == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Injured: the " + label + " MP3 decoded without an AudioClip.")); return; } onLoaded?.Invoke(obj2); ((BaseUnityPlugin)this).Logger.LogInfo((object)("You're Injured: loaded " + label + " audio from " + Path.GetFileName(GetRequestUrl(request)) + ".")); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Injured: could not finish loading " + label + " audio. " + ex.Message)); } finally { DisposeRequest(request); } } private static string GetRequestUrl(object request) { if (request == null) { return string.Empty; } try { PropertyInfo property = request.GetType().GetProperty("url", BindingFlags.Instance | BindingFlags.Public); string text = ((property != null) ? (property.GetValue(request, null) as string) : null); return string.IsNullOrEmpty(text) ? string.Empty : text; } catch { return string.Empty; } } private static void DisposeRequest(object request) { if (request is IDisposable disposable) { disposable.Dispose(); } } private void TryPlayBandageAudio() { if (enableBandageAudio != null && enableBandageAudio.Value && bandageAudioClip != null) { TryPlayOneShot(bandageAudioClip, Mathf.Clamp01(bandageAudioVolume.Value)); } } private void TryPlayHitAudio(HitData hit) { if (enableHitAudio == null || !enableHitAudio.Value || hit == null) { return; } HitSoundKind hitSoundKind = ResolveHitSoundKind(hit); if (hitSoundKind != HitSoundKind.None && !(Time.unscaledTime < nextAllowedRecognizedHitAudioTime)) { object obj = null; switch (hitSoundKind) { case HitSoundKind.Axe: obj = axeHitAudioClip; break; case HitSoundKind.Arrow: obj = arrowHitAudioClip; break; case HitSoundKind.Sword: obj = swordHitAudioClip; break; } if (obj != null && TryPlayOneShot(obj, Mathf.Clamp01(hitAudioVolume.Value))) { float num = ((hitAudioCooldownSeconds == null) ? 0.18f : hitAudioCooldownSeconds.Value); nextAllowedRecognizedHitAudioTime = Time.unscaledTime + Mathf.Clamp(num, 0.05f, 1f); } } } private HitSoundKind ResolveHitSoundKind(HitData hit) { string text = ResolveHitAttackerName(hit).ToLowerInvariant(); string text2 = ResolveHitSkillName(hit).ToLowerInvariant(); if (text.Contains("arrow") || text.Contains("bow") || text2.Contains("bow")) { return HitSoundKind.Arrow; } if (text.Contains("draugr") && !text.Contains("elite")) { return HitSoundKind.Axe; } if (text.Contains("draugr_elite") || text.Contains("draugr elite") || text.Contains("skeleton")) { return HitSoundKind.Sword; } return HitSoundKind.None; } private static string ResolveHitAttackerName(HitData hit) { object hitAttackerObject = GetHitAttackerObject(hit); if (hitAttackerObject == null) { return string.Empty; } GameObject val = ResolveAttackerGameObject(hitAttackerObject); if ((Object)(object)val != (Object)null) { string obj = ((Object)val).name ?? string.Empty; Transform val2 = (((Object)(object)val.transform != (Object)null) ? val.transform.root : null); string text = (((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).gameObject != (Object)null) ? ((Object)((Component)val2).gameObject).name : string.Empty); return obj + " " + text; } return string.Empty; } private static object GetHitAttackerObject(HitData hit) { try { MethodInfo method = ((object)hit).GetType().GetMethod("GetAttacker", BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null); return (method != null) ? method.Invoke(hit, null) : null; } catch { return null; } } private static GameObject ResolveAttackerGameObject(object attacker) { GameObject val = (GameObject)((attacker is GameObject) ? attacker : null); if ((Object)(object)val != (Object)null) { return val; } Component val2 = (Component)((attacker is Component) ? attacker : null); if ((Object)(object)val2 != (Object)null) { return val2.gameObject; } try { Type typeFromHandle = typeof(ZNetScene); FieldInfo field = typeFromHandle.GetField("instance", BindingFlags.Static | BindingFlags.Public); object obj = ((field != null) ? field.GetValue(null) : null); if (obj == null) { PropertyInfo property = typeFromHandle.GetProperty("instance", BindingFlags.Static | BindingFlags.Public); obj = ((property != null) ? property.GetValue(null, null) : null); } if (obj == null) { return null; } MethodInfo[] methods = obj.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name != "FindInstance") { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length == 1 && parameters[0].ParameterType.IsInstanceOfType(attacker)) { object obj2 = methodInfo.Invoke(obj, new object[1] { attacker }); GameObject val3 = (GameObject)((obj2 is GameObject) ? obj2 : null); if ((Object)(object)val3 != (Object)null) { return val3; } Component val4 = (Component)((obj2 is Component) ? obj2 : null); if ((Object)(object)val4 != (Object)null) { return val4.gameObject; } } } } catch { } return null; } private static string ResolveHitSkillName(HitData hit) { try { FieldInfo field = ((object)hit).GetType().GetField("m_skill", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); object obj = ((field != null) ? field.GetValue(hit) : null); return (obj != null) ? obj.ToString() : string.Empty; } catch { return string.Empty; } } private bool TryPlayOneShot(object clip, float volume) { if (clip == null) { return false; } Component val = EnsureHitAudioSource(); if ((Object)(object)val == (Object)null) { return false; } try { MethodInfo[] methods = ((object)val).GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name == "PlayOneShot" && methodInfo.GetParameters().Length == 2) { methodInfo.Invoke(val, new object[2] { clip, volume }); return true; } } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("You're Injured: failed to play external audio. " + ex.Message)); } return false; } private Component EnsureHitAudioSource() { if ((Object)(object)hitAudioSource != (Object)null) { return hitAudioSource; } Type type = FindRuntimeType("UnityEngine.AudioSource"); if (type == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"You're Injured: Unity AudioSource was unavailable."); return null; } hitAudioSource = ((Component)this).gameObject.GetComponent(type); if ((Object)(object)hitAudioSource == (Object)null) { hitAudioSource = ((Component)this).gameObject.AddComponent(type); } if ((Object)(object)hitAudioSource != (Object)null) { SetAudioProperty(hitAudioSource, "playOnAwake", false); SetAudioProperty(hitAudioSource, "spatialBlend", 0f); SetAudioProperty(hitAudioSource, "loop", false); } return hitAudioSource; } private static void SetAudioProperty(Component source, string name, object value) { if (!((Object)(object)source == (Object)null)) { PropertyInfo property = ((object)source).GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.Public); if (property != null && property.CanWrite) { property.SetValue(source, value, null); } } } private static Type FindRuntimeType(string fullName) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { Type type = assemblies[i].GetType(fullName, throwOnError: false); if (type != null) { return type; } } string text = null; if (string.Equals(fullName, "UnityEngine.AudioSource", StringComparison.Ordinal)) { text = "UnityEngine.AudioModule"; } else if (fullName.StartsWith("UnityEngine.Networking.", StringComparison.Ordinal)) { text = "UnityEngine.UnityWebRequestAudioModule"; } if (!string.IsNullOrEmpty(text)) { try { Assembly assembly = Assembly.Load(text); Type type2 = ((assembly != null) ? assembly.GetType(fullName, throwOnError: false) : null); if (type2 != null) { return type2; } } catch { } } return null; } private Material GetBloodDropMaterial() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)bloodDropMaterial == (Object)null) { bloodDropMaterial = CreateBloodMaterial(new Color(0.38f, 0.003f, 0.008f, 1f), 0.62f, transparent: false, 0.006f); } return bloodDropMaterial; } private Material GetBloodLiquidMaterial(int requestedVariant) { EnsureBloodLiquidMaterials(); if (bloodLiquidMaterials == null || bloodLiquidMaterials.Length == 0) { return GetBloodDropMaterial(); } int num = Mathf.Abs(requestedVariant) % bloodLiquidMaterials.Length; return bloodLiquidMaterials[num]; } private void EnsureBloodLiquidMaterials() { if (bloodLiquidMaterials == null || bloodLiquidMaterials.Length != 7) { DestroyBloodLiquidMaterials(); bloodLiquidMaterials = (Material[])(object)new Material[7]; bloodLiquidTextures = (Texture2D[])(object)new Texture2D[7]; for (int i = 0; i < 7; i++) { Texture2D val = CreateLiquidBloodTexture(i); bloodLiquidTextures[i] = val; bloodLiquidMaterials[i] = CreateLiquidBloodDecalMaterial(val); } } } private static Material CreateLiquidBloodDecalMaterial(Texture2D texture) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) Shader val = Shader.Find("Standard"); if ((Object)(object)val == (Object)null) { val = Shader.Find("Legacy Shaders/Transparent/Diffuse"); } if ((Object)(object)val == (Object)null) { val = Shader.Find("Unlit/Transparent"); } if ((Object)(object)val == (Object)null) { val = Shader.Find("Sprites/Default"); } Material val2 = new Material(val); val2.mainTexture = (Texture)(object)texture; if (val2.HasProperty("_Color")) { val2.SetColor("_Color", Color.white); } if (val2.HasProperty("_Glossiness")) { val2.SetFloat("_Glossiness", 0.93f); } if (val2.HasProperty("_Metallic")) { val2.SetFloat("_Metallic", 0f); } if (val2.HasProperty("_Mode")) { val2.SetFloat("_Mode", 3f); val2.SetInt("_SrcBlend", 5); val2.SetInt("_DstBlend", 10); val2.SetInt("_ZWrite", 0); val2.DisableKeyword("_ALPHATEST_ON"); val2.EnableKeyword("_ALPHABLEND_ON"); val2.DisableKeyword("_ALPHAPREMULTIPLY_ON"); } val2.renderQueue = 3001; return val2; } private static Texture2D CreateLiquidBloodTexture(int variant) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_03a0: Unknown result type (might be due to invalid IL or missing references) //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_03ac: Unknown result type (might be due to invalid IL or missing references) //IL_03ba: Unknown result type (might be due to invalid IL or missing references) //IL_03c1: Unknown result type (might be due to invalid IL or missing references) //IL_03c8: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) //IL_03d6: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(