public override void ApplyToItem(Item item)
        {
            base.ApplyToItem(item);

            var comp = item as PistolSkill;

            if (this.AlternativeActivationRequirement != null)
            {
                comp.AlternateActivationLoadoutReq = (PistolSkill.LoadoutStateCondition) this.AlternativeActivationRequirement;
            }

            if (this.PrimaryActivationRequirement != null)
            {
                comp.PrimaryActivationLoadoutReq = (PistolSkill.LoadoutStateCondition) this.PrimaryActivationRequirement;
            }

            if ((bool)At.GetField(comp, "m_isBaseFireReloadSkill") && comp.transform.Find("NormalReload") is Transform reload)
            {
                At.SetField(comp, "m_alternateAnimConditionsHolder", reload.gameObject);

                foreach (var icon in comp.m_alternateIcons)
                {
                    At.SetField(icon, "m_conditionHolder", reload.gameObject);
                }
            }
        }
        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);
            }
        }
        public void ApplyRows()
        {
            var list   = (At.GetField(SkillTreeHolder.Instance, "m_skillTrees") as SkillSchool[]).ToList();
            var treeID = list.Count;

            ApplyRows(treeID);
        }
Beispiel #4
0
        public override void SerializeItem(Item item)
        {
            base.SerializeItem(item);

            var building = item as Building;

            var list = new List <SL_ConstructionPhase>();

            var constructionPhases = At.GetField(building, "m_constructionPhases") as Building.ConstructionPhase[];

            foreach (var phase in constructionPhases)
            {
                list.Add(SL_ConstructionPhase.SerializePhase(phase));
            }

            ConstructionPhases = list.ToArray();

            list.Clear();
            var upgradePhases = At.GetField(building, "m_upgradePhases") as Building.ConstructionPhase[];

            foreach (var phase in upgradePhases)
            {
                list.Add(SL_ConstructionPhase.SerializePhase(phase));
            }

            UpgradePhases = list.ToArray();
        }
Beispiel #5
0
        // internal death callback

        internal void OnDeath(Character character)
        {
            if (this.DestroyOnDeath)
            {
                SLPlugin.Instance.StartCoroutine(DestroyOnDeathCoroutine(character));
                return;
            }

            if (LootableOnDeath && this.DropTableUIDs != null && DropTableUIDs.Length > 0)
            {
                if (character.GetComponent <LootableOnDeath>() is LootableOnDeath lootable &&
                    (bool)At.GetField(lootable, "m_wasAlive"))
                {
                    foreach (var tableUID in this.DropTableUIDs)
                    {
                        if (SL_DropTable.s_registeredTables.TryGetValue(tableUID, out SL_DropTable table))
                        {
                            table.GenerateDrops(character.Inventory.Pouch.transform);
                        }
                        else
                        {
                            SL.LogWarning($"Trying to generate drops for '{UID}', " +
                                          $"but could not find any registered SL_DropTable with the UID '{tableUID}'");
                        }
                    }

                    character.Inventory.MakeLootable(this.DropWeapons, this.DropPouchContents, true, false);
                }
            }
        }
        public override void ApplyToCharacter(Character trainer, bool loadingFromSave)
        {
            base.ApplyToCharacter(trainer, loadingFromSave);

            var trainertemplate = GameObject.Instantiate(Resources.Load <GameObject>("editor/templates/TrainerTemplate"));

            trainertemplate.transform.parent   = trainer.transform;
            trainertemplate.transform.position = trainer.transform.position;

            // set Dialogue Actor name
            var trainerActor = trainertemplate.GetComponentInChildren <DialogueActor>();

            trainerActor.SetName(this.Name);

            // get "Trainer" component, and set the SkillTreeUID to our custom tree UID
            var trainerComp = trainertemplate.GetComponentInChildren <Trainer>();

            if (this.SkillTree != null)
            {
                At.SetField(trainerComp, "m_skillTreeUID", new UID(SkillTree.UID));
            }
            else
            {
                SL.LogWarning("Setting up an SL_CharacterTrainer (" + this.UID + ") but no SL_SkillTree has been created for it!");
            }

            // setup dialogue tree
            var graphController = trainertemplate.GetComponentInChildren <DialogueTreeController>();
            var graph           = graphController.graph;

            // the template comes with an empty ActorParameter, we can use that for our NPC actor.
            var actors = At.GetField(graph as DialogueTree, "_actorParameters") as List <DialogueTree.ActorParameter>;

            actors[0].actor = trainerActor;
            actors[0].name  = this.Name;

            // setup the actual dialogue now
            var rootStatement = graph.allNodes[0] as StatementNodeExt;

            rootStatement.statement = new Statement(this.InitialDialogue);
            rootStatement.SetActorName(this.Name);

            // the template already has an action node for opening the Train menu.
            // Let's grab that and change the trainer to our custom Trainer component (setup above).
            var openTrainer = graph.allNodes[1] as ActionNode;

            (openTrainer.action as TrainDialogueAction).Trainer = new BBParameter <Trainer>(trainerComp);

            // ===== finalize nodes =====
            graph.allNodes.Clear();
            // add the nodes we want to use
            graph.allNodes.Add(rootStatement);
            graph.allNodes.Add(openTrainer);
            graph.primeNode = rootStatement;
            graph.ConnectNodes(rootStatement, openTrainer);

            // set the trainer active
            trainer.gameObject.SetActive(true);
        }
        private IEnumerator DelayedStopCoroutine()
        {
            yield return(new WaitForSeconds(AutoStopTime));

            if (At.GetField(this as PlayVFX, "m_startVFX") is VFXSystem vfx)
            {
                vfx.Stop();
            }
            else
            {
                SL.LogWarning("SL_PlayTimedVFX.DelayedStopCoroutine - vfx was null after delay");
            }
        }
