using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using JetBrains.Annotations;
using LCTarrotCard.Cards;
using LCTarrotCard.Items;
using LCTarrotCard.Ressource;
using LCTarrotCard.Util;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Events;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("LCTarrotCard")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LCTarrotCard")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9457633A-7E87-4BDB-8892-B9C127F9C677")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.3.0")]
namespace LCTarrotCard
{
[HarmonyPatch]
public class Networker : NetworkBehaviour
{
public static bool AllowExtraLife;
private static GameObject _networkPrefab;
private static readonly int Closed = Animator.StringToHash("Closed");
private static readonly int Damage = Animator.StringToHash("Damage");
private static readonly int Limp = Animator.StringToHash("Limp");
public static Networker Instance { get; private set; }
[ServerRpc(RequireOwnership = false)]
public void KillPlayerServerRpc(int playerId, Vector3 velocity, CauseOfDeath causeOfDeath)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
KillPlayerClientRpc(playerId, velocity, causeOfDeath);
}
[ClientRpc]
public void KillPlayerClientRpc(int playerId, Vector3 velocity, CauseOfDeath causeOfDeath)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: 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)
PlayerControllerB obj = StartOfRound.Instance.allPlayerScripts[playerId];
if (obj != null)
{
obj.KillPlayer(velocity, true, causeOfDeath, 0, default(Vector3));
}
}
[ServerRpc(RequireOwnership = false)]
public void SetShipDoorStateServerRpc(bool opened)
{
SetShipDoorStateClientRpc(opened);
}
[ClientRpc]
public void SetShipDoorStateClientRpc(bool opened)
{
HangarShipDoor[] array = Object.FindObjectsOfType<HangarShipDoor>();
foreach (HangarShipDoor val in array)
{
if (opened)
{
val.SetDoorOpen();
val.doorPower = 0f;
}
else
{
val.SetDoorClosed();
val.doorPower = 100f;
}
val.shipDoorsAnimator.SetBool(Closed, !opened);
}
}
[ServerRpc(RequireOwnership = false)]
public void OpenOrCloseRandomDoorServerRpc(int playerId)
{
OpenOrCloseRandomDoorClientRpc(playerId, new Random().Next());
}
[ClientRpc]
public void OpenOrCloseRandomDoorClientRpc(int playerId, int rngSeed)
{
Random random = new Random(rngSeed);
DoorLock[] array = Object.FindObjectsOfType<DoorLock>();
foreach (DoorLock val in array)
{
if (random.Next(0, 2) == 0)
{
val.OpenOrCloseDoor(StartOfRound.Instance.allPlayerScripts[playerId]);
}
}
}
[ServerRpc(RequireOwnership = false)]
public void BreakerOffServerRpc()
{
BreakerOffClientRpc();
}
[ClientRpc]
public void BreakerOffClientRpc()
{
RoundManager.Instance.SwitchPower(false);
BreakerBox[] array = Object.FindObjectsOfType<BreakerBox>();
for (int i = 0; i < array.Length; i++)
{
array[i].SetSwitchesOff();
}
}
[ServerRpc(RequireOwnership = false)]
public void AgroCoilheadOrSpawnServerRpc()
{
SpringManAI[] array = Object.FindObjectsOfType<SpringManAI>();
int num = 0;
SpringManAI[] array2 = array;
foreach (SpringManAI val in array2)
{
if (!((EnemyAI)val).isEnemyDead && ((NetworkBehaviour)val).IsSpawned)
{
num++;
((EnemyAI)val).SwitchToBehaviourState(1);
}
if (num >= 2)
{
return;
}
}
SpawnCoilheadServerRpc();
}
[ServerRpc(RequireOwnership = false)]
public void SpawnCoilheadServerRpc()
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
EnemyVent[] array = Object.FindObjectsOfType<EnemyVent>();
Vector3 position = array[Random.Range(0, array.Length)].floorNode.position;
GameObject val = Object.Instantiate<GameObject>(Helper.Enemies.SpringMan.enemyPrefab, position, Quaternion.identity);
val.GetComponentInChildren<NetworkObject>().Spawn(true);
RoundManager.Instance.SpawnedEnemies.Add((EnemyAI)(object)val.GetComponent<SpringManAI>());
((EnemyAI)val.GetComponent<SpringManAI>()).SetEnemyOutside(false);
((EnemyAI)val.GetComponent<SpringManAI>()).SwitchToBehaviourState(1);
}
[ServerRpc(RequireOwnership = false)]
public void PopOrSpawnJesterServerRpc(float popDelay)
{
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: 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)
bool flag = false;
foreach (EnemyAI spawnedEnemy in RoundManager.Instance.SpawnedEnemies)
{
JesterAI val = (JesterAI)(object)((spawnedEnemy is JesterAI) ? spawnedEnemy : null);
if (val != null && !((EnemyAI)val).isEnemyDead)
{
flag = true;
}
}
if (!flag)
{
EnemyVent[] array = Object.FindObjectsOfType<EnemyVent>();
Vector3 position = array[Random.Range(0, array.Length)].floorNode.position;
GameObject val2 = Object.Instantiate<GameObject>(Helper.Enemies.Jester.enemyPrefab, position, Quaternion.identity);
val2.GetComponentInChildren<NetworkObject>().Spawn(true);
RoundManager.Instance.SpawnedEnemies.Add((EnemyAI)(object)val2.GetComponent<JesterAI>());
((EnemyAI)val2.GetComponent<JesterAI>()).SetEnemyOutside(false);
((EnemyAI)val2.GetComponent<JesterAI>()).SwitchToBehaviourState(1);
}
((MonoBehaviour)this).StartCoroutine(PopDelay(popDelay));
}
[ServerRpc(RequireOwnership = false)]
public void SpawnGiantOrDogServerRpc(int amount)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: 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)
GameObject[] array = GameObject.FindGameObjectsWithTag("OutsideAINode");
for (int i = 0; i < amount; i++)
{
Vector3 position = array[Random.Range(0, array.Length)].transform.position;
if (Random.Range(0, 2) == 0)
{
PluginLogger.Debug("Spawn giant");
GameObject val = Object.Instantiate<GameObject>(Helper.Enemies.ForestGiant.enemyPrefab, position, Quaternion.identity);
val.GetComponentInChildren<NetworkObject>().Spawn(true);
RoundManager.Instance.SpawnedEnemies.Add((EnemyAI)(object)val.GetComponent<ForestGiantAI>());
((EnemyAI)val.GetComponent<ForestGiantAI>()).SetEnemyOutside(true);
}
else
{
PluginLogger.Debug("Spawn dog");
GameObject val2 = Object.Instantiate<GameObject>(Helper.Enemies.MouthDog.enemyPrefab, position, Quaternion.identity);
val2.GetComponentInChildren<NetworkObject>().Spawn(true);
RoundManager.Instance.SpawnedEnemies.Add((EnemyAI)(object)val2.GetComponent<MouthDogAI>());
((EnemyAI)val2.GetComponent<MouthDogAI>()).SetEnemyOutside(true);
}
}
}
[ServerRpc(RequireOwnership = false)]
public void TeleportRandomEntityServerRpc(Vector3 position, bool inside)
{
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: 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)
List<EnemyAI> spawnedEnemies = RoundManager.Instance.SpawnedEnemies;
Helper.Shuffle(spawnedEnemies);
using IEnumerator<EnemyAI> enumerator = spawnedEnemies.Where((EnemyAI enemy) => !enemy.isEnemyDead && enemy.isOutside == !inside && ((NetworkBehaviour)enemy).IsSpawned).GetEnumerator();
if (enumerator.MoveNext())
{
EnemyAI current = enumerator.Current;
PluginLogger.Debug("Enemy is outside ? " + current.isOutside + " player inside ? " + inside);
string enemyName = current.enemyType.enemyName;
Vector3 val = position;
PluginLogger.Debug("Tp " + enemyName + " to " + ((object)(Vector3)(ref val)).ToString());
TeleportEnemy(current, position);
}
}
[ServerRpc(RequireOwnership = false)]
public void GhostBreatheServerRpc(Vector3 position)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
GhostBreatheClientRpc(position);
}
[ClientRpc]
public void GhostBreatheClientRpc(Vector3 position)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
AudioSource.PlayClipAtPoint(Assets.GhostBreathe, position, 3f);
}
[ServerRpc(RequireOwnership = false)]
public void TeleportEnemyAwayServerRpc()
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
foreach (EnemyAI spawnedEnemy in RoundManager.Instance.SpawnedEnemies)
{
Vector3 position = spawnedEnemy.ChooseFarthestNodeFromPosition(((Component)spawnedEnemy).transform.position, false, 0, false, 50, false).position;
TeleportEnemy(spawnedEnemy, position);
}
}
[ServerRpc(RequireOwnership = false)]
public void TeleportPlayerServerRpc(int playerId, Vector3 position, bool inside = true, bool insideShip = false)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
TeleportPlayerClientRpc(playerId, position, inside, insideShip);
}
[ClientRpc]
public void TeleportPlayerClientRpc(int playerId, Vector3 position, bool inside = true, bool insideShip = false)
{
//IL_005c: 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_0067: Unknown result type (might be due to invalid IL or missing references)
PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[playerId];
val.StopSinkingServerRpc();
if (Object.op_Implicit((Object)(object)val.currentTriggerInAnimationWith))
{
val.currentTriggerInAnimationWith.CancelAnimationExternally();
}
val.inSpecialInteractAnimation = false;
val.isClimbingLadder = false;
val.isInElevator = insideShip;
val.isInHangarShipRoom = insideShip;
val.isInsideFactory = inside;
val.averageVelocity = 0f;
val.velocityLastFrame = Vector3.zero;
val.TeleportPlayer(position, false, 0f, false, true);
val.beamOutParticle.Play();
if (playerId == (int)GameNetworkManager.Instance.localPlayerController.playerClientId)
{
HUDManager.Instance.ShakeCamera((ScreenShakeType)1);
}
if (Object.op_Implicit((Object)(object)Object.FindObjectOfType<AudioReverbPresets>()))
{
if (val.isInsideFactory)
{
Object.FindObjectOfType<AudioReverbPresets>().audioPresets[2].ChangeAudioReverbForPlayer(val);
}
else
{
Object.FindObjectOfType<AudioReverbPresets>().audioPresets[3].ChangeAudioReverbForPlayer(val);
}
}
}
[ServerRpc(RequireOwnership = false)]
public void SetPlayerHealthServerRpc(int playerId, int health)
{
SetPlayerHealthClientRpc(playerId, health);
}
[ClientRpc]
public void SetPlayerHealthClientRpc(int playerId, int health)
{
if (health <= 0)
{
health = 1;
}
PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[playerId];
int health2 = val.health;
val.health = health;
if (((NetworkBehaviour)val).IsOwner)
{
HUDManager.Instance.UpdateHealthUI(health, health2 > health);
if (health <= 20 && !val.criticallyInjured)
{
HUDManager.Instance.ShakeCamera((ScreenShakeType)1);
val.MakeCriticallyInjured(true);
}
else if (val.criticallyInjured && health > 20)
{
val.MakeCriticallyInjured(false);
}
}
if (health2 > health)
{
return;
}
if (((NetworkBehaviour)val).IsOwner)
{
((MonoBehaviour)this).StartCoroutine(SetPlayerUI(val, health <= 20));
((UnityEvent)StartOfRound.Instance.LocalPlayerDamagedEvent).Invoke();
val.takingFallDamage = false;
if (val.inSpecialInteractAnimation && !val.twoHandedAnimation)
{
val.playerBodyAnimator.SetTrigger(Damage);
}
val.specialAnimationWeight = 1f;
val.PlayQuickSpecialAnimation(0.7f);
}
PlayerStats obj = val.playersManager.gameStats.allPlayerStats[val.playerClientId];
obj.damageTaken += health2 - health;
val.timeSinceTakingDamage = Time.realtimeSinceStartup;
}
[ServerRpc(RequireOwnership = false)]
public void DamagePlayerServerRpc(int playerId, int damage, Vector3 velocity, CauseOfDeath causeOfDeath)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
DamagePlayerClientRpc(playerId, damage, velocity, causeOfDeath);
}
[ClientRpc]
public void DamagePlayerClientRpc(int playerId, int damage, Vector3 velocity, CauseOfDeath causeOfDeath)
{
//IL_000f: 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)
StartOfRound.Instance.allPlayerScripts[playerId].DamagePlayer(damage, true, true, causeOfDeath, 0, false, velocity);
}
[ServerRpc(RequireOwnership = false)]
public void MultiplyInventoryValueServerRpc(int playerId, float multiplier)
{
MultiplyInventoryValueClientRpc(playerId, multiplier);
}
[ClientRpc]
public void MultiplyInventoryValueClientRpc(int playerId, float multiplier)
{
GrabbableObject[] itemSlots = StartOfRound.Instance.allPlayerScripts[playerId].ItemSlots;
foreach (GrabbableObject obj in itemSlots)
{
obj.SetScrapValue((int)((float)obj.scrapValue * multiplier));
}
}
[ServerRpc(RequireOwnership = false)]
public void MultiplyRandomScrapValueServerRpc(float multiplier)
{
MultiplyRandomScrapValueClientRpc(multiplier, new Random().Next());
}
[ClientRpc]
public void MultiplyRandomScrapValueClientRpc(float multiplier, int randomSeed)
{
Random random = new Random(randomSeed);
GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>();
foreach (GrabbableObject val in array)
{
if (((Behaviour)val).enabled && val.itemProperties.isScrap && val.scrapValue > 0 && random.Next(0, 5) == 0)
{
val.SetScrapValue((int)((float)val.scrapValue * multiplier));
}
}
}
[ServerRpc(RequireOwnership = false)]
public void RevivePlayerServerRpc(int playerId)
{
RevivePlayerClientRpc(playerId);
}
[ClientRpc]
public void RevivePlayerClientRpc(int playerId)
{
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[playerId];
if (!val.isPlayerDead && !val.isPlayerControlled)
{
return;
}
val.ResetPlayerBloodObjects(true);
val.isClimbingLadder = false;
val.clampLooking = false;
val.inVehicleAnimation = false;
val.disableMoveInput = false;
val.ResetZAndXRotation();
((Collider)val.thisController).enabled = true;
val.health = 100;
val.hasBeenCriticallyInjured = false;
val.disableLookInput = false;
val.disableInteract = false;
if (val.isPlayerDead)
{
val.isPlayerDead = false;
val.isPlayerControlled = true;
val.isInElevator = true;
val.isInHangarShipRoom = true;
val.isInsideFactory = false;
val.parentedToElevatorLastFrame = false;
val.overrideGameOverSpectatePivot = null;
StartOfRound.Instance.SetPlayerObjectExtrapolate(false);
val.TeleportPlayer(StartOfRound.Instance.playerSpawnPositions[0].position, false, 0f, false, true);
val.setPositionOfDeadPlayer = false;
val.DisablePlayerModel(StartOfRound.Instance.allPlayerObjects[playerId], true, true);
((Behaviour)val.helmetLight).enabled = false;
val.Crouch(false);
val.criticallyInjured = false;
if (Object.op_Implicit((Object)(object)val.playerBodyAnimator))
{
val.playerBodyAnimator.SetBool(Limp, false);
}
val.bleedingHeavily = false;
val.activatingItem = false;
val.twoHanded = false;
val.inShockingMinigame = false;
val.inSpecialInteractAnimation = false;
val.freeRotationInInteractAnimation = false;
val.disableSyncInAnimation = false;
val.inAnimationWithEnemy = null;
val.holdingWalkieTalkie = false;
val.speakingToWalkieTalkie = false;
val.isSinking = false;
val.isUnderwater = false;
val.sinkingValue = 0f;
val.statusEffectAudio.Stop();
val.DisableJetpackControlsLocally();
val.health = 100;
val.mapRadarDotAnimator.SetBool("dead", false);
val.externalForceAutoFade = Vector3.zero;
if (((NetworkBehaviour)val).IsOwner)
{
HUDManager.Instance.gasHelmetAnimator.SetBool("gasEmitting", false);
val.hasBegunSpectating = false;
HUDManager.Instance.RemoveSpectateUI();
HUDManager.Instance.gameOverAnimator.SetTrigger("revive");
val.hinderedMultiplier = 1f;
val.isMovementHindered = 0;
val.sourcesCausingSinking = 0;
val.reverbPreset = StartOfRound.Instance.shipReverb;
}
}
if (((NetworkBehaviour)val).IsOwner)
{
SoundManager.Instance.earsRingingTimer = 0f;
val.bleedingHeavily = false;
val.criticallyInjured = false;
val.playerBodyAnimator.SetBool(Limp, false);
val.health = 100;
HUDManager.Instance.UpdateHealthUI(100, false);
val.spectatedPlayerScript = null;
((Behaviour)HUDManager.Instance.audioListenerLowPass).enabled = false;
StartOfRound.Instance.SetSpectateCameraToGameOverMode(false, val);
((MonoBehaviour)this).StartCoroutine(SetPlayerUI(val));
}
val.voiceMuffledByEnemy = false;
SoundManager.Instance.playerVoicePitchTargets[playerId] = 1f;
SoundManager.Instance.SetPlayerPitch(1f, playerId);
if (Object.op_Implicit((Object)(object)val.currentVoiceChatIngameSettings))
{
if (!Object.op_Implicit((Object)(object)val.currentVoiceChatIngameSettings.voiceAudio))
{
val.currentVoiceChatIngameSettings.InitializeComponents();
}
if (!Object.op_Implicit((Object)(object)val.currentVoiceChatIngameSettings.voiceAudio))
{
return;
}
((Component)val.currentVoiceChatIngameSettings.voiceAudio).GetComponent<OccludeAudio>().overridingLowPass = false;
}
RagdollGrabbableObject[] array = Object.FindObjectsOfType<RagdollGrabbableObject>();
foreach (RagdollGrabbableObject val2 in array)
{
if (val2.ragdoll.playerObjectId != playerId)
{
continue;
}
if (!((GrabbableObject)val2).isHeld)
{
if (((NetworkBehaviour)this).IsServer)
{
if (((NetworkBehaviour)val2).NetworkObject.IsSpawned)
{
((NetworkBehaviour)val2).NetworkObject.Despawn(true);
}
else
{
Object.Destroy((Object)(object)((Component)val2).gameObject);
}
}
}
else if (Object.op_Implicit((Object)(object)((GrabbableObject)val2).playerHeldBy))
{
((GrabbableObject)val2).playerHeldBy.DropAllHeldItems(true, false);
}
}
DeadBodyInfo[] array2 = Object.FindObjectsOfType<DeadBodyInfo>();
foreach (DeadBodyInfo val3 in array2)
{
if (val3.playerObjectId == playerId)
{
Object.Destroy((Object)(object)((Component)val3).gameObject);
}
}
StartOfRound instance = StartOfRound.Instance;
instance.livingPlayers++;
StartOfRound.Instance.allPlayersDead = false;
StartOfRound.Instance.UpdatePlayerVoiceEffects();
}
[ServerRpc(RequireOwnership = false)]
public void AllowExtraLifeServerRpc()
{
AllowExtraLifeClientRpc(allow: true);
}
[ClientRpc]
public void AllowExtraLifeClientRpc(bool allow)
{
AllowExtraLife = allow;
}
[ServerRpc(RequireOwnership = false)]
public void ExtraLifeServerRpc(int playerId)
{
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
if (AllowExtraLife)
{
PluginLogger.Debug("extra life " + StartOfRound.Instance.allPlayerScripts[playerId].playerUsername);
AllowExtraLifeClientRpc(allow: false);
TeleportPlayerServerRpc(playerId, StartOfRound.Instance.playerSpawnPositions[0].position, inside: false, insideShip: true);
ExtraLifeClientRpc(playerId);
}
}
[ClientRpc]
public void ExtraLifeClientRpc(int playerId)
{
PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[playerId];
val.health = 100;
val.isPlayerDead = false;
val.MakeCriticallyInjured(false);
if (((NetworkBehaviour)val).IsOwner)
{
((MonoBehaviour)this).StartCoroutine(SetPlayerUI(val));
HUDManager.Instance.UpdateHealthUI(100, false);
}
if (((NetworkBehaviour)StartOfRound.Instance.allPlayerScripts[playerId]).IsOwner)
{
HUDManager.Instance.DisplayTip("Extra life", "Thanks to the high priestess card, you are given an extra chance to live", false, false, "LC_Tip1");
}
}
private static IEnumerator SetPlayerUI(PlayerControllerB player, bool critical = false)
{
yield return (object)new WaitForFixedUpdate();
HUDManager.Instance.UpdateHealthUI(player.health, false);
player.MakeCriticallyInjured(critical);
}
public static void TeleportEnemy(EnemyAI enemy, Vector3 position, bool exitEnter = false, bool outside = false)
{
//IL_0037: 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_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_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: 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)
if (exitEnter)
{
enemy.SetEnemyOutside(outside);
}
if (((NetworkBehaviour)enemy).OwnerClientId != GameNetworkManager.Instance.localPlayerController.actualClientId)
{
enemy.ChangeOwnershipOfEnemy(GameNetworkManager.Instance.localPlayerController.actualClientId);
}
Vector3 position2 = enemy.ChooseClosestNodeToPosition(position, false, 0).position;
enemy.serverPosition = position2;
((Component)enemy).transform.position = enemy.serverPosition;
enemy.agent.Warp(enemy.serverPosition);
enemy.SyncPositionToClients();
}
private static IEnumerator PopDelay(float delay)
{
yield return (object)new WaitForSeconds(delay);
PluginLogger.Debug("Popping jesters");
foreach (EnemyAI spawnedEnemy in RoundManager.Instance.SpawnedEnemies)
{
JesterAI val = (JesterAI)(object)((spawnedEnemy is JesterAI) ? spawnedEnemy : null);
if (val != null && !((EnemyAI)val).isEnemyDead)
{
((EnemyAI)val).SwitchToBehaviourState(2);
}
}
}
public override void OnNetworkSpawn()
{
if ((Object)(object)NetworkManager.Singleton != (Object)null && (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer))
{
Networker instance = Instance;
if (instance != null)
{
((Component)instance).gameObject.GetComponent<NetworkObject>().Despawn(true);
}
}
Instance = this;
((NetworkBehaviour)this).OnNetworkSpawn();
}
[HarmonyPatch(typeof(StartOfRound), "Awake")]
[HarmonyPostfix]
private static void SpawnNetHandler()
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
{
Object.Instantiate<GameObject>(_networkPrefab, Vector3.zero, Quaternion.identity).GetComponent<NetworkObject>().Spawn(false);
}
}
[HarmonyPatch(typeof(GameNetworkManager), "Start")]
[HarmonyPostfix]
private static void Init()
{
if (!((Object)(object)_networkPrefab != (Object)null))
{
_networkPrefab = Assets.Bundle.LoadAsset<GameObject>("Assets/Tarrot/Networker.prefab");
_networkPrefab.AddComponent<Networker>();
NetworkManager.Singleton.AddNetworkPrefab(_networkPrefab);
}
}
}
[BepInPlugin("LCTarotCard", "Phasmophobia Tarot Card", "1.0.3")]
public class Plugin : BaseUnityPlugin
{
public static Plugin Instance;
internal static KeyboardShortcut DebugBtn = new KeyboardShortcut((KeyCode)96, Array.Empty<KeyCode>());
private Harmony harmony;
public ManualLogSource logger;
private void Awake()
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Expected O, but got Unknown
if (!((Object)(object)Instance != (Object)null))
{
Instance = this;
logger = Logger.CreateLogSource("LCTarotCard");
harmony = new Harmony("LCTarotCard");
Assets.Load();
AllCards.Init();
harmony.PatchAll();
NetcodePatcher();
}
}
private static void NetcodePatcher()
{
Type[] types = Assembly.GetExecutingAssembly().GetTypes();
for (int i = 0; i < types.Length; i++)
{
MethodInfo[] methods = types[i].GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
foreach (MethodInfo methodInfo in methods)
{
if (methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false).Length != 0)
{
methodInfo.Invoke(null, null);
}
}
}
}
}
[HarmonyPatch(typeof(PlayerControllerB))]
internal class Test
{
[HarmonyPatch("Update")]
[HarmonyPostfix]
private static void TestPatch(PlayerControllerB __instance)
{
}
}
public static class PluginLogger
{
public static bool ShowDebug = true;
public static void Debug(object o)
{
if (ShowDebug)
{
Plugin.Instance.logger.LogDebug((object)("[DEBUG] " + o));
}
}
public static void Info(object o)
{
Plugin.Instance.logger.LogInfo(o);
}
public static void Error(object o)
{
Plugin.Instance.logger.LogError((object)("[ERROR] " + o));
}
public static void Warning(object o)
{
Plugin.Instance.logger.LogWarning((object)("[WARNING] " + o));
}
}
public static class PluginConstants
{
public const string PLUGIN_GUID = "LCTarotCard";
public const string PLUGIN_NAME = "Phasmophobia Tarot Card";
public const string PLUGIN_VERSION = "1.0.3";
internal const bool DEBUG_MODE = false;
}
}
namespace LCTarrotCard.Util
{
[HarmonyPatch]
public class Helper
{
public static class Enemies
{
public static EnemyType Baboon;
public static EnemyType Slime;
public static EnemyType BushWolf;
public static EnemyType Butler;
public static EnemyType ButlerBees;
public static EnemyType Centipede;
public static EnemyType ClaySurgeon;
public static EnemyType Crawler;
public static EnemyType DocileLocust;
public static EnemyType Manticoil;
public static EnemyType DressGirl;
public static EnemyType FlowerMan;
public static EnemyType FlowerSnake;
public static EnemyType ForestGiant;
public static EnemyType HoarderBug;
public static EnemyType Jester;
public static EnemyType LassoMan;
public static EnemyType Masked;
public static EnemyType MouthDog;
public static EnemyType Nutcracker;
public static EnemyType Puffer;
public static EnemyType RadMech;
public static EnemyType RedLocust;
public static EnemyType RedPill;
public static EnemyType Spider;
public static EnemyType SandWorm;
public static EnemyType SpringMan;
public static readonly List<EnemyType> AllEnemies = new List<EnemyType>();
public static readonly List<EnemyType> SpawnableEnemies = new List<EnemyType>();
[CanBeNull]
public static EnemyType GetByName(string name)
{
return ((IEnumerable<EnemyType>)AllEnemies).FirstOrDefault((Func<EnemyType, bool>)((EnemyType enemy) => enemy.enemyName == name));
}
}
private static readonly Random Rng = new Random();
public static void InitEnemies()
{
PluginLogger.Debug("InitEnemies");
EnemyType[] array = Resources.FindObjectsOfTypeAll<EnemyType>().Concat(Object.FindObjectsByType<EnemyType>((FindObjectsInactive)1, (FindObjectsSortMode)1)).ToArray();
PluginLogger.Debug("Found " + array.Length + " enemies");
EnemyType[] array2 = array;
foreach (EnemyType val in array2)
{
PluginLogger.Debug("Found enemy : " + val.enemyName);
if (!Enemies.AllEnemies.Contains(val))
{
Enemies.AllEnemies.Add(val);
if (val.enemyName != "Lasso" || val.enemyName != "Red pill")
{
Enemies.SpawnableEnemies.Add(val);
}
}
switch (val.enemyName)
{
case "Baboon hawk":
Enemies.Baboon = val;
break;
case "Blob":
Enemies.Slime = val;
break;
case "Bush Wolf":
Enemies.BushWolf = val;
break;
case "Butler":
Enemies.Butler = val;
break;
case "Butler Bees":
Enemies.ButlerBees = val;
break;
case "Centipede":
Enemies.Centipede = val;
break;
case "Clay Surgeon":
Enemies.ClaySurgeon = val;
break;
case "Crawler":
Enemies.Crawler = val;
break;
case "Docile Locust Bees":
Enemies.DocileLocust = val;
break;
case "Manticoil":
Enemies.Manticoil = val;
break;
case "Girl":
Enemies.DressGirl = val;
break;
case "Flowerman":
Enemies.FlowerMan = val;
break;
case "Tulip Snake":
Enemies.FlowerSnake = val;
break;
case "ForestGiant":
Enemies.ForestGiant = val;
break;
case "Hoarding bug":
Enemies.HoarderBug = val;
break;
case "Jester":
Enemies.Jester = val;
break;
case "Lasso":
Enemies.LassoMan = val;
break;
case "Masked":
Enemies.Masked = val;
break;
case "MouthDog":
Enemies.MouthDog = val;
break;
case "Nutcracker":
Enemies.Nutcracker = val;
break;
case "Puffer":
Enemies.Puffer = val;
break;
case "RadMech":
Enemies.RadMech = val;
break;
case "Red Locust Bees":
Enemies.RedLocust = val;
break;
case "Red pill":
Enemies.RedPill = val;
break;
case "Bunker Spider":
Enemies.Spider = val;
break;
case "Earth Leviathan":
Enemies.SandWorm = val;
break;
case "Spring":
Enemies.SpringMan = val;
break;
}
}
}
public static void Shuffle<T>(IList<T> list)
{
int num = list.Count;
while (num > 1)
{
num--;
int num2 = Rng.Next(num + 1);
int index = num2;
int index2 = num;
T value = list[num];
T value2 = list[num2];
list[index] = value;
list[index2] = value2;
}
}
public static GameObject ClosestAINode(Vector3 position, bool inside)
{
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
GameObject[] obj = (inside ? GameObject.FindGameObjectsWithTag("AINode") : GameObject.FindGameObjectsWithTag("OutsideAINode"));
GameObject result = null;
float num = float.MaxValue;
GameObject[] array = obj;
foreach (GameObject val in array)
{
float num2 = Vector3.Distance(val.transform.position, position);
if (num2 < num)
{
num = num2;
result = val;
}
}
return result;
}
[HarmonyPatch(typeof(StartOfRound), "Start")]
[HarmonyPostfix]
private static void InitEnemiesPatch()
{
InitEnemies();
}
}
public enum Planet
{
Experimentation,
Assurance,
Vow,
Gordion,
March,
Adamance,
Rend,
Dine,
Offense,
Titan,
Artifice,
Liquidation,
Embrion
}
public class SpawnRarity
{
private readonly int defaultValue;
private readonly Item item;
private readonly Dictionary<Planet, int> rarities = new Dictionary<Planet, int>();
public SpawnRarity(int baseValue, Item itemIn)
{
item = itemIn;
defaultValue = baseValue;
foreach (Planet value in Enum.GetValues(typeof(Planet)))
{
rarities.Add(value, baseValue);
}
}
public int GetRarityFor(Planet planet)
{
return rarities[planet];
}
public int GetRarityFor(int planet)
{
return rarities.Values.ToList()[planet];
}
public void SetValues(int experimentation = -1, int assurance = -1, int vow = -1, int march = -1, int offense = -1, int adamance = -1, int rend = -1, int dine = -1, int titan = -1, int artifice = -1, int embrion = -1)
{
rarities[Planet.Experimentation] = experimentation;
rarities[Planet.Assurance] = assurance;
rarities[Planet.Vow] = vow;
rarities[Planet.March] = march;
rarities[Planet.Offense] = offense;
rarities[Planet.Adamance] = adamance;
rarities[Planet.Rend] = rend;
rarities[Planet.Dine] = dine;
rarities[Planet.Titan] = titan;
rarities[Planet.Artifice] = artifice;
rarities[Planet.Embrion] = embrion;
}
public void CopyRaritiesFrom(SpawnRarity other)
{
rarities[Planet.Experimentation] = other.rarities[Planet.Experimentation];
rarities[Planet.Assurance] = other.rarities[Planet.Assurance];
rarities[Planet.Vow] = other.rarities[Planet.Vow];
rarities[Planet.March] = other.rarities[Planet.March];
rarities[Planet.Offense] = other.rarities[Planet.Offense];
rarities[Planet.Adamance] = other.rarities[Planet.Adamance];
rarities[Planet.Rend] = other.rarities[Planet.Rend];
rarities[Planet.Dine] = other.rarities[Planet.Dine];
rarities[Planet.Titan] = other.rarities[Planet.Titan];
rarities[Planet.Artifice] = other.rarities[Planet.Artifice];
rarities[Planet.Embrion] = other.rarities[Planet.Embrion];
}
public SpawnableItemWithRarity GetSpawnableItemForPlanet(Planet planet)
{
//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_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Expected O, but got Unknown
return new SpawnableItemWithRarity
{
spawnableItem = item,
rarity = AccessRaritySafe((int)planet)
};
}
public SpawnableItemWithRarity GetSpawnableItemForPlanet(int planet)
{
//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_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Expected O, but got Unknown
return new SpawnableItemWithRarity
{
spawnableItem = item,
rarity = AccessRaritySafe(planet)
};
}
private int AccessRaritySafe(int planet)
{
try
{
return rarities.Values.ToList()[planet];
}
catch (Exception)
{
}
return defaultValue;
}
public void ApplySpawnRarity(SelectableLevel level)
{
level.spawnableScrap.Add(GetSpawnableItemForPlanet(level.levelID));
}
}
}
namespace LCTarrotCard.Ressource
{
public static class Assets
{
public static class Materials
{
public static Material CardDeathMat;
public static Material CardHangedMat;
public static Material CardPriestessMat;
public static Material CardDevilMat;
public static Material CardFoolMat;
public static Material CardHermitMat;
public static Material CardMoonMat;
public static Material CardSunMat;
public static Material CardTowerMat;
public static Material CardWheelMat;
public static Material BurnAqua;
public static Material BurnBlue;
public static Material BurnGreen;
public static Material BurnPurple;
public static Material BurnRed;
public static Material BurnWhite;
public static Material BurnYellow;
}
internal static AssetBundle Bundle;
public static Item TarotItem;
public static GameObject SingleTarotCard;
public static readonly List<AudioClip> PullCardClips = new List<AudioClip>();
public static AudioClip FoolCardSound;
public static AudioClip GhostBreathe;
public static SpawnRarity TarotRarity;
public static void Load()
{
if (LoadBundle())
{
LoadAssets();
InitSpawns();
}
}
private static bool LoadBundle()
{
Stream manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("LCTarrotCard.Ressource.tarrotbundle");
if (manifestResourceStream == null)
{
PluginLogger.Error("Cannot load the asset bundle");
return false;
}
Bundle = AssetBundle.LoadFromStream(manifestResourceStream);
if ((Object)(object)Bundle != (Object)null)
{
return true;
}
PluginLogger.Error("Cannot load the asset bundle");
return false;
}
private static void LoadAssets()
{
TarotItem = LoadAsset<Item>("TarrotCard.asset");
TarotBehaviour tarotBehaviour = TarotItem.spawnPrefab.AddComponent<TarotBehaviour>();
((GrabbableObject)tarotBehaviour).grabbable = true;
((GrabbableObject)tarotBehaviour).grabbableToEnemies = true;
((GrabbableObject)tarotBehaviour).itemProperties = TarotItem;
SingleTarotCard = LoadAsset<GameObject>("single_card_prefab.prefab");
PullCardClips.Add(LoadAsset<AudioClip>("Sound/tarot_draw1.ogg"));
PullCardClips.Add(LoadAsset<AudioClip>("Sound/tarot_draw2.ogg"));
PullCardClips.Add(LoadAsset<AudioClip>("Sound/tarot_draw3.ogg"));
FoolCardSound = LoadAsset<AudioClip>("Sound/fool.ogg");
GhostBreathe = LoadAsset<AudioClip>("Sound/breathe.ogg");
LoadMaterials();
}
private static void LoadMaterials()
{
Materials.CardDeathMat = LoadAsset<Material>("Cards/DeathMat.mat");
Materials.CardHangedMat = LoadAsset<Material>("Cards/HangedManMat.mat");
Materials.CardPriestessMat = LoadAsset<Material>("Cards/HighPreistessMat.mat");
Materials.CardDevilMat = LoadAsset<Material>("Cards/TheDevilMat.mat");
Materials.CardFoolMat = LoadAsset<Material>("Cards/TheFoolMat.mat");
Materials.CardHermitMat = LoadAsset<Material>("Cards/TheHermitMat.mat");
Materials.CardMoonMat = LoadAsset<Material>("Cards/TheMoonMat.mat");
Materials.CardSunMat = LoadAsset<Material>("Cards/TheSunMat.mat");
Materials.CardTowerMat = LoadAsset<Material>("Cards/TowerMat.mat");
Materials.CardWheelMat = LoadAsset<Material>("Cards/WheelMat.mat");
Materials.BurnAqua = LoadAsset<Material>("Burn/AquaBurn.mat");
Materials.BurnBlue = LoadAsset<Material>("Burn/BlueBurn.mat");
Materials.BurnGreen = LoadAsset<Material>("Burn/GreenBurn.mat");
Materials.BurnPurple = LoadAsset<Material>("Burn/PurpleBurn.mat");
Materials.BurnRed = LoadAsset<Material>("Burn/RedBurn.mat");
Materials.BurnWhite = LoadAsset<Material>("Burn/WhiteBurn.mat");
Materials.BurnYellow = LoadAsset<Material>("Burn/YellowBurn.mat");
}
private static void InitSpawns()
{
TarotRarity = new SpawnRarity(17, TarotItem);
TarotRarity.SetValues(12, -1, 19, 21, -1, 22, 22, 23, 30, 25, 20);
}
private static T LoadAsset<T>(string assetPath) where T : Object
{
return Bundle.LoadAsset<T>("Assets/Tarrot/" + assetPath);
}
}
[HarmonyPatch(typeof(GameNetworkManager))]
internal class NetworkPatcher
{
[HarmonyPatch("Start")]
[HarmonyPostfix]
private static void RegisterNetworkPrefab()
{
NetworkManager component = ((Component)GameNetworkManager.Instance).GetComponent<NetworkManager>();
component.AddNetworkPrefab(Assets.TarotItem.spawnPrefab);
component.AddNetworkPrefab(Assets.SingleTarotCard);
}
}
[HarmonyPatch(typeof(StartOfRound))]
internal class StartOfRoundPatcher
{
[HarmonyPatch("Awake")]
[HarmonyPostfix]
private static void RegisterItemsPatch(StartOfRound __instance)
{
SelectableLevel[] levels = __instance.levels;
foreach (SelectableLevel level in levels)
{
Assets.TarotRarity.ApplySpawnRarity(level);
}
RegisterItem(Assets.TarotItem, __instance);
}
private static void RegisterItem(Item item, StartOfRound manager)
{
if (!manager.allItemsList.itemsList.Contains(item))
{
manager.allItemsList.itemsList.Add(item);
}
}
}
}
namespace LCTarrotCard.Patches
{
[HarmonyPatch(typeof(PlayerControllerB))]
public class PlayerControllerBPatch
{
[HarmonyPatch("KillPlayer")]
[HarmonyPrefix]
private static bool AllowExtraLife(PlayerControllerB __instance)
{
if (!Networker.AllowExtraLife || !((NetworkBehaviour)__instance).IsOwner)
{
return true;
}
PluginLogger.Debug("Allowing extra life for player " + __instance.playerUsername);
Networker.Instance.ExtraLifeServerRpc((int)__instance.playerClientId);
return false;
}
}
}
namespace LCTarrotCard.Items
{
public class TarotBehaviour : GrabbableObject
{
private readonly AnimationCurve controlCurve = new AnimationCurve((Keyframe[])(object)new Keyframe[2]
{
new Keyframe(0f, 0f, 0f, 0f, 0.5f, 0.5f),
new Keyframe(1f, 1f, 0f, 0f, 0.5f, 0.5f)
});
private int cardLeft = 10;
private GameObject currentCard;
private Card currentCardProperties;
private bool drawingCoroutinePlaying;
private bool isDrawingCard;
private AudioSource itemAudio;
private Vector3 originalCardScale;
private PlayerControllerB playerWhoDrew;
public override void Start()
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
((GrabbableObject)this).Start();
itemAudio = ((Component)this).gameObject.GetComponent<AudioSource>();
originalCardScale = ((Component)this).gameObject.transform.localScale;
}
public override void ItemActivate(bool used, bool buttonDown = true)
{
if (!base.deactivated && StartOfRound.Instance.shipHasLanded && ((NetworkBehaviour)this).IsOwner && buttonDown && !isDrawingCard && base.isHeld && !((Object)(object)base.playerHeldBy == (Object)null) && cardLeft > 0)
{
isDrawingCard = true;
DrawCardServerRpc(base.playerHeldBy.playerClientId);
}
}
public override void SetControlTipsForItem()
{
List<string> list = new List<string>(base.itemProperties.toolTips);
if (cardLeft > 0)
{
list.Add(cardLeft + " card" + ((cardLeft == 1) ? "" : "s") + " left");
}
HUDManager.Instance.ChangeControlTipMultiple(list.ToArray(), true, base.itemProperties);
}
public void StartDrawingCard(int pulledCard)
{
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_0122: Unknown result type (might be due to invalid IL or missing references)
//IL_0136: Unknown result type (might be due to invalid IL or missing references)
//IL_013b: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)playerWhoDrew == (Object)null)
{
PluginLogger.Error("Trying to pull a card with a null player");
DestroyAfterDrawing();
return;
}
if (pulledCard < 0 || pulledCard >= AllCards.GetAllCardsAsList().Count)
{
PluginLogger.Error("Trying to pull a card with an invalid index");
DestroyAfterDrawing();
return;
}
cardLeft--;
PluginLogger.Debug("Card left : " + cardLeft);
((GrabbableObject)this).SetControlTipsForItem();
if (cardLeft > 0)
{
float num = (float)cardLeft * 0.1f;
Vector3 val = default(Vector3);
((Vector3)(ref val))..ctor(originalCardScale.x, originalCardScale.y * num, originalCardScale.z);
((Component)this).gameObject.transform.localScale = val;
base.originalScale = val;
}
else
{
((Component)((Component)this).gameObject.transform.GetChild(0)).gameObject.SetActive(false);
}
if (!drawingCoroutinePlaying)
{
Type type = AllCards.GetAllCardsAsList()[pulledCard];
currentCard = Object.Instantiate<GameObject>(Assets.SingleTarotCard, ((Component)this).gameObject.transform);
Transform transform = currentCard.transform;
transform.localEulerAngles += new Vector3(180f, 0f, 0f);
PluginLogger.Debug("Card with type " + type.Name);
currentCardProperties = (Card)Activator.CreateInstance(type, currentCard, itemAudio);
currentCardProperties.InitCard();
((MonoBehaviour)this).StartCoroutine(DrawingCoroutine());
}
}
private IEnumerator DrawingCoroutine()
{
drawingCoroutinePlaying = true;
((MonoBehaviour)this).StartCoroutine(currentCardProperties.CardPullingCoroutine());
yield return (object)new WaitForSeconds(0.5f);
Vector3 initPos = currentCard.transform.localPosition;
Vector3 endPos = currentCard.transform.localPosition + new Vector3(0.2f, 0f, 0f);
float delta = 0f;
while (delta < 0.5f)
{
currentCard.transform.localPosition = Vector3.Lerp(initPos, endPos, controlCurve.Evaluate(delta * 2f));
delta += Time.deltaTime;
yield return null;
}
yield return (object)new WaitForSeconds(1.1f);
if (((NetworkBehaviour)this).IsOwner)
{
try
{
currentCardProperties.ExecuteEffect(playerWhoDrew);
}
catch (Exception ex)
{
PluginLogger.Error("Error while executing card effect : " + ex);
}
}
yield return (object)new WaitForSeconds(1f);
drawingCoroutinePlaying = false;
EndDrawingCard();
}
public void EndDrawingCard()
{
if (!drawingCoroutinePlaying)
{
DestroyAfterDrawing();
}
}
private void DestroyAfterDrawing()
{
playerWhoDrew = null;
if (Object.op_Implicit((Object)(object)currentCard))
{
Object.Destroy((Object)(object)currentCard);
}
currentCardProperties = null;
if (cardLeft <= 0)
{
DestroyServerRpc();
}
isDrawingCard = false;
}
private void DestroyLocalClient()
{
itemAudio.volume = 0f;
((GrabbableObject)this).DestroyObjectInHand(base.playerHeldBy);
base.deactivated = true;
}
[ServerRpc]
public void DestroyServerRpc()
{
if (!((NetworkBehaviour)this).IsHost)
{
DestroyLocalClient();
}
DestroyClientRpc();
}
[ClientRpc]
public void DestroyClientRpc()
{
DestroyLocalClient();
}
[ServerRpc]
public void DrawCardServerRpc(ulong playerWhoPulled)
{
Type item = AllCards.PullRandomCard();
int pulledCard = AllCards.GetAllCardsAsList().IndexOf(item);
DrawCardClientRpc(playerWhoPulled, pulledCard);
}
[ClientRpc]
public void DrawCardClientRpc(ulong playerWhoPulled, int pulledCard)
{
isDrawingCard = true;
playerWhoDrew = StartOfRound.Instance.allPlayerScripts[playerWhoPulled];
if ((Object)(object)playerWhoDrew == (Object)null)
{
PluginLogger.Error("Player is null when drawing card");
}
StartDrawingCard(pulledCard);
}
}
}
namespace LCTarrotCard.Cards
{
public static class AllCards
{
public static class ProbabilityTable
{
public static int TowerCard = 20;
public static int WheelCard = 20;
public static int SunCard = 5;
public static int MoonCard = 5;
public static int DevilCard = 10;
public static int HermitCard = 10;
public static int HighPriestessCard = 2;
public static int DeathCard = 10;
public static int HangedManCard = 1;
public static int FoolCard = 17;
}
public static readonly Dictionary<Type, int> AllCardsWeighted = new Dictionary<Type, int>();
private static int _totalWeight;
internal static void Init()
{
AllCardsWeighted.Add(typeof(TowerCard), ProbabilityTable.TowerCard);
AllCardsWeighted.Add(typeof(WheelCard), ProbabilityTable.WheelCard);
AllCardsWeighted.Add(typeof(SunCard), ProbabilityTable.SunCard);
AllCardsWeighted.Add(typeof(MoonCard), ProbabilityTable.MoonCard);
AllCardsWeighted.Add(typeof(DevilCard), ProbabilityTable.DevilCard);
AllCardsWeighted.Add(typeof(HermitCard), ProbabilityTable.HermitCard);
AllCardsWeighted.Add(typeof(HighPriestessCard), ProbabilityTable.HighPriestessCard);
AllCardsWeighted.Add(typeof(DeathCard), ProbabilityTable.DeathCard);
AllCardsWeighted.Add(typeof(HangedManCard), ProbabilityTable.HangedManCard);
AllCardsWeighted.Add(typeof(FoolCard), ProbabilityTable.FoolCard);
RecalculateTotalWeight();
}
public static void RegisterCard(Type cardType, int weight)
{
if (!typeof(Card).IsAssignableFrom(cardType))
{
PluginLogger.Warning("Trying to register a non-card type (type : " + cardType.Name + ")");
return;
}
if (AllCardsWeighted.ContainsKey(cardType))
{
PluginLogger.Warning("Trying to register a card that is already registered (type : " + cardType.Name + ")");
return;
}
AllCardsWeighted.Add(cardType, weight);
RecalculateTotalWeight();
}
public static List<Type> GetAllCardsAsList()
{
return new List<Type>(AllCardsWeighted.Keys);
}
private static void RecalculateTotalWeight()
{
_totalWeight = 0;
foreach (int value in AllCardsWeighted.Values)
{
_totalWeight += value;
}
}
public static Type PullRandomCard()
{
int num = 0;
int num2 = Random.Range(0, _totalWeight + 1);
Type type = typeof(object);
foreach (KeyValuePair<Type, int> item in AllCardsWeighted)
{
if (item.Value + num >= num2)
{
type = item.Key;
break;
}
num += item.Value;
}
PluginLogger.Debug(type.Name);
if (typeof(Card).IsAssignableFrom(type))
{
return type;
}
PluginLogger.Warning("Trying to pull a card with a non-card type (type : " + type.Name + ")");
return typeof(FoolCard);
}
}
public abstract class Card
{
protected static readonly AnimationCurve ControlCurve = new AnimationCurve((Keyframe[])(object)new Keyframe[2]
{
new Keyframe(0f, 0f, 0f, 0f, 0.5f, 0.5f),
new Keyframe(1f, 1f, 0f, 0f, 0f, 0f)
});
protected readonly AudioSource cardAudio;
protected readonly GameObject cardPrefab;
protected Card(GameObject cardPrefab, AudioSource audioSource)
{
this.cardPrefab = cardPrefab;
cardAudio = audioSource;
}
public virtual void InitCard()
{
Renderer component = cardPrefab.GetComponent<Renderer>();
Material[] materials = component.materials;
materials[0] = GetCardMaterial();
component.materials = materials;
}
public abstract Material GetCardMaterial();
public abstract Material GetCardBurn();
public abstract void ExecuteEffect(PlayerControllerB playerWhoDrew);
public virtual IEnumerator CardPullingCoroutine()
{
cardAudio.PlayOneShot(Assets.PullCardClips[Random.Range(0, Assets.PullCardClips.Count)]);
yield return (object)new WaitForSeconds(2.2f);
Renderer cardRenderer = cardPrefab.GetComponent<Renderer>();
Material initMat0 = cardRenderer.materials[0];
Material initMat1 = cardRenderer.materials[1];
Material initMat2 = cardRenderer.materials[2];
float delta = 0f;
while (delta < 0.3f)
{
cardRenderer.materials[0].Lerp(initMat0, GetCardBurn(), delta / 0.3f);
cardRenderer.materials[1].Lerp(initMat1, GetCardBurn(), delta / 0.3f);
cardRenderer.materials[2].Lerp(initMat2, GetCardBurn(), delta / 0.3f);
delta += Time.deltaTime;
yield return null;
}
yield return (object)new WaitForSeconds(0.2f);
Vector3 initScale = cardPrefab.transform.localScale;
float delta2 = 0f;
while (delta2 < 0.3f)
{
cardPrefab.transform.localScale = initScale * (1f - ControlCurve.Evaluate(delta2 / 0.3f));
delta2 += Time.deltaTime;
yield return null;
}
cardPrefab.transform.localScale = Vector3.zero;
}
}
public class DeathCard : Card
{
public DeathCard(GameObject cardPrefab, AudioSource audioSource)
: base(cardPrefab, audioSource)
{
}
public override Material GetCardMaterial()
{
return Assets.Materials.CardDeathMat;
}
public override Material GetCardBurn()
{
return Assets.Materials.BurnPurple;
}
public override void ExecuteEffect(PlayerControllerB playerWhoDrew)
{
int num = Random.Range(0, 4);
switch (num)
{
case 0:
PluginLogger.Debug("Agroing coilhead or spawning one");
Networker.Instance.AgroCoilheadOrSpawnServerRpc();
break;
case 1:
PluginLogger.Debug("Pop or spawning jester");
Networker.Instance.PopOrSpawnJesterServerRpc(30f);
break;
default:
PluginLogger.Debug("Spawning giant or dog");
Networker.Instance.SpawnGiantOrDogServerRpc(num - 1);
break;
}
}
}
public class DevilCard : Card
{
public DevilCard(GameObject cardPrefab, AudioSource audioSource)
: base(cardPrefab, audioSource)
{
}
public override Material GetCardMaterial()
{
return Assets.Materials.CardDevilMat;
}
public override Material GetCardBurn()
{
return Assets.Materials.BurnRed;
}
public override void ExecuteEffect(PlayerControllerB playerWhoDrew)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: 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)
int num = Random.Range(0, 4);
if (!playerWhoDrew.isPlayerDead && playerWhoDrew.isPlayerControlled)
{
if (num <= 2)
{
Vector3 position = ((Component)playerWhoDrew).transform.position + ((Component)playerWhoDrew.gameplayCamera).transform.forward * 5f;
Networker.Instance.TeleportRandomEntityServerRpc(position, playerWhoDrew.isInsideFactory);
}
else
{
((MonoBehaviour)playerWhoDrew).StartCoroutine(WaitAndBlow(playerWhoDrew));
}
}
}
private static IEnumerator WaitAndBlow(PlayerControllerB player)
{
yield return (object)new WaitForSeconds(2.5f);
Networker.Instance.GhostBreatheServerRpc(((Component)player).transform.position);
}
}
public class FoolCard : Card
{
private readonly Material[] allCardMat = (Material[])(object)new Material[9]
{
Assets.Materials.CardTowerMat,
Assets.Materials.CardDeathMat,
Assets.Materials.CardWheelMat,
Assets.Materials.CardSunMat,
Assets.Materials.CardMoonMat,
Assets.Materials.CardDevilMat,
Assets.Materials.CardHermitMat,
Assets.Materials.CardPriestessMat,
Assets.Materials.CardHangedMat
};
private Material cardToMimic;
public FoolCard(GameObject cardPrefab, AudioSource audioSource)
: base(cardPrefab, audioSource)
{
}
public override void InitCard()
{
cardToMimic = allCardMat[Random.Range(0, allCardMat.Length)];
base.InitCard();
}
public override Material GetCardMaterial()
{
return cardToMimic;
}
public override Material GetCardBurn()
{
return Assets.Materials.BurnPurple;
}
public override void ExecuteEffect(PlayerControllerB playerWhoDrew)
{
}
public override IEnumerator CardPullingCoroutine()
{
cardAudio.PlayOneShot(Assets.PullCardClips[Random.Range(0, Assets.PullCardClips.Count)]);
Renderer cardRenderer = cardPrefab.GetComponent<Renderer>();
yield return (object)new WaitForSeconds(1.8f);
Material initMat = cardRenderer.materials[0];
Material initMat3 = cardRenderer.materials[1];
Material initMat5 = cardRenderer.materials[2];
cardAudio.PlayOneShot(Assets.FoolCardSound);
float delta3 = 0f;
while (delta3 < 0.15f)
{
cardRenderer.materials[0].Lerp(initMat, GetCardBurn(), delta3 / 0.3f);
cardRenderer.materials[1].Lerp(initMat3, GetCardBurn(), delta3 / 0.3f);
cardRenderer.materials[2].Lerp(initMat5, GetCardBurn(), delta3 / 0.3f);
delta3 += Time.deltaTime;
yield return null;
}
Material trMat0 = cardRenderer.materials[0];
Material trMat1 = cardRenderer.materials[1];
Material trMat2 = cardRenderer.materials[2];
delta3 = 0f;
while (delta3 < 0.15f)
{
cardRenderer.materials[0].Lerp(trMat0, Assets.Materials.CardFoolMat, delta3 / 0.3f);
cardRenderer.materials[1].Lerp(trMat1, initMat3, delta3 / 0.3f);
cardRenderer.materials[2].Lerp(trMat2, initMat5, delta3 / 0.3f);
delta3 += Time.deltaTime;
yield return null;
}
Material[] materials = (Material[])(object)new Material[3]
{
Assets.Materials.CardFoolMat,
initMat3,
initMat5
};
cardRenderer.materials = materials;
yield return (object)new WaitForSeconds(0.1f);
initMat = cardRenderer.materials[0];
initMat3 = cardRenderer.materials[1];
initMat5 = cardRenderer.materials[2];
delta3 = 0f;
while (delta3 < 0.3f)
{
cardRenderer.materials[0].Lerp(initMat, GetCardBurn(), delta3 / 0.3f);
cardRenderer.materials[1].Lerp(initMat3, GetCardBurn(), delta3 / 0.3f);
cardRenderer.materials[2].Lerp(initMat5, GetCardBurn(), delta3 / 0.3f);
delta3 += Time.deltaTime;
yield return null;
}
yield return (object)new WaitForSeconds(0.2f);
Vector3 initScale = cardPrefab.transform.localScale;
float delta4 = 0f;
while (delta4 < 0.3f)
{
cardPrefab.transform.localScale = initScale * (1f - Card.ControlCurve.Evaluate(delta4 / 0.3f));
delta4 += Time.deltaTime;
yield return null;
}
cardPrefab.transform.localScale = Vector3.zero;
}
}
public class HangedManCard : Card
{
public HangedManCard(GameObject cardPrefab, AudioSource audioSource)
: base(cardPrefab, audioSource)
{
}
public override Material GetCardMaterial()
{
return Assets.Materials.CardHangedMat;
}
public override Material GetCardBurn()
{
return Assets.Materials.BurnRed;
}
public override void ExecuteEffect(PlayerControllerB playerWhoDrew)
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
if (!playerWhoDrew.isPlayerDead && playerWhoDrew.isPlayerControlled)
{
Networker.Instance.KillPlayerServerRpc((int)playerWhoDrew.playerClientId, new Vector3(0f, 1f, 0f), (CauseOfDeath)0);
}
}
}
public class HermitCard : Card
{
public HermitCard(GameObject cardPrefab, AudioSource audioSource)
: base(cardPrefab, audioSource)
{
}
public override Material GetCardMaterial()
{
return Assets.Materials.CardHermitMat;
}
public override Material GetCardBurn()
{
return Assets.Materials.BurnAqua;
}
public override void ExecuteEffect(PlayerControllerB playerWhoDrew)
{
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
if (Random.Range(0, 2) == 0)
{
PluginLogger.Debug("Teleporting enemy away");
Networker.Instance.TeleportEnemyAwayServerRpc();
}
else
{
PluginLogger.Debug("Teleporting player to random inside node");
Vector3 position = RoundManager.Instance.insideAINodes[Random.Range(0, RoundManager.Instance.insideAINodes.Length)].transform.position;
Networker.Instance.TeleportPlayerServerRpc((int)playerWhoDrew.playerClientId, position);
}
}
}
public class HighPriestessCard : Card
{
public HighPriestessCard(GameObject cardPrefab, AudioSource audioSource)
: base(cardPrefab, audioSource)
{
}
public override Material GetCardMaterial()
{
return Assets.Materials.CardPriestessMat;
}
public override Material GetCardBurn()
{
return Assets.Materials.BurnYellow;
}
public override void ExecuteEffect(PlayerControllerB playerWhoDrew)
{
int num = -1;
for (int i = 0; i < StartOfRound.Instance.allPlayerScripts.Length; i++)
{
PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[i];
PluginLogger.Debug("Checking player " + val.playerUsername + " isPlayerControlled: " + val.isPlayerControlled + " isPlayerDead: " + val.isPlayerDead);
if (val.isPlayerDead)
{
num = i;
break;
}
}
if (num != -1)
{
PluginLogger.Debug("Reviving player " + StartOfRound.Instance.allPlayerScripts[num].playerUsername);
Networker.Instance.RevivePlayerServerRpc(num);
}
else
{
PluginLogger.Debug("No dead player found, allowing extra life");
Networker.Instance.AllowExtraLifeServerRpc();
}
}
}
public class MoonCard : Card
{
public MoonCard(GameObject cardPrefab, AudioSource audioSource)
: base(cardPrefab, audioSource)
{
}
public override Material GetCardMaterial()
{
return Assets.Materials.CardMoonMat;
}
public override Material GetCardBurn()
{
return Assets.Materials.BurnWhite;
}
public override void ExecuteEffect(PlayerControllerB playerWhoDrew)
{
int num = playerWhoDrew.ItemSlots.Count((GrabbableObject item) => Object.op_Implicit((Object)(object)item));
int num2 = Random.Range(0, 10);
if (num2 > 6 && num > 2)
{
float multiplier = Random.Range(0.1f, 0.9f);
PluginLogger.Debug("Multiplying inventory value by " + multiplier);
Networker.Instance.MultiplyInventoryValueServerRpc((int)playerWhoDrew.playerClientId, multiplier);
return;
}
if (num2 == 0)
{
float multiplier2 = Random.Range(0.1f, 0.9f);
PluginLogger.Debug("Multiplying random scrap value by " + multiplier2);
Networker.Instance.MultiplyRandomScrapValueServerRpc(multiplier2);
return;
}
PluginLogger.Debug("Damaging player to 2 health");
if (!playerWhoDrew.isPlayerDead && playerWhoDrew.health > 2)
{
Networker.Instance.SetPlayerHealthServerRpc((int)playerWhoDrew.playerClientId, 2);
}
}
}
public class SunCard : Card
{
public SunCard(GameObject cardPrefab, AudioSource audioSource)
: base(cardPrefab, audioSource)
{
}
public override Material GetCardMaterial()
{
return Assets.Materials.CardSunMat;
}
public override Material GetCardBurn()
{
return Assets.Materials.BurnYellow;
}
public override void ExecuteEffect(PlayerControllerB playerWhoDrew)
{
int num = playerWhoDrew.ItemSlots.Count((GrabbableObject item) => Object.op_Implicit((Object)(object)item));
int num2 = Random.Range(0, 10);
if (num2 > 6 && num > 2)
{
float multiplier = Random.Range(1.1f, 1.5f);
PluginLogger.Debug("Multiplying inventory value by " + multiplier);
Networker.Instance.MultiplyInventoryValueServerRpc((int)playerWhoDrew.playerClientId, multiplier);
return;
}
if (num2 == 0)
{
float multiplier2 = Random.Range(1.1f, 1.5f);
PluginLogger.Debug("Multiplying random scrap value by " + multiplier2);
Networker.Instance.MultiplyRandomScrapValueServerRpc(multiplier2);
return;
}
PluginLogger.Debug("Healing player to 100 health");
if (!playerWhoDrew.isPlayerDead && playerWhoDrew.health < 100)
{
Networker.Instance.SetPlayerHealthServerRpc((int)playerWhoDrew.playerClientId, 100);
}
}
}
public class TowerCard : Card
{
public TowerCard(GameObject cardPrefab, AudioSource audioSource)
: base(cardPrefab, audioSource)
{
}
public override Material GetCardMaterial()
{
return Assets.Materials.CardTowerMat;
}
public override Material GetCardBurn()
{
return Assets.Materials.BurnBlue;
}
public override void ExecuteEffect(PlayerControllerB playerWhoDrew)
{
int num = Random.Range(0, 60);
if (num == 0)
{
return;
}
if (num <= 22)
{
PluginLogger.Debug("Opening or closing random security doors");
TerminalAccessibleObject[] array = Object.FindObjectsOfType<TerminalAccessibleObject>();
foreach (TerminalAccessibleObject val in array)
{
if (val.isBigDoor && Random.Range(0, 2) == 0)
{
val.SetDoorToggleLocalClient();
}
}
}
else if (num <= 40)
{
PluginLogger.Debug("Opening or closing rng doors");
Networker.Instance.OpenOrCloseRandomDoorServerRpc((int)playerWhoDrew.playerClientId);
}
else if (num <= 55)
{
PluginLogger.Debug("Inverting ship door state");
Networker.Instance.SetShipDoorStateServerRpc(StartOfRound.Instance.hangarDoorsClosed);
}
else
{
PluginLogger.Debug("Turning off breaker");
Networker.Instance.BreakerOffServerRpc();
}
}
}
public class WheelCard : Card
{
private bool outcome;
public WheelCard(GameObject cardPrefab, AudioSource audioSource)
: base(cardPrefab, audioSource)
{
}
public override void InitCard()
{
outcome = Random.Range(0, 2) == 0;
base.InitCard();
}
public override Material GetCardMaterial()
{
return Assets.Materials.CardWheelMat;
}
public override Material GetCardBurn()
{
if (!outcome)
{
return Assets.Materials.BurnRed;
}
return Assets.Materials.BurnGreen;
}
public override void ExecuteEffect(PlayerControllerB playerWhoDrew)
{
//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)
int num = Random.Range(0, 2);
if (outcome)
{
switch (num)
{
case 0:
PluginLogger.Debug("Healing by 20 hp");
if (playerWhoDrew.health >= 80)
{
Networker.Instance.SetPlayerHealthServerRpc((int)playerWhoDrew.playerClientId, 100);
}
else
{
Networker.Instance.SetPlayerHealthServerRpc((int)playerWhoDrew.playerClientId, playerWhoDrew.health + 20);
}
break;
case 1:
PluginLogger.Debug("Multiplying some scrap value by 1.1");
Networker.Instance.MultiplyRandomScrapValueServerRpc(1.1f);
break;
}
}
else
{
switch (num)
{
case 0:
PluginLogger.Debug("Damaging by 20 hp");
Networker.Instance.DamagePlayerServerRpc((int)playerWhoDrew.playerClientId, 20, default(Vector3), (CauseOfDeath)0);
break;
case 1:
PluginLogger.Debug("Multiplying some scrap value by 0.9");
Networker.Instance.MultiplyRandomScrapValueServerRpc(0.9f);
break;
}
}
}
}
}