예제 #1
0
    public void Start()
    {
        CreationReferences references = GetComponent <CreationReferences>();

        if (references && references.thisAbility)
        {
            ability = references.thisAbility;
            if (transform.parent)
            {
                bool     toggleOff = false;
                Stance[] stances   = transform.parent.GetComponentsInChildren <Stance>();
                for (int i = 0; i < stances.Length; i++)
                {
                    if (stances[i].ability == ability && toggle && stances[i] != this)
                    {
                        toggleOff = true;
                    }
                    if (stances[i] != this)
                    {
                        SelfDestroyer destroyer = stances[i].GetComponent <SelfDestroyer>();
                        if (destroyer)
                        {
                            destroyer.die();
                        }
                    }
                }
                if (toggleOff)
                {
                    Comp <SelfDestroyer> .GetOrAdd(gameObject).die();
                }
            }
        }
    }
    public void giveResources(GameObject hit)
    {
        if (hit == creator)
        {
            if (creatorMana && manaOnHit != 0)
            {
                creatorMana.gainMana(manaOnHit);
            }
            if (creatorProtection && creatorProtection.healthClass && healthOnHit != 0)
            {
                creatorProtection.healthClass.Heal(healthOnHit);
            }
            if (creatorProtection && wardOnHit != 0)
            {
                creatorProtection.GainWard(wardOnHit);
            }

            if (destroyAfterCollidingWithCreator)
            {
                SelfDestroyer dest = GetComponent <SelfDestroyer>();
                if (dest)
                {
                    if (destructionDelay == 0)
                    {
                        dest.die();
                    }
                    else
                    {
                        gameObject.AddComponent <DestroyAfterDuration>().duration = destructionDelay;
                    }
                }
            }
        }
    }
예제 #3
0
    // Update is called once per frame
    void Update()
    {
        if (returning && creator && mover)
        {
            mover.SetDirection(creator.transform.position + displacement - transform.position);

            if (destroyOnReachingCreator)
            {
                if (Maths.manhattanDistance(transform.position, creator.transform.position + displacement) < mover.speed * Time.deltaTime * 2)
                {
                    SelfDestroyer destroyer = GetComponent <SelfDestroyer>();
                    if (destroyer)
                    {
                        destroyer.die();
                    }
                    else
                    {
                        Destroy(gameObject);
                    }
                }
            }
        }

        if (age >= duration && !returning)
        {
            returning = true;
        }
        age += Time.deltaTime;
    }
예제 #4
0
    public void Die(Dying _actor)
    {
        SelfDestroyer destroyer = GetComponent <SelfDestroyer>();

        if (destroyer)
        {
            destroyer.die();
        }
    }
    public void Update()
    {
        if (list)
        {
            if (!list.abilities.Contains(references.thisAbility))
            {
                SelfDestroyer destroyer = Comp <SelfDestroyer> .GetOrAdd(gameObject);

                destroyer.die();
            }
        }
    }
예제 #6
0
    public void destroy()
    {
        SelfDestroyer destroyer = GetComponent <SelfDestroyer>();

        if (destroyer)
        {
            destroyer.die();
        }
        else
        {
            Destroy(gameObject);
        }
    }
    // Use this for initialization
    public override void onCreation()
    {
        // find the creator
        GameObject creator = GetComponent <CreationReferences>().creator;

        if (!creator)
        {
            Destroy(this); return;
        }

        bool buffRemoved = false;

        // if the creator already has a buff of this type then remove it if necessary
        if (replaceExistingBuff && GetComponent <CreationReferences>())
        {
            CreationReferences[] references = creator.transform.GetComponentsInChildren <CreationReferences>();
            Ability thisAbility             = GetComponent <CreationReferences>().thisAbility;
            for (int i = 0; i < references.Length; i++)
            {
                // check if the ability if the same as this one
                if (references[i].thisAbility == thisAbility)
                {
                    // destroy the existing buff
                    if (references[i].gameObject.GetComponent <SelfDestroyer>())
                    {
                        references[i].gameObject.GetComponent <SelfDestroyer>().die();
                    }
                    else
                    {
                        Destroy(references[i].gameObject);
                    }
                    buffRemoved = true;
                }
            }
        }

        if (toggle && buffRemoved)
        {
            SelfDestroyer destroyer = Comp <SelfDestroyer> .GetOrAdd(gameObject);

            destroyer.die();
        }

        // attach to the creator
        transform.parent = creator.transform;
        // move to the creator's location
        transform.localPosition = displacement;
        // change to the creator's rotation
        transform.rotation = transform.parent.rotation;
    }
 public void LateUpdate()
 {
     if (destroyAfterLastRetaliation && limitRetaliations && retaliationsRemaining <= 0 && retaliated)
     {
         SelfDestroyer destroyer = GetComponent <SelfDestroyer>();
         if (!destroyer)
         {
             destroyer = gameObject.AddComponent <SelfDestroyer>();
         }
         if (destroyer)
         {
             destroyer.die();
         }
     }
 }
