using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using MuckShrineOfChance;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Rendering;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("MuckUfoAbduction")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A Shrine of Chance outcome: a flying saucer abducts the player who spun and drops them far across the island.")]
[assembly: AssemblyFileVersion("0.1.1.0")]
[assembly: AssemblyInformationalVersion("0.1.1+5caa96df932c509d2f99e20681f4a02fa2d68991")]
[assembly: AssemblyProduct("UFO Abduction")]
[assembly: AssemblyTitle("MuckUfoAbduction")]
[assembly: InternalsVisibleTo("MuckUfoAbduction.Tests")]
[assembly: AssemblyVersion("0.1.1.0")]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
internal sealed class IsReadOnlyAttribute : Attribute
{
}
}
namespace MuckUfoAbduction
{
internal static class PlayerNames
{
public static string Of(int clientId)
{
Dictionary<int, PlayerManager> players = GameManager.players;
if (players != null && players.TryGetValue(clientId, out var value) && (Object)(object)value != (Object)null && !string.IsNullOrEmpty(value.username))
{
return value.username;
}
return "Someone";
}
}
internal static class UfoArt
{
private const string Prefix = "MuckUfoAbduction.";
public const string SaucerObj = "MuckUfoAbduction.ufo.obj";
public const string SaucerJson = "MuckUfoAbduction.ufo.json";
public const string BeamObj = "MuckUfoAbduction.ufo_beam.obj";
public const string BeamJson = "MuckUfoAbduction.ufo_beam.json";
internal static readonly string[] BodyShaders = new string[2] { "Standard", "Legacy Shaders/Diffuse" };
internal static readonly string[] BeamShaders = new string[2] { "Legacy Shaders/Particles/Additive", "Sprites/Default" };
private static bool built;
private static Mesh saucerMesh;
private static Material[] saucerMaterials;
private static Mesh beamMesh;
private static Material beamMaterial;
private static readonly Dictionary<string, Texture2D> Textures = new Dictionary<string, Texture2D>();
public static int LightsSubMesh { get; private set; } = -1;
public static Color LightsEmission { get; private set; }
public static bool TryGetSaucer(out Mesh mesh, out Material[] materials)
{
BuildOnce();
mesh = saucerMesh;
materials = saucerMaterials;
if ((Object)(object)mesh != (Object)null)
{
return materials != null;
}
return false;
}
public static bool TryGetBeam(out Mesh mesh, out Material material)
{
BuildOnce();
mesh = beamMesh;
material = beamMaterial;
if ((Object)(object)mesh != (Object)null)
{
return (Object)(object)material != (Object)null;
}
return false;
}
internal static UfoModel Load(string obj, string json)
{
return UfoModel.Parse(Text(obj), Text(json));
}
internal static string Choose(IList<string> wanted, Func<string, bool> available)
{
foreach (string item in wanted)
{
if (available(item))
{
return item;
}
}
return null;
}
private static void BuildOnce()
{
//IL_017f: Unknown result type (might be due to invalid IL or missing references)
if (built)
{
return;
}
built = true;
string text = Choose(BodyShaders, (string name) => (Object)(object)Shader.Find(name) != (Object)null);
string text2 = Choose(BeamShaders, (string name) => (Object)(object)Shader.Find(name) != (Object)null);
UfoPlugin.Log.LogInfo((object)("UFO shader: body '" + (text ?? "none") + "'" + ((text == "Standard") ? " (normal map, emission map, premultiplied glass)" : "") + ", beam '" + (text2 ?? "none") + "'."));
try
{
UfoModel ufoModel = Load("MuckUfoAbduction.ufo.obj", "MuckUfoAbduction.ufo.json");
if (text == null)
{
throw new InvalidOperationException("no body shader");
}
saucerMesh = ToMesh(ufoModel, "UFO saucer");
saucerMaterials = (Material[])(object)new Material[ufoModel.SubMeshes.Count];
for (int num = 0; num < ufoModel.SubMeshes.Count; num++)
{
string material = ufoModel.SubMeshes[num].Material;
MaterialSpec materialSpec = ufoModel.Materials[material];
saucerMaterials[num] = ((materialSpec.Alpha < 1f) ? Glass(text, materialSpec, material) : Body(text, materialSpec, material));
if (LightsSubMesh < 0 && materialSpec.Emission > 0f)
{
LightsSubMesh = num;
LightsEmission = Emission(materialSpec);
}
}
UfoPlugin.Log.LogInfo((object)$"UFO saucer built: {ufoModel.TriangleCount} triangles, {ufoModel.Positions.Length} vertices, {ufoModel.SubMeshes.Count} materials, {Textures.Count} textures.");
}
catch (Exception ex)
{
saucerMesh = null;
saucerMaterials = null;
UfoPlugin.Log.LogWarning((object)("UFO saucer model was not built (" + ex.Message + "). The UFO shows as a light only."));
}
try
{
UfoModel ufoModel2 = Load("MuckUfoAbduction.ufo_beam.obj", "MuckUfoAbduction.ufo_beam.json");
if (text2 == null)
{
throw new InvalidOperationException("no beam shader");
}
beamMesh = ToMesh(ufoModel2, "UFO beam");
beamMaterial = Beam(text2, ufoModel2.Materials[ufoModel2.SubMeshes[0].Material]);
}
catch (Exception ex2)
{
beamMesh = null;
beamMaterial = null;
UfoPlugin.Log.LogWarning((object)("UFO beam was not built (" + ex2.Message + "). The UFO lifts without a visible beam."));
}
}
private static Mesh ToMesh(UfoModel model, string name)
{
//IL_0000: 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_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Expected O, but got Unknown
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
Mesh val = new Mesh
{
name = name,
hideFlags = (HideFlags)32
};
if (model.Positions.Length > 65000)
{
val.indexFormat = (IndexFormat)1;
}
List<Vector3> list = new List<Vector3>(model.Positions.Length);
List<Vector3> list2 = new List<Vector3>(model.Positions.Length);
List<Vector2> list3 = new List<Vector2>(model.Positions.Length);
for (int i = 0; i < model.Positions.Length; i++)
{
list.Add(new Vector3(model.Positions[i].X, model.Positions[i].Y, model.Positions[i].Z));
list2.Add(new Vector3(model.Normals[i].X, model.Normals[i].Y, model.Normals[i].Z));
list3.Add(new Vector2(model.U[i], model.V[i]));
}
val.SetVertices(list);
val.SetNormals(list2);
val.SetUVs(0, list3);
val.subMeshCount = model.SubMeshes.Count;
for (int j = 0; j < model.SubMeshes.Count; j++)
{
val.SetTriangles(model.SubMeshes[j].Triangles, j);
}
val.RecalculateTangents();
val.RecalculateBounds();
return val;
}
private static Material Body(string shader, MaterialSpec spec, string name)
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
Material val = New(shader, name);
val.color = new Color(spec.R, spec.G, spec.B, 1f);
if (spec.Albedo != null)
{
val.mainTexture = (Texture)(object)Texture(spec.Albedo, linear: false);
}
val.SetFloat("_Metallic", spec.Metallic);
val.SetFloat("_Glossiness", spec.Smoothness);
if (spec.Normal != null && val.HasProperty("_BumpMap"))
{
val.SetTexture("_BumpMap", (Texture)(object)Texture(spec.Normal, linear: true));
val.SetFloat("_BumpScale", 1f);
val.EnableKeyword("_NORMALMAP");
}
if (spec.Emission > 0f && val.HasProperty("_EmissionColor"))
{
if (spec.EmissionMap != null)
{
val.SetTexture("_EmissionMap", (Texture)(object)Texture(spec.EmissionMap, linear: false));
}
val.SetColor("_EmissionColor", Emission(spec));
val.EnableKeyword("_EMISSION");
val.globalIlluminationFlags = (MaterialGlobalIlluminationFlags)1;
}
return val;
}
private static Material Glass(string shader, MaterialSpec spec, string name)
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
Material val = New(shader, name);
val.color = new Color(spec.R, spec.G, spec.B, spec.Alpha);
val.SetFloat("_Metallic", spec.Metallic);
val.SetFloat("_Glossiness", spec.Smoothness);
if (shader != "Standard")
{
return val;
}
val.SetFloat("_Mode", 3f);
val.SetInt("_SrcBlend", 1);
val.SetInt("_DstBlend", 10);
val.SetInt("_ZWrite", 0);
val.EnableKeyword("_ALPHAPREMULTIPLY_ON");
val.renderQueue = 3000;
return val;
}
private static Material Beam(string shader, MaterialSpec spec)
{
//IL_008f: 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_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
Material val = New(shader, "UFO beam");
if (spec.Albedo != null)
{
val.mainTexture = (Texture)(object)Texture(spec.Albedo, linear: false);
}
Color val2 = default(Color);
((Color)(ref val2))..ctor(spec.R, spec.G, spec.B, spec.Alpha);
if (val.HasProperty("_TintColor"))
{
val.SetColor("_TintColor", new Color(val2.r * 0.5f, val2.g * 0.5f, val2.b * 0.5f, val2.a));
}
else
{
val.color = val2;
}
return val;
}
private static Material New(string shader, string name)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
return new Material(Shader.Find(shader))
{
name = name,
hideFlags = (HideFlags)32
};
}
private static Color Emission(MaterialSpec spec)
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
return new Color(spec.EmissionR * spec.Emission, spec.EmissionG * spec.Emission, spec.EmissionB * spec.Emission, 1f);
}
private static Texture2D Texture(string file, bool linear)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Expected O, but got Unknown
if (Textures.TryGetValue(file, out var value))
{
return value;
}
Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true);
if (!ImageConversion.LoadImage(val, Bytes("MuckUfoAbduction." + file)))
{
throw new InvalidDataException(file + " is not an image");
}
Texture2D val2 = val;
if (linear)
{
val2 = new Texture2D(((Texture)val).width, ((Texture)val).height, (TextureFormat)4, true, true);
val2.SetPixels32(val.GetPixels32());
Object.Destroy((Object)(object)val);
}
((Object)val2).name = file;
((Texture)val2).wrapMode = (TextureWrapMode)0;
((Texture)val2).anisoLevel = 4;
((Object)val2).hideFlags = (HideFlags)32;
val2.Apply(true, true);
Textures.Add(file, val2);
return val2;
}
private static byte[] Bytes(string name)
{
using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name);
if (stream == null)
{
throw new FileNotFoundException(name);
}
using MemoryStream memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
private static string Text(string name)
{
using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name);
if (stream == null)
{
throw new FileNotFoundException(name);
}
using StreamReader streamReader = new StreamReader(stream);
return streamReader.ReadToEnd();
}
}
internal static class UfoDrop
{
public static void Aim(float px, float pz, float u, float v, float min, float max, out float x, out float z)
{
if (max < min)
{
max = min;
}
double num = (double)u * 2.0 * Math.PI;
double num2 = Math.Sqrt((double)(min * min) + (double)(max * max - min * min) * (double)v);
x = (float)((double)px + Math.Cos(num) * num2);
z = (float)((double)pz + Math.Sin(num) * num2);
}
}
internal static class UfoRules
{
public const float BossRadius = 50f;
public static bool Abducts(bool alive, bool bossNear, bool dropFound)
{
return alive && !bossNear && dropFound;
}
public static bool BossNear(bool bossType, bool mobTypeBoss, float distance)
{
if (bossType || mobTypeBoss)
{
return distance <= 50f;
}
return false;
}
}
internal static class UfoHost
{
private const int DropAttempts = 40;
public static void Launch(int shrineId, int useIndex, int clientId, Vector3 shrinePos)
{
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_0128: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: Unknown result type (might be due to invalid IL or missing references)
//IL_0134: Unknown result type (might be due to invalid IL or missing references)
//IL_013a: Unknown result type (might be due to invalid IL or missing references)
//IL_0141: Unknown result type (might be due to invalid IL or missing references)
//IL_0148: Unknown result type (might be due to invalid IL or missing references)
PlayerManager value = null;
GameManager.players?.TryGetValue(clientId, out value);
bool flag = (Object)(object)value != (Object)null && !value.dead;
Vector3 val = (((Object)(object)value != (Object)null) ? ((Component)value).transform.position : shrinePos);
bool flag2 = BossNear(val);
Vector3 drop = val;
bool dropFound = flag && !flag2 && TryDrop(val, out drop);
bool flag3 = UfoRules.Abducts(flag, flag2, dropFound);
if (!flag3)
{
drop = val;
}
if (flag3)
{
UfoPlugin.Log.LogInfo((object)$"UFO abduction start: client {clientId} from {UfoText.Point(val.x, val.y, val.z)} to {UfoText.Point(drop.x, drop.y, drop.z)}, {UfoText.Metres(UfoText.FlatDistance(val.x, val.z, drop.x, drop.z))} m.");
}
else
{
UfoPlugin.Log.LogInfo((object)$"UFO flyby: client {clientId} ({UfoText.FlybyReason(flag, flag2, dropFound)}).");
}
string text = UfoWire.Encode(new UfoTrip(shrineId, useIndex, clientId, flag3, val.x, val.y, val.z, drop.x, drop.y, drop.z));
ServerSend.SendChatMessage(-1, "", text);
UfoShow.Present(text);
}
private static bool BossNear(Vector3 at)
{
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Invalid comparison between Unknown and I4
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
MobManager instance = MobManager.Instance;
if ((Object)(object)instance == (Object)null || instance.mobs == null)
{
return false;
}
foreach (KeyValuePair<int, Mob> mob in instance.mobs)
{
Mob value = mob.Value;
if (!((Object)(object)value == (Object)null))
{
bool mobTypeBoss = (Object)(object)value.mobType != (Object)null && value.mobType.boss;
if (UfoRules.BossNear((int)value.bossType > 0, mobTypeBoss, Vector3.Distance(((Component)value).transform.position, at)))
{
return true;
}
}
}
return false;
}
private static bool TryDrop(Vector3 from, out Vector3 drop)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
drop = from;
float value = UfoPlugin.Cfg.MinDistance.Value;
float value2 = UfoPlugin.Cfg.MaxDistance.Value;
int mask = LayerMask.GetMask(new string[2] { "Ground", "Terrain" });
RaycastHit val = default(RaycastHit);
NavMeshHit val2 = default(NavMeshHit);
for (int i = 0; i < 40; i++)
{
UfoDrop.Aim(from.x, from.z, Random.value, Random.value, value, value2, out var x, out var z);
if (Physics.Raycast(new Vector3(x, from.y + 300f, z), Vector3.down, ref val, 800f, mask) && (int)WorldUtility.WorldHeightToBiome(((RaycastHit)(ref val)).point.y - 0.5f) != 0 && NavMesh.SamplePosition(((RaycastHit)(ref val)).point, ref val2, 3f, -1))
{
drop = ((NavMeshHit)(ref val2)).position;
return true;
}
}
return false;
}
}
internal readonly struct Vec3
{
public readonly float X;
public readonly float Y;
public readonly float Z;
public Vec3(float x, float y, float z)
{
X = x;
Y = y;
Z = z;
}
}
internal sealed class MaterialSpec
{
public float R = 1f;
public float G = 1f;
public float B = 1f;
public float Alpha = 1f;
public float Metallic;
public float Smoothness;
public float Emission;
public float EmissionR = 1f;
public float EmissionG = 1f;
public float EmissionB = 1f;
public string Albedo;
public string Normal;
public string EmissionMap;
}
internal sealed class SubMesh
{
public readonly string Material;
public readonly int[] Triangles;
public SubMesh(string material, int[] triangles)
{
Material = material;
Triangles = triangles;
}
}
internal sealed class UfoModel
{
public readonly string Name;
public readonly Vec3[] Positions;
public readonly Vec3[] Normals;
public readonly float[] U;
public readonly float[] V;
public readonly IReadOnlyList<SubMesh> SubMeshes;
public readonly IReadOnlyDictionary<string, MaterialSpec> Materials;
public readonly int TriangleCount;
private UfoModel(string name, Vec3[] positions, Vec3[] normals, float[] u, float[] v, IReadOnlyList<SubMesh> subMeshes, IReadOnlyDictionary<string, MaterialSpec> materials, int triangles)
{
Name = name;
Positions = positions;
Normals = normals;
U = u;
V = v;
SubMeshes = subMeshes;
Materials = materials;
TriangleCount = triangles;
}
public static UfoModel Parse(string objText, string json)
{
if (!(JsonReader.Parse(json) is Dictionary<string, object> obj))
{
throw new FormatException("model json: top level is not an object.");
}
string text = Str(obj, "name");
Dictionary<string, MaterialSpec> dictionary = ReadMaterials(Obj(obj, "materials"));
if (objText == null)
{
throw new FormatException(text + ": OBJ text is null.");
}
List<Vec3> list = new List<Vec3>();
List<Vec3> list2 = new List<Vec3>();
List<float[]> list3 = new List<float[]>();
Dictionary<string, int> dictionary2 = new Dictionary<string, int>();
List<Vec3> list4 = new List<Vec3>();
List<Vec3> list5 = new List<Vec3>();
List<float> list6 = new List<float>();
List<float> list7 = new List<float>();
List<string> list8 = new List<string>();
Dictionary<string, List<int>> dictionary3 = new Dictionary<string, List<int>>();
int num = 0;
int num2 = 0;
string text2 = null;
string[] array = objText.Split(new char[1] { '\n' });
for (int i = 0; i < array.Length; i++)
{
string[] array2 = array[i].Trim().Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries);
if (array2.Length == 0)
{
continue;
}
switch (array2[0])
{
case "v":
{
Vec3 vec = ReadVec(array2, text, i);
list.Add(new Vec3(0f - vec.X, vec.Y, vec.Z));
break;
}
case "vn":
{
Vec3 vec2 = ReadVec(array2, text, i);
list2.Add(new Vec3(0f - vec2.X, vec2.Y, vec2.Z));
break;
}
case "vt":
if (array2.Length < 3)
{
throw new FormatException($"{text}: OBJ line {i + 1} needs two numbers.");
}
list3.Add(new float[2]
{
Float(array2[1], text, i),
Float(array2[2], text, i)
});
break;
case "o":
num++;
break;
case "usemtl":
text2 = ((array2.Length > 1) ? array2[1] : null);
if (text2 != null && !dictionary.ContainsKey(text2))
{
throw new FormatException(text + ": uses undefined material '" + text2 + "'.");
}
break;
case "f":
{
if (text2 == null)
{
throw new FormatException($"{text}: OBJ line {i + 1} has a face outside a material.");
}
if (array2.Length != 4)
{
throw new FormatException($"{text}: OBJ line {i + 1} is not a triangle.");
}
if (!dictionary3.TryGetValue(text2, out var value))
{
value = new List<int>();
dictionary3.Add(text2, value);
list8.Add(text2);
}
int[] array3 = new int[3] { 1, 3, 2 };
foreach (int num3 in array3)
{
if (!dictionary2.TryGetValue(array2[num3], out var value2))
{
string[] array4 = array2[num3].Split(new char[1] { '/' });
if (array4.Length < 3 || array4[1].Length == 0 || array4[2].Length == 0)
{
throw new FormatException($"{text}: OBJ line {i + 1} has a corner without a UV or a normal.");
}
value2 = list4.Count;
list4.Add(list[Index(array4[0], list.Count, text, i)]);
float[] array5 = list3[Index(array4[1], list3.Count, text, i)];
list6.Add(array5[0]);
list7.Add(array5[1]);
list5.Add(list2[Index(array4[2], list2.Count, text, i)]);
dictionary2.Add(array2[num3], value2);
}
value.Add(value2);
}
num2++;
break;
}
}
}
if (num != 1)
{
throw new FormatException($"{text}: the OBJ needs exactly one object, it has {num}.");
}
int num4 = (int)Num(obj, "tris");
if (num2 != num4)
{
throw new FormatException($"{text}: OBJ has {num2} triangles, the json says {num4}.");
}
List<SubMesh> list9 = new List<SubMesh>();
foreach (string item in list8)
{
list9.Add(new SubMesh(item, dictionary3[item].ToArray()));
}
return new UfoModel(text, list4.ToArray(), list5.ToArray(), list6.ToArray(), list7.ToArray(), list9, dictionary, num2);
}
private static Dictionary<string, MaterialSpec> ReadMaterials(Dictionary<string, object> raw)
{
Dictionary<string, MaterialSpec> dictionary = new Dictionary<string, MaterialSpec>();
foreach (KeyValuePair<string, object> item in raw)
{
if (!(item.Value is Dictionary<string, object> dictionary2))
{
throw new FormatException("model json: material " + item.Key + " is not an object.");
}
MaterialSpec materialSpec = new MaterialSpec();
if (dictionary2.ContainsKey("rgb"))
{
Vec3 vec = ReadVec3(dictionary2, "rgb");
materialSpec.R = vec.X;
materialSpec.G = vec.Y;
materialSpec.B = vec.Z;
}
if (dictionary2.ContainsKey("emission_rgb"))
{
Vec3 vec2 = ReadVec3(dictionary2, "emission_rgb");
materialSpec.EmissionR = vec2.X;
materialSpec.EmissionG = vec2.Y;
materialSpec.EmissionB = vec2.Z;
}
else
{
materialSpec.EmissionR = materialSpec.R;
materialSpec.EmissionG = materialSpec.G;
materialSpec.EmissionB = materialSpec.B;
}
materialSpec.Alpha = Optional(dictionary2, "alpha", 1f);
materialSpec.Metallic = Optional(dictionary2, "metallic", 0f);
materialSpec.Smoothness = Optional(dictionary2, "smoothness", 0f);
materialSpec.Emission = Optional(dictionary2, "emission", 0f);
if (dictionary2.TryGetValue("textures", out var value) && value is Dictionary<string, object> dictionary3)
{
materialSpec.Albedo = (dictionary3.TryGetValue("albedo", out var value2) ? (value2 as string) : null);
materialSpec.Normal = (dictionary3.TryGetValue("normal", out var value3) ? (value3 as string) : null);
materialSpec.EmissionMap = (dictionary3.TryGetValue("emission", out var value4) ? (value4 as string) : null);
}
dictionary.Add(item.Key, materialSpec);
}
return dictionary;
}
private static int Index(string raw, int count, string name, int line)
{
if (!int.TryParse(raw, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) || result == 0)
{
throw new FormatException($"{name}: OBJ line {line + 1} has a bad index '{raw}'.");
}
int num = ((result > 0) ? (result - 1) : (count + result));
if (num < 0 || num >= count)
{
throw new FormatException($"{name}: OBJ line {line + 1} index {raw} is out of range.");
}
return num;
}
private static Vec3 ReadVec(string[] tokens, string name, int line)
{
if (tokens.Length < 4)
{
throw new FormatException($"{name}: OBJ line {line + 1} needs three numbers.");
}
return new Vec3(Float(tokens[1], name, line), Float(tokens[2], name, line), Float(tokens[3], name, line));
}
private static float Float(string raw, string name, int line)
{
if (!float.TryParse(raw, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
{
throw new FormatException($"{name}: OBJ line {line + 1} has a bad number '{raw}'.");
}
return result;
}
private static Vec3 ReadVec3(Dictionary<string, object> obj, string key)
{
List<object> list = (Field(obj, key) as List<object>) ?? throw new FormatException("model json: '" + key + "' is not an array.");
if (list.Count != 3 || !(list[0] is double num) || !(list[1] is double num2) || !(list[2] is double num3))
{
throw new FormatException("model json: '" + key + "' is not three numbers.");
}
return new Vec3((float)num, (float)num2, (float)num3);
}
private static float Optional(Dictionary<string, object> obj, string key, float fallback)
{
if (!obj.TryGetValue(key, out var value) || !(value is double num))
{
return fallback;
}
return (float)num;
}
private static object Field(Dictionary<string, object> obj, string key)
{
if (!obj.TryGetValue(key, out var value))
{
throw new FormatException("model json: missing '" + key + "'.");
}
return value;
}
private static string Str(Dictionary<string, object> obj, string key)
{
return (Field(obj, key) as string) ?? throw new FormatException("model json: '" + key + "' is not a string.");
}
private static double Num(Dictionary<string, object> obj, string key)
{
object obj2 = Field(obj, key);
if (obj2 is double)
{
return (double)obj2;
}
throw new FormatException("model json: '" + key + "' is not a number.");
}
private static Dictionary<string, object> Obj(Dictionary<string, object> obj, string key)
{
return (Field(obj, key) as Dictionary<string, object>) ?? throw new FormatException("model json: '" + key + "' is not an object.");
}
}
internal sealed class JsonReader
{
private readonly string text;
private int pos;
private JsonReader(string text)
{
this.text = text;
}
public static object Parse(string text)
{
if (text == null)
{
throw new FormatException("JSON text is null.");
}
JsonReader jsonReader = new JsonReader(text);
object result = jsonReader.ReadValue();
jsonReader.SkipWhitespace();
if (jsonReader.pos != text.Length)
{
throw jsonReader.Error("trailing characters");
}
return result;
}
private object ReadValue()
{
SkipWhitespace();
if (pos >= text.Length)
{
throw Error("unexpected end");
}
char c = text[pos];
switch (c)
{
case '{':
return ReadObject();
case '[':
return ReadArray();
case '"':
return ReadString();
case 't':
Expect("true");
return true;
case 'f':
Expect("false");
return false;
case 'n':
Expect("null");
return null;
default:
switch (c)
{
case '-':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return ReadNumber();
default:
throw Error($"unexpected '{c}'");
}
}
}
private Dictionary<string, object> ReadObject()
{
Dictionary<string, object> dictionary = new Dictionary<string, object>();
pos++;
SkipWhitespace();
if (Peek() == '}')
{
pos++;
return dictionary;
}
while (true)
{
SkipWhitespace();
if (Peek() != '"')
{
throw Error("expected a key");
}
string key = ReadString();
SkipWhitespace();
if (Peek() != ':')
{
break;
}
pos++;
dictionary[key] = ReadValue();
SkipWhitespace();
char c = Peek();
pos++;
switch (c)
{
case ',':
break;
case '}':
return dictionary;
default:
throw Error("expected ',' or '}'");
}
}
throw Error("expected ':'");
}
private List<object> ReadArray()
{
List<object> list = new List<object>();
pos++;
SkipWhitespace();
if (Peek() == ']')
{
pos++;
return list;
}
while (true)
{
list.Add(ReadValue());
SkipWhitespace();
char c = Peek();
pos++;
switch (c)
{
case ',':
break;
case ']':
return list;
default:
throw Error("expected ',' or ']'");
}
}
}
private string ReadString()
{
pos++;
StringBuilder stringBuilder = new StringBuilder();
while (pos < text.Length)
{
char c = text[pos++];
switch (c)
{
case '"':
return stringBuilder.ToString();
default:
stringBuilder.Append(c);
break;
case '\\':
{
if (pos >= text.Length)
{
throw Error("unterminated escape");
}
char c2 = text[pos++];
switch (c2)
{
case '"':
stringBuilder.Append('"');
break;
case '\\':
stringBuilder.Append('\\');
break;
case '/':
stringBuilder.Append('/');
break;
case 'b':
stringBuilder.Append('\b');
break;
case 'f':
stringBuilder.Append('\f');
break;
case 'n':
stringBuilder.Append('\n');
break;
case 'r':
stringBuilder.Append('\r');
break;
case 't':
stringBuilder.Append('\t');
break;
case 'u':
if (pos + 4 > text.Length)
{
throw Error("short \\u escape");
}
stringBuilder.Append((char)int.Parse(text.Substring(pos, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture));
pos += 4;
break;
default:
throw Error($"bad escape '\\{c2}'");
}
break;
}
}
}
throw Error("unterminated string");
}
private double ReadNumber()
{
int num = pos;
while (pos < this.text.Length && "+-0123456789.eE".IndexOf(this.text[pos]) >= 0)
{
pos++;
}
string text = this.text.Substring(num, pos - num);
if (!double.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
{
throw Error("bad number '" + text + "'");
}
return result;
}
private void Expect(string word)
{
if (string.CompareOrdinal(text, pos, word, 0, word.Length) != 0)
{
throw Error("expected '" + word + "'");
}
pos += word.Length;
}
private char Peek()
{
if (pos >= text.Length)
{
return '\0';
}
return text[pos];
}
private void SkipWhitespace()
{
while (pos < text.Length && char.IsWhiteSpace(text[pos]))
{
pos++;
}
}
private FormatException Error(string what)
{
return new FormatException($"JSON: {what} at offset {pos}.");
}
}
[HarmonyPatch(typeof(ChatBox), "AppendMessage")]
internal static class UfoChatPatch
{
private static bool Prefix(int fromUser, string message)
{
if (!UfoWire.Hidden(message))
{
return true;
}
if (fromUser == -1)
{
UfoShow.Present(message);
}
return false;
}
}
[HarmonyPatch(typeof(PlayerStatus), "Damage")]
internal static class UfoDamagePatch
{
private static bool Prefix()
{
return !UfoShow.Shielded;
}
}
[HarmonyPatch(typeof(PlayerStatus), "DealDamage")]
internal static class UfoDealDamagePatch
{
private static bool Prefix()
{
return !UfoShow.Shielded;
}
}
[BepInPlugin("evan.muck.ufoabduction", "UFO Abduction", "0.1.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class UfoPlugin : BaseUnityPlugin
{
public const string Guid = "evan.muck.ufoabduction";
public const string Name = "UFO Abduction";
public const string Version = "0.1.1";
public const string OutcomeId = "evan.muck.ufoabduction.ufo";
internal static readonly Color Cyan = new Color(0.3f, 0.92f, 1f);
internal static ManualLogSource Log;
internal static UfoConfig Cfg;
private void Awake()
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Expected O, but got Unknown
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
Cfg = new UfoConfig(((BaseUnityPlugin)this).Config);
Harmony harmony = new Harmony("evan.muck.ufoabduction");
if (!TryPatch(harmony, typeof(UfoChatPatch)))
{
Log.LogError((object)"UFO Abduction 0.1.1 could not hook ChatBox.AppendMessage, so no peer could see a UFO. The UFO stays out of the shrine's odds.");
return;
}
if (!TryPatch(harmony, typeof(UfoDamagePatch)) || !TryPatch(harmony, typeof(UfoDealDamagePatch)))
{
Log.LogWarning((object)"UFO Abduction could not hook PlayerStatus damage. An abducted player can still be hurt.");
}
ShrineOutcomeRegistry.Register(new ShrineOutcomeSpec("evan.muck.ufoabduction.ufo", "UFO", "UFO", Cyan, "Three UFOs! Look up.", (Func<double>)(() => UfoText.Share(Cfg.Enabled.Value, Cfg.Chance.Value, Cfg.Force.Value)), (Action<ShrineOutcomeRoll>)delegate(ShrineOutcomeRoll roll)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
UfoHost.Launch(((ShrineOutcomeRoll)(ref roll)).ShrineId, ((ShrineOutcomeRoll)(ref roll)).UseIndex, ((ShrineOutcomeRoll)(ref roll)).ClientId, ((ShrineOutcomeRoll)(ref roll)).ShrinePosition);
}));
Log.LogInfo((object)string.Format("{0} {1} loaded. UFO share {2:0.##}% of every shrine roll. Every player must share this config.", "UFO Abduction", "0.1.1", UfoText.Share(Cfg.Enabled.Value, Cfg.Chance.Value, Cfg.Force.Value) * 100.0));
}
private static bool TryPatch(Harmony harmony, Type patchClass)
{
try
{
harmony.CreateClassProcessor(patchClass).Patch();
return true;
}
catch (Exception arg)
{
Log.LogError((object)string.Format("{0} failed to patch {1}: {2}", "UFO Abduction", patchClass.Name, arg));
return false;
}
}
}
internal sealed class UfoConfig
{
public readonly ConfigEntry<bool> Enabled;
public readonly ConfigEntry<float> Chance;
public readonly ConfigEntry<float> MinDistance;
public readonly ConfigEntry<float> MaxDistance;
public readonly ConfigEntry<bool> Force;
public readonly ConfigEntry<bool> VerboseLogging;
public UfoConfig(ConfigFile cfg)
{
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Expected O, but got Unknown
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Expected O, but got Unknown
//IL_00be: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Expected O, but got Unknown
Enabled = cfg.Bind<bool>("UFO", "Enabled", true, "A Shrine of Chance roll can bring a flying saucer over the player who spun. It lifts them up its beam and drops them somewhere else on the island, unhurt. Every player must use the same value.");
Chance = cfg.Bind<float>("UFO", "Chance", 10f, new ConfigDescription("Percent of every paid Shrine of Chance roll that brings the UFO. The six built-in tiers, Nuke included, share what is left, keeping their relative weights. Every player must use the same value.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f), Array.Empty<object>()));
MinDistance = cfg.Bind<float>("UFO", "MinDistance", 60f, new ConfigDescription("Fewest meters from the pickup spot to the drop spot. The host's value picks the spot.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 400f), Array.Empty<object>()));
MaxDistance = cfg.Bind<float>("UFO", "MaxDistance", 150f, new ConfigDescription("Most meters from the pickup spot to the drop spot. Below MinDistance it is raised to MinDistance. The host's value picks the spot.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 400f), Array.Empty<object>()));
Force = cfg.Bind<bool>("Debug", "ForceUfo", false, "Every paid shrine roll brings the UFO. Debug only. Every player must use the same value.");
VerboseLogging = cfg.Bind<bool>("Debug", "VerboseLogging", false, "Logs each UFO decision's details and the hum clip.");
}
}
internal sealed class UfoShow : MonoBehaviour
{
private const float Diameter = 9f;
private const float BeamTopRadius = 0.12f;
private const float BeamBottomRadius = 3f;
private const float HoldBelow = 2.4f;
private const float GraceSeconds = 1.5f;
private const float SpinDegreesPerSecond = 40f;
private const float BeamScrollPerSecond = 0.08f;
private static readonly HashSet<string> Seen = new HashSet<string>();
private static UfoShow holder;
private static float shieldUntil = -1f;
private UfoTrip trip;
private float t;
private Vector3 hover;
private Vector3 dropHover;
private Vector3 from;
private Vector3 away;
private Transform saucer;
private Transform beam;
private Light glow;
private Material beamMat;
private Renderer saucerRenderer;
private MaterialPropertyBlock lightsBlock;
private AudioSource hum;
private bool holding;
private bool refused;
private Vector3 liftStart;
private bool inputWasActive;
private bool wasKinematic;
public static bool Shielded
{
get
{
if (!((Object)(object)holder != (Object)null))
{
return Time.time < shieldUntil;
}
return true;
}
}
public static void Present(string message)
{
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
if (UfoWire.TryParse(message, out var visit))
{
HashSet<string> seen = Seen;
string[] obj = new string[5]
{
GameManager.GetSeed().ToString(),
":",
null,
null,
null
};
int shrineId = visit.ShrineId;
obj[2] = shrineId.ToString();
obj[3] = ":";
shrineId = visit.UseIndex;
obj[4] = shrineId.ToString();
if (seen.Add(string.Concat(obj)))
{
new GameObject("UfoAbduction").AddComponent<UfoShow>().Begin(visit);
}
}
}
private void Begin(UfoTrip visit)
{
//IL_0057: 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_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: Unknown result type (might be due to invalid IL or missing references)
//IL_0125: Unknown result type (might be due to invalid IL or missing references)
trip = visit;
Vector3 val = default(Vector3);
((Vector3)(ref val))..ctor(trip.PickupX, trip.PickupY, trip.PickupZ);
Vector3 val2 = default(Vector3);
((Vector3)(ref val2))..ctor(trip.DropX, trip.DropY, trip.DropZ);
Vector3 val3 = val2 - val;
val3.y = 0f;
val3 = ((((Vector3)(ref val3)).sqrMagnitude > 1f) ? ((Vector3)(ref val3)).normalized : Vector3.forward);
hover = val + Vector3.up * 15f;
dropHover = val2 + Vector3.up * 15f;
from = hover - val3 * 70f + Vector3.up * 50f;
away = dropHover + val3 * 140f + Vector3.up * 90f;
((Component)this).transform.position = from;
Build();
Say(UfoText.Line(PlayerNames.Of(trip.ClientId), trip.Abduct));
}
private void Build()
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Expected O, but got Unknown
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Expected O, but got Unknown
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
if (UfoArt.TryGetSaucer(out var mesh, out var materials))
{
saucer = Part("Saucer", mesh, materials, Vector3.one * 9f);
saucerRenderer = ((Component)saucer).GetComponent<Renderer>();
lightsBlock = new MaterialPropertyBlock();
}
if (UfoArt.TryGetBeam(out var mesh2, out var material))
{
beam = Part("Beam", mesh2, (Material[])(object)new Material[1] { material }, Vector3.one);
beamMat = material;
beam.localPosition = Vector3.down * 9f * 0.2f;
((Component)beam).gameObject.SetActive(false);
}
GameObject val = new GameObject("UfoGlow");
val.transform.SetParent(((Component)this).transform, false);
val.transform.localPosition = Vector3.down * 2.5f;
glow = val.AddComponent<Light>();
glow.type = (LightType)2;
glow.color = UfoPlugin.Cyan;
glow.range = 22f;
glow.intensity = 2f;
hum = UfoSound.Attach(((Component)this).gameObject);
}
private Transform Part(string name, Mesh mesh, Material[] materials, Vector3 scale)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: 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)
GameObject val = new GameObject(name);
val.transform.SetParent(((Component)this).transform, false);
val.transform.localScale = scale;
val.AddComponent<MeshFilter>().sharedMesh = mesh;
((Renderer)val.AddComponent<MeshRenderer>()).sharedMaterials = materials;
return val.transform;
}
private void Update()
{
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
t += Time.deltaTime;
UfoPhase ufoPhase = UfoTimeline.PhaseAt(t);
if (ufoPhase == UfoPhase.Done)
{
Object.Destroy((Object)(object)((Component)this).gameObject);
return;
}
((Component)this).transform.position = UfoPosition(ufoPhase);
if ((Object)(object)saucer != (Object)null)
{
saucer.Rotate(0f, 40f * Time.deltaTime, 0f, (Space)1);
}
float num = 0.5f + 0.5f * Mathf.Sin(t * 9f);
if ((Object)(object)glow != (Object)null)
{
glow.intensity = 1.6f + 1.2f * num;
}
PulseLights(0.7f + 0.6f * num);
if ((Object)(object)hum != (Object)null)
{
hum.volume = 0.8f * (1f - UfoTimeline.Progress(UfoPhase.Leave, t));
}
UpdateBeam();
if (trip.Abduct && IsMine())
{
HoldPlayer(ufoPhase);
}
}
private Vector3 UfoPosition(UfoPhase phase)
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: 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_00a4: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
float num = Mathf.Sin(t * 2.2f) * 0.35f;
switch (phase)
{
case UfoPhase.Arrive:
return Vector3.Lerp(from, hover, UfoTimeline.Progress(UfoPhase.Arrive, t));
case UfoPhase.Beam:
case UfoPhase.Lift:
return hover + Vector3.up * num;
case UfoPhase.Carry:
{
float num2 = UfoTimeline.Progress(UfoPhase.Carry, t);
return Vector3.Lerp(hover, dropHover, num2) + Vector3.up * (Mathf.Sin(num2 * MathF.PI) * 12f + num);
}
case UfoPhase.Lower:
return dropHover + Vector3.up * num;
default:
return Vector3.Lerp(dropHover, away, UfoTimeline.Progress(UfoPhase.Leave, t));
}
}
private void PulseLights(float gain)
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
int lightsSubMesh = UfoArt.LightsSubMesh;
if (!((Object)(object)saucerRenderer == (Object)null) && lightsSubMesh >= 0)
{
lightsBlock.SetColor("_EmissionColor", UfoArt.LightsEmission * gain);
saucerRenderer.SetPropertyBlock(lightsBlock, lightsSubMesh);
}
}
private void UpdateBeam()
{
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)beam == (Object)null)
{
return;
}
if ((Object)(object)beamMat != (Object)null)
{
beamMat.mainTextureOffset = new Vector2(t * 0.08f, 0f);
}
bool flag = trip.Abduct && UfoTimeline.BeamOn(t);
if (((Component)beam).gameObject.activeSelf != flag)
{
((Component)beam).gameObject.SetActive(flag);
}
if (flag)
{
float num = 16f;
int mask = LayerMask.GetMask(new string[2] { "Ground", "Terrain" });
RaycastHit val = default(RaycastHit);
if (Physics.Raycast(beam.position, Vector3.down, ref val, 60f, mask))
{
num = ((RaycastHit)(ref val)).distance;
}
float num2 = 6f;
beam.localScale = new Vector3(num2, Mathf.Max(1f, num), num2);
}
}
private bool IsMine()
{
if ((Object)(object)LocalClient.instance != (Object)null)
{
return LocalClient.instance.myId == trip.ClientId;
}
return false;
}
private void HoldPlayer(UfoPhase phase)
{
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
if (refused)
{
return;
}
if (!UfoTimeline.Holding(t))
{
if (holding)
{
Release();
}
return;
}
PlayerMovement instance = PlayerMovement.Instance;
if (!holding)
{
if ((Object)(object)instance == (Object)null || instance.IsDead())
{
refused = true;
return;
}
Grab(instance);
}
if (!((Object)(object)instance == (Object)null))
{
Vector3 val = ((Component)this).transform.position + Vector3.down * 2.4f;
Vector3 position = (Vector3)(phase switch
{
UfoPhase.Lift => Vector3.Lerp(liftStart, val, UfoTimeline.Progress(UfoPhase.Lift, t)),
UfoPhase.Lower => Vector3.Lerp(val, new Vector3(trip.DropX, trip.DropY + 1f, trip.DropZ), UfoTimeline.Progress(UfoPhase.Lower, t)),
_ => val,
});
((Component)instance).transform.position = position;
}
}
private void Grab(PlayerMovement pm)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
holding = true;
holder = this;
liftStart = ((Component)pm).transform.position;
inputWasActive = (Object)(object)PlayerInput.Instance == (Object)null || PlayerInput.Instance.active;
if ((Object)(object)PlayerInput.Instance != (Object)null)
{
PlayerInput.Instance.active = false;
}
Rigidbody rb = pm.GetRb();
wasKinematic = (Object)(object)rb != (Object)null && rb.isKinematic;
if ((Object)(object)rb != (Object)null)
{
rb.velocity = Vector3.zero;
rb.isKinematic = true;
}
}
private void Release()
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
holding = false;
PlayerMovement instance = PlayerMovement.Instance;
if ((Object)(object)instance != (Object)null)
{
Vector3 position = ((Component)instance).transform.position;
UfoPlugin.Log.LogInfo((object)$"UFO abduction drop: client {trip.ClientId} at {UfoText.Point(position.x, position.y, position.z)}, {UfoText.Metres(UfoText.FlatDistance(trip.PickupX, trip.PickupZ, position.x, position.z))} m from the pickup.");
}
if ((Object)(object)holder == (Object)(object)this)
{
holder = null;
}
shieldUntil = Time.time + 1.5f;
PlayerMovement instance2 = PlayerMovement.Instance;
if ((Object)(object)instance2 != (Object)null)
{
Rigidbody rb = instance2.GetRb();
if ((Object)(object)rb != (Object)null)
{
rb.isKinematic = wasKinematic;
rb.velocity = Vector3.zero;
}
}
if ((Object)(object)PlayerInput.Instance != (Object)null)
{
PlayerInput.Instance.active = inputWasActive;
}
}
private void OnDestroy()
{
if (holding)
{
Release();
}
}
private static void Say(string message)
{
ChatBox instance = ChatBox.Instance;
if ((Object)(object)instance != (Object)null)
{
instance.AppendMessage(-1, message, "");
}
}
}
internal static class UfoSound
{
internal static readonly string[] Preferred = new string[4] { "ChargeHold", "ZoneAmbience", "Charge", "WindFlyby" };
public const float Volume = 0.8f;
private const float Pitch = 0.45f;
private static AudioClip clip;
private static bool warned;
public static int Pick(IList<string> names)
{
string[] preferred = Preferred;
foreach (string text in preferred)
{
for (int j = 0; j < names.Count; j++)
{
if (names[j] == text)
{
return j;
}
}
}
return -1;
}
public static AudioSource Attach(GameObject saucer)
{
if ((Object)(object)clip == (Object)null)
{
clip = Find();
}
if ((Object)(object)clip == (Object)null)
{
if (!warned)
{
UfoPlugin.Log.LogWarning((object)"UFO hum: none of ChargeHold, ZoneAmbience, Charge or WindFlyby is loaded, so the UFO is silent.");
}
warned = true;
return null;
}
AudioSource obj = saucer.AddComponent<AudioSource>();
obj.clip = clip;
obj.loop = true;
obj.pitch = 0.45f;
obj.volume = 0.8f;
obj.spatialBlend = 1f;
obj.rolloffMode = (AudioRolloffMode)1;
obj.minDistance = 12f;
obj.maxDistance = 160f;
obj.dopplerLevel = 0f;
obj.Play();
if (UfoPlugin.Cfg.VerboseLogging.Value)
{
UfoPlugin.Log.LogInfo((object)("UFO hum '" + ((Object)clip).name + "' playing."));
}
return obj;
}
private static AudioClip Find()
{
AudioClip[] array = Resources.FindObjectsOfTypeAll<AudioClip>();
string[] array2 = new string[array.Length];
for (int i = 0; i < array.Length; i++)
{
array2[i] = (((Object)(object)array[i] == (Object)null) ? null : ((Object)array[i]).name);
}
int num = Pick(array2);
if (num >= 0)
{
return array[num];
}
return null;
}
}
internal static class UfoText
{
public const string Label = "UFO";
public const string WinMessage = "Three UFOs! Look up.";
public static string Line(string playerName, bool abduct)
{
if (string.IsNullOrEmpty(playerName))
{
playerName = "Someone";
}
if (!abduct)
{
return "A UFO looks " + playerName + " over and leaves.";
}
return "A UFO is taking " + playerName + "!";
}
public static string FlybyReason(bool alive, bool bossNear, bool dropFound)
{
if (!alive)
{
return "player dead or missing";
}
if (bossNear)
{
return "boss within " + 50f.ToString(CultureInfo.InvariantCulture) + " m";
}
if (!dropFound)
{
return "no dry navmesh drop spot";
}
return "none";
}
public static double Share(bool enabled, float chancePercent, bool force)
{
if (force)
{
return 1.0;
}
if (!enabled || float.IsNaN(chancePercent) || chancePercent <= 0f)
{
return 0.0;
}
if (!(chancePercent >= 100f))
{
return (double)chancePercent / 100.0;
}
return 1.0;
}
public static string Point(float x, float y, float z)
{
CultureInfo invariantCulture = CultureInfo.InvariantCulture;
return "(" + x.ToString("0.0", invariantCulture) + ", " + y.ToString("0.0", invariantCulture) + ", " + z.ToString("0.0", invariantCulture) + ")";
}
public static string Metres(float metres)
{
return metres.ToString("0.0", CultureInfo.InvariantCulture);
}
public static float FlatDistance(float ax, float az, float bx, float bz)
{
float num = bx - ax;
float num2 = bz - az;
return (float)Math.Sqrt(num * num + num2 * num2);
}
}
internal enum UfoPhase
{
Arrive,
Beam,
Lift,
Carry,
Lower,
Leave,
Done
}
internal static class UfoTimeline
{
public const float HoverHeight = 15f;
private static readonly float[] Starts = new float[7] { 0f, 2f, 2.5f, 5.5f, 8f, 9.5f, 12f };
public static UfoPhase PhaseAt(float t)
{
for (int num = Starts.Length - 1; num > 0; num--)
{
if (t >= Starts[num])
{
return (UfoPhase)num;
}
}
return UfoPhase.Arrive;
}
public static float Progress(UfoPhase phase, float t)
{
if ((int)phase >= Starts.Length - 1)
{
if (!(t >= Starts[(int)phase]))
{
return 0f;
}
return 1f;
}
float num = (t - Starts[(int)phase]) / (Starts[(int)(phase + 1)] - Starts[(int)phase]);
if (num <= 0f)
{
return 0f;
}
if (num >= 1f)
{
return 1f;
}
return num * num * (3f - 2f * num);
}
public static bool BeamOn(float t)
{
if (t >= Starts[1])
{
return t < Starts[5];
}
return false;
}
public static bool Holding(float t)
{
if (t >= Starts[2])
{
return t < Starts[5];
}
return false;
}
}
internal readonly struct UfoTrip
{
public readonly int ShrineId;
public readonly int UseIndex;
public readonly int ClientId;
public readonly bool Abduct;
public readonly float PickupX;
public readonly float PickupY;
public readonly float PickupZ;
public readonly float DropX;
public readonly float DropY;
public readonly float DropZ;
public UfoTrip(int shrineId, int useIndex, int clientId, bool abduct, float pickupX, float pickupY, float pickupZ, float dropX, float dropY, float dropZ)
{
ShrineId = shrineId;
UseIndex = useIndex;
ClientId = clientId;
Abduct = abduct;
PickupX = pickupX;
PickupY = pickupY;
PickupZ = pickupZ;
DropX = dropX;
DropY = dropY;
DropZ = dropZ;
}
}
internal static class UfoWire
{
public const string Prefix = "~ufo";
private const string Head = "~ufo1 trip";
public static bool Hidden(string message)
{
return message?.StartsWith("~ufo", StringComparison.Ordinal) ?? false;
}
public static string Encode(UfoTrip trip)
{
CultureInfo invariantCulture = CultureInfo.InvariantCulture;
string[] obj = new string[11]
{
"~ufo1 trip", null, null, null, null, null, null, null, null, null,
null
};
int shrineId = trip.ShrineId;
obj[1] = shrineId.ToString(invariantCulture);
shrineId = trip.UseIndex;
obj[2] = shrineId.ToString(invariantCulture);
shrineId = trip.ClientId;
obj[3] = shrineId.ToString(invariantCulture);
obj[4] = (trip.Abduct ? "a" : "f");
obj[5] = Dm(trip.PickupX);
obj[6] = Dm(trip.PickupY);
obj[7] = Dm(trip.PickupZ);
obj[8] = Dm(trip.DropX);
obj[9] = Dm(trip.DropY);
obj[10] = Dm(trip.DropZ);
return string.Join(" ", obj);
}
public static bool TryParse(string message, out UfoTrip trip)
{
trip = default(UfoTrip);
if (message == null || !message.StartsWith("~ufo1 trip ", StringComparison.Ordinal))
{
return false;
}
string[] array = message.Split(new char[1] { ' ' });
if (array.Length != 12 || (array[5] != "a" && array[5] != "f"))
{
return false;
}
int[] array2 = new int[12];
for (int i = 2; i < 12; i++)
{
if (i != 5 && !int.TryParse(array[i], NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture, out array2[i]))
{
return false;
}
}
trip = new UfoTrip(array2[2], array2[3], array2[4], array[5] == "a", (float)array2[6] / 10f, (float)array2[7] / 10f, (float)array2[8] / 10f, (float)array2[9] / 10f, (float)array2[10] / 10f, (float)array2[11] / 10f);
return true;
}
private static string Dm(float metres)
{
return ((int)Math.Round((double)metres * 10.0, MidpointRounding.AwayFromZero)).ToString(CultureInfo.InvariantCulture);
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "MuckUfoAbduction";
public const string PLUGIN_NAME = "UFO Abduction";
public const string PLUGIN_VERSION = "0.1.1";
}
}