Пример #1
0
        public void ReadAll()
        {
            CustomPostprocessor.DoImports = false;
            try
            {
                BinaryReader reader = new BinaryReader(new MemoryStream(data));
                reader.SkipBytes(16);
                reader.SkipBytes(12);

                Archive arc = null;

                while (reader.BaseStream.Position <= 90000)
                {
                    short entryType = reader.ReadInt16();
                    short subType = reader.ReadInt16();
                    short entryCount = reader.ReadInt16();
                    short entryIndex = reader.ReadInt16();
                    string name = reader.ReadNullTerminatedString();

                    if (reader.PeekChar() == 0)
                    {
                        reader.SkipByte();
                    }

                    if (entryType == 2)
                    {
                        arc = new Archive(name, AssetDatabase.LoadAssetAtPath("Assets/SilentHill3/Archives/" + name + ".arc", typeof(UnityEngine.Object)));
                        arc.OpenArchive();
                    }

                    if (entryType == 3)
                    {
                        try
                        {
                            name = name.Replace("tmp", arc.NameAsPath());
                            string path = "Assets/SilentHill3/Resources/" + name;
                            path = Path.GetDirectoryName(path);
                            if (!Directory.Exists(path))
                            {
                                Directory.CreateDirectory(path);
                            }
                            File.WriteAllBytes("Assets/SilentHill3/Resources/" + name, arc.AllFiles[entryCount].data);
                        }
                        catch (Exception)
                        {
                            Debug.LogError("Problem at " + name + " [" + entryIndex + "](" + arc.AllFiles.Count + ") sub " + subType.ToString("X"));
                        }
                    }
                }
                AssetDatabase.Refresh();
            }
            catch (Exception e)
            {
                Debug.LogException(e);
            }
            CustomPostprocessor.DoImports = true;
        }
Пример #2
0
        public static Texture2D[] ReadTex32(string baseName, BinaryReader reader)
        {
            reader.SkipBytes(12); //Skips -1 0 32
            /*int texGroupLength = */reader.ReadInt32();
            reader.SkipBytes(4); //Skips 0
            int texCount = reader.ReadInt32();
            reader.SkipBytes(8); //Skips 0 0

            List<Texture2D> textures = new List<Texture2D>(texCount);

            for (int i = 0; i != texCount; i++)
            {
                reader.SkipBytes(8); //Skips -1 0
                short width = reader.ReadInt16();
                short height = reader.ReadInt16();
                byte bits = reader.ReadByte();
                byte buffer = reader.ReadByte();
                reader.SkipBytes(2); //skips 0x0000
                int lengthOfTex = reader.ReadInt32();
                /*int nextDataRelativeOffset = */reader.ReadInt32();
                reader.SkipBytes(24 + buffer); //skips -1 0 0 0 0 0 + buffer

                Color32[] _pixels = null;
                if (bits == 32)
                {
                    _pixels = new Color32[lengthOfTex / 4];
                    for (int j = 0; j != lengthOfTex / 4; j++)
                    {
                        _pixels[j] = reader.ReadBGRA();
                    }
                }
                else if (bits == 16)
                {
                    _pixels = new Color32[lengthOfTex / 2];
                    for (int j = 0; j != lengthOfTex / 2; j ++)
                    {
                        _pixels[j] = reader.ReadRGBA5551();
                    }
                }

                Texture2D text = new Texture2D(width, height, TextureFormat.RGBA32, false);
                text.SetPixels32(_pixels);
                text.Apply();

                text.alphaIsTransparency = true;
                text.name = baseName + i;

                textures.Add(text);

            }

            return textures.ToArray();
        }
Пример #3
0
        public static int Deserialise(BinaryReader reader, GameObject parent)
        {
            GameObject go = new GameObject("Mesh Group");
            go.isStatic = true;
            MeshGroup group = go.AddComponent<MeshGroup>();
            go.transform.SetParent(parent.transform);

            int NextOffset = reader.ReadInt32();
            reader.SkipInt32(48);
            reader.SkipInt32(); // Length
            reader.SkipInt32(0);

            group.TextureGroup = reader.ReadInt32();
            group.TextureIndex = reader.ReadInt32();
            group.Unknown1 = reader.ReadInt32();
            reader.SkipInt32(0);

            reader.SkipBytes(16, 0);

            int next;
            do
            {
                next = SubMeshGroup.Deserialise(reader, go);
            } while (next != 0);

            return NextOffset;
        }
