using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("DvergrDiplomacy")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("DvergrDiplomacy")]
[assembly: AssemblyTitle("DvergrDiplomacy")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Pix.DvergrDiplomacy;
[BepInPlugin("Pix.DvergrDiplomacy", "DvergrDiplomacy", "0.1.217")]
public sealed class DvergrDiplomacyTruceWedge : BaseUnityPlugin
{
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static ConsoleEvent <>9__85_0;
internal void <TryRegisterConsoleCommand>b__85_0(ConsoleEventArgs args)
{
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Expected O, but got Unknown
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
try
{
if ((Object)(object)Player.m_localPlayer == (Object)null)
{
args.Context.AddString("No local player.");
return;
}
if ((Object)(object)ZNet.instance == (Object)null || ZRoutedRpc.instance == null)
{
args.Context.AddString("Network not ready.");
return;
}
Vector3 val = ((Component)Player.m_localPlayer).transform.position + ((Component)Player.m_localPlayer).transform.forward * 2f;
ZPackage val2 = new ZPackage();
val2.Write(val);
val2.Write(Quaternion.identity);
ZRoutedRpc.instance.InvokeRoutedRPC(0L, "DD_SpawnDverger_Test", new object[1] { val2 });
args.Context.AddString("Requested server spawn.");
}
catch (Exception ex)
{
args.Context.AddString("dd_spawn_dverger failed: " + ex.Message);
}
}
}
public const string PluginGuid = "Pix.DvergrDiplomacy";
public const string PluginName = "DvergrDiplomacy";
public const string PluginVersion = "0.1.217";
private const string BuildId = "DD_TRUCEWEDGE_0.3.117_CLEAN";
private const string RpcSpawnTest = "DD_SpawnDverger_Test";
private const string CmdSpawnDverger = "dd_spawn_dverger";
internal static DvergrDiplomacyTruceWedge Self;
internal static ManualLogSource Log;
private Harmony _harmony;
private ConfigEntry<bool> _enabled;
private ConfigEntry<float> _hostileSeconds;
private ConfigEntry<int> _forgivenessFreeStrikes;
private ConfigEntry<float> _forgivenessWindowSeconds;
private ConfigEntry<float> _joinGraceSeconds;
private ConfigEntry<float> _calmHoldSeconds;
private ConfigEntry<float> _updateTargetHoldSeconds;
private ConfigEntry<bool> _serverTriggerOnFindEnemy;
private ConfigEntry<bool> _serverTriggerOnSetTarget;
private ConfigEntry<bool> _showMessagesClient;
private ConfigEntry<string> _warningPhrases;
private ConfigEntry<bool> _spawnTestEnabled;
private ConfigEntry<bool> _logEnabled;
private ConfigEntry<float> _perAiLogEverySeconds;
private ConfigEntry<bool> _traceAllAis;
private ConfigEntry<bool> _clientSimWarning;
private static MethodInfo MI_FindEnemy;
private static MethodInfo MI_SetTarget;
private static MethodInfo MI_UpdateAI;
private static MethodInfo MI_CharacterDamage;
private static MethodInfo MI_SetAlertedBool;
private static MethodInfo MI_GetTargetCreature;
private static FieldRef<MonsterAI, Character> FR_TargetCreature;
private static bool FR_TargetCreatureOk;
private static FieldInfo FI_Alerted;
private static FieldInfo FI_Aggravated;
private static FieldInfo FI_LastKnownTargetPos;
private static FieldInfo FI_TargetStatic;
private static FieldInfo FI_UpdateTargetTimer;
private static readonly object _lock = new object();
private static readonly Dictionary<long, long> HostileUntilMsByPlayerId = new Dictionary<long, long>();
private static readonly Dictionary<long, long> JoinGraceUntilMsByPlayerId = new Dictionary<long, long>();
private static readonly Dictionary<long, int> StrikeCountByPlayerId = new Dictionary<long, int>();
private static readonly Dictionary<long, long> StrikeGraceUntilMsByPlayerId = new Dictionary<long, long>();
private static readonly HashSet<int> ActivatedAiIds = new HashSet<int>();
private static readonly Dictionary<int, long> CalmLockUntilMsByAiId = new Dictionary<int, long>();
private static readonly Dictionary<int, long> AiPlayerIdByAiId = new Dictionary<int, long>();
private static readonly Dictionary<int, float> NextLogAtByAiId = new Dictionary<int, float>();
private static readonly HashSet<int> ClientSimWarnedAiIds = new HashSet<int>();
private static bool _rpcsRegistered;
private static bool _consoleRegistered;
private string[] _phrases = new string[1] { "Hold your hand, outsider." };
private Random _rng = new Random();
private void Awake()
{
//IL_024e: Unknown result type (might be due to invalid IL or missing references)
//IL_0258: Expected O, but got Unknown
Self = this;
Log = ((BaseUnityPlugin)this).Logger;
_enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable DvergrDiplomacy.");
_hostileSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Diplomacy", "HostileSeconds", 180f, "How long they stay hostile after diplomacy breaks.");
_forgivenessFreeStrikes = ((BaseUnityPlugin)this).Config.Bind<int>("Forgiveness", "FreeStrikes", 1, "Number of forgiven strikes before diplomacy breaks.");
_forgivenessWindowSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Forgiveness", "WindowSeconds", 30f, "Second strike within this window breaks diplomacy.");
_joinGraceSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Safety", "JoinGraceSeconds", 15f, "Grace period after contact to prevent instant death.");
_calmHoldSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Wedge", "CalmHoldSeconds", 12f, "Hold calm this long (refreshes while hot).");
_updateTargetHoldSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Wedge", "UpdateTargetHoldSeconds", 30f, "Clamp update target timer while holding calm.");
_serverTriggerOnFindEnemy = ((BaseUnityPlugin)this).Config.Bind<bool>("ServerTriggers", "TriggerOnFindEnemy", true, "Server: treat FindEnemy->Player as contact (starts join grace).");
_serverTriggerOnSetTarget = ((BaseUnityPlugin)this).Config.Bind<bool>("ServerTriggers", "TriggerOnSetTarget", true, "Server: treat SetTarget(Player) as contact (starts join grace).");
_showMessagesClient = ((BaseUnityPlugin)this).Config.Bind<bool>("Client", "ShowMessages", true, "Client: show warning popup on forgiven strike.");
_warningPhrases = ((BaseUnityPlugin)this).Config.Bind<string>("Client", "WarningPhrases", "Careful|Hold your hand, outsider.|Odin is watching.", "Pipe-separated list of warning phrases.");
_spawnTestEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("SpawnTest", "Enabled", true, "Enable dd_spawn_dverger and server RPC spawn test.");
_logEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "Log", true, "Enable logs (throttled).");
_perAiLogEverySeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Logging", "PerAiLogEverySeconds", 1f, "Minimum seconds between logs per AI.");
_traceAllAis = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "TraceAllAis", false, "Apply to all MonsterAI (debug).");
_clientSimWarning = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "ClientSimWarning", true, "Client: warn once per AI if AI sim is client-side.");
ParsePhrases();
ResolveHandles();
_harmony = new Harmony("Pix.DvergrDiplomacy");
ApplyPatches();
TryRegisterRpcs();
TryRegisterConsoleCommand();
Log.LogInfo((object)"[DD_TRUCEWEDGE_0.3.117_CLEAN] Loaded v0.1.217.");
}
private void Update()
{
try
{
if (EnabledNow())
{
TryRegisterRpcs();
TryRegisterConsoleCommand();
}
}
catch
{
}
}
private void OnDestroy()
{
try
{
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
catch
{
}
}
private bool EnabledNow()
{
if (_enabled != null)
{
return _enabled.Value;
}
return false;
}
private void ParsePhrases()
{
try
{
string text = ((_warningPhrases != null) ? (_warningPhrases.Value ?? "") : "");
string[] array = text.Split(new char[1] { '|' }, StringSplitOptions.RemoveEmptyEntries);
List<string> list = new List<string>();
for (int i = 0; i < array.Length; i++)
{
string text2 = ((array[i] != null) ? array[i].Trim() : "");
if (text2.Length > 0)
{
list.Add(text2);
}
}
if (list.Count > 0)
{
_phrases = list.ToArray();
}
}
catch
{
_phrases = new string[1] { "Hold your hand, outsider." };
}
}
private static void ResolveHandles()
{
try
{
FR_TargetCreature = AccessTools.FieldRefAccess<MonsterAI, Character>("m_targetCreature");
FR_TargetCreatureOk = true;
}
catch
{
FR_TargetCreatureOk = false;
FR_TargetCreature = null;
}
Type typeFromHandle = typeof(MonsterAI);
FI_Alerted = AccessTools.Field(typeFromHandle, "m_alerted");
FI_Aggravated = AccessTools.Field(typeFromHandle, "m_aggravated");
FI_LastKnownTargetPos = AccessTools.Field(typeFromHandle, "m_lastKnownTargetPos");
FI_TargetStatic = AccessTools.Field(typeFromHandle, "m_targetStatic");
FI_UpdateTargetTimer = AccessTools.Field(typeFromHandle, "m_updateTargetTimer");
MI_SetAlertedBool = AccessTools.Method(typeof(BaseAI), "SetAlerted", new Type[1] { typeof(bool) }, (Type[])null);
MI_GetTargetCreature = AccessTools.Method(typeof(BaseAI), "GetTargetCreature", Type.EmptyTypes, (Type[])null);
MI_FindEnemy = AccessTools.Method(typeof(BaseAI), "FindEnemy", Type.EmptyTypes, (Type[])null);
MI_SetTarget = AccessTools.Method(typeof(MonsterAI), "SetTarget", new Type[1] { typeof(Character) }, (Type[])null);
MI_UpdateAI = AccessTools.Method(typeof(MonsterAI), "UpdateAI", new Type[1] { typeof(float) }, (Type[])null);
MI_CharacterDamage = ResolveCharacterDamageHitData();
}
private static MethodInfo ResolveCharacterDamageHitData()
{
try
{
Type typeFromHandle = typeof(Character);
MethodInfo[] methods = typeFromHandle.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (MethodInfo methodInfo in methods)
{
if (!(methodInfo == null) && !(methodInfo.Name != "Damage"))
{
ParameterInfo[] parameters = methodInfo.GetParameters();
if (parameters.Length == 1 && parameters[0].ParameterType.Name == "HitData")
{
return methodInfo;
}
}
}
}
catch
{
}
return null;
}
private void ApplyPatches()
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Expected O, but got Unknown
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Expected O, but got Unknown
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Expected O, but got Unknown
if (MI_FindEnemy != null)
{
_harmony.Patch((MethodBase)MI_FindEnemy, (HarmonyMethod)null, new HarmonyMethod(typeof(DvergrDiplomacyTruceWedge), "FindEnemy_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
if (MI_SetTarget != null)
{
_harmony.Patch((MethodBase)MI_SetTarget, new HarmonyMethod(typeof(DvergrDiplomacyTruceWedge), "SetTarget_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
if (MI_UpdateAI != null)
{
_harmony.Patch((MethodBase)MI_UpdateAI, new HarmonyMethod(typeof(DvergrDiplomacyTruceWedge), "UpdateAI_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
if (MI_CharacterDamage != null)
{
_harmony.Patch((MethodBase)MI_CharacterDamage, new HarmonyMethod(typeof(DvergrDiplomacyTruceWedge), "CharacterDamage_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
else
{
Log.LogWarning((object)"[DD_TRUCEWEDGE_0.3.117_CLEAN] Could not resolve Character.Damage(HitData). Forgiveness will not detect attacks.");
}
}
private static bool IsServer()
{
try
{
return (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer();
}
catch
{
return false;
}
}
private static long NowMs()
{
try
{
double num = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetTimeSeconds() : ((double)Time.realtimeSinceStartup));
if (num < 0.0)
{
num = 0.0;
}
return (long)(num * 1000.0);
}
catch
{
return (long)((double)Time.realtimeSinceStartup * 1000.0);
}
}
private bool ShouldAct(Character owner)
{
if (!EnabledNow())
{
return false;
}
if (_traceAllAis != null && _traceAllAis.Value)
{
return true;
}
return IsDverger(owner);
}
private static bool IsDverger(Character c)
{
if ((Object)(object)c == (Object)null)
{
return false;
}
try
{
string text = ((object)(Faction)(ref c.m_faction)).ToString();
if (!string.IsNullOrEmpty(text) && text.IndexOf("Dverger", StringComparison.OrdinalIgnoreCase) >= 0)
{
return true;
}
}
catch
{
}
try
{
string text2 = ((Object)c).name ?? "";
if (text2.IndexOf("dver", StringComparison.OrdinalIgnoreCase) >= 0)
{
return true;
}
}
catch
{
}
return false;
}
private static bool IsPlayerChar(Character c)
{
if ((Object)(object)c == (Object)null)
{
return false;
}
try
{
return c.IsPlayer();
}
catch
{
return (Object)(object)((c is Player) ? c : null) != (Object)null;
}
}
private static long GetStablePlayerId(Player p)
{
if ((Object)(object)p == (Object)null)
{
return 0L;
}
try
{
return p.GetPlayerID();
}
catch
{
return 0L;
}
}
private bool ShouldLog(int aiId)
{
if (_logEnabled == null || !_logEnabled.Value)
{
return false;
}
float num = Mathf.Max(0.1f, (_perAiLogEverySeconds != null) ? _perAiLogEverySeconds.Value : 1f);
float time = Time.time;
if (NextLogAtByAiId.TryGetValue(aiId, out var value) && time < value)
{
return false;
}
NextLogAtByAiId[aiId] = time + num;
return true;
}
private void ClientMessage(string msg)
{
if (_showMessagesClient == null || !_showMessagesClient.Value)
{
return;
}
try
{
if ((Object)(object)MessageHud.instance != (Object)null)
{
MessageHud.instance.ShowMessage((MessageType)2, msg, 0, (Sprite)null, false);
}
}
catch
{
}
}
private void PopupForgiven()
{
if (_phrases == null || _phrases.Length == 0)
{
ClientMessage("Hold your hand, outsider.");
return;
}
int num = 0;
try
{
num = _rng.Next(0, _phrases.Length);
}
catch
{
num = 0;
}
string msg = _phrases[num] ?? "Hold your hand, outsider.";
ClientMessage(msg);
}
private bool IsHostileActive(long playerId, long nowMs)
{
if (playerId == 0L)
{
return false;
}
lock (_lock)
{
if (HostileUntilMsByPlayerId.TryGetValue(playerId, out var value))
{
return nowMs < value;
}
}
return false;
}
private void EnsureJoinGrace(long playerId, long nowMs, string reason)
{
if (playerId == 0L)
{
return;
}
long num = nowMs + (long)(Mathf.Max(0.1f, _joinGraceSeconds.Value) * 1000f);
bool flag = false;
lock (_lock)
{
if (!JoinGraceUntilMsByPlayerId.TryGetValue(playerId, out var value) || value < nowMs)
{
JoinGraceUntilMsByPlayerId[playerId] = num;
flag = true;
}
}
if (flag && IsServer())
{
Log.LogInfo((object)string.Format("[{0}] JOIN-GRACE start playerId={1} untilMs={2} reason={3}", "DD_TRUCEWEDGE_0.3.117_CLEAN", playerId, num, reason));
}
}
private int GetStrikeCountResetIfExpired(long playerId, long nowMs)
{
if (playerId == 0L)
{
return 0;
}
lock (_lock)
{
StrikeGraceUntilMsByPlayerId.TryGetValue(playerId, out var value);
if (value != 0L && nowMs > value)
{
StrikeCountByPlayerId[playerId] = 0;
StrikeGraceUntilMsByPlayerId[playerId] = 0L;
}
StrikeCountByPlayerId.TryGetValue(playerId, out var value2);
return value2;
}
}
private void SetStrikeCount(long playerId, int strikes)
{
if (playerId == 0L)
{
return;
}
lock (_lock)
{
StrikeCountByPlayerId[playerId] = strikes;
}
}
private void EnsureForgivenessWindow(long playerId, long nowMs)
{
if (playerId == 0L)
{
return;
}
long num = (long)(Mathf.Max(1f, _forgivenessWindowSeconds.Value) * 1000f);
long value = nowMs + num;
lock (_lock)
{
StrikeGraceUntilMsByPlayerId[playerId] = value;
}
}
private void StartHostile(long playerId, long nowMs, string reason)
{
if (playerId != 0L)
{
long num = nowMs + (long)(Mathf.Max(1f, _hostileSeconds.Value) * 1000f);
lock (_lock)
{
HostileUntilMsByPlayerId[playerId] = num;
StrikeCountByPlayerId[playerId] = 0;
StrikeGraceUntilMsByPlayerId[playerId] = 0L;
JoinGraceUntilMsByPlayerId[playerId] = 0L;
}
if (IsServer())
{
Log.LogInfo((object)string.Format("[{0}] HOSTILE START playerId={1} untilMs={2} reason={3}", "DD_TRUCEWEDGE_0.3.117_CLEAN", playerId, num, reason));
}
}
}
private bool ShouldWedgeProtect(long playerId, long nowMs)
{
if (playerId == 0L)
{
return true;
}
return !IsHostileActive(playerId, nowMs);
}
private void ActivateOrRefreshWedge(int aiId, long playerId, long nowMs, string reason)
{
long num = nowMs + (long)(Mathf.Max(0.1f, _calmHoldSeconds.Value) * 1000f);
lock (_lock)
{
ActivatedAiIds.Add(aiId);
CalmLockUntilMsByAiId[aiId] = num;
AiPlayerIdByAiId[aiId] = playerId;
}
if (IsServer() && ShouldLog(aiId))
{
Log.LogInfo((object)string.Format("[{0}] WEDGE ENGAGE aiId={1} playerId={2} untilMs={3} reason={4}", "DD_TRUCEWEDGE_0.3.117_CLEAN", aiId, playerId, num, reason));
}
}
private void ReleaseWedge(int aiId, string reason)
{
lock (_lock)
{
ActivatedAiIds.Remove(aiId);
CalmLockUntilMsByAiId.Remove(aiId);
AiPlayerIdByAiId.Remove(aiId);
}
if (IsServer() && ShouldLog(aiId))
{
Log.LogInfo((object)string.Format("[{0}] WEDGE RELEASE aiId={1} reason={2}", "DD_TRUCEWEDGE_0.3.117_CLEAN", aiId, reason));
}
}
private void ForceNeutral(MonsterAI ai)
{
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
try
{
try
{
if (FI_Alerted != null)
{
FI_Alerted.SetValue(ai, false);
}
}
catch
{
}
try
{
if (FI_Aggravated != null)
{
FI_Aggravated.SetValue(ai, false);
}
}
catch
{
}
try
{
if (FI_LastKnownTargetPos != null)
{
FI_LastKnownTargetPos.SetValue(ai, Vector3.zero);
}
}
catch
{
}
try
{
if (FI_TargetStatic != null)
{
FI_TargetStatic.SetValue(ai, null);
}
}
catch
{
}
try
{
if (FI_UpdateTargetTimer != null)
{
FI_UpdateTargetTimer.SetValue(ai, Mathf.Max(0f, _updateTargetHoldSeconds.Value));
}
}
catch
{
}
if (FR_TargetCreatureOk && FR_TargetCreature != null)
{
try
{
FR_TargetCreature.Invoke(ai) = null;
}
catch
{
}
}
try
{
if (MI_SetAlertedBool != null)
{
MI_SetAlertedBool.Invoke(ai, new object[1] { false });
}
}
catch
{
}
}
catch
{
}
}
private static Character GetTargetCreature(MonsterAI ai)
{
if ((Object)(object)ai == (Object)null)
{
return null;
}
if (FR_TargetCreatureOk && FR_TargetCreature != null)
{
try
{
return FR_TargetCreature.Invoke(ai);
}
catch
{
}
}
if (MI_GetTargetCreature != null)
{
try
{
object? obj2 = MI_GetTargetCreature.Invoke(ai, null);
return (Character)((obj2 is Character) ? obj2 : null);
}
catch
{
}
}
return null;
}
public static void FindEnemy_Postfix(BaseAI __instance, ref Character __result)
{
try
{
if ((Object)(object)Self == (Object)null || (Object)(object)__instance == (Object)null || (Object)(object)__result == (Object)null || !Self.EnabledNow())
{
return;
}
Character component = ((Component)__instance).GetComponent<Character>();
if (!Self.ShouldAct(component) || !IsPlayerChar(__result))
{
return;
}
Character obj = __result;
Player val = (Player)(object)((obj is Player) ? obj : null);
if (!((Object)(object)val == (Object)null))
{
long nowMs = NowMs();
long stablePlayerId = GetStablePlayerId(val);
if (IsServer() && Self._serverTriggerOnFindEnemy != null && Self._serverTriggerOnFindEnemy.Value)
{
Self.EnsureJoinGrace(stablePlayerId, nowMs, "FindEnemy");
}
if (Self.ShouldWedgeProtect(stablePlayerId, nowMs))
{
int instanceID = ((Object)__instance).GetInstanceID();
Self.ActivateOrRefreshWedge(instanceID, stablePlayerId, nowMs, "FindEnemy->Player");
__result = null;
}
}
}
catch
{
}
}
public static bool SetTarget_Prefix(MonsterAI __instance, Character attacker)
{
try
{
if ((Object)(object)Self == (Object)null)
{
return true;
}
if ((Object)(object)__instance == (Object)null || (Object)(object)attacker == (Object)null)
{
return true;
}
if (!Self.EnabledNow())
{
return true;
}
Character component = ((Component)__instance).GetComponent<Character>();
if (!Self.ShouldAct(component))
{
return true;
}
if (!IsPlayerChar(attacker))
{
return true;
}
Player val = (Player)(object)((attacker is Player) ? attacker : null);
if ((Object)(object)val == (Object)null)
{
return true;
}
long nowMs = NowMs();
long stablePlayerId = GetStablePlayerId(val);
if (IsServer() && Self._serverTriggerOnSetTarget != null && Self._serverTriggerOnSetTarget.Value)
{
Self.EnsureJoinGrace(stablePlayerId, nowMs, "SetTarget");
}
if (Self.ShouldWedgeProtect(stablePlayerId, nowMs))
{
int instanceID = ((Object)__instance).GetInstanceID();
Self.ActivateOrRefreshWedge(instanceID, stablePlayerId, nowMs, "SetTarget->Player");
Self.ForceNeutral(__instance);
return false;
}
return true;
}
catch
{
return true;
}
}
public static void UpdateAI_Prefix(MonsterAI __instance, float dt)
{
//IL_025e: Unknown result type (might be due to invalid IL or missing references)
//IL_0263: Unknown result type (might be due to invalid IL or missing references)
//IL_029e: Unknown result type (might be due to invalid IL or missing references)
//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
try
{
if ((Object)(object)Self == (Object)null || (Object)(object)__instance == (Object)null || !Self.EnabledNow())
{
return;
}
Character component = ((Component)__instance).GetComponent<Character>();
if (!Self.ShouldAct(component))
{
return;
}
int instanceID = ((Object)__instance).GetInstanceID();
if (!IsServer() && Self._clientSimWarning != null && Self._clientSimWarning.Value)
{
bool flag;
lock (_lock)
{
flag = ClientSimWarnedAiIds.Add(instanceID);
}
if (flag)
{
Log.LogWarning((object)string.Format("[{0}] CLIENT-SIM WARNING aiId={1} ownerGO='{2}'.", "DD_TRUCEWEDGE_0.3.117_CLEAN", instanceID, ((Object)(object)component != (Object)null && (Object)(object)((Component)component).gameObject != (Object)null) ? ((Object)((Component)component).gameObject).name : (((Object)(object)component != (Object)null) ? ((Object)component).name : "(null)")));
}
}
long num = NowMs();
Character targetCreature = GetTargetCreature(__instance);
Player val = (Player)(object)((targetCreature is Player) ? targetCreature : null);
if ((Object)(object)val != (Object)null)
{
long stablePlayerId = GetStablePlayerId(val);
Self.EnsureJoinGrace(stablePlayerId, num, "UpdateAI(TargetPlayer)");
if (Self.ShouldWedgeProtect(stablePlayerId, num))
{
Self.ActivateOrRefreshWedge(instanceID, stablePlayerId, num, "UpdateAI(SafetyNet)");
Self.ForceNeutral(__instance);
return;
}
}
bool flag2;
long value;
long value2;
lock (_lock)
{
flag2 = ActivatedAiIds.Contains(instanceID);
AiPlayerIdByAiId.TryGetValue(instanceID, out value);
CalmLockUntilMsByAiId.TryGetValue(instanceID, out value2);
}
if (!flag2)
{
return;
}
if (!Self.ShouldWedgeProtect(value, num))
{
Self.ReleaseWedge(instanceID, "HostileActive");
return;
}
bool flag3 = false;
bool flag4 = false;
Vector3 val2 = Vector3.zero;
object obj = null;
try
{
if (FI_Alerted != null)
{
flag3 = (bool)FI_Alerted.GetValue(__instance);
}
}
catch
{
}
try
{
if (FI_Aggravated != null)
{
flag4 = (bool)FI_Aggravated.GetValue(__instance);
}
}
catch
{
}
try
{
if (FI_LastKnownTargetPos != null)
{
val2 = (Vector3)FI_LastKnownTargetPos.GetValue(__instance);
}
}
catch
{
}
try
{
if (FI_TargetStatic != null)
{
obj = FI_TargetStatic.GetValue(__instance);
}
}
catch
{
}
bool flag5 = (Object)(object)targetCreature != (Object)null;
if (flag3 || flag4 || obj != null || val2 != Vector3.zero || flag5)
{
long num2 = num + (long)(Mathf.Max(0.1f, Self._calmHoldSeconds.Value) * 1000f);
lock (_lock)
{
CalmLockUntilMsByAiId[instanceID] = num2;
}
value2 = num2;
}
if (num < value2)
{
Self.ForceNeutral(__instance);
}
}
catch
{
}
}
public static void CharacterDamage_Prefix(Character __instance, object hit)
{
try
{
if ((Object)(object)Self == (Object)null || !Self.EnabledNow() || (Object)(object)__instance == (Object)null || !IsDverger(__instance))
{
return;
}
Character val = null;
try
{
if (hit != null)
{
MethodInfo method = hit.GetType().GetMethod("GetAttacker", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (method != null)
{
object? obj = method.Invoke(hit, null);
val = (Character)((obj is Character) ? obj : null);
}
}
}
catch
{
val = null;
}
Player val2 = (Player)(object)((val is Player) ? val : null);
if ((Object)(object)val2 == (Object)null)
{
return;
}
long nowMs = NowMs();
long stablePlayerId = GetStablePlayerId(val2);
if (Self.IsHostileActive(stablePlayerId, nowMs))
{
return;
}
int strikeCountResetIfExpired = Self.GetStrikeCountResetIfExpired(stablePlayerId, nowMs);
int num = Mathf.Max(0, Self._forgivenessFreeStrikes.Value);
int num2 = strikeCountResetIfExpired + 1;
Self.EnsureForgivenessWindow(stablePlayerId, nowMs);
Self.SetStrikeCount(stablePlayerId, num2);
Self.EnsureJoinGrace(stablePlayerId, nowMs, "Strike");
if (num2 <= num)
{
if (!IsServer())
{
if ((Object)(object)Player.m_localPlayer != (Object)null && GetStablePlayerId(Player.m_localPlayer) == stablePlayerId)
{
Self.PopupForgiven();
}
}
else
{
Log.LogInfo((object)string.Format("[{0}] STRIKE FORGIVEN playerId={1} strike={2}/{3}", "DD_TRUCEWEDGE_0.3.117_CLEAN", stablePlayerId, num2, num));
}
}
else if (IsServer())
{
Self.StartHostile(stablePlayerId, nowMs, "SecondStrike");
}
else
{
Self.StartHostile(stablePlayerId, nowMs, "SecondStrike(client)");
}
}
catch
{
}
}
private void TryRegisterRpcs()
{
if (_rpcsRegistered || _spawnTestEnabled == null || !_spawnTestEnabled.Value)
{
return;
}
try
{
if (ZRoutedRpc.instance != null)
{
if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
{
ZRoutedRpc.instance.Register<ZPackage>("DD_SpawnDverger_Test", (Action<long, ZPackage>)RPC_ServerSpawnDvergerTest);
Log.LogInfo((object)"[DD_TRUCEWEDGE_0.3.117_CLEAN] Registered RPC DD_SpawnDverger_Test");
}
_rpcsRegistered = true;
}
}
catch
{
}
}
private void TryRegisterConsoleCommand()
{
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//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_0048: Expected O, but got Unknown
if (_consoleRegistered || _spawnTestEnabled == null || !_spawnTestEnabled.Value)
{
return;
}
try
{
object obj = <>c.<>9__85_0;
if (obj == null)
{
ConsoleEvent val = delegate(ConsoleEventArgs args)
{
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Expected O, but got Unknown
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
try
{
if ((Object)(object)Player.m_localPlayer == (Object)null)
{
args.Context.AddString("No local player.");
}
else if ((Object)(object)ZNet.instance == (Object)null || ZRoutedRpc.instance == null)
{
args.Context.AddString("Network not ready.");
}
else
{
Vector3 val2 = ((Component)Player.m_localPlayer).transform.position + ((Component)Player.m_localPlayer).transform.forward * 2f;
ZPackage val3 = new ZPackage();
val3.Write(val2);
val3.Write(Quaternion.identity);
ZRoutedRpc.instance.InvokeRoutedRPC(0L, "DD_SpawnDverger_Test", new object[1] { val3 });
args.Context.AddString("Requested server spawn.");
}
}
catch (Exception ex)
{
args.Context.AddString("dd_spawn_dverger failed: " + ex.Message);
}
};
<>c.<>9__85_0 = val;
obj = (object)val;
}
new ConsoleCommand("dd_spawn_dverger", "Ask the server to spawn a Dverger near you.", (ConsoleEvent)obj, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
_consoleRegistered = true;
Log.LogInfo((object)"[DD_TRUCEWEDGE_0.3.117_CLEAN] Registered console command dd_spawn_dverger");
}
catch
{
}
}
private static void RPC_ServerSpawnDvergerTest(long sender, ZPackage pkg)
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
try
{
if (!((Object)(object)Self == (Object)null) && !((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer())
{
Vector3 pos = pkg.ReadVector3();
Quaternion rot = pkg.ReadQuaternion();
SpawnDvergerServer(pos, rot, "RPC(sender=" + sender + ")");
}
}
catch
{
}
}
private static void SpawnDvergerServer(Vector3 pos, Quaternion rot, string reason)
{
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
try
{
if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || (Object)(object)ZNetScene.instance == (Object)null)
{
return;
}
GameObject prefab = ZNetScene.instance.GetPrefab("Dverger");
if ((Object)(object)prefab == (Object)null)
{
prefab = ZNetScene.instance.GetPrefab("DvergerArbalest");
}
if ((Object)(object)prefab == (Object)null)
{
ManualLogSource log = Log;
if (log != null)
{
log.LogWarning((object)("[DD_TRUCEWEDGE_0.3.117_CLEAN] Dverger prefab not found (" + reason + ")"));
}
return;
}
GameObject val = Object.Instantiate<GameObject>(prefab, pos, rot);
ZNetView component = val.GetComponent<ZNetView>();
if ((Object)(object)component != (Object)null && component.IsValid() && !component.IsOwner())
{
component.ClaimOwnership();
}
ManualLogSource log2 = Log;
if (log2 != null)
{
log2.LogInfo((object)string.Format("[{0}] Server spawned Dverger ({1}) at {2}", "DD_TRUCEWEDGE_0.3.117_CLEAN", reason, pos));
}
}
catch
{
}
}
}