public void Die() { if (!mobile) { return; } // Get corpse marker texture indices int archive, record; EnemyBasics.ReverseCorpseTexture(mobile.Summary.Enemy.CorpseTexture, out archive, out record); // Leave corpse marker DaggerfallUnity dfUnity = DaggerfallUnity.Instance; if (dfUnity) { // Spawn marker GameObject go = GameObjectHelper.CreateDaggerfallBillboardGameObject(archive, record, transform.parent, true); go.transform.position = transform.position; // Align to ground. Be generous with distance as flying enemies might have a way to drop. // This could also be hanlded by adding a Rigidbody and collider then let gravity do the work. GameObjectHelper.AlignBillboardToGround(go, go.GetComponent <DaggerfallBillboard>().Summary.Size, 16f); } // Disable enemy gameobject and schedule for destruction gameObject.SetActive(false); GameObject.Destroy(gameObject); }
public override void OnInspectorGUI() { // Update serializedObject.Update(); DrawDefaultInspector(); if (GUILayout.Button("Apply Person Type")) { setupMobilePerson.ApplyPersonSettingsViaInspector(); } if (GUILayout.Button("Align To Ground")) { MobilePersonBillboard mobilePerson = setupMobilePerson.GetComponentInChildren <MobilePersonBillboard>(); if (mobilePerson) { Vector3 billboardSize = mobilePerson.GetBillboardSize(); GameObjectHelper.AlignBillboardToGround(setupMobilePerson.gameObject, billboardSize); } } // Save modified properties serializedObject.ApplyModifiedProperties(); if (GUI.changed) { EditorUtility.SetDirty(target); } }
private static void OnTransitionToInterior_VariantShopTavernNPCsprites(PlayerEnterExit.TransitionEventArgs args) { PlayerEnterExit playerEnterExit = GameManager.Instance.PlayerEnterExit; DFLocation.BuildingData buildingData = playerEnterExit.Interior.BuildingData; if (buildingData.BuildingType == DFLocation.BuildingTypes.Tavern || RMBLayout.IsShop(buildingData.BuildingType)) { Billboard[] dfBillboards = playerEnterExit.Interior.GetComponentsInChildren <Billboard>(); foreach (Billboard billboard in dfBillboards) { int record = -1; if (billboard.Summary.Archive == 182 && billboard.Summary.Record == 0) { record = GetRecord_182_0(buildingData.Quality); // (buildingData.Quality - 1) / 4; #if UNITY_EDITOR Debug.LogFormat("Shop quality {0} using record {1} to replace 182_0", buildingData.Quality, record); #endif } else if (billboard.Summary.Archive == 182 && billboard.Summary.Record == 1) { if (buildingData.Quality < 12) { // Using big test flats version record = 4; } else if (buildingData.Quality > 14) { record = 5; } #if UNITY_EDITOR Debug.LogFormat("Tavern quality {0} using record {1} to replace 182_1", buildingData.Quality, record); #endif } else if (billboard.Summary.Archive == 182 && billboard.Summary.Record == 2) { if (buildingData.Quality > 12) { record = 6; } #if UNITY_EDITOR Debug.LogFormat("Tavern quality {0} using record {1} to replace 182_2", buildingData.Quality, record); #endif } if (record > -1) { billboard.SetMaterial(197, record); GameObjectHelper.AlignBillboardToGround(billboard.gameObject, billboard.Summary.Size); } } } }
public void PlaceCorpseMarker(int corpseTexture) { // Get corpse marker texture indices int archive, record; EnemyBasics.ReverseCorpseTexture(corpseTexture, out archive, out record); // Spawn corpse marker GameObject go = GameObjectHelper.CreateDaggerfallBillboardGameObject(archive, record, transform.parent, true); go.transform.position = transform.position; // Align to ground. Be generous with distance as flying enemies might have a way to drop. // This could also be handled by adding a Rigidbody and collider then let gravity do the work. // TODO: Ensure corpse markers never land on top of other monsters GameObjectHelper.AlignBillboardToGround(go, go.GetComponent <DaggerfallBillboard>().Summary.Size, 16f); }
/// <summary> /// Spawn a new pool item within range of player. /// </summary> void SpawnAvailableMobile() { // Player must be in range of location if (!playerInLocationRange) { return; } // Get a free mobile from pool int item = GetNextFreePoolItem(); if (item == -1) { return; } // Get closest point on navgrid to player position in world DFPosition playerWorldPos = new DFPosition(playerGPS.WorldX, playerGPS.WorldZ); DFPosition playerGridPos = cityNavigation.WorldToNavGridPosition(playerWorldPos); // Spawn mobile at a random position and schedule to be live DFPosition spawnPosition; if (cityNavigation.GetRandomSpawnPosition(playerGridPos, out spawnPosition, navGridSpawnRadius)) { PoolItem poolItem = populationPool[item]; // Setup spawn position DFPosition worldPosition = cityNavigation.NavGridToWorldPosition(spawnPosition); Vector3 scenePosition = cityNavigation.WorldToScenePosition(worldPosition); poolItem.npc.Motor.transform.position = scenePosition; GameObjectHelper.AlignBillboardToGround(poolItem.npc.Motor.gameObject, new Vector2(0, 2f)); // Schedule for enabling poolItem.active = true; poolItem.scheduleEnable = true; populationPool[item] = poolItem; } }
private void DisplayAboutGUI() { EditorGUILayout.Space(); ShowCustomBillboardFoldout = GUILayoutHelper.Foldout(ShowCustomBillboardFoldout, new GUIContent("Custom"), () => { var propCustomArchive = Prop("customArchive"); var propCustomRecord = Prop("customRecord"); GUILayoutHelper.Indent(() => { propCustomArchive.intValue = EditorGUILayout.IntField(new GUIContent("Archive", "Set texture archive index (e.g. TEXTURE.210 is 210)"), propCustomArchive.intValue); propCustomRecord.intValue = EditorGUILayout.IntField(new GUIContent("Record", "Set texture record index (between 0-n)"), propCustomRecord.intValue); if (GUILayout.Button("Set Billboard Texture")) { try { dfBillboard.SetMaterial(propCustomArchive.intValue, propCustomRecord.intValue); } catch (Exception ex) { Debug.Log("Failed to set custom billboard texture. Exception: " + ex.Message); } } if (GUILayout.Button("Align To Surface")) { GameObjectHelper.AlignBillboardToGround(dfBillboard.gameObject, dfBillboard.Summary.Size, 4); } }); }); EditorGUILayout.Space(); ShowAboutBillboardFoldout = GUILayoutHelper.Foldout(ShowAboutBillboardFoldout, new GUIContent("About"), () => { GUILayoutHelper.Indent(() => { GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField("File", GUILayout.Width(EditorGUIUtility.labelWidth - 4)); EditorGUILayout.SelectableLabel(TextureFile.IndexToFileName(dfBillboard.Summary.Archive), EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight)); }); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField("Index", GUILayout.Width(EditorGUIUtility.labelWidth - 4)); EditorGUILayout.SelectableLabel(dfBillboard.Summary.Record.ToString(), EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight)); }); //GUILayoutHelper.Horizontal(() => //{ // EditorGUILayout.LabelField("In Dungeon", GUILayout.Width(EditorGUIUtility.labelWidth - 4)); // EditorGUILayout.SelectableLabel(dfBillboard.Summary.InDungeon.ToString(), EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight)); //}); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField("Is Mobile", GUILayout.Width(EditorGUIUtility.labelWidth - 4)); EditorGUILayout.SelectableLabel(dfBillboard.Summary.IsMobile.ToString(), EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight)); }); if (dfBillboard.Summary.IsMobile) { GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField("Flags", GUILayout.Width(EditorGUIUtility.labelWidth - 4)); EditorGUILayout.SelectableLabel(dfBillboard.Summary.Flags.ToString(), EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight)); }); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField("Type", GUILayout.Width(EditorGUIUtility.labelWidth - 4)); EditorGUILayout.SelectableLabel(dfBillboard.Summary.FixedEnemyType.ToString(), EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight)); }); } GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField("Is Atlased", GUILayout.Width(EditorGUIUtility.labelWidth - 4)); EditorGUILayout.SelectableLabel(dfBillboard.Summary.AtlasedMaterial.ToString(), EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight)); }); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField("Is Animated", GUILayout.Width(EditorGUIUtility.labelWidth - 4)); EditorGUILayout.SelectableLabel(dfBillboard.Summary.AnimatedMaterial.ToString(), EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight)); }); GUILayoutHelper.Horizontal(() => { EditorGUILayout.LabelField("Current Frame", GUILayout.Width(EditorGUIUtility.labelWidth - 4)); EditorGUILayout.SelectableLabel(dfBillboard.Summary.CurrentFrame.ToString(), EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight)); }); }); }); }
private static void OnTransitionToInterior_VariantResidenceNPCsprites(PlayerEnterExit.TransitionEventArgs args) { if (villagerVarietyMod != null && villagerVarietyNumVariants == 0) { ModManager.Instance.SendModMessage(VILLAGERVARIETY_MODNAME, "getNumVariants", null, (string message, object data) => { villagerVarietyNumVariants = (int)data; }); } PlayerEnterExit playerEnterExit = GameManager.Instance.PlayerEnterExit; DFLocation.BuildingData buildingData = playerEnterExit.Interior.BuildingData; if (RMBLayout.IsResidence(buildingData.BuildingType)) { Races race = GetClimateRace(); int gender = -1; Billboard[] dfBillboards = playerEnterExit.Interior.GetComponentsInChildren <Billboard>(); foreach (Billboard billboard in dfBillboards) { if (billboard.Summary.Archive == 182) { gender = GetGender182(billboard.Summary.Record); } else if (billboard.Summary.Archive == 184) { gender = GetGender184(billboard.Summary.Record); } if (gender != -1) { StaticNPC npc = billboard.GetComponent <StaticNPC>(); if (npc && npc.Data.factionID == 0) { int faceVariant = npc.Data.nameSeed % 29; Debug.LogFormat("Replace house NPC {0}.{1} with faceVariant {2} - {3}", billboard.Summary.Archive, billboard.Summary.Record, faceVariant, faceVariant < 24); if (faceVariant < 24) { int outfitVariant = npc.Data.nameSeed % 4; int archive = gender == (int)Genders.Male ? raceArchivesMale[race][outfitVariant] : raceArchivesFemale[race][outfitVariant]; int record = 5; int faceRecord = gender == (int)Genders.Male ? raceFaceRecordMale[race][outfitVariant] : raceFaceRecordFemale[race][outfitVariant]; faceRecord += faceVariant; bool materialSet = false; if (villagerVarietyMod != null) { int variant = npc.Data.nameSeed % villagerVarietyNumVariants; string season = ""; //ModManager.Instance.SendModMessage(VILLAGERVARIETY_MODNAME, "getSeasonStr", null, (string message, object data) => { season = (string)data; }); Debug.LogFormat("Replace house NPC {0}.{1} with {2}.{3}, outfit: {4} faceRecord: {5} ({6}) variant: {7} season: {8}", billboard.Summary.Archive, billboard.Summary.Record, archive, record, outfitVariant, faceRecord, faceVariant, variant, season); string imageName = null; ModManager.Instance.SendModMessage(VILLAGERVARIETY_MODNAME, "getImageName", new object[] { archive, record, 0, faceRecord, variant, season }, (string message, object data) => { imageName = (string)data; }); if (!string.IsNullOrEmpty(imageName) && villagerVarietyMod.HasAsset(imageName)) { // Get texture and create material Texture2D texture = villagerVarietyMod.GetAsset <Texture2D>(imageName); Material material = MaterialReader.CreateStandardMaterial(MaterialReader.CustomBlendMode.Cutout); material.mainTexture = texture; // Apply material to mesh renderer MeshRenderer meshRenderer = billboard.GetComponent <MeshRenderer>(); meshRenderer.sharedMaterial = material; // Create mesh and setup UV map for mesh filter Vector2 size; Mesh mesh = DaggerfallUnity.Instance.MeshReader.GetBillboardMesh(new Rect(0, 0, 1, 1), archive, record, out size); mesh.uv = new Vector2[] { new Vector2(0, 1), new Vector2(1, 1), new Vector2(0, 0), new Vector2(1, 0) }; MeshFilter meshFilter = billboard.GetComponent <MeshFilter>(); Destroy(meshFilter.sharedMesh); meshFilter.sharedMesh = mesh; materialSet = true; } } if (!materialSet) { billboard.SetMaterial(archive, record); billboard.FramesPerSecond = 1; } GameObjectHelper.AlignBillboardToGround(billboard.gameObject, billboard.Summary.Size); Dictionary <int, FlatsFile.FlatData> flatsDict = DaggerfallUnity.Instance.ContentReader.FlatsFileReader.FlatsDict; int flatId = FlatsFile.GetFlatID(npc.Data.billboardArchiveIndex, npc.Data.billboardRecordIndex); #if UNITY_EDITOR Debug.LogFormat("Replacing face dict for {0} with {1} (for {2}.{3} / {4}.{5})", flatsDict[flatId].faceIndex, faceRecord, npc.Data.billboardArchiveIndex, npc.Data.billboardRecordIndex, billboard.Summary.Archive, billboard.Summary.Record); #endif flatsDict[flatId] = new FlatsFile.FlatData() { archive = billboard.Summary.Archive, record = billboard.Summary.Record, faceIndex = faceRecord, }; } } } } } }