예제 #9
0
    public void giveMana(GameObject hit)
    {
        if (hit == creator && creatorMana)
        {
            creatorMana.gainMana(manaOnHit);

            if (destroyAfterCollidingWithCreator)
            {
                SelfDestroyer dest = GetComponent <SelfDestroyer>();
                if (dest)
                {
                    if (destructionDelay == 0)
                    {
                        dest.die();
                    }
                    else
                    {
                        gameObject.AddComponent <DestroyAfterDuration>().duration = destructionDelay;
                    }
                }
            }
        }
    }
예제 #10
0
    public void Start()
    {
        references = GetComponent <CreationReferences>();
        if (references && references.creator)
        {
            all.RemoveAll(x => x == null);
            foreach (CanOnlyBeOnOneTarget other in all)
            {
                if (other.references && other.references.creator)
                {
                    if (other.references.thisAbility == references.thisAbility && other.references.creator == references.creator && other.transform.parent != transform.parent)
                    {
                        SelfDestroyer destroyer = other.GetComponent <SelfDestroyer>();
                        if (destroyer)
                        {
                            destroyer.die();
                        }
                    }
                }
            }

            all.Add(this);
        }
    }
예제 #11
0
    // Use this for initialization
    public override void onCreation()
    {
        bool      attached  = false;
        Alignment alignment = GetComponent <AlignmentManager>().alignment;

        if (alignment == null)
        {
            Debug.LogError("AttachToNearestAllyOnCreation component on " + gameObject.name + " cannot function as alignment is null");
            if (destroyIfFailedToAttach)
            {
                SelfDestroyer dest = Comp <SelfDestroyer> .GetOrAdd(gameObject);

                dest.die();
            }
            return;
        }
        // find a list of alignment objects that belong to enemies
        List <AlignmentManager> alignments = new List <AlignmentManager>();

        foreach (BaseHealth healthObject in BaseHealth.all)
        {
            if (healthObject.alignmentManager && !alignment.isSameOrFriend(healthObject.alignmentManager.alignment))
            {
                alignments.Add(healthObject.alignmentManager);
            }
        }
        // remove inactive objects from the list
        for (int i = alignments.Count - 1; i >= 0; i--)
        {
            if (!alignments[i].gameObject.activeSelf)
            {
                alignments.Remove(alignments[i]);
            }
        }
        // remove dying objects from the list
        if (requiredLifeState == lifeState.alive)
        {
            for (int i = alignments.Count - 1; i >= 0; i--)
            {
                if (alignments[i].GetComponent <Dying>() != null)
                {
                    if (alignments[i].GetComponent <StateController>().currentState == alignments[i].GetComponent <StateController>().dying)
                    {
                        alignments.Remove(alignments[i]);
                    }
                }
            }
        }
        // or remove living objects from the list
        else if (requiredLifeState == lifeState.dead)
        {
            for (int i = alignments.Count - 1; i >= 0; i--)
            {
                if (alignments[i].GetComponent <Dying>() != null)
                {
                    if (alignments[i].GetComponent <StateController>().currentState != alignments[i].GetComponent <StateController>().dying)
                    {
                        alignments.Remove(alignments[i]);
                    }
                }
                else
                {
                    alignments.Remove(alignments[i]);
                }
            }
        }
        // slightly different to dead as it will include things that died this step, but also things without a dying state
        else if (requiredLifeState == lifeState.zeroHealth)
        {
            BaseHealth bh = null;
            for (int i = alignments.Count - 1; i >= 0; i--)
            {
                bh = alignments[i].GetComponent <BaseHealth>();
                if (bh && bh.currentHealth > 0)
                {
                    alignments.Remove(alignments[i]);
                }
            }
        }
        if (alignments.Count == 0)
        {
            if (destroyIfFailedToAttach)
            {
                SelfDestroyer dest = Comp <SelfDestroyer> .GetOrAdd(gameObject);

                dest.die();
            }
            return;
        }
        else
        {
            // find the nearest alignment object that is an enemy
            AlignmentManager nearestAlignment = alignments[0];
            float            distance         = Vector3.Distance(transform.position, nearestAlignment.transform.position);
            foreach (AlignmentManager alignmentManager in alignments)
            {
                if (Vector3.Distance(transform.position, alignmentManager.transform.position) < distance)
                {
                    nearestAlignment = alignmentManager;
                    distance         = Vector3.Distance(transform.position, alignmentManager.transform.position);
                }
            }

            // return if it is not close enough
            if (useRangeLimit && distance > rangeLimit)
            {
                if (destroyIfFailedToAttach)
                {
                    SelfDestroyer dest = Comp <SelfDestroyer> .GetOrAdd(gameObject);

                    dest.die();
                }
                return;
            }

            // if the nearest one already has a buff of this type then remove it if necessary
            if (replaceExistingDebuff && GetComponent <CreationReferences>())
            {
                CreationReferences[] references = nearestAlignment.transform.GetComponentsInChildren <CreationReferences>();
                Ability thisAbility             = GetComponent <CreationReferences>().thisAbility;
                for (int i = 0; i < references.Length; i++)
                {
                    // check if the ability if the same as this one
                    if (references[i].thisAbility == thisAbility)
                    {
                        // destroy the existing buff
                        if (references[i].gameObject.GetComponent <SelfDestroyer>())
                        {
                            references[i].gameObject.GetComponent <SelfDestroyer>().die();
                        }
                        else
                        {
                            Destroy(references[i].gameObject);
                        }
                    }
                }
            }

            attached = true;
            // attach to the nearest one
            transform.parent = nearestAlignment.transform;
            // move to the ally's location
            transform.localPosition = displacement;
            // change to the ally's rotation
            transform.rotation = transform.parent.rotation;

            if (eraseInsteadOfAttaching)
            {
                BaseHealth bh = nearestAlignment.GetComponent <BaseHealth>();
                if (bh)
                {
                    bh.HealthDamagePercent(1000);
                }
                Dying dying = nearestAlignment.GetComponent <Dying>();
                if (dying && !dying.delaysCannotBeChanged)
                {
                    dying.destructionDelay = 0.02f;
                    dying.sinkingDelay     = 0.01f;
                }

                transform.parent = null;
            }
        }
        if (destroyIfFailedToAttach && !attached)
        {
            SelfDestroyer dest = Comp <SelfDestroyer> .GetOrAdd(gameObject);

            dest.die();
        }
    }
