/// <summary>
        /// Performs a delayed init on the sent list of sosigs. If a sosig fails to init, any character using that sosig will be removed
        /// </summary>
        /// <param name="sosigs"></param>
        private static void InitSosigs(List <SosigTemplate> sosigs)
        {
            for (int i = 0; i < sosigs.Count; i++)
            {
                SosigTemplate sosig = sosigs[i];

                try
                {
                    sosig.DelayedInit();
                }
                catch (Exception e)
                {
                    TNHTweakerLogger.LogError("TNHTweaker -- Failed to load sosig: " + sosig.DisplayName + ". Error Output:\n" + e.ToString());

                    //Find any characters that use this sosig, and remove them
                    for (int j = 0; j < LoadedTemplateManager.LoadedCharactersDict.Values.Count; j++)
                    {
                        //This is probably monsterously inefficient, but if you're at this point you're already f****d :)
                        KeyValuePair <TNH_CharacterDef, CustomCharacter> value_pair = LoadedTemplateManager.LoadedCharactersDict.ToList()[j];

                        if (value_pair.Value.CharacterUsesSosig(sosig.SosigEnemyID))
                        {
                            TNHTweakerLogger.LogError("TNHTweaker -- Removing character that used removed sosig: " + value_pair.Value.DisplayName);
                            LoadedTemplateManager.LoadedCharactersDict.Remove(value_pair.Key);
                            j -= 1;
                        }
                    }
                }
            }
        }
Beispiel #2
0
        public SosigEnemyTemplate GetSosigEnemyTemplate()
        {
            if (template == null)
            {
                TNHTweakerLogger.Log("TNHTweaker -- Getting sosig template", TNHTweakerLogger.LogType.Character);

                template = (SosigEnemyTemplate)ScriptableObject.CreateInstance(typeof(SosigEnemyTemplate));

                template.DisplayName        = DisplayName;
                template.SosigEnemyCategory = SosigEnemyCategory;
                template.SecondaryChance    = SecondaryChance;
                template.TertiaryChance     = TertiaryChance;

                TNHTweakerLogger.Log("TNHTweaker -- Getting sosig config", TNHTweakerLogger.LogType.Character);
                template.ConfigTemplates = new List <SosigConfigTemplate>();
                foreach (SosigConfig temp in Configs)
                {
                    if (temp == null)
                    {
                        TNHTweakerLogger.LogError("One of the sosig configs is null!");
                        continue;
                    }

                    template.ConfigTemplates.Add(temp.GetConfigTemplate());
                }

                template.ConfigTemplates_Easy = ConfigsEasy.Select(o => o.GetConfigTemplate()).ToList();
                template.OutfitConfig         = OutfitConfigs.Select(o => o.GetOutfitConfig()).ToList();
            }

            return(template);
        }
        /// <summary>
        /// Takes a custom SosigTemplate object, and adds it to the necessary dictionaries. This method assumes that you are sending a template for a custom sosig, and that it should be given a new the SosigEnemyID
        /// </summary>
        /// <param name="template">A template for a custom sosig (Loaded at runtime)</param>
        public static void AddSosigTemplate(SosigTemplate template)
        {
            SosigEnemyTemplate realTemplate = template.GetSosigEnemyTemplate();

            //Since this template is for a custom sosig, we should give it a brand new SosigEnemyID
            if (!SosigIDDict.ContainsKey(template.SosigEnemyID))
            {
                SosigIDDict.Add(template.SosigEnemyID, NewSosigID);
                NewSosigID += 1;
            }
            else
            {
                TNHTweakerLogger.LogError("TNHTweaker -- Loaded sosig had same SosigEnemyID as another sosig -- SosigEnemyID : " + template.SosigEnemyID);
                return;
            }

            //Now fill out the SosigEnemyIDs values for the real sosig template (These will effectively be ints, but this is ok since enums are just ints in disguise)
            realTemplate.SosigEnemyID = (SosigEnemyID)SosigIDDict[template.SosigEnemyID];

            //Finally add the templates to our global dictionary
            CustomSosigs.Add(template);
            LoadedSosigsDict.Add(realTemplate, template);

            TNHTweakerLogger.Log("TNHTweaker -- Sosig added successfuly : " + template.DisplayName, TNHTweakerLogger.LogType.Character);
        }
Beispiel #4
0
        public void Awake()
        {
            original = gameObject.GetComponent <TNH_MagDuplicator>();
            if (original == null)
            {
                TNHTweakerLogger.LogError("Fire Rate Modifier failed, original Mag Duplicator was null!");
            }
            original.enabled = false;

            InitPanel();
            UpdateIcons();
        }
