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); }
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(); }
// 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"); } }
//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... } }
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); }
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(); } }
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)); } } }
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(); } }
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(), }); }
// 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); }
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"); }
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); } }
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(); }