示例#1
0
        /// <summary>
        /// Add interior people flats.
        /// </summary>
        private void AddPeople(PlayerGPS.DiscoveredBuilding buildingData)
        {
            GameObject node = new GameObject("People Flats");

            node.transform.parent = this.transform;
            bool isMemberOfBuildingGuild = GameManager.Instance.GuildManager.GetGuild(buildingData.factionID).IsMember();

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

                // Import 3D character instead of billboard
                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 RMB data to billboard
                dfBillboard.SetRMBPeopleData(obj);

                // Add StaticNPC behaviour
                StaticNPC npc = go.AddComponent <StaticNPC>();
                npc.SetLayoutData(obj, entryDoor.buildingKey);

                // Disable people if shop or building is closed
                DFLocation.BuildingTypes buildingType = buildingData.buildingType;
                if ((RMBLayout.IsShop(buildingType) && !GameManager.Instance.PlayerEnterExit.IsPlayerInsideOpenShop) ||
                    (buildingType <= DFLocation.BuildingTypes.Palace && !RMBLayout.IsShop(buildingType) && !PlayerActivate.IsBuildingOpen(buildingType)))
                {
                    go.SetActive(false);
                }
                // Disable people if player owns this house
                else if (DaggerfallBankManager.IsHouseOwned(buildingData.buildingKey))
                {
                    go.SetActive(false);
                }
                // Disable people if this is TG/DB house and player is not a member
                else if (buildingData.buildingType == DFLocation.BuildingTypes.House2 && buildingData.factionID != 0 && !isMemberOfBuildingGuild)
                {
                    go.SetActive(false);
                }
                // Disable people if they are TG spymaster, but not in a legit TG house (TODO: spot any other instances for TG/DB)
                else if (buildingData.buildingType == DFLocation.BuildingTypes.House2 && buildingData.factionID == 0 &&
                         npc.Data.factionID == (int)GuildNpcServices.TG_Spymaster)
                {
                    go.SetActive(false);
                }
            }
        }
示例#2
0
        /// <summary>
        /// Add interior people flats.
        /// </summary>
        private void AddPeople(PlayerGPS.DiscoveredBuilding buildingData)
        {
            GameObject node = new GameObject(peopleFlats);

            node.transform.parent = this.transform;
            IGuild guild = GameManager.Instance.GuildManager.GetGuild(buildingData.factionID);
            bool   isMemberOfBuildingGuild = guild.IsMember();

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

                // Make person gameobject
                GameObject go = MeshReplacement.ImportCustomFlatGameobject(obj.TextureArchive, obj.TextureRecord, billboardPosition, node.transform);
                if (!go)
                {
                    // Spawn billboard 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 RMB data to billboard
                    dfBillboard.SetRMBPeopleData(obj);
                }

                // Add StaticNPC behaviour
                StaticNPC npc = go.AddComponent <StaticNPC>();
                npc.SetLayoutData(obj, entryDoor.buildingKey);

                // Disable people if shop or building is closed
                DFLocation.BuildingTypes buildingType = buildingData.buildingType;
                if ((RMBLayout.IsShop(buildingType) && !GameManager.Instance.PlayerEnterExit.IsPlayerInsideOpenShop) ||
                    (buildingType <= DFLocation.BuildingTypes.Palace && !RMBLayout.IsShop(buildingType) &&
                     !(PlayerActivate.IsBuildingOpen(buildingType) || buildingType == DFLocation.BuildingTypes.GuildHall && guild.HallAccessAnytime())))
                {
                    go.SetActive(false);
                }
                // Disable people if player owns this house
                else if (DaggerfallBankManager.IsHouseOwned(buildingData.buildingKey))
                {
                    go.SetActive(false);
                }
                // Disable people if this is TG/DB house and player is not a member
                else if (buildingData.buildingType == DFLocation.BuildingTypes.House2 && buildingData.factionID != 0 && !isMemberOfBuildingGuild)
                {
                    go.SetActive(false);
                }
            }
        }
示例#3
0
        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);
                    }
                }
            }
        }