Beispiel #8
0
        //Set up a control mapping UI section and bind references

        internal static void InitCustomSection(ControlMappingSection mapSection, ControllerMap _controllerMap, IEnumerable <KeybindInfo> keysToAdd)
        {
            if (_controllerMap == null)
            {
                return;
            }

            // Loop through the custom actions we defined
            foreach (var customKey in keysToAdd)
            {
                // add the actual keybind mapping to this controller in Rewired
                _controllerMap.CreateElementMap(customKey.actionID, Pole.Positive, KeyCode.None, ModifierKeyFlags.None);

                var alreadyKnown = At.GetField(mapSection, "m_actionAlreadyKnown") as List <int>;

                // see if the UI has already been set up for this keybind
                if (alreadyKnown.Contains(customKey.actionID))
                {
                    continue;
                }

                // set up the UI for this keybind (same as how game does it)
                alreadyKnown.Add(customKey.actionID);

                var action = ReInput.mapping.GetAction(customKey.actionID);

                var actTemplate = At.GetField(mapSection, "m_actionTemplate") as ControlMappingAction;

                actTemplate.gameObject.SetActive(true);
                if (action.type == InputActionType.Button)
                {
                    At.Invoke(mapSection, "CreateActionRow", CUSTOM_CATEGORY, action, AxisRange.Positive);
                }
                else
                {
                    if (mapSection.ControllerType == ControlMappingPanel.ControlType.Keyboard)
                    {
                        At.Invoke(mapSection, "CreateActionRow", CUSTOM_CATEGORY, action, AxisRange.Positive);
                        At.Invoke(mapSection, "CreateActionRow", CUSTOM_CATEGORY, action, AxisRange.Negative);
                    }
                    else
                    {
                        At.Invoke(mapSection, "CreateActionRow", CUSTOM_CATEGORY, action, AxisRange.Full);
                    }
                }
                actTemplate.gameObject.SetActive(false);

                // Continue the loop of custom keys...
            }
        }
Beispiel #9
0
        public static void ApplyHairVisuals(CharacterVisuals visuals, int _hairStyleIndex, int _hairColorIndex)
        {
            var presets = CharacterManager.CharacterVisualsPresets;
            var key     = $"Hair{_hairStyleIndex}";
            var dict    = At.GetField(visuals, "m_armorVisualPreview") as Dictionary <string, ArmorVisuals>;

            Material     material = presets.HairMaterials[_hairColorIndex];
            ArmorVisuals hairVisuals;

            if (dict.ContainsKey(key))
            {
                if (!dict[key].gameObject.activeSelf)
                {
                    dict[key].gameObject.SetActive(true);
                }

                hairVisuals = dict[key];
            }
            else
            {
                visuals.UseDefaultVisuals = true;

                hairVisuals = visuals.InstantiateVisuals(presets.Hairs[_hairStyleIndex].transform, visuals.transform).GetComponent <ArmorVisuals>();

                At.SetProperty(visuals, "DefaultHairVisuals", hairVisuals);

                if (!hairVisuals.gameObject.activeSelf)
                {
                    hairVisuals.gameObject.SetActive(true);
                }

                // Add to dict
                dict.Add(key, hairVisuals);
            }

            if (_hairStyleIndex != 0)
            {
                if (!hairVisuals.Renderer)
                {
                    var renderer = hairVisuals.GetComponent <SkinnedMeshRenderer>();
                    At.SetField(hairVisuals, "m_skinnedMeshRenderer", renderer);
                }

                hairVisuals.Renderer.material = material;
                At.Invoke(visuals, "FinalizeSkinnedRenderer", hairVisuals.Renderer);
            }

            hairVisuals.ApplyToCharacterVisuals(visuals);
        }
