protected internal void LateApplyStatusEffects(StatusEffect status)
        {
            if (!string.IsNullOrEmpty(this.ComplicationStatusIdentifier))
            {
                var complicStatus = ResourcesPrefabManager.Instance.GetStatusEffectPrefab(this.ComplicationStatusIdentifier);
                if (complicStatus)
                {
                    status.ComplicationStatus = complicStatus;
                }
            }

            if (!string.IsNullOrEmpty(RequiredStatusIdentifier))
            {
                var required = ResourcesPrefabManager.Instance.GetStatusEffectPrefab(this.RequiredStatusIdentifier);
                if (required)
                {
                    status.RequiredStatus = required;
                }
            }

            if (!string.IsNullOrEmpty(this.AmplifiedStatusIdentifier))
            {
                var amp = ResourcesPrefabManager.Instance.GetStatusEffectPrefab(AmplifiedStatusIdentifier);
                if (amp)
                {
                    At.SetField(status, "m_amplifiedStatus", amp);
                }
                else
                {
                    SL.Log("StatusEffect.ApplyTemplate - could not find AmplifiedStatusIdentifier " + this.AmplifiedStatusIdentifier);
                }
            }

            // setup signature and finalize

            if (EffectBehaviour == EditBehaviours.Destroy)
            {
                UnityHelpers.DestroyChildren(status.transform);
            }

            Transform signature;

            if (status.transform.childCount < 1)
            {
                signature        = new GameObject($"SIGNATURE_{status.IdentifierName}").transform;
                signature.parent = status.transform;
                var comp = signature.gameObject.AddComponent <EffectSignature>();
                comp.SignatureUID = new UID($"{NewStatusID}_{status.IdentifierName}");
            }
            else
            {
                signature = status.transform.GetChild(0);
            }

            if (Effects != null)
            {
                if (signature)
                {
                    SL_EffectTransform.ApplyTransformList(signature, Effects, EffectBehaviour);
                }
                else
                {
                    SL.Log("Could not get effect signature!");
                }
            }

            // fix StatusData for the new effects
            CompileEffectsToData(status);

            var sigComp = signature.GetComponent <EffectSignature>();

            sigComp.enabled = true;

            var effects = signature.GetComponentsInChildren <Effect>();

            sigComp.Effects = effects.ToList();

            // Fix the effect signature for reference families
            if (status.FamilyMode == StatusEffect.FamilyModes.Reference)
            {
                signature.transform.parent = SL.CloneHolder;

                var family = status.EffectFamily;
                family.EffectSignature            = sigComp;
                status.StatusData.EffectSignature = sigComp;
            }

            // Need to reset description after changing effects.
            At.Invoke(status, "RefreshLoc");
        }
        public static StatusData.EffectData[] GenerateEffectsData(List <Effect> effects, int level = 1)
        {
            // Create a list to generate the EffectData[] array into.
            var list = new List <StatusData.EffectData>();

            // Iterate over the effects
            foreach (var effect in effects)
            {
                // Create a blank holder, in the case this effect isn't supported or doesn't serialize anything.
                var data = new StatusData.EffectData()
                {
                    Data = new string[] { "" }
                };

                var type = effect.GetType();

                if (typeof(PunctualDamage).IsAssignableFrom(type))
                {
                    var comp = effect as PunctualDamage;

                    // For PunctualDamage, Data[0] is the entire damage, and Data[1] is the impact.

                    // Each damage goes "Damage : Type", and separated by a ';' char.
                    // So we just iterate over the damage and serialize like that.
                    var dmgString = "";
                    foreach (var dmg in comp.Damages)
                    {
                        if (dmgString != "")
                        {
                            dmgString += ";";
                        }

                        dmgString += $"{dmg.Damage * level}:{dmg.Type}";
                    }

                    // finally, set data
                    data.Data = new string[]
                    {
                        dmgString,
                        comp.Knockback.ToString()
                    };
                }
                else if (typeof(AffectNeed).IsAssignableFrom(type))
                {
                    var fi = At.GetFieldInfo(typeof(AffectNeed), "m_affectQuantity");
                    data.Data = new string[]
                    {
                        ((float)fi.GetValue(effect) * level).ToString()
                    };
                }
                // For most AffectStat components, the only thing that is serialized is the AffectQuantity.
                else if (At.GetFieldInfo(type, "AffectQuantity") is FieldInfo fi_AffectQuantity)
                {
                    data.Data = new string[]
                    {
                        ((float)fi_AffectQuantity.GetValue(effect) * level).ToString()
                    };
                }
                // AffectMana uses "Value" instead of AffectQuantity for some reason...
                else if (At.GetFieldInfo(type, "Value") is FieldInfo fi_Value)
                {
                    data.Data = new string[]
                    {
                        ((float)fi_Value.GetValue(effect) * level).ToString()
                    };
                }
                else // otherwise maybe I need to add support for this effect...
                {
                    //SL.Log("[StatusEffect] Unsupported effect: " + type, 1);
                }

                list.Add(data);
            }

            return(list.ToArray());
        }