示例#4
0
        private static void ShopShelfBurglar(RaycastHit hit)
        {
            PlayerGPS.DiscoveredBuilding buildingData = GameManager.Instance.PlayerEnterExit.BuildingDiscoveryData;
            if (RMBLayout.IsShop(buildingData.buildingType) && !PlayerActivate.IsBuildingOpen(buildingData.buildingType))
            {
                int stealthValue = playerEntity.Skills.GetLiveSkillValue(DFCareer.Skills.Stealth);
                stealthValue -= buildingData.quality * 2;

                if (Dice100.FailedRoll(StealthCalc(stealthValue, false)))
                {
                    burglaryCounter += Mathf.Clamp(UnityEngine.Random.Range(100, 200) - playerEntity.Stats.LiveLuck, 10, 100);
                }
            }
        }
示例#5
0
        private void AddFurnitureAction(DFBlock.RmbBlock3dObjectRecord obj, GameObject go, PlayerGPS.DiscoveredBuilding buildingData)
        {
            // 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);

            DFLocation.BuildingTypes buildingType = buildingData.buildingType;

            // Handle shelves:
            if (shopShelvesObjectGroupIndices.Contains(obj.ModelIdNum - containerObjectGroupOffset))
            {
                if (RMBLayout.IsShop(buildingType))
                {
                    // Shop shelves, so add a DaggerfallLoot component
                    DaggerfallLoot loot = go.AddComponent <DaggerfallLoot>();
                    if (loot)
                    {
                        // Set as shelves, assign load id and create serialization object
                        loot.ContainerType  = LootContainerTypes.ShopShelves;
                        loot.ContainerImage = InventoryContainerImages.Shelves;
                        loot.LoadID         = loadID;
                        if (SaveLoadManager.Instance != null)
                        {
                            go.AddComponent <SerializableLootContainer>();
                        }
                    }
                }
                else if (buildingType == DFLocation.BuildingTypes.Library ||
                         buildingType == DFLocation.BuildingTypes.GuildHall ||
                         buildingType == DFLocation.BuildingTypes.Temple)
                {
                    // Bookshelves, add DaggerfallBookshelf component
                    go.AddComponent <DaggerfallBookshelf>();
                }
                else if (DaggerfallBankManager.IsHouseOwned(buildingData.buildingKey))
                {   // Player owned house, everything is a house container
                    MakeHouseContainer(obj, go, loadID);
                }
            }
            // Handle generic furniture as (private) house containers:
            // (e.g. shelves, boxes, wardrobes, drawers etc)
            else if (obj.ModelIdNum / 100 == houseContainerObjectGroup ||
                     houseContainerObjectGroupIndices.Contains(obj.ModelIdNum - containerObjectGroupOffset))
            {
                MakeHouseContainer(obj, go, loadID);
            }
        }
