示例#1
0
            public static string Execute(params string[] args)
            {
                DaggerfallWorkshop.StreamingWorld  streamingWorld  = GameManager.Instance.StreamingWorld;//GameObject.FindObjectOfType<DaggerfallWorkshop.StreamingWorld>();
                DaggerfallWorkshop.DaggerfallUnity daggerfallUnity = DaggerfallUnity.Instance;
                DaggerfallSongPlayer songPlayer = GameObject.FindObjectOfType <DaggerfallSongPlayer>();

                DefaultCommands.showDebugStrings = !DefaultCommands.showDebugStrings;
                bool show = DefaultCommands.showDebugStrings;

                if (streamingWorld)
                {
                    streamingWorld.ShowDebugString = show;
                }
                if (daggerfallUnity)
                {
                    daggerfallUnity.WorldTime.ShowDebugString = show;
                }
                if (songPlayer)
                {
                    songPlayer.ShowDebugString = show;
                }
                if (FPSDisplay.fpsDisplay == null)
                {
                    GameManager.Instance.gameObject.AddComponent <FPSDisplay>();
                }
                FPSDisplay.fpsDisplay.ShowDebugString = show;
                return(string.Format("Debug string show: {0}", show));
            }
        bool IsReady()
        {
            if (!dfUnity)
                dfUnity = DaggerfallUnity.Instance;

            if (!dfUnity.IsReady || string.IsNullOrEmpty(dfUnity.Arena2Path))
                return false;

            return true;
        }
        bool IsReady()
        {
            if (!dfUnity)
                dfUnity = DaggerfallUnity.Instance;

            if (nameHelper == null)
                nameHelper = new NameHelper();

            return true;
        }
        /// <summary>
        /// Set ground climate by texture archive index.
        /// </summary>
        /// <param name="dfUnity">DaggerfallUnity singleton. Required for content readers and settings.</param>
        /// <param name="archive">Texture archive index.</param>
        /// <param name="season">Season to set.</param>
        public void SetClimate(DaggerfallUnity dfUnity, int archive, ClimateSeason season)
        {
            // Create tileMap texture
            Texture2D tileMapTexture = new Texture2D(tileMapDim, tileMapDim, TextureFormat.RGB24, false);
            tileMapTexture.SetPixels32(tileMap);
            tileMapTexture.Apply(false, true);
            tileMapTexture.filterMode = FilterMode.Point;
            tileMapTexture.wrapMode = TextureWrapMode.Clamp;

            // Get tileMap material
            Material material = Instantiate(dfUnity.MaterialReader.GetTerrainTilesetMaterial(archive)) as Material;
            material.SetTexture("_TilemapTex", tileMapTexture);
            material.SetInt("_TilemapDim", tileMapDim);

            // Assign new season
            summary.archive = archive;
            summary.season = season;
            GetComponent<MeshRenderer>().material = material;
        }
