예제 #1
0
        public PlayerEntity LoadPlayer(string name)
        {
            PlayerEntity entity = new PlayerEntity(Difficulty);
            if (LevelDirectory == null || !File.Exists(Path.Combine(LevelDirectory, "players", name + ".dat")))
            {
                // Return default player entity
                entity.Position = SpawnPoint;
                entity.SpawnPoint = SpawnPoint;
                entity.Position += new Vector3(0, PlayerEntity.Height, 0);
                entity.GameMode = GameMode;
                return entity;
            }
            
            NbtFile file = new NbtFile();
            using (Stream stream = File.Open(Path.Combine(LevelDirectory, "players", name + ".dat"), FileMode.Open))
                file.LoadFromStream(stream, NbtCompression.GZip, null);
            var data = file.RootTag;
            entity.OnGround = data.Get<NbtByte>("OnGround").Value == 1;
            entity.Air = data.Get<NbtShort>("Air").Value;
            entity.Health = data.Get<NbtShort>("Health").Value;
            Dimension dimension = (Dimension)data.Get<NbtInt>("Dimension").Value; // TODO
            entity.Food = (short)data.Get<NbtInt>("foodLevel").Value;
            entity.XpLevel = data.Get<NbtInt>("XpLevel").Value;
            entity.XpTotal = data.Get<NbtInt>("XpTotal").Value;
            // TODO: Set velocity based on fall distance
            entity.FoodExhaustion = data.Get<NbtFloat>("foodExhaustionLevel").Value;
            entity.FoodSaturation = data.Get<NbtFloat>("foodSaturationLevel").Value;
            entity.XpProgress = data.Get<NbtFloat>("XpP").Value;

            var equipment = data.Get<NbtList>("Equipment");
            var inventory = data.Get<NbtList>("Inventory");
            var motion = data.Get<NbtList>("Motion");
            var pos = data.Get<NbtList>("Pos");
            var rotation = data.Get<NbtList>("Rotation");
            var abilities = data.Get<NbtCompound>("abilities");

            // Appears to be unused, is overriden by the inventory contents
            // foreach (var item in equipment.Tags)

            foreach (var item in inventory)
            {
                var slot = Slot.FromNbt((NbtCompound)item);
                slot.Index = DataSlotToNetworkSlot(slot.Index);
                entity.Inventory[slot.Index] = slot;
            }

            entity.Velocity = new Vector3(
                ((NbtDouble)motion[0]).Value,
                ((NbtDouble)motion[1]).Value,
                ((NbtDouble)motion[2]).Value);

            entity.Position = new Vector3(
                ((NbtDouble)pos[0]).Value,
                ((NbtDouble)pos[1]).Value,
                ((NbtDouble)pos[2]).Value);

            if (data.Get<NbtInt>("SpawnX") != null)
            {
                entity.SpawnPoint = new Vector3(
                    data.Get<NbtInt>("SpawnX").Value,
                    data.Get<NbtInt>("SpawnY").Value,
                    data.Get<NbtInt>("SpawnZ").Value);
            }

            entity.Yaw = ((NbtFloat)rotation[0]).Value;
            entity.Pitch = ((NbtFloat)rotation[1]).Value;

            // TODO: Abilities

            return entity;
        }
예제 #2
0
 /// <summary>
 /// Retrieves the requested chunk from the region, or
 /// generates it if a world generator is provided.
 /// </summary>
 /// <param name="position">The position of the requested local chunk coordinates.</param>
 public Chunk GetChunk(Vector3 position)
 {
     // TODO: This could use some refactoring
     lock (Chunks)
     {
         if (!Chunks.ContainsKey(position))
         {
             if (regionFile != null)
             {
                 // Search the stream for that region
                 lock (regionFile)
                 {
                     var chunkData = GetChunkFromTable(position);
                     if (chunkData == null)
                     {
                         if (WorldGenerator == null)
                             throw new ArgumentException("The requested chunk is not loaded.", "position");
                         Chunks.Add(position, WorldGenerator.GenerateChunk(position, this));
                         return Chunks[position];
                     }
                     regionFile.Seek(chunkData.Item1, SeekOrigin.Begin);
                     int length = new MinecraftStream(regionFile).ReadInt32(); // TODO: Avoid making new objects here, and in the WriteInt32
                     int compressionMode = regionFile.ReadByte();
                     switch (compressionMode)
                     {
                         case 1: // gzip
                             break;
                         case 2: // zlib
                             var nbt = new NbtFile();
                             nbt.LoadFromStream(regionFile, NbtCompression.ZLib, null);
                             var chunk = Chunk.FromNbt(position, nbt);
                             chunk.ParentRegion = this;
                             Chunks.Add(position, chunk);
                             break;
                         default:
                             throw new InvalidDataException("Invalid compression scheme provided by region file.");
                     }
                 }
             }
             else if (WorldGenerator == null)
                 throw new ArgumentException("The requested chunk is not loaded.", "position");
             else
                 Chunks.Add(position, WorldGenerator.GenerateChunk(position, this));
         }
         return Chunks[position];
     }
 }
예제 #3
0
        private void LoadFromFile(string directory)
        {
            NbtFile file = new NbtFile();
            using (var stream = File.Open(Path.Combine(LevelDirectory, "level.dat"), FileMode.Open))
                file.LoadFromStream(stream, NbtCompression.None, null);
            var data = file.RootTag.Get<NbtCompound>("Data");
            var serializer = new NbtSerializer(typeof(SavedLevel));
            SavedLevel level = (SavedLevel)serializer.Deserialize(data);
            Name = level.LevelName;
            Time = level.Time;
            GameMode = (GameMode)level.GameMode;
            MapFeatures = level.MapFeatures;
            Seed = level.Seed;
            // Find world generator
            string generatorName = level.GeneratorName;
            WorldGenerator = GetGenerator(generatorName);
            WorldGenerator.Seed = Seed;
                GeneratorOptions = level.GeneratorOptions;
            WorldGenerator.Initialize(this);

            SpawnPoint = level.SpawnPoint;

            World = new World(this, WorldGenerator, Path.Combine(directory, "region"));
        }