예제 #1
0
        public void Start()
        {
            slider = GetComponent <Slider>();
            slider.onValueChanged.AddListener(SliderChanged);

            value = statCog.FindStat(valueName);
            if (value == null)
            {
                Debug.LogError(name + ".StatSlider could not find stat '" + valueName + "'");
                enabled = false;
                return;
            }
            value.onValueChanged.AddListener(UpdateStat);

            min = statCog.FindStat(minName);
            if (min)
            {
                min.onMinValueChanged.AddListener(UpdateStat);
            }

            max = statCog.FindStat(maxName);
            if (max)
            {
                max.onMaxValueChanged.AddListener(UpdateStat);
            }

            UpdateStat(0, 0);
        }
예제 #2
0
        public void SetStatsCog(StatsCog statsCog)
        {
            ClearEffects();

            StatMonitorTMP[] monitors = GetComponentsInChildren <StatMonitorTMP>();
            for (int i = 0; i < monitors.Length; i++)
            {
                monitors[i].statsCog = statsCog;
            }

            EnemyInfoList[] infoLists = GetComponentsInChildren <EnemyInfoList>();
            for (int i = 0; i < infoLists.Length; i++)
            {
                infoLists[i].statsCog = statsCog;
            }

            foreach (StatEffect effect in statsCog.Effects)
            {
                Instantiate(effectPrefab, effectsContainer).SetEffect(effect);
            }

            StatValue info = statsCog.FindStat(infoStat);

            if (info != null)
            {
                enemySprite.sprite = info.icon;
                enemyName.text     = info.displayName;
            }

            // Subscribe to new effects
            statsCog.onEffectAdded.AddListener(AddEffect);
        }
예제 #3
0
 public void LoadStat(StatsCog statsCog, string statName)
 {
     StatsCog  = statsCog;
     StatValue = StatsCog.FindStat(statName);
     Subscribe();
     UpdateUI(0, 0);
 }
예제 #4
0
        /// <summary>
        /// Calculate the change in value when replacing one modifier with another
        /// </summary>
        /// <param name="original">Original Stat Modifier</param>
        /// <param name="replacement"></param>
        /// <returns></returns>
        public float GetModifierChange(StatModifier original, StatModifier replacement)
        {
            // Get stat
            StatValue stat = FindStat(original.affectedStat);

            return(stat.GetModifierChange(original, replacement));
        }
예제 #5
0
        public void Awake()
        {
            // Create new lists
            Stats       = new List <StatValue>();
            Effects     = new List <StatEffect>();
            deadEffects = new List <StatEffect>();

            // Update dealers
            UpdateDamageDealers();
            // Instance stats
            foreach (StatValue stat in stats)
            {
                StatValue instance = InstanceStatValue(stat);
                Stats.Add(instance);
            }

            // Initialize Stats
            foreach (StatValue stat in Stats)
            {
                stat.Initialize(this);
            }

            // Initailize Damage Modifiers
            foreach (DamageModifier modifer in damageModifiers)
            {
                modifer.Initialize(this);
            }

            // Initialize Starting Effects
            foreach (StatEffect effect in startingEffects)
            {
                AddEffect(effect);
            }
        }
