Example #1
0
        protected void ChangeLocationType(LocationTypeChange change)
        {
            if (change == null)
            {
                throw new ArgumentException();
            }
            if (GameMain.GameSession.GameMode is CampaignMode && !IsClient)
            {
                int srcIndex = -1;
                for (int i = 0; i < Locations.Length; i++)
                {
                    if (Locations[i].Type.Identifier.Equals(change.CurrentType, StringComparison.OrdinalIgnoreCase))
                    {
                        srcIndex = i;
                        break;
                    }
                }
                if (srcIndex == -1)
                {
                    return;
                }
                var location = Locations[srcIndex];

                if (change.RequiredDurationRange.X > 0)
                {
                    location.PendingLocationTypeChange = (change, Rand.Range(change.RequiredDurationRange.X, change.RequiredDurationRange.Y), Prefab);
                }
                else
                {
                    location.ChangeType(LocationType.List.Find(lt => lt.Identifier.Equals(change.ChangeToType, StringComparison.OrdinalIgnoreCase)));
                    location.LocationTypeChangeCooldown = change.CooldownAfterChange;
                }
            }
        }
Example #2
0
        partial void ChangeLocationType(Location location, string prevName, LocationTypeChange change)
        {
            //focus on the location
            var mapAnim = new MapAnim()
            {
                EndZoom     = zoom * 1.5f,
                EndLocation = location,
                Duration    = CurrentLocation == location ? 1.0f : 2.0f,
                StartDelay  = 1.0f
            };

            if (change.Messages != null && change.Messages.Count > 0)
            {
                mapAnim.EndMessage = change.Messages[Rand.Range(0, change.Messages.Count)]
                                     .Replace("[previousname]", prevName)
                                     .Replace("[name]", location.Name);
            }
            mapAnimQueue.Enqueue(mapAnim);

            mapAnimQueue.Enqueue(new MapAnim()
            {
                EndZoom       = zoom,
                StartLocation = location,
                EndLocation   = CurrentLocation,
                Duration      = 1.0f,
                StartDelay    = 0.5f
            });
        }
Example #3
0
        private void ChangeLocationType(Location location, LocationTypeChange change)
        {
            string prevName = location.Name;

            location.ChangeType(LocationType.List.Find(lt => lt.Identifier.Equals(change.ChangeToType, StringComparison.OrdinalIgnoreCase)));
            ChangeLocationTypeProjSpecific(location, prevName, change);
            location.ProximityTimer.Remove(change);
            location.TimeSinceLastTypeChange   = 0;
            location.PendingLocationTypeChange = null;
        }
Example #4
0
 partial void ChangeLocationType(Location location, string prevName, LocationTypeChange change)
 {
     if (change.Messages.Any())
     {
         string msg = change.Messages[Rand.Range(0, change.Messages.Count)]
                      .Replace("[previousname]", prevName)
                      .Replace("[name]", location.Name);
         location.LastTypeChangeMessage = msg;
         if (GameMain.Client != null)
         {
             GameMain.Client.AddChatMessage(msg, Networking.ChatMessageType.Default, TextManager.Get("RadioAnnouncerName"));
         }
         else
         {
             GameMain.GameSession?.GameMode.CrewManager.AddSinglePlayerChatMessage(
                 TextManager.Get("RadioAnnouncerName"),
                 msg,
                 Networking.ChatMessageType.Default,
                 sender: null);
         }
     }
 }
