コード例 #1
0
        /// <summary>
        /// Load an SL_Type object from XML.
        /// </summary>
        public static object LoadFromXml(string path)
        {
            if (!File.Exists(path))
            {
                SL.Log("LoadFromXml :: Trying to load an XML but path doesnt exist: " + path);
                return(null);
            }

            try
            {
                var type = GetBaseTypeOfXmlDocument(path);

                object ret;
                using (var file = File.OpenRead(path))
                {
                    ret = LoadFromXml(file, type);
                }
                return(ret);
            }
            catch (Exception e)
            {
                SL.LogError($"Exception reading the XML file: '{path}'!");
                SL.LogInnerException(e);

                return(null);
            }
        }
コード例 #2
0
        // ================ Main Setup ====================

        internal void Awake()
        {
            Instance = this;
            new SL();

            SL.Log($"Version {SL.VERSION} starting...");

            /* setup Harmony */

            var harmony = new Harmony(SL.GUID);

            harmony.PatchAll();

            /* SceneManager.sceneLoaded event */

            SceneManager.sceneLoaded += SL.Instance.SceneLoaded;

            /* Initialize custom textures callbacks */

            CustomTextures.Init();

            /* Setup keybinding */

            CustomKeybindings.AddAction(UIManager.MENU_TOGGLE_KEY, KeybindingsCategory.CustomKeybindings);
        }
コード例 #3
0
        internal void Internal_Apply()
        {
            // add uid to CustomCharacters callback dictionary
            if (!string.IsNullOrEmpty(this.UID))
            {
                if (CustomCharacters.Templates.ContainsKey(this.UID))
                {
                    SL.LogError("Trying to register an SL_Character Template, but one is already registered with this UID: " + UID);
                    return;
                }

                CustomCharacters.Templates.Add(this.UID, this);
            }

            if (this.LootableOnDeath && this.DropTableUIDs?.Length > 0 && !this.DropPouchContents)
            {
                SL.LogWarning($"SL_Character '{UID}' has LootableOnDeath=true and DropTableUIDs set, but DropPouchContents is false!" +
                              $"You should set DropPouchContents to true in this case or change your template behaviour. Forcing DropPouchContents to true.");
                this.DropPouchContents = true;
            }

            OnPrepare();

            SL.Log("Prepared SL_Character '" + Name + "' (" + UID + ").");
        }
コード例 #4
0
        private static IEnumerator LoadAudioFromFileCoroutine(string filePath, SLPack pack, Action <AudioClip> onClipLoaded)
        {
            var name    = Path.GetFileNameWithoutExtension(filePath);
            var request = UnityWebRequestMultimedia.GetAudioClip($@"file://{Path.GetFullPath(filePath)}", AudioType.WAV);

            yield return(request.SendWebRequest());

            while (!request.isDone)
            {
                yield return(null);
            }

            if (!string.IsNullOrEmpty(request.error))
            {
                SL.LogWarning(request.error);
                yield break;
            }

            SL.Log($"Loaded audio clip: {Path.GetFileName(filePath)}");

            var clip = DownloadHandlerAudioClip.GetContent(request);

            FinalizeAudioClip(clip, name, pack);

            onClipLoaded?.Invoke(clip);
        }
コード例 #5
0
        public override void SerializeStats(ItemStats stats)
        {
            base.SerializeStats(stats);

            try
            {
                var eStats = stats as EquipmentStats;

                Impact_Resistance   = eStats.ImpactResistance;
                Damage_Protection   = eStats.GetDamageProtection(DamageType.Types.Physical);
                Stamina_Use_Penalty = eStats.StaminaUsePenalty;
                Mana_Use_Modifier   = eStats.ManaUseModifier;
                Mana_Regen          = eStats.ManaRegenBonus;
                Movement_Penalty    = eStats.MovementPenalty;
                Pouch_Bonus         = eStats.PouchCapacityBonus;
                Heat_Protection     = eStats.HeatProtection;
                Cold_Protection     = eStats.ColdProtection;

                Corruption_Protection = eStats.CorruptionResistance;
                Health_Regen          = eStats.HealthRegenBonus;
                Cooldown_Reduction    = eStats.CooldownReduction;

                BarrierProtection            = eStats.BarrierProtection;
                GlobalStatusEffectResistance = eStats.GlobalStatusEffectResistance;
                StaminaRegenModifier         = eStats.StaminaRegenModifier;

                Damage_Bonus      = At.GetField(eStats, "m_damageAttack") as float[];
                Damage_Resistance = At.GetField(eStats, "m_damageResistance") as float[];
                Impact_Bonus      = eStats.ImpactModifier;
            }
            catch (Exception e)
            {
                SL.Log("Exception getting EquipmentStats of " + stats.name + "\r\n" + e.Message + "\r\n" + e.StackTrace);
            }
        }