예제 #6
0
        public float CalculateAppliedValue(StatValue stat)
        {
            if (effectType != EffectTypes.Instant)
            {
                switch (valueTarget)
                {
                case EffectValueTarget.MaximumValue:
                    return(GetSustainedValue(stat.CurrentMaximum, stat) - stat.CurrentMaximum);

                case EffectValueTarget.MinimumValue:
                    return(GetSustainedValue(stat.CurrentMinimum, stat) - stat.CurrentMinimum);

                case EffectValueTarget.RegenAmount:
                    return(GetSustainedValue(stat.CurrentRegenAmount, stat) - stat.CurrentRegenAmount);

                case EffectValueTarget.RegenDelay:
                    return(GetSustainedValue(stat.CurrentRegenDelay, stat) - stat.CurrentRegenDelay);

                case EffectValueTarget.Value:
                    if (valueType == EffectValueTypes.Add || valueType == EffectValueTypes.AddMultiplier)
                    {
                        return(Mathf.Clamp(GetSustainedValue(stat.CurrentValue, stat) - stat.CurrentValue, stat.CurrentMinimum, stat.CurrentMaximum));
                    }
                    else
                    {
                        return(GetSustainedValue(stat.CurrentValue, stat) - stat.CurrentValue);
                    }
                }
            }
            else
            {
                switch (valueTarget)
                {
                case EffectValueTarget.MaximumValue:
                    return(GetSustainedValue(stat.CurrentMaximum, stat));

                case EffectValueTarget.MinimumValue:
                    return(GetSustainedValue(stat.CurrentMinimum, stat));

                case EffectValueTarget.RegenAmount:
                    return(GetSustainedValue(stat.CurrentRegenAmount, stat));

                case EffectValueTarget.RegenDelay:
                    return(GetSustainedValue(stat.CurrentRegenDelay, stat));

                case EffectValueTarget.Value:
                    if (valueType == EffectValueTypes.Add || valueType == EffectValueTypes.AddMultiplier)
                    {
                        return(Mathf.Clamp(GetSustainedValue(stat.CurrentValue, stat) - stat.CurrentValue, stat.CurrentMinimum, stat.CurrentMaximum));
                    }
                    else
                    {
                        return(GetSustainedValue(stat.CurrentValue, stat) - stat.CurrentValue);
                    }
                }
            }

            return(0);
        }
        public void Start()
        {
            StatValue stat = statCog.FindStat(statName);

            if (stat == null)
            {
                return;
            }
            stat.onValueChanged.AddListener(StatChanged);
            StatChanged(0, 0);
        }
예제 #8
0
 public void OnEnable()
 {
     text = GetComponent <TextMeshProUGUI>();
     stat = statsCog.FindStat(statName);
     if (stat == null)
     {
         Debug.LogError(name + ".StatMonitorTMP could not find stat '" + statName + "'");
         enabled = false;
         return;
     }
     stat.onMaxValueChanged.AddListener(UpdateStat);
     stat.onMinValueChanged.AddListener(UpdateStat);
     stat.onValueChanged.AddListener(UpdateStat);
     UpdateStat(0, 0);
 }
예제 #9
0
        /// <summary>
        /// Get unchanging value of modifier
        /// </summary>
        /// <param name="statVal"></param>
        /// <param name="stat"></param>
        /// <returns></returns>
        private float GetSustainedValue(float statVal, StatValue stat)
        {
            float modVal = stat.Parent.GetExpressionValue(value);

            switch (valueType)
            {
            case EffectValueTypes.AddMultiplier:
                return(statVal + (statVal * modVal));

            case EffectValueTypes.Subtract:
                return(statVal - modVal);

            case EffectValueTypes.SubtractMultiplier:
                return(statVal - (statVal * modVal));

            default:            // Add
                return(statVal + modVal);
            }
        }
        private void Start()
        {
            if (lockCursor)
            {
                Cursor.lockState = CursorLockMode.Locked;
            }

            m_Animator      = GetComponent <Animator>();
            m_Rigidbody     = GetComponent <Rigidbody>();
            m_Capsule       = GetComponent <CapsuleCollider>();
            m_CapsuleHeight = m_Capsule.height;
            m_CapsuleCenter = m_Capsule.center;

            m_Rigidbody.constraints   = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezeRotationZ;
            m_OrigGroundCheckDistance = m_GroundCheckDistance;

            // get the transform of the main camera
            if (Camera.main != null)
            {
                m_Cam = Camera.main.transform;
            }
            else
            {
                Debug.LogWarning(
                    "Warning: no main camera found. Third person character needs a Camera tagged \"MainCamera\", for camera-relative controls.", gameObject);
                // we use self-relative controls in this case, which probably isn't what the user wants, but hey, we warned them!
            }

            // get the third person character ( this should never be null due to require component )
            m_Character = GetComponent <BasicPersonController>();

#if STATS_COG
            statsCog = GetComponentInChildren <Stats.StatsCog>();
            if (statsCog != null)
            {
                health = statsCog.FindStat(healthStatName);
            }
#endif

#if INVENTORY_COG
            inventory = GetComponent <Inventory.InventoryCog>();
#endif
        }
