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);
        }
        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);
                }
            }
        }
Beispiel #3
0
        public override void ApplyToComponent <T>(T component)
        {
            var comp = component as Preserver;

            if (this.NullifyPerish != null)
            {
                comp.NullifyPerishing = (bool)this.NullifyPerish;
            }

            if (this.PreservedElements != null)
            {
                var list = new List <Preserver.PreservedElement>();

                foreach (var ele in this.PreservedElements)
                {
                    list.Add(new Preserver.PreservedElement
                    {
                        Preservation = ele.Preservation,
                        Tag          = new TagSourceSelector(CustomTags.GetTag(ele.PreservedItemTag)),
                    });
                }

                At.SetField(comp, "m_preservedElements", list);
            }
        }
        public override SkillSlot ApplyToRow(Transform row, int treeID)
        {
            var col = new GameObject("Col" + this.ColumnIndex);

            col.transform.parent = row;

            var comp = col.AddComponent <SkillSlot>();

            comp.IsBreakthrough = Breakthrough;

            At.SetField(comp, "m_requiredMoney", SilverCost);
            At.SetField(comp as BaseSkillSlot, "m_columnIndex", ColumnIndex);

            var skill = ResourcesPrefabManager.Instance.GetItemPrefab(SkillID) as Skill;

            if (!skill)
            {
                SL.LogWarning("SL_SkillSlot: Could not find skill by id '" + SkillID + "'");
                return(comp);
            }

            At.SetField(comp, "m_skill", skill);

            At.SetField(skill, "m_schoolIndex", treeID);
            //SL.LogWarning("Set " + treeID + " for " + skill.Name + "'s treeID");

            if (this.RequiredSkillSlot != Vector2.zero)
            {
                SetRequiredSlot(comp);
            }

            return(comp);
        }
Beispiel #5
0
        public override void ApplyToComponent <T>(T component)
        {
            base.ApplyToComponent(component);

            var comp = component as ItemAddOn;

            if (this.SnappingRadius != null)
            {
                At.SetField(comp, "m_snappingRadius", (float)this.SnappingRadius);
            }

            if (this.AddOnCompatibleItemID != null)
            {
                var addOnComptaible = ResourcesPrefabManager.Instance.GetItemPrefab((int)this.AddOnCompatibleItemID);
                if (addOnComptaible)
                {
                    At.SetField(comp, "m_addOnCompatibleItem", addOnComptaible);
                }
            }

            if (this.AddOnStatePrefabItemID != null)
            {
                var addOnStateItem = ResourcesPrefabManager.Instance.GetItemPrefab((int)this.AddOnStatePrefabItemID);
                if (addOnStateItem)
                {
                    comp.AddOnStateItemPrefab = addOnStateItem;
                }
            }
        }
Beispiel #6
0
        public void ApplyToItemFilter(ItemFilter component)
        {
            component.MatchOnEmpty = this.MatchOnEmpty;

            At.SetField(component, "m_equipmentTypes", this.EquipmentTypes);
            At.SetField(component, "m_tagTypeFilters", this.TagTypes);
        }
