예제 #1
0
 /// <summary>
 /// Normailzes each stat.
 /// </summary>
 /// <param name="effect">The stats to be normalized</param>
 public void NormalizeStats(ref StatsEffect effect)
 {
     effect.health = Mathf.Clamp(effect.health, minValue, maxValue);
     effect.speed  = Mathf.Clamp(effect.speed, minValue, maxValue);
     effect.luck   = Mathf.Clamp(effect.luck, minValue, maxValue);
     effect.dodge  = Mathf.Clamp(effect.dodge, minValue, maxValue);
 }
    public void ApplyEffect(EPlayerEffect pType, float pDuration)    //, float pValue = 1)
    {
        StatsEffect appliedEffect = appliedEffects.Find(a => a.Type == pType);
        float       duration      = pDuration;

        //Debug.Log($"ApplyEffect {pType} for {duration}");

        if (appliedEffect != null)
        {
            LeanTween.cancel(appliedEffect.id);
            appliedEffects.Remove(appliedEffect);
            if (appliedEffect.TimeLeft < 0)
            {
                Debug.LogError("Time left cant be < 0");
            }
            duration += appliedEffect.TimeLeft;
            //Debug.Log($"{pType}: add {appliedEffect.TimeLeft}s => {duration}s");
        }

        StatsEffect newEffect = new StatsEffect(pType, duration);        //, pValue);

        appliedEffects.Add(newEffect);
        SetEffectActive(pType, true);
        int id = DoInTime(() => RemoveEffect(pType), duration);

        newEffect.id = id;
    }
예제 #3
0
 public void ApplyStatsEffect(StatsEffect effect)
 {
     spaceShip.Reactor.AddToStatus(effect.Energy);
     spaceShip.WaterBlock.AddToStatus(effect.Water);
     spaceShip.OxygenBlock.AddToStatus(effect.Oxygen);
     spaceShip.FoodBlock.AddToStatus(effect.Food);
 }
예제 #4
0
    private void SetStats(StatsEffect effect)
    {
        PlayerStatsDict.Instance.NormalizeStats(ref effect);

        if (effect.health != health)
        {
            health = effect.health;
            player.Health.SetMax(PlayerStatsDict.Instance.GetHealth(health));
            OnHealthChanged?.Invoke(health);
        }
        if (effect.speed != speed)
        {
            speed = effect.speed;
            OnSpeedChanged?.Invoke(speed);
        }
        if (effect.luck != luck)
        {
            luck = effect.luck;
            OnLuckChanged?.Invoke(luck);
        }
        if (effect.dodge != dodge)
        {
            dodge = effect.dodge;
            OnDodgeChanged?.Invoke(dodge);
        }
    }
예제 #5
0
 void Update()
 {
     if (Input.GetKeyDown(KeyCode.S))
     {
         StatsEffect.CreateStatsEffect(transform.position, Random.Range(-7, 7), Random.Range(-7, 7));
     }
 }
예제 #6
0
        private void OnEffect(StatsEffect effect, int effectValue, float duration = 0)
        {
            switch (effect)
            {
            case StatsEffect.HealthModifier:
                AddHealth(effectValue);
                break;

            case StatsEffect.ManaModifier:
                AddMana(effectValue);
                break;

            case StatsEffect.NourishmentModifier:
                AddNourishment(effectValue);
                break;

            case StatsEffect.StrengthModifier:
                AddStrength(effectValue, duration);
                break;

            case StatsEffect.Invisibility:
                SetInvisible(duration);
                break;

            default:
                throw new System.NotSupportedException("The effect of the consumable cannot be determined");
            }
        }
