From ac880f38512afc5d6dc9f2ab8354e5a14fe5d44a Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Fri, 25 Apr 2025 02:38:51 -0500 Subject: [PATCH 01/42] feat: Added documentation generation --- S1API/S1API.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/S1API/S1API.csproj b/S1API/S1API.csproj index e154ad15..84580431 100644 --- a/S1API/S1API.csproj +++ b/S1API/S1API.csproj @@ -17,6 +17,7 @@ Mono;Il2Cpp AnyCPU S1API + true From c7800b4f403c874c84dbbd0b1b027eae97cd14ea Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Fri, 25 Apr 2025 02:39:52 -0500 Subject: [PATCH 02/42] feat: Initial npc adjustments to support base NPCs and additional functionality --- S1API/Entities/Interfaces/IEntity.cs | 26 + S1API/Entities/Interfaces/ILivingEntity.cs | 57 ++ S1API/Entities/NPC.cs | 610 +++++++++++++++++++++ S1API/Entities/NPCs/AlbertHoover.cs | 15 + S1API/Entities/NPCs/NPC_LIST.md | 260 +++++++++ S1API/Internal/Patches/NPCPatches.cs | 13 +- S1API/Map/Region.cs | 38 ++ S1API/{NPCs => Messaging}/Response.cs | 0 S1API/NPCs/NPC.cs | 270 --------- S1API/NPCs/NPCInstance.cs | 13 - S1API/NPCs/NPCManager.cs | 7 - S1API/Player/Player.cs | 10 + 12 files changed, 1026 insertions(+), 293 deletions(-) create mode 100644 S1API/Entities/Interfaces/IEntity.cs create mode 100644 S1API/Entities/Interfaces/ILivingEntity.cs create mode 100644 S1API/Entities/NPC.cs create mode 100644 S1API/Entities/NPCs/AlbertHoover.cs create mode 100644 S1API/Entities/NPCs/NPC_LIST.md create mode 100644 S1API/Map/Region.cs rename S1API/{NPCs => Messaging}/Response.cs (100%) delete mode 100644 S1API/NPCs/NPC.cs delete mode 100644 S1API/NPCs/NPCInstance.cs delete mode 100644 S1API/NPCs/NPCManager.cs create mode 100644 S1API/Player/Player.cs diff --git a/S1API/Entities/Interfaces/IEntity.cs b/S1API/Entities/Interfaces/IEntity.cs new file mode 100644 index 00000000..8cbf5d3a --- /dev/null +++ b/S1API/Entities/Interfaces/IEntity.cs @@ -0,0 +1,26 @@ +using UnityEngine; + +namespace S1API.Entities +{ + /// + /// Represents an entity within the game world. + /// + public interface IEntity + { + GameObject gameObject { get; } + + /// + /// The world position of the entity. + /// + public Vector3 Position => gameObject.transform.position; + + /// + /// The scale of the entity. + /// + public float Scale + { + get => gameObject.transform.localScale.magnitude; + set => gameObject.transform.localScale = new Vector3(value, value, value); + } + } +} \ No newline at end of file diff --git a/S1API/Entities/Interfaces/ILivingEntity.cs b/S1API/Entities/Interfaces/ILivingEntity.cs new file mode 100644 index 00000000..65641618 --- /dev/null +++ b/S1API/Entities/Interfaces/ILivingEntity.cs @@ -0,0 +1,57 @@ +using System; + +namespace S1API.Entities +{ + /// + /// Represents an entity that has health associated. + /// + public interface ILivingEntity : IEntity + { + /// + /// The current health of the entity. + /// + public float CurrentHealth { get; } + + /// + /// The max health of the entity. + /// + public float MaxHealth { get; set; } + + /// + /// Whether the entity is dead or not. + /// + public bool IsDead { get; } + + /// + /// Whether the entity is invincible. + /// + public bool IsInvincible { get; set; } + + /// + /// Revives the entity. + /// + public void Revive(); + + /// + /// Deals damage to the entity. + /// + /// Amount of damage to deal. + public void Damage(int amount); + + /// + /// Heals the entity. + /// + /// Amount of health to heal. + public void Heal(int amount); + + /// + /// Kills the entity. + /// + public void Kill(); + + /// + /// Called when entity's health is less than or equal to 0. + /// + public event Action OnDeath; + } +} \ No newline at end of file diff --git a/S1API/Entities/NPC.cs b/S1API/Entities/NPC.cs new file mode 100644 index 00000000..9680d5de --- /dev/null +++ b/S1API/Entities/NPC.cs @@ -0,0 +1,610 @@ +#if (IL2CPP) +using S1DevUtilities = Il2CppScheduleOne.DevUtilities; +using S1Interaction = Il2CppScheduleOne.Interaction; +using S1Messaging = Il2CppScheduleOne.Messaging; +using S1Noise = Il2CppScheduleOne.Noise; +using S1Relation = Il2CppScheduleOne.NPCs.Relation; +using S1Responses = Il2CppScheduleOne.NPCs.Responses; +using S1PlayerScripts = Il2CppScheduleOne.PlayerScripts; +using S1ContactApps = Il2CppScheduleOne.UI.Phone.ContactsApp; +using S1WorkspacePopup = Il2CppScheduleOne.UI.WorldspacePopup; +using S1AvatarFramework = Il2CppScheduleOne.AvatarFramework; +using S1Behaviour = Il2CppScheduleOne.NPCs.Behaviour; +using S1Vehicles = Il2CppScheduleOne.Vehicles; +using S1Vision = Il2CppScheduleOne.Vision; +using S1NPCs = Il2CppScheduleOne.NPCs; +using Il2CppSystem.Collections.Generic; +#elif (MONO) +using S1DevUtilities = ScheduleOne.DevUtilities; +using S1Interaction = ScheduleOne.Interaction; +using S1Messaging = ScheduleOne.Messaging; +using S1Noise = ScheduleOne.Noise; +using S1Relation = ScheduleOne.NPCs.Relation; +using S1Responses = ScheduleOne.NPCs.Responses; +using S1PlayerScripts = ScheduleOne.PlayerScripts; +using S1ContactApps = ScheduleOne.UI.Phone.ContactsApp; +using S1WorkspacePopup = ScheduleOne.UI.WorldspacePopup; +using S1AvatarFramework = ScheduleOne.AvatarFramework; +using S1Behaviour = ScheduleOne.NPCs.Behaviour; +using S1Vehicles = ScheduleOne.Vehicles; +using S1Vision = ScheduleOne.Vision; +using S1NPCs = ScheduleOne.NPCs; +using System.Collections.Generic; +using System.Reflection; +using HarmonyLib; +#endif + +using System; +using System.IO; +using System.Linq; +using S1API.Entities; +using S1API.Internal.Abstraction; +using S1API.Map; +using UnityEngine; +using UnityEngine.Events; + +namespace S1API.NPCs +{ + /// + /// An abstract class intended to be derived from for creating custom NPCs in the game. + /// + public abstract class NPC : Saveable, ILivingEntity + { + // Protected members intended to be used by modders. + // Intended to be used from within the class / derived classes ONLY. + #region Protected Members + + /// + /// A list of text responses you've added to your NPC. + /// + protected readonly List Responses = new List(); + + /// + /// Base constructor for a new NPC. + /// Not intended for instancing your NPC! + /// Instead, create your derived class and let S1API handle instancing. + /// + /// Unique identifier for your NPC. + /// The first name for your NPC. + /// The last name for your NPC. + /// The icon for your NPC for messages, realationships, etc. + protected NPC( + string id, + string? firstName, + string? lastName, + Sprite? icon = null + ) + { + _isCustomNPC = true; + gameObject = new GameObject(); + + // Deactivate game object til we're done + gameObject.SetActive(false); + + // Setup the base NPC class + S1NPC = gameObject.AddComponent(); + S1NPC.FirstName = firstName; + S1NPC.LastName = lastName; + S1NPC.ID = id; + S1NPC.MugshotSprite = icon ?? S1DevUtilities.PlayerSingleton.Instance.AppIcon; + S1NPC.BakedGUID = Guid.NewGuid().ToString(); + + // ReSharper disable once UseObjectOrCollectionInitializer (IL2CPP COMPAT) + S1NPC.ConversationCategories = new List(); + S1NPC.ConversationCategories.Add(S1Messaging.EConversationCategory.Customer); + + // Create our MessageConversation +#if (IL2CPP) + S1NPC.CreateMessageConversation(); +#elif (MONO) + MethodInfo createConvoMethod = AccessTools.Method(typeof(S1NPCs.NPC), "CreateMessageConversation"); + createConvoMethod.Invoke(S1NPC, null); +#endif + + // Add UnityEvents for NPCHealth + S1NPC.Health = gameObject.GetComponent(); + S1NPC.Health.onDie = new UnityEvent(); + S1NPC.Health.onKnockedOut = new UnityEvent(); + S1NPC.Health.Invincible = true; + S1NPC.Health.MaxHealth = 100f; + + // Awareness behaviour + GameObject awarenessObject = new GameObject("NPCAwareness"); + awarenessObject.transform.SetParent(gameObject.transform); + S1NPC.awareness = awarenessObject.AddComponent(); + S1NPC.awareness.onExplosionHeard = new UnityEvent(); + S1NPC.awareness.onGunshotHeard = new UnityEvent(); + S1NPC.awareness.onHitByCar = new UnityEvent(); + S1NPC.awareness.onNoticedDrugDealing = new UnityEvent(); + S1NPC.awareness.onNoticedGeneralCrime = new UnityEvent(); + S1NPC.awareness.onNoticedPettyCrime = new UnityEvent(); + S1NPC.awareness.onNoticedPlayerViolatingCurfew = new UnityEvent(); + S1NPC.awareness.onNoticedSuspiciousPlayer = new UnityEvent(); + S1NPC.awareness.Listener = gameObject.AddComponent(); + + /////// START BEHAVIOUR CODE //////// + // NPCBehaviours behaviour + GameObject behaviourObject = new GameObject("NPCBehaviour"); + behaviourObject.transform.SetParent(gameObject.transform); + S1Behaviour.NPCBehaviour behaviour = behaviourObject.AddComponent(); + + GameObject cowingBehaviourObject = new GameObject("CowingBehaviour"); + cowingBehaviourObject.transform.SetParent(behaviourObject.transform); + S1Behaviour.CoweringBehaviour coweringBehaviour = cowingBehaviourObject.AddComponent(); + + GameObject fleeBehaviourObject = new GameObject("FleeBehaviour"); + fleeBehaviourObject.transform.SetParent(behaviourObject.transform); + S1Behaviour.FleeBehaviour fleeBehaviour = fleeBehaviourObject.AddComponent(); + + behaviour.CoweringBehaviour = coweringBehaviour; + behaviour.FleeBehaviour = fleeBehaviour; + S1NPC.behaviour = behaviour; + /////// END BEHAVIOUR CODE //////// + + // Response to actions like gunshots, drug deals, etc. + GameObject responsesObject = new GameObject("NPCResponses"); + responsesObject.transform.SetParent(gameObject.transform); + S1NPC.awareness.Responses = responsesObject.AddComponent(); + + // Vision cone object and behaviour + GameObject visionObject = new GameObject("VisionCone"); + visionObject.transform.SetParent(gameObject.transform); + S1Vision.VisionCone visionCone = visionObject.AddComponent(); + visionCone.StatesOfInterest.Add(new S1Vision.VisionCone.StateContainer + { + state = S1PlayerScripts.PlayerVisualState.EVisualState.PettyCrime, RequiredNoticeTime = 0.1f + }); + S1NPC.awareness.VisionCone = visionCone; + + + // Suspicious ? icon in world space + S1NPC.awareness.VisionCone.QuestionMarkPopup = gameObject.AddComponent(); + + // Interaction behaviour +#if (IL2CPP) + S1NPC.intObj = gameObject.AddComponent(); +#elif (MONO) + FieldInfo intObjField = AccessTools.Field(typeof(S1NPCs.NPC), "intObj"); + intObjField.SetValue(S1NPC, gameObject.AddComponent()); +#endif + + // Relationship data + S1NPC.RelationData = new S1Relation.NPCRelationData(); + + // Inventory behaviour + S1NPCs.NPCInventory inventory = gameObject.AddComponent(); + + // Pickpocket behaviour + inventory.PickpocketIntObj = gameObject.AddComponent(); + + // Defaulting to the local player for Avatar TODO: Change + S1NPC.Avatar = S1AvatarFramework.MugshotGenerator.Instance.MugshotRig; + + // Enable our custom gameObjects so they can initialize + gameObject.SetActive(true); + + All.Add(this); + } + + /// + /// Called when a response is loaded from the save file. + /// Override this method for attaching your callbacks to your methods. + /// + /// The response that was loaded. + protected virtual void OnResponseLoaded(Response response) { } + + #endregion + + // Public members intended to be used by modders. + // Can be used inside your derived class, or outside via instance reference. + #region Public Members + + /// + /// List of all NPCs within the base game and modded. + /// + public static readonly System.Collections.Generic.List All = new System.Collections.Generic.List(); + + /// + /// The first name of this NPC. + /// + public string FirstName + { + get => S1NPC.FirstName; + set => S1NPC.FirstName = value; + } + + /// + /// The last name of this NPC. + /// + public string LastName + { + get => S1NPC.LastName; + set => S1NPC.LastName = value; + } + + /// + /// The full name of this NPC. + /// If there is no last name, it will just return the first name. + /// + public string FullName => + S1NPC.fullName; + + /// + /// The unique identifier to assign to this NPC. + /// Used when saving and loading. Probably other things within the base game code. + /// + public string ID + { + get => S1NPC.ID; + protected set => S1NPC.ID = value; + } + + /// + /// The icon assigned to this NPC. + /// + public Sprite Icon + { + get => S1NPC.MugshotSprite; + set => S1NPC.MugshotSprite = value; + } + + /// + /// Whether the NPC is currently conscious or not. + /// + public bool IsConscious => + S1NPC.IsConscious; + + /// + /// Whether the NPC is currently inside a building or not. + /// + public bool IsInBuilding => + S1NPC.isInBuilding; + + /// + /// Whether the NPC is currently inside a vehicle or not. + /// + public bool IsInVehicle => + S1NPC.IsInVehicle; + + /// + /// Whether the NPC is currently panicking or not. + /// + public bool IsPanicking => + S1NPC.IsPanicked; + + /// + /// Whether the NPC is currently unsettled or not. + /// + public bool IsUnsettled => + S1NPC.isUnsettled; + + /// + /// UNCONFIRMED: Whether the NPC is currently visible to the player or not. + /// If you confirm this, please let us know so we can update the documentation! + /// + public bool IsVisible => + S1NPC.isVisible; + + /// + /// How aggressive this NPC is towards others. + /// + public float Aggressiveness + { + get => S1NPC.Aggression; + set => S1NPC.Aggression = value; + } + + /// + /// The region the NPC is associated with. + /// Note: Not the region they're in currently. Just the region they're designated to. + /// + public Region Region => + (Region)S1NPC.Region; + + /// + /// UNCONFIRMED: How long the NPC will panic for. + /// If you confirm this, please let us know so we can update the documentation! + /// + public float PanicDuration + { + get => (float)_panicField.GetValue(S1NPC); + set => _panicField.SetValue(S1NPC, value); + } + + /// + /// Sets the scale of the NPC. + /// + public float Scale + { + get => S1NPC.Scale; + set => S1NPC.SetScale(value); + } + + /// + /// Whether the NPC is knocked out or not. + /// + public bool IsKnockedOut => + S1NPC.Health.IsKnockedOut; + + /// + /// UNCONFIRMED: Whether the NPC requires the region unlocked in order to deal to. + /// If you confirm this, please let us know so we can update the documentation! + /// + public bool RequiresRegionUnlocked + { + get => (bool)_requiresRegionUnlockedField.GetValue(S1NPC); + set => _panicField.SetValue(S1NPC, value); + } + + // TODO: Add CurrentBuilding (currently missing NPCEnterableBuilding abstraction) + // public ??? CurrentBuilding { get; set; } + + // TODO: Add CurrentVehicle (currently missing LandVehicle abstraction) + // public ??? CurrentVehicle { get; set; } + + // TODO: Add Inventory (currently missing NPCInventory abstraction) + // public ??? Inventory { get; set; } + + /// + /// The current health the NPC has. + /// + public float CurrentHealth => + S1NPC.Health.Health; + + /// + /// The maximum health the NPC has. + /// + public float MaxHealth + { + get => S1NPC.Health.MaxHealth; + set => S1NPC.Health.MaxHealth = value; + } + + /// + /// Whether the NPC is dead or not. + /// + public bool IsDead => + S1NPC.Health.IsDead; + + /// + /// Whether the NPC is invincible or not. + /// + public bool IsInvincible + { + get => S1NPC.Health.Invincible; + set => S1NPC.Health.Invincible = value; + } + + /// + /// Revives the NPC. + /// + public void Revive() => + S1NPC.Health.Revive(); + + /// + /// Deals damage to the NPC. + /// + /// The amount of damage to deal. + public void Damage(int amount) + { + if (amount >= 0) + return; + + S1NPC.Health.TakeDamage(amount, true); + } + + /// + /// Heals the NPC. + /// + /// The amount of health to heal. + public void Heal(int amount) + { + if (amount <= 0) + return; + + float actualHealAmount = Mathf.Min(amount, S1NPC.Health.MaxHealth - S1NPC.Health.Health); + S1NPC.Health.TakeDamage(-actualHealAmount, false); + } + + /// + /// Kills the NPC. + /// + public void Kill() => + S1NPC.Health.TakeDamage(S1NPC.Health.MaxHealth); + + /// + /// Causes the NPC to become unsettled. + /// UNCONFIRMED: Will panic them for PanicDuration amount of time. + /// If you confirm this, please let us know so we can update the documentation! + /// + /// Length of time they should stay unsettled. + public void Unsettle(float duration) => + _unsettleMethod.Invoke(S1NPC, new object[] { duration }); + + /// + /// Smoothly scales the NPC over lerpTime. + /// + /// The scale you want set. + /// The time to scale over. + public void LerpScale(float scale, float lerpTime) => + S1NPC.SetScale(scale, lerpTime); + + /// + /// Causes the NPC to become panicked. + /// + public void Panic() => + S1NPC.SetPanicked(); + + /// + /// Causes the NPC to stop panicking, if they are currently. + /// + public void StopPanicking() => + _removePanicMethod.Invoke(S1NPC, new object[] { }); + + /// + /// Knocks the NPC out. + /// NOTE: Does not work for invincible NPCs. + /// + public void KnockOut() => + S1NPC.Health.KnockOut(); + + /// + /// Tells the NPC to travel to a specific position in world space. + /// + /// The position to travel to. + public void Goto(Vector3 position) => + S1NPC.Movement.SetDestination(position); + + // TODO: Add OnEnterVehicle listener (currently missing LandVehicle abstraction) + // public event Action OnEnterVehicle { } + + // TODO: Add OnExitVehicle listener (currently missing LandVehicle abstraction) + // public event Action OnExitVehicle { } + + // TODO: Add OnExplosionHeard listener (currently missing NoiseEvent abstraction) + // public event Action OnExplosionHeard { } + + // TODO: Add OnGunshotHeard listener (currently missing NoiseEvent abstraction) + // public event Action OnGunshotHeard { } + + // TODO: Add OnHitByCar listener (currently missing LandVehicle abstraction) + // public event Action OnHitByCar { } + + // TODO: Add OnNoticedDrugDealing listener (currently missing Player abstraction) + // public event Action OnNoticedDrugDealing { } + + // TODO: Add OnNoticedGeneralCrime listener (currently missing Player abstraction) + // public event Action OnNoticedGeneralCrime { } + + // TODO: Add OnNoticedPettyCrime listener (currently missing Player abstraction) + // public event Action OnNoticedPettyCrime { } + + // TODO: Add OnPlayerViolatingCurfew listener (currently missing Player abstraction) + // public event Action OnPlayerViolatingCurfew { } + + // TODO: Add OnNoticedSuspiciousPlayer listener (currently missing Player abstraction) + // public event Action OnNoticedSuspiciousPlayer { } + + /// + /// Called when the NPC died. + /// + public event Action OnDeath + { + add => EventHelper.AddListener(value, S1NPC.Health.onDie); + remove => EventHelper.RemoveListener(value, S1NPC.Health.onDie); + } + + /// + /// Called when the NPC's inventory contents change. + /// + public event Action OnInventoryChanged + { + add => EventHelper.AddListener(value, S1NPC.Inventory.onContentsChanged); + remove => EventHelper.RemoveListener(value, S1NPC.Inventory.onContentsChanged); + } + + /// + /// Sends a text message from this NPC to the players. + /// Supports responses with callbacks for additional logic. + /// + /// The message you want the player to see. Unity rich text is allowed. + /// Instances of to display. + /// The delay between when the message is sent and when the player can reply. + /// Whether this should propagate to all players or not. + public void SendTextMessage(string message, Response[]? responses = null, float responseDelay = 1f, bool network = true) + { + S1NPC.SendTextMessage(message); + S1NPC.MSGConversation.ClearResponses(); + + if (responses == null || responses.Length == 0) + return; + + Responses.Clear(); + + List responsesList = new List(); + + foreach (Response response in responses) + { + Responses.Add(response); + responsesList.Add(response.S1Response); + } + + S1NPC.MSGConversation.ShowResponses( + responsesList, + responseDelay, + network + ); + } + + /// + /// Gets the instance of an NPC. + /// Supports base NPCs as well as other mod NPCs. + /// For base NPCs, . + /// + /// The NPC class to get the instance of. + /// + public static NPC? Get() => + All.FirstOrDefault(npc => npc.GetType() == typeof(T)); + + #endregion + + // Internal members used by S1API. + // Please do not attempt to use these members! + #region Internal Members + + /// + /// INTERNAL: Reference to the NPC on the S1 side. + /// + internal readonly S1NPCs.NPC S1NPC; + + /// + /// INTERNAL: Constructor used for base game NPCs. + /// + /// Reference to a base game NPC. + internal NPC(S1NPCs.NPC npc) + { + S1NPC = npc; + gameObject = npc.gameObject; + _isCustomNPC = false; + All.Add(this); + } + + /// + /// INTERNAL: Initializes the responses that have been added / loaded + /// + internal override void CreateInternal() + { + // Assign responses to our tracked responses + foreach (S1Messaging.Response s1Response in S1NPC.MSGConversation.currentResponses) + { + Response response = new Response(s1Response) { Label = s1Response.label, Text = s1Response.text }; + Responses.Add(response); + OnResponseLoaded(response); + } + + base.CreateInternal(); + } + + internal override void SaveInternal(string folderPath, ref List extraSaveables) + { + string npcPath = Path.Combine(folderPath, S1NPC.SaveFolderName); + base.SaveInternal(npcPath, ref extraSaveables); + } + #endregion + + // Private members used by the NPC class. + // Please do not attempt to use these members! + #region Private Members + + public GameObject gameObject { get; } + private readonly bool _isCustomNPC; + + private readonly FieldInfo _panicField = AccessTools.Field(typeof(S1NPCs.NPC), "PANIC_DURATION"); + private readonly FieldInfo _requiresRegionUnlockedField = AccessTools.Field(typeof(S1NPCs.NPC), "RequiresRegionUnlocked"); + + private readonly MethodInfo _unsettleMethod = AccessTools.Method(typeof(S1NPCs.NPC), "SetUnsettled"); + private readonly MethodInfo _removePanicMethod = AccessTools.Method(typeof(S1NPCs.NPC), "RemovePanicked"); + + #endregion + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/AlbertHoover.cs b/S1API/Entities/NPCs/AlbertHoover.cs new file mode 100644 index 00000000..072da13a --- /dev/null +++ b/S1API/Entities/NPCs/AlbertHoover.cs @@ -0,0 +1,15 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif + +using System.Linq; + +namespace S1API.NPCs +{ + public class AlbertHoover : NPC + { + internal AlbertHoover() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "albert_hoover")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/NPC_LIST.md b/S1API/Entities/NPCs/NPC_LIST.md new file mode 100644 index 00000000..334576fa --- /dev/null +++ b/S1API/Entities/NPCs/NPC_LIST.md @@ -0,0 +1,260 @@ +**manny_oakfield** +ScheduleOne.NPCs.CharacterClasses.Fixer +--- +**jessi_waters** +ScheduleOne.NPCs.CharacterClasses.Jessi +--- +**brad_crosby** +ScheduleOne.NPCs.CharacterClasses.Brad +--- +**donna_martin** +ScheduleOne.NPCs.NPC +--- +**keith_wagner** +ScheduleOne.NPCs.CharacterClasses.Keith +--- +**kevin_oakley** +ScheduleOne.NPCs.CharacterClasses.Kevin +--- +**billy_kramer** +ScheduleOne.NPCs.Billy +--- +**marco_baron** +ScheduleOne.NPCs.CharacterClasses.Marco +--- +**officergreen** +ScheduleOne.Police.PoliceOfficer +--- +**stan_carney** +ScheduleOne.NPCs.Stan +--- +**kathy_henderson** +ScheduleOne.NPCs.CharacterClasses.Kathy +--- +**jane_lucero** +ScheduleOne.NPCs.CharacterClasses.Jane +--- +**beth_penn** +ScheduleOne.NPCs.CharacterClasses.Beth +--- +**officerhoward** +ScheduleOne.Police.PoliceOfficer +--- +**officerlopez** +ScheduleOne.Police.PoliceOfficer +--- +**tobias_wentworth** +ScheduleOne.NPCs.CharacterClasses.Tobias +--- +**kim_delaney** +ScheduleOne.NPCs.CharacterClasses.Kim +--- +**officerdavis** +ScheduleOne.Police.PoliceOfficer +--- +**officermurphy** +ScheduleOne.Police.PoliceOfficer +--- +**lisa_gardener** +ScheduleOne.NPCs.CharacterClasses.Lisa +--- +**eugene_buckley** +ScheduleOne.NPCs.CharacterClasses.Eugene +--- +**karen_kennedy** +ScheduleOne.NPCs.CharacterClasses.Karen +--- +**jen_heard** +ScheduleOne.NPCs.CharacterClasses.Jen +--- +**michael_boog** +ScheduleOne.NPCs.CharacterClasses.Michael +--- +**dean_webster** +ScheduleOne.NPCs.CharacterClasses.Dean +--- +**elizabeth_homley** +ScheduleOne.NPCs.CharacterClasses.Elizabeth +--- +**herbert_bleuball** +ScheduleOne.NPCs.CharacterClasses.Herbert +--- +**mick_lubbin** +ScheduleOne.NPCs.CharacterClasses.Mick +--- +**mac_cooper** +ScheduleOne.NPCs.CharacterClasses.Mac +--- +**sam_thompson** +ScheduleOne.NPCs.CharacterClasses.Sam +--- +**molly_presley** +ScheduleOne.Economy.Dealer +--- +**greg_fliggle** +ScheduleOne.NPCs.CharacterClasses.Greg +--- +**jeff_gilmore** +ScheduleOne.NPCs.CharacterClasses.Jeff +--- +**benji_coleman** +ScheduleOne.NPCs.CharacterClasses.Benji +--- +**albert_hoover** +ScheduleOne.NPCs.CharacterClasses.Albert +--- +**chris_sullivan** +ScheduleOne.NPCs.CharacterClasses.Chris +--- +**oscar_holland** +ScheduleOne.NPCs.CharacterClasses.Oscar +--- +**peter_file** +ScheduleOne.NPCs.CharacterClasses.Peter +--- +**jennifer_rivera** +ScheduleOne.NPCs.CharacterClasses.Jennifer +--- +**hank_stevenson** +ScheduleOne.NPCs.CharacterClasses.Steve +--- +**officerjackson** +ScheduleOne.Police.PoliceOfficer +--- +**louis_fourier** +ScheduleOne.NPCs.CharacterClasses.Louis +--- +**officerlee** +ScheduleOne.Police.PoliceOfficer +--- +**melissa_wood** +ScheduleOne.NPCs.CharacterClasses.Melissa +--- +**jackie_stevenson** +ScheduleOne.NPCs.CharacterClasses.Jackie +--- +**lucy_pennington** +ScheduleOne.NPCs.NPC +--- +**peggy_myers** +ScheduleOne.NPCs.CharacterClasses.Peggy +--- +**joyce_ball** +ScheduleOne.NPCs.NPC +--- +**meg_cooley** +ScheduleOne.NPCs.Meg +--- +**trent_sherman** +ScheduleOne.NPCs.NPC +--- +**charles_rowland** +ScheduleOne.NPCs.CharacterClasses.Charles +--- +**george_greene** +ScheduleOne.NPCs.CharacterClasses.George +--- +**jerry_montero** +ScheduleOne.NPCs.Jerry +--- +**doris_lubbin** +ScheduleOne.NPCs.Doris +--- +**dan_samwell** +ScheduleOne.NPCs.CharacterClasses.Dan +--- +**uncle_nelson** +ScheduleOne.NPCs.CharacterClasses.UncleNelson +--- +**igor_romanovich** +ScheduleOne.NPCs.CharacterClasses.Igor +--- +**wei_long** +ScheduleOne.NPCs.CharacterClasses.Wei +--- +**leo_rivers** +ScheduleOne.NPCs.CharacterClasses.Leo +--- +**officerbailey** +ScheduleOne.Police.PoliceOfficer +--- +**officercooper** +ScheduleOne.Police.PoliceOfficer +--- +**officeroakley** +ScheduleOne.Police.PoliceOfficer +--- +**lily_turner** +ScheduleOne.NPCs.CharacterClasses.Lily +--- +**ray_hoffman** +ScheduleOne.NPCs.CharacterClasses.Ray +--- +**walter_cussler** +ScheduleOne.NPCs.CharacterClasses.Walter +--- +**pearl_moore** +ScheduleOne.NPCs.CharacterClasses.Pearl +--- +**fiona_hancock** +ScheduleOne.NPCs.CharacterClasses.Fiona +--- +**genghis_barn** +ScheduleOne.NPCs.CharacterClasses.Genghis +--- +**anna_chesterfield** +ScheduleOne.NPCs.CharacterClasses.Anna +--- +**javier_perez** +ScheduleOne.NPCs.CharacterClasses.Javier +--- +**cranky_frank** +ScheduleOne.NPCs.CharacterClasses.Frank +--- +**randy_caulfield** +ScheduleOne.NPCs.CharacterClasses.Randy +--- +**philip_wentworth** +ScheduleOne.NPCs.CharacterClasses.Philip +--- +**jeremy_wilkinson** +ScheduleOne.NPCs.CharacterClasses.Jeremy +--- +**alison_knight** +ScheduleOne.NPCs.CharacterClasses.Alison +--- +**carl_bundy** +ScheduleOne.NPCs.CharacterClasses.Carl +--- +**harold_colt** +ScheduleOne.NPCs.CharacterClasses.Harold +--- +**jack_knight** +ScheduleOne.NPCs.CharacterClasses.Jack +--- +**dennis_kennedy** +ScheduleOne.NPCs.CharacterClasses.Dennis +--- +**shirley_watts** +ScheduleOne.NPCs.CharacterClasses.Shirley +--- +**salvador_moreno** +ScheduleOne.NPCs.CharacterClasses.Salvador +--- +**kyle_cooley** +ScheduleOne.NPCs.CharacterClasses.Kyle +--- +**ludwig_meyer** +ScheduleOne.NPCs.NPC +--- +**austin_steiner** +ScheduleOne.NPCs.CharacterClasses.Austin +--- +**chloe_bowers** +ScheduleOne.NPCs.Chloe +--- +**ming** +ScheduleOne.NPCs.CharacterClasses.Ming +--- +**geraldine_poon** +ScheduleOne.NPCs.CharacterClasses.Geraldine \ No newline at end of file diff --git a/S1API/Internal/Patches/NPCPatches.cs b/S1API/Internal/Patches/NPCPatches.cs index c4304982..8e812141 100644 --- a/S1API/Internal/Patches/NPCPatches.cs +++ b/S1API/Internal/Patches/NPCPatches.cs @@ -11,6 +11,7 @@ using System; using System.IO; using System.Linq; +using System.Reflection; using HarmonyLib; using S1API.Internal.Utils; using S1API.NPCs; @@ -28,7 +29,7 @@ internal class NPCPatches /// /// List of all custom NPCs currently created. /// - private static readonly System.Collections.Generic.List NPCs = new System.Collections.Generic.List(); + internal static readonly System.Collections.Generic.List NPCs = new System.Collections.Generic.List(); /// /// Patching performed for when game NPCs are loaded. @@ -41,13 +42,18 @@ private static void NPCsLoadersLoad(S1Loaders.NPCsLoader __instance, string main { foreach (Type type in ReflectionUtils.GetDerivedClasses()) { - NPC customNPC = (NPC)Activator.CreateInstance(type); + NPC customNPC = (NPC)Activator.CreateInstance(type, true); NPCs.Add(customNPC); + + // We skip any S1API NPCs, as they are base NPC wrappers. + if (type.Assembly == Assembly.GetExecutingAssembly()) + continue; + string npcPath = Path.Combine(mainPath, customNPC.S1NPC.SaveFolderName); customNPC.LoadInternal(npcPath); } } - + /// /// Patching performed for when a single NPC starts (including modded in NPCs). /// @@ -56,6 +62,7 @@ private static void NPCsLoadersLoad(S1Loaders.NPCsLoader __instance, string main [HarmonyPostfix] private static void NPCStart(S1NPCs.NPC __instance) => NPCs.FirstOrDefault(npc => npc.S1NPC == __instance)?.CreateInternal(); + /// /// Patching performed for when an NPC calls to save data. diff --git a/S1API/Map/Region.cs b/S1API/Map/Region.cs new file mode 100644 index 00000000..1ed6785b --- /dev/null +++ b/S1API/Map/Region.cs @@ -0,0 +1,38 @@ +namespace S1API.Map +{ + /// + /// The regions available in the game. + /// + public enum Region + { + /// + /// The first region in the game. + /// + Northtown, + + /// + /// The second region in the game. + /// + Westville, + + /// + /// The third region in the game. + /// + Downtown, + + /// + /// The fourth region in the game. + /// + Docks, + + /// + /// The fifth region in the game. + /// + Suburbia, + + /// + /// The sixth region in the game. + /// + Uptown + } +} \ No newline at end of file diff --git a/S1API/NPCs/Response.cs b/S1API/Messaging/Response.cs similarity index 100% rename from S1API/NPCs/Response.cs rename to S1API/Messaging/Response.cs diff --git a/S1API/NPCs/NPC.cs b/S1API/NPCs/NPC.cs deleted file mode 100644 index a9a14699..00000000 --- a/S1API/NPCs/NPC.cs +++ /dev/null @@ -1,270 +0,0 @@ -#if (IL2CPP) -using S1DevUtilities = Il2CppScheduleOne.DevUtilities; -using S1Interaction = Il2CppScheduleOne.Interaction; -using S1Messaging = Il2CppScheduleOne.Messaging; -using S1Noise = Il2CppScheduleOne.Noise; -using S1Relation = Il2CppScheduleOne.NPCs.Relation; -using S1Responses = Il2CppScheduleOne.NPCs.Responses; -using S1PlayerScripts = Il2CppScheduleOne.PlayerScripts; -using S1ContactApps = Il2CppScheduleOne.UI.Phone.ContactsApp; -using S1WorkspacePopup = Il2CppScheduleOne.UI.WorldspacePopup; -using S1AvatarFramework = Il2CppScheduleOne.AvatarFramework; -using S1Behaviour = Il2CppScheduleOne.NPCs.Behaviour; -using S1Vehicles = Il2CppScheduleOne.Vehicles; -using S1Vision = Il2CppScheduleOne.Vision; -using S1NPCs = Il2CppScheduleOne.NPCs; -using Il2CppSystem.Collections.Generic; -#elif (MONO) -using S1DevUtilities = ScheduleOne.DevUtilities; -using S1Interaction = ScheduleOne.Interaction; -using S1Messaging = ScheduleOne.Messaging; -using S1Noise = ScheduleOne.Noise; -using S1Relation = ScheduleOne.NPCs.Relation; -using S1Responses = ScheduleOne.NPCs.Responses; -using S1PlayerScripts = ScheduleOne.PlayerScripts; -using S1ContactApps = ScheduleOne.UI.Phone.ContactsApp; -using S1WorkspacePopup = ScheduleOne.UI.WorldspacePopup; -using S1AvatarFramework = ScheduleOne.AvatarFramework; -using S1Behaviour = ScheduleOne.NPCs.Behaviour; -using S1Vehicles = ScheduleOne.Vehicles; -using S1Vision = ScheduleOne.Vision; -using S1NPCs = ScheduleOne.NPCs; -using System.Collections.Generic; -using System.Reflection; -using HarmonyLib; -#endif - -using System; -using System.IO; -using S1API.Internal.Abstraction; -using UnityEngine; -using UnityEngine.Events; - -namespace S1API.NPCs -{ - /// - /// An abstract class intended to be derived from for creating custom NPCs in the game. - /// - public abstract class NPC : Saveable - { - /// - /// A list of text responses you've added to your NPC. - /// - protected readonly System.Collections.Generic.List Responses = - new System.Collections.Generic.List(); - - internal readonly S1NPCs.NPC S1NPC; - - private readonly GameObject _gameObject; - /// - /// Optional custom mugshot icon sprite. If null, defaults to ContactsApp icon. - /// protected override Sprite? NPCIcon => ImageUtils.LoadImage("icon.png"); - /// - protected virtual Sprite? NPCIcon => null; - - /// - /// Base constructor for a new NPC. - /// Intended to be wrapped in your derived class constructor such as: - /// public class MyNPC : NPC ... - /// public MyNPC() : base(id, fname, lname) { ... } - /// - /// The unique identifier for this NPC - /// - /// - public NPC(string guid, string firstName, string lastName) - { - _gameObject = new GameObject("NPC"); - - // Deactivate game object til we're done - _gameObject.SetActive(false); - - // Setup the base NPC class - S1NPC = _gameObject.AddComponent(); - S1NPC.FirstName = firstName; - S1NPC.LastName = lastName; - S1NPC.ID = guid; - S1NPC.BakedGUID = Guid.NewGuid().ToString(); - S1NPC.MugshotSprite = NPCIcon ?? S1DevUtilities.PlayerSingleton.Instance.AppIcon; - - // ReSharper disable once UseObjectOrCollectionInitializer - S1NPC.ConversationCategories = new List(); - S1NPC.ConversationCategories.Add(S1Messaging.EConversationCategory.Customer); - - // Create our MessageConversation -#if (IL2CPP) - S1NPC.CreateMessageConversation(); -#elif (MONO) - MethodInfo createConvoMethod = AccessTools.Method(typeof(S1NPCs.NPC), "CreateMessageConversation"); - createConvoMethod.Invoke(S1NPC, null); -#endif - - // Add UnityEvents for NPCHealth - S1NPC.Health = _gameObject.GetComponent(); - S1NPC.Health.onDie = new UnityEvent(); - S1NPC.Health.onKnockedOut = new UnityEvent(); - S1NPC.Health.Invincible = true; - S1NPC.Health.MaxHealth = 100f; - - // Awareness behaviour - GameObject awarenessObject = new GameObject("NPCAwareness"); - awarenessObject.SetActive(false); - awarenessObject.transform.SetParent(_gameObject.transform); - S1NPC.awareness = awarenessObject.AddComponent(); - S1NPC.awareness.onExplosionHeard = new UnityEvent(); - S1NPC.awareness.onGunshotHeard = new UnityEvent(); - S1NPC.awareness.onHitByCar = new UnityEvent(); - S1NPC.awareness.onNoticedDrugDealing = new UnityEvent(); - S1NPC.awareness.onNoticedGeneralCrime = new UnityEvent(); - S1NPC.awareness.onNoticedPettyCrime = new UnityEvent(); - S1NPC.awareness.onNoticedPlayerViolatingCurfew = new UnityEvent(); - S1NPC.awareness.onNoticedSuspiciousPlayer = new UnityEvent(); - S1NPC.awareness.Listener = _gameObject.AddComponent(); - - /////// START BEHAVIOUR CODE //////// - // NPCBehaviours behaviour - GameObject behaviourObject = new GameObject("NPCBehaviour"); - behaviourObject.SetActive(false); - behaviourObject.transform.SetParent(_gameObject.transform); - S1Behaviour.NPCBehaviour behaviour = behaviourObject.AddComponent(); - - GameObject cowingBehaviourObject = new GameObject("CowingBehaviour"); - cowingBehaviourObject.transform.SetParent(behaviourObject.transform); - S1Behaviour.CoweringBehaviour coweringBehaviour = cowingBehaviourObject.AddComponent(); - - GameObject fleeBehaviourObject = new GameObject("FleeBehaviour"); - fleeBehaviourObject.transform.SetParent(behaviourObject.transform); - S1Behaviour.FleeBehaviour fleeBehaviour = fleeBehaviourObject.AddComponent(); - - behaviour.CoweringBehaviour = coweringBehaviour; - behaviour.FleeBehaviour = fleeBehaviour; - S1NPC.behaviour = behaviour; - /////// END BEHAVIOUR CODE //////// - - // Response to actions like gunshots, drug deals, etc. - GameObject responsesObject = new GameObject("NPCResponses"); - responsesObject.SetActive(false); - responsesObject.transform.SetParent(_gameObject.transform); - S1NPC.awareness.Responses = responsesObject.AddComponent(); - - // Vision cone object and behaviour - GameObject visionObject = new GameObject("VisionCone"); - visionObject.SetActive(false); - visionObject.transform.SetParent(_gameObject.transform); - S1Vision.VisionCone visionCone = visionObject.AddComponent(); - visionCone.StatesOfInterest.Add(new S1Vision.VisionCone.StateContainer - { - state = S1PlayerScripts.PlayerVisualState.EVisualState.PettyCrime, RequiredNoticeTime = 0.1f - }); - S1NPC.awareness.VisionCone = visionCone; - - - // Suspicious ? icon in world space - S1NPC.awareness.VisionCone.QuestionMarkPopup = _gameObject.AddComponent(); - - // Interaction behaviour -#if (IL2CPP) - S1NPC.intObj = _gameObject.AddComponent(); -#elif (MONO) - FieldInfo intObjField = AccessTools.Field(typeof(S1NPCs.NPC), "intObj"); - intObjField.SetValue(S1NPC, _gameObject.AddComponent()); -#endif - - // Relationship data - S1NPC.RelationData = new S1Relation.NPCRelationData(); - - // void OnUnlockAction(S1Relation.NPCRelationData.EUnlockType unlockType, bool notify) - // { - // if (!string.IsNullOrEmpty(S1NPC.NPCUnlockedVariable)) - // { - // S1DevUtilities.NetworkSingleton.Instance.SetVariableValue(S1NPC.NPCUnlockedVariable, true.ToString()); - // } - // } - - // S1NPC.RelationData.onUnlocked += (Action)OnUnlockAction; - - // Inventory behaviour - S1NPCs.NPCInventory inventory = _gameObject.AddComponent(); - - // Pickpocket behaviour - inventory.PickpocketIntObj = _gameObject.AddComponent(); - - // Defaulting to the local player for Avatar TODO: Change - S1NPC.Avatar = S1AvatarFramework.MugshotGenerator.Instance.MugshotRig; - - - // NetworkObject networkObject = gameObject.AddComponent(); - // // networkObject.NetworkBehaviours = InstanceFinder.NetworkManager; - // PropertyInfo networkBehavioursProperty = AccessTools.Property(typeof(NetworkObject), "NetworkBehaviours"); - // networkBehavioursProperty.SetValue(networkObject, new [] { this }); - - // Enable our custom gameObjects so they can initialize - _gameObject.SetActive(true); - visionObject.SetActive(true); - responsesObject.SetActive(true); - awarenessObject.SetActive(true); - behaviourObject.SetActive(true); - } - - /// - /// INTERNAL: Initializes the responses that have been added / loaded - /// - internal override void CreateInternal() - { - // Assign responses to our tracked responses - foreach (S1Messaging.Response s1Response in S1NPC.MSGConversation.currentResponses) - { - Response response = new Response(s1Response) { Label = s1Response.label, Text = s1Response.text }; - Responses.Add(response); - OnResponseLoaded(response); - } - - base.CreateInternal(); - } - - internal override void SaveInternal(string folderPath, ref List extraSaveables) - { - string npcPath = Path.Combine(folderPath, S1NPC.SaveFolderName); - base.SaveInternal(npcPath, ref extraSaveables); - } - - /// - /// Sends a text message from this NPC to the players. - /// Supports responses with callbacks for additional logic. - /// - /// The message you want the player to see. Unity rich text is allowed. - /// Instances of to display. - /// The delay between when the message is sent and when the player can reply. - /// Whether this should propagate to all players or not. - public void SendTextMessage(string message, Response[]? responses = null, float responseDelay = 1f, bool network = true) - { - S1NPC.SendTextMessage(message); - S1NPC.MSGConversation.ClearResponses(); - - if (responses == null || responses.Length == 0) - return; - - Responses.Clear(); - - List responsesList = new List(); - - foreach (Response response in responses) - { - Responses.Add(response); - responsesList.Add(response.S1Response); - } - - S1NPC.MSGConversation.ShowResponses( - responsesList, - responseDelay, - network - ); - } - - /// - /// Called when a response is loaded from the save file. - /// Override this method for attaching your callbacks to your methods. - /// - /// The response that was loaded. - protected virtual void OnResponseLoaded(Response response) { } - } -} \ No newline at end of file diff --git a/S1API/NPCs/NPCInstance.cs b/S1API/NPCs/NPCInstance.cs deleted file mode 100644 index d4858d1b..00000000 --- a/S1API/NPCs/NPCInstance.cs +++ /dev/null @@ -1,13 +0,0 @@ -#if (IL2CPP) -using S1NPCs = Il2CppScheduleOne.NPCs; -#elif (MONO) -using S1NPCs = ScheduleOne.NPCs; -#endif - -namespace S1API.NPCs -{ - public class NPCInstance - { - - } -} \ No newline at end of file diff --git a/S1API/NPCs/NPCManager.cs b/S1API/NPCs/NPCManager.cs deleted file mode 100644 index b8fa86dc..00000000 --- a/S1API/NPCs/NPCManager.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace S1API.NPCs -{ - public class NPCManager - { - - } -} \ No newline at end of file diff --git a/S1API/Player/Player.cs b/S1API/Player/Player.cs new file mode 100644 index 00000000..34f0a683 --- /dev/null +++ b/S1API/Player/Player.cs @@ -0,0 +1,10 @@ +// using UnityEngine; +// +// namespace S1API.Player +// { +// public class Player +// { +// public static Player Local => new Player(); +// public Vector3 Position = Vector3.zero; +// } +// } \ No newline at end of file From 5773f765321707067771aa04cc58b5ac8dd485bb Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Fri, 25 Apr 2025 22:11:15 -0500 Subject: [PATCH 03/42] fix: Refactored namespaces globally --- S1API/Console/ConsoleHelper.cs | 6 +- S1API/Entities/Interfaces/IEntity.cs | 2 +- S1API/Entities/Interfaces/ILivingEntity.cs | 2 +- S1API/Entities/NPC.cs | 7 +- S1API/Internal/Patches/NPCPatches.cs | 2 +- S1API/Internal/Utils/ButtonListener.cs | 115 +++++++++---------- S1API/Internal/Utils/RandomUtils.cs | 3 +- S1API/Messaging/Response.cs | 2 +- S1API/UI/UIFactory.cs | 123 ++++++++++----------- 9 files changed, 130 insertions(+), 132 deletions(-) diff --git a/S1API/Console/ConsoleHelper.cs b/S1API/Console/ConsoleHelper.cs index 60e54d82..92b82e22 100644 --- a/S1API/Console/ConsoleHelper.cs +++ b/S1API/Console/ConsoleHelper.cs @@ -1,14 +1,12 @@ -using System.Collections.Generic; - #if IL2CPP using Il2CppSystem.Collections.Generic; using static Il2CppScheduleOne.Console; - #else using static ScheduleOne.Console; +using System.Collections.Generic; #endif -namespace S1API.Utils +namespace S1API.Console { public static class ConsoleHelper { diff --git a/S1API/Entities/Interfaces/IEntity.cs b/S1API/Entities/Interfaces/IEntity.cs index 8cbf5d3a..eff5f980 100644 --- a/S1API/Entities/Interfaces/IEntity.cs +++ b/S1API/Entities/Interfaces/IEntity.cs @@ -1,6 +1,6 @@ using UnityEngine; -namespace S1API.Entities +namespace S1API.Entities.Interfaces { /// /// Represents an entity within the game world. diff --git a/S1API/Entities/Interfaces/ILivingEntity.cs b/S1API/Entities/Interfaces/ILivingEntity.cs index 65641618..1bb14dd2 100644 --- a/S1API/Entities/Interfaces/ILivingEntity.cs +++ b/S1API/Entities/Interfaces/ILivingEntity.cs @@ -1,6 +1,6 @@ using System; -namespace S1API.Entities +namespace S1API.Entities.Interfaces { /// /// Represents an entity that has health associated. diff --git a/S1API/Entities/NPC.cs b/S1API/Entities/NPC.cs index 9680d5de..d379a783 100644 --- a/S1API/Entities/NPC.cs +++ b/S1API/Entities/NPC.cs @@ -29,21 +29,22 @@ using S1Vehicles = ScheduleOne.Vehicles; using S1Vision = ScheduleOne.Vision; using S1NPCs = ScheduleOne.NPCs; +using HarmonyLib; using System.Collections.Generic; using System.Reflection; -using HarmonyLib; #endif using System; using System.IO; using System.Linq; -using S1API.Entities; +using S1API.Entities.Interfaces; using S1API.Internal.Abstraction; using S1API.Map; +using S1API.Messaging; using UnityEngine; using UnityEngine.Events; -namespace S1API.NPCs +namespace S1API.Entities { /// /// An abstract class intended to be derived from for creating custom NPCs in the game. diff --git a/S1API/Internal/Patches/NPCPatches.cs b/S1API/Internal/Patches/NPCPatches.cs index 8e812141..9fc21df5 100644 --- a/S1API/Internal/Patches/NPCPatches.cs +++ b/S1API/Internal/Patches/NPCPatches.cs @@ -13,8 +13,8 @@ using System.Linq; using System.Reflection; using HarmonyLib; +using S1API.Entities; using S1API.Internal.Utils; -using S1API.NPCs; namespace S1API.Internal.Patches { diff --git a/S1API/Internal/Utils/ButtonListener.cs b/S1API/Internal/Utils/ButtonListener.cs index 75f6a75a..2174930f 100644 --- a/S1API/Internal/Utils/ButtonListener.cs +++ b/S1API/Internal/Utils/ButtonListener.cs @@ -1,69 +1,72 @@ -using UnityEngine.UI; using System; using S1API.Internal.Abstraction; using UnityEngine; +using UnityEngine.UI; -public static class ButtonUtils +namespace S1API.Internal.Utils { - /// - /// Adds a click listener to the specified button, ensuring compatibility with IL2CPP and Mono. - /// - public static void AddListener(Button button, Action action) + public static class ButtonUtils { - if (button == null || action == null) return; - EventHelper.AddListener(action, button.onClick); - } + /// + /// Adds a click listener to the specified button, ensuring compatibility with IL2CPP and Mono. + /// + public static void AddListener(Button button, Action action) + { + if (button == null || action == null) return; + EventHelper.AddListener(action, button.onClick); + } - /// - /// Removes a previously added click listener from the specified button. - /// - public static void RemoveListener(Button button, Action action) - { - if (button == null || action == null) return; - EventHelper.RemoveListener(action, button.onClick); - } + /// + /// Removes a previously added click listener from the specified button. + /// + public static void RemoveListener(Button button, Action action) + { + if (button == null || action == null) return; + EventHelper.RemoveListener(action, button.onClick); + } - /// - /// Removes all listeners from the specified button safely. - /// - public static void ClearListeners(Button button) - { - if (button == null) return; - button.onClick.RemoveAllListeners(); - } + /// + /// Removes all listeners from the specified button safely. + /// + public static void ClearListeners(Button button) + { + if (button == null) return; + button.onClick.RemoveAllListeners(); + } - /// - /// Enables the button and optionally updates the label. - /// - public static void Enable(Button button, Text label = null, string text = null) - { - if (button != null) button.interactable = true; - if (label != null && !string.IsNullOrEmpty(text)) label.text = text; - } + /// + /// Enables the button and optionally updates the label. + /// + public static void Enable(Button button, Text label = null, string text = null) + { + if (button != null) button.interactable = true; + if (label != null && !string.IsNullOrEmpty(text)) label.text = text; + } - /// - /// Disables the button and optionally updates the label. - /// - public static void Disable(Button button, Text label = null, string text = null) - { - if (button != null) button.interactable = false; - if (label != null && !string.IsNullOrEmpty(text)) label.text = text; - } + /// + /// Disables the button and optionally updates the label. + /// + public static void Disable(Button button, Text label = null, string text = null) + { + if (button != null) button.interactable = false; + if (label != null && !string.IsNullOrEmpty(text)) label.text = text; + } - /// - /// Sets the label text of a button with a known Text child. - /// - public static void SetLabel(Text label, string text) - { - if (label != null) label.text = text; - } - /// - /// Sets the button label and background color. - /// - public static void SetStyle(Button button, Text label, string text, Color bg) - { - if (button == null || label == null) return; - label.text = text; - button.image.color = bg; + /// + /// Sets the label text of a button with a known Text child. + /// + public static void SetLabel(Text label, string text) + { + if (label != null) label.text = text; + } + /// + /// Sets the button label and background color. + /// + public static void SetStyle(Button button, Text label, string text, Color bg) + { + if (button == null || label == null) return; + label.text = text; + button.image.color = bg; + } } } \ No newline at end of file diff --git a/S1API/Internal/Utils/RandomUtils.cs b/S1API/Internal/Utils/RandomUtils.cs index a1d984ac..e8d18480 100644 --- a/S1API/Internal/Utils/RandomUtils.cs +++ b/S1API/Internal/Utils/RandomUtils.cs @@ -1,8 +1,7 @@ using System; using System.Collections.Generic; -using UnityEngine; -namespace S1API.Utils +namespace S1API.Internal.Utils { /// /// A utility class providing random selection functionality for lists and numeric ranges. diff --git a/S1API/Messaging/Response.cs b/S1API/Messaging/Response.cs index 100dc6b7..97294cfb 100644 --- a/S1API/Messaging/Response.cs +++ b/S1API/Messaging/Response.cs @@ -5,7 +5,7 @@ #endif using System; -namespace S1API.NPCs +namespace S1API.Messaging { /// /// Represents a message response displayed for the player. diff --git a/S1API/UI/UIFactory.cs b/S1API/UI/UIFactory.cs index 831f68ab..12972121 100644 --- a/S1API/UI/UIFactory.cs +++ b/S1API/UI/UIFactory.cs @@ -1,15 +1,12 @@ #if IL2CPP -using UnityEngine; -using UnityEngine.UI; using Il2CppInterop.Runtime.InteropTypes.Arrays; -#else -using UnityEngine; -using UnityEngine.UI; #endif using System; +using S1API.Internal.Utils; +using UnityEngine; using UnityEngine.Events; -using System.Collections.Generic; +using UnityEngine.UI; namespace S1API.UI { @@ -322,39 +319,39 @@ public static GameObject CreateQuestRow(string name, Transform parent, out GameO /// The text to display on the optional button. Defaults to "Action" if not specified. /// The created GameObject representing the top bar. public static GameObject TopBar(string name, Transform parent, string title,float buttonWidth,float buttonHeight,float topbarSize,int rectleft,int rectright,int recttop,int rectbottom, - Action onRightButtonClick = null, - string rightButtonText = "Action") -{ - var topBar = Panel(name, parent, new Color(0.15f, 0.15f, 0.15f), - new Vector2(0f, topbarSize), new Vector2(1f, 1f)); - - var layout = topBar.AddComponent(); - layout.padding = new RectOffset(rectleft,rectright,recttop,rectbottom);; - layout.spacing = 20; - layout.childAlignment = TextAnchor.MiddleCenter; - layout.childForceExpandWidth = false; - layout.childForceExpandHeight = true; - - // Title - var titleText = Text("TopBarTitle", title, topBar.transform, 26, TextAnchor.MiddleLeft, FontStyle.Bold); - var titleLayout = titleText.gameObject.AddComponent(); - titleLayout.minWidth = 300; - titleLayout.flexibleWidth = 1; - - // Button (if any) - if (onRightButtonClick != null) - { - var (btnGO, btn, label) = ButtonWithLabel("TopBarButton", rightButtonText, topBar.transform, new Color(0.25f, 0.5f, 1f), buttonWidth, buttonHeight); - ButtonUtils.AddListener(btn, onRightButtonClick); + Action onRightButtonClick = null, + string rightButtonText = "Action") + { + var topBar = Panel(name, parent, new Color(0.15f, 0.15f, 0.15f), + new Vector2(0f, topbarSize), new Vector2(1f, 1f)); - var btnLayout = btnGO.AddComponent(); - btnLayout.minWidth = buttonWidth; - btnLayout.preferredHeight = buttonHeight; - btnLayout.flexibleWidth = 0; - } + var layout = topBar.AddComponent(); + layout.padding = new RectOffset(rectleft,rectright,recttop,rectbottom);; + layout.spacing = 20; + layout.childAlignment = TextAnchor.MiddleCenter; + layout.childForceExpandWidth = false; + layout.childForceExpandHeight = true; + + // Title + var titleText = Text("TopBarTitle", title, topBar.transform, 26, TextAnchor.MiddleLeft, FontStyle.Bold); + var titleLayout = titleText.gameObject.AddComponent(); + titleLayout.minWidth = 300; + titleLayout.flexibleWidth = 1; + + // Button (if any) + if (onRightButtonClick != null) + { + var (btnGO, btn, label) = ButtonWithLabel("TopBarButton", rightButtonText, topBar.transform, new Color(0.25f, 0.5f, 1f), buttonWidth, buttonHeight); + ButtonUtils.AddListener(btn, onRightButtonClick); + + var btnLayout = btnGO.AddComponent(); + btnLayout.minWidth = buttonWidth; + btnLayout.preferredHeight = buttonHeight; + btnLayout.flexibleWidth = 0; + } - return topBar; -} + return topBar; + } /// Binds an action to a button and updates its label text. @@ -369,35 +366,35 @@ public static void BindAcceptButton(Button btn, Text label, string text, UnityAc btn.onClick.AddListener(callback); } } -} - -/// -/// Represents a handler that encapsulates a callback action to be invoked when a click event occurs. -/// -/// -/// This class provides a mechanism to handle and execute logic when a click event is triggered. -/// It associates an action defined by a UnityAction delegate with the click event. -/// -public class ClickHandler -{ - /// - /// A private field that stores the UnityAction delegate to be invoked during a specific click event. - /// - private readonly UnityAction _callback; + /// /// Represents a handler that encapsulates a callback action to be invoked when a click event occurs. - public ClickHandler(UnityAction callback) - { - _callback = callback; - } - - /// Invokes the callback action associated with a click event. + /// /// - /// Executes the UnityAction delegate provided during the creation of the ClickHandler instance. - /// This method is used to process and handle click events associated with the handler. + /// This class provides a mechanism to handle and execute logic when a click event is triggered. + /// It associates an action defined by a UnityAction delegate with the click event. /// - public void OnClick() + public class ClickHandler { - _callback.Invoke(); + /// + /// A private field that stores the UnityAction delegate to be invoked during a specific click event. + /// + private readonly UnityAction _callback; + + /// Represents a handler that encapsulates a callback action to be invoked when a click event occurs. + public ClickHandler(UnityAction callback) + { + _callback = callback; + } + + /// Invokes the callback action associated with a click event. + /// + /// Executes the UnityAction delegate provided during the creation of the ClickHandler instance. + /// This method is used to process and handle click events associated with the handler. + /// + public void OnClick() + { + _callback.Invoke(); + } } -} +} \ No newline at end of file From 879ed46200f0e0dd573ff0c4e302daec806a3f47 Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Fri, 25 Apr 2025 22:12:00 -0500 Subject: [PATCH 04/42] feat: Added initial classes for all base game NPCs. (as of current version) --- S1API/Entities/NPCs/DanSamwell.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Docks/AnnaChesterfield.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Docks/BillyKramer.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Docks/CrankyFrank.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Docks/GenghisBarn.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Docks/JaneLucero.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Docks/JavierPerez.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Docks/LisaGardener.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Docks/MacCooper.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Docks/MarcoBaron.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Docks/MelissaWood.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Docks/SalvadorMoreno.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Downtown/BradCrosby.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Downtown/ElizabethHomley.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Downtown/EugeneBuckley.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Downtown/GregFliggle.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Downtown/JeffGilmore.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Downtown/JenniferRivera.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Downtown/KevinOakley.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Downtown/LouisFourier.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Downtown/LucyPennington.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Downtown/PhilipWentworth.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Downtown/RandyCaulfield.cs | 14 ++++++++++++++ S1API/Entities/NPCs/IgorRomanovich.cs | 14 ++++++++++++++ S1API/Entities/NPCs/MannyOakfield.cs | 14 ++++++++++++++ S1API/Entities/NPCs/NPC_LIST.md | 7 +++++++ .../Entities/NPCs/{ => Northtown}/AlbertHoover.cs | 5 ++--- S1API/Entities/NPCs/Northtown/AustinSteiner.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Northtown/BenjiColeman.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Northtown/BethPenn.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Northtown/ChloeBowers.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Northtown/DonnaMartin.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Northtown/GeraldinePoon.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Northtown/JessiWaters.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Northtown/KathyHenderson.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Northtown/KyleCooley.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Northtown/LudwigMeyer.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Northtown/MickLubbin.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Northtown/Ming.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Northtown/PeggyMyers.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Northtown/PeterFile.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Northtown/SamThompson.cs | 14 ++++++++++++++ S1API/Entities/NPCs/OscarHolland.cs | 14 ++++++++++++++ .../Entities/NPCs/PoliceOfficers/OfficerBailey.cs | 14 ++++++++++++++ .../Entities/NPCs/PoliceOfficers/OfficerCooper.cs | 14 ++++++++++++++ .../Entities/NPCs/PoliceOfficers/OfficerGreen.cs | 14 ++++++++++++++ .../Entities/NPCs/PoliceOfficers/OfficerHoward.cs | 14 ++++++++++++++ .../NPCs/PoliceOfficers/OfficerJackson.cs | 14 ++++++++++++++ S1API/Entities/NPCs/PoliceOfficers/OfficerLee.cs | 14 ++++++++++++++ .../Entities/NPCs/PoliceOfficers/OfficerLopez.cs | 14 ++++++++++++++ .../Entities/NPCs/PoliceOfficers/OfficerMurphy.cs | 14 ++++++++++++++ .../Entities/NPCs/PoliceOfficers/OfficerOakley.cs | 14 ++++++++++++++ S1API/Entities/NPCs/StanCarney.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Suburbia/AlisonKnight.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Suburbia/CarlBundy.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Suburbia/ChrisSullivan.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Suburbia/DennisKennedy.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Suburbia/HankStevenson.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Suburbia/HaroldColt.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Suburbia/JackKnight.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Suburbia/JackieStevenson.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Suburbia/JeremyWilkinson.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Suburbia/KarenKennedy.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Suburbia/WeiLong.cs | 14 ++++++++++++++ S1API/Entities/NPCs/UncleNelson.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Uptown/FionaHancock.cs | 15 +++++++++++++++ S1API/Entities/NPCs/Uptown/HerbertBleuball.cs | 15 +++++++++++++++ S1API/Entities/NPCs/Uptown/JenHeard.cs | 15 +++++++++++++++ S1API/Entities/NPCs/Uptown/LeoRivers.cs | 15 +++++++++++++++ S1API/Entities/NPCs/Uptown/LilyTurner.cs | 15 +++++++++++++++ S1API/Entities/NPCs/Uptown/MichaelBoog.cs | 15 +++++++++++++++ S1API/Entities/NPCs/Uptown/PearlMoore.cs | 15 +++++++++++++++ S1API/Entities/NPCs/Uptown/RayHoffman.cs | 15 +++++++++++++++ S1API/Entities/NPCs/Uptown/TobiasWentworth.cs | 15 +++++++++++++++ S1API/Entities/NPCs/Uptown/WalterCussler.cs | 15 +++++++++++++++ S1API/Entities/NPCs/Westville/CharlesRowland.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Westville/DeanWebster.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Westville/DorisLubbin.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Westville/GeorgeGreene.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Westville/JerryMontero.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Westville/JoyceBall.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Westville/KeithWagner.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Westville/KimDelaney.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Westville/MegCooley.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Westville/MollyPresley.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Westville/ShirleyWatts.cs | 14 ++++++++++++++ S1API/Entities/NPCs/Westville/TrentSherman.cs | 14 ++++++++++++++ 87 files changed, 1209 insertions(+), 3 deletions(-) create mode 100644 S1API/Entities/NPCs/DanSamwell.cs create mode 100644 S1API/Entities/NPCs/Docks/AnnaChesterfield.cs create mode 100644 S1API/Entities/NPCs/Docks/BillyKramer.cs create mode 100644 S1API/Entities/NPCs/Docks/CrankyFrank.cs create mode 100644 S1API/Entities/NPCs/Docks/GenghisBarn.cs create mode 100644 S1API/Entities/NPCs/Docks/JaneLucero.cs create mode 100644 S1API/Entities/NPCs/Docks/JavierPerez.cs create mode 100644 S1API/Entities/NPCs/Docks/LisaGardener.cs create mode 100644 S1API/Entities/NPCs/Docks/MacCooper.cs create mode 100644 S1API/Entities/NPCs/Docks/MarcoBaron.cs create mode 100644 S1API/Entities/NPCs/Docks/MelissaWood.cs create mode 100644 S1API/Entities/NPCs/Docks/SalvadorMoreno.cs create mode 100644 S1API/Entities/NPCs/Downtown/BradCrosby.cs create mode 100644 S1API/Entities/NPCs/Downtown/ElizabethHomley.cs create mode 100644 S1API/Entities/NPCs/Downtown/EugeneBuckley.cs create mode 100644 S1API/Entities/NPCs/Downtown/GregFliggle.cs create mode 100644 S1API/Entities/NPCs/Downtown/JeffGilmore.cs create mode 100644 S1API/Entities/NPCs/Downtown/JenniferRivera.cs create mode 100644 S1API/Entities/NPCs/Downtown/KevinOakley.cs create mode 100644 S1API/Entities/NPCs/Downtown/LouisFourier.cs create mode 100644 S1API/Entities/NPCs/Downtown/LucyPennington.cs create mode 100644 S1API/Entities/NPCs/Downtown/PhilipWentworth.cs create mode 100644 S1API/Entities/NPCs/Downtown/RandyCaulfield.cs create mode 100644 S1API/Entities/NPCs/IgorRomanovich.cs create mode 100644 S1API/Entities/NPCs/MannyOakfield.cs rename S1API/Entities/NPCs/{ => Northtown}/AlbertHoover.cs (84%) create mode 100644 S1API/Entities/NPCs/Northtown/AustinSteiner.cs create mode 100644 S1API/Entities/NPCs/Northtown/BenjiColeman.cs create mode 100644 S1API/Entities/NPCs/Northtown/BethPenn.cs create mode 100644 S1API/Entities/NPCs/Northtown/ChloeBowers.cs create mode 100644 S1API/Entities/NPCs/Northtown/DonnaMartin.cs create mode 100644 S1API/Entities/NPCs/Northtown/GeraldinePoon.cs create mode 100644 S1API/Entities/NPCs/Northtown/JessiWaters.cs create mode 100644 S1API/Entities/NPCs/Northtown/KathyHenderson.cs create mode 100644 S1API/Entities/NPCs/Northtown/KyleCooley.cs create mode 100644 S1API/Entities/NPCs/Northtown/LudwigMeyer.cs create mode 100644 S1API/Entities/NPCs/Northtown/MickLubbin.cs create mode 100644 S1API/Entities/NPCs/Northtown/Ming.cs create mode 100644 S1API/Entities/NPCs/Northtown/PeggyMyers.cs create mode 100644 S1API/Entities/NPCs/Northtown/PeterFile.cs create mode 100644 S1API/Entities/NPCs/Northtown/SamThompson.cs create mode 100644 S1API/Entities/NPCs/OscarHolland.cs create mode 100644 S1API/Entities/NPCs/PoliceOfficers/OfficerBailey.cs create mode 100644 S1API/Entities/NPCs/PoliceOfficers/OfficerCooper.cs create mode 100644 S1API/Entities/NPCs/PoliceOfficers/OfficerGreen.cs create mode 100644 S1API/Entities/NPCs/PoliceOfficers/OfficerHoward.cs create mode 100644 S1API/Entities/NPCs/PoliceOfficers/OfficerJackson.cs create mode 100644 S1API/Entities/NPCs/PoliceOfficers/OfficerLee.cs create mode 100644 S1API/Entities/NPCs/PoliceOfficers/OfficerLopez.cs create mode 100644 S1API/Entities/NPCs/PoliceOfficers/OfficerMurphy.cs create mode 100644 S1API/Entities/NPCs/PoliceOfficers/OfficerOakley.cs create mode 100644 S1API/Entities/NPCs/StanCarney.cs create mode 100644 S1API/Entities/NPCs/Suburbia/AlisonKnight.cs create mode 100644 S1API/Entities/NPCs/Suburbia/CarlBundy.cs create mode 100644 S1API/Entities/NPCs/Suburbia/ChrisSullivan.cs create mode 100644 S1API/Entities/NPCs/Suburbia/DennisKennedy.cs create mode 100644 S1API/Entities/NPCs/Suburbia/HankStevenson.cs create mode 100644 S1API/Entities/NPCs/Suburbia/HaroldColt.cs create mode 100644 S1API/Entities/NPCs/Suburbia/JackKnight.cs create mode 100644 S1API/Entities/NPCs/Suburbia/JackieStevenson.cs create mode 100644 S1API/Entities/NPCs/Suburbia/JeremyWilkinson.cs create mode 100644 S1API/Entities/NPCs/Suburbia/KarenKennedy.cs create mode 100644 S1API/Entities/NPCs/Suburbia/WeiLong.cs create mode 100644 S1API/Entities/NPCs/UncleNelson.cs create mode 100644 S1API/Entities/NPCs/Uptown/FionaHancock.cs create mode 100644 S1API/Entities/NPCs/Uptown/HerbertBleuball.cs create mode 100644 S1API/Entities/NPCs/Uptown/JenHeard.cs create mode 100644 S1API/Entities/NPCs/Uptown/LeoRivers.cs create mode 100644 S1API/Entities/NPCs/Uptown/LilyTurner.cs create mode 100644 S1API/Entities/NPCs/Uptown/MichaelBoog.cs create mode 100644 S1API/Entities/NPCs/Uptown/PearlMoore.cs create mode 100644 S1API/Entities/NPCs/Uptown/RayHoffman.cs create mode 100644 S1API/Entities/NPCs/Uptown/TobiasWentworth.cs create mode 100644 S1API/Entities/NPCs/Uptown/WalterCussler.cs create mode 100644 S1API/Entities/NPCs/Westville/CharlesRowland.cs create mode 100644 S1API/Entities/NPCs/Westville/DeanWebster.cs create mode 100644 S1API/Entities/NPCs/Westville/DorisLubbin.cs create mode 100644 S1API/Entities/NPCs/Westville/GeorgeGreene.cs create mode 100644 S1API/Entities/NPCs/Westville/JerryMontero.cs create mode 100644 S1API/Entities/NPCs/Westville/JoyceBall.cs create mode 100644 S1API/Entities/NPCs/Westville/KeithWagner.cs create mode 100644 S1API/Entities/NPCs/Westville/KimDelaney.cs create mode 100644 S1API/Entities/NPCs/Westville/MegCooley.cs create mode 100644 S1API/Entities/NPCs/Westville/MollyPresley.cs create mode 100644 S1API/Entities/NPCs/Westville/ShirleyWatts.cs create mode 100644 S1API/Entities/NPCs/Westville/TrentSherman.cs diff --git a/S1API/Entities/NPCs/DanSamwell.cs b/S1API/Entities/NPCs/DanSamwell.cs new file mode 100644 index 00000000..4e374279 --- /dev/null +++ b/S1API/Entities/NPCs/DanSamwell.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs +{ + public class DanSamwell : NPC + { + internal DanSamwell() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "dan_samwell")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Docks/AnnaChesterfield.cs b/S1API/Entities/NPCs/Docks/AnnaChesterfield.cs new file mode 100644 index 00000000..aaeb3fd5 --- /dev/null +++ b/S1API/Entities/NPCs/Docks/AnnaChesterfield.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Docks +{ + public class AnnaChesterfield : NPC + { + internal AnnaChesterfield() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "anna_chesterfield")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Docks/BillyKramer.cs b/S1API/Entities/NPCs/Docks/BillyKramer.cs new file mode 100644 index 00000000..f7e2ab9c --- /dev/null +++ b/S1API/Entities/NPCs/Docks/BillyKramer.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Docks +{ + public class BillyKramer : NPC + { + internal BillyKramer() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "billy_kramer")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Docks/CrankyFrank.cs b/S1API/Entities/NPCs/Docks/CrankyFrank.cs new file mode 100644 index 00000000..60a0f3c3 --- /dev/null +++ b/S1API/Entities/NPCs/Docks/CrankyFrank.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Docks +{ + public class CrankyFrank : NPC + { + internal CrankyFrank() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "cranky_frank")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Docks/GenghisBarn.cs b/S1API/Entities/NPCs/Docks/GenghisBarn.cs new file mode 100644 index 00000000..a0bd37cf --- /dev/null +++ b/S1API/Entities/NPCs/Docks/GenghisBarn.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Docks +{ + public class GenghisBarn : NPC + { + internal GenghisBarn() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "genghis_barn")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Docks/JaneLucero.cs b/S1API/Entities/NPCs/Docks/JaneLucero.cs new file mode 100644 index 00000000..1bc5ed3e --- /dev/null +++ b/S1API/Entities/NPCs/Docks/JaneLucero.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Docks +{ + public class JaneLucero : NPC + { + internal JaneLucero() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "jane_lucero")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Docks/JavierPerez.cs b/S1API/Entities/NPCs/Docks/JavierPerez.cs new file mode 100644 index 00000000..996bb995 --- /dev/null +++ b/S1API/Entities/NPCs/Docks/JavierPerez.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Docks +{ + public class JavierPerez : NPC + { + internal JavierPerez() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "javier_perez")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Docks/LisaGardener.cs b/S1API/Entities/NPCs/Docks/LisaGardener.cs new file mode 100644 index 00000000..94690444 --- /dev/null +++ b/S1API/Entities/NPCs/Docks/LisaGardener.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Docks +{ + public class LisaGardener : NPC + { + internal LisaGardener() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "lisa_gardener")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Docks/MacCooper.cs b/S1API/Entities/NPCs/Docks/MacCooper.cs new file mode 100644 index 00000000..f51263f4 --- /dev/null +++ b/S1API/Entities/NPCs/Docks/MacCooper.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Docks +{ + public class MacCooper : NPC + { + internal MacCooper() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "mac_cooper")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Docks/MarcoBaron.cs b/S1API/Entities/NPCs/Docks/MarcoBaron.cs new file mode 100644 index 00000000..98cc3f38 --- /dev/null +++ b/S1API/Entities/NPCs/Docks/MarcoBaron.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Docks +{ + public class MarcoBaron : NPC + { + internal MarcoBaron() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "marco_baron")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Docks/MelissaWood.cs b/S1API/Entities/NPCs/Docks/MelissaWood.cs new file mode 100644 index 00000000..deebcd71 --- /dev/null +++ b/S1API/Entities/NPCs/Docks/MelissaWood.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Docks +{ + public class MelissaWood : NPC + { + internal MelissaWood() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "melissa_wood")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Docks/SalvadorMoreno.cs b/S1API/Entities/NPCs/Docks/SalvadorMoreno.cs new file mode 100644 index 00000000..e2ab021e --- /dev/null +++ b/S1API/Entities/NPCs/Docks/SalvadorMoreno.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Docks +{ + public class SalvadorMoreno : NPC + { + internal SalvadorMoreno() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "salvador_moreno")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Downtown/BradCrosby.cs b/S1API/Entities/NPCs/Downtown/BradCrosby.cs new file mode 100644 index 00000000..5afde74a --- /dev/null +++ b/S1API/Entities/NPCs/Downtown/BradCrosby.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Downtown +{ + public class BradCrosby : NPC + { + internal BradCrosby() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "brad_crosby")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Downtown/ElizabethHomley.cs b/S1API/Entities/NPCs/Downtown/ElizabethHomley.cs new file mode 100644 index 00000000..9a4ff903 --- /dev/null +++ b/S1API/Entities/NPCs/Downtown/ElizabethHomley.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Downtown +{ + public class ElizabethHomley : NPC + { + internal ElizabethHomley() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "elizabeth_homley")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Downtown/EugeneBuckley.cs b/S1API/Entities/NPCs/Downtown/EugeneBuckley.cs new file mode 100644 index 00000000..ef59eaed --- /dev/null +++ b/S1API/Entities/NPCs/Downtown/EugeneBuckley.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Downtown +{ + public class EugeneBuckley : NPC + { + internal EugeneBuckley() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "eugene_buckley")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Downtown/GregFliggle.cs b/S1API/Entities/NPCs/Downtown/GregFliggle.cs new file mode 100644 index 00000000..bf8264ad --- /dev/null +++ b/S1API/Entities/NPCs/Downtown/GregFliggle.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Downtown +{ + public class GregFliggle : NPC + { + internal GregFliggle() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "greg_fliggle")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Downtown/JeffGilmore.cs b/S1API/Entities/NPCs/Downtown/JeffGilmore.cs new file mode 100644 index 00000000..42ce8592 --- /dev/null +++ b/S1API/Entities/NPCs/Downtown/JeffGilmore.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Downtown +{ + public class JeffGilmore : NPC + { + internal JeffGilmore() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "jeff_gilmore")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Downtown/JenniferRivera.cs b/S1API/Entities/NPCs/Downtown/JenniferRivera.cs new file mode 100644 index 00000000..1e2b7d9c --- /dev/null +++ b/S1API/Entities/NPCs/Downtown/JenniferRivera.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Downtown +{ + public class JenniferRivera : NPC + { + internal JenniferRivera() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "jennifer_rivera")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Downtown/KevinOakley.cs b/S1API/Entities/NPCs/Downtown/KevinOakley.cs new file mode 100644 index 00000000..809690c1 --- /dev/null +++ b/S1API/Entities/NPCs/Downtown/KevinOakley.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Downtown +{ + public class KevinOakley : NPC + { + internal KevinOakley() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "kevin_oakley")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Downtown/LouisFourier.cs b/S1API/Entities/NPCs/Downtown/LouisFourier.cs new file mode 100644 index 00000000..35e27246 --- /dev/null +++ b/S1API/Entities/NPCs/Downtown/LouisFourier.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Downtown +{ + public class LouisFourier : NPC + { + internal LouisFourier() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "louis_fourier")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Downtown/LucyPennington.cs b/S1API/Entities/NPCs/Downtown/LucyPennington.cs new file mode 100644 index 00000000..f00de681 --- /dev/null +++ b/S1API/Entities/NPCs/Downtown/LucyPennington.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Downtown +{ + public class LucyPennington : NPC + { + internal LucyPennington() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "lucy_pennington")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Downtown/PhilipWentworth.cs b/S1API/Entities/NPCs/Downtown/PhilipWentworth.cs new file mode 100644 index 00000000..3d2d2d81 --- /dev/null +++ b/S1API/Entities/NPCs/Downtown/PhilipWentworth.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Downtown +{ + public class PhilipWentworth : NPC + { + internal PhilipWentworth() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "philip_wentworth")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Downtown/RandyCaulfield.cs b/S1API/Entities/NPCs/Downtown/RandyCaulfield.cs new file mode 100644 index 00000000..8ece0b34 --- /dev/null +++ b/S1API/Entities/NPCs/Downtown/RandyCaulfield.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Downtown +{ + public class RandyCaulfield : NPC + { + internal RandyCaulfield() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "randy_caulfield")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/IgorRomanovich.cs b/S1API/Entities/NPCs/IgorRomanovich.cs new file mode 100644 index 00000000..a5ed262a --- /dev/null +++ b/S1API/Entities/NPCs/IgorRomanovich.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs +{ + public class IgorRomanovich : NPC + { + internal IgorRomanovich() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "igor_romanovich")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/MannyOakfield.cs b/S1API/Entities/NPCs/MannyOakfield.cs new file mode 100644 index 00000000..5fe76811 --- /dev/null +++ b/S1API/Entities/NPCs/MannyOakfield.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs +{ + public class MannyOakfield : NPC + { + internal MannyOakfield() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "manny_oakfield")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/NPC_LIST.md b/S1API/Entities/NPCs/NPC_LIST.md index 334576fa..6c223ab2 100644 --- a/S1API/Entities/NPCs/NPC_LIST.md +++ b/S1API/Entities/NPCs/NPC_LIST.md @@ -1,3 +1,10 @@ +# NPC List +Current list of NPCs in the game. +Includes which class is associated with the NPC. + +**Last Updated: (v0.3.4f8)** + +--- **manny_oakfield** ScheduleOne.NPCs.CharacterClasses.Fixer --- diff --git a/S1API/Entities/NPCs/AlbertHoover.cs b/S1API/Entities/NPCs/Northtown/AlbertHoover.cs similarity index 84% rename from S1API/Entities/NPCs/AlbertHoover.cs rename to S1API/Entities/NPCs/Northtown/AlbertHoover.cs index 072da13a..c74ca04e 100644 --- a/S1API/Entities/NPCs/AlbertHoover.cs +++ b/S1API/Entities/NPCs/Northtown/AlbertHoover.cs @@ -2,11 +2,10 @@ using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; -#endif - +#endif using System.Linq; -namespace S1API.NPCs +namespace S1API.Entities.NPCs.Northtown { public class AlbertHoover : NPC { diff --git a/S1API/Entities/NPCs/Northtown/AustinSteiner.cs b/S1API/Entities/NPCs/Northtown/AustinSteiner.cs new file mode 100644 index 00000000..ff960a88 --- /dev/null +++ b/S1API/Entities/NPCs/Northtown/AustinSteiner.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Northtown +{ + public class AustinSteiner : NPC + { + internal AustinSteiner() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "austin_steiner")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Northtown/BenjiColeman.cs b/S1API/Entities/NPCs/Northtown/BenjiColeman.cs new file mode 100644 index 00000000..f749c5bc --- /dev/null +++ b/S1API/Entities/NPCs/Northtown/BenjiColeman.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Northtown +{ + public class BenjiColeman : NPC + { + internal BenjiColeman() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "benji_coleman")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Northtown/BethPenn.cs b/S1API/Entities/NPCs/Northtown/BethPenn.cs new file mode 100644 index 00000000..3b3ae6d6 --- /dev/null +++ b/S1API/Entities/NPCs/Northtown/BethPenn.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Northtown +{ + public class BethPenn : NPC + { + internal BethPenn() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "beth_penn")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Northtown/ChloeBowers.cs b/S1API/Entities/NPCs/Northtown/ChloeBowers.cs new file mode 100644 index 00000000..a7e004ed --- /dev/null +++ b/S1API/Entities/NPCs/Northtown/ChloeBowers.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Northtown +{ + public class ChloeBowers : NPC + { + internal ChloeBowers() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "chloe_bowers")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Northtown/DonnaMartin.cs b/S1API/Entities/NPCs/Northtown/DonnaMartin.cs new file mode 100644 index 00000000..830201bb --- /dev/null +++ b/S1API/Entities/NPCs/Northtown/DonnaMartin.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Northtown +{ + public class DonnaMartin : NPC + { + internal DonnaMartin() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "donna_martin")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Northtown/GeraldinePoon.cs b/S1API/Entities/NPCs/Northtown/GeraldinePoon.cs new file mode 100644 index 00000000..7860d411 --- /dev/null +++ b/S1API/Entities/NPCs/Northtown/GeraldinePoon.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Northtown +{ + public class GeraldinePoon : NPC + { + internal GeraldinePoon() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "geraldine_poon")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Northtown/JessiWaters.cs b/S1API/Entities/NPCs/Northtown/JessiWaters.cs new file mode 100644 index 00000000..d8b32fcc --- /dev/null +++ b/S1API/Entities/NPCs/Northtown/JessiWaters.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Northtown +{ + public class JessiWaters : NPC + { + internal JessiWaters() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "jessi_waters")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Northtown/KathyHenderson.cs b/S1API/Entities/NPCs/Northtown/KathyHenderson.cs new file mode 100644 index 00000000..516afb8d --- /dev/null +++ b/S1API/Entities/NPCs/Northtown/KathyHenderson.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Northtown +{ + public class KathyHenderson : NPC + { + internal KathyHenderson() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "kathy_henderson")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Northtown/KyleCooley.cs b/S1API/Entities/NPCs/Northtown/KyleCooley.cs new file mode 100644 index 00000000..be282459 --- /dev/null +++ b/S1API/Entities/NPCs/Northtown/KyleCooley.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Northtown +{ + public class KyleCooley : NPC + { + internal KyleCooley() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "kyle_cooley")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Northtown/LudwigMeyer.cs b/S1API/Entities/NPCs/Northtown/LudwigMeyer.cs new file mode 100644 index 00000000..46eddc2c --- /dev/null +++ b/S1API/Entities/NPCs/Northtown/LudwigMeyer.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Northtown +{ + public class LudwigMeyer : NPC + { + internal LudwigMeyer() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "ludwig_meyer")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Northtown/MickLubbin.cs b/S1API/Entities/NPCs/Northtown/MickLubbin.cs new file mode 100644 index 00000000..1b86ff16 --- /dev/null +++ b/S1API/Entities/NPCs/Northtown/MickLubbin.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Northtown +{ + public class MickLubbin : NPC + { + internal MickLubbin() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "mick_lubbin")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Northtown/Ming.cs b/S1API/Entities/NPCs/Northtown/Ming.cs new file mode 100644 index 00000000..a9ed1c41 --- /dev/null +++ b/S1API/Entities/NPCs/Northtown/Ming.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Northtown +{ + public class Ming : NPC + { + internal Ming() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "ming")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Northtown/PeggyMyers.cs b/S1API/Entities/NPCs/Northtown/PeggyMyers.cs new file mode 100644 index 00000000..b9e2ddd1 --- /dev/null +++ b/S1API/Entities/NPCs/Northtown/PeggyMyers.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Northtown +{ + public class PeggyMyers : NPC + { + internal PeggyMyers() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "peggy_myers")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Northtown/PeterFile.cs b/S1API/Entities/NPCs/Northtown/PeterFile.cs new file mode 100644 index 00000000..efe8c3ad --- /dev/null +++ b/S1API/Entities/NPCs/Northtown/PeterFile.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Northtown +{ + public class PeterFile : NPC + { + internal PeterFile() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "peter_file")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Northtown/SamThompson.cs b/S1API/Entities/NPCs/Northtown/SamThompson.cs new file mode 100644 index 00000000..40beb60b --- /dev/null +++ b/S1API/Entities/NPCs/Northtown/SamThompson.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Northtown +{ + public class SamThompson : NPC + { + internal SamThompson() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "sam_thompson")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/OscarHolland.cs b/S1API/Entities/NPCs/OscarHolland.cs new file mode 100644 index 00000000..41362dc8 --- /dev/null +++ b/S1API/Entities/NPCs/OscarHolland.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs +{ + public class OscarHolland : NPC + { + internal OscarHolland() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "oscar_holland")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerBailey.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerBailey.cs new file mode 100644 index 00000000..404513a7 --- /dev/null +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerBailey.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.PoliceOfficers +{ + public class OfficerBailey : NPC + { + internal OfficerBailey() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_bailey")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerCooper.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerCooper.cs new file mode 100644 index 00000000..c9893d5d --- /dev/null +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerCooper.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.PoliceOfficers +{ + public class OfficerCooper : NPC + { + internal OfficerCooper() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_cooper")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerGreen.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerGreen.cs new file mode 100644 index 00000000..a3bc346e --- /dev/null +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerGreen.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.PoliceOfficers +{ + public class OfficerGreen : NPC + { + internal OfficerGreen() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_green")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerHoward.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerHoward.cs new file mode 100644 index 00000000..038b2e82 --- /dev/null +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerHoward.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.PoliceOfficers +{ + public class OfficerHoward : NPC + { + internal OfficerHoward() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_howard")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerJackson.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerJackson.cs new file mode 100644 index 00000000..8acb6ea4 --- /dev/null +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerJackson.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.PoliceOfficers +{ + public class OfficerJackson : NPC + { + internal OfficerJackson() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_jackson")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerLee.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerLee.cs new file mode 100644 index 00000000..a94fe42c --- /dev/null +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerLee.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.PoliceOfficers +{ + public class OfficerLee : NPC + { + internal OfficerLee() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_lee")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerLopez.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerLopez.cs new file mode 100644 index 00000000..e85e22c5 --- /dev/null +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerLopez.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.PoliceOfficers +{ + public class OfficerLopez : NPC + { + internal OfficerLopez() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_lopez")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerMurphy.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerMurphy.cs new file mode 100644 index 00000000..7d8a66df --- /dev/null +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerMurphy.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.PoliceOfficers +{ + public class OfficerMurphy : NPC + { + internal OfficerMurphy() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_murphy")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerOakley.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerOakley.cs new file mode 100644 index 00000000..d444cb58 --- /dev/null +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerOakley.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.PoliceOfficers +{ + public class OfficerOakley : NPC + { + internal OfficerOakley() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_oakley")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/StanCarney.cs b/S1API/Entities/NPCs/StanCarney.cs new file mode 100644 index 00000000..6f3fbe41 --- /dev/null +++ b/S1API/Entities/NPCs/StanCarney.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs +{ + public class StanCarney : NPC + { + internal StanCarney() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "stan_carney")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Suburbia/AlisonKnight.cs b/S1API/Entities/NPCs/Suburbia/AlisonKnight.cs new file mode 100644 index 00000000..3bdf3056 --- /dev/null +++ b/S1API/Entities/NPCs/Suburbia/AlisonKnight.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Suburbia +{ + public class AlisonKnight : NPC + { + internal AlisonKnight() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "alison_knight")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Suburbia/CarlBundy.cs b/S1API/Entities/NPCs/Suburbia/CarlBundy.cs new file mode 100644 index 00000000..c5a625d7 --- /dev/null +++ b/S1API/Entities/NPCs/Suburbia/CarlBundy.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Suburbia +{ + public class CarlBundy : NPC + { + internal CarlBundy() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "carl_bundy")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Suburbia/ChrisSullivan.cs b/S1API/Entities/NPCs/Suburbia/ChrisSullivan.cs new file mode 100644 index 00000000..afdcdde6 --- /dev/null +++ b/S1API/Entities/NPCs/Suburbia/ChrisSullivan.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Suburbia +{ + public class ChrisSullivan : NPC + { + internal ChrisSullivan() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "chris_sullivan")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Suburbia/DennisKennedy.cs b/S1API/Entities/NPCs/Suburbia/DennisKennedy.cs new file mode 100644 index 00000000..b3c9d0d8 --- /dev/null +++ b/S1API/Entities/NPCs/Suburbia/DennisKennedy.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Suburbia +{ + public class DennisKennedy : NPC + { + internal DennisKennedy() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "dennis_kennedy")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Suburbia/HankStevenson.cs b/S1API/Entities/NPCs/Suburbia/HankStevenson.cs new file mode 100644 index 00000000..054b283f --- /dev/null +++ b/S1API/Entities/NPCs/Suburbia/HankStevenson.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Suburbia +{ + public class HankStevenson : NPC + { + internal HankStevenson() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "hank_stevenson")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Suburbia/HaroldColt.cs b/S1API/Entities/NPCs/Suburbia/HaroldColt.cs new file mode 100644 index 00000000..9c13dd51 --- /dev/null +++ b/S1API/Entities/NPCs/Suburbia/HaroldColt.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Suburbia +{ + public class HaroldColt : NPC + { + internal HaroldColt() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "harold_colt")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Suburbia/JackKnight.cs b/S1API/Entities/NPCs/Suburbia/JackKnight.cs new file mode 100644 index 00000000..3e5e5c2b --- /dev/null +++ b/S1API/Entities/NPCs/Suburbia/JackKnight.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Suburbia +{ + public class JackKnight : NPC + { + internal JackKnight() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "jack_knight")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Suburbia/JackieStevenson.cs b/S1API/Entities/NPCs/Suburbia/JackieStevenson.cs new file mode 100644 index 00000000..d5b0bea9 --- /dev/null +++ b/S1API/Entities/NPCs/Suburbia/JackieStevenson.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Suburbia +{ + public class JackieStevenson : NPC + { + internal JackieStevenson() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "jackie_stevenson")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Suburbia/JeremyWilkinson.cs b/S1API/Entities/NPCs/Suburbia/JeremyWilkinson.cs new file mode 100644 index 00000000..d2b24f9d --- /dev/null +++ b/S1API/Entities/NPCs/Suburbia/JeremyWilkinson.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Suburbia +{ + public class JeremyWilkinson : NPC + { + internal JeremyWilkinson() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "jeremy_wilkinson")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Suburbia/KarenKennedy.cs b/S1API/Entities/NPCs/Suburbia/KarenKennedy.cs new file mode 100644 index 00000000..f775dfc4 --- /dev/null +++ b/S1API/Entities/NPCs/Suburbia/KarenKennedy.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Suburbia +{ + public class KarenKennedy : NPC + { + internal KarenKennedy() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "karen_kennedy")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Suburbia/WeiLong.cs b/S1API/Entities/NPCs/Suburbia/WeiLong.cs new file mode 100644 index 00000000..617a5f50 --- /dev/null +++ b/S1API/Entities/NPCs/Suburbia/WeiLong.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Suburbia +{ + public class WeiLong : NPC + { + internal WeiLong() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "wei_long")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/UncleNelson.cs b/S1API/Entities/NPCs/UncleNelson.cs new file mode 100644 index 00000000..31ece8c8 --- /dev/null +++ b/S1API/Entities/NPCs/UncleNelson.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs +{ + public class UncleNelson : NPC + { + internal UncleNelson() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "uncle_nelson")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Uptown/FionaHancock.cs b/S1API/Entities/NPCs/Uptown/FionaHancock.cs new file mode 100644 index 00000000..d8b01fc6 --- /dev/null +++ b/S1API/Entities/NPCs/Uptown/FionaHancock.cs @@ -0,0 +1,15 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; +using NPC = S1API.Entities.NPC; + +namespace S1API.Entities.NPCs.Uptown +{ + public class FionaHancock : NPC + { + internal FionaHancock() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "fiona_hancock")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Uptown/HerbertBleuball.cs b/S1API/Entities/NPCs/Uptown/HerbertBleuball.cs new file mode 100644 index 00000000..a97faa9a --- /dev/null +++ b/S1API/Entities/NPCs/Uptown/HerbertBleuball.cs @@ -0,0 +1,15 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; +using NPC = S1API.Entities.NPC; + +namespace S1API.Entities.NPCs.Uptown +{ + public class HerbertBleuball : NPC + { + internal HerbertBleuball() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "herbert_bleuball")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Uptown/JenHeard.cs b/S1API/Entities/NPCs/Uptown/JenHeard.cs new file mode 100644 index 00000000..59a04042 --- /dev/null +++ b/S1API/Entities/NPCs/Uptown/JenHeard.cs @@ -0,0 +1,15 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; +using NPC = S1API.Entities.NPC; + +namespace S1API.Entities.NPCs.Uptown +{ + public class JenHeard : NPC + { + internal JenHeard() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "jen_heard")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Uptown/LeoRivers.cs b/S1API/Entities/NPCs/Uptown/LeoRivers.cs new file mode 100644 index 00000000..6be3b15a --- /dev/null +++ b/S1API/Entities/NPCs/Uptown/LeoRivers.cs @@ -0,0 +1,15 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; +using NPC = S1API.Entities.NPC; + +namespace S1API.Entities.NPCs.Uptown +{ + public class LeoRivers : NPC + { + internal LeoRivers() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "leo_rivers")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Uptown/LilyTurner.cs b/S1API/Entities/NPCs/Uptown/LilyTurner.cs new file mode 100644 index 00000000..a0795802 --- /dev/null +++ b/S1API/Entities/NPCs/Uptown/LilyTurner.cs @@ -0,0 +1,15 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; +using NPC = S1API.Entities.NPC; + +namespace S1API.Entities.NPCs.Uptown +{ + public class LilyTurner : NPC + { + internal LilyTurner() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "lily_turner")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Uptown/MichaelBoog.cs b/S1API/Entities/NPCs/Uptown/MichaelBoog.cs new file mode 100644 index 00000000..6fa190ad --- /dev/null +++ b/S1API/Entities/NPCs/Uptown/MichaelBoog.cs @@ -0,0 +1,15 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; +using NPC = S1API.Entities.NPC; + +namespace S1API.Entities.NPCs.Uptown +{ + public class MichaelBoog : NPC + { + internal MichaelBoog() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "michael_boog")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Uptown/PearlMoore.cs b/S1API/Entities/NPCs/Uptown/PearlMoore.cs new file mode 100644 index 00000000..b1b601e1 --- /dev/null +++ b/S1API/Entities/NPCs/Uptown/PearlMoore.cs @@ -0,0 +1,15 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; +using NPC = S1API.Entities.NPC; + +namespace S1API.Entities.NPCs.Uptown +{ + public class PearlMoore : NPC + { + internal PearlMoore() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "pearl_moore")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Uptown/RayHoffman.cs b/S1API/Entities/NPCs/Uptown/RayHoffman.cs new file mode 100644 index 00000000..c8123084 --- /dev/null +++ b/S1API/Entities/NPCs/Uptown/RayHoffman.cs @@ -0,0 +1,15 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; +using NPC = S1API.Entities.NPC; + +namespace S1API.Entities.NPCs.Uptown +{ + public class RayHoffman : NPC + { + internal RayHoffman() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "ray_hoffman")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Uptown/TobiasWentworth.cs b/S1API/Entities/NPCs/Uptown/TobiasWentworth.cs new file mode 100644 index 00000000..8f8110fa --- /dev/null +++ b/S1API/Entities/NPCs/Uptown/TobiasWentworth.cs @@ -0,0 +1,15 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; +using NPC = S1API.Entities.NPC; + +namespace S1API.Entities.NPCs.Uptown +{ + public class TobiasWentworth : NPC + { + internal TobiasWentworth() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "tobias_wentworth")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Uptown/WalterCussler.cs b/S1API/Entities/NPCs/Uptown/WalterCussler.cs new file mode 100644 index 00000000..73768430 --- /dev/null +++ b/S1API/Entities/NPCs/Uptown/WalterCussler.cs @@ -0,0 +1,15 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; +using NPC = S1API.Entities.NPC; + +namespace S1API.Entities.NPCs.Uptown +{ + public class WalterCussler : NPC + { + internal WalterCussler() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "walter_cussler")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Westville/CharlesRowland.cs b/S1API/Entities/NPCs/Westville/CharlesRowland.cs new file mode 100644 index 00000000..56a42b80 --- /dev/null +++ b/S1API/Entities/NPCs/Westville/CharlesRowland.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Westville +{ + public class CharlesRowland : NPC + { + internal CharlesRowland() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "charles_rowland")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Westville/DeanWebster.cs b/S1API/Entities/NPCs/Westville/DeanWebster.cs new file mode 100644 index 00000000..4136830e --- /dev/null +++ b/S1API/Entities/NPCs/Westville/DeanWebster.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Westville +{ + public class DeanWebster : NPC + { + internal DeanWebster() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "dean_webster")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Westville/DorisLubbin.cs b/S1API/Entities/NPCs/Westville/DorisLubbin.cs new file mode 100644 index 00000000..bdf8f983 --- /dev/null +++ b/S1API/Entities/NPCs/Westville/DorisLubbin.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Westville +{ + public class DorisLubbin : NPC + { + internal DorisLubbin() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "doris_lubbin")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Westville/GeorgeGreene.cs b/S1API/Entities/NPCs/Westville/GeorgeGreene.cs new file mode 100644 index 00000000..bb106e07 --- /dev/null +++ b/S1API/Entities/NPCs/Westville/GeorgeGreene.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Westville +{ + public class GeorgeGreene : NPC + { + internal GeorgeGreene() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "george_greene")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Westville/JerryMontero.cs b/S1API/Entities/NPCs/Westville/JerryMontero.cs new file mode 100644 index 00000000..309d49a7 --- /dev/null +++ b/S1API/Entities/NPCs/Westville/JerryMontero.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Westville +{ + public class JerryMontero : NPC + { + internal JerryMontero() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "jerry_montero")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Westville/JoyceBall.cs b/S1API/Entities/NPCs/Westville/JoyceBall.cs new file mode 100644 index 00000000..ef36f7d5 --- /dev/null +++ b/S1API/Entities/NPCs/Westville/JoyceBall.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Westville +{ + public class JoyceBall : NPC + { + internal JoyceBall() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "joyce_ball")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Westville/KeithWagner.cs b/S1API/Entities/NPCs/Westville/KeithWagner.cs new file mode 100644 index 00000000..b98c273e --- /dev/null +++ b/S1API/Entities/NPCs/Westville/KeithWagner.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Westville +{ + public class KeithWagner : NPC + { + internal KeithWagner() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "keith_wagner")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Westville/KimDelaney.cs b/S1API/Entities/NPCs/Westville/KimDelaney.cs new file mode 100644 index 00000000..341ab65d --- /dev/null +++ b/S1API/Entities/NPCs/Westville/KimDelaney.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Westville +{ + public class KimDelaney : NPC + { + internal KimDelaney() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "kim_delaney")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Westville/MegCooley.cs b/S1API/Entities/NPCs/Westville/MegCooley.cs new file mode 100644 index 00000000..6bc4b444 --- /dev/null +++ b/S1API/Entities/NPCs/Westville/MegCooley.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Westville +{ + public class MegCooley : NPC + { + internal MegCooley() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "meg_cooley")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Westville/MollyPresley.cs b/S1API/Entities/NPCs/Westville/MollyPresley.cs new file mode 100644 index 00000000..f81cf549 --- /dev/null +++ b/S1API/Entities/NPCs/Westville/MollyPresley.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Westville +{ + public class MollyPresley : NPC + { + internal MollyPresley() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "molly_presley")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Westville/ShirleyWatts.cs b/S1API/Entities/NPCs/Westville/ShirleyWatts.cs new file mode 100644 index 00000000..0883a1f3 --- /dev/null +++ b/S1API/Entities/NPCs/Westville/ShirleyWatts.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Westville +{ + public class ShirleyWatts : NPC + { + internal ShirleyWatts() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "shirley_watts")) { } + } +} \ No newline at end of file diff --git a/S1API/Entities/NPCs/Westville/TrentSherman.cs b/S1API/Entities/NPCs/Westville/TrentSherman.cs new file mode 100644 index 00000000..2b099b37 --- /dev/null +++ b/S1API/Entities/NPCs/Westville/TrentSherman.cs @@ -0,0 +1,14 @@ +#if IL2CPP +using Il2CppScheduleOne.NPCs; +#else +using ScheduleOne.NPCs; +#endif +using System.Linq; + +namespace S1API.Entities.NPCs.Westville +{ + public class TrentSherman : NPC + { + internal TrentSherman() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "trent_sherman")) { } + } +} \ No newline at end of file From 2d6ae96f9f88551672e927016b6c0e4625a94423 Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Fri, 25 Apr 2025 22:15:18 -0500 Subject: [PATCH 05/42] fix: Fixed harmony and reflection referencing for il2cpp build --- S1API/Entities/NPC.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/S1API/Entities/NPC.cs b/S1API/Entities/NPC.cs index d379a783..4100f29f 100644 --- a/S1API/Entities/NPC.cs +++ b/S1API/Entities/NPC.cs @@ -29,14 +29,14 @@ using S1Vehicles = ScheduleOne.Vehicles; using S1Vision = ScheduleOne.Vision; using S1NPCs = ScheduleOne.NPCs; -using HarmonyLib; using System.Collections.Generic; -using System.Reflection; #endif using System; using System.IO; using System.Linq; +using System.Reflection; +using HarmonyLib; using S1API.Entities.Interfaces; using S1API.Internal.Abstraction; using S1API.Map; From c63fd4499edbbd48bf9def7654612b308365302a Mon Sep 17 00:00:00 2001 From: MaxtorCoder Date: Sat, 26 Apr 2025 12:55:52 +0200 Subject: [PATCH 06/42] feat: Implement BepInEx modloader support - Add centralized Log class for both BepInEx and MelonLoader - Add `MonoBepInEx` and `Il2CppBepInEx` configurations - Improve `.csproj` layout for S1API --- .gitignore | 1 + S1API.sln | 30 ++-- S1API/Console/ConsoleHelper.cs | 6 +- S1API/DeadDrops/DeadDropInstance.cs | 6 +- S1API/DeadDrops/DeadDropManager.cs | 6 +- S1API/GameTime/GameDateTime.cs | 6 +- S1API/GameTime/TimeManager.cs | 6 +- S1API/Internal/Abstraction/ISaveable.cs | 4 +- S1API/Internal/Abstraction/Saveable.cs | 4 +- S1API/Internal/Patches/NPCPatches.cs | 6 +- S1API/Internal/Patches/PhoneAppPatches.cs | 11 +- S1API/Internal/Patches/QuestPatches.cs | 6 +- S1API/Internal/Patches/TimePatches.cs | 6 +- S1API/Internal/Utils/CrossType.cs | 26 ++-- S1API/Internal/Utils/ImageUtils.cs | 13 +- S1API/Items/ItemDefinition.cs | 6 +- S1API/Items/ItemInstance.cs | 6 +- S1API/Items/ItemManager.cs | 6 +- S1API/Items/ItemSlotInstance.cs | 6 +- S1API/Leveling/LevelManager.cs | 6 +- S1API/Logging/Log.cs | 81 +++++++++++ S1API/Money/CashDefinition.cs | 6 +- S1API/Money/CashInstance.cs | 6 +- S1API/NPCs/NPC.cs | 14 +- S1API/NPCs/NPCInstance.cs | 6 +- S1API/NPCs/Response.cs | 6 +- S1API/PhoneApp/PhoneApp.cs | 27 +++- S1API/Products/CocaineDefinition.cs | 6 +- S1API/Products/MethDefinition.cs | 6 +- S1API/Products/PackagingDefinition.cs | 6 +- S1API/Products/ProductDefinition.cs | 6 +- S1API/Products/ProductDefinitionWrapper.cs | 4 +- S1API/Products/ProductInstance.cs | 6 +- S1API/Products/ProductManager.cs | 6 +- S1API/Products/WeedDefinition.cs | 6 +- S1API/Quests/Quest.cs | 10 +- S1API/Quests/QuestEntry.cs | 6 +- S1API/S1API.cs | 18 ++- S1API/S1API.csproj | 154 +++++++++------------ S1API/Storages/StorageInstance.cs | 6 +- S1API/UI/UIFactory.cs | 8 +- S1APILoader/S1APILoader.csproj | 2 +- example.build.props | 3 +- 43 files changed, 334 insertions(+), 232 deletions(-) create mode 100644 S1API/Logging/Log.cs diff --git a/.gitignore b/.gitignore index cf6412f6..4b329393 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ obj/ bin/ *.user +.vs/ # Build props local.* diff --git a/S1API.sln b/S1API.sln index b923963a..72b17c00 100644 --- a/S1API.sln +++ b/S1API.sln @@ -6,17 +6,27 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "S1APILoader", "S1APILoader\ EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Mono|Any CPU = Mono|Any CPU - Il2Cpp|Any CPU = Il2Cpp|Any CPU + MonoBepInEx|Any CPU = MonoBepInEx|Any CPU + Il2CppMelon|Any CPU = Il2CppMelon|Any CPU + MonoMelon|Any CPU = MonoMelon|Any CPU + Il2CppBepInEx|Any CPU = Il2CppBepInEx|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D2C9A6B1-B9E0-4E6D-AE65-B5264C2A4E04}.Mono|Any CPU.ActiveCfg = Mono|Any CPU - {D2C9A6B1-B9E0-4E6D-AE65-B5264C2A4E04}.Mono|Any CPU.Build.0 = Mono|Any CPU - {D2C9A6B1-B9E0-4E6D-AE65-B5264C2A4E04}.Il2Cpp|Any CPU.ActiveCfg = Il2Cpp|Any CPU - {D2C9A6B1-B9E0-4E6D-AE65-B5264C2A4E04}.Il2Cpp|Any CPU.Build.0 = Il2Cpp|Any CPU - {B97277C2-27FE-4BB9-AB5A-D479C8DF6827}.Mono|Any CPU.ActiveCfg = Mono|Any CPU - {B97277C2-27FE-4BB9-AB5A-D479C8DF6827}.Mono|Any CPU.Build.0 = Mono|Any CPU - {B97277C2-27FE-4BB9-AB5A-D479C8DF6827}.Il2Cpp|Any CPU.ActiveCfg = Il2Cpp|Any CPU - {B97277C2-27FE-4BB9-AB5A-D479C8DF6827}.Il2Cpp|Any CPU.Build.0 = Il2Cpp|Any CPU + {D2C9A6B1-B9E0-4E6D-AE65-B5264C2A4E04}.MonoBepInEx|Any CPU.ActiveCfg = MonoBepInEx|Any CPU + {D2C9A6B1-B9E0-4E6D-AE65-B5264C2A4E04}.MonoBepInEx|Any CPU.Build.0 = MonoBepInEx|Any CPU + {D2C9A6B1-B9E0-4E6D-AE65-B5264C2A4E04}.Il2CppMelon|Any CPU.ActiveCfg = Il2CppMelon|Any CPU + {D2C9A6B1-B9E0-4E6D-AE65-B5264C2A4E04}.Il2CppMelon|Any CPU.Build.0 = Il2CppMelon|Any CPU + {D2C9A6B1-B9E0-4E6D-AE65-B5264C2A4E04}.MonoMelon|Any CPU.ActiveCfg = MonoMelon|Any CPU + {D2C9A6B1-B9E0-4E6D-AE65-B5264C2A4E04}.MonoMelon|Any CPU.Build.0 = MonoMelon|Any CPU + {D2C9A6B1-B9E0-4E6D-AE65-B5264C2A4E04}.Il2CppBepInEx|Any CPU.ActiveCfg = Il2CppBepInEx|Any CPU + {D2C9A6B1-B9E0-4E6D-AE65-B5264C2A4E04}.Il2CppBepInEx|Any CPU.Build.0 = Il2CppBepInEx|Any CPU + {B97277C2-27FE-4BB9-AB5A-D479C8DF6827}.MonoBepInEx|Any CPU.ActiveCfg = MonoBepInEx|Any CPU + {B97277C2-27FE-4BB9-AB5A-D479C8DF6827}.MonoBepInEx|Any CPU.Build.0 = MonoBepInEx|Any CPU + {B97277C2-27FE-4BB9-AB5A-D479C8DF6827}.Il2CppMelon|Any CPU.ActiveCfg = Il2CppMelon|Any CPU + {B97277C2-27FE-4BB9-AB5A-D479C8DF6827}.Il2CppMelon|Any CPU.Build.0 = Il2CppMelon|Any CPU + {B97277C2-27FE-4BB9-AB5A-D479C8DF6827}.MonoMelon|Any CPU.ActiveCfg = MonoMelon|Any CPU + {B97277C2-27FE-4BB9-AB5A-D479C8DF6827}.MonoMelon|Any CPU.Build.0 = MonoMelon|Any CPU + {B97277C2-27FE-4BB9-AB5A-D479C8DF6827}.Il2CppBepInEx|Any CPU.ActiveCfg = Il2CppBepInEx|Any CPU + {B97277C2-27FE-4BB9-AB5A-D479C8DF6827}.Il2CppBepInEx|Any CPU.Build.0 = Il2CppBepInEx|Any CPU EndGlobalSection EndGlobal diff --git a/S1API/Console/ConsoleHelper.cs b/S1API/Console/ConsoleHelper.cs index 60e54d82..ef60823b 100644 --- a/S1API/Console/ConsoleHelper.cs +++ b/S1API/Console/ConsoleHelper.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -#if IL2CPP +#if IL2CPPMELON || IL2CPPBEPINEX using Il2CppSystem.Collections.Generic; using static Il2CppScheduleOne.Console; @@ -19,7 +19,7 @@ public static class ConsoleHelper /// The cash amount to add or remove. public static void RunCashCommand(int amount) { -#if IL2CPP +#if IL2CPPMELON || IL2CPPBEPINEX var command = new ChangeCashCommand(); var args = new Il2CppSystem.Collections.Generic.List(); #else @@ -30,4 +30,4 @@ public static void RunCashCommand(int amount) command.Execute(args); } } -} \ No newline at end of file +} diff --git a/S1API/DeadDrops/DeadDropInstance.cs b/S1API/DeadDrops/DeadDropInstance.cs index ee49c249..91c57942 100644 --- a/S1API/DeadDrops/DeadDropInstance.cs +++ b/S1API/DeadDrops/DeadDropInstance.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Economy = Il2CppScheduleOne.Economy; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Economy = ScheduleOne.Economy; #endif @@ -59,4 +59,4 @@ internal DeadDropInstance(S1Economy.DeadDrop deadDrop) => public Vector3 Position => S1DeadDrop.transform.position; } -} \ No newline at end of file +} diff --git a/S1API/DeadDrops/DeadDropManager.cs b/S1API/DeadDrops/DeadDropManager.cs index edf1345c..e162f337 100644 --- a/S1API/DeadDrops/DeadDropManager.cs +++ b/S1API/DeadDrops/DeadDropManager.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Economy = Il2CppScheduleOne.Economy; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Economy = ScheduleOne.Economy; #endif @@ -19,4 +19,4 @@ public class DeadDropManager public static DeadDropInstance[] All => S1Economy.DeadDrop.DeadDrops.ToArray() .Select(deadDrop => new DeadDropInstance(deadDrop)).ToArray(); } -} \ No newline at end of file +} diff --git a/S1API/GameTime/GameDateTime.cs b/S1API/GameTime/GameDateTime.cs index bf72ea81..ce8ac68c 100644 --- a/S1API/GameTime/GameDateTime.cs +++ b/S1API/GameTime/GameDateTime.cs @@ -1,7 +1,7 @@ // TODO: Implement GameDateTime wrapper -// #if (IL2CPP) +// #if (IL2CPPMELON || IL2CPPBEPINEX) // using S1GameTime = Il2CppScheduleOne.GameTime; -// #elif (MONO) +// #elif (MONOMELON || MONOBEPINEX) // using S1GameTime = ScheduleOne.GameTime; // #endif // @@ -19,4 +19,4 @@ // // public void Ad // } -// } \ No newline at end of file +// } diff --git a/S1API/GameTime/TimeManager.cs b/S1API/GameTime/TimeManager.cs index 45f78f9c..5f658135 100644 --- a/S1API/GameTime/TimeManager.cs +++ b/S1API/GameTime/TimeManager.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1GameTime = Il2CppScheduleOne.GameTime; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1GameTime = ScheduleOne.GameTime; #endif @@ -24,4 +24,4 @@ public static class TimeManager public static Day CurrentDay => (Day)S1GameTime.TimeManager.Instance.CurrentDay; } -} \ No newline at end of file +} diff --git a/S1API/Internal/Abstraction/ISaveable.cs b/S1API/Internal/Abstraction/ISaveable.cs index 6ac86151..94a5431e 100644 --- a/S1API/Internal/Abstraction/ISaveable.cs +++ b/S1API/Internal/Abstraction/ISaveable.cs @@ -1,4 +1,4 @@ -#if (MONO) +#if (MONOMELON || MONOBEPINEX) using System.Collections.Generic; #elif (IL2CPP) using Il2CppSystem.Collections.Generic; @@ -46,4 +46,4 @@ internal interface ISaveable : IRegisterable Converters = new System.Collections.Generic.List() { new GUIDReferenceConverter() } }; } -} \ No newline at end of file +} diff --git a/S1API/Internal/Abstraction/Saveable.cs b/S1API/Internal/Abstraction/Saveable.cs index b40c61aa..4dd23602 100644 --- a/S1API/Internal/Abstraction/Saveable.cs +++ b/S1API/Internal/Abstraction/Saveable.cs @@ -1,4 +1,4 @@ -#if (MONO) +#if (MONOMELON || MONOBEPINEX) using System.Collections.Generic; #elif (IL2CPP) using Il2CppSystem.Collections.Generic; @@ -119,4 +119,4 @@ void ISaveable.OnSaved() => /// protected virtual void OnSaved() { } } -} \ No newline at end of file +} diff --git a/S1API/Internal/Patches/NPCPatches.cs b/S1API/Internal/Patches/NPCPatches.cs index c4304982..b00bba50 100644 --- a/S1API/Internal/Patches/NPCPatches.cs +++ b/S1API/Internal/Patches/NPCPatches.cs @@ -1,8 +1,8 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Loaders = Il2CppScheduleOne.Persistence.Loaders; using S1NPCs = Il2CppScheduleOne.NPCs; using Il2CppSystem.Collections.Generic; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Loaders = ScheduleOne.Persistence.Loaders; using S1NPCs = ScheduleOne.NPCs; using System.Collections.Generic; @@ -84,4 +84,4 @@ private static void NPCOnDestroy(S1NPCs.NPC __instance) NPCs.Remove(npc); } } -} \ No newline at end of file +} diff --git a/S1API/Internal/Patches/PhoneAppPatches.cs b/S1API/Internal/Patches/PhoneAppPatches.cs index 30804bfb..7d48da32 100644 --- a/S1API/Internal/Patches/PhoneAppPatches.cs +++ b/S1API/Internal/Patches/PhoneAppPatches.cs @@ -3,11 +3,12 @@ using UnityEngine.SceneManagement; using S1API.Internal.Utils; using S1API.Internal.Abstraction; +using S1API.Logging; using S1API.PhoneApp; namespace S1API.Internal.Patches -{ -#if IL2CPP +{ +#if IL2CPPMELON || IL2CPPBEPINEX [HarmonyPatch(typeof(SceneManager), nameof(SceneManager.Internal_SceneLoaded))] #else [HarmonyPatch(typeof(SceneManager), "Internal_SceneLoaded", new Type[] { typeof(Scene), typeof(LoadSceneMode) })] @@ -15,6 +16,8 @@ namespace S1API.Internal.Patches #endif internal static class PhoneAppPatches { + private static readonly Log _loggerInstance = new Log("PhoneAppPatches"); + private static bool _loaded = false; /// @@ -41,9 +44,9 @@ static void Postfix(Scene scene, LoadSceneMode mode) } catch (System.Exception e) { - MelonLoader.MelonLogger.Warning($"[PhoneApp] Failed to register {type.FullName}: {e.Message}"); + _loggerInstance.Warning($"[PhoneApp] Failed to register {type.FullName}: {e.Message}"); } } } } -} \ No newline at end of file +} diff --git a/S1API/Internal/Patches/QuestPatches.cs b/S1API/Internal/Patches/QuestPatches.cs index 6e9fd49a..6b825e21 100644 --- a/S1API/Internal/Patches/QuestPatches.cs +++ b/S1API/Internal/Patches/QuestPatches.cs @@ -1,9 +1,9 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Loaders = Il2CppScheduleOne.Persistence.Loaders; using S1Datas = Il2CppScheduleOne.Persistence.Datas; using S1Quests = Il2CppScheduleOne.Quests; using Il2CppSystem.Collections.Generic; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Loaders = ScheduleOne.Persistence.Loaders; using S1Datas = ScheduleOne.Persistence.Datas; using S1Quests = ScheduleOne.Quests; @@ -128,4 +128,4 @@ private static void QuestStart(S1Quests.Quest __instance) => // NPCs.Remove(npc); // } } -} \ No newline at end of file +} diff --git a/S1API/Internal/Patches/TimePatches.cs b/S1API/Internal/Patches/TimePatches.cs index 34a3f176..32712fbe 100644 --- a/S1API/Internal/Patches/TimePatches.cs +++ b/S1API/Internal/Patches/TimePatches.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1GameTime = Il2CppScheduleOne.GameTime; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1GameTime = ScheduleOne.GameTime; #endif @@ -33,4 +33,4 @@ void DayPass() __instance.onDayPass += (Action)DayPass; } } -} \ No newline at end of file +} diff --git a/S1API/Internal/Utils/CrossType.cs b/S1API/Internal/Utils/CrossType.cs index 5ce09684..f1d0bdad 100644 --- a/S1API/Internal/Utils/CrossType.cs +++ b/S1API/Internal/Utils/CrossType.cs @@ -1,6 +1,6 @@ -#if (MONO) +#if (MONOMELON || MONOBEPINEX) using System; -# elif (IL2CPP) +# elif (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppSystem; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.InteropTypes; @@ -21,9 +21,9 @@ internal static class CrossType /// The type of the class. internal static Type Of() { -#if (MONO) +#if (MONOMELON || MONOBEPINEX) return typeof(T); -# elif (IL2CPP) +# elif (IL2CPPMELON || IL2CPPBEPINEX) return Il2CppType.Of(); #endif } @@ -36,13 +36,13 @@ internal static Type Of() /// The class we're checking against. /// Whether obj is of class T or not. internal static bool Is(object obj, out T result) -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) where T : Il2CppObjectBase -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) where T : class #endif { -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) if (obj is Object il2CppObj) { Type il2CppType = Il2CppType.Of(); @@ -52,7 +52,7 @@ internal static bool Is(object obj, out T result) return true; } } -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) if (obj is T t) { result = t; @@ -71,16 +71,16 @@ internal static bool Is(object obj, out T result) /// The type to cast to. /// The object cast to the specified type. internal static T As(object obj) -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) where T : Il2CppObjectBase -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) where T : class #endif => -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) obj is Object il2CppObj ? il2CppObj.Cast() : null!; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) (T)obj; #endif } -} \ No newline at end of file +} diff --git a/S1API/Internal/Utils/ImageUtils.cs b/S1API/Internal/Utils/ImageUtils.cs index 1f072b6f..8ca166e1 100644 --- a/S1API/Internal/Utils/ImageUtils.cs +++ b/S1API/Internal/Utils/ImageUtils.cs @@ -1,14 +1,13 @@ -using MelonLoader; -using System; -using System.Collections.Generic; +using S1API.Logging; using System.IO; -using System.Text; using UnityEngine; namespace S1API.Internal.Utils { public static class ImageUtils { + private static readonly Log _loggerInstance = new Log("ImageUtils"); + /// /// Loads an image from the specified file path and converts it into a Sprite object. /// @@ -21,7 +20,7 @@ public static Sprite LoadImage(string fileName) string fullPath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) ?? string.Empty, fileName); if (!File.Exists(fullPath)) { - MelonLogger.Error($"❌ Icon file not found: {fullPath}"); + _loggerInstance.Error($"❌ Icon file not found: {fullPath}"); return null; } @@ -36,10 +35,10 @@ public static Sprite LoadImage(string fileName) } catch (System.Exception ex) { - MelonLogger.Error("❌ Failed to load sprite: " + ex); + _loggerInstance.Error("❌ Failed to load sprite: " + ex); } return null; } } -} \ No newline at end of file +} diff --git a/S1API/Items/ItemDefinition.cs b/S1API/Items/ItemDefinition.cs index b7884c67..cff1924b 100644 --- a/S1API/Items/ItemDefinition.cs +++ b/S1API/Items/ItemDefinition.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1ItemFramework = Il2CppScheduleOne.ItemFramework; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1ItemFramework = ScheduleOne.ItemFramework; #endif @@ -115,4 +115,4 @@ public override int GetHashCode() => public virtual ItemInstance CreateInstance(int quantity = 1) => new ItemInstance(S1ItemDefinition.GetDefaultInstance(quantity)); } -} \ No newline at end of file +} diff --git a/S1API/Items/ItemInstance.cs b/S1API/Items/ItemInstance.cs index 5d498184..2fdb7f35 100644 --- a/S1API/Items/ItemInstance.cs +++ b/S1API/Items/ItemInstance.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1ItemFramework = Il2CppScheduleOne.ItemFramework; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1ItemFramework = ScheduleOne.ItemFramework; #endif @@ -32,4 +32,4 @@ internal ItemInstance(S1ItemFramework.ItemInstance itemInstance) => public ItemDefinition Definition => new ItemDefinition(S1ItemInstance.Definition); } -} \ No newline at end of file +} diff --git a/S1API/Items/ItemManager.cs b/S1API/Items/ItemManager.cs index 10551c92..e886c6df 100644 --- a/S1API/Items/ItemManager.cs +++ b/S1API/Items/ItemManager.cs @@ -1,8 +1,8 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1 = Il2CppScheduleOne; using S1ItemFramework = Il2CppScheduleOne.ItemFramework; using S1Product = Il2CppScheduleOne.Product; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1 = ScheduleOne; using S1ItemFramework = ScheduleOne.ItemFramework; using S1Product = ScheduleOne.Product; @@ -39,4 +39,4 @@ public static ItemDefinition GetItemDefinition(string itemID) return new ItemDefinition(itemDefinition); } } -} \ No newline at end of file +} diff --git a/S1API/Items/ItemSlotInstance.cs b/S1API/Items/ItemSlotInstance.cs index 5b6d750b..ad51429d 100644 --- a/S1API/Items/ItemSlotInstance.cs +++ b/S1API/Items/ItemSlotInstance.cs @@ -1,7 +1,7 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1ItemFramework = Il2CppScheduleOne.ItemFramework; using S1Product = Il2CppScheduleOne.Product; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1ItemFramework = ScheduleOne.ItemFramework; using S1Product = ScheduleOne.Product; #endif @@ -67,4 +67,4 @@ public ItemInstance? ItemInstance public void AddQuantity(int amount) => S1ItemSlot.ChangeQuantity(amount); } -} \ No newline at end of file +} diff --git a/S1API/Leveling/LevelManager.cs b/S1API/Leveling/LevelManager.cs index c9a8ac8e..5bbc31a1 100644 --- a/S1API/Leveling/LevelManager.cs +++ b/S1API/Leveling/LevelManager.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Levelling = Il2CppScheduleOne.Levelling; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Levelling = ScheduleOne.Levelling; #endif @@ -16,4 +16,4 @@ public static class LevelManager /// public static Rank Rank = (Rank)S1Levelling.LevelManager.Instance.Rank; } -} \ No newline at end of file +} diff --git a/S1API/Logging/Log.cs b/S1API/Logging/Log.cs new file mode 100644 index 00000000..939309dd --- /dev/null +++ b/S1API/Logging/Log.cs @@ -0,0 +1,81 @@ +#if MONOMELON || IL2CPPMELON +using MelonLoader +#else +using BepInEx.Logging; +#endif + +namespace S1API.Logging +{ + /// + /// Centralized Logging class that handles both BepInEx and MelonLoader logging. + /// + public class Log + { +#if MONOMELON || IL2CPPMELON + private readonly MelonLogger.Instance _loggerInstance; +#else + private readonly ManualLogSource _loggerInstance; +#endif + + public Log(string sourceName) + { +#if MONOMELON || IL2CPPMELON + _loggerInstance = new MelonLogger.Instancer(sourceName); +#else + _loggerInstance = new ManualLogSource(sourceName); +#endif + } + + /// + /// Logs a message with Info level + /// + /// Message to log + public void Msg(string message) + { +#if MONOMELON || IL2CPPMELON + _loggerInstance.Msg(message); +#else + _loggerInstance.LogInfo(message); +#endif + } + + /// + /// Logs a message with Warning level + /// + /// Message to log + public void Warning(string message) + { +#if MONOMELON || IL2CPPMELON + _loggerInstance.Warning(message); +#else + _loggerInstance.LogWarning(message); +#endif + } + + /// + /// Logs a message with Error level + /// + /// Message to log + public void Error(string message) + { +#if MONOMELON || IL2CPPMELON + _loggerInstance.Error(message); +#else + _loggerInstance.LogError(message); +#endif + } + + /// + /// Logs a message with Fatal level + /// + /// Message to log + public void BigError(string message) + { +#if MONOMELON || IL2CPPMELON + _loggerInstance.BigError(message); +#else + _loggerInstance.LogFatal(message); +#endif + } + } +} diff --git a/S1API/Money/CashDefinition.cs b/S1API/Money/CashDefinition.cs index 67186f63..47cc026d 100644 --- a/S1API/Money/CashDefinition.cs +++ b/S1API/Money/CashDefinition.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1ItemFramework = Il2CppScheduleOne.ItemFramework; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1ItemFramework = ScheduleOne.ItemFramework; #endif @@ -35,4 +35,4 @@ internal CashDefinition(S1ItemFramework.CashDefinition s1ItemDefinition) : base( public override ItemInstance CreateInstance(int quantity = 1) => new CashInstance(S1CashDefinition.GetDefaultInstance(quantity)); } -} \ No newline at end of file +} diff --git a/S1API/Money/CashInstance.cs b/S1API/Money/CashInstance.cs index f555c355..a9b96e9c 100644 --- a/S1API/Money/CashInstance.cs +++ b/S1API/Money/CashInstance.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1ItemFramework = Il2CppScheduleOne.ItemFramework; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1ItemFramework = ScheduleOne.ItemFramework; #endif @@ -42,4 +42,4 @@ public void AddQuantity(float amount) => public void SetQuantity(float newQuantity) => S1CashInstance.SetBalance(newQuantity); } -} \ No newline at end of file +} diff --git a/S1API/NPCs/NPC.cs b/S1API/NPCs/NPC.cs index a9a14699..f39611db 100644 --- a/S1API/NPCs/NPC.cs +++ b/S1API/NPCs/NPC.cs @@ -1,4 +1,4 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1DevUtilities = Il2CppScheduleOne.DevUtilities; using S1Interaction = Il2CppScheduleOne.Interaction; using S1Messaging = Il2CppScheduleOne.Messaging; @@ -14,7 +14,7 @@ using S1Vision = Il2CppScheduleOne.Vision; using S1NPCs = Il2CppScheduleOne.NPCs; using Il2CppSystem.Collections.Generic; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1DevUtilities = ScheduleOne.DevUtilities; using S1Interaction = ScheduleOne.Interaction; using S1Messaging = ScheduleOne.Messaging; @@ -91,9 +91,9 @@ public NPC(string guid, string firstName, string lastName) S1NPC.ConversationCategories.Add(S1Messaging.EConversationCategory.Customer); // Create our MessageConversation -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) S1NPC.CreateMessageConversation(); -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) MethodInfo createConvoMethod = AccessTools.Method(typeof(S1NPCs.NPC), "CreateMessageConversation"); createConvoMethod.Invoke(S1NPC, null); #endif @@ -162,9 +162,9 @@ public NPC(string guid, string firstName, string lastName) S1NPC.awareness.VisionCone.QuestionMarkPopup = _gameObject.AddComponent(); // Interaction behaviour -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) S1NPC.intObj = _gameObject.AddComponent(); -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) FieldInfo intObjField = AccessTools.Field(typeof(S1NPCs.NPC), "intObj"); intObjField.SetValue(S1NPC, _gameObject.AddComponent()); #endif @@ -267,4 +267,4 @@ public void SendTextMessage(string message, Response[]? responses = null, float /// The response that was loaded. protected virtual void OnResponseLoaded(Response response) { } } -} \ No newline at end of file +} diff --git a/S1API/NPCs/NPCInstance.cs b/S1API/NPCs/NPCInstance.cs index d4858d1b..27354028 100644 --- a/S1API/NPCs/NPCInstance.cs +++ b/S1API/NPCs/NPCInstance.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1NPCs = Il2CppScheduleOne.NPCs; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1NPCs = ScheduleOne.NPCs; #endif @@ -10,4 +10,4 @@ public class NPCInstance { } -} \ No newline at end of file +} diff --git a/S1API/NPCs/Response.cs b/S1API/NPCs/Response.cs index 100dc6b7..9ab12e45 100644 --- a/S1API/NPCs/Response.cs +++ b/S1API/NPCs/Response.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Messaging = Il2CppScheduleOne.Messaging; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Messaging = ScheduleOne.Messaging; #endif using System; @@ -55,4 +55,4 @@ public string Text set => S1Response.text = value; } } -} \ No newline at end of file +} diff --git a/S1API/PhoneApp/PhoneApp.cs b/S1API/PhoneApp/PhoneApp.cs index 44385db8..4b9dbb33 100644 --- a/S1API/PhoneApp/PhoneApp.cs +++ b/S1API/PhoneApp/PhoneApp.cs @@ -1,19 +1,25 @@ -#if IL2CPP +#if IL2CPPMELON || IL2CPPBEPINEX using UnityEngine; using UnityEngine.UI; using UnityEngine.Events; -#elif MONO +#elif MONOMELON || MONOBEPINEX using UnityEngine; using UnityEngine.UI; using UnityEngine.Events; #endif +using FishNet; using System.Collections; using System.IO; +#if MONOMELON || IL2CPPMELON using MelonLoader; -using Object = UnityEngine.Object; using MelonLoader.Utils; +#elif MONOBEPINEX || IL2CPPBEPINEX +using BepInEx.Logging; +#endif +using Object = UnityEngine.Object; using S1API.Internal.Abstraction; +using S1API.Logging; namespace S1API.PhoneApp { @@ -27,7 +33,7 @@ namespace S1API.PhoneApp /// public abstract class PhoneApp : Registerable { - protected static readonly MelonLogger.Instance LoggerInstance = new MelonLogger.Instance("PhoneApp"); + protected static readonly Log LoggerInstance = new Log("PhoneApp"); /// /// The player object in the scene. @@ -80,7 +86,10 @@ public abstract class PhoneApp : Registerable /// protected override void OnCreated() { - MelonCoroutines.Start(InitApp()); + // @TODO: Find out if this actually is the proper way of starting a coroutine + // for both BepInEx and MelonLoader + // Old code: MelonCoroutines.Start(InitApp()); + InstanceFinder.TimeManager.StartCoroutine(InitApp()); } /// @@ -197,14 +206,14 @@ private bool ModifyAppIcon(string labelText, string fileName) GameObject parent = GameObject.Find("Player_Local/CameraContainer/Camera/OverlayCamera/GameplayMenu/Phone/phone/HomeScreen/AppIcons/"); if (parent == null) { - LoggerInstance?.Error("AppIcons not found."); + LoggerInstance.Error("AppIcons not found."); return false; } Transform lastIcon = parent.transform.childCount > 0 ? parent.transform.GetChild(parent.transform.childCount - 1) : null; if (lastIcon == null) { - LoggerInstance?.Error("No icon found to clone."); + LoggerInstance.Error("No icon found to clone."); return false; } @@ -235,7 +244,11 @@ private bool ChangeAppIconImage(GameObject iconObj, string filename) return false; } +#if MONOMELON || IL2CPPMELON string path = Path.Combine(MelonEnvironment.ModsDirectory, filename); +#elif MONOBEPINEX || IL2CPPBEPINEX + string path = Path.Combine(BepInEx.Paths.PluginPath, filename); +#endif if (!File.Exists(path)) { LoggerInstance?.Error("Icon file not found: " + path); diff --git a/S1API/Products/CocaineDefinition.cs b/S1API/Products/CocaineDefinition.cs index e0b45e3c..18b0e5ab 100644 --- a/S1API/Products/CocaineDefinition.cs +++ b/S1API/Products/CocaineDefinition.cs @@ -1,7 +1,7 @@ -#if IL2CPP +#if IL2CPPMELON || IL2CPPBEPINEX using Il2CppScheduleOne.Product; using S1CocaineDefinition = Il2CppScheduleOne.Product.CocaineDefinition; -#elif MONO +#elif MONOMELON || MONOBEPINEX using ScheduleOne.Product; using S1CocaineDefinition = ScheduleOne.Product.CocaineDefinition; #endif @@ -37,4 +37,4 @@ public override ItemInstance CreateInstance(int quantity = 1) => new ProductInstance(CrossType.As( S1CocaineDefinition.GetDefaultInstance(quantity))); } -} \ No newline at end of file +} diff --git a/S1API/Products/MethDefinition.cs b/S1API/Products/MethDefinition.cs index 943f5d72..46cb4926 100644 --- a/S1API/Products/MethDefinition.cs +++ b/S1API/Products/MethDefinition.cs @@ -1,7 +1,7 @@ -#if IL2CPP +#if IL2CPPMELON || IL2CPPBEPINEX using Il2CppScheduleOne.Product; using S1MethDefinition = Il2CppScheduleOne.Product.MethDefinition; -#elif MONO +#elif MONOMELON || MONOBEPINEX using ScheduleOne.Product; using S1MethDefinition = ScheduleOne.Product.MethDefinition; #endif @@ -36,4 +36,4 @@ public override ItemInstance CreateInstance(int quantity = 1) => new ProductInstance(CrossType.As( S1MethDefinition.GetDefaultInstance(quantity))); } -} \ No newline at end of file +} diff --git a/S1API/Products/PackagingDefinition.cs b/S1API/Products/PackagingDefinition.cs index b9dfee8c..54052293 100644 --- a/S1API/Products/PackagingDefinition.cs +++ b/S1API/Products/PackagingDefinition.cs @@ -1,7 +1,7 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Packaging = Il2CppScheduleOne.Product.Packaging; using S1ItemFramework = Il2CppScheduleOne.ItemFramework; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Packaging = ScheduleOne.Product.Packaging; using S1ItemFramework = ScheduleOne.ItemFramework; #endif @@ -35,4 +35,4 @@ internal PackagingDefinition(S1ItemFramework.ItemDefinition s1ItemDefinition) : public int Quantity => S1PackagingDefinition.Quantity; } -} \ No newline at end of file +} diff --git a/S1API/Products/ProductDefinition.cs b/S1API/Products/ProductDefinition.cs index bcb467a7..38dbadb2 100644 --- a/S1API/Products/ProductDefinition.cs +++ b/S1API/Products/ProductDefinition.cs @@ -1,8 +1,8 @@ -#if IL2CPP +#if IL2CPPMELON || IL2CPPBEPINEX using Il2CppInterop.Runtime.InteropTypes; using S1Product = Il2CppScheduleOne.Product; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Product = ScheduleOne.Product; #endif @@ -52,4 +52,4 @@ public Sprite Icon } } -} \ No newline at end of file +} diff --git a/S1API/Products/ProductDefinitionWrapper.cs b/S1API/Products/ProductDefinitionWrapper.cs index 97903e3e..a8374c83 100644 --- a/S1API/Products/ProductDefinitionWrapper.cs +++ b/S1API/Products/ProductDefinitionWrapper.cs @@ -1,5 +1,5 @@ using S1API.Internal.Utils; -#if IL2CPP +#if IL2CPPMELON || IL2CPPBEPINEX using S1Product = Il2CppScheduleOne.Product; #else using S1Product = ScheduleOne.Product; @@ -21,4 +21,4 @@ public static ProductDefinition Wrap(ProductDefinition def) return def; } } -} \ No newline at end of file +} diff --git a/S1API/Products/ProductInstance.cs b/S1API/Products/ProductInstance.cs index a1380bce..f3763101 100644 --- a/S1API/Products/ProductInstance.cs +++ b/S1API/Products/ProductInstance.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Product = Il2CppScheduleOne.Product; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Product = ScheduleOne.Product; #endif @@ -38,4 +38,4 @@ internal ProductInstance(S1Product.ProductItemInstance productInstance) : base(p public PackagingDefinition AppliedPackaging => new PackagingDefinition(S1ProductInstance.AppliedPackaging); } -} \ No newline at end of file +} diff --git a/S1API/Products/ProductManager.cs b/S1API/Products/ProductManager.cs index 264d65ca..4c5625e1 100644 --- a/S1API/Products/ProductManager.cs +++ b/S1API/Products/ProductManager.cs @@ -1,7 +1,7 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Product = Il2CppScheduleOne.Product; using Il2CppSystem.Collections.Generic; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Product = ScheduleOne.Product; #endif using System.Linq; @@ -21,4 +21,4 @@ public static class ProductManager .ToArray(); } -} \ No newline at end of file +} diff --git a/S1API/Products/WeedDefinition.cs b/S1API/Products/WeedDefinition.cs index 6c953289..bbff0a17 100644 --- a/S1API/Products/WeedDefinition.cs +++ b/S1API/Products/WeedDefinition.cs @@ -1,7 +1,7 @@ -#if IL2CPP +#if IL2CPPMELON || IL2CPPBEPINEX using Il2CppScheduleOne.Product; using S1WeedDefinition = Il2CppScheduleOne.Product.WeedDefinition; -#elif MONO +#elif MONOMELON || MONOBEPINEX using ScheduleOne.Product; using S1WeedDefinition = ScheduleOne.Product.WeedDefinition; #endif @@ -37,4 +37,4 @@ public override ItemInstance CreateInstance(int quantity = 1) => new ProductInstance(CrossType.As( S1WeedDefinition.GetDefaultInstance(quantity))); } -} \ No newline at end of file +} diff --git a/S1API/Quests/Quest.cs b/S1API/Quests/Quest.cs index 4fdfdc88..eb094abe 100644 --- a/S1API/Quests/Quest.cs +++ b/S1API/Quests/Quest.cs @@ -1,11 +1,11 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Quests = Il2CppScheduleOne.Quests; using S1Dev = Il2CppScheduleOne.DevUtilities; using S1Map = Il2CppScheduleOne.Map; using S1Data = Il2CppScheduleOne.Persistence.Datas; using S1Contacts = Il2CppScheduleOne.UI.Phone.ContactsApp; using Il2CppSystem.Collections.Generic; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Quests = ScheduleOne.Quests; using S1Dev = ScheduleOne.DevUtilities; using S1Map = ScheduleOne.Map; @@ -87,7 +87,7 @@ public Quest() S1Quest.onTrackChange = new UnityEvent(); S1Quest.TrackOnBegin = true; S1Quest.AutoCompleteOnAllEntriesComplete = true; -#if (MONO) +#if (MONOMELON || MONOBEPINEX) FieldInfo autoInitField = AccessTools.Field(typeof(S1Quests.Quest), "autoInitialize"); autoInitField.SetValue(S1Quest, false); #elif (IL2CPP) @@ -138,7 +138,7 @@ public Quest() poiPrefabObject.transform.SetParent(_gameObject.transform); S1Map.POI poi = poiPrefabObject.AddComponent(); poi.DefaultMainText = "Did it work?"; -#if (MONO) +#if (MONOMELON || MONOBEPINEX) FieldInfo uiPrefabField = AccessTools.Field(typeof(S1Map.POI), "UIPrefab"); uiPrefabField.SetValue(poi, uiPrefabObject); #elif (IL2CPP) @@ -241,4 +241,4 @@ protected QuestEntry AddEntry(string title, Vector3? poiPosition = null) /// public void End() => S1Quest?.End(); } -} \ No newline at end of file +} diff --git a/S1API/Quests/QuestEntry.cs b/S1API/Quests/QuestEntry.cs index 956fb5f9..68ffb545 100644 --- a/S1API/Quests/QuestEntry.cs +++ b/S1API/Quests/QuestEntry.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Quests = Il2CppScheduleOne.Quests; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Quests = ScheduleOne.Quests; #endif @@ -72,4 +72,4 @@ public Vector3 POIPosition public void SetState(QuestState questState) => S1QuestEntry.SetState((S1Quests.EQuestState)questState); } -} \ No newline at end of file +} diff --git a/S1API/S1API.cs b/S1API/S1API.cs index b50ec326..9aabfbec 100644 --- a/S1API/S1API.cs +++ b/S1API/S1API.cs @@ -1,4 +1,6 @@ -using MelonLoader; + +#if MONOMELON || IL2CPPMELON +using MelonLoader; [assembly: MelonInfo(typeof(S1API.S1API), "S1API", "{VERSION_NUMBER}", "KaBooMa")] @@ -8,3 +10,17 @@ public class S1API : MelonMod { } } +#elif MONOBEPINEX || IL2CPPBEPINEX +using BepInEx; +using BepInEx.Unity.Mono; + +namespace S1API +{ + [BepInPlugin(MyPluginInfo.PLUGIN_GUID, MyPluginInfo.PLUGIN_NAME, MyPluginInfo.PLUGIN_VERSION)] + public class S1API : BaseUnityPlugin + { + + } +} + +#endif diff --git a/S1API/S1API.csproj b/S1API/S1API.csproj index e154ad15..51a19069 100644 --- a/S1API/S1API.csproj +++ b/S1API/S1API.csproj @@ -1,10 +1,10 @@  - + - + netstandard2.1 @@ -14,107 +14,87 @@ https://github.com/KaBooMa/S1API MIT enable - Mono;Il2Cpp + MonoMelon;MonoBepInEx;Il2CppMelon;Il2CppBepInEx AnyCPU S1API + + + https://api.nuget.org/v3/index.json; + https://nuget.bepinex.dev/v3/index.json; + https://nuget.samboy.dev/v3/index.json + + + - - - $(MelonLoaderAssembliesPath)\Il2CppInterop.Runtime.dll - - - $(MelonLoaderAssembliesPath)\Il2CppInterop.Common.dll - - - $(MelonLoaderAssembliesPath)\Il2CppInterop.HarmonySupport.dll - - - $(MelonLoaderAssembliesPath)\Il2CppInterop.Generator.dll - - - $(Il2CppAssembliesPath)\Assembly-CSharp.dll - - - $(Il2CppAssembliesPath)\Il2CppFishNet.Runtime.dll - - - $(Il2CppAssembliesPath)\Il2Cppmscorlib.dll - - - $(Il2CppAssembliesPath)\UnityEngine.dll - - - $(Il2CppAssembliesPath)\UnityEngine.CoreModule.dll - - - $(Il2CppAssembliesPath)\UnityEngine.UI.dll - - - $(Il2CppAssembliesPath)\UnityEngine.UIModule.dll - - - $(Il2CppAssembliesPath)\UnityEngine.JSONSerializeModule.dll - - - $(Il2CppAssembliesPath)\UnityEngine.TextRenderingModule.dll - - - $(Il2CppAssembliesPath)\UnityEngine.ImageConversionModule.dll - + + + + + + + + + + + + + + + + + + + + + - - - $(MonoAssembliesPath)\Assembly-CSharp.dll - - - $(MonoAssembliesPath)\UnityEngine.dll - - - $(MonoAssembliesPath)\UnityEngine.CoreModule.dll - - - $(MonoAssembliesPath)\FishNet.Runtime.dll - - - $(MonoAssembliesPath)\UnityEngine.UI.dll - - - $(MonoAssembliesPath)\UnityEngine.UIModule.dll - - - $(MonoAssembliesPath)\UnityEngine.JSONSerializeModule.dll - - - $(MonoAssembliesPath)\UnityEngine.TextRenderingModule.dll - - - $(MonoAssembliesPath)\UnityEngine.ImageConversionModule.dll - + + + + + + + + + + + + + + + + + + + + + + + + + + - - $(MelonLoaderAssembliesPath)\0Harmony.dll - - - - - - + + + + - - - - + + + + - \ No newline at end of file + diff --git a/S1API/Storages/StorageInstance.cs b/S1API/Storages/StorageInstance.cs index 217f49f1..46561db8 100644 --- a/S1API/Storages/StorageInstance.cs +++ b/S1API/Storages/StorageInstance.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Storage = Il2CppScheduleOne.Storage; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Storage = ScheduleOne.Storage; #endif @@ -67,4 +67,4 @@ public event Action OnClosed remove => EventHelper.RemoveListener(value, S1Storage.onClosed); } } -} \ No newline at end of file +} diff --git a/S1API/UI/UIFactory.cs b/S1API/UI/UIFactory.cs index fc3795a3..f97eab43 100644 --- a/S1API/UI/UIFactory.cs +++ b/S1API/UI/UIFactory.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if IL2CPPMELON || IL2CPPBEPINEX using UnityEngine; using UnityEngine.UI; using Il2CppInterop.Runtime.InteropTypes.Arrays; @@ -9,8 +9,6 @@ using System; using UnityEngine.Events; -using System.Collections.Generic; -using MelonLoader; using Object = UnityEngine.Object; namespace S1API.UI @@ -290,8 +288,8 @@ public static GameObject CreateQuestRow(string name, Transform parent, out GameO rowRT.sizeDelta = new Vector2(0f, 90f); // Let layout handle width row.AddComponent().minHeight = 50f; row.AddComponent().effectColor = new Color(0, 0, 0, 0.2f); // or Image line separator below - - + + var line = UIFactory.Panel("Separator", row.transform, new Color(1,1,1,0.05f)); line.GetComponent().sizeDelta = new Vector2(300f, 1f); diff --git a/S1APILoader/S1APILoader.csproj b/S1APILoader/S1APILoader.csproj index 8d79d7be..7fdb89ee 100644 --- a/S1APILoader/S1APILoader.csproj +++ b/S1APILoader/S1APILoader.csproj @@ -8,7 +8,7 @@ netstandard2.1 enable - Mono;Il2Cpp + Il2CppMelon;MonoBepInEx;MonoMelon;Il2CppBepInEx AnyCPU S1APILoader diff --git a/example.build.props b/example.build.props index 3c0a2143..475f048a 100644 --- a/example.build.props +++ b/example.build.props @@ -11,6 +11,7 @@ C:\Program Files (x86)\Steam\steamapps\common\Schedule I\MelonLoader\net6 + C:\Program Files (x86)\Steam\steamapps\common\Schedule I\BepInEx\core @@ -28,4 +29,4 @@ C:\Program Files (x86)\Steam\steamapps\common\Schedule I\Melonloader\Il2CppAssemblies - \ No newline at end of file + From c7933e435f8d7272004d0f5e2705a700b2dbdd7f Mon Sep 17 00:00:00 2001 From: MaxtorCoder Date: Sat, 26 Apr 2025 13:47:21 +0200 Subject: [PATCH 07/42] Improve logging code and documentation --- S1API/Logging/Log.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/S1API/Logging/Log.cs b/S1API/Logging/Log.cs index 939309dd..03986b93 100644 --- a/S1API/Logging/Log.cs +++ b/S1API/Logging/Log.cs @@ -17,15 +17,30 @@ public class Log private readonly ManualLogSource _loggerInstance; #endif + /// + /// Default constructor for instance + /// + /// The source name to use for logging public Log(string sourceName) { #if MONOMELON || IL2CPPMELON _loggerInstance = new MelonLogger.Instancer(sourceName); #else - _loggerInstance = new ManualLogSource(sourceName); + _loggerInstance = Logger.CreateLogSource(sourceName); #endif } +#if MONOBEPINEX || IL2CPPBEPINEX + /// + /// Default constructor for instance when BepInEx is enabled + /// + /// Existing instance to use + public Log(ManualLogSource loggerInstance) + { + _loggerInstance = loggerInstance; + } +#endif + /// /// Logs a message with Info level /// From 0517550dff338fa30786b6ac487c37a46ae77e42 Mon Sep 17 00:00:00 2001 From: MaxtorCoder Date: Sat, 26 Apr 2025 14:01:20 +0200 Subject: [PATCH 08/42] Add Harmony patching to main Plugin file --- S1API/S1API.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/S1API/S1API.cs b/S1API/S1API.cs index 9aabfbec..b3c3936b 100644 --- a/S1API/S1API.cs +++ b/S1API/S1API.cs @@ -1,5 +1,4 @@ - -#if MONOMELON || IL2CPPMELON +#if MONOMELON || IL2CPPMELON using MelonLoader; [assembly: MelonInfo(typeof(S1API.S1API), "S1API", "{VERSION_NUMBER}", "KaBooMa")] @@ -14,12 +13,17 @@ public class S1API : MelonMod using BepInEx; using BepInEx.Unity.Mono; +using HarmonyLib; + namespace S1API { [BepInPlugin(MyPluginInfo.PLUGIN_GUID, MyPluginInfo.PLUGIN_NAME, MyPluginInfo.PLUGIN_VERSION)] public class S1API : BaseUnityPlugin { - + private void Awake() + { + new Harmony("com.S1API").PatchAll(); + } } } From 46af4894104f98f31e5dfd2405ee519efb525a47 Mon Sep 17 00:00:00 2001 From: Omar Akermi Date: Sun, 27 Apr 2025 00:58:42 +0200 Subject: [PATCH 09/42] feat: finished timemanager and gamedatetime --- S1API/GameTime/GameDateTime.cs | 172 ++++++++++++++++++++++++++++----- S1API/GameTime/TimeManager.cs | 131 +++++++++++++++++++++++-- 2 files changed, 273 insertions(+), 30 deletions(-) diff --git a/S1API/GameTime/GameDateTime.cs b/S1API/GameTime/GameDateTime.cs index bf72ea81..9aa462d7 100644 --- a/S1API/GameTime/GameDateTime.cs +++ b/S1API/GameTime/GameDateTime.cs @@ -1,22 +1,150 @@ -// TODO: Implement GameDateTime wrapper -// #if (IL2CPP) -// using S1GameTime = Il2CppScheduleOne.GameTime; -// #elif (MONO) -// using S1GameTime = ScheduleOne.GameTime; -// #endif -// -// namespace S1API.API.GameTime -// { -// struct GameDateTime -// { -// public int elapsedDays; -// public int time; -// -// public GameDateTime(S1GameTime.GameDateTime gameDateTime) -// { -// -// } -// -// public void Ad -// } -// } \ No newline at end of file +#if (IL2CPP) +using S1GameDateTime = Il2CppScheduleOne.GameTime.GameDateTime; +using S1TimeManager = Il2CppScheduleOne.GameTime.TimeManager; +using S1GameDateTimeData = Il2CppScheduleOne.Persistence.Datas.GameDateTimeData; +#elif (MONO) +using S1GameDateTime = ScheduleOne.GameTime.GameDateTime; +using S1TimeManager = ScheduleOne.GameTime.TimeManager; +using S1GameDateTimeData = ScheduleOne.Persistence.Datas.GameDateTimeData; +#endif + +using System; + +namespace S1API.GameTime +{ + /// + /// Represents an in-game datetime (elapsed days and 24-hour time). + /// + public struct GameDateTime + { + public int ElapsedDays; + public int Time; + + /// + /// Constructs a GameDateTime from elapsed days and 24-hour time. + /// + public GameDateTime(int elapsedDays, int time) + { + ElapsedDays = elapsedDays; + Time = time; + } + + /// + /// Constructs a GameDateTime from total minutes. + /// + public GameDateTime(int minSum) + { + ElapsedDays = minSum / 1440; + int minutesInDay = minSum % 1440; + if (minSum < 0) + { + minutesInDay = -minSum % 1440; + } + Time = S1TimeManager.Get24HourTimeFromMinSum(minutesInDay); + } + + /// + /// Constructs a GameDateTime from an internal GameDateTimeData. + /// + public GameDateTime(S1GameDateTimeData data) + { + ElapsedDays = data.ElapsedDays; + Time = data.Time; + } + + /// + /// Constructs a GameDateTime from the internal GameDateTime struct. + /// + public GameDateTime(S1GameDateTime gameDateTime) + { + ElapsedDays = gameDateTime.elapsedDays; + Time = gameDateTime.time; + } + + /// + /// Returns the total minute sum (days * 1440 + minutes of day). + /// + public int GetMinSum() + { + return ElapsedDays * 1440 + S1TimeManager.GetMinSumFrom24HourTime(Time); + } + + /// + /// Returns a new GameDateTime with additional minutes added. + /// + public GameDateTime AddMinutes(int minutes) + { + return new GameDateTime(GetMinSum() + minutes); + } + + /// + /// Converts this wrapper to the internal GameDateTime struct. + /// + public S1GameDateTime ToS1() + { + return new S1GameDateTime(ElapsedDays, Time); + } + + /// + /// Returns the current time formatted as a 12-hour AM/PM string. + /// Example: "12:30 PM" + /// + public string GetFormattedTime() + { + return S1TimeManager.Get12HourTime(Time, true); + } + + /// + /// Returns true if the time is considered nighttime. + /// (Before 6AM or after 6PM) + /// + public bool IsNightTime() + { + return Time < 600 || Time >= 1800; + } + + /// + /// Returns true if the two GameDateTimes are on the same day (ignores time). + /// + public bool IsSameDay(GameDateTime other) + { + return ElapsedDays == other.ElapsedDays; + } + + /// + /// Returns true if the two GameDateTimes are at the same day and time. + /// + public bool IsSameTime(GameDateTime other) + { + return ElapsedDays == other.ElapsedDays && Time == other.Time; + } + + /// + /// String representation: "Day 3, 2:30 PM" + /// + public override string ToString() + { + return $"Day {ElapsedDays}, {GetFormattedTime()}"; + } + + public static GameDateTime operator +(GameDateTime a, GameDateTime b) + { + return new GameDateTime(a.GetMinSum() + b.GetMinSum()); + } + + public static GameDateTime operator -(GameDateTime a, GameDateTime b) + { + return new GameDateTime(a.GetMinSum() - b.GetMinSum()); + } + + public static bool operator >(GameDateTime a, GameDateTime b) + { + return a.GetMinSum() > b.GetMinSum(); + } + + public static bool operator <(GameDateTime a, GameDateTime b) + { + return a.GetMinSum() < b.GetMinSum(); + } + } +} diff --git a/S1API/GameTime/TimeManager.cs b/S1API/GameTime/TimeManager.cs index 45f78f9c..6e181260 100644 --- a/S1API/GameTime/TimeManager.cs +++ b/S1API/GameTime/TimeManager.cs @@ -1,7 +1,7 @@ #if (IL2CPP) -using S1GameTime = Il2CppScheduleOne.GameTime; +using S1GameTime = Il2CppScheduleOne.GameTime.TimeManager; #elif (MONO) -using S1GameTime = ScheduleOne.GameTime; +using S1GameTime = ScheduleOne.GameTime.TimeManager; #endif using System; @@ -14,14 +14,129 @@ namespace S1API.GameTime public static class TimeManager { /// - /// Action called when the day passes in-game. + /// Called when a new in-game day starts. /// public static Action OnDayPass = delegate { }; - + + /// + /// Called when a new in-game week starts. + /// + public static Action OnWeekPass = delegate { }; + + /// + /// Called when the player starts sleeping. + /// + public static Action OnSleepStart = delegate { }; + + /// + /// Called when the player finishes sleeping. + /// Parameter: total minutes skipped during sleep. + /// + public static Action OnSleepEnd = delegate { }; + + static TimeManager() + { + if (S1GameTime.Instance != null) + { + S1GameTime.Instance.onDayPass += (Action)(() => OnDayPass()); + S1GameTime.Instance.onWeekPass += (Action)(() => OnWeekPass()); + } + + S1GameTime.onSleepStart += (Action)(() => OnSleepStart()); + S1GameTime.onSleepEnd += (Action)(minutes => OnSleepEnd(minutes)); + } + + + /// + /// The current in-game day (Monday, Tuesday, etc.). + /// + public static Day CurrentDay => (Day)S1GameTime.Instance.CurrentDay; + + /// + /// The number of in-game days elapsed. + /// + public static int ElapsedDays => S1GameTime.Instance.ElapsedDays; + + /// + /// The current 24-hour time (e.g., 1330 for 1:30 PM). + /// + public static int CurrentTime => S1GameTime.Instance.CurrentTime; + + /// + /// Whether it is currently nighttime in-game. + /// + public static bool IsNight => S1GameTime.Instance.IsNight; + + /// + /// Whether the game is currently at the end of the day (4:00 AM). + /// + public static bool IsEndOfDay => S1GameTime.Instance.IsEndOfDay; + + /// + /// Whether the player is currently sleeping. + /// + public static bool SleepInProgress => S1GameTime.Instance.SleepInProgress; + + /// + /// Whether the time is currently overridden (frozen or custom). + /// + public static bool TimeOverridden => S1GameTime.Instance.TimeOverridden; + + /// + /// The current normalized time of day (0.0 = start, 1.0 = end). + /// + public static float NormalizedTime => S1GameTime.Instance.NormalizedTime; + + /// + /// Total playtime (in seconds). + /// + public static float Playtime => S1GameTime.Instance.Playtime; + + /// + /// Fast-forwards time to morning wake time (7:00 AM). + /// + public static void FastForwardToWakeTime() => S1GameTime.Instance.FastForwardToWakeTime(); + + /// + /// Sets the current time manually. + /// + public static void SetTime(int time24h, bool local = false) => S1GameTime.Instance.SetTime(time24h, local); + + /// + /// Sets the number of elapsed in-game days. + /// + public static void SetElapsedDays(int days) => S1GameTime.Instance.SetElapsedDays(days); + + /// + /// Gets the current time formatted in 12-hour AM/PM format. + /// + public static string GetFormatted12HourTime() + { + return S1GameTime.Get12HourTime(CurrentTime, true); + } + + /// + /// Returns true if the current time is within the specified 24-hour range. + /// + public static bool IsCurrentTimeWithinRange(int startTime24h, int endTime24h) + { + return S1GameTime.Instance.IsCurrentTimeWithinRange(startTime24h, endTime24h); + } + + /// + /// Converts 24-hour time to total minutes. + /// + public static int GetMinutesFrom24HourTime(int time24h) + { + return S1GameTime.GetMinSumFrom24HourTime(time24h); + } + /// - /// The current in-game day. + /// Converts total minutes into 24-hour time format. /// - public static Day CurrentDay => - (Day)S1GameTime.TimeManager.Instance.CurrentDay; + public static int Get24HourTimeFromMinutes(int minutes) + { + return S1GameTime.Get24HourTimeFromMinSum(minutes); + } } -} \ No newline at end of file +} From 9955a77baedc320ffa6e7afa864d665d00b01006 Mon Sep 17 00:00:00 2001 From: Omar Akermi Date: Sun, 27 Apr 2025 02:55:01 +0200 Subject: [PATCH 10/42] feat: moneymanager --- S1API/Money/MoneyManager.cs | 109 ++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 S1API/Money/MoneyManager.cs diff --git a/S1API/Money/MoneyManager.cs b/S1API/Money/MoneyManager.cs new file mode 100644 index 00000000..92e68168 --- /dev/null +++ b/S1API/Money/MoneyManager.cs @@ -0,0 +1,109 @@ +// REMOVE dynamic usage. Use the real FloatContainer. + +using S1API.Internal.Abstraction; +using UnityEngine; + +namespace S1API.Money +{ + /// + /// Provides methods for managing financial data, including cash balance, + /// online transactions, and net worth calculations. + /// + public class MoneyManager : Registerable + { +#if IL2CPP + private static Il2CppScheduleOne.Money.MoneyManager InternalInstance => Il2CppScheduleOne.Money.MoneyManager.Instance; +#else + /// + /// Provides internal access to the singleton instance of the underlying `ScheduleOne.Money.MoneyManager`. + /// This property is used internally to interact with the core money management system. + /// + private static ScheduleOne.Money.MoneyManager InternalInstance => ScheduleOne.Money.MoneyManager.Instance; +#endif + + /// + /// Invoked when the instance of the class is created and initialized. + /// Provides an entry point for subclasses to include additional setup logic during creation. + /// + protected override void OnCreated() => base.OnCreated(); + + /// + /// Executes cleanup or teardown logic when the instance is being destroyed. + /// This method is invoked when the object lifecycle ends and should typically + /// handle resource deallocation, event unsubscriptions, or other finalization tasks. + /// + protected override void OnDestroyed() => base.OnDestroyed(); + + /// + /// Changes the cash balance by the specified amount. + /// + /// The amount to adjust the cash balance by. Positive values increase the balance, while negative values decrease it. + /// Indicates whether the change in cash balance should be visually represented. + /// Indicates whether a sound effect should play when the cash balance is changed. + public static void ChangeCashBalance(float amount, bool visualizeChange = true, bool playCashSound = false) + { + InternalInstance?.ChangeCashBalance(amount, visualizeChange, playCashSound); + } + + /// + /// Creates an online transaction with specified details. + /// + /// The name of the transaction. + /// The monetary value of a single unit in the transaction. + /// The quantity involved in the transaction. + /// A note or description for the transaction. + public static void CreateOnlineTransaction(string transactionName, float unitAmount, float quantity, string transactionNote) + { + InternalInstance?.CreateOnlineTransaction(transactionName, unitAmount, quantity, transactionNote); + } + + /// + /// Retrieves the current net worth. + /// + /// The calculated net worth as a floating-point number. + public static float GetNetWorth() + { + return InternalInstance != null ? InternalInstance.GetNetWorth() : 0f; + } + + /// + /// Retrieves the current cash balance. + /// + /// The current cash balance as a floating-point value. + public static float GetCashBalance() + { + return InternalInstance != null ? InternalInstance.cashBalance : 0f; + } + + /// + /// Retrieves the current online balance of the user. + /// + /// + /// A float representing the user's current online balance. Returns 0 if the internal instance is null. + /// + public static float GetOnlineBalance() + { + return InternalInstance != null ? InternalInstance.sync___get_value_onlineBalance() : 0f; + } + + /// + /// Register a networth calculation event. + /// + /// An action to invoke during the networth calculation event. + public static void AddNetworthCalculation(System.Action callback) + { + if (InternalInstance != null) + InternalInstance.onNetworthCalculation += callback; + } + + /// + /// Remove a networth calculation event. + /// + /// The callback function to remove from the networth calculation event. + public static void RemoveNetworthCalculation(System.Action callback) + { + if (InternalInstance != null) + InternalInstance.onNetworthCalculation -= callback; + } + } +} From 88850bbeb85e06690ae1f712f03bbd18b22a4f95 Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Sat, 26 Apr 2025 20:16:17 -0500 Subject: [PATCH 11/42] feat: Building for net6.0 for Il2Cpp per melon recommendation (and warning resolutions) --- S1API/Console/ConsoleHelper.cs | 3 + S1API/Entities/Interfaces/IEntity.cs | 3 + S1API/Entities/NPC.cs | 17 +++-- S1API/Entities/NPCs/DanSamwell.cs | 5 ++ S1API/Entities/NPCs/Docks/AnnaChesterfield.cs | 5 ++ S1API/Entities/NPCs/Docks/BillyKramer.cs | 4 ++ S1API/Entities/NPCs/Docks/CrankyFrank.cs | 5 ++ S1API/Entities/NPCs/Docks/GenghisBarn.cs | 5 ++ S1API/Entities/NPCs/Docks/JaneLucero.cs | 5 ++ S1API/Entities/NPCs/Docks/JavierPerez.cs | 5 ++ S1API/Entities/NPCs/Docks/LisaGardener.cs | 5 ++ S1API/Entities/NPCs/Docks/MacCooper.cs | 5 ++ S1API/Entities/NPCs/Docks/MarcoBaron.cs | 5 ++ S1API/Entities/NPCs/Docks/MelissaWood.cs | 5 ++ S1API/Entities/NPCs/Docks/SalvadorMoreno.cs | 5 ++ S1API/Entities/NPCs/Downtown/BradCrosby.cs | 5 ++ .../Entities/NPCs/Downtown/ElizabethHomley.cs | 5 ++ S1API/Entities/NPCs/Downtown/EugeneBuckley.cs | 5 ++ S1API/Entities/NPCs/Downtown/GregFliggle.cs | 5 ++ S1API/Entities/NPCs/Downtown/JeffGilmore.cs | 5 ++ .../Entities/NPCs/Downtown/JenniferRivera.cs | 5 ++ S1API/Entities/NPCs/Downtown/KevinOakley.cs | 5 ++ S1API/Entities/NPCs/Downtown/LouisFourier.cs | 5 ++ .../Entities/NPCs/Downtown/LucyPennington.cs | 5 ++ .../Entities/NPCs/Downtown/PhilipWentworth.cs | 5 ++ .../Entities/NPCs/Downtown/RandyCaulfield.cs | 5 ++ S1API/Entities/NPCs/IgorRomanovich.cs | 5 ++ S1API/Entities/NPCs/MannyOakfield.cs | 5 ++ S1API/Entities/NPCs/NPC_LIST.md | 7 -- S1API/Entities/NPCs/Northtown/AlbertHoover.cs | 5 ++ .../Entities/NPCs/Northtown/AustinSteiner.cs | 5 ++ S1API/Entities/NPCs/Northtown/BenjiColeman.cs | 6 ++ S1API/Entities/NPCs/Northtown/BethPenn.cs | 5 ++ S1API/Entities/NPCs/Northtown/ChloeBowers.cs | 5 ++ S1API/Entities/NPCs/Northtown/DonnaMartin.cs | 5 ++ .../Entities/NPCs/Northtown/GeraldinePoon.cs | 5 ++ S1API/Entities/NPCs/Northtown/JessiWaters.cs | 5 ++ .../Entities/NPCs/Northtown/KathyHenderson.cs | 5 ++ S1API/Entities/NPCs/Northtown/KyleCooley.cs | 5 ++ S1API/Entities/NPCs/Northtown/LudwigMeyer.cs | 5 ++ S1API/Entities/NPCs/Northtown/MickLubbin.cs | 5 ++ S1API/Entities/NPCs/Northtown/Ming.cs | 5 ++ S1API/Entities/NPCs/Northtown/PeggyMyers.cs | 5 ++ S1API/Entities/NPCs/Northtown/PeterFile.cs | 5 ++ S1API/Entities/NPCs/Northtown/SamThompson.cs | 5 ++ S1API/Entities/NPCs/OscarHolland.cs | 4 ++ .../NPCs/PoliceOfficers/OfficerBailey.cs | 4 ++ .../NPCs/PoliceOfficers/OfficerCooper.cs | 4 ++ .../NPCs/PoliceOfficers/OfficerGreen.cs | 4 ++ .../NPCs/PoliceOfficers/OfficerHoward.cs | 4 ++ .../NPCs/PoliceOfficers/OfficerJackson.cs | 4 ++ .../NPCs/PoliceOfficers/OfficerLee.cs | 4 ++ .../NPCs/PoliceOfficers/OfficerLopez.cs | 4 ++ .../NPCs/PoliceOfficers/OfficerMurphy.cs | 4 ++ .../NPCs/PoliceOfficers/OfficerOakley.cs | 4 ++ S1API/Entities/NPCs/StanCarney.cs | 5 ++ S1API/Entities/NPCs/Suburbia/AlisonKnight.cs | 5 ++ S1API/Entities/NPCs/Suburbia/CarlBundy.cs | 5 ++ S1API/Entities/NPCs/Suburbia/ChrisSullivan.cs | 5 ++ S1API/Entities/NPCs/Suburbia/DennisKennedy.cs | 5 ++ S1API/Entities/NPCs/Suburbia/HankStevenson.cs | 5 ++ S1API/Entities/NPCs/Suburbia/HaroldColt.cs | 5 ++ S1API/Entities/NPCs/Suburbia/JackKnight.cs | 5 ++ .../Entities/NPCs/Suburbia/JackieStevenson.cs | 5 ++ .../Entities/NPCs/Suburbia/JeremyWilkinson.cs | 5 ++ S1API/Entities/NPCs/Suburbia/KarenKennedy.cs | 6 ++ S1API/Entities/NPCs/Suburbia/WeiLong.cs | 5 ++ S1API/Entities/NPCs/UncleNelson.cs | 4 ++ S1API/Entities/NPCs/Uptown/FionaHancock.cs | 5 ++ S1API/Entities/NPCs/Uptown/HerbertBleuball.cs | 5 ++ S1API/Entities/NPCs/Uptown/JenHeard.cs | 5 ++ S1API/Entities/NPCs/Uptown/LeoRivers.cs | 5 ++ S1API/Entities/NPCs/Uptown/LilyTurner.cs | 5 ++ S1API/Entities/NPCs/Uptown/MichaelBoog.cs | 5 ++ S1API/Entities/NPCs/Uptown/PearlMoore.cs | 5 ++ S1API/Entities/NPCs/Uptown/RayHoffman.cs | 5 ++ S1API/Entities/NPCs/Uptown/TobiasWentworth.cs | 5 ++ S1API/Entities/NPCs/Uptown/WalterCussler.cs | 5 ++ .../Entities/NPCs/Westville/CharlesRowland.cs | 5 ++ S1API/Entities/NPCs/Westville/DeanWebster.cs | 5 ++ S1API/Entities/NPCs/Westville/DorisLubbin.cs | 5 ++ S1API/Entities/NPCs/Westville/GeorgeGreene.cs | 5 ++ S1API/Entities/NPCs/Westville/JerryMontero.cs | 5 ++ S1API/Entities/NPCs/Westville/JoyceBall.cs | 5 ++ S1API/Entities/NPCs/Westville/KeithWagner.cs | 5 ++ S1API/Entities/NPCs/Westville/KimDelaney.cs | 5 ++ S1API/Entities/NPCs/Westville/MegCooley.cs | 5 ++ S1API/Entities/NPCs/Westville/MollyPresley.cs | 5 ++ S1API/Entities/NPCs/Westville/ShirleyWatts.cs | 5 ++ S1API/Entities/NPCs/Westville/TrentSherman.cs | 5 ++ S1API/GameTime/Day.cs | 27 +++++++ S1API/Internal/Abstraction/EventHelper.cs | 2 +- S1API/Internal/Abstraction/Saveable.cs | 6 +- S1API/Internal/Patches/NPCPatches.cs | 7 +- S1API/Internal/Patches/PhoneAppPatches.cs | 1 + S1API/Internal/Patches/QuestPatches.cs | 4 +- S1API/Internal/Utils/ButtonListener.cs | 8 ++- S1API/Internal/Utils/ImageUtils.cs | 6 +- S1API/Internal/Utils/RandomUtils.cs | 12 ++-- S1API/Internal/Utils/ReflectionUtils.cs | 12 ++-- S1API/Items/ItemCategory.cs | 49 +++++++++++++ S1API/Leveling/Rank.cs | 43 +++++++++++ S1API/Messaging/Response.cs | 2 +- S1API/PhoneApp/MyAwesomeApp.cs | 16 +++-- S1API/PhoneApp/PhoneApp.cs | 71 +++++++++---------- S1API/Products/ProductDefinitionWrapper.cs | 7 +- S1API/Quests/QuestManager.cs | 5 +- S1API/Quests/QuestState.cs | 23 ++++++ S1API/S1API.cs | 3 + S1API/S1API.csproj | 9 ++- S1API/Saveables/SaveableField.cs | 6 ++ S1API/UI/UIFactory.cs | 50 ++++++++----- 112 files changed, 718 insertions(+), 101 deletions(-) diff --git a/S1API/Console/ConsoleHelper.cs b/S1API/Console/ConsoleHelper.cs index 92b82e22..a7bded34 100644 --- a/S1API/Console/ConsoleHelper.cs +++ b/S1API/Console/ConsoleHelper.cs @@ -8,6 +8,9 @@ namespace S1API.Console { + /// + /// This class provides easy access to the in-game console system. + /// public static class ConsoleHelper { /// diff --git a/S1API/Entities/Interfaces/IEntity.cs b/S1API/Entities/Interfaces/IEntity.cs index eff5f980..8cd62f76 100644 --- a/S1API/Entities/Interfaces/IEntity.cs +++ b/S1API/Entities/Interfaces/IEntity.cs @@ -7,6 +7,9 @@ namespace S1API.Entities.Interfaces /// public interface IEntity { + /// + /// INTERNAL: Tracking of the GameObject associated with this entity. + /// GameObject gameObject { get; } /// diff --git a/S1API/Entities/NPC.cs b/S1API/Entities/NPC.cs index 4100f29f..afa3e341 100644 --- a/S1API/Entities/NPC.cs +++ b/S1API/Entities/NPC.cs @@ -76,7 +76,7 @@ protected NPC( Sprite? icon = null ) { - _isCustomNPC = true; + IsCustomNPC = true; gameObject = new GameObject(); // Deactivate game object til we're done @@ -200,6 +200,12 @@ protected virtual void OnResponseLoaded(Response response) { } // Can be used inside your derived class, or outside via instance reference. #region Public Members + /// + /// INTERNAL: Tracking for the GameObject associated with this NPC. + /// Not intended for use by modders! + /// + public GameObject gameObject { get; } + /// /// List of all NPCs within the base game and modded. /// @@ -308,7 +314,7 @@ public float Aggressiveness /// public float PanicDuration { - get => (float)_panicField.GetValue(S1NPC); + get => (float)_panicField.GetValue(S1NPC)!; set => _panicField.SetValue(S1NPC, value); } @@ -333,7 +339,7 @@ public float Scale /// public bool RequiresRegionUnlocked { - get => (bool)_requiresRegionUnlockedField.GetValue(S1NPC); + get => (bool)_requiresRegionUnlockedField.GetValue(S1NPC)!; set => _panicField.SetValue(S1NPC, value); } @@ -566,7 +572,7 @@ internal NPC(S1NPCs.NPC npc) { S1NPC = npc; gameObject = npc.gameObject; - _isCustomNPC = false; + IsCustomNPC = false; All.Add(this); } @@ -597,8 +603,7 @@ internal override void SaveInternal(string folderPath, ref List extraSav // Please do not attempt to use these members! #region Private Members - public GameObject gameObject { get; } - private readonly bool _isCustomNPC; + internal readonly bool IsCustomNPC; private readonly FieldInfo _panicField = AccessTools.Field(typeof(S1NPCs.NPC), "PANIC_DURATION"); private readonly FieldInfo _requiresRegionUnlockedField = AccessTools.Field(typeof(S1NPCs.NPC), "RequiresRegionUnlocked"); diff --git a/S1API/Entities/NPCs/DanSamwell.cs b/S1API/Entities/NPCs/DanSamwell.cs index 4e374279..e3f3b0aa 100644 --- a/S1API/Entities/NPCs/DanSamwell.cs +++ b/S1API/Entities/NPCs/DanSamwell.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs { + /// + /// UNCONFIRMED: Dan Samwell is a customer. + /// He is the NPC that owns Dan's Hardware! + /// If you confirm this, please let us know so we can update the documentation! + /// public class DanSamwell : NPC { internal DanSamwell() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "dan_samwell")) { } diff --git a/S1API/Entities/NPCs/Docks/AnnaChesterfield.cs b/S1API/Entities/NPCs/Docks/AnnaChesterfield.cs index aaeb3fd5..716271c2 100644 --- a/S1API/Entities/NPCs/Docks/AnnaChesterfield.cs +++ b/S1API/Entities/NPCs/Docks/AnnaChesterfield.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Docks { + /// + /// Anna Chesterfield is a customer. + /// She lives in the Docks region. + /// Anna also works at the Barbershop. + /// public class AnnaChesterfield : NPC { internal AnnaChesterfield() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "anna_chesterfield")) { } diff --git a/S1API/Entities/NPCs/Docks/BillyKramer.cs b/S1API/Entities/NPCs/Docks/BillyKramer.cs index f7e2ab9c..1195c3ba 100644 --- a/S1API/Entities/NPCs/Docks/BillyKramer.cs +++ b/S1API/Entities/NPCs/Docks/BillyKramer.cs @@ -7,6 +7,10 @@ namespace S1API.Entities.NPCs.Docks { + /// + /// Billy Kramer is a customer. + /// He lives in the Docks region. + /// public class BillyKramer : NPC { internal BillyKramer() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "billy_kramer")) { } diff --git a/S1API/Entities/NPCs/Docks/CrankyFrank.cs b/S1API/Entities/NPCs/Docks/CrankyFrank.cs index 60a0f3c3..b5b91835 100644 --- a/S1API/Entities/NPCs/Docks/CrankyFrank.cs +++ b/S1API/Entities/NPCs/Docks/CrankyFrank.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Docks { + /// + /// Cranky Frank is a customer. + /// He lives in the Docks region. + /// Frank is the NPC with a pot on his head! + /// public class CrankyFrank : NPC { internal CrankyFrank() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "cranky_frank")) { } diff --git a/S1API/Entities/NPCs/Docks/GenghisBarn.cs b/S1API/Entities/NPCs/Docks/GenghisBarn.cs index a0bd37cf..3f0053a9 100644 --- a/S1API/Entities/NPCs/Docks/GenghisBarn.cs +++ b/S1API/Entities/NPCs/Docks/GenghisBarn.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Docks { + /// + /// Genghis Barn is a customer. + /// He lives in the Docks region. + /// Genghis is the NPC with a mohawk! + /// public class GenghisBarn : NPC { internal GenghisBarn() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "genghis_barn")) { } diff --git a/S1API/Entities/NPCs/Docks/JaneLucero.cs b/S1API/Entities/NPCs/Docks/JaneLucero.cs index 1bc5ed3e..92dfb778 100644 --- a/S1API/Entities/NPCs/Docks/JaneLucero.cs +++ b/S1API/Entities/NPCs/Docks/JaneLucero.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Docks { + /// + /// Jane Lucero is a dealer. + /// She lives in the Docks region. + /// Jane is the dealer with a tear tattoo! + /// public class JaneLucero : NPC { internal JaneLucero() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "jane_lucero")) { } diff --git a/S1API/Entities/NPCs/Docks/JavierPerez.cs b/S1API/Entities/NPCs/Docks/JavierPerez.cs index 996bb995..d60491cd 100644 --- a/S1API/Entities/NPCs/Docks/JavierPerez.cs +++ b/S1API/Entities/NPCs/Docks/JavierPerez.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Docks { + /// + /// Javier Perez is a customer. + /// He lives in the Docks region. + /// Javier works night shift at the Gas-Mart! + /// public class JavierPerez : NPC { internal JavierPerez() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "javier_perez")) { } diff --git a/S1API/Entities/NPCs/Docks/LisaGardener.cs b/S1API/Entities/NPCs/Docks/LisaGardener.cs index 94690444..25ff3c57 100644 --- a/S1API/Entities/NPCs/Docks/LisaGardener.cs +++ b/S1API/Entities/NPCs/Docks/LisaGardener.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Docks { + /// + /// Lisa Gardener is a customer. + /// She lives in the Docks region. + /// Lisa is the NPC wearing blue scrubs! + /// public class LisaGardener : NPC { internal LisaGardener() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "lisa_gardener")) { } diff --git a/S1API/Entities/NPCs/Docks/MacCooper.cs b/S1API/Entities/NPCs/Docks/MacCooper.cs index f51263f4..417812a9 100644 --- a/S1API/Entities/NPCs/Docks/MacCooper.cs +++ b/S1API/Entities/NPCs/Docks/MacCooper.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Docks { + /// + /// Mac Cooper is a customer. + /// He lives in the Docks region. + /// Mac is the NPC with a blonde mohawk and gold shades! + /// public class MacCooper : NPC { internal MacCooper() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "mac_cooper")) { } diff --git a/S1API/Entities/NPCs/Docks/MarcoBaron.cs b/S1API/Entities/NPCs/Docks/MarcoBaron.cs index 98cc3f38..acc1e4b9 100644 --- a/S1API/Entities/NPCs/Docks/MarcoBaron.cs +++ b/S1API/Entities/NPCs/Docks/MarcoBaron.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Docks { + /// + /// Marco Baron is a customer. + /// He lives in the Docks region. + /// Marco is the NPC that runs the Auto Shop! + /// public class MarcoBaron : NPC { internal MarcoBaron() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "marco_baron")) { } diff --git a/S1API/Entities/NPCs/Docks/MelissaWood.cs b/S1API/Entities/NPCs/Docks/MelissaWood.cs index deebcd71..f951d422 100644 --- a/S1API/Entities/NPCs/Docks/MelissaWood.cs +++ b/S1API/Entities/NPCs/Docks/MelissaWood.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Docks { + /// + /// Melissa Wood is a customer. + /// She lives in the Docks region. + /// Melissa is the Blackjack dealer at the casino! + /// public class MelissaWood : NPC { internal MelissaWood() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "melissa_wood")) { } diff --git a/S1API/Entities/NPCs/Docks/SalvadorMoreno.cs b/S1API/Entities/NPCs/Docks/SalvadorMoreno.cs index e2ab021e..5874de36 100644 --- a/S1API/Entities/NPCs/Docks/SalvadorMoreno.cs +++ b/S1API/Entities/NPCs/Docks/SalvadorMoreno.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Docks { + /// + /// Salvador Moreno is a supplier. + /// He lives in the Docks region. + /// Salvador is the NPC that supplies coca seeds to the player! + /// public class SalvadorMoreno : NPC { internal SalvadorMoreno() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "salvador_moreno")) { } diff --git a/S1API/Entities/NPCs/Downtown/BradCrosby.cs b/S1API/Entities/NPCs/Downtown/BradCrosby.cs index 5afde74a..193ff48c 100644 --- a/S1API/Entities/NPCs/Downtown/BradCrosby.cs +++ b/S1API/Entities/NPCs/Downtown/BradCrosby.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Downtown { + /// + /// Brad Crosby is a dealer. + /// He lives in the Downtown region. + /// Brad lives in a tent at the parking garage next to the casino! + /// public class BradCrosby : NPC { internal BradCrosby() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "brad_crosby")) { } diff --git a/S1API/Entities/NPCs/Downtown/ElizabethHomley.cs b/S1API/Entities/NPCs/Downtown/ElizabethHomley.cs index 9a4ff903..cc5dc2e9 100644 --- a/S1API/Entities/NPCs/Downtown/ElizabethHomley.cs +++ b/S1API/Entities/NPCs/Downtown/ElizabethHomley.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Downtown { + /// + /// Elizabeth Homley is a customer. + /// She lives in the Downtown region. + /// Elizabeth is the NPC is lightning blue hair! + /// public class ElizabethHomley : NPC { internal ElizabethHomley() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "elizabeth_homley")) { } diff --git a/S1API/Entities/NPCs/Downtown/EugeneBuckley.cs b/S1API/Entities/NPCs/Downtown/EugeneBuckley.cs index ef59eaed..e497a5cc 100644 --- a/S1API/Entities/NPCs/Downtown/EugeneBuckley.cs +++ b/S1API/Entities/NPCs/Downtown/EugeneBuckley.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Downtown { + /// + /// Eugene Buckley is a customer. + /// He lives in the Downtown region. + /// Eugene is the NPC with light brown hair, freckles, and black glasses! + /// public class EugeneBuckley : NPC { internal EugeneBuckley() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "eugene_buckley")) { } diff --git a/S1API/Entities/NPCs/Downtown/GregFliggle.cs b/S1API/Entities/NPCs/Downtown/GregFliggle.cs index bf8264ad..6645f34a 100644 --- a/S1API/Entities/NPCs/Downtown/GregFliggle.cs +++ b/S1API/Entities/NPCs/Downtown/GregFliggle.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Downtown { + /// + /// Greg Fliggle is a customer. + /// He lives in the Downtown region. + /// Greg is the NPC with a teardrop tattoo and wrinkles! + /// public class GregFliggle : NPC { internal GregFliggle() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "greg_fliggle")) { } diff --git a/S1API/Entities/NPCs/Downtown/JeffGilmore.cs b/S1API/Entities/NPCs/Downtown/JeffGilmore.cs index 42ce8592..8b7ca3d8 100644 --- a/S1API/Entities/NPCs/Downtown/JeffGilmore.cs +++ b/S1API/Entities/NPCs/Downtown/JeffGilmore.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Downtown { + /// + /// Jeff Gilmore is a customer. + /// He lives in the Downtown region. + /// Jeff is the NPC that runs the skateboard shop! + /// public class JeffGilmore : NPC { internal JeffGilmore() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "jeff_gilmore")) { } diff --git a/S1API/Entities/NPCs/Downtown/JenniferRivera.cs b/S1API/Entities/NPCs/Downtown/JenniferRivera.cs index 1e2b7d9c..7df65be4 100644 --- a/S1API/Entities/NPCs/Downtown/JenniferRivera.cs +++ b/S1API/Entities/NPCs/Downtown/JenniferRivera.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Downtown { + /// + /// Jennifer Rivera is a customer. + /// She lives in the Downtown region. + /// Jennifer is the NPC with blonde haired buns! + /// public class JenniferRivera : NPC { internal JenniferRivera() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "jennifer_rivera")) { } diff --git a/S1API/Entities/NPCs/Downtown/KevinOakley.cs b/S1API/Entities/NPCs/Downtown/KevinOakley.cs index 809690c1..6d841940 100644 --- a/S1API/Entities/NPCs/Downtown/KevinOakley.cs +++ b/S1API/Entities/NPCs/Downtown/KevinOakley.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Downtown { + /// + /// Kevin Oakley is a customer. + /// He lives in the Downtown region. + /// Kevin is the NPC wearing a green apron! + /// public class KevinOakley : NPC { internal KevinOakley() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "kevin_oakley")) { } diff --git a/S1API/Entities/NPCs/Downtown/LouisFourier.cs b/S1API/Entities/NPCs/Downtown/LouisFourier.cs index 35e27246..6012bb2c 100644 --- a/S1API/Entities/NPCs/Downtown/LouisFourier.cs +++ b/S1API/Entities/NPCs/Downtown/LouisFourier.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Downtown { + /// + /// Louis Fourier is a customer. + /// He lives in the Downtown region. + /// Louis is the NPC with a chef's hat! + /// public class LouisFourier : NPC { internal LouisFourier() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "louis_fourier")) { } diff --git a/S1API/Entities/NPCs/Downtown/LucyPennington.cs b/S1API/Entities/NPCs/Downtown/LucyPennington.cs index f00de681..97fde0e6 100644 --- a/S1API/Entities/NPCs/Downtown/LucyPennington.cs +++ b/S1API/Entities/NPCs/Downtown/LucyPennington.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Downtown { + /// + /// Lucy Pennington is a customer. + /// She lives in the Downtown region. + /// Lucy is the NPC with blonde haired buns up high! + /// public class LucyPennington : NPC { internal LucyPennington() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "lucy_pennington")) { } diff --git a/S1API/Entities/NPCs/Downtown/PhilipWentworth.cs b/S1API/Entities/NPCs/Downtown/PhilipWentworth.cs index 3d2d2d81..42d715a3 100644 --- a/S1API/Entities/NPCs/Downtown/PhilipWentworth.cs +++ b/S1API/Entities/NPCs/Downtown/PhilipWentworth.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Downtown { + /// + /// Philip Wentworth is a customer. + /// He lives in the Downtown region. + /// Philip is the bald NPC with a goatee! + /// public class PhilipWentworth : NPC { internal PhilipWentworth() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "philip_wentworth")) { } diff --git a/S1API/Entities/NPCs/Downtown/RandyCaulfield.cs b/S1API/Entities/NPCs/Downtown/RandyCaulfield.cs index 8ece0b34..3a8fecca 100644 --- a/S1API/Entities/NPCs/Downtown/RandyCaulfield.cs +++ b/S1API/Entities/NPCs/Downtown/RandyCaulfield.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Downtown { + /// + /// Randy Caulfield is a customer. + /// He lives in the Downtown region. + /// Randy is the NPC wearing a green hat! + /// public class RandyCaulfield : NPC { internal RandyCaulfield() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "randy_caulfield")) { } diff --git a/S1API/Entities/NPCs/IgorRomanovich.cs b/S1API/Entities/NPCs/IgorRomanovich.cs index a5ed262a..4723d905 100644 --- a/S1API/Entities/NPCs/IgorRomanovich.cs +++ b/S1API/Entities/NPCs/IgorRomanovich.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs { + /// + /// Igor Romanovich is a npc. + /// He is Manny's bodyguard. + /// Igor can be found inside the Warehouse! + /// public class IgorRomanovich : NPC { internal IgorRomanovich() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "igor_romanovich")) { } diff --git a/S1API/Entities/NPCs/MannyOakfield.cs b/S1API/Entities/NPCs/MannyOakfield.cs index 5fe76811..403897a4 100644 --- a/S1API/Entities/NPCs/MannyOakfield.cs +++ b/S1API/Entities/NPCs/MannyOakfield.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs { + /// + /// Manny is a NPC. + /// He provides workers to the player. + /// Manny can be found in the Warehouse! + /// public class MannyOakfield : NPC { internal MannyOakfield() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "manny_oakfield")) { } diff --git a/S1API/Entities/NPCs/NPC_LIST.md b/S1API/Entities/NPCs/NPC_LIST.md index 6c223ab2..334576fa 100644 --- a/S1API/Entities/NPCs/NPC_LIST.md +++ b/S1API/Entities/NPCs/NPC_LIST.md @@ -1,10 +1,3 @@ -# NPC List -Current list of NPCs in the game. -Includes which class is associated with the NPC. - -**Last Updated: (v0.3.4f8)** - ---- **manny_oakfield** ScheduleOne.NPCs.CharacterClasses.Fixer --- diff --git a/S1API/Entities/NPCs/Northtown/AlbertHoover.cs b/S1API/Entities/NPCs/Northtown/AlbertHoover.cs index c74ca04e..162bcfb8 100644 --- a/S1API/Entities/NPCs/Northtown/AlbertHoover.cs +++ b/S1API/Entities/NPCs/Northtown/AlbertHoover.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Northtown { + /// + /// Albert Hoover is a supplier. + /// He lives in the Northtown region. + /// Albert is the supplier for weed seeds! + /// public class AlbertHoover : NPC { internal AlbertHoover() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "albert_hoover")) { } diff --git a/S1API/Entities/NPCs/Northtown/AustinSteiner.cs b/S1API/Entities/NPCs/Northtown/AustinSteiner.cs index ff960a88..393ebf90 100644 --- a/S1API/Entities/NPCs/Northtown/AustinSteiner.cs +++ b/S1API/Entities/NPCs/Northtown/AustinSteiner.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Northtown { + /// + /// Austin Steiner is a customer. + /// He lives in the Northtown region. + /// Austin is the NPC with a red/orange afro and black glasses! + /// public class AustinSteiner : NPC { internal AustinSteiner() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "austin_steiner")) { } diff --git a/S1API/Entities/NPCs/Northtown/BenjiColeman.cs b/S1API/Entities/NPCs/Northtown/BenjiColeman.cs index f749c5bc..b0c6528b 100644 --- a/S1API/Entities/NPCs/Northtown/BenjiColeman.cs +++ b/S1API/Entities/NPCs/Northtown/BenjiColeman.cs @@ -7,6 +7,12 @@ namespace S1API.Entities.NPCs.Northtown { + /// + /// Benji Coleman is a dealer. + /// He lives in the Northtown region. + /// Benji lives at the motel in room #2. + /// He is the first dealer the player unlocks! + /// public class BenjiColeman : NPC { internal BenjiColeman() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "benji_coleman")) { } diff --git a/S1API/Entities/NPCs/Northtown/BethPenn.cs b/S1API/Entities/NPCs/Northtown/BethPenn.cs index 3b3ae6d6..e5538920 100644 --- a/S1API/Entities/NPCs/Northtown/BethPenn.cs +++ b/S1API/Entities/NPCs/Northtown/BethPenn.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Northtown { + /// + /// Beth Penn is a customer. + /// She lives in the Northtown region. + /// Beth is the NPC with a blonde bowl cut and wears green glasses! + /// public class BethPenn : NPC { internal BethPenn() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "beth_penn")) { } diff --git a/S1API/Entities/NPCs/Northtown/ChloeBowers.cs b/S1API/Entities/NPCs/Northtown/ChloeBowers.cs index a7e004ed..03ab02b8 100644 --- a/S1API/Entities/NPCs/Northtown/ChloeBowers.cs +++ b/S1API/Entities/NPCs/Northtown/ChloeBowers.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Northtown { + /// + /// Chloe Bowers is a customer. + /// She lives in the Northtown region. + /// Chloe is the NPC with long, straight, red hair! + /// public class ChloeBowers : NPC { internal ChloeBowers() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "chloe_bowers")) { } diff --git a/S1API/Entities/NPCs/Northtown/DonnaMartin.cs b/S1API/Entities/NPCs/Northtown/DonnaMartin.cs index 830201bb..ef38ed01 100644 --- a/S1API/Entities/NPCs/Northtown/DonnaMartin.cs +++ b/S1API/Entities/NPCs/Northtown/DonnaMartin.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Northtown { + /// + /// Donna Martin is a customer. + /// She lives in the Northtown region. + /// Donna is the attendant of the Motel! + /// public class DonnaMartin : NPC { internal DonnaMartin() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "donna_martin")) { } diff --git a/S1API/Entities/NPCs/Northtown/GeraldinePoon.cs b/S1API/Entities/NPCs/Northtown/GeraldinePoon.cs index 7860d411..3b04d209 100644 --- a/S1API/Entities/NPCs/Northtown/GeraldinePoon.cs +++ b/S1API/Entities/NPCs/Northtown/GeraldinePoon.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Northtown { + /// + /// Geraldine Poon is a customer. + /// He lives in the Northtown region. + /// Geraldine is the balding NPC with small gold glasses! + /// public class GeraldinePoon : NPC { internal GeraldinePoon() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "geraldine_poon")) { } diff --git a/S1API/Entities/NPCs/Northtown/JessiWaters.cs b/S1API/Entities/NPCs/Northtown/JessiWaters.cs index d8b32fcc..7ed78aaa 100644 --- a/S1API/Entities/NPCs/Northtown/JessiWaters.cs +++ b/S1API/Entities/NPCs/Northtown/JessiWaters.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Northtown { + /// + /// Jessi Waters is a customer. + /// She lives in the Northtown region. + /// Jessi is the purple haired NPC with face tattoos! + /// public class JessiWaters : NPC { internal JessiWaters() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "jessi_waters")) { } diff --git a/S1API/Entities/NPCs/Northtown/KathyHenderson.cs b/S1API/Entities/NPCs/Northtown/KathyHenderson.cs index 516afb8d..58a9135b 100644 --- a/S1API/Entities/NPCs/Northtown/KathyHenderson.cs +++ b/S1API/Entities/NPCs/Northtown/KathyHenderson.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Northtown { + /// + /// Kathy Henderson is a customer. + /// She lives in the Northtown region. + /// Kathy is the NPC with long blonde hair with bangs! + /// public class KathyHenderson : NPC { internal KathyHenderson() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "kathy_henderson")) { } diff --git a/S1API/Entities/NPCs/Northtown/KyleCooley.cs b/S1API/Entities/NPCs/Northtown/KyleCooley.cs index be282459..b4104f2c 100644 --- a/S1API/Entities/NPCs/Northtown/KyleCooley.cs +++ b/S1API/Entities/NPCs/Northtown/KyleCooley.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Northtown { + /// + /// Kyle Cooley is a customer. + /// He lives in the Northtown region. + /// Kyle is the NPC that works at Taco Ticklers! + /// public class KyleCooley : NPC { internal KyleCooley() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "kyle_cooley")) { } diff --git a/S1API/Entities/NPCs/Northtown/LudwigMeyer.cs b/S1API/Entities/NPCs/Northtown/LudwigMeyer.cs index 46eddc2c..e3b77d8c 100644 --- a/S1API/Entities/NPCs/Northtown/LudwigMeyer.cs +++ b/S1API/Entities/NPCs/Northtown/LudwigMeyer.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Northtown { + /// + /// Ludwig Meyer is a customer. + /// He lives in the Northtown region. + /// Ludwig is the NPC with spiky hair and gold glasses! + /// public class LudwigMeyer : NPC { internal LudwigMeyer() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "ludwig_meyer")) { } diff --git a/S1API/Entities/NPCs/Northtown/MickLubbin.cs b/S1API/Entities/NPCs/Northtown/MickLubbin.cs index 1b86ff16..293e7a80 100644 --- a/S1API/Entities/NPCs/Northtown/MickLubbin.cs +++ b/S1API/Entities/NPCs/Northtown/MickLubbin.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Northtown { + /// + /// Mick Lubbin is a customer. + /// He lives in the Northtown region. + /// Mick is the owner of the pawn shop! + /// public class MickLubbin : NPC { internal MickLubbin() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "mick_lubbin")) { } diff --git a/S1API/Entities/NPCs/Northtown/Ming.cs b/S1API/Entities/NPCs/Northtown/Ming.cs index a9ed1c41..5c5b3e11 100644 --- a/S1API/Entities/NPCs/Northtown/Ming.cs +++ b/S1API/Entities/NPCs/Northtown/Ming.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Northtown { + /// + /// Mrs. Ming is a customer. + /// She lives in the Northtown region. + /// Ming is the NPC that owns the chinese restaurant! + /// public class Ming : NPC { internal Ming() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "ming")) { } diff --git a/S1API/Entities/NPCs/Northtown/PeggyMyers.cs b/S1API/Entities/NPCs/Northtown/PeggyMyers.cs index b9e2ddd1..875983ab 100644 --- a/S1API/Entities/NPCs/Northtown/PeggyMyers.cs +++ b/S1API/Entities/NPCs/Northtown/PeggyMyers.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Northtown { + /// + /// Peggy Myers is a customer. + /// She lives in the Northtown region. + /// Peggy is the NPC with freckles and brown hair pulled back! + /// public class PeggyMyers : NPC { internal PeggyMyers() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "peggy_myers")) { } diff --git a/S1API/Entities/NPCs/Northtown/PeterFile.cs b/S1API/Entities/NPCs/Northtown/PeterFile.cs index efe8c3ad..e2af8748 100644 --- a/S1API/Entities/NPCs/Northtown/PeterFile.cs +++ b/S1API/Entities/NPCs/Northtown/PeterFile.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Northtown { + /// + /// Peter File is a customer. + /// He lives in the Northtown region. + /// Peter is the NPC with a black bowl cut and black glasses! + /// public class PeterFile : NPC { internal PeterFile() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "peter_file")) { } diff --git a/S1API/Entities/NPCs/Northtown/SamThompson.cs b/S1API/Entities/NPCs/Northtown/SamThompson.cs index 40beb60b..d9a49e98 100644 --- a/S1API/Entities/NPCs/Northtown/SamThompson.cs +++ b/S1API/Entities/NPCs/Northtown/SamThompson.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Northtown { + /// + /// Sam Thompson is a customer. + /// He lives in the Northtown region. + /// Sam is the NPC with a green hair and wrinkles! + /// public class SamThompson : NPC { internal SamThompson() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "sam_thompson")) { } diff --git a/S1API/Entities/NPCs/OscarHolland.cs b/S1API/Entities/NPCs/OscarHolland.cs index 41362dc8..5a557110 100644 --- a/S1API/Entities/NPCs/OscarHolland.cs +++ b/S1API/Entities/NPCs/OscarHolland.cs @@ -7,6 +7,10 @@ namespace S1API.Entities.NPCs { + /// + /// Oscar Holland is a NPC. + /// He is a supplier located in the Warehouse! + /// public class OscarHolland : NPC { internal OscarHolland() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "oscar_holland")) { } diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerBailey.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerBailey.cs index 404513a7..4e59e4be 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerBailey.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerBailey.cs @@ -7,6 +7,10 @@ namespace S1API.Entities.NPCs.PoliceOfficers { + /// + /// Officer Bailey is a police officer. + /// He is the bald officer with a swirling mustache! + /// public class OfficerBailey : NPC { internal OfficerBailey() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_bailey")) { } diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerCooper.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerCooper.cs index c9893d5d..e81b6d0c 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerCooper.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerCooper.cs @@ -7,6 +7,10 @@ namespace S1API.Entities.NPCs.PoliceOfficers { + /// + /// Officer Cooper is a police officer. + /// She is the officer with two high black buns and black glasses! + /// public class OfficerCooper : NPC { internal OfficerCooper() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_cooper")) { } diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerGreen.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerGreen.cs index a3bc346e..fd8e3990 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerGreen.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerGreen.cs @@ -7,6 +7,10 @@ namespace S1API.Entities.NPCs.PoliceOfficers { + /// + /// Officer Green is a police officer. + /// She is the officer with light brown hair in a bun! + /// public class OfficerGreen : NPC { internal OfficerGreen() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_green")) { } diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerHoward.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerHoward.cs index 038b2e82..38048808 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerHoward.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerHoward.cs @@ -7,6 +7,10 @@ namespace S1API.Entities.NPCs.PoliceOfficers { + /// + /// Officer Howard is a police officer. + /// He is the officer with a light brown afro and goatee! + /// public class OfficerHoward : NPC { internal OfficerHoward() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_howard")) { } diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerJackson.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerJackson.cs index 8acb6ea4..7af40f28 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerJackson.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerJackson.cs @@ -7,6 +7,10 @@ namespace S1API.Entities.NPCs.PoliceOfficers { + /// + /// Officer Jackson is a police officer. + /// He is the officer with a light brown goatee and police hat! + /// public class OfficerJackson : NPC { internal OfficerJackson() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_jackson")) { } diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerLee.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerLee.cs index a94fe42c..f96dcb4e 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerLee.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerLee.cs @@ -7,6 +7,10 @@ namespace S1API.Entities.NPCs.PoliceOfficers { + /// + /// Officer Lee is a police officer. + /// He is the officer with a button-up shirt and black hair! + /// public class OfficerLee : NPC { internal OfficerLee() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_lee")) { } diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerLopez.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerLopez.cs index e85e22c5..d79d4b38 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerLopez.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerLopez.cs @@ -7,6 +7,10 @@ namespace S1API.Entities.NPCs.PoliceOfficers { + /// + /// Officer Lopez is a police officer. + /// She is the officer with a blue button-up and long black hair! + /// public class OfficerLopez : NPC { internal OfficerLopez() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_lopez")) { } diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerMurphy.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerMurphy.cs index 7d8a66df..61916fe1 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerMurphy.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerMurphy.cs @@ -7,6 +7,10 @@ namespace S1API.Entities.NPCs.PoliceOfficers { + /// + /// Officer Murphy is a police officer. + /// He is the balding officer with grey hair and wrinkles! + /// public class OfficerMurphy : NPC { internal OfficerMurphy() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_murphy")) { } diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerOakley.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerOakley.cs index d444cb58..590b2e74 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerOakley.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerOakley.cs @@ -7,6 +7,10 @@ namespace S1API.Entities.NPCs.PoliceOfficers { + /// + /// Officer Oakley is a police officer. + /// He is the officer with light brown spiky hair and a goatee! + /// public class OfficerOakley : NPC { internal OfficerOakley() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_oakley")) { } diff --git a/S1API/Entities/NPCs/StanCarney.cs b/S1API/Entities/NPCs/StanCarney.cs index 6f3fbe41..017983c5 100644 --- a/S1API/Entities/NPCs/StanCarney.cs +++ b/S1API/Entities/NPCs/StanCarney.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs { + /// + /// Stan Carney is a NPC. + /// He is the NPC that sells weapons. + /// Stan can be found in the Warehouse! + /// public class StanCarney : NPC { internal StanCarney() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "stan_carney")) { } diff --git a/S1API/Entities/NPCs/Suburbia/AlisonKnight.cs b/S1API/Entities/NPCs/Suburbia/AlisonKnight.cs index 3bdf3056..a534cddc 100644 --- a/S1API/Entities/NPCs/Suburbia/AlisonKnight.cs +++ b/S1API/Entities/NPCs/Suburbia/AlisonKnight.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Suburbia { + /// + /// Alison Knight is a customer. + /// She lives in the Suburbia region. + /// Alison is the NPC with long light brown hair! + /// public class AlisonKnight : NPC { internal AlisonKnight() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "alison_knight")) { } diff --git a/S1API/Entities/NPCs/Suburbia/CarlBundy.cs b/S1API/Entities/NPCs/Suburbia/CarlBundy.cs index c5a625d7..e9fcbbb6 100644 --- a/S1API/Entities/NPCs/Suburbia/CarlBundy.cs +++ b/S1API/Entities/NPCs/Suburbia/CarlBundy.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Suburbia { + /// + /// Carl Bundy is a customer. + /// He lives in the Suburbia region. + /// Carl is the NPC with a brown apron! + /// public class CarlBundy : NPC { internal CarlBundy() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "carl_bundy")) { } diff --git a/S1API/Entities/NPCs/Suburbia/ChrisSullivan.cs b/S1API/Entities/NPCs/Suburbia/ChrisSullivan.cs index afdcdde6..5c24211c 100644 --- a/S1API/Entities/NPCs/Suburbia/ChrisSullivan.cs +++ b/S1API/Entities/NPCs/Suburbia/ChrisSullivan.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Suburbia { + /// + /// Chris Sullivan is a customer. + /// He lives in the Suburbia region. + /// Chris is the NPC with black spiky hair and black glasses! + /// public class ChrisSullivan : NPC { internal ChrisSullivan() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "chris_sullivan")) { } diff --git a/S1API/Entities/NPCs/Suburbia/DennisKennedy.cs b/S1API/Entities/NPCs/Suburbia/DennisKennedy.cs index b3c9d0d8..d733d06a 100644 --- a/S1API/Entities/NPCs/Suburbia/DennisKennedy.cs +++ b/S1API/Entities/NPCs/Suburbia/DennisKennedy.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Suburbia { + /// + /// Dennis Kennedy is a customer. + /// He lives in the Suburbia region. + /// Dennis is the NPC with light blonde spiky hair and a thick mustache! + /// public class DennisKennedy : NPC { internal DennisKennedy() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "dennis_kennedy")) { } diff --git a/S1API/Entities/NPCs/Suburbia/HankStevenson.cs b/S1API/Entities/NPCs/Suburbia/HankStevenson.cs index 054b283f..9440e3ec 100644 --- a/S1API/Entities/NPCs/Suburbia/HankStevenson.cs +++ b/S1API/Entities/NPCs/Suburbia/HankStevenson.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Suburbia { + /// + /// Hank Stevenson is a customer. + /// He lives in the Suburbia region. + /// Hank is the balding NPC with greying brown hair and a goatee! + /// public class HankStevenson : NPC { internal HankStevenson() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "hank_stevenson")) { } diff --git a/S1API/Entities/NPCs/Suburbia/HaroldColt.cs b/S1API/Entities/NPCs/Suburbia/HaroldColt.cs index 9c13dd51..e313c440 100644 --- a/S1API/Entities/NPCs/Suburbia/HaroldColt.cs +++ b/S1API/Entities/NPCs/Suburbia/HaroldColt.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Suburbia { + /// + /// Harold Colt is a customer. + /// He lives in the Suburbia region. + /// Harold is the NPC with grey spiky hair and wrinkles! + /// public class HaroldColt : NPC { internal HaroldColt() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "harold_colt")) { } diff --git a/S1API/Entities/NPCs/Suburbia/JackKnight.cs b/S1API/Entities/NPCs/Suburbia/JackKnight.cs index 3e5e5c2b..921ef9d2 100644 --- a/S1API/Entities/NPCs/Suburbia/JackKnight.cs +++ b/S1API/Entities/NPCs/Suburbia/JackKnight.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Suburbia { + /// + /// Jack Knight is a customer. + /// He lives in the Suburbia region. + /// Jack is the balding NPC with small gold glasses! + /// public class JackKnight : NPC { internal JackKnight() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "jack_knight")) { } diff --git a/S1API/Entities/NPCs/Suburbia/JackieStevenson.cs b/S1API/Entities/NPCs/Suburbia/JackieStevenson.cs index d5b0bea9..ca504988 100644 --- a/S1API/Entities/NPCs/Suburbia/JackieStevenson.cs +++ b/S1API/Entities/NPCs/Suburbia/JackieStevenson.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Suburbia { + /// + /// Jackie Stevenson is a customer. + /// He lives in the Suburbia region. + /// Jackie is the NPC with short brown hair and light freckles! + /// public class JackieStevenson : NPC { internal JackieStevenson() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "jackie_stevenson")) { } diff --git a/S1API/Entities/NPCs/Suburbia/JeremyWilkinson.cs b/S1API/Entities/NPCs/Suburbia/JeremyWilkinson.cs index d2b24f9d..4a7ebe04 100644 --- a/S1API/Entities/NPCs/Suburbia/JeremyWilkinson.cs +++ b/S1API/Entities/NPCs/Suburbia/JeremyWilkinson.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Suburbia { + /// + /// Jeremy Wilkinson is a customer. + /// He lives in the Suburbia region. + /// Jeremy is the NPC that works at Hyland Auto! + /// public class JeremyWilkinson : NPC { internal JeremyWilkinson() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "jeremy_wilkinson")) { } diff --git a/S1API/Entities/NPCs/Suburbia/KarenKennedy.cs b/S1API/Entities/NPCs/Suburbia/KarenKennedy.cs index f775dfc4..0df4bccd 100644 --- a/S1API/Entities/NPCs/Suburbia/KarenKennedy.cs +++ b/S1API/Entities/NPCs/Suburbia/KarenKennedy.cs @@ -7,6 +7,12 @@ namespace S1API.Entities.NPCs.Suburbia { + /// + /// Karen Kennedy is a customer. + /// She lives in the Suburbia region. + /// Karen is the NPC with wavy blonde hair and purple eyelids! + /// She can be found at the casino upstairs when it's open. + /// public class KarenKennedy : NPC { internal KarenKennedy() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "karen_kennedy")) { } diff --git a/S1API/Entities/NPCs/Suburbia/WeiLong.cs b/S1API/Entities/NPCs/Suburbia/WeiLong.cs index 617a5f50..bec8f78f 100644 --- a/S1API/Entities/NPCs/Suburbia/WeiLong.cs +++ b/S1API/Entities/NPCs/Suburbia/WeiLong.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Suburbia { + /// + /// Wei Long is a dealer. + /// He lives in the Suburbia region. + /// Wei is the dealer with a black bowl cut and gold glasses! + /// public class WeiLong : NPC { internal WeiLong() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "wei_long")) { } diff --git a/S1API/Entities/NPCs/UncleNelson.cs b/S1API/Entities/NPCs/UncleNelson.cs index 31ece8c8..15e6b06b 100644 --- a/S1API/Entities/NPCs/UncleNelson.cs +++ b/S1API/Entities/NPCs/UncleNelson.cs @@ -7,6 +7,10 @@ namespace S1API.Entities.NPCs { + /// + /// Uncle Nelson is a NPC. + /// He is the uncle of the main character! + /// public class UncleNelson : NPC { internal UncleNelson() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "uncle_nelson")) { } diff --git a/S1API/Entities/NPCs/Uptown/FionaHancock.cs b/S1API/Entities/NPCs/Uptown/FionaHancock.cs index d8b01fc6..59a3b968 100644 --- a/S1API/Entities/NPCs/Uptown/FionaHancock.cs +++ b/S1API/Entities/NPCs/Uptown/FionaHancock.cs @@ -8,6 +8,11 @@ namespace S1API.Entities.NPCs.Uptown { + /// + /// Fiona Hancock is a customer. + /// She lives in the Uptown region. + /// Fiona is the NPC with light brown buns and green glasses! + /// public class FionaHancock : NPC { internal FionaHancock() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "fiona_hancock")) { } diff --git a/S1API/Entities/NPCs/Uptown/HerbertBleuball.cs b/S1API/Entities/NPCs/Uptown/HerbertBleuball.cs index a97faa9a..0361d983 100644 --- a/S1API/Entities/NPCs/Uptown/HerbertBleuball.cs +++ b/S1API/Entities/NPCs/Uptown/HerbertBleuball.cs @@ -8,6 +8,11 @@ namespace S1API.Entities.NPCs.Uptown { + /// + /// Herbert Bleuball is a customer. + /// He lives in the Uptown region. + /// Herbert is the NPC that owns Bleuball's Boutique! + /// public class HerbertBleuball : NPC { internal HerbertBleuball() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "herbert_bleuball")) { } diff --git a/S1API/Entities/NPCs/Uptown/JenHeard.cs b/S1API/Entities/NPCs/Uptown/JenHeard.cs index 59a04042..d2ffe6b5 100644 --- a/S1API/Entities/NPCs/Uptown/JenHeard.cs +++ b/S1API/Entities/NPCs/Uptown/JenHeard.cs @@ -8,6 +8,11 @@ namespace S1API.Entities.NPCs.Uptown { + /// + /// Jen Heard is a customer. + /// She lives in the Uptown region. + /// Jen is the NPC with low orange buns! + /// public class JenHeard : NPC { internal JenHeard() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "jen_heard")) { } diff --git a/S1API/Entities/NPCs/Uptown/LeoRivers.cs b/S1API/Entities/NPCs/Uptown/LeoRivers.cs index 6be3b15a..6f22c063 100644 --- a/S1API/Entities/NPCs/Uptown/LeoRivers.cs +++ b/S1API/Entities/NPCs/Uptown/LeoRivers.cs @@ -8,6 +8,11 @@ namespace S1API.Entities.NPCs.Uptown { + /// + /// Leo Rivers is a dealer. + /// He lives in the Uptown region. + /// Leo is the dealer wearing a black hat and gold shades! + /// public class LeoRivers : NPC { internal LeoRivers() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "leo_rivers")) { } diff --git a/S1API/Entities/NPCs/Uptown/LilyTurner.cs b/S1API/Entities/NPCs/Uptown/LilyTurner.cs index a0795802..a2d6b77f 100644 --- a/S1API/Entities/NPCs/Uptown/LilyTurner.cs +++ b/S1API/Entities/NPCs/Uptown/LilyTurner.cs @@ -8,6 +8,11 @@ namespace S1API.Entities.NPCs.Uptown { + /// + /// Lily Turner is a customer. + /// She lives in the Uptown region. + /// Lily is the NPC with long brown hair with bangs! + /// public class LilyTurner : NPC { internal LilyTurner() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "lily_turner")) { } diff --git a/S1API/Entities/NPCs/Uptown/MichaelBoog.cs b/S1API/Entities/NPCs/Uptown/MichaelBoog.cs index 6fa190ad..d8d160c2 100644 --- a/S1API/Entities/NPCs/Uptown/MichaelBoog.cs +++ b/S1API/Entities/NPCs/Uptown/MichaelBoog.cs @@ -8,6 +8,11 @@ namespace S1API.Entities.NPCs.Uptown { + /// + /// Michael Boog is a customer. + /// He lives in the Uptown region. + /// Michael is the NPC with a bright blue flat cap and black glasses! + /// public class MichaelBoog : NPC { internal MichaelBoog() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "michael_boog")) { } diff --git a/S1API/Entities/NPCs/Uptown/PearlMoore.cs b/S1API/Entities/NPCs/Uptown/PearlMoore.cs index b1b601e1..902efae0 100644 --- a/S1API/Entities/NPCs/Uptown/PearlMoore.cs +++ b/S1API/Entities/NPCs/Uptown/PearlMoore.cs @@ -8,6 +8,11 @@ namespace S1API.Entities.NPCs.Uptown { + /// + /// Pearl Moore is a customer. + /// She lives in the Uptown region. + /// Pearl is the NPC with long white hair with bangs! + /// public class PearlMoore : NPC { internal PearlMoore() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "pearl_moore")) { } diff --git a/S1API/Entities/NPCs/Uptown/RayHoffman.cs b/S1API/Entities/NPCs/Uptown/RayHoffman.cs index c8123084..0716d33e 100644 --- a/S1API/Entities/NPCs/Uptown/RayHoffman.cs +++ b/S1API/Entities/NPCs/Uptown/RayHoffman.cs @@ -8,6 +8,11 @@ namespace S1API.Entities.NPCs.Uptown { + /// + /// Ray Hoffman is a customer. + /// He lives in the Uptown region. + /// Ray is the NPC that owns Ray's Realty! + /// public class RayHoffman : NPC { internal RayHoffman() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "ray_hoffman")) { } diff --git a/S1API/Entities/NPCs/Uptown/TobiasWentworth.cs b/S1API/Entities/NPCs/Uptown/TobiasWentworth.cs index 8f8110fa..b4950553 100644 --- a/S1API/Entities/NPCs/Uptown/TobiasWentworth.cs +++ b/S1API/Entities/NPCs/Uptown/TobiasWentworth.cs @@ -8,6 +8,11 @@ namespace S1API.Entities.NPCs.Uptown { + /// + /// Tobias Wentworth is a customer. + /// He lives in the Uptown region. + /// Tobias is the balding NPC with extremely light brown hair and small black glasses! + /// public class TobiasWentworth : NPC { internal TobiasWentworth() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "tobias_wentworth")) { } diff --git a/S1API/Entities/NPCs/Uptown/WalterCussler.cs b/S1API/Entities/NPCs/Uptown/WalterCussler.cs index 73768430..ee6b726e 100644 --- a/S1API/Entities/NPCs/Uptown/WalterCussler.cs +++ b/S1API/Entities/NPCs/Uptown/WalterCussler.cs @@ -8,6 +8,11 @@ namespace S1API.Entities.NPCs.Uptown { + /// + /// Walter Cussler is a customer. + /// He lives in the Uptown region. + /// Walter is the NPC with white hair and dressed as a priest! + /// public class WalterCussler : NPC { internal WalterCussler() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "walter_cussler")) { } diff --git a/S1API/Entities/NPCs/Westville/CharlesRowland.cs b/S1API/Entities/NPCs/Westville/CharlesRowland.cs index 56a42b80..a82f5374 100644 --- a/S1API/Entities/NPCs/Westville/CharlesRowland.cs +++ b/S1API/Entities/NPCs/Westville/CharlesRowland.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Westville { + /// + /// Charles Rowland is a customer. + /// He lives in the Westville region. + /// Charles is the bald NPC with black glasses! + /// public class CharlesRowland : NPC { internal CharlesRowland() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "charles_rowland")) { } diff --git a/S1API/Entities/NPCs/Westville/DeanWebster.cs b/S1API/Entities/NPCs/Westville/DeanWebster.cs index 4136830e..00d9da03 100644 --- a/S1API/Entities/NPCs/Westville/DeanWebster.cs +++ b/S1API/Entities/NPCs/Westville/DeanWebster.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Westville { + /// + /// Dean Webster is a customer. + /// He lives in the Westville region. + /// Dean is the NPC that owns Top Tattoo! + /// public class DeanWebster : NPC { internal DeanWebster() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "dean_webster")) { } diff --git a/S1API/Entities/NPCs/Westville/DorisLubbin.cs b/S1API/Entities/NPCs/Westville/DorisLubbin.cs index bdf8f983..a30fd86a 100644 --- a/S1API/Entities/NPCs/Westville/DorisLubbin.cs +++ b/S1API/Entities/NPCs/Westville/DorisLubbin.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Westville { + /// + /// Doris Lubbin is a customer. + /// She lives in the Westville region. + /// Doris is the NPC with light brown, wavy hair and black glasses! + /// public class DorisLubbin : NPC { internal DorisLubbin() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "doris_lubbin")) { } diff --git a/S1API/Entities/NPCs/Westville/GeorgeGreene.cs b/S1API/Entities/NPCs/Westville/GeorgeGreene.cs index bb106e07..0aa2e27a 100644 --- a/S1API/Entities/NPCs/Westville/GeorgeGreene.cs +++ b/S1API/Entities/NPCs/Westville/GeorgeGreene.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Westville { + /// + /// George Greene is a customer. + /// He lives in the Westville region. + /// George is the NPC with light brown, spiky hair and gold glasses! + /// public class GeorgeGreene : NPC { internal GeorgeGreene() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "george_greene")) { } diff --git a/S1API/Entities/NPCs/Westville/JerryMontero.cs b/S1API/Entities/NPCs/Westville/JerryMontero.cs index 309d49a7..8100e54c 100644 --- a/S1API/Entities/NPCs/Westville/JerryMontero.cs +++ b/S1API/Entities/NPCs/Westville/JerryMontero.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Westville { + /// + /// Jerry Montero is a customer. + /// He lives in the Westville region. + /// Jerry is the NPC with a green hat and black glasses! + /// public class JerryMontero : NPC { internal JerryMontero() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "jerry_montero")) { } diff --git a/S1API/Entities/NPCs/Westville/JoyceBall.cs b/S1API/Entities/NPCs/Westville/JoyceBall.cs index ef36f7d5..83452668 100644 --- a/S1API/Entities/NPCs/Westville/JoyceBall.cs +++ b/S1API/Entities/NPCs/Westville/JoyceBall.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Westville { + /// + /// Joyce Ball is a customer. + /// She lives in the Westville region. + /// Joyce is the NPC with light brown hair and wrinkles! + /// public class JoyceBall : NPC { internal JoyceBall() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "joyce_ball")) { } diff --git a/S1API/Entities/NPCs/Westville/KeithWagner.cs b/S1API/Entities/NPCs/Westville/KeithWagner.cs index b98c273e..98b0b302 100644 --- a/S1API/Entities/NPCs/Westville/KeithWagner.cs +++ b/S1API/Entities/NPCs/Westville/KeithWagner.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Westville { + /// + /// Keith Wagner is a customer. + /// He lives in the Westville region. + /// Keith is the NPC with blonde spiky hair and always angry! + /// public class KeithWagner : NPC { internal KeithWagner() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "keith_wagner")) { } diff --git a/S1API/Entities/NPCs/Westville/KimDelaney.cs b/S1API/Entities/NPCs/Westville/KimDelaney.cs index 341ab65d..abbc07a4 100644 --- a/S1API/Entities/NPCs/Westville/KimDelaney.cs +++ b/S1API/Entities/NPCs/Westville/KimDelaney.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Westville { + /// + /// Kim Delaney is a customer. + /// She lives in the Westville region. + /// Kim is the NPC with long, black hair with bangs! + /// public class KimDelaney : NPC { internal KimDelaney() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "kim_delaney")) { } diff --git a/S1API/Entities/NPCs/Westville/MegCooley.cs b/S1API/Entities/NPCs/Westville/MegCooley.cs index 6bc4b444..b60df006 100644 --- a/S1API/Entities/NPCs/Westville/MegCooley.cs +++ b/S1API/Entities/NPCs/Westville/MegCooley.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Westville { + /// + /// Meg Cooley is a customer. + /// She lives in the Westville region. + /// Meg is the npc with a mustard yellow bowl cut hairstyle! + /// public class MegCooley : NPC { internal MegCooley() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "meg_cooley")) { } diff --git a/S1API/Entities/NPCs/Westville/MollyPresley.cs b/S1API/Entities/NPCs/Westville/MollyPresley.cs index f81cf549..7f55b99f 100644 --- a/S1API/Entities/NPCs/Westville/MollyPresley.cs +++ b/S1API/Entities/NPCs/Westville/MollyPresley.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Westville { + /// + /// Molly Presley is a dealer. + /// She lives in the Westville region. + /// Molly is the dealer with gold shades and a red backward cap! + /// public class MollyPresley : NPC { internal MollyPresley() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "molly_presley")) { } diff --git a/S1API/Entities/NPCs/Westville/ShirleyWatts.cs b/S1API/Entities/NPCs/Westville/ShirleyWatts.cs index 0883a1f3..705bb0a2 100644 --- a/S1API/Entities/NPCs/Westville/ShirleyWatts.cs +++ b/S1API/Entities/NPCs/Westville/ShirleyWatts.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Westville { + /// + /// Shirley Watts is a supplier. + /// She lives in the Westville region. + /// Shirley is the supplier for pseudo! + /// public class ShirleyWatts : NPC { internal ShirleyWatts() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "shirley_watts")) { } diff --git a/S1API/Entities/NPCs/Westville/TrentSherman.cs b/S1API/Entities/NPCs/Westville/TrentSherman.cs index 2b099b37..e46f1c2b 100644 --- a/S1API/Entities/NPCs/Westville/TrentSherman.cs +++ b/S1API/Entities/NPCs/Westville/TrentSherman.cs @@ -7,6 +7,11 @@ namespace S1API.Entities.NPCs.Westville { + /// + /// Trent Sherman is a customer. + /// He lives in the Westville region. + /// Trent is the NPC with short black hair and dark-colored skin! + /// public class TrentSherman : NPC { internal TrentSherman() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "trent_sherman")) { } diff --git a/S1API/GameTime/Day.cs b/S1API/GameTime/Day.cs index 61311920..38b2fa45 100644 --- a/S1API/GameTime/Day.cs +++ b/S1API/GameTime/Day.cs @@ -5,12 +5,39 @@ /// public enum Day { + /// + /// Represents the first day of the week. + /// Monday, + + /// + /// Represents the second day of the week. + /// Tuesday, + + /// + /// Represents the third day of the week. + /// Wednesday, + + /// + /// Represents the fourth day of the week. + /// Thursday, + + /// + /// Represents the fifth day of the week. + /// Friday, + + /// + /// Represents the sixth day of the week. + /// Saturday, + + /// + /// Represents the seventh day of the week. + /// Sunday } } \ No newline at end of file diff --git a/S1API/Internal/Abstraction/EventHelper.cs b/S1API/Internal/Abstraction/EventHelper.cs index 1dd94e81..900eeaee 100644 --- a/S1API/Internal/Abstraction/EventHelper.cs +++ b/S1API/Internal/Abstraction/EventHelper.cs @@ -36,7 +36,7 @@ internal static void AddListener(Action listener, UnityEvent unityEvent) /// The event you want to unsubscribe from. internal static void RemoveListener(Action listener, UnityEvent unityEvent) { - SubscribedActions.TryGetValue(listener, out UnityAction wrappedAction); + SubscribedActions.TryGetValue(listener, out UnityAction? wrappedAction); SubscribedActions.Remove(listener); unityEvent.RemoveListener(wrappedAction); } diff --git a/S1API/Internal/Abstraction/Saveable.cs b/S1API/Internal/Abstraction/Saveable.cs index b40c61aa..7ef1ff00 100644 --- a/S1API/Internal/Abstraction/Saveable.cs +++ b/S1API/Internal/Abstraction/Saveable.cs @@ -33,7 +33,7 @@ internal virtual void LoadInternal(string folderPath) FieldInfo[] saveableFields = GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo saveableField in saveableFields) { - SaveableField saveableFieldAttribute = saveableField.GetCustomAttribute(); + SaveableField? saveableFieldAttribute = saveableField.GetCustomAttribute(); if (saveableFieldAttribute == null) continue; @@ -68,7 +68,7 @@ internal virtual void SaveInternal(string folderPath, ref List extraSave FieldInfo[] saveableFields = ReflectionUtils.GetAllFields(GetType(), BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo saveableField in saveableFields) { - SaveableField saveableFieldAttribute = saveableField.GetCustomAttribute(); + SaveableField? saveableFieldAttribute = saveableField.GetCustomAttribute(); if (saveableFieldAttribute == null) continue; @@ -78,7 +78,7 @@ internal virtual void SaveInternal(string folderPath, ref List extraSave string saveDataPath = Path.Combine(folderPath, saveFileName); - object value = saveableField.GetValue(this); + object? value = saveableField.GetValue(this); if (value == null) // Remove the save if the field is null File.Delete(saveDataPath); diff --git a/S1API/Internal/Patches/NPCPatches.cs b/S1API/Internal/Patches/NPCPatches.cs index 9fc21df5..db28df08 100644 --- a/S1API/Internal/Patches/NPCPatches.cs +++ b/S1API/Internal/Patches/NPCPatches.cs @@ -42,7 +42,10 @@ private static void NPCsLoadersLoad(S1Loaders.NPCsLoader __instance, string main { foreach (Type type in ReflectionUtils.GetDerivedClasses()) { - NPC customNPC = (NPC)Activator.CreateInstance(type, true); + NPC? customNPC = (NPC)Activator.CreateInstance(type, true)!; + if (customNPC == null) + throw new Exception($"Unable to create instance of {type.FullName}!"); + NPCs.Add(customNPC); // We skip any S1API NPCs, as they are base NPC wrappers. @@ -73,7 +76,7 @@ private static void NPCStart(S1NPCs.NPC __instance) => [HarmonyPatch(typeof(S1NPCs.NPC), "WriteData")] [HarmonyPostfix] private static void NPCWriteData(S1NPCs.NPC __instance, string parentFolderPath, ref List __result) => - NPCs.FirstOrDefault(npc => npc.S1NPC == __instance)?.SaveInternal(parentFolderPath, ref __result); + NPCs.FirstOrDefault(npc => npc.IsCustomNPC && npc.S1NPC == __instance)?.SaveInternal(parentFolderPath, ref __result); /// /// Patching performed for when an NPC is destroyed. diff --git a/S1API/Internal/Patches/PhoneAppPatches.cs b/S1API/Internal/Patches/PhoneAppPatches.cs index 30804bfb..9c9bf913 100644 --- a/S1API/Internal/Patches/PhoneAppPatches.cs +++ b/S1API/Internal/Patches/PhoneAppPatches.cs @@ -15,6 +15,7 @@ namespace S1API.Internal.Patches #endif internal static class PhoneAppPatches { + // TODO (@omar-akermi): Can you look into if this is still needed pls? private static bool _loaded = false; /// diff --git a/S1API/Internal/Patches/QuestPatches.cs b/S1API/Internal/Patches/QuestPatches.cs index 6e9fd49a..53b7e295 100644 --- a/S1API/Internal/Patches/QuestPatches.cs +++ b/S1API/Internal/Patches/QuestPatches.cs @@ -59,8 +59,8 @@ private static void QuestsLoaderLoad(S1Loaders.QuestsLoader __instance, string m string[] questDirectories = Directory.GetDirectories(mainPath) .Select(Path.GetFileName) - .Where(directory => directory.StartsWith("Quest_")) - .ToArray(); + .Where(directory => directory != null && directory.StartsWith("Quest_")) + .ToArray()!; foreach (string questDirectory in questDirectories) { diff --git a/S1API/Internal/Utils/ButtonListener.cs b/S1API/Internal/Utils/ButtonListener.cs index 2174930f..8f8d6ab3 100644 --- a/S1API/Internal/Utils/ButtonListener.cs +++ b/S1API/Internal/Utils/ButtonListener.cs @@ -5,6 +5,10 @@ namespace S1API.Internal.Utils { + /// + /// Utility class for managing UI Buttons. + /// TODO (@omar-akermi): Is this intended to be internal instead of public?? + /// public static class ButtonUtils { /// @@ -37,7 +41,7 @@ public static void ClearListeners(Button button) /// /// Enables the button and optionally updates the label. /// - public static void Enable(Button button, Text label = null, string text = null) + public static void Enable(Button button, Text? label = null, string? text = null) { if (button != null) button.interactable = true; if (label != null && !string.IsNullOrEmpty(text)) label.text = text; @@ -46,7 +50,7 @@ public static void Enable(Button button, Text label = null, string text = null) /// /// Disables the button and optionally updates the label. /// - public static void Disable(Button button, Text label = null, string text = null) + public static void Disable(Button button, Text? label = null, string? text = null) { if (button != null) button.interactable = false; if (label != null && !string.IsNullOrEmpty(text)) label.text = text; diff --git a/S1API/Internal/Utils/ImageUtils.cs b/S1API/Internal/Utils/ImageUtils.cs index 1f072b6f..8d82eb5e 100644 --- a/S1API/Internal/Utils/ImageUtils.cs +++ b/S1API/Internal/Utils/ImageUtils.cs @@ -7,6 +7,10 @@ namespace S1API.Internal.Utils { + /// + /// A utility class to assist with loading images into the game. + /// Useful for icons such as on phone apps, custom NPCs, quests, etc. + /// public static class ImageUtils { /// @@ -16,7 +20,7 @@ public static class ImageUtils /// /// A Sprite object representing the loaded image, or null if the image could not be loaded or the file does not exist. /// - public static Sprite LoadImage(string fileName) + public static Sprite? LoadImage(string fileName) { string fullPath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) ?? string.Empty, fileName); if (!File.Exists(fullPath)) diff --git a/S1API/Internal/Utils/RandomUtils.cs b/S1API/Internal/Utils/RandomUtils.cs index e8d18480..f57dc030 100644 --- a/S1API/Internal/Utils/RandomUtils.cs +++ b/S1API/Internal/Utils/RandomUtils.cs @@ -16,7 +16,7 @@ public static class RandomUtils public static T PickOne(this IList list) { if (list == null || list.Count == 0) - return default; + return default!; return list[UnityEngine.Random.Range(0, list.Count)]; } @@ -31,8 +31,8 @@ public static T PickOne(this IList list) /// A randomly selected item that satisfies the condition, or the default value of the type if no valid item is found. public static T PickUnique(this IList list, Func isDuplicate, int maxTries = 10) { - if (list == null || list.Count == 0) - return default; + if (list.Count == 0) + return default!; for (int i = 0; i < maxTries; i++) { @@ -41,7 +41,7 @@ public static T PickUnique(this IList list, Func isDuplicate, int return item; } - return default; + return default!; } /// @@ -53,7 +53,9 @@ public static T PickUnique(this IList list, Func isDuplicate, int /// A list containing the selected random items, or an empty list if the input list is null or empty. public static List PickMany(this IList list, int count) { - if (list == null || list.Count == 0) return new List(); + if (list.Count == 0) + return new List(); + var copy = new List(list); var result = new List(); diff --git a/S1API/Internal/Utils/ReflectionUtils.cs b/S1API/Internal/Utils/ReflectionUtils.cs index ff22e152..664c6e7d 100644 --- a/S1API/Internal/Utils/ReflectionUtils.cs +++ b/S1API/Internal/Utils/ReflectionUtils.cs @@ -19,12 +19,12 @@ internal static List GetDerivedClasses() { List derivedClasses = new List(); Assembly[] applicableAssemblies = AppDomain.CurrentDomain.GetAssemblies() - .Where(assembly => !assembly.FullName.StartsWith("System") && - !assembly.FullName.StartsWith("Unity") && - !assembly.FullName.StartsWith("Il2Cpp") && - !assembly.FullName.StartsWith("mscorlib") && - !assembly.FullName.StartsWith("Mono.") && - !assembly.FullName.StartsWith("netstandard")) + .Where(assembly => !assembly.FullName!.StartsWith("System") && + !assembly.FullName!.StartsWith("Unity") && + !assembly.FullName!.StartsWith("Il2Cpp") && + !assembly.FullName!.StartsWith("mscorlib") && + !assembly.FullName!.StartsWith("Mono.") && + !assembly.FullName!.StartsWith("netstandard")) .ToArray(); foreach (Assembly assembly in applicableAssemblies) derivedClasses.AddRange(assembly.GetTypes() diff --git a/S1API/Items/ItemCategory.cs b/S1API/Items/ItemCategory.cs index 483a6ed2..a4e88df8 100644 --- a/S1API/Items/ItemCategory.cs +++ b/S1API/Items/ItemCategory.cs @@ -5,17 +5,66 @@ /// public enum ItemCategory { + /// + /// Represents items such as Cocaine, Weed, etc. + /// Oddly, SpeedGrow is in this category as of (v0.3.4f8). + /// Product, + + /// + /// Represents items such as Baggies, Bricks, Jars, etc. + /// Packaging, + + /// + /// Represents items such as Soil, Fertilizer, Pots, etc. + /// Growing, + + /// + /// Represents equipment tools such as the clippers. + /// Oddly, trash bags is in this category as of (v0.3.4f8). + /// Tools, + + /// + /// Represents items such as TV, Trash Can, Bed, etc. + /// Furniture, + + /// + /// Represents items such as Floor Lamps, Halogen Lights, etc. + /// Lighting, + + /// + /// Represents cash-based items. + /// Cash, + + /// + /// Represents items such as Cuke, Energy Drink, etc. + /// Consumable, + + /// + /// Represents items such as Drying Rack, Brick Press, Mixing Station, etc. + /// Equipment, + + /// + /// Represents items such as Acid, Banana, Chili, etc. + /// Ingredient, + + /// + /// Represents items such as GoldBar, WallClock, WoodSign, etc. + /// Decoration, + + /// + /// Represents clothing items. + /// Clothing } } \ No newline at end of file diff --git a/S1API/Leveling/Rank.cs b/S1API/Leveling/Rank.cs index 1582ee51..9144b28f 100644 --- a/S1API/Leveling/Rank.cs +++ b/S1API/Leveling/Rank.cs @@ -5,16 +5,59 @@ /// public enum Rank { + /// + /// Represents the first rank for the player. + /// StreetRat, + + /// + /// Represents the second rank for the player. + /// Hoodlum, + + /// + /// Represents the third rank for the player. + /// Peddler, + + /// + /// Represents the fourth rank for the player. + /// Hustler, + + /// + /// Represents the fifth rank for the player. + /// Bagman, + + /// + /// Represents the sixth rank for the player. + /// Enforcer, + + /// + /// Represents the seventh rank for the player. + /// ShotCaller, + + /// + /// Represents the eighth rank for the player. + /// BlockBoss, + + /// + /// Represents the ninth rank for the player. + /// Underlord, + + /// + /// Represents the tenth rank for the player. + /// Baron, + + /// + /// Represents the eleventh rank for the player. + /// Kingpin } } \ No newline at end of file diff --git a/S1API/Messaging/Response.cs b/S1API/Messaging/Response.cs index 97294cfb..1e9028c6 100644 --- a/S1API/Messaging/Response.cs +++ b/S1API/Messaging/Response.cs @@ -1,4 +1,4 @@ -#if (IL2CPP) +#if (IL2CPP) using S1Messaging = Il2CppScheduleOne.Messaging; #elif (MONO) using S1Messaging = ScheduleOne.Messaging; diff --git a/S1API/PhoneApp/MyAwesomeApp.cs b/S1API/PhoneApp/MyAwesomeApp.cs index 54ef4495..31d3c30f 100644 --- a/S1API/PhoneApp/MyAwesomeApp.cs +++ b/S1API/PhoneApp/MyAwesomeApp.cs @@ -5,13 +5,15 @@ namespace S1API.PhoneApp { - /// - /// Defines the MyAwesomeApp, a specialized application integrated into an in-game phone system. - /// - /// - /// This class leverages the PhoneApp framework to specify application-specific properties like name, title, - /// icon label, and icon file name. It also overrides the method for defining the user interface layout upon creation. - /// + // TODO(@omar-akermi): Can we move this into markdown pls <3 + + // /// + // /// Defines the MyAwesomeApp, a specialized application integrated into an in-game phone system. + // /// + // /// + // /// This class leverages the PhoneApp framework to specify application-specific properties like name, title, + // /// icon label, and icon file name. It also overrides the method for defining the user interface layout upon creation. + // /// /* public class MyAwesomeApp : PhoneApp { diff --git a/S1API/PhoneApp/PhoneApp.cs b/S1API/PhoneApp/PhoneApp.cs index 44385db8..7f59e4e7 100644 --- a/S1API/PhoneApp/PhoneApp.cs +++ b/S1API/PhoneApp/PhoneApp.cs @@ -1,16 +1,8 @@ -#if IL2CPP -using UnityEngine; -using UnityEngine.UI; -using UnityEngine.Events; -#elif MONO -using UnityEngine; -using UnityEngine.UI; -using UnityEngine.Events; -#endif - -using System.Collections; +using System.Collections; using System.IO; using MelonLoader; +using UnityEngine; +using UnityEngine.UI; using Object = UnityEngine.Object; using MelonLoader.Utils; using S1API.Internal.Abstraction; @@ -27,27 +19,31 @@ namespace S1API.PhoneApp /// public abstract class PhoneApp : Registerable { + /// + /// INTERNAL: A dedicated logger for all custom phone apps. + /// protected static readonly MelonLogger.Instance LoggerInstance = new MelonLogger.Instance("PhoneApp"); /// /// The player object in the scene. /// - protected GameObject Player; + private GameObject? _player; /// /// The in-game UI panel representing the app. /// - protected GameObject AppPanel; + private GameObject? _appPanel; + // TODO (@omar-akermi): Can you look into if this is still needed pls? /// /// Whether the app was successfully created. /// - protected bool AppCreated; + private bool _appCreated; /// /// Whether the app icon was already modified. /// - protected bool IconModified; + private bool _iconModified; /// /// Unique GameObject name of the app (e.g. "SilkroadApp"). @@ -58,7 +54,7 @@ public abstract class PhoneApp : Registerable /// The title shown at the top of the app UI. /// protected abstract string AppTitle { get; } - + /// /// The label shown under the app icon on the home screen. /// @@ -88,14 +84,14 @@ protected override void OnCreated() /// protected override void OnDestroyed() { - if (AppPanel != null) + if (_appPanel != null) { - Object.Destroy(AppPanel); - AppPanel = null; + Object.Destroy(_appPanel); + _appPanel = null; } - AppCreated = false; - IconModified = false; + _appCreated = false; + _iconModified = false; } /// @@ -105,8 +101,8 @@ private IEnumerator InitApp() { yield return new WaitForSeconds(5f); - Player = GameObject.Find("Player_Local"); - if (Player == null) + _player = GameObject.Find("Player_Local"); + if (_player == null) { LoggerInstance.Error("Player_Local not found."); yield break; @@ -122,8 +118,8 @@ private IEnumerator InitApp() Transform existingApp = appsCanvas.transform.Find(AppName); if (existingApp != null) { - AppPanel = existingApp.gameObject; - SetupExistingAppPanel(AppPanel); + _appPanel = existingApp.gameObject; + SetupExistingAppPanel(_appPanel); } else { @@ -134,10 +130,10 @@ private IEnumerator InitApp() yield break; } - AppPanel = Object.Instantiate(templateApp.gameObject, appsCanvas.transform); - AppPanel.name = AppName; + _appPanel = Object.Instantiate(templateApp.gameObject, appsCanvas.transform); + _appPanel.name = AppName; - Transform containerTransform = AppPanel.transform.Find("Container"); + Transform containerTransform = _appPanel.transform.Find("Container"); if (containerTransform != null) { GameObject container = containerTransform.gameObject; @@ -145,14 +141,14 @@ private IEnumerator InitApp() OnCreatedUI(container); } - AppCreated = true; + _appCreated = true; } - AppPanel.SetActive(true); + _appPanel.SetActive(true); - if (!IconModified) + if (!_iconModified) { - IconModified = ModifyAppIcon(IconLabel, IconFileName); + _iconModified = ModifyAppIcon(IconLabel, IconFileName); } } @@ -173,7 +169,7 @@ private void SetupExistingAppPanel(GameObject panel) } } - AppCreated = true; + _appCreated = true; } private void ClearContainer(GameObject container) @@ -201,7 +197,7 @@ private bool ModifyAppIcon(string labelText, string fileName) return false; } - Transform lastIcon = parent.transform.childCount > 0 ? parent.transform.GetChild(parent.transform.childCount - 1) : null; + Transform? lastIcon = parent.transform.childCount > 0 ? parent.transform.GetChild(parent.transform.childCount - 1) : null; if (lastIcon == null) { LoggerInstance?.Error("No icon found to clone."); @@ -212,8 +208,9 @@ private bool ModifyAppIcon(string labelText, string fileName) iconObj.name = AppName; Transform labelTransform = iconObj.transform.Find("Label"); - Text label = labelTransform?.GetComponent(); - if (label != null) label.text = labelText; + Text? label = labelTransform?.GetComponent(); + if (label != null) + label.text = labelText; return ChangeAppIconImage(iconObj, fileName); } @@ -228,7 +225,7 @@ private bool ModifyAppIcon(string labelText, string fileName) private bool ChangeAppIconImage(GameObject iconObj, string filename) { Transform imageTransform = iconObj.transform.Find("Mask/Image"); - Image image = imageTransform?.GetComponent(); + Image? image = imageTransform?.GetComponent(); if (image == null) { LoggerInstance?.Error("Image component not found in icon."); diff --git a/S1API/Products/ProductDefinitionWrapper.cs b/S1API/Products/ProductDefinitionWrapper.cs index 97903e3e..0a24f80b 100644 --- a/S1API/Products/ProductDefinitionWrapper.cs +++ b/S1API/Products/ProductDefinitionWrapper.cs @@ -7,9 +7,12 @@ namespace S1API.Products { - public static class ProductDefinitionWrapper + /// + /// INTERNAL: A wrapper class for converting a product definition to its proper dedicated class. + /// + internal static class ProductDefinitionWrapper { - public static ProductDefinition Wrap(ProductDefinition def) + internal static ProductDefinition Wrap(ProductDefinition def) { var item = def.S1ItemDefinition; if (CrossType.Is(item, out var weed)) diff --git a/S1API/Quests/QuestManager.cs b/S1API/Quests/QuestManager.cs index bf15845d..36e694f9 100644 --- a/S1API/Quests/QuestManager.cs +++ b/S1API/Quests/QuestManager.cs @@ -29,7 +29,10 @@ public static Quest CreateQuest(string? guid = null) where T : Quest => /// public static Quest CreateQuest(Type questType, string? guid = null) { - Quest quest = (Quest)Activator.CreateInstance(questType); + Quest? quest = (Quest)Activator.CreateInstance(questType)!; + if (quest == null) + throw new Exception($"Unable to create quest instance of {questType.FullName}!"); + Quests.Add(quest); return quest; } diff --git a/S1API/Quests/QuestState.cs b/S1API/Quests/QuestState.cs index 8f02c675..d907b328 100644 --- a/S1API/Quests/QuestState.cs +++ b/S1API/Quests/QuestState.cs @@ -5,11 +5,34 @@ /// public enum QuestState { + /// + /// Represents a quest / quest entry that has not been started yet. + /// Inactive, + + /// + /// Represents a quest / quest entry that has been started but not ended. + /// Active, + + /// + /// Represents a quest / quest entry that has been completed successfully by the player. + /// Completed, + + /// + /// Represents a quest / quest entry that has been failed by the played. + /// Failed, + + /// + /// Represents a quest / quest entry that has been expired. + /// Expired, + + /// + /// Represents a quest / quest entry that has been cancelled. + /// Cancelled } } \ No newline at end of file diff --git a/S1API/S1API.cs b/S1API/S1API.cs index b50ec326..a14f1d58 100644 --- a/S1API/S1API.cs +++ b/S1API/S1API.cs @@ -4,6 +4,9 @@ namespace S1API { + /// + /// Not currently utilized by S1API. + /// public class S1API : MelonMod { } diff --git a/S1API/S1API.csproj b/S1API/S1API.csproj index 84580431..7e63c647 100644 --- a/S1API/S1API.csproj +++ b/S1API/S1API.csproj @@ -7,7 +7,6 @@ - netstandard2.1 KaBooMa S1API A Schedule One Mono / Il2Cpp Cross Compatibility Layer @@ -19,6 +18,14 @@ S1API true + + + netstandard2.1 + + + + net6.0 + diff --git a/S1API/Saveables/SaveableField.cs b/S1API/Saveables/SaveableField.cs index ec5be204..1df462af 100644 --- a/S1API/Saveables/SaveableField.cs +++ b/S1API/Saveables/SaveableField.cs @@ -4,6 +4,8 @@ namespace S1API.Saveables { /// /// Marks a field to be saved alongside the class instance. + /// This attribute is intended to work across all custom game elements. + /// (For example, custom NPCs, quests, etc.) /// [AttributeUsage(AttributeTargets.Field)] public class SaveableField : Attribute @@ -13,6 +15,10 @@ public class SaveableField : Attribute /// internal string SaveName { get; } + /// + /// Base constructor for initializing a SaveableField. + /// + /// public SaveableField(string saveName) { SaveName = saveName; diff --git a/S1API/UI/UIFactory.cs b/S1API/UI/UIFactory.cs index 12972121..4ae6d900 100644 --- a/S1API/UI/UIFactory.cs +++ b/S1API/UI/UIFactory.cs @@ -244,7 +244,7 @@ public static void ClearChildren(Transform parent) /// The GameObject to which a VerticalLayoutGroup will be added or configured. /// The spacing between child objects within the VerticalLayoutGroup. Default is 10. /// The padding around the edges of the VerticalLayoutGroup. If null, a default RectOffset of (10, 10, 10, 10) will be used. - public static void VerticalLayoutOnGO(GameObject go, int spacing = 10, RectOffset padding = null) + public static void VerticalLayoutOnGO(GameObject go, int spacing = 10, RectOffset? padding = null) { var layout = go.AddComponent(); layout.spacing = spacing; @@ -317,16 +317,32 @@ public static GameObject CreateQuestRow(string name, Transform parent, out GameO /// The height of the button, if displayed. /// An optional action to be invoked when the button is clicked. If null, the button will not be created. /// The text to display on the optional button. Defaults to "Action" if not specified. + /// The size of the top bar. + /// The left position of the bar. + /// The right position of the bar. + /// The top position of the bar. + /// The bottom position of the bar. /// The created GameObject representing the top bar. - public static GameObject TopBar(string name, Transform parent, string title,float buttonWidth,float buttonHeight,float topbarSize,int rectleft,int rectright,int recttop,int rectbottom, - Action onRightButtonClick = null, - string rightButtonText = "Action") + public static GameObject TopBar( + string name, + Transform parent, + string title, + float buttonWidth, + float buttonHeight, + float topBarSize, + int rectLeft, + int rectRight, + int rectTop, + int rectBottom, + Action? onRightButtonClick = null, + string rightButtonText = "Action" + ) { var topBar = Panel(name, parent, new Color(0.15f, 0.15f, 0.15f), - new Vector2(0f, topbarSize), new Vector2(1f, 1f)); + new Vector2(0f, topBarSize), new Vector2(1f, 1f)); var layout = topBar.AddComponent(); - layout.padding = new RectOffset(rectleft,rectright,recttop,rectbottom);; + layout.padding = new RectOffset(rectLeft,rectRight,rectTop,rectBottom);; layout.spacing = 20; layout.childAlignment = TextAnchor.MiddleCenter; layout.childForceExpandWidth = false; @@ -338,17 +354,17 @@ public static GameObject TopBar(string name, Transform parent, string title,floa titleLayout.minWidth = 300; titleLayout.flexibleWidth = 1; - // Button (if any) - if (onRightButtonClick != null) - { - var (btnGO, btn, label) = ButtonWithLabel("TopBarButton", rightButtonText, topBar.transform, new Color(0.25f, 0.5f, 1f), buttonWidth, buttonHeight); - ButtonUtils.AddListener(btn, onRightButtonClick); - - var btnLayout = btnGO.AddComponent(); - btnLayout.minWidth = buttonWidth; - btnLayout.preferredHeight = buttonHeight; - btnLayout.flexibleWidth = 0; - } + if (onRightButtonClick == null) + return topBar; + + // Create the button element if we have an Action to invoke + var (btnGO, btn, label) = ButtonWithLabel("TopBarButton", rightButtonText, topBar.transform, new Color(0.25f, 0.5f, 1f), buttonWidth, buttonHeight); + ButtonUtils.AddListener(btn, onRightButtonClick); + + var btnLayout = btnGO.AddComponent(); + btnLayout.minWidth = buttonWidth; + btnLayout.preferredHeight = buttonHeight; + btnLayout.flexibleWidth = 0; return topBar; } From 8196467b9059dc4c67cfde329e54226135ad1af3 Mon Sep 17 00:00:00 2001 From: Omar Akermi Date: Sun, 27 Apr 2025 03:59:42 +0200 Subject: [PATCH 12/42] Refactor: Replace MoneyManager with static Money API --- S1API/Money/Money.cs | 132 ++++++++++++++++++++++++++++++++++++ S1API/Money/MoneyManager.cs | 109 ----------------------------- 2 files changed, 132 insertions(+), 109 deletions(-) create mode 100644 S1API/Money/Money.cs delete mode 100644 S1API/Money/MoneyManager.cs diff --git a/S1API/Money/Money.cs b/S1API/Money/Money.cs new file mode 100644 index 00000000..77ab3f3f --- /dev/null +++ b/S1API/Money/Money.cs @@ -0,0 +1,132 @@ +#if IL2CPP +using Il2CppScheduleOne; +using S1ItemFramework = Il2CppScheduleOne.ItemFramework; +using S1MoneyFramework = Il2CppScheduleOne.Money; +#else +using ScheduleOne; +using S1ItemFramework = ScheduleOne.ItemFramework; +using S1MoneyFramework = ScheduleOne.Money; + +#endif + +using S1API.Internal.Utils; +using System; +using UnityEngine; + +namespace S1API.Money +{ + /// + /// Provides static access to financial operations, including methods for managing cash balance, + /// creating online transactions, and calculating net worth. + /// + public static class Money + { + /// + /// Provides internal access to the underlying financial operations manager. + /// This property is utilized for interacting with the core financial functionality. + /// + private static S1MoneyFramework.MoneyManager Internal => S1MoneyFramework.MoneyManager.Instance; + + /// + /// Event triggered whenever there is a change in the balance, + /// including cash balance or online transactions. + /// + public static event Action? OnBalanceChanged; + + /// + /// Adjusts the cash balance by the specified amount. + /// + /// The amount to modify the cash balance by. Positive values increase the balance, and negative values decrease it. + /// Indicates whether the cash change should be visualized on the HUD. + /// Indicates whether a sound effect should be played to signify the cash adjustment. + public static void ChangeCashBalance(float amount, bool visualizeChange = true, bool playCashSound = false) + { + Internal?.ChangeCashBalance(amount, visualizeChange, playCashSound); + OnBalanceChanged?.Invoke(); + } + + /// + /// Creates an online transaction. + /// + /// The name of the transaction. + /// The monetary amount per unit involved in the transaction. + /// The number of units in the transaction. + /// An optional note or description for the transaction. + public static void CreateOnlineTransaction(string transactionName, float unitAmount, float quantity, + string transactionNote) + { + Internal?.CreateOnlineTransaction(transactionName, unitAmount, quantity, transactionNote); + OnBalanceChanged?.Invoke(); + } + + /// + /// Retrieves the total net worth, including all cash and online balances combined. + /// + /// The total net worth as a floating-point value. + public static float GetNetWorth() + { + return Internal != null ? Internal.GetNetWorth() : 0f; + } + + /// + /// Retrieves the current cash balance. + /// + /// The current cash balance as a floating-point value. + public static float GetCashBalance() + { + return Internal != null ? Internal.cashBalance : 0f; + } + + /// + /// Retrieves the current online balance. + /// + /// The current amount of online balance. + public static float GetOnlineBalance() + { + return Internal != null ? Internal.sync___get_value_onlineBalance() : 0f; + } + + /// + /// Registers a callback to be invoked during net worth calculation. + /// + /// The callback to be executed when net worth is calculated. It receives an object as its parameter. + public static void AddNetworthCalculation(System.Action callback) + { + if (Internal != null) + Internal.onNetworthCalculation += callback; + } + + /// + /// Removes a previously registered networth calculation callback. + /// + /// The callback to be removed from the networth calculation updates. + public static void RemoveNetworthCalculation(System.Action callback) + { + if (Internal != null) + Internal.onNetworthCalculation -= callback; + } + + /// + /// Creates a new cash instance with the specified balance. + /// + /// The initial amount of cash to set in the instance. + /// A newly created instance of cash with the specified balance. + public static CashInstance CreateCashInstance(float amount) + { +#if IL2CPP + var cashItem = Registry.GetItem("cash"); + var instance = CrossType.As(cashItem.GetDefaultInstance(1)); + var cashInstance = new CashInstance(instance); + cashInstance.SetQuantity(amount); + return cashInstance; +#else + var cashItem = Registry.GetItem("cash"); + var instance = CrossType.As(cashItem.GetDefaultInstance(1)); + var cashInstance = new CashInstance(instance); + cashInstance.SetQuantity(amount); + return cashInstance; + +#endif + } + } +} diff --git a/S1API/Money/MoneyManager.cs b/S1API/Money/MoneyManager.cs deleted file mode 100644 index 92e68168..00000000 --- a/S1API/Money/MoneyManager.cs +++ /dev/null @@ -1,109 +0,0 @@ -// REMOVE dynamic usage. Use the real FloatContainer. - -using S1API.Internal.Abstraction; -using UnityEngine; - -namespace S1API.Money -{ - /// - /// Provides methods for managing financial data, including cash balance, - /// online transactions, and net worth calculations. - /// - public class MoneyManager : Registerable - { -#if IL2CPP - private static Il2CppScheduleOne.Money.MoneyManager InternalInstance => Il2CppScheduleOne.Money.MoneyManager.Instance; -#else - /// - /// Provides internal access to the singleton instance of the underlying `ScheduleOne.Money.MoneyManager`. - /// This property is used internally to interact with the core money management system. - /// - private static ScheduleOne.Money.MoneyManager InternalInstance => ScheduleOne.Money.MoneyManager.Instance; -#endif - - /// - /// Invoked when the instance of the class is created and initialized. - /// Provides an entry point for subclasses to include additional setup logic during creation. - /// - protected override void OnCreated() => base.OnCreated(); - - /// - /// Executes cleanup or teardown logic when the instance is being destroyed. - /// This method is invoked when the object lifecycle ends and should typically - /// handle resource deallocation, event unsubscriptions, or other finalization tasks. - /// - protected override void OnDestroyed() => base.OnDestroyed(); - - /// - /// Changes the cash balance by the specified amount. - /// - /// The amount to adjust the cash balance by. Positive values increase the balance, while negative values decrease it. - /// Indicates whether the change in cash balance should be visually represented. - /// Indicates whether a sound effect should play when the cash balance is changed. - public static void ChangeCashBalance(float amount, bool visualizeChange = true, bool playCashSound = false) - { - InternalInstance?.ChangeCashBalance(amount, visualizeChange, playCashSound); - } - - /// - /// Creates an online transaction with specified details. - /// - /// The name of the transaction. - /// The monetary value of a single unit in the transaction. - /// The quantity involved in the transaction. - /// A note or description for the transaction. - public static void CreateOnlineTransaction(string transactionName, float unitAmount, float quantity, string transactionNote) - { - InternalInstance?.CreateOnlineTransaction(transactionName, unitAmount, quantity, transactionNote); - } - - /// - /// Retrieves the current net worth. - /// - /// The calculated net worth as a floating-point number. - public static float GetNetWorth() - { - return InternalInstance != null ? InternalInstance.GetNetWorth() : 0f; - } - - /// - /// Retrieves the current cash balance. - /// - /// The current cash balance as a floating-point value. - public static float GetCashBalance() - { - return InternalInstance != null ? InternalInstance.cashBalance : 0f; - } - - /// - /// Retrieves the current online balance of the user. - /// - /// - /// A float representing the user's current online balance. Returns 0 if the internal instance is null. - /// - public static float GetOnlineBalance() - { - return InternalInstance != null ? InternalInstance.sync___get_value_onlineBalance() : 0f; - } - - /// - /// Register a networth calculation event. - /// - /// An action to invoke during the networth calculation event. - public static void AddNetworthCalculation(System.Action callback) - { - if (InternalInstance != null) - InternalInstance.onNetworthCalculation += callback; - } - - /// - /// Remove a networth calculation event. - /// - /// The callback function to remove from the networth calculation event. - public static void RemoveNetworthCalculation(System.Action callback) - { - if (InternalInstance != null) - InternalInstance.onNetworthCalculation -= callback; - } - } -} From 0ecb4e797b1248839d0069137a7a1ee0adda3c6a Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Sun, 27 Apr 2025 01:18:18 -0500 Subject: [PATCH 13/42] fix: Fixed the ID for officers --- S1API/Entities/NPCs/PoliceOfficers/OfficerBailey.cs | 2 +- S1API/Entities/NPCs/PoliceOfficers/OfficerCooper.cs | 2 +- S1API/Entities/NPCs/PoliceOfficers/OfficerGreen.cs | 2 +- S1API/Entities/NPCs/PoliceOfficers/OfficerHoward.cs | 2 +- S1API/Entities/NPCs/PoliceOfficers/OfficerJackson.cs | 2 +- S1API/Entities/NPCs/PoliceOfficers/OfficerLee.cs | 2 +- S1API/Entities/NPCs/PoliceOfficers/OfficerLopez.cs | 2 +- S1API/Entities/NPCs/PoliceOfficers/OfficerMurphy.cs | 2 +- S1API/Entities/NPCs/PoliceOfficers/OfficerOakley.cs | 2 +- S1API/Internal/Patches/NPCPatches.cs | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerBailey.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerBailey.cs index 4e59e4be..a5203922 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerBailey.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerBailey.cs @@ -13,6 +13,6 @@ namespace S1API.Entities.NPCs.PoliceOfficers /// public class OfficerBailey : NPC { - internal OfficerBailey() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_bailey")) { } + internal OfficerBailey() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officerbailey")) { } } } \ No newline at end of file diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerCooper.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerCooper.cs index e81b6d0c..c2c40ba9 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerCooper.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerCooper.cs @@ -13,6 +13,6 @@ namespace S1API.Entities.NPCs.PoliceOfficers /// public class OfficerCooper : NPC { - internal OfficerCooper() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_cooper")) { } + internal OfficerCooper() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officercooper")) { } } } \ No newline at end of file diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerGreen.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerGreen.cs index fd8e3990..a5950489 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerGreen.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerGreen.cs @@ -13,6 +13,6 @@ namespace S1API.Entities.NPCs.PoliceOfficers /// public class OfficerGreen : NPC { - internal OfficerGreen() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_green")) { } + internal OfficerGreen() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officergreen")) { } } } \ No newline at end of file diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerHoward.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerHoward.cs index 38048808..b077a19b 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerHoward.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerHoward.cs @@ -13,6 +13,6 @@ namespace S1API.Entities.NPCs.PoliceOfficers /// public class OfficerHoward : NPC { - internal OfficerHoward() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_howard")) { } + internal OfficerHoward() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officerhoward")) { } } } \ No newline at end of file diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerJackson.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerJackson.cs index 7af40f28..3c3c4a4e 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerJackson.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerJackson.cs @@ -13,6 +13,6 @@ namespace S1API.Entities.NPCs.PoliceOfficers /// public class OfficerJackson : NPC { - internal OfficerJackson() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_jackson")) { } + internal OfficerJackson() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officerjackson")) { } } } \ No newline at end of file diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerLee.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerLee.cs index f96dcb4e..ce448bdf 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerLee.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerLee.cs @@ -13,6 +13,6 @@ namespace S1API.Entities.NPCs.PoliceOfficers /// public class OfficerLee : NPC { - internal OfficerLee() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_lee")) { } + internal OfficerLee() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officerlee")) { } } } \ No newline at end of file diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerLopez.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerLopez.cs index d79d4b38..6d2235b0 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerLopez.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerLopez.cs @@ -13,6 +13,6 @@ namespace S1API.Entities.NPCs.PoliceOfficers /// public class OfficerLopez : NPC { - internal OfficerLopez() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_lopez")) { } + internal OfficerLopez() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officerlopez")) { } } } \ No newline at end of file diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerMurphy.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerMurphy.cs index 61916fe1..206b2eea 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerMurphy.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerMurphy.cs @@ -13,6 +13,6 @@ namespace S1API.Entities.NPCs.PoliceOfficers /// public class OfficerMurphy : NPC { - internal OfficerMurphy() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_murphy")) { } + internal OfficerMurphy() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officermurphy")) { } } } \ No newline at end of file diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerOakley.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerOakley.cs index 590b2e74..11724460 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerOakley.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerOakley.cs @@ -13,6 +13,6 @@ namespace S1API.Entities.NPCs.PoliceOfficers /// public class OfficerOakley : NPC { - internal OfficerOakley() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officer_oakley")) { } + internal OfficerOakley() : base(NPCManager.NPCRegistry.ToArray().First(n => n.ID == "officeroakley")) { } } } \ No newline at end of file diff --git a/S1API/Internal/Patches/NPCPatches.cs b/S1API/Internal/Patches/NPCPatches.cs index db28df08..7dc52821 100644 --- a/S1API/Internal/Patches/NPCPatches.cs +++ b/S1API/Internal/Patches/NPCPatches.cs @@ -64,7 +64,7 @@ private static void NPCsLoadersLoad(S1Loaders.NPCsLoader __instance, string main [HarmonyPatch(typeof(S1NPCs.NPC), "Start")] [HarmonyPostfix] private static void NPCStart(S1NPCs.NPC __instance) => - NPCs.FirstOrDefault(npc => npc.S1NPC == __instance)?.CreateInternal(); + NPCs.FirstOrDefault(npc => npc.IsCustomNPC && npc.S1NPC == __instance)?.CreateInternal(); /// From e3b82b083cf8d229f82526abf2e1da7cc37e27af Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Sun, 27 Apr 2025 01:52:12 -0500 Subject: [PATCH 14/42] fix: Corrected reference to net6.0 for local deployment Il2Cpp --- S1API/S1API.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/S1API/S1API.csproj b/S1API/S1API.csproj index 7e63c647..63bb5fea 100644 --- a/S1API/S1API.csproj +++ b/S1API/S1API.csproj @@ -116,8 +116,8 @@ - - + + From 0e4ba0155e6aad2f6fe7c2d29e3915ef24525c4b Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Sun, 27 Apr 2025 01:53:11 -0500 Subject: [PATCH 15/42] fix: Corrected reference to net6.0 for local deployment Il2Cpp --- S1API/S1API.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/S1API/S1API.csproj b/S1API/S1API.csproj index 63bb5fea..d9003c5d 100644 --- a/S1API/S1API.csproj +++ b/S1API/S1API.csproj @@ -117,12 +117,12 @@ - + - + \ No newline at end of file From fc8c1b238a30f0b0eb8a5e2f1067ae3231e10468 Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Sun, 27 Apr 2025 01:55:50 -0500 Subject: [PATCH 16/42] fix: Corrected Il2Cpp list vs System list; --- S1API/Entities/NPC.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/S1API/Entities/NPC.cs b/S1API/Entities/NPC.cs index afa3e341..9da22598 100644 --- a/S1API/Entities/NPC.cs +++ b/S1API/Entities/NPC.cs @@ -58,7 +58,7 @@ public abstract class NPC : Saveable, ILivingEntity /// /// A list of text responses you've added to your NPC. /// - protected readonly List Responses = new List(); + protected readonly System.Collections.Generic.List Responses = new System.Collections.Generic.List(); /// /// Base constructor for a new NPC. @@ -591,7 +591,7 @@ internal override void CreateInternal() base.CreateInternal(); } - + internal override void SaveInternal(string folderPath, ref List extraSaveables) { string npcPath = Path.Combine(folderPath, S1NPC.SaveFolderName); From 6a464eac6ef56619bd329f0a4066dd3d1a7a6bf6 Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Sun, 27 Apr 2025 01:56:12 -0500 Subject: [PATCH 17/42] fix: Using new NPC list in NPC vs NPCPatches for tracking all NPCs --- S1API/Internal/Patches/NPCPatches.cs | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/S1API/Internal/Patches/NPCPatches.cs b/S1API/Internal/Patches/NPCPatches.cs index 7dc52821..9c8298d9 100644 --- a/S1API/Internal/Patches/NPCPatches.cs +++ b/S1API/Internal/Patches/NPCPatches.cs @@ -24,13 +24,6 @@ namespace S1API.Internal.Patches [HarmonyPatch] internal class NPCPatches { - - // ReSharper disable once RedundantNameQualifier - /// - /// List of all custom NPCs currently created. - /// - internal static readonly System.Collections.Generic.List NPCs = new System.Collections.Generic.List(); - /// /// Patching performed for when game NPCs are loaded. /// @@ -45,8 +38,6 @@ private static void NPCsLoadersLoad(S1Loaders.NPCsLoader __instance, string main NPC? customNPC = (NPC)Activator.CreateInstance(type, true)!; if (customNPC == null) throw new Exception($"Unable to create instance of {type.FullName}!"); - - NPCs.Add(customNPC); // We skip any S1API NPCs, as they are base NPC wrappers. if (type.Assembly == Assembly.GetExecutingAssembly()) @@ -64,7 +55,7 @@ private static void NPCsLoadersLoad(S1Loaders.NPCsLoader __instance, string main [HarmonyPatch(typeof(S1NPCs.NPC), "Start")] [HarmonyPostfix] private static void NPCStart(S1NPCs.NPC __instance) => - NPCs.FirstOrDefault(npc => npc.IsCustomNPC && npc.S1NPC == __instance)?.CreateInternal(); + NPC.All.FirstOrDefault(npc => npc.IsCustomNPC && npc.S1NPC == __instance)?.CreateInternal(); /// @@ -76,7 +67,7 @@ private static void NPCStart(S1NPCs.NPC __instance) => [HarmonyPatch(typeof(S1NPCs.NPC), "WriteData")] [HarmonyPostfix] private static void NPCWriteData(S1NPCs.NPC __instance, string parentFolderPath, ref List __result) => - NPCs.FirstOrDefault(npc => npc.IsCustomNPC && npc.S1NPC == __instance)?.SaveInternal(parentFolderPath, ref __result); + NPC.All.FirstOrDefault(npc => npc.IsCustomNPC && npc.S1NPC == __instance)?.SaveInternal(parentFolderPath, ref __result); /// /// Patching performed for when an NPC is destroyed. @@ -84,14 +75,7 @@ private static void NPCWriteData(S1NPCs.NPC __instance, string parentFolderPath, /// Instance of the NPC [HarmonyPatch(typeof(S1NPCs.NPC), "OnDestroy")] [HarmonyPostfix] - private static void NPCOnDestroy(S1NPCs.NPC __instance) - { - NPCs.RemoveAll(npc => npc.S1NPC == __instance); - NPC? npc = NPCs.FirstOrDefault(npc => npc.S1NPC == __instance); - if (npc == null) - return; - - NPCs.Remove(npc); - } + private static void NPCOnDestroy(S1NPCs.NPC __instance) => + NPC.All.RemoveAll(npc => npc.S1NPC == __instance); } } \ No newline at end of file From fa029b20dd4c8a5060f065c76a0c664d33f812ac Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Sun, 27 Apr 2025 02:08:00 -0500 Subject: [PATCH 18/42] fix: Remove only destroyed NPC instead of all when OnDestroy is called --- S1API/Internal/Patches/NPCPatches.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/S1API/Internal/Patches/NPCPatches.cs b/S1API/Internal/Patches/NPCPatches.cs index 9c8298d9..e16df81e 100644 --- a/S1API/Internal/Patches/NPCPatches.cs +++ b/S1API/Internal/Patches/NPCPatches.cs @@ -76,6 +76,6 @@ private static void NPCWriteData(S1NPCs.NPC __instance, string parentFolderPath, [HarmonyPatch(typeof(S1NPCs.NPC), "OnDestroy")] [HarmonyPostfix] private static void NPCOnDestroy(S1NPCs.NPC __instance) => - NPC.All.RemoveAll(npc => npc.S1NPC == __instance); + NPC.All.Remove(NPC.All.First(npc => npc.S1NPC == __instance)); } } \ No newline at end of file From 0867899a6846ccf65ea51cb3d6d1d8c58b0117e2 Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Sun, 27 Apr 2025 03:30:55 -0500 Subject: [PATCH 19/42] fix: Split the interfaces, as they weren't functioning as I originally intended. --- S1API/Entities/Interfaces/IEntity.cs | 8 ++------ .../{ILivingEntity.cs => IHealth.cs} | 2 +- S1API/Entities/NPC.cs | 20 +++++++++++++++++-- 3 files changed, 21 insertions(+), 9 deletions(-) rename S1API/Entities/Interfaces/{ILivingEntity.cs => IHealth.cs} (97%) diff --git a/S1API/Entities/Interfaces/IEntity.cs b/S1API/Entities/Interfaces/IEntity.cs index 8cd62f76..cc551b10 100644 --- a/S1API/Entities/Interfaces/IEntity.cs +++ b/S1API/Entities/Interfaces/IEntity.cs @@ -15,15 +15,11 @@ public interface IEntity /// /// The world position of the entity. /// - public Vector3 Position => gameObject.transform.position; + public Vector3 Position { get; set; } /// /// The scale of the entity. /// - public float Scale - { - get => gameObject.transform.localScale.magnitude; - set => gameObject.transform.localScale = new Vector3(value, value, value); - } + public float Scale { get; set; } } } \ No newline at end of file diff --git a/S1API/Entities/Interfaces/ILivingEntity.cs b/S1API/Entities/Interfaces/IHealth.cs similarity index 97% rename from S1API/Entities/Interfaces/ILivingEntity.cs rename to S1API/Entities/Interfaces/IHealth.cs index 1bb14dd2..2be07bf1 100644 --- a/S1API/Entities/Interfaces/ILivingEntity.cs +++ b/S1API/Entities/Interfaces/IHealth.cs @@ -5,7 +5,7 @@ namespace S1API.Entities.Interfaces /// /// Represents an entity that has health associated. /// - public interface ILivingEntity : IEntity + public interface IHealth { /// /// The current health of the entity. diff --git a/S1API/Entities/NPC.cs b/S1API/Entities/NPC.cs index 9da22598..9d5b92e2 100644 --- a/S1API/Entities/NPC.cs +++ b/S1API/Entities/NPC.cs @@ -49,7 +49,7 @@ namespace S1API.Entities /// /// An abstract class intended to be derived from for creating custom NPCs in the game. /// - public abstract class NPC : Saveable, ILivingEntity + public abstract class NPC : Saveable, IEntity, IHealth { // Protected members intended to be used by modders. // Intended to be used from within the class / derived classes ONLY. @@ -205,7 +205,23 @@ protected virtual void OnResponseLoaded(Response response) { } /// Not intended for use by modders! /// public GameObject gameObject { get; } + + /// + /// The world position of the NPC. + /// + public Vector3 Position + { + get => gameObject.transform.position; + set => S1NPC.Movement.Warp(value); + } + /// + /// The transform of the NPC. + /// Please do not set the properties of this transform. + /// + public Transform Transform => + gameObject.transform; + /// /// List of all NPCs within the base game and modded. /// @@ -394,7 +410,7 @@ public void Revive() => /// The amount of damage to deal. public void Damage(int amount) { - if (amount >= 0) + if (amount <= 0) return; S1NPC.Health.TakeDamage(amount, true); From 2559d9afa284b92c4d731ccb1d64b89699f74fa3 Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Sun, 27 Apr 2025 03:31:13 -0500 Subject: [PATCH 20/42] fix: Added the start of the player implementation. --- S1API/Entities/Player.cs | 192 ++++++++++++++++++++++++ S1API/Internal/Patches/PlayerPatches.cs | 39 +++++ 2 files changed, 231 insertions(+) create mode 100644 S1API/Entities/Player.cs create mode 100644 S1API/Internal/Patches/PlayerPatches.cs diff --git a/S1API/Entities/Player.cs b/S1API/Entities/Player.cs new file mode 100644 index 00000000..a8abc0e6 --- /dev/null +++ b/S1API/Entities/Player.cs @@ -0,0 +1,192 @@ +#if IL2CPP +using S1PlayerScripts = Il2CppScheduleOne.PlayerScripts; +using S1Health = Il2CppScheduleOne.PlayerScripts.Health; +#else +using S1PlayerScripts = ScheduleOne.PlayerScripts; +using S1Health = ScheduleOne.PlayerScripts.Health; +#endif + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using HarmonyLib; +using MelonLoader; +using S1API.Entities.Interfaces; +using S1API.Internal.Abstraction; +using UnityEngine; + +namespace S1API.Entities +{ + /// + /// Represents a player within the game. + /// + public class Player : IEntity, IHealth + { + /// + /// Health when the player is invincible. + /// Invincibility isn't baked in the base game. + /// Hence, why we're doing it this way :). + /// + private const float InvincibleHealth = 1000000000f; + + /// + /// The standard MAX_HEALTH of a player. + /// + private const float MortalHealth = 100f; + + /// + /// All players currently in the game. + /// + public static readonly List All = new List(); + + /// + /// INTERNAL: Tracking of the S1 instance of the player. + /// + internal S1PlayerScripts.Player S1Player; + + /// + /// INTERNAL: Constructor to create a new player from an S1 instance. + /// + /// + internal Player(S1PlayerScripts.Player player) + { + S1Player = player; + All.Add(this); + } + + /// + /// The current client player (player executing your code). + /// + public static Player Local => + All.FirstOrDefault(player => player.IsLocal)!; + + /// + /// Whether this player is the client player or a networked player. + /// + public bool IsLocal => + S1Player.IsLocalPlayer; + + /// + /// The name of the player. + /// For single player, this appears to always return `Player`. + /// + public string Name => + S1Player.PlayerName; + + /// + /// INTERNAL: The game object associated with this player. + /// + GameObject IEntity.gameObject => + S1Player.gameObject; + + /// + /// The world position of the player. + /// + public Vector3 Position + { + get => ((IEntity)this).gameObject.transform.position; + set => ((IEntity)this).gameObject.transform.position = value; + } + + /// + /// The transform of the player. + /// Please do not set the properties of the Transform. + /// + public Transform Transform => + ((IEntity)this).gameObject.transform; + + /// + /// The scale of the player. + /// + public float Scale + { + get => S1Player.Scale; + set => S1Player.SetScale(value); + } + + /// + /// The current health of the player. + /// + public float CurrentHealth => + S1Player.Health.CurrentHealth; + + /// + /// The maximum health of the player. + /// + public float MaxHealth + { + get => (float)_maxHealthField.GetValue(S1Player.Health)!; + set => _maxHealthField.SetValue(S1Player.Health, value); + } + + /// + /// Whether the player is dead or not. + /// + public bool IsDead => + !S1Player.Health.IsAlive; + + /// + /// Whether the player is invincible or not. + /// + public bool IsInvincible + { + get => MaxHealth == InvincibleHealth; + set + { + MaxHealth = value ? InvincibleHealth : MortalHealth; + S1Player.Health.SetHealth(MaxHealth); + } + } + + /// + /// Revives the player. + /// + public void Revive() => + S1Player.Health.Revive(Position, Quaternion.identity); + + /// + /// Deals damage to the player. + /// + /// The amount of damage to deal. + public void Damage(int amount) + { + if (amount <= 0) + return; + + S1Player.Health.TakeDamage(amount); + } + + /// + /// Heals the player. + /// + /// The amount of healing to apply to the player. + public void Heal(int amount) + { + if (amount <= 0) + return; + + S1Player.Health.SetHealth(CurrentHealth + amount); + } + + /// + /// Kills the player. + /// + public void Kill() => + S1Player.Health.SetHealth(0f); + + /// + /// Called when the player dies. + /// + public event Action OnDeath + { + add => EventHelper.AddListener(value, S1Player.Health.onDie); + remove => EventHelper.RemoveListener(value, S1Player.Health.onDie); + } + + /// + /// INTERNAL: Field access for the MAX_HEALTH const. + /// + private readonly FieldInfo _maxHealthField = AccessTools.Field(typeof(S1Health.PlayerHealth), "MAX_HEALTH"); + } +} diff --git a/S1API/Internal/Patches/PlayerPatches.cs b/S1API/Internal/Patches/PlayerPatches.cs new file mode 100644 index 00000000..d3f24c65 --- /dev/null +++ b/S1API/Internal/Patches/PlayerPatches.cs @@ -0,0 +1,39 @@ +#if IL2CPP +using S1PlayerScripts = Il2CppScheduleOne.PlayerScripts; +#else +using S1PlayerScripts = ScheduleOne.PlayerScripts; +#endif + + +using System.Linq; +using HarmonyLib; +using S1API.Entities; + +namespace S1API.Internal.Patches +{ + /// + /// INTERNAL: Patches to apply to the Players for tracking. + /// + [HarmonyPatch] + internal class PlayerPatches + { + /// + /// INTERNAL: Adds players to the player list upon wake. + /// + /// The player to add. + [HarmonyPatch(typeof(S1PlayerScripts.Player), "Awake")] + [HarmonyPostfix] + private static void PlayerAwake(S1PlayerScripts.Player __instance) => + new Player(__instance); + + + /// + /// INTERNAL: Removes players from the player list upon destruction. + /// + /// The player to remove. + [HarmonyPatch(typeof(S1PlayerScripts.Player), "OnDestroy")] + [HarmonyPostfix] + private static void PlayerOnDestroy(S1PlayerScripts.Player __instance) => + Player.All.Remove(Player.All.First(player => player.S1Player == __instance)); + } +} \ No newline at end of file From 6dc0bbc138699d6116c3c5cde41adac0193caef8 Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Sun, 27 Apr 2025 04:25:56 -0500 Subject: [PATCH 21/42] fix: Resolved merge issues; Adjusted workflows for BepInEx --- .github/workflows/deploy-build.yml | 23 ++++++---- .github/workflows/verify-build.yml | 18 +++++--- S1API/Console/ConsoleHelper.cs | 4 +- S1API/Entities/NPC.cs | 12 +++--- S1API/Entities/NPCs/DanSamwell.cs | 2 +- S1API/Entities/NPCs/Docks/AnnaChesterfield.cs | 2 +- S1API/Entities/NPCs/Docks/BillyKramer.cs | 2 +- S1API/Entities/NPCs/Docks/CrankyFrank.cs | 2 +- S1API/Entities/NPCs/Docks/GenghisBarn.cs | 2 +- S1API/Entities/NPCs/Docks/JaneLucero.cs | 2 +- S1API/Entities/NPCs/Docks/JavierPerez.cs | 2 +- S1API/Entities/NPCs/Docks/LisaGardener.cs | 2 +- S1API/Entities/NPCs/Docks/MacCooper.cs | 2 +- S1API/Entities/NPCs/Docks/MarcoBaron.cs | 2 +- S1API/Entities/NPCs/Docks/MelissaWood.cs | 2 +- S1API/Entities/NPCs/Docks/SalvadorMoreno.cs | 2 +- S1API/Entities/NPCs/Downtown/BradCrosby.cs | 2 +- .../Entities/NPCs/Downtown/ElizabethHomley.cs | 2 +- S1API/Entities/NPCs/Downtown/EugeneBuckley.cs | 2 +- S1API/Entities/NPCs/Downtown/GregFliggle.cs | 2 +- S1API/Entities/NPCs/Downtown/JeffGilmore.cs | 2 +- .../Entities/NPCs/Downtown/JenniferRivera.cs | 2 +- S1API/Entities/NPCs/Downtown/KevinOakley.cs | 2 +- S1API/Entities/NPCs/Downtown/LouisFourier.cs | 2 +- .../Entities/NPCs/Downtown/LucyPennington.cs | 2 +- .../Entities/NPCs/Downtown/PhilipWentworth.cs | 2 +- .../Entities/NPCs/Downtown/RandyCaulfield.cs | 2 +- S1API/Entities/NPCs/IgorRomanovich.cs | 2 +- S1API/Entities/NPCs/MannyOakfield.cs | 2 +- S1API/Entities/NPCs/Northtown/AlbertHoover.cs | 2 +- .../Entities/NPCs/Northtown/AustinSteiner.cs | 2 +- S1API/Entities/NPCs/Northtown/BenjiColeman.cs | 2 +- S1API/Entities/NPCs/Northtown/BethPenn.cs | 2 +- S1API/Entities/NPCs/Northtown/ChloeBowers.cs | 2 +- S1API/Entities/NPCs/Northtown/DonnaMartin.cs | 2 +- .../Entities/NPCs/Northtown/GeraldinePoon.cs | 2 +- S1API/Entities/NPCs/Northtown/JessiWaters.cs | 2 +- .../Entities/NPCs/Northtown/KathyHenderson.cs | 2 +- S1API/Entities/NPCs/Northtown/KyleCooley.cs | 2 +- S1API/Entities/NPCs/Northtown/LudwigMeyer.cs | 2 +- S1API/Entities/NPCs/Northtown/MickLubbin.cs | 2 +- S1API/Entities/NPCs/Northtown/Ming.cs | 2 +- S1API/Entities/NPCs/Northtown/PeggyMyers.cs | 2 +- S1API/Entities/NPCs/Northtown/PeterFile.cs | 2 +- S1API/Entities/NPCs/Northtown/SamThompson.cs | 2 +- S1API/Entities/NPCs/OscarHolland.cs | 2 +- .../NPCs/PoliceOfficers/OfficerBailey.cs | 2 +- .../NPCs/PoliceOfficers/OfficerCooper.cs | 2 +- .../NPCs/PoliceOfficers/OfficerGreen.cs | 2 +- .../NPCs/PoliceOfficers/OfficerHoward.cs | 2 +- .../NPCs/PoliceOfficers/OfficerJackson.cs | 2 +- .../NPCs/PoliceOfficers/OfficerLee.cs | 2 +- .../NPCs/PoliceOfficers/OfficerLopez.cs | 2 +- .../NPCs/PoliceOfficers/OfficerMurphy.cs | 2 +- .../NPCs/PoliceOfficers/OfficerOakley.cs | 2 +- S1API/Entities/NPCs/StanCarney.cs | 2 +- S1API/Entities/NPCs/Suburbia/AlisonKnight.cs | 2 +- S1API/Entities/NPCs/Suburbia/CarlBundy.cs | 2 +- S1API/Entities/NPCs/Suburbia/ChrisSullivan.cs | 2 +- S1API/Entities/NPCs/Suburbia/DennisKennedy.cs | 2 +- S1API/Entities/NPCs/Suburbia/HankStevenson.cs | 2 +- S1API/Entities/NPCs/Suburbia/HaroldColt.cs | 2 +- S1API/Entities/NPCs/Suburbia/JackKnight.cs | 2 +- .../Entities/NPCs/Suburbia/JackieStevenson.cs | 2 +- .../Entities/NPCs/Suburbia/JeremyWilkinson.cs | 2 +- S1API/Entities/NPCs/Suburbia/KarenKennedy.cs | 2 +- S1API/Entities/NPCs/Suburbia/WeiLong.cs | 2 +- S1API/Entities/NPCs/UncleNelson.cs | 2 +- S1API/Entities/NPCs/Uptown/FionaHancock.cs | 2 +- S1API/Entities/NPCs/Uptown/HerbertBleuball.cs | 2 +- S1API/Entities/NPCs/Uptown/JenHeard.cs | 2 +- S1API/Entities/NPCs/Uptown/LeoRivers.cs | 2 +- S1API/Entities/NPCs/Uptown/LilyTurner.cs | 2 +- S1API/Entities/NPCs/Uptown/MichaelBoog.cs | 2 +- S1API/Entities/NPCs/Uptown/PearlMoore.cs | 2 +- S1API/Entities/NPCs/Uptown/RayHoffman.cs | 2 +- S1API/Entities/NPCs/Uptown/TobiasWentworth.cs | 2 +- S1API/Entities/NPCs/Uptown/WalterCussler.cs | 2 +- .../Entities/NPCs/Westville/CharlesRowland.cs | 2 +- S1API/Entities/NPCs/Westville/DeanWebster.cs | 2 +- S1API/Entities/NPCs/Westville/DorisLubbin.cs | 2 +- S1API/Entities/NPCs/Westville/GeorgeGreene.cs | 2 +- S1API/Entities/NPCs/Westville/JerryMontero.cs | 2 +- S1API/Entities/NPCs/Westville/JoyceBall.cs | 2 +- S1API/Entities/NPCs/Westville/KeithWagner.cs | 2 +- S1API/Entities/NPCs/Westville/KimDelaney.cs | 2 +- S1API/Entities/NPCs/Westville/MegCooley.cs | 2 +- S1API/Entities/NPCs/Westville/MollyPresley.cs | 2 +- S1API/Entities/NPCs/Westville/ShirleyWatts.cs | 2 +- S1API/Entities/NPCs/Westville/TrentSherman.cs | 2 +- S1API/Entities/Player.cs | 2 +- S1API/GameTime/TimeManager.cs | 42 +++++++++---------- S1API/Internal/Abstraction/ISaveable.cs | 2 +- S1API/Internal/Abstraction/Saveable.cs | 2 +- S1API/Internal/Patches/PhoneAppPatches.cs | 2 +- S1API/Internal/Patches/PlayerPatches.cs | 2 +- S1API/Logging/Log.cs | 20 ++++----- S1API/Messaging/Response.cs | 4 +- S1API/Money/Money.cs | 4 +- S1API/Products/CocaineDefinition.cs | 4 +- S1API/Products/MethDefinition.cs | 4 +- S1API/Products/ProductDefinition.cs | 2 +- S1API/Products/ProductDefinitionWrapper.cs | 2 +- S1API/Products/WeedDefinition.cs | 4 +- S1API/Quests/Quest.cs | 4 +- S1API/S1API.cs | 5 +-- S1API/S1API.csproj | 4 +- S1API/UI/UIFactory.cs | 2 +- 108 files changed, 177 insertions(+), 163 deletions(-) diff --git a/.github/workflows/deploy-build.yml b/.github/workflows/deploy-build.yml index e91358e5..07f4d251 100644 --- a/.github/workflows/deploy-build.yml +++ b/.github/workflows/deploy-build.yml @@ -56,18 +56,27 @@ jobs: sed -i "s/{VERSION_NUMBER}/${{ steps.semantic-release.outputs.new_release_version }}/" ./S1API/S1API.cs sed -i "s/{VERSION_NUMBER}/${{ steps.semantic-release.outputs.new_release_version }}/" ./S1APILoader/S1APILoader.cs - - name: Run .NET build for Mono - run: dotnet build ./S1API.sln -c Mono -f netstandard2.1 + - name: Run .NET build for MonoBepInEx + run: dotnet build ./S1API.sln -c MonoBepInEx -f netstandard2.1 - - name: Run .NET build for Il2Cpp - run: dotnet build ./S1API.sln -c Il2Cpp -f netstandard2.1 + - name: Run .NET build for Il2CppBepInEx + run: dotnet build ./S1API.sln -c Il2CppBepInEx -f net6.0 + + - name: Run .NET build for MonoMelon + run: dotnet build ./S1API.sln -c MonoMelon -f netstandard2.1 + + - name: Run .NET build for Il2CppMelon + run: dotnet build ./S1API.sln -c Il2CppMelon -f net6.0 - name: Build artifact zip for Thunderstore run: | mkdir -p ./artifacts/thunderstore/Plugins/S1API - cp ./S1APILoader/bin/Mono/netstandard2.1/S1APILoader.dll ./artifacts/thunderstore/Plugins/S1APILoader.dll - cp ./S1API/bin/Il2Cpp/netstandard2.1/S1API.dll ./artifacts/thunderstore/Plugins/S1API/S1API.Il2Cpp.dll - cp ./S1API/bin/Mono/netstandard2.1/S1API.dll ./artifacts/thunderstore/Plugins/S1API/S1API.Mono.dll + cp ./S1APILoader/bin/MonoMelon/netstandard2.1/S1APILoader.dll ./artifacts/thunderstore/Plugins/S1APILoader.MelonLoader.dll + cp ./S1APILoader/bin/MonoBepInEx/netstandard2.1/S1APILoader.dll ./artifacts/thunderstore/Plugins/S1APILoader.BepInEx.dll + cp ./S1API/bin/Il2CppMelon/net6.0/S1API.dll ./artifacts/thunderstore/Plugins/S1API/S1API.Il2Cpp.MelonLoader.dll + cp ./S1API/bin/MonoMelon/netstandard2.1/S1API.dll ./artifacts/thunderstore/Plugins/S1API/S1API.Mono.MelonLoader.dll + cp ./S1API/bin/Il2CppMelon/net6.0/S1API.dll ./artifacts/thunderstore/Plugins/S1API/S1API.Il2Cpp.BepInEx.dll + cp ./S1API/bin/MonoMelon/netstandard2.1/S1API.dll ./artifacts/thunderstore/Plugins/S1API/S1API.Mono.BepInEx.dll - name: Publish artifact to Thunderstore uses: GreenTF/upload-thunderstore-package@v4.3 diff --git a/.github/workflows/verify-build.yml b/.github/workflows/verify-build.yml index 99706f0f..04ae7715 100644 --- a/.github/workflows/verify-build.yml +++ b/.github/workflows/verify-build.yml @@ -27,9 +27,15 @@ jobs: - name: Restore .NET Dependencies run: dotnet restore - - - name: Run .NET Build for Mono - run: dotnet build ./S1API.sln -c Mono -f netstandard2.1 - - - name: Run .NET Build for Il2Cpp - run: dotnet build ./S1API.sln -c Il2Cpp -f netstandard2.1 \ No newline at end of file + + - name: Run .NET build for MonoBepInEx + run: dotnet build ./S1API.sln -c MonoBepInEx -f netstandard2.1 + + - name: Run .NET build for Il2CppBepInEx + run: dotnet build ./S1API.sln -c Il2CppBepInEx -f net6.0 + + - name: Run .NET build for MonoMelon + run: dotnet build ./S1API.sln -c MonoMelon -f netstandard2.1 + + - name: Run .NET build for Il2CppMelon + run: dotnet build ./S1API.sln -c Il2CppMelon -f net6.0 \ No newline at end of file diff --git a/S1API/Console/ConsoleHelper.cs b/S1API/Console/ConsoleHelper.cs index a7bded34..f1239090 100644 --- a/S1API/Console/ConsoleHelper.cs +++ b/S1API/Console/ConsoleHelper.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppSystem.Collections.Generic; using static Il2CppScheduleOne.Console; #else @@ -20,7 +20,7 @@ public static class ConsoleHelper /// The cash amount to add or remove. public static void RunCashCommand(int amount) { -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) var command = new ChangeCashCommand(); var args = new Il2CppSystem.Collections.Generic.List(); #else diff --git a/S1API/Entities/NPC.cs b/S1API/Entities/NPC.cs index 9d5b92e2..6cfea9e9 100644 --- a/S1API/Entities/NPC.cs +++ b/S1API/Entities/NPC.cs @@ -1,4 +1,4 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1DevUtilities = Il2CppScheduleOne.DevUtilities; using S1Interaction = Il2CppScheduleOne.Interaction; using S1Messaging = Il2CppScheduleOne.Messaging; @@ -14,7 +14,7 @@ using S1Vision = Il2CppScheduleOne.Vision; using S1NPCs = Il2CppScheduleOne.NPCs; using Il2CppSystem.Collections.Generic; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1DevUtilities = ScheduleOne.DevUtilities; using S1Interaction = ScheduleOne.Interaction; using S1Messaging = ScheduleOne.Messaging; @@ -95,9 +95,9 @@ protected NPC( S1NPC.ConversationCategories.Add(S1Messaging.EConversationCategory.Customer); // Create our MessageConversation -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) S1NPC.CreateMessageConversation(); -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) MethodInfo createConvoMethod = AccessTools.Method(typeof(S1NPCs.NPC), "CreateMessageConversation"); createConvoMethod.Invoke(S1NPC, null); #endif @@ -162,9 +162,9 @@ protected NPC( S1NPC.awareness.VisionCone.QuestionMarkPopup = gameObject.AddComponent(); // Interaction behaviour -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) S1NPC.intObj = gameObject.AddComponent(); -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) FieldInfo intObjField = AccessTools.Field(typeof(S1NPCs.NPC), "intObj"); intObjField.SetValue(S1NPC, gameObject.AddComponent()); #endif diff --git a/S1API/Entities/NPCs/DanSamwell.cs b/S1API/Entities/NPCs/DanSamwell.cs index e3f3b0aa..45170f06 100644 --- a/S1API/Entities/NPCs/DanSamwell.cs +++ b/S1API/Entities/NPCs/DanSamwell.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Docks/AnnaChesterfield.cs b/S1API/Entities/NPCs/Docks/AnnaChesterfield.cs index 716271c2..8941322d 100644 --- a/S1API/Entities/NPCs/Docks/AnnaChesterfield.cs +++ b/S1API/Entities/NPCs/Docks/AnnaChesterfield.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Docks/BillyKramer.cs b/S1API/Entities/NPCs/Docks/BillyKramer.cs index 1195c3ba..4c103ba5 100644 --- a/S1API/Entities/NPCs/Docks/BillyKramer.cs +++ b/S1API/Entities/NPCs/Docks/BillyKramer.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Docks/CrankyFrank.cs b/S1API/Entities/NPCs/Docks/CrankyFrank.cs index b5b91835..d8bbd5db 100644 --- a/S1API/Entities/NPCs/Docks/CrankyFrank.cs +++ b/S1API/Entities/NPCs/Docks/CrankyFrank.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Docks/GenghisBarn.cs b/S1API/Entities/NPCs/Docks/GenghisBarn.cs index 3f0053a9..0a015cf0 100644 --- a/S1API/Entities/NPCs/Docks/GenghisBarn.cs +++ b/S1API/Entities/NPCs/Docks/GenghisBarn.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Docks/JaneLucero.cs b/S1API/Entities/NPCs/Docks/JaneLucero.cs index 92dfb778..3d041ac9 100644 --- a/S1API/Entities/NPCs/Docks/JaneLucero.cs +++ b/S1API/Entities/NPCs/Docks/JaneLucero.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Docks/JavierPerez.cs b/S1API/Entities/NPCs/Docks/JavierPerez.cs index d60491cd..a5bd941e 100644 --- a/S1API/Entities/NPCs/Docks/JavierPerez.cs +++ b/S1API/Entities/NPCs/Docks/JavierPerez.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Docks/LisaGardener.cs b/S1API/Entities/NPCs/Docks/LisaGardener.cs index 25ff3c57..0e87ae8e 100644 --- a/S1API/Entities/NPCs/Docks/LisaGardener.cs +++ b/S1API/Entities/NPCs/Docks/LisaGardener.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Docks/MacCooper.cs b/S1API/Entities/NPCs/Docks/MacCooper.cs index 417812a9..ec01cc86 100644 --- a/S1API/Entities/NPCs/Docks/MacCooper.cs +++ b/S1API/Entities/NPCs/Docks/MacCooper.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Docks/MarcoBaron.cs b/S1API/Entities/NPCs/Docks/MarcoBaron.cs index acc1e4b9..5c76f853 100644 --- a/S1API/Entities/NPCs/Docks/MarcoBaron.cs +++ b/S1API/Entities/NPCs/Docks/MarcoBaron.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Docks/MelissaWood.cs b/S1API/Entities/NPCs/Docks/MelissaWood.cs index f951d422..f60c8e1f 100644 --- a/S1API/Entities/NPCs/Docks/MelissaWood.cs +++ b/S1API/Entities/NPCs/Docks/MelissaWood.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Docks/SalvadorMoreno.cs b/S1API/Entities/NPCs/Docks/SalvadorMoreno.cs index 5874de36..52b28808 100644 --- a/S1API/Entities/NPCs/Docks/SalvadorMoreno.cs +++ b/S1API/Entities/NPCs/Docks/SalvadorMoreno.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Downtown/BradCrosby.cs b/S1API/Entities/NPCs/Downtown/BradCrosby.cs index 193ff48c..3e80ad39 100644 --- a/S1API/Entities/NPCs/Downtown/BradCrosby.cs +++ b/S1API/Entities/NPCs/Downtown/BradCrosby.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Downtown/ElizabethHomley.cs b/S1API/Entities/NPCs/Downtown/ElizabethHomley.cs index cc5dc2e9..1f709e6a 100644 --- a/S1API/Entities/NPCs/Downtown/ElizabethHomley.cs +++ b/S1API/Entities/NPCs/Downtown/ElizabethHomley.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Downtown/EugeneBuckley.cs b/S1API/Entities/NPCs/Downtown/EugeneBuckley.cs index e497a5cc..6cc2b80b 100644 --- a/S1API/Entities/NPCs/Downtown/EugeneBuckley.cs +++ b/S1API/Entities/NPCs/Downtown/EugeneBuckley.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Downtown/GregFliggle.cs b/S1API/Entities/NPCs/Downtown/GregFliggle.cs index 6645f34a..f37072ee 100644 --- a/S1API/Entities/NPCs/Downtown/GregFliggle.cs +++ b/S1API/Entities/NPCs/Downtown/GregFliggle.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Downtown/JeffGilmore.cs b/S1API/Entities/NPCs/Downtown/JeffGilmore.cs index 8b7ca3d8..38774f22 100644 --- a/S1API/Entities/NPCs/Downtown/JeffGilmore.cs +++ b/S1API/Entities/NPCs/Downtown/JeffGilmore.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Downtown/JenniferRivera.cs b/S1API/Entities/NPCs/Downtown/JenniferRivera.cs index 7df65be4..153638a4 100644 --- a/S1API/Entities/NPCs/Downtown/JenniferRivera.cs +++ b/S1API/Entities/NPCs/Downtown/JenniferRivera.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Downtown/KevinOakley.cs b/S1API/Entities/NPCs/Downtown/KevinOakley.cs index 6d841940..55d6f886 100644 --- a/S1API/Entities/NPCs/Downtown/KevinOakley.cs +++ b/S1API/Entities/NPCs/Downtown/KevinOakley.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Downtown/LouisFourier.cs b/S1API/Entities/NPCs/Downtown/LouisFourier.cs index 6012bb2c..be7a9816 100644 --- a/S1API/Entities/NPCs/Downtown/LouisFourier.cs +++ b/S1API/Entities/NPCs/Downtown/LouisFourier.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Downtown/LucyPennington.cs b/S1API/Entities/NPCs/Downtown/LucyPennington.cs index 97fde0e6..91cdb9f7 100644 --- a/S1API/Entities/NPCs/Downtown/LucyPennington.cs +++ b/S1API/Entities/NPCs/Downtown/LucyPennington.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Downtown/PhilipWentworth.cs b/S1API/Entities/NPCs/Downtown/PhilipWentworth.cs index 42d715a3..2c136602 100644 --- a/S1API/Entities/NPCs/Downtown/PhilipWentworth.cs +++ b/S1API/Entities/NPCs/Downtown/PhilipWentworth.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Downtown/RandyCaulfield.cs b/S1API/Entities/NPCs/Downtown/RandyCaulfield.cs index 3a8fecca..db3c1c19 100644 --- a/S1API/Entities/NPCs/Downtown/RandyCaulfield.cs +++ b/S1API/Entities/NPCs/Downtown/RandyCaulfield.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/IgorRomanovich.cs b/S1API/Entities/NPCs/IgorRomanovich.cs index 4723d905..8ee77af1 100644 --- a/S1API/Entities/NPCs/IgorRomanovich.cs +++ b/S1API/Entities/NPCs/IgorRomanovich.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/MannyOakfield.cs b/S1API/Entities/NPCs/MannyOakfield.cs index 403897a4..928e373b 100644 --- a/S1API/Entities/NPCs/MannyOakfield.cs +++ b/S1API/Entities/NPCs/MannyOakfield.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Northtown/AlbertHoover.cs b/S1API/Entities/NPCs/Northtown/AlbertHoover.cs index 162bcfb8..23a30f0b 100644 --- a/S1API/Entities/NPCs/Northtown/AlbertHoover.cs +++ b/S1API/Entities/NPCs/Northtown/AlbertHoover.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Northtown/AustinSteiner.cs b/S1API/Entities/NPCs/Northtown/AustinSteiner.cs index 393ebf90..2daa4e34 100644 --- a/S1API/Entities/NPCs/Northtown/AustinSteiner.cs +++ b/S1API/Entities/NPCs/Northtown/AustinSteiner.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Northtown/BenjiColeman.cs b/S1API/Entities/NPCs/Northtown/BenjiColeman.cs index b0c6528b..35b1deb6 100644 --- a/S1API/Entities/NPCs/Northtown/BenjiColeman.cs +++ b/S1API/Entities/NPCs/Northtown/BenjiColeman.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Northtown/BethPenn.cs b/S1API/Entities/NPCs/Northtown/BethPenn.cs index e5538920..31914721 100644 --- a/S1API/Entities/NPCs/Northtown/BethPenn.cs +++ b/S1API/Entities/NPCs/Northtown/BethPenn.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Northtown/ChloeBowers.cs b/S1API/Entities/NPCs/Northtown/ChloeBowers.cs index 03ab02b8..a4989c5a 100644 --- a/S1API/Entities/NPCs/Northtown/ChloeBowers.cs +++ b/S1API/Entities/NPCs/Northtown/ChloeBowers.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Northtown/DonnaMartin.cs b/S1API/Entities/NPCs/Northtown/DonnaMartin.cs index ef38ed01..b745d44f 100644 --- a/S1API/Entities/NPCs/Northtown/DonnaMartin.cs +++ b/S1API/Entities/NPCs/Northtown/DonnaMartin.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Northtown/GeraldinePoon.cs b/S1API/Entities/NPCs/Northtown/GeraldinePoon.cs index 3b04d209..9c24b6b4 100644 --- a/S1API/Entities/NPCs/Northtown/GeraldinePoon.cs +++ b/S1API/Entities/NPCs/Northtown/GeraldinePoon.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Northtown/JessiWaters.cs b/S1API/Entities/NPCs/Northtown/JessiWaters.cs index 7ed78aaa..8b227ff1 100644 --- a/S1API/Entities/NPCs/Northtown/JessiWaters.cs +++ b/S1API/Entities/NPCs/Northtown/JessiWaters.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Northtown/KathyHenderson.cs b/S1API/Entities/NPCs/Northtown/KathyHenderson.cs index 58a9135b..4ac0dcfe 100644 --- a/S1API/Entities/NPCs/Northtown/KathyHenderson.cs +++ b/S1API/Entities/NPCs/Northtown/KathyHenderson.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Northtown/KyleCooley.cs b/S1API/Entities/NPCs/Northtown/KyleCooley.cs index b4104f2c..523dcab7 100644 --- a/S1API/Entities/NPCs/Northtown/KyleCooley.cs +++ b/S1API/Entities/NPCs/Northtown/KyleCooley.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Northtown/LudwigMeyer.cs b/S1API/Entities/NPCs/Northtown/LudwigMeyer.cs index e3b77d8c..21653c19 100644 --- a/S1API/Entities/NPCs/Northtown/LudwigMeyer.cs +++ b/S1API/Entities/NPCs/Northtown/LudwigMeyer.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Northtown/MickLubbin.cs b/S1API/Entities/NPCs/Northtown/MickLubbin.cs index 293e7a80..8ab5f9b6 100644 --- a/S1API/Entities/NPCs/Northtown/MickLubbin.cs +++ b/S1API/Entities/NPCs/Northtown/MickLubbin.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Northtown/Ming.cs b/S1API/Entities/NPCs/Northtown/Ming.cs index 5c5b3e11..ea1e1721 100644 --- a/S1API/Entities/NPCs/Northtown/Ming.cs +++ b/S1API/Entities/NPCs/Northtown/Ming.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Northtown/PeggyMyers.cs b/S1API/Entities/NPCs/Northtown/PeggyMyers.cs index 875983ab..ae7660a3 100644 --- a/S1API/Entities/NPCs/Northtown/PeggyMyers.cs +++ b/S1API/Entities/NPCs/Northtown/PeggyMyers.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Northtown/PeterFile.cs b/S1API/Entities/NPCs/Northtown/PeterFile.cs index e2af8748..6ae508d7 100644 --- a/S1API/Entities/NPCs/Northtown/PeterFile.cs +++ b/S1API/Entities/NPCs/Northtown/PeterFile.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Northtown/SamThompson.cs b/S1API/Entities/NPCs/Northtown/SamThompson.cs index d9a49e98..4f349c23 100644 --- a/S1API/Entities/NPCs/Northtown/SamThompson.cs +++ b/S1API/Entities/NPCs/Northtown/SamThompson.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/OscarHolland.cs b/S1API/Entities/NPCs/OscarHolland.cs index 5a557110..3349bf8b 100644 --- a/S1API/Entities/NPCs/OscarHolland.cs +++ b/S1API/Entities/NPCs/OscarHolland.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerBailey.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerBailey.cs index a5203922..46fb882f 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerBailey.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerBailey.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerCooper.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerCooper.cs index c2c40ba9..64555f6a 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerCooper.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerCooper.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerGreen.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerGreen.cs index a5950489..1757e3c2 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerGreen.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerGreen.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerHoward.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerHoward.cs index b077a19b..a2866ec7 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerHoward.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerHoward.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerJackson.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerJackson.cs index 3c3c4a4e..f07628da 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerJackson.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerJackson.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerLee.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerLee.cs index ce448bdf..4048acab 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerLee.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerLee.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerLopez.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerLopez.cs index 6d2235b0..f98ec696 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerLopez.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerLopez.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerMurphy.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerMurphy.cs index 206b2eea..69cf7610 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerMurphy.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerMurphy.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/PoliceOfficers/OfficerOakley.cs b/S1API/Entities/NPCs/PoliceOfficers/OfficerOakley.cs index 11724460..61a2159a 100644 --- a/S1API/Entities/NPCs/PoliceOfficers/OfficerOakley.cs +++ b/S1API/Entities/NPCs/PoliceOfficers/OfficerOakley.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/StanCarney.cs b/S1API/Entities/NPCs/StanCarney.cs index 017983c5..196975e1 100644 --- a/S1API/Entities/NPCs/StanCarney.cs +++ b/S1API/Entities/NPCs/StanCarney.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Suburbia/AlisonKnight.cs b/S1API/Entities/NPCs/Suburbia/AlisonKnight.cs index a534cddc..b8023319 100644 --- a/S1API/Entities/NPCs/Suburbia/AlisonKnight.cs +++ b/S1API/Entities/NPCs/Suburbia/AlisonKnight.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Suburbia/CarlBundy.cs b/S1API/Entities/NPCs/Suburbia/CarlBundy.cs index e9fcbbb6..663e1a59 100644 --- a/S1API/Entities/NPCs/Suburbia/CarlBundy.cs +++ b/S1API/Entities/NPCs/Suburbia/CarlBundy.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Suburbia/ChrisSullivan.cs b/S1API/Entities/NPCs/Suburbia/ChrisSullivan.cs index 5c24211c..0360fc4f 100644 --- a/S1API/Entities/NPCs/Suburbia/ChrisSullivan.cs +++ b/S1API/Entities/NPCs/Suburbia/ChrisSullivan.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Suburbia/DennisKennedy.cs b/S1API/Entities/NPCs/Suburbia/DennisKennedy.cs index d733d06a..df287efb 100644 --- a/S1API/Entities/NPCs/Suburbia/DennisKennedy.cs +++ b/S1API/Entities/NPCs/Suburbia/DennisKennedy.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Suburbia/HankStevenson.cs b/S1API/Entities/NPCs/Suburbia/HankStevenson.cs index 9440e3ec..ea0bf972 100644 --- a/S1API/Entities/NPCs/Suburbia/HankStevenson.cs +++ b/S1API/Entities/NPCs/Suburbia/HankStevenson.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Suburbia/HaroldColt.cs b/S1API/Entities/NPCs/Suburbia/HaroldColt.cs index e313c440..e7442eb4 100644 --- a/S1API/Entities/NPCs/Suburbia/HaroldColt.cs +++ b/S1API/Entities/NPCs/Suburbia/HaroldColt.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Suburbia/JackKnight.cs b/S1API/Entities/NPCs/Suburbia/JackKnight.cs index 921ef9d2..36dbac8a 100644 --- a/S1API/Entities/NPCs/Suburbia/JackKnight.cs +++ b/S1API/Entities/NPCs/Suburbia/JackKnight.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Suburbia/JackieStevenson.cs b/S1API/Entities/NPCs/Suburbia/JackieStevenson.cs index ca504988..76cee8c9 100644 --- a/S1API/Entities/NPCs/Suburbia/JackieStevenson.cs +++ b/S1API/Entities/NPCs/Suburbia/JackieStevenson.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Suburbia/JeremyWilkinson.cs b/S1API/Entities/NPCs/Suburbia/JeremyWilkinson.cs index 4a7ebe04..3ff5a30f 100644 --- a/S1API/Entities/NPCs/Suburbia/JeremyWilkinson.cs +++ b/S1API/Entities/NPCs/Suburbia/JeremyWilkinson.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Suburbia/KarenKennedy.cs b/S1API/Entities/NPCs/Suburbia/KarenKennedy.cs index 0df4bccd..c6a0d6d9 100644 --- a/S1API/Entities/NPCs/Suburbia/KarenKennedy.cs +++ b/S1API/Entities/NPCs/Suburbia/KarenKennedy.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Suburbia/WeiLong.cs b/S1API/Entities/NPCs/Suburbia/WeiLong.cs index bec8f78f..2e82f1e9 100644 --- a/S1API/Entities/NPCs/Suburbia/WeiLong.cs +++ b/S1API/Entities/NPCs/Suburbia/WeiLong.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/UncleNelson.cs b/S1API/Entities/NPCs/UncleNelson.cs index 15e6b06b..99cd30e5 100644 --- a/S1API/Entities/NPCs/UncleNelson.cs +++ b/S1API/Entities/NPCs/UncleNelson.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Uptown/FionaHancock.cs b/S1API/Entities/NPCs/Uptown/FionaHancock.cs index 59a3b968..0829fdb9 100644 --- a/S1API/Entities/NPCs/Uptown/FionaHancock.cs +++ b/S1API/Entities/NPCs/Uptown/FionaHancock.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Uptown/HerbertBleuball.cs b/S1API/Entities/NPCs/Uptown/HerbertBleuball.cs index 0361d983..9c34e326 100644 --- a/S1API/Entities/NPCs/Uptown/HerbertBleuball.cs +++ b/S1API/Entities/NPCs/Uptown/HerbertBleuball.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Uptown/JenHeard.cs b/S1API/Entities/NPCs/Uptown/JenHeard.cs index d2ffe6b5..9cf9ea11 100644 --- a/S1API/Entities/NPCs/Uptown/JenHeard.cs +++ b/S1API/Entities/NPCs/Uptown/JenHeard.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Uptown/LeoRivers.cs b/S1API/Entities/NPCs/Uptown/LeoRivers.cs index 6f22c063..d5fd88ea 100644 --- a/S1API/Entities/NPCs/Uptown/LeoRivers.cs +++ b/S1API/Entities/NPCs/Uptown/LeoRivers.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Uptown/LilyTurner.cs b/S1API/Entities/NPCs/Uptown/LilyTurner.cs index a2d6b77f..3a26941e 100644 --- a/S1API/Entities/NPCs/Uptown/LilyTurner.cs +++ b/S1API/Entities/NPCs/Uptown/LilyTurner.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Uptown/MichaelBoog.cs b/S1API/Entities/NPCs/Uptown/MichaelBoog.cs index d8d160c2..20798227 100644 --- a/S1API/Entities/NPCs/Uptown/MichaelBoog.cs +++ b/S1API/Entities/NPCs/Uptown/MichaelBoog.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Uptown/PearlMoore.cs b/S1API/Entities/NPCs/Uptown/PearlMoore.cs index 902efae0..85075c02 100644 --- a/S1API/Entities/NPCs/Uptown/PearlMoore.cs +++ b/S1API/Entities/NPCs/Uptown/PearlMoore.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Uptown/RayHoffman.cs b/S1API/Entities/NPCs/Uptown/RayHoffman.cs index 0716d33e..3c5c6fc0 100644 --- a/S1API/Entities/NPCs/Uptown/RayHoffman.cs +++ b/S1API/Entities/NPCs/Uptown/RayHoffman.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Uptown/TobiasWentworth.cs b/S1API/Entities/NPCs/Uptown/TobiasWentworth.cs index b4950553..91064578 100644 --- a/S1API/Entities/NPCs/Uptown/TobiasWentworth.cs +++ b/S1API/Entities/NPCs/Uptown/TobiasWentworth.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Uptown/WalterCussler.cs b/S1API/Entities/NPCs/Uptown/WalterCussler.cs index ee6b726e..b870e8b7 100644 --- a/S1API/Entities/NPCs/Uptown/WalterCussler.cs +++ b/S1API/Entities/NPCs/Uptown/WalterCussler.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Westville/CharlesRowland.cs b/S1API/Entities/NPCs/Westville/CharlesRowland.cs index a82f5374..4c78605c 100644 --- a/S1API/Entities/NPCs/Westville/CharlesRowland.cs +++ b/S1API/Entities/NPCs/Westville/CharlesRowland.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Westville/DeanWebster.cs b/S1API/Entities/NPCs/Westville/DeanWebster.cs index 00d9da03..381083bf 100644 --- a/S1API/Entities/NPCs/Westville/DeanWebster.cs +++ b/S1API/Entities/NPCs/Westville/DeanWebster.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Westville/DorisLubbin.cs b/S1API/Entities/NPCs/Westville/DorisLubbin.cs index a30fd86a..03ea2f64 100644 --- a/S1API/Entities/NPCs/Westville/DorisLubbin.cs +++ b/S1API/Entities/NPCs/Westville/DorisLubbin.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Westville/GeorgeGreene.cs b/S1API/Entities/NPCs/Westville/GeorgeGreene.cs index 0aa2e27a..31cebf2f 100644 --- a/S1API/Entities/NPCs/Westville/GeorgeGreene.cs +++ b/S1API/Entities/NPCs/Westville/GeorgeGreene.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Westville/JerryMontero.cs b/S1API/Entities/NPCs/Westville/JerryMontero.cs index 8100e54c..dd1ec080 100644 --- a/S1API/Entities/NPCs/Westville/JerryMontero.cs +++ b/S1API/Entities/NPCs/Westville/JerryMontero.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Westville/JoyceBall.cs b/S1API/Entities/NPCs/Westville/JoyceBall.cs index 83452668..c8b67a71 100644 --- a/S1API/Entities/NPCs/Westville/JoyceBall.cs +++ b/S1API/Entities/NPCs/Westville/JoyceBall.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Westville/KeithWagner.cs b/S1API/Entities/NPCs/Westville/KeithWagner.cs index 98b0b302..31c2a76e 100644 --- a/S1API/Entities/NPCs/Westville/KeithWagner.cs +++ b/S1API/Entities/NPCs/Westville/KeithWagner.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Westville/KimDelaney.cs b/S1API/Entities/NPCs/Westville/KimDelaney.cs index abbc07a4..91d54980 100644 --- a/S1API/Entities/NPCs/Westville/KimDelaney.cs +++ b/S1API/Entities/NPCs/Westville/KimDelaney.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Westville/MegCooley.cs b/S1API/Entities/NPCs/Westville/MegCooley.cs index b60df006..d3123ec1 100644 --- a/S1API/Entities/NPCs/Westville/MegCooley.cs +++ b/S1API/Entities/NPCs/Westville/MegCooley.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Westville/MollyPresley.cs b/S1API/Entities/NPCs/Westville/MollyPresley.cs index 7f55b99f..82c26c84 100644 --- a/S1API/Entities/NPCs/Westville/MollyPresley.cs +++ b/S1API/Entities/NPCs/Westville/MollyPresley.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Westville/ShirleyWatts.cs b/S1API/Entities/NPCs/Westville/ShirleyWatts.cs index 705bb0a2..16f044da 100644 --- a/S1API/Entities/NPCs/Westville/ShirleyWatts.cs +++ b/S1API/Entities/NPCs/Westville/ShirleyWatts.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/NPCs/Westville/TrentSherman.cs b/S1API/Entities/NPCs/Westville/TrentSherman.cs index e46f1c2b..5536466e 100644 --- a/S1API/Entities/NPCs/Westville/TrentSherman.cs +++ b/S1API/Entities/NPCs/Westville/TrentSherman.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.NPCs; #else using ScheduleOne.NPCs; diff --git a/S1API/Entities/Player.cs b/S1API/Entities/Player.cs index a8abc0e6..cc3520aa 100644 --- a/S1API/Entities/Player.cs +++ b/S1API/Entities/Player.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1PlayerScripts = Il2CppScheduleOne.PlayerScripts; using S1Health = Il2CppScheduleOne.PlayerScripts.Health; #else diff --git a/S1API/GameTime/TimeManager.cs b/S1API/GameTime/TimeManager.cs index c6d5cdc9..e3670802 100644 --- a/S1API/GameTime/TimeManager.cs +++ b/S1API/GameTime/TimeManager.cs @@ -36,83 +36,83 @@ public static class TimeManager static TimeManager() { - if (S1GameTime.Instance != null) + if (S1GameTime.TimeManager.Instance != null) { - S1GameTime.Instance.onDayPass += (Action)(() => OnDayPass()); - S1GameTime.Instance.onWeekPass += (Action)(() => OnWeekPass()); + S1GameTime.TimeManager.Instance.onDayPass += (Action)(() => OnDayPass()); + S1GameTime.TimeManager.Instance.onWeekPass += (Action)(() => OnWeekPass()); } - S1GameTime.onSleepStart += (Action)(() => OnSleepStart()); - S1GameTime.onSleepEnd += (Action)(minutes => OnSleepEnd(minutes)); + S1GameTime.TimeManager.onSleepStart += (Action)(() => OnSleepStart()); + S1GameTime.TimeManager.onSleepEnd += (Action)(minutes => OnSleepEnd(minutes)); } /// /// The current in-game day (Monday, Tuesday, etc.). /// - public static Day CurrentDay => (Day)S1GameTime.Instance.CurrentDay; + public static Day CurrentDay => (Day)S1GameTime.TimeManager.Instance.CurrentDay; /// /// The number of in-game days elapsed. /// - public static int ElapsedDays => S1GameTime.Instance.ElapsedDays; + public static int ElapsedDays => S1GameTime.TimeManager.Instance.ElapsedDays; /// /// The current 24-hour time (e.g., 1330 for 1:30 PM). /// - public static int CurrentTime => S1GameTime.Instance.CurrentTime; + public static int CurrentTime => S1GameTime.TimeManager.Instance.CurrentTime; /// /// Whether it is currently nighttime in-game. /// - public static bool IsNight => S1GameTime.Instance.IsNight; + public static bool IsNight => S1GameTime.TimeManager.Instance.IsNight; /// /// Whether the game is currently at the end of the day (4:00 AM). /// - public static bool IsEndOfDay => S1GameTime.Instance.IsEndOfDay; + public static bool IsEndOfDay => S1GameTime.TimeManager.Instance.IsEndOfDay; /// /// Whether the player is currently sleeping. /// - public static bool SleepInProgress => S1GameTime.Instance.SleepInProgress; + public static bool SleepInProgress => S1GameTime.TimeManager.Instance.SleepInProgress; /// /// Whether the time is currently overridden (frozen or custom). /// - public static bool TimeOverridden => S1GameTime.Instance.TimeOverridden; + public static bool TimeOverridden => S1GameTime.TimeManager.Instance.TimeOverridden; /// /// The current normalized time of day (0.0 = start, 1.0 = end). /// - public static float NormalizedTime => S1GameTime.Instance.NormalizedTime; + public static float NormalizedTime => S1GameTime.TimeManager.Instance.NormalizedTime; /// /// Total playtime (in seconds). /// - public static float Playtime => S1GameTime.Instance.Playtime; + public static float Playtime => S1GameTime.TimeManager.Instance.Playtime; /// /// Fast-forwards time to morning wake time (7:00 AM). /// - public static void FastForwardToWakeTime() => S1GameTime.Instance.FastForwardToWakeTime(); + public static void FastForwardToWakeTime() => S1GameTime.TimeManager.Instance.FastForwardToWakeTime(); /// /// Sets the current time manually. /// - public static void SetTime(int time24h, bool local = false) => S1GameTime.Instance.SetTime(time24h, local); + public static void SetTime(int time24h, bool local = false) => S1GameTime.TimeManager.Instance.SetTime(time24h, local); /// /// Sets the number of elapsed in-game days. /// - public static void SetElapsedDays(int days) => S1GameTime.Instance.SetElapsedDays(days); + public static void SetElapsedDays(int days) => S1GameTime.TimeManager.Instance.SetElapsedDays(days); /// /// Gets the current time formatted in 12-hour AM/PM format. /// public static string GetFormatted12HourTime() { - return S1GameTime.Get12HourTime(CurrentTime, true); + return S1GameTime.TimeManager.Get12HourTime(CurrentTime, true); } /// @@ -120,7 +120,7 @@ public static string GetFormatted12HourTime() /// public static bool IsCurrentTimeWithinRange(int startTime24h, int endTime24h) { - return S1GameTime.Instance.IsCurrentTimeWithinRange(startTime24h, endTime24h); + return S1GameTime.TimeManager.Instance.IsCurrentTimeWithinRange(startTime24h, endTime24h); } /// @@ -128,7 +128,7 @@ public static bool IsCurrentTimeWithinRange(int startTime24h, int endTime24h) /// public static int GetMinutesFrom24HourTime(int time24h) { - return S1GameTime.GetMinSumFrom24HourTime(time24h); + return S1GameTime.TimeManager.GetMinSumFrom24HourTime(time24h); } /// @@ -136,7 +136,7 @@ public static int GetMinutesFrom24HourTime(int time24h) /// public static int Get24HourTimeFromMinutes(int minutes) { - return S1GameTime.Get24HourTimeFromMinSum(minutes); + return S1GameTime.TimeManager.Get24HourTimeFromMinSum(minutes); } } } diff --git a/S1API/Internal/Abstraction/ISaveable.cs b/S1API/Internal/Abstraction/ISaveable.cs index 94a5431e..9d7a1db5 100644 --- a/S1API/Internal/Abstraction/ISaveable.cs +++ b/S1API/Internal/Abstraction/ISaveable.cs @@ -1,6 +1,6 @@ #if (MONOMELON || MONOBEPINEX) using System.Collections.Generic; -#elif (IL2CPP) +#elif (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppSystem.Collections.Generic; #endif diff --git a/S1API/Internal/Abstraction/Saveable.cs b/S1API/Internal/Abstraction/Saveable.cs index 7afa79aa..e40d390a 100644 --- a/S1API/Internal/Abstraction/Saveable.cs +++ b/S1API/Internal/Abstraction/Saveable.cs @@ -1,6 +1,6 @@ #if (MONOMELON || MONOBEPINEX) using System.Collections.Generic; -#elif (IL2CPP) +#elif (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppSystem.Collections.Generic; #endif diff --git a/S1API/Internal/Patches/PhoneAppPatches.cs b/S1API/Internal/Patches/PhoneAppPatches.cs index 9c9bf913..0229638b 100644 --- a/S1API/Internal/Patches/PhoneAppPatches.cs +++ b/S1API/Internal/Patches/PhoneAppPatches.cs @@ -7,7 +7,7 @@ namespace S1API.Internal.Patches { -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) [HarmonyPatch(typeof(SceneManager), nameof(SceneManager.Internal_SceneLoaded))] #else [HarmonyPatch(typeof(SceneManager), "Internal_SceneLoaded", new Type[] { typeof(Scene), typeof(LoadSceneMode) })] diff --git a/S1API/Internal/Patches/PlayerPatches.cs b/S1API/Internal/Patches/PlayerPatches.cs index d3f24c65..79395e16 100644 --- a/S1API/Internal/Patches/PlayerPatches.cs +++ b/S1API/Internal/Patches/PlayerPatches.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1PlayerScripts = Il2CppScheduleOne.PlayerScripts; #else using S1PlayerScripts = ScheduleOne.PlayerScripts; diff --git a/S1API/Logging/Log.cs b/S1API/Logging/Log.cs index 03986b93..031fe680 100644 --- a/S1API/Logging/Log.cs +++ b/S1API/Logging/Log.cs @@ -1,5 +1,5 @@ -#if MONOMELON || IL2CPPMELON -using MelonLoader +#if (MONOMELON || IL2CPPMELON) +using MelonLoader; #else using BepInEx.Logging; #endif @@ -11,7 +11,7 @@ namespace S1API.Logging /// public class Log { -#if MONOMELON || IL2CPPMELON +#if (MONOMELON || IL2CPPMELON) private readonly MelonLogger.Instance _loggerInstance; #else private readonly ManualLogSource _loggerInstance; @@ -23,14 +23,14 @@ public class Log /// The source name to use for logging public Log(string sourceName) { -#if MONOMELON || IL2CPPMELON - _loggerInstance = new MelonLogger.Instancer(sourceName); +#if (MONOMELON || IL2CPPMELON) + _loggerInstance = new MelonLogger.Instance(sourceName); #else _loggerInstance = Logger.CreateLogSource(sourceName); #endif } -#if MONOBEPINEX || IL2CPPBEPINEX +#if (MONOBEPINEX || IL2CPPBEPINEX) /// /// Default constructor for instance when BepInEx is enabled /// @@ -47,7 +47,7 @@ public Log(ManualLogSource loggerInstance) /// Message to log public void Msg(string message) { -#if MONOMELON || IL2CPPMELON +#if (MONOMELON || IL2CPPMELON) _loggerInstance.Msg(message); #else _loggerInstance.LogInfo(message); @@ -60,7 +60,7 @@ public void Msg(string message) /// Message to log public void Warning(string message) { -#if MONOMELON || IL2CPPMELON +#if (MONOMELON || IL2CPPMELON) _loggerInstance.Warning(message); #else _loggerInstance.LogWarning(message); @@ -73,7 +73,7 @@ public void Warning(string message) /// Message to log public void Error(string message) { -#if MONOMELON || IL2CPPMELON +#if (MONOMELON || IL2CPPMELON) _loggerInstance.Error(message); #else _loggerInstance.LogError(message); @@ -86,7 +86,7 @@ public void Error(string message) /// Message to log public void BigError(string message) { -#if MONOMELON || IL2CPPMELON +#if (MONOMELON || IL2CPPMELON) _loggerInstance.BigError(message); #else _loggerInstance.LogFatal(message); diff --git a/S1API/Messaging/Response.cs b/S1API/Messaging/Response.cs index 1e9028c6..d0a2d021 100644 --- a/S1API/Messaging/Response.cs +++ b/S1API/Messaging/Response.cs @@ -1,6 +1,6 @@ -#if (IL2CPP) +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Messaging = Il2CppScheduleOne.Messaging; -#elif (MONO) +#elif (MONOMELON || MONOBEPINEX) using S1Messaging = ScheduleOne.Messaging; #endif using System; diff --git a/S1API/Money/Money.cs b/S1API/Money/Money.cs index 77ab3f3f..d886dc5b 100644 --- a/S1API/Money/Money.cs +++ b/S1API/Money/Money.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne; using S1ItemFramework = Il2CppScheduleOne.ItemFramework; using S1MoneyFramework = Il2CppScheduleOne.Money; @@ -113,7 +113,7 @@ public static void RemoveNetworthCalculation(System.Action callback) /// A newly created instance of cash with the specified balance. public static CashInstance CreateCashInstance(float amount) { -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) var cashItem = Registry.GetItem("cash"); var instance = CrossType.As(cashItem.GetDefaultInstance(1)); var cashInstance = new CashInstance(instance); diff --git a/S1API/Products/CocaineDefinition.cs b/S1API/Products/CocaineDefinition.cs index 18b0e5ab..5507e6f8 100644 --- a/S1API/Products/CocaineDefinition.cs +++ b/S1API/Products/CocaineDefinition.cs @@ -1,7 +1,7 @@ -#if IL2CPPMELON || IL2CPPBEPINEX +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.Product; using S1CocaineDefinition = Il2CppScheduleOne.Product.CocaineDefinition; -#elif MONOMELON || MONOBEPINEX +#elif (MONOMELON || MONOBEPINEX) using ScheduleOne.Product; using S1CocaineDefinition = ScheduleOne.Product.CocaineDefinition; #endif diff --git a/S1API/Products/MethDefinition.cs b/S1API/Products/MethDefinition.cs index 46cb4926..8904a616 100644 --- a/S1API/Products/MethDefinition.cs +++ b/S1API/Products/MethDefinition.cs @@ -1,7 +1,7 @@ -#if IL2CPPMELON || IL2CPPBEPINEX +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.Product; using S1MethDefinition = Il2CppScheduleOne.Product.MethDefinition; -#elif MONOMELON || MONOBEPINEX +#elif (MONOMELON || MONOBEPINEX) using ScheduleOne.Product; using S1MethDefinition = ScheduleOne.Product.MethDefinition; #endif diff --git a/S1API/Products/ProductDefinition.cs b/S1API/Products/ProductDefinition.cs index 38dbadb2..3c4b7fb2 100644 --- a/S1API/Products/ProductDefinition.cs +++ b/S1API/Products/ProductDefinition.cs @@ -1,4 +1,4 @@ -#if IL2CPPMELON || IL2CPPBEPINEX +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppInterop.Runtime.InteropTypes; using S1Product = Il2CppScheduleOne.Product; diff --git a/S1API/Products/ProductDefinitionWrapper.cs b/S1API/Products/ProductDefinitionWrapper.cs index a6fb9eb5..2670adca 100644 --- a/S1API/Products/ProductDefinitionWrapper.cs +++ b/S1API/Products/ProductDefinitionWrapper.cs @@ -1,5 +1,5 @@ using S1API.Internal.Utils; -#if IL2CPPMELON || IL2CPPBEPINEX +#if (IL2CPPMELON || IL2CPPBEPINEX) using S1Product = Il2CppScheduleOne.Product; #else using S1Product = ScheduleOne.Product; diff --git a/S1API/Products/WeedDefinition.cs b/S1API/Products/WeedDefinition.cs index bbff0a17..f467819e 100644 --- a/S1API/Products/WeedDefinition.cs +++ b/S1API/Products/WeedDefinition.cs @@ -1,7 +1,7 @@ -#if IL2CPPMELON || IL2CPPBEPINEX +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.Product; using S1WeedDefinition = Il2CppScheduleOne.Product.WeedDefinition; -#elif MONOMELON || MONOBEPINEX +#elif (MONOMELON || MONOBEPINEX) using ScheduleOne.Product; using S1WeedDefinition = ScheduleOne.Product.WeedDefinition; #endif diff --git a/S1API/Quests/Quest.cs b/S1API/Quests/Quest.cs index eb094abe..f281bccb 100644 --- a/S1API/Quests/Quest.cs +++ b/S1API/Quests/Quest.cs @@ -90,7 +90,7 @@ public Quest() #if (MONOMELON || MONOBEPINEX) FieldInfo autoInitField = AccessTools.Field(typeof(S1Quests.Quest), "autoInitialize"); autoInitField.SetValue(S1Quest, false); -#elif (IL2CPP) +#elif (IL2CPPMELON || IL2CPPBEPINEX) S1Quest.autoInitialize = false; #endif @@ -141,7 +141,7 @@ public Quest() #if (MONOMELON || MONOBEPINEX) FieldInfo uiPrefabField = AccessTools.Field(typeof(S1Map.POI), "UIPrefab"); uiPrefabField.SetValue(poi, uiPrefabObject); -#elif (IL2CPP) +#elif (IL2CPPMELON || IL2CPPBEPINEX) poi.UIPrefab = uiPrefabObject; #endif S1Quest.PoIPrefab = poiPrefabObject; diff --git a/S1API/S1API.cs b/S1API/S1API.cs index 847adb45..ba4eaa7b 100644 --- a/S1API/S1API.cs +++ b/S1API/S1API.cs @@ -1,4 +1,4 @@ -#if MONOMELON || IL2CPPMELON +#if (MONOMELON || IL2CPPMELON) using MelonLoader; [assembly: MelonInfo(typeof(S1API.S1API), "S1API", "{VERSION_NUMBER}", "KaBooMa")] @@ -12,7 +12,7 @@ public class S1API : MelonMod { } } -#elif MONOBEPINEX || IL2CPPBEPINEX +#elif (MONOBEPINEX || IL2CPPBEPINEX) using BepInEx; using BepInEx.Unity.Mono; @@ -29,5 +29,4 @@ private void Awake() } } } - #endif diff --git a/S1API/S1API.csproj b/S1API/S1API.csproj index 223cc89b..a28f1c2d 100644 --- a/S1API/S1API.csproj +++ b/S1API/S1API.csproj @@ -19,11 +19,11 @@ true - + netstandard2.1 - + net6.0 diff --git a/S1API/UI/UIFactory.cs b/S1API/UI/UIFactory.cs index 4ae6d900..57c5b0b3 100644 --- a/S1API/UI/UIFactory.cs +++ b/S1API/UI/UIFactory.cs @@ -1,4 +1,4 @@ -#if IL2CPP +#if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppInterop.Runtime.InteropTypes.Arrays; #endif From f82cda1d2a45ffa1e9853c287d0555e451763121 Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Sun, 27 Apr 2025 04:27:46 -0500 Subject: [PATCH 22/42] fix: Added BepInEx assembly path for private repo --- github.build.props | 1 + 1 file changed, 1 insertion(+) diff --git a/github.build.props b/github.build.props index 1648fc4d..2c4c39ec 100644 --- a/github.build.props +++ b/github.build.props @@ -11,6 +11,7 @@ ..\ScheduleOneAssemblies\MelonLoader + ..\ScheduleOneAssemblies\BepInEx From 69a1cc532637de19dd926b6078d333727d5ffc28 Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Sun, 27 Apr 2025 04:29:52 -0500 Subject: [PATCH 23/42] fix: Removed stale code --- S1API/Entities/Player.cs | 1 - S1API/Player/Player.cs | 10 ---------- 2 files changed, 11 deletions(-) delete mode 100644 S1API/Player/Player.cs diff --git a/S1API/Entities/Player.cs b/S1API/Entities/Player.cs index cc3520aa..835bcf82 100644 --- a/S1API/Entities/Player.cs +++ b/S1API/Entities/Player.cs @@ -11,7 +11,6 @@ using System.Linq; using System.Reflection; using HarmonyLib; -using MelonLoader; using S1API.Entities.Interfaces; using S1API.Internal.Abstraction; using UnityEngine; diff --git a/S1API/Player/Player.cs b/S1API/Player/Player.cs deleted file mode 100644 index 34f0a683..00000000 --- a/S1API/Player/Player.cs +++ /dev/null @@ -1,10 +0,0 @@ -// using UnityEngine; -// -// namespace S1API.Player -// { -// public class Player -// { -// public static Player Local => new Player(); -// public Vector3 Position = Vector3.zero; -// } -// } \ No newline at end of file From 3cd18ff6133cd07c87ae2085de8a0daa22934b2c Mon Sep 17 00:00:00 2001 From: Omar Akermi Date: Sun, 27 Apr 2025 13:26:16 +0200 Subject: [PATCH 24/42] Refactor: Replace PhoneApp.InitApp coroutine with HomeScreen.Start injection --- S1API/Internal/Patches/HomeScreen.Start.cs | 53 ++++++ S1API/Internal/Patches/PhoneAppRegistry.cs | 36 ++++ S1API/PhoneApp/PhoneApp.cs | 201 ++++++++++++--------- 3 files changed, 202 insertions(+), 88 deletions(-) create mode 100644 S1API/Internal/Patches/HomeScreen.Start.cs create mode 100644 S1API/Internal/Patches/PhoneAppRegistry.cs diff --git a/S1API/Internal/Patches/HomeScreen.Start.cs b/S1API/Internal/Patches/HomeScreen.Start.cs new file mode 100644 index 00000000..ab8ab830 --- /dev/null +++ b/S1API/Internal/Patches/HomeScreen.Start.cs @@ -0,0 +1,53 @@ +using System; +using HarmonyLib; +using Il2CppScheduleOne.UI.Phone; +using UnityEngine.SceneManagement; +using S1API.Internal.Utils; +using S1API.Internal.Abstraction; +using S1API.PhoneApp; + +namespace S1API.Internal.Patches; + +/// +/// The HomeScreen_Start class contains functionality that patches the +/// HomeScreen's Start method using the Harmony library within the Il2CppScheduleOne UI.Phone namespace. +/// This class is part of the S1API.Internal.Patches namespace, enabling modification or extension +/// of the behavior of the HomeScreen component's Start method. +/// +public class HomeScreen_Start +{ + /// + /// Represents a patch class for modifying the behavior of the Start method in the HomeScreen class. + /// This class is implemented as part of the Harmony patching mechanism to apply modifications + /// or inject additional logic during the execution of the Start method. + /// + [HarmonyPatch(typeof(HomeScreen), "Start")] + internal static class HomeScreen_Start_Patch + { + /// + /// Postfix method to modify the behavior of the HomeScreen's Start method after it is executed. + /// + /// + /// This method iterates over the list of registered phone applications and performs initialization for each app. + /// It ensures that the UI panel and the app icon for each application are created and properly configured. + /// If an error occurs during this process, a warning is logged with relevant details. + /// + static void Postfix() + { + foreach (var app in PhoneAppRegistry.RegisteredApps) + { + try + { + app.SpawnUI(); // Clone ProductManagerApp, clear container, call OnCreatedUI + app.SpawnIcon(); // Clone last HomeScreen icon, set label + icon image + } + catch (Exception e) + { + MelonLoader.MelonLogger.Warning($"[PhoneApp] Failed to spawn UI for {app.GetType().Name}: {e.Message}"); + } + } + } + } + + +} \ No newline at end of file diff --git a/S1API/Internal/Patches/PhoneAppRegistry.cs b/S1API/Internal/Patches/PhoneAppRegistry.cs new file mode 100644 index 00000000..996162da --- /dev/null +++ b/S1API/Internal/Patches/PhoneAppRegistry.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; + +namespace S1API.PhoneApp +{ + /// + /// Provides functionality for managing the registration of custom phone applications. + /// + /// + /// This static class serves as a registry for tracking instances of phone applications. + /// Applications are added to a centralized list which can then be used for initialization or + /// interacting with registered applications at runtime. + /// + internal static class PhoneAppRegistry + { + /// + /// A static readonly list that stores instances of phone applications registered via the PhoneAppRegistry. + /// + /// + /// This list holds all registered instances of objects. Applications are added to this collection + /// whenever they are registered using the PhoneAppRegistry.Register method, which is typically called automatically + /// during the application's lifecycle. + /// It serves as a central repository for all in-game phone applications, enabling other systems to access and manage + /// these registered apps efficiently. + /// + public static readonly List RegisteredApps = new(); + + /// + /// Registers a specified phone app into the phone application registry. + /// + /// The PhoneApp instance to be registered. + public static void Register(PhoneApp app) + { + RegisteredApps.Add(app); + } + } +} \ No newline at end of file diff --git a/S1API/PhoneApp/PhoneApp.cs b/S1API/PhoneApp/PhoneApp.cs index 7f59e4e7..0b9033fd 100644 --- a/S1API/PhoneApp/PhoneApp.cs +++ b/S1API/PhoneApp/PhoneApp.cs @@ -1,8 +1,7 @@ -using System.Collections; -using System.IO; -using MelonLoader; +using System.IO; using UnityEngine; using UnityEngine.UI; +using MelonLoader; using Object = UnityEngine.Object; using MelonLoader.Utils; using S1API.Internal.Abstraction; @@ -10,77 +9,110 @@ namespace S1API.PhoneApp { /// - /// Serves as an abstract base class for creating in-game phone applications with customizable functionality and appearance. + /// Abstract base class for creating custom applications to be used within an in-game phone system. /// /// - /// Implementations of this class enable the creation of bespoke applications that integrate seamlessly into a game's phone system. - /// Derived classes are required to define key properties and methods, such as application name, icon, and UI behavior. - /// This class also manages the app's lifecycle, including its initialization and destruction processes. + /// This class provides an extensible framework for defining application behaviors, user interface elements, + /// and registration mechanics for integration into the phone's ecosystem. /// public abstract class PhoneApp : Registerable { /// - /// INTERNAL: A dedicated logger for all custom phone apps. + /// Logger instance used for logging messages, warnings, or errors + /// related to the functionality of in-game phone applications. /// protected static readonly MelonLogger.Instance LoggerInstance = new MelonLogger.Instance("PhoneApp"); /// - /// The player object in the scene. - /// - private GameObject? _player; - - /// - /// The in-game UI panel representing the app. + /// Represents the panel associated with the phone app's UI. + /// This is dynamically instantiated or retrieved when the app is initiated and serves as the container + /// for the app's user interface elements within the phone system. The panel exists within the + /// app canvas structure in the game's Unity hierarchy. /// private GameObject? _appPanel; - // TODO (@omar-akermi): Can you look into if this is still needed pls? /// - /// Whether the app was successfully created. + /// Indicates whether the application UI has been successfully created and initialized. /// + /// + /// This variable is used internally to track the state of the application's UI. + /// When set to true, it denotes that the app UI panel has been created and configured. + /// private bool _appCreated; /// - /// Whether the app icon was already modified. + /// Indicates whether the phone application icon has been modified. + /// This flag prevents redundant modification of the icon once it has already + /// been updated or created. /// private bool _iconModified; /// - /// Unique GameObject name of the app (e.g. "SilkroadApp"). + /// Gets the unique identifier for the application within the phone system. /// + /// + /// This property is used as a key to identify the application when creating UI elements or interacting with other components + /// of the in-game phone system. It must be implemented in derived classes to provide a consistent and unique name for + /// the application. + /// protected abstract string AppName { get; } /// - /// The title shown at the top of the app UI. + /// Gets the display title of the application as it appears in the in-game phone system. /// + /// + /// This property specifies the human-readable name of the application, different from the internal + /// AppName that uniquely identifies the app within the system. It is displayed to the user + /// on the application icon or within the application UI. + /// protected abstract string AppTitle { get; } - + /// - /// The label shown under the app icon on the home screen. + /// Gets the label text displayed on the application's icon. /// + /// + /// The IconLabel property is an abstract member that must be overridden by each implementation + /// of the class. It specifies the label text shown directly below the application's + /// icon on the in-game phone's home screen. + /// This property is utilized when creating or modifying the app's icon, as part of the SpawnIcon method, + /// to ensure that the label represents the application's name or a relevant description. The value should + /// be concise and contextually meaningful to the user. + /// + /// + /// A string representing the label text displayed under the app icon, which explains or identifies + /// the app to the user. + /// protected abstract string IconLabel { get; } /// - /// The PNG file name (in UserData) used for the app icon. + /// Specifies the file name of the icon used to represent the phone application in the in-game phone system. /// + /// + /// The value of this property is typically a string containing the file name of the icon asset, + /// such as "icon-name.png". It is used to identify and load the appropriate icon for the application. + /// protected abstract string IconFileName { get; } /// - /// Called when the app's UI should be created inside the container. + /// Invoked to define the user interface layout when the application panel is created. + /// The method is used to populate the provided container with custom UI elements specific to the application. /// - /// The container GameObject to build into. + /// The GameObject container where the application's UI elements will be added. protected abstract void OnCreatedUI(GameObject container); /// - /// Called when the app is loaded into the scene (delayed after phone UI is present). + /// Invoked when the PhoneApp instance is created. + /// Responsible for registering the app with the PhoneAppRegistry, + /// integrating it into the in-game phone system. /// protected override void OnCreated() { - MelonCoroutines.Start(InitApp()); + PhoneAppRegistry.Register(this); } /// - /// Called when the app is unloaded or the scene is reset. + /// Cleans up resources and resets state when the app is destroyed. + /// This method ensures any associated UI elements and resources are properly disposed of and variables tracking the app state are reset. /// protected override void OnDestroyed() { @@ -95,24 +127,19 @@ protected override void OnDestroyed() } /// - /// Coroutine that injects the app UI and icon after scene/UI has loaded. + /// Generates and initializes the UI panel for the application within the in-game phone system. + /// This method locates the parent container in the UI hierarchy, clones a template panel if needed, + /// clears its content, and then invokes the implementation-specific OnCreatedUI method + /// for further customization of the UI panel. /// - private IEnumerator InitApp() + internal void SpawnUI() { - yield return new WaitForSeconds(5f); - - _player = GameObject.Find("Player_Local"); - if (_player == null) - { - LoggerInstance.Error("Player_Local not found."); - yield break; - } - - GameObject appsCanvas = GameObject.Find("Player_Local/CameraContainer/Camera/OverlayCamera/GameplayMenu/Phone/phone/AppsCanvas"); + GameObject appsCanvas = + GameObject.Find("Player_Local/CameraContainer/Camera/OverlayCamera/GameplayMenu/Phone/phone/AppsCanvas"); if (appsCanvas == null) { LoggerInstance.Error("AppsCanvas not found."); - yield break; + return; } Transform existingApp = appsCanvas.transform.Find(AppName); @@ -127,7 +154,7 @@ private IEnumerator InitApp() if (templateApp == null) { LoggerInstance.Error("Template ProductManagerApp not found."); - yield break; + return; } _appPanel = Object.Instantiate(templateApp.gameObject, appsCanvas.transform); @@ -145,17 +172,46 @@ private IEnumerator InitApp() } _appPanel.SetActive(true); + } + + /// + /// Creates or modifies the application icon displayed on the in-game phone's home screen. + /// This method clones an existing icon, updates its label, and changes its image based on the provided file name. + /// + internal void SpawnIcon() + { + if (_iconModified) + return; - if (!_iconModified) + GameObject parent = GameObject.Find("Player_Local/CameraContainer/Camera/OverlayCamera/GameplayMenu/Phone/phone/HomeScreen/AppIcons/"); + if (parent == null) + { + LoggerInstance.Error("AppIcons not found."); + return; + } + + Transform? lastIcon = parent.transform.childCount > 0 ? parent.transform.GetChild(parent.transform.childCount - 1) : null; + if (lastIcon == null) { - _iconModified = ModifyAppIcon(IconLabel, IconFileName); + LoggerInstance.Error("No icon found to clone."); + return; } + + GameObject iconObj = lastIcon.gameObject; + iconObj.name = AppName; + + Transform labelTransform = iconObj.transform.Find("Label"); + Text? label = labelTransform?.GetComponent(); + if (label != null) + label.text = IconLabel; + + _iconModified = ChangeAppIconImage(iconObj, IconFileName); } /// - /// Configures the provided GameObject panel to prepare it for use with the app. + /// Configures an existing app panel by clearing and rebuilding its UI elements if necessary. /// - /// The GameObject representing the UI panel of the app. + /// The app panel to configure, represented as a GameObject. private void SetupExistingAppPanel(GameObject panel) { Transform containerTransform = panel.transform.Find("Container"); @@ -172,6 +228,10 @@ private void SetupExistingAppPanel(GameObject panel) _appCreated = true; } + /// + /// Removes all child objects from the specified container to clear its contents. + /// + /// The parent GameObject whose child objects will be destroyed. private void ClearContainer(GameObject container) { for (int i = container.transform.childCount - 1; i >= 0; i--) @@ -179,63 +239,28 @@ private void ClearContainer(GameObject container) } /// - /// Modifies the application's icon by cloning an existing icon, updating its label, - /// and setting a new icon image based on the specified parameters. + /// Changes the image of the app icon based on the specified filename, and applies the new icon to the given GameObject. /// - /// The text to be displayed as the label for the modified icon. - /// The file name of the new icon image to apply. + /// The GameObject representing the app icon that will have its image changed. + /// The name of the file containing the new icon image to be loaded. /// - /// A boolean value indicating whether the icon modification was successful. - /// Returns true if the modification was completed successfully; otherwise, false. + /// A boolean value indicating whether the operation was successful. + /// Returns true if the image was successfully loaded and applied; otherwise, returns false. /// - private bool ModifyAppIcon(string labelText, string fileName) - { - GameObject parent = GameObject.Find("Player_Local/CameraContainer/Camera/OverlayCamera/GameplayMenu/Phone/phone/HomeScreen/AppIcons/"); - if (parent == null) - { - LoggerInstance?.Error("AppIcons not found."); - return false; - } - - Transform? lastIcon = parent.transform.childCount > 0 ? parent.transform.GetChild(parent.transform.childCount - 1) : null; - if (lastIcon == null) - { - LoggerInstance?.Error("No icon found to clone."); - return false; - } - - GameObject iconObj = lastIcon.gameObject; - iconObj.name = AppName; - - Transform labelTransform = iconObj.transform.Find("Label"); - Text? label = labelTransform?.GetComponent(); - if (label != null) - label.text = labelText; - - return ChangeAppIconImage(iconObj, fileName); - } - - - /// - /// Updates the app icon image with the specified file if the corresponding Image component is found and the file exists. - /// - /// The GameObject representing the app icon whose image is to be updated. - /// The name of the image file to be loaded and applied as the icon. - /// True if the icon image was successfully updated, otherwise false. private bool ChangeAppIconImage(GameObject iconObj, string filename) { Transform imageTransform = iconObj.transform.Find("Mask/Image"); Image? image = imageTransform?.GetComponent(); if (image == null) { - LoggerInstance?.Error("Image component not found in icon."); + LoggerInstance.Error("Image component not found in icon."); return false; } string path = Path.Combine(MelonEnvironment.ModsDirectory, filename); if (!File.Exists(path)) { - LoggerInstance?.Error("Icon file not found: " + path); + LoggerInstance.Error("Icon file not found: " + path); return false; } @@ -252,7 +277,7 @@ private bool ChangeAppIconImage(GameObject iconObj, string filename) } catch (System.Exception e) { - LoggerInstance?.Error("Failed to load image: " + e.Message); + LoggerInstance.Error("Failed to load image: " + e.Message); } return false; From abdb0f54b0e5a3492b6261278e46ebfe16613225 Mon Sep 17 00:00:00 2001 From: Omar Akermi Date: Sun, 27 Apr 2025 14:25:06 +0200 Subject: [PATCH 25/42] refactor: dynamic finding --- S1API/Internal/Patches/HomeScreen.Start.cs | 56 ++++++++++------------ S1API/Internal/Patches/PhoneAppPatches.cs | 20 ++++---- S1API/Internal/Patches/PhoneAppRegistry.cs | 6 +-- S1API/PhoneApp/PhoneApp.cs | 42 +++++++++------- 4 files changed, 63 insertions(+), 61 deletions(-) diff --git a/S1API/Internal/Patches/HomeScreen.Start.cs b/S1API/Internal/Patches/HomeScreen.Start.cs index ab8ab830..59930b41 100644 --- a/S1API/Internal/Patches/HomeScreen.Start.cs +++ b/S1API/Internal/Patches/HomeScreen.Start.cs @@ -1,53 +1,45 @@ using System; using HarmonyLib; -using Il2CppScheduleOne.UI.Phone; using UnityEngine.SceneManagement; using S1API.Internal.Utils; using S1API.Internal.Abstraction; using S1API.PhoneApp; +#if (IL2CPPMELON || IL2CPPBEPINEX) +using Il2CppScheduleOne.UI.Phone; +#else +using ScheduleOne.UI.Phone; +#endif -namespace S1API.Internal.Patches; - -/// -/// The HomeScreen_Start class contains functionality that patches the -/// HomeScreen's Start method using the Harmony library within the Il2CppScheduleOne UI.Phone namespace. -/// This class is part of the S1API.Internal.Patches namespace, enabling modification or extension -/// of the behavior of the HomeScreen component's Start method. -/// -public class HomeScreen_Start +namespace S1API.Internal.Patches { /// - /// Represents a patch class for modifying the behavior of the Start method in the HomeScreen class. - /// This class is implemented as part of the Harmony patching mechanism to apply modifications - /// or inject additional logic during the execution of the Start method. + /// The HomeScreen_Start class contains functionality that patches the + /// HomeScreen's Start method using the Harmony library within the Il2CppScheduleOne UI.Phone namespace. + /// This class is part of the S1API.Internal.Patches namespace, enabling modification or extension + /// of the behavior of the HomeScreen component's Start method. /// - [HarmonyPatch(typeof(HomeScreen), "Start")] - internal static class HomeScreen_Start_Patch + public class HomeScreen_Start { /// - /// Postfix method to modify the behavior of the HomeScreen's Start method after it is executed. + /// Represents a patch class for modifying the behavior of the Start method in the HomeScreen class. + /// This class is implemented as part of the Harmony patching mechanism to apply modifications + /// or inject additional logic during the execution of the Start method. /// - /// - /// This method iterates over the list of registered phone applications and performs initialization for each app. - /// It ensures that the UI panel and the app icon for each application are created and properly configured. - /// If an error occurs during this process, a warning is logged with relevant details. - /// - static void Postfix() + [HarmonyPatch(typeof(HomeScreen), "Start")] + internal static class HomeScreen_Start_Patch { - foreach (var app in PhoneAppRegistry.RegisteredApps) + static void Postfix(HomeScreen __instance) { - try - { - app.SpawnUI(); // Clone ProductManagerApp, clear container, call OnCreatedUI - app.SpawnIcon(); // Clone last HomeScreen icon, set label + icon image - } - catch (Exception e) + if (__instance == null) + return; + + foreach (var app in PhoneAppRegistry.RegisteredApps) { - MelonLoader.MelonLogger.Warning($"[PhoneApp] Failed to spawn UI for {app.GetType().Name}: {e.Message}"); + app.SpawnUI(__instance); + app.SpawnIcon(__instance); } } } - } - + } } \ No newline at end of file diff --git a/S1API/Internal/Patches/PhoneAppPatches.cs b/S1API/Internal/Patches/PhoneAppPatches.cs index 0229638b..b13f3049 100644 --- a/S1API/Internal/Patches/PhoneAppPatches.cs +++ b/S1API/Internal/Patches/PhoneAppPatches.cs @@ -3,6 +3,7 @@ using UnityEngine.SceneManagement; using S1API.Internal.Utils; using S1API.Internal.Abstraction; +using S1API.Logging; using S1API.PhoneApp; namespace S1API.Internal.Patches @@ -15,8 +16,7 @@ namespace S1API.Internal.Patches #endif internal static class PhoneAppPatches { - // TODO (@omar-akermi): Can you look into if this is still needed pls? - private static bool _loaded = false; + private static readonly Log Logger = new Log("PhoneApp"); /// /// Executes logic after the Unity SceneManager completes loading a scene. @@ -27,11 +27,12 @@ internal static class PhoneAppPatches /// The loading mode used by the SceneManager. static void Postfix(Scene scene, LoadSceneMode mode) { - if (scene.name != "Main") return; - - // Re-register all PhoneApps every time the Main scene loads - var phoneApp = ReflectionUtils.GetDerivedClasses(); - foreach (var type in phoneApp) + if (scene.name != "Main") + { + return; + } + var phoneApps = ReflectionUtils.GetDerivedClasses(); + foreach (var type in phoneApps) { if (type.GetConstructor(Type.EmptyTypes) == null) continue; @@ -40,11 +41,12 @@ static void Postfix(Scene scene, LoadSceneMode mode) var instance = (PhoneApp.PhoneApp)Activator.CreateInstance(type)!; ((IRegisterable)instance).CreateInternal(); } - catch (System.Exception e) + catch (Exception e) { - MelonLoader.MelonLogger.Warning($"[PhoneApp] Failed to register {type.FullName}: {e.Message}"); + Logger.Error($"Failed to create instance of {type.Name}: {e}"); } } } + } } \ No newline at end of file diff --git a/S1API/Internal/Patches/PhoneAppRegistry.cs b/S1API/Internal/Patches/PhoneAppRegistry.cs index 996162da..af62c2b3 100644 --- a/S1API/Internal/Patches/PhoneAppRegistry.cs +++ b/S1API/Internal/Patches/PhoneAppRegistry.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace S1API.PhoneApp +namespace S1API.Internal.Patches { /// /// Provides functionality for managing the registration of custom phone applications. @@ -22,13 +22,13 @@ internal static class PhoneAppRegistry /// It serves as a central repository for all in-game phone applications, enabling other systems to access and manage /// these registered apps efficiently. /// - public static readonly List RegisteredApps = new(); + public static readonly List RegisteredApps = new List(); /// /// Registers a specified phone app into the phone application registry. /// /// The PhoneApp instance to be registered. - public static void Register(PhoneApp app) + public static void Register(PhoneApp.PhoneApp app) { RegisteredApps.Add(app); } diff --git a/S1API/PhoneApp/PhoneApp.cs b/S1API/PhoneApp/PhoneApp.cs index 0b9033fd..daffd049 100644 --- a/S1API/PhoneApp/PhoneApp.cs +++ b/S1API/PhoneApp/PhoneApp.cs @@ -5,7 +5,12 @@ using Object = UnityEngine.Object; using MelonLoader.Utils; using S1API.Internal.Abstraction; - +using S1API.Internal.Patches; +#if IL2CPPBEPINEX || IL2CPPMELON +using Il2CppScheduleOne.UI.Phone; +#else +using ScheduleOne.UI.Phone; +#endif namespace S1API.PhoneApp { /// @@ -21,7 +26,7 @@ public abstract class PhoneApp : Registerable /// Logger instance used for logging messages, warnings, or errors /// related to the functionality of in-game phone applications. /// - protected static readonly MelonLogger.Instance LoggerInstance = new MelonLogger.Instance("PhoneApp"); + protected static readonly Logging.Log Logger = new Logging.Log("PhoneApp"); /// /// Represents the panel associated with the phone app's UI. @@ -132,13 +137,12 @@ protected override void OnDestroyed() /// clears its content, and then invokes the implementation-specific OnCreatedUI method /// for further customization of the UI panel. /// - internal void SpawnUI() + internal void SpawnUI(HomeScreen homeScreenInstance) { - GameObject appsCanvas = - GameObject.Find("Player_Local/CameraContainer/Camera/OverlayCamera/GameplayMenu/Phone/phone/AppsCanvas"); + GameObject? appsCanvas = homeScreenInstance.transform.parent.Find("AppsCanvas")?.gameObject; if (appsCanvas == null) { - LoggerInstance.Error("AppsCanvas not found."); + Logger.Error("AppsCanvas not found."); return; } @@ -153,7 +157,7 @@ internal void SpawnUI() Transform templateApp = appsCanvas.transform.Find("ProductManagerApp"); if (templateApp == null) { - LoggerInstance.Error("Template ProductManagerApp not found."); + Logger.Error("Template ProductManagerApp not found."); return; } @@ -178,36 +182,40 @@ internal void SpawnUI() /// Creates or modifies the application icon displayed on the in-game phone's home screen. /// This method clones an existing icon, updates its label, and changes its image based on the provided file name. /// - internal void SpawnIcon() + internal void SpawnIcon(HomeScreen homeScreenInstance) { if (_iconModified) return; - GameObject parent = GameObject.Find("Player_Local/CameraContainer/Camera/OverlayCamera/GameplayMenu/Phone/phone/HomeScreen/AppIcons/"); - if (parent == null) + GameObject? appIcons = homeScreenInstance.transform.Find("AppIcons")?.gameObject; + if (appIcons == null) { - LoggerInstance.Error("AppIcons not found."); + Logger.Error("AppIcons not found under HomeScreen."); return; } - Transform? lastIcon = parent.transform.childCount > 0 ? parent.transform.GetChild(parent.transform.childCount - 1) : null; + // Find the LAST icon (the one most recently added) + Transform? lastIcon = appIcons.transform.childCount > 0 ? appIcons.transform.GetChild(appIcons.transform.childCount - 1) : null; if (lastIcon == null) { - LoggerInstance.Error("No icon found to clone."); + Logger.Error("No icons found in AppIcons."); return; } GameObject iconObj = lastIcon.gameObject; - iconObj.name = AppName; + iconObj.name = AppName; // Rename it now + // Update label Transform labelTransform = iconObj.transform.Find("Label"); Text? label = labelTransform?.GetComponent(); if (label != null) label.text = IconLabel; + // Update image _iconModified = ChangeAppIconImage(iconObj, IconFileName); } + /// /// Configures an existing app panel by clearing and rebuilding its UI elements if necessary. /// @@ -253,14 +261,14 @@ private bool ChangeAppIconImage(GameObject iconObj, string filename) Image? image = imageTransform?.GetComponent(); if (image == null) { - LoggerInstance.Error("Image component not found in icon."); + Logger.Error("Image component not found in icon."); return false; } string path = Path.Combine(MelonEnvironment.ModsDirectory, filename); if (!File.Exists(path)) { - LoggerInstance.Error("Icon file not found: " + path); + Logger.Error("Icon file not found: " + path); return false; } @@ -277,7 +285,7 @@ private bool ChangeAppIconImage(GameObject iconObj, string filename) } catch (System.Exception e) { - LoggerInstance.Error("Failed to load image: " + e.Message); + Logger.Error("Failed to load image: " + e.Message); } return false; From 6ac6b813627eb67d472c63a19b528e18b25b16b3 Mon Sep 17 00:00:00 2001 From: Omar Akermi Date: Sun, 27 Apr 2025 14:39:58 +0200 Subject: [PATCH 26/42] move PhoneAppPatches.cs into HomeScreen.Start.cs --- S1API/Internal/Patches/HomeScreen.Start.cs | 49 ++++++++++++++++---- S1API/Internal/Patches/PhoneAppPatches.cs | 52 ---------------------- 2 files changed, 40 insertions(+), 61 deletions(-) delete mode 100644 S1API/Internal/Patches/PhoneAppPatches.cs diff --git a/S1API/Internal/Patches/HomeScreen.Start.cs b/S1API/Internal/Patches/HomeScreen.Start.cs index 59930b41..d779da14 100644 --- a/S1API/Internal/Patches/HomeScreen.Start.cs +++ b/S1API/Internal/Patches/HomeScreen.Start.cs @@ -4,6 +4,8 @@ using S1API.Internal.Utils; using S1API.Internal.Abstraction; using S1API.PhoneApp; +using S1API.Logging; + #if (IL2CPPMELON || IL2CPPBEPINEX) using Il2CppScheduleOne.UI.Phone; #else @@ -13,17 +15,47 @@ namespace S1API.Internal.Patches { /// - /// The HomeScreen_Start class contains functionality that patches the - /// HomeScreen's Start method using the Harmony library within the Il2CppScheduleOne UI.Phone namespace. - /// This class is part of the S1API.Internal.Patches namespace, enabling modification or extension - /// of the behavior of the HomeScreen component's Start method. + /// Patches related to PhoneApp system initialization and UI injection. /// public class HomeScreen_Start { + private static readonly Log Logger = new Log("PhoneApp"); + + /// + /// Patches SceneManager scene loading to register all PhoneApps after Main scene loads. + /// +#if (IL2CPPMELON || IL2CPPBEPINEX) + [HarmonyPatch(typeof(SceneManager), nameof(SceneManager.Internal_SceneLoaded))] +#else + [HarmonyPatch(typeof(SceneManager), "Internal_SceneLoaded", new Type[] { typeof(Scene), typeof(LoadSceneMode) })] +#endif + internal static class PhoneAppPatches + { + static void Postfix(Scene scene, LoadSceneMode mode) + { + if (scene.name != "Main") + return; + + var phoneApps = ReflectionUtils.GetDerivedClasses(); + foreach (var type in phoneApps) + { + if (type.GetConstructor(Type.EmptyTypes) == null) continue; + + try + { + var instance = (PhoneApp.PhoneApp)Activator.CreateInstance(type)!; + ((IRegisterable)instance).CreateInternal(); + } + catch (Exception e) + { + Logger.Error($"Failed to create instance of {type.Name}: {e}"); + } + } + } + } + /// - /// Represents a patch class for modifying the behavior of the Start method in the HomeScreen class. - /// This class is implemented as part of the Harmony patching mechanism to apply modifications - /// or inject additional logic during the execution of the Start method. + /// Patches HomeScreen.Start to spawn registered PhoneApp UIs and icons. /// [HarmonyPatch(typeof(HomeScreen), "Start")] internal static class HomeScreen_Start_Patch @@ -40,6 +72,5 @@ static void Postfix(HomeScreen __instance) } } } - } -} \ No newline at end of file +} diff --git a/S1API/Internal/Patches/PhoneAppPatches.cs b/S1API/Internal/Patches/PhoneAppPatches.cs deleted file mode 100644 index b13f3049..00000000 --- a/S1API/Internal/Patches/PhoneAppPatches.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using HarmonyLib; -using UnityEngine.SceneManagement; -using S1API.Internal.Utils; -using S1API.Internal.Abstraction; -using S1API.Logging; -using S1API.PhoneApp; - -namespace S1API.Internal.Patches -{ -#if (IL2CPPMELON || IL2CPPBEPINEX) - [HarmonyPatch(typeof(SceneManager), nameof(SceneManager.Internal_SceneLoaded))] -#else - [HarmonyPatch(typeof(SceneManager), "Internal_SceneLoaded", new Type[] { typeof(Scene), typeof(LoadSceneMode) })] - -#endif - internal static class PhoneAppPatches - { - private static readonly Log Logger = new Log("PhoneApp"); - - /// - /// Executes logic after the Unity SceneManager completes loading a scene. - /// Registers all derived implementations of the PhoneApp class during the loading - /// process of the "Main" scene. - /// - /// The scene that has been loaded. - /// The loading mode used by the SceneManager. - static void Postfix(Scene scene, LoadSceneMode mode) - { - if (scene.name != "Main") - { - return; - } - var phoneApps = ReflectionUtils.GetDerivedClasses(); - foreach (var type in phoneApps) - { - if (type.GetConstructor(Type.EmptyTypes) == null) continue; - - try - { - var instance = (PhoneApp.PhoneApp)Activator.CreateInstance(type)!; - ((IRegisterable)instance).CreateInternal(); - } - catch (Exception e) - { - Logger.Error($"Failed to create instance of {type.Name}: {e}"); - } - } - } - - } -} \ No newline at end of file From 5cfb6d896b6a68e63bc21c160049536e14c4f3cc Mon Sep 17 00:00:00 2001 From: Omar Akermi Date: Mon, 28 Apr 2025 00:21:14 +0200 Subject: [PATCH 27/42] fix references ? --- S1API/PhoneApp/PhoneApp.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/S1API/PhoneApp/PhoneApp.cs b/S1API/PhoneApp/PhoneApp.cs index daffd049..a6aff653 100644 --- a/S1API/PhoneApp/PhoneApp.cs +++ b/S1API/PhoneApp/PhoneApp.cs @@ -1,15 +1,18 @@ using System.IO; using UnityEngine; using UnityEngine.UI; -using MelonLoader; using Object = UnityEngine.Object; -using MelonLoader.Utils; using S1API.Internal.Abstraction; using S1API.Internal.Patches; #if IL2CPPBEPINEX || IL2CPPMELON +using MelonLoader; +using MelonLoader.Utils; using Il2CppScheduleOne.UI.Phone; #else using ScheduleOne.UI.Phone; +using MelonLoader; +using MelonLoader.Utils; +using Il2CppScheduleOne.UI.Phone; #endif namespace S1API.PhoneApp { From c0fc1ad29fef708908254bc10e200ec246c5d77c Mon Sep 17 00:00:00 2001 From: Omar Akermi Date: Mon, 28 Apr 2025 00:37:49 +0200 Subject: [PATCH 28/42] pls work --- S1API/PhoneApp/PhoneApp.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/S1API/PhoneApp/PhoneApp.cs b/S1API/PhoneApp/PhoneApp.cs index a6aff653..43212650 100644 --- a/S1API/PhoneApp/PhoneApp.cs +++ b/S1API/PhoneApp/PhoneApp.cs @@ -268,7 +268,11 @@ private bool ChangeAppIconImage(GameObject iconObj, string filename) return false; } +#if MONOMELON || IL2CPPMELON string path = Path.Combine(MelonEnvironment.ModsDirectory, filename); +#elif MONOBEPINEX || IL2CPPBEPINEX + string path = Path.Combine(BepInEx.Paths.PluginPath, filename); +#endif if (!File.Exists(path)) { Logger.Error("Icon file not found: " + path); From 63f41e3b00c7f82670ebe3566c8b61e7ce4bcfed Mon Sep 17 00:00:00 2001 From: Omar Akermi Date: Mon, 28 Apr 2025 00:39:38 +0200 Subject: [PATCH 29/42] last one --- S1API/PhoneApp/PhoneApp.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/S1API/PhoneApp/PhoneApp.cs b/S1API/PhoneApp/PhoneApp.cs index 43212650..c618d924 100644 --- a/S1API/PhoneApp/PhoneApp.cs +++ b/S1API/PhoneApp/PhoneApp.cs @@ -4,15 +4,15 @@ using Object = UnityEngine.Object; using S1API.Internal.Abstraction; using S1API.Internal.Patches; -#if IL2CPPBEPINEX || IL2CPPMELON +#if (IL2CPPMELON || MONOMELON) using MelonLoader; using MelonLoader.Utils; +#endif + +#if (IL2CPPBEPINEX || IL2CPPMONO) using Il2CppScheduleOne.UI.Phone; -#else +#elif (MONOBEPINEX || MONOMELON) using ScheduleOne.UI.Phone; -using MelonLoader; -using MelonLoader.Utils; -using Il2CppScheduleOne.UI.Phone; #endif namespace S1API.PhoneApp { From fdd37d8782a4dad525fc493c658db686c57c6614 Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Sun, 27 Apr 2025 17:44:52 -0500 Subject: [PATCH 30/42] fix: Resolved issue with missing ' in references --- S1API/S1API.csproj | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/S1API/S1API.csproj b/S1API/S1API.csproj index a28f1c2d..fbc93d6b 100644 --- a/S1API/S1API.csproj +++ b/S1API/S1API.csproj @@ -37,15 +37,15 @@ - - - - + + + + - - - - + + + + From ea40e0db66866ac6feaa2691701aae7b4589aa56 Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Sun, 27 Apr 2025 18:03:24 -0500 Subject: [PATCH 31/42] fix: Allowed net6.0 build for S1API (possible hacky solution to allow GitHub action to succeed) --- S1APILoader/S1APILoader.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/S1APILoader/S1APILoader.csproj b/S1APILoader/S1APILoader.csproj index 7fdb89ee..b1f35e40 100644 --- a/S1APILoader/S1APILoader.csproj +++ b/S1APILoader/S1APILoader.csproj @@ -6,7 +6,7 @@ - netstandard2.1 + netstandard2.1;net6.0 enable Il2CppMelon;MonoBepInEx;MonoMelon;Il2CppBepInEx AnyCPU From e28a85c0a46396725c6a2cab114b714692725571 Mon Sep 17 00:00:00 2001 From: Omar Akermi Date: Mon, 28 Apr 2025 01:09:40 +0200 Subject: [PATCH 32/42] refactor homescreen --- S1API/Internal/Patches/HomeScreen.Start.cs | 71 +++++++++------------- S1API/PhoneApp/PhoneApp.cs | 14 +++-- 2 files changed, 36 insertions(+), 49 deletions(-) diff --git a/S1API/Internal/Patches/HomeScreen.Start.cs b/S1API/Internal/Patches/HomeScreen.Start.cs index d779da14..be76234d 100644 --- a/S1API/Internal/Patches/HomeScreen.Start.cs +++ b/S1API/Internal/Patches/HomeScreen.Start.cs @@ -15,62 +15,47 @@ namespace S1API.Internal.Patches { /// - /// Patches related to PhoneApp system initialization and UI injection. + /// A Harmony patch for the Start method of the HomeScreen class, facilitating the registration and initialization of PhoneApps. /// - public class HomeScreen_Start + [HarmonyPatch(typeof(HomeScreen), "Start")] + internal static class HomeScreen_Start_Patch { + /// + /// A logging instance used for handling log messages pertaining to PhoneApp registration + /// and operations. Provides methods to log messages with different severity levels such + /// as Info, Warning, Error, and Fatal. + /// private static readonly Log Logger = new Log("PhoneApp"); /// - /// Patches SceneManager scene loading to register all PhoneApps after Main scene loads. + /// Executes after the HomeScreen's Start method to handle the registration + /// and initialization of PhoneApps. /// -#if (IL2CPPMELON || IL2CPPBEPINEX) - [HarmonyPatch(typeof(SceneManager), nameof(SceneManager.Internal_SceneLoaded))] -#else - [HarmonyPatch(typeof(SceneManager), "Internal_SceneLoaded", new Type[] { typeof(Scene), typeof(LoadSceneMode) })] -#endif - internal static class PhoneAppPatches + /// The HomeScreen instance being targeted in the patch. + static void Postfix(HomeScreen __instance) { - static void Postfix(Scene scene, LoadSceneMode mode) + if (__instance == null) + return; + + // Re-register all PhoneApps + var phoneApps = ReflectionUtils.GetDerivedClasses(); + foreach (var type in phoneApps) { - if (scene.name != "Main") - return; + if (type.GetConstructor(Type.EmptyTypes) == null) + continue; - var phoneApps = ReflectionUtils.GetDerivedClasses(); - foreach (var type in phoneApps) + try { - if (type.GetConstructor(Type.EmptyTypes) == null) continue; - - try - { - var instance = (PhoneApp.PhoneApp)Activator.CreateInstance(type)!; - ((IRegisterable)instance).CreateInternal(); - } - catch (Exception e) - { - Logger.Error($"Failed to create instance of {type.Name}: {e}"); - } + var instance = (PhoneApp.PhoneApp)Activator.CreateInstance(type)!; + ((IRegisterable)instance).CreateInternal(); + instance.SpawnUI(__instance); + instance.SpawnIcon(__instance); } - } - } - - /// - /// Patches HomeScreen.Start to spawn registered PhoneApp UIs and icons. - /// - [HarmonyPatch(typeof(HomeScreen), "Start")] - internal static class HomeScreen_Start_Patch - { - static void Postfix(HomeScreen __instance) - { - if (__instance == null) - return; - - foreach (var app in PhoneAppRegistry.RegisteredApps) + catch (Exception e) { - app.SpawnUI(__instance); - app.SpawnIcon(__instance); + Logger.Warning($"[PhoneApp] Failed to register {type.FullName}: {e.Message}"); } } } } -} +} \ No newline at end of file diff --git a/S1API/PhoneApp/PhoneApp.cs b/S1API/PhoneApp/PhoneApp.cs index c618d924..8bb0885f 100644 --- a/S1API/PhoneApp/PhoneApp.cs +++ b/S1API/PhoneApp/PhoneApp.cs @@ -1,18 +1,20 @@ using System.IO; +using Il2CppScheduleOne.UI.Phone; using UnityEngine; using UnityEngine.UI; using Object = UnityEngine.Object; using S1API.Internal.Abstraction; using S1API.Internal.Patches; -#if (IL2CPPMELON || MONOMELON) -using MelonLoader; +#if IL2CPPMELON +using Il2CppScheduleOne.UI.Phone; using MelonLoader.Utils; -#endif - -#if (IL2CPPBEPINEX || IL2CPPMONO) +#elif IL2CPPBEPINEX using Il2CppScheduleOne.UI.Phone; -#elif (MONOBEPINEX || MONOMELON) +#elif MONOBEPINEX +using ScheduleOne.UI.Phone; +#elif MONOMELON using ScheduleOne.UI.Phone; +using MelonLoader.Utils; #endif namespace S1API.PhoneApp { From f3ba4f2b297148eebf1b0cd8f9f0c459df7ae7b5 Mon Sep 17 00:00:00 2001 From: Omar Akermi Date: Mon, 28 Apr 2025 01:14:01 +0200 Subject: [PATCH 33/42] fix S1API.cs --- S1API/S1API.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/S1API/S1API.cs b/S1API/S1API.cs index ba4eaa7b..117a16d3 100644 --- a/S1API/S1API.cs +++ b/S1API/S1API.cs @@ -12,8 +12,9 @@ public class S1API : MelonMod { } } -#elif (MONOBEPINEX || IL2CPPBEPINEX) +#elif (IL2CPPBEPINEX) using BepInEx; +#elif MONOBEPINEX using BepInEx.Unity.Mono; using HarmonyLib; From b0800adf3a2872b4fdd09235145470576696bb4f Mon Sep 17 00:00:00 2001 From: Omar Akermi Date: Mon, 28 Apr 2025 01:20:19 +0200 Subject: [PATCH 34/42] should work --- S1API/PhoneApp/PhoneApp.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/S1API/PhoneApp/PhoneApp.cs b/S1API/PhoneApp/PhoneApp.cs index 8bb0885f..f0b426fd 100644 --- a/S1API/PhoneApp/PhoneApp.cs +++ b/S1API/PhoneApp/PhoneApp.cs @@ -1,5 +1,4 @@ using System.IO; -using Il2CppScheduleOne.UI.Phone; using UnityEngine; using UnityEngine.UI; using Object = UnityEngine.Object; From 475b0fbdb074f061bc698d05c5385820c163381e Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Sun, 27 Apr 2025 18:30:07 -0500 Subject: [PATCH 35/42] fix: Resolved missing BepInEx reference --- S1API/S1API.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/S1API/S1API.cs b/S1API/S1API.cs index 117a16d3..68f0a542 100644 --- a/S1API/S1API.cs +++ b/S1API/S1API.cs @@ -12,10 +12,11 @@ public class S1API : MelonMod { } } -#elif (IL2CPPBEPINEX) +#elif (IL2CPPBEPINEX || MONOBEPINEX) using BepInEx; -#elif MONOBEPINEX +#if MONOBEPINEX using BepInEx.Unity.Mono; +#endif using HarmonyLib; From 139408b9fe69fb07e804e21efb98cef7091ec085 Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Sun, 27 Apr 2025 18:31:38 -0500 Subject: [PATCH 36/42] fix: Resolved missing BepInEx reference --- S1API/S1API.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/S1API/S1API.cs b/S1API/S1API.cs index 68f0a542..fdcf8160 100644 --- a/S1API/S1API.cs +++ b/S1API/S1API.cs @@ -14,8 +14,11 @@ public class S1API : MelonMod } #elif (IL2CPPBEPINEX || MONOBEPINEX) using BepInEx; + #if MONOBEPINEX using BepInEx.Unity.Mono; +#elif IL2CPPBEPINEX +using BepInEx.Unity.IL2CPP; #endif using HarmonyLib; From 413b925b1597f1da055ba2d93d14ef65df3c10c4 Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Sun, 27 Apr 2025 18:41:25 -0500 Subject: [PATCH 37/42] fix: Resolved BepInEx Il2Cpp/Mono differences --- S1API/S1API.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/S1API/S1API.cs b/S1API/S1API.cs index fdcf8160..76da5219 100644 --- a/S1API/S1API.cs +++ b/S1API/S1API.cs @@ -26,9 +26,18 @@ public class S1API : MelonMod namespace S1API { [BepInPlugin(MyPluginInfo.PLUGIN_GUID, MyPluginInfo.PLUGIN_NAME, MyPluginInfo.PLUGIN_VERSION)] - public class S1API : BaseUnityPlugin + public class S1API : +#if MONOBEPINEX + BaseUnityPlugin +#elif IL2CPPBEPINEX + BasePlugin +#endif { +#if MONOBEPINEX private void Awake() +#elif IL2CPPBEPINEX + public override void Load() +#endif { new Harmony("com.S1API").PatchAll(); } From 6a8b19049afffee07769924caca9eaed2ae4d943 Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Sun, 27 Apr 2025 18:41:45 -0500 Subject: [PATCH 38/42] fix: Disabling BepInEx building until it can be properly built locally --- .github/workflows/deploy-build.yml | 17 +++++++++-------- .github/workflows/verify-build.yml | 13 +++++++------ 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/.github/workflows/deploy-build.yml b/.github/workflows/deploy-build.yml index 07f4d251..d5b1e4d5 100644 --- a/.github/workflows/deploy-build.yml +++ b/.github/workflows/deploy-build.yml @@ -56,11 +56,12 @@ jobs: sed -i "s/{VERSION_NUMBER}/${{ steps.semantic-release.outputs.new_release_version }}/" ./S1API/S1API.cs sed -i "s/{VERSION_NUMBER}/${{ steps.semantic-release.outputs.new_release_version }}/" ./S1APILoader/S1APILoader.cs - - name: Run .NET build for MonoBepInEx - run: dotnet build ./S1API.sln -c MonoBepInEx -f netstandard2.1 - - - name: Run .NET build for Il2CppBepInEx - run: dotnet build ./S1API.sln -c Il2CppBepInEx -f net6.0 +# TODO (@MaxtorCoder): Temporarily disabling until BepInEx is building properly locally. +# - name: Run .NET build for MonoBepInEx +# run: dotnet build ./S1API.sln -c MonoBepInEx -f netstandard2.1 +# +# - name: Run .NET build for Il2CppBepInEx +# run: dotnet build ./S1API.sln -c Il2CppBepInEx -f net6.0 - name: Run .NET build for MonoMelon run: dotnet build ./S1API.sln -c MonoMelon -f netstandard2.1 @@ -72,11 +73,11 @@ jobs: run: | mkdir -p ./artifacts/thunderstore/Plugins/S1API cp ./S1APILoader/bin/MonoMelon/netstandard2.1/S1APILoader.dll ./artifacts/thunderstore/Plugins/S1APILoader.MelonLoader.dll - cp ./S1APILoader/bin/MonoBepInEx/netstandard2.1/S1APILoader.dll ./artifacts/thunderstore/Plugins/S1APILoader.BepInEx.dll +# cp ./S1APILoader/bin/MonoBepInEx/netstandard2.1/S1APILoader.dll ./artifacts/thunderstore/Plugins/S1APILoader.BepInEx.dll cp ./S1API/bin/Il2CppMelon/net6.0/S1API.dll ./artifacts/thunderstore/Plugins/S1API/S1API.Il2Cpp.MelonLoader.dll cp ./S1API/bin/MonoMelon/netstandard2.1/S1API.dll ./artifacts/thunderstore/Plugins/S1API/S1API.Mono.MelonLoader.dll - cp ./S1API/bin/Il2CppMelon/net6.0/S1API.dll ./artifacts/thunderstore/Plugins/S1API/S1API.Il2Cpp.BepInEx.dll - cp ./S1API/bin/MonoMelon/netstandard2.1/S1API.dll ./artifacts/thunderstore/Plugins/S1API/S1API.Mono.BepInEx.dll +# cp ./S1API/bin/Il2CppMelon/net6.0/S1API.dll ./artifacts/thunderstore/Plugins/S1API/S1API.Il2Cpp.BepInEx.dll +# cp ./S1API/bin/MonoMelon/netstandard2.1/S1API.dll ./artifacts/thunderstore/Plugins/S1API/S1API.Mono.BepInEx.dll - name: Publish artifact to Thunderstore uses: GreenTF/upload-thunderstore-package@v4.3 diff --git a/.github/workflows/verify-build.yml b/.github/workflows/verify-build.yml index 04ae7715..1cdef91b 100644 --- a/.github/workflows/verify-build.yml +++ b/.github/workflows/verify-build.yml @@ -27,12 +27,13 @@ jobs: - name: Restore .NET Dependencies run: dotnet restore - - - name: Run .NET build for MonoBepInEx - run: dotnet build ./S1API.sln -c MonoBepInEx -f netstandard2.1 - - - name: Run .NET build for Il2CppBepInEx - run: dotnet build ./S1API.sln -c Il2CppBepInEx -f net6.0 + +# TODO (@MaxtorCoder): Temporarily disabling until BepInEx is building properly locally. +# - name: Run .NET build for MonoBepInEx +# run: dotnet build ./S1API.sln -c MonoBepInEx -f netstandard2.1 +# +# - name: Run .NET build for Il2CppBepInEx +# run: dotnet build ./S1API.sln -c Il2CppBepInEx -f net6.0 - name: Run .NET build for MonoMelon run: dotnet build ./S1API.sln -c MonoMelon -f netstandard2.1 From 908e1010cdfa0793be7514c109e3b33278adb220 Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Sun, 27 Apr 2025 19:22:49 -0500 Subject: [PATCH 39/42] fix: Updated .csprojs to use new build configs --- S1API/S1API.csproj | 8 ++++---- S1APILoader/S1APILoader.csproj | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/S1API/S1API.csproj b/S1API/S1API.csproj index fbc93d6b..fc6e8191 100644 --- a/S1API/S1API.csproj +++ b/S1API/S1API.csproj @@ -96,13 +96,13 @@ - - + + - - + + diff --git a/S1APILoader/S1APILoader.csproj b/S1APILoader/S1APILoader.csproj index b1f35e40..b664e6a4 100644 --- a/S1APILoader/S1APILoader.csproj +++ b/S1APILoader/S1APILoader.csproj @@ -20,13 +20,13 @@ - + - + - + - + From 696f482fb47ca2ebebc1e57f4a6a597cf8df423d Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Sun, 27 Apr 2025 19:23:07 -0500 Subject: [PATCH 40/42] fix: Switched to renames to satisfy TSMM --- S1APILoader/S1APILoader.cs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/S1APILoader/S1APILoader.cs b/S1APILoader/S1APILoader.cs index 4c53f247..13daaded 100644 --- a/S1APILoader/S1APILoader.cs +++ b/S1APILoader/S1APILoader.cs @@ -17,20 +17,22 @@ public override void OnPreModsLoaded() if (pluginsFolder == null) throw new Exception("Failed to identify plugins folder."); - string buildsFolder = Path.Combine(pluginsFolder, BuildFolderName); + string modsFolder = Path.Combine(pluginsFolder, "../Mods"); string activeBuild = MelonUtils.IsGameIl2Cpp() ? "Il2Cpp" : "Mono"; + string inactiveBuild = !MelonUtils.IsGameIl2Cpp() ? "Il2Cpp" : "Mono"; + MelonLogger.Msg($"Loading S1API for {activeBuild}..."); - string s1APIBuildFile = Path.Combine(buildsFolder, $"S1API.{activeBuild}.dll"); + string s1APIActiveBuildFile = Path.Combine(modsFolder, $"S1API.{activeBuild}.dll"); + string s1APIInactiveBuildFile = Path.Combine(modsFolder, $"S1API.{inactiveBuild}.dll"); - // FIX: https://github.com/KaBooMa/S1API/issues/30 - // Manual assembly loading versus file manipulation. - // Thunderstore doesn't pick it up if we do file manipulation. - Assembly assembly = Assembly.LoadFile(s1APIBuildFile); - MelonAssembly melonAssembly = MelonAssembly.LoadMelonAssembly(s1APIBuildFile, assembly); - foreach (MelonBase melon in melonAssembly.LoadedMelons) - melon.Register(); + string disabledActiveBuildFile = $"{s1APIActiveBuildFile}.disabled"; + if (File.Exists(disabledActiveBuildFile)) + File.Move($"{s1APIActiveBuildFile}.disabled", s1APIActiveBuildFile); + + if (File.Exists(s1APIInactiveBuildFile)) + File.Move(s1APIInactiveBuildFile, $"{s1APIInactiveBuildFile}.disabled"); MelonLogger.Msg($"Successfully loaded S1API for {activeBuild}!"); } From 43ec5c5f5ef8546df7abad2aced72b9c15dfc1ed Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Sun, 27 Apr 2025 19:30:57 -0500 Subject: [PATCH 41/42] fix: Updated deployment to Mods/ folder --- .github/workflows/deploy-build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-build.yml b/.github/workflows/deploy-build.yml index d5b1e4d5..7655e5e4 100644 --- a/.github/workflows/deploy-build.yml +++ b/.github/workflows/deploy-build.yml @@ -72,10 +72,10 @@ jobs: - name: Build artifact zip for Thunderstore run: | mkdir -p ./artifacts/thunderstore/Plugins/S1API - cp ./S1APILoader/bin/MonoMelon/netstandard2.1/S1APILoader.dll ./artifacts/thunderstore/Plugins/S1APILoader.MelonLoader.dll + cp ./S1APILoader/bin/MonoMelon/netstandard2.1/S1APILoader.dll ./artifacts/thunderstore/Plugins/S1APILoader.dll # cp ./S1APILoader/bin/MonoBepInEx/netstandard2.1/S1APILoader.dll ./artifacts/thunderstore/Plugins/S1APILoader.BepInEx.dll - cp ./S1API/bin/Il2CppMelon/net6.0/S1API.dll ./artifacts/thunderstore/Plugins/S1API/S1API.Il2Cpp.MelonLoader.dll - cp ./S1API/bin/MonoMelon/netstandard2.1/S1API.dll ./artifacts/thunderstore/Plugins/S1API/S1API.Mono.MelonLoader.dll + cp ./S1API/bin/Il2CppMelon/net6.0/S1API.dll ./artifacts/thunderstore/Mods/S1API.Il2Cpp.MelonLoader.dll + cp ./S1API/bin/MonoMelon/netstandard2.1/S1API.dll ./artifacts/thunderstore/Mods/S1API.Mono.MelonLoader.dll # cp ./S1API/bin/Il2CppMelon/net6.0/S1API.dll ./artifacts/thunderstore/Plugins/S1API/S1API.Il2Cpp.BepInEx.dll # cp ./S1API/bin/MonoMelon/netstandard2.1/S1API.dll ./artifacts/thunderstore/Plugins/S1API/S1API.Mono.BepInEx.dll From 282ed8d761fff4d5620045edbaaa45ce0e285bb7 Mon Sep 17 00:00:00 2001 From: KaBooMa Date: Sun, 27 Apr 2025 19:31:10 -0500 Subject: [PATCH 42/42] fix: Added MelonLoader to filename for future BepInEx support --- S1APILoader/S1APILoader.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/S1APILoader/S1APILoader.cs b/S1APILoader/S1APILoader.cs index 13daaded..d52334d7 100644 --- a/S1APILoader/S1APILoader.cs +++ b/S1APILoader/S1APILoader.cs @@ -24,8 +24,8 @@ public override void OnPreModsLoaded() MelonLogger.Msg($"Loading S1API for {activeBuild}..."); - string s1APIActiveBuildFile = Path.Combine(modsFolder, $"S1API.{activeBuild}.dll"); - string s1APIInactiveBuildFile = Path.Combine(modsFolder, $"S1API.{inactiveBuild}.dll"); + string s1APIActiveBuildFile = Path.Combine(modsFolder, $"S1API.{activeBuild}.MelonLoader.dll"); + string s1APIInactiveBuildFile = Path.Combine(modsFolder, $"S1API.{inactiveBuild}.MelonLoader.dll"); string disabledActiveBuildFile = $"{s1APIActiveBuildFile}.disabled"; if (File.Exists(disabledActiveBuildFile))