Beispiel #7
0
        public override void ApplyToItem(Item item)
        {
            base.ApplyToItem(item);

            var comp = item as Building;

            if (this.BuildingType != null)
            {
                comp.BuildingType = (Building.BuildingTypes) this.BuildingType;
            }

            if (this.ConstructionPhases != null)
            {
                var list = new List <Building.ConstructionPhase>();
                foreach (var phase in this.ConstructionPhases)
                {
                    list.Add(phase.GeneratePhase());
                }
                At.SetField(comp, "m_constructionPhases", list.ToArray());
            }

            if (this.UpgradePhases != null)
            {
                var list = new List <Building.ConstructionPhase>();
                foreach (var phase in this.UpgradePhases)
                {
                    list.Add(phase.GeneratePhase());
                }
                At.SetField(comp, "m_upgradePhases", list.ToArray());
            }
        }
        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);
        }
        // Normal template apply method
        internal void Internal_ApplyTemplate()
        {
            if (!StatusEffectFamilyLibrary.Instance)
            {
                return;
            }

            var library = StatusEffectFamilyLibrary.Instance;

            StatusEffectFamily family;

            if (library.StatusEffectFamilies.Where(it => (string)it.UID == this.UID).Any())
            {
                family = library.StatusEffectFamilies.First(it => (string)it.UID == this.UID);
            }
            else
            {
                family = new StatusEffectFamily();
                library.StatusEffectFamilies.Add(family);
            }

            if (family == null)
            {
                SL.LogWarning("Applying SL_StatusEffectFamily template, null error");
                return;
            }

            if (this.UID != null)
            {
                At.SetField(family, "m_uid", new UID(this.UID));
            }

            if (this.Name != null)
            {
                family.Name = this.Name;
            }

            if (this.StackBehaviour != null)
            {
                family.StackBehavior = (StatusEffectFamily.StackBehaviors) this.StackBehaviour;
            }

            if (this.MaxStackCount != null)
            {
                family.MaxStackCount = (int)this.MaxStackCount;
            }

            if (this.LengthType != null)
            {
                family.LengthType = (StatusEffectFamily.LengthTypes) this.LengthType;
            }
        }
        // used by SL_StatusEffect Bind Families
        public StatusEffectFamily CreateAsBindFamily()
        {
            var ret = new StatusEffectFamily
            {
                Name          = this.Name,
                LengthType    = (StatusEffectFamily.LengthTypes) this.LengthType,
                MaxStackCount = (int)this.MaxStackCount,
                StackBehavior = (StatusEffectFamily.StackBehaviors) this.StackBehaviour
            };

            At.SetField(ret, "m_uid", new UID(this.UID));

            return(ret);
        }
        /// <summary> Set both name and description. Used by SetName and SetDescription. </summary>
        public static void SetNameAndDescription(Item item, string _name, string _description)
        {
            var name = _name ?? "";
            var desc = _description ?? "";

            // set the local fields on the item (this should be enough for 99% of cases)

            At.SetField(item, "m_name", name);
            At.SetField(item, "m_localizedName", name);
            At.SetField(item, "m_lastNameLang", LocalizationManager.Instance.CurrentLanguage);

            At.SetField(item, "m_localizedDescription", desc);
            At.SetField(item, "m_lastDescLang", LocalizationManager.Instance.CurrentLanguage);

            // set the localization to the LocalizationManager dictionary

            var loc = new ItemLocalization(name, desc);

            if (References.ITEM_LOCALIZATION.ContainsKey(item.ItemID))
            {
                References.ITEM_LOCALIZATION[item.ItemID] = loc;
            }
            else
            {
                References.ITEM_LOCALIZATION.Add(item.ItemID, loc);
            }

            // keep track of the custom localization in case the user changes language

            if (s_customLocalizations.ContainsKey(item.ItemID))
            {
                s_customLocalizations[item.ItemID] = loc;
            }
            else
            {
                s_customLocalizations.Add(item.ItemID, loc);
            }

            // If the item is in the "duplicate" localization dicts, remove it.

            if (References.LOCALIZATION_DUPLICATE_NAME.ContainsKey(item.ItemID))
            {
                References.LOCALIZATION_DUPLICATE_NAME.Remove(item.ItemID);
            }

            if (References.LOCALIZATION_DUPLICATE_DESC.ContainsKey(item.ItemID))
            {
                References.LOCALIZATION_DUPLICATE_DESC.Remove(item.ItemID);
            }
        }
