Ejemplo n.º 1
0
        /// <summary>
        /// Spawns an instance of the world from prototype and adds it to the cache.
        /// </summary>
        /// <param name="withEntities">Whether to also spawn contained areas.</param>
        /// <param name="parent">The parent instance ID; ignored</param>
        /// <returns>The instance ID of the spawned world. Will return null if the method is called from an instanced object.</returns>
        public override uint?Spawn(bool withEntities, uint parent)
        {
            if (CacheType != CacheType.Prototype)
            {
                return(null);
            }

            Logger.Info(nameof(World), nameof(Spawn), "Spawning world: " + Name + ": ProtoID=" + Prototype.ToString());

            // Create new instance world
            var newWorld = DataAccess.Get <World>(DataAccess.Add <World>(new World(), CacheType.Instance), CacheType.Instance);

            // Set remaining properties
            newWorld.Prototype = Prototype;
            CopyTo(newWorld);

            // Spawn contained areas
            if (withEntities)
            {
                newWorld.Areas = Areas.SpawnAsObject <EntityContainer>(!withEntities, (uint)newWorld.Instance);
                foreach (var area in Areas.GetAllEntitiesAsObjects <Area>())
                {
                    area.Spawn(withEntities, (uint)newWorld.Areas.Instance);
                }
            }
            else
            {
                newWorld.Areas = Areas.SpawnAsObject <EntityContainer>(!withEntities, (uint)newWorld.Instance);
            }

            newWorld.StartingLocation = DataAccess.GetInstancesOfPrototype <Room>(StartingLocation).FirstOrDefault()?.Instance;

            Logger.Info(nameof(World), nameof(LoadWorld), "Linking instanced room exits.");
            RoomExits.LinkInstancedRoomExits();

            Logger.Info(nameof(World), nameof(LoadWorld), "Fixing null exits.");
            RoomExits.FixNullExits(CacheType.Instance);

            Logger.Info(nameof(World), nameof(Spawn), "Finished spawning world.");

            return(newWorld.Instance);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Loads a new prototype world.
        /// </summary>
        /// <param name="instantiate">Whether to also instantiate all loaded prototypes</param>
        /// <param name="basePath">The location of the world to load</param>
        /// <remarks>If this is called on a world that has already been loaded, it will be wiped from the cache and reloaded.</remarks>
        public World LoadWorld(bool instantiate, string basePath = null)
        {
            // Remove the current world from the prototype cache in case it is being reloaded
            DataAccess.Remove <World>(Prototype, CacheType.Prototype);

            World newWorld = new World
            {
                IsLoading = true,
                CacheType = CacheType.Prototype
            };

            newWorld.Areas.CacheType = CacheType.Prototype;

            // Set read path
            if (basePath == "" || basePath == null)
            {
                basePath = DataPersistence.PersistencePath;
            }

            if (!basePath.EndsWith(@"\"))
            {
                basePath += @"\";
            }

            string[] world;

            try
            {
                world = Directory.GetFiles(basePath + typeof(World).ToString(), @"*.json");
            }
            catch
            {
                // No world was found in the filesystem
                newWorld           = NewPrototype();
                newWorld.IsLoading = true;

                world = Directory.GetFiles(basePath + typeof(World).ToString(), @"*.json");
            }

            var areas      = new string[0];
            var rooms      = new string[0];
            var containers = new string[0];
            var mobs       = new string[0];
            var potions    = new string[0];
            var statics    = new string[0];
            var weapons    = new string[0];

            if (Directory.Exists(basePath + typeof(Area).ToString()))
            {
                areas = Directory.GetFiles(basePath + typeof(Area).ToString(), @"*.json");
            }

            if (Directory.Exists(basePath + typeof(Room).ToString()))
            {
                rooms = Directory.GetFiles(basePath + typeof(Room).ToString(), @"*.json");
            }

            if (Directory.Exists(basePath + typeof(EntityContainer).ToString()))
            {
                containers = Directory.GetFiles(basePath + typeof(EntityContainer).ToString(), @"*.json");
            }

            if (Directory.Exists(basePath + typeof(Mob).ToString()))
            {
                mobs = Directory.GetFiles(basePath + typeof(Mob).ToString(), @"*.json");
            }

            if (Directory.Exists(basePath + typeof(ItemPotion).ToString()))
            {
                potions = Directory.GetFiles(basePath + typeof(ItemPotion).ToString(), @"*.json");
            }

            if (Directory.Exists(basePath + typeof(ItemStatic).ToString()))
            {
                statics = Directory.GetFiles(basePath + typeof(ItemStatic).ToString(), @"*.json");
            }

            if (Directory.Exists(basePath + typeof(ItemWeapon).ToString()))
            {
                weapons = Directory.GetFiles(basePath + typeof(ItemWeapon).ToString(), @"*.json");
            }

            // Load containers
            foreach (var container in containers)
            {
                // Add container prototype
                var newContainer = new EntityContainer();
                DataPersistence.LoadObject(container, out newContainer);

                newWorld.WorldLoaded += newContainer.World_HandleLoaded;

                // Add to cache
                try
                {
                    DataAccess.Add <EntityContainer>(newContainer, CacheType.Prototype, newContainer.Prototype, false);
                }
                catch (ArgumentException ex)
                {
                    // The container was already added to the cache as a result of creating a new world
                    continue;
                }
            }

            // Load world
            foreach (var w in world)
            {
                DataPersistence.LoadObject(w, out newWorld);
                try
                {
                    DataAccess.Add <World>(newWorld, CacheType.Prototype, newWorld.Prototype, false);
                }
                catch (ArgumentException ex)
                {
                    // The world was already added to the cache as a result of creating a new world
                    continue;
                }
            }

            // Load rooms
            foreach (var room in rooms)
            {
                // Add room prototype
                var newRoom = new Room();
                DataPersistence.LoadObject(room, out newRoom);

                // Add to cache
                DataAccess.Add <Room>(newRoom, CacheType.Prototype, newRoom.Prototype, false);
            }

            // Load areas
            foreach (var area in areas)
            {
                // Add area prototype
                var newArea = new Area();
                DataPersistence.LoadObject(area, out newArea);

                // Add to cache
                DataAccess.Add <Area>(newArea, CacheType.Prototype, newArea.Prototype, false);
            }

            // Load mobs
            foreach (var mob in mobs)
            {
                var newMob = new Mob();
                DataPersistence.LoadObject(mob, out newMob);

                // Add to cache
                DataAccess.Add <Mob>(newMob, CacheType.Prototype, newMob.Prototype, false);
            }

            // Load items
            foreach (var item in statics)
            {
                var newItem = new ItemStatic();
                DataPersistence.LoadObject(item, out newItem);

                // Add to cache
                DataAccess.Add <ItemStatic>(newItem, CacheType.Prototype, newItem.Prototype, false);
            }

            // Load potions
            foreach (var item in potions)
            {
                var newPotion = new ItemPotion();
                DataPersistence.LoadObject(item, out newPotion);

                // Add to cache
                DataAccess.Add <ItemStatic>(newPotion, CacheType.Prototype, newPotion.Prototype, false);
            }

            // Load weapons
            foreach (var weapon in weapons)
            {
                var newWeapon = new ItemWeapon();
                DataPersistence.LoadObject(weapon, out newWeapon);

                // Add to cache
                DataAccess.Add <ItemWeapon>(newWeapon, CacheType.Prototype, newWeapon.Prototype, false);
            }

            // Add entities to containers
            // OnWorldLoaded(new EventArgs());

            // Fix prototype null exits
            RoomExits.FixNullExits(CacheType.Prototype);

            newWorld.IsLoading = false;

            if (instantiate)
            {
                Logger.Info(nameof(World), nameof(LoadWorld), "Instantiating world.");
                newWorld = newWorld.SpawnAsObject <World>(instantiate, 0);

                Logger.Info(nameof(World), nameof(LoadWorld), "Finished instantiating world.");
            }

            return(newWorld);
        }