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); } } }
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); }
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; } } }
public void ApplyToItemFilter(ItemFilter component) { component.MatchOnEmpty = this.MatchOnEmpty; At.SetField(component, "m_equipmentTypes", this.EquipmentTypes); At.SetField(component, "m_tagTypeFilters", this.TagTypes); }
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); } }
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); }
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()); } }
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; } }
// 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); } }
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); }
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); }