Beispiel #5
0
        public void Awake()
        {
            original = gameObject.GetComponent <TNH_MagDuplicator>();
            if (original == null)
            {
                TNHTweakerLogger.LogError("Mag Upgrader failed, original Mag Duplicator was null!");
            }
            original.enabled = false;

            blacklist = LoadedTemplateManager.LoadedCharactersDict[original.M.C].GetMagazineBlacklist();

            InitPanel();
            UpdateIcons();
        }
        /// <summary>
        /// Performs a delayed init on the sent list of custom characters, and removes any characters that failed to init
        /// </summary>
        /// <param name="characters"></param>
        /// <param name="isCustom"></param>
        private static void InitCharacters(List <CustomCharacter> characters, bool isCustom)
        {
            for (int i = 0; i < characters.Count; i++)
            {
                CustomCharacter character = characters[i];

                try
                {
                    character.DelayedInit(isCustom);
                }
                catch (Exception e)
                {
                    TNHTweakerLogger.LogError("TNHTweaker -- Failed to load character: " + character.DisplayName + ". Error Output:\n" + e.ToString());
                    characters.RemoveAt(i);
                    LoadedTemplateManager.LoadedCharactersDict.Remove(character.GetCharacter());
                    i -= 1;
                }
            }
        }
        public void LoadAsset(SetupStage stage, Mod mod, IHandle handle)
        {
            if (handle is not IFileHandle file)
            {
                throw new ArgumentException("Could not load sosig! Make sure you're pointing to a sosig template json file in the manifest");
            }

            try
            {
                SosigTemplate sosig = stage.ImmediateReaders.Get <JToken>()(file).ToObject <SosigTemplate>();
                TNHTweakerLogger.Log("TNHTweaker -- Sosig loaded successfuly : " + sosig.DisplayName, TNHTweakerLogger.LogType.File);

                LoadedTemplateManager.AddSosigTemplate(sosig);
            }
            catch (Exception e)
            {
                TNHTweakerLogger.LogError("Failed to load setup assets for sosig file! Caused Error: " + e.ToString());
            }
        }
        public void LoadAsset(SetupStage stage, Mod mod, IHandle handle)
        {
            if (handle is not IFileHandle file)
            {
                throw new ArgumentException("Could not load vault file! Make sure you're pointing to a vault json file in the manifest");
            }

            try
            {
                SavedGunSerializable savedGun = stage.ImmediateReaders.Get <JToken>()(file).ToObject <SavedGunSerializable>();

                TNHTweakerLogger.Log("TNHTweaker -- Vault file loaded successfuly : " + savedGun.FileName, TNHTweakerLogger.LogType.File);

                LoadedTemplateManager.AddVaultFile(savedGun);
            }
            catch (Exception e)
            {
                TNHTweakerLogger.LogError("Failed to load setup assets for vault file! Caused Error: " + e.ToString());
            }
        }
        public static void AddSosigTemplate(SosigEnemyTemplate realTemplate)
        {
            SosigTemplate template = new SosigTemplate(realTemplate);

            //This template is from a sogig that already has a valid SosigEnemyID, so we can just add that to the dictionary casted as an int
            if (!SosigIDDict.ContainsKey(template.SosigEnemyID))
            {
                SosigIDDict.Add(template.SosigEnemyID, (int)realTemplate.SosigEnemyID);
            }
            else
            {
                TNHTweakerLogger.LogError("TNHTweaker -- Loaded sosig had same SosigEnemyID as another sosig -- SosigEnemyID : " + template.SosigEnemyID);
                return;
            }

            //Since the real template already had a valid SosigEnemyID, we can skip the part where we reassign them
            DefaultSosigs.Add(realTemplate);
            LoadedSosigsDict.Add(realTemplate, template);

            TNHTweakerLogger.Log("TNHTweaker -- Sosig added successfuly : " + template.DisplayName, TNHTweakerLogger.LogType.Character);
        }
