protected virtual void RaiseOnTransitionInteriorEvent(StaticDoor staticDoor, DaggerfallInterior daggerfallInterior)
 {
     TransitionEventArgs args = new TransitionEventArgs(TransitionType.ToBuildingInterior, staticDoor, daggerfallInterior);
     if (OnTransitionInterior != null)
         OnTransitionInterior(args);
 }
 /// <summary>Constructor helper.</summary>
 public TransitionEventArgs(TransitionType transitionType, StaticDoor staticDoor, DaggerfallInterior daggerfallInterior = null, DaggerfallDungeon daggerfallDungeon = null)
     : base()
 {
     this.TransitionType = transitionType;
     this.StaticDoor = staticDoor;
     this.DaggerfallInterior = daggerfallInterior;
     this.DaggerfallDungeon = daggerfallDungeon;
 }
        /// <summary>
        /// Transition player through an exterior door into building interior.
        /// </summary>
        /// <param name="doorOwner">Parent transform owning door array.</param>
        /// <param name="door">Exterior door player clicked on.</param>
        public void TransitionInterior(Transform doorOwner, StaticDoor door)
        {
            // Ensure we have component references
            if (!ReferenceComponents())
                return;

            // Raise event
            RaiseOnPreTransitionEvent(TransitionType.ToBuildingInterior, door);

            // Get climate
            ClimateBases climateBase = ClimateBases.Temperate;
            if (OverrideLocation)
            {
                climateBase = OverrideLocation.Summary.Climate;
            }
            else if (playerGPS)
            {
                climateBase = ClimateSwaps.FromAPIClimateBase(playerGPS.ClimateSettings.ClimateType);
            }

            // Layout interior
            // This needs to be done first so we know where the enter markers are
            GameObject newInterior = new GameObject(string.Format("DaggerfallInterior [Block={0}, Record={1}]", door.blockIndex, door.recordIndex));
            newInterior.hideFlags = HideFlags.HideAndDontSave;
            interior = newInterior.AddComponent<DaggerfallInterior>();
            interior.DoLayout(doorOwner, door, climateBase);

            // Position interior directly inside of exterior
            // This helps with finding closest enter/exit point relative to player position
            interior.transform.position = doorOwner.position + (Vector3)door.buildingMatrix.GetColumn(3);
            interior.transform.rotation = GameObjectHelper.QuaternionFromMatrix(door.buildingMatrix);

            // Position player above closest enter marker
            Vector3 marker;
            if (!interior.FindClosestEnterMarker(transform.position, out marker))
            {
                // Could not find an enter marker, probably not a valid interior
                Destroy(newInterior);
                return;
            }

            // Assign new interior to parent
            if (InteriorParent != null)
                newInterior.transform.parent = InteriorParent.transform;

            // Disable exterior parent
            if (ExteriorParent != null)
                ExteriorParent.SetActive(false);

            // Enable interior parent
            if (InteriorParent != null)
                InteriorParent.SetActive(true);

            // Cache some information about this interior
            buildingType = interior.BuildingData.BuildingType;

            // Set player to marker position
            // Not sure how to set facing here as player transitions to a marker, not a door
            // Could always find closest door and use that
            transform.position = marker + Vector3.up * (controller.height * 0.6f);
            SetStanding();

            // Player is now inside building
            isPlayerInside = true;

            // Raise event
            RaiseOnTransitionInteriorEvent(door, interior);
        }
        /// <summary>
        /// Transition player through an exterior door into building interior.
        /// </summary>
        /// <param name="doorOwner">Parent transform owning door array..</param>
        /// <param name="door">Exterior door player clicked on.</param>
        public void TransitionInterior(Transform doorOwner, StaticDoor door, bool doFade = false)
        {
            // Ensure we have component references
            if (!ReferenceComponents())
                return;

            // Copy owner position to door
            // This ensures the door itself is all we need to reposition interior
            // Useful when loading a save and doorOwner is null (as outside world does not exist)
            if (doorOwner)
            {
                door.ownerPosition = doorOwner.position;
                door.ownerRotation = doorOwner.rotation;
            }

            // Raise event
            RaiseOnPreTransitionEvent(TransitionType.ToBuildingInterior, door);

            // Get climate
            ClimateBases climateBase = ClimateBases.Temperate;
            if (OverrideLocation)
                climateBase = OverrideLocation.Summary.Climate;
            else if (playerGPS)
                climateBase = ClimateSwaps.FromAPIClimateBase(playerGPS.ClimateSettings.ClimateType);

            // Layout interior
            // This needs to be done first so we know where the enter markers are
            GameObject newInterior = new GameObject(string.Format("DaggerfallInterior [Block={0}, Record={1}]", door.blockIndex, door.recordIndex));
            newInterior.hideFlags = defaultHideFlags;
            interior = newInterior.AddComponent<DaggerfallInterior>();

            // Try to layout interior
            // If we fail for any reason, use that old chestnut "this house has nothing of value"
            try
            {
                interior.DoLayout(doorOwner, door, climateBase);
            }
            catch
            {
                DaggerfallUI.AddHUDText(UserInterfaceWindows.HardStrings.thisHouseHasNothingOfValue);
                Destroy(newInterior);
                return;
            }

            // Position interior directly inside of exterior
            // This helps with finding closest enter/exit point relative to player position
            interior.transform.position = door.ownerPosition + (Vector3)door.buildingMatrix.GetColumn(3);
            interior.transform.rotation = GameObjectHelper.QuaternionFromMatrix(door.buildingMatrix);

            // Position player above closest enter marker
            Vector3 marker;
            if (!interior.FindClosestEnterMarker(transform.position, out marker))
            {
                // Could not find an enter marker, probably not a valid interior
                Destroy(newInterior);
                return;
            }

            // Enumerate all exterior doors belonging to this building
            DaggerfallStaticDoors exteriorStaticDoors = interior.ExteriorDoors;
            if (exteriorStaticDoors && doorOwner)
            {
                List<StaticDoor> buildingDoors = new List<StaticDoor>();
                for (int i = 0; i < exteriorStaticDoors.Doors.Length; i++)
                {
                    if (exteriorStaticDoors.Doors[i].recordIndex == door.recordIndex)
                    {
                        StaticDoor newDoor = exteriorStaticDoors.Doors[i];
                        newDoor.ownerPosition = doorOwner.position;
                        newDoor.ownerRotation = doorOwner.rotation;
                        buildingDoors.Add(newDoor);
                    }
                }
                exteriorDoors = buildingDoors.ToArray();
            }

            // Assign new interior to parent
            if (InteriorParent != null)
                newInterior.transform.parent = InteriorParent.transform;

            // Cache some information about this interior
            buildingType = interior.BuildingData.BuildingType;

            // Set player to marker position
            // TODO: Find closest door for player facing
            transform.position = marker + Vector3.up * (controller.height * 0.6f);
            SetStanding();

            EnableInteriorParent();

            // Raise event
            RaiseOnTransitionInteriorEvent(door, interior);

            // Fade in from black
            if (doFade)
                DaggerfallUI.Instance.FadeHUDFromBlack();
        }
        /// <summary>
        /// Transition player through an interior door to building exterior. Player must be inside.
        /// Interior stores information about exterior, no need for extra params.
        /// </summary>
        public void TransitionExterior()
        {
            // Exit if missing required components or not currently inside
            if (!ReferenceComponents() || !interior || !isPlayerInside)
                return;

            // Raise event
            RaiseOnPreTransitionEvent(TransitionType.ToBuildingExterior);

            // Find closest exterior door
            Vector3 exitDoorPos = Vector3.zero;
            int doorIndex = -1;
            DaggerfallStaticDoors exteriorDoors = interior.ExteriorDoors;
            if (exteriorDoors)
            {
                if (!exteriorDoors.FindClosestDoorToPlayer(transform.position, interior.EntryDoor.recordIndex, out exitDoorPos, out doorIndex))
                {
                    // Could not find exterior door or fall back to entry door
                    // Just push player outside of building, better than having them trapped inside
                    exitDoorPos = transform.position + transform.forward * 4;
                }
            }

            // Enable exterior parent
            if (ExteriorParent != null)
                ExteriorParent.SetActive(true);

            // Disable interior parent
            if (InteriorParent != null)
                InteriorParent.SetActive(false);

            // Destroy interior game object
            Destroy(interior.gameObject);
            interior = null;

            // Set player outside exterior door position
            transform.position = exitDoorPos;
            if (doorIndex >= 0)
            {
                // Adjust player position and facing
                Vector3 normal = exteriorDoors.GetDoorNormal(doorIndex);
                transform.position += normal * (controller.radius * 2f);
                SetFacing(normal);
                SetStanding();
            }

            // Player is now outside building
            isPlayerInside = false;

            // Fire event
            RaiseOnTransitionExteriorEvent();
        }
