Decompiled source of MayheimHelheimExpedition v0.14.0

plugins\MayheimHelheimExpedition\MayheimHelheimExpedition.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using MayheimHelheim.Abertura;
using MayheimHelheim.Acampamento;
using MayheimHelheim.Chefes;
using MayheimHelheim.Corrupcao;
using MayheimHelheim.Criaturas;
using MayheimHelheim.Expedicao;
using MayheimHelheim.Itens;
using MayheimHelheim.Mundo;
using MayheimHelheim.Testing;
using MayheimHelheim.Viagem;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using ValheimMMO.Cities;
using ValheimMMO.Config;
using ValheimMMO.Hunts;
using ValheimMMO.Merchant;
using ValheimMMO.Progression;
using ValheimMMO.Quests;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: IgnoresAccessChecksTo("ValheimMMO")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MayheimHelheimExpedition")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("MayheimHelheimExpedition")]
[assembly: AssemblyTitle("MayheimHelheimExpedition")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: UnverifiableCode]
[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 MayheimHelheim
{
	internal static class Cfg
	{
		internal const string SepulcralNoCatalogo = "Helheim_EspadaSepulcral=9:58000,Helheim_MachadoSepulcral=9:55000,Helheim_MacaSepulcral=9:58000,Helheim_LancaSepulcral=9:52000,Helheim_FacaSepulcral=9:49000,Helheim_AdagasSepulcrais=9:49000,Helheim_AtgeirSepulcral=9:62000,Helheim_MontanteSepulcral=9:72000,Helheim_MarretaSepulcral=9:72000,Helheim_ArcoSepulcral=9:62000,Helheim_BestaSepulcral=9:68000,Helheim_CajadoSepulcral=9:98000,Helheim_EscudoSepulcral=9:44000,Helheim_ElmoSepulcral=9:65000,Helheim_PeitoralSepulcral=9:72000,Helheim_GrevasSepulcrais=9:78000,Helheim_CapaSepulcral=9:39000,Helheim_CapuzSepulcral=9:55000,Helheim_GibaoSepulcral=9:65000,Helheim_CalcasSepulcrais=9:65000,Helheim_MantoSepulcral=9:45000,Helheim_CapeloSepulcral=9:52000,Helheim_TunicaSepulcral=9:62000,Helheim_PerneirasSepulcrais=9:62000,Helheim_MortalhaSepulcral=9:55000";

		public static ConfigEntry<bool> Ativo;

		public static ConfigEntry<float> RaioInterno;

		public static ConfigEntry<float> RaioExterno;

		public static ConfigEntry<float> Penhasco;

		public static ConfigEntry<string> Setores;

		public static ConfigEntry<string> VegetacaoPermitida;

		public static ConfigEntry<string> VegetacaoProibida;

		public static ConfigEntry<string> AmbienteBase;

		public static ConfigEntry<float> Brilho;

		public static ConfigEntry<float> Nevoa;

		public static ConfigEntry<float> RaidMinutos;

		public static ConfigEntry<bool> CorrupcaoAtiva;

		public static ConfigEntry<float> CorrupcaoBase;

		public static ConfigEntry<float> CorrupcaoEscuro;

		public static ConfigEntry<float> CorrupcaoGolpe;

		public static ConfigEntry<float> CorrupcaoLuz;

		public static ConfigEntry<float> CorrupcaoAcampamento;

		public static ConfigEntry<float> CorrupcaoFora;

		public static ConfigEntry<float> CorrupcaoDanoConsumido;

		public static ConfigEntry<string> CorrupcaoPorTier;

		public static ConfigEntry<string> CriaturasStats;

		public static ConfigEntry<bool> CriaturasNascem;

		public static ConfigEntry<float> EquipDano;

		public static ConfigEntry<float> EquipArmadura;

		public static ConfigEntry<float> EquipPorTier;

		public static ConfigEntry<float> DrenoCorrupcao;

		public static ConfigEntry<float> ChamaNegraDano;

		public static ConfigEntry<float> ChamaNegraSegundos;

		public static ConfigEntry<float> InfestacaoDano;

		public static ConfigEntry<float> InfestacaoSegundos;

		public static ConfigEntry<float> InfestacaoRaio;

		public static ConfigEntry<float> SobrecargaDano;

		public static ConfigEntry<float> SobrecargaRaio;

		public static ConfigEntry<float> SobrecargaCorrupcao;

		public static ConfigEntry<float> PactoMaximo;

		public static ConfigEntry<int> InfestacaoAlvos;

		public static ConfigEntry<int> SobrecargaGolpes;

		public static ConfigEntry<float> SetCorrupcao;

		public static ConfigEntry<float> SetPesadoRegen;

		public static ConfigEntry<float> SetAgilVelocidade;

		public static ConfigEntry<float> SetAgilStamina;

		public static ConfigEntry<float> SetMagoEitr;

		public static ConfigEntry<float> SetMagoDano;

		public static ConfigEntry<string> LojaCatalogo;

		public static ConfigEntry<string> LojaPrecosVenda;

		public static ConfigEntry<string> MissaoValores;

		public static ConfigEntry<bool> VersionCheck;

		public static ConfigEntry<bool> MorteSemPerda;

		public static ConfigEntry<bool> MontariaAtiva;

		public static ConfigEntry<float> MontariaVelocidade;

		public static ConfigEntry<float> MontariaPorTier;

		public static ConfigEntry<float> MontariaDistancia;

		internal const string SecRede = "9 - Rede";

		internal static void Bind(ConfigFile cfg)
		{
			Ativo = cfg.Bind<bool>("1 - Geral", "Ativo", true, "Liga o Helheim. Desligado, o mundo fica como o do jogo base (o anel volta a ser abismo).");
			RaioInterno = cfg.Bind<float>("2 - Anel", "RaioInterno", 10900f, "Onde o anel comeca (m do centro do mundo). Entre 10.500 (borda do jogo) e este raio fica o abismo.");
			RaioExterno = cfg.Bind<float>("2 - Anel", "RaioExterno", 12200f, "Onde o anel termina (m). Maximo 12.250: alem disso o mapa e os dados de bioma do jogo nao alcancam.");
			Penhasco = cfg.Bind<float>("2 - Anel", "Penhasco", 90f, "Largura (m) da queda do anel para o abismo, nas duas bordas.");
			Setores = cfg.Bind<string>("2 - Anel", "Setores", "9=0-100,10=100-200,11=200-300,12=300-360", "Tier de cada fatia do anel, em graus (0 = norte, sentido horario). O acampamento fica no inicio do tier 9.");
			VegetacaoPermitida = cfg.Bind<string>("2 - Anel", "VegetacaoPermitida", "rock,Rock,stubbe,Stubbe,boulder,Boulder,MineRock", "Vegetacao do jogo base que pode nascer no anel: entra se o nome tiver um destes trechos. O resto do jogo base nao nasce la.");
			VegetacaoProibida = cfg.Bind<string>("2 - Anel", "VegetacaoProibida", "copper,silver,Tin,Obsidian,Lava,Pickable,ice_,deepnorth,Pillar,cliff_", "Mesmo com nome permitido, fica de fora se tiver um destes trechos: minerio, gelo, lava e pedra coletavel nao nascem de graca no Helheim.");
			AmbienteBase = cfg.Bind<string>("3 - Ambiente", "AmbienteBase", "Ashlands_ashrain,Ashlands_misty,Darklands_dark,Twilight_Clear,Clear", "Ambiente do jogo usado de base para o ceu do Helheim (o primeiro que existir). Particulas, sons e vento vem dele.");
			Brilho = cfg.Bind<float>("3 - Ambiente", "Brilho", 1f, "Brilho do Helheim: 1 = o padrao (dia um pouco mais escuro que o do jogo base, noite escura mas visivel). 0,5 = metade, 1,5 = mais claro.");
			Nevoa = cfg.Bind<float>("3 - Ambiente", "Nevoa", 0.004f, "Densidade da nevoa no Helheim. Baixa de proposito: o terror vem do escuro, nao da nevoa.");
			RaidMinutos = cfg.Bind<float>("4 - Abertura", "RaidMinutos", 10f, "Duracao da raid de invasao que abre o portal (minutos de tempo corrido, contando so com alguem perto do templo).");
			CorrupcaoAtiva = cfg.Bind<bool>("5 - Corrupcao", "Ativa", true, "Liga a Corrupcao: a barra de 0 a 100 que sobe enquanto voce esta no Helheim.");
			CorrupcaoBase = cfg.Bind<float>("5 - Corrupcao", "SobeBase", 0.2f, "Quanto sobe por segundo no Helheim, de dia, sem luz por perto (0,2 = de 0 a 100 em ~8 min).");
			CorrupcaoEscuro = cfg.Bind<float>("5 - Corrupcao", "MultiplicadorNoEscuro", 3f, "Multiplicador da subida a noite sem tocha ou lanterna na mao.");
			CorrupcaoGolpe = cfg.Bind<float>("5 - Corrupcao", "PorGolpe", 2f, "Quanto sobe a cada golpe recebido de criatura do Helheim.");
			CorrupcaoLuz = cfg.Bind<float>("5 - Corrupcao", "DescePertoDoFogo", 1f, "Quanto desce por segundo perto de fogo (fogueira, braseiro, tocha de parede).");
			CorrupcaoAcampamento = cfg.Bind<float>("5 - Corrupcao", "DesceNoAcampamento", 3f, "Quanto desce por segundo no acampamento da expedicao.");
			CorrupcaoFora = cfg.Bind<float>("5 - Corrupcao", "DesceForaDoHelheim", 2f, "Quanto desce por segundo fora do Helheim.");
			CorrupcaoPorTier = cfg.Bind<string>("5 - Corrupcao", "MultiplicadorPorTier", "9=1,10=1.25,11=1.5,12=2", "Multiplicador da subida em cada tier.");
			CorrupcaoDanoConsumido = cfg.Bind<float>("5 - Corrupcao", "DanoConsumido", 0.02f, "Com a barra em 100 (Consumido): dano por segundo, em fracao da vida maxima.");
			CriaturasStats = cfg.Bind<string>("6 - Criaturas", "VidaEDano", "Helheim_Carnical=2400:250;Helheim_Arqueiro=1900:225;Helheim_Espectro=2900:250;Helheim_Guardiao=6000:300;Helheim_Colosso=15000:370;Helheim_Arauto=30000:335;Helheim_Lobo=1800:230;Helheim_Abutre=1200:190;Helheim_Lebre=250:0;Helheim_Tecelao=3100:280;Helheim_Carrapato=1300:180;Helheim_Soldado=7800:335;Helheim_Gjall=19500:400;Helheim_Mineiro=4050:315;Helheim_Besteiro=3200:280;Helheim_Fundidor=3200:300;Helheim_Morgen=25000:460;Helheim_Asksvin=2500:250;Helheim_Condenado=5300:350;Helheim_Contorcido=2400:260;Helheim_Lodo=3500:300;Helheim_Valquiria=33000:520;Helheim_Alma=4500:330", "Vida e dano por golpe (bruto) de cada criatura do Helheim: Prefab=vida:dano. Vale para as criaturas que nascerem depois da mudanca. Criatura fora desta lista usa o padrao do mod.");
			CriaturasNascem = cfg.Bind<bool>("6 - Criaturas", "NascemNoErmos", true, "As criaturas do Helheim nascem pelos tiers do anel (fora do acampamento).");
			EquipDano = cfg.Bind<float>("7 - Equipamento", "MultiplicadorDano", 1.35f, "Dano da linha Sepulcral sobre a arma de ouro do Deep North que serviu de base.");
			EquipArmadura = cfg.Bind<float>("7 - Equipamento", "MultiplicadorArmadura", 1.3f, "Armadura e bloqueio da linha Sepulcral sobre a peca pesada do Deep North que serviu de base.");
			EquipPorTier = cfg.Bind<float>("7 - Equipamento", "MultiplicadorPorTier", 1.12f, "Cada linha de equipamento acima da Sepulcral (tier 10, 11 e 12) tem dano e armadura este tanto maior que a anterior.");
			ChamaNegraDano = cfg.Bind<float>("7 - Equipamento", "ChamaNegraDano", 0.05f, "Traço Chama Negra das armas Sepulcrais: fracao do dano do golpe que o alvo queima de novo (dano continuo).");
			ChamaNegraSegundos = cfg.Bind<float>("7 - Equipamento", "ChamaNegraSegundos", 5f, "Traço Chama Negra: em quantos segundos o alvo queima esse dano. Golpes seguidos somam e renovam o tempo.");
			DrenoCorrupcao = cfg.Bind<float>("7 - Equipamento", "DrenoCorrupcao", 0.5f, "Corrupcao somada a cada golpe de arma Sepulcral acertado no Helheim (o preco do poder).");
			InfestacaoDano = cfg.Bind<float>("7 - Equipamento", "InfestacaoDano", 0.04f, "Traco Infestacao (armas da Ninhada): fracao do dano do golpe que as larvas causam como veneno.");
			InfestacaoSegundos = cfg.Bind<float>("7 - Equipamento", "InfestacaoSegundos", 6f, "Traco Infestacao: em quantos segundos as larvas causam esse dano.");
			InfestacaoRaio = cfg.Bind<float>("7 - Equipamento", "InfestacaoRaio", 6f, "Traco Infestacao: alvo que morre infestado solta as larvas nos inimigos a ate este raio (m).");
			InfestacaoAlvos = cfg.Bind<int>("7 - Equipamento", "InfestacaoAlvos", 3, "Traco Infestacao: em quantos inimigos as larvas pulam quando o alvo morre.");
			SobrecargaGolpes = cfg.Bind<int>("7 - Equipamento", "SobrecargaGolpes", 5, "Traco Sobrecarga (armas de Brasa Negra): golpes para carregar a arma; o golpe seguinte descarrega.");
			SobrecargaDano = cfg.Bind<float>("7 - Equipamento", "SobrecargaDano", 0.6f, "Traco Sobrecarga: dano de fogo da descarga em volta do alvo, em fracao do golpe que descarregou.");
			SobrecargaRaio = cfg.Bind<float>("7 - Equipamento", "SobrecargaRaio", 4f, "Traco Sobrecarga: raio da descarga (m).");
			SobrecargaCorrupcao = cfg.Bind<float>("7 - Equipamento", "SobrecargaCorrupcao", 2f, "Traco Sobrecarga: Corrupcao a mais em quem descarrega.");
			PactoMaximo = cfg.Bind<float>("7 - Equipamento", "PactoMaximo", 0.3f, "Traco Pacto (armas de Hel): dano a mais com a Corrupcao em 100 (proporcional abaixo disso).");
			SetCorrupcao = cfg.Bind<float>("7 - Equipamento", "ConjuntoMenosCorrupcao", 0.15f, "Qualquer conjunto Sepulcral completo (4 pecas): fracao a menos de Corrupcao ganha.");
			SetPesadoRegen = cfg.Bind<float>("7 - Equipamento", "BastiaoRegenVida", 0.15f, "Conjunto Bastiao (pesado): regeneracao de vida a mais (alem da resistencia a dano fisico).");
			SetAgilVelocidade = cfg.Bind<float>("7 - Equipamento", "PassoVelocidade", 0.1f, "Conjunto Passo (agil): velocidade a mais.");
			SetAgilStamina = cfg.Bind<float>("7 - Equipamento", "PassoStamina", 0.25f, "Conjunto Passo (agil): stamina a menos para correr e esquivar (60% disso para atacar).");
			SetMagoEitr = cfg.Bind<float>("7 - Equipamento", "VeuRegenEitr", 0.3f, "Conjunto Veu (mago): regeneracao de eitr a mais.");
			SetMagoDano = cfg.Bind<float>("7 - Equipamento", "VeuDanoMagia", 0.15f, "Conjunto Veu (mago): dano de magia elemental a mais.");
			LojaCatalogo = cfg.Bind<string>("8 - Acampamento", "Catalogo", "Helheim_EspadaSepulcral=9:58000,Helheim_MachadoSepulcral=9:55000,Helheim_MacaSepulcral=9:58000,Helheim_LancaSepulcral=9:52000,Helheim_FacaSepulcral=9:49000,Helheim_AdagasSepulcrais=9:49000,Helheim_AtgeirSepulcral=9:62000,Helheim_MontanteSepulcral=9:72000,Helheim_MarretaSepulcral=9:72000,Helheim_ArcoSepulcral=9:62000,Helheim_BestaSepulcral=9:68000,Helheim_CajadoSepulcral=9:98000,Helheim_EscudoSepulcral=9:44000,Helheim_ElmoSepulcral=9:65000,Helheim_PeitoralSepulcral=9:72000,Helheim_GrevasSepulcrais=9:78000,Helheim_CapaSepulcral=9:39000,Helheim_CapuzSepulcral=9:55000,Helheim_GibaoSepulcral=9:65000,Helheim_CalcasSepulcrais=9:65000,Helheim_MantoSepulcral=9:45000,Helheim_CapeloSepulcral=9:52000,Helheim_TunicaSepulcral=9:62000,Helheim_PerneirasSepulcrais=9:62000,Helheim_MortalhaSepulcral=9:55000,Helheim_LanternaPurificacao=9:25000,Helheim_HidromelPurificacao=9:600" + Equipamento.CatalogoDosTiers("Helheim_EspadaSepulcral=9:58000,Helheim_MachadoSepulcral=9:55000,Helheim_MacaSepulcral=9:58000,Helheim_LancaSepulcral=9:52000,Helheim_FacaSepulcral=9:49000,Helheim_AdagasSepulcrais=9:49000,Helheim_AtgeirSepulcral=9:62000,Helheim_MontanteSepulcral=9:72000,Helheim_MarretaSepulcral=9:72000,Helheim_ArcoSepulcral=9:62000,Helheim_BestaSepulcral=9:68000,Helheim_CajadoSepulcral=9:98000,Helheim_EscudoSepulcral=9:44000,Helheim_ElmoSepulcral=9:65000,Helheim_PeitoralSepulcral=9:72000,Helheim_GrevasSepulcrais=9:78000,Helheim_CapaSepulcral=9:39000,Helheim_CapuzSepulcral=9:55000,Helheim_GibaoSepulcral=9:65000,Helheim_CalcasSepulcrais=9:65000,Helheim_MantoSepulcral=9:45000,Helheim_CapeloSepulcral=9:52000,Helheim_TunicaSepulcral=9:62000,Helheim_PerneirasSepulcrais=9:62000,Helheim_MortalhaSepulcral=9:55000"), "O que o Mercador da Expedicao vende, no formato do Mayheim: prefab=tier:ouro (ouro de UMA unidade; comida e pocao vao em lote). Os itens de um tier so aparecem depois que o chefe do tier anterior morreu (o 9 vem com o portal). As pocoes, o mapa e os outros itens do Mayheim continuam a venda, como em toda cidade.");
			LojaPrecosVenda = cfg.Bind<string>("8 - Acampamento", "PrecosVenda", "Helheim_OssoCorrompido=300,Helheim_EssenciaSombria=1200,Helheim_OlhoVazio=2500,Helheim_MinerioSepulcral=500,Helheim_FerroSepulcral=1200,Helheim_CoroaPartida=6000,Helheim_TrofeuRei=65000", "Quanto o mercador PAGA por unidade do loot do Helheim (prefab=ouro), como o PrecosVenda do Mayheim. Item que ele tambem vende paga no maximo o teto do Mayheim (80% do preco da loja).");
			MissaoValores = cfg.Bind<string>("8 - Acampamento", "ValoresDeMissao", "Helheim_OssoCorrompido=40,Helheim_EssenciaSombria=150,Helheim_MinerioSepulcral=260,Helheim_FerroSepulcral=400", "Valor de cada material nas missoes de entrega do Emissario (recompensa = valor x quantidade x 1,5, como no Mayheim). So os materiais listados aqui entram nas missoes de entrega.");
			MorteSemPerda = cfg.Bind<bool>("10 - Expedicao", "MorteSemPerda", true, "Morrer do lado de Helheim nao deixa lapide nem tira habilidade ou XP: o jogador renasce no acampamento com tudo o que tinha.");
			MontariaAtiva = cfg.Bind<bool>("10 - Expedicao", "Montarias", true, "As Redeas (slot de utilidade) chamam a montaria do tier do lado de Helheim.");
			MontariaVelocidade = cfg.Bind<float>("10 - Expedicao", "MontariaVelocidade", 10f, "Velocidade de corrida (m/s) do Mamute do Ermos (tier 9). O jogador correndo faz uns 7.");
			MontariaPorTier = cfg.Bind<float>("10 - Expedicao", "MontariaPorTier", 1.1f, "Cada montaria acima da do Ermos corre este tanto mais que a anterior.");
			MontariaDistancia = cfg.Bind<float>("10 - Expedicao", "MontariaDistancia", 60f, "Montaria mais longe que isto do dono (um portal) some e volta ao lado dele.");
			VersionCheck = cfg.Bind<bool>("9 - Rede", "VersionCheck", true, "Servidor com o Helheim recusa cliente sem o mod ou com outra versao (a geracao do anel tem de ser igual nos dois lados).");
		}
	}
	[BepInPlugin("com.mayheim.helheim", "MayheimHelheimExpedition", "0.14.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginId = "com.mayheim.helheim";

		public const string PluginName = "MayheimHelheimExpedition";

		public const string PluginVersion = "0.14.0";

		internal static ManualLogSource Log;

		internal static Plugin Instance;

		internal static readonly List<string> PatchesComFalha = new List<string>();

		private Harmony _harmony;

		private void Awake()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Cfg.Bind(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony("com.mayheim.helheim");
			PatchIsolated();
			try
			{
				Adagas.Integra(_harmony);
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("[Adagas] integracao com as Adagas Cruzadas falhou: " + ex.Message));
			}
			HelheimTests.Registrar();
			AberturaTests.Registrar();
			CorrupcaoTests.Registrar();
			ErmosTests.Registrar();
			ForjaTests.Registrar();
			ReiTests.Registrar();
			MaeTests.Registrar();
			ForjadorTests.Registrar();
			HelTests.Registrar();
			LuzTests.Registrar();
			TelaTests.Registrar();
			DiagnosticoTests.Registrar();
			GaleriaTests.Registrar();
			MedidaTests.Registrar();
			AcampamentoTests.Registrar();
			VisualTests.Registrar();
			RetratoTests.Registrar();
			ExpedicaoTests.Registrar();
			TracosTests.Registrar();
			Vigia.Liga();
			Rastro.Liga(_harmony);
			Log.LogInfo((object)"MayheimHelheimExpedition v0.14.0 carregado.");
		}

		private void PatchIsolated()
		{
			int num = 0;
			PatchesComFalha.Clear();
			Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(typeof(Plugin).Assembly);
			foreach (Type type in typesFromAssembly)
			{
				if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: true).Length != 0)
				{
					try
					{
						_harmony.CreateClassProcessor(type).Patch();
						num++;
					}
					catch (Exception ex)
					{
						PatchesComFalha.Add(type.FullName + ": " + ex.Message);
						Log.LogError((object)("Falha ao aplicar patch " + type.FullName + ": " + ex.Message));
					}
				}
			}
			Log.LogInfo((object)($"Patches aplicados: {num} classes" + ((PatchesComFalha.Count > 0) ? $", {PatchesComFalha.Count} com falha." : ".")));
		}

		private void Update()
		{
			Vigia.Bate();
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
}
namespace MayheimHelheim.Viagem
{
	internal static class Rota
	{
		internal static Vector3 PontoDoTier(int tier)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_000f: Unknown result type (might be due to invalid IL or missing references)
			//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)
			if (tier == 9)
			{
				return Objetos.Saida(Objetos.PortalDoAcampamento(), Objetos.GiroDoAcampamento()) + Vector3.up;
			}
			float num = Anel.InicioDoTier(tier);
			float num2 = Anel.FimDoTier(tier);
			Vector3 result = Anel.PontoNoMeio(num + Mathf.Min(6f, (num2 - num) * 0.1f));
			result.y += 2f;
			return result;
		}

		internal static Vector3 Templo()
		{
			//IL_004a: 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_0026: 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)
			Vector3 val = default(Vector3);
			if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetLocationIcon(Game.instance.m_StartLocation, ref val))
			{
				return val + Vector3.up * 2f;
			}
			return new Vector3(0f, 40f, 0f);
		}

		internal static bool Leva(Player p, Vector3 destino)
		{
			//IL_000c: 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)
			if ((Object)(object)p == (Object)null)
			{
				return false;
			}
			return ((Character)p).TeleportTo(destino, ((Component)p).transform.rotation, true);
		}
	}
	internal static class Comandos
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static ConsoleEvent <>9__1_0;

			internal void <Registrar>b__1_0(ConsoleEventArgs args)
			{
				//IL_009d: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0106: Unknown result type (might be due to invalid IL or missing references)
				//IL_0114: Unknown result type (might be due to invalid IL or missing references)
				//IL_011f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0264: Unknown result type (might be due to invalid IL or missing references)
				//IL_021e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0223: Unknown result type (might be due to invalid IL or missing references)
				//IL_0227: Unknown result type (might be due to invalid IL or missing references)
				//IL_0243: Unknown result type (might be due to invalid IL or missing references)
				//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
				Terminal context = args.Context;
				string text = ((args.Length >= 2) ? args[1].ToLowerInvariant() : "info");
				Player localPlayer = Player.m_localPlayer;
				if (text == "teste")
				{
					if (!T.Disponivel)
					{
						context.AddString("A suite de teste precisa do Mayheim instalado.");
						return;
					}
					T.Iniciar((args.Length >= 3) ? args[2] : "helheim");
					context.AddString("Suite iniciada; resultado no log com o prefixo [MMOTEST].");
					return;
				}
				if ((Object)(object)localPlayer == (Object)null)
				{
					context.AddString("Entre em um mundo primeiro.");
					return;
				}
				if (text == "info")
				{
					Vector3 position = ((Component)localPlayer).transform.position;
					float num = Anel.Raio(position.x, position.z);
					context.AddString(string.Format("Helheim {0} · anel de {1:0} a {2:0} m · voce a {3:0} m do centro.", Estado.Ativo ? "LIGADO" : "dormente", Anel.Rin, Anel.Rout, num));
					if (Anel.NoAnel(position))
					{
						object arg = Anel.Tier(position);
						string arg2 = Setores.Nome(Anel.Tier(position));
						EnvMan instance = EnvMan.instance;
						context.AddString($"Voce esta no tier {arg}: {arg2} (ambiente {((instance == null) ? null : instance.GetCurrentEnvironment()?.m_name)}).");
					}
					if ((Object)(object)Minimap.instance != (Object)null)
					{
						context.AddString($"Mapa: {Minimap.instance.m_textureSize} px x {Minimap.instance.m_pixelSize} m = raio {(float)Minimap.instance.m_textureSize * Minimap.instance.m_pixelSize / 2f:0} m.");
					}
					return;
				}
				if (!Estado.Ativo)
				{
					context.AddString("Helheim dormente neste mundo (servidor sem o mod).");
					return;
				}
				if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer())
				{
					context.AddString("Na prova de conceito, a viagem por comando e so no mundo local.");
					return;
				}
				switch (text)
				{
				case "ir":
				{
					int result = 9;
					if (args.Length >= 3 && !int.TryParse(args[2], out result))
					{
						context.AddString("Uso: helheim ir [9-12]");
						break;
					}
					Vector3 val2 = Rota.PontoDoTier(result);
					context.AddString(Rota.Leva(localPlayer, val2) ? $"Indo para {Setores.Nome(result)} ({val2:F0})." : "O jogo recusou o teleporte agora.");
					break;
				}
				case "voltar":
					context.AddString(Rota.Leva(localPlayer, Rota.Templo()) ? "Voltando ao templo." : "O jogo recusou o teleporte agora.");
					break;
				case "estado":
				{
					int encontradas;
					int num3 = Templo.PedrasAcesas(out encontradas);
					RandEventSystem instance3 = RandEventSystem.instance;
					RandomEvent val3 = ((instance3 != null) ? instance3.GetCurrentRandomEvent() : null);
					context.AddString($"Pedras do templo: {num3} de {Templo.Pedras.Length} acesas ({encontradas} encontradas).");
					context.AddString("Invasao: " + (Chaves.EmInvasao ? "SIM" : "nao") + " · Portal aberto: " + (Chaves.EstaAberto ? "SIM" : "nao") + ((val3 != null && val3.m_name == "helheim_invasao") ? $" · raid {val3.m_time / 60f:0.0} de {val3.m_duration / 60f:0} min" : ""));
					break;
				}
				case "invasao":
					Templo.ComecaInvasao();
					context.AddString("Invasao iniciada (teste).");
					break;
				case "abrir":
					Templo.Abre();
					context.AddString("Portal de Helheim aberto (teste, sem raid).");
					break;
				case "resetar":
				{
					RandEventSystem instance2 = RandEventSystem.instance;
					RandomEvent val = ((instance2 != null) ? instance2.GetCurrentRandomEvent() : null);
					if (val != null && val.m_name == "helheim_invasao")
					{
						RandEventSystem.instance.ResetRandomEvent();
					}
					if (Templo.Centro(out var pos))
					{
						Raid.Recolhe(pos, 250f);
					}
					int num2 = Objetos.RemoveTudo();
					Chaves.ApagaTudo();
					context.AddString($"Abertura desfeita (teste): {num2} objeto(s) removido(s), chaves apagadas.");
					break;
				}
				default:
					context.AddString("Uso: helheim [info | estado | ir [9-12] | voltar | invasao | abrir | resetar | teste [filtro]]");
					break;
				}
			}
		}

		private static bool _feito;

		internal static void Registrar()
		{
			//IL_0041: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			if (_feito)
			{
				return;
			}
			_feito = true;
			object obj = <>c.<>9__1_0;
			if (obj == null)
			{
				ConsoleEvent val = delegate(ConsoleEventArgs args)
				{
					//IL_009d: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
					//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
					//IL_0106: Unknown result type (might be due to invalid IL or missing references)
					//IL_0114: Unknown result type (might be due to invalid IL or missing references)
					//IL_011f: Unknown result type (might be due to invalid IL or missing references)
					//IL_0264: Unknown result type (might be due to invalid IL or missing references)
					//IL_021e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0223: Unknown result type (might be due to invalid IL or missing references)
					//IL_0227: Unknown result type (might be due to invalid IL or missing references)
					//IL_0243: Unknown result type (might be due to invalid IL or missing references)
					//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
					Terminal context = args.Context;
					string text = ((args.Length >= 2) ? args[1].ToLowerInvariant() : "info");
					Player localPlayer = Player.m_localPlayer;
					if (text == "teste")
					{
						if (!T.Disponivel)
						{
							context.AddString("A suite de teste precisa do Mayheim instalado.");
						}
						else
						{
							T.Iniciar((args.Length >= 3) ? args[2] : "helheim");
							context.AddString("Suite iniciada; resultado no log com o prefixo [MMOTEST].");
						}
					}
					else if ((Object)(object)localPlayer == (Object)null)
					{
						context.AddString("Entre em um mundo primeiro.");
					}
					else if (text == "info")
					{
						Vector3 position = ((Component)localPlayer).transform.position;
						float num = Anel.Raio(position.x, position.z);
						context.AddString(string.Format("Helheim {0} · anel de {1:0} a {2:0} m · voce a {3:0} m do centro.", Estado.Ativo ? "LIGADO" : "dormente", Anel.Rin, Anel.Rout, num));
						if (Anel.NoAnel(position))
						{
							object arg = Anel.Tier(position);
							string arg2 = Setores.Nome(Anel.Tier(position));
							EnvMan instance = EnvMan.instance;
							context.AddString($"Voce esta no tier {arg}: {arg2} (ambiente {((instance == null) ? null : instance.GetCurrentEnvironment()?.m_name)}).");
						}
						if ((Object)(object)Minimap.instance != (Object)null)
						{
							context.AddString($"Mapa: {Minimap.instance.m_textureSize} px x {Minimap.instance.m_pixelSize} m = raio {(float)Minimap.instance.m_textureSize * Minimap.instance.m_pixelSize / 2f:0} m.");
						}
					}
					else if (!Estado.Ativo)
					{
						context.AddString("Helheim dormente neste mundo (servidor sem o mod).");
					}
					else if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer())
					{
						context.AddString("Na prova de conceito, a viagem por comando e so no mundo local.");
					}
					else
					{
						switch (text)
						{
						case "ir":
						{
							int result = 9;
							if (args.Length >= 3 && !int.TryParse(args[2], out result))
							{
								context.AddString("Uso: helheim ir [9-12]");
							}
							else
							{
								Vector3 val3 = Rota.PontoDoTier(result);
								context.AddString(Rota.Leva(localPlayer, val3) ? $"Indo para {Setores.Nome(result)} ({val3:F0})." : "O jogo recusou o teleporte agora.");
							}
							break;
						}
						case "voltar":
							context.AddString(Rota.Leva(localPlayer, Rota.Templo()) ? "Voltando ao templo." : "O jogo recusou o teleporte agora.");
							break;
						case "estado":
						{
							int encontradas;
							int num3 = Templo.PedrasAcesas(out encontradas);
							RandEventSystem instance3 = RandEventSystem.instance;
							RandomEvent val4 = ((instance3 != null) ? instance3.GetCurrentRandomEvent() : null);
							context.AddString($"Pedras do templo: {num3} de {Templo.Pedras.Length} acesas ({encontradas} encontradas).");
							context.AddString("Invasao: " + (Chaves.EmInvasao ? "SIM" : "nao") + " · Portal aberto: " + (Chaves.EstaAberto ? "SIM" : "nao") + ((val4 != null && val4.m_name == "helheim_invasao") ? $" · raid {val4.m_time / 60f:0.0} de {val4.m_duration / 60f:0} min" : ""));
							break;
						}
						case "invasao":
							Templo.ComecaInvasao();
							context.AddString("Invasao iniciada (teste).");
							break;
						case "abrir":
							Templo.Abre();
							context.AddString("Portal de Helheim aberto (teste, sem raid).");
							break;
						case "resetar":
						{
							RandEventSystem instance2 = RandEventSystem.instance;
							RandomEvent val2 = ((instance2 != null) ? instance2.GetCurrentRandomEvent() : null);
							if (val2 != null && val2.m_name == "helheim_invasao")
							{
								RandEventSystem.instance.ResetRandomEvent();
							}
							if (Templo.Centro(out var pos))
							{
								Raid.Recolhe(pos, 250f);
							}
							int num2 = Objetos.RemoveTudo();
							Chaves.ApagaTudo();
							context.AddString($"Abertura desfeita (teste): {num2} objeto(s) removido(s), chaves apagadas.");
							break;
						}
						default:
							context.AddString("Uso: helheim [info | estado | ir [9-12] | voltar | invasao | abrir | resetar | teste [filtro]]");
							break;
						}
					}
				};
				<>c.<>9__1_0 = val;
				obj = (object)val;
			}
			new ConsoleCommand("helheim", "Helheim. Uso: helheim [info | estado | ir [9-12] | voltar | invasao | abrir | resetar | teste [filtro]]", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
		}
	}
	[HarmonyPatch(typeof(Terminal), "InitTerminal")]
	internal static class Terminal_InitTerminal_HelheimPatch
	{
		private static void Postfix()
		{
			Comandos.Registrar();
		}
	}
}
namespace MayheimHelheim.Testing
{
	internal static class AberturaTests
	{
		private const string G = "helheim";

