// // SceneManager.cs // // Copyright (c) František Boháček. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using NosSmooth.LocalBinding.Errors; using NosSmooth.LocalBinding.Extensions; using NosSmooth.LocalBinding.Options; using Reloaded.Memory.Sources; using Remora.Results; namespace NosSmooth.LocalBinding.Structs; /// /// Represents nostale scene manager struct. /// public class SceneManager { /// /// Create instance. /// /// The NosTale process browser. /// The options. /// The player manager or an error. public static Result Create(ExternalNosBrowser nosBrowser, SceneManagerOptions options) { var characterObjectAddress = nosBrowser.Scanner.CompiledFindPattern(options.SceneManagerObjectPattern); if (!characterObjectAddress.Found) { return new BindingNotFoundError(options.SceneManagerObjectPattern, "SceneManager"); } if (nosBrowser.Process.MainModule is null) { return new NotFoundError("Cannot find the main module of the target process."); } int staticManagerAddress = (int)nosBrowser.Process.MainModule.BaseAddress + characterObjectAddress.Offset; return new SceneManager(nosBrowser.Memory, staticManagerAddress, options.SceneManagerOffsets); } private readonly int[] _sceneManagerOffsets; private readonly IMemory _memory; private readonly int _staticSceneManagerAddress; /// /// Initializes a new instance of the class. /// /// The memory. /// The pointer to the scene manager. /// The offsets from the static scene manager address. public SceneManager(IMemory memory, int staticSceneManagerAddress, int[] sceneManagerOffsets) { _memory = memory; _staticSceneManagerAddress = staticSceneManagerAddress; _sceneManagerOffsets = sceneManagerOffsets; } /// /// Gets the address of the scene manager. /// public IntPtr Address => _memory.FollowStaticAddressOffsets(_staticSceneManagerAddress, _sceneManagerOffsets); /// /// Gets the player list. /// public MapObjBaseList PlayerList => new MapObjBaseList(_memory, ReadPtr(Address + 0xC)); /// /// Gets the monster list. /// public MapObjBaseList MonsterList => new MapObjBaseList(_memory, ReadPtr(Address + 0x10)); /// /// Gets the npc list. /// public MapObjBaseList NpcList => new MapObjBaseList(_memory, ReadPtr(Address + 0x14)); /// /// Gets the item list. /// public MapObjBaseList ItemList => new MapObjBaseList(_memory, ReadPtr(Address + 0x18)); /// /// Gets the entity that is currently being followed by the player. /// public MapBaseObj? FollowEntity { get { var ptr = ReadPtr(Address + 0x48); if (ptr == IntPtr.Zero) { return null; } return new MapBaseObj(_memory, ptr); } } private IntPtr ReadPtr(IntPtr ptr) { _memory.Read(ptr, out int read); return (IntPtr)read; } }