Example #3
0
        public virtual void SetStats(Character character)
        {
            if (character.GetComponent <PlayerCharacterStats>())
            {
                CustomCharacters.FixStats(character);
            }

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

            if (!stats)
            {
                return;
            }

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

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

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

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

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

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

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

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

                At.SetField(stats, "m_statusEffectsNaturalImmunity", immunities.ToArray());
            }
        }
        internal virtual void Internal_ApplyTemplate(StatusEffect status)
        {
            SL.Log("Applying Status Effect template: " + Name ?? status.name);

            SLPackManager.AddLateApplyListener(OnLateApply, status);

            CustomStatusEffects.SetStatusLocalization(status, Name, Description);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                    status.OverrideIcon = sprite;
                    At.SetField(status, "m_defaultStatusIcon", new StatusTypeIcon(Tag.None)
                    {
                        Icon = sprite
                    });
                }
            }
        }
Example #5
0
        public override void ApplyToItem(Item item)
        {
            base.ApplyToItem(item);

            var comp = item as ItemContainer;

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

            if (this.SpecialType != null)
            {
                comp.SpecialType = (ItemContainer.SpecialContainerTypes) this.SpecialType;
            }

            if (this.OpenSound != null)
            {
                comp.OpenSoundOverride = (GlobalAudioManager.Sounds) this.OpenSound;
            }

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

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

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

            if (this.CanRemoveItems != null)
            {
                At.SetField(comp, "m_canRemoveItems", (bool)this.CanRemoveItems);
            }

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

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

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

            if (this.ItemFilter != null)
            {
                ItemFilter filterComp = comp.gameObject.GetOrAddComponent <ItemFilter>();
                ItemFilter.ApplyToItemFilter(filterComp);
            }
        }
        public void SetWeaponStats(CustomWeapon template)
        {
            if (ResourcesPrefabManager.Instance.GetItemPrefab(template.New_ItemID) is Item item)
            {
                WeaponStats stats = (item as Weapon).Stats;

                // equipment stats (which weapons can actually use and display)
                At.SetValue(template.DamageBonuses, typeof(EquipmentStats), stats as EquipmentStats, "m_damageAttack");
                At.SetValue(template.ManaUseModifier, typeof(EquipmentStats), stats as EquipmentStats, "m_manaUseModifier");

                // set base weapon stats
                stats.BaseDamage  = template.BaseDamage;
                stats.Impact      = template.Impact;
                stats.AttackSpeed = template.AttackSpeed;

                // set attack steps
                for (int i = 0; i < stats.Attacks.Count(); i++)
                {
                    var step = stats.Attacks[i];

                    List <float> newDamage = new List <float>();
                    foreach (DamageType type in template.BaseDamage.List)
                    {
                        newDamage.Add(type.Damage);
                    }
                    float newImpact = template.Impact;
                    StatHelpers.SetScaledDamages((item as Weapon).Type, i, ref newDamage, ref newImpact);

                    step.Damage    = newDamage;
                    step.Knockback = newImpact;
                }

                // =========== hit effects =============

                // remove existing hit effects
                if (item.transform.Find("HitEffects") is Transform t)
                {
                    t.transform.parent = null;
                    DestroyImmediate(t.gameObject);
                }
                // make new hit effects
                GameObject hiteffects = new GameObject("HitEffects");
                hiteffects.transform.parent = item.transform;
                foreach (string effect in template.hitEffects)
                {
                    if (string.IsNullOrEmpty(effect))
                    {
                        continue;
                    }

                    if (ResourcesPrefabManager.Instance.GetStatusEffectPrefab(effect) is StatusEffect status)
                    {
                        hiteffects.AddComponent(new AddStatusEffectBuildUp
                        {
                            Status       = status,
                            BuildUpValue = 60.0f,
                        });
                    }
                }
            }
        }
        public static void SetItemTags(Item item, string[] tags, bool destroyExisting)
        {
            var tagsource = CustomTags.SetTagSource(item.gameObject, tags, destroyExisting);

            At.SetField(item, "m_tagSource", tagsource);
        }
        /// <summary>
        /// Use this to create or modify an Imbue Effect status.
        /// </summary>
        /// <param name="template">The SL_ImbueEffect Template for this imbue.</param>
        public static ImbueEffectPreset CreateCustomImbue(SL_ImbueEffect template)
        {
            var original = (ImbueEffectPreset)GetOrigEffectPreset(template.TargetStatusID);

            if (!original)
            {
                SL.LogError("Could not find an ImbueEffectPreset with the Preset ID " + template.TargetStatusID);
                return(null);
            }

            ImbueEffectPreset newEffect;

            if (template.TargetStatusID == template.NewStatusID)
            {
                if (!OrigEffectPresets.ContainsKey(template.TargetStatusID))
                {
                    // instantiate and cache original
                    var cached = GameObject.Instantiate(original.gameObject).GetComponent <EffectPreset>();
                    cached.gameObject.SetActive(false);
                    GameObject.DontDestroyOnLoad(cached.gameObject);
                    OrigEffectPresets.Add(template.TargetStatusID, cached);
                }

                newEffect = original;
            }
            else
            {
                // instantiate original and use that as newEffect
                newEffect = GameObject.Instantiate(original.gameObject).GetComponent <ImbueEffectPreset>();
                newEffect.gameObject.SetActive(false);

                // Set Preset ID
                At.SetField <EffectPreset>(newEffect, "m_StatusEffectID", template.NewStatusID);

                // Fix localization
                GetImbueLocalization(original, out string name, out string desc);
                SetImbueLocalization(newEffect, name, desc);
            }

            newEffect.gameObject.name = template.NewStatusID + "_" + (template.Name ?? newEffect.Name);

            // fix RPM_Presets dictionary
            if (!References.RPM_EFFECT_PRESETS.ContainsKey(template.NewStatusID))
            {
                References.RPM_EFFECT_PRESETS.Add(template.NewStatusID, newEffect.GetComponent <EffectPreset>());
            }
            else
            {
                References.RPM_EFFECT_PRESETS[template.NewStatusID] = newEffect;
            }

            // Always do this
            GameObject.DontDestroyOnLoad(newEffect.gameObject);

            //// Apply template
            //if (SL.PacksLoaded)
            //    template.ApplyTemplate();
            //else
            //    SL.INTERNAL_ApplyStatuses += template.ApplyTemplate;

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

            var eStats = stats as EquipmentStats;

            if (this.Damage_Resistance != null)
            {
                At.SetField(eStats, "m_damageResistance", this.Damage_Resistance);
            }

            if (this.Impact_Resistance != null)
            {
                At.SetField(eStats, "m_impactResistance", (float)this.Impact_Resistance);
            }

            if (this.Damage_Protection != null)
            {
                At.SetField(eStats, "m_damageProtection", new float[9] {
                    (float)this.Damage_Protection, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f
                });
            }

            if (this.Damage_Bonus != null)
            {
                At.SetField(eStats, "m_damageAttack", this.Damage_Bonus);
            }

            if (this.Impact_Bonus != null)
            {
                At.SetField(eStats, "m_baseImpactModifier", this.Impact_Bonus);
            }

            if (this.Stamina_Use_Penalty != null)
            {
                At.SetField(eStats, "m_staminaUsePenalty", (float)this.Stamina_Use_Penalty);
            }

            if (this.Mana_Use_Modifier != null)
            {
                At.SetField(eStats, "m_manaUseModifier", (float)this.Mana_Use_Modifier);
            }

            if (this.Mana_Regen != null)
            {
                At.SetField(eStats, "m_baseManaRegenBonus", (float)this.Mana_Regen);
            }

            if (this.Movement_Penalty != null)
            {
                At.SetField(eStats, "m_movementPenalty", (float)this.Movement_Penalty);
            }

            if (this.Pouch_Bonus != null)
            {
                At.SetField(eStats, "m_pouchCapacityBonus", (float)this.Pouch_Bonus);
            }

            if (this.Heat_Protection != null)
            {
                At.SetField(eStats, "m_heatProtection", (float)this.Heat_Protection);
            }

            if (this.Cold_Protection != null)
            {
                At.SetField(eStats, "m_coldProtection", (float)this.Cold_Protection);
            }

            if (this.Corruption_Protection != null)
            {
                At.SetField(eStats, "m_corruptionProtection", (float)this.Corruption_Protection);
            }

            if (this.Cooldown_Reduction != null)
            {
                At.SetField(eStats, "m_baseCooldownReductionBonus", (float)this.Cooldown_Reduction);
            }

            if (this.Health_Regen != null)
            {
                At.SetField(eStats, "m_baseHealthRegenBonus", (float)this.Health_Regen);
            }

            if (this.BarrierProtection != null)
            {
                At.SetField(eStats, "m_baseBarrierProtection", (float)this.BarrierProtection);
            }

            if (this.GlobalStatusEffectResistance != null)
            {
                At.SetField(eStats, "m_baseStatusEffectResistance", (float)this.GlobalStatusEffectResistance);
            }

            if (this.StaminaRegenModifier != null)
            {
                At.SetField(eStats, "m_baseStaminaRegen", this.StaminaRegenModifier);
            }
        }
        internal void Internal_ApplyTemplate()
        {
            SL.Log($"Applying Enchantment Recipe, ID: {this.EnchantmentID}, Name: {this.Name}");

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

            recipe.RecipeID = this.EnchantmentID;
            recipe.ResultID = this.EnchantmentID;

            if (ResourcesPrefabManager.Instance.GetItemPrefab(this.IncenseItemID) is Item incense)
            {
                var list = new List <EnchantmentRecipe.PillarData>();
                foreach (var pillar in this.PillarDatas)
                {
                    list.Add(new EnchantmentRecipe.PillarData
                    {
                        Direction             = (UICardinalPoint_v2.CardinalPoint)pillar.Direction,
                        IsFar                 = pillar.IsFar,
                        CompatibleIngredients = new EnchantmentRecipe.IngredientData[]
                        {
                            new EnchantmentRecipe.IngredientData
                            {
                                Type = EnchantmentRecipe.IngredientData.IngredientType.Specific,
                                SpecificIngredient = incense
                            }
                        }
                    });
                }
                recipe.PillarDatas = list.ToArray();
            }

            recipe.CompatibleEquipments = new EnchantmentRecipe.EquipmentData
            {
                EquipmentTag = new TagSourceSelector(CustomTags.GetTag(this.CompatibleEquipment.RequiredTag)),
            };
            if (this.CompatibleEquipment.Equipments != null)
            {
                var equipList = new List <EnchantmentRecipe.IngredientData>();
                foreach (var ingData in this.CompatibleEquipment.Equipments)
                {
                    var data = new EnchantmentRecipe.IngredientData();
                    if (ingData.SelectorType == IngredientTypes.Tag)
                    {
                        data.Type          = EnchantmentRecipe.IngredientData.IngredientType.Generic;
                        data.IngredientTag = new TagSourceSelector(CustomTags.GetTag(ingData.SelectorValue));
                    }
                    else if (ingData.SelectorType == IngredientTypes.SpecificItem)
                    {
                        data.Type = EnchantmentRecipe.IngredientData.IngredientType.Specific;
                        data.SpecificIngredient = ResourcesPrefabManager.Instance.GetItemPrefab(ingData.SelectorValue);
                    }
                    equipList.Add(data);
                }
                recipe.CompatibleEquipments.CompatibleEquipments = equipList.ToArray();
            }
            else
            {
                recipe.CompatibleEquipments.CompatibleEquipments = new EnchantmentRecipe.IngredientData[0];
            }

            recipe.TimeOfDay          = this.TimeOfDay ?? new Vector2[0];
            recipe.Region             = this.Areas ?? new AreaManager.AreaEnum[0];
            recipe.Temperature        = this.Temperature ?? new TemperatureSteps[0];
            recipe.WindAltarActivated = this.WindAltarActivated;

            if (!string.IsNullOrEmpty(this.QuestEventUID))
            {
                recipe.QuestEvent = new QuestEventReference()
                {
                    m_eventUID = QuestEventUID, UID = QuestEventUID
                };
            }

            if (this.WeatherConditions != null)
            {
                var list = new List <EnchantmentRecipe.WeaterCondition>();
                foreach (var condition in this.WeatherConditions)
                {
                    list.Add(new EnchantmentRecipe.WeaterCondition
                    {
                        Invert  = condition.Invert,
                        Weather = (EnchantmentRecipe.WeaterType)condition.WeatherType
                    });
                }
                recipe.Weather = list.ToArray();
            }
            else
            {
                recipe.Weather = new EnchantmentRecipe.WeaterCondition[0];
            }

            recipe.TableIsInBuilding = this.IsEnchantingGuildRecipe;

            // ========== Create actual Enchantment effects prefab ==========

            var enchantmentObject = new GameObject(this.EnchantmentID + "_" + this.Name);

            GameObject.DontDestroyOnLoad(enchantmentObject);
            var enchantment = enchantmentObject.AddComponent <Enchantment>();

            At.SetField <EffectPreset>(enchantment, "m_StatusEffectID", this.EnchantmentID);

            SetLocalization(this, out enchantment.CustomDescLocKey);

            enchantment.EnchantTime = this.EnchantTime;

            if (this.Effects != null)
            {
                SL_EffectTransform.ApplyTransformList(enchantment.transform, this.Effects?.ToArray(), EditBehaviours.Override);
            }

            if (this.AddedDamages != null)
            {
                var list = new List <Enchantment.AdditionalDamage>();
                foreach (var dmg in this.AddedDamages)
                {
                    list.Add(new Enchantment.AdditionalDamage
                    {
                        BonusDamageType  = dmg.AddedDamageType,
                        ConversionRatio  = dmg.ConversionRatio,
                        SourceDamageType = dmg.SourceDamageType
                    });
                }
                enchantment.AdditionalDamages = list.ToArray();
            }
            if (this.StatModifications != null)
            {
                var list = new Enchantment.StatModificationList();
                foreach (var mod in this.StatModifications)
                {
                    list.Add(new Enchantment.StatModification
                    {
                        Name  = mod.Stat,
                        Type  = mod.Type,
                        Value = mod.Value
                    });
                }
                enchantment.StatModifications = list;
            }
            if (this.FlatDamageAdded != null)
            {
                enchantment.DamageBonus = SL_Damage.GetDamageList(this.FlatDamageAdded);
            }
            if (this.DamageModifierBonus != null)
            {
                enchantment.DamageModifier = SL_Damage.GetDamageList(this.DamageModifierBonus);
            }
            if (this.DamageResistanceBonus != null)
            {
                enchantment.ElementalResistances = SL_Damage.GetDamageList(this.DamageResistanceBonus);
            }

            enchantment.HealthAbsorbRatio  = this.HealthAbsorbRatio;
            enchantment.StaminaAbsorbRatio = this.StaminaAbsorbRatio;
            enchantment.ManaAbsorbRatio    = this.ManaAbsorbRatio;

            enchantment.Indestructible   = this.Indestructible;
            enchantment.TrackDamageRatio = this.TrackDamageRatio;

            enchantment.GlobalStatusResistance = this.GlobalStatusResistance;

            // =========== SET DICTIONARY REFS ============

            // Recipe dict
            if (References.ENCHANTMENT_RECIPES.ContainsKey(this.EnchantmentID))
            {
                References.ENCHANTMENT_RECIPES[this.EnchantmentID] = recipe;
            }
            else
            {
                References.ENCHANTMENT_RECIPES.Add(this.EnchantmentID, recipe);
            }

            // Enchantment dict
            if (References.ENCHANTMENT_PREFABS.ContainsKey(this.EnchantmentID))
            {
                References.ENCHANTMENT_PREFABS[this.EnchantmentID] = enchantment;
            }
            else
            {
                References.ENCHANTMENT_PREFABS.Add(this.EnchantmentID, enchantment);
            }
        }