Пример #4
0
        public int MeshFlags; // 60 is normal, 124 is decal

        public static int Deserialise(BinaryReader reader, GameObject parent)
        {
            GameObject go = new GameObject("Mesh Part");
            MeshPart part = go.AddComponent<MeshPart>();
            part.transform.SetParent(parent.transform);

            long offset = reader.BaseStream.Position;

            int NextOffset = reader.ReadInt32();
            reader.SkipInt32(64);
            reader.SkipInt32();//Length 
            reader.SkipInt32(0);

            int VertexCount = reader.ReadInt32();
            part.ObjectType = reader.ReadInt32(); //1 = static, 2 = can be or not there, 3 = can move
            int val = reader.ReadInt32();
            part.OcclusionGroup = "0x" + val.ToString("X") + " 0b" + Convert.ToString(val, 2);
            part.MeshFlags = reader.ReadInt32();

            reader.SkipBytes(32, 0);

            go.isStatic = part.ObjectType != 3;

            Matrix4x4 matrix = part.GetComponentInParent<Scene>().GetSH3ToUnityMatrix();

            List<Vector3> _verts = new List<Vector3>();
            List<Vector3> _norms = new List<Vector3>();
            List<Vector2> _uvs = new List<Vector2>();
            List<Color32> _colors = new List<Color32>();
            for (int i = 0; i != VertexCount; i++)
            {
                Vector3 temp = reader.ReadVector3();
                temp.y = -temp.y;
                _verts.Add(matrix.MultiplyPoint(temp));

                temp = reader.ReadVector3();
                temp.x = -temp.x;
                temp.z = -temp.z;
                _norms.Add(temp);

                _uvs.Add(reader.ReadVector2());
                _colors.Add(reader.ReadBGRA());
            }

            Mesh mesh = MeshUtils.MakeStripped(_verts, _norms, _uvs, _colors);

            mesh.name = "mesh_" + offset;
            go.AddComponent<MeshFilter>().sharedMesh = mesh;
            go.AddComponent<MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;

            return NextOffset;
        }