Beispiel #12
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);
        }
        /// <summary>
        /// Helper to set the Name and Description localization for an Imbue Preset
        /// </summary>
        public static void SetImbueLocalization(ImbueEffectPreset preset, string name, string description)
        {
            GetImbueLocalization(preset, out string oldName, out string oldDesc);

            if (string.IsNullOrEmpty(name))
            {
                name = oldName;
            }

            if (string.IsNullOrEmpty(description))
            {
                description = oldDesc;
            }

            var nameKey = $"NAME_{preset.PresetID}_{preset.Name.Trim()}";

            At.SetField(preset, "m_imbueNameKey", nameKey);

            if (References.GENERAL_LOCALIZATION.ContainsKey(nameKey))
            {
                References.GENERAL_LOCALIZATION[nameKey] = name;
            }
            else
            {
                References.GENERAL_LOCALIZATION.Add(nameKey, name);
            }

            var descKey = $"DESC_{preset.PresetID}_{preset.Name.Trim()}";

            At.SetField(preset, "m_imbueDescKey", descKey);

            if (References.GENERAL_LOCALIZATION.ContainsKey(descKey))
            {
                References.GENERAL_LOCALIZATION[descKey] = description;
            }
            else
            {
                References.GENERAL_LOCALIZATION.Add(descKey, description);
            }

            if (preset.GetComponent <StatusEffect>() is StatusEffect status)
            {
                SetStatusLocalization(status, name, description);
            }
        }
        // Generate StatusData for the StatusEffect automatically
        public static void CompileEffectsToData(StatusEffect status)
        {
            // Get the EffectSignature component
            var signature = status.GetComponentInChildren <EffectSignature>();

            status.StatusData.EffectSignature = signature;

            // Get and Set the Effects list
            var effects = signature.GetComponentsInChildren <Effect>()?.ToList() ?? new List <Effect>();

            signature.Effects = effects;
            At.SetField(status, "m_effectList", effects);

            // Finally, set the EffectsData[] array.
            status.StatusData.EffectsData = GenerateEffectsData(effects);

            // Not sure if this is needed or not, but I'm doing it to be extra safe.
            At.SetField(status, "m_totalData", status.StatusData.EffectsData);
        }
Beispiel #15
0
        public static void InitLocalization()
        {
            if (s_doneLocalization)
            {
                return;
            }

            s_doneLocalization = true;

            // get the Rewired Category for the category we're using
            var category = ReInput.mapping.GetActionCategory(CUSTOM_CATEGORY);

            // override the internal name
            At.SetField(category, "_name", "CustomKeybindings");

            // Get reference to localization dict
            var genLoc = References.GENERAL_LOCALIZATION;

            // add localization for our category, in the format the game will expect to find it
            genLoc.Add("ActionCategory_CustomKeybindings", "Custom Keybindings");

            // Localize the keys
            foreach (var customKey in s_customKeyDict.Values)
            {
                if (customKey.name.Contains("QS_Instant"))
                {
                    //SL.Log("Skipping localization for " + customKey.name);
                    continue;
                }

                string key = "InputAction_" + customKey.name;

                if (!genLoc.ContainsKey(key))
                {
                    genLoc.Add(key, customKey.name);
                }
                else
                {
                    genLoc[key] = customKey.name;
                }
            }
        }
        public override SkillSlot ApplyToRow(Transform row, int treeID)
        {
            var col = new GameObject("Col" + this.ColumnIndex);

            col.transform.parent = row;

            var comp = col.AddComponent <SkillSlotFork>();

            At.SetField(comp as BaseSkillSlot, "m_columnIndex", this.ColumnIndex);

            if (this.RequiredSkillSlot != Vector2.zero)
            {
                SetRequiredSlot(comp);
            }

            Choice1.ApplyToRow(col.transform, treeID);
            Choice2.ApplyToRow(col.transform, treeID);

            return(null);
        }
        public override void ApplyToItem(ItemStats stats)
        {
            base.ApplyToItem(stats);

            var wStats = stats as WeaponStats;

            if (this.AttackSpeed != null)
            {
                wStats.AttackSpeed = (float)this.AttackSpeed;
            }

            if (this.Impact != null)
            {
                wStats.Impact = (float)this.Impact;
            }

            if (this.BaseDamage != null)
            {
                wStats.BaseDamage = SL_Damage.GetDamageList(this.BaseDamage);

                // fix for m_activeBaseDamage
                var weapon = wStats.GetComponent <Weapon>();
                At.SetField(weapon, "m_activeBaseDamage", wStats.BaseDamage.Clone());
                At.SetField(weapon, "m_baseDamage", wStats.BaseDamage.Clone());
            }

            if (this.StamCost != null)
            {
                wStats.StamCost = (float)this.StamCost;
            }

            if (AutoGenerateAttackData || this.Attacks == null || this.Attacks.Length < 1)
            {
                // SL.Log("Generating AttackData automatically");
                wStats.Attacks = GetScaledAttackData(wStats.GetComponent <Weapon>());
            }
            else
            {
                wStats.Attacks = Attacks;
            }
        }
        public override void ApplyToItem(Item item)
        {
            base.ApplyToItem(item);

            var trap = item as DeployableTrap;

            if (this.OneTimeUse != null)
            {
                At.SetField(trap, "m_oneTimeUse", (bool)this.OneTimeUse);
            }

            if (this.TrapRecipeEffects != null)
            {
                var list = new List <TrapEffectRecipe>();
                foreach (var holder in this.TrapRecipeEffects)
                {
                    list.Add(holder.Apply());
                }
                At.SetField(trap, "m_trapRecipes", list.ToArray());
            }
        }