		private static readonly Dictionary<string, string> ItemDaPedra = new Dictionary<string, string>
		{
			{ "BossStone_Eikthyr", "TrophyEikthyr" },
			{ "BossStone_TheElder", "TrophyTheElder" },
			{ "BossStone_Bonemass", "TrophyBonemass" },
			{ "BossStone_DragonQueen", "TrophyDragonQueen" },
			{ "BossStone_Yagluth", "TrophyGoblinKing" },
			{ "BossStone_TheQueen", "TrophySeekerQueen" },
			{ "BossStone_Fader", "TrophyFader" },
			{ "StartPlatform", "FrozenKingDrop" }
		};

		private static Player Eu => Player.m_localPlayer;

		internal static void Registrar()
		{
			T.Registrar("helheim", "criaturas corrompidas registradas", CriaturasRegistradas);
			T.Registrar("helheim", "abertura: 8 pedras, raid, portal e acampamento", AberturaCompleta);
			T.Registrar("helheim", "portal comum nao atravessa o abismo", PortalComum);
		}

		private static IEnumerator CriaturasRegistradas()
		{
			DefCriatura[] defs = MayheimHelheim.Criaturas.Criaturas.Defs;
			foreach (DefCriatura defCriatura in defs)
			{
				GameObject prefab = ZNetScene.instance.GetPrefab(defCriatura.Prefab);
				T.Ok((Object)(object)prefab != (Object)null, defCriatura.Prefab + " no ZNetScene");
				Character val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Character>() : null);
				if (!((Object)(object)val == (Object)null))
				{
					T.Igual(defCriatura.Vida, val.m_health, defCriatura.Prefab + ": vida");
					T.Igual(defCriatura.Nome, val.m_name, defCriatura.Prefab + ": nome");
				}
			}
			yield break;
		}