Beispiel #10
0
        public override void SerializeComponent <T>(T extension)
        {
            base.SerializeComponent(extension);

            var comp = extension as BuildingUpgrade;

            this.BuildingToUpgradeID = comp.BuildingToUpgrade?.ItemID;
            this.SnappingRadius      = (float)At.GetField(comp, "m_snappingRadius");
            this.UpgradeFromIndex    = comp.UpgradeFromIndex;
            this.UpgradeIndex        = comp.UpgradeIndex;

            if (comp.RequiredQuestEvents != null && comp.RequiredQuestEvents.Length > 0)
            {
                this.RequiredQuestEventUIDs = comp.RequiredQuestEvents.Select(it => it.EventUID).ToArray();
            }
        }
Beispiel #11
0
        public static SL_ItemFilter ParseItemFilter(ItemFilter itemFilter)
        {
            if (itemFilter == null)
            {
                return(null);
            }

            var ret = new SL_ItemFilter
            {
                MatchOnEmpty = itemFilter.MatchOnEmpty,
            };

            ret.EquipmentTypes = (List <EquipmentSlot.EquipmentSlotIDs>)At.GetField(itemFilter, "m_equipmentTypes");
            ret.TagTypes       = (List <Tag.TagTypes>)At.GetField(itemFilter, "m_tagTypeFilters");

            return(ret);
        }
        public void Serialize(TrapEffectRecipe recipe)
        {
            this.Name        = recipe.Name;
            this.Description = recipe.Description;

            var items = (Item[])At.GetField(recipe, "m_compatibleItems");

            if (items != null)
            {
                this.CompatibleItemIDs = new List <int>();
                foreach (var item in items)
                {
                    // this.CompatibleItemIDs.Add(item.ItemID);
                    this.CompatibleItemIDs.Add(item.ItemID);
                }
            }

            var tags = (TagSourceSelector[])At.GetField(recipe, "m_compatibleTags");

            if (tags != null)
            {
                this.CompatibleItemTags = new List <string>();
                foreach (var tag in tags)
                {
                    this.CompatibleItemTags.Add(tag.Tag.TagName);
                }
            }

            if (recipe.TrapEffectsPrefab)
            {
                this.TrapEffects = new List <SL_Effect>();
                foreach (var effect in recipe.TrapEffectsPrefab.GetComponents <Effect>())
                {
                    this.TrapEffects.Add(SL_Effect.ParseEffect(effect));
                }
            }
            if (recipe.HiddenTrapEffectsPrefab)
            {
                this.HiddenEffects = new List <SL_Effect>();
                foreach (var effect in recipe.HiddenTrapEffectsPrefab.GetComponents <Effect>())
                {
                    this.HiddenEffects.Add(SL_Effect.ParseEffect(effect));
                }
            }
        }