예제 #11
0
        private void OnEnable()
        {
            if (target is StatValue)
            {
                myTarget = (StatValue)target;

                // Header
                commandList = new ReorderableList(serializedObject, serializedObject.FindProperty("incrementCommand"), true, true, true, true);
                commandList.elementHeight      = EditorGUIUtility.singleLineHeight + 4;
                commandList.drawHeaderCallback = (Rect rect) => { EditorGUI.LabelField(rect, "Commands"); };

                // Elements
                commandList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) =>
                {
                    var element = commandList.serializedProperty.GetArrayElementAtIndex(index);
                    rect.y += 2;

                    EditorGUI.PropertyField(new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight), element, new GUIContent("Command", null, string.Empty));
                };
            }
        }
예제 #12
0
        private StatValue InstanceStatValue(StatValue stat)
        {
            StatValue instance = (StatValue)ScriptableObject.CreateInstance("StatValue");

            instance.value             = stat.value;
            instance.minValue          = stat.minValue;
            instance.maxValue          = stat.maxValue;
            instance.startWithMaxValue = stat.startWithMaxValue;
            instance.category          = stat.category;
            instance.displayInList     = stat.displayInList;

            instance.enableRegen    = stat.enableRegen;
            instance.regenDelay     = stat.regenDelay;
            instance.regenPerSecond = stat.regenPerSecond;

            instance.enableIncrement  = stat.enableIncrement;
            instance.incrementWhen    = stat.incrementWhen;
            instance.incrementAmount  = stat.incrementAmount;
            instance.incrementCommand = stat.incrementCommand;

            instance.onBaseMaxValueChanged = new ValueChanged();
            instance.onBaseMinValueChanged = new ValueChanged();
            instance.onBaseValueChanged    = new ValueChanged();
            instance.onInit            = new UnityEvent();
            instance.onMaxValueChanged = new ValueChanged();
            instance.onMinValueChanged = new ValueChanged();
            instance.onValueChanged    = new ValueChanged();

            instance.icon        = stat.icon;
            instance.iconColor   = stat.iconColor;
            instance.displayName = stat.displayName;
            instance.textColor   = stat.textColor;

            instance.name = stat.name;

            return(instance);
        }
예제 #13
0
        private void DrawStats()
        {
            GUILayout.BeginHorizontal(GUILayout.MaxWidth(750));

            GUILayout.BeginVertical(GUILayout.Width(300));
            SectionHeader("Local Stat Values");
            statsPos = GUILayout.BeginScrollView(statsPos);
            int editId = statsEditor.DrawStatsList();

            if (editId > -1)
            {
                editStat   = stats.stats[editId];
                statEditor = (StatValueEditor)Editor.CreateEditor(editStat);
            }

            GUILayout.EndScrollView();
            GUILayout.EndVertical();

            GUILayout.Space(32);

            GUILayout.BeginVertical(GUILayout.Width(300));
            if (editStat == null)
            {
                if (addStat == null)
                {
                    addStat      = (StatValue)ScriptableObject.CreateInstance(typeof(StatValue));
                    addStat.name = "New Stat";
                    statEditor   = (StatValueEditor)Editor.CreateEditor(addStat);
                }

                statEditor.serializedObject.Update();
                SectionHeader("Create Stat");
                statPos = GUILayout.BeginScrollView(statPos);
                statEditor.DrawInspector();

                GUILayout.Space(16);
                if (GUILayout.Button("Create and Add"))
                {
                    if (string.IsNullOrWhiteSpace(stats.statFolder))
                    {
                        stats.statFolder = Application.dataPath;
                    }
                    string path = EditorUtility.SaveFilePanelInProject("Save Stat", addStat.displayName, "asset", "Select a location to save the stat", stats.statFolder);
                    if (path.Length != 0)
                    {
                        stats.statFolder = System.IO.Path.GetDirectoryName(path);

                        addStat.name = System.IO.Path.GetFileNameWithoutExtension(path);
                        AssetDatabase.CreateAsset(addStat, path);
                        AssetDatabase.SaveAssets();

                        if (stats.stats == null)
                        {
                            stats.stats = new System.Collections.Generic.List <StatValue>();
                        }
                        stats.stats.Add(AssetDatabase.LoadAssetAtPath(path, typeof(StatValue)) as StatValue);
                        addStat = null;
                        statPos = Vector2.zero;
                        GUI.FocusControl("Clear");
                    }
                }
                GUILayout.EndScrollView();

                statEditor.serializedObject.ApplyModifiedProperties();
            }
            else
            {
                statEditor.serializedObject.Update();
                SectionHeader("Edit Stat");
                statPos = GUILayout.BeginScrollView(statPos);
                statEditor.DrawInspector();

                GUILayout.Space(16);
                if (GUILayout.Button("Done"))
                {
                    addStat  = null;
                    editStat = null;
                    GUI.FocusControl("Clear");
                    Repaint();
                }
                else
                {
                    statEditor.serializedObject.ApplyModifiedProperties();
                }
                GUILayout.EndScrollView();
            }
            GUILayout.EndVertical();


            GUILayout.EndHorizontal();
        }