		private static IEnumerator Chega(Vector3 destino, string onde)
		{
			//IL_0007: 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)
			Rota.Leva(Eu, destino);
			yield return T.EsperaAte(() => (Object)(object)Eu != (Object)null && !((Character)Eu).IsTeleporting(), 90f, "fim do teleporte para " + onde);
			yield return T.Espera(3f);
		}

		private static T2 Perto<T2>(Vector3 p, float raio) where T2 : Component
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			T2[] array = Object.FindObjectsByType<T2>((FindObjectsSortMode)0);
			foreach (T2 val in array)
			{
				if ((Object)(object)val != (Object)null && Vector3.Distance(((Component)val).transform.position, p) < raio)
				{
					return val;
				}
			}
			return default(T2);
		}

		private static int Contar(string prefab, Vector3 p, float raio)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				if ((Object)(object)allCharacter != (Object)null && !allCharacter.IsDead() && Utils.GetPrefabName(((Component)allCharacter).gameObject) == prefab && Vector3.Distance(((Component)allCharacter).transform.position, p) < raio)
				{
					num++;
				}
			}
			return num;
		}

		private static void Desfaz()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			RandEventSystem instance = RandEventSystem.instance;
			RandomEvent val = ((instance != null) ? instance.GetCurrentRandomEvent() : null);
			if (val != null && val.m_name == "helheim_invasao")
			{
				RandEventSystem.instance.ResetRandomEvent();
			}
			if (Templo.Centro(out var pos))
			{
				Raid.Recolhe(pos, 250f);
			}
			Objetos.RemoveTudo();
			Chaves.ApagaTudo();
		}

		private static IEnumerator AberturaCompleta()
		{
			if ((Object)(object)Eu == (Object)null)
			{
				T.Ok(c: false, "personagem");
				yield break;
			}
			Desfaz();
			yield return Chega(Rota.Templo(), "templo");
			List<ZDO> pedras = Templo.ZdosDasPedras();
			T.Igual(8, pedras.Count, "pedras do templo encontradas");
			Dictionary<ZDO, int> antes = new Dictionary<ZDO, int>();
			foreach (ZDO item in pedras)
			{
				antes[item] = item.GetInt(ZDOVars.s_item, 0);
				item.Set(ZDOVars.s_item, 0, false);
			}
			for (int i = 0; i < pedras.Count - 1; i++)
			{
				Acende(pedras[i]);
			}
			yield return T.Espera(5f);
			T.Ok(!Chaves.EmInvasao && !Chaves.EstaAberto, "com 7 pedras acesas, nada acontece");
			Acende(pedras[pedras.Count - 1]);
			yield return T.EsperaAte(() => Chaves.EmInvasao, 10f, "invasao comeca com a 8a pedra");
			RandomEvent currentRandomEvent = RandEventSystem.instance.GetCurrentRandomEvent();
			T.Ok(currentRandomEvent != null && currentRandomEvent.m_name == "helheim_invasao", "evento da raid ativo");
			T.Ok(Chaves.PortalDoTemplo(out var portalPos, out var _), "posicao do portal gravada");
			float num = Vector3.Distance(new Vector3(portalPos.x, 0f, portalPos.z), new Vector3(Rota.Templo().x, 0f, Rota.Templo().z));
			T.Ok(num > 14f, $"portal fora do circulo de pedras ({num:0} m do centro)");
			yield return T.EsperaAte(() => (Object)(object)Perto<TeleportWorld>(portalPos, 6f) != (Object)null, 20f, "portal do templo aparece");
			yield return OlhaPara(portalPos, 9f, "abertura-0-portal-selado");
			TeleportWorld tw = Perto<TeleportWorld>(portalPos, 6f);
			if ((Object)(object)tw != (Object)null)
			{
				T.Igual(TipoObjeto.PortalTemplo, Marca.De(((Component)tw).GetComponent<ZNetView>()), "portal marcado como do templo");
				Vector3 pos0 = ((Component)Eu).transform.position;
				tw.Teleport(Eu);
				yield return T.Espera(2f);
				T.Ok(!((Character)Eu).IsTeleporting() && Vector3.Distance(pos0, ((Component)Eu).transform.position) < 3f, "portal selado durante a raid");
			}
			if (Raid.Rodando() == null)
			{
				T.Ok(c: false, "raid rodando");
			}
			yield return T.EsperaAte(() => Contar("Helheim_Carnical", portalPos, 14f) > 0, 60f, "carnical nasce em volta do portal");
			T.Igual(0, Contar("Helheim_Arauto", portalPos, 200f), "Arauto ainda nao veio (primeira onda)");
			yield return TelaTests.Print("abertura-1-raid");
			currentRandomEvent = RandEventSystem.instance.GetCurrentRandomEvent();
			if (currentRandomEvent != null)
			{
				currentRandomEvent.m_time = Raid.Duracao * 0.7f;
			}
			yield return T.EsperaAte(() => Contar("Helheim_Arauto", portalPos, 30f) > 0, 60f, "Arauto nasce no ultimo terco");
			yield return TelaTests.Print("abertura-2-arauto");
			currentRandomEvent = RandEventSystem.instance.GetCurrentRandomEvent();
			if (currentRandomEvent != null)
			{
				currentRandomEvent.m_time = Raid.Duracao - 3f;
			}
			yield return T.EsperaAte(() => Chaves.EstaAberto && !Chaves.EmInvasao, 30f, "raid acaba por tempo e o portal abre");
			yield return T.Espera(2f);
			int num2 = 0;
			DefCriatura[] defs = MayheimHelheim.Criaturas.Criaturas.Defs;
			foreach (DefCriatura defCriatura in defs)
			{
				num2 += Contar(defCriatura.Prefab, portalPos, 150f);
			}
			T.Igual(0, num2, "corrompidos da raid recolhidos quando ela acaba");
			yield return T.EsperaAte(() => Objetos.Acha(Objetos.PortalDoAcampamento(), TipoObjeto.PortalAcampamento) != null, 10f, "portal do acampamento criado");
			T.Ok(Objetos.Acha(Objetos.Fogueira(), TipoObjeto.Fogueira) != null, "fogueira do acampamento criada");
			T.Ok(Objetos.Acha(Objetos.Bau(), TipoObjeto.Bau) != null, "bau do acampamento criado");
			tw = Perto<TeleportWorld>(portalPos, 6f);
			WearNTear val = (((Object)(object)tw != (Object)null) ? ((Component)tw).GetComponent<WearNTear>() : null);
			if ((Object)(object)val != (Object)null)
			{
				HitData val2 = new HitData();
				val2.m_damage.m_blunt = 1000000f;
				val2.m_damage.m_chop = 1000000f;
				val2.m_damage.m_pickaxe = 1000000f;
				val.Damage(val2);
				val.Remove(false);
				yield return T.Espera(2f);
				T.Ok((Object)(object)tw != (Object)null && ((Component)tw).GetComponent<ZNetView>().IsValid(), "portal do templo resiste a dano e a desmontar");
			}
			yield return TelaTests.Print("abertura-3-portal-aceso");
			tw = Perto<TeleportWorld>(portalPos, 6f);
			if ((Object)(object)tw != (Object)null)
			{
				tw.Teleport(Eu);
				yield return T.EsperaAte(() => ((Character)Eu).IsTeleporting(), 5f, "teleporte comeca no portal aceso");
				yield return T.EsperaAte(() => !((Character)Eu).IsTeleporting(), 90f, "chega ao acampamento");
				yield return T.Espera(4f);
				float num4 = Vector3.Distance(((Component)Eu).transform.position, Objetos.PortalDoAcampamento());
				T.Ok(num4 < 15f, $"no acampamento ({num4:0} m do portal de la)");
				Fireplace val3 = Perto<Fireplace>(Objetos.Fogueira(), 4f);
				T.Ok((Object)(object)val3 != (Object)null && val3.m_infiniteFuel, "fogueira eterna no acampamento");
				yield return T.Espera(5f);
				yield return TelaTests.Print("abertura-4-acampamento");
				yield return OlhaPara(Objetos.PortalDoAcampamento(), 10f, "abertura-5-portal-do-acampamento");
				TeleportWorld val4 = Perto<TeleportWorld>(Objetos.PortalDoAcampamento(), 6f);
				T.Ok((Object)(object)val4 != (Object)null, "portal de volta no acampamento");
				if ((Object)(object)val4 != (Object)null)
				{
					val4.Teleport(Eu);
					yield return T.EsperaAte(() => ((Character)Eu).IsTeleporting(), 5f, "teleporte de volta comeca");
					yield return T.EsperaAte(() => !((Character)Eu).IsTeleporting(), 90f, "chega ao templo");
					yield return T.Espera(2f);
					float num5 = Vector3.Distance(((Component)Eu).transform.position, portalPos);
					T.Ok(num5 < 15f, $"de volta ao templo ({num5:0} m do portal)");
				}
			}
			Desfaz();
			foreach (KeyValuePair<ZDO, int> item2 in antes)
			{
				item2.Key.Set(ZDOVars.s_item, item2.Value, false);
			}
		}

		private static void DiagnosticoDoSpawn()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: 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_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			RandEventSystem instance = RandEventSystem.instance;
			T.Nota("evento ativo para o jogador: " + (instance.m_activeEvent?.m_name ?? "-") + "; spawners do evento: " + (instance.GetCurrentSpawners()?.Count.ToString() ?? "null"));
			SpawnSystem val = null;
			float num = float.MaxValue;
			SpawnSystem[] array = Object.FindObjectsByType<SpawnSystem>((FindObjectsSortMode)0);
			foreach (SpawnSystem val2 in array)
			{
				float num2 = Vector3.Distance(((Component)val2).transform.position, ((Component)Eu).transform.position);
				if (num2 < num)
				{
					num = num2;
					val = val2;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				T.Nota("nenhum SpawnSystem carregado");
				return;
			}
			List<Player> list = new List<Player>();
			val.GetPlayersInZone(list);
			T.Nota($"SpawnSystem a {num:0} m, dono={val.m_nview.IsOwner()}, jogadores na zona={list.Count}");
			List<SpawnData> currentSpawners = instance.GetCurrentSpawners();
			if (currentSpawners == null)
			{
				return;
			}
			Vector3 val3 = default(Vector3);
			Player val4 = default(Player);
			foreach (SpawnData item in currentSpawners)
			{
				bool flag = val.FindBaseSpawnPoint(item, new List<Player> { Eu }, ref val3, ref val4);
				GameObject prefab = item.m_prefab;
				T.Nota("  " + ((prefab != null) ? ((Object)prefab).name : null) + ": ponto base " + (flag ? ("achado em " + ((Vector3)(ref val3)).ToString("F0")) : "NAO achado"));
			}
			SpawnData val5 = currentSpawners[0];
			Vector3 val6 = ((Component)Eu).transform.position + ((Component)Eu).transform.forward * 15f;
			Vector3 val7 = default(Vector3);
			Biome val8 = default(Biome);
			BiomeArea val9 = default(BiomeArea);
			Heightmap val10 = default(Heightmap);
			ZoneSystem.instance.GetGroundData(ref val6, ref val7, ref val8, ref val9, ref val10);
			T.Nota($"  ponto de exemplo {val6:F0}: bioma={val8} (pede {val5.m_biome}), area={val9}, bloqueado={ZoneSystem.instance.IsBlocked(val6)}, " + $"base={(Object)(object)EffectArea.IsPointInsideArea(val6, (Type)4, 0f) != (Object)null}, inclinacao={val7.y:0.00}, lava={ZoneSystem.instance.IsLava(val6, true)}, " + $"ponto bom={val.IsSpawnPointGood(val5, ref val6)}");
		}

		private static IEnumerator OlhaPara(Vector3 alvo, float distancia, string print)
		{
			//IL_0007: 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)
			if (TelaTests.TemTela)
			{
				Vector3 val = ((Component)Eu).transform.position - alvo;
				val.y = 0f;
				if (((Vector3)(ref val)).sqrMagnitude < 1f)
				{
					val = Vector3.back;
				}
				Vector3 val2 = alvo + ((Vector3)(ref val)).normalized * distancia;
				val2.y = ZoneSystem.instance.GetGroundHeight(val2) + 0.2f;
				((Component)Eu).transform.position = val2;
				Player eu = Eu;
				Vector3 val3 = alvo - val2;
				((Character)eu).SetLookDir(((Vector3)(ref val3)).normalized, 0f);
				yield return T.Espera(2f);
				yield return TelaTests.Print(print);
			}
		}

		private static void Acende(ZDO z)
		{
			GameObject prefab = ZNetScene.instance.GetPrefab(z.GetPrefab());
			string key = ((prefab != null) ? ((Object)prefab).name : null) ?? "";
			string value;
			string text = (ItemDaPedra.TryGetValue(key, out value) ? value : "TrophyEikthyr");
			z.Set(ZDOVars.s_item, StringExtensionMethods.GetStableHashCode(text), false);
		}

		private static IEnumerator PortalComum()
		{
			if ((Object)(object)Eu == (Object)null)
			{
				T.Ok(c: false, "personagem");
				yield break;
			}
			yield return Chega(Rota.Templo(), "templo");
			GameObject prefab = ZNetScene.instance.GetPrefab("portal_wood");
			GameObject a = Object.Instantiate<GameObject>(prefab, Rota.Templo() + new Vector3(30f, 0f, 30f), Quaternion.identity);
			GameObject obj = Object.Instantiate<GameObject>(prefab, Objetos.PortalDoAcampamento() + new Vector3(15f, 0f, 0f), Quaternion.identity);
			ZDO za = a.GetComponent<ZNetView>().GetZDO();
			ZDO zDO = obj.GetComponent<ZNetView>().GetZDO();
			za.Set(ZDOVars.s_tag, "hhteste");
			zDO.Set(ZDOVars.s_tag, "hhteste");
			ZDOMan.instance.SetDirtyPortals();
			yield return T.EsperaAte(() => za.GetConnectionZDOID((ConnectionType)1) != ZDOID.None, 20f, "portais comuns ligados pelo nome");
			Vector3 antes = ((Component)Eu).transform.position;
			a.GetComponent<TeleportWorld>().Teleport(Eu);
			yield return T.Espera(2f);
			T.Ok(!((Character)Eu).IsTeleporting() && Vector3.Distance(antes, ((Component)Eu).transform.position) < 3f, "portal comum do templo nao leva ao Helheim");
			RemovePortaisDeTeste();
		}

		internal static int RemovePortaisDeTeste()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_0046: 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)
			int num = 0;
			List<Vector3> list = new List<Vector3> { Objetos.PortalDoAcampamento() };
			if (Templo.Centro(out var pos))
			{
				list.Add(pos);
			}
			foreach (Vector3 item in list)
			{
				List<ZDO> list2 = new List<ZDO>();
				ZDOMan.instance.FindSectorObjects(ZoneSystem.GetZone(item), new SimulationDistance(2, 0, true), list2, (List<ZDO>)null);
				foreach (ZDO item2 in list2)
				{
					if (item2 != null && item2.IsValid() && !(item2.GetString(ZDOVars.s_tag, "") != "hhteste"))
					{
						ZNetView val = ZNetScene.instance.FindInstance(item2);
						if ((Object)(object)val != (Object)null)
						{
							val.ClaimOwnership();
							ZNetScene.instance.Destroy(((Component)val).gameObject);
						}
						else
						{
							item2.SetOwner(ZDOMan.GetSessionID());
							ZDOMan.instance.DestroyZDO(item2);
						}
						num++;
					}
				}
			}
			return num;
		}
	}
	internal static class AcampamentoTests
	{
		private const string G = "helheim";

		private static Player Eu => Player.m_localPlayer;

		internal static void Registrar()
		{
			T.Registrar("helheim", "acampamento: mercador e emissaria do Mayheim no acampamento", Moradores_);
			T.Registrar("helheim", "acampamento: catalogo liberado chefe a chefe, precos e venda", Loja_);
			T.Registrar("helheim", "acampamento: missoes do Helheim (aceitar, abater, concluir)", Missoes_);
		}

		private static Trader Npc(TipoObjeto tipo)
		{
			Trader[] array = Object.FindObjectsByType<Trader>((FindObjectsSortMode)0);
			foreach (Trader val in array)
			{
				if ((Object)(object)val != (Object)null && Marca.De((Component)(object)val) == tipo)
				{
					return val;
				}
			}
			return null;
		}

		private static IEnumerator NoAcampamento()
		{
			if (!Chaves.EstaAberto)
			{
				Templo.Abre();
			}
			Rota.Leva(Eu, Rota.PontoDoTier(9));
			yield return T.EsperaAte(() => !((Character)Eu).IsTeleporting(), 90f, "teleporte ao acampamento");
			yield return T.Espera(2f);
			yield return T.EsperaAte(() => (Object)(object)Npc(TipoObjeto.Mercador) != (Object)null && (Object)(object)Npc(TipoObjeto.Emissario) != (Object)null, 20f, "os dois moradores carregados");
		}

		private static IEnumerator Moradores_()
		{
			if ((Object)(object)Eu == (Object)null)
			{
				T.Ok(c: false, "personagem");
				yield break;
			}
			yield return NoAcampamento();
			Trader val = Npc(TipoObjeto.Mercador);
			Trader val2 = Npc(TipoObjeto.Emissario);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null))
			{
				T.Ok(CitySystem.IsCityMerchant(val), "o Mayheim reconhece o mercador");
				T.Ok(CitySystem.IsQuestNpc(val2), "o Mayheim reconhece a emissaria");
				T.Ok(MerchantSpawner.IsMerchant(val) && MerchantSpawner.TierOf(val) == 9, "loja do Mayheim no tier do Helheim");
				T.Igual("Mercador da Expedição", val.m_name, "nome do mercador");
				T.Igual("Emissária da Expedição", val2.m_name, "nome da emissaria");
				T.Ok(Vector3.Distance(((Component)val).transform.position, Moradores.Mercador()) < 2f, "mercador no lugar");
				Vector3 val3 = Objetos.Saida(Objetos.PortalDoAcampamento(), Objetos.GiroDoAcampamento());
				val3.y = ZoneSystem.instance.GetGroundHeight(val3) + 0.2f;
				((Character)Eu).m_body.position = val3;
				((Character)Eu).m_body.velocity = Vector3.zero;
				((Component)Eu).transform.position = val3;
				Vector3 val4 = (((Component)val).transform.position + ((Component)val2).transform.position) * 0.5f;
				Player eu = Eu;
				Vector3 val5 = val4 - ((Component)Eu).transform.position;
				((Character)eu).SetLookDir(((Vector3)(ref val5)).normalized, 0f);
				EnvMan.instance.m_debugTimeOfDay = true;
				EnvMan.instance.m_debugTime = 0.5f;
				yield return T.Espera(3f);
				T.Ok(((Character)Eu).m_lavaHeatLevel < 0.05f, $"sem calor de lava das Cinzas no acampamento (calor {((Character)Eu).m_lavaHeatLevel:0.00})");
				T.Nota($"na saida do portal: calor lava {((Character)Eu).m_lavaHeatLevel:0.00}, oceano {((Character)Eu).m_ashlandsOceanHeatLevel:0.00}, na agua {((Character)Eu).InWater()}, cinzas {WorldGenerator.IsAshlands(((Component)Eu).transform.position.x, ((Component)Eu).transform.position.z)}");
				yield return TelaTests.Print("acamp-1-moradores");
				Vector3 val6 = Objetos.PortalDoAcampamento() + Objetos.GiroDoAcampamento() * new Vector3(0f, 0f, 7f);
				val6.y = ZoneSystem.instance.GetGroundHeight(val6) + 0.2f;
				((Character)Eu).m_body.position = val6;
				((Character)Eu).m_body.velocity = Vector3.zero;
				((Component)Eu).transform.position = val6;
				yield return T.Espera(3f);
				T.Nota($"a 7 m do portal: calor lava {((Character)Eu).m_lavaHeatLevel:0.00}, oceano {((Character)Eu).m_ashlandsOceanHeatLevel:0.00}, na agua {((Character)Eu).InWater()}");
				yield return TelaTests.Print("acamp-1b-longe-do-portal");
				EnvMan.instance.m_debugTimeOfDay = false;
			}
		}

		private static List<TradeItem> Catalogo(Trader m)
		{
			Trader_GetAvailableItems_Patch.InStore = true;
			try
			{
				return m.GetAvailableItems();
			}
			finally
			{
				Trader_GetAvailableItems_Patch.InStore = false;
			}
		}

		private static IEnumerator Loja_()
		{
			if ((Object)(object)Eu == (Object)null)
			{
				T.Ok(c: false, "personagem");
				yield break;
			}
			yield return NoAcampamento();
			Trader m = Npc(TipoObjeto.Mercador);
			if ((Object)(object)m == (Object)null)
			{
				yield break;
			}
			string cfgOriginal = Cfg.LojaCatalogo.Value;
			bool reiMorto = Chaves.Tem("helheim_rei_derrotado");
			bool maeMorta = Chaves.Tem("helheim_mae_derrotada");
			bool forjadorMorto = Chaves.Tem("helheim_forjador_derrotado");
			bool helMorta = Chaves.Tem("helheim_hel_derrotada");
			try
			{
				Cfg.LojaCatalogo.Value = cfgOriginal + ",Helheim_CoroaPartida=10:7777";
				Chaves.Desliga("helheim_rei_derrotado");
				Chaves.Desliga("helheim_mae_derrotada");
				Chaves.Desliga("helheim_forjador_derrotado");
				Chaves.Desliga("helheim_hel_derrotada");
				List<TradeItem> list = Catalogo(m);
				TradeItem val = list.Find((TradeItem t) => ((Object)((Component)t.m_prefab).gameObject).name == "Helheim_EspadaSepulcral");
				T.Ok(val != null, "tier 9 a venda desde o portal (espada sepulcral)");
				T.Igual(58000, val?.m_price ?? 0, "espada sepulcral: 58.000 (SwordGold 45.000 x 1,3)");
				TradeItem val2 = list.Find((TradeItem t) => ((Object)((Component)t.m_prefab).gameObject).name == "Helheim_HidromelPurificacao");
				T.Ok(val2 != null && val2.m_stack > 1 && val2.m_price == 600 * val2.m_stack, "hidromel vendido em lote, 600 cada");
				T.Ok(list.Exists((TradeItem t) => ((Object)((Component)t.m_prefab).gameObject).name.StartsWith("MMO_")), "pocoes e itens do Mayheim continuam a venda");
				T.Ok(!list.Exists((TradeItem t) => ((Object)((Component)t.m_prefab).gameObject).name == "Helheim_CoroaPartida"), "tier 10 fechado com o Rei vivo");
				Chaves.Liga("helheim_rei_derrotado");
				yield return T.EsperaAte(() => Progresso.Liberado(10), 5f, "Rei morto libera o tier 10");
				TradeItem val3 = Catalogo(m).Find((TradeItem t) => ((Object)((Component)t.m_prefab).gameObject).name == "Helheim_CoroaPartida");
				T.Ok(val3 != null && val3.m_price == 7777, "tier 10 a venda depois do Rei");
				T.Igual(10, Progresso.Fronteira(), "fronteira no tier 10");
			}
			finally
			{
				Cfg.LojaCatalogo.Value = cfgOriginal;
				if (reiMorto)
				{
					Chaves.Liga("helheim_rei_derrotado");
				}
				else
				{
					Chaves.Desliga("helheim_rei_derrotado");
				}
				if (maeMorta)
				{
					Chaves.Liga("helheim_mae_derrotada");
				}
				if (forjadorMorto)
				{
					Chaves.Liga("helheim_forjador_derrotado");
				}
				if (helMorta)
				{
					Chaves.Liga("helheim_hel_derrotada");
				}
			}
			T.Igual(58000, MerchantTable.OuroDe("Helheim_EspadaSepulcral"), "o Mayheim conhece o preco da espada");
			((Humanoid)Eu).GetInventory().RemoveAll();
			((Humanoid)Eu).GetInventory().AddItem("Helheim_EspadaSepulcral", 1, 1, 0, 0L, "", false, false);
			((Humanoid)Eu).GetInventory().AddItem("Helheim_OssoCorrompido", 20, 1, 0, 0L, "", false, false);
			((Humanoid)Eu).GetInventory().AddItem("Helheim_TrofeuRei", 1, 1, 0, 0L, "", false, false);
			List<ItemData> allItems = ((Humanoid)Eu).GetInventory().GetAllItems();
			ItemData val4 = allItems.Find((ItemData i) => ((Object)i.m_dropPrefab).name == "Helheim_EspadaSepulcral");
			ItemData val5 = allItems.Find((ItemData i) => ((Object)i.m_dropPrefab).name == "Helheim_OssoCorrompido");
			T.Igual(11600, MerchantSellUI.UnitBuyPrice(val4), "mercador paga 20% da espada");
			T.Ok(MerchantSellUI.CanSell(val5), "osso corrompido vendavel");
			T.Igual(300, MerchantSellUI.UnitBuyPrice(val5), "osso corrompido: 300");
			Vector3 val6 = ((Component)m).transform.position + ((Component)m).transform.forward * 2.2f;
			val6.y = ZoneSystem.instance.GetGroundHeight(val6) + 0.2f;
			((Character)Eu).m_body.position = val6;
			((Character)Eu).m_body.velocity = Vector3.zero;
			((Component)Eu).transform.position = val6;
			Player eu = Eu;
			Vector3 val7 = ((Component)m).transform.position - val6;
			((Character)eu).SetLookDir(((Vector3)(ref val7)).normalized, 0f);
			EnvMan.instance.m_debugTimeOfDay = true;
			EnvMan.instance.m_debugTime = 0.5f;
			yield return T.Espera(1f);
			m.Interact((Humanoid)(object)Eu, false, false);
			yield return T.EsperaAte(() => StoreGui.IsVisible(), 5f, "loja abre");
			yield return T.Espera(1.5f);
			yield return TelaTests.Print("acamp-2-loja");
			T.Ok(StoreGui.IsVisible(), "loja continua aberta ao lado do mercador");
			StoreGui.instance.Hide();
			EnvMan.instance.m_debugTimeOfDay = false;
			((Humanoid)Eu).GetInventory().RemoveAll();
			yield return T.Espera(0.5f);
		}

		private static IEnumerator Missoes_()
		{
			if ((Object)(object)Eu == (Object)null)
			{
				T.Ok(c: false, "personagem");
				yield break;
			}
			yield return NoAcampamento();
			Trader val = Npc(TipoObjeto.Emissario);
			if ((Object)(object)val == (Object)null)
			{
				yield break;
			}
			QuestSystem.EnsureLoaded(Eu);
			string text = default(string);
			foreach (Quest item in new List<Quest>(QuestSystem._active))
			{
				QuestSystem.Abandon(Eu, item, ref text);
			}
			List<Quest> list = QuestSystem.TodayFor(Eu, 9);
			T.Igual(3, list.Count, "tres missoes por dia");
			T.Ok(list.TrueForAll((Quest q) => q.Target.StartsWith("Helheim_") && q.Tier == 9), "todas do Helheim");
			T.Ok(list.Exists((Quest q) => (int)q.Kind == 1), "uma de entrega");
			T.Ok(HuntSystem.For(9) == null, "sem cacada do Deep North na emissaria");
			foreach (Quest item2 in list)
			{
				T.Nota($"missao: {item2.Title} -- {item2.GoldReward} ouro, {item2.XpReward} XP");
			}
			Quest val2 = list.Find((Quest q) => (int)q.Kind == 0 && !q.Claimed);
			if (val2 != null)
			{
				string text2 = default(string);
				T.Ok(QuestSystem.Accept(Eu, val2, ref text2), "aceitar (" + text2 + ")");
				for (int num = 0; num < val2.Required; num++)
				{
					QuestSystem.OnKill(val2.Target, 0);
				}
				T.Ok(val2.Complete, "abates contam");
				int num2 = ((Humanoid)Eu).GetInventory().CountItems("$item_coins", -1, true);
				T.Ok(QuestSystem.Claim(Eu, val2, ref text2), "concluir (" + text2 + ")");
				T.Igual(num2 + val2.GoldReward, ((Humanoid)Eu).GetInventory().CountItems("$item_coins", -1, true), "ouro da missao na mochila");
			}
			val.Interact((Humanoid)(object)Eu, false, false);
			yield return T.EsperaAte(() => QuestNpcUI.IsOpen, 5f, "janela de missoes abre");
			yield return T.Espera(1.5f);
			T.Ok(QuestNpcUI._win.Title.text.Contains("HELHEIM"), "titulo da janela");
			yield return TelaTests.Print("acamp-3-missoes");
			QuestNpcUI.Close();
			((Humanoid)Eu).GetInventory().RemoveAll();
		}
	}
	internal static class CorrupcaoTests
	{
		private const string G = "helheim";

		private static Player Eu => Player.m_localPlayer;

		internal static void Registrar()
		{
			T.Registrar("helheim", "corrupcao: sobe no anel, mais no escuro, desce no acampamento e fora", SobeEDesce);
			T.Registrar("helheim", "corrupcao: estagios (regeneracao, vida maxima, vinheta, consumido)", Estagios);
			T.Registrar("helheim", "corrupcao: golpe de corrompido soma", Golpe);
		}

		private static IEnumerator Vai(Vector3 p)
		{
			//IL_0007: 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)
			Rota.Leva(Eu, p);
			yield return T.EsperaAte(() => (Object)(object)Eu != (Object)null && !((Character)Eu).IsTeleporting(), 90f, "fim do teleporte");
			yield return T.Espera(2f);
			Raid.Recolhe(((Component)Eu).transform.position, 120f);
		}

		private static IEnumerator Hora(float fracao)
		{
			EnvMan.instance.m_debugTimeOfDay = true;
			EnvMan.instance.m_debugTime = fracao;
			yield return T.Espera(1.5f);
		}

		private static Vector3 MeioDoTier9()
		{
			//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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			return Anel.PontoNoMeio((Anel.InicioDoTier(9) + Anel.FimDoTier(9)) * 0.5f) + Vector3.up * 2f;
		}

		private static IEnumerator SobeEDesce()
		{
			if ((Object)(object)Eu == (Object)null)
			{
				T.Ok(c: false, "personagem");
				yield break;
			}
			((Humanoid)Eu).UnequipAllItems();
			((Humanoid)Eu).GetInventory().RemoveAll();
			yield return Vai(MeioDoTier9());
			yield return Hora(0.5f);
			MayheimHelheim.Corrupcao.Corrupcao.Define(Eu, 10f);
			float a = MayheimHelheim.Corrupcao.Corrupcao.Valor(Eu);
			yield return T.Espera(6f);
			float num = MayheimHelheim.Corrupcao.Corrupcao.Valor(Eu) - a;
			T.Nota($"de dia no tier 9: +{num:0.0} em 6 s (taxa agora {MayheimHelheim.Corrupcao.Corrupcao.Taxa(Eu, out var motivo):0.00}/s, {motivo})");
			T.Ok(num > 0.5f && num < 3f, "de dia, sobe devagar");
			SE_Corrupcao sE_Corrupcao = ((Character)Eu).GetSEMan().GetStatusEffect(StringExtensionMethods.GetStableHashCode("Helheim_Corrupcao")) as SE_Corrupcao;
			T.Ok((Object)(object)sE_Corrupcao != (Object)null, "status Corrupcao no HUD");
			if ((Object)(object)sE_Corrupcao != (Object)null)
			{
				T.Igual($"{MayheimHelheim.Corrupcao.Corrupcao.Valor(Eu):0}%", ((StatusEffect)sE_Corrupcao).GetIconText(), "icone mostra a porcentagem");
			}
			yield return Hora(0f);
			string motivo2;
			float num2 = MayheimHelheim.Corrupcao.Corrupcao.Taxa(Eu, out motivo2);
			T.Nota($"a noite sem tocha: {num2:0.00}/s ({motivo2})");
			T.Ok(Mathf.Abs(num2 - Cfg.CorrupcaoBase.Value * Cfg.CorrupcaoEscuro.Value) < 0.01f, "a noite, sem luz, sobe 3x");
			yield return TelaTests.Print("corrupcao-1-noite");
			yield return Hora(0.5f);
			MayheimHelheim.Corrupcao.Corrupcao.Define(Eu, 40f);
			yield return Vai(Rota.PontoDoTier(9));
			float antes = MayheimHelheim.Corrupcao.Corrupcao.Valor(Eu);
			yield return T.Espera(4f);
			T.Ok(MayheimHelheim.Corrupcao.Corrupcao.Valor(Eu) < antes - 5f, $"no acampamento desce rapido ({antes:0} -> {MayheimHelheim.Corrupcao.Corrupcao.Valor(Eu):0})");
			MayheimHelheim.Corrupcao.Corrupcao.Define(Eu, 4f);
			yield return Vai(Rota.Templo());
			yield return T.EsperaAte(() => MayheimHelheim.Corrupcao.Corrupcao.Valor(Eu) <= 0f, 10f, "fora do Helheim a barra zera");
			yield return T.Espera(1.5f);
			T.Ok((Object)(object)((Character)Eu).GetSEMan().GetStatusEffect(StringExtensionMethods.GetStableHashCode("Helheim_Corrupcao")) == (Object)null, "status some fora do Helheim com a barra zerada");
			EnvMan.instance.m_debugTimeOfDay = false;
		}

		private static IEnumerator Estagios()
		{
			if ((Object)(object)Eu == (Object)null)
			{
				T.Ok(c: false, "personagem");
				yield break;
			}
			yield return Vai(MeioDoTier9());
			yield return Hora(0.5f);
			Eu.SetGodMode(false);
			float vidaCheia = ((Character)Eu).GetMaxHealth();
			MayheimHelheim.Corrupcao.Corrupcao.Define(Eu, 60f);
			yield return T.Espera(2.5f);
			SE_Corrupcao sE_Corrupcao = ((Character)Eu).GetSEMan().GetStatusEffect(StringExtensionMethods.GetStableHashCode("Helheim_Corrupcao")) as SE_Corrupcao;
			T.Ok((Object)(object)sE_Corrupcao != (Object)null && Mathf.Approximately(((SE_Stats)sE_Corrupcao).m_staminaRegenMultiplier, 0.75f) && Mathf.Approximately(((SE_Stats)sE_Corrupcao).m_eitrRegenMultiplier, 0.75f), "50+: -25% de regeneracao de stamina e eitr");
			T.Ok(Vinheta.Alfa > 0.2f, $"vinheta na tela ({Vinheta.Alfa:0.00})");
			MayheimHelheim.Corrupcao.Corrupcao.Define(Eu, 80f);
			yield return T.EsperaAte(() => ((Character)Eu).GetMaxHealth() < vidaCheia * 0.9f, 8f, "75+: vida maxima cai");
			T.Nota($"vida maxima: {vidaCheia:0} -> {((Character)Eu).GetMaxHealth():0}");
			yield return TelaTests.Print("corrupcao-2-estagio3");
			MayheimHelheim.Corrupcao.Corrupcao.Define(Eu, 100f);
			((Character)Eu).SetHealth(((Character)Eu).GetMaxHealth());
			float vida0 = ((Character)Eu).GetHealth();
			yield return T.Espera(3.5f);
			T.Ok(((Character)Eu).GetHealth() < vida0 - 0.5f, $"100: consumido, perde vida ({vida0:0} -> {((Character)Eu).GetHealth():0})");
			MayheimHelheim.Corrupcao.Corrupcao.Define(Eu, 0f);
			yield return T.EsperaAte(() => ((Character)Eu).GetMaxHealth() >= vidaCheia - 0.5f, 8f, "vida maxima volta quando a barra cai");
			((Character)Eu).SetHealth(((Character)Eu).GetMaxHealth());
		}

		private static IEnumerator Golpe()
		{
			if ((Object)(object)Eu == (Object)null)
			{
				T.Ok(c: false, "personagem");
				yield break;
			}
			yield return Vai(MeioDoTier9());
			yield return Hora(0.5f);
			GameObject prefab = ZNetScene.instance.GetPrefab("Helheim_Carnical");
			GameObject go = Object.Instantiate<GameObject>(prefab, ((Component)Eu).transform.position + ((Component)Eu).transform.forward * 6f, Quaternion.identity);
			BaseAI component = go.GetComponent<BaseAI>();
			if ((Object)(object)component != (Object)null)
			{
				((Behaviour)component).enabled = false;
			}
			yield return T.Espera(1f);
			MayheimHelheim.Corrupcao.Corrupcao.Define(Eu, 10f);
			HitData val = new HitData();
			val.m_damage.m_slash = 1f;
			val.m_point = ((Character)Eu).GetCenterPoint();
			val.SetAttacker(go.GetComponent<Character>());
			((Character)Eu).Damage(val);
			yield return T.Espera(1f);
			T.Ok(MayheimHelheim.Corrupcao.Corrupcao.Valor(Eu) >= 10f + Cfg.CorrupcaoGolpe.Value - 0.5f, $"golpe de corrompido soma {Cfg.CorrupcaoGolpe.Value} ({MayheimHelheim.Corrupcao.Corrupcao.Valor(Eu):0.0})");
			go.GetComponent<ZNetView>().ClaimOwnership();
			ZNetScene.instance.Destroy(go);
			MayheimHelheim.Corrupcao.Corrupcao.Define(Eu, 0f);
			EnvMan.instance.m_debugTimeOfDay = false;
		}
	}
	internal static class DiagnosticoTests
	{
		internal static bool LogaNascimentos;

		private static bool _someDeDia;

		private static bool _comIa;

		internal static void Registrar()
		{
			T.Registrar("medidahel", "pedras do templo: objetos, ZDOs e chaves", PedrasDoTemplo);
			T.Registrar("medidahel", "prefabs usados pela abertura existem", Prefabs);
			T.Registrar("medidahel", "nomes para o tier 9 (vegetacao, ossadas, itens)", Nomes);
			T.Registrar("medidahel", "bases da forja e das armas", BasesDaForja);
			T.Registrar("medidahel", "bases dos itens de luz", BasesDaLuz);
			T.Registrar("medidahel", "chefe do tier 10: a Rainha e o ninho", BasesDaMae);
			T.Registrar("medidahel", "chefe do tier 10: ossos da Rainha e pecas do ninho", OssosDaMae);
			T.Registrar("medidahel", "visual do Ermos: corpos, ossos e equipamento das bases", BasesDoErmos);
			T.Registrar("medidahel", "visual dos tiers 10 a 12: corpos, ossos e equipamento das bases", () => Bases(new string[12]
			{
				"Seeker", "Tick", "SeekerBrute", "Gjall", "Charred_Melee", "Charred_Archer", "Charred_Mage", "Morgen", "Asksvin", "Charred_Twitcher",
				"BlobElite", "FallenValkyrie"
			}));
			T.Registrar("medidahel", "chefe do tier 11: bases do Forjador e pecas da forja", BasesDoForjador);
			T.Registrar("medidahel", "chefe do tier 12: o rei do Deep North e o Fader", BasesDeHel);
			T.Registrar("medidahel", "modelos do jogo: armas, escudos e armaduras por tipo", ModelosDoJogo);
			T.Registrar("medidahel", "materiais do cajado da ninhada", () => Materiais("Helheim_CajadoDaNinhada"));
			T.Registrar("medidahel", "montarias do jogo: criaturas com sela, velocidades e itens de sela", Montarias);
			T.Registrar("medidahel", "o que esta salvo perto do trono de Hel (ZDOs por prefab)", PertoDoTrono);
			T.Registrar("medidahel", "travamento: chefe vivo e criaturas nascendo, por partes", TravamentoPorPartes);
			T.Registrar("medidahel", "navmeshtrono: pathfinding e colisores no trono", TravamentoNoTrono);
			T.Registrar("medidahel", "nivelcriatura: criaturas do tier 12 com estrelas, em campo", NivelEmCampo);
		}

		private static IEnumerator NivelEmCampo()
		{
			yield return T.PersonagemPronto();
			Player.m_localPlayer.SetGodMode(true);
			((MonoBehaviour)Plugin.Instance).StartCoroutine(PulsoDaNavmesh(200f));
			yield return RetratoTests.PreparaNoTier(12);
			Transform t = ((Component)Player.m_localPlayer).transform;
			ZNetScene cena = ZNetScene.instance;
			string[] array = new string[3] { "Helheim_Condenado", "Helheim_Contorcido", "Helheim_Lodo" };
			foreach (string prefab in array)
			{
				for (int nivel = 1; nivel <= 3; nivel++)
				{
					List<GameObject> criados = new List<GameObject>();
					for (int j = 0; j < 3; j++)
					{
						Vector3 val = t.position + t.right * (6f + 3f * (float)j) + t.forward * 12f;
						val.y = ZoneSystem.instance.GetGroundHeight(val) + 0.5f;
						GameObject val2 = Object.Instantiate<GameObject>(cena.GetPrefab(prefab), val, Quaternion.identity);
						Character component = val2.GetComponent<Character>();
						if (component != null)
						{
							component.SetLevel(nivel);
						}
						MonsterAI component2 = val2.GetComponent<MonsterAI>();
						if (component2 != null)
						{
							component2.SetDespawnInDay(nivel == 2);
						}
						criados.Add(val2);
					}
					int q0 = Time.frameCount;
					float t2 = Time.realtimeSinceStartup;
					Plugin.Log.LogInfo((object)string.Format("[Trava] {0} nivel {1}{2}: comeca (dia {3})", prefab, nivel, (nivel == 2) ? " (some de dia)" : "", EnvMan.IsDay()));
					yield return (object)new WaitForSecondsRealtime(5f);
					Plugin.Log.LogInfo((object)$"[Trava] {prefab} nivel {nivel}: {(float)(Time.frameCount - q0) / Mathf.Max(0.01f, Time.realtimeSinceStartup - t2):0.0} fps");
					foreach (GameObject item in criados)
					{
						if ((Object)(object)item != (Object)null)
						{
							ZNetView component3 = item.GetComponent<ZNetView>();
							if ((Object)(object)component3 != (Object)null && component3.IsValid())
							{
								component3.ClaimOwnership();
								cena.Destroy(item);
							}
						}
					}
					yield return (object)new WaitForSecondsRealtime(2f);
				}
			}
			Player localPlayer = Player.m_localPlayer;
			if (localPlayer != null)
			{
				localPlayer.SetGodMode(false);
			}
		}

		private static IEnumerator PulsoDaNavmesh(float segundos)
		{
			float fim = Time.realtimeSinceStartup + segundos;
			int q0 = Time.frameCount;
			float t0 = Time.realtimeSinceStartup;
			while (Time.realtimeSinceStartup < fim)
			{
				yield return (object)new WaitForSecondsRealtime(2f);
				Pathfinding instance = Pathfinding.instance;
				int num = 0;
				if ((Object)(object)instance != (Object)null)
				{
					foreach (NavMeshTile value in instance.m_tiles.Values)
					{
						num += value.m_links1.Count + value.m_links2.Count;
					}
				}
				float num2 = (float)(Time.frameCount - q0) / Mathf.Max(0.01f, Time.realtimeSinceStartup - t0);
				q0 = Time.frameCount;
				t0 = Time.realtimeSinceStartup;
				Player localPlayer = Player.m_localPlayer;
				ManualLogSource log = Plugin.Log;
				object[] obj = new object[10]
				{
					num2,
					instance?.m_tiles.Count,
					instance?.m_queuedAreas.Count,
					instance?.m_edgeBuildQueue.Count,
					num,
					instance?.m_linkRemoveQueue.Count,
					instance?.m_tileRemoveQueue.Count,
					Character.GetAllCharacters().Count,
					GC.GetTotalMemory(forceFullCollection: false) / 1048576,
					null
				};
				object obj2;
				if (!((Object)(object)localPlayer != (Object)null))
				{
					obj2 = "-";
				}
				else
				{
					Vector3 position = ((Component)localPlayer).transform.position;
					obj2 = ((Vector3)(ref position)).ToString("F0");
				}
				obj[9] = obj2;
				log.LogInfo((object)string.Format("[Navmesh] fps {0:0.0} | blocos {1} | fila {2} | bordas {3} | ligacoes {4} | remover {5}/{6} | criaturas {7} | mem {8} MB | jogador {9}", obj));
			}
		}

		private static string Colisores(GameObject go)
		{
			//IL_001d: 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_00dd: 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_004b: 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)
			if ((Object)(object)go == (Object)null)
			{
				return "-";
			}
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			Bounds bounds = default(Bounds);
			((Bounds)(ref bounds))..ctor(go.transform.position, Vector3.zero);
			Collider[] componentsInChildren = go.GetComponentsInChildren<Collider>(true);
			foreach (Collider val in componentsInChildren)
			{
				num++;
				if (num == 1)
				{
					bounds = val.bounds;
				}
				else
				{
					((Bounds)(ref bounds)).Encapsulate(val.bounds);
				}
				MeshCollider val2 = (MeshCollider)(object)((val is MeshCollider) ? val : null);
				if (val2 != null && (Object)(object)val2.sharedMesh != (Object)null)
				{
					num2++;
					num3 += val2.sharedMesh.vertexCount;
				}
			}
			int num4 = go.GetComponentsInChildren<Transform>(true).Length;
			return $"{num} colisores ({num2} de malha, {num3} vertices), {num4} filhos, tamanho {((Bounds)(ref bounds)).size}";
		}

		private static IEnumerator TravamentoNoTrono()
		{
			yield return T.PersonagemPronto();
			LogaNascimentos = true;
			SpawnSystem.m_nospawn = true;
			ZNetScene cena = ZNetScene.instance;
			Plugin.Log.LogInfo((object)("[Trava] prefab do trono: " + Colisores(cena.GetPrefab("Helheim_TronoDeHel"))));
			Plugin.Log.LogInfo((object)("[Trava] prefab da ossada: " + Colisores(cena.GetPrefab("Helheim_OssadaDeHel"))));
			Player.m_localPlayer.SetGodMode(true);
			((MonoBehaviour)Plugin.Instance).StartCoroutine(PulsoDaNavmesh(240f));
			yield return T.Vai(Hel.NoTrono(10f, 32f) + Vector3.up * 2f);
			Transform t = ((Component)Player.m_localPlayer).transform;
			Collider[] array = Physics.OverlapSphere(t.position, 64f, -1, (QueryTriggerInteraction)1);
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			Collider[] array2 = array;
			foreach (Collider val in array2)
			{
				string key = ((object)val).GetType().Name + "/" + LayerMask.LayerToName(((Component)val).gameObject.layer) + "/" + Utils.GetPrefabName(((Component)((Component)val).transform.root).gameObject);
				dictionary.TryGetValue(key, out var value);
				dictionary[key] = value + 1;
			}
			List<KeyValuePair<string, int>> list = new List<KeyValuePair<string, int>>(dictionary);
			list.Sort((KeyValuePair<string, int> a, KeyValuePair<string, int> b) => b.Value.CompareTo(a.Value));
			Plugin.Log.LogInfo((object)($"[Trava] {array.Length} colisores a 64 m: " + string.Join("; ", list.GetRange(0, Mathf.Min(15, list.Count)).ConvertAll((KeyValuePair<string, int> k) => $"{k.Key} {k.Value}"))));
			yield return (object)new WaitForSecondsRealtime(3f);
			List<GameObject> criados = new List<GameObject>();
			int num = HelTests.LimpaZdos(Anel.Trono(), 250f, "fx_Fader_Ragdoll");
			Plugin.Log.LogInfo((object)$"[Trava] corpos do Fader tirados: {num}");
			yield return (object)new WaitForSecondsRealtime(2f);
			_someDeDia = false;
			yield return Passo("trono SEM o corpo do Fader, 3 Condenados cacando");
			_someDeDia = true;
			yield return Passo("trono, 3 Condenados que somem de dia");
			SpawnSystem.m_nospawn = false;
			yield return Passo("trono, gerador natural ligado");
			LogaNascimentos = false;
			Player localPlayer = Player.m_localPlayer;
			if (localPlayer != null)
			{
				localPlayer.SetGodMode(false);
			}
			IEnumerator Passo(string nome)
			{
				for (int j = 0; j < 3; j++)
				{
					Vector3 val2 = t.position + t.right * (6f + 3f * (float)j) + t.forward * 10f;
					val2.y = ZoneSystem.instance.GetGroundHeight(val2) + 0.5f;
					GameObject val3 = Object.Instantiate<GameObject>(cena.GetPrefab("Helheim_Condenado"), val2, Quaternion.identity);
					if (_someDeDia)
					{
						MonsterAI component = val3.GetComponent<MonsterAI>();
						if (component != null)
						{
							component.SetDespawnInDay(true);
						}
					}
					else
					{
						MonsterAI component2 = val3.GetComponent<MonsterAI>();
						if (component2 != null)
						{
							((BaseAI)component2).SetHuntPlayer(true);
						}
					}
					criados.Add(val3);
				}
				int q0 = Time.frameCount;
				float t2 = Time.realtimeSinceStartup;
				Plugin.Log.LogInfo((object)("[Trava] " + nome + ": comeca"));
				yield return (object)new WaitForSecondsRealtime(8f);
				Plugin.Log.LogInfo((object)$"[Trava] {nome}: {(float)(Time.frameCount - q0) / Mathf.Max(0.01f, Time.realtimeSinceStartup - t2):0.0} fps");
				foreach (GameObject item in criados)
				{
					if ((Object)(object)item != (Object)null)
					{
						ZNetView component3 = item.GetComponent<ZNetView>();
						if ((Object)(object)component3 != (Object)null && component3.IsValid())
						{
							component3.ClaimOwnership();
							cena.Destroy(item);
						}
					}
				}
				criados.Clear();
				yield return (object)new WaitForSecondsRealtime(2f);
			}
		}

		private static IEnumerator TravamentoPorPartes()
		{
			yield return T.PersonagemPronto();
			Player localPlayer = Player.m_localPlayer;
			localPlayer.SetGodMode(true);
			yield return RetratoTests.PreparaNoTier(12);
			Transform t = ((Component)Player.m_localPlayer).transform;
			ZNetScene cena = ZNetScene.instance;
			List<GameObject> criados = new List<GameObject>();
			_comIa = true;
			for (int lugar = 0; lugar < 2; lugar++)
			{
				if (lugar == 1)
				{
					yield return T.Vai(Hel.NoTrono(10f, 32f) + Vector3.up * 2f);
					t = ((Component)Player.m_localPlayer).transform;
				}
				string onde = ((lugar == 0) ? "campo" : "trono");
				Vector3 frente = ((lugar == 0) ? (t.position + t.forward * 30f) : Hel.OndeNasceHel());
				(string, string)[] array = new(string, string)[4]
				{
					("sem chefe", ""),
					("so Nidhogg", "Helheim_Nidhogg"),
					("so Hel", "Helheim_Hel"),
					("o casal", "casal")
				};
				for (int i = 0; i < array.Length; i++)
				{
					(string, string) tuple = array[i];
					string item = tuple.Item1;
					string item2 = tuple.Item2;
					string nome = onde + ", " + item;
					if (item2 == "casal")
					{
						Cria("Helheim_Hel", frente);
						Cria("Helheim_Nidhogg", frente + t.right * 25f);
						yield return Mede(nome + ": chefes sozinhos", 4f);
					}
					else if (item2 != "")
					{
						Cria(item2, frente);
						yield return Mede(nome + ": chefe sozinho", 4f);
					}
					for (int j = 0; j < 3; j++)
					{
						Cria("Helheim_Condenado", t.position + t.right * (6f + 3f * (float)j) + t.forward * 10f);
					}
					yield return Mede(nome + ": + 3 Condenados com IA", 8f);
					Limpa();
					yield return Mede(nome + ": limpo", 3f);
				}
			}
			_comIa = false;
			localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null)
			{
				localPlayer.SetGodMode(false);
			}
			GameObject Cria(string prefab, Vector3 val)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				val.y = ZoneSystem.instance.GetGroundHeight(val) + 0.5f;
				GameObject val2 = Object.Instantiate<GameObject>(cena.GetPrefab(prefab), val, Quaternion.identity);
				BaseAI component = val2.GetComponent<BaseAI>();
				if ((Object)(object)component != (Object)null)
				{
					if (_comIa)
					{
						Character component2 = val2.GetComponent<Character>();
						if (component2 == null || !component2.IsBoss())
						{
							BaseAI obj = ((component is MonsterAI) ? component : null);
							if (obj != null)
							{
								obj.SetHuntPlayer(true);
							}
							goto IL_0076;
						}
					}
					((Behaviour)component).enabled = false;
				}
				goto IL_0076;
				IL_0076:
				criados.Add(val2);
				return val2;
			}
			void Limpa()
			{
				foreach (GameObject item3 in criados)
				{
					if ((Object)(object)item3 != (Object)null)
					{
						ZNetView component = item3.GetComponent<ZNetView>();
						if ((Object)(object)component != (Object)null && component.IsValid())
						{
							component.ClaimOwnership();
							cena.Destroy(item3);
						}
					}
				}
				criados.Clear();
			}
			static IEnumerator Mede(string passo, float s)
			{
				int q0 = Time.frameCount;
				float t2 = Time.realtimeSinceStartup;
				Plugin.Log.LogInfo((object)("[Trava] " + passo + ": comeca"));
				yield return (object)new WaitForSecondsRealtime(s);
				float num = (float)(Time.frameCount - q0) / Mathf.Max(0.01f, Time.realtimeSinceStartup - t2);
				Plugin.Log.LogInfo((object)$"[Trava] {passo}: {num:0.0} fps, {Character.GetAllCharacters().Count} criaturas, mem {GC.GetTotalMemory(forceFullCollection: false) / 1048576} MB");
				T.Nota($"{passo}: {num:0.0} fps");
			}
		}

		private static IEnumerator PertoDoTrono()
		{
			Vector3 val = Anel.Trono();
			Dictionary<int, int> dictionary = new Dictionary<int, int>();
			int num = 0;
			foreach (ZDO value4 in ZDOMan.instance.m_objectsByID.Values)
			{
				if (value4 != null)
				{
					Vector3 position = value4.GetPosition();
					if (!(Vector2.Distance(new Vector2(position.x, position.z), new Vector2(val.x, val.z)) > 200f))
					{
						dictionary.TryGetValue(value4.GetPrefab(), out var value);
						dictionary[value4.GetPrefab()] = value + 1;
						num++;
					}
				}
			}
			List<KeyValuePair<int, int>> list = new List<KeyValuePair<int, int>>(dictionary);
			list.Sort((KeyValuePair<int, int> a, KeyValuePair<int, int> b) => b.Value.CompareTo(a.Value));
			ZNetScene instance = ZNetScene.instance;
			T.Nota($"{num} ZDOs a 200 m do trono (antes de ir la), {dictionary.Count} prefabs:");
			foreach (KeyValuePair<int, int> item in list.GetRange(0, Mathf.Min(25, list.Count)))
			{
				GameObject prefab = instance.GetPrefab(item.Key);
				T.Nota($"  {((prefab != null) ? ((Object)prefab).name : null) ?? item.Key.ToString()}: {item.Value}");
			}
			T.Nota($"ZDOs no mundo inteiro: {ZDOMan.instance.m_objectsByID.Count}");
			Dictionary<string, int> dictionary2 = new Dictionary<string, int>();
			int num2 = 0;
			foreach (ZDO value5 in ZDOMan.instance.m_objectsByID.Values)
			{
				if (value5 == null)
				{
					continue;
				}
				GameObject prefab2 = instance.GetPrefab(value5.GetPrefab());
				string text = ((prefab2 != null) ? ((Object)prefab2).name : null) ?? "";
				if (text.StartsWith("Rock_") || text.StartsWith("rock"))
				{
					Vector3 position2 = value5.GetPosition();
					if (!(Vector2.Distance(new Vector2(position2.x, position2.z), new Vector2(val.x, val.z)) > 200f))
					{
						num2++;
						string key = $"{text}@{Mathf.RoundToInt(position2.x)},{Mathf.RoundToInt(position2.z)}";
						dictionary2.TryGetValue(key, out var value2);
						dictionary2[key] = value2 + 1;
					}
				}
			}
			int num3 = 0;
			int num4 = 0;
			foreach (int value6 in dictionary2.Values)
			{
				if (value6 > 1)
				{
					num3 += value6 - 1;
				}
				num4 = Mathf.Max(num4, value6);
			}
			T.Nota($"pedras perto do trono: {num2} em {dictionary2.Count} lugares distintos; {num3} repetidas (ate {num4} no mesmo ponto)");
			Dictionary<int, int> dictionary3 = new Dictionary<int, int>();
			foreach (ZDO value7 in ZDOMan.instance.m_objectsByID.Values)
			{
				if (value7 != null)
				{
					dictionary3.TryGetValue(value7.GetPrefab(), out var value3);
					dictionary3[value7.GetPrefab()] = value3 + 1;
				}
			}
			List<KeyValuePair<int, int>> list2 = new List<KeyValuePair<int, int>>(dictionary3);
			list2.Sort((KeyValuePair<int, int> a, KeyValuePair<int, int> b) => b.Value.CompareTo(a.Value));
			foreach (KeyValuePair<int, int> item2 in list2.GetRange(0, Mathf.Min(12, list2.Count)))
			{
				GameObject prefab3 = instance.GetPrefab(item2.Key);
				T.Nota($"  mundo: {((prefab3 != null) ? ((Object)prefab3).name : null) ?? item2.Key.ToString()}: {item2.Value}");
			}
			yield break;
		}

		private static IEnumerator Montarias()
		{
			foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
			{
				if ((Object)(object)prefab == (Object)null)
				{
					continue;
				}
				Sadle componentInChildren = prefab.GetComponentInChildren<Sadle>(true);
				if (!((Object)(object)componentInChildren == (Object)null))
				{
					Character component = prefab.GetComponent<Character>();
					Tameable component2 = prefab.GetComponent<Tameable>();
					MonsterAI component3 = prefab.GetComponent<MonsterAI>();
					string text = $"{((Object)prefab).name}: vida {component?.m_health} andar {component?.m_walkSpeed} vel {component?.m_speed} correr {component?.m_runSpeed} nadar {component?.m_swimSpeed} giro {component?.m_turnSpeed}/{component?.m_runTurnSpeed} pulo {component?.m_jumpForce} | ";
					object[] obj = new object[8]
					{
						((Object)componentInChildren).name,
						((Component)componentInChildren).gameObject.activeSelf,
						componentInChildren.m_maxStamina,
						componentInChildren.m_runStaminaDrain,
						componentInChildren.m_staminaRegen,
						componentInChildren.m_maxUseRange,
						componentInChildren.m_attachAnimation,
						null
					};
					Transform attachPoint = componentInChildren.m_attachPoint;
					obj[7] = ((attachPoint != null) ? ((Object)attachPoint).name : null);
					string text2 = string.Format("sela '{0}' ativa {1} stamina {2} gasto {3} regen {4} alcance {5} anim '{6}' ponto {7} | ", obj);
					object[] array = new object[7];
					object obj2;
					if (component2 == null)
					{
						obj2 = null;
					}
					else
					{
						ItemDrop saddleItem = component2.m_saddleItem;
						obj2 = ((saddleItem != null) ? ((Object)saddleItem).name : null);
					}
					array[0] = obj2;
					object obj3;
					if (component2 == null)
					{
						obj3 = null;
					}
					else
					{
						Sadle saddle = component2.m_saddle;
						obj3 = ((saddle != null) ? ((Object)saddle).name : null);
					}
					array[1] = obj3;
					array[2] = component2?.m_commandable;
					array[3] = component2?.m_tamingTime;
					array[4] = ((BaseAI)(component3?)).m_viewRange;
					array[5] = ((BaseAI)(component3?)).m_hearRange;
					array[6] = prefab.GetComponent<ZNetView>()?.m_persistent;
					T.Nota(text + text2 + string.Format("domar: item {0} sela {1} comandavel {2} tempo {3} | ai visao {4} ouvir {5} | persistente {6}", array));
				}
			}
			foreach (GameObject item in ObjectDB.instance.m_items)
			{
				SharedData val = ((!((Object)(object)item != (Object)null)) ? null : item.GetComponent<ItemDrop>()?.m_itemData?.m_shared);
				if (val == null)
				{
					continue;
				}
				bool flag = ((Object)item).name.ToLower().Contains("saddle");
				if ((int)val.m_itemType != 18 && (int)val.m_itemType != 24 && !flag)
				{
					continue;
				}
				List<string> list = new List<string>();
				foreach (Transform item2 in item.transform)
				{
					Transform val2 = item2;
					list.Add(((Object)val2).name);
				}
				object[] obj4 = new object[6]
				{
					((Object)item).name,
					val.m_itemType,
					val.m_weight,
					null,
					null,
					null
				};
				StatusEffect equipStatusEffect = val.m_equipStatusEffect;
				obj4[3] = ((equipStatusEffect != null) ? ((Object)equipStatusEffect).name : null);
				obj4[4] = ((val.m_icons != null && val.m_icons.Length != 0) ? ((Object)val.m_icons[0]).name : "-");
				obj4[5] = string.Join(",", list);
				T.Nota(string.Format("item {0}: {1} peso {2} efeito {3} icone {4} filhos [{5}]", obj4));
			}
			yield break;
		}

		private static IEnumerator Materiais(string item)
		{
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item);
			if ((Object)(object)itemPrefab == (Object)null)
			{
				T.Ok(c: false, item);
				yield break;
			}
			Renderer[] componentsInChildren = itemPrefab.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				Material[] sharedMaterials = val.sharedMaterials;
				foreach (Material m in sharedMaterials)
				{
					if (!((Object)(object)m == (Object)null))
					{
						T.Nota(string.Format("{0} {1} (ativo {2}): {3} [{4}] kw {5} {6} {7} {8} {9} {10}", ((object)val).GetType().Name, ((Object)val).name, ((Component)val).gameObject.activeInHierarchy, ((Object)m).name, ((Object)m.shader).name, string.Join(",", m.shaderKeywords), Cor("_Color"), Cor("_EmissionColor"), Cor("_TintColor"), Tex("_MainTex"), Tex("_EmissionMap")));
					}
					string Cor(string p)
					{
						//IL_0021: Unknown result type (might be due to invalid IL or missing references)
						if (!m.HasProperty(p))
						{
							return "";
						}
						return $"{p}={m.GetColor(p)}";
					}
					string Tex(string p)
					{
						if (!m.HasProperty(p) || !((Object)(object)m.GetTexture(p) != (Object)null))
						{
							return "";
						}
						return p + "=" + ((Object)m.GetTexture(p)).name;
					}
				}
			}
		}

		private unsafe static IEnumerator ModelosDoJogo()
		{
			SortedDictionary<string, List<string>> sortedDictionary = new SortedDictionary<string, List<string>>();
			foreach (GameObject item in ObjectDB.instance.m_items)
			{
				ItemData val = ((!((Object)(object)item != (Object)null)) ? null : item.GetComponent<ItemDrop>()?.m_itemData);
				if (val == null || ((Object)item).name.StartsWith("Helheim_") || ((Object)item).name.EndsWith("_FrostFire"))
				{
					continue;
				}
				SharedData shared = val.m_shared;
				ItemType itemType = shared.m_itemType;
				bool flag = (int)itemType == 3 || (int)itemType == 14 || (int)itemType == 22 || (int)itemType == 4 || (int)itemType == 5;
				bool flag2 = (int)itemType == 6 || (int)itemType == 7 || (int)itemType == 11 || (int)itemType == 17;
				if (flag || flag2)
				{
					string key = (flag ? $"{itemType}/{shared.m_skillType}/{shared.m_animationState}" : ((object)(*(ItemType*)(&itemType))/*cast due to .constrained prefix*/).ToString());
					if (!sortedDictionary.TryGetValue(key, out var value))
					{
						value = (sortedDictionary[key] = new List<string>());
					}
					bool flag3 = (Object)(object)ObjectDB.instance.GetItemPrefab(((Object)item).name + "_FrostFire") != (Object)null;
					string text;
					if (!flag2)
					{
						DamageTypes damage = val.GetDamage();
						text = $" dano {((DamageTypes)(ref damage)).GetTotalDamage():0}";
					}
					else
					{
						text = $" arm {shared.m_armor:0} mov {shared.m_movementModifier:0.##}" + ((shared.m_eitrRegenModifier > 0f) ? " eitr" : "");
					}
					string text2 = text;
					value.Add(((Object)item).name + (flag3 ? "*" : "") + text2 + ((shared.m_variants > 1) ? $" var{shared.m_variants}" : ""));
				}
			}
			foreach (KeyValuePair<string, List<string>> item2 in sortedDictionary)
			{
				T.Nota(item2.Key + ": " + string.Join(", ", item2.Value));
			}
			yield break;
		}

		private static IEnumerator BasesDeHel()
		{
			ZNetScene instance = ZNetScene.instance;
			List<string> list = new List<string>();
			foreach (GameObject prefab2 in instance.m_prefabs)
			{
				if ((Object)(object)prefab2 != (Object)null && (((Object)prefab2).name.Contains("FrozenKing") || ((Object)prefab2).name.Contains("Frozen_King") || ((Object)prefab2).name.Contains("Jotun") || ((Object)prefab2).name == "Fader") && (Object)(object)prefab2.GetComponent<Character>() != (Object)null)
				{
					list.Add(((Object)prefab2).name);
				}
			}
			T.Nota("criaturas: " + string.Join(", ", list));
			foreach (string item in list)
			{
				GameObject prefab = instance.GetPrefab(item);
				Character component = prefab.GetComponent<Character>();
				Humanoid component2 = prefab.GetComponent<Humanoid>();
				List<string> list2 = new List<string>();
				if ((Object)(object)component2 != (Object)null)
				{
					List<GameObject> list3 = new List<GameObject>();
					if (component2.m_defaultItems != null)
					{
						list3.AddRange(component2.m_defaultItems);
					}
					if (component2.m_randomWeapon != null)
					{
						list3.AddRange(component2.m_randomWeapon);
					}
					foreach (GameObject item2 in list3)
					{
						ItemData val = ((!((Object)(object)item2 != (Object)null)) ? null : item2.GetComponent<ItemDrop>()?.m_itemData);
						if (val != null)
						{
							Attack attack = val.m_shared.m_attack;
							object[] obj = new object[6]
							{
								((Object)item2).name,
								null,
								null,
								null,
								null,
								null
							};
							DamageTypes damage = val.GetDamage();
							obj[1] = ((DamageTypes)(ref damage)).GetTotalDamage();
							obj[2] = attack?.m_attackAnimation;
							object obj2;
							if (attack == null)
							{
								obj2 = null;
							}
							else
							{
								GameObject attackProjectile = attack.m_attackProjectile;
								obj2 = ((attackProjectile != null) ? ((Object)attackProjectile).name : null);
							}
							obj[3] = obj2;
							obj[4] = val.m_shared.m_aiAttackInterval;
							obj[5] = val.m_shared.m_aiAttackRange;
							list2.Add(string.Format("{0}(dano {1:0}, anim {2}, proj {3}, int {4}, alc {5})", obj));
						}
					}
				}
				List<string> list4 = new List<string>();
				MonoBehaviour[] componentsInChildren = prefab.GetComponentsInChildren<MonoBehaviour>(true);
				foreach (MonoBehaviour val2 in componentsInChildren)
				{
					if ((Object)(object)val2 != (Object)null && !list4.Contains(((object)val2).GetType().Name))
					{
						list4.Add(((object)val2).GetType().Name);
					}
				}
				List<string> list5 = new List<string>();
				Renderer[] componentsInChildren2 = prefab.GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val3 in componentsInChildren2)
				{
					if (!(val3 is ParticleSystemRenderer))
					{
						Material sharedMaterial = val3.sharedMaterial;
						object[] obj3 = new object[5]
						{
							((Object)val3).name,
							(sharedMaterial != null) ? ((Object)sharedMaterial).name : null,
							null,
							null,
							null
						};
						object obj4;
						if (sharedMaterial == null)
						{
							obj4 = null;
						}
						else
						{
							Shader shader = sharedMaterial.shader;
							obj4 = ((shader != null) ? ((Object)shader).name : null);
						}
						obj3[2] = obj4;
						obj3[3] = (Object)(object)sharedMaterial != (Object)null && sharedMaterial.HasProperty("_EmissionMap") && (Object)(object)sharedMaterial.GetTexture("_EmissionMap") != (Object)null;
						obj3[4] = (((Object)(object)sharedMaterial != (Object)null && sharedMaterial.HasProperty("_NoiseGlowEnabled")) ? sharedMaterial.GetFloat("_NoiseGlowEnabled") : (-1f));
						list5.Add(string.Format("{0}[{1}|{2}|mapa {3}|ruido {4:0}]", obj3));
					}
				}
				List<string> list6 = new List<string>();
				Transform[] componentsInChildren3 = prefab.GetComponentsInChildren<Transform>(true);
				foreach (Transform val4 in componentsInChildren3)
				{
					string text = ((Object)val4).name.ToLowerInvariant();
					if (text.Contains("head") || text.Contains("spine") || text.Contains("neck") || text.Contains("back") || text.Contains("helmet") || text.Contains("hand") || text.Contains("saddle") || text.Contains("mount"))
					{
						list6.Add($"{((Object)val4).name}({val4.lossyScale.x:0.##})");
					}
				}
				CapsuleCollider component3 = prefab.GetComponent<CapsuleCollider>();
				T.Nota(string.Format("{0}: vida {1}, chefe {2}, voa {3}, chave '{4}', faccao {5}, capsula {6:0.#}x{7:0.#}, comps [{8}], armas [{9}], renderers [{10}], ossos [{11}]", item, component?.m_health, component?.m_boss, component?.m_flying, component?.m_defeatSetGlobalKey, component?.m_faction, (component3 != null) ? new float?(component3.height) : ((float?)null), (component3 != null) ? new float?(component3.radius) : ((float?)null), string.Join(",", list4), string.Join("; ", list2), string.Join("; ", list5), string.Join(" ", list6)));
			}
			List<string> list7 = new List<string>();
			foreach (GameObject item3 in ObjectDB.instance.m_items)
			{
				if ((Object)(object)item3 != (Object)null && (((Object)item3).name.Contains("FrozenKing") || ((Object)item3).name.Contains("TrophyFader") || ((Object)item3).name.Contains("Jotun")))
				{
					list7.Add(((Object)item3).name);
				}
			}
			T.Nota("itens: " + string.Join(", ", list7));
			List<string> list8 = new List<string>();
			foreach (GameObject prefab3 in instance.m_prefabs)
			{
				if ((Object)(object)prefab3 != (Object)null && (((Object)prefab3).name.Contains("FrozenKing") || ((Object)prefab3).name.Contains("Fader")) && (Object)(object)prefab3.GetComponent<Character>() == (Object)null)
				{
					list8.Add(((Object)prefab3).name);
				}
			}
			T.Nota("prefabs: " + string.Join(", ", list8));
			yield break;
		}

		private static IEnumerator BasesDoForjador()
		{
			ZNetScene instance = ZNetScene.instance;
			string[] array = new string[8] { "Charred_Melee_Dyrnwyn", "Charred_Melee_Fader", "Charred_Melee", "Fader", "GoblinKing", "Dragon", "Troll_Summoned", "Charred_Mage" };
			foreach (string text in array)
			{
				GameObject prefab = instance.GetPrefab(text);
				if ((Object)(object)prefab == (Object)null)
				{
					T.Nota(text + ": NAO");
					continue;
				}
				Character component = prefab.GetComponent<Character>();
				Humanoid component2 = prefab.GetComponent<Humanoid>();
				List<string> list = new List<string>();
				if ((Object)(object)component2 != (Object)null)
				{
					List<GameObject> list2 = new List<GameObject>();
					if (component2.m_defaultItems != null)
					{
						list2.AddRange(component2.m_defaultItems);
					}
					if (component2.m_randomWeapon != null)
					{
						list2.AddRange(component2.m_randomWeapon);
					}
					foreach (GameObject item in list2)
					{
						ItemData val = ((!((Object)(object)item != (Object)null)) ? null : item.GetComponent<ItemDrop>()?.m_itemData);
						if (val != null)
						{
							Attack attack = val.m_shared.m_attack;
							object[] obj = new object[7]
							{
								((Object)item).name,
								null,
								null,
								null,
								null,
								null,
								null
							};
							DamageTypes damage = val.GetDamage();
							obj[1] = ((DamageTypes)(ref damage)).GetTotalDamage();
							obj[2] = attack?.m_attackAnimation;
							obj[3] = attack?.m_attackType;
							object obj2;
							if (attack == null)
							{
								obj2 = null;
							}
							else
							{
								GameObject attackProjectile = attack.m_attackProjectile;
								obj2 = ((attackProjectile != null) ? ((Object)attackProjectile).name : null);
							}
							obj[4] = obj2;
							obj[5] = val.m_shared.m_aiAttackInterval;
							obj[6] = val.m_shared.m_aiAttackRange;
							list.Add(string.Format("{0}(dano {1:0}, anim {2}, t