Exemple #1
0
        void ParseQBN(Quest quest, List <string> lines)
        {
            bool foundHeadlessTask = false;

            for (int i = 0; i < lines.Count; i++)
            {
                // Skip empty lines while scanning for next QBN item
                if (string.IsNullOrEmpty(lines[i].Trim()))
                {
                    continue;
                }

                // Simple way to identify certain lines
                // This is just to get started on some basics for now
                if (lines[i].StartsWith("clock", StringComparison.InvariantCultureIgnoreCase))
                {
                    Clock clock = new Clock(quest, lines[i]);
                    quest.AddResource(clock);
                }
                else if (lines[i].StartsWith("item", StringComparison.InvariantCultureIgnoreCase))
                {
                    Item item = new Item(quest, lines[i]);
                    quest.AddResource(item);
                }
                else if (lines[i].StartsWith("person", StringComparison.InvariantCultureIgnoreCase))
                {
                    // This is a person declaration
                    Person person = new Person(quest, lines[i]);
                    quest.AddResource(person);
                }
                else if (lines[i].StartsWith("foe", StringComparison.InvariantCultureIgnoreCase))
                {
                    // This is an enemy declaration
                    Foe foe = new Foe(quest, lines[i]);
                    quest.AddResource(foe);
                }
                else if (lines[i].StartsWith("place", StringComparison.InvariantCultureIgnoreCase))
                {
                    // This is a place declaration
                    Place place = new Place(quest, lines[i]);
                    quest.AddResource(place);
                }
                else if (lines[i].StartsWith("variable", StringComparison.InvariantCultureIgnoreCase))
                {
                    // This is a single-line variable declaration task
                    string[] variableLines = new string[1];
                    variableLines[0] = lines[i];
                    Task task = new Task(quest, variableLines);
                    quest.AddTask(task);
                }
                else if (lines[i].Contains("task:") ||
                         (lines[i].StartsWith("until", StringComparison.InvariantCultureIgnoreCase) && lines[i].Contains("performed:")))
                {
                    // This is a standard or repeating task declaration
                    List <string> taskLines = ReadBlock(lines, ref i);
                    Task          task      = new Task(quest, taskLines.ToArray());
                    quest.AddTask(task);
                }
                else if (IsGlobalReference(lines[i]))
                {
                    // Check if following line is another task or a line break
                    bool hasBody = false;
                    if (i + 1 != lines.Count)
                    {
                        hasBody = !IsNewTaskOrLineBreak(lines[i + 1]);
                    }

                    // This is a global variable link task
                    Task task;
                    int  globalVar = GetGlobalReference(lines[i]);
                    if (hasBody)
                    {
                        List <string> taskLines = ReadBlock(lines, ref i);
                        task = new Task(quest, taskLines.ToArray(), globalVar);
                    }
                    else
                    {
                        string[] variableLines = new string[1];
                        variableLines[0] = lines[i];
                        task             = new Task(quest, variableLines, globalVar);
                    }
                    quest.AddTask(task);
                }
                else if (foundHeadlessTask == false)
                {
                    // The first QBN line found that is not a resource declaration should be our headless entry point
                    // Currently only a single headless task is expected for startup task
                    // May be expanded later to allow multiple headless tasks
                    List <string> taskLines = ReadBlock(lines, ref i);
                    Task          task      = new Task(quest, taskLines.ToArray());
                    quest.AddTask(task);
                    foundHeadlessTask = true;
                }
                else
                {
                    // Something went wrong
                    throw new Exception(string.Format("Unknown line signature encounted '{0}'.", lines[i]));
                }
            }
        }