Пример #5
0
        public static MapShadows ReadShadowCasters(string path)
        {
            string assetPath = path.Replace(".kg2", ".asset");
            GameObject subGO = Scene.BeginEditingPrefab(path, "Shadows");

            try
            {
                MapShadows casters = subGO.AddComponent<MapShadows>();

                BinaryReader reader = new BinaryReader(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read));

                if (reader.BaseStream.Length != 0)
                {

                    //Master header
                    reader.SkipInt32();
                    short casterCount = reader.ReadInt16();
                    reader.SkipBytes(10, 0);

                    Matrix4x4 transMat = casters.GetComponentInParent<Scene>().GetSH3ToUnityMatrix();

                    //Reading casters
                    for (int i = 0; i != casterCount; i++)
                    {
                        //Caster header
                        reader.SkipInt32(0);
                        /*short index = */reader.ReadInt16();
                        short shapeCounts = reader.ReadInt16();
                        reader.SkipBytes(16, 0);
                        /*Vector3 mainPivot = */reader.ReadShortVector3();
                        /*short casterGroup = */reader.ReadInt16();
                        Matrix4x4 mainMatrix = reader.ReadMatrix4x4();
                        Vector3 debugPosition = Matrix4x4Utils.ExtractTranslationFromMatrix(ref mainMatrix);
                        debugPosition.y = -debugPosition.y;
                        Vector3 currentNormal = Vector3.zero;

                        //reading shapes
                        for (int j = 0; j != shapeCounts; j++)
                        {
                            short countOfPoints = reader.ReadInt16();
                            short UnknownS1 = reader.ReadInt16();
                            /*short UnknownS2 = */reader.ReadInt16();
                            reader.SkipInt16(countOfPoints);
                            /*Vector3 pivot = */reader.ReadShortVector3();
                            short shapeGroup = reader.ReadInt16();

                            List<Vector3> _verts = new List<Vector3>();
                            List<Vector3> _norms = new List<Vector3>();

                            for (int k = 0; k != countOfPoints; )
                            {
                                Vector3 v = reader.ReadShortVector3();
                                short flag = reader.ReadInt16();

                                if (flag == 0)
                                {
                                    currentNormal = Vector3.Normalize(v);
                                }
                                else
                                {
                                    _verts.Add(transMat.MultiplyPoint(v + debugPosition));
                                    _norms.Add(currentNormal);
                                    k++;
                                }
                            }

                            Mesh mesh = null;
                            if (UnknownS1 == 6)
                            {
                                mesh = MeshUtils.MakeStripped(_verts, _norms, null, null, true);
                            }
                            else if (UnknownS1 == 5)
                            {
                                mesh = MeshUtils.MakeStrippedInverted(_verts, _norms);
                            }
                            else
                            {
                                mesh = MeshUtils.MakeSquare(_verts, _norms, null, null, true);
                            }

                            mesh.name = "shadowMesh_" + shapeGroup;
                            GameObject go = new GameObject("Shadow mesh");
                            go.transform.SetParent(subGO.transform);
                            go.AddComponent<MeshFilter>().sharedMesh = mesh;
                            MeshRenderer mr = go.AddComponent<MeshRenderer>();
                            mr.sharedMaterial = MaterialRolodex.defaultDiffuse;
                            mr.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.ShadowsOnly;


                            if (reader.BaseStream.Position % 16 != 0)
                            {
                                reader.SkipBytes(8, 0);
                            }
                        }
                    }
                }

                reader.Close();

                foreach (MeshFilter mf in subGO.GetComponentsInChildren<MeshFilter>())
                {
                    AssetDatabase.AddObjectToAsset(mf.sharedMesh, assetPath);
                }

                Scene.FinishEditingPrefab(path, subGO);

                return casters;

            }
            catch (Exception e)
            {
                Debug.LogException(e);
            }

            return null;
        }
Пример #6
0
        public static MapLights ReadLights(string path)
        {
            /*string assetPath = path.Replace(".ded", ".asset");*/
            GameObject subGO = Scene.BeginEditingPrefab(path, "Lights");

            try
            {
                MapLights lights = subGO.AddComponent<MapLights>();

                BinaryReader reader = new BinaryReader(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read));

                reader.SkipInt16(); //Usually the area's code
                reader.SkipInt16(); //Usually 1, saw a 20
                short globalLightsCount = reader.ReadInt16();
                reader.SkipInt16(0);
                short globalLightsOffset = reader.ReadInt16();
                reader.SkipInt16(0);
                reader.SkipBytes(8, 0);

                short weirdLightsCount = reader.ReadInt16();
                reader.SkipInt16(0);
                short weirdLightsOffset = reader.ReadInt16();
                reader.SkipInt16(0);
                reader.SkipBytes(8, 0);
                
                short lightsCount = reader.ReadInt16();
                reader.SkipInt16(0);
                short lightsOffset = reader.ReadInt16();
                reader.SkipInt16(0);

                reader.SkipBytes(40, 0);
                short ambientOffset = reader.ReadInt16();
                reader.SkipBytes(24, 0);

                Matrix4x4 transMat = lights.GetComponentInParent<Scene>().GetSH3ToUnityMatrix();

                reader.BaseStream.Position = globalLightsOffset;
                for (int i = 0; i != globalLightsCount; i++)
                {
                    GlobalLight gl = new GlobalLight();
                    gl.rotation = reader.ReadQuaternion();
                    gl.Unknown1 = reader.ReadVector3();
                    reader.SkipInt16(0);
                    gl.Unknown2 = reader.ReadInt16();
                    lights.globalLights.Add(gl);
                }

                reader.BaseStream.Position = weirdLightsOffset;
                for (int i = 0; i != weirdLightsCount; i++)
                {
                    LocalLight ll = new LocalLight();
                    ll.color = reader.ReadColor();
                    ll.Unknown1 = reader.ReadSingle();
                    ll.Range = reader.ReadSingle();
                    reader.SkipBytes(8, 0);
                    ll.position = reader.ReadVector3YInverted();
                    reader.SkipInt16(0x0);
                    ll.Unknown2 = reader.ReadInt16();
                    lights.weirdLights.Add(ll);
                }

                reader.BaseStream.Position = lightsOffset;
                for (int i = 0; i != lightsCount; i++)
                {
                    LocalLight ll = new LocalLight();
                    ll.color = reader.ReadColor();
                    ll.Unknown1 = reader.ReadSingle();
                    ll.Range = reader.ReadSingle();
                    reader.SkipBytes(8, 0);
                    ll.position = reader.ReadVector3YInverted();
                    reader.SkipInt16(0x0);
                    ll.Unknown2 = reader.ReadInt16();
                    lights.localLights.Add(ll);

                    GameObject lightGO = new GameObject("Light " + i);
                    lightGO.transform.SetParent(subGO.transform);
                    lightGO.transform.localPosition = transMat.MultiplyPoint(ll.position);

                    Light light = lightGO.AddComponent<Light>();
                    light.type = LightType.Point;
                    light.range = ll.Range * Scene.GLOBAL_SCALE;
                    light.color = ll.color;
                    light.intensity = 8.0f;
                    light.bounceIntensity = 1.0f;
                }

                reader.BaseStream.Position = ambientOffset;
                lights.Unknown1 = reader.ReadVector4();
                lights.Unknown2 = reader.ReadVector4();
                lights.ambientColor = reader.ReadColor();
                lights.Unknown3 = reader.ReadVector4();

                reader.Close();

                Scene.FinishEditingPrefab(path, subGO);

                return lights;

            }
            catch (Exception e)
            {
                Debug.LogException(e);
            }

            return null;
        }