示例#5
0
            public static string Execute(params string[] args)
            {
                int speed;

                DaggerfallWorkshop.DaggerfallUnity daggerfallUnity = DaggerfallWorkshop.DaggerfallUnity.Instance;

                if (daggerfallUnity == null)
                {
                    return(error);
                }

                if (args == null || args.Length < 1)
                {
                    try
                    {
                        Console.Log(string.Format("Current TimeScale: {0}", DaggerfallWorkshop.DaggerfallUnity.Instance.WorldTime.TimeScale));
                        return(HelpCommand.Execute(SetTimeScale.name));
                    }
                    catch
                    {
                        return(HelpCommand.Execute(SetTimeScale.name));
                    }
                }
                else if (!int.TryParse(args[0], out speed))
                {
                    return(error);
                }
                else
                {
                    try
                    {
                        DaggerfallWorkshop.DaggerfallUnity.Instance.WorldTime.TimeScale = speed;
                        return(string.Format("Time Scale set to: {0}", speed));
                    }
                    catch
                    {
                        return("Unspecified error; failed to set timescale");
                    }
                }
            }
        void Start()
        {
            dfUnity = DaggerfallUnity.Instance;
            songPlayer = GetComponent<DaggerfallSongPlayer>();

            // Get local player GPS if not set
            if (LocalPlayerGPS == null)
                LocalPlayerGPS = GameManager.Instance.PlayerGPS;

            // Get streaming world if not set
            if (StreamingWorld == null)
                StreamingWorld = GameManager.Instance.StreamingWorld;

            // Get required player components
            if (LocalPlayerGPS)
            {
                playerEnterExit = LocalPlayerGPS.GetComponent<PlayerEnterExit>();
                playerWeather = LocalPlayerGPS.GetComponent<PlayerWeather>();
            }
        }
        public static bool FindDaggerfallUnity(out DaggerfallUnity dfUnityOut)
        {
            dfUnityOut = GameObject.FindObjectOfType(typeof(DaggerfallUnity)) as DaggerfallUnity;
            if (dfUnityOut == null)
            {
                LogMessage("Could not locate DaggerfallUnity GameObject instance in scene!", true);
                return false;
            }

            return true;
        }
 /// <summary>
 /// Set ground climate.
 /// </summary>
 /// <param name="dfUnity">DaggerfallUnity singleton. Required for content readers and settings.</param>
 /// <param name="climate">Climate to set.</param>
 /// <param name="season">Season to set.</param>
 public void SetClimate(DaggerfallUnity dfUnity, ClimateBases climate, ClimateSeason season)
 {
     int archive = ClimateSwaps.GetGroundArchive(climate, season);
     SetClimate(dfUnity, archive, season);
     summary.climate = climate;
 }
        public override void OnInspectorGUI()
        {
            // Update
            dfUnity.EditorUpdate();

#if UNITY_EDITOR_LINUX
            string message = string.Empty;
            message += "Linux users please set your Daggerfall installation path (i.e. parent folder of complete Daggerfall install) in Resources/defaults.ini then click 'Update Path' below.";
            message += " This is a temporary limitation to work around Inspector bugs in experimental Linux build.";
            EditorGUILayout.HelpBox(message, MessageType.Info);
            EditorGUILayout.SelectableLabel(dfUnity.Arena2Path, EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
            if (GUILayout.Button("Update Path"))
            {
                dfUnity.Arena2Path = string.Empty;
                dfUnity.EditorResetArena2Path();
            }
#else
            // Get properties
            var propArena2Path = Prop("Arena2Path");

            // Browse for Arena2 path
            EditorGUILayout.Space();
            GUILayoutHelper.Horizontal(() =>
            {
                EditorGUILayout.LabelField(new GUIContent("Arena2 Path", "The local Arena2 path used for development only."), GUILayout.Width(EditorGUIUtility.labelWidth - 4));
                EditorGUILayout.SelectableLabel(dfUnity.Arena2Path, EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
                if (GUILayout.Button("Browse..."))
                {
                    string path = EditorUtility.OpenFolderPanel("Locate Arena2 Path", "", "");
                    if (!string.IsNullOrEmpty(path))
                    {
                        if (!DaggerfallUnity.ValidateArena2Path(path))
                        {
                            EditorUtility.DisplayDialog("Invalid Path", "The selected Arena2 path is invalid", "Close");
                        }
                        else
                        {
                            dfUnity.Arena2Path         = path;
                            propArena2Path.stringValue = path;
                            dfUnity.EditorResetArena2Path();
                        }
                    }
                }
                if (GUILayout.Button("Clear"))
                {
                    dfUnity.EditorClearArena2Path();
                    EditorUtility.SetDirty(target);
                }
            });

            // Prompt user to set Arena2 path
            if (string.IsNullOrEmpty(dfUnity.Arena2Path))
            {
                EditorGUILayout.HelpBox("Please set the Arena2 path of your Daggerfall installation.", MessageType.Info);
                return;
            }
#endif

            // Display other GUI items
            DisplayOptionsGUI();
            DisplayImporterGUI();

            // Save modified properties
            serializedObject.ApplyModifiedProperties();
            if (GUI.changed)
            {
                EditorUtility.SetDirty(target);
            }
        }
        public override void GenerateSamples(ref MapPixelData mapPixel)
        {
            DaggerfallUnity dfUnity = DaggerfallUnity.Instance;

            // Divisor ensures continuous 0-1 range of tile samples
            float div = (float)TerrainHelper.terrainTileDim / 3f;

            // Read neighbouring height samples for this map pixel
            int mx = mapPixel.mapPixelX;
            int my = mapPixel.mapPixelY;

            byte[,] shm = dfUnity.ContentReader.WoodsFileReader.GetHeightMapValuesRange(mx - 2, my - 2, 4);
            byte[,] lhm = dfUnity.ContentReader.WoodsFileReader.GetLargeHeightMapValuesRange(mx - 1, my, 3);

            // Extract height samples for all chunks
            float averageHeight = 0;
            float maxHeight = float.MinValue;
            float baseHeight, noiseHeight;
            float x1, x2, x3, x4;
            int   dim = TerrainHelper.terrainSampleDim;

            mapPixel.samples = new WorldSample[dim * dim];
            for (int y = 0; y < dim; y++)
            {
                for (int x = 0; x < dim; x++)
                {
                    float rx           = (float)x / div;
                    float ry           = (float)y / div;
                    int   ix           = Mathf.FloorToInt(rx);
                    int   iy           = Mathf.FloorToInt(ry);
                    float sfracx       = (float)x / (float)(dim - 1);
                    float sfracy       = (float)y / (float)(dim - 1);
                    float fracx        = (float)(x - ix * div) / div;
                    float fracy        = (float)(y - iy * div) / div;
                    float scaledHeight = 0;

                    // Bicubic sample small height map for base terrain elevation
                    x1            = TerrainHelper.CubicInterpolator(shm[0, 3], shm[1, 3], shm[2, 3], shm[3, 3], sfracx);
                    x2            = TerrainHelper.CubicInterpolator(shm[0, 2], shm[1, 2], shm[2, 2], shm[3, 2], sfracx);
                    x3            = TerrainHelper.CubicInterpolator(shm[0, 1], shm[1, 1], shm[2, 1], shm[3, 1], sfracx);
                    x4            = TerrainHelper.CubicInterpolator(shm[0, 0], shm[1, 0], shm[2, 0], shm[3, 0], sfracx);
                    baseHeight    = TerrainHelper.CubicInterpolator(x1, x2, x3, x4, sfracy);
                    scaledHeight += baseHeight * baseHeightScale;

                    // Bicubic sample large height map for noise mask over terrain features
                    x1            = TerrainHelper.CubicInterpolator(lhm[ix, iy + 0], lhm[ix + 1, iy + 0], lhm[ix + 2, iy + 0], lhm[ix + 3, iy + 0], fracx);
                    x2            = TerrainHelper.CubicInterpolator(lhm[ix, iy + 1], lhm[ix + 1, iy + 1], lhm[ix + 2, iy + 1], lhm[ix + 3, iy + 1], fracx);
                    x3            = TerrainHelper.CubicInterpolator(lhm[ix, iy + 2], lhm[ix + 1, iy + 2], lhm[ix + 2, iy + 2], lhm[ix + 3, iy + 2], fracx);
                    x4            = TerrainHelper.CubicInterpolator(lhm[ix, iy + 3], lhm[ix + 1, iy + 3], lhm[ix + 2, iy + 3], lhm[ix + 3, iy + 3], fracx);
                    noiseHeight   = TerrainHelper.CubicInterpolator(x1, x2, x3, x4, fracy);
                    scaledHeight += noiseHeight * noiseMapScale;

                    // Additional noise mask for small terrain features at ground level
                    float latitude  = mapPixel.mapPixelX * MapsFile.WorldMapTileDim + x;
                    float longitude = MapsFile.MaxWorldTileCoordZ - mapPixel.mapPixelY * MapsFile.WorldMapTileDim + y;
                    float lowFreq   = TerrainHelper.GetNoise(dfUnity.ContentReader.Noise, latitude, longitude, 0.1f, 0.5f, 0.5f, 1);
                    float highFreq  = TerrainHelper.GetNoise(dfUnity.ContentReader.Noise, latitude, longitude, 6f, 0.5f, 0.5f, 1);
                    scaledHeight += (lowFreq * highFreq) * extraNoiseScale;

                    // Clamp lower values to ocean elevation
                    if (scaledHeight < scaledOceanElevation)
                    {
                        scaledHeight = scaledOceanElevation;
                    }

                    // Accumulate average height
                    averageHeight += scaledHeight;

                    // Get max height
                    if (scaledHeight > maxHeight)
                    {
                        maxHeight = scaledHeight;
                    }

                    // Set sample
                    mapPixel.samples[y * dim + x] = new WorldSample()
                    {
                        scaledHeight = scaledHeight,
                        record       = 2,
                    };
                }
            }

            // Average and max heights are passed back for locations
            mapPixel.averageHeight = averageHeight /= (float)(dim * dim);
            mapPixel.maxHeight     = maxHeight;
        }
        private bool ReadyCheck()
        {
            // Ensure we have a DaggerfallUnity reference
            if (dfUnity == null)
            {
                dfUnity = DaggerfallUnity.Instance;

                // Force first update to set lights
                lastCityLightsFlag = !dfUnity.WorldTime.Now.IsCityLightsOn;
            }

            // Do nothing if DaggerfallUnity not ready
            if (!dfUnity.IsReady)
            {
                DaggerfallUnity.LogMessage("DaggerfallLight: DaggerfallUnity component is not ready. Have you set your Arena2 path?");
                return false;
            }

            // Must have a light component added
            if (!myLight)
                return false;

            return true;
        }
        void Start()
        {
            dfUnity = DaggerfallUnity.Instance;

            useDeferredReflections = (GameManager.Instance.MainCamera.renderingPath == RenderingPath.DeferredShading);

            if (!streamingWorld)
                streamingWorld = GameObject.Find("StreamingWorld").GetComponent<StreamingWorld>();
            if (!streamingWorld)
            {
                DaggerfallUnity.LogMessage("InjectReflectiveMaterialProperty: Missing StreamingWorld reference.", true);
                if (Application.isEditor)
                    Debug.Break();
                else
                    Application.Quit();
            }

            if (GameObject.Find("IncreasedTerrainDistanceMod") != null)
            {
                if (DaggerfallUnity.Settings.Nystul_IncreasedTerrainDistance)
                {
                    extraTranslationY = GameObject.Find("IncreasedTerrainDistanceMod").GetComponent<ProjectIncreasedTerrainDistance.IncreasedTerrainDistance>().ExtraTranslationY;
                }
            }

            gameObjectReflectionPlaneGroundLevel = GameObject.Find("ReflectionPlaneBottom");
            gameObjectReflectionPlaneSeaLevel = GameObject.Find("ReflectionPlaneSeaLevel");
            gameObjectReflectionPlaneLowerLevel = gameObjectReflectionPlaneSeaLevel;

            // get inactive gameobject StreamingTarget (just GameObject.Find() would fail to find inactive gameobjects)
            GameObject[] gameObjects = Resources.FindObjectsOfTypeAll<GameObject>();
            foreach (GameObject currentGameObject in gameObjects)
            {
                string objectPathInHierarchy = GetGameObjectPath(currentGameObject);
                if (objectPathInHierarchy == "/Exterior/StreamingTarget")
                {
                    gameObjectStreamingTarget = currentGameObject;
                }
            }

            iniData = getIniParserConfigInjectionTextures();
        }
示例#13
0
        // Set location tilemap data
        public static void SetLocationTiles(ref MapPixelData mapPixel)
        {
            //const int tileDim = 16;
            //const int chunkDim = 8;

            DaggerfallUnity dfUnity = DaggerfallUnity.Instance;

            // Get location
            DFLocation location = dfUnity.ContentReader.MapFileReader.GetLocation(mapPixel.mapRegionIndex, mapPixel.mapLocationIndex);

            // Centre location tiles inside terrain area
            //int startX = ((chunkDim * tileDim) - location.Exterior.ExteriorData.Width * tileDim) / 2;
            //int startY = ((chunkDim * tileDim) - location.Exterior.ExteriorData.Height * tileDim) / 2;

            // Position tiles inside terrain area
            //int width = location.Exterior.ExteriorData.Width;
            //int height = location.Exterior.ExteriorData.Height;
            DFPosition tilePos = TerrainHelper.GetLocationTerrainTileOrigin(location);

            // Full 8x8 locations have "terrain blend space" around walls to smooth down random terrain towards flat area.
            // This is indicated by texture index > 55 (ground texture range is 0-55), larger values indicate blend space.
            // We need to know rect of actual city area so we can use blend space outside walls.
            int xmin = int.MaxValue, ymin = int.MaxValue;
            int xmax = 0, ymax = 0;

            // Iterate blocks of this location
            for (int blockY = 0; blockY < location.Exterior.ExteriorData.Height; blockY++)
            {
                for (int blockX = 0; blockX < location.Exterior.ExteriorData.Width; blockX++)
                {
                    // Get block data
                    DFBlock block;
                    string  blockName = dfUnity.ContentReader.MapFileReader.GetRmbBlockName(ref location, blockX, blockY);
                    if (!dfUnity.ContentReader.GetBlock(blockName, out block))
                    {
                        continue;
                    }

                    // Copy ground tile info
                    for (int tileY = 0; tileY < RMBLayout.RMBTilesPerBlock; tileY++)
                    {
                        for (int tileX = 0; tileX < RMBLayout.RMBTilesPerBlock; tileX++)
                        {
                            DFBlock.RmbGroundTiles tile = block.RmbBlock.FldHeader.GroundData.GroundTiles[tileX, (RMBLayout.RMBTilesPerBlock - 1) - tileY];
                            int xpos = tilePos.X + blockX * RMBLayout.RMBTilesPerBlock + tileX;
                            int ypos = tilePos.Y + blockY * RMBLayout.RMBTilesPerBlock + tileY;

                            int record = tile.TextureRecord;
                            if (tile.TextureRecord < 56)
                            {
                                // Track interior bounds of location tiled area
                                if (xpos < xmin)
                                {
                                    xmin = xpos;
                                }
                                if (xpos > xmax)
                                {
                                    xmax = xpos;
                                }
                                if (ypos < ymin)
                                {
                                    ymin = ypos;
                                }
                                if (ypos > ymax)
                                {
                                    ymax = ypos;
                                }

                                // Store texture data from block
                                mapPixel.tilemapSamples[xpos, ypos].record   = record;
                                mapPixel.tilemapSamples[xpos, ypos].flip     = tile.IsFlipped;
                                mapPixel.tilemapSamples[xpos, ypos].rotate   = tile.IsRotated;
                                mapPixel.tilemapSamples[xpos, ypos].location = true;
                            }
                        }
                    }
                }
            }

            // Update location rect with extra clearance
            const int extraClearance = 2;
            Rect      locationRect = new Rect();

            locationRect.xMin     = xmin - extraClearance;
            locationRect.xMax     = xmax + extraClearance;
            locationRect.yMin     = ymin - extraClearance;
            locationRect.yMax     = ymax + extraClearance;
            mapPixel.locationRect = locationRect;
        }
示例#14
0
        /// <summary>
        /// Gets Unity Mesh from Daggerfall model.
        /// </summary>
        /// <param name="dfUnity">DaggerfallUnity singleon for loading content.</param>
        /// <param name="modelID">Daggerfall model ID to load..</param>
        /// <param name="cachedMaterialsOut">Array of cached materials in order of submesh.</param>
        /// <param name="textureKeysOut">Array of original texture keys in order of submesh.</param>
        /// <param name="hasAnimationsOut">True if one or more materials have animations.</param>
        /// <param name="solveTangents">Solve tangents for this mesh.</param>
        /// <param name="lightmapUVs">Add secondary lightmap UVs to this mesh.</param>
        /// <returns>Mesh object or null.</returns>
        public Mesh GetMesh(
            DaggerfallUnity dfUnity,
            uint modelID,
            out CachedMaterial[] cachedMaterialsOut,
            out int[] textureKeysOut,
            out bool hasAnimationsOut,
            bool solveTangents = false,
            bool lightmapUVs   = false)
        {
            cachedMaterialsOut = null;
            hasAnimationsOut   = false;
            textureKeysOut     = null;

            // Ready check
            if (!IsReady)
            {
                return(null);
            }

            // Get model data
            ModelData model;

            if (!GetModelData(modelID, out model))
            {
                DaggerfallUnity.LogMessage(string.Format("Unknown ModelID {0}.", modelID.ToString()), true);
                return(null);
            }

            // Load materials
            cachedMaterialsOut = new CachedMaterial[model.SubMeshes.Length];
            textureKeysOut     = new int[model.SubMeshes.Length];
            for (int i = 0; i < model.SubMeshes.Length; i++)
            {
                int archive = model.DFMesh.SubMeshes[i].TextureArchive;
                int record  = model.DFMesh.SubMeshes[i].TextureRecord;
                textureKeysOut[i] = MaterialReader.MakeTextureKey((short)archive, (byte)record, (byte)0);

                // Add material to array
                CachedMaterial cachedMaterial;
                dfUnity.MaterialReader.GetCachedMaterial(archive, record, 0, out cachedMaterial);
                cachedMaterialsOut[i] = cachedMaterial;

                // Set animation flag
                if (cachedMaterial.singleFrameCount > 1 && !hasAnimationsOut)
                {
                    hasAnimationsOut = true;
                }
            }

            // Create mesh
            Mesh mesh = new Mesh();

            mesh.name         = modelID.ToString();
            mesh.vertices     = model.Vertices;
            mesh.normals      = model.Normals;
            mesh.uv           = model.UVs;
            mesh.subMeshCount = model.SubMeshes.Length;

            // Set submesh triangles
            for (int s = 0; s < mesh.subMeshCount; s++)
            {
                var   sub       = model.SubMeshes[s];
                int[] triangles = new int[sub.PrimitiveCount * 3];
                for (int t = 0; t < sub.PrimitiveCount * 3; t++)
                {
                    triangles[t] = model.Indices[sub.StartIndex + t];
                }
                mesh.SetTriangles(triangles, s);
            }

            // Finalise mesh
            if (solveTangents)
            {
                TangentSolver(mesh);
            }
            if (lightmapUVs)
            {
                AddLightmapUVs(mesh);
            }
            mesh.RecalculateBounds();

            return(mesh);
        }
        /// <summary>
        /// Sets new Daggerfall material and recreates mesh.
        /// Will use an atlas if specified in DaggerfallUnity singleton.
        /// </summary>
        /// <param name="dfUnity">DaggerfallUnity singleton. Required for content readers and settings.</param>
        /// <param name="archive">Texture archive index.</param>
        /// <param name="record">Texture record index.</param>
        /// <param name="frame">Frame index.</param>
        /// <param name="dungeon">This is a dungeon billboard.</param>
        /// <returns>Material.</returns>
        public Material SetMaterial(int archive, int record, int frame, bool dungeon)
        {
            // Get DaggerfallUnity
            DaggerfallUnity dfUnity = DaggerfallUnity.Instance;

            if (!dfUnity.IsReady)
            {
                return(null);
            }

            // Get references
            meshRenderer = GetComponent <MeshRenderer>();

            Vector2  size;
            Mesh     mesh     = null;
            Material material = null;

            if (dfUnity.MaterialReader.AtlasTextures)
            {
                material = dfUnity.MaterialReader.GetMaterialAtlas(
                    archive,
                    0,
                    4,
                    2048,
                    out summary.AtlasRects,
                    out summary.AtlasIndices,
                    4,
                    true,
                    0,
                    false);
                mesh = dfUnity.MeshReader.GetBillboardMesh(
                    summary.AtlasRects[summary.AtlasIndices[record].startIndex],
                    archive,
                    record,
                    out size,
                    dungeon);
                summary.AtlasedMaterial = true;
                if (summary.AtlasIndices[record].frameCount > 1)
                {
                    summary.AnimatedMaterial = true;
                }
                else
                {
                    summary.AnimatedMaterial = false;
                }
            }
            else
            {
                material = dfUnity.MaterialReader.GetMaterial(
                    archive,
                    record,
                    frame,
                    0,
                    out summary.Rect,
                    4,
                    true);
                mesh = dfUnity.MeshReader.GetBillboardMesh(
                    summary.Rect,
                    archive,
                    record,
                    out size,
                    dungeon);
                summary.AtlasedMaterial  = false;
                summary.AnimatedMaterial = false;
            }

            // Update material properties
            MaterialReader.SetBlendMode(material, MaterialReader.CustomBlendMode.Cutout);

            // Set summary
            summary.InDungeon = dungeon;
            summary.FlatType  = MaterialReader.GetFlatType(archive);
            summary.Archive   = archive;
            summary.Record    = record;
            summary.Size      = size;

            // Set editor flat types
            if (summary.FlatType == FlatTypes.Editor)
            {
                summary.EditorFlatType = MaterialReader.GetEditorFlatType(summary.Record);
            }

            // Assign mesh and material
            MeshFilter meshFilter = GetComponent <MeshFilter>();
            Mesh       oldMesh    = meshFilter.sharedMesh;

            if (mesh)
            {
                meshFilter.sharedMesh       = mesh;
                meshRenderer.sharedMaterial = material;
            }
            if (oldMesh)
            {
                // The old mesh is no longer required
                Destroy(oldMesh);
            }

            // Standalone billboards never cast shadows
            meshRenderer.shadowCastingMode = ShadowCastingMode.Off;

            return(material);
        }
示例#16
0
        private bool InitSynth()
        {
            // Get peer AudioSource
            audioSource = GetComponent <AudioSource>();
            if (audioSource == null)
            {
                DaggerfallUnity.LogMessage("DaggerfallSongPlayer: Could not find AudioSource component.");
                return(false);
            }

            // Create synthesizer and load bank
            if (midiSynthesizer == null)
            {
                // Get number of channels
                if (AudioSettings.driverCapabilities.ToString() == "Mono")
                {
                    channels = 1;
                }
                else
                {
                    channels = 2;
                }

                // Create synth
                AudioSettings.GetDSPBufferSize(out bufferLength, out numBuffers);
                midiSynthesizer = new Synthesizer(sampleRate, channels, bufferLength / numBuffers, numBuffers, polyphony);

                // Load bank data
                string filename = DaggerfallUnity.Settings.SoundFont;
                byte[] bankData = LoadBank(filename);
                if (bankData == null)
                {
                    // Attempt to fallback to default internal soundfont
                    bankData = LoadDefaultSoundFont();
                    filename = defaultSoundFontFilename;
                    Debug.LogFormat("Using default SoundFont {0}", defaultSoundFontFilename);
                }
                else
                {
                    Debug.LogFormat("Trying custom SoundFont {0}", filename);
                }

                // Assign to synth
                if (bankData == null)
                {
                    return(false);
                }
                else
                {
                    midiSynthesizer.LoadBank(new MyMemoryFile(bankData, filename));
                    midiSynthesizer.ResetSynthControls(); // Need to do this for bank to load properly, don't know why
                }
            }

            // Create sequencer
            if (midiSequencer == null)
            {
                midiSequencer = new MidiFileSequencer(midiSynthesizer);
            }

            // Check init
            if (midiSynthesizer == null || midiSequencer == null)
            {
                DaggerfallUnity.LogMessage("DaggerfallSongPlayer: Failed to init synth.");
                return(false);
            }

            return(true);
        }
        /// <summary>
        /// Sets new Daggerfall material and recreates mesh.
        /// Will use an atlas if specified in DaggerfallUnity singleton.
        /// </summary>
        /// <param name="dfUnity">DaggerfallUnity singleton. Required for content readers and settings.</param>
        /// <param name="archive">Texture archive index.</param>
        /// <param name="record">Texture record index.</param>
        /// <param name="frame">Frame index.</param>
        /// <returns>Material.</returns>
        public Material SetMaterial(int archive, int record, int frame = 0)
        {
            // Get DaggerfallUnity
            DaggerfallUnity dfUnity = DaggerfallUnity.Instance;

            if (!dfUnity.IsReady)
            {
                return(null);
            }

            // Get references
            meshRenderer = GetComponent <MeshRenderer>();

            Vector2  size;
            Vector2  scale;
            Mesh     mesh     = null;
            Material material = null;

            if (material = TextureReplacement.GetStaticBillboardMaterial(gameObject, archive, record, ref summary, out scale))
            {
                mesh  = dfUnity.MeshReader.GetBillboardMesh(summary.Rect, archive, record, out size);
                size *= scale;
                summary.AtlasedMaterial  = false;
                summary.AnimatedMaterial = summary.ImportedTextures.FrameCount > 1;
            }
            else if (dfUnity.MaterialReader.AtlasTextures)
            {
                material = dfUnity.MaterialReader.GetMaterialAtlas(
                    archive,
                    0,
                    4,
                    2048,
                    out summary.AtlasRects,
                    out summary.AtlasIndices,
                    4,
                    true,
                    0,
                    false,
                    true);
                mesh = dfUnity.MeshReader.GetBillboardMesh(
                    summary.AtlasRects[summary.AtlasIndices[record].startIndex],
                    archive,
                    record,
                    out size);
                summary.AtlasedMaterial = true;
                if (summary.AtlasIndices[record].frameCount > 1)
                {
                    summary.AnimatedMaterial = true;
                }
                else
                {
                    summary.AnimatedMaterial = false;
                }
            }
            else
            {
                material = dfUnity.MaterialReader.GetMaterial(
                    archive,
                    record,
                    frame,
                    0,
                    out summary.Rect,
                    4,
                    true,
                    true);
                mesh = dfUnity.MeshReader.GetBillboardMesh(
                    summary.Rect,
                    archive,
                    record,
                    out size);
                summary.AtlasedMaterial  = false;
                summary.AnimatedMaterial = false;
            }

            // Set summary
            summary.FlatType = MaterialReader.GetFlatType(archive);
            summary.Archive  = archive;
            summary.Record   = record;
            summary.Size     = size;

            // Set editor flat types
            if (summary.FlatType == FlatTypes.Editor)
            {
                summary.EditorFlatType = MaterialReader.GetEditorFlatType(summary.Record);
            }

            // Set NPC flat type based on archive
            if (RDBLayout.IsNPCFlat(summary.Archive))
            {
                summary.FlatType = FlatTypes.NPC;
            }

            // Assign mesh and material
            MeshFilter meshFilter = GetComponent <MeshFilter>();
            Mesh       oldMesh    = meshFilter.sharedMesh;

            if (mesh)
            {
                meshFilter.sharedMesh       = mesh;
                meshRenderer.sharedMaterial = material;
            }
            if (oldMesh)
            {
                // The old mesh is no longer required
#if UNITY_EDITOR
                DestroyImmediate(oldMesh);
#else
                Destroy(oldMesh);
#endif
            }

            // General billboard shadows if enabled
            bool isLightArchive = (archive == TextureReader.LightsTextureArchive);
            meshRenderer.shadowCastingMode = (DaggerfallUnity.Settings.GeneralBillboardShadows && !isLightArchive) ? ShadowCastingMode.TwoSided : ShadowCastingMode.Off;

            // Add NPC trigger collider
            if (summary.FlatType == FlatTypes.NPC)
            {
                Collider col = gameObject.AddComponent <BoxCollider>();
                col.isTrigger = true;
            }

            return(material);
        }
示例#18
0
        /// <summary>
        /// Apply current sound index and behaviour to AudioSource.
        /// </summary>
        private void Apply(float spatialBlend = 1)
        {
            // Do nothing if not ready
            if (!ReadyCheck() || !audioSource.enabled)
            {
                return;
            }

            // Do nothing if out of range
            if (SoundIndex < minIndex || SoundIndex >= maxIndex)
            {
                return;
            }

            // Get new clip
            audioClip = dfUnity.SoundReader.GetAudioClip(SoundIndex);
            if (audioClip == null)
            {
                DaggerfallUnity.LogMessage("Failed to load Daggerfall audio clip.");
                return;
            }

            // Set spatial blend
            audioSource.spatialBlend = spatialBlend;

            // Apply preset
            switch (Preset)
            {
            case AudioPresets.OnDemand:
                audioSource.playOnAwake = false;
                audioSource.loop        = false;
                playerCheck             = false;
                playRandomly            = false;
                break;

            case AudioPresets.LoopOnAwake:
                audioSource.playOnAwake = true;
                audioSource.loop        = true;
                playerCheck             = false;
                playRandomly            = false;
                break;

            case AudioPresets.LoopOnDemand:
                audioSource.playOnAwake = false;
                audioSource.loop        = true;
                playerCheck             = false;
                playRandomly            = false;
                break;

            case AudioPresets.LoopIfPlayerNear:
                audioSource.playOnAwake = true;
                audioSource.loop        = true;
                playerCheck             = true;
                playRandomly            = false;
                break;

            case AudioPresets.PlayRandomlyIfPlayerNear:
                audioSource.playOnAwake = false;
                audioSource.loop        = false;
                playerCheck             = true;
                playRandomly            = true;
                break;

            default:
                break;
            }

            // Assign clip to Unity AudioSource only if app playing
            if (Application.isPlaying)
            {
                audioSource.clip = audioClip;
            }

            // Manually start sound if playOnAwake true.
            // This is necessary as sound is procedurally created after awake.
            if (audioSource.playOnAwake)
            {
                audioSource.Play();
            }
        }
示例#19
0
        private bool ReadyCheck()
        {
            // Ensure we have a DaggerfallUnity reference
            if (dfUnity == null)
            {
                dfUnity = DaggerfallUnity.Instance;
            }

            // Do nothing until DaggerfallUnity is ready
            if (!dfUnity.IsReady)
                return false;

            return true;
        }
示例#20
0
 void Awake()
 {
     dfUnity = DaggerfallUnity.Instance;
 }
 void Start()
 {
     dfUnity = DaggerfallUnity.Instance;
 }
示例#22
0
        //void ShowUnknownGUI()
        //{
        //    EditorGUILayout.Space();
        //    showUnknownFoldout = GUILayoutHelper.Foldout(showUnknownFoldout, new GUIContent("Unknown"), () =>
        //    {
        //        EditorGUILayout.Space();
        //        GUILayoutHelper.Indent(() =>
        //        {
        //            EditorGUILayout.LabelField("Unknown1 [1 Bytes]");
        //            EditorGUILayout.SelectableLabel(selectedCareer.RawData.Unknown1.ToString("X2"), EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
        //        });
        //        GUILayoutHelper.Indent(() =>
        //        {
        //            EditorGUILayout.LabelField("Unknown2 [8 Bytes]");
        //            string valuesString = string.Empty;
        //            for (int i = 0; i < selectedCareer.RawData.Unknown2.Length; i++)
        //            {
        //                valuesString += selectedCareer.RawData.Unknown2[i].ToString("X2") + " ";
        //            }
        //            EditorGUILayout.SelectableLabel(valuesString, EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
        //        });
        //    });
        //}

        bool IsReady()
        {
            dfUnity = DaggerfallUnity.Instance;

            if (!dfUnity.IsReady || string.IsNullOrEmpty(dfUnity.Arena2Path))
            {
                return(false);
            }

            // Read all CLASS*.CFG files
            if (classTemplates == null)
            {
                string[] files = Directory.GetFiles(dfUnity.Arena2Path, "class*.cfg");
                if (files != null && files.Length > 0)
                {
                    classTemplates = new DFCareer[files.Length - 1];
                    classNames     = new GUIContent[files.Length - 1];
                    for (int i = 0; i < files.Length - 1; i++)
                    {
                        ClassFile classFile = new ClassFile(files[i]);
                        classTemplates[i] = classFile.Career;
                        classNames[i]     = new GUIContent(classTemplates[i].Name);
                    }
                }
            }

            // Read all ENEMY*.CFG files
            if (monsterTemplates == null)
            {
                MonsterFile monsterFile = new MonsterFile();
                if (monsterFile.Load(Path.Combine(dfUnity.Arena2Path, MonsterFile.Filename), FileUsage.UseMemory, true))
                {
                    // First pass locates CFG record indices
                    List <int> cfgIndices = new List <int>();
                    for (int i = 0; i < monsterFile.Count; i++)
                    {
                        string recordName = monsterFile.GetRecordName(i);
                        if (recordName.EndsWith(".cfg", StringComparison.InvariantCultureIgnoreCase))
                        {
                            cfgIndices.Add(i);
                        }
                    }

                    // Second pass populates arrays
                    monsterTemplates = new DFCareer[cfgIndices.Count];
                    monsterNames     = new GUIContent[cfgIndices.Count];
                    for (int i = 0; i < cfgIndices.Count; i++)
                    {
                        // Read ENEMY.CFG class file from stream
                        ClassFile    classFile = new ClassFile();
                        byte[]       data      = monsterFile.GetRecordBytes(cfgIndices[i]);
                        MemoryStream stream    = new MemoryStream(data);
                        BinaryReader reader    = new BinaryReader(stream);
                        classFile.Load(reader);
                        reader.Close();

                        // Add to arrays
                        monsterTemplates[i] = classFile.Career;
                        monsterNames[i]     = new GUIContent(monsterTemplates[i].Name);
                    }
                }
                else
                {
                    return(false);
                }
            }

            return(true);
        }
        bool IsReady()
        {
            if (!dfUnity)
                dfUnity = DaggerfallUnity.Instance;

            if (itemHelper == null)
                itemHelper = new ItemHelper();

            if (!dfUnity.IsReady || string.IsNullOrEmpty(dfUnity.Arena2Path))
                return false;

            if (factionFile == null)
                factionFile = new FactionFile(Path.Combine(dfUnity.Arena2Path, FactionFile.Filename), FileUsage.UseMemory, true);

            if (saveGames == null || saveTrees == null || saveNames == null)
            {
                saveGames = new SaveGames();
                saveNames = new GUIContent[6];
                saveTrees = new SaveTree[6];
                saveVars = new SaveVars[6];
                saveTextures = new Texture2D[6];
                if (saveGames.OpenSavesPath(Path.GetDirectoryName(DaggerfallUnity.Instance.Arena2Path)))
                {
                    for (int i = 0; i < 6; i++)
                    {
                        if (saveGames.HasSave(i))
                        {
                            saveGames.OpenSave(i);
                            saveTrees[i] = saveGames.SaveTree;
                            saveVars[i] = saveGames.SaveVars;
                            saveNames[i] = new GUIContent(saveGames.SaveName);
                            saveTextures[i] = TextureReader.CreateFromAPIImage(saveGames.SaveImage);
                            saveTextures[i].filterMode = FilterMode.Point;
                        }
                        else
                        {
                            saveTrees[i] = null;
                            saveVars[i] = null;
                            saveTextures[i] = null;
                            saveNames[i] = new GUIContent("Empty");
                        }
                    }
                }
            }

            return true;
        }
        /// <summary>
        /// Precalculate and cache billboard scale for every record.
        /// This will change based on animation state and orientation.
        /// Cache this to array so it only needs to be calculated once.
        /// Also store number of frames for state animations.
        /// </summary>
        /// <param name="dfUnity">DaggerfallUnity singleton. Required for content readers and settings.</param>
        /// <param name="archive">Texture archive index derived from type and gender.</param>
        private void CacheRecordSizesAndFrames(DaggerfallUnity dfUnity, int archive)
        {
            // Open texture file
            string path = Path.Combine(dfUnity.Arena2Path, TextureFile.IndexToFileName(archive));
            TextureFile textureFile = new TextureFile(path, FileUsage.UseMemory, true);

            // Cache size and scale for each record
            summary.RecordSizes = new Vector2[textureFile.RecordCount];
            summary.RecordFrames = new int[textureFile.RecordCount];
            for (int i = 0; i < textureFile.RecordCount; i++)
            {
                // Get size and scale of this texture
                DFSize size = textureFile.GetSize(i);
                DFSize scale = textureFile.GetScale(i);

                // Set start size
                Vector2 startSize;
                startSize.x = size.Width;
                startSize.y = size.Height;

                // Apply scale
                Vector2 finalSize;
                int xChange = (int)(size.Width * (scale.Width / BlocksFile.ScaleDivisor));
                int yChange = (int)(size.Height * (scale.Height / BlocksFile.ScaleDivisor));
                finalSize.x = (size.Width + xChange);
                finalSize.y = (size.Height + yChange);

                // Store final size and frame count
                summary.RecordSizes[i] = finalSize * MeshReader.GlobalScale;
                summary.RecordFrames[i] = textureFile.GetFrameCount(i);
            }
        }
        bool IsReady()
        {
            if (!dfUnity)
                dfUnity = DaggerfallUnity.Instance;

            if (!dfUnity.IsReady || string.IsNullOrEmpty(dfUnity.Arena2Path))
                return false;

            if (regionNames.Length == 0)
            {
                regionNames = (string[])dfUnity.ContentReader.MapFileReader.RegionNames.Clone();
                System.Array.Sort(regionNames);
            }

            return true;
        }
        private bool ReadyCheck()
        {
            // Ensure we have a DaggerfallUnity reference
            if (dfUnity == null)
                dfUnity = DaggerfallUnity.Instance;
            if (!dfUnity.IsReady)
                return false;

            // Get audio source
            audioSource = GetComponent<AudioSource>();
            if (audioSource == null)
            {
                DaggerfallUnity.LogMessage("DaggerfallAudioSource: Could not find AudioSource component.");
                return false;
            }

            return true;
        }
示例#27
0
        private void UpdateWorldInfo(int x, int y)
        {
            // Requires DaggerfallUnity to be ready
            if (!ReadyCheck())
            {
                return;
            }

            // Requires MAPS.BSA connection
            if (dfUnity.ContentReader.MapFileReader == null)
            {
                return;
            }

            // Get climate and politic data
            currentClimateIndex = dfUnity.ContentReader.MapFileReader.GetClimateIndex(x, y);
            currentPoliticIndex = dfUnity.ContentReader.MapFileReader.GetPoliticIndex(x, y);
            climateSettings     = MapsFile.GetWorldClimateSettings(currentClimateIndex);
            if (currentPoliticIndex > 128)
            {
                regionName = dfUnity.ContentReader.MapFileReader.GetRegionName(currentPoliticIndex - 128);
            }
            else if (currentPoliticIndex == 64)
            {
                regionName = "Ocean";
            }
            else
            {
                regionName = "Unknown";
            }

            // Get region data
            currentRegion = dfUnity.ContentReader.MapFileReader.GetRegion(CurrentRegionIndex);

            // Get location data
            ContentReader.MapSummary mapSummary;
            if (dfUnity.ContentReader.HasLocation(x, y, out mapSummary))
            {
                currentLocation    = dfUnity.ContentReader.MapFileReader.GetLocation(mapSummary.RegionIndex, mapSummary.MapIndex);
                hasCurrentLocation = true;
                CalculateWorldLocationRect();
            }
            else
            {
                currentLocation    = new DFLocation();
                hasCurrentLocation = false;
                ClearWorldLocationRect();
            }

            // Get location type
            if (hasCurrentLocation)
            {
                if (currentRegion.MapTable == null)
                {
                    DaggerfallUnity.LogMessage(string.Format("PlayerGPS: Location {0} in region{1} has a null MapTable.", currentLocation.Name, currentLocation.RegionName));
                }
                else
                {
                    currentLocationType = currentRegion.MapTable[mapSummary.MapIndex].LocationType;
                }
            }
        }
示例#28
0
        /// <summary>
        /// Updates enemy state based on current settings.
        /// Called automatially by SetEnemyType().
        /// This should be called after changing enemy state (e.g. from in code or in editor).
        /// </summary>
        private void ApplyEnemyState()
        {
            // Get state animations
            summary.StateAnims = GetStateAnims(summary.EnemyState);
            if (summary.EnemyState == MobileStates.PrimaryAttack)
            {
                int random = Dice100.Roll();

                if (random <= summary.Enemy.ChanceForAttack2)
                {
                    summary.StateAnimFrames = summary.Enemy.PrimaryAttackAnimFrames2;
                }
                else
                {
                    random -= summary.Enemy.ChanceForAttack2;
                    if (random <= summary.Enemy.ChanceForAttack3)
                    {
                        summary.StateAnimFrames = summary.Enemy.PrimaryAttackAnimFrames3;
                    }
                    else
                    {
                        random -= summary.Enemy.ChanceForAttack3;
                        if (random <= summary.Enemy.ChanceForAttack4)
                        {
                            summary.StateAnimFrames = summary.Enemy.PrimaryAttackAnimFrames4;
                        }
                        else
                        {
                            random -= summary.Enemy.ChanceForAttack4;
                            if (random <= summary.Enemy.ChanceForAttack5)
                            {
                                summary.StateAnimFrames = summary.Enemy.PrimaryAttackAnimFrames5;
                            }
                            else
                            {
                                summary.StateAnimFrames = summary.Enemy.PrimaryAttackAnimFrames;
                            }
                        }
                    }
                }

                // Set to the first frame of this animation, and prepare frameIterator to start from the second frame when AnimateEnemy() next runs
                currentFrame  = summary.StateAnimFrames[0];
                frameIterator = 1;
            }

            if (summary.EnemyState == MobileStates.RangedAttack1 || summary.EnemyState == MobileStates.RangedAttack2)
            {
                summary.StateAnimFrames = summary.Enemy.RangedAttackAnimFrames;

                // Set to the first frame of this animation, and prepare frameIterator to start from the second frame when AnimateEnemy() next runs
                currentFrame  = summary.StateAnimFrames[0];
                frameIterator = 1;
            }

            if (summary.EnemyState == MobileStates.Spell)
            {
                summary.StateAnimFrames = summary.Enemy.SpellAnimFrames;

                // Set to the first frame of this animation, and prepare frameIterator to start from the second frame when AnimateEnemy() next runs
                currentFrame  = summary.StateAnimFrames[0];
                frameIterator = 1;
            }

            if (summary.StateAnims == null)
            {
                // Log error message
                DaggerfallUnity.LogMessage(string.Format("DaggerfalMobileUnit: Enemy does not have animation for {0} state. Defaulting to Idle state.", summary.EnemyState.ToString()), true);

                // Set back to idle (which every enemy has in one form or another)
                summary.EnemyState = MobileStates.Idle;
                summary.StateAnims = GetStateAnims(summary.EnemyState);
            }

            // One of the frost daedra's sets of attack frames starts with the hit frame (-1), so we need to check for that right away before updating orientation.
            if (currentFrame == -1 && summary.EnemyState == MobileStates.PrimaryAttack)
            {
                doMeleeDamage = true;
                if (frameIterator < summary.StateAnimFrames.Length)
                {
                    currentFrame = summary.StateAnimFrames[frameIterator++];
                }
            }

            // Orient enemy relative to camera
            UpdateOrientation();
        }
        /// <summary>
        /// Sets new enemy type.
        /// </summary>
        /// <param name="dfUnity">DaggerfallUnity singleton. Required for content readers and settings.</param>
        /// <param name="enemyType">Enemy type.</param>
        public void SetEnemy(DaggerfallUnity dfUnity, MobileEnemy enemy, MobileReactions reaction)
        {
            // Initial enemy settings
            summary.Enemy = enemy;
            summary.EnemyState = MobileStates.Move;
            summary.Enemy.Reactions = reaction;

            // Load enemy content
            int archive = GetTextureArchive();
            CacheRecordSizesAndFrames(dfUnity, archive);
            AssignMeshAndMaterial(dfUnity, archive);

            // Apply enemy state and update orientation
            lastOrientation = -1;
            ApplyEnemyState();

            // Raise setup flag
            summary.IsSetup = true;
        }
示例#30
0
        /// <summary>
        /// Gets Unity Mesh from previously combined model data.
        /// </summary>
        /// <param name="dfUnity">DaggerfallUnity singleon for loading content.</param>
        /// <param name="combiner">ModelCombiner to build from.</param>
        /// <param name="cachedMaterialsOut">Array of cached materials in order of submesh.</param>
        /// <param name="textureKeysOut">Array of original texture keys in order of submesh.</param>
        /// <param name="hasAnimationsOut">True if one or more materials have animations.</param>
        /// <param name="solveTangents">Solve tangents for this mesh.</param>
        /// <param name="lightmapUVs">Add secondary lightmap UVs to this mesh.</param>
        /// <returns>Mesh object or null.</returns>
        public Mesh GetCombinedMesh(
            DaggerfallUnity dfUnity,
            ModelCombiner combiner,
            out CachedMaterial[] cachedMaterialsOut,
            out int[] textureKeysOut,
            out bool hasAnimationsOut,
            bool solveTangents = false,
            bool lightmapUVs   = false)
        {
            cachedMaterialsOut = null;
            hasAnimationsOut   = false;
            textureKeysOut     = null;

            // Ready check
            if (!IsReady)
            {
                return(null);
            }

            // Get combined model
            ModelCombiner.CombinedModel combinedModel;
            if (!combiner.GetCombinedModel(out combinedModel))
            {
                return(null);
            }

            // Load materials
            cachedMaterialsOut = new CachedMaterial[combinedModel.SubMeshes.Length];
            textureKeysOut     = new int[combinedModel.SubMeshes.Length];
            for (int i = 0; i < combinedModel.SubMeshes.Length; i++)
            {
                int archive = combinedModel.SubMeshes[i].TextureArchive;
                int record  = combinedModel.SubMeshes[i].TextureRecord;
                textureKeysOut[i] = MaterialReader.MakeTextureKey((short)archive, (byte)record, (byte)0);

                // Add material to array
                CachedMaterial cachedMaterial;
                dfUnity.MaterialReader.GetCachedMaterial(archive, record, 0, out cachedMaterial);
                cachedMaterialsOut[i] = cachedMaterial;

                // Set animation flag
                if (cachedMaterial.singleFrameCount > 1 && !hasAnimationsOut)
                {
                    hasAnimationsOut = true;
                }
            }

            // Create mesh
            Mesh mesh = new Mesh();

            mesh.name         = "CombinedMesh";
            mesh.vertices     = combinedModel.Vertices;
            mesh.normals      = combinedModel.Normals;
            mesh.uv           = combinedModel.UVs;
            mesh.subMeshCount = combinedModel.SubMeshes.Length;

            // Set submesh triangles
            for (int s = 0; s < mesh.subMeshCount; s++)
            {
                var   sub       = combinedModel.SubMeshes[s];
                int[] triangles = new int[sub.PrimitiveCount * 3];
                for (int t = 0; t < sub.PrimitiveCount * 3; t++)
                {
                    triangles[t] = combinedModel.Indices[sub.StartIndex + t];
                }
                mesh.SetTriangles(triangles, s);
            }

            // Finalise mesh
            if (solveTangents)
            {
                TangentSolver(mesh);
            }
            if (lightmapUVs)
            {
                AddLightmapUVs(mesh);
            }
            mesh.RecalculateBounds();
            mesh.Optimize();

            return(mesh);
        }
        /// <summary>
        /// Creates mesh and material for this enemy.
        /// </summary>
        /// <param name="dfUnity">DaggerfallUnity singleton. Required for content readers and settings.</param>
        /// <param name="archive">Texture archive index derived from type and gender.</param>
        private void AssignMeshAndMaterial(DaggerfallUnity dfUnity, int archive)
        {
            // Get mesh filter
            if (meshFilter == null)
                meshFilter = GetComponent<MeshFilter>();

            // Vertices for a 1x1 unit quad
            // This is scaled to correct size depending on facing and orientation
            float hx = 0.5f, hy = 0.5f;
            Vector3[] vertices = new Vector3[4];
            vertices[0] = new Vector3(hx, hy, 0);
            vertices[1] = new Vector3(-hx, hy, 0);
            vertices[2] = new Vector3(hx, -hy, 0);
            vertices[3] = new Vector3(-hx, -hy, 0);

            // Indices
            int[] indices = new int[6]
                {
                    0, 1, 2,
                    3, 2, 1,
                };

            // Normals
            Vector3 normal = Vector3.Normalize(Vector3.up + Vector3.forward);
            Vector3[] normals = new Vector3[4];
            normals[0] = normal;
            normals[1] = normal;
            normals[2] = normal;
            normals[3] = normal;

            // Create mesh
            Mesh mesh = new Mesh();
            mesh.name = string.Format("MobileEnemyMesh");
            mesh.vertices = vertices;
            mesh.triangles = indices;
            mesh.normals = normals;

            // Assign mesh
            meshFilter.sharedMesh = mesh;

            // Load material atlas
            Material material = dfUnity.MaterialReader.GetMaterialAtlas(
                archive,
                0,
                4,
                1024,
                out summary.AtlasRects,
                out summary.AtlasIndices,
                4,
                true,
                0,
                false,
                true);

            // Set new enemy material
            GetComponent<MeshRenderer>().sharedMaterial = material;
        }
        void Start()
        {
            dfUnity = DaggerfallUnity.Instance;

            reflectionTexturesScript = GameObject.Find("ReflectionsMod").GetComponent<UpdateReflectionTextures>();

            if (!streamingWorld)
                streamingWorld = GameObject.Find("StreamingWorld").GetComponent<StreamingWorld>();
            if (!streamingWorld)
            {
                DaggerfallUnity.LogMessage("InjectReflectiveMaterialProperty: Missing StreamingWorld reference.", true);
                if (Application.isEditor)
                    Debug.Break();
                else
                    Application.Quit();
            }

            gameObjectReflectionPlaneGroundLevel = GameObject.Find("ReflectionPlaneBottom");
            gameObjectReflectionPlaneSeaLevel = GameObject.Find("ReflectionPlaneSeaLevel");
            gameObjectReflectionPlaneLowerLevel = gameObjectReflectionPlaneSeaLevel;

            // get inactive gameobject StreamingTarget (just GameObject.Find() would fail to find inactive gameobjects)
            GameObject[] gameObjects = Resources.FindObjectsOfTypeAll<GameObject>();
            foreach (GameObject currentGameObject in gameObjects)
            {
                string objectPathInHierarchy = GetGameObjectPath(currentGameObject);
                if (objectPathInHierarchy == "/Exterior/StreamingTarget")
                {
                    gameObjectStreamingTarget = currentGameObject;
                }
            }

            iniData = getIniParserConfigInjectionTextures();
        }
        /// <summary>
        /// Performs a fully standalone in-place location layout.
        /// This method is used only by editor layouts, not by streaming world.
        /// </summary>
        private void LayoutLocation(ref DFLocation location)
        {
#if SHOW_LAYOUT_TIMES
            // Start timing
            System.Diagnostics.Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew();
            long startTime = stopwatch.ElapsedMilliseconds;
#endif

            // Get city dimensions
            int width  = location.Exterior.ExteriorData.Width;
            int height = location.Exterior.ExteriorData.Height;

            // Create billboard batch game objects for this location
            //TextureAtlasBuilder miscBillboardAtlas = null;
            summary.NatureBillboardBatch = null;
            DaggerfallBillboardBatch lightsBillboardBatch  = null;
            DaggerfallBillboardBatch animalsBillboardBatch = null;
            //DaggerfallBillboardBatch miscBillboardBatch = null;
            if (dfUnity.Option_BatchBillboards)
            {
                //miscBillboardAtlas = dfUnity.MaterialReader.MiscBillboardAtlas;
                int natureArchive = ClimateSwaps.GetNatureArchive(CurrentNatureSet, CurrentSeason);
                summary.NatureBillboardBatch = GameObjectHelper.CreateBillboardBatchGameObject(natureArchive, transform);
                lightsBillboardBatch         = GameObjectHelper.CreateBillboardBatchGameObject(TextureReader.LightsTextureArchive, transform);
                animalsBillboardBatch        = GameObjectHelper.CreateBillboardBatchGameObject(TextureReader.AnimalsTextureArchive, transform);
                //miscBillboardBatch = GameObjectHelper.CreateBillboardBatchGameObject(miscBillboardAtlas.AtlasMaterial, transform);
            }

            // Import blocks
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    if (dfUnity.Option_BatchBillboards)
                    {
                        // Set block origin for billboard batches
                        // This causes next additions to be offset by this position
                        Vector3 blockOrigin = new Vector3((x * RMBLayout.RMBSide), 0, (y * RMBLayout.RMBSide));
                        summary.NatureBillboardBatch.BlockOrigin = blockOrigin;
                        lightsBillboardBatch.BlockOrigin         = blockOrigin;
                        animalsBillboardBatch.BlockOrigin        = blockOrigin;
                        //miscBillboardBatch.BlockOrigin = blockOrigin;
                    }

                    string     blockName = dfUnity.ContentReader.BlockFileReader.CheckName(dfUnity.ContentReader.MapFileReader.GetRmbBlockName(ref location, x, y));
                    GameObject go        = GameObjectHelper.CreateRMBBlockGameObject(
                        blockName,
                        x,
                        y,
                        dfUnity.Option_RMBGroundPlane,
                        dfUnity.Option_CityBlockPrefab,
                        summary.NatureBillboardBatch,
                        lightsBillboardBatch,
                        animalsBillboardBatch,
                        null, //miscBillboardAtlas,
                        null, //miscBillboardBatch,
                        CurrentNatureSet,
                        CurrentSeason);
                    go.transform.parent   = this.transform;
                    go.transform.position = new Vector3((x * RMBLayout.RMBSide), 0, (y * RMBLayout.RMBSide));
                }
            }

            // Apply batches
            if (summary.NatureBillboardBatch)
            {
                summary.NatureBillboardBatch.Apply();
            }
            if (lightsBillboardBatch)
            {
                lightsBillboardBatch.Apply();
            }
            if (animalsBillboardBatch)
            {
                animalsBillboardBatch.Apply();
            }
            //if (miscBillboardBatch) miscBillboardBatch.Apply();

            // Enumerate start marker game objects
            EnumerateStartMarkers();

#if SHOW_LAYOUT_TIMES
            // Show timer
            long totalTime = stopwatch.ElapsedMilliseconds - startTime;
            DaggerfallUnity.LogMessage(string.Format("Time to layout location: {0}ms", totalTime), true);
#endif
        }