Beispiel #13
0
        public override void SerializeItem(Item item)
        {
            base.SerializeItem(item);

            var comp = item as ItemContainer;

            this.BaseContainerCapacity = (float)At.GetField(comp, "m_baseContainerCapacity");

            this.SpecialType              = comp.SpecialType;
            this.OpenSound                = comp.OpenSoundOverride;
            this.AllowOverCapacity        = comp.AllowOverCapacity;
            this.CanContainMoney          = comp.CanContainMoney;
            this.CanReceiveCharacterItems = comp.CanReceiveCharacterItems;
            this.CanRemoveItems           = comp.CanRemoveItems;
            this.NonSavableContent        = comp.NonSavableContent;
            this.ShowMoneyIfEmpty         = comp.ShowMoneyIfEmpty;
            this.VisibleIfEmpty           = comp.VisibleIfEmpty;
            this.ItemFilter               = SL_ItemFilter.ParseItemFilter(comp.GetComponent <ItemFilter>());
        }
        /// <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);
            }
        }
        public override void SerializeItem(Item item)
        {
            base.SerializeItem(item);

            var trap = item as DeployableTrap;

            OneTimeUse = (bool)At.GetField(trap, "m_oneTimeUse");

            var recipes = (TrapEffectRecipe[])At.GetField(trap, "m_trapRecipes");

            if (recipes != null)
            {
                var list = new List <SL_TrapEffectRecipe>();
                foreach (var recipe in recipes)
                {
                    var dmRecipe = new SL_TrapEffectRecipe();
                    dmRecipe.Serialize(recipe);
                    list.Add(dmRecipe);
                }
                this.TrapRecipeEffects = list.ToArray();
            }
        }
Beispiel #16
0
        public override void SerializeComponent <T>(T extension)
        {
            var comp = extension as Preserver;

            this.NullifyPerish = comp.NullifyPerishing;

            var list = (List <Preserver.PreservedElement>)At.GetField(comp, "m_preservedElements");

            if (list != null)
            {
                var slList = new List <SL_PreservedElement>();
                foreach (var ele in list)
                {
                    slList.Add(new SL_PreservedElement
                    {
                        Preservation     = ele.Preservation,
                        PreservedItemTag = ele.Tag.Tag.TagName
                    });
                }
                this.PreservedElements = slList.ToArray();
            }
        }
 public static SL_ConstructionPhase SerializePhase(Building.ConstructionPhase phase)
 {
     return(new SL_ConstructionPhase
     {
         Name = LocalizationManager.Instance.GetLoc(phase.NameLocKey),
         PhaseType = phase.ConstructionType,
         HouseCountRequirement = phase.HouseCountRequirements,
         ConstructionTime = phase.GetConstructionTime(),
         ConstructionCosts = (BuildingResourceValues)At.GetField(phase, "m_constructionCosts"),
         UpkeepCosts = phase.UpkeepCosts,
         UpkeepProductions = phase.UpkeepProductions,
         CapacityBonus = phase.CapacityBonus,
         MultiplyProductionPerHouse = phase.MultiplyProductionPerHouse,
         HousingValue = phase.HousingValue,
         RareMaterialID = phase.RareMaterial?.ItemID ?? -1,
         BuildingRequirements = (from req in phase.BuildingRequirements
                                 select new SL_BuildingRequirement()
         {
             ReqBuildingID = req.ReqBuilding?.ItemID ?? -1,
             ReqUpgradeIndex = req.UpgradeIndex
         }).ToList(),
     });
 }
Beispiel #18
0
        // This helper clamps the desired head variation within the available options.
        // Minimum is always 0 obviously, but the max index varies between gender and skin index.
        private static void ClampHeadVariation(ref int index, int gender, int skinindex)
        {
            if (skinindex == -999)
            {
                return;
            }

            // get the first letter of the gender name (either M or F)
            // Could cast to Character.Gender and then Substring(0, 1), but that seems unnecessary over a simple if/else.
            string sex = gender == 0 ? "M" : "F";

            // cast skinindex to ethnicity name
            string ethnicity = ((Ethnicities)skinindex).ToString();

            // get the field name (eg. MHeadsWhite, FHeadsBlack, etc)
            string fieldName = sex + "Heads" + ethnicity;

            var array = (GameObject[])At.GetField(CharacterManager.CharacterVisualsPresets, fieldName);

            int limit = array.Length - 1;

            // clamp desired head inside 0 and limit
            index = Mathf.Clamp(index, 0, limit);
        }
        public override void SerializeItem(Item item)
        {
            base.SerializeItem(item);

            var comp = item as LevelAttackSkill;

            WatchedStatusIdentifier = comp.WatchedStatus?.IdentifierName;

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

            if (stages != null)
            {
                this.Stages = new SL_SkillStage[stages.Length];
                for (int i = 0; i < stages.Length; i++)
                {
                    var stage = stages[i];
                    this.Stages[i] = new SL_SkillStage
                    {
                        Name      = stage.GetName(),
                        Animation = stage.StageAnim
                    };
                }
            }
        }
        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);
        }