예제 #12
0
    // Use this for initialization
    public override void onCreation()
    {
        bool success = false;

        CreationReferences references = GetComponent <CreationReferences>();

        if (!references || !references.creator)
        {
            if (destroyIfFailedToMove)
            {
                SelfDestroyer dest = Comp <SelfDestroyer> .GetOrAdd(gameObject);

                dest.failedAbility = true;
                dest.die();
            }
            return;
        }

        SummonTracker tracker = references.creator.GetComponent <SummonTracker>();

        if (!tracker)
        {
            if (destroyIfFailedToMove)
            {
                SelfDestroyer dest = Comp <SelfDestroyer> .GetOrAdd(gameObject);

                dest.failedAbility = true;
                dest.die();
            }
            return;
        }

        // find a lit of summon
        List <Summoned> summons = new List <Summoned>();

        foreach (Summoned summoned in tracker.summons)
        {
            if (summoned)
            {
                summons.Add(summoned);
            }
        }
        // remove inactive objects from the list
        for (int i = summons.Count - 1; i >= 0; i--)
        {
            if (!summons[i].gameObject.activeSelf)
            {
                summons.Remove(summons[i]);
            }
        }
        // remove dying objects from the list
        if (requiredLifeState == lifeState.alive)
        {
            for (int i = summons.Count - 1; i >= 0; i--)
            {
                if (summons[i].GetComponent <Dying>() != null)
                {
                    if (summons[i].GetComponent <StateController>().currentState == summons[i].GetComponent <StateController>().dying)
                    {
                        summons.Remove(summons[i]);
                    }
                }
            }
        }
        // or remove living objects from the list
        else if (requiredLifeState == lifeState.dead)
        {
            for (int i = summons.Count - 1; i >= 0; i--)
            {
                if (summons[i].GetComponent <Dying>() != null)
                {
                    if (summons[i].GetComponent <StateController>().currentState != summons[i].GetComponent <StateController>().dying)
                    {
                        summons.Remove(summons[i]);
                    }
                }
                else
                {
                    summons.Remove(summons[i]);
                }
            }
        }
        if (summons.Count == 0)
        {
            if (destroyIfFailedToMove)
            {
                SelfDestroyer dest = Comp <SelfDestroyer> .GetOrAdd(gameObject);

                dest.failedAbility = true;
                dest.die();
            }
            return;
        }
        else
        {
            // find the nearest summon
            Summoned nearest  = summons[0];
            float    distance = Vector3.Distance(transform.position, nearest.transform.position);
            foreach (Summoned summon in summons)
            {
                if (Vector3.Distance(transform.position, summon.transform.position) < distance)
                {
                    nearest  = summon;
                    distance = Vector3.Distance(transform.position, summon.transform.position);
                }
            }

            // move to the summon's location
            transform.position = nearest.transform.position;
            // change to the summon's rotation
            transform.rotation = nearest.transform.rotation;

            success = true;

            if (kill)
            {
                Dying dying = nearest.GetComponent <Dying>();

                if (dying)
                {
                    if (eraseCorpse)
                    {
                        dying.setDelays(0.01f, 0.02f);
                    }

                    dying.myHealth.HealthDamage(dying.myHealth.maxHealth * 200);
                }
            }
        }
        if (destroyIfFailedToMove && success == false)
        {
            SelfDestroyer dest = Comp <SelfDestroyer> .GetOrAdd(gameObject);

            dest.failedAbility = true;
            dest.die();
        }
    }