Example #5
0
            public Requirement(XElement element, LocationTypeChange change)
            {
                RequiredLocations                       = element.GetAttributeStringArray("requiredlocations", element.GetAttributeStringArray("requiredadjacentlocations", new string[0])).ToList();
                RequiredProximity                       = Math.Max(element.GetAttributeInt("requiredproximity", 1), 1);
                ProximityProbabilityIncrease            = element.GetAttributeFloat("proximityprobabilityincrease", 0.0f);
                RequiredProximityForProbabilityIncrease = element.GetAttributeInt("requiredproximityforprobabilityincrease", -1);
                RequireBeaconStation                    = element.GetAttributeBool("requirebeaconstation", false);
                RequireHuntingGrounds                   = element.GetAttributeBool("requirehuntinggrounds", false);

                string functionStr = element.GetAttributeString("function", "Add");

                if (!Enum.TryParse(functionStr, ignoreCase: true, out Function))
                {
                    DebugConsole.ThrowError(
                        $"Invalid location type change in location type \"{change.CurrentType}\". " +
                        $"\"{functionStr}\" is not a valid function.");
                }

                Probability = element.GetAttributeFloat("probability", 1.0f);

                if (RequiredProximityForProbabilityIncrease > 0 || ProximityProbabilityIncrease > 0.0f)
                {
                    if (!RequiredLocations.Any() && !RequireBeaconStation && !RequireHuntingGrounds)
                    {
                        DebugConsole.AddWarning(
                            $"Invalid location type change in location type \"{change.CurrentType}\". " +
                            "Probability is configured to increase when near some other type of location, but the RequiredLocations attribute is not set.");
                    }
                    if (Probability >= 1.0f)
                    {
                        DebugConsole.AddWarning(
                            $"Invalid location type change in location type \"{change.CurrentType}\". " +
                            "Probability is configured to increase when near some other type of location, but the base probability is already 100%");
                    }
                }
            }
Example #6
0
 partial void ChangeLocationType(Location location, string prevName, LocationTypeChange change);
Example #7
0
 partial void ChangeLocationTypeProjSpecific(Location location, string prevName, LocationTypeChange change);
