using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.Json;
using System.Text.Json.Serialization;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using SOD.Common;
using SOD.Common.BepInEx;
using SOD.Common.BepInEx.Configuration;
using SOD.Common.Extensions;
using SOD.Common.Helpers;
using SOD.RelationsPlus.Objects;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("SOD.RelationsPlus")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+105368c6fd0dd8757a25de203851c1af249c7651")]
[assembly: AssemblyProduct("SOD.RelationsPlus")]
[assembly: AssemblyTitle("SOD.RelationsPlus")]
[assembly: AssemblyVersion("1.0.0.0")]
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;
}
}
}
namespace SOD.RelationsPlus
{
public interface IPluginBindings : IRelationGateBindings, IDecayModifierBindings, ISeenModifierBindings, IKnowModifierBindings, ILikeModifierBindings
{
[Binding(false, "Debug mode shows extra logging to track relational changes between citizens and the player.", null)]
bool DebugMode { get; set; }
}
public interface IRelationGateBindings
{
[Binding(0.2f, "The first gate, (0 -> GateOneValue): The player is a stranger to the citizen.", "Relation.Gates.KnowGateOne")]
float KnowGateOne { get; set; }
[Binding(0.4f, "The second gate, (GateOneValue -> GateTwoValue): The citizen becomes aware of the player.", "Relation.Gates.KnowGateTwo")]
float KnowGateTwo { get; set; }
[Binding(0.6f, "The third gate, (GateTwoValue -> GateThreeValue): The citizen becomes familiar with the player.", "Relation.Gates.KnowGateThree")]
float KnowGateThree { get; set; }
[Binding(0.8f, "The fourth gate, (GateThreeValue -> GateFourValue): The citizen knows the player.", "Relation.Gates.KnowGateFour")]
float KnowGateFour { get; set; }
[Binding(1f, "The fifth gate, (GateFourValue -> GateFiveValue): The citizen knows the player very well. (CANNOT BE MODIFIED)", "Relation.Gates.KnowGateFive")]
float KnowGateFive { get; set; }
[Binding(0.2f, "The first gate, (0 -> GateOneValue): The citizen hates the player.", "Relation.Gates.LikeGateOne")]
float LikeGateOne { get; set; }
[Binding(0.4f, "The second gate, (GateOneValue -> GateTwoValue): The citizen dislikes the player", "Relation.Gates.LikeGateTwo")]
float LikeGateTwo { get; set; }
[Binding(0.6f, "The third gate, (GateTwoValue -> GateThreeValue): The citizen is neutral towards the player.", "Relation.Gates.LikeGateThree")]
float LikeGateThree { get; set; }
[Binding(0.8f, "The fourth gate, (GateThreeValue -> GateFourValue): The citizen likes the player.", "Relation.Gates.LikeGateFour")]
float LikeGateFour { get; set; }
[Binding(1f, "The fifth gate, (GateFourValue -> GateFiveValue): The citizen loves the player. (CANNOT BE MODIFIED)", "Relation.Gates.LikeGateFive")]
float LikeGateFive { get; set; }
}
public interface IDecayModifierBindings
{
[Binding(60, "After how many in-game minutes is the decay check executed each time?", "Modifiers.Decay.DecayTimeMinutesCheck")]
int DecayTimeMinutesCheck { get; set; }
[Binding(120, "After how many in-game minutes that the citizen hasn't seen the player should decay start? (both 'Know' and 'Like' if enabled)", "Modifiers.Decay.DecayKnowAfterUnseenMinutes")]
int DecayKnowAfterUnseenMinutes { get; set; }
[Binding(-0.005f, "How much does 'Know' decay automatically? (cannot decay past certain stages of 'Know')", "Modifiers.Decay.DecayKnowAmount")]
float DecayKnowAmount { get; set; }
[Binding(false, "Can the automatic decay of 'Know' go past the relation stages once reached.", "Modifiers.Decay.AllowDecayPastRelationGates")]
bool AllowDecayPastKnowGates { get; set; }
[Binding(false, "Can 'Like' automatically decay back to neutral?", "Modifiers.Decay.AllowDecayLikeToNeutral")]
bool AllowDecayLikeToNeutral { get; set; }
[Binding(-0.0025f, "How much does 'Like' decay automatically? (cannot decay past neutral)", "Modifiers.Decay.DecayLikeAmount")]
float DecayLikeAmount { get; set; }
[Binding(0.0035f, "How much does 'Like' improve automatically back to neutral (0.5)?", "Modifiers.Decay.ImproveLikeAmount")]
float ImproveLikeAmount { get; set; }
[Binding(true, "Can 'Like' automatically improve back to neutral (0.5) when it is under neutral?", "Modifiers.Decay.AutoImproveLike")]
bool AllowAutoImproveLikeToNeutral { get; set; }
}
public interface ISeenModifierBindings
{
[Binding(10, "How often a check is executed per citizen in in-game minutes if they see the player.", "Modifiers.Seen.SeenTimeMinutesCheck")]
int SeenTimeMinutesCheck { get; set; }
}
public interface IKnowModifierBindings
{
[Binding(0.01f, "How much the \"Know\" property changes for the citizen and player when seen passing by on the street.", "Modifiers.Know.SeenOnStreetModifier")]
float SeenOnStreetModifier { get; set; }
[Binding(0.02f, "How much the \"Know\" property changes for the citizen and player when seen at their workplace.", "Modifiers.Know.SeenAtWorkplaceModifier")]
float SeenAtWorkplaceModifier { get; set; }
[Binding(0.035f, "How much the \"Know\" property changes for the citizen and player when seen inside their home.", "Modifiers.Know.SeenInHome")]
float SeenInHomeModifier { get; set; }
[Binding(0.025f, "How much the \"Know\" property changes for the citizen and player when seen inside their home's building/apartement.", "Modifiers.Know.SeenInHomeBuilding")]
float SeenInHomeBuildingModifier { get; set; }
[Binding(0.035f, "How much the \"Know\" property changes for the citizen when the player accepts a job for them.", "Modifiers.Know.AcceptedJobKnowModifier")]
float AcceptedJobKnowModifier { get; set; }
[Binding(0.015f, "How much the \"Know\" property changes for the citizen and player when they talk to eachother.", "Modifiers.Know.SpeakingToCitizenModifier")]
float SpeakingToCitizenModifier { get; set; }
}
public interface ILikeModifierBindings
{
[Binding(-0.05f, "How much the \"Like\" property changes for the citizen and player when seen trespassing.", "Modifiers.Like.SeenTrespassingModifier")]
float SeenTrespassingModifier { get; set; }
[Binding(-0.05f, "How much the \"Like\" property changes for the citizen when they see the player doing something illegal.", "Modifiers.Like.SeenDoingIllegalModifier")]
float SeenDoingIllegalModifier { get; set; }
[Binding(0.125f, "How much the \"Like\" property changes for the citizen when the player solves a job from them.", "Modifiers.Like.SolvedJobModifier")]
float SolvedJobModifier { get; set; }
[Binding(-0.065f, "How much the \"Like\" property changes for the citizen when the player fails a job from them.", "Modifiers.Like.FailedJobModifier")]
float FailedJobModifier { get; set; }
[Binding(-0.1f, "How much the \"Like\" property changes for the citizen when the player fails a job from them.", "Modifiers.Like.OnAttackCitizenModifier")]
float OnAttackCitizenModifier { get; set; }
[Binding(0.025f, "How much the \"Know\" property changes for the citizen when the player accepts a job for them.", "Modifiers.Know.AcceptedJobLikeModifier")]
float AcceptedJobLikeModifier { get; set; }
}
[BepInPlugin("Venomaus.SOD.RelationsPlus", "RelationsPlus", "1.0.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : PluginController<Plugin, IPluginBindings>
{
public const string PLUGIN_GUID = "Venomaus.SOD.RelationsPlus";
public const string PLUGIN_NAME = "RelationsPlus";
public const string PLUGIN_VERSION = "1.0.1";
public override void Load()
{
base.Harmony.PatchAll(Assembly.GetExecutingAssembly());
PluginController<Plugin, IPluginBindings>.Log.LogInfo((object)"Plugin is patched.");
Lib.SaveGame.OnBeforeNewGame += delegate
{
RelationManager.Instance.Clear();
};
Lib.SaveGame.OnBeforeLoad += delegate(object? sender, SaveGameArgs e)
{
RelationManager.Instance.Load(Lib.SaveGame.GetUniqueString(e.FilePath));
};
Lib.SaveGame.OnBeforeSave += delegate(object? sender, SaveGameArgs e)
{
RelationManager.Instance.Save(Lib.SaveGame.GetUniqueString(e.FilePath));
};
Lib.SaveGame.OnBeforeDelete += delegate(object? sender, SaveGameArgs e)
{
RelationManager.Delete(Lib.SaveGame.GetUniqueString(e.FilePath));
};
Lib.Time.OnMinuteChanged += RelationManager.Instance.Timed_DecayLogic;
}
public override void OnConfigureBindings()
{
base.OnConfigureBindings();
base.UpdateConfigFileLayout();
base.Config.LikeGateFive = 1f;
base.Config.KnowGateFive = 1f;
}
}
public sealed class RelationManager : IEnumerable<CitizenRelation>, IEnumerable
{
internal enum EventName
{
KnowChange,
LikeChange,
Seen
}
private static RelationManager _instance;
private readonly Dictionary<int, CitizenRelation> _relationMatrixes = new Dictionary<int, CitizenRelation>();
private int _lastDecayCheckMinute;
public static RelationManager Instance => _instance ?? (_instance = new RelationManager());
public CitizenRelation this[int citizenId] => GetOrCreate(citizenId);
internal bool IsLoading { get; private set; }
public event EventHandler<RelationChangeArgs> OnKnowChanged;
public event EventHandler<RelationChangeArgs> OnLikeChanged;
public event EventHandler<SeenPlayerArgs> OnPlayerSeen;
private RelationManager()
{
}
public bool TryGetValue(int citizenId, out CitizenRelation relation)
{
return _relationMatrixes.TryGetValue(citizenId, out relation);
}
public bool ContainsKey(int citizenId)
{
return _relationMatrixes.ContainsKey(citizenId);
}
public void Remove(int citizenId)
{
_relationMatrixes.Remove(citizenId);
}
public CitizenRelation GetOrCreate(int citizenId)
{
if (!_relationMatrixes.TryGetValue(citizenId, out var value))
{
value = (_relationMatrixes[citizenId] = new CitizenRelation(citizenId));
}
return value;
}
public void Clear()
{
_lastDecayCheckMinute = 0;
_relationMatrixes.Clear();
}
public IEnumerator<CitizenRelation> GetEnumerator()
{
return _relationMatrixes.Values.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
internal void AddOrReplace(CitizenRelation relation)
{
_relationMatrixes[relation.CitizenId] = relation;
}
internal void RaiseEvent(EventName eventName, EventArgs args)
{
switch (eventName)
{
case EventName.KnowChange:
this.OnKnowChanged?.Invoke(this, args as RelationChangeArgs);
return;
case EventName.LikeChange:
this.OnLikeChanged?.Invoke(this, args as RelationChangeArgs);
return;
case EventName.Seen:
this.OnPlayerSeen?.Invoke(this, args as SeenPlayerArgs);
return;
}
throw new NotSupportedException($"Event ({eventName}) \"{eventName}\" not supported.");
}
internal void Load(string hash)
{
IsLoading = true;
string savestoreDirectoryPath = Lib.SaveGame.GetSavestoreDirectoryPath(Assembly.GetExecutingAssembly(), "RelationsPlusData_" + hash + ".json");
Clear();
if (File.Exists(savestoreDirectoryPath))
{
CitizenSaveData citizenSaveData = JsonSerializer.Deserialize<CitizenSaveData>(File.ReadAllText(savestoreDirectoryPath));
_lastDecayCheckMinute = citizenSaveData.LastDecayCheckMinute;
foreach (KeyValuePair<int, CitizenRelation> item in citizenSaveData.RelationMatrix)
{
_relationMatrixes.Add(item.Key, item.Value);
}
PluginController<Plugin, IPluginBindings>.Log.LogInfo((object)"Loaded citizen relations.");
}
IsLoading = false;
}
internal void Save(string hash)
{
string savestoreDirectoryPath = Lib.SaveGame.GetSavestoreDirectoryPath(Assembly.GetExecutingAssembly(), "RelationsPlusData_" + hash + ".json");
if (!_relationMatrixes.Any())
{
if (File.Exists(savestoreDirectoryPath))
{
File.Delete(savestoreDirectoryPath);
PluginController<Plugin, IPluginBindings>.Log.LogInfo((object)"Deleted citizen relations.");
}
}
else
{
string contents = JsonSerializer.Serialize(new CitizenSaveData
{
RelationMatrix = _relationMatrixes,
LastDecayCheckMinute = _lastDecayCheckMinute
}, new JsonSerializerOptions
{
WriteIndented = false
});
File.WriteAllText(savestoreDirectoryPath, contents);
PluginController<Plugin, IPluginBindings>.Log.LogInfo((object)"Saved citizen relations.");
}
}
internal static void Delete(string hash)
{
string savestoreDirectoryPath = Lib.SaveGame.GetSavestoreDirectoryPath(Assembly.GetExecutingAssembly(), "RelationsPlusData_" + hash + ".json");
if (File.Exists(savestoreDirectoryPath))
{
File.Delete(savestoreDirectoryPath);
PluginController<Plugin, IPluginBindings>.Log.LogInfo((object)"Deleted citizen relations.");
}
}
internal void Timed_DecayLogic(object sender, TimeChangedArgs e)
{
//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
if (_lastDecayCheckMinute >= ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.DecayTimeMinutesCheck)
{
_lastDecayCheckMinute = 0;
float decayKnowAmount = ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.DecayKnowAmount;
int decayKnowAfterUnseenMinutes = ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.DecayKnowAfterUnseenMinutes;
bool allowAutoImproveLikeToNeutral = ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.AllowAutoImproveLikeToNeutral;
float improveLikeAmount = ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.ImproveLikeAmount;
float decayLikeAmount = ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.DecayLikeAmount;
bool allowDecayLikeToNeutral = ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.AllowDecayLikeToNeutral;
bool debugMode = ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.DebugMode;
if (debugMode)
{
PluginController<Plugin, IPluginBindings>.Log.LogInfo((object)"[Debug]: Start decay process.");
}
foreach (CitizenRelation value2 in _relationMatrixes.Values)
{
if (!value2.LastSeenGameTime.HasValue)
{
continue;
}
TimeData value = value2.LastSeenGameTime.Value;
if (((TimeData)(ref value)).AddMinutes(decayKnowAfterUnseenMinutes) <= Lib.Time.CurrentDateTime)
{
float currentKnowGate = GetCurrentKnowGate(value2);
value2.Know = Mathf.Clamp(value2.Know + decayKnowAmount, currentKnowGate, 1f);
if (allowDecayLikeToNeutral && value2.Like > 0.5f)
{
value2.Like = Mathf.Clamp(value2.Like + decayLikeAmount, 0.5f, 1f);
}
}
if (allowAutoImproveLikeToNeutral && value2.Like < 0.5f)
{
value2.Like = Mathf.Clamp(value2.Like + improveLikeAmount, 0f, 0.5f);
}
}
if (debugMode)
{
PluginController<Plugin, IPluginBindings>.Log.LogInfo((object)"[Debug]: Finalized decay process.");
}
}
else
{
_lastDecayCheckMinute++;
}
}
private static float GetCurrentKnowGate(CitizenRelation citizenRelation)
{
if (((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.AllowDecayPastKnowGates)
{
return 0f;
}
float know = citizenRelation.Know;
if (know < ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.KnowGateOne)
{
return 0f;
}
if (know < ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.KnowGateTwo)
{
return ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.KnowGateOne;
}
if (know < ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.KnowGateThree)
{
return ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.KnowGateTwo;
}
if (know < ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.KnowGateFour)
{
return ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.KnowGateThree;
}
return ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.KnowGateFour;
}
}
}
namespace SOD.RelationsPlus.Patches
{
internal class ActorPatches
{
[HarmonyPatch(typeof(Actor), "RecieveDamage")]
internal static class Actor_RecieveDamage
{
[HarmonyPostfix]
internal static void Prefix(Actor __instance, ref float __state)
{
__state = __instance.currentHealth;
}
internal static void Postfix(Actor __instance, float amount, Actor fromWho, ref float __state)
{
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Expected O, but got Unknown
if (amount == 0f || __instance.currentHealth <= 0f || __instance.isStunned || __instance.currentHealth == __state || __instance.isPlayer || (Object)(object)fromWho == (Object)null || !fromWho.isPlayer)
{
return;
}
Human val = null;
try
{
val = ((Il2CppObjectBase)__instance).TryCast<Human>();
}
catch (InvalidCastException)
{
}
if ((Object)(object)val == (Object)null)
{
return;
}
if (((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.DebugMode)
{
ManualLogSource log = PluginController<Plugin, IPluginBindings>.Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(33, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Debug]: ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(val.GetCitizenName());
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" was attacked by player!");
}
log.LogInfo(val2);
}
RelationManager.Instance[val.humanID].Like += ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.OnAttackCitizenModifier;
}
}
}
internal class HumanPatches
{
[HarmonyPatch(typeof(Human), "UpdateLastSighting")]
internal static class Human_UpdateLastSighting
{
[HarmonyPrefix]
internal static void Prefix(Human __instance, Human citizen)
{
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: 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)
//IL_0060: 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_007d: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)citizen == (Object)null || ((Actor)__instance).isMachine || !((Actor)citizen).isPlayer)
{
return;
}
CitizenRelation relation;
bool flag = RelationManager.Instance.TryGetValue(__instance.humanID, out relation);
if (flag && (relation.WasTrespassingLastTimeSeen || !((Actor)citizen).isTrespassing) && relation.LastSeenGameTime.HasValue)
{
TimeData value = relation.LastSeenGameTime.Value;
if (!(((TimeData)(ref value)).AddMinutes(((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.SeenTimeMinutesCheck) <= Lib.Time.CurrentDateTime))
{
return;
}
}
float num = Vector3.Distance(((Actor)__instance).lookAtThisTransform.position, ((Actor)citizen).lookAtThisTransform.position);
float num2 = Mathf.Min(GameplayControls.Instance.citizenSightRange, ((Actor)__instance).stealthDistance);
RaycastHit val = default(RaycastHit);
if (!(num <= num2) || (!(num < GameplayControls.Instance.minimumStealthDetectionRange) && !((Actor)__instance).ActorRaycastCheck((Actor)(object)citizen, num + 3f, ref val, false, Color.green, Color.red, Color.white, 1f)))
{
return;
}
if (relation == null)
{
relation = new CitizenRelation(__instance.humanID);
}
relation.WasTrespassingLastTimeSeen = ((Actor)citizen).isTrespassing;
bool flag2 = (Object)(object)((Actor)__instance).currentRoom != (Object)null && (Object)(object)((Actor)citizen).currentRoom != (Object)null && ((Actor)__instance).currentRoom.roomID == ((Actor)citizen).currentRoom.roomID;
bool flag3 = (Object)(object)((Actor)__instance).currentBuilding != (Object)null && (Object)(object)((Actor)citizen).currentBuilding != (Object)null && ((Actor)__instance).currentBuilding.buildingID == ((Actor)citizen).currentBuilding.buildingID;
bool flag4 = (Object)(object)__instance.home != (Object)null && (Object)(object)((Actor)citizen).currentGameLocation != (Object)null && (Object)(object)((Actor)citizen).currentGameLocation.thisAsAddress != (Object)null && (Object)(object)((Actor)citizen).currentGameLocation.thisAsAddress == (Object)(object)__instance.home;
float know = relation.Know;
float like = relation.Like;
SeenPlayerArgs.SeenLocation seenLocation = (SeenPlayerArgs.SeenLocation)(-1);
if (((Actor)__instance).isAtWork && flag2)
{
relation.Know += ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.SeenAtWorkplaceModifier;
seenLocation = SeenPlayerArgs.SeenLocation.Workplace;
}
else if (((Actor)__instance).isHome && flag2)
{
relation.Know += ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.SeenInHomeModifier;
seenLocation = SeenPlayerArgs.SeenLocation.Home;
}
else if (flag4)
{
relation.Know += ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.SeenInHomeBuildingModifier;
seenLocation = SeenPlayerArgs.SeenLocation.HomeBuilding;
}
else if ((((Actor)__instance).isOnStreet && ((Actor)citizen).isOnStreet) || flag2 || flag3)
{
relation.Know += ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.SeenOnStreetModifier;
seenLocation = SeenPlayerArgs.SeenLocation.Street;
}
if (seenLocation != (SeenPlayerArgs.SeenLocation)(-1))
{
if (((Actor)citizen).isTrespassing)
{
relation.Like += ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.SeenTrespassingModifier;
}
if (!flag)
{
RelationManager.Instance.AddOrReplace(relation);
}
relation.RaiseSeenEvent(seenLocation, know - relation.Know, like - relation.Like);
}
}
}
}
internal class InteractionControllerPatches
{
[HarmonyPatch(typeof(InteractionController), "SetIllegalActionActive")]
internal static class InteractionController_SetIllegalActionActive
{
[HarmonyPostfix]
internal static void Prefix(bool val)
{
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_0115: Expected O, but got Unknown
if (!val)
{
return;
}
Enumerator<Actor> enumerator = CityData.Instance.visibleActors.GetEnumerator();
bool flag = default(bool);
while (enumerator.MoveNext())
{
Actor current = enumerator.Current;
if (current.isMachine || current.isPlayer || !GameExtensions.Sees(current, (Actor)(object)Player.Instance))
{
continue;
}
Human val2 = null;
try
{
val2 = (Human)((dynamic)current).Cast<Human>();
}
catch (InvalidCastException)
{
}
if ((Object)(object)val2 == (Object)null)
{
continue;
}
if (((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.DebugMode)
{
ManualLogSource log = PluginController<Plugin, IPluginBindings>.Log;
BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(35, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Debug]: Illegal activity seen by ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(val2.GetCitizenName());
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("!");
}
log.LogInfo(val3);
}
RelationManager.Instance[val2.humanID].Like += ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.SeenDoingIllegalModifier;
}
}
}
}
internal class NewAIControllerPatches
{
[HarmonyPatch(typeof(NewAIController), "TalkTo")]
internal static class NewAIController_TalkTo
{
[HarmonyPrefix]
internal static void Prefix(ref Interactable __state)
{
__state = ((Actor)Player.Instance).interactingWith;
}
[HarmonyPostfix]
internal static void Postfix(NewAIController __instance, ref Interactable __state)
{
if (((Actor)Player.Instance).interactingWith != null && (__state == null || ((Actor)Player.Instance).interactingWith.id != __state.id))
{
RelationManager.Instance[__instance.human.humanID].Know += ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.SpeakingToCitizenModifier;
}
}
}
}
internal class SideJobPatches
{
[HarmonyPatch(typeof(SideJob), "AcceptJob")]
internal static class SideJob_AcceptJob
{
[HarmonyPrefix]
internal static void Prefix(SideJob __instance, ref bool __state)
{
__state = __instance.accepted;
}
[HarmonyPostfix]
internal static void Postfix(SideJob __instance, ref bool __state)
{
if (!__state && __instance.accepted && (Object)(object)__instance.poster != (Object)null && __instance.posterID > 0)
{
RelationManager.Instance[__instance.posterID].Know += ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.AcceptedJobKnowModifier;
RelationManager.Instance[__instance.posterID].Like += ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.AcceptedJobLikeModifier;
}
}
}
[HarmonyPatch(typeof(Case), "Resolve")]
internal static class Case_Resolve
{
[HarmonyPostfix]
internal static void Postfix(Case __instance)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
if ((int)__instance.caseType == 2 && __instance.job != null && !((Object)(object)__instance.job.poster == (Object)null))
{
if (__instance.isSolved)
{
RelationManager.Instance[__instance.job.posterID].Like += ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.SolvedJobModifier;
}
else
{
RelationManager.Instance[__instance.job.posterID].Like += ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.FailedJobModifier;
}
}
}
}
}
}
namespace SOD.RelationsPlus.Objects
{
public sealed class CitizenRelation
{
public enum KnowStage
{
Stranger,
Aware,
Familiar,
Known,
WellKnown
}
public enum LikeStage
{
Neutral,
Hated,
Disliked,
Liked,
Loved
}
private float _know;
private float _like = 0.5f;
public int CitizenId { get; }
public DateTime? LastSeenRealTime { get; private set; }
public TimeData? LastSeenGameTime { get; private set; }
public bool WasTrespassingLastTimeSeen { get; internal set; }
public float Know
{
get
{
return _know;
}
set
{
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Expected O, but got Unknown
float know = _know;
float num = Mathf.Clamp01(value);
if (_know == num)
{
return;
}
_know = num;
if (RelationManager.Instance.IsLoading)
{
return;
}
if (((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.DebugMode)
{
ManualLogSource log = PluginController<Plugin, IPluginBindings>.Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(75, 5, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Debug]: Citizen(");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(CitizenId);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("|");
Human citizen = GetCitizen();
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((citizen != null) ? citizen.GetCitizenName() : null) ?? "Unknown");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("): Changed 'Know' value from \"");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(know);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\" to \"");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(num);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\" | KnowRelation: \"");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<KnowStage>(GetKnowRelation());
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\".");
}
log.LogInfo(val);
}
RelationChangeArgs relationChangeArgs = null;
this.OnKnowChanged?.Invoke(this, relationChangeArgs ?? (relationChangeArgs = new RelationChangeArgs(CitizenId, know, num)));
RelationManager.Instance.RaiseEvent(RelationManager.EventName.KnowChange, relationChangeArgs ?? new RelationChangeArgs(CitizenId, know, num));
}
}
public float Like
{
get
{
return _like;
}
set
{
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Expected O, but got Unknown
float like = _like;
float num = Mathf.Clamp01(value);
if (_like == num)
{
return;
}
_like = num;
if (RelationManager.Instance.IsLoading)
{
return;
}
if (((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.DebugMode)
{
ManualLogSource log = PluginController<Plugin, IPluginBindings>.Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(75, 5, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Debug]: Citizen(");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(CitizenId);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("|");
Human citizen = GetCitizen();
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((citizen != null) ? citizen.GetCitizenName() : null) ?? "Unknown");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("): Changed 'Like' value from \"");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(like);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\" to \"");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(num);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\" | LikeRelation: \"");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<LikeStage>(GetLikeRelation());
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\".");
}
log.LogInfo(val);
}
RelationChangeArgs relationChangeArgs = null;
this.OnLikeChanged?.Invoke(this, relationChangeArgs ?? (relationChangeArgs = new RelationChangeArgs(CitizenId, like, num)));
RelationManager.Instance.RaiseEvent(RelationManager.EventName.LikeChange, relationChangeArgs ?? new RelationChangeArgs(CitizenId, like, num));
}
}
public event EventHandler<RelationChangeArgs> OnKnowChanged;
public event EventHandler<RelationChangeArgs> OnLikeChanged;
public event EventHandler<SeenPlayerArgs> OnPlayerSeen;
public KnowStage GetKnowRelation()
{
if (Know < ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.KnowGateOne)
{
return KnowStage.Stranger;
}
if (Know < ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.KnowGateTwo)
{
return KnowStage.Aware;
}
if (Know < ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.KnowGateThree)
{
return KnowStage.Familiar;
}
if (Know < ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.KnowGateFour)
{
return KnowStage.Known;
}
return KnowStage.WellKnown;
}
public LikeStage GetLikeRelation()
{
if (Like < ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.LikeGateOne)
{
return LikeStage.Hated;
}
if (Like < ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.LikeGateTwo)
{
return LikeStage.Disliked;
}
if (Like < ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.LikeGateThree)
{
return LikeStage.Neutral;
}
if (Like < ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.LikeGateFour)
{
return LikeStage.Liked;
}
return LikeStage.Loved;
}
[JsonConstructor]
public CitizenRelation(int citizenId)
{
CitizenId = citizenId;
}
public Human GetCitizen()
{
Human result = default(Human);
if (!CityData.Instance.citizenDictionary.TryGetValue(CitizenId, ref result))
{
return null;
}
return result;
}
internal void RaiseSeenEvent(SeenPlayerArgs.SeenLocation location, float knowChange, float likeChange)
{
//IL_0016: 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_0049: Expected O, but got Unknown
LastSeenRealTime = DateTime.Now;
LastSeenGameTime = Lib.Time.CurrentDateTime;
if (((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.DebugMode)
{
ManualLogSource log = PluginController<Plugin, IPluginBindings>.Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(44, 4, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Debug]: Citizen(");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(CitizenId);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("|");
Human citizen = GetCitizen();
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((citizen != null) ? citizen.GetCitizenName() : null) ?? "Unknown");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("): saw player at \"");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<SeenPlayerArgs.SeenLocation>(location);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\" on \"");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<TimeData?>(LastSeenGameTime);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\".");
}
log.LogInfo(val);
}
SeenPlayerArgs seenPlayerArgs = null;
this.OnPlayerSeen?.Invoke(this, seenPlayerArgs ?? (seenPlayerArgs = new SeenPlayerArgs(CitizenId, location, knowChange, likeChange)));
RelationManager.Instance.RaiseEvent(RelationManager.EventName.Seen, seenPlayerArgs ?? new SeenPlayerArgs(CitizenId, location, knowChange, likeChange));
}
}
public class CitizenSaveData
{
public int LastDecayCheckMinute { get; set; }
public Dictionary<int, CitizenRelation> RelationMatrix { get; set; }
}
public sealed class RelationChangeArgs : EventArgs
{
public int CitizenId { get; }
public float OldValue { get; }
public float NewValue { get; }
internal RelationChangeArgs(int citizenId, float oldValue, float newValue)
{
CitizenId = citizenId;
OldValue = oldValue;
NewValue = newValue;
}
}
public sealed class SeenPlayerArgs : EventArgs
{
public enum SeenLocation
{
Street,
Workplace,
Home,
HomeBuilding
}
public int CitizenId { get; }
public float KnowChange { get; }
public float LikeChange { get; }
public SeenLocation Location { get; }
public DateTime SeenRealTime { get; }
public TimeData SeenGameTime { get; }
internal SeenPlayerArgs(int citizenId, SeenLocation location, float knowChange, float likeChange)
{
//IL_0034: 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)
CitizenId = citizenId;
KnowChange = knowChange;
LikeChange = likeChange;
Location = location;
SeenRealTime = DateTime.Now;
SeenGameTime = Lib.Time.CurrentDateTime;
}
}
}