예제 #7
0
        public void CompareDifferentProperties()
        {
            // Bigger by health, smaller by mana, equal by intelligence
            var a = new StatsEffect(ChangeType.Add, new Dictionary <StatsProperty, decimal>
            {
                { StatsProperty.Health, 5 },
                { StatsProperty.Mana, 3 },
                { StatsProperty.Intelligence, 1 }
            });

            // Smaller by health, bigger by mana, equal by intelligence
            var b = new StatsEffect(ChangeType.Add, new Dictionary <StatsProperty, decimal>
            {
                { StatsProperty.Health, 3 },
                { StatsProperty.Mana, 5 },
                { StatsProperty.Intelligence, 1 }
            });

            var health = new StructFlag <StatsProperty>(StatsProperty.Health);

            Assert.Equal(-1, StatsEffect.Compare(health, a, b));

            var mana = new StructFlag <StatsProperty>(StatsProperty.Mana);

            Assert.Equal(1, StatsEffect.Compare(mana, a, b));

            var intelligence = new StructFlag <StatsProperty>(StatsProperty.Intelligence);

            Assert.Equal(0, StatsEffect.Compare(intelligence, a, b));
        }
예제 #8
0
        public void CompareDifferent()
        {
            var props = new StructFlag <StatsProperty>(StatsProperty.Health);

            var comparer = StatsEffect.CreateComparer(props);

            // Bigger
            var a = new StatsEffect(ChangeType.Add, new Dictionary <StatsProperty, decimal>
            {
                { StatsProperty.Health, 5 }
            });

            // Smaller
            var b = new StatsEffect(ChangeType.Add, new Dictionary <StatsProperty, decimal>
            {
                { StatsProperty.Health, 3 }
            });

            // Bigger first
            Assert.Equal(-1, comparer.Compare(a, b));
            Assert.Equal(-1, StatsEffect.Compare(props, a, b));

            // Smaller first
            Assert.Equal(1, comparer.Compare(b, a));
            Assert.Equal(1, StatsEffect.Compare(props, b, a));
        }
예제 #9
0
 public void Add(StatsEffect effect)
 {
     health += effect.health;
     speed  += effect.speed;
     luck   += effect.luck;
     dodge  += effect.dodge;
 }
예제 #10
0
 public void OnDie()
 {
     for (int i = appliedEffects.Count - 1; i >= 0; i--)
     {
         StatsEffect effect = appliedEffects[i];
         RemoveEffect(effect.Type);
     }
 }
 public void ChangeStats(int attackAmount, int healthAmount, int attackAfter, int healthAfter)
 {
     if (attackAmount != 0 || healthAmount != 0)
     {
         StatsEffect.CreateStatsEffect(transform.position, attackAmount, healthAmount);
         AttackText.text = System.Math.Max(attackAfter, 0).ToString();
         HealthText.text = System.Math.Max(healthAfter, 0).ToString();
     }
 }
예제 #12
0
 private void Update()
 {
     if (Input.GetKeyDown(KeyCode.F))
     {
         var effect = new StatsEffect();
         effect.Food = 10;
         shipController.ApplyStatsEffect(effect);
     }
 }
예제 #13
0
        private int EnergySpending()
        {
            StatsEffect statsEffect              = ResourceProducing();
            float       spendedToFoodProducing   = statsEffect.Food * coefficients.K_EnergyToFoodProducing;
            float       spendedToWaterProducing  = statsEffect.Water * coefficients.K_EnergyToWaterProducing;
            float       spendedToOxygenProducing = statsEffect.Oxygen * coefficients.K_EnergyToOxygenProducing;

            return((int)((spendedToFoodProducing + spendedToWaterProducing + spendedToOxygenProducing) * coefficients.K_Global));
        }
예제 #14
0
        private StatsEffect ResourceProducing()
        {
            StatsEffect producing = new StatsEffect();

            producing.Food   = Producing(BlockType.Food);
            producing.Water  = Producing(BlockType.Water);
            producing.Oxygen = Producing(BlockType.Oxygen);
            return(producing);
        }