示例#34
0
        bool IsReady()
        {
            if (!dfUnity)
            {
                dfUnity = DaggerfallUnity.Instance;
            }

            if (itemHelper == null)
            {
                itemHelper = new ItemHelper();
            }

            if (!dfUnity.IsReady || string.IsNullOrEmpty(dfUnity.Arena2Path))
            {
                return(false);
            }

            if (factionFile == null)
            {
                factionFile = new FactionFile(dfUnity.ContentReader.GetFactionFilePath(), FileUsage.UseMemory, true);
            }

            if (saveGames == null || saveTrees == null || saveNames == null)
            {
                saveGames    = new SaveGames();
                saveNames    = new GUIContent[6];
                saveTrees    = new SaveTree[6];
                saveVars     = new SaveVars[6];
                saveTextures = new Texture2D[6];
                if (saveGames.OpenSavesPath(Path.GetDirectoryName(DaggerfallUnity.Instance.Arena2Path)))
                {
                    for (int i = 0; i < 6; i++)
                    {
                        if (saveGames.HasSave(i))
                        {
                            saveGames.OpenSave(i, false);
                            saveTrees[i]               = saveGames.SaveTree;
                            saveVars[i]                = saveGames.SaveVars;
                            saveNames[i]               = new GUIContent(saveGames.SaveName);
                            saveTextures[i]            = TextureReader.CreateFromAPIImage(saveGames.SaveImage);
                            saveTextures[i].filterMode = FilterMode.Point;
                        }
                        else
                        {
                            saveTrees[i]    = null;
                            saveVars[i]     = null;
                            saveTextures[i] = null;
                            saveNames[i]    = new GUIContent("Empty");
                        }
                    }
                }

                // Prevent duplicate names so save games aren't automatically removed from the Save Select GUI
                for (int i = 0; i < saveNames.Length; i++)
                {
                    int duplicateCount = 0;
                    for (int j = i + 1; j < saveNames.Length; j++)
                    {
                        if (saveNames[j].text == saveNames[i].text)
                        {
                            bool unique = false;
                            while (!unique)
                            {
                                unique = true;
                                string replaceText = saveNames[j].text + "(" + ++duplicateCount + ")";
                                for (int k = 0; k < saveNames.Length; k++)
                                {
                                    if (saveNames[k].text == replaceText)
                                    {
                                        unique = false;
                                        break;
                                    }
                                }

                                if (unique)
                                {
                                    saveNames[j].text = replaceText;
                                }
                            }
                        }
                    }
                }
            }

            return(true);
        }
        //void ShowUnknownGUI()
        //{
        //    EditorGUILayout.Space();
        //    showUnknownFoldout = GUILayoutHelper.Foldout(showUnknownFoldout, new GUIContent("Unknown"), () =>
        //    {
        //        EditorGUILayout.Space();
        //        GUILayoutHelper.Indent(() =>
        //        {
        //            EditorGUILayout.LabelField("Unknown1 [1 Bytes]");
        //            EditorGUILayout.SelectableLabel(selectedCareer.RawData.Unknown1.ToString("X2"), EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
        //        });
        //        GUILayoutHelper.Indent(() =>
        //        {
        //            EditorGUILayout.LabelField("Unknown2 [8 Bytes]");
        //            string valuesString = string.Empty;
        //            for (int i = 0; i < selectedCareer.RawData.Unknown2.Length; i++)
        //            {
        //                valuesString += selectedCareer.RawData.Unknown2[i].ToString("X2") + " ";
        //            }
        //            EditorGUILayout.SelectableLabel(valuesString, EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
        //        });
        //    });
        //}
        bool IsReady()
        {
            dfUnity = DaggerfallUnity.Instance;

            if (!dfUnity.IsReady || string.IsNullOrEmpty(dfUnity.Arena2Path))
                return false;

            // Read all CLASS*.CFG files
            if (classTemplates == null)
            {
                string[] files = Directory.GetFiles(dfUnity.Arena2Path, "class*.cfg");
                if (files != null && files.Length > 0)
                {
                    classTemplates = new DFCareer[files.Length - 1];
                    classNames = new GUIContent[files.Length - 1];
                    for (int i = 0; i < files.Length - 1; i++)
                    {
                        ClassFile classFile = new ClassFile(files[i]);
                        classTemplates[i] = classFile.Career;
                        classNames[i] = new GUIContent(classTemplates[i].Name);
                    }
                }
            }

            // Read all ENEMY*.CFG files
            if (monsterTemplates == null)
            {
                MonsterFile monsterFile = new MonsterFile();
                if (monsterFile.Load(Path.Combine(dfUnity.Arena2Path, MonsterFile.Filename), FileUsage.UseMemory, true))
                {
                    // First pass locates CFG record indices
                    List<int> cfgIndices = new List<int>();
                    for (int i = 0; i < monsterFile.Count; i++)
                    {
                        string recordName = monsterFile.GetRecordName(i);
                        if (recordName.EndsWith(".cfg", StringComparison.InvariantCultureIgnoreCase))
                            cfgIndices.Add(i);
                    }

                    // Second pass populates arrays
                    monsterTemplates = new DFCareer[cfgIndices.Count];
                    monsterNames = new GUIContent[cfgIndices.Count];
                    for (int i = 0; i < cfgIndices.Count; i++)
                    {
                        // Read ENEMY.CFG class file from stream
                        ClassFile classFile = new ClassFile();
                        byte[] data = monsterFile.GetRecordBytes(cfgIndices[i]);
                        MemoryStream stream = new MemoryStream(data);
                        BinaryReader reader = new BinaryReader(stream);
                        classFile.Load(reader);
                        reader.Close();

                        // Add to arrays
                        monsterTemplates[i] = classFile.Career;
                        monsterNames[i] = new GUIContent(monsterTemplates[i].Name);
                    }
                }
                else
                {
                    return false;
                }
            }

            return true;
        }
        /// <summary>
        /// Creates mesh and material for this enemy.
        /// </summary>
        /// <param name="dfUnity">DaggerfallUnity singleton. Required for content readers and settings.</param>
        /// <param name="archive">Texture archive index derived from type and gender.</param>
        private void AssignMeshAndMaterial(DaggerfallUnity dfUnity, int archive)
        {
            // Get mesh filter
            if (meshFilter == null)
            {
                meshFilter = GetComponent <MeshFilter>();
            }

            // Vertices for a 1x1 unit quad
            // This is scaled to correct size depending on facing and orientation
            float hx = 0.5f, hy = 0.5f;

            Vector3[] vertices = new Vector3[4];
            vertices[0] = new Vector3(hx, hy, 0);
            vertices[1] = new Vector3(-hx, hy, 0);
            vertices[2] = new Vector3(hx, -hy, 0);
            vertices[3] = new Vector3(-hx, -hy, 0);

            // Indices
            int[] indices = new int[6]
            {
                0, 1, 2,
                3, 2, 1,
            };

            // Normals
            Vector3 normal = Vector3.Normalize(Vector3.up + Vector3.forward);

            Vector3[] normals = new Vector3[4];
            normals[0] = normal;
            normals[1] = normal;
            normals[2] = normal;
            normals[3] = normal;

            // Create mesh
            Mesh mesh = new Mesh();

            mesh.name      = string.Format("MobileEnemyMesh");
            mesh.vertices  = vertices;
            mesh.triangles = indices;
            mesh.normals   = normals;

            // Assign mesh
            meshFilter.sharedMesh = mesh;

            // Load material atlas
            Material material = dfUnity.MaterialReader.GetMaterialAtlas(
                archive,
                0,
                4,
                1024,
                out summary.AtlasRects,
                out summary.AtlasIndices,
                4,
                true,
                0,
                false,
                true);

            // Set new enemy material
            GetComponent <MeshRenderer>().sharedMaterial = material;
        }
 private void SetupSingleton()
 {
     if (instance == null)
         instance = this;
     else if (instance != this)
     {
         if (Application.isPlaying)
         {
             LogMessage("Multiple DaggerfallUnity instances detected in scene!", true);
             Destroy(gameObject);
         }
     }
 }
 void Start()
 {
     dfUnity = DaggerfallUnity.Instance;
 }
        void Start()
        {
            dfUnity = DaggerfallUnity.Instance;

            // Try to find local player GPS if not set
            if (LocalPlayerGPS == null)
            {
                GameObject player = GameObject.FindGameObjectWithTag("Player");
                if (player)
                {
                    LocalPlayerGPS = player.GetComponent<PlayerGPS>();
                }
            }

            // Find main camera gameobject
            GameObject go = GameObject.FindGameObjectWithTag("MainCamera");
            if (go)
            {
                mainCamera = go.GetComponent<Camera>();
            }

            // Check main camera component
            if (!mainCamera)
            {
                DaggerfallUnity.LogMessage("DaggerfallSky could not find MainCamera object. Disabling sky.", true);
                gameObject.SetActive(false);
                return;
            }

            // Save starting clear flags
            initialClearFlags = mainCamera.clearFlags;

            // Get my camera
            myCamera = GetComponent<Camera>();
            if (!myCamera)
            {
                DaggerfallUnity.LogMessage("DaggerfallSky could not find local camera. Disabling sky.", true);
                gameObject.SetActive(false);
                return;
            }

            // My camera must not be on the same GameObject as MainCamera
            if (myCamera == mainCamera)
            {
                DaggerfallUnity.LogMessage("DaggerfallSky must not be attached to same GameObject as MainCamera. Disabling sky.", true);
                gameObject.SetActive(false);
                return;
            }

            // Setup cameras
            SetupCameras();
        }
        /// <summary>
        /// Add interior flats.
        /// </summary>
        private void AddFlats(PlayerGPS.DiscoveredBuilding buildingData)
        {
            GameObject node = new GameObject("Interior Flats");

            node.transform.parent = this.transform;

            // Add block flats
            markers.Clear();
            foreach (DFBlock.RmbBlockFlatObjectRecord obj in recordData.Interior.BlockFlatObjectRecords)
            {
                // Calculate position
                Vector3 billboardPosition = new Vector3(obj.XPos, -obj.YPos, obj.ZPos) * MeshReader.GlobalScale;

                // Import custom 3d gameobject instead of flat
                if (MeshReplacement.ImportCustomFlatGameobject(obj.TextureArchive, obj.TextureRecord, billboardPosition, node.transform) != null)
                {
                    continue;
                }

                // Spawn billboard gameobject
                GameObject go = GameObjectHelper.CreateDaggerfallBillboardGameObject(obj.TextureArchive, obj.TextureRecord, node.transform);

                // Set position
                DaggerfallBillboard dfBillboard = go.GetComponent <DaggerfallBillboard>();
                go.transform.position  = billboardPosition;
                go.transform.position += new Vector3(0, dfBillboard.Summary.Size.y / 2, 0);

                // Add editor markers to list
                if (obj.TextureArchive == TextureReader.EditorFlatsTextureArchive)
                {
                    InteriorEditorMarker marker = new InteriorEditorMarker();
                    marker.type       = (InteriorMarkerTypes)obj.TextureRecord;
                    marker.gameObject = go;
                    markers.Add(marker);

                    // Add loot containers for treasure markers for TG, DB & taverns (uses pile of clothes icon)
                    if (marker.type == InteriorMarkerTypes.Treasure &&
                        (buildingData.buildingType == DFLocation.BuildingTypes.Tavern ||
                         buildingData.factionID == ThievesGuild.FactionId ||
                         buildingData.factionID == DarkBrotherhood.FactionId))
                    {
                        // Create unique LoadID for save system, using 9 lsb and the sign bit from each coord pos int
                        ulong loadID = ((ulong)buildingData.buildingKey) << 30 |
                                       (uint)(obj.XPos << 1 & posMask) << 20 |
                                       (uint)(obj.YPos << 1 & posMask) << 10 |
                                       (uint)(obj.ZPos << 1 & posMask);

                        DaggerfallLoot loot = GameObjectHelper.CreateLootContainer(
                            LootContainerTypes.RandomTreasure,
                            InventoryContainerImages.Chest,
                            billboardPosition,
                            node.transform,
                            DaggerfallLootDataTables.clothingArchive,
                            0, loadID);

                        if (!LootTables.GenerateLoot(loot, (int)GameManager.Instance.PlayerGPS.CurrentLocationType))
                        {
                            DaggerfallUnity.LogMessage(string.Format("DaggerfallInterior: Location type {0} is out of range or unknown.", GameManager.Instance.PlayerGPS.CurrentLocationType), true);
                        }
                    }
                }

                // Add point lights
                if (obj.TextureArchive == TextureReader.LightsTextureArchive)
                {
                    AddLight(obj, go.transform);
                }
            }
        }
        bool IsReady()
        {
            if (!dfUnity)
                dfUnity = DaggerfallUnity.Instance;

            if (!dfUnity.IsReady || string.IsNullOrEmpty(dfUnity.Arena2Path))
                return false;

            if (saveGames == null || saveTrees == null || saveNames == null)
            {
                saveGames = new SaveGames();
                saveNames = new GUIContent[6];
                saveTrees = new SaveTree[6];
                saveTextures = new Texture2D[6];
                if (saveGames.OpenSavesPath(Path.GetDirectoryName(DaggerfallUnity.Instance.Arena2Path)))
                {
                    for (int i = 0; i < 6; i++)
                    {
                        if (saveGames.HasSave(i))
                        {
                            saveGames.OpenSave(i);
                            saveTrees[i] = saveGames.SaveTree;
                            saveNames[i] = new GUIContent(saveGames.SaveName);
                            saveTextures[i] = TextureReader.CreateFromAPIImage(saveGames.SaveImage);
                            saveTextures[i].filterMode = FilterMode.Point;
                        }
                        else
                        {
                            saveTrees[i] = null;
                            saveTextures[i] = null;
                            saveNames[i] = new GUIContent("Empty");
                        }
                    }
                }
            }

            return true;
        }