Пример #7
0
        public static Texture2D[] ReadDDS(string baseName, BinaryReader reader)
        {
            reader.SkipInt32(2);
            int texturesSize = reader.ReadInt32();
            reader.SkipInt32(0);
            reader.SkipInt32(0);

            reader.SkipInt32(0x19990901); //magic
            reader.SkipInt32(0);
            reader.SkipInt32(0);
            reader.SkipInt32(1);

            List<Texture2D> textures = new List<Texture2D>();

            int i = 0;
            while (reader.BaseStream.Position < texturesSize)
            {
                short textureID = reader.ReadInt16();
                reader.SkipInt16(0);
                short width = reader.ReadInt16();
                short height = reader.ReadInt16();
                reader.SkipInt16(512);
                reader.SkipInt16(512);
                int subgroupsCount = reader.ReadInt32(); //1 more?

                reader.SkipInt16();
                reader.SkipInt16();
                reader.SkipBytes(12); //Skips 0 0 0

                int texLength = 0;
                for (int j = 0; j != subgroupsCount; j++)
                {
                    //Subgroup thingie
                    /*short subgroupID = */
                    reader.SkipInt16();
                    reader.SkipInt16();
                    reader.SkipInt16(0);
                    reader.SkipInt16(0);
                    reader.SkipInt16(512);
                    reader.SkipInt16(512);
                    reader.SkipInt16(256);
                    reader.SkipInt16(0);

                    texLength = reader.ReadInt32();
                    /*int texAndHeaderLength = */
                    reader.SkipInt32();
                    reader.SkipInt32(0);
                    reader.SkipUInt32(0x99000000);
                }

                Texture2D text = new Texture2D(width, height, TextureFormat.DXT1, false);
                text.LoadRawTextureData(reader.ReadBytes(texLength));
                text.Apply();

                text.alphaIsTransparency = true;
                text.name = baseName + textureID.ToString("0000");

                textures.Add(text);
                i++;
            }
            reader.SkipBytes(0x10);

            return textures.ToArray();
        }