예제 #13
0
    public void Summon()
    {
        for (int i = 0; i < numberToSummon; i++)
        {
            // get a reference to this objects creation references
            CreationReferences myReferences = GetComponent <CreationReferences>();

            // remove previous summons if necessary
            if (limitNumber && myReferences && attachCreationReferences && entity.GetComponent <Prefabs>())
            {
                abilitiesThatCountForLimit.Add(myReferences.thisAbility);
                List <GameObject> existingSummons = new List <GameObject>();
                foreach (Summoned summoned in Summoned.all)
                {
                    if (abilitiesThatCountForLimit.Contains(summoned.references.thisAbility))
                    {
                        if (summoned.references.creator = myReferences.creator)
                        {
                            existingSummons.Add(summoned.gameObject);
                        }
                    }
                }

                // components for removing summons
                SelfDestroyer selfDestroyer = null;
                Dying         dying         = null;

                while (existingSummons.Count >= limit)
                {
                    GameObject SummonToKill = getLowestPriority(existingSummons);
                    existingSummons.Remove(SummonToKill);

                    selfDestroyer = SummonToKill.GetComponent <SelfDestroyer>();
                    dying         = SummonToKill.GetComponent <Dying>();

                    // death events
                    if (dying && dying.getController())
                    {
                        dying.unsummoned = true;
                        dying.die();
                    }

                    // self destroyer events
                    if (selfDestroyer)
                    {
                        selfDestroyer.die();
                    }

                    // if neither exist, resort to destroying the game object
                    if (!dying && !selfDestroyer)
                    {
                        Destroy(SummonToKill);
                    }
                }
            }

            // decide the position
            Vector3 pos = displacement;
            if (distance > 0)
            {
                float angle = Random.Range(0, Mathf.PI * 2);
                pos = new Vector3(distance * Mathf.Cos(angle), displacement.y, distance * Mathf.Sin(angle));
            }

            pos = transform.position + pos;
            pos = new Vector3(pos.x, getY(pos), pos.z);

            // create the entity
            GameObject summon = Instantiate(entity, pos, Quaternion.Euler(0, 0, 0));

            // adapt the entity
            foreach (EntityAdapter adapter in GetComponents <EntityAdapter>())
            {
                summon = adapter.adapt(summon);
            }

            // attach creation references if necessary, if not then update them
            CreationReferences references = null;
            if (attachCreationReferences && myReferences != null)
            {
                if (!summon.GetComponent <CreationReferences>())
                {
                    references = summon.AddComponent <CreationReferences>();
                }
                else
                {
                    references = summon.GetComponent <CreationReferences>();
                }
                references.creator     = myReferences.creator;
                references.thisAbility = myReferences.thisAbility;
            }

            // add a summoned component
            Summoned summonedComponent = summon.AddComponent <Summoned>();
            summonedComponent.singeCardForAllMinions = singeCardForAllMinions;

            // initialise the summoned component
            summonedComponent.references = references;
            summonedComponent.initialise();

            //adds recent events tracker
            summon.AddComponent <CharacterStatusTracker>();

            // get a reference to the minion's stats
            BaseStats stats = summon.GetComponent <BaseStats>();

            // give it damage bonuses based on a tagged stats holder
            if (GetComponent <TaggedStatsHolder>() && stats)
            {
                TaggedStatsHolder holder = GetComponent <TaggedStatsHolder>();
                foreach (TaggedStatsHolder.TaggableStat ts in holder.taggedStats)
                {
                    List <Tags.AbilityTags> newTagList = new List <Tags.AbilityTags>();
                    newTagList.AddRange(ts.tagList);
                    if (newTagList.Contains(Tags.AbilityTags.Minion))
                    {
                        newTagList.Remove(Tags.AbilityTags.Minion);

                        stats.ChangeStatModifier(ts.property, ts.addedValue, BaseStats.ModType.ADDED, newTagList);
                        stats.ChangeStatModifier(ts.property, ts.increasedValue, BaseStats.ModType.INCREASED, newTagList);
                        foreach (float value in ts.moreValues)
                        {
                            stats.ChangeStatModifier(ts.property, value, BaseStats.ModType.MORE, newTagList);
                        }
                        foreach (float value in ts.quotientValues)
                        {
                            stats.ChangeStatModifier(ts.property, value, BaseStats.ModType.QUOTIENT, newTagList);
                        }
                    }
                }
            }

            // make it follow the creator if necessary
            if (followsCreator)
            {
                if (GetComponent <CreationReferences>())
                {
                    // if no follow ranges have been defined then use the defaults
                    if (followRangesAndPriorities.Count <= 0)
                    {
                        summon.AddComponent <Following>().leader = myReferences.creator;
                    }
                    // otherwise create follow states for each entry in the list
                    Following following;
                    foreach (FollowRangeAndPriority frar in followRangesAndPriorities)
                    {
                        following        = summon.AddComponent <Following>();
                        following.leader = myReferences.creator;
                        following.startFollowingRange = frar.range;
                        following.priority            = frar.priority;
                    }
                }
            }

            // make it move away from the creator when close if necessary
            if (movesAwayFromSummonerWhenClose)
            {
                if (myReferences)
                {
                    summon.AddComponent <MovingAwayFromSummoner>().summoner = myReferences.creator;
                }
            }

            // if necessary limit the duration by adding a destroy after duration component
            if (limitDuration)
            {
                // use a self destroyer if it has ones, otherwise use the dying state
                if (summon.GetComponent <SelfDestroyer>())
                {
                    DestroyAfterDuration destroyer = summon.AddComponent <DestroyAfterDuration>();
                    destroyer.duration = duration;
                }
                else
                {
                    DieAfterDelay destroyer = null;
                    if (!summon.GetComponent <DieAfterDelay>())
                    {
                        destroyer = summon.AddComponent <DieAfterDelay>();
                        destroyer.timeUntilDeath = duration;
                    }
                    // if there is already a destroy after duration component, lower the duration if this component's duration is lower than the one already there
                    else
                    {
                        destroyer = summon.GetComponent <DieAfterDelay>();
                        destroyer.timeUntilDeath = Mathf.Min(destroyer.timeUntilDeath, duration);
                    }
                    // make the destroyer unsummon rather than kill
                    if (destroyer)
                    {
                        destroyer.countsAsUnsummoned = true;
                    }
                }
            }

            // pass on alignment if necessary, may require an alignment manager to be added to the entity
            if (passOnAlignment && GetComponent <AlignmentManager>())
            {
                AlignmentManager alignmentManager = null;
                if (!summon.GetComponent <AlignmentManager>())
                {
                    alignmentManager = summon.AddComponent <AlignmentManager>();
                }
                else
                {
                    alignmentManager = summon.GetComponent <AlignmentManager>();
                }
                alignmentManager.alignment = GetComponent <AlignmentManager>().alignment;
            }

            // give the entity a custom name if necessary, may require a display information component to be added to the entity
            if (giveCustomName && customNames.Count > 0)
            {
                DisplayInformation displayInformation = null;
                if (!summon.GetComponent <DisplayInformation>())
                {
                    displayInformation = summon.AddComponent <DisplayInformation>();
                }
                else
                {
                    displayInformation = summon.GetComponent <DisplayInformation>();
                }
                int nameIndex = Random.Range(0, customNames.Count);
                displayInformation.displayName = customNames[nameIndex];
            }

            // add stats
            if (statList != null && statList.Count > 0)
            {
                if (stats)
                {
                    foreach (TaggedStatsHolder.TaggableStat stat in statList)
                    {
                        stats.addStat(stat);
                    }
                    stats.UpdateStats();
                    stats.myHealth.currentHealth = stats.myHealth.maxHealth;
                }
            }

            // give the entity a custom tag if necessary
            if (giveCustomTag)
            {
                summon.tag = customTag;
            }

            if (stats)
            {
                stats.UpdateStats();
                if (stats.myHealth)
                {
                    stats.myHealth.currentHealth = stats.myHealth.maxHealth;
                }
            }

            // pass on this summon information to a summonChangeTracker
            SummonChangeTracker sct = summon.AddComponent <SummonChangeTracker>();
            sct.statList.AddRange(statList);
            sct.limitDuration = limitDuration;

            sct.followsCreator            = followsCreator;
            sct.followRangesAndPriorities = new List <FollowRangeAndPriority>();
            sct.followRangesAndPriorities.AddRange(followRangesAndPriorities);

            sct.limitDuration = limitDuration;
            sct.duration      = duration;
        }
    }
