using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using LongRead.Dialogue;
using LongRead.Patches;
using NodeCanvas.DialogueTrees;
using NodeCanvas.Framework;
using NodeCanvas.Tasks.Actions;
using SideLoader;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("SideLoader")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
namespace LongRead
{
public enum TrainerChoice
{
Lawrence,
Odette
}
public enum BowCast
{
PowerShot,
PierceShot,
EvasionShoot,
StrafingShot
}
internal static class Settings
{
public static ConfigEntry<int> Price;
public static ConfigEntry<bool> RequirePrerequisites;
public static ConfigEntry<float> BowDamageMultiplier;
public static ConfigEntry<float> FlourishDamageMultiplier;
public static ConfigEntry<bool> ConsumeArrows;
public static ConfigEntry<bool> UseBowFormNames;
public static ConfigEntry<BowCast> BowCastAnimation;
public static ConfigEntry<TrainerChoice> Trainer;
public static void Bind(ConfigFile cfg)
{
Price = cfg.Bind<int>("General", "Price", 50, "Silver cost of Long Read when Dakers teaches it.");
RequirePrerequisites = cfg.Bind<bool>("General", "RequirePrerequisites", true, "Require Probe and Hunter's Eye to be known before Dakers will teach Long Read.");
BowDamageMultiplier = cfg.Bind<float>("Bow", "BowDamageMultiplier", 0.5f, "Weapon damage multiplier of the probing arrow at Alert levels 0-3 (vanilla melee Probe uses 0.5).");
FlourishDamageMultiplier = cfg.Bind<float>("Bow", "FlourishDamageMultiplier", 1.25f, "Weapon damage multiplier of the probing arrow at Alert level 4 / Flourish (vanilla melee Flourish uses 1.25).");
ConsumeArrows = cfg.Bind<bool>("Bow", "ConsumeArrows", true, "Consume one equipped arrow per probing shot.");
UseBowFormNames = cfg.Bind<bool>("Bow", "UseBowFormNames", false, "Show bow-form stage names (Ranging Shot, Feint, Goad, Mark, Trick Shot) instead of the melee names while a bow is equipped.");
BowCastAnimation = cfg.Bind<BowCast>("Bow", "BowCastAnimation", BowCast.PowerShot, "Animation used for the probing shot. PowerShot = Sniper Shot's long aimed draw; PierceShot = Piercing Shot's draw; EvasionShoot = quick shot with a backwards hop; StrafingShot = Strafing Run's shot.");
Trainer = cfg.Bind<TrainerChoice>("Trainer", "Trainer", TrainerChoice.Lawrence, "Who teaches Long Read in Harmattan: Lawrence (extends Lawrence Dakers' dialogue) or Odette (spawns Odette Dakers, Tracker, beside him).");
}
}
internal static class Ids
{
public const int LongRead = 2317000;
public const int Probe = 8205422;
public const int HuntersEye = 8205160;
public const int Silver = 9000010;
public const string AlertStatus = "Alert";
}
internal static class Text
{
public const string LongReadName = "Long Read";
public const string TrainChoice = "I want to train with you.";
public const string ReadyChoice = "I know the Probe and I've got the hunter's eye. Teach me.";
public const string NotNowChoice = "Not now.";
public const string AcceptLine = "You actually went and did it! Alright, nock an arrow and watch close...";
public const string ClosingLine = "Hah! See that? A probing shot's no different from a probing jab. You just need farther eyes!";
public const string OdetteWhoChoice = "Who are you?";
public const string OdetteWhoLine = "Lawrence's sister. I run the trap lines outside the walls and read the ground for the Academy's hunters.";
public const string OdetteGoodbye = "Goodbye.";
public static readonly string[] BowFormNames = new string[5] { "Ranging Shot", "Feint", "Goad", "Mark", "Trick Shot" };
public static string ExplainLine(int price)
{
string text = ((price > 0) ? ("Bring " + price + " silver with you and I'll teach you the rest!") : "Come back when you have them and I'll teach you the rest!");
return "Reading a mark from bow range? Ha! Now that's a hunter's trick! But you need the basics first: learn Probe from Battleborn, right here in the market, and Hunter's Eye from Ture up in Berg. " + text;
}
}
[BepInPlugin("djk.longread", "Long Read", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
public const string GUID = "djk.longread";
public const string NAME = "Long Read";
public const string VERSION = "1.0.0";
internal static ManualLogSource Log;
private Harmony m_harmony;
private void Awake()
{
//IL_0055: 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_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
Settings.Bind(((BaseUnityPlugin)this).Config);
string text = Settings.BowCastAnimation.Value.ToString();
if (Enum.IsDefined(typeof(SpellCastType), text))
{
CastPatch.BowCastType = (SpellCastType)Enum.Parse(typeof(SpellCastType), text);
}
else
{
Log.LogWarning((object)("Could not resolve the bow cast type '" + text + "'; the probing shot will use PowerShot."));
}
m_harmony = new Harmony("djk.longread");
m_harmony.PatchAll(typeof(Plugin).Assembly);
Log.LogInfo((object)"Harmony patches applied.");
SL.OnPacksLoaded += OnPacksLoaded;
SL.OnSceneLoaded += OnSceneLoaded;
}
private static void OnPacksLoaded()
{
try
{
Item val = ((ResourcesPrefabManager.Instance != null) ? ResourcesPrefabManager.Instance.GetItemPrefab(2317000) : null);
if ((Object)(object)val == (Object)null)
{
Log.LogWarning((object)"Long Read skill (2317000) was not created; check the SideLoader pack (Items/LongRead/LongRead.xml).");
}
else
{
Log.LogInfo((object)("Long Read skill registered (item " + 2317000 + ")."));
}
ProbeSetup.Apply();
TrainerSetup.Prepare();
}
catch (Exception ex)
{
Log.LogError((object)("Long Read setup failed: " + ex));
}
}
private static void OnSceneLoaded()
{
try
{
TrainerSetup.OnSceneLoaded();
}
catch (Exception ex)
{
Log.LogError((object)("Long Read trainer hook failed: " + ex));
}
}
}
public class LongReadBowRelay : MonoBehaviour
{
public const string BowChildName = "ReferencedLongReadBow";
private LevelAttackSkill m_skill;
private void Awake()
{
m_skill = ((Component)this).GetComponent<LevelAttackSkill>();
}
private bool TryGetBowCast(out Character owner, out ProjectileWeapon bow)
{
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Invalid comparison between Unknown and I4
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
owner = (((Object)(object)m_skill != (Object)null) ? ((EffectSynchronizer)m_skill).OwnerCharacter : null);
bow = (ProjectileWeapon)(((Object)(object)owner != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null);
return (Object)(object)bow != (Object)null && (int)((Weapon)bow).Type == 200 && owner.CurrentSpellCast == CastPatch.BowCastType;
}
private void ShootProjectileCastInit()
{
if (TryGetBowCast(out var _, out var bow) && ((Weapon)bow).IsEmpty && bow.CanBeLoaded())
{
((Weapon)bow).InstantLoadWeapon();
}
}
private void ShootProjectileCast()
{
if (TryGetBowCast(out var owner, out var bow) && !((Weapon)bow).IsEmpty)
{
((Item)m_skill).CharSpellCast();
((EffectSynchronizer)m_skill).SynchronizeEffects((EffectCategories)5, owner);
bow.UnloadWeapon();
}
}
private void ShootProjectileCastDone()
{
}
}
internal static class LongReadState
{
public static bool IsLearned(Character c, int itemId)
{
object obj;
if (c == null)
{
obj = null;
}
else
{
CharacterInventory inventory = c.Inventory;
obj = ((inventory != null) ? inventory.SkillKnowledge : null);
}
CharacterSkillKnowledge val = (CharacterSkillKnowledge)obj;
return (Object)(object)val != (Object)null && ((CharacterKnowledge)val).IsItemLearned(itemId);
}
public static bool KnowsLongRead(Character c)
{
return IsLearned(c, 2317000);
}
public static bool HasPrerequisites(Character c)
{
if (!Settings.RequirePrerequisites.Value)
{
return true;
}
return IsLearned(c, 8205422) && IsLearned(c, 8205160);
}
public static bool IsBowEquipped(Character c)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Invalid comparison between Unknown and I4
int result;
if ((Object)(object)c != (Object)null)
{
Weapon currentWeapon = c.CurrentWeapon;
ProjectileWeapon val = (ProjectileWeapon)(object)((currentWeapon is ProjectileWeapon) ? currentWeapon : null);
if (val != null)
{
result = (((int)((Weapon)val).Type == 200) ? 1 : 0);
goto IL_0029;
}
}
result = 0;
goto IL_0029;
IL_0029:
return (byte)result != 0;
}
public static bool IsBowBranch(Character c)
{
return IsBowEquipped(c) && KnowsLongRead(c);
}
}
internal static class ProbeSetup
{
public static void Apply()
{
ResourcesPrefabManager instance = ResourcesPrefabManager.Instance;
if (instance == null)
{
Plugin.Log.LogWarning((object)"ResourcesPrefabManager is not available; Probe could not be wired for bows.");
return;
}
Item itemPrefab = instance.GetItemPrefab(8205422);
LevelAttackSkill val = (LevelAttackSkill)(object)((itemPrefab is LevelAttackSkill) ? itemPrefab : null);
if ((Object)(object)val == (Object)null)
{
Plugin.Log.LogWarning((object)"Probe prefab (8205422) not found; the bow branch is disabled.");
return;
}
if ((Object)(object)((Component)val).GetComponent<LongReadBowRelay>() == (Object)null)
{
((Component)val).gameObject.AddComponent<LongReadBowRelay>();
}
Transform val2 = ((Component)val).transform.Find("ReferencedLongReadBow");
if ((Object)(object)val2 == (Object)null)
{
Plugin.Log.LogWarning((object)"Probe is missing the 'ReferencedLongReadBow' effect child; the SideLoader template Items/Probe_LongRead.xml did not apply.");
return;
}
ShootProjectileAmmoVisuals component = ((Component)val2).GetComponent<ShootProjectileAmmoVisuals>();
Projectile val3 = (((Object)(object)component != (Object)null) ? ((ShootProjectile)component).BaseProjectile : null);
if ((Object)(object)val3 == (Object)null)
{
Plugin.Log.LogWarning((object)"Probe's bow effect set has no projectile; the SniperShot projectile could not be cloned.");
return;
}
int num = 0;
WeaponDamageProjectileWeapon[] componentsInChildren = ((Component)val3).GetComponentsInChildren<WeaponDamageProjectileWeapon>(true);
foreach (WeaponDamageProjectileWeapon val4 in componentsInChildren)
{
bool flag = ((Object)((Component)val4).transform).name.StartsWith("Flourish");
((WeaponDamage)val4).WeaponDamageMult = (flag ? Settings.FlourishDamageMultiplier.Value : Settings.BowDamageMultiplier.Value);
((WeaponDamage)val4).WeaponDurabilityLoss = 1f;
num++;
}
UseLoadoutAmunition component2 = ((Component)val2).GetComponent<UseLoadoutAmunition>();
if (!Settings.ConsumeArrows.Value && (Object)(object)component2 != (Object)null)
{
Object.DestroyImmediate((Object)(object)component2);
}
string[] array = new string[3] { "Alert", "Confusion", "Pain" };
foreach (string text in array)
{
if ((Object)(object)instance.GetStatusEffectPrefab(text) == (Object)null)
{
Plugin.Log.LogWarning((object)("Status effect '" + text + "' not found; the probing arrow will not apply it."));
}
}
Plugin.Log.LogInfo((object)("Probe wired for bows: " + num + " hit groups, arrows " + (Settings.ConsumeArrows.Value ? "consumed" : "not consumed") + "."));
}
}
internal static class TrainerSetup
{
public const string OdetteUid = "djk.longread.odette";
public const string HarmattanScene = "Harmattan";
public static bool LawrenceTeaches => Settings.Trainer.Value == TrainerChoice.Lawrence || PhotonNetwork.isNonMasterClientInRoom;
public static void Prepare()
{
PrepareOdette();
Plugin.Log.LogInfo((object)((Settings.Trainer.Value == TrainerChoice.Odette) ? "Trainer: Odette Dakers, Tracker spawns beside Lawrence Dakers when Harmattan loads." : "Trainer: Lawrence Dakers, Hunter (Harmattan) teaches Long Read in his dialogue."));
}
public static void PrepareOdette()
{
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Expected O, but got Unknown
if (CustomCharacters.Templates.TryGetValue("djk.longread.odette", out var value))
{
SL_CharacterTrainer val = (SL_CharacterTrainer)(object)((value is SL_CharacterTrainer) ? value : null);
if (val != null)
{
val.SkillTree = new SL_SkillTree
{
UID = "djk.longread.odette.unused",
Name = "Long Read"
};
((SL_Character)val).ShouldSpawn = () => Settings.Trainer.Value == TrainerChoice.Odette;
((SL_Character)val).OnSpawn -= OnOdetteSpawned;
((SL_Character)val).OnSpawn += OnOdetteSpawned;
return;
}
}
Plugin.Log.LogWarning((object)"Odette Dakers' character template (Characters/OdetteDakers.xml) was not loaded; the Odette trainer option is unavailable.");
}
private static void OnOdetteSpawned(Character character, string rpcData)
{
try
{
if (CustomCharacters.Templates.TryGetValue("djk.longread.odette", out var value))
{
SL_CharacterTrainer val = (SL_CharacterTrainer)(object)((value is SL_CharacterTrainer) ? value : null);
if (val != null)
{
OdetteDialogue.Build(character, val);
Plugin.Log.LogInfo((object)"Trainer hooked: Odette Dakers, Tracker spawned in Harmattan.");
}
}
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("Odette Dakers' dialogue could not be built: " + ex));
}
}
public static void OnSceneLoaded()
{
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Expected O, but got Unknown
if (!LawrenceTeaches || SceneManagerHelper.ActiveSceneName != "Harmattan")
{
return;
}
DialogueTreeController[] array = Resources.FindObjectsOfTypeAll<DialogueTreeController>();
foreach (DialogueTreeController val in array)
{
Graph val2 = (((Object)(object)val != (Object)null) ? ((GraphOwner)val).graph : null);
if (DakersDialogue.IsDakersGraph(val2) && DakersDialogue.Inject((DialogueTreeExt)val2))
{
Plugin.Log.LogInfo((object)"Trainer hooked: Lawrence Dakers, Hunter (Harmattan) now offers Long Read.");
}
}
}
}
}
namespace LongRead.Patches
{
[HarmonyPatch(typeof(Item), "StartEffectsCast")]
internal static class CastPatch
{
internal static SpellCastType BowCastType = (SpellCastType)53;
[HarmonyPrefix]
private static bool Prefix(Item __instance, Character _targetChar)
{
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
if (__instance.ItemID != 8205422 || (Object)(object)_targetChar == (Object)null)
{
return true;
}
if (!LongReadState.IsBowBranch(_targetChar))
{
return true;
}
_targetChar.CastSpell(BowCastType, ((Component)__instance).gameObject, (SpellCastModifier)0, __instance.GetCastSheathRequired(), __instance.MobileCastMovementMult);
return false;
}
}
[HarmonyPatch(typeof(DialogueTreeController), "GetInstance")]
internal static class DialogueGraphPatch
{
[HarmonyPostfix]
private static void Postfix(Graph __result)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
if (TrainerSetup.LawrenceTeaches && DakersDialogue.IsDakersGraph(__result) && DakersDialogue.Inject((DialogueTreeExt)__result))
{
Plugin.Log.LogInfo((object)"Trainer hooked: Lawrence Dakers, Hunter (Harmattan) now offers Long Read.");
}
}
}
[HarmonyPatch(typeof(SL), "Setup")]
internal static class HotReloadPatch
{
[HarmonyPostfix]
private static void Postfix(bool isFirstSetup)
{
if (isFirstSetup)
{
return;
}
try
{
ProbeSetup.Apply();
TrainerSetup.PrepareOdette();
Plugin.Log.LogInfo((object)"SideLoader hot reload: Long Read wiring re-applied.");
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("Long Read re-wiring after hot reload failed: " + ex));
}
}
}
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
internal static class NamePatch
{
[HarmonyPostfix]
private static void Postfix(Item __instance, ref string __result)
{
if (__instance.ItemID != 8205422 || !Settings.UseBowFormNames.Value)
{
return;
}
LevelAttackSkill val = (LevelAttackSkill)(object)((__instance is LevelAttackSkill) ? __instance : null);
if (val == null)
{
return;
}
Character ownerCharacter = ((EffectSynchronizer)val).OwnerCharacter;
if (!((Object)(object)ownerCharacter == (Object)null) && LongReadState.IsBowBranch(ownerCharacter))
{
int num = val.m_currentStage;
if (num < 0)
{
num = 0;
}
if (num >= Text.BowFormNames.Length)
{
num = Text.BowFormNames.Length - 1;
}
__result = Text.BowFormNames[num];
}
}
}
[HarmonyPatch(typeof(AttackSkill), "OwnerHasAllRequiredItems")]
internal static class ProbeRequirementPatch
{
[HarmonyPrefix]
private static bool Prefix(AttackSkill __instance, bool _TryingToActivate, ref bool __result)
{
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Invalid comparison between Unknown and I4
if (((Item)__instance).ItemID != 8205422)
{
return true;
}
Character ownerCharacter = ((EffectSynchronizer)__instance).OwnerCharacter;
if (!((Object)(object)ownerCharacter == (Object)null))
{
Weapon currentWeapon = ownerCharacter.CurrentWeapon;
ProjectileWeapon val = (ProjectileWeapon)(object)((currentWeapon is ProjectileWeapon) ? currentWeapon : null);
if (val != null && (int)((Weapon)val).Type == 200)
{
__instance.m_weaponReq = null;
__instance.m_offhandReq = null;
if (!LongReadState.KnowsLongRead(ownerCharacter))
{
if (_TryingToActivate && (Object)(object)ownerCharacter.CharacterUI != (Object)null)
{
ownerCharacter.CharacterUI.ShowInfoNotificationLoc("Notification_Quickslot_MissingWeapon");
}
__result = false;
return false;
}
if (((Weapon)val).IsEmpty && !val.CanBeLoaded())
{
if (_TryingToActivate && (Object)(object)ownerCharacter.CharacterUI != (Object)null)
{
ownerCharacter.CharacterUI.ShowInfoNotificationLoc("Notification_ProjectileWeapon_NoAmmunition");
}
__result = false;
return false;
}
__instance.m_weaponReq = (Weapon)(object)val;
__result = SkillOwnerHasAllRequiredItems((Skill)(object)__instance, _TryingToActivate);
return false;
}
}
return true;
}
[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
[HarmonyPatch(typeof(Skill), "OwnerHasAllRequiredItems")]
private static bool SkillOwnerHasAllRequiredItems(Skill instance, bool tryingToActivate)
{
throw new NotImplementedException("Harmony reverse patch stub");
}
}
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
internal static class WeaponDamagePatch
{
[HarmonyPrefix]
private static bool Prefix(WeaponDamage __instance, Character _targetCharacter, ref DamageList _list, ref float _knockback, ref Weapon __result)
{
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Invalid comparison between Unknown and I4
if (!(__instance is WeaponDamageProjectileWeapon))
{
return true;
}
AttackSkill attackSkill = __instance.m_attackSkill;
if ((Object)(object)attackSkill == (Object)null || ((Item)attackSkill).ItemID != 8205422)
{
return true;
}
__result = PunctualDamageBuildDamage((PunctualDamage)(object)__instance, _targetCharacter, ref _list, ref _knockback);
Character ownerCharacter = ((EffectSynchronizer)attackSkill).OwnerCharacter;
if ((Object)(object)ownerCharacter != (Object)null)
{
Weapon currentWeapon = ownerCharacter.CurrentWeapon;
ProjectileWeapon val = (ProjectileWeapon)(object)((currentWeapon is ProjectileWeapon) ? currentWeapon : null);
if (val != null && (int)((Weapon)val).Type == 200)
{
__instance.BuildDamage((Weapon)(object)val, _targetCharacter, true, ref _list, ref _knockback);
__result = (Weapon)(object)val;
}
}
return false;
}
[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
private static Weapon PunctualDamageBuildDamage(PunctualDamage instance, Character targetCharacter, ref DamageList list, ref float knockback)
{
throw new NotImplementedException("Harmony reverse patch stub");
}
}
}
namespace LongRead.Dialogue
{
internal static class DakersDialogue
{
public const string GraphName = "Dialogue_Merchant_HarmattanGeneral";
public const string ActorKey = "name_merchant_sorobormarketgeneral_01";
private const string MenuNodeUid = "6b2bc05e-46e0-425f-a08d-842b9669d401";
private const string FinishNodeUid = "4a817acc-d33a-4d44-99ed-1ca2624d92e0";
private const string TrainChoiceLocKey = "Merchant_Generic_Train_01";
public static bool IsDakersGraph(Graph graph)
{
return graph is DialogueTreeExt && graph.name != null && graph.name.StartsWith("Dialogue_Merchant_HarmattanGeneral");
}
public static bool Inject(DialogueTreeExt graph)
{
//IL_0137: Unknown result type (might be due to invalid IL or missing references)
//IL_013c: Unknown result type (might be due to invalid IL or missing references)
//IL_014d: Expected O, but got Unknown
//IL_0148: Unknown result type (might be due to invalid IL or missing references)
//IL_014d: Unknown result type (might be due to invalid IL or missing references)
//IL_015c: Expected O, but got Unknown
if ((Object)(object)graph == (Object)null)
{
return false;
}
if (((Graph)graph).allNodes.Any((Node n) => n != null && n.tag == "LongRead.Train"))
{
return false;
}
MultipleChoiceNode val = ((Graph)graph).allNodes.OfType<MultipleChoiceNode>().FirstOrDefault((Func<MultipleChoiceNode, bool>)((MultipleChoiceNode n) => ((Node)n).UID == "6b2bc05e-46e0-425f-a08d-842b9669d401")) ?? ((Graph)graph).allNodes.OfType<MultipleChoiceNode>().FirstOrDefault();
if (val == null)
{
Plugin.Log.LogWarning((object)"Lawrence Dakers' dialogue has no choice menu; the train option was not added.");
return false;
}
FinishNode finish = ((Graph)graph).allNodes.OfType<FinishNode>().FirstOrDefault((Func<FinishNode, bool>)((FinishNode n) => ((Node)n).UID == "4a817acc-d33a-4d44-99ed-1ca2624d92e0")) ?? ((Graph)graph).allNodes.OfType<FinishNode>().FirstOrDefault() ?? TrainingDialogue.Tagged<FinishNode>(((Graph)graph).AddNode<FinishNode>());
DTNode val2 = TrainingDialogue.Build(graph, "name_merchant_sorobormarketgeneral_01", finish);
List<Choice> availableChoices = val.availableChoices;
int num = ((availableChoices.Count > 0) ? (availableChoices.Count - 1) : 0);
Choice item = new Choice(new Statement("I want to train with you.")
{
meta = "Merchant_Generic_Train_01"
})
{
condition = (ConditionTask)(object)TrainingDialogue.Condition(graph, LongReadCondition.Check.NotLearned)
};
availableChoices.Insert(num, item);
((Graph)graph).ConnectNodes((Node)(object)val, (Node)(object)val2, num, -1);
return true;
}
}
public class LongReadCondition : ConditionTask
{
public enum Check
{
NotLearned,
CanTrain
}
public Check Mode;
public BBParameter<Character> character;
public override string info => "Long Read: " + Mode;
public override bool OnCheck()
{
Character val = ((character != null) ? character.value : null);
if ((Object)(object)val == (Object)null && (Object)(object)((Task)this).agent != (Object)null)
{
val = ((Task)this).agent.GetComponent<Character>();
}
if ((Object)(object)val == (Object)null && (Object)(object)CharacterManager.Instance != (Object)null)
{
val = CharacterManager.Instance.GetFirstLocalCharacter();
}
if ((Object)(object)val == (Object)null || (Object)(object)val.Inventory == (Object)null)
{
return false;
}
switch (Mode)
{
case Check.NotLearned:
return !LongReadState.KnowsLongRead(val);
case Check.CanTrain:
{
if (!LongReadState.HasPrerequisites(val))
{
return false;
}
int value = Settings.Price.Value;
return value <= 0 || val.Inventory.OwnsItem(9000010, value);
}
default:
return false;
}
}
public LongReadCondition()
{
BBParameter<Character> obj = new BBParameter<Character>();
((BBParameter)obj).name = "gInstigator";
character = obj;
((ConditionTask)this)..ctor();
}
}
internal static class OdetteDialogue
{
public static void Build(Character trainer, SL_CharacterTrainer template)
{
DialogueTreeController componentInChildren = ((Component)trainer).GetComponentInChildren<DialogueTreeController>(true);
DialogueTreeExt val = (DialogueTreeExt)(((Object)(object)componentInChildren != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null);
if ((Object)(object)val == (Object)null)
{
Plugin.Log.LogWarning((object)"Odette Dakers has no dialogue graph; her dialogue was left as SideLoader built it.");
}
else
{
if (((Graph)val).allNodes.Any((Node n) => n != null && n.tag == "LongRead.Train"))
{
return;
}
StatementNodeExt val2 = ((Graph)val).allNodes.OfType<StatementNodeExt>().FirstOrDefault();
if (val2 == null)
{
Plugin.Log.LogWarning((object)"Odette Dakers' dialogue template is not the expected trainer graph; left unchanged.");
return;
}
Connection[] array = ((Node)val2).outConnections.ToArray();
foreach (Connection val3 in array)
{
((Graph)val).RemoveConnection(val3, false);
}
ActionNode[] array2 = ((Graph)val).allNodes.OfType<ActionNode>().ToArray();
foreach (ActionNode item in array2)
{
((Graph)val).allNodes.Remove((Node)(object)item);
}
string name = ((SL_Character)template).Name;
MultipleChoiceNodeExt val4 = TrainingDialogue.Tagged<MultipleChoiceNodeExt>(((Graph)val).AddNode<MultipleChoiceNodeExt>());
StatementNodeExt val5 = TrainingDialogue.Statement(val, "Lawrence's sister. I run the trap lines outside the walls and read the ground for the Academy's hunters.", name);
FinishNode val6 = TrainingDialogue.Tagged<FinishNode>(((Graph)val).AddNode<FinishNode>());
DTNode target = TrainingDialogue.Build(val, name, val6);
((Graph)val).ConnectNodes((Node)(object)val2, (Node)(object)val4, -1, -1);
TrainingDialogue.AddChoice(val, val4, "Who are you?", null, null, (Node)(object)val5);
TrainingDialogue.AddChoice(val, val4, "I want to train with you.", "Merchant_Generic_Train_01", (ConditionTask)(object)TrainingDialogue.Condition(val, LongReadCondition.Check.NotLearned), (Node)(object)target);
TrainingDialogue.AddChoice(val, val4, "Goodbye.", null, null, (Node)(object)val6);
((Graph)val).ConnectNodes((Node)(object)val5, (Node)(object)val6, -1, -1);
((Node)val2).tag = "LongRead.Train";
((Graph)val).primeNode = (Node)(object)val2;
}
}
}
internal static class TrainingDialogue
{
public const string Tag = "LongRead.Train";
private const string NotNowLocKey = "Merchant_Generic_NotNow_01";
public static DTNode Build(DialogueTreeExt graph, string actorKey, FinishNode finish)
{
StatementNodeExt val = Statement(graph, Text.ExplainLine(Settings.Price.Value), actorKey);
MultipleChoiceNodeExt val2 = TrainingDialogue.Tagged<MultipleChoiceNodeExt>(((Graph)graph).AddNode<MultipleChoiceNodeExt>());
StatementNodeExt val3 = Statement(graph, "You actually went and did it! Alright, nock an arrow and watch close...", actorKey);
StatementNodeExt val4 = Statement(graph, "Hah! See that? A probing shot's no different from a probing jab. You just need farther eyes!", actorKey);
ActionNode val5 = TrainingDialogue.Tagged<ActionNode>(((Graph)graph).AddNode<ActionNode>());
val5.action = (ActionTask)(object)Task.Create<FadeOut>((ITaskSystem)(object)graph);
ActionNode val6 = TrainingDialogue.Tagged<ActionNode>(((Graph)graph).AddNode<ActionNode>());
val6.action = CreateRewardActions(graph);
ActionNode val7 = TrainingDialogue.Tagged<ActionNode>(((Graph)graph).AddNode<ActionNode>());
val7.action = (ActionTask)(object)Task.Create<FadeIn>((ITaskSystem)(object)graph);
((Graph)graph).ConnectNodes((Node)(object)val, (Node)(object)val2, -1, -1);
AddChoice(graph, val2, "I know the Probe and I've got the hunter's eye. Teach me.", null, (ConditionTask)(object)Condition(graph, LongReadCondition.Check.CanTrain), (Node)(object)val3);
AddChoice(graph, val2, "Not now.", "Merchant_Generic_NotNow_01", null, (Node)(object)finish);
((Graph)graph).ConnectNodes((Node)(object)val3, (Node)(object)val5, -1, -1);
((Graph)graph).ConnectNodes((Node)(object)val5, (Node)(object)val6, -1, -1);
((Graph)graph).ConnectNodes((Node)(object)val6, (Node)(object)val7, -1, -1);
((Graph)graph).ConnectNodes((Node)(object)val7, (Node)(object)val4, -1, -1);
((Graph)graph).ConnectNodes((Node)(object)val4, (Node)(object)finish, -1, -1);
return (DTNode)(object)val;
}
private static ActionTask CreateRewardActions(DialogueTreeExt graph)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Expected O, but got Unknown
//IL_004e: 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_006b: Expected O, but got Unknown
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Expected O, but got Unknown
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
GiveReward val = Task.Create<GiveReward>((ITaskSystem)(object)graph);
val.RewardReceiver = (Receiver)1;
val.SilverAmount = new BBParameter<int>(0);
val.XpAmount = new BBParameter<int>(0);
val.ItemReward.Add(new ItemQuantity
{
Item = new BBParameter<ItemReference>(new ItemReference
{
ItemID = 2317000
}),
Quantity = new BBParameter<int>(1),
TryToEquip = new BBParameter<bool>(false)
});
int value = Settings.Price.Value;
if (value <= 0)
{
return (ActionTask)(object)val;
}
RemoveItem val2 = Task.Create<RemoveItem>((ITaskSystem)(object)graph);
BBParameter<Character> obj = new BBParameter<Character>();
((BBParameter)obj).name = "gInstigator";
val2.fromCharacter = obj;
val2.Items.Add(new BBParameter<ItemReference>(new ItemReference
{
ItemID = 9000010
}));
val2.Amount.Add(new BBParameter<int>(value));
ActionList val3 = Task.Create<ActionList>((ITaskSystem)(object)graph);
val3.executionMode = (ActionsExecutionMode)0;
val3.actions.Add((ActionTask)(object)val);
val3.actions.Add((ActionTask)(object)val2);
return (ActionTask)(object)val3;
}
public static LongReadCondition Condition(DialogueTreeExt graph, LongReadCondition.Check mode)
{
LongReadCondition longReadCondition = Task.Create<LongReadCondition>((ITaskSystem)(object)graph);
longReadCondition.Mode = mode;
return longReadCondition;
}
public static void AddChoice(DialogueTreeExt graph, MultipleChoiceNodeExt menu, string text, string locKey, ConditionTask condition, Node target)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Expected O, but got Unknown
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
Statement val = new Statement(text);
if (!string.IsNullOrEmpty(locKey))
{
val.meta = locKey;
}
menu.availableChoices.Add(new Choice(val)
{
condition = condition
});
((Graph)graph).ConnectNodes((Node)(object)menu, target, menu.availableChoices.Count - 1, -1);
}
public static StatementNodeExt Statement(DialogueTreeExt graph, string line, string actorKey)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Expected O, but got Unknown
StatementNodeExt val = TrainingDialogue.Tagged<StatementNodeExt>(((Graph)graph).AddNode<StatementNodeExt>());
val.statement = new Statement(line);
val.SetActorName(actorKey);
return val;
}
public static T Tagged<T>(T node) where T : Node
{
((Node)node).tag = "LongRead.Train";
return node;
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}