Пример #8
0
            public CollisionPane(BinaryReader reader, Matrix4x4 transMat)
            {
                type = reader.ReadInt32();
                int vectorsToRead = reader.ReadInt32(); //Not neccessarely
                group = reader.ReadInt32(); //More like group
                reader.SkipInt32(0);

                if (type == 769)
                {
                    Vector3 vertex = reader.ReadVector3YInverted();
                    vectors = new Vector3[] { transMat.MultiplyPoint(vertex) };
                    reader.SkipSingle(1.0f);
                    offset = transMat.MultiplyPoint(reader.ReadVector3YInverted());
                    radius = reader.ReadSingle() * Scene.GLOBAL_SCALE;
                }
                else if (type == 257 || type == 1)
                {
                    List<Vector3> v3s = new List<Vector3>();
                    for (int i = 0; i != vectorsToRead; i++)
                    {
                        if (type == 1 && i != 0 && i % 3 == 0)
                        {
                            reader.SkipBytes(16);
                            continue;
                        }
                        Vector3 vertex = reader.ReadVector3YInverted();
                        v3s.Add(transMat.MultiplyPoint(vertex));
                        reader.SkipSingle(1.0f);
                    }
                    vectors = v3s.ToArray();
                    offset = Vector3.zero;
                    radius = 0.0f;
                }
                else
                {
                    Debug.LogWarning("UNHANDLED COLLIDER TYPE " + type + " FIX IT");
                }
            }
Пример #9
0
        static void ReadSH2Map(BinaryReader reader, Map scene, string path)
        {
            GameObject subGO = scene.gameObject;
            string assetPath = path.Replace(".map", ".asset");

            int fileID = reader.ReadInt32();
            int fileSize = reader.ReadInt32();
            int Unknown1 = reader.ReadInt32();
            reader.SkipInt32(0);

            //Textures
            Texture[] textures = TextureUtils.ReadDDS(Path.GetFileName(path).Replace(".map", "_tex"), reader);


            //Meshes
            reader.SkipInt32(1);
            reader.SkipInt32(); //Length from magic to bottom
            reader.SkipInt32(0);
            reader.SkipInt32(0);

            long magicPosition = reader.BaseStream.Position;
            reader.SkipInt32(0x20010730); //Magic number?
            reader.SkipInt32(1);
            int materialsOffset = reader.ReadInt32() + (int)magicPosition; 
            int meshCount = reader.ReadInt32();

            reader.SkipInt32(0);
            reader.SkipInt32(); // Length of elements from 0^
            reader.SkipInt32(20);
            reader.SkipInt32(0);

            reader.SkipInt32(0);
            reader.SkipInt32(1);
            reader.SkipInt32(8);
            
            long v1offset = reader.BaseStream.Position;
            reader.ReadVector3YInverted(); //V1
            reader.SkipInt32(0);
            reader.ReadVector3YInverted(); //V2
            reader.SkipInt32(0);
            int headerLength = reader.ReadInt32(); //From v1 to vertexLength

            int indicesOffset = reader.ReadInt32() + (int)v1offset;
            int indicesLength = reader.ReadInt32();
            int Unknown = reader.ReadInt32();
            reader.SkipInt32(meshCount);

            List<MeshGroupSH2> groups = new List<MeshGroupSH2>();
            for (int i = 0; i != meshCount; i++)
            {
                groups.Add(MeshGroupSH2.Initialise(reader, subGO));
            }

            int vertexLength = reader.ReadInt32();
            reader.SkipInt32(1);
            reader.SkipInt32(0);
            int elementLength = reader.ReadInt32();
            reader.SkipInt32(vertexLength);

            int vertexElementsCount = vertexLength / elementLength;
            List<Vector3> verts = new List<Vector3>();
            List<Vector3> norms = new List<Vector3>();
            List<Color32> colors = new List<Color32>();
            List<Vector2> uvs = new List<Vector2>();

            for (int i = 0; i != vertexElementsCount; i++)
            {
                verts.Add(reader.ReadVector3YInverted() * Scene.GLOBAL_SCALE);
                norms.Add(reader.ReadVector3YInverted());
                if (elementLength == 36)
                {
                    colors.Add(reader.ReadBGRA());
                }
                uvs.Add(reader.ReadVector2());
            }

            reader.BaseStream.Position = indicesOffset;

            List<short[]> indices = new List<short[]>(groups.Count);

            //stupid
            for (int i = 0; i != groups.Count; i++)
            {
                indices.Add(null);
            }

            for(int i = 0; i != groups.Count; i++)
            {
                MeshGroupSH2 group = groups[i];
                indices[group.MainID] = new short[group.indexCount];
                for (int j = 0; j != group.indexCount ; j++)
                {
                    indices[group.MainID][j] = reader.ReadInt16();
                }
                Debug.Log("End of i = " + reader.BaseStream.Position.ToString("X"));
            }

            reader.BaseStream.Position = materialsOffset;

            //Mesh renderer
            MaterialRolodex rolodex = MaterialRolodex.GetOrCreateAt(assetPath);
            rolodex.AddTextures(textures);
            

            MeshRenderer mr = subGO.AddComponent<MeshRenderer>();
            Material[] mats = new Material[groups.Count];
            for (int i = 0; i != groups.Count; i++)
            {
                reader.SkipInt16();
                MaterialRolodex.TexMatsPair tmp = rolodex.GetWithSH2ID(reader.ReadInt16());
                mats[i] = tmp.GetOrCreateDiffuse();
                reader.SkipBytes(12);
            }
            mr.sharedMaterials = mats;

            reader.Close();

            //Mesh filter
            subGO.AddComponent<MeshFilter>().sharedMesh = MeshUtils.MakeIndexedStrip(verts, indices, norms, uvs, colors);

            foreach (MeshFilter mf in subGO.GetComponentsInChildren<MeshFilter>())
            {
                AssetDatabase.AddObjectToAsset(mf.sharedMesh, assetPath);
            }
        }