Example #11
0
        public IEnumerator ReplaceActiveAssets()
        {
            SideLoader.Log("Replacing Materials..");
            float start = Time.time;

            // ============ materials ============
            var list = Resources.FindObjectsOfTypeAll <Material>()
                       .Where(x => x.mainTexture != null && SL.Instance.TextureData.ContainsKey(x.mainTexture.name))
                       .ToList();

            SideLoader.Log(string.Format("Found {0} materials to replace.", list.Count));

            int i = 0;

            foreach (Material m in list)
            {
                string name = m.mainTexture.name;
                i++; SideLoader.Log(string.Format(" - Replacing material {0} of {1}: {2}", i, list.Count, name));

                // set maintexture (diffuse map)
                m.mainTexture = SL.Instance.TextureData[name];

                // ======= set other shader material layers =======
                if (name.EndsWith("_d"))
                {
                    name = name.Substring(0, name.Length - 2);
                }                                                                       // try remove the _d suffix, if its there

                // check each shader material suffix name
                foreach (KeyValuePair <string, string> entry in TextureSuffixes)
                {
                    if (entry.Key == "_d")
                    {
                        continue;
                    }                                    // already set MainTex

                    if (SL.Instance.TextureData.ContainsKey(name + entry.Key))
                    {
                        SideLoader.Log(" - Setting " + entry.Value + " for " + m.name);
                        m.SetTexture(entry.Value, SL.Instance.TextureData[name + entry.Key]);
                    }
                }

                yield return(null);
            }

            // ========= sprites =========

            SideLoader.Log("Replacing PrefabManager icons...");
            if (At.GetValue(typeof(ResourcesPrefabManager), null, "ITEM_PREFABS") is Dictionary <string, Item> dict)
            {
                foreach (Item item in dict.Values
                         .Where(x =>
                                x.ItemID > 2000000 &&
                                x.ItemIcon != null &&
                                x.ItemIcon.texture != null &&
                                SL.Instance.TextureData.ContainsKey(x.ItemIcon.texture.name)))
                {
                    string name = item.ItemIcon.texture.name;
                    SideLoader.Log(string.Format(" - Replacing item icon: {0}", name));

                    var tex    = SL.Instance.TextureData[name];
                    var sprite = CreateSprite(tex);
                    At.SetValue(sprite, typeof(Item), item, "m_itemIcon");
                }
            }

            // ==============================================

            SideLoader.Log("Active assets replaced. Time: " + (Time.time - start), 0);
            SL.Instance.Loading = false;
        }
        public override void ApplyToComponent <T>(T component)
        {
            var comp = component as Sleepable;

            if (!string.IsNullOrEmpty(this.RestStatusIdentifier))
            {
                var status = ResourcesPrefabManager.Instance.GetStatusEffectPrefab(this.RestStatusIdentifier);
                if (status)
                {
                    At.SetField(comp, "m_restEffect", status);
                }
            }

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

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

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

            if (this.CharAnimOffset != null)
            {
                comp.CharAnimOffset = (Vector3)this.CharAnimOffset;
            }

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

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

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

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

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

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

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

            if (this.StaminaRecuperationModifier != null)
            {
                comp.StaminaRecuperationModifier = (int)this.StaminaRecuperationModifier;
            }
        }