Beispiel #10
0
        public static IEnumerator SendScore(int score)
        {
            TNHTweakerLogger.Log("Sending modded score to the TNH Dashboard", TNHTweakerLogger.LogType.TNH);
            waitForScore = true;

            //First, send the map data for this map
            using (UnityWebRequest wwwSendMap = new UnityWebRequest("https://tnh-dashboard.azure-api.net/v1/api/maps", "Put"))
            {
                wwwSendMap.SetRequestHeader(Globals.Accept, "*/*");
                wwwSendMap.SetRequestHeader(Globals.Content_Type, Globals.ApplicationJson);

                GetHoldList().ForEach(o => TNHTweakerLogger.Log($"Hold: x={o.x}, z={o.z}", TNHTweakerLogger.LogType.TNH));

                MapData mapData = new MapData()
                {
                    MapName              = GM.TNH_Manager.LevelName,
                    HoldPointLocations   = JsonConvert.SerializeObject(GetHoldList()),
                    SupplyPointLocations = JsonConvert.SerializeObject(GetSupplyList())
                };

                string data = JsonConvert.SerializeObject(mapData);
                wwwSendMap.uploadHandler             = new UploadHandlerRaw(Encoding.UTF8.GetBytes(data));
                wwwSendMap.uploadHandler.contentType = "application/json";

                yield return(wwwSendMap.Send());

                if (wwwSendMap.isError)
                {
                    TNHTweakerLogger.LogError("Something bad happened sending map data! \n" + wwwSendMap.error);
                }
                else
                {
                    TNHTweakerLogger.Log("Sent map data", TNHTweakerLogger.LogType.TNH);
                }
            }


            //Now send the score
            using (UnityWebRequest wwwScores = new UnityWebRequest("https://tnh-dashboard.azure-api.net/v1/api/scores", "Put"))
            {
                wwwScores.SetRequestHeader(Globals.Accept, "*/*");
                wwwScores.SetRequestHeader(Globals.Content_Type, Globals.ApplicationJson);

                ScoreEntry entry = GetScoreEntry(GM.TNH_Manager, score);
                string     data  = JsonConvert.SerializeObject(entry);
                wwwScores.uploadHandler             = new UploadHandlerRaw(Encoding.UTF8.GetBytes(data));
                wwwScores.uploadHandler.contentType = "application/json";

                yield return(wwwScores.Send());

                if (wwwScores.isError)
                {
                    TNHTweakerLogger.LogError("Something bad happened sending score! \n" + wwwScores.error);
                }
                else
                {
                    TNHTweakerLogger.Log("Sent score data", TNHTweakerLogger.LogType.TNH);
                }
            }

            waitForScore = false;
        }