Beispiel #21
0
        public static IEnumerator SetVisuals(Character character, string visualData)
        {
            var visuals = character.GetComponentInChildren <CharacterVisuals>(true);

            var newData = CharacterVisualData.CreateFromNetworkData(visualData);

            if (newData.SkinIndex == -999)
            {
                yield break;
            }

            float start = Time.time;

            while (!visuals && Time.time - start < 5f)
            {
                yield return(new WaitForSeconds(0.5f));

                visuals = character.GetComponentInChildren <CharacterVisuals>(true);
            }

            yield return(new WaitForSeconds(0.5f));

            if (visuals)
            {
                // disable default visuals
                visuals.transform.Find("HeadWhiteMaleA")?.gameObject.SetActive(false);
                ((ArmorVisuals)At.GetField(visuals, "m_defaultHeadVisuals"))?.gameObject.SetActive(false);
                visuals.transform.Find("MBody0")?.gameObject.SetActive(false);
                visuals.transform.Find("MFeet0")?.gameObject.SetActive(false);

                // failsafe for head index based on skin and gender
                ClampHeadVariation(ref newData.HeadVariationIndex, (int)newData.Gender, newData.SkinIndex);

                // set visual data
                var data = visuals.VisualData;
                data.Gender             = newData.Gender;
                data.SkinIndex          = newData.SkinIndex;
                data.HeadVariationIndex = newData.HeadVariationIndex;
                data.HairColorIndex     = newData.HairColorIndex;
                data.HairStyleIndex     = newData.HairStyleIndex;

                // set to the character too
                character.VisualData = data;

                var presets = CharacterManager.CharacterVisualsPresets;

                // get the skin material
                var mat = (data.Gender == 0) ? presets.MSkins[data.SkinIndex] : presets.FSkins[data.SkinIndex];
                At.SetField(visuals, "m_skinMat", mat);

                // apply the visuals
                var hideface = false;
                var hidehair = false;

                if (visuals.ActiveVisualsHead)
                {
                    hideface = visuals.ActiveVisualsHead.HideFace;
                    hidehair = visuals.ActiveVisualsHead.HideHair;
                }

                //SL.Log("hideface: " + hideface);

                if (!hideface)
                {
                    visuals.LoadCharacterCreationHead(data.SkinIndex, (int)data.Gender, data.HeadVariationIndex);
                }

                if (!hidehair)
                {
                    ApplyHairVisuals(visuals, data.HairStyleIndex, data.HairColorIndex);
                }

                if (!character.Inventory.Equipment.GetEquippedItem(EquipmentSlot.EquipmentSlotIDs.Chest))
                {
                    visuals.LoadCharacterCreationBody((int)data.Gender, data.SkinIndex);
                }

                if (!character.Inventory.Equipment.GetEquippedItem(EquipmentSlot.EquipmentSlotIDs.Foot))
                {
                    visuals.LoadCharacterCreationBoots((int)data.Gender, data.SkinIndex);
                }
            }
            else
            {
                SL.Log("Couldn't get visuals!");
            }
        }
        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);
        }
        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;
                }
            }
        }
        public override void SerializeStatus(StatusEffect status)
        {
            base.SerializeStatus(status);

            this.MaxLevel = (int)At.GetField(status as LevelStatusEffect, "m_maxLevel");
        }