Пример #10
0
            public static Camera TryMakeCamera(BinaryReader reader, Matrix4x4 transMat)
            {
                Vector2 zoneA = reader.ReadVector2();
                reader.SkipBytes(8);
                Vector2 zoneB = reader.ReadVector2();
                Vector2 zoneHeights = reader.ReadVector2();

                Vector2 constraintA = reader.ReadVector2();
                reader.SkipBytes(8);
                Vector2 constraintB = reader.ReadVector2();
                Vector2 constraintHeights = reader.ReadVector2();

                reader.SkipInt32(0);
                int type = reader.ReadInt32();
                reader.SkipInt32(0);
                int Unknown1 = reader.ReadInt32();

                Vector4 Unknown2 = reader.ReadVector4();
                Vector2 Unknown3 = reader.ReadVector2();
                reader.SkipInt32(0);
                int Unknown4 = reader.ReadInt32();
                Vector2 Unknown5 = reader.ReadVector2();
                Vector2 Unknown6 = reader.ReadVector2();

                if (type != 1)
                {
                    Camera cam = new Camera();

                    Vector3 activeMin = new Vector3(zoneA.x, -zoneHeights.x, zoneA.y);
                    Vector3 activeMax = new Vector3(zoneB.x, -zoneHeights.y, zoneB.y);
                    cam.activeArea = new Bounds();
                    cam.activeArea.SetMinMax(transMat.MultiplyPoint(activeMin), transMat.MultiplyPoint(activeMax));

                    Vector3 constraintMin = new Vector3(constraintA.x, -constraintHeights.x, constraintA.y);
                    Vector3 constraintMax = new Vector3(constraintB.x, -constraintHeights.y, constraintB.y);
                    cam.constraintsArea = new Bounds();
                    cam.constraintsArea.SetMinMax(transMat.MultiplyPoint(constraintMin), transMat.MultiplyPoint(constraintMax));

                    cam.type = type;
                    cam.Unknown1 = Unknown1;
                    cam.Unknown2 = Unknown2;
                    cam.Unknown3 = Unknown3;
                    cam.Unknown4 = Unknown4;
                    cam.Unknown5 = Unknown5;
                    cam.Unknown6 = Unknown6;

                    return cam;
                }
                return null;
            }