示例#6
0
 /// <summary>Constructor helper.</summary>
 public TransitionEventArgs(TransitionType transitionType, StaticDoor staticDoor, DaggerfallInterior daggerfallInterior = null, DaggerfallDungeon daggerfallDungeon = null)
     : base()
 {
     this.TransitionType     = transitionType;
     this.StaticDoor         = staticDoor;
     this.DaggerfallInterior = daggerfallInterior;
     this.DaggerfallDungeon  = daggerfallDungeon;
 }
示例#7
0
        /// <summary>
        /// Transition player through an exterior door into building interior.
        /// </summary>
        /// <param name="doorOwner">Parent transform owning door array..</param>
        /// <param name="door">Exterior door player clicked on.</param>
        public void TransitionInterior(Transform doorOwner, StaticDoor door, bool doFade = false)
        {
            // Ensure we have component references
            if (!ReferenceComponents())
            {
                return;
            }

            // Copy owner position to door
            // This ensures the door itself is all we need to reposition interior
            // Useful when loading a save and doorOwner is null (as outside world does not exist)
            if (doorOwner)
            {
                door.ownerPosition = doorOwner.position;
                door.ownerRotation = doorOwner.rotation;
            }

            // Raise event
            RaiseOnPreTransitionEvent(TransitionType.ToBuildingInterior, door);

            // Get climate
            ClimateBases climateBase = ClimateBases.Temperate;

            if (OverrideLocation)
            {
                climateBase = OverrideLocation.Summary.Climate;
            }
            else if (playerGPS)
            {
                climateBase = ClimateSwaps.FromAPIClimateBase(playerGPS.ClimateSettings.ClimateType);
            }

            // Layout interior
            // This needs to be done first so we know where the enter markers are
            GameObject newInterior = new GameObject(string.Format("DaggerfallInterior [Block={0}, Record={1}]", door.blockIndex, door.recordIndex));

            newInterior.hideFlags = defaultHideFlags;
            interior = newInterior.AddComponent <DaggerfallInterior>();

            // Try to layout interior
            // If we fail for any reason, use that old chestnut "this house has nothing of value"
            try
            {
                interior.DoLayout(doorOwner, door, climateBase);
            }
            catch
            {
                DaggerfallUI.AddHUDText(HardStrings.thisHouseHasNothingOfValue);
                Destroy(newInterior);
                return;
            }

            // Position interior directly inside of exterior
            // This helps with finding closest enter/exit point relative to player position
            interior.transform.position = door.ownerPosition + (Vector3)door.buildingMatrix.GetColumn(3);
            interior.transform.rotation = GameObjectHelper.QuaternionFromMatrix(door.buildingMatrix);

            // Position player above closest enter marker
            Vector3 marker;

            if (!interior.FindClosestEnterMarker(transform.position, out marker))
            {
                // Could not find an enter marker, probably not a valid interior
                Destroy(newInterior);
                return;
            }

            // Enumerate all exterior doors belonging to this building
            DaggerfallStaticDoors exteriorStaticDoors = interior.ExteriorDoors;

            if (exteriorStaticDoors && doorOwner)
            {
                List <StaticDoor> buildingDoors = new List <StaticDoor>();
                for (int i = 0; i < exteriorStaticDoors.Doors.Length; i++)
                {
                    if (exteriorStaticDoors.Doors[i].recordIndex == door.recordIndex)
                    {
                        StaticDoor newDoor = exteriorStaticDoors.Doors[i];
                        newDoor.ownerPosition = doorOwner.position;
                        newDoor.ownerRotation = doorOwner.rotation;
                        buildingDoors.Add(newDoor);
                    }
                }
                SetExteriorDoors(buildingDoors.ToArray());
            }

            // Assign new interior to parent
            if (InteriorParent != null)
            {
                newInterior.transform.parent = InteriorParent.transform;
            }

            // Cache some information about this interior
            buildingType = interior.BuildingData.BuildingType;

            // Set player to marker position
            // TODO: Find closest door for player facing
            transform.position = marker + Vector3.up * (controller.height * 0.6f);
            SetStanding();

            EnableInteriorParent();

            // Add quest resources
            GameObjectHelper.AddQuestResourceObjects(SiteTypes.Building, interior.transform, interior.EntryDoor.buildingKey);

            // Raise event
            RaiseOnTransitionInteriorEvent(door, interior);

            // Fade in from black
            if (doFade)
            {
                DaggerfallUI.Instance.FadeHUDFromBlack();
            }
        }
