using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using Battle;
using Battle.Attacks;
using Battle.Enemies;
using Battle.Enemies.Behaviours;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Cruciball;
using Data;
using HarmonyLib;
using Map;
using Microsoft.CodeAnalysis;
using PeglinBalatroScore.Core;
using PeglinUtils.Locators;
using TMPro;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Worldmap;
[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: AssemblyCompany("PeglinBalatroScore")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+3a733610194201056a5c516dede904fbcc451ffa")]
[assembly: AssemblyProduct("PeglinBalatroScore")]
[assembly: AssemblyTitle("PeglinBalatroScore")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace PeglinBalatroScore
{
internal static class BossTarget
{
private static readonly FieldRef<MapController, CruciballManager> CruciballRef = AccessTools.FieldRefAccess<MapController, CruciballManager>("_cruciballManager");
private static readonly FieldRef<MapController, int> FloorRef = AccessTools.FieldRefAccess<MapController, int>("floorCount");
private static string _cachedKey;
private static long _cachedTarget;
public static int FloorInAct()
{
MapController instance = MapController.instance;
if (!((Object)(object)instance != (Object)null))
{
return 1;
}
return FloorRef.Invoke(instance);
}
public static long Get()
{
//IL_011d: Unknown result type (might be due to invalid IL or missing references)
try
{
MapController instance = MapController.instance;
MapNode val = (((Object)(object)instance != (Object)null) ? instance.bossNode : null);
if ((Object)(object)val == (Object)null || val.potentialMapData == null || val.selectedBossIndex < 0 || val.selectedBossIndex >= val.potentialMapData.Length)
{
return 0L;
}
MapData obj = val.potentialMapData[val.selectedBossIndex];
MapDataBattle val2 = (MapDataBattle)(object)((obj is MapDataBattle) ? obj : null);
if ((Object)(object)val2 == (Object)null)
{
return 0L;
}
CruciballManager val3 = CruciballRef.Invoke(instance);
int num = (((Object)(object)val3 != (Object)null) ? Math.Max(0, val3.currentCruciballLevel) : 0);
string text = $"{instance.Act}|{((Object)val2).name}|{num}";
if (text == _cachedKey)
{
return _cachedTarget;
}
List<string> list = new List<string>();
_cachedTarget = BossHealthRules.TargetHealth(ReadSpawns(val2, list), num);
_cachedKey = text;
ModLog.Info($"Act {instance.Act} boss is {((Object)val2).name} ({val2.bossType}): score target {_cachedTarget} HP at Cruciball {num}. " + "Spawns: " + ((list.Count > 0) ? string.Join("; ", list) : "none found"));
return _cachedTarget;
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("Couldn't read the act boss's HP, flames will use the enemies on screen instead: " + ex.Message));
_cachedKey = null;
return 0L;
}
}
private static List<BossFightSpawn> ReadSpawns(MapDataBattle fight, List<string> described)
{
List<BossFightSpawn> list = new List<BossFightSpawn>();
if (fight.starterSpawns != null)
{
foreach (StarterSpawn starterSpawn in fight.starterSpawns)
{
AddSpawn(list, described, 0, starterSpawn?.spawnData);
}
}
if (fight.waveGroups != null)
{
WaveGroup[] waveGroups = fight.waveGroups;
foreach (WaveGroup val in waveGroups)
{
if (val?.waveData == null)
{
continue;
}
WaveData[] waveData = val.waveData;
foreach (WaveData val2 in waveData)
{
if (val2 != null)
{
AddSpawn(list, described, val2.turnNumber, val2.spawnData);
}
}
}
}
return list;
}
private static void AddSpawn(List<BossFightSpawn> spawns, List<string> described, int turn, SpawnData spawnData)
{
if ((Object)(object)spawnData == (Object)null)
{
return;
}
AddSpawn(spawns, described, turn, spawnData.enemyAssetReference);
if (spawnData.randomizedAssets != null)
{
AssetReferenceGameObject[] randomizedAssets = spawnData.randomizedAssets;
foreach (AssetReferenceGameObject reference in randomizedAssets)
{
AddSpawn(spawns, described, turn, reference);
}
}
}
private static void AddSpawn(List<BossFightSpawn> spawns, List<string> described, int turn, AssetReferenceGameObject reference)
{
//IL_010c: 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_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
if (reference == null || !((AssetReference)reference).RuntimeKeyIsValid())
{
return;
}
AsyncOperationHandle<GameObject> val = Addressables.LoadAssetAsync<GameObject>(((AssetReference)reference).RuntimeKey);
try
{
GameObject val2 = val.WaitForCompletion();
Enemy val3 = (((Object)(object)val2 != (Object)null) ? val2.GetComponentInChildren<Enemy>(true) : null);
if ((Object)(object)val3 != (Object)null)
{
bool flag = ((Enum)val3.enemyTypes).HasFlag((Enum)(object)(EnemyType)128);
float health = val3.StartingHealth;
float cruciballHealth = val3.StartingHealthFirstCruciball;
ScaleHealthAndDamageByAct component = ((Component)val3).GetComponent<ScaleHealthAndDamageByAct>();
if ((Object)(object)component != (Object)null)
{
ActHealth(component, MapController.instance.Act, ref health, ref cruciballHealth);
}
spawns.Add(new BossFightSpawn(turn, flag, health, cruciballHealth));
described.Add(string.Format("{0} turn {1}{2} {3}/{4} HP{5}", ((Object)val2).name, turn, flag ? " boss" : "", health, cruciballHealth, ((Object)(object)component != (Object)null) ? " (scaled by act)" : ""));
}
}
finally
{
Addressables.Release<GameObject>(val);
}
}
private static void ActHealth(ScaleHealthAndDamageByAct byAct, int act, ref float health, ref float cruciballHealth)
{
switch (act)
{
case 1:
health = byAct.act1Health;
cruciballHealth = byAct.act1CruciballHealth;
break;
case 2:
health = byAct.act2Health;
cruciballHealth = byAct.act2CruciballHealth;
break;
case 3:
health = byAct.act3Health;
cruciballHealth = byAct.act3CruciballHealth;
break;
case 4:
health = byAct.act4Health;
cruciballHealth = byAct.act4CruciballHealth;
break;
}
}
}
internal static class ModLog
{
public static void Info(string message)
{
if (Plugin.EnableLogging == null || Plugin.EnableLogging.Value)
{
Plugin.Log.LogInfo((object)message);
}
}
}
internal class OverkillStamp
{
private const string DamageWord = "OVERKILL!";
private const string HealWord = "OVERHEAL!";
private const float StampTime = 0.18f;
private const float StampFromScale = 2.4f;
private const float RestAngle = -4f;
private static readonly int FaceTexId = Shader.PropertyToID("_FaceTex");
private readonly RectTransform _rect;
private readonly CanvasGroup _group;
private readonly TextMeshProUGUI _text;
private readonly TextMeshProUGUI _shadow;
private readonly PixelFlame _backFlame;
private readonly PixelFlame _letterFill;
private Material _material;
private FlamePalette _palette = ScoreColours.DamageFlame;
private float _age = -1f;
public bool Showing => _age >= 0f;
public OverkillStamp(Transform parent)
{
//IL_008f: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_0133: Unknown result type (might be due to invalid IL or missing references)
//IL_0138: 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_0172: Unknown result type (might be due to invalid IL or missing references)
_rect = ScoreBox.NewRect("Overkill", parent);
_group = ((Component)_rect).gameObject.AddComponent<CanvasGroup>();
_group.blocksRaycasts = false;
_group.interactable = false;
_backFlame = new PixelFlame(48, 22, 91, _palette);
RectTransform obj = ScoreBox.NewRect("Flames", (Transform)(object)_rect);
obj.pivot = new Vector2(0.5f, 0f);
obj.anchorMin = new Vector2(0f, 0f);
obj.anchorMax = new Vector2(1f, 0f);
obj.anchoredPosition = new Vector2(0f, 6f);
obj.sizeDelta = new Vector2(0f, 70f);
RawImage obj2 = ((Component)obj).gameObject.AddComponent<RawImage>();
obj2.texture = _backFlame.Texture;
((Graphic)obj2).raycastTarget = false;
_letterFill = new PixelFlame(12, 16, 57, _palette, opaque: true);
_shadow = NewText("Shadow", (Transform)(object)_rect, Color32.op_Implicit(ScoreColours.Outline));
((TMP_Text)_shadow).rectTransform.anchoredPosition = new Vector2(4f, -4f);
_text = NewText("Text", (Transform)(object)_rect, Color.white);
((TMP_Text)_text).enableVertexGradient = true;
Hide();
}
public void Layout(Vector2 position, Vector2 size)
{
//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)
_rect.anchoredPosition = position;
_rect.sizeDelta = size;
}
public void SetFont(TMP_FontAsset font)
{
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Expected O, but got Unknown
if (!((Object)(object)font == (Object)null) && !((Object)(object)((TMP_Text)_text).font == (Object)(object)font))
{
((TMP_Text)_text).font = font;
((TMP_Text)_shadow).font = font;
if ((Object)(object)_material != (Object)null)
{
Object.Destroy((Object)(object)_material);
}
_material = new Material(((TMP_Asset)font).material);
if (_material.HasProperty(FaceTexId))
{
_material.SetTexture(FaceTexId, _letterFill.Texture);
((TMP_Text)_text).fontSharedMaterial = _material;
}
}
}
public void Show(bool heal)
{
if (!Showing)
{
string text = (heal ? "OVERHEAL!" : "OVERKILL!");
((TMP_Text)_text).text = text;
((TMP_Text)_shadow).text = text;
_palette = (heal ? ScoreColours.HealFlame : ScoreColours.DamageFlame);
_backFlame.SetPalette(_palette);
_letterFill.SetPalette(_palette);
_age = 0f;
_group.alpha = 1f;
_backFlame.Clear();
}
}
public void SetAlpha(float alpha)
{
if (Showing)
{
_group.alpha = alpha;
}
}
public void Hide()
{
_age = -1f;
_group.alpha = 0f;
}
public void Tick(float deltaTime, float time)
{
//IL_0086: 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_00b8: 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_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
//IL_00f8: 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_0119: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
//IL_0126: Unknown result type (might be due to invalid IL or missing references)
//IL_0128: 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_012f: 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_0136: Unknown result type (might be due to invalid IL or missing references)
//IL_013b: Unknown result type (might be due to invalid IL or missing references)
//IL_013d: Unknown result type (might be due to invalid IL or missing references)
//IL_0142: Unknown result type (might be due to invalid IL or missing references)
if (Showing)
{
_age += deltaTime;
float num = Mathf.Clamp01(_age / 0.18f);
float num2 = Mathf.Lerp(2.4f, 1f, 1f - (1f - num) * (1f - num));
float num3 = ((num >= 1f) ? (Mathf.Sin(time * 5f) * 2f + Random.Range(-0.6f, 0.6f)) : 0f);
((Transform)_rect).localScale = Vector3.one * num2;
((Transform)_rect).localRotation = Quaternion.Euler(0f, 0f, Mathf.Lerp(-22f, -4f, num) + num3);
float num4 = Mathf.PerlinNoise(time * 9f, 0.3f);
Color32 val = Color32.Lerp(_palette.Bright, _palette.Core, num4);
Color32 val2 = Color32.Lerp(_palette.Ember, _palette.Body, Mathf.PerlinNoise(time * 7f, 2.1f));
((TMP_Text)_text).colorGradient = new VertexGradient(Color32.op_Implicit(val), Color32.op_Implicit(val), Color32.op_Implicit(val2), Color32.op_Implicit(val2));
_backFlame.Tick(deltaTime, (num >= 1f) ? 1.0 : 1.4);
_letterFill.Tick(deltaTime, 1.1);
}
}
public void Destroy()
{
_backFlame.Destroy();
_letterFill.Destroy();
if ((Object)(object)_material != (Object)null)
{
Object.Destroy((Object)(object)_material);
}
}
private static TextMeshProUGUI NewText(string name, Transform parent, Color colour)
{
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
RectTransform obj = ScoreBox.NewRect(name, parent);
ScoreBox.Stretch(obj);
TextMeshProUGUI obj2 = ((Component)obj).gameObject.AddComponent<TextMeshProUGUI>();
((TMP_Text)obj2).text = "OVERKILL!";
((TMP_Text)obj2).alignment = (TextAlignmentOptions)514;
((TMP_Text)obj2).enableAutoSizing = true;
((TMP_Text)obj2).fontSizeMax = 46f;
((TMP_Text)obj2).fontSizeMin = 16f;
((Graphic)obj2).color = colour;
((TMP_Text)obj2).enableWordWrapping = false;
((TMP_Text)obj2).overflowMode = (TextOverflowModes)0;
((Graphic)obj2).raycastTarget = false;
return obj2;
}
}
internal struct FlamePalette
{
public Color32 Ember;
public Color32 Body;
public Color32 Bright;
public Color32 Core;
public FlamePalette(Color32 ember, Color32 body, Color32 bright, Color32 core)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: 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_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
Ember = ember;
Body = body;
Bright = bright;
Core = core;
}
}
internal class PixelFlame
{
private const float StepsPerSecond = 30f;
private const int Shades = 7;
private const float VisibleHeat = 0.1f;
private const double GrowHeadroom = 1.15;
private readonly Color32[] _shades = (Color32[])(object)new Color32[7];
private readonly bool _opaque;
private readonly bool _growable;
private readonly int _baseRows;
private readonly int _seed;
private FireSimulation _fire;
private Texture2D _texture;
private Color32[] _pixels;
private float _stepTimer;
private int _coldSteps;
public Texture Texture => (Texture)(object)_texture;
public int HeightScale => _fire.Height / _baseRows;
public PixelFlame(int width, int height, int seed, FlamePalette palette, bool opaque = false, bool growable = false)
{
_baseRows = height;
_seed = seed;
_opaque = opaque;
_growable = growable;
Build(width, 1, null);
SetPalette(palette);
Draw();
}
private void Build(int width, int scale, FireSimulation carryOver)
{
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: 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_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Expected O, but got Unknown
if ((Object)(object)_texture != (Object)null)
{
Object.Destroy((Object)(object)_texture);
}
int num = _baseRows * scale;
_fire = new FireSimulation(width, num, _seed + scale, _baseRows);
if (carryOver != null)
{
_fire.CopyFrom(carryOver);
}
_texture = new Texture2D(width, num, (TextureFormat)4, false)
{
filterMode = (FilterMode)0,
wrapMode = (TextureWrapMode)1,
name = "PeglinBalatroScoreFlame"
};
_pixels = (Color32[])(object)new Color32[width * num];
}
public void SetPalette(FlamePalette palette)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: 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_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: 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)
Color32[] array = (Color32[])(object)new Color32[4] { palette.Ember, palette.Body, palette.Bright, palette.Core };
for (int i = 0; i < 7; i++)
{
float num = (float)i / 6f * (float)(array.Length - 1);
int num2 = Mathf.Min((int)num, array.Length - 2);
_shades[i] = Color32.Lerp(array[num2], array[num2 + 1], num - (float)num2);
}
_coldSteps = 0;
}
public void Tick(float unscaledDeltaTime, double intensity)
{
_stepTimer += unscaledDeltaTime;
if (_stepTimer < 1f / 30f)
{
return;
}
_stepTimer = Mathf.Min(_stepTimer - 1f / 30f, 1f / 30f);
_coldSteps = ((!(intensity > 0.0)) ? (_coldSteps + 1) : 0);
if (_coldSteps > _fire.Height + 1)
{
if (_growable && HeightScale > 1)
{
Build(_fire.Width, 1, null);
Draw();
}
return;
}
if (_growable)
{
int num = Mathf.Max(1, Mathf.CeilToInt((float)(intensity * 1.15)));
if (num > HeightScale)
{
Build(_fire.Width, num, _fire);
}
}
_fire.Step(intensity);
Draw();
}
public void Clear()
{
_fire.Clear();
_coldSteps = 0;
Draw();
}
public void Destroy()
{
Object.Destroy((Object)(object)_texture);
}
private void Draw()
{
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: 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_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: 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)
for (int i = 0; i < _fire.Height; i++)
{
for (int j = 0; j < _fire.Width; j++)
{
float num = _fire[j, i];
Color32 val;
if (num < 0.1f)
{
val = (Color32)(_opaque ? _shades[0] : new Color32((byte)0, (byte)0, (byte)0, (byte)0));
}
else
{
int num2 = Mathf.Clamp((int)((num - 0.1f) / 0.9f * 7f), 0, 6);
val = _shades[num2];
}
_pixels[i * _fire.Width + j] = val;
}
}
_texture.SetPixels32(_pixels);
_texture.Apply(false);
}
}
[BepInPlugin("PeglinBalatroScore", "PeglinBalatroScore", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
public const string Guid = "PeglinBalatroScore";
public const string Name = "PeglinBalatroScore";
public const string Version = "1.0.0";
public const string SupportedGameVersion = "2.0.12";
internal static ManualLogSource Log;
internal static ConfigEntry<bool> ShowScore;
internal static ConfigEntry<float> ResultSeconds;
internal static ConfigEntry<bool> ShowFlames;
internal static ConfigEntry<bool> ShakeNumbers;
internal static ConfigEntry<bool> ShowOverkill;
internal static ConfigEntry<float> Scale;
internal static ConfigEntry<float> OffsetX;
internal static ConfigEntry<float> OffsetY;
internal static ConfigEntry<bool> EnableLogging;
private void Awake()
{
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Expected O, but got Unknown
//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Expected O, but got Unknown
//IL_0178: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
ShowScore = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowScore", true, "Show the pegs x damage score above the enemy scroll during battles.");
ResultSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ResultSeconds", 3f, new ConfigDescription("How long the final total stays on screen after a shot, in real seconds (game speed doesn't shorten it).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 10f), Array.Empty<object>()));
ShowFlames = ((BaseUnityPlugin)this).Config.Bind<bool>("Effects", "ShowFlames", true, "Flames grow behind the score as it closes in on the act boss's max HP, and burst when it passes it.");
ShakeNumbers = ((BaseUnityPlugin)this).Config.Bind<bool>("Effects", "ShakeNumbers", true, "The numbers shake harder the closer the score gets to the act boss's max HP.");
ShowOverkill = ((BaseUnityPlugin)this).Config.Bind<bool>("Effects", "ShowOverkill", true, "Stamp a flaming OVERKILL above the result when a shot's damage beats the act boss's max HP (a green OVERHEAL when healing past your max HP).");
Scale = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "Scale", 1f, new ConfigDescription("Size of the score, relative to the width of the enemy scroll.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2f), Array.Empty<object>()));
OffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "OffsetX", 0f, "Move the score left (negative) or right (positive), in pixels at 1920x1080.");
OffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "OffsetY", 0f, "Move the score down (negative) or up (positive), in pixels at 1920x1080.");
EnableLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableLogging", true, "Write informational messages (the boss HP target for each act) to the BepInEx log.");
CheckGameVersion();
new Harmony("PeglinBalatroScore").PatchAll();
ScoreHud.Ensure();
Log.LogInfo((object)"PeglinBalatroScore 1.0.0 loaded.");
}
private void CheckGameVersion()
{
string version = Application.version;
if (!(version == "2.0.12"))
{
Log.LogWarning((object)("PeglinBalatroScore 1.0.0 was built for Peglin v2.0.12, but this is Peglin v" + version + ". The score may not work correctly until the mod is updated for this game version."));
}
}
}
internal class ScoreBox
{
private const float Raise = 6f;
private const float PunchDecay = 7f;
private const float FlashDecay = 6f;
private const float BobSpeed = 2.4f;
private const float BobHeight = 2.5f;
private const float TextDrop = -5f;
private const float FlameRootInset = 6f;
private const float FlameHeight = 3.4f;
public readonly RectTransform Rect;
private readonly RectTransform _body;
private readonly Image _face;
private readonly Image _shade;
private readonly Image _flash;
private readonly Outline _outline;
private readonly TextMeshProUGUI _text;
private readonly TextMeshProUGUI _shadow;
private readonly RectTransform _textRect;
private readonly CanvasGroup _group;
private readonly float _bobPhase;
private readonly PixelFlame _flame;
private readonly RawImage _flameImage;
private readonly RectTransform _flameRect;
private float _flameBaseHeight;
private long _value = -1L;
private float _punch;
private float _tilt;
private float _flashAlpha;
public long Value => _value;
public ScoreBox(Transform parent, Transform flameLayer, string name, TextAlignmentOptions alignment, int seed, FlamePalette? flamePalette)
{
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: 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_0130: Unknown result type (might be due to invalid IL or missing references)
//IL_0190: Unknown result type (might be due to invalid IL or missing references)
//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
//IL_020c: Unknown result type (might be due to invalid IL or missing references)
//IL_020e: Unknown result type (might be due to invalid IL or missing references)
//IL_0232: Unknown result type (might be due to invalid IL or missing references)
//IL_0248: Unknown result type (might be due to invalid IL or missing references)
//IL_024a: Unknown result type (might be due to invalid IL or missing references)
//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
Rect = NewRect(name, parent);
_group = ((Component)Rect).gameObject.AddComponent<CanvasGroup>();
_group.blocksRaycasts = false;
_group.interactable = false;
_body = NewRect("Body", (Transform)(object)Rect);
Stretch(_body);
_shade = ((Component)NewRect("Shade", (Transform)(object)_body)).gameObject.AddComponent<Image>();
Stretch(((Graphic)_shade).rectTransform);
((Graphic)_shade).raycastTarget = false;
_outline = ((Component)_shade).gameObject.AddComponent<Outline>();
((Shadow)_outline).effectColor = Color32.op_Implicit(ScoreColours.Outline);
((Shadow)_outline).effectDistance = new Vector2(3f, -3f);
_face = ((Component)NewRect("Face", (Transform)(object)_body)).gameObject.AddComponent<Image>();
Stretch(((Graphic)_face).rectTransform);
((Graphic)_face).rectTransform.offsetMin = new Vector2(0f, 6f);
((Graphic)_face).raycastTarget = false;
_flash = ((Component)NewRect("Flash", (Transform)(object)_body)).gameObject.AddComponent<Image>();
Stretch(((Graphic)_flash).rectTransform);
((Graphic)_flash).color = new Color(1f, 1f, 1f, 0f);
((Graphic)_flash).raycastTarget = false;
_textRect = NewRect("Number", (Transform)(object)((Graphic)_face).rectTransform);
Stretch(_textRect);
_textRect.offsetMin = new Vector2(12f, 2f);
_textRect.offsetMax = new Vector2(-12f, -2f);
_shadow = NewText("Shadow", (Transform)(object)_textRect, alignment, ScoreColours.TextShadow);
((TMP_Text)_shadow).rectTransform.anchoredPosition = new Vector2(3f, -3f);
_text = NewText("Text", (Transform)(object)_textRect, alignment, ScoreColours.Text);
_bobPhase = (float)seed * 1.7f;
if (flamePalette.HasValue)
{
_flame = new PixelFlame(26, 46, seed, flamePalette.Value, opaque: false, growable: true);
_flameRect = NewRect(name + "Flame", flameLayer);
_flameRect.pivot = new Vector2(0.5f, 0f);
_flameImage = ((Component)_flameRect).gameObject.AddComponent<RawImage>();
_flameImage.texture = _flame.Texture;
((Graphic)_flameImage).raycastTarget = false;
}
}
public void Layout(Vector2 position, Vector2 size)
{
//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_002c: 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_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_0054: Unknown result type (might be due to invalid IL or missing references)
Rect.anchoredPosition = position;
Rect.sizeDelta = size;
if ((Object)(object)_flameRect != (Object)null)
{
_flameRect.anchoredPosition = position + new Vector2(0f, size.y / 2f - 6f);
_flameBaseHeight = size.y * 3.4f;
FitFlame();
}
}
private void FitFlame()
{
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_flameImage.texture != (Object)(object)_flame.Texture)
{
_flameImage.texture = _flame.Texture;
}
_flameRect.sizeDelta = new Vector2(Rect.sizeDelta.x, _flameBaseHeight * (float)_flame.HeightScale);
}
public void SetColours(Color32 face, Color32 shade, FlamePalette? flamePalette = null)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: 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_0018: Unknown result type (might be due to invalid IL or missing references)
((Graphic)_face).color = Color32.op_Implicit(face);
((Graphic)_shade).color = Color32.op_Implicit(shade);
if (flamePalette.HasValue && _flame != null)
{
_flame.SetPalette(flamePalette.Value);
}
}
public void AddBorder(Color32 colour)
{
//IL_0011: 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_0026: Unknown result type (might be due to invalid IL or missing references)
Outline obj = ((Component)_face).gameObject.AddComponent<Outline>();
((Shadow)obj).effectColor = Color32.op_Implicit(colour);
((Shadow)obj).effectDistance = new Vector2(3f, 3f);
}
public void SetFont(TMP_FontAsset font)
{
if (!((Object)(object)font == (Object)null))
{
((TMP_Text)_text).font = font;
((TMP_Text)_shadow).font = font;
}
}
public void SetTextColour(Color32 colour)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
((Graphic)_text).color = Color32.op_Implicit(colour);
}
public void SetVisible(float alpha)
{
_group.alpha = alpha;
if ((Object)(object)_flameImage != (Object)null)
{
((Behaviour)_flameImage).enabled = alpha > 0f;
}
}
public void SetValue(long value, string text)
{
if (value != _value)
{
bool num = _value >= 0 && value > _value;
float num2 = ((_value > 0) ? Mathf.Clamp01((float)(value - _value) / (float)_value) : 1f);
_value = value;
((TMP_Text)_text).text = text;
((TMP_Text)_shadow).text = text;
if (num)
{
Punch(0.55f + 0.45f * num2);
}
}
}
public void Punch(float strength)
{
_punch = Mathf.Max(_punch, strength);
_tilt = ((Random.value < 0.5f) ? (-1f) : 1f) * Random.Range(6f, 12f);
_flashAlpha = Mathf.Max(_flashAlpha, 0.55f * strength);
}
public void Tick(float deltaTime, float time, float shake, double flameIntensity)
{
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_011f: 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_0146: 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_00c0: 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_00cd: 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)
_punch = Mathf.MoveTowards(_punch, 0f, _punch * 7f * deltaTime + 0.2f * deltaTime);
_flashAlpha = Mathf.MoveTowards(_flashAlpha, 0f, 6f * deltaTime * Mathf.Max(_flashAlpha, 0.1f));
((Graphic)_flash).color = new Color(1f, 1f, 1f, _flashAlpha);
Vector2 val = default(Vector2);
((Vector2)(ref val))..ctor(0f, -5f + Mathf.Sin(time * 2.4f + _bobPhase) * 2.5f);
float num = _tilt * _punch;
if (shake > 0f)
{
val += Random.insideUnitCircle * (shake * 5f);
num += Random.Range(-1f, 1f) * shake * 4f;
}
_textRect.anchoredPosition = val;
((Transform)_textRect).localRotation = Quaternion.Euler(0f, 0f, num);
((Transform)_textRect).localScale = Vector3.one * (1f + 0.5f * _punch);
((Transform)_body).localScale = Vector3.one * (1f + 0.1f * _punch);
if (_flame != null)
{
_flame.Tick(deltaTime, flameIntensity);
FitFlame();
}
}
public void ClearFlame()
{
_flame?.Clear();
}
public void Destroy()
{
_flame?.Destroy();
}
internal static RectTransform NewRect(string name, Transform parent)
{
//IL_0014: 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_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Expected O, but got Unknown
GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
val.transform.SetParent(parent, false);
return (RectTransform)val.transform;
}
internal static void Stretch(RectTransform rect)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: 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_0022: Unknown result type (might be due to invalid IL or missing references)
rect.anchorMin = Vector2.zero;
rect.anchorMax = Vector2.one;
rect.offsetMin = Vector2.zero;
rect.offsetMax = Vector2.zero;
}
private static TextMeshProUGUI NewText(string name, Transform parent, TextAlignmentOptions alignment, Color32 colour)
{
//IL_0018: 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_0020: Unknown result type (might be due to invalid IL or missing references)
RectTransform obj = NewRect(name, parent);
Stretch(obj);
TextMeshProUGUI obj2 = ((Component)obj).gameObject.AddComponent<TextMeshProUGUI>();
((TMP_Text)obj2).alignment = alignment;
((Graphic)obj2).color = Color32.op_Implicit(colour);
((TMP_Text)obj2).enableAutoSizing = true;
((TMP_Text)obj2).fontSizeMax = 46f;
((TMP_Text)obj2).fontSizeMin = 14f;
((TMP_Text)obj2).enableWordWrapping = false;
((TMP_Text)obj2).overflowMode = (TextOverflowModes)0;
((Graphic)obj2).raycastTarget = false;
((TMP_Text)obj2).text = "0";
return obj2;
}
}
internal static class ScoreColours
{
public static readonly Color32 PegsFace = new Color32((byte)112, (byte)142, (byte)46, byte.MaxValue);
public static readonly Color32 PegsShade = new Color32((byte)70, (byte)92, (byte)26, byte.MaxValue);
public static readonly FlamePalette PegsFlame = new FlamePalette(new Color32((byte)66, (byte)92, (byte)24, byte.MaxValue), new Color32((byte)124, (byte)168, (byte)44, byte.MaxValue), new Color32((byte)190, (byte)226, (byte)84, byte.MaxValue), new Color32((byte)246, (byte)252, (byte)190, byte.MaxValue));
public static readonly Color32 DamageFace = new Color32((byte)222, (byte)170, (byte)30, byte.MaxValue);
public static readonly Color32 DamageShade = new Color32((byte)150, (byte)104, (byte)14, byte.MaxValue);
public static readonly FlamePalette DamageFlame = new FlamePalette(new Color32((byte)150, (byte)54, (byte)16, byte.MaxValue), new Color32((byte)226, (byte)120, (byte)24, byte.MaxValue), new Color32((byte)250, (byte)196, (byte)50, byte.MaxValue), new Color32(byte.MaxValue, (byte)246, (byte)180, byte.MaxValue));
public static readonly Color32 HealFace = new Color32((byte)70, (byte)186, (byte)120, byte.MaxValue);
public static readonly Color32 HealShade = new Color32((byte)36, (byte)120, (byte)76, byte.MaxValue);
public static readonly FlamePalette HealFlame = new FlamePalette(new Color32((byte)24, (byte)104, (byte)84, byte.MaxValue), new Color32((byte)56, (byte)178, (byte)120, byte.MaxValue), new Color32((byte)130, (byte)232, (byte)160, byte.MaxValue), new Color32((byte)226, byte.MaxValue, (byte)226, byte.MaxValue));
public static readonly Color32 ResultFace = new Color32((byte)44, (byte)36, (byte)32, byte.MaxValue);
public static readonly Color32 ResultShade = new Color32((byte)24, (byte)18, (byte)16, byte.MaxValue);
public static readonly Color32 ResultBorder = new Color32((byte)222, (byte)170, (byte)30, byte.MaxValue);
public static readonly Color32 Text = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);
public static readonly Color32 TextShadow = new Color32((byte)28, (byte)22, (byte)20, (byte)200);
public static readonly Color32 Outline = new Color32((byte)24, (byte)18, (byte)16, byte.MaxValue);
public static readonly Color32 Times = new Color32((byte)222, (byte)170, (byte)30, byte.MaxValue);
}
internal class ScoreHud : MonoBehaviour
{
private const float BoxHeight = 58f;
private const float TimesGap = 48f;
private const float TimesDrop = -6f;
private const float ForestBottom = 0.312f;
private const float ScrollTop = 0.413f;
private const float WallRight = 0.8075f;
private const float SideMargin = 0.01f;
private const float BossBarGap = 0.012f;
private const float ShiftSpeed = 10f;
private const float BandFill = 0.56f;
private const float BurstSeconds = 0.8f;
private const float BurstExtraIntensity = 0.9f;
private const float IntensityRiseSpeed = 3f;
private const float IntensityFallSpeed = 1.2f;
private const float FadeSpeed = 6f;
private const float ResultFadeSeconds = 0.3f;
private const float MaxShake = 1.6f;
private static ScoreHud _instance;
private readonly ScoreTracker _tracker = new ScoreTracker();
private Canvas _canvas;
private RectTransform _canvasRect;
private ScoreTooltip _tooltip;
private TooltipManager _gameTooltips;
private GameObject _bossBars;
private readonly List<ScreenShift> _shifts = new List<ScreenShift>();
private float _nextShiftSearch;
private float _shift;
private bool _loggedShift;
private string _loggedFlameNote;
private float _resultFade;
private readonly List<Canvas> _tooltipCanvases = new List<Canvas>();
private float _nextTooltipSearch;
private bool _loggedSorting;
private double _flameStart = 0.1;
private RectTransform _root;
private ScoreBox _pegs;
private ScoreBox _damage;
private ScoreBox _result;
private TextMeshProUGUI _times;
private OverkillStamp _overkill;
private BattleController _battle;
private EnemyInfoManager _scroll;
private float _nextScrollSearch;
private bool _fontApplied;
private bool _warnedRead;
private float _layoutWidth = -1f;
private RectTransform _timesRect;
private ShotDamage _lastRead;
private bool _hasRead;
private long _target;
private long _previousTotal;
private double _intensity;
private float _burst;
private float _alpha;
private ScorePhase _shownPhase;
private bool _shownHeal;
private Camera CanvasCamera
{
get
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
if ((int)_canvas.renderMode != 0)
{
return _canvas.worldCamera;
}
return null;
}
}
public static void Ensure()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Expected O, but got Unknown
if (!((Object)(object)_instance != (Object)null))
{
GameObject val = new GameObject("PeglinBalatroScore")
{
hideFlags = (HideFlags)61
};
Object.DontDestroyOnLoad((Object)val);
_instance = val.AddComponent<ScoreHud>();
}
}
internal static void AttackFired(AttackManager attackManager, int pegTally, float damageMultiplier, long damageBonus, int critCount)
{
if (!((Object)(object)_instance == (Object)null) && _instance._tracker.Phase == ScorePhase.Result)
{
long currentDamage = attackManager.GetCurrentDamage(pegTally, damageMultiplier, damageBonus, critCount, false);
_instance._tracker.RefineResult(currentDamage);
}
}
private void Awake()
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Expected O, but got Unknown
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Expected O, but got Unknown
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: 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_00e0: 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_0153: 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_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_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_0236: Unknown result type (might be due to invalid IL or missing references)
//IL_023b: Unknown result type (might be due to invalid IL or missing references)
//IL_0255: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("Canvas", new Type[2]
{
typeof(Canvas),
typeof(CanvasScaler)
});
val.transform.SetParent(((Component)this).transform, false);
_canvas = val.GetComponent<Canvas>();
_canvas.renderMode = (RenderMode)0;
_canvas.sortingOrder = 10;
CanvasScaler component = val.GetComponent<CanvasScaler>();
component.uiScaleMode = (ScaleMode)1;
component.referenceResolution = new Vector2(1920f, 1080f);
component.matchWidthOrHeight = 0.5f;
_canvasRect = (RectTransform)val.transform;
_root = ScoreBox.NewRect("Score", val.transform);
RectTransform root = _root;
RectTransform root2 = _root;
RectTransform root3 = _root;
Vector2 val2 = default(Vector2);
((Vector2)(ref val2))..ctor(0.5f, 0.5f);
root3.pivot = val2;
Vector2 anchorMin = (root2.anchorMax = val2);
root.anchorMin = anchorMin;
RectTransform flameLayer = ScoreBox.NewRect("Flames", (Transform)(object)_root);
_pegs = new ScoreBox((Transform)(object)_root, (Transform)(object)flameLayer, "Pegs", (TextAlignmentOptions)516, 11, ScoreColours.PegsFlame);
_damage = new ScoreBox((Transform)(object)_root, (Transform)(object)flameLayer, "Damage", (TextAlignmentOptions)513, 23, ScoreColours.DamageFlame);
_pegs.SetColours(ScoreColours.PegsFace, ScoreColours.PegsShade);
_damage.SetColours(ScoreColours.DamageFace, ScoreColours.DamageShade);
_timesRect = ScoreBox.NewRect("Times", (Transform)(object)_root);
_times = ((Component)_timesRect).gameObject.AddComponent<TextMeshProUGUI>();
((TMP_Text)_times).text = "x";
((TMP_Text)_times).fontSize = 40f;
((TMP_Text)_times).alignment = (TextAlignmentOptions)544;
((Graphic)_times).color = Color32.op_Implicit(ScoreColours.Times);
((Graphic)_times).raycastTarget = false;
_result = new ScoreBox((Transform)(object)_root, (Transform)(object)flameLayer, "Result", (TextAlignmentOptions)514, 37, null);
_result.SetColours(ScoreColours.ResultFace, ScoreColours.ResultShade);
_result.AddBorder(ScoreColours.ResultBorder);
_overkill = new OverkillStamp((Transform)(object)_root);
_tooltip = new ScoreTooltip(val.transform);
LayoutWidget(312f);
ShowValues(0L, 0L);
ApplyPhaseLayout();
((Component)_root).gameObject.SetActive(false);
}
private void OnEnable()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected O, but got Unknown
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Expected O, but got Unknown
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Expected O, but got Unknown
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Expected O, but got Unknown
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Expected O, but got Unknown
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Expected O, but got Unknown
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Expected O, but got Unknown
PachinkoBall.OnShotFired = (PachinkoBallFired)Delegate.Combine((Delegate?)(object)PachinkoBall.OnShotFired, (Delegate?)new PachinkoBallFired(OnShotFired));
BattleController.OnShotComplete = (ShotComplete)Delegate.Combine((Delegate?)(object)BattleController.OnShotComplete, (Delegate?)new ShotComplete(OnShotComplete));
BattleController.OnBattleEnded = (BattleEvent)Delegate.Combine((Delegate?)(object)BattleController.OnBattleEnded, (Delegate?)new BattleEvent(OnBattleEnded));
BattleController.OnBattleStarted = (BattleEvent)Delegate.Combine((Delegate?)(object)BattleController.OnBattleStarted, (Delegate?)new BattleEvent(OnBattleStarted));
}
private void OnDisable()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected O, but got Unknown
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Expected O, but got Unknown
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Expected O, but got Unknown
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Expected O, but got Unknown
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Expected O, but got Unknown
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Expected O, but got Unknown
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Expected O, but got Unknown
PachinkoBall.OnShotFired = (PachinkoBallFired)Delegate.Remove((Delegate?)(object)PachinkoBall.OnShotFired, (Delegate?)new PachinkoBallFired(OnShotFired));
BattleController.OnShotComplete = (ShotComplete)Delegate.Remove((Delegate?)(object)BattleController.OnShotComplete, (Delegate?)new ShotComplete(OnShotComplete));
BattleController.OnBattleEnded = (BattleEvent)Delegate.Remove((Delegate?)(object)BattleController.OnBattleEnded, (Delegate?)new BattleEvent(OnBattleEnded));
BattleController.OnBattleStarted = (BattleEvent)Delegate.Remove((Delegate?)(object)BattleController.OnBattleStarted, (Delegate?)new BattleEvent(OnBattleStarted));
}
private void OnBattleStarted()
{
BossTarget.Get();
}
private void OnDestroy()
{
ModLog.Info("Score widget destroyed; it will be rebuilt when the next battle starts.");
_pegs?.Destroy();
_damage?.Destroy();
_result?.Destroy();
_overkill?.Destroy();
}
private void OnShotFired(Vector2 aimVector)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Invalid comparison between Unknown and I4
BattleController val = FindBattle();
if (!((Object)(object)val == (Object)null) && BattleController.BattleActive && _tracker.Phase != ScorePhase.Counting && (int)BattleController.CurrentBattleState != 9)
{
bool flag = (Object)(object)val.attackManager != (Object)null && val.attackManager.isHeal;
_tracker.ResultHoldSeconds = Plugin.ResultSeconds.Value;
_tracker.BeginShot(flag);
_target = (flag ? PlayerMaxHealth(val) : BossTarget.Get());
if (!flag && BattleController.IsBossBattle)
{
_target = Math.Max(_target, ToughestEnemyOnScreen(bossOnly: true));
}
if (_target <= 0)
{
_target = ToughestEnemyOnScreen(bossOnly: false);
}
int num = BossTarget.FloorInAct();
_flameStart = FlameCurve.StartRatioForFloor(num);
string text = string.Format("floor {0}: flames light at {1:P0} of {2} = {3} {4}", num, _flameStart, _target, Math.Ceiling(_flameStart * (double)_target), flag ? "healing" : "damage");
if (text != _loggedFlameNote)
{
_loggedFlameNote = text;
ModLog.Info("Score target for this battle, " + text + ".");
}
_previousTotal = 0L;
_hasRead = false;
_overkill.Hide();
}
}
private void OnShotComplete()
{
if (_tracker.Phase == ScorePhase.Counting)
{
ReadGame(force: true);
_tracker.CompleteShot(_tracker.Total);
}
}
private void OnBattleEnded()
{
if (_tracker.Phase == ScorePhase.Counting)
{
_tracker.Clear();
}
}
private void Update()
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Invalid comparison between Unknown and I4
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Invalid comparison between Unknown and I4
float unscaledDeltaTime = Time.unscaledDeltaTime;
float unscaledTime = Time.unscaledTime;
BattleController val = FindBattle();
if (_tracker.Phase == ScorePhase.Counting)
{
if ((Object)(object)val == (Object)null)
{
_tracker.Clear();
}
else if ((int)BattleController.CurrentBattleState == 2)
{
_tracker.CompleteShot(_tracker.Total);
}
else
{
ReadGame(force: false);
}
}
_tracker.Tick(unscaledDeltaTime);
bool flag = (Object)(object)val != (Object)null && BattleController.BattleActive && (int)BattleController.CurrentBattleState != 9;
bool flag2 = Plugin.ShowScore.Value && Time.timeScale > 0f && (_tracker.Phase != ScorePhase.Ready || (flag && ScrollVisible()));
_alpha = Mathf.MoveTowards(_alpha, flag2 ? 1f : 0f, 6f * unscaledDeltaTime);
if (_alpha <= 0f)
{
if (((Component)_root).gameObject.activeSelf)
{
((Component)_root).gameObject.SetActive(false);
}
_tooltip.Hide();
}
else
{
((Component)_root).gameObject.SetActive(true);
ApplyFont();
SyncCanvas();
Place();
Animate(unscaledDeltaTime, unscaledTime);
UpdateTooltip();
}
}
private void UpdateTooltip()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: 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_007e: 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)
if (!RectTransformUtility.RectangleContainsScreenPoint(_root, Vector2.op_Implicit(Input.mousePosition), CanvasCamera))
{
_tooltip.Hide();
return;
}
string text = ScoreExplanation.Build(_tracker.LastShotTotal, _tracker.LastShotWasHeal);
Vector3[] array = (Vector3[])(object)new Vector3[4];
_root.GetWorldCorners(array);
Vector2 anchorBottomRight = Vector2.op_Implicit(((Transform)_canvasRect).InverseTransformPoint(array[3]));
ScoreTooltip tooltip = _tooltip;
Rect rect = _canvasRect.rect;
tooltip.Show(text, anchorBottomRight, (0f - ((Rect)(ref rect)).height) / 2f);
}
private void ReadGame(bool force)
{
BattleController val = FindBattle();
if ((Object)(object)val == (Object)null)
{
return;
}
try
{
ShotDamage lastRead = ShotDamage.ReadInputs(val);
if (force || !_hasRead || !lastRead.SameInputs(_lastRead))
{
lastRead.Calculate(val);
_lastRead = lastRead;
_hasRead = true;
_tracker.Update(lastRead.PegTally, lastRead.PerPeg, lastRead.Total);
}
}
catch (Exception arg)
{
if (!_warnedRead)
{
_warnedRead = true;
Plugin.Log.LogWarning((object)$"Couldn't read the shot's damage from the game: {arg}");
}
}
}
private void Animate(float deltaTime, float time)
{
if (_tracker.Phase != _shownPhase || _tracker.IsHeal != _shownHeal)
{
bool num = _tracker.Phase == ScorePhase.Result;
bool flag = _shownPhase == ScorePhase.Result && _tracker.Phase == ScorePhase.Ready;
_resultFade = (flag ? 0.3f : 0f);
_shownPhase = _tracker.Phase;
_shownHeal = _tracker.IsHeal;
ApplyPhaseLayout();
if (num)
{
_result.SetValue(-1L, string.Empty);
}
}
long total = _tracker.Total;
if (_tracker.Phase == ScorePhase.Result)
{
bool num2 = _result.Value < 0;
_result.SetValue(total, ScoreFormat.Format(total));
if (num2)
{
_result.Punch(1f);
}
if (Plugin.ShowOverkill.Value && _target > 0 && total >= _target)
{
_overkill.Show(_tracker.IsHeal);
}
}
else
{
ShowValues(_tracker.Pegs, _tracker.PerPeg);
if (_tracker.Phase == ScorePhase.Ready && _resultFade <= 0f)
{
_overkill.Hide();
}
}
if (_tracker.Phase != ScorePhase.Ready && FlameCurve.CrossedTarget(_previousTotal, total, _target))
{
_burst = 0.8f;
_pegs.Punch(1f);
_damage.Punch(1f);
_result.Punch(1f);
}
_previousTotal = total;
_burst = Mathf.Max(0f, _burst - deltaTime);
double num3 = ((_tracker.Phase == ScorePhase.Ready) ? 0.0 : FlameCurve.Intensity(total, _target, _flameStart));
double num4 = ((num3 > _intensity) ? 3f : 1.2f);
_intensity = MoveTowards(_intensity, num3, num4 * (double)deltaTime);
double flameIntensity = (Plugin.ShowFlames.Value ? (_intensity + (double)(0.9f * (_burst / 0.8f))) : 0.0);
float shake = (Plugin.ShakeNumbers.Value ? Mathf.Min(1.6f, (float)_intensity + _burst) : 0f);
_pegs.Tick(deltaTime, time, shake, flameIntensity);
_damage.Tick(deltaTime, time, shake, flameIntensity);
_result.Tick(deltaTime, time, shake, 0.0);
_overkill.Tick(deltaTime, time);
FadeResult(deltaTime);
}
private void ShowValues(long pegs, long perPeg)
{
_pegs.SetValue(pegs, ScoreFormat.Format(pegs));
_damage.SetValue(perPeg, ScoreFormat.Format(perPeg));
}
private void ApplyPhaseLayout()
{
//IL_00e0: 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_00ef: 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_0125: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: Unknown result type (might be due to invalid IL or missing references)
bool flag = _tracker.Phase == ScorePhase.Result;
_pegs.SetVisible(1f);
_damage.SetVisible(1f);
((Component)_pegs.Rect).gameObject.SetActive(!flag);
((Component)_damage.Rect).gameObject.SetActive(!flag);
((Component)_times).gameObject.SetActive(!flag);
_result.SetVisible((flag || _resultFade > 0f) ? 1f : 0f);
((Component)_result.Rect).gameObject.SetActive(flag || _resultFade > 0f);
bool isHeal = _tracker.IsHeal;
_damage.SetColours(isHeal ? ScoreColours.HealFace : ScoreColours.DamageFace, isHeal ? ScoreColours.HealShade : ScoreColours.DamageShade, isHeal ? ScoreColours.HealFlame : ScoreColours.DamageFlame);
if (flag)
{
_result.SetTextColour(isHeal ? ScoreColours.HealFlame.Bright : ScoreColours.Text);
}
}
private void FadeResult(float deltaTime)
{
if (!(_resultFade <= 0f))
{
_resultFade = Mathf.Max(0f, _resultFade - deltaTime);
float num = _resultFade / 0.3f;
_result.SetVisible(num);
_overkill.SetAlpha(num);
if (_resultFade <= 0f)
{
((Component)_result.Rect).gameObject.SetActive(false);
_overkill.Hide();
}
}
}
private void Place()
{
//IL_002d: 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_0032: 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_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_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_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
//IL_011a: 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_011e: Unknown result type (might be due to invalid IL or missing references)
//IL_0128: Unknown result type (might be due to invalid IL or missing references)
//IL_0141: 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_0156: 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)
Camera main = Camera.main;
Rect val = (Rect)(((Object)(object)main != (Object)null) ? main.pixelRect : new Rect(0f, 0f, (float)Screen.width, (float)Screen.height));
float num = ((Rect)(ref val)).x + ((Rect)(ref val)).width * 0.8175f;
float num2 = ((Rect)(ref val)).xMax - ((Rect)(ref val)).width * 0.01f;
float num3 = ((Rect)(ref val)).yMax - ((Rect)(ref val)).height * 0.312f;
float num4 = ((Rect)(ref val)).yMax - ((Rect)(ref val)).height * 0.413f;
Vector2 val2 = ToCanvas(new Vector2(num, num3));
Vector2 val3 = ToCanvas(new Vector2(num2, num4));
float num5 = val2.y - val3.y;
float num6 = Mathf.Max(0.1f, num5 * 0.56f / 58f * Plugin.Scale.Value);
float num7 = (val3.x - val2.x) / num6;
if (Mathf.Abs(num7 - _layoutWidth) > 0.5f)
{
LayoutWidget(num7);
}
_root.anchoredPosition = (val2 + val3) / 2f + new Vector2(Plugin.OffsetX.Value, Plugin.OffsetY.Value);
((Transform)_root).localScale = Vector3.one * num6;
}
private Vector2 ToCanvas(Vector2 screenPoint)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
Vector2 result = default(Vector2);
RectTransformUtility.ScreenPointToLocalPointInRectangle(_canvasRect, screenPoint, CanvasCamera, ref result);
return result;
}
private void FindTooltipCanvases()
{
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
_tooltipCanvases.Clear();
_gameTooltips = Object.FindObjectOfType<TooltipManager>();
if ((Object)(object)_gameTooltips != (Object)null && (Object)(object)((Component)_gameTooltips).GetComponent<Canvas>() != (Object)null)
{
_tooltipCanvases.Add(((Component)_gameTooltips).GetComponent<Canvas>());
}
RelicTooltip[] array = Resources.FindObjectsOfTypeAll<RelicTooltip>();
foreach (RelicTooltip val in array)
{
Scene scene = ((Component)val).gameObject.scene;
if (((Scene)(ref scene)).IsValid())
{
Canvas componentInParent = ((Component)val).GetComponentInParent<Canvas>(true);
if ((Object)(object)componentInParent != (Object)null && !_tooltipCanvases.Contains(componentInParent.rootCanvas))
{
_tooltipCanvases.Add(componentInParent.rootCanvas);
}
}
}
}
private void SyncCanvas()
{
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_0179: Unknown result type (might be due to invalid IL or missing references)
//IL_017f: Invalid comparison between Unknown and I4
Camera main = Camera.main;
if ((Object)(object)main == (Object)null)
{
_canvas.renderMode = (RenderMode)0;
return;
}
EnemyInfoManager val = FindScroll();
Canvas val2 = (((Object)(object)val != (Object)null && (Object)(object)((Component)val).GetComponentInParent<Canvas>() != (Object)null) ? ((Component)val).GetComponentInParent<Canvas>().rootCanvas : null);
if (Time.unscaledTime >= _nextTooltipSearch)
{
_nextTooltipSearch = Time.unscaledTime + 2f;
FindTooltipCanvases();
}
Canvas val3 = (((Object)(object)_gameTooltips != (Object)null) ? ((Component)_gameTooltips).GetComponent<Canvas>() : null);
_canvas.renderMode = (RenderMode)1;
_canvas.worldCamera = main;
int num = (((Object)(object)val2 != (Object)null) ? val2.sortingLayerID : (((Object)(object)val3 != (Object)null) ? val3.sortingLayerID : 0));
int num2 = (((Object)(object)val2 != (Object)null) ? (val2.sortingOrder + 1) : (((Object)(object)val3 != (Object)null) ? (val3.sortingOrder - 1) : 0));
foreach (Canvas tooltipCanvase in _tooltipCanvases)
{
if ((Object)(object)tooltipCanvase != (Object)null && (int)tooltipCanvase.renderMode != 0 && tooltipCanvase.sortingLayerID == num && num2 >= tooltipCanvase.sortingOrder)
{
num2 = tooltipCanvase.sortingOrder - 1;
}
}
_canvas.sortingLayerID = num;
_canvas.sortingOrder = num2;
float num3 = (((Object)(object)val2 != (Object)null && (int)val2.renderMode == 1) ? val2.planeDistance : 10f);
_canvas.planeDistance = Mathf.Clamp(num3, main.nearClipPlane + 0.01f, main.farClipPlane - 0.01f);
if (!_loggedSorting)
{
_loggedSorting = true;
ModLog.Info($"Score drawn on camera {((Object)main).name}, sorting layer {SortingLayer.IDToName(num)} order {num2} " + "(scroll " + (((Object)(object)val2 != (Object)null) ? val2.sortingOrder.ToString() : "?") + ", tooltip canvases " + string.Join(", ", _tooltipCanvases.ConvertAll((Canvas c) => (!((Object)(object)c == (Object)null)) ? $"{((Object)c).name} {c.renderMode} {SortingLayer.IDToName(c.sortingLayerID)}/{c.sortingOrder}" : "?")) + ").");
}
}
private void LayoutWidget(float width)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: 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_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
_layoutWidth = width;
_root.sizeDelta = new Vector2(width, 58f);
float num = Mathf.Max(40f, (width - 48f) / 2f);
float num2 = 24f + num / 2f;
_pegs.Layout(new Vector2(0f - num2, 0f), new Vector2(num, 58f));
_damage.Layout(new Vector2(num2, 0f), new Vector2(num, 58f));
_timesRect.anchoredPosition = new Vector2(0f, -6f);
_timesRect.sizeDelta = new Vector2(48f, 58f);
_result.Layout(Vector2.zero, new Vector2(width, 58f));
_overkill.Layout(new Vector2(0f, 59f), new Vector2(width * 0.9f, 44f));
}
private void LateUpdate()
{
//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)
float num = 0f;
if (((Component)_root).gameObject.activeSelf && BattleController.IsBossBattle && TryBossBarTop(out var top))
{
Vector3[] array = (Vector3[])(object)new Vector3[4];
_root.GetWorldCorners(array);
float y = RectTransformUtility.WorldToScreenPoint(CanvasCamera, array[0]).y;
float num2 = (float)Screen.height * 0.012f;
num = Mathf.Max(0f, top + _shift - (y - num2));
}
_shift = ((num <= 0f && _shift < 0.5f) ? 0f : Mathf.Lerp(_shift, num, 1f - Mathf.Exp(-10f * Time.unscaledDeltaTime)));
if (Time.unscaledTime >= _nextShiftSearch || _shifts.Exists((ScreenShift s) => !s.Alive))
{
_nextShiftSearch = Time.unscaledTime + 1f;
FindShiftTargets();
}
foreach (ScreenShift shift in _shifts)
{
shift.Apply(_shift);
}
if (_shift > 0f && !_loggedShift)
{
_loggedShift = true;
ModLog.Info($"Moved down to make room for the score (target {num:0}px): " + string.Join(", ", _shifts.ConvertAll((ScreenShift s) => (!((Object)(object)s.Target != (Object)null)) ? "?" : ((Object)s.Target).name)));
}
}
private void FindShiftTargets()
{
_shifts.RemoveAll((ScreenShift s) => !s.Alive);
List<Transform> list = new List<Transform>();
if ((Object)(object)_bossBars != (Object)null)
{
list.Add(_bossBars.transform);
}
UpcomingEnemyViewLocator val = Object.FindObjectOfType<UpcomingEnemyViewLocator>();
if ((Object)(object)val != (Object)null)
{
list.Add(((Component)val).transform);
}
EnemyInfoManager val2 = FindScroll();
if ((Object)(object)val2 != (Object)null)
{
list.Add(((Component)val2).transform);
if ((Object)(object)val2._scrollAnim != (Object)null)
{
list.Add(((Component)val2._scrollAnim).transform);
}
if ((Object)(object)val2._mask != (Object)null)
{
list.Add(((Component)val2._mask).transform);
}
}
foreach (Transform candidate in list)
{
bool num = list.Exists((Transform other) => (Object)(object)other != (Object)(object)candidate && candidate.IsChildOf(other));
bool flag = _shifts.Exists((ScreenShift s) => (Object)(object)s.Target == (Object)(object)candidate);
if (num || flag)
{
continue;
}
foreach (ScreenShift item in _shifts.FindAll((ScreenShift s) => s.Target.IsChildOf(candidate)))
{
item.Restore();
_shifts.Remove(item);
}
_shifts.Add(new ScreenShift(candidate));
}
}
private bool TryBossBarTop(out float top)
{
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
top = float.MinValue;
if ((Object)(object)_bossBars == (Object)null)
{
try
{
_bossBars = GameObject.FindGameObjectWithTag("BossHealthBar");
}
catch (UnityException)
{
}
if ((Object)(object)_bossBars == (Object)null)
{
return false;
}
_nextShiftSearch = 0f;
}
Vector3[] array = (Vector3[])(object)new Vector3[4];
CanvasGroup[] componentsInChildren = _bossBars.GetComponentsInChildren<CanvasGroup>(false);
foreach (CanvasGroup val in componentsInChildren)
{
if (!(val.alpha < 0.05f))
{
Camera val2 = ScreenShift.CameraFor(((Component)val).transform);
Graphic[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<Graphic>(false);
for (int j = 0; j < componentsInChildren2.Length; j++)
{
componentsInChildren2[j].rectTransform.GetWorldCorners(array);
top = Mathf.Max(top, RectTransformUtility.WorldToScreenPoint(val2, array[1]).y);
}
}
}
return top > float.MinValue;
}
private bool ScrollVisible()
{
EnemyInfoManager val = FindScroll();
if (!((Object)(object)val == (Object)null))
{
return ((Behaviour)val).isActiveAndEnabled;
}
return true;
}
private EnemyInfoManager FindScroll()
{
if ((Object)(object)_scroll == (Object)null && Time.unscaledTime >= _nextScrollSearch)
{
_nextScrollSearch = Time.unscaledTime + 1f;
_scroll = Object.FindObjectOfType<EnemyInfoManager>();
}
return _scroll;
}
private BattleController FindBattle()
{
if ((Object)(object)_battle == (Object)null && BattleController.BattleActive)
{
_battle = Object.FindObjectOfType<BattleController>();
}
return _battle;
}
private void ApplyFont()
{
if (_fontApplied)
{
return;
}
TMP_FontAsset val = null;
EnemyInfoManager val2 = FindScroll();
TMP_Text val3 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponentInChildren<TMP_Text>(true) : null);
if ((Object)(object)val3 != (Object)null && (Object)(object)val3.font != (Object)null && (Object)(object)val3.font != (Object)(object)TMP_Settings.defaultFontAsset)
{
val = val3.font;
}
if ((Object)(object)val == (Object)null)
{
TextMeshProUGUI[] array = Object.FindObjectsOfType<TextMeshProUGUI>();
foreach (TextMeshProUGUI val4 in array)
{
if ((Object)(object)((TMP_Text)val4).font != (Object)null && (Object)(object)((TMP_Text)val4).font != (Object)(object)TMP_Settings.defaultFontAsset && !((TMP_Text)val4).transform.IsChildOf(((Component)this).transform))
{
val = ((TMP_Text)val4).font;
break;
}
}
}
if (!((Object)(object)val == (Object)null))
{
_pegs.SetFont(val);
_damage.SetFont(val);
_result.SetFont(val);
((TMP_Text)_times).font = val;
_overkill.SetFont(val);
_tooltip.SetFont(val);
_fontApplied = true;
}
}
private static long PlayerMaxHealth(BattleController battle)
{
PlayerHealthController playerHealthController = battle.PlayerHealthController;
if (!((Object)(object)playerHealthController != (Object)null))
{
return 0L;
}
return (long)Mathf.Ceil(playerHealthController.MaxHealth);
}
private static long ToughestEnemyOnScreen(bool bossOnly)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
float num = 0f;
Enemy[] array = Object.FindObjectsOfType<Enemy>();
foreach (Enemy val in array)
{
if (!bossOnly || ((Enum)val.enemyTypes).HasFlag((Enum)(object)(EnemyType)128))
{
num = Mathf.Max(num, val.maxHealth);
}
}
return (long)Mathf.Ceil(num);
}
private static double MoveTowards(double current, double target, double maxDelta)
{
if (Math.Abs(target - current) <= maxDelta)
{
return target;
}
return current + (double)Math.Sign(target - current) * maxDelta;
}
}
[HarmonyPatch(typeof(BattleController), "OnEnable")]
internal static class BattleEnablePatch
{
private static void Postfix()
{
ScoreHud.Ensure();
}
}
[HarmonyPatch(typeof(AttackManager), "Attack")]
internal static class AttackFiredPatch
{
private static void Prefix(AttackManager __instance, int pegMultipliersTally, float dmgMultiplier, long dmgBonus, int criticalHitCount)
{
try
{
ScoreHud.AttackFired(__instance, pegMultipliersTally, dmgMultiplier, dmgBonus, criticalHitCount);
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("Couldn't read the attack's final damage: " + ex.Message));
}
}
}
internal class ScoreTooltip
{
private const float Width = 440f;
private const float Padding = 16f;
private const float Gap = 10f;
private static readonly Color32 Paper = new Color32((byte)238, (byte)186, (byte)120, (byte)250);
private static readonly Color32 Ink = new Color32((byte)62, (byte)39, (byte)35, byte.MaxValue);
private readonly RectTransform _rect;
private readonly TextMeshProUGUI _text;
private string _shown;
public ScoreTooltip(Transform canvas)
{
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: 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_0070: 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_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: 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_0121: Unknown result type (might be due to invalid IL or missing references)
_rect = ScoreBox.NewRect("ScoreTooltip", canvas);
RectTransform rect = _rect;
RectTransform rect2 = _rect;
Vector2 val = default(Vector2);
((Vector2)(ref val))..ctor(0.5f, 0.5f);
rect2.anchorMax = val;
rect.anchorMin = val;
_rect.pivot = new Vector2(1f, 1f);
Image obj = ((Component)_rect).gameObject.AddComponent<Image>();
((Graphic)obj).color = Color32.op_Implicit(Paper);
((Graphic)obj).raycastTarget = false;
Outline obj2 = ((Component)_rect).gameObject.AddComponent<Outline>();
((Shadow)obj2).effectColor = Color32.op_Implicit(Ink);
((Shadow)obj2).effectDistance = new Vector2(3f, -3f);
RectTransform val2 = ScoreBox.NewRect("Text", (Transform)(object)_rect);
ScoreBox.Stretch(val2);
val2.offsetMin = new Vector2(16f, 16f);
val2.offsetMax = new Vector2(-16f, -16f);
_text = ((Component)val2).gameObject.AddComponent<TextMeshProUGUI>();
((TMP_Text)_text).fontSize = 22f;
((Graphic)_text).color = Color32.op_Implicit(Ink);
((TMP_Text)_text).enableWordWrapping = true;
((TMP_Text)_text).alignment = (TextAlignmentOptions)257;
((TMP_Text)_text).richText = true;
((Graphic)_text).raycastTarget = false;
Hide();
}
public void SetFont(TMP_FontAsset font)
{
if ((Object)(object)font != (Object)null)
{
((TMP_Text)_text).font = font;
_shown = null;
}
}
public void Show(string text, Vector2 anchorBottomRight, float canvasBottom)
{
//IL_007c: 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_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
if (!((Component)_rect).gameObject.activeSelf)
{
((Component)_rect).gameObject.SetActive(true);
}
if (text != _shown)
{
_shown = text;
((TMP_Text)_text).text = text;
float num = ((TMP_Text)_text).GetPreferredValues(text, 408f, 0f).y + 32f;
_rect.sizeDelta = new Vector2(440f, num);
}
Vector2 val = anchorBottomRight + new Vector2(0f, -10f);
val.y = Mathf.Max(val.y, canvasBottom + _rect.sizeDelta.y + 10f);
_rect.anchoredPosition = val;
((Transform)_rect).SetAsLastSibling();
}
public void Hide()
{
if (((Component)_rect).gameObject.activeSelf)
{
((Component)_rect).gameObject.SetActive(false);
}
}
}
internal class ScreenShift
{
private readonly Transform _target;
private Vector3 _base;
private Vector3 _lastSet;
private bool _hasBase;
public bool Alive => (Object)(object)_target != (Object)null;
public Transform Target => _target;
public ScreenShift(Transform target)
{
_target = target;
}
public void Apply(float pixels)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: 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_0057: 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_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: 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)
if (!((Object)(object)_target == (Object)null))
{
Vector3 position = _target.position;
if (!_hasBase || position != _lastSet)
{
_base = position;
_hasBase = true;
}
Vector3 val = ((pixels <= 0f) ? _base : ShiftedDown(_base, pixels));
_target.position = val;
_lastSet = val;
}
}
public void Restore()
{
Apply(0f);
}
private Vector3 ShiftedDown(Vector3 world, float pixels)
{
//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)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: 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)
Camera val = CameraFor(_target);
if ((Object)(object)val == (Object)null)
{
return world - new Vector3(0f, pixels, 0f);
}
Vector3 val2 = val.WorldToScreenPoint(world);
val2.y -= pixels;
return val.ScreenToWorldPoint(val2);
}
internal static Camera CameraFor(Transform transform)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
Canvas componentInParent = ((Component)transform).GetComponentInParent<Canvas>();
if ((Object)(object)componentInParent != (Object)null)
{
componentInParent = componentInParent.rootCanvas;
if ((int)componentInParent.renderMode == 0)
{
return null;
}
if (!((Object)(object)componentInParent.worldCamera != (Object)null))
{
return Camera.main;
}
return componentInParent.worldCamera;
}
return Camera.main;
}
}
internal struct ShotDamage
{
public int PegTally;
public int CritCount;
public float DamageMultiplier;
public int DamageBonus;
public long PerPeg;
public long Total;
private static readonly FieldRef<BattleController, int> PegTallyRef = AccessTools.FieldRefAccess<BattleController, int>("_pegMultiplierDamageTally");
private static readonly FieldRef<BattleController, float> DamageMultiplierRef = AccessTools.FieldRefAccess<BattleController, float>("_damageMultiplier");
private static readonly FieldRef<BattleController, int> DamageBonusRef = AccessTools.FieldRefAccess<BattleController, int>("_damageBonus");
private static readonly FieldRef<AttackManager, Attack> AttackRef = AccessTools.FieldRefAccess<AttackManager, Attack>("_attack");
public bool SameInputs(ShotDamage other)
{
if (PegTally == other.PegTally && CritCount == other.CritCount && DamageMultiplier == other.DamageMultiplier)
{
return DamageBonus == other.DamageBonus;
}
return false;
}
public static ShotDamage ReadInputs(BattleController battle)
{
return new ShotDamage
{
PegTally = PegTallyRef.Invoke(battle),
CritCount = BattleController.criticalHitCount,
DamageMultiplier = DamageMultiplierRef.Invoke(battle),
DamageBonus = DamageBonusRef.Invoke(battle)
};
}
public void Calculate(BattleController battle)
{
AttackManager attackManager = battle.attackManager;
Attack val = (((Object)(object)attackManager != (Object)null) ? AttackRef.Invoke(attackManager) : null);
if ((Object)(object)val == (Object)null)
{
PerPeg = 0L;
Total = 0L;
}
else
{
PerPeg = val.GetModifiedDamagePerPeg(CritCount, false);
Total = attackManager.GetCurrentDamage(PegTally, DamageMultiplier, (long)DamageBonus, CritCount, false);
}
}
}
}
namespace PeglinBalatroScore.Core
{
public struct BossFightSpawn
{
public int Turn;
public bool IsBoss;
public float StartingHealth;
public float StartingHealthFirstCruciball;
public BossFightSpawn(int turn, bool isBoss, float startingHealth, float startingHealthFirstCruciball)
{
Turn = turn;
IsBoss = isBoss;
StartingHealth = startingHealth;
StartingHealthFirstCruciball = startingHealthFirstCruciball;
}
}
public static class BossHealthRules
{
public const int ImprovedBossHealthCruciball = 10;
public static float MaxHealth(BossFightSpawn spawn, int cruciballLevel)
{
if (cruciballLevel < 10)
{
return spawn.StartingHealth;
}
return spawn.StartingHealthFirstCruciball;
}
public static long TargetHealth(IList<BossFightSpawn> spawns, int cruciballLevel)
{
float num = 0f;
float num2 = 0f;
foreach (BossFightSpawn spawn in spawns)
{
float val = MaxHealth(spawn, cruciballLevel);
num2 = Math.Max(num2, val);
if (spawn.IsBoss)
{
num = Math.Max(num, val);
}
}
float num3 = ((num > 0f) ? num : num2);
if (!(num3 > 0f))
{
return 0L;
}
return (long)Math.Ceiling(num3);
}
}
public class FireSimulation
{
public const double MinReach = 0.12;
private readonly float[] _heat;
private readonly Random _random;
public int Width { get; }
public int Height { get; }
public int ReferenceHeight { get; }
public float this[int x, int y] => _heat[y * Width + x];
public FireSimulation(int width, int height, int seed, int referenceHeight = 0)
{
if (width <= 0 || height <= 0)
{
throw new ArgumentOutOfRangeException((width <= 0) ? "width" : "height");
}
Width = width;
Height = height;
ReferenceHeight = ((referenceHeight > 0) ? referenceHeight : height);
_heat = new float[width * height];
_random = new Random(seed);
}
public void Step(double intensity)
{
bool flag = intensity > 0.0;
for (int i = 0; i < Width; i++)
{
_heat[i] = (flag ? ((float)(0.85 + _random.NextDouble() * 0.15)) : 0f);
}
double num = (double)ReferenceHeight * (0.12 + 0.88 * Math.Max(0.0, intensity));
double num2 = (flag ? (1.0 / num) : 1.0);
for (int num3 = Height - 1; num3 >= 1; num3--)
{
for (int j = 0; j < Width; j++)
{
int num4 = j + _random.Next(-1, 2);
if (num4 < 0 || num4 >= Width)
{
_heat[num3 * Width + j] = 0f;
continue;
}
float num5 = _heat[(num3 - 1) * Width + num4] - (float)(_random.NextDouble() * 2.0 * num2);
_heat[num3 * Width + j] = ((num5 > 0f) ? num5 : 0f);
}
}
}
public void CopyFrom(FireSimulation other)
{
if (other.Width != Width)
{
throw new ArgumentException("Fire can only be copied between simulations of the same width.", "other");
}
Array.Copy(other._heat, _heat, Math.Min(other._heat.Length, _heat.Length));
}
public float RowHeat(int y)
{
float num = 0f;
for (int i = 0; i < Width; i++)
{
num += _heat[y * Width + i];
}
return num / (float)Width;
}
public void Clear()
{
Array.Clear(_heat, 0, _heat.Length);
}
}
public static class FlameCurve
{
public const double StartRatio = 0.1;
public const double StartRatioPerFloor = 0.05;
public const double OverflowPerTenfold = 2.0;
public static double StartRatioForFloor(int floor)
{
return Math.Min(0.1, (double)Math.Max(1, floor) * 0.05);
}
public static double Ratio(long score, long target)
{
if (target <= 0 || score <= 0)
{
return 0.0;
}
return (double)score / (double)target;
}
public static double Intensity(long score, long target, double startRatio = 0.1)
{
double num = Ratio(score, target);
if (num < startRatio)
{
return 0.0;
}
if (num < 1.0)
{
double num2 = (num - startRatio) / (1.0 - startRatio);
return num2 * num2 * (3.0 - 2.0 * num2);
}
return 1.0 + Math.Log10(num) * 2.0;
}
public static bool CrossedTarget(long previousScore, long score, long target)
{
if (target > 0 && previousScore < target)
{
return score >= target;
}
return false;
}
}
public static class ScoreExplanation
{
public static string Build(long? lastShotTotal, bool lastShotWasHeal)
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine("<b>How your shot adds up</b>");
stringBuilder.AppendLine();
stringBuilder.AppendLine("<b>Left:</b> what the pegs your orb has hit are worth. Most pegs add 1, but some pegs and relics make a hit worth more.");
stringBuilder.AppendLine();
stringBuilder.AppendLine("<b>Right:</b> your orb's damage per peg, or its crit damage once a crit has been triggered.");
stringBuilder.AppendLine();
stringBuilder.Append("The final total is always what the game itself works out, so it can be a little off from left x right because of relics, bonuses and other effects.");
if (lastShotTotal.HasValue)
{
stringBuilder.AppendLine();
stringBuilder.AppendLine();
stringBuilder.Append(LastShot(lastShotTotal.Value, lastShotWasHeal));
}
return stringBuilder.ToString();
}
public static string LastShot(long total, bool wasHeal)
{
return "<b>Last shot:</b> " + ScoreFormat.Format(total) + " " + (wasHeal ? "healing" : "damage");
}
}
public static class ScoreFormat
{
public const long ScientificFrom = 100000000L;
public static string Format(long value)
{
if (value <= 0)
{
return "0";
}
if (value == long.MaxValue)
{
return "∞";
}
if (value < 100000000)
{
return value.ToString("N0", CultureInfo.InvariantCulture);
}
return value.ToString("0.00e0", CultureInfo.InvariantCulture);
}
}
public enum ScorePhase
{
Ready,
Counting,
Result
}
public class ScoreTracker
{
public ScorePhase Phase { get; private set; }
public long Pegs { get; private set; }
public long PerPeg { get; private set; }
public long Total { get; private set; }
public bool IsHeal { get; private set; }
public float ResultSecondsLeft { get; private set; }
public long? LastShotTotal { get; private set; }
public bool LastShotWasHeal { get; private set; }
public float ResultHoldSeconds { get; set; } = 3f;
public void BeginShot(bool isHeal)
{
Zero();
IsHeal = isHeal;
Phase = ScorePhase.Counting;
}
public void Update(long pegs, long perPeg, long total)
{
if (Phase == ScorePhase.Counting)
{
if (pegs <= 0)
{
Pegs = 0L;
PerPeg = 0L;
}
else
{
Pegs = pegs;
PerPeg = Math.Max(0L, perPeg);
}
Total = Math.Max(0L, total);
}
}
public void CompleteShot(long total)
{
if (Phase == ScorePhase.Counting)
{
Total = Math.Max(0L, total);
Phase = ScorePhase.Result;
ResultSecondsLeft = ResultHoldSeconds;
LastShotTotal = Total;
LastShotWasHeal = IsHeal;
}
}
public void RefineResult(long total)
{
if (Phase == ScorePhase.Result)
{
Total = Math.Max(0L, total);
LastShotTotal = Total;
}
}
public void Tick(float unscaledDeltaTime)
{
if (Phase == ScorePhase.Result)
{
ResultSecondsLeft -= unscaledDeltaTime;
if (ResultSecondsLeft <= 0f)
{
Clear();
}
}
}
public void Clear()
{
Zero();
IsHeal = false;
Phase = ScorePhase.Ready;
}
private void Zero()
{
Pegs = 0L;
PerPeg = 0L;
Total = 0L;
ResultSecondsLeft = 0f;
}
}
}