Beispiel #25
0
        internal void Internal_ApplyRecipe()
        {
            try
            {
                SL.Log("Defining recipe UID: " + this.UID);

                if (string.IsNullOrEmpty(this.UID))
                {
                    SL.LogWarning("No UID was set! Please set a UID, for example 'myname.myrecipe'. Aborting.");
                    return;
                }

                if (m_applied)
                {
                    SL.Log("Trying to apply an SL_Recipe that is already applied! This is not allowed.");
                    return;
                }

                var results = new List <ItemReferenceQuantity>();
                foreach (var result in this.Results)
                {
                    var resultItem = ResourcesPrefabManager.Instance.GetItemPrefab(result.ItemID);
                    if (!resultItem)
                    {
                        SL.Log("Error: Could not get recipe result id : " + result.ItemID);
                        return;
                    }
                    results.Add(new ItemReferenceQuantity(resultItem, result.Quantity));
                }

                var ingredients = new List <RecipeIngredient>();
                foreach (var ingredient in this.Ingredients)
                {
                    // legacy support
                    if (!string.IsNullOrEmpty(ingredient.Ingredient_Tag))
                    {
                        ingredient.SelectorValue = ingredient.Ingredient_Tag;
                    }
                    else if (ingredient.Ingredient_ItemID != 0)
                    {
                        ingredient.SelectorValue = ingredient.Ingredient_ItemID.ToString();
                    }

                    if (ingredient.Type == RecipeIngredient.ActionTypes.AddGenericIngredient)
                    {
                        var tag = CustomTags.GetTag(ingredient.SelectorValue);
                        if (tag == Tag.None)
                        {
                            SL.LogWarning("Could not get a tag by the name of '" + ingredient.SelectorValue);
                            return;
                        }

                        ingredients.Add(new RecipeIngredient
                        {
                            ActionType          = ingredient.Type,
                            AddedIngredientType = new TagSourceSelector(tag)
                        });
                    }
                    else
                    {
                        int.TryParse(ingredient.SelectorValue, out int id);
                        if (id == 0)
                        {
                            SL.LogWarning("Picking an Ingredient based on Item ID, but no ID was set. Check your XML and make sure there are no logical errors. Aborting");
                            return;
                        }

                        var ingredientItem = ResourcesPrefabManager.Instance.GetItemPrefab(id);
                        if (!ingredientItem)
                        {
                            SL.Log("Error: Could not get ingredient id : " + id);
                            return;
                        }

                        // The item needs the station type tag in order to be used in a manual recipe on that station
                        var tag = TagSourceManager.GetCraftingIngredient(StationType);
                        if (!ingredientItem.HasTag(tag))
                        {
                            //SL.Log($"Adding tag {tag.TagName} to " + ingredientItem.name);

                            if (!ingredientItem.GetComponent <TagSource>())
                            {
                                ingredientItem.gameObject.AddComponent <TagSource>();
                            }

                            ((List <TagSourceSelector>)At.GetField <TagListSelectorComponent>(ingredientItem.GetComponent <TagSource>(), "m_tagSelectors"))
                            .Add(new TagSourceSelector(tag));
                        }

                        ingredients.Add(new RecipeIngredient()
                        {
                            ActionType      = RecipeIngredient.ActionTypes.AddSpecificIngredient,
                            AddedIngredient = ingredientItem,
                        });
                    }
                }

                var recipe = ScriptableObject.CreateInstance <Recipe>();

                recipe.SetCraftingType(this.StationType);

                At.SetField(recipe, "m_results", results.ToArray());
                recipe.SetRecipeIngredients(ingredients.ToArray());

                // set or generate UID
                if (string.IsNullOrEmpty(this.UID))
                {
                    var uid = $"{recipe.Results[0].ItemID}{recipe.Results[0].Quantity}";
                    foreach (var ing in recipe.Ingredients)
                    {
                        if (ing.AddedIngredient != null)
                        {
                            uid += $"{ing.AddedIngredient.ItemID}";
                        }
                        else if (ing.AddedIngredientType != null)
                        {
                            uid += $"{ing.AddedIngredientType.Tag.TagName}";
                        }
                    }
                    this.UID = uid;
                    At.SetField(recipe, "m_uid", new UID(uid));
                }
                else
                {
                    At.SetField(recipe, "m_uid", new UID(this.UID));
                }

                recipe.Init();

                // fix Recipe Manager dictionaries to contain our recipe
                var dict  = References.ALL_RECIPES;
                var dict2 = References.RECIPES_PER_UTENSIL;

                if (dict.ContainsKey(recipe.UID))
                {
                    dict[recipe.UID] = recipe;
                }
                else
                {
                    dict.Add(recipe.UID, recipe);
                }

                if (!dict2.ContainsKey(recipe.CraftingStationType))
                {
                    dict2.Add(recipe.CraftingStationType, new List <UID>());
                }

                if (!dict2[recipe.CraftingStationType].Contains(recipe.UID))
                {
                    dict2[recipe.CraftingStationType].Add(recipe.UID);
                }

                m_applied = true;
            }
            catch (Exception e)
            {
                SL.LogWarning("Error applying recipe!");
                SL.LogInnerException(e);
            }
        }