예제 #15
0
    public void OnItemsChanged(SyncList <Item> items)
    {
        StatsEffect effect = new StatsEffect(baseHealth, baseSpeed, baseLuck, baseDodge);

        for (int i = 0; i < items.Count; i++)
        {
            items[i].OnHold(player, ref effect);
        }
        SetStats(effect);
    }
예제 #16
0
        public void ApplySetTest()
        {
            var stats  = new Stats();
            var effect = new StatsEffect(ChangeType.Set, new Dictionary <StatsProperty, decimal>
            {
                { StatsProperty.Health, 5 }
            });
            var applied = stats.Apply(effect);

            Assert.Equal(effect.Effect[StatsProperty.Health], applied.Effect[StatsProperty.Health]);
        }
예제 #17
0
        private bool DetectUseSet(StructFlag <StatsProperty> prop,
                                  IDictionary <ChangeType, MustBeOrderedList <ItemInfo> > items)
        {
            if (items.TryGetValue(ChangeType.Set, out var setItems))
            {
                // Returns is best "set" item better than BaseStats
                return(StatsEffect.Compare(prop, User.Info.BaseStats, TakeBest(1, setItems).First().Item.Effect) == 1);
            }

            return(false);
        }
예제 #18
0
        private StatsEffect ResourceSpending()
        {
            StatsEffect spend = new StatsEffect();

            foreach (var c in characterPool.GetAllCharacters())
            {
                spend.Food   += System.Convert.ToInt32(c.Mass * coefficients.K_FoodSpending);
                spend.Water  += System.Convert.ToInt32(c.Mass * coefficients.K_WaterSpending);
                spend.Oxygen += System.Convert.ToInt32(c.Mass * coefficients.K_OxygenSpending);
            }

            return(spend);
        }
예제 #19
0
        public StatsEffect GetResultEffect()
        {
            StatsEffect summary           = new StatsEffect();
            StatsEffect resourceProducing = ResourceProducing();
            StatsEffect resourceSpending  = ResourceSpending();

            summary.Food   = CalculateResult(resourceProducing.Food, resourceSpending.Food);
            summary.Water  = CalculateResult(resourceProducing.Water, resourceSpending.Water);
            summary.Oxygen = CalculateResult(resourceProducing.Oxygen, resourceSpending.Oxygen);
            summary.Energy = -(EnergySpending() + coefficients.GlobalConstantSpending);

            return(summary);
        }
예제 #20
0
        public void CompareSame()
        {
            var props = new StructFlag <StatsProperty>(StatsProperty.Health);

            var comparer = StatsEffect.CreateComparer(props);

            var a = new StatsEffect(ChangeType.Add, new Dictionary <StatsProperty, decimal>
            {
                { StatsProperty.Health, 5 }
            });
            var b = new StatsEffect(ChangeType.Add, new Dictionary <StatsProperty, decimal>
            {
                { StatsProperty.Health, 5 }
            });

            Assert.Equal(0, comparer.Compare(a, b));
            Assert.Equal(0, StatsEffect.Compare(props, a, b));
        }
예제 #21
0
        internal static Stats.Stats ApplyItems(StatsEffect stats, IEnumerable <ItemInfo> activeItems)
        {
            var result = new Stats.Stats(stats.Effect);

            foreach (var item in activeItems)
            {
                if (item.Item.Effect == null)
                {
                    continue;
                }

                for (var i = 0; i < item.Count; i++)
                {
                    result = result.Apply(item.Item.Effect);
                }
            }

            return(result);
        }
예제 #22
0
파일: Item.cs 프로젝트: RhythNS/RunAndGun
 public abstract void OnHold(Player player, ref StatsEffect statsEffect);
예제 #23
0
 public TestItem(string identifier, StatsEffect effect)
 {
     Identifier = identifier;
     Effect     = effect;
 }
예제 #24
0
 public void OnHit(StatsEffect effect, int effectValue, float duration = 0)
 {
     // Negate the value so it damages by default
     OnEffect(effect, -effectValue, duration);
 }
