예제 #1
0
        /// <summary>
        /// Gets discovered building data for current location.
        /// </summary>
        /// <param name="buildingKey">Building key in current location.</param>
        /// <param name="discoveredBuildingOut">Building discovery data out.</param>
        /// <returns>True if building discovered, false if building not discovered.</returns>
        public bool GetDiscoveredBuilding(int buildingKey, out DiscoveredBuilding discoveredBuildingOut)
        {
            discoveredBuildingOut = new DiscoveredBuilding();

            // Must have discovered building
            if (!HasDiscoveredBuilding(buildingKey))
            {
                return(false);
            }

            // Get the location discovery for this mapID
            int mapPixelID        = MapsFile.GetMapPixelIDFromLongitudeLatitude((int)CurrentLocation.MapTableData.Longitude, CurrentLocation.MapTableData.Latitude);
            DiscoveredLocation dl = discoveredLocations[mapPixelID];

            if (dl.discoveredBuildings == null)
            {
                return(false);
            }

            // Get discovery data for building
            discoveredBuildingOut = dl.discoveredBuildings[buildingKey];

            // Check if name should be overridden (owned house / quest site)
            PlayerEntity playerEntity = GameManager.Instance.PlayerEntity;

            if (DaggerfallBankManager.IsHouseOwned(buildingKey))
            {
                discoveredBuildingOut.displayName = HardStrings.playerResidence.Replace("%s", playerEntity.Name);
            }

            return(true);
        }
예제 #2
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);
                }
            }
        }
예제 #3
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);
                }
            }
        }
예제 #4
0
        void CheckInterior()
        {
            if (CurrentBuildingKey == 0)
            {
                Debug.LogWarning("CurrentBuildingKey == 0");
                return;
            }
            else
            {
                if (!DaggerfallBankManager.IsHouseOwned(CurrentBuildingKey))
                {
                    if (playerHomeObjects.ContainsKey(CurrentBuildingKey))
                    {
                        playerHomeObjects.Remove(CurrentBuildingKey);
                    }

                    if (DaggerfallInterior.GetSceneName(playerGPS.CurrentMapID, BuildingDirectory.buildingKey0) == Ship1Interior ||
                        DaggerfallInterior.GetSceneName(playerGPS.CurrentMapID, BuildingDirectory.buildingKey0) == Ship2Interior)
                    {
                        CreatePlacedObjects(playerShipObjects, PlayerShip);
                        inPlayerHome         = false;
                        inPlayerShip         = true;
                        inPlayerShipExterior = false;
                    }
                    else
                    {
                        inPlayerHome         = false;
                        inPlayerShip         = false;
                        inPlayerShipExterior = false;
                    }
                }
                else
                {
                    PlacedObjectData_v2[] value = null;

                    if (playerHomeObjects.ContainsKey(CurrentBuildingKey))
                    {
                        playerHomeObjects.TryGetValue(CurrentBuildingKey, out value);
                        CreatePlacedObjects(value, PlayerHome);
                    }
                    else
                    {
                        playerHomeObjects.Add(CurrentBuildingKey, value);
                    }

                    inPlayerHome         = true;
                    inPlayerShip         = false;
                    inPlayerShipExterior = false;
                }

                lastBuildingKey = CurrentBuildingKey;
            }
        }