Beispiel #19
0
        public virtual void ApplyToItem(ItemStats stats)
        {
            //set base value
            if (this.BaseValue != null)
            {
                At.SetField(stats, "m_baseValue", (int)this.BaseValue);
            }

            //set raw weight
            if (this.RawWeight != null)
            {
                At.SetField(stats, "m_rawWeight", (float)this.RawWeight);
            }

            //max durability
            if (this.MaxDurability != null)
            {
                At.SetField(stats, "m_baseMaxDurability", (int)this.MaxDurability);
                stats.StartingDurability = (int)this.MaxDurability;
            }
        }
        /// <summary>
        /// Helper to set the ItemVisualLink Icon or SkillTreeIcon for an Item.
        /// </summary>
        /// <param name="item">The item you want to set to.</param>
        /// <param name="sprite">The Sprite you want to set.</param>
        /// <param name="skill">Whether this is a "small skill tree icon", or just the main item icon.</param>
        public static void SetSpriteLink(Item item, Sprite sprite, bool skill = false)
        {
            var link = GetOrAddVisualLink(item);

            if (skill)
            {
                (item as Skill).SkillTreeIcon = sprite;
                link.SkillTreeIcon            = sprite;
            }
            else
            {
                At.SetField(item, "m_itemIcon", sprite);

                if (item.HasDefaultIcon)
                {
                    At.SetField(item, "m_itemIconPath", "notnull");
                }

                link.ItemIcon = sprite;
            }
        }
Beispiel #21
0
        // Actually add the Rewired control map

        internal static InputAction AddRewiredAction(UserData userData, string name, KeybindingsCategory category, InputType type, out int actionID)
        {
            int[] preAddIDs = userData.GetActionIds();

            // Add an action to the data store
            userData.AddAction((int)category);

            actionID = userData.GetActionIds().Where(it => !preAddIDs.Contains(it)).FirstOrDefault();

            // Get a reference to the added action
            var inputAction = userData.GetActionById(actionID);

            // Configure our action according to args
            At.SetField(inputAction, "_name", name);
            At.SetField(inputAction, "_descriptiveName", name);
            At.SetField(inputAction, "_type", (InputActionType)type);
            At.SetField(inputAction, "_userAssignable", true);
            At.SetField(inputAction, "_categoryId", (int)category);

            return(inputAction);
        }
        /// <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?");
            }
        }
        /// <summary>
        /// Helper to set the Name and Description localization for a StatusEffect
        /// </summary>
        public static void SetStatusLocalization(StatusEffect effect, string name, string description)
        {
            GetStatusLocalization(effect, out string oldName, out string oldDesc);

            if (string.IsNullOrEmpty(name))
            {
                name = oldName;
            }
            if (string.IsNullOrEmpty(description))
            {
                description = oldDesc;
            }

            var nameKey = $"NAME_{effect.IdentifierName}";

            At.SetField(effect, "m_nameLocKey", nameKey);

            if (References.GENERAL_LOCALIZATION.ContainsKey(nameKey))
            {
                References.GENERAL_LOCALIZATION[nameKey] = name;
            }
            else
            {
                References.GENERAL_LOCALIZATION.Add(nameKey, name);
            }

            var descKey = $"DESC_{effect.IdentifierName}";

            At.SetField(effect, "m_descriptionLocKey", descKey);

            if (References.GENERAL_LOCALIZATION.ContainsKey(descKey))
            {
                References.GENERAL_LOCALIZATION[descKey] = description;
            }
            else
            {
                References.GENERAL_LOCALIZATION.Add(descKey, description);
            }
        }
