using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using Microsoft.CodeAnalysis;
using On.EntityStates;
using On.RoR2;
using On.RoR2.UI;
using R2API;
using R2API.Networking;
using R2API.Networking.Interfaces;
using R2API.Utils;
using RoR2;
using RoR2.Artifacts;
using RoR2.Stats;
using RoR2.UI;
using RoR2BepInExPack.GameAssetPathsBetter;
using TMPro;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Tasks")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+3bda125dc5aa5a034a0728bb0d20bd1af632a188")]
[assembly: AssemblyProduct("Tasks")]
[assembly: AssemblyTitle("Tasks")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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]
[Microsoft.CodeAnalysis.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]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace Tasks
{
internal class AirKills : Task
{
private int[] kills;
private int killsNeeded = 3;
private List<HitGroundDelegate> groundDelegateList = new List<HitGroundDelegate>();
protected new string description { get; } = "Get 3 kills whilst airborne";
public override TaskType type { get; } = TaskType.AirKills;
protected override string name { get; } = "Air Kills";
public override string GetDescription()
{
return description;
}
public override string GetWinMessage(int winningPlayer)
{
return GetStylizedName(winningPlayer) + " completed " + GetStylizedTaskName(name) + ".";
}
protected override void SetHooks(int numPlayers)
{
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Expected O, but got Unknown
Debug.Log((object)$"Set Hooks in AirKills. {numPlayers} players");
base.SetHooks(numPlayers);
kills = new int[numPlayers];
GlobalEventManager.onCharacterDeathGlobal += OnKill;
for (int i = 0; i < totalNumberPlayers; i++)
{
CharacterMaster playerCharacterMaster = TasksPlugin.GetPlayerCharacterMaster(i);
if (playerCharacterMaster == null || playerCharacterMaster.GetBody() == null || playerCharacterMaster.GetBody().characterMotor == null)
{
break;
}
int tempInt = i;
HitGroundDelegate item = (HitGroundDelegate)delegate
{
PlayerHitGround(tempInt);
};
groundDelegateList.Add(item);
playerCharacterMaster.GetBody().characterMotor.onHitGround += groundDelegateList[tempInt];
}
}
protected override void Unhook()
{
GlobalEventManager.onCharacterDeathGlobal -= OnKill;
for (int i = 0; i < totalNumberPlayers; i++)
{
CharacterMaster playerCharacterMaster = TasksPlugin.GetPlayerCharacterMaster(i);
if (playerCharacterMaster == null || playerCharacterMaster.GetBody() == null || playerCharacterMaster.GetBody().characterMotor == null)
{
break;
}
int index = i;
playerCharacterMaster.GetBody().characterMotor.onHitGround -= groundDelegateList[index];
}
ResetAllKills();
base.Unhook();
}
private void UpdateProgress()
{
for (int i = 0; i < progress.Length; i++)
{
progress[i] = (float)kills[i] / (float)killsNeeded;
}
base.UpdateProgress(progress);
}
protected override bool IsComplete(int playerNum)
{
return kills[playerNum] >= killsNeeded;
}
public void OnKill(DamageReport damageReport)
{
if (damageReport == null || damageReport.attackerMaster == null || damageReport.attackerMaster.playerCharacterMasterController == null)
{
return;
}
int playerNumber = TasksPlugin.GetPlayerNumber(damageReport.attackerMaster);
if (!damageReport.attackerMaster.GetBody().characterMotor.isGrounded)
{
kills[playerNumber]++;
UpdateProgress();
if (IsComplete(playerNumber))
{
CompleteTask(playerNumber);
ResetAllKills();
}
}
}
private void PlayerHitGround(int playerNum)
{
UpdateProgress();
kills[playerNum] = 0;
}
private void ResetAllKills()
{
if (kills != null)
{
for (int i = 0; i < kills.Length; i++)
{
kills[i] = 0;
}
ResetProgress();
}
}
}
internal class BabyDrone : Task
{
private CharacterMaster[] drones;
private CharacterMaster createdDrone;
private bool[] playerFailed;
private int numPlayersFailed;
private bool alreadyAwarded;
public override TaskType type { get; } = TaskType.BabyDrone;
protected override string name { get; } = "Baby Drone";
public override bool CanActivate(int numPlayers)
{
return true;
}
public override string GetDescription()
{
return "Keep your drone alive";
}
public override string GetWinMessage(int winningPlayer)
{
if (winningPlayer < 0)
{
return "You failed " + GetStylizedTaskName(name) + " by letting your drone die.";
}
return GetStylizedName(winningPlayer) + " kept their drone alive the longest. Completed " + GetStylizedTaskName(name) + ".";
}
protected override void SetHooks(int numPlayers)
{
Debug.Log((object)$"Set Hooks in BabyDrone. {numPlayers} players");
base.SetHooks(numPlayers);
drones = (CharacterMaster[])(object)new CharacterMaster[numPlayers];
playerFailed = new bool[numPlayers];
numPlayersFailed = 0;
alreadyAwarded = false;
for (int i = 0; i < numPlayers; i++)
{
playerFailed[i] = false;
SpawnDrone(i);
}
GlobalEventManager.onCharacterDeathGlobal += OnKill;
}
protected override void StageEnd()
{
base.StageEnd();
Evaluate();
ResetProgress();
}
protected override void Unhook()
{
GlobalEventManager.onCharacterDeathGlobal -= OnKill;
base.Unhook();
}
private void Evaluate()
{
if (alreadyAwarded)
{
return;
}
for (int i = 0; i < playerFailed.Length; i++)
{
if (!playerFailed[i])
{
UpdateProgressMultiWinner();
CompleteTask(i);
}
}
}
private void UpdateProgress()
{
for (int i = 0; i < progress.Length; i++)
{
if (totalNumberPlayers > 1)
{
progress[i] = ((!playerFailed[i]) ? (numPlayersFailed / (totalNumberPlayers - 1)) : 0);
}
else
{
progress[i] = 0f;
}
}
base.UpdateProgress(progress);
}
private void UpdateProgressMultiWinner()
{
for (int i = 0; i < progress.Length; i++)
{
progress[i] = ((!playerFailed[i]) ? 1 : 0);
}
base.UpdateProgress(progress);
}
public void OnKill(DamageReport damageReport)
{
if (damageReport == null || damageReport.victimMaster == null)
{
return;
}
for (int i = 0; i < drones.Length; i++)
{
if (playerFailed[i] || !((Object)(object)damageReport.victimMaster == (Object)(object)drones[i]))
{
continue;
}
string text = $"BABY_DRONE_{i}";
ChatMessage.Send(GetDroneDeathMessage(Language.currentLanguage.GetLocalizedStringByToken(text)));
playerFailed[i] = true;
numPlayersFailed++;
UpdateProgress();
if (totalNumberPlayers > 1)
{
if (numPlayersFailed < totalNumberPlayers - 1)
{
continue;
}
for (int j = 0; j < playerFailed.Length; j++)
{
if (!playerFailed[j])
{
alreadyAwarded = true;
CompleteTask(j);
return;
}
}
}
else
{
CompleteTask(-1);
}
}
}
private void SpawnDrone(int playerNum)
{
//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_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: 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_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Expected O, but got Unknown
//IL_005e: Expected O, but got Unknown
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Expected O, but got Unknown
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Expected O, but got Unknown
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Expected O, but got Unknown
CharacterBody body = TasksPlugin.GetPlayerCharacterMaster(playerNum).GetBody();
GameObject val = DirectorCore.instance.TrySpawnObject(new DirectorSpawnRequest(Resources.Load<SpawnCard>("SpawnCards/InteractableSpawnCard/iscbrokendrone1"), new DirectorPlacementRule
{
placementMode = (PlacementMode)0,
position = body.transform.position + new Vector3(1f, 0f, 0f)
}, new Xoroshiro128Plus(0uL)));
PurchaseInteraction component = val.GetComponent<PurchaseInteraction>();
component.cost = 0;
Interactor component2 = ((Component)body).GetComponent<Interactor>();
if (Object.op_Implicit((Object)(object)component2))
{
MasterSummon.Perform += new hook_Perform(GrabDrone);
component.OnInteractionBegin(component2);
MasterSummon.Perform -= new hook_Perform(GrabDrone);
string text = $"BABY_DRONE_{playerNum}";
Language.currentLanguage.SetStringByToken(text, GetDroneName(playerNum));
CharacterBody body2 = createdDrone.GetBody();
body2.baseNameToken = text;
body2.baseRegen = 0f;
drones[playerNum] = createdDrone;
((MonoBehaviour)TasksPlugin.instance).StartCoroutine(DamageDrone(body2));
}
}
private CharacterMaster GrabDrone(orig_Perform orig_Perform, MasterSummon self)
{
return createdDrone = orig_Perform.Invoke(self);
}
private string GetDroneName(int playerNum)
{
string displayName = ((Component)TasksPlugin.GetPlayerCharacterMaster(playerNum)).GetComponent<PlayerCharacterMasterController>().GetDisplayName();
WeightedSelection<string> val = new WeightedSelection<string>(14);
val.AddChoice(displayName + " Junior", 1f);
val.AddChoice(displayName + " Jr.", 1f);
val.AddChoice("Baby " + displayName, 1f);
val.AddChoice("Little " + displayName, 1f);
val.AddChoice("Li'l " + displayName, 1f);
val.AddChoice(displayName + " the Second", 1f);
val.AddChoice(displayName + " the Third", 1f);
val.AddChoice(displayName + " II", 1f);
val.AddChoice(displayName + " III", 1f);
val.AddChoice(displayName + " the Younger", 1f);
val.AddChoice("Mini " + displayName, 1f);
val.AddChoice(displayName + " Mk II", 1f);
val.AddChoice(displayName + " 2.0", 1f);
val.AddChoice(displayName + " (Clone)", 1f);
return val.Evaluate(Random.value);
}
private string GetDroneDeathMessage(string droneName)
{
WeightedSelection<string> val = new WeightedSelection<string>(8);
val.AddChoice(droneName + " died. And it was all your fault.", 1f);
val.AddChoice(droneName + " died. And you just let it happen.", 1f);
val.AddChoice(droneName + " died because you didn't love him enough.", 1f);
val.AddChoice(droneName + " died. Play on an easier difficulty so this doesn't happen again.", 1f);
val.AddChoice("You killed " + droneName + ". You monster.", 1f);
val.AddChoice("You let " + droneName + " die. You monster.", 1f);
val.AddChoice("You let " + droneName + " die. What did he ever do to you?", 1f);
val.AddChoice(droneName + " said goodbye. When he died.", 1f);
val.AddChoice(droneName + " died. You can repair him, but it won't be the same " + droneName + ".", 1f);
val.AddChoice(droneName + " has went to a junkyard in the country.", 1f);
val.AddChoice(droneName + " has went to a junkyard in the country.", 1f);
val.AddChoice("MISSION FAILURE! " + droneName + " has been lost.", 1f);
val.AddChoice("Well, " + droneName + " has been lost. Hope you're happy", 1f);
val.AddChoice("Well, " + droneName + " is gone. Hope you're happy", 1f);
val.AddChoice(droneName + " has gone and there shall never be another like him.", 1f);
val.AddChoice("RIP " + droneName + ", the goodest boy.", 1f);
val.AddChoice("RIP " + droneName + ".", 1f);
val.AddChoice("At least " + droneName + " didn't suffer.", 1f);
val.AddChoice(droneName + " deserved better.", 1f);
return "<style=cDeath><sprite name=\"Skull\" tint=1> " + val.Evaluate(Random.value) + " <sprite name=\"Skull\" tint=1></style>";
}
private IEnumerator DamageDrone(CharacterBody droneBody)
{
yield return (object)new WaitForSeconds(1f);
DamageInfo damageInfo = new DamageInfo
{
damage = droneBody.healthComponent.combinedHealth,
position = droneBody.corePosition,
force = Vector3.zero,
damageColorIndex = (DamageColorIndex)0,
crit = false,
attacker = null,
inflictor = null,
damageType = DamageTypeCombo.op_Implicit((DamageType)3),
procCoefficient = 0f,
procChainMask = default(ProcChainMask)
};
droneBody.healthComponent.TakeDamage(damageInfo);
}
}
internal class BiggestHit : Task
{
private float[] biggestHit;
protected new string description { get; } = "Biggest hit wins";
public override TaskType type { get; } = TaskType.BiggestHit;
protected override string name { get; } = "Biggest Hit";
public override bool CanActivate(int numPlayers)
{
return numPlayers > 1;
}
public override string GetDescription()
{
return description;
}
public override string GetWinMessage(int winningPlayer)
{
return GetStylizedName(winningPlayer) + " completed " + GetStylizedTaskName(name) + " with the big hit of " + GetStylizedTaskWinStat(biggestHit[winningPlayer].ToString()) + " damage.";
}
protected override void SetHooks(int numPlayers)
{
Debug.Log((object)$"Set Hooks in BiggestHit. {numPlayers} players");
base.SetHooks(numPlayers);
GlobalEventManager.onServerDamageDealt += OnDamage;
if (biggestHit == null || biggestHit.Length != numPlayers)
{
biggestHit = new float[numPlayers];
}
Reset();
}
protected override void StageEnd()
{
base.StageEnd();
Evaluate();
Reset();
}
protected override void Unhook()
{
GlobalEventManager.onServerDamageDealt -= OnDamage;
base.Unhook();
}
protected void UpdateProgress()
{
float num = 0f;
for (int i = 0; i < biggestHit.Length; i++)
{
if (biggestHit[i] > num)
{
num = biggestHit[i];
}
}
if (num > 0f)
{
for (int j = 0; j < progress.Length; j++)
{
progress[j] = biggestHit[j] / num;
}
}
else
{
for (int k = 0; k < progress.Length; k++)
{
progress[k] = 0f;
}
}
base.UpdateProgress(progress);
}
public void OnDamage(DamageReport report)
{
if (report != null && report.attackerMaster != null && report.attackerMaster.playerCharacterMasterController != null)
{
int playerNumber = TasksPlugin.GetPlayerNumber(report.attackerMaster);
float damageDealt = report.damageDealt;
if (damageDealt > biggestHit[playerNumber])
{
biggestHit[playerNumber] = damageDealt;
UpdateProgress();
}
}
}
private void Evaluate()
{
float num = 0f;
int playerNum = 0;
for (int i = 0; i < biggestHit.Length; i++)
{
if (biggestHit[i] > num)
{
num = biggestHit[i];
playerNum = i;
}
}
CompleteTask(playerNum);
}
private void Reset()
{
if (biggestHit != null)
{
for (int i = 0; i < biggestHit.Length; i++)
{
biggestHit[i] = 0f;
}
ResetProgress();
}
}
}
internal class ConfigManager
{
public static ConfigManager instance;
private ConfigFile config;
public static ConfigEntry<int> TasksPerPlayer { get; set; }
public static ConfigEntry<int> AdditionalTasks { get; set; }
public static ConfigEntry<float> AirKillsWeight { get; set; }
public static ConfigEntry<float> DamageMultipleWeight { get; set; }
public static ConfigEntry<float> DamageInTimeWeight { get; set; }
public static ConfigEntry<float> StayInAirWeight { get; set; }
public static ConfigEntry<float> BiggestHitWeight { get; set; }
public static ConfigEntry<float> MostDistanceWeight { get; set; }
public static ConfigEntry<float> PreonEventWeight { get; set; }
public static ConfigEntry<float> FarthestAwayWeight { get; set; }
public static ConfigEntry<float> FailShrineWeight { get; set; }
public static ConfigEntry<float> OpenChestsWeight { get; set; }
public static ConfigEntry<float> StartTeleWeight { get; set; }
public static ConfigEntry<float> UsePrintersWeight { get; set; }
public static ConfigEntry<float> OrderedSkillsWeight { get; set; }
public static ConfigEntry<float> BadSkillWeight { get; set; }
public static ConfigEntry<float> BabyDroneWeight { get; set; }
public static ConfigEntry<float> DieWeight { get; set; }
public static ConfigEntry<float> FindLockboxWeight { get; set; }
public static ConfigEntry<float> HealingItemWeight { get; set; }
public static ConfigEntry<float> NoJumpWeight { get; set; }
public static ConfigEntry<float> VeryBestWeight { get; set; }
public static ConfigEntry<float> FewestElitesWeight { get; set; }
public static ConfigEntry<float> GetLuckyWeight { get; set; }
public static ConfigEntry<float> GetLowWeight { get; set; }
public static ConfigEntry<float> KillStreakWeight { get; set; }
public static ConfigEntry<float> QuickDrawWeight { get; set; }
public static ConfigEntry<float> FarKillWeight { get; set; }
public static ConfigEntry<float> FewEliteWeight { get; set; }
public ConfigManager()
{
if (instance == null)
{
instance = this;
}
}
public void Awake()
{
SetupWeights();
}
public void SetConfigFile(ConfigFile c)
{
config = c;
}
private void SetupWeights()
{
TasksPerPlayer = config.Bind<int>("TaskOptions", "TasksPerPlayer", 1, "Number of tasks per player. Number of tasks: (TasksPerPlayer * number of player) + AdditionalTasks");
AdditionalTasks = config.Bind<int>("TaskOptions", "AdditionalTasks", 2, "Extra tasks. Number of tasks: (TasksPerPlayer * number of player) + AdditionalTasks");
AirKillsWeight = config.Bind<float>("TaskWeights", "AirKills", 1.5f, "Relative weight of this task. Bigger number means more likely to roll task. 0 for no chance.");
DamageMultipleWeight = config.Bind<float>("TaskWeights", "DamageMultiple", 2f, "Relative weight of this task.");
DamageInTimeWeight = config.Bind<float>("TaskWeights", "DamageInTime", 2f, "Relative weight of this task. Do x damage within y seconds");
StayInAirWeight = config.Bind<float>("TaskWeights", "StayInAir", 1.5f, "Relative weight of this task.");
BiggestHitWeight = config.Bind<float>("TaskWeights", "BiggestHit", 2f, "Relative weight of this task.");
MostDistanceWeight = config.Bind<float>("TaskWeights", "MostDistance", 1f, "Relative weight of this task.");
PreonEventWeight = config.Bind<float>("TaskWeights", "PreonEvent", 1f, "Relative weight of this task.");
FarthestAwayWeight = config.Bind<float>("TaskWeights", "FarthestAway", 1.5f, "Relative weight of this task.");
FailShrineWeight = config.Bind<float>("TaskWeights", "FailShrine", 1f, "Relative weight of this task.");
OpenChestsWeight = config.Bind<float>("TaskWeights", "OpenChests", 2f, "Relative weight of this task.");
StartTeleWeight = config.Bind<float>("TaskWeights", "StartTele", 2f, "Relative weight of this task.");
UsePrintersWeight = config.Bind<float>("TaskWeights", "UsePrinters", 1f, "Relative weight of this task.");
OrderedSkillsWeight = config.Bind<float>("TaskWeights", "OrderedSkills", 0f, "Relative weight of this task. Use abilities in left-to-right order. This task sucks.");
BadSkillWeight = config.Bind<float>("TaskWeights", "BadSkill", 0.5f, "Relative weight of this task. Don't use utility skill");
BabyDroneWeight = config.Bind<float>("TaskWeights", "BabyDrone", 0.75f, "Relative weight of this task. Keep your drone alive");
DieWeight = config.Bind<float>("TaskWeights", "Die", 0.25f, "Relative weight of this task.");
FindLockboxWeight = config.Bind<float>("TaskWeights", "FindLockbox", 2f, "Relative weight of this task.");
HealingItemWeight = config.Bind<float>("TaskWeights", "HealingItem", 1.5f, "Relative weight of this task. Find a healing item");
NoJumpWeight = config.Bind<float>("TaskWeights", "NoJump", 1f, "Relative weight of this task.");
VeryBestWeight = config.Bind<float>("TaskWeights", "VeryBest", 1.5f, "Relative weight of this task. Be the very best. Like no one ever was.");
FewestElitesWeight = config.Bind<float>("TaskWeights", "FewestElites", 1.5f, "Relative weight of this task.");
GetLuckyWeight = config.Bind<float>("TaskWeights", "GetLucky", 0.5f, "Relative weight of this task.");
GetLowWeight = config.Bind<float>("TaskWeights", "GetLow", 1.5f, "Relative weight of this task.");
KillStreakWeight = config.Bind<float>("TaskWeights", "KillStreaks", 1.5f, "Relative weight of this task.");
QuickDrawWeight = config.Bind<float>("TaskWeights", "QuickDraw", 1.5f, "Relative weight of this task. Kill something that spawned 3s ago");
FarKillWeight = config.Bind<float>("TaskWeights", "FarKill", 1f, "Relative weight of this task. Kill something far away from where you last left the ground");
FewEliteWeight = config.Bind<float>("TaskWeights", "FewElites", 1f, "Relative weight of this task. Kill the boss before you kill 10 elites");
}
public float GetTaskWeight(TaskType type)
{
return type switch
{
TaskType.AirKills => AirKillsWeight.Value,
TaskType.DamageMultiple => DamageMultipleWeight.Value,
TaskType.DamageInTime => DamageInTimeWeight.Value,
TaskType.StayInAir => StayInAirWeight.Value,
TaskType.BiggestHit => BiggestHitWeight.Value,
TaskType.MostDistance => MostDistanceWeight.Value,
TaskType.PreonEvent => PreonEventWeight.Value,
TaskType.FarthestAway => FarthestAwayWeight.Value,
TaskType.FailShrine => FailShrineWeight.Value,
TaskType.OpenChests => OpenChestsWeight.Value,
TaskType.StartTele => StartTeleWeight.Value,
TaskType.UsePrinters => UsePrintersWeight.Value,
TaskType.OrderedSkills => OrderedSkillsWeight.Value,
TaskType.BadSkill => BadSkillWeight.Value,
TaskType.BabyDrone => BabyDroneWeight.Value,
TaskType.Die => DieWeight.Value,
TaskType.FindLockbox => FindLockboxWeight.Value,
TaskType.HealingItem => HealingItemWeight.Value,
TaskType.NoJump => NoJumpWeight.Value,
TaskType.VeryBest => VeryBestWeight.Value,
TaskType.FewestElites => FewestElitesWeight.Value,
TaskType.GetLucky => GetLuckyWeight.Value,
TaskType.GetLow => GetLowWeight.Value,
TaskType.KillStreak => KillStreakWeight.Value,
TaskType.QuickDraw => QuickDrawWeight.Value,
TaskType.FarKill => FarKillWeight.Value,
TaskType.FewElites => FewEliteWeight.Value,
_ => 1f,
};
}
public int GetNumberOfTasks(int numPlayers)
{
return numPlayers * TasksPerPlayer.Value + AdditionalTasks.Value;
}
}
internal class DamageMultipleTargets : Task
{
private int numToHit = 4;
private HashSet<GameObject>[] targets;
protected new string description { get; } = "Have 4 enemies damaged by you alive at once";
public override TaskType type { get; } = TaskType.DamageMultiple;
protected override string name { get; } = "Damage Multiple";
public override string GetDescription()
{
return description;
}
public override string GetWinMessage(int winningPlayer)
{
return GetStylizedName(winningPlayer) + " completed " + GetStylizedTaskName(name) + " by having " + GetStylizedTaskWinStat(numToHit.ToString()) + " enemies damaged, but alive, at once.";
}
protected override void SetHooks(int numPlayers)
{
Debug.Log((object)$"Set Hooks in DamageMultiple. {numPlayers} players");
base.SetHooks(numPlayers);
GlobalEventManager.onServerDamageDealt += OnDamage;
GlobalEventManager.onCharacterDeathGlobal += OnKill;
targets = new HashSet<GameObject>[numPlayers];
for (int i = 0; i < targets.Length; i++)
{
targets[i] = new HashSet<GameObject>();
}
}
protected override void Unhook()
{
GlobalEventManager.onServerDamageDealt -= OnDamage;
GlobalEventManager.onCharacterDeathGlobal -= OnKill;
ResetKills();
base.Unhook();
}
private void UpdateProgress()
{
for (int i = 0; i < progress.Length; i++)
{
progress[i] = (float)targets[i].Count / (float)numToHit;
}
base.UpdateProgress(progress);
}
public void OnDamage(DamageReport report)
{
if (report == null || report.attackerMaster == null || report.attackerMaster.playerCharacterMasterController == null)
{
return;
}
int playerNumber = TasksPlugin.GetPlayerNumber(report.attackerMaster);
if (report.victim.alive && !targets[playerNumber].Contains(((Component)report.victim).gameObject))
{
targets[playerNumber].Add(((Component)report.victim).gameObject);
UpdateProgress();
if (IsComplete(playerNumber))
{
CompleteTask(playerNumber);
ResetKills();
}
}
}
protected override bool IsComplete(int playerNum)
{
return targets[playerNum].Count >= numToHit;
}
private void OnKill(DamageReport report)
{
if (report != null && report.attackerMaster != null && report.attackerMaster.playerCharacterMasterController != null)
{
int playerNumber = TasksPlugin.GetPlayerNumber(report.attackerMaster);
targets[playerNumber].Remove(((Component)report.victim).gameObject);
UpdateProgress();
}
}
private void ResetKills()
{
if (targets != null)
{
for (int i = 0; i < targets.Length; i++)
{
targets[i].Clear();
}
ResetProgress();
}
}
}
internal class DealDamageInTime : Task
{
private float damageToDeal = 500f;
private float timeLimit = 5f;
private float[] currentDamage;
private bool active = false;
protected new string description { get; } = "Deal 500 damage in 5 seconds";
public override TaskType type { get; } = TaskType.DamageInTime;
protected override string name { get; } = "Damage In Time";
public override string GetDescription()
{
return $"Deal {damageToDeal:N0} damage in 5 seconds";
}
public override string GetWinMessage(int winningPlayer)
{
return GetStylizedName(winningPlayer) + " completed " + GetStylizedTaskName(name) + " by dealing " + GetStylizedTaskWinStat(damageToDeal.ToString()) + " damage within 5s.";
}
protected override void SetHooks(int numPlayers)
{
Debug.Log((object)$"Set Hooks in DamageInTime. {numPlayers} players");
base.SetHooks(numPlayers);
GlobalEventManager.onServerDamageDealt += OnDamage;
damageToDeal = Run.instance.difficultyCoefficient * damageToDeal;
if (currentDamage == null || currentDamage.Length != numPlayers)
{
currentDamage = new float[numPlayers];
}
active = true;
Reset();
}
protected override void Unhook()
{
GlobalEventManager.onServerDamageDealt -= OnDamage;
Reset();
base.Unhook();
}
private void UpdateProgress()
{
for (int i = 0; i < progress.Length; i++)
{
progress[i] = currentDamage[i] / damageToDeal;
}
base.UpdateProgress(progress);
}
public void OnDamage(DamageReport report)
{
if (report != null && report.attackerMaster != null && report.attackerMaster.playerCharacterMasterController != null)
{
int playerNumber = TasksPlugin.GetPlayerNumber(report.attackerMaster);
currentDamage[playerNumber] += report.damageDealt;
UpdateProgress();
((MonoBehaviour)TasksPlugin.instance).StartCoroutine(ReduceDamage(report.damageDealt, playerNumber));
if (IsComplete(playerNumber))
{
active = false;
CompleteTask(playerNumber);
Reset();
}
}
}
protected override bool IsComplete(int playerNum)
{
return currentDamage[playerNum] >= damageToDeal;
}
private IEnumerator ReduceDamage(float damage, int playerNum)
{
yield return (object)new WaitForSeconds(timeLimit);
currentDamage[playerNum] = Mathf.Max(0f, currentDamage[playerNum] - damage);
if (active)
{
UpdateProgress();
}
}
private void Reset()
{
if (currentDamage != null)
{
for (int i = 0; i < currentDamage.Length; i++)
{
currentDamage[i] = 0f;
}
ResetProgress();
}
}
}
internal class Die : Task
{
public override TaskType type { get; } = TaskType.Die;
protected override string name { get; } = "Die";
public override bool CanActivate(int numPlayers)
{
return numPlayers > 1;
}
public override string GetDescription()
{
return "Die";
}
public override string GetWinMessage(int winningPlayer)
{
return GetStylizedName(winningPlayer) + " completed " + GetStylizedTaskName(name) + " by dying first. Congratulations.";
}
protected override void SetHooks(int numPlayers)
{
base.SetHooks(numPlayers);
GlobalEventManager.onCharacterDeathGlobal += OnKill;
}
protected override void Unhook()
{
GlobalEventManager.onCharacterDeathGlobal -= OnKill;
base.Unhook();
}
public void OnKill(DamageReport damageReport)
{
if (damageReport != null && damageReport.victimMaster != null)
{
int playerNumber = TasksPlugin.GetPlayerNumber(damageReport.victimMaster);
if (playerNumber > -1)
{
CompleteTask(playerNumber);
}
}
}
}
internal class DontUseSkill : Task
{
private SkillSlot badSkill;
private bool[] playerFailed;
private int numPlayersFailed;
protected new string description { get; } = "Last to use their utility skill wins";
public override TaskType type { get; } = TaskType.BadSkill;
protected override string name { get; } = "Bad Skill";
public override bool CanActivate(int numPlayers)
{
return numPlayers > 1;
}
public override string GetDescription()
{
return description;
}
public override string GetWinMessage(int winningPlayer)
{
return GetStylizedName(winningPlayer) + " completed " + GetStylizedTaskName(name) + " by not using their " + GetStylizedTaskWinStat(((object)(SkillSlot)(ref badSkill)).ToString()) + " skill.";
}
protected override void SetHooks(int numPlayers)
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
Debug.Log((object)$"Set Hooks in DontUseSkill. {numPlayers} players");
base.SetHooks(numPlayers);
badSkill = (SkillSlot)2;
playerFailed = new bool[numPlayers];
Reset();
TasksPlugin.OnAbilityUsed += AbilityUsed;
}
protected override void StageEnd()
{
base.StageEnd();
Evaluate();
Reset();
}
protected override void Unhook()
{
TasksPlugin.OnAbilityUsed -= AbilityUsed;
base.Unhook();
}
private void Evaluate()
{
if (totalNumberPlayers - numPlayersFailed <= 1)
{
return;
}
for (int i = 0; i < playerFailed.Length; i++)
{
if (!playerFailed[i])
{
UpdateProgressMultiWinner();
CompleteTask(i);
}
}
}
private void UpdateProgress()
{
for (int i = 0; i < progress.Length; i++)
{
progress[i] = ((!playerFailed[i]) ? (numPlayersFailed / (totalNumberPlayers - 1)) : 0);
}
base.UpdateProgress(progress);
}
private void UpdateProgressMultiWinner()
{
for (int i = 0; i < progress.Length; i++)
{
progress[i] = ((!playerFailed[i]) ? 1 : 0);
}
base.UpdateProgress(progress);
}
private void AbilityUsed(int playerNum, SkillSlot slot)
{
//IL_0001: 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)
if (slot != badSkill || playerFailed[playerNum])
{
return;
}
Debug.Log((object)$"Player {playerNum} failed BadSkill");
playerFailed[playerNum] = true;
numPlayersFailed++;
UpdateProgress();
if (numPlayersFailed < totalNumberPlayers - 1)
{
return;
}
for (int i = 0; i < playerFailed.Length; i++)
{
if (!playerFailed[i])
{
CompleteTask(i);
break;
}
}
}
private void Reset()
{
if (playerFailed != null)
{
for (int i = 0; i < playerFailed.Length; i++)
{
playerFailed[i] = false;
}
ResetProgress();
}
}
}
internal class FailShrine : Task
{
protected new string description { get; } = "First to Fail";
public override TaskType type { get; } = TaskType.FailShrine;
protected override string name { get; } = "Fail a Chance Shrine";
public override string GetDescription()
{
return description;
}
public override string GetWinMessage(int winningPlayer)
{
return GetStylizedName(winningPlayer) + " completed " + GetStylizedTaskName(name) + " by " + GetStylizedTaskWinStat("failing") + " a chance shrine.";
}
protected override void SetHooks(int numPlayers)
{
Debug.Log((object)$"Set Hooks in FailShrine. {numPlayers} players");
base.SetHooks(numPlayers);
ShrineChanceBehavior.onShrineChancePurchaseGlobal += OnShrineChancePurchase;
}
protected override void Unhook()
{
ShrineChanceBehavior.onShrineChancePurchaseGlobal -= OnShrineChancePurchase;
base.Unhook();
}
private void OnShrineChancePurchase(bool failed, Interactor interactor)
{
if (!failed)
{
return;
}
for (int i = 0; i < totalNumberPlayers; i++)
{
if ((Object)(object)((Component)TasksPlugin.GetPlayerCharacterMaster(i).GetBody()).GetComponent<Interactor>() == (Object)(object)interactor)
{
CompleteTask(i);
break;
}
}
}
}
internal class FarKill : Task
{
private int distance = 70;
private Vector3[] playerGroundPositions;
private bool active = false;
public override TaskType type { get; } = TaskType.FarKill;
protected override string name { get; } = "Far Kill";
public override string GetDescription()
{
return $"Kill an enemy {distance}m from where you left the ground";
}
public override string GetWinMessage(int winningPlayer)
{
return GetStylizedName(winningPlayer) + " completed " + GetStylizedTaskName(name) + " by killing something from a ways away.";
}
protected override void SetHooks(int numPlayers)
{
//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)
Debug.Log((object)$"Set hooks in FarKill. {numPlayers} players");
base.SetHooks(numPlayers);
GlobalEventManager.onCharacterDeathGlobal += OnKill;
playerGroundPositions = (Vector3[])(object)new Vector3[numPlayers];
for (int i = 0; i < totalNumberPlayers; i++)
{
CharacterMaster playerCharacterMaster = TasksPlugin.GetPlayerCharacterMaster(i);
playerGroundPositions[i] = playerCharacterMaster.GetBody().corePosition;
}
active = true;
((MonoBehaviour)TasksPlugin.instance).StartCoroutine(CalculatePositions());
}
protected override void Unhook()
{
if (active)
{
active = false;
GlobalEventManager.onCharacterDeathGlobal -= OnKill;
base.Unhook();
}
}
private void OnKill(DamageReport report)
{
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
if (report != null && report.attackerMaster != null && report.attackerMaster.playerCharacterMasterController != null)
{
int playerNumber = TasksPlugin.GetPlayerNumber(report.attackerMaster);
float num = Vector3.Distance(report.victimBody.corePosition, playerGroundPositions[playerNumber]);
if (num > (float)distance)
{
CompleteTask(playerNumber);
return;
}
progress[playerNumber] = num / (float)distance;
UpdateProgress(progress);
}
}
private IEnumerator CalculatePositions()
{
while (active)
{
for (int i = 0; i < totalNumberPlayers; i++)
{
CharacterBody body = TasksPlugin.GetPlayerCharacterMaster(i).GetBody();
if (body.characterMotor.isGrounded)
{
playerGroundPositions[i] = body.corePosition;
}
}
yield return null;
}
}
}
internal class FarthestAway : Task
{
private Vector3[] startPositions;
private bool active = false;
private IEnumerator timerRoutine;
private float winnerDist = 0f;
protected new string description { get; } = "Farthest away in 20s wins";
public override TaskType type { get; } = TaskType.FarthestAway;
protected override string name { get; } = "Farthest From Spawn";
public override bool CanActivate(int numPlayers)
{
return numPlayers > 1;
}
public override string GetDescription()
{
return description;
}
public override string GetWinMessage(int winningPlayer)
{
return GetStylizedName(winningPlayer) + " completed " + GetStylizedTaskName(name) + " by being " + GetStylizedTaskWinStat(winnerDist.ToString("F2")) + "m away in 20 seconds.";
}
protected override void SetHooks(int numPlayers)
{
//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_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
Debug.Log((object)$"Set Hooks in FarthestAway. {numPlayers} players");
base.SetHooks(numPlayers);
if (startPositions == null || startPositions.Length != numPlayers)
{
startPositions = (Vector3[])(object)new Vector3[numPlayers];
}
for (int i = 0; i < startPositions.Length; i++)
{
if (TasksPlugin.GetPlayerCharacterMaster(i).GetBody() == null)
{
Debug.Log((object)$"Task.FarthestAway player body is null. Player: {i}");
startPositions[i] = Vector3.zero;
}
else
{
startPositions[i] = TasksPlugin.GetPlayerCharacterMaster(i).GetBody().transform.position;
}
}
timerRoutine = EndTask();
((MonoBehaviour)TasksPlugin.instance).StartCoroutine(timerRoutine);
active = true;
}
protected override void Unhook()
{
if (active)
{
active = false;
if (timerRoutine != null)
{
((MonoBehaviour)TasksPlugin.instance).StopCoroutine(timerRoutine);
}
base.Unhook();
}
}
private void UpdateProgress(int time)
{
//IL_002c: 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)
float[] array = new float[startPositions.Length];
float num = 0f;
if (time > 0)
{
for (int i = 0; i < startPositions.Length; i++)
{
array[i] = Vector3.Distance(startPositions[i], TasksPlugin.GetPlayerCharacterMaster(i).GetBody().transform.position);
if (array[i] > num)
{
num = array[i];
}
}
}
if (num > 0f)
{
for (int j = 0; j < progress.Length; j++)
{
progress[j] = (float)time * (array[j] / num) / 20f;
}
}
else
{
for (int k = 0; k < progress.Length; k++)
{
progress[k] = 0f;
}
}
base.UpdateProgress(progress);
}
private IEnumerator EndTask()
{
for (int i = 0; i < 20; i++)
{
yield return (object)new WaitForSeconds(1f);
UpdateProgress(i + 1);
}
Evaluate();
}
private void Evaluate()
{
//IL_0043: 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_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
float num = 0f;
int playerNum = 0;
for (int i = 0; i < startPositions.Length; i++)
{
CharacterMaster playerCharacterMaster = TasksPlugin.GetPlayerCharacterMaster(i);
if ((Object)(object)playerCharacterMaster == (Object)null)
{
continue;
}
CharacterBody body = playerCharacterMaster.GetBody();
if (!((Object)(object)body == (Object)null))
{
Vector3 position = body.transform.position;
float num2 = Vector3.Distance(startPositions[i], position);
if (num2 > num)
{
num = num2;
playerNum = i;
}
}
}
winnerDist = num;
CompleteTask(playerNum);
ResetProgress();
}
}
internal class FewElites : Task
{
private int[] kills;
private int maxKills = 5;
private bool taskFinished = false;
public override TaskType type { get; } = TaskType.FewElites;
protected override string name { get; } = "Few Elites";
public override bool CanActivate(int numPlayers)
{
return true;
}
public override string GetDescription()
{
return "Kill the boss before you kill 5 elites.";
}
public override string GetWinMessage(int winningPlayer)
{
if (winningPlayer < 0)
{
return "You failed " + GetStylizedTaskName(name) + " by killing too many elites.";
}
return $"{GetStylizedName(winningPlayer)} completed {GetStylizedTaskName(name)} by killing the boss while only killing {GetStylizedTaskWinStat(kills[winningPlayer].ToString())}/{maxKills} elites.";
}
protected override void SetHooks(int numPlayers)
{
Debug.Log((object)$"Set hooks in FewElites. {numPlayers} players");
base.SetHooks(numPlayers);
GlobalEventManager.onCharacterDeathGlobal += OnKill;
BossGroup.onBossGroupDefeatedServer += BossDied;
kills = new int[numPlayers];
taskFinished = false;
Reset();
UpdateProgress();
}
private void BossDied(BossGroup group)
{
Evaluate();
taskFinished = true;
}
protected override void StageEnd()
{
base.StageEnd();
Reset();
}
protected override void Unhook()
{
GlobalEventManager.onCharacterDeathGlobal -= OnKill;
BossGroup.onBossGroupDefeatedServer -= BossDied;
base.Unhook();
}
public void OnKill(DamageReport damageReport)
{
if (taskFinished || damageReport == null || damageReport.attackerMaster == null || damageReport.attackerMaster.playerCharacterMasterController == null)
{
return;
}
int playerNumber = TasksPlugin.GetPlayerNumber(damageReport.attackerMaster);
if (damageReport.victimIsElite)
{
kills[playerNumber]++;
if (totalNumberPlayers == 1 && kills[playerNumber] > maxKills)
{
CompleteTask(-1);
}
}
UpdateProgress();
}
private void UpdateProgress()
{
for (int i = 0; i < progress.Length; i++)
{
if (taskFinished)
{
progress[i] = 0f;
continue;
}
float num = (float)(maxKills - kills[i]) / (float)maxKills;
num = Mathf.Max(num, 0f);
progress[i] = num;
}
base.UpdateProgress(progress);
}
private void Evaluate()
{
if (kills == null)
{
return;
}
string text = "";
string text2 = "";
for (int i = 0; i < kills.Length; i++)
{
if (kills[i] <= maxKills)
{
CompleteTask(i);
text += $"{i}, ";
text2 += $"{kills[i]}, ";
}
}
Debug.Log((object)$"Players {text} won with {text2} /{maxKills} kills");
}
private void Reset()
{
if (kills != null)
{
taskFinished = false;
for (int i = 0; i < kills.Length; i++)
{
kills[i] = 0;
}
ResetProgress();
}
}
}
internal class FewestElites : Task
{
private int[] kills;
public override TaskType type { get; } = TaskType.FewestElites;
protected override string name { get; } = "Fewest Elites";
public override bool CanActivate(int numPlayers)
{
return numPlayers > 1;
}
public override string GetDescription()
{
return "Kill the fewest elites.";
}
public override string GetWinMessage(int winningPlayer)
{
return GetStylizedName(winningPlayer) + " completed " + GetStylizedTaskName(name) + " by killing the fewest (" + GetStylizedTaskWinStat(kills[winningPlayer].ToString()) + ") elites.";
}
protected override void SetHooks(int numPlayers)
{
Debug.Log((object)$"Set hooks in FewestElites. {numPlayers} players");
base.SetHooks(numPlayers);
GlobalEventManager.onCharacterDeathGlobal += OnKill;
kills = new int[numPlayers];
Reset();
}
protected override void StageEnd()
{
base.StageEnd();
Evaluate();
Reset();
}
protected override void Unhook()
{
GlobalEventManager.onCharacterDeathGlobal -= OnKill;
base.Unhook();
}
public void OnKill(DamageReport damageReport)
{
if (damageReport != null && damageReport.attackerMaster != null && damageReport.attackerMaster.playerCharacterMasterController != null)
{
int playerNumber = TasksPlugin.GetPlayerNumber(damageReport.attackerMaster);
if (damageReport.victimIsElite)
{
kills[playerNumber]++;
}
UpdateProgress();
}
}
private void UpdateProgress()
{
int num = 0;
for (int i = 0; i < kills.Length; i++)
{
int num2 = kills[i];
if (num2 > num)
{
num = num2;
}
}
if (num > 0)
{
for (int j = 0; j < progress.Length; j++)
{
progress[j] = (float)kills[j] / (float)num;
}
}
else
{
for (int k = 0; k < progress.Length; k++)
{
progress[k] = 0f;
}
}
base.UpdateProgress(progress);
}
private void Evaluate()
{
if (kills == null)
{
return;
}
int num = 0;
int num2 = kills[0];
for (int i = 1; i < kills.Length; i++)
{
int num3 = kills[i];
if (num3 < num2)
{
num = i;
num2 = num3;
}
}
Debug.Log((object)$"Player {num} won with {num2} elite kills");
CompleteTask(num);
}
private void Reset()
{
if (kills != null)
{
for (int i = 0; i < kills.Length; i++)
{
kills[i] = 0;
}
ResetProgress();
}
}
}
internal class FindLockbox : Task
{
public override TaskType type { get; } = TaskType.FindLockbox;
protected override string name { get; } = "Find Lockbox";
public override bool CanActivate(int numPlayers)
{
int num = 0;
foreach (CharacterMaster readOnlyInstances in CharacterMaster.readOnlyInstancesList)
{
num += readOnlyInstances.inventory.GetItemCount(Items.TreasureCache);
}
return num > 0;
}
public override string GetDescription()
{
return "Find the Lockbox";
}
public override string GetWinMessage(int winningPlayer)
{
return GetStylizedName(winningPlayer) + " completed " + GetStylizedTaskName(name) + " by finding the lockbox first.";
}
protected override void SetHooks(int numPlayers)
{
base.SetHooks(numPlayers);
GlobalEventManager.OnInteractionsGlobal += ChestsOpened;
TasksPlugin.StartLockboxTask();
}
protected override void Unhook()
{
GlobalEventManager.OnInteractionsGlobal -= ChestsOpened;
base.Unhook();
}
private void ChestsOpened(Interactor interactor, IInteractable interactable, GameObject go)
{
int playerNum = 0;
for (int i = 0; i < totalNumberPlayers; i++)
{
if ((Object)(object)((Component)TasksPlugin.GetPlayerCharacterMaster(i).GetBody()).GetComponent<Interactor>() == (Object)(object)interactor)
{
playerNum = i;
}
}
if (Object.op_Implicit((Object)(object)((go != null) ? go.GetComponent<ChestBehavior>() : null)) && ((Object)go).name.Contains("Lockbox"))
{
CompleteTask(playerNum);
}
}
}
internal class GetLow : Task
{
private float[] lowPercents;
public override TaskType type { get; } = TaskType.GetLow;
protected override string name { get; } = "Get Low";
public override bool CanActivate(int numPlayers)
{
return numPlayers > 1;
}
public override string GetDescription()
{
return "Get to the lowest life. No dying.";
}
public override string GetWinMessage(int winningPlayer)
{
return GetStylizedName(winningPlayer) + " completed " + GetStylizedTaskName(name) + " by getting down to " + GetStylizedTaskWinStat(lowPercents[winningPlayer].ToString("F2")) + "% hp.";
}
protected override void SetHooks(int numPlayers)
{
Debug.Log((object)$"Set Hooks in GetLow. {numPlayers} players");
base.SetHooks(numPlayers);
GlobalEventManager.onServerDamageDealt += OnDamage;
lowPercents = new float[numPlayers];
Reset();
}
protected override void StageEnd()
{
base.StageEnd();
Evaluate();
Reset();
}
protected override void Unhook()
{
GlobalEventManager.onServerDamageDealt -= OnDamage;
base.Unhook();
}
private void OnDamage(DamageReport report)
{
if (report == null || report.victimMaster == null || report.victim == null || report.victimMaster.playerCharacterMasterController == null)
{
return;
}
int playerNumber = TasksPlugin.GetPlayerNumber(report.victimMaster);
float num = 100f * (report.victim.health + report.victim.shield) / report.victim.fullCombinedHealth;
if (num > 0f)
{
if (num < lowPercents[playerNumber])
{
lowPercents[playerNumber] = num;
UpdateProgress();
}
}
else
{
lowPercents[playerNumber] = 101f;
UpdateProgress();
}
}
protected void UpdateProgress()
{
for (int i = 0; i < progress.Length; i++)
{
progress[i] = (100f - lowPercents[i]) / 100f;
}
base.UpdateProgress(progress);
}
private void Evaluate()
{
float num = 100f;
int playerNum = 0;
for (int i = 0; i < lowPercents.Length; i++)
{
if (lowPercents[i] < num)
{
num = lowPercents[i];
playerNum = i;
}
}
CompleteTask(playerNum);
}
private void Reset()
{
if (lowPercents != null)
{
for (int i = 0; i < lowPercents.Length; i++)
{
lowPercents[i] = 100f;
}
ResetProgress();
}
}
}
internal class GetLucky : Task
{
private bool active = false;
public override TaskType type { get; } = TaskType.GetLucky;
protected override string name { get; } = "Get Lucky";
public override bool CanActivate(int numPlayers)
{
return true;
}
public override string GetDescription()
{
return "Be the luckiest.";
}
public override string GetWinMessage(int winningPlayer)
{
return GetStylizedName(winningPlayer) + " completed " + GetStylizedTaskName(name) + " by getting " + GetStylizedTaskWinStat("lucky") + ".";
}
protected override void SetHooks(int numPlayers)
{
Debug.Log((object)$"Set hooks in GetLucky. {numPlayers} players");
base.SetHooks(numPlayers);
active = true;
}
protected override void StageEnd()
{
base.StageEnd();
Evaluate();
}
protected override void Unhook()
{
base.Unhook();
}
private void Evaluate()
{
int playerNum = Random.Range(0, totalNumberPlayers);
if (totalNumberPlayers == 1)
{
playerNum = Random.Range(0, 4);
}
if (Object.op_Implicit((Object)(object)TasksPlugin.instance))
{
((MonoBehaviour)TasksPlugin.instance).StartCoroutine(RollEvent(playerNum));
}
}
private string GetRollMessage()
{
WeightedSelection<string> val = new WeightedSelection<string>(8);
val.AddChoice("Rolling...", 1f);
val.AddChoice("Who's going to be the lucky one?", 1f);
val.AddChoice("Feeling lucky?", 1f);
val.AddChoice("Choosing the winner. Stand by.", 1f);
val.AddChoice("Scratching the lottery ticket.", 1f);
val.AddChoice("Rolling for the winner.", 1f);
val.AddChoice("Flipping a coin. Call it in the air.", 1f);
val.AddChoice("Rigging the draw. Please wait.", 1f);
return "<style=cEvent>" + val.Evaluate(Random.value) + "</style>";
}
private string GetWinFlavourMessage(string playerName)
{
WeightedSelection<string> val = new WeightedSelection<string>(8);
playerName = GetStylizedTaskName(playerName);
val.AddChoice(playerName + " won!", 1f);
val.AddChoice(playerName + " was the lucky one!", 1f);
val.AddChoice("Congrats, " + playerName + ".", 1f);
val.AddChoice("The winner is " + playerName + ".", 1f);
val.AddChoice("Your winner was " + playerName + ".", 1f);
val.AddChoice("Congrats, " + playerName + ".", 1f);
val.AddChoice("It's your lucky day, " + playerName + ".", 1f);
val.AddChoice("Enjoy your prize, " + playerName + ".", 1f);
val.AddChoice(playerName + " won, but it was rigged from the start.", 1f);
val.AddChoice("Everyone loses except for " + playerName + ".", 1f);
return val.Evaluate(Random.value);
}
private IEnumerator RollEvent(int playerNum)
{
ChatMessage.Send(GetRollMessage());
yield return (object)new WaitForSeconds(1.5f);
string name = "Nobody";
if (totalNumberPlayers > 1 || playerNum == 0)
{
name = Util.GetBestMasterName(TasksPlugin.GetPlayerCharacterMaster(playerNum));
CompleteTask(playerNum);
}
ChatMessage.Send(GetWinFlavourMessage(name));
}
}
internal class HealingItem : Task
{
public override TaskType type { get; } = TaskType.HealingItem;
protected override string name { get; } = "Find a Healing Item";
public override string GetDescription()
{
return "Find a healing item";
}
public override string GetWinMessage(int winningPlayer)
{
return GetStylizedName(winningPlayer) + " completed " + GetStylizedTaskName(name) + " by finding a " + GetStylizedTaskWinStat("healing") + " item first.";
}
protected override void SetHooks(int numPlayers)
{
Debug.Log((object)$"Set Hooks in HealingItem. {numPlayers} players");
base.SetHooks(numPlayers);
Inventory.onServerItemGiven += OnItemGained;
}
protected override void Unhook()
{
Inventory.onServerItemGiven -= OnItemGained;
base.Unhook();
}
private void OnItemGained(Inventory inventory, ItemIndex item, int count)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
if (!ItemCatalog.GetItemDef(item).ContainsTag((ItemTag)2))
{
return;
}
for (int i = 0; i < totalNumberPlayers; i++)
{
if ((Object)(object)TasksPlugin.GetPlayerCharacterMaster(i).inventory == (Object)(object)inventory)
{
CompleteTask(i);
break;
}
}
}
}
internal class KillStreak : Task
{
private int[] bestStreaks;
private int[] currentStreaks;
public override TaskType type { get; } = TaskType.KillStreak;
protected override string name { get; } = "Kill Streak";
public override bool CanActivate(int numPlayers)
{
return numPlayers > 1;
}
public override string GetDescription()
{
return "Most kills without getting hit";
}
public override string GetWinMessage(int winningPlayer)
{
return GetStylizedName(winningPlayer) + " completed " + GetStylizedTaskName(name) + " with a streak of " + GetStylizedTaskWinStat(bestStreaks[winningPlayer].ToString()) + ".";
}
protected override void SetHooks(int numPlayers)
{
Debug.Log((object)$"Set Hooks in KillStreak. {numPlayers} players");
base.SetHooks(numPlayers);
GlobalEventManager.onServerDamageDealt += OnDamage;
GlobalEventManager.onCharacterDeathGlobal += OnKill;
bestStreaks = new int[numPlayers];
currentStreaks = new int[numPlayers];
Reset();
}
protected override void StageEnd()
{
base.StageEnd();
Evaluate();
Reset();
}
protected override void Unhook()
{
GlobalEventManager.onServerDamageDealt -= OnDamage;
GlobalEventManager.onCharacterDeathGlobal -= OnKill;
base.Unhook();
}
private void OnDamage(DamageReport report)
{
if (report == null || report.victimMaster == null || report.victimMaster.playerCharacterMasterController == null)
{
return;
}
if (report.damageInfo.attacker == null && !report.isFallDamage)
{
Debug.Log((object)"KillStreak. Self damage ignore.");
return;
}
int playerNumber = TasksPlugin.GetPlayerNumber(report.victimMaster);
if (playerNumber > -1)
{
currentStreaks[playerNumber] = 0;
}
}
private void OnKill(DamageReport report)
{
if (report != null && report.attackerMaster != null && report.attackerMaster.playerCharacterMasterController != null)
{
int playerNumber = TasksPlugin.GetPlayerNumber(report.attackerMaster);
if (playerNumber > -1)
{
currentStreaks[playerNumber]++;
UpdateStreaks(playerNumber);
}
}
}
private void UpdateStreaks(int playerNum)
{
if (currentStreaks[playerNum] > bestStreaks[playerNum])
{
Debug.Log((object)$"Player {playerNum} improved their streak. {bestStreaks[playerNum]} -> {currentStreaks[playerNum]}");
bestStreaks[playerNum] = currentStreaks[playerNum];
UpdateProgress();
}
}
protected void UpdateProgress()
{
int num = 0;
for (int i = 0; i < bestStreaks.Length; i++)
{
if (bestStreaks[i] > num)
{
num = bestStreaks[i];
}
}
if (num > 0)
{
for (int j = 0; j < progress.Length; j++)
{
progress[j] = (float)bestStreaks[j] / (float)num;
}
}
else
{
for (int k = 0; k < progress.Length; k++)
{
progress[k] = 0f;
}
}
base.UpdateProgress(progress);
}
private void Evaluate()
{
int num = 0;
int num2 = 0;
for (int i = 0; i < bestStreaks.Length; i++)
{
if (bestStreaks[i] > num2)
{
num2 = bestStreaks[i];
num = i;
}
}
Debug.Log((object)$"Player {num} won with a streak of {num2}");
CompleteTask(num);
}
private void Reset()
{
if (bestStreaks != null && currentStreaks != null)
{
for (int i = 0; i < bestStreaks.Length; i++)
{
bestStreaks[i] = 0;
currentStreaks[i] = 0;
}
ResetProgress();
}
}
}
internal class MostDistance : Task
{
private double[] startDistances;
private double winnerDist;
protected new string description { get; } = "Most distance wins";
public override TaskType type { get; } = TaskType.MostDistance;
protected override string name { get; } = "Most Distance";
public override bool CanActivate(int numPlayers)
{
return numPlayers > 1;
}
public override string GetDescription()
{
return description;
}
public override string GetWinMessage(int winningPlayer)
{
return GetStylizedName(winningPlayer) + " completed " + GetStylizedTaskName(name) + " by covering the most (" + GetStylizedTaskWinStat(winnerDist.ToString("F2")) + "m) distance.";
}
protected override void SetHooks(int numPlayers)
{
Debug.Log((object)$"Set Hooks in MostDistance. {numPlayers} players");
base.SetHooks(numPlayers);
if (startDistances == null || startDistances.Length != numPlayers)
{
startDistances = new double[numPlayers];
}
for (int i = 0; i < startDistances.Length; i++)
{
StatSheet currentStats = TasksPlugin.GetPlayerCharacterMaster(i).playerStatsComponent.currentStats;
startDistances[i] = currentStats.GetStatValueDouble(StatDef.totalDistanceTraveled);
}
}
protected override void StageEnd()
{
base.StageEnd();
Evaluate();
}
protected override void Unhook()
{
base.Unhook();
}
private void Evaluate()
{
double num = 0.0;
int num2 = 0;
for (int i = 0; i < startDistances.Length; i++)
{
StatSheet currentStats = TasksPlugin.GetPlayerCharacterMaster(i).playerStatsComponent.currentStats;
double statValueDouble = currentStats.GetStatValueDouble(StatDef.totalDistanceTraveled);
double num3 = statValueDouble - startDistances[i];
if (num3 > num)
{
num = num3;
num2 = i;
}
Chat.AddMessage($"MostDist({i}): {startDistances[i]} -> {statValueDouble} = {num3}. Winner: {num2} with {num}");
}
winnerDist = num;
CompleteTask(num2);
}
}
internal class NoJump : Task
{
private bool[] playerFailed;
private int numPlayersFailed;
public override TaskType type { get; } = TaskType.NoJump;
protected override string name { get; } = "No Jump";
public override string GetDescription()
{
return "Don't jump";
}
public override string GetWinMessage(int winningPlayer)
{
return GetStylizedName(winningPlayer) + " completed " + GetStylizedTaskName(name) + " by being the last to jump.";
}
public override bool CanActivate(int numPlayers)
{
return numPlayers > 1;
}
protected override void SetHooks(int numPlayers)
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Expected O, but got Unknown
Debug.Log((object)$"Set Hooks in NoJump. {numPlayers} players");
base.SetHooks(numPlayers);
playerFailed = new bool[numPlayers];
Reset();
GenericCharacterMain.ApplyJumpVelocity += new hook_ApplyJumpVelocity(OnJump);
}
protected override void StageEnd()
{
base.StageEnd();
Evaluate();
Reset();
}
protected override void Unhook()
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Expected O, but got Unknown
GenericCharacterMain.ApplyJumpVelocity -= new hook_ApplyJumpVelocity(OnJump);
base.Unhook();
}
private void Evaluate()
{
if (totalNumberPlayers - numPlayersFailed <= 1)
{
return;
}
for (int i = 0; i < playerFailed.Length; i++)
{
if (!playerFailed[i])
{
UpdateProgressMultiWinner();
CompleteTask(i);
}
}
}
private void UpdateProgress()
{
for (int i = 0; i < progress.Length; i++)
{
progress[i] = ((!playerFailed[i]) ? (numPlayersFailed / (totalNumberPlayers - 1)) : 0);
}
base.UpdateProgress(progress);
}
private void UpdateProgressMultiWinner()
{
for (int i = 0; i < progress.Length; i++)
{
progress[i] = ((!playerFailed[i]) ? 1 : 0);
}
base.UpdateProgress(progress);
}
private void OnJump(orig_ApplyJumpVelocity orig, CharacterMotor characterMotor, CharacterBody characterBody, float horizontalBonus, float verticalBonus, bool vault = false)
{
orig.Invoke(characterMotor, characterBody, horizontalBonus, verticalBonus, vault);
int playerNumber = TasksPlugin.GetPlayerNumber(characterBody.master);
if (playerNumber < 0 || playerFailed[playerNumber])
{
return;
}
Debug.Log((object)$"Player {playerNumber} failed NoJump");
playerFailed[playerNumber] = true;
numPlayersFailed++;
UpdateProgress();
if (numPlayersFailed < totalNumberPlayers - 1)
{
return;
}
for (int i = 0; i < playerFailed.Length; i++)
{
if (!playerFailed[i])
{
CompleteTask(i);
break;
}
}
}
private void Reset()
{
if (playerFailed != null)
{
for (int i = 0; i < playerFailed.Length; i++)
{
playerFailed[i] = false;
}
ResetProgress();
}
}
}
internal class OpenChests : Task
{
private int[] chestsOpened;
private int numToOpen = 5;
protected new string description { get; } = "First to open 5 chests wins (multishops count too)";
public override TaskType type { get; } = TaskType.OpenChests;
protected override string name { get; } = "Open 5 Chests";
public override string GetDescription()
{
return description;
}
public override string GetWinMessage(int winningPlayer)
{
return GetStylizedName(winningPlayer) + " completed " + GetStylizedTaskName(name) + " by opening " + GetStylizedTaskWinStat(numToOpen.ToString()) + " chests first.";
}
protected override void SetHooks(int numPlayers)
{
Debug.Log((object)$"Set Hooks in OpenChests. {numPlayers} players");
base.SetHooks(numPlayers);
GlobalEventManager.OnInteractionsGlobal += ChestsOpened;
chestsOpened = new int[numPlayers];
Reset();
}
protected override void Unhook()
{
GlobalEventManager.OnInteractionsGlobal -= ChestsOpened;
Reset();
base.Unhook();
}
protected void UpdateProgress()
{
for (int i = 0; i < progress.Length; i++)
{
progress[i] = (float)chestsOpened[i] / (float)numToOpen;
}
base.UpdateProgress(progress);
}
private void ChestsOpened(Interactor interactor, IInteractable interactable, GameObject go)
{
int num = 0;
for (int i = 0; i < chestsOpened.Length; i++)
{
if ((Object)(object)((Component)TasksPlugin.GetPlayerCharacterMaster(i).GetBody()).GetComponent<Interactor>() == (Object)(object)interactor)
{
num = i;
}
}
if (Object.op_Implicit((Object)(object)((go != null) ? go.GetComponent<ChestBehavior>() : null)))
{
chestsOpened[num]++;
}
else if (Object.op_Implicit((Object)(object)((go != null) ? go.GetComponent<ShopTerminalBehavior>() : null)) && ((Object)go).name.Contains("MultiShop"))
{
chestsOpened[num]++;
}
UpdateProgress();
if (IsComplete(num))
{
CompleteTask(num);
}
}
protected override bool IsComplete(int playerNum)
{
return chestsOpened[playerNum] >= numToOpen;
}
private void Reset()
{
if (chestsOpened != null)
{
for (int i = 0; i < chestsOpened.Length; i++)
{
chestsOpened[i] = 0;
}
ResetProgress();
}
}
}
internal class OrderedSkills : Task
{
private SkillSlot[] order;
private int[] whereInOrder;
protected new string description { get; } = "Use skills in order";
public override TaskType type { get; } = TaskType.OrderedSkills;
protected override string name { get; } = "Ordered Skills";
public override string GetDescription()
{
return description;
}
public override string GetWinMessage(int winningPlayer)
{
return GetStylizedName(winningPlayer) + " completed " + GetStylizedTaskName(name) + " by using their abilities in order.";
}
protected override void SetHooks(int numPlayers)
{
Debug.Log((object)$"Set Hooks in OrderedSkills. {numPlayers} players");
base.SetHooks(numPlayers);
SkillSlot[] array = new SkillSlot[4];
RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
order = (SkillSlot[])(object)array;
whereInOrder = new int[numPlayers];
Reset();
TasksPlugin.OnAbilityUsed += AbilityUsed;
}
protected override void Unhook()
{
TasksPlugin.OnAbilityUsed -= AbilityUsed;
Reset();
base.Unhook();
}
private void AbilityUsed(int playerNum, SkillSlot slot)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Invalid comparison between I4 and Unknown
int num = whereInOrder[playerNum];
if ((int)order[num] == (int)slot)
{
whereInOrder[playerNum]++;
if (whereInOrder[playerNum] >= order.Length)
{
CompleteTask(playerNum);
}
}
else
{
whereInOrder[playerNum] = 0;
}
}
private void Reset()
{
if (whereInOrder != null)
{
for (int i = 0; i < whereInOrder.Length; i++)
{
whereInOrder[i] = 0;
}
}
}
}
internal class PreonEvent : Task
{
private int[] kills;
private int preonIndex = -1;
protected new string description { get; } = "Most Preon kills wins";
public override TaskType type { get; } = TaskType.PreonEvent;
protected override string name { get; } = "Preon Event";
public override bool CanActivate(int numPlayers)
{
return numPlayers > 1;
}
public override string GetDescription()
{
return description;
}
public override string GetWinMessage(int winningPlayer)
{
return GetStylizedName(winningPlayer) + " completed " + GetStylizedTaskName(name) + " by getting " + GetStylizedTaskWinStat(kills[winningPlayer].ToString()) + " kills with the Preon Accumulator.";
}
protected override void SetHooks(int numPlayers)
{
Debug.Log((object)$"Set Hooks in PreonEvent. {numPlayers} players");
base.SetHooks(numPlayers);
preonIndex = ProjectileCatalog.FindProjectileIndex("BeamSphere");
GlobalEventManager.onCharacterDeathGlobal += OnKill;
if (kills == null || kills.Length != numPlayers)
{
kills = new int[numPlayers];
}
Reset();
TasksPlugin.StartPreonEvent();
}
protected override void StageEnd()
{
base.StageEnd();
Evaluate();
TasksPlugin.EndPreonEvent();
Reset();
}
protected override void Unhook()
{
GlobalEventManager.onCharacterDeathGlobal -= OnKill;
base.Unhook();
}
protected void UpdateProgress()
{
int num = 0;
for (int i = 0; i < kills.Length; i++)
{
if (kills[i] > num)
{
num = kills[i];
}
}
if (num > 0)
{
for (int j = 0; j < progress.Length; j++)
{
progress[j] = (float)kills[j] / (float)num;
}
}
else
{
for (int k = 0; k < progress.Length; k++)
{
progress[k] = 0f;
}
}
base.UpdateProgress(progress);
}
public void OnKill(DamageReport damageReport)
{
if (damageReport != null && damageReport.attackerMaster != null && damageReport.attackerMaster.playerCharacterMasterController != null)
{
int playerNumber = TasksPlugin.GetPlayerNumber(damageReport.attackerMaster);
if (ProjectileCatalog.GetProjectileIndex(damageReport.damageInfo.inflictor) == preonIndex)
{
kills[playerNumber]++;
UpdateProgress();
}
}
}
private void Evaluate()
{
int num = 0;
int num2 = 0;
for (int i = 0; i < kills.Length; i++)
{
if (kills[i] > num)
{
num = kills[i];
num2 = i;
}
}
Chat.AddMessage($"Player {num2} won Preon event with {num} kills");
CompleteTask(num2);
}
private void Reset()
{
if (kills != null)
{
for (int i = 0; i < kills.Length; i++)
{
kills[i] = 0;
}
ResetProgress();
}
}
}
internal class QuickDraw : Task
{
public override TaskType type { get; } = TaskType.QuickDraw;
protected override string name { get; } = "Quick Draw";
public override string GetDescription()
{
return "Kill an enemy within 3s of spawning.";
}
public override string GetWinMessage(int winningPlayer)
{
return GetStylizedName(winningPlayer) + " completed " + GetStylizedTaskName(name) + " by killing an enemy within " + GetStylizedTaskWinStat("3") + "s of spawning.";
}
protected override void SetHooks(int numPlayers)
{
Debug.Log((object)$"Set Hooks in KillStreak. {numPlayers} players");
base.SetHooks(numPlayers);
GlobalEventManager.onCharacterDeathGlobal += OnKill;
}
protected override void Unhook()
{
GlobalEventManager.onCharacterDeathGlobal -= OnKill;
base.Unhook();
}
private void OnKill(DamageReport report)
{
//IL_002e: 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)
if (report != null && report.attackerMaster != null && report.attackerMaster.playerCharacterMasterController != null)
{
float num = FixedTimeStamp.now.t - report.victimBody.localStartTime.t;
if (num < 3f)
{
int playerNumber = TasksPlugin.GetPlayerNumber(report.attackerMaster);
CompleteTask(playerNumber);
}
}
}
}
internal class RewardBuilder
{
public static Reward CreateRandomReward()
{
//IL_0068: 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_0078: Unknown result type (might be due to invalid IL or missing references)
WeightedSelection<RewardType> val = new WeightedSelection<RewardType>(8);
val.AddChoice(RewardType.Item, 2f);
val.AddChoice(RewardType.TempItem, 1f);
val.AddChoice(RewardType.Command, 0.5f);
val.AddChoice(RewardType.Drone, 0.5f);
RewardType rewardType = val.Evaluate(Random.value);
List<PickupIndex> list = Run.instance.smallChestDropTierSelector.Evaluate(Random.value);
PickupIndex item = Run.instance.treasureRng.NextElementUniform<PickupIndex>(list);
string randomDronePath = GetRandomDronePath();
Reward result = new Reward(rewardType, item, (rewardType != RewardType.TempItem) ? 1 : 5, _temporary: false, 100, 100, randomDronePath);
return result;
}
public static string GetRandomDronePath()
{
WeightedSelection<string> val = new WeightedSelection<string>(8);
val.AddChoice("iscBrokenDrone1", 4f);
val.AddChoice("iscBrokenDrone2", 4f);
val.AddChoice("iscBrokenTurret1", 3f);
val.AddChoice("iscBrokenFlameDrone", 1f);
val.AddChoice("iscBrokenEmergencyDrone", 1f);
val.AddChoice("iscBrokenMissileDrone", 0.5f);
return val.Evaluate(Random.value);
}
public static string GetDroneTexturePath(string spawnCardName)
{
return spawnCardName switch
{
"iscBrokenDrone1" => "Textures/BodyIcons/texDrone1Icon",
"iscBrokenDrone2" => "Textures/BodyIcons/texDrone2Icon",
"iscBrokenTurret1" => "Textures/BodyIcons/texTurret1Icon",
"iscBrokenFlameDrone" => "Textures/BodyIcons/FlameDroneBody",
"iscBrokenEmergencyDrone" => "Textures/BodyIcons/EmergencyDroneBody",
"iscBrokenMissileDrone" => "Textures/BodyIcons/texMissileDroneIcon",
_ => "Textures/BodyIcons/texDrone1Icon",
};
}
public static void GivePlayerDrone(int playerNum, string droneSpawnCardName)
{
//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_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: 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_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Expected O, but got Unknown
//IL_0064: Expected O, but got Unknown
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Expected O, but got Unknown
CharacterBody body = TasksPlugin.GetPlayerCharacterMaster(playerNum).GetBody();
GameObject val = DirectorCore.instance.TrySpawnObject(new DirectorSpawnRequest(Resources.Load<SpawnCard>("SpawnCards/InteractableSpawnCard/" + droneSpawnCardName), new DirectorPlacementRule
{
placementMode = (PlacementMode)3,
position = body.transform.position + new Vector3(1f, 0f, 0f)
}, new Xoroshiro128Plus(0uL)));
PurchaseInteraction component = val.GetComponent<PurchaseInteraction>();
component.cost = 0;
Interactor component2 = ((Component)body).GetComponent<Interactor>();
if (Object.op_Implicit((Object)(object)component2))
{
component.OnInteractionBegin(component2);
}
}
}
public struct Reward
{
public RewardType type;
public PickupIndex item;
public int numItems;
public bool temporary;
public int gold;
public int xp;
public string dronePath;
public Reward(RewardType _type, PickupIndex _item, int _numItems, bool _temporary, int _gold, int _xp, string _path)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
type = _type;
item = _item;
numItems = _numItems;
temporary = _temporary;
gold = _gold;
xp = _xp;
dronePath = _path;
}
public override string ToString()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
return $"{type:g}, {item:g}";
}
}
public struct TempItem
{
public PickupIndex item;
public int count;
public TempItem(PickupIndex _item, int _count)
{
//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)
item = _item;
count = _count;
}
}
public enum RewardType
{
Item,
TempItem,
Command,
Gold,
Xp,
Drone
}
public class TaskInfo : MessageBase
{
public int taskType;
public string description;
public bool completed;
public int index;
public int total;
public Reward reward;
public override void Serialize(NetworkWriter writer)
{
writer.Write(taskType);
writer.Write(description);
writer.Write(completed);
writer.Write(index);
writer.Write(total);
writer.Write((int)reward.type);
writer.Write(reward.item.value);
writer.Write(reward.numItems);
writer.Write(reward.temporary);
writer.Write(reward.gold);
writer.Write(reward.xp);
writer.Write(reward.dronePath);
}
public override void Deserialize(NetworkReader reader)
{
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
taskType = reader.ReadInt32();
description = reader.ReadString();
completed = reader.ReadBoolean();
index = reader.ReadInt32();
total = reader.ReadInt32();
int type = reader.ReadInt32();
int num = reader.ReadInt32();
int numItems = reader.ReadInt32();
bool temporary = reader.ReadBoolean();
int gold = reader.ReadInt32();
int xp = reader.ReadInt32();
string path = reader.ReadString();
PickupIndex item = default(PickupIndex);
((PickupIndex)(ref item))..ctor(num);
reward = new Reward((RewardType)type, item, numItems, temporary, gold, xp, path);
}
public TaskInfo(int _type, string _description, bool _completed, int _index, int _total, Reward _reward)
{
taskType = _type;
description = _description;
completed = _completed;
index = _index;
total = _total;
reward = _reward;
}
public TaskInfo(NetworkReader reader)
{
((MessageBase)this).Deserialize(reader);
}
public override string ToString()
{
return $"TaskInfo: {taskType}, {description}, {completed}, {index}/{total}";
}
}
public class ProgressInfo : MessageBase
{
public int taskIndex;
private float myProgress;
private float rivalProgress;
public ProgressInfo(int _taskIndex, float _myProgress, float _rivalProgress)
{
taskIndex = _taskIndex;
myProgress = _myProgress;
rivalProgress = _rivalProgress;
}
public ProgressInfo(int _taskIndex, int _myProgress, int _rivalProgress)
{
taskIndex = _taskIndex;
myProgress = _myProgress;
rivalProgress = _rivalProgress;
}
public float GetMyProgress()
{
return myProgress;
}
public float GetRivalProgress()
{
return rivalProgress;
}
public override void Serialize(NetworkWriter writer)
{
writer.Write(taskIndex);
writer.Write(myProgress);
writer.Write(rivalProgress);
}
public override void Deserialize(NetworkReader reader)
{
taskIndex = reader.ReadInt32();
myProgress = reader.ReadSingle();
rivalProgress = reader.ReadSingle();
}
}
public class TaskCompletionInfo : MessageBase
{
public int taskType;
public string winnerName;
public TaskCompletionInfo(int _taskType, string _winnerName)
{
taskType = _taskType;
winnerName = _winnerName;
}
public override void Serialize(NetworkWriter writer)
{
writer.Write(taskType);
writer.Write(winnerName);
}
public override void Deserialize(NetworkReader reader)
{
taskType = reader.ReadInt32();
winnerName = reader.ReadString();
}
}
internal class StartTeleporter : Task
{
private float soloTimer;
private float soloTimeAmountSec = 90f;
private bool hasFailed = false;
private bool succeeded = false;
protected new string description { get; } = "Better be First";
public override TaskType type { get; } = TaskType.StartTele;
protected override string name { get; } = "Activate the Teleporter";
public override bool CanActivate(int numPlayers)
{
return true;
}
public override string GetDescription()
{
return description;
}
public override string GetWinMessage(int winningPlayer)
{
if (winningPlayer < 0)
{
return "You failed " + GetStylizedTaskName(name) + " by not getting to the " + GetStylizedTaskWinStat("teleporter") + " in " + GetStylizedTaskWinStat(soloTimeAmountSec.ToString()) + " seconds.";
}
return GetStylizedName(winningPlayer) + " completed " + GetStylizedTaskName(name) + " by triggering the " + GetStylizedTaskWinStat("teleporter") + " first.";
}
protected override void SetHooks(int numPlayers)
{
Debug.Log((object)$"Set Hooks in StartTele. {numPlayers} players");
base.SetHooks(numPlayers);
GlobalEventManager.OnInteractionsGlobal += OnInteraction;
if (numPlayers == 1)
{
StartSolo();
}
}
protected override void Unhook()
{
GlobalEventManager.OnInteractionsGlobal -= OnInteraction;
base.Unhook();
}
private void OnInteraction(Interactor interactor, IInteractable interactable, GameObject go)
{
int playerNum = 0;
for (int i = 0; i < totalNumberPlayers; i++)
{
if ((Object)(object)((Component)TasksPlugin.GetPlayerCharacterMaster(i).GetBody()).GetComponent<Interactor>() == (Object)(object)interactor)
{
playerNum = i;
}
}
if (Object.op_Implicit((Object)(object)((go != null) ? go.GetComponent<TeleporterInteraction>() : null)))
{
Evaluate(playerNum);
}
}
private void StartSolo()
{
if (Object.op_Implicit((Object)(object)TasksPlugin.instance))
{
((MonoBehaviour)TasksPlugin.instance).StartCoroutine(Countdown());
}
}
private IEnumerator Countdown()
{
hasFailed = false;
succeeded = false;
soloTimer = soloTimeAmountSec;
for (int i = 0; (float)i < soloTimeAmountSec; i++)
{
yield return (object)new WaitForSeconds(1f);
soloTimer -= 1f;
UpdateProgressSolo();
}
hasFailed = true;
if (!succeeded)
{
CompleteTask(-1);
}
}
private void Evaluate(int playerNum)
{
if (totalNumberPlayers > 1)
{
CompleteTask(playerNum);
}
else if (!hasFailed)
{
succeeded = true;
CompleteTask(playerNum);
}
}
private void UpdateProgressSolo()
{
if (succeeded)
{
progress[0] = 0f;
}
else
{
progress[0] = Mathf.Max(0f, soloTimer / soloTimeAmountSec);
}
base.UpdateProgress(progress);
}
}
internal class StayInAir : Task
{
private CharacterMotor[] motors;
private CharacterBody[] bodies;
private float[] timeInAir;
private float timeToStayInAir;
protected new string description { get; } = "Stay airborne for 10 seconds";
public override TaskType type { get; } = TaskType.StayInAir;
protected override string name { get; } = "Stay Airborne";
public override string GetDescription()
{
return $"Stay in the air for {Math.Round(timeToStayInAir, 1)} seconds";
}
public override string GetWinMessage(int winningPlayer)
{
return GetStylizedName(winningPlayer) + " completed " + GetStylizedTaskName(name) + " by staying in the air for " + GetStylizedTaskWinStat(timeToStayInAir.ToString("0.00")) + "s.";
}
protected override void SetHooks(int numPlayers)
{
Debug.Log((object)$"Set Hooks in Stay Airborne. {numPlayers} players");
base.SetHooks(numPlayers);
timeToStayInAir = 2f + Run.instance.difficultyCoefficient;
if (timeInAir == null || timeInAir.Length != numPlayers)
{
timeInAir = new float[numPlayers];
for (int i = 0; i < timeInAir.Length; i++)
{
timeInAir[i] = 0f;
}
}
if (motors == null || motors.Length != numPlayers)
{
motors = (CharacterMotor[])(object)new CharacterMotor[numPlayers];
}
if (bodies == null || motors.Length != numPlayers)
{
bodies = (CharacterBody[])(object)new CharacterBody[numPlayers];
}
SetupBodies();
RoR2Application.onFixedUpdate += AirborneFixedUpdate;
}
protected override void Unhook()
{
RoR2Application.onFixedUpdate -= AirborneFixedUpdate;
Reset();
base.Unhook();
}
protected void UpdateProgress()
{
if (timeInAir != null && progress != null)
{
for (int i = 0; i < progress.Length; i++)
{
progress[i] = timeInAir[i] / timeToStayInAir;
}
base.UpdateProgress(progress);
}
}
private void AirborneFixedUpdate()
{
UpdateProgress();
for (int i = 0; i < timeInAir.Length; i++)
{
timeInAir[i] = ((Object.op_Implicit((Object)(object)motors[i]) && !motors[i].isGrounded && !Object.op_Implicit((Object)(object)bodies[i].currentVehicle)) ? (timeInAir[i] + Time.fixedDeltaTime) : 0f);
if (IsComplete(i))
{
CompleteTask(i);
Reset();
}
}
}
protected override bool IsComplete(int playerNum)
{
return timeInAir[playerNum] >= timeToStayInAir;
}
private void Reset()
{
UpdateProgress();
if (timeInAir != null)
{
for (int i = 0; i < timeInAir.Length; i++)
{
timeInAir[i] = 0f;
}
ResetProgress();
}
}
private void SetupBodies()
{
for (int i = 0; i < motors.Length; i++)
{
CharacterMaster playerCharacterMaster = TasksPlugin.GetPlayerCharacterMaster(i);
bodies[i] = playerCharacterMaster.GetBody();
motors[i] = playerCharacterMaster.GetBody().characterMotor;
}
}
}
public enum TaskType
{
Base,
AirKills,
DamageMultiple,
DamageInTime,
StayInAir,
BiggestHit,
MostDistance,
PreonEvent,
FarthestAway,
FailShrine,
OpenChests,
StartTele,
UsePrinters,
OrderedSkills,
BadSkill,
BabyDrone,
Die,
FindLockbox,
HealingItem,
NoJump,
VeryBest,
FewestElites,
GetLucky,
GetLow,
KillStreak,
QuickDraw,
FarKill,
FewElites
}
internal class Task
{
private static string myName = "SOLRUN_";
private static string myMod = "TASKS_";
protected static string thisClass = "BASE_TASK_";
protected int totalNumberPlayers;
protected float[] progress;
private bool taskActive = false;
protected string description { get; } = "Base description";
public virtual TaskType type { get; } = TaskType.Base;
protected virtual string name { get; } = "Base Task";
public static event Action<TaskType, int, string> OnCompletion;
public static event Action<TaskType, float[]> OnUpdateProgress;
public Task()
{
OnInstall();
}
protected virtual void SetupName()
{
}
public virtual string GetDescription()
{
return description;
}
public virtual void OnInstall()
{
Run.onRunDestroyGlobal += RunOver;
TasksPlugin.OnActivate += Activate;
TasksPlugin.OnDeactivate += Deactivate;
TasksPlugin.OnCancelAll += CancelAllTasks;
}
public virtual void OnUninstall()
{
Run.onRunDestroyGlobal -= RunOver;
TasksPlugin.OnActivate -= Activate;
TasksPlugin.OnDeactivate -= Deactivate;
TasksPlugin.OnCancelAll -= CancelAllTasks;
}
protected virtual void UpdateProgress(float[] progress)
{
if (taskActive)
{
Task.OnUpdateProgress?.Invoke(type, progress);
}
}
protected void ResetProgress()
{
TasksPlugin instance = TasksPlugin.instance;
if (instance != null)
{
((MonoBehaviour)instance).StartCoroutine(ResetProgressInTime());
}
}
private IEnumerator ResetProgressInTime()
{
yield return (object)new WaitForSeconds(4f);
if (progress != null)
{
for (int i = 0; i < progress.Length; i++)
{
progress[i] = 0f;
}
if (taskActive)
{
Task.OnUpdateProgress?.Invoke(type, progress);
}
else
{
Debug.Log((object)$"{type:g} was inactive. Don't update progress");
}
}
}
public virtual string GetWinMessage(int winningPlayer)
{
return GetStylizedName(winningPlayer) + " completed " + name;
}
protected string GetStylizedName(int playerNum)
{
return "<color=#ffffff>" + TasksPlugin.GetPlayerName(playerNum) + "</color>";
}
protected string GetStylizedTaskName(string taskName)
{
return "<style=cIsUtility>" + taskName + "</style>";
}
protected string GetStylizedTaskWinStat(string stat)
{
return "<style=cIsUtility>" + stat + "</style>";
}
protected virtual void CompleteTask(int playerNum)
{
Unhook();
Task.OnCompletion?.Invoke(type, playerNum, GetWinMessage(playerNum));
}
protected virtual bool IsComplete(int playerNum)
{
return false;
}
public virtual bool CanActivate(int numPlayers)
{
return true;
}
private void Activate(int id, int numPlayers)
{
if (id == (int)type)
{
totalNumberPlayers = numPlayers;
progress = new float[numPlayers];
SetHooks(numPlayers);
taskActive = true;
}
}
public void Deactivate(int id)
{
if (id == (int)type || id < 0)
{
taskActive = false;
StageEnd();
Unhook();
}
}
public void CancelAllTasks()
{
taskActive = false;
Unhook();
}
protected virtual void StageEnd()
{
}
protected virtual void SetHooks(int numPlayers)
{
}
protected virtual void Unhook()
{
}
private void RunOver(Run run)
{
Unhook();
OnUninstall();
}
}
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("com.Solrun.Tasks", "Tasks", "1.2.5")]
public sealed class TasksPlugin : BaseUnityPlugin
{
[CompilerGenerated]
private static class <>O
{
public static hook_OnCollisionEnter <0>__TurnOffCommand;
}
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static hook_OnSkillActivated <>9__48_0;
public static Func<string> <>9__65_1;
internal void <SetGameHooks>b__48_0(orig_OnSkillActivated orig, CharacterBody self, GenericSkill param)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
if (NetworkServer.active && self.isPlayerControlled)
{
int playerNumber = GetPlayerNumber(self.master);
SkillSlot arg = self.skillLocator.FindSkillSlot(param);
TasksPlugin.OnAbilityUsed?.Invoke(playerNumber, arg);
}
orig.Invoke(self, param);
}
internal string <CreateNotification>b__65_1()
{
return "Task Complete!";
}
}
public const string MODNAME = "Tasks";
public const string AUTHOR = "Solrun";
public const string GUID = "com.Solrun.Tasks";
public const string VERSION = "1.2.5";
public static TasksPlugin instance;
private static List<CharacterMaster> playerCharacterMasters;
private int totalNumPlayers = 0;
private int totalNumTasks;
public Reward[] rewards;
private List<TempItem>[] TempItemLists;
private EquipmentIndex[] preonEventEqCache;
private int[] stageStartTasks;
private int[] teleStartTasks;
private Task[] taskCopies;
private bool telePlaced = false;
public TaskInfo[] currentTasks;
public GameObject[] tasksUIObjects;
public RectTransform[] tasksUIRects;
public RectTransform[] rivalTasksUIRects;
private HUD hud;
private ObjectivePanelController panel;
private GameObject itemIconPrefabCopy;
private bool rectWasAlreadyNull = false;
private bool rivalRectWasAlreadyNull = false;
public static event Action<int, int> OnActivate;
public static event Action<int> OnDeactivate;
public static event Action OnCancelAll;
public static event Action<int> OnPopup;
public static event Action<int, SkillSlot> OnAbilityUsed;
public void InvokeOnPopup(int taskType)
{
TasksPlugin.OnPopup?.Invoke(taskType);
}
private void Awake()
{
Chat.AddMessage("Loaded Task plugin");
if (instance == null)
{
instance = this;
}
ConfigManager configManager = new ConfigManager();
ConfigManager.instance.SetConfigFile(((BaseUnityPlugin)this).Config);
ConfigManager.instance.Awake();
Task.OnCompletion += TaskCompletion;
Task.OnUpdateProgress += UpdateTaskProgress;
Run.onRunStartGlobal += GameSetup;
SetupNetworking();
SetGameHooks();
}
private void Start()
{
}
public void Update()
{
if (0 == 0)
{
}
}
private void GameSetup(Run run)
{
totalNumTasks = Enum.GetNames(typeof(TaskType)).Length;
rewards = new Reward[totalNumTasks];
Debug.Log((object)$"Tasks mod: Number of players: {run.participatingPlayerCount} Living Players: {run.livingPlayerCount}");
totalNumPlayers = run.participatingPlayerCount;
playerCharacterMasters = new List<CharacterMaster>(totalNumPlayers);
rectWasAlreadyNull = false;
rivalRectWasAlreadyNull = false;
PopulatePlayerCharaterMasterList();
if (NetworkServer.active)
{
TaskSetup();
PopulateTempItemLists();
TasksPlugin.OnCancelAll?.Invoke();
}
}
private void TaskSetup()
{
Debug.Log((object)"Creating Task Objects");
taskCopies = new Task[27];
AirKills airKills = new AirKills();
DamageMultipleTargets damageMultipleTargets = new DamageMultipleTargets();
DealDamageInTime dealDamageInTime = new DealDamageInTime();
StayInAir stayInAir = new StayInAir();
BiggestHit biggestHit = new BiggestHit();
MostDistance mostDistance = new MostDistance();
PreonEvent preonEvent = new PreonEvent();
FarthestAway farthestAway = new FarthestAway();
FailShrine failShrine = new FailShrine();
OpenChests openChests = new OpenChests();
StartTeleporter startTeleporter = new StartTeleporter();
UsePrinters usePrinters = new UsePrinters();
OrderedSkills orderedSkills = new OrderedSkills();
DontUseSkill dontUseSkill = new DontUseSkill();
BabyDrone babyDrone = new BabyDrone();
Die die = new Die();
FindLockbox findLockbox = new FindLockbox();
HealingItem healingItem = new HealingItem();
NoJump noJump = new NoJump();
VeryBest veryBest = new VeryBest();
FewestElites fewestElites = new FewestElites();
GetLucky getLucky = new GetLucky();
GetLow getLow = new GetLow();
KillStreak killStreak = new KillStreak();
QuickDraw quickDraw = new QuickDraw();
FarKill farKill = new FarKill();
FewElites fewElites = new FewElites();
taskCopies[(int)(airKills.type - 1)] = airKills;
taskCopies[(int)(damageMultipleTargets.type - 1)] = damageMultipleTargets;
taskCopies[(int)(dealDamageInTime.type - 1)] = dealDamageInTime;
taskCopies[(int)(stayInAir.type - 1)] = stayInAir;
taskCopies[(int)(biggestHit.type - 1)] = biggestHit;
taskCopies[(int)(mostDistance.type - 1)] = mostDistance;
taskCopies[(int)(preonEvent.type - 1)] = preonEvent;
taskCopies[(int)(farthestAway.type - 1)] = farthestAway;
taskCopies[(int)(failShrine.type - 1)] = failShrine;
taskCopies[(int)(openChests.type - 1)] = openChests;
taskCopies[(int)(startTeleporter.type - 1)] = startTeleporter;
taskCopies[(int)(usePrinters.type - 1)] = usePrinters;
taskCopies[(int)(orderedSkills.type - 1)] = orderedSkills;
taskCopies[(int)(dontUseSkill.type - 1)] = dontUseSkill;
taskCopies[(int)(babyDrone.type - 1)] = babyDrone;
taskCopies[(int)(die.type - 1)] = die;
taskCopies[(int)(findLockbox.type - 1)] = findLockbox;
taskCopies[(int)(healingItem.type - 1)] = healingItem;
taskCopies[(int)(noJump.type - 1)] = noJump;
taskCopies[(int)(veryBest.type - 1)] = veryBest;
taskCopies[(int)(fewestElites.type - 1)] = fewestElites;
taskCopies[(int)(getLucky.type - 1)] = getLucky;
taskCopies[(int)(getLow.type - 1)] = getLow;
taskCopies[(int)(killStreak.type - 1)] = killStreak;
taskCopies[(int)(quickDraw.type - 1)] = quickDraw;
taskCopies[(int)(farKill.type - 1)] = farKill;
taskCopies[(int)(fewElites.type - 1)] = fewElites;
}
private void PopulatePlayerCharaterMasterList()
{
for (int i = 0; i < CharacterMaster.readOnlyInstancesList.Count; i++)
{
if ((Object)(object)CharacterMaster.readOnlyInstancesList[i].playerCharacterMasterController != (Object)null)
{
playerCharacterMasters.Add(CharacterMaster.readOnlyInstancesList[i]);
}
}
}
private void PopulateTempItemLists()
{
TempItemLists = new List<TempItem>[CharacterMaster.readOnlyInstancesList.Count];
for (int i = 0; i < TempItemLists.Length; i++)
{
TempItemLists[i] = new List<TempItem>();
}
}
private void SetupNetworking()
{
NetworkingAPI.RegisterMessageType<SyncTaskCompletion>();
NetworkingAPI.RegisterMessageType<SyncTaskEnded>();
NetworkingAPI.RegisterMessageType<SyncUpdateTask>();
NetworkingAPI.RegisterMessageType<SyncUpdateProgress>();
}
private void SetGameHooks()
{
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Expected O, but got Unknown
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Expected O, but got Unknown
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Expected O, but got Unknown
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Expected O, but got Unknown
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Expected O, but got Unknown
object obj = <>c.<>9__48_0;
if (obj == null)
{
hook_OnSkillActivated val = delegate(orig_OnSkillActivated orig, CharacterBody self, GenericSkill param)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
if (NetworkServer.active && self.isPlayerControlled)
{
int playerNumber = GetPlayerNumber(self.master);
SkillSlot arg = self.skillLocator.FindSkillSlot(param);
TasksPlugin.OnAbilityUsed?.Invoke(playerNumber, arg);
}
orig.Invoke(self, param);
};
<>c.<>9__48_0 = val;
obj = (object)val;
}
CharacterBody.OnSkillActivated += (hook_OnSkillActivated)obj;
GlobalEventManager.OnInteractionsGlobal += delegate(Interactor interactor, IInteractable interactable, GameObject go)
{
string text = ((object)interactable).GetType().ToString();
if (Object.op_Implicit((Object)(object)((go != null) ? go.GetComponent<TeleporterInteraction>() : null)))
{
Debug.Log((object)("Interacted with TP. InterType: " + text + " name: " + ((Object)go).name));
}
else if (Object.op_Implicit((Object)(object)((go != null) ? go.GetComponent<SceneExitController>() : null)))
{
Debug.Log((object)("Interacted with a SceneExitController " + ((Object)go).name));
StageEnd();
}
};
TeleporterInteraction.onTeleporterFinishGlobal += delegate
{
Debug.Log((object)"TP finished and player chose to leave");
if (NetworkServer.active)
{
StageEnd();
}
};
Run.OnServerTeleporterPlaced += (hook_OnServerTeleporterPlaced)delegate(orig_OnServerTeleporterPlaced orig, Run self, SceneDirector director, GameObject teleporter)
{
orig.Invoke(self, director, teleporter);
telePlaced = true;
};
HudObjectiveTargetSetter.Update += (hook_Update)delegate(orig_Update orig, HudObjectiveTargetSetter self)
{
orig.Invoke(self);
if ((Object)(object)panel == (Object)null)
{
Debug.Log((object)"Panel is null in HudObjSetter.Update");
}
if (self.objectivePanelController == null)
{
Debug.Log((object)"Task mod: objectivePanelController was null");
}
if (Object.op_Implicit((Object)(object)self.objectivePanelController))
{
panel = self.objectivePanelController;
}
};
HUD.Awake += (hook_Awake)delegate(orig_Awake orig, HUD self)
{
orig.Invoke(self);
hud = self;
int numberOfTasks = ConfigManager.instance.GetNumberOfTasks(totalNumPlayers);
numberOfTasks = Math.Min(numberOfTasks, 7);
tasksUIObjects = (GameObject[])(object)new GameObject[numberOfTasks];
tasksUIRects = (RectTransform[])(object)new RectTransform[numberOfTasks];
rivalTasksUIRects = (RectTransform[])(object)new RectTransform[numberOfTasks];
if (telePlaced && NetworkServer.active)
{
GenerateTasks(numberOfTasks);
}
};
GameOverController.Awake += (hook_Awake)delegate(orig_Awake orig, GameOverController self)
{
Debug.Log((object)"GameOverController.Awake");
CancelAllTasks();
orig.Invoke(self);
};
}
public void UpdateTasksUI(int taskIndex, string text = "")
{
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Expected O, but got Unknown
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
//IL_0112: Unknown result type (might be due to invalid IL or missing references)
//IL_0181: Unknown result type (might be due to invalid IL or missing references)
//IL_01a1: Unknown result type (might be