示例#42
0
        /// <summary>
        /// Updates enemy state based on current settings.
        /// Called automatially by SetEnemyType().
        /// This should be called after changing enemy state (e.g. from in code or in editor).
        /// </summary>
        private void ApplyEnemyState()
        {
            // Get state animations
            summary.StateAnims = GetStateAnims(summary.EnemyState);
            if (summary.EnemyState == MobileStates.PrimaryAttack)
            {
                int random = UnityEngine.Random.Range(1, 101);

                if (random <= summary.Enemy.ChanceForAttack2)
                {
                    summary.StateAnimFrames = summary.Enemy.PrimaryAttackAnimFrames2;
                }
                else
                {
                    random -= summary.Enemy.ChanceForAttack2;
                    if (random <= summary.Enemy.ChanceForAttack3)
                    {
                        summary.StateAnimFrames = summary.Enemy.PrimaryAttackAnimFrames3;
                    }
                    else
                    {
                        random -= summary.Enemy.ChanceForAttack3;
                        if (random <= summary.Enemy.ChanceForAttack4)
                        {
                            summary.StateAnimFrames = summary.Enemy.PrimaryAttackAnimFrames4;
                        }
                        else
                        {
                            random -= summary.Enemy.ChanceForAttack4;
                            if (random <= summary.Enemy.ChanceForAttack5)
                            {
                                summary.StateAnimFrames = summary.Enemy.PrimaryAttackAnimFrames5;
                            }
                            else
                            {
                                summary.StateAnimFrames = summary.Enemy.PrimaryAttackAnimFrames;
                            }
                        }
                    }
                }

                // Set to the first frame of this animation, and prepare frameIterator to start from the second frame when AnimateEnemy() next runs
                currentFrame  = summary.StateAnimFrames[0];
                frameIterator = 1;
            }

            if (summary.EnemyState == MobileStates.RangedAttack1 || summary.EnemyState == MobileStates.RangedAttack2)
            {
                summary.StateAnimFrames = summary.Enemy.RangedAttackAnimFrames;

                // Set to the first frame of this animation, and prepare frameIterator to start from the second frame when AnimateEnemy() next runs
                currentFrame  = summary.StateAnimFrames[0];
                frameIterator = 1;
            }

            if (summary.StateAnims == null)
            {
                // Log error message
                DaggerfallUnity.LogMessage(string.Format("DaggerfalMobileUnit: Enemy does not have animation for {0} state. Defaulting to Idle state.", summary.EnemyState.ToString()), true);

                // Set back to idle (which every enemy has in one form or another)
                summary.EnemyState = MobileStates.Idle;
                summary.StateAnims = GetStateAnims(summary.EnemyState);
            }

            // Orient enemy relative to camera
            UpdateOrientation();
        }
        /// <summary>
        /// Layout interior based on data in exterior door and optional location for climate settings.
        /// </summary>
        /// <param name="doorOwner">Parent transform owning door array.</param>
        /// <param name="door">Exterior door player clicked on.</param>
        /// <returns>True if successful.</returns>
        public bool DoLayout(Transform doorOwner, StaticDoor door, ClimateBases climateBase)
        {
            if (dfUnity == null)
                dfUnity = DaggerfallUnity.Instance;

            // Use specified climate
            this.climateBase = climateBase;

            // Save exterior information
            this.entryDoor = door;
            this.doorOwner = doorOwner;

            // Get block data
            blockData = dfUnity.ContentReader.BlockFileReader.GetBlock(door.blockIndex);
            if (blockData.Type != DFBlock.BlockTypes.Rmb)
                throw new Exception(string.Format("Could not load RMB block index {0}", door.blockIndex), null);

            // Get record data
            recordData = blockData.RmbBlock.SubRecords[door.recordIndex];
            if (recordData.Interior.Header.Num3dObjectRecords == 0)
                throw new Exception(string.Format("No interior 3D models found for record index {0}", door.recordIndex), null);

            // Layout interior data
            AddModels();
            AddFlats();
            AddPeople();
            AddActionDoors();

            return true;
        }
