Пример #1
0
    // Use this for initialization
    void Start()
    {
        mutatorManager      = GetComponent <AbilityMutatorManager>();
        myAlignmentManager  = GetComponent <AlignmentManager>();
        myTaggedStatsHolder = GetComponent <TaggedStatsHolder>();

        myCreationReferences = GetComponent <CreationReferences>();
        myHitDetector        = GetComponent <HitDetector>();
    }
Пример #2
0
        public InGameState()
        {
            bg = new Sprite(AssetManager.getTexture(AssetManager.TextureName.InGameBackground));
            bg.Origin = (Vector2) bg.Texture.Size / 2F;
            bg.Scale = Vector2.One * 0.08F;
            
            resetView = true;

            this.Map = new Map();
            ParticleManager = new ParticleManager(Map);
            Player = new Player(ParticleManager, Map);
            EnemyManager = new EnemyManager(Player);
            AlignmentManager = new AlignmentManager(Player, Map);
        }
Пример #3
0
    private void Awake()
    {
        Instance = this;

        SturfeeEventManager.Instance.OnSessionReady          += OnSessionReady;
        SturfeeEventManager.Instance.OnSessionFailed         += OnSessionFailed;
        SturfeeEventManager.Instance.OnCoverageCheckComplete += OnCoverageCheckComplete;
        SturfeeEventManager.Instance.OnLocalizationComplete  += OnLocalizationComplete;
        SturfeeEventManager.Instance.OnLocalizationLoading   += OnLocalizationLoading;

        LookUpTrigger.OnUserLookedUp += HandleOnLookUpComplete;

        ScanButton.SetActive(false);
        BackButton.SetActive(false);
        Cursor.SetActive(false);
        Arrow.SetActive(false);
        ScanAnimation.SetActive(false);
    }