Beispiel #11
0
        public static IEnumerator GetPlayerScores(int num_before, int num_after, TNH_ScoreDisplay instance)
        {
            TNHTweakerLogger.Log("Getting player scores from TNH Dashboard", TNHTweakerLogger.LogType.TNH);

            string url = "https://tnh-dashboard.azure-api.net/v1/api/scores/search";
            List <RUST.Steamworks.HighScoreManager.HighScore> combinedScores = new List <RUST.Steamworks.HighScoreManager.HighScore>();

            if (GM.TNH_Manager != null)
            {
                url += "?character=" + GM.TNH_Manager.C.DisplayName;
                url += "&map=" + GM.TNH_Manager.LevelName;
                url += "&health=" + health[(int)GM.TNHOptions.HealthModeSetting];
                url += "&equipment=" + equipment[(int)GM.TNHOptions.EquipmentModeSetting];
                url += "&length=" + length[(int)GM.TNHOptions.ProgressionTypeSetting];
                url += "&name=" + SteamFriends.GetPersonaName();
                url += "&num_before=1";
                url += "&num_after=1";
            }
            else
            {
                TNH_UIManager manager = GameObject.FindObjectOfType <TNH_UIManager>();
                if (manager == null)
                {
                    TNHTweakerLogger.LogError("Neither the TNH Manager or the UI Manager were found! Scores will not display");
                    yield break;
                }

                url += "?character=" + manager.CharDatabase.GetDef((TNH_Char)GM.TNHOptions.LastPlayedChar).DisplayName;
                url += "&map=" + manager.CurLevelID;
                url += "&health=" + health[(int)GM.TNHOptions.HealthModeSetting];
                url += "&equipment=" + equipment[(int)GM.TNHOptions.EquipmentModeSetting];
                url += "&length=" + length[(int)GM.TNHOptions.ProgressionTypeSetting];
                url += "&name=" + SteamFriends.GetPersonaName();
                url += "&num_before=1";
                url += "&num_after=1";
            }

            TNHTweakerLogger.Log("Request URL: " + url, TNHTweakerLogger.LogType.TNH);

            using (UnityWebRequest wwwGetScores = UnityWebRequest.Get(url))
            {
                yield return(wwwGetScores.Send());

                if (wwwGetScores.isError)
                {
                    TNHTweakerLogger.LogError("Something bad happened getting scores \n" + wwwGetScores.error);
                }
                else if (wwwGetScores.responseCode == 404)
                {
                    TNHTweakerLogger.LogWarning("High scores not found for player in table!");

                    combinedScores.AddRange(instance.m_scoresTop.Take(6));
                }
                else
                {
                    TNHTweakerLogger.Log("Got Scores!", TNHTweakerLogger.LogType.TNH);

                    string scores = wwwGetScores.downloadHandler.text;
                    TNHTweakerLogger.Log(scores, TNHTweakerLogger.LogType.TNH);

                    List <ScoreEntry> playerScores = JsonConvert.DeserializeObject <List <ScoreEntry> >(scores);

                    for (int i = 0; i < playerScores.Count; i++)
                    {
                        instance.m_scoresPlayer.Add(new RUST.Steamworks.HighScoreManager.HighScore()
                        {
                            name  = playerScores[i].Name,
                            rank  = playerScores[i].Rank,
                            score = playerScores[i].Score
                        });
                    }

                    if (instance.m_scoresTop != null)
                    {
                        combinedScores.AddRange(instance.m_scoresTop.Take(3));
                    }
                    if (instance.m_scoresPlayer != null)
                    {
                        combinedScores.AddRange(instance.m_scoresPlayer.Take(3));
                    }
                }
            }

            instance.m_hasScoresPlayer = true;
            instance.SetGlobalHighScoreDisplay(combinedScores);
        }
        public static Sosig SpawnEnemy(SosigTemplate template, CustomCharacter character, Vector3 spawnLocation, Quaternion spawnRotation, TNHModifier_AIDifficulty difficulty, int IFF, bool isAssault, Vector3 pointOfInterest, bool allowAllWeapons)
        {
            if (character.ForceAllAgentWeapons)
            {
                allowAllWeapons = true;
            }

            TNHTweakerLogger.Log("TNHTWEAKER -- Spawning sosig: " + template.SosigEnemyID, TNHTweakerLogger.LogType.TNH);

            //Create the sosig object
            GameObject sosigPrefab    = UnityEngine.Object.Instantiate(IM.OD[template.SosigPrefabs.GetRandom <string>()].GetGameObject(), spawnLocation, spawnRotation);
            Sosig      sosigComponent = sosigPrefab.GetComponentInChildren <Sosig>();

            //Fill out the sosigs config based on the difficulty
            SosigConfig config;

            if (difficulty == TNHModifier_AIDifficulty.Arcade && template.ConfigsEasy.Count > 0)
            {
                config = template.ConfigsEasy.GetRandom <SosigConfig>();
            }
            else if (template.Configs.Count > 0)
            {
                config = template.Configs.GetRandom <SosigConfig>();
            }
            else
            {
                TNHTweakerLogger.LogError("TNHTweaker -- Sosig did not have normal difficulty config when playing on normal difficulty! Not spawning this enemy!");
                return(null);
            }

            sosigComponent.Configure(config.GetConfigTemplate());
            sosigComponent.SetIFF(IFF);

            //Setup the sosigs inventory
            sosigComponent.Inventory.Init();
            sosigComponent.Inventory.FillAllAmmo();
            sosigComponent.InitHands();

            //Equip the sosigs weapons
            if (template.WeaponOptions.Count > 0)
            {
                GameObject weaponPrefab = IM.OD[template.WeaponOptions.GetRandom <string>()].GetGameObject();
                EquipSosigWeapon(sosigComponent, weaponPrefab, difficulty);
            }

            if (template.WeaponOptionsSecondary.Count > 0 && allowAllWeapons && template.SecondaryChance >= UnityEngine.Random.value)
            {
                GameObject weaponPrefab = IM.OD[template.WeaponOptionsSecondary.GetRandom <string>()].GetGameObject();
                EquipSosigWeapon(sosigComponent, weaponPrefab, difficulty);
            }

            if (template.WeaponOptionsTertiary.Count > 0 && allowAllWeapons && template.TertiaryChance >= UnityEngine.Random.value)
            {
                GameObject weaponPrefab = IM.OD[template.WeaponOptionsTertiary.GetRandom <string>()].GetGameObject();
                EquipSosigWeapon(sosigComponent, weaponPrefab, difficulty);
            }

            //Equip clothing to the sosig
            OutfitConfig outfitConfig = template.OutfitConfigs.GetRandom <OutfitConfig>();

            if (outfitConfig.Chance_Headwear >= UnityEngine.Random.value)
            {
                EquipSosigClothing(outfitConfig.Headwear, sosigComponent.Links[0], outfitConfig.ForceWearAllHead);
            }

            if (outfitConfig.Chance_Facewear >= UnityEngine.Random.value)
            {
                EquipSosigClothing(outfitConfig.Facewear, sosigComponent.Links[0], outfitConfig.ForceWearAllFace);
            }

            if (outfitConfig.Chance_Eyewear >= UnityEngine.Random.value)
            {
                EquipSosigClothing(outfitConfig.Eyewear, sosigComponent.Links[0], outfitConfig.ForceWearAllEye);
            }

            if (outfitConfig.Chance_Torsowear >= UnityEngine.Random.value)
            {
                EquipSosigClothing(outfitConfig.Torsowear, sosigComponent.Links[1], outfitConfig.ForceWearAllTorso);
            }

            if (outfitConfig.Chance_Pantswear >= UnityEngine.Random.value)
            {
                EquipSosigClothing(outfitConfig.Pantswear, sosigComponent.Links[2], outfitConfig.ForceWearAllPants);
            }

            if (outfitConfig.Chance_Pantswear_Lower >= UnityEngine.Random.value)
            {
                EquipSosigClothing(outfitConfig.Pantswear_Lower, sosigComponent.Links[3], outfitConfig.ForceWearAllPantsLower);
            }

            if (outfitConfig.Chance_Backpacks >= UnityEngine.Random.value)
            {
                EquipSosigClothing(outfitConfig.Backpacks, sosigComponent.Links[1], outfitConfig.ForceWearAllBackpacks);
            }


            //Setup the sosigs orders
            if (isAssault)
            {
                sosigComponent.CurrentOrder  = Sosig.SosigOrder.Assault;
                sosigComponent.FallbackOrder = Sosig.SosigOrder.Assault;
                sosigComponent.CommandAssaultPoint(pointOfInterest);
            }
            else
            {
                sosigComponent.CurrentOrder  = Sosig.SosigOrder.Wander;
                sosigComponent.FallbackOrder = Sosig.SosigOrder.Wander;
                sosigComponent.CommandGuardPoint(pointOfInterest, true);
                sosigComponent.SetDominantGuardDirection(UnityEngine.Random.onUnitSphere);
            }
            sosigComponent.SetGuardInvestigateDistanceThreshold(25f);

            //Handle sosig dropping custom loot
            if (UnityEngine.Random.value < template.DroppedLootChance && template.DroppedObjectPool != null)
            {
                SosigLinkLootWrapper component = sosigComponent.Links[2].gameObject.AddComponent <SosigLinkLootWrapper>();
                component.shouldDropOnCleanup = !character.DisableCleanupSosigDrops;
                component.group = template.DroppedObjectPool;
            }

            return(sosigComponent);
        }
        public void LoadAsset(SetupStage stage, Mod mod, IHandle handle)
        {
            if (handle is not IDirectoryHandle dir)
            {
                throw new ArgumentException("Could not load character! Character should point to a folder holding the character.json and thumb.png");
            }


            try
            {
                CustomCharacter character = null;
                Sprite          thumbnail = null;

                foreach (IFileHandle file in dir.GetFiles())
                {
                    if (file.Path.EndsWith("character.json"))
                    {
                        string charString = stage.ImmediateReaders.Get <string>()(file);
                        JsonSerializerSettings settings = new JsonSerializerSettings
                        {
                            NullValueHandling = NullValueHandling.Ignore
                        };
                        character = JsonConvert.DeserializeObject <CustomCharacter>(charString, settings);
                    }
                    else if (file.Path.EndsWith("thumb.png"))
                    {
                        thumbnail = TNHTweakerUtils.LoadSprite(file);
                    }
                }

                if (character == null)
                {
                    TNHTweakerLogger.LogError("TNHTweaker -- Failed to load custom character! No character.json file found");
                    return;
                }

                else if (thumbnail == null)
                {
                    TNHTweakerLogger.LogError("TNHTweaker -- Failed to load custom character! No thumb.png file found");
                    return;
                }

                //Now we want to load the icons for each pool
                foreach (IFileHandle iconFile in dir.GetFiles())
                {
                    foreach (EquipmentPool pool in character.EquipmentPools)
                    {
                        if (iconFile.Path.EndsWith(pool.IconName))
                        {
                            pool.GetPoolEntry().TableDef.Icon = TNHTweakerUtils.LoadSprite(iconFile);
                        }
                    }
                }


                TNHTweakerLogger.Log("TNHTweaker -- Character loaded successfuly : " + character.DisplayName, TNHTweakerLogger.LogType.File);

                LoadedTemplateManager.AddCharacterTemplate(character, thumbnail);
            }
            catch (Exception e)
            {
                TNHTweakerLogger.LogError("Failed to load setup assets for character! Caused Error: " + e.ToString());
            }
        }