using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using FalseGods.Core.Arena; using FalseGods.Core.Bosses; using FalseGods.Core.Simulation; using FalseGods.RuntimeContracts.Multiplayer; using FalseGods.RuntimeContracts.Transport; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("FalseGods.RuntimeContracts")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+6e5740a80f810ab422551028733810b527fb614d")] [assembly: AssemblyProduct("FalseGods.RuntimeContracts")] [assembly: AssemblyTitle("FalseGods.RuntimeContracts")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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; } } internal static class IsExternalInit { } } namespace FalseGods.RuntimeContracts.Transport { public readonly struct EncodedPayload { private readonly byte[]? _bytes; public int Length { get { byte[]? bytes = _bytes; if (bytes == null) { return 0; } return bytes.Length; } } public EncodedPayload(byte[] bytes) { if (bytes == null) { throw new ArgumentNullException("bytes"); } _bytes = (byte[])bytes.Clone(); } public byte[] ToArray() { return (byte[])(_bytes ?? Array.Empty()).Clone(); } } public enum MessageDelivery { ReliableOrdered, Unreliable } public enum MessageTargetKind { Host, AllClients, SpecificPeer } public readonly struct MessageTarget { public MessageTargetKind Kind { get; } public SessionPeerId Peer { get; } public static MessageTarget Host { get; } = new MessageTarget(MessageTargetKind.Host, default(SessionPeerId)); public static MessageTarget AllClients { get; } = new MessageTarget(MessageTargetKind.AllClients, default(SessionPeerId)); private MessageTarget(MessageTargetKind kind, SessionPeerId peer) { Kind = kind; Peer = peer; } public static MessageTarget ToPeer(SessionPeerId peer) { return new MessageTarget(MessageTargetKind.SpecificPeer, peer); } public override string ToString() { if (Kind != MessageTargetKind.SpecificPeer) { return Kind.ToString(); } return $"{Kind}({Peer})"; } } public readonly struct SessionPeerId : IEquatable { private readonly int _value; public int Value => _value; public SessionPeerId(int value) { _value = value; } public bool Equals(SessionPeerId other) { return _value == other._value; } public override bool Equals(object? obj) { if (obj is SessionPeerId other) { return Equals(other); } return false; } public override int GetHashCode() { return _value; } public override string ToString() { return $"peer:{_value}"; } public static bool operator ==(SessionPeerId left, SessionPeerId right) { return left.Equals(right); } public static bool operator !=(SessionPeerId left, SessionPeerId right) { return !left.Equals(right); } } } namespace FalseGods.RuntimeContracts.Presentation { public enum AttackVisualKind { Projectile = 1, Area } public enum BossVisualActivity { Idle, Telegraphing, Committing, Recovering, Dead, Vanishing, Hidden, Appearing } public interface IEncounterPresentation { void Apply(PresentationState state); void Handle(IPresentationEvent presentationEvent); } public interface IPresentationEvent { } public sealed record BossAppeared(BossInstanceId Boss, int PhaseVisualId) : IPresentationEvent; public sealed record AttackTelegraphStarted(BossInstanceId Boss, AttackInstanceId Attack, AttackVisualKind Kind, SimVector2 AimPoint, float TelegraphSeconds) : IPresentationEvent; public sealed record AttackLanded(BossInstanceId Boss, AttackInstanceId Attack, AttackVisualKind Kind, SimVector2 AimPoint) : IPresentationEvent; public sealed record WeakPointVisibilityChanged(BossInstanceId Boss, bool Exposed) : IPresentationEvent; public sealed record PhaseTransition(BossInstanceId Boss, int PhaseVisualId) : IPresentationEvent; public sealed record BossHit(BossInstanceId Boss, int Amount, bool WeakPointHit) : IPresentationEvent; public sealed record RageChanged(BossInstanceId Boss, bool Enraged) : IPresentationEvent; public sealed record BossRoared(BossInstanceId Boss) : IPresentationEvent; public sealed record BossDefeated(BossInstanceId Boss) : IPresentationEvent; public sealed record BossMoved(BossInstanceId Boss, SimVector2 Position, float PositionHeight) : IPresentationEvent; public sealed record MechanismGroupEngaged(MechanismGroupId Group) : IPresentationEvent; public sealed record ExitOpened : IPresentationEvent; public sealed record PresentationState(BossInstanceId Boss, SimVector2 Position, float PositionHeight, SimVector2 Facing, int PhaseVisualId, BossVisualActivity Activity, bool WeakPointExposed, bool Enraged, float HealthFraction); } namespace FalseGods.RuntimeContracts.Multiplayer { public interface IDestructibleOwnership { void ClaimAsOurs(object destructible); } public interface IEncounterChannel { event Action Received; void Send(EncodedPayload payload, MessageDelivery delivery, MessageTarget target); } public interface IMultiplayerSession { SessionRole Role { get; } bool IsActive { get; } SessionPeerId LocalPeer { get; } SessionPeerId HostPeer { get; } } public interface IParticipantPeerMap { bool TryGetRemotePeer(int participantIndex, out SessionPeerId peer); } public interface IPlayerLifeQuery { bool IsOutOfTheFight(object playerUnit); } public interface IPlayerRoster { IReadOnlyList Members { get; } } public interface ISpawnOwnership { IDisposable? DeclareHostAuthoritative(object spawnOwner); } public enum SessionRole { Host, Client } } namespace FalseGods.RuntimeContracts.Integration { public static class FalseGodsIntegrations { private sealed class RegistrationToken : IIntegrationRegistration, IDisposable { public IFalseGodsIntegration Integration { get; } public RegistrationToken(IFalseGodsIntegration integration) { Integration = integration; } public void Dispose() { Revoke(this); } } private static readonly object Gate = new object(); private static RegistrationToken? _active; public static IFalseGodsIntegration? Current { get { lock (Gate) { return _active?.Integration; } } } public static event Action? Changed; public static IIntegrationRegistration? Register(IFalseGodsIntegration integration) { if (integration == null) { throw new ArgumentNullException("integration"); } RegistrationToken result; lock (Gate) { if (_active != null) { return null; } result = (_active = new RegistrationToken(integration)); } RaiseChanged(); return result; } private static void Revoke(RegistrationToken token) { lock (Gate) { if (_active != token) { return; } _active = null; } RaiseChanged(); } private static void RaiseChanged() { FalseGodsIntegrations.Changed?.Invoke(); } } public interface IFalseGodsIntegration { IMultiplayerSession Session { get; } IEncounterChannel Channel { get; } IPlayerRoster Roster { get; } IParticipantPeerMap Players { get; } ISpawnOwnership Spawns { get; } IPlayerLifeQuery Lives { get; } IDestructibleOwnership Destructibles { get; } } public interface IIntegrationRegistration : IDisposable { } } namespace FalseGods.RuntimeContracts.Diagnostics { public interface ILogger { void Log(string message); void LogWarning(string message); } } namespace FalseGods.RuntimeContracts.Arena { public readonly struct ArenaRotation : IEquatable { public static ArenaRotation Identity => new ArenaRotation(0f, 0f, 0f, 1f); public float X { get; } public float Y { get; } public float Z { get; } public float W { get; } public ArenaRotation(float x, float y, float z, float w) { X = x; Y = y; Z = z; W = w; } public bool Equals(ArenaRotation other) { if (X.Equals(other.X) && Y.Equals(other.Y) && Z.Equals(other.Z)) { return W.Equals(other.W); } return false; } public override bool Equals(object? obj) { if (obj is ArenaRotation other) { return Equals(other); } return false; } public override int GetHashCode() { return (((((X.GetHashCode() * 397) ^ Y.GetHashCode()) * 397) ^ Z.GetHashCode()) * 397) ^ W.GetHashCode(); } public override string ToString() { return $"({X:0.###}, {Y:0.###}, {Z:0.###}, {W:0.###})"; } public static bool operator ==(ArenaRotation left, ArenaRotation right) { return left.Equals(right); } public static bool operator !=(ArenaRotation left, ArenaRotation right) { return !left.Equals(right); } } public readonly struct ArenaWorldPoint : IEquatable { public float X { get; } public float Y { get; } public float Z { get; } public ArenaWorldPoint(float x, float y, float z) { X = x; Y = y; Z = z; } public bool Equals(ArenaWorldPoint other) { if (X.Equals(other.X) && Y.Equals(other.Y)) { return Z.Equals(other.Z); } return false; } public override bool Equals(object? obj) { if (obj is ArenaWorldPoint other) { return Equals(other); } return false; } public override int GetHashCode() { return (((X.GetHashCode() * 397) ^ Y.GetHashCode()) * 397) ^ Z.GetHashCode(); } public override string ToString() { return $"({X:0.###}, {Y:0.###}, {Z:0.###})"; } public static bool operator ==(ArenaWorldPoint left, ArenaWorldPoint right) { return left.Equals(right); } public static bool operator !=(ArenaWorldPoint left, ArenaWorldPoint right) { return !left.Equals(right); } } public sealed record ArenaAssetLoadResult(bool Success, string? Error, string? ArtifactText) { public static ArenaAssetLoadResult Loaded(string artifactText) { return new ArenaAssetLoadResult(Success: true, null, artifactText); } public static ArenaAssetLoadResult Failed(string error) { return new ArenaAssetLoadResult(Success: false, error, null); } } public interface IArenaAssetProvider { ArenaAssetLoadResult Load(); void Release(); } public sealed record RealizedParityNode(string Path, ArenaWorldPoint LocalPosition, ArenaRotation LocalRotation, ArenaWorldPoint LocalScale); public sealed record RealizedMarker(string Path, ArenaWorldPoint WorldPosition, ArenaWorldPoint LocalScale); public sealed record ArenaRealizationResult(bool Success, string? Error, IReadOnlyList ParityNodes, IReadOnlyList Markers) { public static ArenaRealizationResult Failed(string error) { return new ArenaRealizationResult(Success: false, error, Array.Empty(), Array.Empty()); } } public interface IArenaRealization { ArenaRealizationResult Realize(ArenaWorldPoint origin, IReadOnlyList parityPaths, IReadOnlyList markerPaths, IReadOnlyList markerGroupPaths); void Teardown(); } }