Beispiel #26
0
        public virtual void SetStats(Character character)
        {
            if (character.GetComponent <PlayerCharacterStats>())
            {
                CustomCharacters.FixStats(character);
            }

            var stats = character.GetComponent <CharacterStats>();

            if (!stats)
            {
                return;
            }

            if (Health != null)
            {
                var m_maxHealthStat = (Stat)At.GetField(stats, "m_maxHealthStat");
                m_maxHealthStat.AddStack(new StatStack(SL_STAT_ID, (float)Health - 100), false);
            }

            if (HealthRegen != null)
            {
                var m_healthRegenStat = (Stat)At.GetField(stats, "m_healthRegen");
                m_healthRegenStat.AddStack(new StatStack(SL_STAT_ID, (float)HealthRegen), false);
            }

            if (ImpactResist != null)
            {
                var m_impactResistance = (Stat)At.GetField(stats, "m_impactResistance");
                m_impactResistance.AddStack(new StatStack(SL_STAT_ID, (float)ImpactResist), false);
            }

            if (Protection != null)
            {
                var m_damageProtection = (Stat[])At.GetField(stats, "m_damageProtection");
                m_damageProtection[0].AddStack(new StatStack(SL_STAT_ID, (float)Protection), false);
            }

            if (this.Barrier != null)
            {
                var m_barrier = (Stat)At.GetField(stats, "m_barrierStat");
                m_barrier.AddStack(new StatStack(SL_STAT_ID, (float)Barrier), false);
            }

            if (Damage_Resists != null)
            {
                var m_damageResistance = (Stat[])At.GetField(stats, "m_damageResistance");
                for (int i = 0; i < 6; i++)
                {
                    m_damageResistance[i].AddStack(new StatStack(SL_STAT_ID, Damage_Resists[i]), false);
                }
            }

            if (Damage_Bonus != null)
            {
                var m_damageTypesModifier = (Stat[])At.GetField(stats, "m_damageTypesModifier");
                for (int i = 0; i < 6; i++)
                {
                    m_damageTypesModifier[i].AddStack(new StatStack(SL_STAT_ID, Damage_Bonus[i]), false);
                }
            }

            // status immunity
            if (this.Status_Immunity != null)
            {
                var immunities = new List <TagSourceSelector>();
                foreach (var tagName in this.Status_Immunity)
                {
                    if (CustomItems.GetTag(tagName) is Tag tag && tag != Tag.None)
                    {
                        immunities.Add(new TagSourceSelector(tag));
                    }
                }

                At.SetField(stats, "m_statusEffectsNaturalImmunity", immunities.ToArray());
            }
        }
 /// <summary>
 /// Get the Localization for the Status Effect (name and description).
 /// </summary>
 /// <param name="effect">The Status Effect to get localization for.</param>
 /// <param name="name">The output name.</param>
 /// <param name="desc">The output description.</param>
 public static void GetStatusLocalization(StatusEffect effect, out string name, out string desc)
 {
     name = LocalizationManager.Instance.GetLoc((string)At.GetField(effect, "m_nameLocKey"));
     desc = LocalizationManager.Instance.GetLoc((string)At.GetField(effect, "m_descriptionLocKey"));
 }
        // ========== parsing from CustomSpawnInfo ===========

        internal static SL_CharacterSaveData FromSpawnInfo(CustomSpawnInfo info)
        {
            // should probably debug this if it happens
            if (info.Template == null || !info.ActiveCharacter)
            {
                SL.LogWarning("Trying to save a CustomSpawnInfo, but template or activeCharacter is null!");
                return(null);
            }

            var character = info.ActiveCharacter;
            var template  = info.Template;

            // capture the save data in an instance
            var data = new SL_CharacterSaveData()
            {
                SaveType      = template.SaveType,
                TemplateUID   = template.UID,
                ExtraSaveData = template.INTERNAL_OnPrepareSave(character),
                ExtraRPCData  = info.ExtraRPCData,

                CharacterUID = character.UID,
                WasDead      = character.IsDead,
                Forward      = character.transform.forward,
                Position     = character.transform.position,
                Silver       = character.Inventory.ContainedSilver,
            };

            if (character.Inventory)
            {
                data.SetSavedItems(character);
            }

            if (character.GetComponentInChildren <AISWander>() is AISWander aiWander)
            {
                if (aiWander.FollowTransform && aiWander.FollowTransform.GetComponent <Character>() is Character followTarget)
                {
                    data.FollowTargetUID = followTarget.UID.ToString();
                }
            }

            try
            {
                data.Health = character.Health;

                if (character.StatusEffectMngr)
                {
                    var statuses = character.StatusEffectMngr.Statuses.ToArray().Where(it => !string.IsNullOrEmpty(it.IdentifierName));
                    data.StatusData = new string[statuses.Count()];

                    int i = 0;
                    foreach (var status in statuses)
                    {
                        var sourceChar = (UID)At.GetField(status, "m_sourceCharacterUID")?.ToString();
                        data.StatusData[i] = $"{status.IdentifierName}|{sourceChar}|{status.RemainingLifespan}";
                        i++;
                    }
                }
            }
            catch { }

            return(data);
        }
        public virtual void SerializeStatus(StatusEffect status)
        {
            var preset = status.GetComponent <EffectPreset>();

            this.NewStatusID            = preset?.PresetID ?? -1;
            this.TargetStatusIdentifier = status.IdentifierName;
            this.StatusIdentifier       = status.IdentifierName;
            this.IgnoreBuildupIfApplied = status.IgnoreBuildUpIfApplied;
            this.BuildupRecoverySpeed   = status.BuildUpRecoverSpeed;
            this.DisplayedInHUD         = status.DisplayInHud;
            this.IsHidden    = status.IsHidden;
            this.Lifespan    = status.StatusData.LifeSpan;
            this.RefreshRate = status.RefreshRate;
            this.AmplifiedStatusIdentifier    = status.AmplifiedStatus?.IdentifierName ?? "";
            this.PlayFXOnActivation           = status.PlayFXOnActivation;
            this.ComplicationStatusIdentifier = status.ComplicationStatus?.IdentifierName;
            this.FXOffset                 = status.FxOffset;
            this.IgnoreBarrier            = status.IgnoreBarrier;
            this.IsMalusEffect            = status.IsMalusEffect;
            this.NormalizeDamageDisplay   = status.NormalizeDamageDisplay;
            this.PlaySpecialFXOnStop      = status.PlaySpecialFXOnStop;
            this.RemoveRequiredStatus     = status.RemoveRequiredStatus;
            this.RequiredStatusIdentifier = status.RequiredStatus?.IdentifierName;
            this.SpecialSFX               = status.SpecialSFX;
            this.VFXInstantiationType     = status.FxInstantiation;

            this.ActionOnHit = status.ActionOnHit;

            this.Priority = (int)At.GetField(status, "m_priority");

            this.DelayedDestroyTime = status.DelayedDestroyTime;
            this.Purgeable          = status.Purgeable;

            CustomStatusEffects.GetStatusLocalization(status, out Name, out Description);

            var tags = At.GetField(status, "m_tagSource") as TagListSelectorComponent;

            if (tags)
            {
                Tags = tags.Tags.Select(it => it.TagName).ToArray();
            }

            var vfx = status.FXPrefab?.GetComponent <VFXSystem>();

            if (vfx)
            {
                VFXPrefab = SL_PlayVFX.GetVFXSystemEnum(vfx);
            }

            // PARSE EFFECT FAMILY
            FamilyMode = status.FamilyMode;
            if (status.EffectFamily != null)
            {
                if (FamilyMode == StatusEffect.FamilyModes.Bind)
                {
                    BindFamily = SL_StatusEffectFamily.ParseEffectFamily(status.EffectFamily);
                }
                else
                {
                    ReferenceFamilyUID = status.EffectFamily.UID;
                }
            }

            // For existing StatusEffects, the StatusData contains the real values, so we need to SetValue to each Effect.
            var statusData = status.StatusData.EffectsData;
            var components = status.GetComponentsInChildren <Effect>();

            for (int i = 0; i < components.Length; i++)
            {
                var comp = components[i];
                if (comp && comp.Signature.Length > 0)
                {
                    comp.SetValue(statusData[i].Data);
                }
            }

            var       effects = new List <SL_EffectTransform>();
            Transform signature;

            if (status.transform.childCount > 0)
            {
                signature = status.transform.GetChild(0);
                if (signature.transform.childCount > 0)
                {
                    foreach (Transform child in signature.transform)
                    {
                        var effectsChild = SL_EffectTransform.ParseTransform(child);

                        if (effectsChild.HasContent)
                        {
                            effects.Add(effectsChild);
                        }
                    }
                }
            }

            Effects = effects.ToArray();
        }