示例#6
0
        /// <summary>
        /// Update NPC presence for shops and guilds after resting/idling.
        /// </summary>
        public void UpdateNpcPresence()
        {
            PlayerEnterExit playerEnterExit = GameManager.Instance.PlayerEnterExit;

            DFLocation.BuildingTypes buildingType = playerEnterExit.BuildingType;
            if ((RMBLayout.IsShop(buildingType) && !playerEnterExit.IsPlayerInsideOpenShop) ||
                (!RMBLayout.IsShop(buildingType) && buildingType <= DFLocation.BuildingTypes.Palace && buildingType != DFLocation.BuildingTypes.HouseForSale))
            {
                Transform npcTransforms = transform.Find(peopleFlats);
                if (PlayerActivate.IsBuildingOpen(buildingType))
                {
                    foreach (Transform npcTransform in npcTransforms)
                    {
                        npcTransform.gameObject.SetActive(true);
                    }
                    Debug.Log("Updated npcs to be present.");
                }
            }
        }
        // Player has clicked on a static NPC
        void StaticNPCClick(StaticNPC npc)
        {
            // Do nothing if no NPC passed or fade in progress
            // Quest machine does not tick while fading (to prevent things happening while screen is black)
            // But this can result in player clicking a quest NPC before quest state ticks after load and breaking quest
            if (!npc || DaggerfallUI.Instance.FadeInProgress)
            {
                return;
            }

            // Store the NPC just clicked in quest engine
            QuestMachine.Instance.LastNPCClicked = npc;

            // Check if this NPC is a quest giver and show temp guild quest popup
            // This will be changed later when temp guild system replaced with real thing
            if (QuestorCheck(npc))
            {
                return;
            }

            // Handle quest NPC click and exit if linked to a Person resource
            QuestResourceBehaviour questResourceBehaviour = npc.gameObject.GetComponent <QuestResourceBehaviour>();

            if (questResourceBehaviour)
            {
                if (TriggerQuestResourceBehaviourClick(questResourceBehaviour))
                {
                    return;
                }
            }

            // Do nothing further if a quest is actively listening on this individual NPC
            // This NPC not reserved as a Person resource but has a WhenNpcIsAvailable action listening on it
            // This effectively shuts down several named NPCs during main quest, but not trivial to otherwise determine appropriate access
            // TODO: Try to find a good solution for releasing listeners when the owning action is disabled
            if (QuestMachine.Instance.HasFactionListener(npc.Data.factionID))
            {
                return;
            }

            // Get faction data.
            FactionFile.FactionData factionData;
            if (playerEnterExit.IsPlayerInsideBuilding &&
                GameManager.Instance.PlayerEntity.FactionData.GetFactionData(npc.Data.factionID, out factionData))
            {
                UserInterfaceManager uiManager = DaggerfallUI.Instance.UserInterfaceManager;
                Debug.LogFormat("faction id: {0}, social group: {1}, guild: {2}",
                                npc.Data.factionID, (FactionFile.SocialGroups)factionData.sgroup, (FactionFile.GuildGroups)factionData.ggroup);

                // Check if the NPC offers a guild service.
                if (Enum.IsDefined(typeof(GuildServices), npc.Data.factionID))
                {
                    FactionFile.GuildGroups guild   = (FactionFile.GuildGroups)factionData.ggroup;
                    GuildServices           service = (GuildServices)npc.Data.factionID;
                    Debug.Log("NPC offers guild service: " + service.ToString());
                    uiManager.PushWindow(new DaggerfallGuildServicePopupWindow(uiManager, npc, guild, service));
                }
                // Check if this NPC is a merchant.
                else if ((FactionFile.SocialGroups)factionData.sgroup == FactionFile.SocialGroups.Merchants)
                {
                    // Shop?
                    if (RMBLayout.IsShop(playerEnterExit.BuildingDiscoveryData.buildingType))
                    {
                        if (RMBLayout.IsRepairShop(playerEnterExit.BuildingDiscoveryData.buildingType))
                        {
                            uiManager.PushWindow(new DaggerfallMerchantRepairPopupWindow(uiManager, npc));
                        }
                        else
                        {
                            uiManager.PushWindow(new DaggerfallMerchantServicePopupWindow(uiManager, npc, DaggerfallMerchantServicePopupWindow.Services.Sell));
                        }
                    }
                    // Bank?
                    else if (playerEnterExit.BuildingDiscoveryData.buildingType == DFLocation.BuildingTypes.Bank)
                    {
                        uiManager.PushWindow(new DaggerfallMerchantServicePopupWindow(uiManager, npc, DaggerfallMerchantServicePopupWindow.Services.Banking));
                    }
                    // Tavern?
                    else if (playerEnterExit.BuildingDiscoveryData.buildingType == DFLocation.BuildingTypes.Tavern)
                    {
                        // for now only talk to all npc in taverns - TODO: add tavern option in here
                        GameManager.Instance.TalkManager.TalkToStaticNPC(npc);
                    }
                }
                // TODO - more checks for npc social types?
                else // if no special handling had to be done for npc with social group of type merchant: talk to the static npc
                {
                    GameManager.Instance.TalkManager.TalkToStaticNPC(npc);
                }
            }
            else // if no special handling had to be done (all remaining npcs of the remaining social groups not handled explicitely above): default is talk to the static npc
            {
                // with one exception: guards
                if (npc.Data.billboardArchiveIndex == 183 && npc.Data.billboardRecordIndex == 3) // detect if clicked guard (comment Nystul: didn't find a better mechanism than billboard texture check)
                {
                    return;                                                                      // if guard was clicked don't open talk window
                }
                // otherwise open talk window
                GameManager.Instance.TalkManager.TalkToStaticNPC(npc);
            }
        }
        // Display a shop quality level
        private DaggerfallMessageBox PresentShopQuality(StaticBuilding building)
        {
            const int qualityLevel1TextId = 266;    // "Incense and soft music soothe your nerves"
            const int qualityLevel2TextId = 267;    // "The shop is better appointed than many"
            const int qualityLevel3TextId = 268;    // "The shop is laid out in a practical"
            const int qualityLevel4TextId = 269;    // "Sturdy shelves, cobbled together"
            const int qualityLevel5TextId = 270;    // "Rusty relics lie wherever they were last tossed"

            // Get building directory for location
            BuildingDirectory buildingDirectory = GameManager.Instance.StreamingWorld.GetCurrentBuildingDirectory();

            if (!buildingDirectory)
            {
                return(null);
            }

            // Get detailed building data from directory
            BuildingSummary buildingSummary;

            if (!buildingDirectory.GetBuildingSummary(building.buildingKey, out buildingSummary))
            {
                return(null);
            }

            // Do nothing if not a shop
            if (!RMBLayout.IsShop(buildingSummary.BuildingType))
            {
                return(null);
            }

            // Set quality level text ID from quality value 01-20
            // UESP states this is building quality / 4 but Daggerfall uses manual thresholds
            int qualityTextId;

            if (buildingSummary.Quality <= 3)
            {
                qualityTextId = qualityLevel5TextId;        // 01 - 03
            }
            else if (buildingSummary.Quality <= 7)
            {
                qualityTextId = qualityLevel4TextId;        // 04 - 07
            }
            else if (buildingSummary.Quality <= 13)
            {
                qualityTextId = qualityLevel3TextId;        // 08 - 13
            }
            else if (buildingSummary.Quality <= 17)
            {
                qualityTextId = qualityLevel2TextId;        // 14 - 17
            }
            else
            {
                qualityTextId = qualityLevel1TextId;        // 18 - 20
            }
            // Log quality of building entered for debugging
            //Debug.Log("Entered store with quality of " + buildingData.Quality);

            // Output quality text based on settings
            switch (DaggerfallUnity.Settings.ShopQualityPresentation)
            {
            case 0:         // Display popup as per classic
                return(DaggerfallUI.MessageBox(qualityTextId));

            case 1:         // Display HUD text only with variable delay
                TextFile.Token[] tokens = DaggerfallUnity.Instance.TextProvider.GetRSCTokens(qualityTextId);
                for (int i = 0; i < tokens.Length; i++)
                {
                    if (tokens[i].formatting == TextFile.Formatting.Text)
                    {
                        DaggerfallUI.AddHUDText(tokens[i].text, DaggerfallUnity.Settings.ShopQualityHUDDelay);
                    }
                }
                break;

            case 2:         // Display nothing about shop quality
            default:
                return(null);
            }

            return(null);
        }