예제 #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>
        /// Check if player is allowed to rest at this location.
        /// </summary>
        bool CanRest(bool alreadyWarned = false)
        {
            remainingHoursRented = -1;
            allocatedBed         = Vector3.zero;
            PlayerEnterExit playerEnterExit = GameManager.Instance.PlayerEnterExit;
            PlayerGPS       playerGPS       = GameManager.Instance.PlayerGPS;

            if (playerGPS.IsPlayerInTown(true, true))
            {
                if (!alreadyWarned)
                {
                    CloseWindow();
                    DaggerfallUI.MessageBox(cityCampingIllegal);
                }

                // Register crime and start spawning guards
                playerEntity.CrimeCommitted = PlayerEntity.Crimes.Vagrancy;
                playerEntity.SpawnCityGuards(true);

                return(alreadyWarned);
            }
            else if (playerGPS.IsPlayerInTown() && playerEnterExit.IsPlayerInsideBuilding)
            {
                // Check owned locations
                string sceneName = DaggerfallInterior.GetSceneName(playerGPS.CurrentLocation.MapTableData.MapId, playerEnterExit.BuildingDiscoveryData.buildingKey);
                if (SaveLoadManager.StateManager.ContainsPermanentScene(sceneName))
                {
                    // Can rest if it's an player owned ship/house.
                    int buildingKey = playerEnterExit.BuildingDiscoveryData.buildingKey;
                    if (playerEnterExit.BuildingType == DFLocation.BuildingTypes.Ship || DaggerfallBankManager.IsHouseOwned(buildingKey))
                    {
                        return(true);
                    }

                    // Find room rental record and get remaining time..
                    int           mapId = playerGPS.CurrentLocation.MapTableData.MapId;
                    RoomRental_v1 room  = GameManager.Instance.PlayerEntity.GetRentedRoom(mapId, buildingKey);
                    remainingHoursRented = PlayerEntity.GetRemainingHours(room);

                    // Get allocated bed marker - default to 0 if out of range
                    // We relink marker position by index as building positions are not stable, they can move from terrain mods or floating Y
                    Vector3[] restMarkers = playerEnterExit.Interior.FindMarkers(DaggerfallInterior.InteriorMarkerTypes.Rest);
                    int       bedIndex    = (room.allocatedBedIndex >= 0 && room.allocatedBedIndex < restMarkers.Length) ? room.allocatedBedIndex : 0;
                    allocatedBed = restMarkers[bedIndex];
                    if (remainingHoursRented > 0)
                    {
                        return(true);
                    }
                }
                // Check for guild hall rest privileges (exclude taverns since they are all marked as fighters guilds in data)
                if (playerEnterExit.BuildingDiscoveryData.buildingType != DFLocation.BuildingTypes.Tavern &&
                    GameManager.Instance.GuildManager.GetGuild(playerEnterExit.BuildingDiscoveryData.factionID).CanRest())
                {
                    playerEnterExit.Interior.FindMarker(out allocatedBed, DaggerfallInterior.InteriorMarkerTypes.Rest);
                    return(true);
                }
                CloseWindow();
                DaggerfallUI.MessageBox(TextManager.Instance.GetLocalizedText("haveNotRentedRoom"));
                return(false);
            }
            return(true);
        }
예제 #7
0
        /// <summary>
        /// Gets building information from current location.
        /// Does not change discovery state for building.
        /// </summary>
        /// <param name="buildingKey">Key of building to query.</param>
        /// <param name="buildingDiscoveryData">[out] building discovery data of queried building</param>
        /// <returns>True if building discovered, false if building not discovered.</returns>
        bool GetBuildingDiscoveryData(int buildingKey, out DiscoveredBuilding buildingDiscoveryData)
        {
            buildingDiscoveryData = new DiscoveredBuilding();

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

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

            // Get detailed building data from directory
            BuildingSummary buildingSummary;

            if (!buildingDirectory.GetBuildingSummary(buildingKey, out buildingSummary))
            {
                int layoutX, layoutY, recordIndex;
                BuildingDirectory.ReverseBuildingKey(buildingKey, out layoutX, out layoutY, out recordIndex);
                Debug.LogFormat("Unable to find expected building key {0} in {1}.{2}", buildingKey, buildingDirectory.LocationData.RegionName, buildingDirectory.LocationData.Name);
                Debug.LogFormat("LayoutX={0}, LayoutY={1}, RecordIndex={2}", layoutX, layoutY, recordIndex);
                return(false);
            }

            // Resolve name by building type
            string buildingName;

            if (RMBLayout.IsResidence(buildingSummary.BuildingType))
            {
                // Residence
                buildingName = HardStrings.residence;

                // Link to quest system active sites
                // note Nystul: do this via TalkManager, this might seem odd at first glance but there is a reason to do so:
                //              get info from TalkManager if pc learned about existence of the building (i.e. its name)
                //              either through dialog ("add dialog" or by dialog-link) or quest (quest did not hide location via "dialog link" command)
                bool   pcLearnedAboutExistence     = false;
                bool   receivedDirectionalHints    = false;
                bool   locationWasMarkedOnMapByNPC = false;
                string overrideBuildingName        = string.Empty;
                if (GameManager.Instance.TalkManager.IsBuildingQuestResource(buildingSummary.buildingKey, ref overrideBuildingName, ref pcLearnedAboutExistence, ref receivedDirectionalHints, ref locationWasMarkedOnMapByNPC))
                {
                    if (pcLearnedAboutExistence)
                    {
                        buildingName = overrideBuildingName;
                    }
                }
            }
            else
            {
                // Fixed building name
                buildingName = BuildingNames.GetName(
                    buildingSummary.NameSeed,
                    buildingSummary.BuildingType,
                    buildingSummary.FactionId,
                    buildingDirectory.LocationData.Name,
                    buildingDirectory.LocationData.RegionName);
            }

            // Add to data
            buildingDiscoveryData.buildingKey  = buildingKey;
            buildingDiscoveryData.displayName  = buildingName;
            buildingDiscoveryData.factionID    = buildingSummary.FactionId;
            buildingDiscoveryData.quality      = buildingSummary.Quality;
            buildingDiscoveryData.buildingType = buildingSummary.BuildingType;

            // Check if name should be overridden (owned house / quest site)
            PlayerEntity playerEntity = GameManager.Instance.PlayerEntity;

            if (DaggerfallBankManager.IsHouseOwned(buildingKey))
            {
                buildingDiscoveryData.displayName = HardStrings.playerResidence.Replace("%s", playerEntity.Name);
            }

            return(true);
        }
        /// <summary>
        /// Check if player is allowed to rest at this location.
        /// </summary>
        bool CanRest()
        {
            remainingHoursRented = -1;
            allocatedBed         = Vector3.zero;
            PlayerEnterExit playerEnterExit = GameManager.Instance.PlayerEnterExit;
            PlayerGPS       playerGPS       = GameManager.Instance.PlayerGPS;

            bool inTown = playerGPS.IsPlayerInTown(true);

            if (inTown && !playerEnterExit.IsPlayerInside)
            {
                CloseWindow();
                DaggerfallUI.MessageBox(cityCampingIllegal);

                // Register crime and start spawning guards
                playerEntity.CrimeCommitted = PlayerEntity.Crimes.Vagrancy;
                playerEntity.SpawnCityGuards(true);

                return(false);
            }
            else if ((inTown || !playerGPS.HasCurrentLocation) && playerEnterExit.IsPlayerInsideBuilding)
            {
                // Check for guild hall rest privileges
                if (GameManager.Instance.GuildManager.GetGuild(playerEnterExit.BuildingDiscoveryData.factionID).CanRest())
                {
                    playerEnterExit.Interior.FindMarker(out allocatedBed, DaggerfallInterior.InteriorMarkerTypes.Rest);
                    return(true);
                }
                // Check owned locations
                string sceneName = DaggerfallInterior.GetSceneName(playerGPS.CurrentLocation.MapTableData.MapId, playerEnterExit.BuildingDiscoveryData.buildingKey);
                if (SaveLoadManager.StateManager.ContainsPermanentScene(sceneName))
                {
                    // Can rest if it's an player owned ship/house.
                    int buildingKey = playerEnterExit.BuildingDiscoveryData.buildingKey;
                    if (playerEnterExit.BuildingType == DFLocation.BuildingTypes.Ship || DaggerfallBankManager.IsHouseOwned(buildingKey))
                    {
                        return(true);
                    }

                    // Find room rental record and get remaining time..
                    int           mapId = playerGPS.CurrentLocation.MapTableData.MapId;
                    RoomRental_v1 room  = GameManager.Instance.PlayerEntity.GetRentedRoom(mapId, buildingKey);
                    remainingHoursRented = PlayerEntity.GetRemainingHours(room);
                    allocatedBed         = room.allocatedBed;
                    if (remainingHoursRented > 0)
                    {
                        return(true);
                    }
                }
                CloseWindow();
                DaggerfallUI.MessageBox(HardStrings.haveNotRentedRoom);
                return(false);
            }
            return(true);
        }