예제 #14
0
    public void chain(GameObject hit)
    {
        // make sure this specific ability object only creates one chain
        if (hasChained)
        {
            return;
        }
        else
        {
            hasChained = true;
        }

        // check that there are chains remaining
        if (limitNumberOfChains)
        {
            if (chainsRemaining <= 0)
            {
                if (destroyAfterChainAttempt)
                {
                    SelfDestroyer destroyer = GetComponent <SelfDestroyer>();
                    if (destroyer)
                    {
                        destroyer.die();
                    }
                }
                return;
            }
        }

        // find potential enemies to hit
        TargetFinder     targetFinder = GetComponent <TargetFinder>();
        AlignmentManager am           = GetComponent <AlignmentManager>();

        BaseHealth[] potentialTargetArray = targetFinder.getPotentialTargets(am.alignment, abilityToChain.targetsAllies, null, new LifeStateHolder(abilityToChain.requiredLifeState));

        // exclude the object hit
        List <GameObject> potentialTargets = new List <GameObject>();

        foreach (BaseHealth health in potentialTargetArray)
        {
            if (health.gameObject != hit)
            {
                potentialTargets.Add(health.gameObject);
            }
        }

        // if there is a shared hit detector remove objects that have already been hit
        bool hasSharedHitDetector = (detector.sharedHitDetector != null);

        if (hasSharedHitDetector)
        {
            foreach (GameObject removeObj in detector.sharedHitDetector.enemiesHit)
            {
                potentialTargets.Remove(removeObj);
            }
        }

        // get the positions of targets in range
        List <GameObject> outOfRangeObjects = new List <GameObject>();
        Vector3           position          = transform.position;

        foreach (GameObject target in potentialTargets)
        {
            if (Vector3.Distance(position, target.transform.position) > range)
            {
                outOfRangeObjects.Add(target);
            }
        }
        foreach (GameObject removeObject in outOfRangeObjects)
        {
            potentialTargets.Remove(removeObject);
        }

        // if there are no targets remaining return
        if (potentialTargets.Count <= 0)
        {
            if (destroyAfterChainAttempt)
            {
                SelfDestroyer destroyer = GetComponent <SelfDestroyer>();
                if (destroyer)
                {
                    destroyer.die();
                }
            }
            return;
        }
        // if there is just one target chain to that
        else if (potentialTargets.Count == 1)
        {
            chainTo(potentialTargets[0], hit);
            if (destroyAfterSuccessfulChainAttempt)
            {
                SelfDestroyer destroyer = GetComponent <SelfDestroyer>();
                if (destroyer)
                {
                    destroyer.die();
                }
            }
        }
        // if there are multiple targets, pick a random one
        else
        {
            int randTarget = Random.Range(0, potentialTargets.Count - 1);
            chainTo(potentialTargets[randTarget], hit);
            if (destroyAfterSuccessfulChainAttempt)
            {
                SelfDestroyer destroyer = GetComponent <SelfDestroyer>();
                if (destroyer)
                {
                    destroyer.die();
                }
            }
        }

        if (destroyAfterChainAttempt)
        {
            SelfDestroyer destroyer = GetComponent <SelfDestroyer>();
            if (destroyer)
            {
                destroyer.die();
            }
        }
    }