/// <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); }
/// <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); } } }
/// <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); } } }
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; } }
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); } }
/// <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); }
/// <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); }
/// <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); }