示例#44
0
 void Awake()
 {
     dfUnity = DaggerfallUnity.Instance;
 }
示例#45
0
        void SetupControl()
        {
            dfUnity = DaggerfallUnity.Instance;
            if (!dfUnity.IsReady)
                return;

            // Load highlight texture
            ImgFile imgFile = new ImgFile(Path.Combine(dfUnity.Arena2Path, highlightImgName), FileUsage.UseMemory, true);
            imgFile.LoadPalette(Path.Combine(dfUnity.Arena2Path, imgFile.PaletteName));
            highlightTexture = TextureReader.CreateFromAPIImage(imgFile, 0, 0, 0);
            highlightTexture.filterMode = DaggerfallUI.Instance.GlobalFilterMode;

            // Add buttons
            Vector2 buttonPos = new Vector2(0, 0);
            Vector2 buttonSize = new Vector2(66, 9);
            for (int i = 0; i < 5; i++)
            {
                selectButtons[i] = new Button();
                this.Components.Add(selectButtons[i]);
                selectButtons[i].Position = buttonPos;
                selectButtons[i].Size = buttonSize;
                selectButtons[i].Tag = i;
                selectButtons[i].OnMouseClick += ReflexButton_OnMouseClick;
                buttonPos.y += buttonSize.y;
            }

            // Set size of this panel
            Size = new Vector2(66, 45);

            // Set starting value
            PlayerReflexes = PlayerReflexes.Average;
        }