コード例 #6
0
        public static void BuildPrefabDictionary()
        {
            if (m_initDone)
            {
                return;
            }

            var vfxSystems = Resources.FindObjectsOfTypeAll <VFXSystem>();

            foreach (var vfx in vfxSystems)
            {
                var name = GetVFXSystemEnum(vfx);

                if (name == VFXPrefabs.NONE)
                {
                    SL.Log("Couldn't parse vfx prefab to enum: " + vfx.transform.GetGameObjectPath());
                }
                else if (!VfxPrefabCache.ContainsKey(name))
                {
                    bool wasActive = vfx.gameObject.activeSelf;
                    vfx.gameObject.SetActive(false);

                    var copy = GameObject.Instantiate(vfx.gameObject);
                    GameObject.DontDestroyOnLoad(copy);
                    copy.SetActive(false);

                    VfxPrefabCache.Add(name, copy);

                    vfx.gameObject.SetActive(wasActive);
                }
            }

            m_initDone = true;
        }
コード例 #7
0
        public override void ApplyToComponent <T>(T component)
        {
            bool anyValid = false;
            var  list     = new List <ImbueEffectPreset>();

            foreach (var id in this.ImbuePresetIDs)
            {
                var preset = ResourcesPrefabManager.Instance.GetEffectPreset(id) as ImbueEffectPreset;

                if (preset)
                {
                    anyValid = true;
                    list.Add(preset);
                }
            }

            if (!anyValid && !AnyImbue)
            {
                SL.Log("SL_ImbueEffectORCondition : Could not find any valid Imbue Preset ID!");
                return;
            }

            var comp = component as ImbueEffectORCondition;

            comp.ImbueEffectPresets = list.ToArray();
            comp.AnyImbue           = this.AnyImbue;
            comp.WeaponToCheck      = this.WeaponToCheck;
        }
コード例 #8
0
        public void ApplyRows(int treeID)
        {
            if (!this.m_object)
            {
                SL.Log("Trying to apply SL_SkillSchool but it is not created yet! Call CreateBaseSchool first!");
                return;
            }

            var school = m_object.GetComponent <SkillSchool>();

            At.SetField(school, "m_branches", new List <SkillBranch>());
            At.SetField(school, "m_skillSlots", new List <BaseSkillSlot>());

            for (int i = 0; i < 6; i++)
            {
                if (m_object.transform.Find("Row" + i) is Transform row)
                {
                    UnityEngine.Object.DestroyImmediate(row.gameObject);
                }
            }

            foreach (var row in this.SkillRows)
            {
                row.ApplyToSchoolTransform(m_object.transform, treeID);
            }

            m_object.transform.parent = SkillTreeHolder.Instance.transform;
            m_object.SetActive(true);
        }
コード例 #9
0
        internal static void CheckPrefabDictionaries()
        {
            //// This debug is for when we need to dump prefab names for enums.
            //// Only needs to be run on updates.

            //SL_ShootBlast.DebugBlastNames();
            //SL_ShootProjectile.DebugProjectileNames();
            //SL_PlayVFX.DebugVfxNames();

            // Once names have been dumped after an update and enums built, we only need this.

            SL_ShootBlast.BuildBlastsDictionary();
            SL_ShootProjectile.BuildProjectileDictionary();
            SL_PlayVFX.BuildPrefabDictionary();

            foreach (var vfx in SL_ShootProjectile.ProjectilePrefabCache.Values)
            {
                vfx.transform.parent = SL.CloneHolder;
            }

            foreach (var vfx in SL_PlayVFX.VfxPrefabCache.Values)
            {
                vfx.transform.parent = SL.CloneHolder;
            }

            foreach (var vfx in SL_ShootBlast.BlastPrefabCache.Values)
            {
                vfx.transform.parent = SL.CloneHolder;
            }

            SL.Log("Built FX prefab dictionaries");
        }