예제 #25
0
        private List <ItemInfo> ActivateItems(StructFlag <StatsProperty> prop, MustBeOrderedList <ItemInfo> items)
        {
            if (!ActiveProportions.TryGetValue(prop, out var limit))
            {
                return(new List <ItemInfo>());
            }

            var groups = GroupByChangeType(items);
            var useSet = DetectUseSet(prop, groups);

            var max = limit;

            if (useSet)
            {
                max--;
            }

            var selectedItems = new List <ItemInfo>();

            if (useSet)
            {
                selectedItems.AddRange(TakeBest(1, groups[ChangeType.Set]));
            }

            if (!groups.ContainsKey(ChangeType.Add) && !groups.ContainsKey(ChangeType.Multiply))
            {
                // No multiplication and addition. Only set, maybe.
                // So just do nothing, because DetectUseSet() will handle set.
                return(selectedItems);
            }

            if (!groups.ContainsKey(ChangeType.Add))
            {
                // Only multiplication (and set, maybe)
                selectedItems.AddRange(TakeBest(max, groups[ChangeType.Multiply]));
                return(selectedItems);
            }

            if (!groups.ContainsKey(ChangeType.Multiply))
            {
                // Only addition (and set, maybe)
                selectedItems.AddRange(TakeBest(max, groups[ChangeType.Add]));
                return(selectedItems);
            }

            // Both multiplication and addition (and set, maybe)

            /*
             * Наилучшая комбинация будет если сначала складывать, а потом умножать, т.к. (x + a) * b > (x * b) + a
             * Этот алгоритм сначала пробует взять максимальное количество умножения,
             * потом в каждой итерации добавляет одно сложение. В конце концов пробует только сложения.
             * Работает за O(N^2), где N -- max (ActiveProportions[prop])
             */
            var selectedItemsBase = selectedItems.ToList();
            var bestStats         = User.Info.BaseStats;
            var bestItems         = new List <ItemInfo>();

            for (var addCount = 0; addCount < max; addCount++)
            {
                selectedItems = selectedItemsBase.ToList();

                var mulCount = max - addCount;
                selectedItems.AddRange(TakeBest(addCount, groups[ChangeType.Add]));
                selectedItems.AddRange(TakeBest(mulCount, groups[ChangeType.Multiply]));

                var currentStats = UserInfo.ApplyItems(User.Info.BaseStats, selectedItems);

                if (StatsEffect.Compare(prop, bestStats, currentStats) == 1)
                {
                    bestStats = currentStats;
                    bestItems = selectedItems.ToList();
                }
            }

            return(bestItems);
        }
예제 #26
0
        private static IReadOnlyDictionary <StructFlag <StatsProperty>, MustBeOrderedList <ItemInfo> > GroupByStats(
            IEnumerable <ItemInfo> items)
        {
            var result = new Dictionary <StructFlag <StatsProperty>, List <ItemInfo> >();

            foreach (var item in items)
            {
                var combined = new StructFlag <StatsProperty>();
                Debug.Assert(item.Item.Effect != null, "item.Item.Effect != null");
                foreach (var effectKey in item.Item.Effect.Effect.Keys)
                {
                    combined = new StructFlag <StatsProperty>(combined.Values.Add(effectKey));
                }

                if (result.TryGetValue(combined, out var list))
                {
                    list.Add(item);
                }
                else
                {
                    result[combined] = new List <ItemInfo> {
                        item
                    };
                }
            }

            return(result.ToDictionary(
                       kv => kv.Key,
                       kv => new MustBeOrderedList <ItemInfo>(kv.Value
                                                              .OrderBy(i => i.Item.Effect, StatsEffect.CreateComparer(kv.Key)))
                       ));
        }
예제 #27
0
 public override void OnHold(Player player, ref StatsEffect statsEffect)
 {
 }