Example #13
0
        public static IEnumerator SetVisuals(Character character, string visualData)
        {
            var visuals = character.GetComponentInChildren <CharacterVisuals>(true);

            var newData = CharacterVisualData.CreateFromNetworkData(visualData);

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

            float start = Time.time;

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

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

            yield return(new WaitForSeconds(0.5f));

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

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

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

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

                var presets = CharacterManager.CharacterVisualsPresets;

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

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

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

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

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

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

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

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

            this.MaxLevel = (int)At.GetField(status as LevelStatusEffect, "m_maxLevel");
        }
        /// <summary>
        /// Use this to create or modify a Status Effect.
        /// </summary>
        /// <param name="template">The SL_StatusEffect template.</param>
        /// <returns>The new or existing StatusEffect.</returns>
        public static StatusEffect CreateCustomStatus(SL_StatusEffect template)
        {
            var original = ResourcesPrefabManager.Instance.GetStatusEffectPrefab(template.TargetStatusIdentifier);

            if (!original)
            {
                SL.Log($"CreateCustomStatus - Could not find any status with the Identifier '{template.TargetStatusIdentifier}' (or none was set).");
                return(null);
            }

            var preset = original.GetComponent <EffectPreset>();

            if (!preset && template.NewStatusID < -1 || template.NewStatusID > 0)
            {
                preset = original.gameObject.AddComponent <EffectPreset>();
                At.SetField(preset, "m_StatusEffectID", template.NewStatusID);
            }

            StatusEffect status;

            if (template.TargetStatusIdentifier == template.StatusIdentifier)
            {
                // editing orig status
                if (!OrigStatusEffects.ContainsKey(template.TargetStatusIdentifier))
                {
                    // instantiate and cache original
                    var cached = GameObject.Instantiate(original.gameObject).GetComponent <StatusEffect>();
                    cached.gameObject.SetActive(false);
                    GameObject.DontDestroyOnLoad(cached.gameObject);
                    OrigStatusEffects.Add(template.TargetStatusIdentifier, cached);
                }

                status = original;
            }
            else
            {
                // instantiate original and use that as newEffect
                status = GameObject.Instantiate(original.gameObject).GetComponent <StatusEffect>();
                status.gameObject.SetActive(false);

                // Set Status identifier
                At.SetField(status, "m_identifierName", template.StatusIdentifier);

                if (preset && (template.NewStatusID < -1 || template.NewStatusID > 0))
                {
                    At.SetField(preset, "m_StatusEffectID", template.NewStatusID);
                }

                // Fix localization
                GetStatusLocalization(original, out string name, out string desc);
                SetStatusLocalization(status, name, desc);

                // Fix status data and stack
                At.SetField(status, "m_statusStack", null);
                At.SetField(status, "m_amplifiedStatus", null);
            }

            var gameType = Serializer.GetGameType(template.GetType());

            if (gameType != status.GetType())
            {
                status = (StatusEffect)UnityHelpers.FixComponentType(gameType, status);
            }

            int presetID = status.GetComponent <EffectPreset>()?.PresetID ?? -1;
            var id       = "";

            if (presetID < -1 || presetID > 0)
            {
                id += presetID + "_";
            }
            status.gameObject.name = id + status.IdentifierName;

            // fix RPM_STATUS_EFFECTS dictionary
            if (!References.RPM_STATUS_EFFECTS.ContainsKey(status.IdentifierName))
            {
                References.RPM_STATUS_EFFECTS.Add(status.IdentifierName, status);
            }
            else
            {
                References.RPM_STATUS_EFFECTS[status.IdentifierName] = status;
            }

            // fix RPM_Presets dictionary
            if (template.NewStatusID < -1 || template.NewStatusID > 0)
            {
                if (!References.RPM_EFFECT_PRESETS.ContainsKey(template.NewStatusID))
                {
                    References.RPM_EFFECT_PRESETS.Add(template.NewStatusID, status.GetComponent <EffectPreset>());
                }
                else
                {
                    References.RPM_EFFECT_PRESETS[template.NewStatusID] = status.GetComponent <EffectPreset>();
                }
            }

            // Always do this
            GameObject.DontDestroyOnLoad(status.gameObject);

            return(status);
        }