예제 #14
0
        private void DrawDebug()
        {
            bool tmp = showStatsDebug;

            showStatsDebug = SectionGroup("Stat Values", showStatsDebug);
            if (tmp)
            {
                if (myTarget.stats == null || myTarget.stats.Count == 0)
                {
                    EditorGUILayout.LabelField("No StatValues available to be monitored.", Skin.GetStyle("WrapText"));
                }
                else
                {
                    string[] options = new string[myTarget.Stats.Count];
                    for (int i = 0; i < options.Length; i++)
                    {
                        options[i] = myTarget.stats[i].name;
                    }
                    if (selStat > options.Length - 1)
                    {
                        selStat = options.Length - 1;
                    }
                    selStat = EditorGUILayout.Popup("Stat Value", selStat, options);

                    SectionHeader("Current Values");
                    if (myTarget.Stats != null && myTarget.Stats.Count > 0)
                    {
                        StatValue stat = myTarget.Stats[selStat];
                        EditorGUILayout.LabelField("Value", stat.CurrentValue.ToString());
                        EditorGUILayout.LabelField("Min", stat.CurrentMinimum.ToString());
                        EditorGUILayout.LabelField("Max", stat.CurrentMaximum.ToString());
                        if (stat.enableRegen)
                        {
                            EditorGUILayout.LabelField("Regen", stat.CurrentRegenAmount.ToString());
                            EditorGUILayout.LabelField("Regen Delay", stat.CurrentRegenDelay.ToString());
                        }

                        SectionHeader("Base Values");
                        EditorGUILayout.LabelField("Value", stat.CurrentBaseValue.ToString());
                        EditorGUILayout.LabelField("Min", stat.CurrentBaseMinimum.ToString());
                        EditorGUILayout.LabelField("Max", stat.CurrentBaseMaximum.ToString());
                        if (stat.enableRegen)
                        {
                            EditorGUILayout.LabelField("Regen", stat.CurrentBaseRegenAmount.ToString());
                            EditorGUILayout.LabelField("Regen Delay", stat.CurrentBaseRegenDelay.ToString());
                        }

                        SectionHeader("Active Modifiers");
                        if (stat.ActiveModifiers != null && stat.ActiveModifiers.Count == 0)
                        {
                            EditorGUILayout.LabelField("No modifiers active.", Skin.GetStyle("WrapText"));
                        }
                        else
                        {
                            for (int i = 0; i < stat.ActiveModifiers.Count; i++)
                            {
                                EditorGUILayout.LabelField("[" + i + "]", stat.ActiveModifiers[i].AppliedValue.ToString());
                            }
                        }
                    }
                }
            }

            tmp = showEffectsDebug;
            showEffectsDebug = SectionGroup("Active Effects", showEffectsDebug);
            if (tmp)
            {
                if (myTarget.Effects == null || myTarget.Effects.Count == 0)
                {
                    EditorGUILayout.LabelField("There are no active effects.", Skin.GetStyle("WrapText"));
                }
                else
                {
                    for (int i = 0; i < myTarget.Effects.Count; i++)
                    {
                        EditorGUILayout.LabelField("[" + i + "] " + myTarget.Effects[i].displayName);
                    }
                }
            }

            SectionHeader("Console");
            scroll  = EditorGUILayout.BeginScrollView(scroll);
            command = EditorGUILayout.TextArea(command, GUILayout.Height(30));
            EditorGUILayout.EndScrollView();

            if (GUILayout.Button("Process Command"))
            {
                myTarget.SendCommand(command);
                command = string.Empty;
                scroll  = Vector2.zero;
                EditorUtility.SetDirty(target);
                Repaint();
            }
        }
