/// <summary> /// Handles the ObjectDestroyed event. Only DataAccess should call this directly. /// </summary> /// <param name="source">The object raising the event</param> /// <param name="args">The generic event args</param> override protected void OnObjectDestroyed(object source, CacheObjectEventArgs args) { // Safely remove players without deleting/disconnecting them var players = Animates.GetAllEntitiesAsObjects <Player>(); foreach (var player in players) { Animates.RemoveEntity(player?.Instance, player); } DataAccess.Remove <EntityContainer>(args.CacheType == CacheType.Instance ? Animates.Instance : Animates.Prototype, args.CacheType); DataAccess.Remove <EntityContainer>(args.CacheType == CacheType.Instance ? Items.Instance : Items.Prototype, args.CacheType); DataAccess.Remove <EntityContainer>(args.CacheType == CacheType.Instance ? ShopItems.Instance : ShopItems.Prototype, args.CacheType); DataAccess.Remove <EntityContainer>(args.CacheType == CacheType.Instance ? StorageItems.Instance : StorageItems.Prototype, args.CacheType); }
/// <summary> /// Spawns an instance of the room from prototype and adds it to the cache. /// </summary> /// <param name="withEntities">Whether to also spawn contained entities</param> /// <param name="parent">The parent area instance ID</param> /// <returns>The instance ID of the spawned room. Will return null if the method is called from an instanced object.</returns> /// <remarks>Exits will all be null and must be fixed from prototype. Parent cannot be null. Adds new room to instanced area.</remarks> public override uint?Spawn(bool withEntities, uint parent) { if (CacheType != CacheType.Prototype) { return(null); } var parentContainer = DataAccess.Get <EntityContainer>(parent, CacheType.Instance); var parentArea = DataAccess.Get <Area>(parentContainer.InstanceParent, CacheType.Instance); if (parentContainer == null || parentArea == null) { throw new LocaleException("Parent cannot be null when spawning a room."); } Logger.Info(nameof(Room), nameof(Spawn), "Spawning room: " + Name + ": ProtoID=" + Prototype.ToString()); // Create new instance room and add to parent area var newRoom = DataAccess.Get <Room>(DataAccess.Add <Room>(new Room(), CacheType.Instance), CacheType.Instance); parentArea.Rooms.AddEntity(newRoom.Instance, newRoom, false); // Set remaining properties newRoom.Prototype = Prototype; CopyTo(newRoom); // Spawn contained entities if (withEntities) { newRoom.Animates = Animates.SpawnAsObject <EntityContainer>(!withEntities, (uint)newRoom.Instance); foreach (var animate in Animates.GetAllEntitiesAsObjects <EntityAnimate>()) { animate.Spawn(withEntities, (uint)newRoom.Animates.Instance); } newRoom.Items = Items.SpawnAsObject <EntityContainer>(!withEntities, (uint)newRoom.Instance); foreach (var item in Items.GetAllEntitiesAsObjects <EntityInanimate>()) { item.Spawn(withEntities, (uint)newRoom.Items.Instance); } newRoom.ShopItems = ShopItems.SpawnAsObject <EntityContainer>(!withEntities, (uint)newRoom.Instance); foreach (var item in ShopItems.GetAllEntitiesAsObjects <EntityInanimate>()) { item.Spawn(withEntities, (uint)newRoom.ShopItems.Instance); } newRoom.StorageItems = StorageItems.SpawnAsObject <EntityContainer>(!withEntities, (uint)newRoom.Instance); foreach (var item in StorageItems.GetAllEntitiesAsObjects <EntityInanimate>()) { item.Spawn(withEntities, (uint)newRoom.StorageItems.Instance); } } else { newRoom.Animates = Animates.SpawnAsObject <EntityContainer>(!withEntities, (uint)newRoom.Instance); newRoom.Items = Items.SpawnAsObject <EntityContainer>(!withEntities, (uint)newRoom.Instance); newRoom.ShopItems = ShopItems.SpawnAsObject <EntityContainer>(!withEntities, (uint)newRoom.Instance); newRoom.StorageItems = StorageItems.SpawnAsObject <EntityContainer>(!withEntities, (uint)newRoom.Instance); } Logger.Info(nameof(Room), nameof(Spawn), "Finished spawning room."); return(newRoom.Instance); }