Example #8
0
        public MissionPrefab(XElement element)
        {
            ConfigElement = element;

            Identifier     = element.GetAttributeString("identifier", "");
            TextIdentifier = element.GetAttributeString("textidentifier", null) ?? Identifier;

            tags = element.GetAttributeStringArray("tags", new string[0], convertToLowerInvariant: true);

            Name            = TextManager.Get("MissionName." + TextIdentifier, true) ?? element.GetAttributeString("name", "");
            Description     = TextManager.Get("MissionDescription." + TextIdentifier, true) ?? element.GetAttributeString("description", "");
            Reward          = element.GetAttributeInt("reward", 1);
            AllowRetry      = element.GetAttributeBool("allowretry", false);
            IsSideObjective = element.GetAttributeBool("sideobjective", false);
            Commonness      = element.GetAttributeInt("commonness", 1);
            if (element.GetAttribute("difficulty") != null)
            {
                int difficulty = element.GetAttributeInt("difficulty", MinDifficulty);
                Difficulty = Math.Clamp(difficulty, MinDifficulty, MaxDifficulty);
            }

            SuccessMessage = TextManager.Get("MissionSuccess." + TextIdentifier, true) ?? element.GetAttributeString("successmessage", "Mission completed successfully");
            FailureMessage = TextManager.Get("MissionFailure." + TextIdentifier, true) ?? "";
            if (string.IsNullOrEmpty(FailureMessage) && TextManager.ContainsTag("missionfailed"))
            {
                FailureMessage = TextManager.Get("missionfailed", returnNull: true) ?? "";
            }
            if (string.IsNullOrEmpty(FailureMessage) && GameMain.Config.Language == "English")
            {
                FailureMessage = element.GetAttributeString("failuremessage", "");
            }

            SonarLabel =
                TextManager.Get("MissionSonarLabel." + TextIdentifier, true) ??
                TextManager.Get("MissionSonarLabel." + element.GetAttributeString("sonarlabel", ""), true) ??
                element.GetAttributeString("sonarlabel", "");
            SonarIconIdentifier = element.GetAttributeString("sonaricon", "");

            MultiplayerOnly  = element.GetAttributeBool("multiplayeronly", false);
            SingleplayerOnly = element.GetAttributeBool("singleplayeronly", false);

            AchievementIdentifier = element.GetAttributeString("achievementidentifier", "");

            UnhideEntitySubCategories = element.GetAttributeStringArray("unhideentitysubcategories", new string[0]).ToList();

            Headers  = new List <string>();
            Messages = new List <string>();
            AllowedConnectionTypes = new List <Pair <string, string> >();

            for (int i = 0; i < 100; i++)
            {
                string header  = TextManager.Get("MissionHeader" + i + "." + TextIdentifier, true);
                string message = TextManager.Get("MissionMessage" + i + "." + TextIdentifier, true);
                if (!string.IsNullOrEmpty(message))
                {
                    Headers.Add(header);
                    Messages.Add(message);
                }
            }

            int messageIndex = 0;

            foreach (XElement subElement in element.Elements())
            {
                switch (subElement.Name.ToString().ToLowerInvariant())
                {
                case "message":
                    if (messageIndex > Headers.Count - 1)
                    {
                        Headers.Add(string.Empty);
                        Messages.Add(string.Empty);
                    }
                    Headers[messageIndex]  = TextManager.Get("MissionHeader" + messageIndex + "." + TextIdentifier, true) ?? subElement.GetAttributeString("header", "");
                    Messages[messageIndex] = TextManager.Get("MissionMessage" + messageIndex + "." + TextIdentifier, true) ?? subElement.GetAttributeString("text", "");
                    messageIndex++;
                    break;

                case "locationtype":
                case "connectiontype":
                    if (subElement.Attribute("identifier") != null)
                    {
                        AllowedLocationTypes.Add(subElement.GetAttributeString("identifier", ""));
                    }
                    else
                    {
                        AllowedConnectionTypes.Add(new Pair <string, string>(
                                                       subElement.GetAttributeString("from", ""),
                                                       subElement.GetAttributeString("to", "")));
                    }
                    break;

                case "locationtypechange":
                    LocationTypeChangeOnCompleted = new LocationTypeChange(subElement.GetAttributeString("from", ""), subElement, requireChangeMessages: false, defaultProbability: 1.0f);
                    break;

                case "reputation":
                case "reputationreward":
                    string factionIdentifier = subElement.GetAttributeString("identifier", "");
                    float  amount            = subElement.GetAttributeFloat("amount", 0.0f);
                    if (ReputationRewards.ContainsKey(factionIdentifier))
                    {
                        DebugConsole.ThrowError($"Error in mission prefab \"{Identifier}\". Multiple reputation changes defined for the identifier \"{factionIdentifier}\".");
                        continue;
                    }
                    ReputationRewards.Add(factionIdentifier, amount);
                    if (!factionIdentifier.Equals("location", StringComparison.OrdinalIgnoreCase))
                    {
                        if (FactionPrefab.Prefabs != null && !FactionPrefab.Prefabs.Any(p => p.Identifier.Equals(factionIdentifier, StringComparison.OrdinalIgnoreCase)))
                        {
                            DebugConsole.ThrowError($"Error in mission prefab \"{Identifier}\". Could not find a faction with the identifier \"{factionIdentifier}\".");
                        }
                    }
                    break;

                case "metadata":
                    string identifier  = subElement.GetAttributeString("identifier", string.Empty);
                    string stringValue = subElement.GetAttributeString("value", string.Empty);
                    if (!string.IsNullOrWhiteSpace(stringValue) && !string.IsNullOrWhiteSpace(identifier))
                    {
                        object value = SetDataAction.ConvertXMLValue(stringValue);
                        SetDataAction.OperationType operation = SetDataAction.OperationType.Set;

                        string operatingString = subElement.GetAttributeString("operation", string.Empty);
                        if (!string.IsNullOrWhiteSpace(operatingString))
                        {
                            operation = (SetDataAction.OperationType)Enum.Parse(typeof(SetDataAction.OperationType), operatingString);
                        }

                        DataRewards.Add(Tuple.Create(identifier, value, operation));
                    }
                    break;
                }
            }

            string missionTypeName = element.GetAttributeString("type", "");

            if (!Enum.TryParse(missionTypeName, out Type))
            {
                DebugConsole.ThrowError("Error in mission prefab \"" + Name + "\" - \"" + missionTypeName + "\" is not a valid mission type.");
                return;
            }
            if (Type == MissionType.None)
            {
                DebugConsole.ThrowError("Error in mission prefab \"" + Name + "\" - mission type cannot be none.");
                return;
            }

            if (CoOpMissionClasses.ContainsKey(Type))
            {
                constructor = CoOpMissionClasses[Type].GetConstructor(new[] { typeof(MissionPrefab), typeof(Location[]) });
            }
            else if (PvPMissionClasses.ContainsKey(Type))
            {
                constructor = PvPMissionClasses[Type].GetConstructor(new[] { typeof(MissionPrefab), typeof(Location[]) });
            }
            else
            {
                DebugConsole.ThrowError("Error in mission prefab \"" + Name + "\" - unsupported mission type \"" + Type.ToString() + "\"");
            }

            InitProjSpecific(element);
        }