Beispiel #24
0
        public override void ApplyToComponent <T>(T component)
        {
            base.ApplyToComponent(component);

            var comp = component as BuildingUpgrade;

            if (this.BuildingToUpgradeID != null)
            {
                comp.BuildingToUpgrade = ResourcesPrefabManager.Instance.GetItemPrefab((int)this.BuildingToUpgradeID) as Building;
            }

            if (this.SnappingRadius != null)
            {
                At.SetField(comp, "m_snappingRadius", (float)this.SnappingRadius);
            }

            if (this.UpgradeFromIndex != null)
            {
                comp.UpgradeFromIndex = (int)this.UpgradeFromIndex;
            }

            if (this.UpgradeIndex != null)
            {
                comp.UpgradeIndex = (int)this.UpgradeIndex;
            }

            if (this.RequiredQuestEventUIDs != null)
            {
                var list = new List <QuestEventReference>();
                foreach (var evt in this.RequiredQuestEventUIDs)
                {
                    list.Add(new QuestEventReference {
                        m_eventUID = evt
                    });
                }
                comp.RequiredQuestEvents = list.ToArray();
            }
        }
        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);
        }
        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);
        }
        public TrapEffectRecipe Apply()
        {
            var recipe = new TrapEffectRecipe();

            At.SetField(recipe, "m_name", this.Name);

            SetLocalization();

            if (this.CompatibleItemTags != null)
            {
                var list = new List <TagSourceSelector>();
                foreach (var tagName in this.CompatibleItemTags)
                {
                    if (CustomTags.GetTag(tagName) is Tag tag && tag != Tag.None)
                    {
                        list.Add(new TagSourceSelector(tag));
                    }
                }
                At.SetField(recipe, "m_compatibleTags", list.ToArray());
            }

            if (this.CompatibleItemIDs != null)
            {
                var list = new List <Item>();
                foreach (var itemID in this.CompatibleItemIDs)
                {
                    if (ResourcesPrefabManager.Instance.GetItemPrefab(itemID) is Item item)
                    {
                        list.Add(item);
                    }
                }
                At.SetField(recipe, "m_compatibleItems", list.ToArray());
            }

            if (this.TrapEffects != null && this.TrapEffects.Count > 0)
            {
                var prefab = recipe.TrapEffectsPrefab;
                if (!prefab)
                {
                    prefab = new GameObject($"{this.Name}_NormalEffects").transform;
                    GameObject.DontDestroyOnLoad(prefab.gameObject);
                    recipe.TrapEffectsPrefab = prefab;
                }
                UnityHelpers.DestroyChildren(prefab);

                foreach (var effect in this.TrapEffects)
                {
                    effect.ApplyToTransform(prefab);
                }
            }

            if (this.HiddenEffects != null && this.HiddenEffects.Count > 0)
            {
                var prefab = recipe.HiddenTrapEffectsPrefab;
                if (!prefab)
                {
                    prefab = new GameObject($"{this.Name}_HiddenEffects").transform;
                    GameObject.DontDestroyOnLoad(prefab.gameObject);
                    recipe.HiddenTrapEffectsPrefab = prefab;
                }
                UnityHelpers.DestroyChildren(prefab);

                foreach (var effect in this.HiddenEffects)
                {
                    effect.ApplyToTransform(prefab);
                }
            }

            return(recipe);
        }