示例#9
0
        static void ThiefEffects_OnNewMagicRound()
        {
            //Debug.Log("[ThiefOverhaul] Magic Round");
            if (playerEnterExit.IsPlayerInsideBuilding)
            {
                PlayerGPS.DiscoveredBuilding buildingData = GameManager.Instance.PlayerEnterExit.BuildingDiscoveryData;
                if (RMBLayout.IsShop(buildingData.buildingType) && !PlayerActivate.IsBuildingOpen(buildingData.buildingType))
                {
                    int stealthValue = playerEntity.Skills.GetLiveSkillValue(DFCareer.Skills.Stealth);
                    stealthValue -= buildingData.quality * 2;

                    if (Dice100.FailedRoll(StealthCalc(stealthValue, false)))
                    {
                        if (burglaryCounter >= 100)
                        {
                            DaggerfallUI.MessageBox("'Guards! Guards! We're being robbed!'");
                            if (Dice100.SuccessRoll(playerEntity.Stats.LiveLuck))
                            {
                                playerEntity.MagicalConcealmentFlags = MagicalConcealmentFlags.None;
                                DaggerfallUI.AddHUDText("Your magical concealment is broken");
                            }

                            playerEntity.CrimeCommitted = PlayerEntity.Crimes.Breaking_And_Entering;
                            playerEntity.SpawnCityGuards(true);
                        }
                        else if (burglaryCounter == 0)
                        {
                            DaggerfallUI.MessageBox(burglaryString1());
                            burglaryCounter += Mathf.Clamp(UnityEngine.Random.Range(100, 200) - playerEntity.Stats.LiveLuck, 10, 100);
                        }
                        else if (burglaryCounter < 50)
                        {
                            DaggerfallUI.MessageBox(burglaryString2());
                            burglaryCounter += Mathf.Clamp(UnityEngine.Random.Range(100, 200) - playerEntity.Stats.LiveLuck, 10, 100);
                        }
                        else
                        {
                            burglaryCounter += Mathf.Clamp(UnityEngine.Random.Range(100, 200) - playerEntity.Stats.LiveLuck, 10, 100);
                        }
                    }
                }
            }

            DaggerfallUnityItem ringSlot0     = playerEntity.ItemEquipTable.GetItem(EquipSlots.Ring0);
            DaggerfallUnityItem ringSlot1     = playerEntity.ItemEquipTable.GetItem(EquipSlots.Ring1);
            DaggerfallUnityItem markSlot0     = playerEntity.ItemEquipTable.GetItem(EquipSlots.Mark0);
            DaggerfallUnityItem markSlot1     = playerEntity.ItemEquipTable.GetItem(EquipSlots.Mark1);
            DaggerfallUnityItem braceletSlot0 = playerEntity.ItemEquipTable.GetItem(EquipSlots.Bracelet0);
            DaggerfallUnityItem braceletSlot1 = playerEntity.ItemEquipTable.GetItem(EquipSlots.Bracelet1);
            DaggerfallUnityItem bracerSlot0   = playerEntity.ItemEquipTable.GetItem(EquipSlots.Bracer0);
            DaggerfallUnityItem bracerSlot1   = playerEntity.ItemEquipTable.GetItem(EquipSlots.Bracer1);
            DaggerfallUnityItem crystalSlot0  = playerEntity.ItemEquipTable.GetItem(EquipSlots.Crystal0);
            DaggerfallUnityItem crystalSlot1  = playerEntity.ItemEquipTable.GetItem(EquipSlots.Crystal1);

            if (ringSlot0 != null && ringSlot0.TemplateIndex == templateIndex_Ring)
            {
                lockpickingBonus = 20;
            }
            else if (ringSlot1 != null && ringSlot1.TemplateIndex == templateIndex_Ring)
            {
                lockpickingBonus = 20;
            }
            else
            {
                lockpickingBonus = 0;
            }

            if (markSlot0 != null && markSlot0.TemplateIndex == templateIndex_Mark)
            {
                streetwiseBonus = 20;
            }
            else if (markSlot1 != null && markSlot1.TemplateIndex == templateIndex_Mark)
            {
                streetwiseBonus = 20;
            }
            else
            {
                streetwiseBonus = 0;
            }

            if (braceletSlot0 != null && braceletSlot0.TemplateIndex == templateIndex_Bracelet)
            {
                pickpocketBonus = 20;
            }
            else if (braceletSlot1 != null && braceletSlot1.TemplateIndex == templateIndex_Bracelet)
            {
                pickpocketBonus = 20;
            }
            else
            {
                pickpocketBonus = 0;
            }

            if (bracerSlot0 != null && bracerSlot0.TemplateIndex == templateIndex_Bracer)
            {
                climbingBonus = 20;
            }
            else if (bracerSlot1 != null && bracerSlot1.TemplateIndex == templateIndex_Bracer)
            {
                climbingBonus = 20;
            }
            else
            {
                climbingBonus = 0;
            }

            if (crystalSlot0 != null && crystalSlot0.TemplateIndex == templateIndex_Crystal)
            {
                stealthBonus = 20;
            }
            else if (crystalSlot1 != null && crystalSlot1.TemplateIndex == templateIndex_Crystal)
            {
                stealthBonus = 20;
            }
            else
            {
                stealthBonus = 0;
            }


            if (!GameManager.IsGamePaused && playerEntity.CurrentHealth > 0)
            {
                int[] skillMods = new int[DaggerfallSkills.Count];
                skillMods[(int)DFCareer.Skills.Lockpicking] = +lockpickingBonus;
                skillMods[(int)DFCareer.Skills.Streetwise]  = +streetwiseBonus;
                skillMods[(int)DFCareer.Skills.Pickpocket]  = +pickpocketBonus;
                skillMods[(int)DFCareer.Skills.Climbing]    = +climbingBonus;
                skillMods[(int)DFCareer.Skills.Stealth]     = +stealthBonus;
                playerEffectManager.MergeDirectSkillMods(skillMods);
            }
        }