Пример #4
0
    // Use this for initialization
    void Start()
    {
        abilityMover = GetComponent <AbilityMover>();

        locationDetector = GetComponent <LocationDetector>();
        AlignmentManager alignmentManager = GetComponent <AlignmentManager>();

        if (locationDetector && alignmentManager)
        {
            Alignment alignment = alignmentManager.alignment;
            if (alignment)
            {
                List <Transform> possibleTargets = new List <Transform>();
                foreach (BaseHealth health in BaseHealth.all)
                {
                    if (health.alignmentManager && alignment.foes.Contains(health.alignmentManager.alignment) && health.currentHealth > 0)
                    {
                        possibleTargets.Add(health.transform);
                    }
                }

                Vector3 position = locationDetector.targetLocation;
                targetPosition = position;
                float distance       = 0f;
                float targetDistance = 0f;

                foreach (Transform possibleTarget in possibleTargets)
                {
                    distance       = Vector3.Distance(position, possibleTarget.position);
                    targetDistance = Vector3.Distance(position, targetPosition);
                    if ((target == null || distance < targetDistance) && distance < maxDistanceFromTarget)
                    {
                        targetPosition = possibleTarget.position;
                        target         = possibleTarget;
                    }
                }

                if (target)
                {
                    targetGo = target.gameObject;
                }
            }
        }
    }
        private void Awake()
        {
            AlignSubtree subTree = FindObjectOfType <AlignSubtree>();

            if (subTree != null)
            {
                if (subTree.AlignmentManager == null)
                {
                    subTree.OnAlignManagerCreated += (sender, manager) =>
                    {
                        this.alignmentManager = manager;
                        alignmentManager.OnTriangulationBuilt += OnNewTriangulationWasBuilt;
                    };
                }
                else
                {
                    this.alignmentManager = subTree.AlignmentManager;
                    alignmentManager.OnTriangulationBuilt += OnNewTriangulationWasBuilt;
                }
            }
        }
    void Start()
    {
        AlignmentManager alignmentManager = GetComponent <AlignmentManager>();

        if (alignmentManager && alignmentManager.alignment)
        {
            Vector3 position = transform.position;
            foreach (Dying dying in Dying.all)
            {
                if (dying.isDying() && dying.myHealth && dying.myHealth.alignmentManager && dying.myHealth.alignmentManager.alignment &&
                    alignmentManager.alignment.foes.Contains(dying.myHealth.alignmentManager.alignment))
                {
                    if (Vector3.Distance(position, dying.transform.position) <= radius)
                    {
                        createAbilityObject(dying.gameObject);
                        if (eraseCorpses)
                        {
                            dying.setDelays(0f, 0f);
                        }
                    }
                }
            }
        }
    }
    // Use this for initialization
    public override void onCreation()
    {
        Alignment alignment = GetComponent <AlignmentManager>().alignment;

        if (alignment == null)
        {
            Debug.LogError("AttachToNearestAllyOnCreation component on " + gameObject.name + " cannot function as alignment is null"); return;
        }
        // find a lit of alignment objects that belong to allies
        List <AlignmentManager> alignments = new List <AlignmentManager>();

        foreach (BaseHealth healthObject in BaseHealth.all)
        {
            if (alignment.isSameOrFriend(healthObject.GetComponent <AlignmentManager>().alignment))
            {
                alignments.Add(healthObject.GetComponent <AlignmentManager>());
            }
        }
        // remove dying objects from the list
        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]);
                }
            }
        }
        if (alignments.Count == 0)
        {
            return;
        }
        else
        {
            // find the nearest alignment object that is an ally
            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);
                }
            }

            // if the nearest one already has a buff of this type then remove it if necessary
            if (replaceExistingBuff && 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);
                        }
                    }
                }
            }

            // 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;
        }
    }
    public void Apply(GameObject hitObject)
    {
        GameObject        effect              = Instantiate(statusEffect.effectObject, hitObject.transform);
        StatusDamage      statusDamage        = effect.GetComponent <StatusDamage>();
        TaggedStatsHolder myTaggedStatsHolder = GetComponent <TaggedStatsHolder>();
        ProtectionClass   protection          = hitObject.GetComponent <ProtectionClass>();

        if (protection)
        {
            if (statusDamage && myTaggedStatsHolder)
            {
                TaggedStatsHolder taggedStatsHolder = effect.AddComponent <TaggedStatsHolder>();
                taggedStatsHolder.simpleStats.AddRange(myTaggedStatsHolder.simpleStats);
                taggedStatsHolder.taggedStats.AddRange(myTaggedStatsHolder.taggedStats);

                // apply DoT damage
                foreach (TaggedStatsHolder.TaggableStat taggableStat in taggedStatsHolder.taggedStats)
                {
                    if (taggableStat.tagList.Contains(Tags.AbilityTags.DoT))
                    {
                        taggableStat.tagList.Remove(Tags.AbilityTags.DoT);
                    }
                }
                // build damage stats if necessary
                foreach (DamageStatsHolder holder in effect.GetComponents <DamageStatsHolder>())
                {
                    holder.damageStats = DamageStats.buildDamageStats(holder, taggedStatsHolder);
                }
            }
            // add creation reference
            CreationReferences myReferences = GetComponent <CreationReferences>();
            if (myReferences)
            {
                CreationReferences references = effect.AddComponent <CreationReferences>();
                references.creator     = myReferences.creator;
                references.thisAbility = myReferences.thisAbility;
            }
            // add alignment
            AlignmentManager myAlignmentManager = GetComponent <AlignmentManager>();
            if (myAlignmentManager)
            {
                AlignmentManager alignmentManager = effect.AddComponent <AlignmentManager>();
                alignmentManager.alignment = myAlignmentManager.alignment;
            }
            // apply shock effect
            if (statusEffect.effectID == 13)
            {
                TaggedStatsHolder tsh = GetComponent <TaggedStatsHolder>();
                if (tsh)
                {
                    float      shockEffect = tsh.GetStatValue(Tags.Properties.IncreasedShockEffect);
                    BuffParent pb          = effect.GetComponent <BuffParent>();
                    if (shockEffect != 0 && pb)
                    {
                        foreach (TaggedStatsHolder.TaggableStat stat in pb.taggedStats)
                        {
                            stat.addedValue     *= (1 + shockEffect);
                            stat.increasedValue *= (1 + shockEffect);
                        }
                    }
                }
            }
            // apply
            protection.effectControl.AddEffect(effect, effect.GetComponent <StatusEffect>());
        }
    }