Пример #11
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="stageFileName"></param>
        /// <param name="mapChipImageFileName"></param>
        /// <param name="objectFileName"></param>
        /// <param name="town"></param>
        /// <param name="wall"></param>
        /// <param name="road"></param>
        /// <param name="directionsToWarArea">攻め込む方向のリスト。昇順にソートされているのが前提</param>
        /// <returns></returns>
        public WarMap Load(string stageFileName, int town, int wall, int road, IEnumerable<int> directionsToWarArea)
        {
            const int NUMOFMAPCHIP = 32;
            const int DEPLOY_CANDIDATE_NUM = 20;
            const int ENDCITY = 15, ENDWALL = 24, ENDSTREET = 39;

            string gameDataPath = Path.Combine(_scenarioPath, "Data");

            var mapchipID = new int[NUMOFMAPCHIP,NUMOFMAPCHIP];
            var objectID = new int[NUMOFMAPCHIP,NUMOFMAPCHIP];
            var height = new int[NUMOFMAPCHIP,NUMOFMAPCHIP];
            var initDeployCandidates = new List<List<Point2>>();

            using (var filestream = new FileStream(Path.Combine(gameDataPath, stageFileName), FileMode.Open))
            using (var reader = new BinaryReader(filestream))
            {
                // (x,y) = (0,0), (0,1), ..., (0,MAX), (1,0) という順序でチップが記述されている

                // マップチップID
                for (int x = 0; x < NUMOFMAPCHIP; x++)
                {
                    for (int y = 0; y < NUMOFMAPCHIP; y++)
                    {
                        mapchipID[x, y] = reader.ReadByte();
                    }
                }
                // オブジェクトID(0は移動不可(ダミー), 1はオブジェクトなし)
                for (int x = 0; x < NUMOFMAPCHIP; x++)
                {
                    for (int y = 0; y < NUMOFMAPCHIP; y++)
                    {
                        objectID[x, y] = reader.ReadByte() + 1;
                    }
                }
                // 半分しか表示されないチップを移動不可に設定
                for (int y = 0; y < NUMOFMAPCHIP; y++)
                {
                    objectID[0, y] = 0;
                    if (!(++y < NUMOFMAPCHIP))
                        break;
                    objectID[NUMOFMAPCHIP - 1, y] = 0;
                }
                // オブジェクトの生成順序
                for (int x = 0; x < NUMOFMAPCHIP; x++)
                {
                    for (int y = 0; y < NUMOFMAPCHIP; y++)
                    {
                        int rankOrder = reader.ReadByte();
                        int id = objectID[x, y] - 1;
                        if (id <= 0)
                            continue;
                        // 指定した個数以上の順序を持つオブジェクトを削除
                        if (id <= ENDCITY)
                        {
                            // 都市
                            if (rankOrder > town)
                                objectID[x, y] = 1;
                        }
                        else if (id <= ENDWALL)
                        {
                            // 壁
                            if (rankOrder > wall)
                                objectID[x, y] = 1;
                        }
                        else if (id <= ENDSTREET)
                        {
                            // 道
                            if (rankOrder > road)
                                objectID[x, y] = 1;
                        }
                    }
                }
                // 高さの読み込み
                for (int x = 0; x < NUMOFMAPCHIP; x++)
                {
                    for (int y = 0; y < NUMOFMAPCHIP; y++)
                    {
                        height[x, y] = reader.ReadByte();
                    }
                }

                // 座標(x, y)をそれぞれ1+1=2バイトで表現。20組の座標で1エリアからの初期配置候補
                // 攻め込む方向により初期配置候補が異なるので、実際に攻め込んだ方向になるまで読み飛ばす。
                directionsToWarArea.ConcatFirst(0)
                    .Zip2Chain()
                    .ForEach(t => {
                        var list = new List<Point2>();
                        reader.SkipBytes((t.Item2 - t.Item1) * 2 * DEPLOY_CANDIDATE_NUM);

                        for (int i = 0; i < DEPLOY_CANDIDATE_NUM; i++)
                        {
                            int x = reader.ReadByte(), y = reader.ReadByte();
                            list.Add(AtatCoordToGameCoord(new Point2(x, y)));
                        }
                        initDeployCandidates.Add(list);
                    });
            }

            // 各チップの生成
            var lands = new Land[NUMOFMAPCHIP,NUMOFMAPCHIP];
            for (int x = 0; x < lands.GetLength(0); x++)
            {
                for (int y = 0; y < lands.GetLength(1); y++)
                {
                    lands[x, y] = new Land(height[x, y], WarGlobal.Landforms[mapchipID[x, y]],
                        objectID[x, y] == 0 ? null : WarGlobal.Constructs[objectID[x, y]]);
                }
            }

            return new WarMap(lands, lands[0, 0], new FarenMoveCalculator(), initDeployCandidates);
        }