Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
0
        internal ImbueEffectPreset Internal_ApplyTemplate()
        {
            if (this.NewStatusID == -1)
            {
                this.NewStatusID = this.TargetStatusID;
            }

            var preset = CustomStatusEffects.CreateCustomImbue(this);

            SLPackManager.AddLateApplyListener(OnLateApply, preset);

            CustomStatusEffects.SetImbueLocalization(preset, Name, Description);

            // check for custom icon
            if (!string.IsNullOrEmpty(SLPackName) && !string.IsNullOrEmpty(SubfolderName) && SL.GetSLPack(SLPackName) is SLPack pack)
            {
                var dir = $@"{pack.GetPathForCategory<StatusCategory>()}\{SubfolderName}";

                if (pack.FileExists(dir, "icon.png"))
                {
                    var tex    = pack.LoadTexture2D(dir, "icon.png");
                    var sprite = CustomTextures.CreateSprite(tex, CustomTextures.SpriteBorderTypes.NONE);

                    preset.ImbueStatusIcon = sprite;
                }
            }

            return(preset);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Serializes a Material into a SL_Material.
        /// </summary>
        /// <param name="mat">The material to serialize.</param>
        /// <returns>Serialized SL_Material.</returns>
        public static SL_Material ParseMaterial(Material mat)
        {
            var holder = new SL_Material()
            {
                Name       = CustomItemVisuals.GetSafeMaterialName(mat.name),
                ShaderName = mat.shader.name,
                Properties = CustomTextures.GetProperties(mat).ToArray(),
                Keywords   = mat.shaderKeywords,
            };

            var list = new List <TextureConfig>();

            foreach (var texName in mat.GetTexturePropertyNames())
            {
                if (mat.GetTexture(texName) is Texture2D tex)
                {
                    list.Add(new TextureConfig()
                    {
                        TextureName = texName,
                        MipMapBias  = tex.mipMapBias,
                        UseMipMap   = (tex.mipmapCount > 0),
                    });
                }
            }
            holder.TextureConfigs = list.ToArray();

            return(holder);
        }
Ejemplo n.º 4
0
        public override void ExportIcons(Component comp, string folder)
        {
            base.ExportIcons(comp, folder);

            var imbue = comp as ImbueEffectPreset;

            if (imbue.ImbueStatusIcon)
            {
                CustomTextures.SaveIconAsPNG(imbue.ImbueStatusIcon, folder);
            }
        }
Ejemplo n.º 5
0
        protected internal virtual Texture2D LoadTexture2D(string relativeDirectory, string file, bool mipmap = false, bool linear = false)
        {
            var path = Path.Combine(relativeDirectory, file);

            if (!File.Exists(path))
            {
                return(null);
            }

            return(CustomTextures.LoadTexture(path, mipmap, linear));
        }
        public override void ExportIcons(Component comp, string folder)
        {
            base.ExportIcons(comp, folder);

            var status = comp as StatusEffect;

            if (status.StatusIcon)
            {
                CustomTextures.SaveIconAsPNG(status.StatusIcon, folder);
            }

            if (comp is LevelStatusEffect levelComp)
            {
                for (int i = 0; i < levelComp.StatusLevelData.Length; i++)
                {
                    var data = levelComp.StatusLevelData[i];
                    if (data != null && data.Icon)
                    {
                        CustomTextures.SaveIconAsPNG(data.Icon, folder, $"icon{i + 2}");
                    }
                }
            }
        }
        /// <summary>
        /// Searches the provided AssetBundle for folders in the expected format, and applies textures to the corresponding Item.
        /// Each item must have its own sub-folder, where the name of this folder starts with the Item's ItemID.
        /// The folder name can have anything else after the ID, but it must start with the ID.
        /// Eg., '2000010_IronSword\' would be valid to set the textures on the Iron Sword.
        /// The textures should be placed inside this folder and should match the Shader Layer names of the texture (the same way you set Item textures from a folder).
        /// </summary>
        /// <param name="bundle">The AssetBundle to apply Textures from.</param>
        public static void ApplyTexturesFromAssetBundle(AssetBundle bundle)
        {
            // Keys: Item IDs
            // Values: List of Textures/Sprites to apply to the item
            // The ItemTextures Value Key is the Material name, and the List<Texture2D> are the actual textures.
            var itemTextures = new Dictionary <int, Dictionary <string, List <Texture2D> > >();
            var icons        = new Dictionary <int, List <Sprite> >();

            string[] names = bundle.GetAllAssetNames();
            foreach (var name in names)
            {
                try
                {
                    SL.Log("Loading texture from AssetBundle, path: " + name);

                    Texture2D tex = bundle.LoadAsset <Texture2D>(name);

                    // cleanup the name (remove ".png")
                    tex.name = tex.name.Replace(".png", "");

                    // Split the assetbundle path by forward slashes
                    string[] splitPath = name.Split('/');

                    // Get the ID from the first 7 characters of the path
                    int id = int.Parse(splitPath[1].Substring(0, 7));

                    // Identify icons by name
                    if (tex.name.Contains("icon"))
                    {
                        if (!icons.ContainsKey(id))
                        {
                            icons.Add(id, new List <Sprite>());
                        }

                        Sprite sprite;
                        if (tex.name.Contains("skill"))
                        {
                            sprite = CustomTextures.CreateSprite(tex, CustomTextures.SpriteBorderTypes.SkillTreeIcon);
                        }
                        else
                        {
                            sprite = CustomTextures.CreateSprite(tex, CustomTextures.SpriteBorderTypes.ItemIcon);
                        }

                        icons[id].Add(sprite);
                    }
                    else // is not an icon
                    {
                        var mat = "";
                        if (splitPath[2] == "textures")
                        {
                            mat = splitPath[3];
                        }
                        else
                        {
                            mat = splitPath[2];
                        }

                        if (!itemTextures.ContainsKey(id))
                        {
                            itemTextures.Add(id, new Dictionary <string, List <Texture2D> >());
                        }

                        if (!itemTextures[id].ContainsKey(mat))
                        {
                            itemTextures[id].Add(mat, new List <Texture2D>());
                        }

                        itemTextures[id][mat].Add(tex);
                    }
                }
                catch (InvalidCastException)
                {
                    // suppress
                }
                catch (Exception ex)
                {
                    SL.Log("Exception loading textures from asset bundle!");
                    SL.Log(ex.Message);
                    SL.Log(ex.StackTrace);
                }
            }

            // Apply material textures
            foreach (var entry in itemTextures)
            {
                if (ResourcesPrefabManager.Instance.GetItemPrefab(entry.Key) is Item item)
                {
                    SL_Item.ApplyTexAndMats(entry.Value, null, item);
                }
            }

            // Apply icons
            foreach (var entry in icons)
            {
                if (ResourcesPrefabManager.Instance.GetItemPrefab(entry.Key) is Item item)
                {
                    ApplyIconsByName(entry.Value.ToArray(), item);
                }
            }
        }
        public override void ApplyToItem(Item item)
        {
            base.ApplyToItem(item);

            var comp = item as LevelAttackSkill;

            if (this.WatchedStatusIdentifier != null)
            {
                var status = ResourcesPrefabManager.Instance.GetStatusEffectPrefab(this.WatchedStatusIdentifier);
                if (status)
                {
                    comp.WatchedStatus = status;
                }
                else
                {
                    SL.LogWarning("SL_LevelAttackSkill: could not find a status by the name of '" + this.WatchedStatusIdentifier + "'");
                }
            }

            var stages = At.GetField(comp, "m_skillStages") as LevelAttackSkill.SkillStage[];

            int newMax = this.Stages?.Length ?? stages.Length;

            if (this.Stages != null)
            {
                if (stages.Length != newMax)
                {
                    Array.Resize(ref stages, newMax);
                }

                for (int i = 0; i < stages.Length; i++)
                {
                    var stage = stages[i];
                    stage.StageDefaultName = Stages[i].Name;
                    stage.StageLocKey      = null;
                    stage.StageAnim        = Stages[i].Animation;
                    if (!stage.StageIcon)
                    {
                        stage.StageIcon = comp.ItemIcon;
                    }
                }
            }

            // check for custom level icons
            if (!string.IsNullOrEmpty(SLPackName) && !string.IsNullOrEmpty(SubfolderName) && SL.GetSLPack(SLPackName) is SLPack pack)
            {
                var dir = $@"{pack.GetPathForCategory<ItemCategory>()}\{SubfolderName}\Textures";

                for (int i = 0; i < newMax; i++)
                {
                    //var path = dir + $@"\icon{i + 2}.png";

                    if (pack.FileExists(dir, $@"icon{i + 2}.png"))
                    {
                        var tex    = pack.LoadTexture2D(dir, $@"icon{i + 2}.png");
                        var sprite = CustomTextures.CreateSprite(tex, CustomTextures.SpriteBorderTypes.NONE);

                        stages[i].StageIcon = sprite;
                    }
                }
            }

            At.SetField(comp, "m_skillStages", stages);
        }
Ejemplo n.º 9
0
        private SkillSchool CreateSchool(bool applyRowsInstantly = false)
        {
            var template = (Resources.Load("_characters/CharacterProgression") as GameObject).transform.Find("Test");

            // instantiate a copy of the dev template
            m_object = UnityEngine.Object.Instantiate(template).gameObject;

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

            // set the name to the gameobject and the skill tree name/uid
            m_object.name = this.Name;
            At.SetField(school, "m_defaultName", this.Name);
            At.SetField(school, "m_nameLocKey", "");

            if (string.IsNullOrEmpty(this.UID))
            {
                this.UID = this.Name;
            }
            At.SetField(school, "m_uid", new UID(this.UID));

            // TODO set currency and icon

            // fix the breakthrough int
            At.SetField(school, "m_breakthroughSkillIndex", -1);

            // set the sprite
            if (this.Sigil)
            {
                school.SchoolSigil = this.Sigil;
            }
            else if (!string.IsNullOrEmpty(this.SigilIconName) && !string.IsNullOrEmpty(this.SLPackName))
            {
                var pack = SL.GetSLPack(this.SLPackName);
                if (pack != null)
                {
                    if (pack.Texture2D.TryGetValue(this.SigilIconName, out Texture2D sigilTex))
                    {
                        var sprite = CustomTextures.CreateSprite(sigilTex);
                        school.SchoolSigil = sprite;
                    }
                    else
                    {
                        SL.LogWarning("Applying an SL_SkillTree, could not find any loaded Texture by the name of '" + this.SigilIconName + "'");
                    }
                }
                else
                {
                    SL.LogWarning("Applying an SL_SkillSchool, could not find any loaded SLPack with the name '" + this.SLPackName + "'");
                }
            }

            // add it to the game's skill tree holder.
            var list = (At.GetField(SkillTreeHolder.Instance, "m_skillTrees") as SkillSchool[]).ToList();

            list.Add(school);
            At.SetField(SkillTreeHolder.Instance, "m_skillTrees", list.ToArray());

            if (applyRowsInstantly)
            {
                ApplyRows();
            }

            return(school);
        }
Ejemplo n.º 10
0
        internal virtual void Internal_ApplyTemplate(StatusEffect status)
        {
            SL.Log("Applying Status Effect template: " + Name ?? status.name);

            SLPackManager.AddLateApplyListener(OnLateApply, status);

            CustomStatusEffects.SetStatusLocalization(status, Name, Description);

            if (status.StatusData == null)
            {
                status.StatusData = new StatusData();
            }

            if (Lifespan != null)
            {
                status.StatusData.LifeSpan = (float)Lifespan;
            }

            if (RefreshRate != null)
            {
                status.RefreshRate = (float)RefreshRate;
            }

            if (this.Priority != null)
            {
                At.SetField(status, "m_priority", (int)this.Priority);
            }

            if (this.Purgeable != null)
            {
                At.SetField(status, "m_purgeable", (bool)this.Purgeable);
            }

            if (this.DelayedDestroyTime != null)
            {
                status.DelayedDestroyTime = (int)this.DelayedDestroyTime;
            }

            if (BuildupRecoverySpeed != null)
            {
                status.BuildUpRecoverSpeed = (float)BuildupRecoverySpeed;
            }

            if (IgnoreBuildupIfApplied != null)
            {
                status.IgnoreBuildUpIfApplied = (bool)IgnoreBuildupIfApplied;
            }

            if (DisplayedInHUD != null)
            {
                status.DisplayInHud = (bool)DisplayedInHUD;
            }

            if (IsHidden != null)
            {
                status.IsHidden = (bool)IsHidden;
            }

            if (IsMalusEffect != null)
            {
                status.IsMalusEffect = (bool)this.IsMalusEffect;
            }

            if (this.ActionOnHit != null)
            {
                At.SetField(status, "m_actionOnHit", (StatusEffect.ActionsOnHit) this.ActionOnHit);
            }

            if (this.RemoveRequiredStatus != null)
            {
                status.RemoveRequiredStatus = (bool)this.RemoveRequiredStatus;
            }

            if (this.NormalizeDamageDisplay != null)
            {
                status.NormalizeDamageDisplay = (bool)this.NormalizeDamageDisplay;
            }

            if (this.IgnoreBarrier != null)
            {
                status.IgnoreBarrier = (bool)this.IgnoreBarrier;
            }

            if (this.StatusIdentifier != this.TargetStatusIdentifier)
            {
                At.SetField(status, "m_effectType", new TagSourceSelector(Tag.None));
            }

            if (Tags != null)
            {
                var tagSource = CustomTags.SetTagSource(status.gameObject, Tags, true);
                At.SetField(status, "m_tagSource", tagSource);
            }
            else if (!status.GetComponent <TagSource>())
            {
                var tagSource = status.gameObject.AddComponent <TagSource>();
                At.SetField(status, "m_tagSource", tagSource);
            }

            if (this.PlayFXOnActivation != null)
            {
                status.PlayFXOnActivation = (bool)this.PlayFXOnActivation;
            }

            if (this.VFXInstantiationType != null)
            {
                status.FxInstantiation = (StatusEffect.FXInstantiationTypes) this.VFXInstantiationType;
            }

            if (this.VFXPrefab != null)
            {
                if (this.VFXPrefab == SL_PlayVFX.VFXPrefabs.NONE)
                {
                    status.FXPrefab = null;
                }
                else
                {
                    var clone = GameObject.Instantiate(SL_PlayVFX.GetVfxSystem((SL_PlayVFX.VFXPrefabs) this.VFXPrefab));
                    GameObject.DontDestroyOnLoad(clone);
                    status.FXPrefab = clone.transform;
                }
            }

            if (this.FXOffset != null)
            {
                status.FxOffset = (Vector3)this.FXOffset;
            }

            if (this.PlaySpecialFXOnStop != null)
            {
                status.PlaySpecialFXOnStop = (bool)this.PlaySpecialFXOnStop;
            }

            // setup family
            if (this.FamilyMode == null && this.StatusIdentifier != this.TargetStatusIdentifier)
            {
                // Creating a new status, but no unique bind family was declared. Create one.
                var family = new StatusEffectFamily
                {
                    Name          = this.StatusIdentifier + "_FAMILY",
                    LengthType    = StatusEffectFamily.LengthTypes.Short,
                    MaxStackCount = 1,
                    StackBehavior = StatusEffectFamily.StackBehaviors.IndependantUnique
                };

                At.SetField(status, "m_bindFamily", family);
                At.SetField(status, "m_familyMode", StatusEffect.FamilyModes.Bind);
            }

            if (this.FamilyMode == StatusEffect.FamilyModes.Bind)
            {
                At.SetField(status, "m_familyMode", StatusEffect.FamilyModes.Bind);

                if (this.BindFamily != null)
                {
                    At.SetField(status, "m_bindFamily", this.BindFamily.CreateAsBindFamily());
                }
            }
            else if (this.FamilyMode == StatusEffect.FamilyModes.Reference)
            {
                At.SetField(status, "m_familyMode", StatusEffect.FamilyModes.Reference);

                if (this.ReferenceFamilyUID != null)
                {
                    At.SetField(status, "m_stackingFamily", new StatusEffectFamilySelector()
                    {
                        SelectorValue = this.ReferenceFamilyUID
                    });
                }
            }

            // check for custom icon
            if (!string.IsNullOrEmpty(SerializedSLPackName) &&
                !string.IsNullOrEmpty(SerializedSubfolderName) &&
                SL.GetSLPack(SerializedSLPackName) is SLPack pack)
            {
                var dir = $@"{pack.GetPathForCategory<StatusCategory>()}\{SerializedSubfolderName}";

                if (pack.FileExists(dir, "icon.png"))
                {
                    var tex    = pack.LoadTexture2D(dir, "icon.png");
                    var sprite = CustomTextures.CreateSprite(tex, CustomTextures.SpriteBorderTypes.NONE);

                    status.OverrideIcon = sprite;
                    At.SetField(status, "m_defaultStatusIcon", new StatusTypeIcon(Tag.None)
                    {
                        Icon = sprite
                    });
                }
            }
        }
        private void OnLateApply(object[] obj)
        {
            var comp = obj[0] as LevelStatusEffect;

            int origMax = (int)At.GetField(comp, "m_maxLevel");
            int newMax  = MaxLevel ?? origMax;

            At.SetField(comp, "m_maxLevel", newMax);

            Sprite[] origIcons = new Sprite[origMax - 1];

            // prepare the level data array and get current icons
            if (comp.StatusLevelData == null)
            {
                comp.StatusLevelData = new LevelStatusEffect.LevelData[newMax - 1];
            }
            else if (comp.StatusLevelData.Length > 0)
            {
                comp.StatusLevelData = comp.StatusLevelData.OrderBy(it => it.LevelIndex).ToArray();

                for (int i = 0; i < origMax - 1; i++)
                {
                    origIcons[i] = comp.StatusLevelData[i].Icon;
                }
            }

            if (origMax != newMax)
            {
                Array.Resize(ref comp.StatusLevelData, newMax - 1);
            }

            // set the level datas
            for (int i = 0; i < newMax - 1; i++)
            {
                if (comp.StatusLevelData[i] == null)
                {
                    comp.StatusLevelData[i] = new LevelStatusEffect.LevelData();
                }

                var level = comp.StatusLevelData[i];
                level.LevelIndex = i;
                level.StatusData = new StatusData(comp.StatusData)
                {
                    EffectsData = GenerateEffectsData(comp.StatusEffectSignature.Effects, i + 2)
                };
            }

            // check for custom level icons
            if (!string.IsNullOrEmpty(SerializedSLPackName) &&
                !string.IsNullOrEmpty(SerializedSubfolderName) &&
                SL.GetSLPack(SerializedSLPackName) is SLPack pack)
            {
                var dir = $@"{pack.GetPathForCategory<StatusCategory>()}\{SerializedSubfolderName}";
                for (int i = 0; i < newMax - 1; i++)
                {
                    if (pack.FileExists(dir, $@"icon{i + 2}.png"))
                    {
                        var tex    = pack.LoadTexture2D(dir, $@"icon{i + 2}.png");
                        var sprite = CustomTextures.CreateSprite(tex, CustomTextures.SpriteBorderTypes.NONE);

                        //list.Add(sprite);
                        comp.StatusLevelData[i].Icon = sprite;
                    }
                }
            }

            // ensure all levels at least have some icon
            for (int i = 0; i < newMax - 1; i++)
            {
                if (!comp.StatusLevelData[i].Icon)
                {
                    comp.StatusLevelData[i].Icon = comp.StatusIcon;
                }
            }
        }