示例#46
0
        private bool ReadyCheck()
        {
            if (suppressWorld)
                return false;

            if (isReady)
                return true;

            if (dfUnity == null)
            {
                dfUnity = DaggerfallUnity.Instance;
            }

            if (LocalPlayerGPS == null)
                return false;
            else
                InitWorld();

            // Do nothing if DaggerfallUnity not ready
            if (!dfUnity.IsReady)
            {
                DaggerfallUnity.LogMessage("StreamingWorld: DaggerfallUnity component is not ready. Have you set your Arena2 path?");
                return false;
            }

            // Perform initial runtime setup
            if (Application.isPlaying)
            {
                // Fix coastal climate data
                TerrainHelper.DilateCoastalClimate(dfUnity.ContentReader, 2);

                // Smooth steep location on steep gradients
                TerrainHelper.SmoothLocationNeighbourhood(dfUnity.ContentReader);
            }

            // Raise ready flag
            isReady = true;
            RaiseOnReadyEvent();

            return true;
        }
        private bool ReadyCheck()
        {
            // Ensure we have a DaggerfallUnity reference
            if (dfUnity == null)
            {
                dfUnity = DaggerfallUnity.Instance;
            }

            // Do nothing if DaggerfallUnity not ready
            if (!dfUnity.IsReady)
            {
                DaggerfallUnity.LogMessage("MaterialReader: DaggerfallUnity component is not ready. Have you set your Arena2 path?");
                return false;
            }

            // Ensure texture reader is ready
            if (textureReader == null)
            {
                textureReader = new TextureReader(dfUnity.Arena2Path);
            }

            return true;
        }
        bool IsReady()
        {
            if (!dfUnity)
                dfUnity = DaggerfallUnity.Instance;
            if (!dfUnity.IsReady)
                return false;

            return true;
        }