Example #19
0
        internal void Internal_ApplyRecipe()
        {
            try
            {
                SL.Log("Defining recipe UID: " + this.UID);

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

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

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

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

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

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

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

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

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

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

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

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

                recipe.SetCraftingType(this.StationType);

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

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

                recipe.Init();

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

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

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

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

                m_applied = true;
            }
            catch (Exception e)
            {
                SL.LogWarning("Error applying recipe!");
                SL.LogInnerException(e);
            }
        }
Example #20
0
        public void SetItemIcon(Item item, Texture2D icon)
        {
            var sprite = TexReplacer.CreateSprite(icon);

            At.SetValue(sprite, typeof(Item), item, "m_itemIcon");
        }
Example #21
0
        /// <summary>
        /// Apply the SL_ItemVisual prefab to the Item.
        /// </summary>
        /// <param name="item">The Item to set to.</param>
        public void ApplyToItem(Item item)
        {
            if (CustomItemVisuals.GetOrigItemVisuals(item, Type) is Transform origPrefab)
            {
                bool setPrefab = false;

                // Check for AssetBundle Prefabs first
                if (!string.IsNullOrEmpty(Prefab_SLPack) && SL.GetSLPack(Prefab_SLPack) is SLPack pack)
                {
                    if (pack.AssetBundles.ContainsKey(Prefab_AssetBundle))
                    {
                        var newVisuals = pack.AssetBundles[Prefab_AssetBundle].LoadAsset <GameObject>(Prefab_Name);

                        origPrefab = SetCustomVisualPrefab(item, this.Type, newVisuals.transform, origPrefab).transform;

                        SL.Log("Loaded custom visual prefab: " + newVisuals.name);
                        setPrefab = true;
                    }
                }
                // Not using AssetBundle, check for ResourcesPrefabPath.
                else if (!string.IsNullOrEmpty(ResourcesPrefabPath))
                {
                    // Only set this if the user has defined a different value than what exists on the item.
                    bool set = false;
                    switch (Type)
                    {
                    case VisualPrefabType.VisualPrefab:
                        set = item.VisualPrefabPath == ResourcesPrefabPath; break;

                    case VisualPrefabType.SpecialVisualPrefabDefault:
                        set = item.SpecialVisualPrefabDefaultPath == ResourcesPrefabPath; break;

                    case VisualPrefabType.SpecialVisualPrefabFemale:
                        set = item.SpecialVisualPrefabFemalePath == ResourcesPrefabPath; break;
                    }

                    if (!set)
                    {
                        // Get the original visual prefab to clone from
                        var orig = ResourcesPrefabManager.Instance.GetItemVisualPrefab(ResourcesPrefabPath);

                        if (!orig)
                        {
                            SL.Log("SL_ItemVisual: Could not find an Item Visual at the Resources path: " + ResourcesPrefabPath);
                        }
                        else
                        {
                            CustomItemVisuals.CloneAndSetVisuals(item, orig.gameObject, Type);

                            switch (Type)
                            {
                            case VisualPrefabType.VisualPrefab:
                                At.SetField(item, "m_visualPrefabPath", ResourcesPrefabPath); break;

                            case VisualPrefabType.SpecialVisualPrefabDefault:
                                At.SetField(item, "m_specialVisualPrefabDefaultPath", ResourcesPrefabPath); break;

                            case VisualPrefabType.SpecialVisualPrefabFemale:
                                At.SetField(item, "m_specialVisualPrefabFemalePath", ResourcesPrefabPath); break;
                            }

                            setPrefab = true;
                        }
                    }
                }

                // If we didn't change the Visual Prefab in any way, clone the original to avoid conflicts.
                if (!setPrefab)
                {
                    origPrefab = CustomItemVisuals.CloneVisualPrefab(item, Type).transform;
                }

                // Get the actual visuals (for weapons and a lot of items, this is not the base prefab).
                Transform actualVisuals = origPrefab.transform;
                if (this.Type == VisualPrefabType.VisualPrefab)
                {
                    if (origPrefab.childCount > 0)
                    {
                        foreach (Transform child in origPrefab)
                        {
                            if (child.gameObject.activeSelf && child.GetComponent <BoxCollider>() && child.GetComponent <MeshRenderer>())
                            {
                                actualVisuals = child;
                                break;
                            }
                        }
                    }
                }

                if (actualVisuals)
                {
                    var visualComp = origPrefab.GetComponent <ItemVisual>();

                    ApplyItemVisualSettings(visualComp, actualVisuals);
                }
            }
        }
        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);
        }