コード例 #10
0
        public static Texture2D ForceReadTexture(Texture2D tex)
        {
            try
            {
                FilterMode origFilter = tex.filterMode;
                tex.filterMode = FilterMode.Point;

                var rt = RenderTexture.GetTemporary(tex.width, tex.height, 0, RenderTextureFormat.ARGB32);
                rt.filterMode        = FilterMode.Point;
                RenderTexture.active = rt;

                Graphics.Blit(tex, rt);

                var _newTex = new Texture2D(tex.width, tex.height, TextureFormat.ARGB32, false);

                _newTex.ReadPixels(new Rect(0, 0, tex.width, tex.height), 0, 0);
                _newTex.Apply(false, false);

                RenderTexture.active = null;
                tex.filterMode       = origFilter;

                return(_newTex);
            }
            catch (Exception e)
            {
                SL.Log("Exception on ForceReadTexture: " + e.ToString());
                return(default);
コード例 #11
0
        public static void BuildProjectileDictionary()
        {
            if (m_initDone)
            {
                return;
            }

            foreach (var projectile in Resources.FindObjectsOfTypeAll <Projectile>())
            {
                var name = GetProjectilePrefabEnum(projectile);

                if (name == ProjectilePrefabs.NONE)
                {
                    SL.Log("Couldn't parse projectile prefab: " + projectile.name);
                }
                else if (!ProjectilePrefabCache.ContainsKey(name))
                {
                    bool wasActive = projectile.gameObject.activeSelf;
                    projectile.gameObject.SetActive(false);

                    var copy = GameObject.Instantiate(projectile.gameObject);
                    GameObject.DontDestroyOnLoad(copy);
                    copy.SetActive(false);

                    ProjectilePrefabCache.Add(name, copy);

                    projectile.gameObject.SetActive(wasActive);
                }
            }

            m_initDone = true;
        }
コード例 #12
0
        public override void ApplyToComponent <T>(T component)
        {
            var comp = component as ProximityCondition;

            comp.ProximityDist  = this.MaxDistance;
            comp.Offset         = this.Offset;
            comp.OrMode         = this.OrMode;
            comp.ProximityAngle = this.ProximityAngle;

            var list = new List <Skill.ItemRequired>();

            foreach (var req in this.RequiredItems)
            {
                Item item = ResourcesPrefabManager.Instance.GetItemPrefab(req.ItemID);
                if (!item)
                {
                    SL.Log("SkillItemReq: Couldn't find an item with the ID " + req.ItemID);
                    continue;
                }

                list.Add(new Skill.ItemRequired()
                {
                    Item     = item,
                    Quantity = req.Quantity,
                    Consume  = req.Consume
                });
            }

            comp.ProximityItemReq = list.ToArray();
        }
コード例 #13
0
        /// <summary>
        /// Helper to take a VFXSystem and get the VFXSystemPrefabs enum value for it (if valid).
        /// </summary>
        /// <param name="vfx">The vfx system</param>
        public static VFXPrefabs GetVFXSystemEnum(VFXSystem vfx)
        {
            if (Enum.TryParse(GetSafeVFXName(vfx), out VFXPrefabs name))
            {
                return(name);
            }

            SL.Log("PlayVFX: could not get name for " + vfx.name);

            return(VFXPrefabs.NONE);
        }
コード例 #14
0
        // ======== SL Setup ========

        internal static void Setup(bool isFirstSetup = true)
        {
            var start = Time.realtimeSinceStartup;

            if (isFirstSetup)
            {
                CloneHolder = new GameObject("SL_CloneHolder").transform;
                GameObject.DontDestroyOnLoad(CloneHolder.gameObject);
                CloneHolder.hideFlags |= HideFlags.HideAndDontSave;
                CloneHolder.gameObject.SetActive(false);

                SLRPCManager.Setup();

                PlayerSaveExtension.LoadExtensionTypes();

                CheckPrefabDictionaries();

                TryInvoke(BeforePacksLoaded);
            }
            else
            {
                ResetForHotReload();
            }

            // Load SL Packs
            SLPackManager.LoadAllPacks(isFirstSetup);

            if (isFirstSetup)
            {
                foreach (var pack in SL.s_packs)
                {
                    pack.Value.TryApplyItemTextureBundles();
                }
            }

            // Invoke OnPacksLoaded and cleanup
            PacksLoaded = true;
            Log("SideLoader Setup Finished");
            Log("-------------------------");

            SL.Log("SL Setup took " + (Time.realtimeSinceStartup - start) + " seconds");

            if (isFirstSetup)
            {
                if (OnPacksLoaded != null)
                {
                    TryInvoke(OnPacksLoaded);
                    Log("Finished invoking OnPacksLoaded.");
                }

                /* Setup UI */
                UIManager.Init();
            }
        }
コード例 #15
0
        // main actual spawn method
        internal Character InternalSpawn(Vector3 position, Vector3 rotation, string characterUID, string extraRpcData, bool loadingFromSave)
        {
            characterUID = characterUID ?? this.UID;

            if (CharacterManager.Instance.GetCharacter(characterUID) is Character existing)
            {
                SL.Log("Trying to spawn a character UID " + characterUID + " but one already exists with that UID!");
                return(existing);
            }

            return(CustomCharacters.SpawnCharacter(this, position, rotation, characterUID, extraRpcData, loadingFromSave).GetComponent <Character>());
        }
コード例 #16
0
            public static void InitializePatch(InputManager_Base __instance)
            {
                //s_userData = __instance.userData;

                foreach (var keybindInfo in s_customKeyDict.Values)
                {
                    // This actually creates the new actions:
                    AddRewiredAction(__instance.userData, keybindInfo.name, keybindInfo.category, keybindInfo.type, out int actionID);
                    keybindInfo.actionID = actionID;

                    SL.Log($"Set up custom keybinding '{keybindInfo.name}', actionID: " + keybindInfo.actionID);
                }
            }
コード例 #17
0
        /// <summary> Clone's an items current visual prefab (and materials), then sets this item's visuals to the new cloned prefab. </summary>
        public static GameObject CloneVisualPrefab(Item item, VisualPrefabType type, bool logging = false)
        {
            var prefab = GetOrigItemVisuals(item, type);

            if (!prefab)
            {
                if (logging)
                {
                    SL.Log("Error, no VisualPrefabType defined or could not find visual prefab of that type!");
                }
                return(null);
            }

            return(CloneAndSetVisuals(item, prefab.gameObject, type));
        }
コード例 #18
0
        public static void DebugVfxNames()
        {
            SL.Log("----------- VFXSystems ------------ ");
            var vfxsystems = Resources.FindObjectsOfTypeAll <VFXSystem>();
            var names      = new List <string>();

            foreach (var vfx in vfxsystems)
            {
                var safename = GetSafeVFXName(vfx);
                if (!names.Contains(safename))
                {
                    names.Add(safename);
                }
            }
            File.WriteAllLines("vfxsystems.txt", names.ToArray());
        }
コード例 #19
0
        internal void Internal_ApplyTemplate()
        {
            if (string.IsNullOrEmpty(this.UID))
            {
                SL.LogWarning("Cannot prepare an SL_DropTable with a null or empty UID!");
                return;
            }

            if (s_registeredTables.ContainsKey(this.UID))
            {
                SL.LogWarning("Trying to register an SL_DropTable but one already exists with this UID: " + this.UID);
                return;
            }

            s_registeredTables.Add(this.UID, this);
            SL.Log("Registered SL_DropTable '" + this.UID + "'");
        }
コード例 #20
0
        public static Texture2D LoadTexture(byte[] data, bool mipmap, bool linear)
        {
            Texture2D tex = new Texture2D(4, 4, TextureFormat.DXT5, mipmap, linear);

            try
            {
                tex.LoadImage(data);
            }
            catch (Exception e)
            {
                SL.Log("Error loading texture! Message: " + e.Message + "\r\nStack: " + e.StackTrace);
            }

            tex.filterMode = FilterMode.Bilinear;

            return(tex);
        }
コード例 #21
0
        public static SL_EffectCondition ParseCondition(EffectCondition component)
        {
            Type slType = Serializer.GetBestSLType(component.GetType());

            if (slType != null && !slType.IsAbstract)
            {
                var holder = Activator.CreateInstance(slType) as SL_EffectCondition;

                holder.Invert = component.Invert;

                holder.SerializeEffect(component);
                return(holder);
            }
            else
            {
                SL.Log(component.ToString() + " is not supported yet, sorry!");
                return(null);
            }
        }
コード例 #22
0
        public EffectCondition ApplyToTransform(Transform transform)
        {
            Type componentType = Serializer.GetGameType(this.GetType());

            if (componentType != null)
            {
                var comp = transform.gameObject.AddComponent(componentType) as EffectCondition;
                comp.Invert = this.Invert;

                ApplyToComponent(comp);

                return(comp);
            }
            else
            {
                SL.Log("Could not get Game type for SL_type: " + this.ToString());
                return(null);
            }
        }
コード例 #23
0
        /// <summary>
        /// Returns the game's actual Tag for the string you provide, if it exists.
        /// </summary>
        /// <param name="TagName">Eg "Food", "Blade", etc...</param>
        /// <param name="logging">Whether to log error messages to debug console or not (if tag doesnt exist)</param>
        /// <returns></returns>
        public static Tag GetTag(string TagName, bool logging = true)
        {
            var tags = (Tag[])At.GetField(TagSourceManager.Instance, "m_tags");

            var tag = tags.FirstOrDefault(x => x.TagName == TagName);

            if (tag.TagName == TagName)
            {
                return(tag);
            }
            else
            {
                if (logging)
                {
                    SL.Log("GetTag :: Could not find a tag by the name: " + TagName);
                }
                return(Tag.None);
            }
        }
コード例 #24
0
        internal static void OnSceneLoaded()
        {
            if (PhotonNetwork.isNonMasterClientInRoom)
            {
                return;
            }

            SL.Log("Checking SL_ItemSpawns...");

            s_activeSavableSpawns.Clear();

            Dictionary <string, ItemSpawnInfo> savedData = null;

            if (!SL.WasLastSceneReset)
            {
                savedData = LoadItemSpawnData();
            }

            foreach (var spawn in s_registeredSpawnSources.Values)
            {
                // Check if already spawned
                if (savedData != null && savedData.ContainsKey(spawn.IdentifierName))
                {
                    var data = savedData[spawn.IdentifierName];
                    s_activeSavableSpawns.Add(data);

                    var item = ItemManager.Instance.GetItem(data.ItemUID);
                    if (item && string.IsNullOrEmpty(item.MostRecentOwnerUID))
                    {
                        // item hasn't been picked up yet, update it to current template settings.
                        s_registeredSpawnSources[spawn.IdentifierName].ApplyToItem(item);
                    }

                    continue;
                }

                // else, new spawn
                if (spawn.SceneToSpawnIn == SceneManagerHelper.ActiveSceneName)
                {
                    spawn.GenerateItem();
                }
            }
        }
コード例 #25
0
        /// <summary>Serialize an effect and get the equivalent SL_Effect.</summary>
        public static SL_Effect ParseEffect(Effect effect)
        {
            Type slType = Serializer.GetBestSLType(effect.GetType());

            if (slType != null && !slType.IsAbstract)
            {
                var holder = Activator.CreateInstance(slType) as SL_Effect;
                holder.Delay            = effect.Delay;
                holder.OverrideCategory = effect.OverrideEffectCategory;
                holder.SyncType         = effect.SyncType;

                holder.SerializeEffect(effect);
                return(holder);
            }
            else
            {
                SL.Log(effect.ToString() + " is not supported yet, sorry!");
                return(null);
            }
        }
コード例 #26
0
        internal virtual void ApplyItemVisualSettings(ItemVisual itemVisual, Transform visuals)
        {
            SL.Log($"Applying ItemVisuals settings to " + visuals.name);

            if (Position != null)
            {
                visuals.localPosition = (Vector3)Position;
            }
            if (Rotation != null)
            {
                visuals.eulerAngles = (Vector3)Rotation;
            }
            if (PositionOffset != null)
            {
                visuals.localPosition += (Vector3)PositionOffset;
            }
            if (RotationOffset != null)
            {
                visuals.eulerAngles += (Vector3)RotationOffset;
            }
        }
コード例 #27
0
        /// <summary>
        /// Internal use for setting a required slot.
        /// </summary>
        /// <param name="comp">The component that this SkillSlot is setting. Not the required slot.</param>
        public void SetRequiredSlot(BaseSkillSlot comp)
        {
            bool success = false;
            var  reqrow  = RequiredSkillSlot.x;
            var  reqcol  = RequiredSkillSlot.y;

            if (comp.transform.root.Find("Row" + reqrow) is Transform reqrowTrans &&
                reqrowTrans.Find("Col" + reqcol) is Transform reqcolTrans)
            {
                var reqslot = reqcolTrans.GetComponent <BaseSkillSlot>();
                if (reqslot)
                {
                    At.SetField(comp, "m_requiredSkillSlot", reqslot);
                    success = true;
                }
            }

            if (!success)
            {
                SL.Log("Could not set required slot. Maybe it's not set yet?");
            }
        }
コード例 #28
0
        public override void ApplyToComponent <T>(T component)
        {
            var comp = component as Summon;

            if (this.SummonPrefabType == PrefabTypes.Resource)
            {
                if (Resources.Load <GameObject>(Prefab) is GameObject prefab)
                {
                    comp.SummonedPrefab = prefab.transform;
                }
                else
                {
                    SL.Log("Could not find Resources asset: " + this.Prefab + "!");
                    return;
                }
            }
            else
            {
                if (int.TryParse(this.Prefab, out int id) && ResourcesPrefabManager.Instance.GetItemPrefab(id) is Item item)
                {
                    comp.SummonedPrefab = item.transform;
                }
                else
                {
                    SL.Log("Could not find an Item with the ID " + this.Prefab + ", or that is not a valid ID!");
                    return;
                }
            }

            comp.BufferSize         = this.BufferSize;
            comp.LimitOfOne         = this.LimitOfOne;
            comp.InstantiationMode  = this.SummonMode;
            comp.PositionType       = this.PositionType;
            comp.MinDistance        = this.MinDistance;
            comp.MaxDistance        = this.MaxDistance;
            comp.SameDirAsSummoner  = this.SameDirectionAsSummoner;
            comp.SummonLocalForward = this.SummonLocalForward;
            comp.IgnoreOnDestroy    = this.IgnoreOnDestroy;
        }
コード例 #29
0
        /// <summary>Replace a global sound with the provided AudioClip.</summary>
        public static void ReplaceAudio(GlobalAudioManager.Sounds sound, AudioClip clip)
        {
            if (!GAMInstance)
            {
                SL.LogWarning("Cannot find GlobalAudioManager Instance!");
                return;
            }

            if (ReplacedClips.Contains(sound))
            {
                SL.Log($"The Sound clip '{sound}' has already been replaced, replacing again...");
            }

            try
            {
                DoReplaceClip(sound, clip);
            }
            catch (Exception e)
            {
                SL.LogError($"Exception replacing clip '{sound}'.\r\nMessage: {e.Message}\r\nStack: {e.StackTrace}");
            }
        }
コード例 #30
0
        public SL_ItemDropChance GetDropForDiceRoll(int diceRoll)
        {
            if (diceRoll < 0 || diceRoll > MaxDiceValue)
            {
                SL.Log("ERROR: Roll " + diceRoll + " is <0 or >" + MaxDiceValue);
                return(null);
            }

            if (m_dropRanges == null)
            {
                GetDropRanges();
            }

            for (int i = 0; i < m_dropRanges.Count; i++)
            {
                var entry = m_dropRanges.ElementAt(i);

                // if dice roll was within range
                if (entry.Key <= diceRoll && entry.Value >= diceRoll)
                {
                    // if there is a NoDrop chance
                    if (NoDrop_DiceValue > 0)
                    {
                        if (i == 0)
                        {
                            return(null); // Index was 0 so it was a no-drop.
                        }
                        else
                        {
                            i--;         // NoDrop was set, so remove 1 from index to get the real drop index.
                        }
                    }

                    return(Drops[i]);
                }
            }

            return(null);
        }