Exemple #2
0
        void AssignHomeTown()
        {
            Place  homePlace;
            string symbolName = string.Format("_{0}_home_", Symbol.Name);

            // If this is a Questor or individual NPC then use current location of player using a special helper
            if (isQuestor || (IsIndividualNPC && isIndividualAtHome))
            {
                homePlace = new Place(ParentQuest);
                if (GameManager.Instance.PlayerGPS.HasCurrentLocation)
                {
                    if (!homePlace.ConfigureFromPlayerLocation(symbolName))
                    {
                        throw new Exception("AssignHomeTown() could not configure questor/individual home from current player location.");
                    }

                    homePlaceSymbol = homePlace.Symbol;
                    ParentQuest.AddResource(homePlace);
                    LogHomePlace(homePlace);
                    return;
                }
            }

            // For other NPCs use default scope and building type
            Place.Scopes scope = Place.Scopes.Remote;
            string       buildingTypeString = "house";

            // Adjust scope and building type based on faction hints
            int p1 = 0, p2 = 0, p3 = 0;

            if (!string.IsNullOrEmpty(factionTableKey))
            {
                // Get faction parameters
                p1 = Parser.ParseInt(QuestMachine.Instance.FactionsTable.GetValue("p1", factionTableKey));
                p2 = Parser.ParseInt(QuestMachine.Instance.FactionsTable.GetValue("p2", factionTableKey));
                p3 = Parser.ParseInt(QuestMachine.Instance.FactionsTable.GetValue("p3", factionTableKey));

                // Set based on parameters
                if (p1 == 0 && p2 == -3 || p1 == 0 && p2 == -4)
                {
                    // For local types set to local place
                    // This will support Local_3.0 - Local_4.10k
                    // Referencing quest Sx009 where player must locate and click an NPC with only a home location to go by
                    scope = Place.Scopes.Local;
                }
                else if (p1 == 0 && p2 >= 0 && p2 <= 20 && p3 == 0)
                {
                    // Set to a specific building type
                    buildingTypeString = QuestMachine.Instance.PlacesTable.GetKeyForValue("p2", p2.ToString());
                }
            }

            // Get scope string - must be "local" or "remote"
            string scopeString = string.Empty;

            if (scope == Place.Scopes.Local)
            {
                scopeString = "local";
            }
            else if (scope == Place.Scopes.Remote)
            {
                scopeString = "remote";
            }
            else
            {
                throw new Exception("AssignHomeTown() scope must be either 'local' or 'remote'.");
            }

            // Create the home location
            string source = string.Format("Place {0} {1} {2}", symbolName, scopeString, buildingTypeString);

            homePlace       = new Place(ParentQuest, source);
            homePlaceSymbol = homePlace.Symbol.Clone();
            ParentQuest.AddResource(homePlace);
            LogHomePlace(homePlace);


            //
            // NOTE: Keeping the below for reference only at this time
            //

            //const string blank = "BLANK";

            //// If this is a Questor or individual NPC then use current location name
            //// Person is being instantiated where player currently is
            //if (isQuestor || (IsIndividualNPC && isIndividualAtHome))
            //{
            //    if (GameManager.Instance.PlayerGPS.HasCurrentLocation)
            //    {
            //        homeTownName = GameManager.Instance.PlayerGPS.CurrentLocation.Name;
            //        homeRegionName = GameManager.Instance.PlayerGPS.CurrentLocation.RegionName;
            //        homeBuildingName = blank;
            //        return;
            //    }
            //}

            //// Handle specific home Place assigned at create time
            //if (homePlaceSymbol != null)
            //{
            //    Place home = ParentQuest.GetPlace(homePlaceSymbol);
            //    if (home != null)
            //    {
            //        homeTownName = home.SiteDetails.locationName;
            //        homeRegionName = home.SiteDetails.regionName;
            //        homeBuildingName = home.SiteDetails.buildingName;
            //    }
            //}
            //else
            //{
            //    // Find a random location name from town types for flavour text
            //    // This might take a few attempts but will very quickly find a random town name
            //    int index;
            //    bool found = false;
            //    int regionIndex = GameManager.Instance.PlayerGPS.CurrentRegionIndex;
            //    DFRegion regionData = DaggerfallUnity.Instance.ContentReader.MapFileReader.GetRegion(regionIndex);
            //    while (!found)
            //    {
            //        index = UnityEngine.Random.Range(0, regionData.MapTable.Length);
            //        DFRegion.LocationTypes locationType = regionData.MapTable[index].LocationType;
            //        if (locationType == DFRegion.LocationTypes.TownCity ||
            //            locationType == DFRegion.LocationTypes.TownHamlet ||
            //            locationType == DFRegion.LocationTypes.TownVillage)
            //        {
            //            homeTownName = regionData.MapNames[index];
            //            homeRegionName = regionData.Name;
            //            homeBuildingName = blank;
            //            found = true;
            //        }
            //    }
            //}

            //// Handle Local_3.x group NPCs (limited)
            //// These appear to be a special case of assigning a residential person who is automatically instantiated to home Place
            //// Creating a full target Place for this person automatically and storing in Quest
            //// NOTE: Understanding is still being developed here, likely will need to rework this later
            //if (QuestMachine.Instance.FactionsTable.HasValue(careerAllianceName))
            //{
            //    // Get params for this case
            //    int p1 = Parser.ParseInt(QuestMachine.Instance.FactionsTable.GetValue("p1", careerAllianceName));
            //    int p2 = Parser.ParseInt(QuestMachine.Instance.FactionsTable.GetValue("p2", careerAllianceName));
            //    //int p3 = Parser.ParseInt(QuestMachine.Instance.FactionsTable.GetValue("p3", careerAllianceName));

            //    // Only supporting specific cases for now - can expand later based on testing and iteration of support
            //    // This will support Local_3.0 - Local_3.3
            //    // Referencing quest Sx009 here where player must locate and click an NPC with only a home location to go by
            //    if (p1 == 0 && p2 == -3)
            //    {
            //        // Just using "house2" here as actual meaning of p3 unknown
            //        string homeSymbol = string.Format("_{0}_home_", Symbol.Name);
            //        string source = string.Format("Place {0} remote house2", homeSymbol);
            //        Place home = new Place(ParentQuest, source);
            //        homePlaceSymbol = home.Symbol.Clone();
            //        ParentQuest.AddResource(home);
            //    }
            //    else if (p1 == 0 && p2 >= 0)
            //    {
            //        // Handle standard building types
            //        string buildingSymbol = string.Format("_{0}_building_", Symbol.Name);
            //        string buildingType = QuestMachine.Instance.PlacesTable.GetKeyForValue("p2", p2.ToString());
            //        string source = string.Format("Place {0} remote {1}", buildingSymbol, buildingType);
            //        Place building = new Place(ParentQuest, source);
            //        homePlaceSymbol = building.Symbol.Clone();
            //        ParentQuest.AddResource(building);
            //    }
            //}
        }
        public override void Update(Task caller)
        {
            base.Update(caller);

            // Do nothing while player respawning
            if (GameManager.Instance.PlayerEnterExit.IsRespawning)
            {
                return;
            }

            // Handle resume on next tick of action after respawn process complete
            if (resumePending)
            {
                GameObject player = GameManager.Instance.PlayerObject;
                player.transform.position = resumePosition;
                resumePending             = false;
                SetComplete();
                return;
            }

            // Create SiteLink if not already present
            if (!QuestMachine.HasSiteLink(ParentQuest, targetPlace))
            {
                QuestMachine.CreateSiteLink(ParentQuest, targetPlace);
            }

            // Attempt to get Place resource
            Place place = ParentQuest.GetPlace(targetPlace);

            if (place == null)
            {
                return;
            }

            // Get selected spawn QuestMarker for this Place
            bool        usingMarker = false;
            QuestMarker marker      = new QuestMarker();

            if (targetMarker >= 0 && targetMarker < place.SiteDetails.questSpawnMarkers.Length)
            {
                marker      = place.SiteDetails.questSpawnMarkers[targetMarker];
                usingMarker = true;
            }

            // Attempt to get location data - using GetLocation(regionName, locationName) as it can support all locations
            DFLocation location;

            if (!DaggerfallUnity.Instance.ContentReader.GetLocation(place.SiteDetails.regionName, place.SiteDetails.locationName, out location))
            {
                return;
            }

            // Spawn inside dungeon at this world position
            DFPosition mapPixel = MapsFile.LongitudeLatitudeToMapPixel((int)location.MapTableData.Longitude, location.MapTableData.Latitude);
            DFPosition worldPos = MapsFile.MapPixelToWorldCoord(mapPixel.X, mapPixel.Y);

            GameManager.Instance.PlayerEnterExit.RespawnPlayer(
                worldPos.X,
                worldPos.Y,
                true,
                true);

            // Determine start position
            if (usingMarker)
            {
                // Use specified quest marker
                Vector3 dungeonBlockPosition = new Vector3(marker.dungeonX * RDBLayout.RDBSide, 0, marker.dungeonZ * RDBLayout.RDBSide);
                resumePosition = dungeonBlockPosition + marker.flatPosition;
            }
            else
            {
                // Use first quest marker
                marker = place.SiteDetails.questSpawnMarkers[0];
                Vector3 dungeonBlockPosition = new Vector3(marker.dungeonX * RDBLayout.RDBSide, 0, marker.dungeonZ * RDBLayout.RDBSide);
                resumePosition = dungeonBlockPosition + marker.flatPosition;
            }

            resumePending = true;
        }