예제 #9
0
        /// <summary>
        /// Check if player is allowed to rest at this location.
        /// </summary>
        bool CanRest()
        {
            remainingHoursRented = -1;
            allocatedBed         = Vector3.zero;
            PlayerEnterExit playerEnterExit = GameManager.Instance.PlayerEnterExit;
            PlayerGPS       playerGPS       = GameManager.Instance.PlayerGPS;

            bool inTown = playerGPS.IsPlayerInTown(true);

            if (inTown && !playerEnterExit.IsPlayerInside)
            {
                CloseWindow();
                DaggerfallUI.MessageBox(cityCampingIllegal);
                return(false);
            }
            else if ((inTown || !playerGPS.HasCurrentLocation) && playerEnterExit.IsPlayerInsideBuilding)
            {
                string sceneName = DaggerfallInterior.GetSceneName(playerGPS.CurrentLocation.MapTableData.MapId, playerEnterExit.BuildingDiscoveryData.buildingKey);
                if (SaveLoadManager.StateManager.ContainsPermanentScene(sceneName))
                {
                    // Can rest if it's an player owned ship/house.
                    int buildingKey = playerEnterExit.BuildingDiscoveryData.buildingKey;
                    if (playerEnterExit.BuildingType == DFLocation.BuildingTypes.Ship || DaggerfallBankManager.IsHouseOwned(buildingKey))
                    {
                        return(true);
                    }

                    // Find room rental record and get remaining time..
                    int           mapId = playerGPS.CurrentLocation.MapTableData.MapId;
                    RoomRental_v1 room  = GameManager.Instance.PlayerEntity.GetRentedRoom(mapId, buildingKey);
                    remainingHoursRented = PlayerEntity.GetRemainingHours(room);
                    allocatedBed         = room.allocatedBed;
                    if (remainingHoursRented > 0)
                    {
                        return(true);
                    }
                }
                CloseWindow();
                DaggerfallUI.MessageBox(HardStrings.haveNotRentedRoom);
                return(false);
            }
            return(true);
        }