예제 #15
0
        private void DrawDragBox(SerializedProperty values, SerializedProperty effects)
        {
            GUILayout.BeginVertical();
            GUI.skin.box.alignment        = TextAnchor.MiddleCenter;
            GUI.skin.box.normal.textColor = Color.white;

            DragBox("Drag & Drop Values/Effects Here");

            var dragAreaGroup = GUILayoutUtility.GetLastRect();

            switch (Event.current.type)
            {
            case EventType.DragUpdated:
            case EventType.DragPerform:
                if (!dragAreaGroup.Contains(Event.current.mousePosition))
                {
                    break;
                }
                DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

                if (Event.current.type == EventType.DragPerform)
                {
                    DragAndDrop.AcceptDrag();

                    foreach (var dragged in DragAndDrop.objectReferences)
                    {
                        StatEffect effect = dragged as StatEffect;
                        if (effect != null)
                        {
                            if (HasValue(effects, effect))
                            {
                                EditorUtility.DisplayDialog("Stats Cog", "An effect named '" + effect.name + "' already exists on this StatsCog.", "Ok");
                            }
                            else
                            {
                                effects.arraySize++;
                                effects.GetArrayElementAtIndex(effects.arraySize - 1).objectReferenceValue = effect;
                            }
                            continue;
                        }

                        StatValue stat = dragged as StatValue;
                        if (stat != null)
                        {
                            if (HasValue(values, stat))
                            {
                                EditorUtility.DisplayDialog("Stats Cog", "A value named '" + stat.name + "' already exists on this StatsCog.", "Ok");
                            }
                            else
                            {
                                values.arraySize++;
                                values.GetArrayElementAtIndex(values.arraySize - 1).objectReferenceValue = stat;
                            }
                            continue;
                        }
                    }
                }
                serializedObject.ApplyModifiedProperties();
                Event.current.Use();
                break;
            }

            GUILayout.EndVertical();
        }
예제 #16
0
 public void OnEnable()
 {
     text = GetComponent <Text>();
     stat = statsCog.FindStat(statName);
 }