Пример #9
0
    void OnTriggerEnter(Collider hitObject)
    {
        // if the other object is an interactable then don't interact with it
        if (hitObject.gameObject.layer == 14)
        {
            return;
        }

        // if the other object is an ability object, e.g. another projectile, then don't interact with it
        if (hitObject.GetComponent <AbilityObjectIndicator>())
        {
            return;
        }

        // get the shared hit detector's lists
        if (sharedHitDetector != null)
        {
            enemiesHit = sharedHitDetector.enemiesHit;
            alliesHit  = sharedHitDetector.alliesHit;
        }

        // if the other object is dead, then don't interact with it
        StateController otherStateController = hitObject.GetComponent <StateController>();

        if (otherStateController && otherStateController.currentState == otherStateController.dying)
        {
            return;
        }

        // if this is an enemy that has already been hit then invoke an enemy hit again event
        if (enemiesHit.Contains(hitObject.gameObject))
        {
            if (enemyHitAgainEvent != null)
            {
                if (TryToHitEnemy(hitObject.gameObject))
                {
                    enemyHitAgainEvent.Invoke(hitObject.gameObject);
                    if (afterEnemyHitEvent != null)
                    {
                        afterEnemyHitEvent.Invoke(hitObject.gameObject);
                    }
                }
            }
            return;
        }

        // if this is an ally that has already been hit then invoke an ally hit again event
        if (alliesHit.Contains(hitObject.gameObject))
        {
            if (allyHitAgainEvent != null)
            {
                allyHitAgainEvent.Invoke(hitObject.gameObject);
                if (afterAllyHitEvent != null)
                {
                    afterAllyHitEvent.Invoke(hitObject.gameObject);
                }
            }
            return;
        }

        // check if the object hit is damageable
        AlignmentManager alignmentManager = GetComponent <AlignmentManager>();

        if (hitObject.GetComponent <BaseHealth>() != null && alignmentManager != null && alignmentManager.alignment != null)
        {
            // check that the object hit is a friend
            if (alignmentManager.alignment.isSameOrFriend(hitObject.GetComponent <AlignmentManager>().alignment))
            {
                // this is an enemy and this was not in the enemiesHit list so it is a new enemy
                alliesHit.Add(hitObject.gameObject);
                if (sharedHitDetector != null)
                {
                    sharedHitDetector.alliesHit.Add(hitObject.gameObject);
                }
                if (newAllyHitEvent != null)
                {
                    newAllyHitEvent.Invoke(hitObject.gameObject);
                    if (afterAllyHitEvent != null)
                    {
                        afterAllyHitEvent.Invoke(hitObject.gameObject);
                    }
                }
                return;
            }
            // if it is not with me, then it is against me....
            else
            {
                // this is an enemy and this was not in the enemiesHit list so it is a new enemy
                enemiesHit.Add(hitObject.gameObject);
                if (sharedHitDetector != null)
                {
                    sharedHitDetector.enemiesHit.Add(hitObject.gameObject);
                }
                if (newEnemyHitEvent != null)
                {
                    if (TryToHitEnemy(hitObject.gameObject))
                    {
                        newEnemyHitEvent.Invoke(hitObject.gameObject);
                        if (afterEnemyHitEvent != null)
                        {
                            afterEnemyHitEvent.Invoke(hitObject.gameObject);
                        }
                    }
                }
                return;
            }
        }


        // if it's got to this point, the thing being hit shows no signs of life
        if (inanimateHitEvent != null)
        {
            inanimateHitEvent.Invoke(hitObject.gameObject);
        }
    }
Пример #10
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();
        }
    }