Example #9
0
        private void ProgressWorld()
        {
            foreach (Location location in Locations)
            {
                if (furthestDiscoveredLocation == null ||
                    location.MapPosition.X > furthestDiscoveredLocation.MapPosition.X)
                {
                    furthestDiscoveredLocation = location;
                }
            }

            foreach (Location location in Locations)
            {
                if (location.MapPosition.X < furthestDiscoveredLocation.MapPosition.X)
                {
                    furthestDiscoveredLocation = location;
                }

                if (location == CurrentLocation || location == SelectedLocation)
                {
                    continue;
                }

                //find which types of locations this one can change to
                var cct = location.Type.CanChangeTo;
                List <LocationTypeChange> allowedTypeChanges = new List <LocationTypeChange>();
                List <int> readyTypeChanges = new List <int>();
                for (int i = 0; i < cct.Count; i++)
                {
                    LocationTypeChange typeChange = cct[i];
                    if (typeChange.RequireDiscovered && !location.Discovered)
                    {
                        continue;
                    }
                    //check if there are any adjacent locations that would prevent the change
                    bool disallowedFound = false;
                    foreach (string disallowedLocationName in typeChange.DisallowedAdjacentLocations)
                    {
                        if (location.Connections.Any(c => c.OtherLocation(location).Type.Identifier.Equals(disallowedLocationName, StringComparison.OrdinalIgnoreCase)))
                        {
                            disallowedFound = true;
                            break;
                        }
                    }
                    if (disallowedFound)
                    {
                        continue;
                    }

                    //check that there's a required adjacent location present
                    bool requiredFound = false;
                    foreach (string requiredLocationName in typeChange.RequiredAdjacentLocations)
                    {
                        if (location.Connections.Any(c => c.OtherLocation(location).Type.Identifier.Equals(requiredLocationName, StringComparison.OrdinalIgnoreCase)))
                        {
                            requiredFound = true;
                            break;
                        }
                    }
                    if (!requiredFound && typeChange.RequiredAdjacentLocations.Count > 0)
                    {
                        continue;
                    }

                    allowedTypeChanges.Add(typeChange);

                    if (location.TypeChangeTimer >= typeChange.RequiredDuration)
                    {
                        readyTypeChanges.Add(i);
                    }
                }

                List <float> readyTypeProbabilities = readyTypeChanges.Select(i => cct[i].DetermineProbability(location)).ToList();
                //select a random type change
                if (Rand.Range(0.0f, 1.0f) < readyTypeChanges.Sum(i => readyTypeProbabilities[i]))
                {
                    var selectedTypeChangeIndex =
                        ToolBox.SelectWeightedRandom(
                            readyTypeChanges,
                            readyTypeChanges.Select(i => readyTypeProbabilities[i]).ToList(),
                            Rand.RandSync.Unsynced);
                    var selectedTypeChange = cct[selectedTypeChangeIndex];
                    if (selectedTypeChange != null)
                    {
                        string prevName = location.Name;
                        location.ChangeType(LocationType.List.Find(lt => lt.Identifier.Equals(selectedTypeChange.ChangeToType, StringComparison.OrdinalIgnoreCase)));
                        ChangeLocationType(location, prevName, selectedTypeChange);
                        location.TypeChangeTimer = -1;
                    }
                }

                if (allowedTypeChanges.Count > 0)
                {
                    location.TypeChangeTimer++;
                }
                else
                {
                    location.TypeChangeTimer = 0;
                }

                location.UpdateStore();
            }
        }