Пример #1
0
    /// <summary>
    /// clones this EffectData to a new object
    /// </summary>
    public EffectData clone()
    {
        EffectData clone = new EffectData();

        clone.XMLEffects = XMLEffects; //copy the list of xml effects over so we dont lose it

        //parse our own effects if needed
        if (effectsParsed == false)
        {
            parseEffects();
        }

        //clone the effects also
        foreach (IEffect ie in effects)
        {
            clone.Add(cloneEffect(ie));
        }

        //dont let the clone parse effects again, since we just did it for them
        clone.effectsParsed = true;

        return(clone);
    }
Пример #2
0
    /// <summary>
    /// deals damage to the enemy.  (make sure to call onExpectedDamage() first to avoid targeting bugs)
    /// </summary>
    /// <param name="e">damage event containing information about the attack</param>
    /// <param name="showParticles">if true, particles will be generated from the attack</param>
    public void onDamage(DamageEventData e, bool showParticles = true)
    {
        //dont bother if we are already dead
        if (curHealth <= 0)
        {
            return;
        }

        //trigger enemyDamaged effects
        if (effectData != null)
        {
            foreach (IEffect i in effectData.effects)
            {
                if (i.triggersAs(EffectType.enemyDamaged))
                {
                    //DEBUG CHECK: actualDamage() should not alter damage value
                    float checkDamage = e.rawDamage;

                    ((IEffectEnemyDamaged)i).actualDamage(ref e);

                    //DEBUG CHECK: actualDamage() should not alter damage value
                    if (checkDamage != e.rawDamage)
                    {
                        Debug.LogWarning(i.XMLName + " has altered rawDamage in actualDamage()!");
                    }
                }
            }
        }

        //copy periodic effects from the attack onto this unit so they can take effect, provided they are not forbidden in this context
        if (e.effects != null)
        {
            foreach (IEffect toCopy in e.effects.effects)
            {
                if (toCopy.triggersAs(EffectType.periodic))
                {
                    if (toCopy.forbiddenInContext(EffectContext.enemyUnit) == false)
                    {
                        //found an effect we need to copy.  first make sure we have an object to copy it to.
                        if (effectData == null)
                        {
                            effectData = new EffectData();
                        }

                        //then copy it
                        effectData.Add(EffectData.cloneEffect(toCopy));
                    }
                }
            }
        }

        //take damage
        int damage = Mathf.CeilToInt(e.rawDamage);

        damage     = System.Math.Min(damage, curHealth);
        curHealth -= damage;

        //tell the attacking tower about it so it can keep track
        if (e.source != null)
        {
            e.source.trackDamage(damage);
        }

        //provide user feedback
        if (damage > 0)
        {
            //sound
            int soundToPlay = Random.Range(0, enemyHitSounds.Length);
            audioSource.clip = enemyHitSounds[soundToPlay];
            if (isActiveAndEnabled)
            {
                StartCoroutine(playRespectLimit(audioSource)); //plays the sound, if we are not at the sound cap and the object is not disabled
            }
            //particles
            if (showParticles)
            {
                damageParticles.Emit(damageParticleBaseCount + Mathf.FloorToInt(damage / damagePerExtraParticle));
            }
        }

        if (curHealth <= 0)
        {
            //catch a recurring issue where the enemy does not get the expected damage event and thus dies without expecting it
            if (expectedHealth > 0)
            {
                Debug.LogWarning("Enemy did not expect to die, but did anyway!  This can cause targeting issues as towers attack an enemy that will die anyway.");
                expectedHealth = 0;
                EnemyManagerScript.instance.EnemyExpectedDeath(this);
            }

            //(bugfix: works around race condition where an enemy is deactivated and then dies immediately afterward
            if (gameObject.activeSelf == false)
            {
                gameObject.SetActive(true);
            }

            //and start the death coroutine
            StartCoroutine(onDeath());
        }
    }
Пример #3
0
    /// <summary>
    /// copies effects from newEffectData and adds them to the ones already present
    /// </summary>
    public void AddEffects(EffectData newEffectData)
    {
        //make sure we have an effectData object to add to
        if (effects == null)
        {
            effects = new EffectData();
        }

        //for each effect to add
        foreach (IEffect newEffect in newEffectData.effects)
        {
            //apply upgrade effects
            if (newEffect.triggersAs(EffectType.upgrade))
            {
                ((IEffectUpgrade)newEffect).upgradeTower(this);
            }

            //trigger instant effects
            if (newEffect.triggersAs(EffectType.instant))
            {
                if (LevelManagerScript.instance.levelLoaded) //skip them while the level is being loaded so we dont trigger card draws, etc.
                {
                    ((IEffectInstant)newEffect).trigger();
                }
            }

            //do not copy effects that are forbidden on towers
            if (newEffect.forbiddenInContext(EffectContext.tower))
            {
                continue;
            }

            //tell it about the source, if it wants to know
            if (newEffect.triggersAs(EffectType.sourceTracked))
            {
                ((IEffectSourceTracked)newEffect).effectSource = this;
            }

            //add it
            effects.Add(EffectData.cloneEffect(newEffect));
        }

        //update tooltip text
        UpdateTooltipText();

        updateLifespanText();

        //max tower charge is 1.0 unless an effect overrides it
        maxCharge = 1.0f;
        if (effects != null)
        {
            if (effects.propertyEffects.maxOvercharge != null)
            {
                maxCharge += effects.propertyEffects.maxOvercharge.Value;
            }
        }

        //use the range sprite appropriate to the top targeting effect
        switch (effects.topTargetingEffect.XMLName)
        {
        case "targetMouse":
            rangeImage.sprite   = mouseRangeSprite;
            rangeImage2.enabled = false;
            break;

        case "targetOrthogonal":
            rangeImage.sprite   = orthogonalRangeSprite;
            rangeImage2.enabled = false;
            break;

        default:
            rangeImage.sprite   = defaultRangeSprite;
            rangeImage2.enabled = false;
            break;
        }

        //make sure the scale is being set right
        updateRangeImage();
    }