Пример #11
0
    public GameObject constructAbilityObject(Ability ability, Vector3 location, Vector3 targetLocation, GameObject overridePrefab = null, bool InheritSharedHitDetector = true)
    {
        // create the ability object
        GameObject abilityObject = null;

        if (overridePrefab == null)
        {
            // if there is no override prefab instantiate the ability's ability prefab
            abilityObject = Instantiate(ability.abilityPrefab, location, Quaternion.Euler(targetLocation - location));
        }
        else // othewise instrantiate the override prefab
        {
            abilityObject = Instantiate(overridePrefab, location, Quaternion.Euler(targetLocation - location));
        }

        // apply the relevant mutator if this entity has one
        if (mutatorManager)
        {
            mutators = mutatorManager.getMutators(ability);
            if (mutators != null)
            {
                foreach (AbilityMutator mutator in mutators)
                {
                    abilityObject = mutator.Mutate(abilityObject, location, targetLocation);
                    if (mutator.changeLocation)
                    {
                        targetLocation = mutator.newLocation;
                    }
                    if (mutator.changeTargetLocation)
                    {
                        targetLocation = mutator.newTargetLocation;
                    }
                }
            }
        }

        // move the ability object if necessary
        foreach (DefineStartLocation defineStartLocation in abilityObject.GetComponents <DefineStartLocation>())
        {
            if (defineStartLocation.active)
            {
                defineStartLocation.setLocation(location, targetLocation);
                // the direction from the cast point needs to be maintained
                if (defineStartLocation.maintainDirectionFromCastPoint())
                {
                    targetLocation = abilityObject.transform.position + targetLocation - location;
                }
            }
        }


        // initialise a location detector if necessary
        LocationDetector locationDetector = abilityObject.GetComponent <LocationDetector>();

        if (locationDetector)
        {
            locationDetector.startLocation  = abilityObject.transform.position;
            locationDetector.targetLocation = targetLocation;
        }

        // rotate the ability object
        abilityObject.transform.LookAt(targetLocation);

        // give the ability object its alignment
        AlignmentManager abilityAlignmentManager = abilityObject.GetComponent <AlignmentManager>();

        if (!abilityAlignmentManager)
        {
            abilityAlignmentManager = abilityObject.AddComponent <AlignmentManager>();
        }
        abilityAlignmentManager.alignment = myAlignmentManager.alignment;

        // give the ability object its creation references
        CreationReferences abilityCreationReferences = abilityObject.GetComponent <CreationReferences>();

        if (!abilityCreationReferences)
        {
            abilityCreationReferences = abilityObject.AddComponent <CreationReferences>();
        }
        abilityCreationReferences.thisAbility         = ability;
        abilityCreationReferences.locationCreatedFrom = location;
        // if this an ability object then the creator is this objects creator, otherwise the creator is this object
        if (myCreationReferences && GetComponent <AbilityObjectIndicator>())
        {
            abilityCreationReferences.creator = myCreationReferences.creator;
        }
        else
        {
            abilityCreationReferences.creator = gameObject;
        }

        // check whether there should be a shared hit detector
        HitDetector abilityHitDetector = abilityObject.GetComponent <HitDetector>();

        if (abilityHitDetector)
        {
            SharedHitDetector sharedHitDetector = null;
            if (myHitDetector && myHitDetector.sharedHitDetector && InheritSharedHitDetector)
            {
                sharedHitDetector = myHitDetector.sharedHitDetector;
            }
            // create a shared hit detector
            else if (ability.sharedHitDetector)
            {
                GameObject newGameObject = new GameObject();
                sharedHitDetector = newGameObject.AddComponent <SharedHitDetector>();
                sharedHitDetector.gameObject.AddComponent <SelfDestroyer>();
                sharedHitDetector.name = abilityObject.name + "'s shared hit detector";
            }
            if (sharedHitDetector != null && !abilityHitDetector.cannotHaveSharedhitDetector)
            {
                abilityHitDetector.sharedHitDetector = sharedHitDetector;
            }
        }

        // build the damage stats for each damage stats holder
        foreach (DamageStatsHolder damageStatsHolder in abilityObject.GetComponents <DamageStatsHolder>())
        {
            damageStatsHolder.damageStats = DamageStats.buildDamageStats(damageStatsHolder, GetComponent <TaggedStatsHolder>());
        }

        // attach any on hit status appliers if this ability deals damage on hit
        if (myTaggedStatsHolder && abilityObject.GetComponent <DamageEnemyOnHit>() && !abilityObject.GetComponent <CannotApplyAdditionalStatuses>())
        {
            ChanceToApplyStatusOnEnemyHit applier;
            float poisonChance = myTaggedStatsHolder.GetStatValue(Tags.Properties.PoisonChance, ability.useTags);
            if (poisonChance > 0)
            {
                applier = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>();
                applier.statusEffect             = StatusEffectList.getEffect(StatusEffectID.Poison);
                applier.chance                   = poisonChance;
                applier.canApplyToSameEnemyAgain = false;
            }
            float igniteChance = myTaggedStatsHolder.GetStatValue(Tags.Properties.IgniteChance, ability.useTags);
            if (igniteChance > 0)
            {
                applier = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>();
                applier.statusEffect             = StatusEffectList.getEffect(StatusEffectID.Ignite);
                applier.chance                   = igniteChance;
                applier.canApplyToSameEnemyAgain = false;
            }
            float chillChance = myTaggedStatsHolder.GetStatValue(Tags.Properties.ChillChance, ability.useTags);
            if (chillChance > 0)
            {
                applier = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>();
                applier.statusEffect             = StatusEffectList.getEffect(StatusEffectID.Chill);
                applier.chance                   = chillChance;
                applier.canApplyToSameEnemyAgain = false;
            }
            float slowChance = myTaggedStatsHolder.GetStatValue(Tags.Properties.SlowChance, ability.useTags);
            if (slowChance > 0)
            {
                applier = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>();
                applier.statusEffect             = StatusEffectList.getEffect(StatusEffectID.Slow);
                applier.chance                   = slowChance;
                applier.canApplyToSameEnemyAgain = false;
            }
            float blindChance = myTaggedStatsHolder.GetStatValue(Tags.Properties.BlindChance, ability.useTags);
            if (blindChance > 0)
            {
                applier = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>();
                applier.statusEffect             = StatusEffectList.getEffect(StatusEffectID.Blind);
                applier.chance                   = blindChance;
                applier.canApplyToSameEnemyAgain = false;
            }

            float bleedChance = myTaggedStatsHolder.GetStatValue(Tags.Properties.BleedChance, ability.useTags);
            if (bleedChance > 0)
            {
                applier = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>();
                applier.statusEffect             = StatusEffectList.getEffect(StatusEffectID.Bleed);
                applier.chance                   = bleedChance;
                applier.canApplyToSameEnemyAgain = false;
            }
            float shockChance = myTaggedStatsHolder.GetStatValue(Tags.Properties.ShockChance, ability.useTags);
            if (shockChance > 0)
            {
                applier = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>();
                applier.statusEffect             = StatusEffectList.getEffect(StatusEffectID.Shock);
                applier.chance                   = shockChance;
                applier.canApplyToSameEnemyAgain = false;
            }
        }


        // if the ability has an ability object constructor give it a tagged stats holder with your tagged stats
        if (myTaggedStatsHolder && abilityObject.GetComponent <RequiresTaggedStats>())
        {
            TaggedStatsHolder holder = abilityObject.GetComponent <TaggedStatsHolder>();
            if (holder == null)
            {
                holder = abilityObject.AddComponent <TaggedStatsHolder>();
            }
            holder.simpleStats.AddRange(myTaggedStatsHolder.simpleStats);
            holder.taggedStats.AddRange(myTaggedStatsHolder.taggedStats);
        }

        // set the direction if there is an ability mover
        if (abilityObject.GetComponent <AbilityMover>())
        {
            abilityObject.GetComponent <AbilityMover>().positionDelta = Vector3.Normalize(targetLocation - location);
            // if the ability object defines its own start direction then let it
            if (abilityObject.GetComponent <DefineStartDirection>())
            {
                abilityObject.GetComponent <DefineStartDirection>().setDirection();
            }
        }

        // run any on creation methods
        foreach (OnCreation component in abilityObject.GetComponents <OnCreation>())
        {
            if (component.runOnCreation)
            {
                component.onCreation();
            }
        }

        // invoke the event
        if (abilityObjectCreatedEvent != null)
        {
            abilityObjectCreatedEvent.Invoke(ability, abilityObject);
        }

        return(abilityObject);
    }
    // Use this for initialization
    public override void onCreation()
    {
        Alignment alignment = GetComponent <AlignmentManager>().alignment;

        if (alignment == null)
        {
            Debug.LogError("AttachToNearestAllyOnCreation component on " + gameObject.name + " cannot function as alignment is null"); return;
        }
        // find a lit of alignment objects that belong to enemies
        List <AlignmentManager> alignments = new List <AlignmentManager>();

        if (moveToAllyInstead)
        {
            foreach (BaseHealth healthObject in BaseHealth.all)
            {
                if (alignment.friends.Contains(healthObject.GetComponent <AlignmentManager>().alignment))
                {
                    alignments.Add(healthObject.GetComponent <AlignmentManager>());
                }
            }
        }
        else
        {
            foreach (BaseHealth healthObject in BaseHealth.all)
            {
                if (alignment.foes.Contains(healthObject.GetComponent <AlignmentManager>().alignment))
                {
                    alignments.Add(healthObject.GetComponent <AlignmentManager>());
                }
            }
        }
        // remove dying objects from the list
        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]);
                }
            }
        }
        if (alignments.Count == 0)
        {
            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);
                }
            }

            // only move if the nearest one is within range
            if (distance < maxRange)
            {
                // move to the enemy's location
                transform.position = nearestAlignment.transform.position + offset;
                //// change to the ally's rotation
                //transform.rotation = transform.parent.rotation;
            }
        }
    }
Пример #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();
            }
        }
    }