private float ComputeUnitScore(GameObject go, Dictionary <DamageMatrix.Damage, float> enemyDamage, Dictionary <DamageMatrix.Armor, float> enemyArmorMinusAlliedDamage)
    {
        float armorScore  = 0f;
        float damageScore = 0f;

        (Unit unit, float productionTime) = GetUnitProductionInfo(go.GetComponent <Unit>());

        Health[] healths = go.GetComponentsInChildren <Health>();
        foreach (var pair in enemyDamage)
        {
            foreach (Health health in healths)
            {
                armorScore -= DamageMatrix.GetDamageFactor(pair.Key, health.ArmorType) * pair.Value / (health.MaxHealth / 1000f) / productionTime;
            }
        }

        var weapons = go.GetComponent <Unit>().GetWeapons();

        foreach (var pair in enemyArmorMinusAlliedDamage)
        {
            foreach (var weapon in weapons)
            {
                damageScore += weapon.GetDPS() * DamageMatrix.GetDamageFactor(weapon.DamageType, pair.Key) * Mathf.Max(0f, pair.Value) / productionTime;
            }
        }

        return(Mathf.Max(0.1f, armorScore + damageScore));
    }
Ejemplo n.º 2
0
    public virtual bool GetDamaged(DamageMatrix attackMatrix, bool heal = false)
    {
        foreach (StatusEffect effect in statusEffects)
        {
            if (effect.GetType() == typeof(BufferStatus))
            {
                //buffer shields get used up on an attack
                effect.TickDown(1);

                return(false);
            }
        }

        //foreach attack matrix type of damage that is not 0 - trigger the effect mb?
        damageAmount = attackMatrix.CalcualateDamage(attackMatrix);
        HealthChanged(heal);

        if (heal)
        {
            currentHealth = Mathf.Clamp(currentHealth + damageAmount, currentHealth, maxHealth); //can't heal for negative amount or over max health
            return(true);
            //overheal status effect?
        }

        //calculated resistances and all that nonsense here
        currentHealth -= damageAmount;
        if (currentHealth <= 0)
        {
            Die();
        }

        return(true);
    }
Ejemplo n.º 3
0
    public float CalcualateDamage(DamageMatrix attacker)
    {
        calucalatedDamage = 0;

        foreach (DamageTypes type in System.Enum.GetValues(typeof(DamageTypes)))
        {
            calucalatedDamage += attacker.attackMatrix[type] * defenseMatrix[type];
        }

        return(calucalatedDamage);
    }
Ejemplo n.º 4
0
    public virtual void ResetStats()
    {
        defaultSpeed     = (agent == null) ? 0 : agent.speed;
        timeFromLastShot = shotCooldown; //fighter starts with no cooldown
        damageMatrix     = new DamageMatrix(damageAttack.Values, damageResistances.Values);

        currentHealth  = maxHealth;
        targetsInRange = new Dictionary <string, List <GameObject> >();

        statusEffects = new List <StatusEffect>();
    }
Ejemplo n.º 5
0
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        IWeapon weapon = target as IWeapon;

        EditorGUILayout.LabelField("Raw DPS: " + weapon.GetDPS());
        _showAllDamage = EditorGUILayout.BeginFoldoutHeaderGroup(_showAllDamage, "Damage / DPS against armor");
        if (_showAllDamage)
        {
            var values = System.Enum.GetValues(typeof(DamageMatrix.Armor));
            foreach (var value in values)
            {
                float factor = DamageMatrix.GetDamageFactor(weapon.DamageType, (DamageMatrix.Armor)value);
                EditorGUILayout.LabelField("Damage / DPS against " + value.ToString() + ": " + weapon.Damage * factor + " / " + weapon.GetDPS() * factor);
            }
        }
        EditorGUILayout.EndFoldoutHeaderGroup();
    }
Ejemplo n.º 6
0
    public float TakeDamage(DamageInfo info)
    {
        OnTakeDamage?.Invoke(info);
        float dmg = info.Damage * DamageMatrix.GetDamageFactor(info.Type, ArmorType);

        CurrentHealth -= dmg;
        OnDamageTaken?.Invoke(dmg);
        if (CurrentHealth <= 0f && !_isDead)
        {
            Die();
            OnDeath?.Invoke();
            _isDead = true;
        }
        if (CurrentHealth > MaxHealth)
        {
            CurrentHealth = MaxHealth;
        }
        return(CurrentHealth);
    }
    public override Dictionary <GameObject, float> GetWeights(IEnumerable <GameObject> options)
    {
        if (_damageMappingCopy == null) // Cache a copy of the damage mapping.
        {
            _damageMappingCopy = DamageMatrix.CopyMapping();
        }

        var enemyDamage = Enum.GetValues(typeof(DamageMatrix.Damage)).Cast <DamageMatrix.Damage>().ToDictionary(x => x, y => 0f);
        var enemyArmorMinusAlliedDamage = Enum.GetValues(typeof(DamageMatrix.Armor)).Cast <DamageMatrix.Armor>().ToDictionary(x => x, y => 0f);

        var enemyPlaced  = Team.GetOtherTeams(_commander.TeamInfo).SelectMany(x => x.GetCommanders()).SelectMany(x => x.GetPlacedUnits());
        var alliedPlaced = Team.GetTeam(_commander.TeamInfo).GetCommanders().SelectMany(x => x.GetPlacedUnits());

        foreach (var placed in enemyPlaced)
        {
            // Aggregate enemy damage - lowest damage type is the one we want to build armor against.
            (Unit unit, float productionTime) = GetUnitProductionInfo(placed);
            foreach (IWeapon weapon in unit.GetWeapons())
            {
                enemyDamage[weapon.DamageType] += weapon.GetDPS() / productionTime;
            }

            // Aggregate enemy armor.
            Health health = unit.GetComponent <Health>();
            enemyArmorMinusAlliedDamage[health.ArmorType] += health.MaxHealth / productionTime;
        }

        // Subtract our damage from enemy armor - highest remaining armor type is the one we need to counter.
        foreach (var placed in alliedPlaced)
        {
            (Unit unit, float productionTime) = GetUnitProductionInfo(placed);
            foreach (IWeapon weapon in unit.GetWeapons())
            {
                foreach (var value in Enum.GetValues(typeof(DamageMatrix.Armor)))
                {
                    var   armorType  = (DamageMatrix.Armor)value;
                    float dpsVsArmor = weapon.GetDPS() * DamageMatrix.GetDamageFactor(weapon.DamageType, armorType);
                    enemyArmorMinusAlliedDamage[armorType] -= dpsVsArmor / productionTime;
                }
            }
        }

        // Compute unit weights for each unit and normalize.
        var   weights      = new Dictionary <GameObject, float>();
        float highestScore = 0.1f;

        // Compute weights
        foreach (var option in options)
        {
            float score = ComputeUnitScore(option, enemyDamage, enemyArmorMinusAlliedDamage);
            if (score > highestScore)
            {
                highestScore = score;
            }
            weights.Add(option, score);
        }

        // Normalize
        foreach (var option in options)
        {
            weights[option] /= highestScore;
        }

        return(weights);
    }