Beispiel #28
0
        private void OnLateApply(object[] obj)
        {
            var skill = obj[0] as Skill;

            if (!skill)
            {
                return;
            }

            if (this.RequiredItems != null)
            {
                var list = new List <Skill.ItemRequired>();
                foreach (var req in this.RequiredItems)
                {
                    if (ResourcesPrefabManager.Instance.GetItemPrefab(req.ItemID) is Item reqItem)
                    {
                        list.Add(new Skill.ItemRequired()
                        {
                            Item     = reqItem,
                            Consume  = req.Consume,
                            Quantity = req.Quantity
                        });
                    }
                }

                skill.RequiredItems = list.ToArray();
            }

            var activationConditions = new List <Skill.ActivationCondition>();

            if (skill.transform.childCount > 0)
            {
                foreach (Transform child in skill.transform)
                {
                    if (child.name.Contains("Activation"))
                    {
                        foreach (var condition in child.GetComponentsInChildren <EffectCondition>())
                        {
                            var skillCondition = new Skill.ActivationCondition
                            {
                                Condition = condition
                            };

                            string msgLoc;
                            if (condition is WindAltarActivatedCondition)
                            {
                                msgLoc = "Notification_Skill_WindAltarRequired";
                            }
                            else
                            {
                                msgLoc = "Notification_Skill_RequirementsNotMet";
                            }

                            At.SetField(skillCondition, "m_messageLocKey", msgLoc);

                            activationConditions.Add(skillCondition);
                        }
                    }
                }
            }

            At.SetField(skill, "m_additionalConditions", activationConditions.ToArray());

            LateApply(skill);
        }
        internal IEnumerator ApplyCoroutine(Character character, SL_Character template)
        {
            yield return(new WaitForSeconds(0.5f));

            if (this.Silver > 0)
            {
                character.Inventory.AddMoney(this.Silver);
            }

            if (!string.IsNullOrEmpty(FollowTargetUID))
            {
                var followTarget = CharacterManager.Instance.GetCharacter(FollowTargetUID);
                var aisWander    = character.GetComponentInChildren <AISWander>();
                if (followTarget && aisWander)
                {
                    aisWander.FollowTransform = followTarget.transform;
                }
                else
                {
                    SL.LogWarning("Failed setting follow target!");
                }
            }

            if (WasDead)
            {
                At.SetField(character, "m_loadedDead", true);

                if (character.GetComponentInChildren <LootableOnDeath>() is LootableOnDeath loot)
                {
                    At.SetField(loot, "m_wasAlive", false);
                }
            }

            if (ItemSaves != null && ItemSaves.Count > 0)
            {
                foreach (var itemSave in ItemSaves)
                {
                    switch (itemSave.Type)
                    {
                    case CharItemSaveData.EquipSaveType.Pouch:
                        var item = ItemManager.Instance.GenerateItemNetwork(itemSave.ItemID);
                        if (item)
                        {
                            item.ChangeParent(character.Inventory.Pouch.transform);
                            item.RemainingAmount = itemSave.Quantity;
                        }
                        break;

                    case CharItemSaveData.EquipSaveType.Equipped:
                        SL_Character.TryEquipItem(character, itemSave.ItemID);
                        break;

                    case CharItemSaveData.EquipSaveType.Backpack:
                        item = ItemManager.Instance.GenerateItemNetwork(itemSave.ItemID);
                        if (item && character.Inventory.EquippedBag)
                        {
                            item.ChangeParent(character.Inventory.EquippedBag.Container.transform);
                            item.RemainingAmount = itemSave.Quantity;
                        }
                        break;
                    }
                }
            }

            if (character.GetComponent <CharacterStats>() is CharacterStats stats)
            {
                stats.SetHealth(this.Health);
            }

            if (this.StatusData != null)
            {
                var statusMgr = character.GetComponentInChildren <StatusEffectManager>(true);
                if (statusMgr)
                {
                    foreach (var statusData in this.StatusData)
                    {
                        var data = statusData.Split('|');

                        var status = ResourcesPrefabManager.Instance.GetStatusEffectPrefab(data[0]);
                        if (!status)
                        {
                            continue;
                        }

                        var dealer = CharacterManager.Instance.GetCharacter(data[1]);
                        var effect = statusMgr.AddStatusEffect(status, dealer);

                        var remaining = float.Parse(data[2]);
                        At.SetField(effect, "m_remainingTime", remaining);
                        if (effect.StatusData != null)
                        {
                            At.SetField(effect.StatusData, "m_remainingLifespan", remaining);
                        }
                    }
                }
            }

            template.INTERNAL_OnSaveApplied(character, this.ExtraRPCData, this.ExtraSaveData);
        }
        protected override void ApplyToCharacter(Character character)
        {
            var aiRootPrefab = new GameObject("BasicMelee_AIRoot").AddComponent <AIRoot>();

            aiRootPrefab.gameObject.SetActive(false);

            aiRootPrefab.transform.parent = character.transform;

            // -- create base state objects --

            // state 1: Wander
            var wanderState = new GameObject("1_Wander").AddComponent <AISWander>();

            wanderState.transform.parent = aiRootPrefab.transform;

            // state 2: Suspicious
            var susState = new GameObject("2_Suspicious").AddComponent <AISSuspicious>();

            susState.transform.parent = aiRootPrefab.transform;

            //state 3: alert
            var alertState = new GameObject("3_Alert").AddComponent <AISSuspicious>();

            alertState.transform.parent = aiRootPrefab.transform;

            //state 4: Combat
            var combatState = new GameObject("4_Combat").AddComponent <AISCombatMelee>();

            combatState.transform.parent = aiRootPrefab.transform;

            // ---- setup actual state parameters and links ----

            // setup 1 - Wander

            wanderState.ContagionRange   = this.AIContagionRange;
            wanderState.ForceNotCombat   = this.ForceNonCombat;
            wanderState.SpeedModif       = this.Wander_Speed;
            wanderState.WanderFar        = this.CanWanderFar;
            wanderState.AutoFollowPlayer = this.Wander_FollowPlayer;

            if (this.Wander_PatrolWaypoints != null && this.Wander_Type == AISWander.WanderType.Patrol)
            {
                var wanderTrans = new GameObject($"Waypoints_{character.UID}");
                wanderState.WaypointsParent = wanderTrans.transform;

                for (int i = 0; i < this.Wander_PatrolWaypoints.Length; i++)
                {
                    var waypointObj = new GameObject("Waypoint " + i + 1);
                    var waypoint    = waypointObj.AddComponent <Waypoint>();

                    waypointObj.transform.parent = wanderTrans.transform;

                    waypointObj.transform.position = Wander_PatrolWaypoints[i].WorldPosition;
                    waypoint.RandomRadius          = Wander_PatrolWaypoints[i].RandomRadius;
                    waypoint.WaitTime = Wander_PatrolWaypoints[i].WaitTime;
                }
            }

            var wanderDetection = new GameObject("Detection").AddComponent <AICEnemyDetection>();

            wanderDetection.transform.parent = wanderState.transform;
            var wanderDetectEffects = new GameObject("DetectEffects").AddComponent <AIESwitchState>();

            wanderDetectEffects.ToState          = susState;
            wanderDetectEffects.transform.parent = wanderDetection.transform;
            wanderDetection.DetectEffectsTrans   = wanderDetectEffects.transform;

            //setup 2 - Suspicious

            susState.SpeedModif         = this.Suspicious_Speed;
            susState.SuspiciousDuration = this.Suspicious_Duration;
            susState.Range     = this.Suspicious_Range;
            susState.WanderFar = this.CanWanderFar;
            susState.TurnModif = this.Suspicious_TurnModif;

            var susEnd = new GameObject("EndSuspiciousEffects").AddComponent <AIESwitchState>();

            susEnd.ToState = wanderState;
            var sheathe = susEnd.gameObject.AddComponent <AIESheathe>();

            sheathe.Sheathed                   = true;
            susEnd.transform.parent            = susState.transform;
            susState.EndSuspiciousEffectsTrans = susEnd.transform;

            var susDetection = new GameObject("Detection").AddComponent <AICEnemyDetection>();

            susDetection.transform.parent = susState.transform;
            var susDetectEffects = new GameObject("DetectEffects").AddComponent <AIESwitchState>();

            susDetectEffects.ToState          = combatState;
            susDetectEffects.transform.parent = susDetection.transform;
            susDetection.DetectEffectsTrans   = susDetectEffects.transform;
            var susSuspiciousEffects = new GameObject("SuspiciousEffects").AddComponent <AIESwitchState>();

            susSuspiciousEffects.ToState          = alertState;
            susSuspiciousEffects.transform.parent = susDetection.transform;
            susDetection.SuspiciousEffectsTrans   = susSuspiciousEffects.transform;

            // setup 3 - alert

            alertState.SpeedModif         = this.Suspicious_Speed;
            alertState.SuspiciousDuration = this.Suspicious_Duration;
            alertState.Range     = this.Suspicious_Range;
            alertState.WanderFar = this.CanWanderFar;
            alertState.TurnModif = this.Suspicious_TurnModif;

            var alertEnd = new GameObject("EndSuspiciousEffects").AddComponent <AIESwitchState>();

            alertEnd.ToState = susState;
            var alertsheathe = alertEnd.gameObject.AddComponent <AIESheathe>();

            alertsheathe.Sheathed                = true;
            alertEnd.transform.parent            = alertState.transform;
            alertState.EndSuspiciousEffectsTrans = alertEnd.transform;

            var alertDetection = new GameObject("Detection").AddComponent <AICEnemyDetection>();

            alertDetection.transform.parent = alertState.transform;
            var alertDetectEffects = new GameObject("DetectEffects").AddComponent <AIESwitchState>();

            alertDetectEffects.ToState          = combatState;
            alertDetectEffects.transform.parent = alertDetection.transform;
            alertDetection.DetectEffectsTrans   = alertDetectEffects.transform;

            // setup 4 - Combat

            combatState.ChargeTime = this.Combat_ChargeTime;
            combatState.TargetVulnerableChargeTimeMult = this.Combat_TargetVulnerableChargeModifier;
            combatState.ChargeAttackRangeMult          = this.Combat_ChargeAttackRangeMulti;
            combatState.ChargeAttackTimeToAttack       = this.Combat_ChargeTimeToAttack;
            combatState.ChargeStartRangeMult           = this.Combat_ChargeStartRangeMult;
            combatState.AttackPatterns   = this.Combat_AttackPatterns;
            combatState.SpeedModifs      = this.Combat_SpeedModifiers;
            combatState.ChanceToAttack   = this.Combat_ChanceToAttack;
            combatState.KnowsUnblockable = this.Combat_KnowsUnblockable;
            combatState.DodgeCooldown    = this.Combat_DodgeCooldown;
            combatState.CanBlock         = this.CanBlock;
            combatState.CanDodge         = this.CanDodge;

            var combatDetect = new GameObject("Detection").AddComponent <AICEnemyDetection>();

            combatDetect.transform.parent = combatState.transform;
            var combatEnd = new GameObject("EndCombatEffects").AddComponent <AIESwitchState>();

            combatEnd.ToState          = wanderState;
            combatEnd.transform.parent = combatState.transform;

            // add required components for AIs (no setup required)
            character.gameObject.AddComponent <NavMeshAgent>();
            character.gameObject.AddComponent <AISquadMember>();
            character.gameObject.AddComponent <EditorCharacterAILoadAI>();

            if (character.GetComponent <NavMeshObstacle>() is NavMeshObstacle navObstacle)
            {
                GameObject.Destroy(navObstacle);
            }

            // add our basic AIStatesPrefab to a CharacterAI component. This is the prefab set up by SetupBasicAIPrefab(), below.
            CharacterAI charAI = character.gameObject.AddComponent <CharacterAI>();

            At.SetField(charAI, "m_character", character);
            charAI.AIStatesPrefab = aiRootPrefab;

            // initialize the AI States (not entirely necessary, but helpful if we want to do something with the AI immediately after)
            At.Invoke(charAI, "GetAIStates", null);
        }