示例#8
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);
        }
示例#9
0
        /// <summary>
        /// Transition player through an exterior door into building interior.
        /// </summary>
        /// <param name="doorOwner">Parent transform owning door array.</param>
        /// <param name="door">Exterior door player clicked on.</param>
        public void TransitionInterior(Transform doorOwner, StaticDoor door)
        {
            // Ensure we have component references
            if (!ReferenceComponents())
            {
                return;
            }

            // Get current climate
            ClimateBases climateBase = ClimateBases.Temperate;

            if (playerGPS)
            {
                climateBase = ClimateSwaps.FromAPIClimateBase(playerGPS.ClimateSettings.ClimateType);
            }

            // Layout interior
            // This needs to be done first so we know where the enter markers are
            GameObject newInterior = new GameObject(string.Format("DaggerfallInterior [Block={0}, Record={1}]", door.blockIndex, door.recordIndex));

            newInterior.hideFlags = HideFlags.HideAndDontSave;
            interior = newInterior.AddComponent <DaggerfallInterior>();
            interior.DoLayout(doorOwner, door, climateBase);

            // Position interior directly inside of exterior
            // This helps with finding closest enter/exit point relative to player position
            interior.transform.position = doorOwner.position + (Vector3)door.buildingMatrix.GetColumn(3);
            interior.transform.rotation = GameObjectHelper.QuaternionFromMatrix(door.buildingMatrix);

            // Position player above closest enter marker
            Vector3 marker;

            if (!interior.FindClosestEnterMarker(transform.position, out marker))
            {
                // Could not find an enter marker, probably not a valid interior
                Destroy(newInterior);
                return;
            }

            // Assign new interior to parent
            if (InteriorParent != null)
            {
                newInterior.transform.parent = InteriorParent.transform;
            }

            // Disable exterior parent
            if (ExteriorParent != null)
            {
                ExteriorParent.SetActive(false);
            }

            // Enable interior parent
            if (InteriorParent != null)
            {
                InteriorParent.SetActive(true);
            }

            // Set player to marker position
            // Not sure how to set facing here as player transitions to a marker, not a door
            // Could always find closest door and use that
            transform.position = marker + Vector3.up * (controller.height * 0.6f);
            SetStanding();

            // Player is now inside building
            isPlayerInside = true;
        }