示例#49
0
        private bool ReadyCheck()
        {
            // Ensure we have a DaggerfallUnity reference
            if (dfUnity == null)
            {
                dfUnity = DaggerfallUnity.Instance;
            }

            // Do nothing if DaggerfallUnity not ready
            if (!dfUnity.IsReady)
            {
                DaggerfallUnity.LogMessage("SoundReader: DaggerfallUnity component is not ready. Have you set your Arena2 path?");
                return false;
            }

            // Ensure sound reader is ready
            if (soundFile == null)
            {
                soundFile = new SndFile(Path.Combine(dfUnity.Arena2Path, SndFile.Filename), FileUsage.UseMemory, true);
            }

            return true;
        }
示例#50
0
        void Start()
        {
            // Reference components
            dfUnity = DaggerfallUnity.Instance;
            mainCamera = Camera.main;

            // Adjust scale based on resolution
            // You can plug in your own UI scaling here instead
            if (Screen.currentResolution.height >= 1080 && Screen.currentResolution.height < 1440)
                scale = 3;
            if (Screen.currentResolution.height >= 1440)
                scale = 4;
        }
        private bool ReadyCheck()
        {
            if (ready)
                return true;

            // Ensure we have a DaggerfallUnity reference
            if (dfUnity == null)
            {
                dfUnity = DaggerfallUnity.Instance;
            }

            // Do nothing if DaggerfallUnity not ready
            if (!dfUnity.IsReady)
            {
                DaggerfallUnity.LogMessage("DaggerfallTerrain: DaggerfallUnity component is not ready. Have you set your Arena2 path?");
                return false;
            }

            // Raise ready flag
            ready = true;

            return true;
        }
        /// <summary>
        /// Creates mesh and material for this enemy.
        /// </summary>
        /// <param name="dfUnity">DaggerfallUnity singleton. Required for content readers and settings.</param>
        /// <param name="archive">Texture archive index derived from type and gender.</param>
        private void AssignMeshAndMaterial(DaggerfallUnity dfUnity, int archive)
        {
            // Get mesh filter
            if (meshFilter == null)
            {
                meshFilter = GetComponent <MeshFilter>();
            }

            // Vertices for a 1x1 unit quad
            // This is scaled to correct size depending on facing and orientation
            float hx = 0.5f, hy = 0.5f;

            Vector3[] vertices = new Vector3[4];
            vertices[0] = new Vector3(hx, hy, 0);
            vertices[1] = new Vector3(-hx, hy, 0);
            vertices[2] = new Vector3(hx, -hy, 0);
            vertices[3] = new Vector3(-hx, -hy, 0);

            // Indices
            int[] indices = new int[6]
            {
                0, 1, 2,
                3, 2, 1,
            };

            // Normals
            Vector3 normal = Vector3.Normalize(Vector3.up + Vector3.forward);

            Vector3[] normals = new Vector3[4];
            normals[0] = normal;
            normals[1] = normal;
            normals[2] = normal;
            normals[3] = normal;

            // Create mesh
            Mesh mesh = new Mesh();

            mesh.name      = string.Format("MobileEnemyMesh");
            mesh.vertices  = vertices;
            mesh.triangles = indices;
            mesh.normals   = normals;

            // Assign mesh
            meshFilter.sharedMesh = mesh;

            // Create material
            Material material = TextureReplacement.GetMobileBillboardMaterial(archive, GetComponent <MeshFilter>(), ref summary.ImportedTextures) ??
                                dfUnity.MaterialReader.GetMaterialAtlas(
                archive,
                0,
                4,
                1024,
                out summary.AtlasRects,
                out summary.AtlasIndices,
                4,
                true,
                0,
                false,
                true);

            // Update cached record values in case of non-classic texture
            if (summary.RecordSizes == null || summary.RecordSizes.Length == 0)
            {
                if (summary.ImportedTextures.Albedo != null && summary.ImportedTextures.Albedo.Length > 0)
                {
                    int recordCount = summary.ImportedTextures.Albedo.Length;

                    // Cache size and scale for each record
                    summary.RecordSizes  = new Vector2[recordCount];
                    summary.RecordFrames = new int[recordCount];
                    for (int i = 0; i < recordCount; i++)
                    {
                        // Get size and scale of this texture
                        Texture2D firstFrame = summary.ImportedTextures.Albedo[i][0];

                        Vector2 size = new Vector2(firstFrame.width, firstFrame.height);

                        // Set optional scale
                        TextureReplacement.SetBillboardScale(archive, i, ref size);

                        // Store final size and frame count
                        summary.RecordSizes[i]  = size * MeshReader.GlobalScale;
                        summary.RecordFrames[i] = summary.ImportedTextures.Albedo[i].Length;
                    }
                }
                else
                {
                    Debug.LogError($"Texture archive {archive} has no valid records");
                }
            }

            // Set new enemy material
            GetComponent <MeshRenderer>().sharedMaterial = material;
        }