예제 #17
0
        /// <summary>
        /// Take damage
        /// </summary>
        /// <param name="damageDealer"></param>
        /// <returns></returns>
        private void TakeDamage(DamageDealer damageDealer, GameObject damageSourceObject)
        {
            // check if damage dealer is self
            if (GetComponentsInChildren <DamageDealer>().ToList().Contains(damageDealer))
            {
                return;
            }

            // Get hit direction
            HitDirection hitDirection = GetHitDirection(damageDealer.gameObject.transform.position);

            // Check for immunity
            if (directionImmunity != 0 && (directionImmunity | hitDirection) == hitDirection)
            {
                onImmuneToDamage?.Invoke();
                return;
            }

            if (immuneRemaining > 0)
            {
                return;
            }

            // Add Effects
#if STATS_COG
            if (damageDealer.effects != null)
            {
                foreach (StatEffect effect in damageDealer.effects)
                {
                    if (effectList.availableEffects.Contains(effect))
                    {
                        AddEffect(effect);
                    }
                }
            }
#endif

            float adjustedDamage      = 0;
            float totalAdjustedDamage = 0;

            // Apply weakness
            foreach (Damage damage in damageDealer.damage)
            {
#if STATS_COG
                if (damageDealer.StatsSource != null)
                {
                    adjustedDamage = damageDealer.StatsSource.GetExpressionValue(damage.baseAmount);
                }
                else
                {
                    adjustedDamage = float.Parse(damage.baseAmount);
                }
#endif
                if (damage.damageType != null)
                {
                    List <DamageModifier> modifiers = FindDamageModifiers(damage.damageType.name);
                    foreach (DamageModifier dm in modifiers)
                    {
                        if (dm.modifierType == DamageModType.Resistance)
                        {
                            adjustedDamage -= adjustedDamage * dm.CurrentValue;
                            if (dm.CurrentValue == 1)
                            {
                                onImmuneToDamage?.Invoke();
                            }
                        }
                        else
                        {
                            adjustedDamage *= dm.CurrentValue;
                        }
                    }
                }
                else
                {
                    Debug.LogError("Damage is missing a DamageType");
                }

                totalAdjustedDamage += adjustedDamage;
            }

            // Apply damage
            StatValue hp = FindStat(healthStat);
            if (hp != null)
            {
                adjustedDamage = Mathf.Clamp(GetExpressionValue(ReplaceInsensitive(damageValue, "[damage]", totalAdjustedDamage.ToString())), 0, float.MaxValue);
                hp.SetValue(hp.CurrentValue - adjustedDamage);
                lastDmgSource = damageDealer.StatsSource;
                onDamageTaken?.Invoke(adjustedDamage, damageDealer, damageSourceObject);
                onHitDamageDirection?.Invoke(hitDirection);
                immuneRemaining = immunityAfterHit;
                onHitDirection?.Invoke(hitDirection);
                if (hp.CurrentValue <= 0)
                {
                    onDeath?.Invoke();
                }
            }
            else
            {
                Debug.LogWarning("Could not find '" + healthStat + "' to apply damage");
            }
        }
예제 #18
0
 /// <summary>
 /// Initialize modifier
 /// </summary>
 /// <param name="stat"></param>
 public void Initialize(StatValue stat)
 {
     AppliedValue = CalculateAppliedValue(stat);
     Initialized  = true;
 }
예제 #19
0
        /// <summary>
        /// Send a command to StatsCog
        /// </summary>
        /// <param name="command"></param>
        public void SendCommand(string command)
        {
            command = command.Replace("  ", " ");
            int   i = command.IndexOf(' ');
            int   e = command.IndexOf('=');
            float res;

            switch (command.Substring(0, i).Trim().ToLower())
            {
            case "add":             // Add effect
                AddEffect(command.Substring(i).Trim());
                break;

            case "remove":          // Remove effect
                RemoveEffect(command.Substring(i).Trim());
                break;

            case "removeall":       // Remove effect all
                RemoveEffectAll(command.Substring(i).Trim());
                break;

            case "clear":           // Clear effects
                ClearEffects();
                break;

            case "max":             // Set max value
                res = ParseStatValue(command.Substring(e + 1));
                FindStat(command.Substring(i, e - i - 1).Trim()).SetMaximum(res);
                break;

            case "min":             // Set min value
                res = ParseStatValue(command.Substring(e + 1));
                FindStat(command.Substring(i, e - i - 1).Trim()).SetMinimum(res);
                break;

            case "restore-min":     // Retore value to a minimum of passed value
                e   = command.IndexOf(' ', i + 1);
                res = ParseStatValue(command.Substring(e + 1).Trim());
                StatValue val = FindStat(command.Substring(i, e - i).Trim());
                if (val != null)
                {
                    if (val.CurrentValue < res)
                    {
                        val.SetValue(res);
                    }
                }
                break;

            case "setmax":          // Set value to maximum
                StatValue stat = FindStat(command.Substring(i).Trim());
                if (stat != null)
                {
                    stat.SetValue(stat.CurrentBaseMaximum);
                }
                break;

            case "value":           // Set value
                res = ParseStatValue(command.Substring(e + 1));
                FindStat(command.Substring(i, e - i - 1).Trim()).SetValue(res);
                break;
            }
        }