Exemple #4
0
        // Creates a career-based NPC like a Shopkeeper or Banker
        void SetupCareerAllianceNPC(string careerAllianceName)
        {
            // Special handling for Questor class
            // Will revisit this later when guilds are more integrated
            if (careerAllianceName.Equals("Questor", StringComparison.InvariantCultureIgnoreCase))
            {
                if (SetupQuestorNPC())
                {
                    return;
                }
            }

            // Handle Local_3.x group NPCs (limited)
            // These appear to be a special case of assigning a residential person who is automatically instantiated to home Place
            // Creating a full target Place for this person automatically and storing in Quest
            // NOTE: Understanding is still being developed here, likely will need to rework this later
            if (QuestMachine.Instance.FactionsTable.HasValue(careerAllianceName))
            {
                // Get params for this case
                int p1 = Parser.ParseInt(QuestMachine.Instance.FactionsTable.GetValue("p1", careerAllianceName));
                int p2 = Parser.ParseInt(QuestMachine.Instance.FactionsTable.GetValue("p2", careerAllianceName));
                //int p3 = Parser.ParseInt(QuestMachine.Instance.FactionsTable.GetValue("p3", careerAllianceName));

                // Only supporting specific cases for now - can expand later based on testing and iteration of support
                // This will support Local_3.0 - Local_3.3
                // Referencing quest Sx009 here where player must locate and click an NPC with only a home location to go by
                if (p1 == 0 && p2 == -3)
                {
                    // Just using "house2" here as actual meaning of p3 unknown
                    string homeSymbol = string.Format("_{0}_home_", Symbol.Name);
                    string source     = string.Format("Place {0} remote house2", homeSymbol);
                    Place  home       = new Place(ParentQuest, source);
                    homePlaceSymbol = home.Symbol.Clone();
                    ParentQuest.AddResource(home);
                }
                else if (p1 == 0 && p2 >= 0)
                {
                    // Handle standard building types
                    string buildingSymbol = string.Format("_{0}_building_", Symbol.Name);
                    string buildingType   = QuestMachine.Instance.PlacesTable.GetKeyForValue("p2", p2.ToString());
                    string source         = string.Format("Place {0} remote {1}", buildingSymbol, buildingType);
                    Place  building       = new Place(ParentQuest, source);
                    homePlaceSymbol = building.Symbol.Clone();
                    ParentQuest.AddResource(building);
                }
            }

            // Get faction data
            int factionID = GetCareerFactionID(careerAllianceName);

            if (factionID != -1)
            {
                FactionFile.FactionData factionData = GetFactionData(factionID);

                // Setup Person resource
                this.factionData = factionData;
            }
            else
            {
                Debug.LogErrorFormat("SetupCareerAllianceNPC() failed to setup {0}", careerAllianceName);
            }
        }