Example #23
0
        // ~~~~~~~~~~~~~~~~ Tempate applying ~~~~~~~~~~~~~~~~

        public virtual void ApplyToCharacter(Character character, bool loadingFromSave)
        {
            SL.Log("Applying SL_Character template, template UID: " + this.UID + ", char UID: " + character.UID);

            character.NonSavable = true;

            // set name
            if (Name != null)
            {
                At.SetField(character, "m_nameLocKey", "");
                At.SetField(character, "m_name", Name);
            }

            // set scale
            character.transform.localScale = this.Scale;

            // set starting pose
            if (!PhotonNetwork.isNonMasterClientInRoom)
            {
                SLPlugin.Instance.StartCoroutine(DelayedSetPose(character));
            }

            // if host
            if (!PhotonNetwork.isNonMasterClientInRoom)
            {
                character.OnDeath += () => { OnDeath(character); };

                // set faction
                if (Faction != null)
                {
                    character.ChangeFaction((Character.Factions)Faction);
                }

                if (!loadingFromSave)
                {
                    SetItems(character);
                }
            }

            // AI
            if (this.AI != null)
            {
                //SL.Log("SL_Character AI is " + this.AI.GetType().FullName + ", applying...");
                this.AI.Apply(character);
            }

            // stats
            SetStats(character);

            if (this.AI is SL_CharacterAIMelee aiMelee && aiMelee.ForceNonCombat)
            {
                this.TargetableFactions = new Character.Factions[0];
            }

            if (this.TargetableFactions != null)
            {
                var targeting = character.GetComponent <TargetingSystem>();
                if (targeting)
                {
                    targeting.TargetableFactions = this.TargetableFactions;
                }
                else
                {
                    SL.LogWarning("SL_Character: Could not get TargetingSystem component!");
                }
            }

            // loot/death
            if (LootableOnDeath)
            {
                var lootable = character.gameObject.AddComponent <LootableOnDeath>();
                lootable.DropWeapons  = this.DropWeapons;
                lootable.EnabledPouch = this.DropPouchContents;

                At.SetField(lootable, "m_character", character);

                // todo droptables
                lootable.SkinDrops = new DropInstance[0];
                lootable.LootDrops = new DropInstance[0];
            }

            character.gameObject.SetActive(true);
        }