示例#1
0
        //a method called when the unit's health has been updated:
        public override void OnHealthUpdated(int value, FactionEntity source)
        {
            base.OnHealthUpdated(value, source);
            CustomEvents.OnUnitHealthUpdated(unit, value, source);

            if (value < 0)                                     //if the unit's health has been decreased
            {
                unit.SetAnimState(UnitAnimState.takingDamage); //set the animator state to taking damage.

                if (stopMovingOnDamage == true)                //stop player movement on damage if this is set to true
                {
                    unit.MovementComp.Stop();
                }
                if (enableDamageAnimation == true)                   //if the damage animation is enabled
                {
                    damageAnimationTimer  = damageAnimationDuration; //start the timer.
                    damageAnimationActive = true;                    //mark as active
                }

                if (source != null && (GameManager.MultiplayerGame == false || RTSHelper.IsLocalPlayer(unit) == true)) //if the attack source is known and this is either a single player game or the local player's unit
                {
                    //if the unit has an attack component and it can attack back and it is idle
                    if (unit.AttackComp != null && unit.AttackComp.IsActive() && unit.AttackComp.CanEngageWhenAttacked() == true && unit.IsIdle() == true)
                    {
                        gameMgr.MvtMgr.LaunchAttack(unit, source, source.GetSelection().transform.position, MovementManager.AttackModes.none, false); //launch attack at the source
                    }
                    TriggerEscapeOnAttack();                                                                                                          //attempt to trigger the escape on attack behavior if it is enabled
                }
            }
        }
        //cancel an in progress task of this type
        public void Cancel()
        {
            switch (type)
            {
            case TaskTypes.createUnit:

                //update the population slots
                gameMgr.GetFaction(factionEntity.FactionID).UpdateCurrentPopulation(-UnitPopulationSlots);

                //update the limits list:
                factionEntity.FactionMgr.UpdateLimitsList(UnitCode, UnitCategory, false);
                break;
            }

            gameMgr.ResourceMgr.UpdateRequiredResources(requiredResources, true, factionEntity.FactionID); //Give back the task resources.

            cancelEvent.Invoke();                                                                          //trigger unity event.

            //if the task was supposed to be used once but is cancelled:
            if (useMode != UseMode.multiple)
            {
                IsAvailable = true;                      //make it available again.
                if (useMode == UseMode.onceAllInstances) //if this was marked as usable once for all instances.
                {
                    gameMgr.TaskMgr.Status.ToggleTask(code, factionEntity.FactionID, true);
                }
            }

            if (factionEntity.FactionID == GameManager.PlayerFactionID && factionEntity.GetSelection().IsSelected) //if this is the local player and the faction entity is selected
            {
                AudioManager.Play(gameMgr.GetGeneralAudioSource(), cancelAudio, false);
            }
        }
示例#3
0
        //search for a target to attack
        private void SearchTarget()
        {
            //first pick the search center and size/range (if this is an AI unit defending a range center, the search range and size are that of the building center).
            float   searchSize   = (SearchRangeCenter == null) ? searchRange : SearchRangeCenter.Size;
            Vector3 searchCenter = (SearchRangeCenter == null) ? transform.position : SearchRangeCenter.transform.position;

            FactionEntity potentialTarget = null; //this will hold the potential target faction entity
            float         currDistance    = 0.0f;

            //go through the enemy faction entities of the attack entity's faction
            foreach (FactionEntity enemyEntity in (FactionEntity.IsFree() == true || engageFriendly) ? gameMgr.UnitMgr.GetAllUnits() : FactionEntity.FactionMgr.GetEnemyFactionEntities())
            {
                if (enemyEntity == null || enemyEntity.enabled == false || enemyEntity.EntityHealthComp.IsDead() == true || enemyEntity == FactionEntity as Unit)
                {
                    continue; //move to the next enemy faction entity in case the Unit's component is not enabled or the entity isn't alive
                }
                //if the enemy faction entity is inside the current search size and it can be attacked
                if ((currDistance = Vector3.Distance(enemyEntity.transform.position, searchCenter)) < searchSize && CanEngageTarget(enemyEntity) == ErrorMessage.none)
                {
                    searchSize      = currDistance; //this will always decrease the search size to the closest enemy entity
                    potentialTarget = enemyEntity;
                }
            }

            if (potentialTarget != null)
            {
                SetTarget(potentialTarget, potentialTarget.GetSelection().transform.position); //if there's a potential target found, set it as next target
            }
        }
示例#4
0
        //attack the assigned target.
        void AttackTarget()
        {
            //making sure that the NPC faction in an attack in progress and that there's a valid target:
            if (currentTarget == null || isAttacking == false)
            {
                return;
            }

            MovementManager.AttackModes attackMode = MovementManager.AttackModes.none;

            Building targetBuilding = currentTarget.Type == EntityTypes.building ? (Building)currentTarget : null; //is this target a building?

            //if the current target is a building and it is being constructed:
            if (targetBuilding != null && targetBuilding.WorkerMgr.currWorkers > 0)
            {
                Unit[] workersList = targetBuilding.WorkerMgr.GetAll(); //get all workers in the worker manager
                //attack the workers first: go through the workers positions
                for (int i = 0; i < workersList.Length; i++)
                {
                    //find worker:
                    if (workersList[i] != null && workersList[i].BuilderComp.IsInProgress() == true)
                    {
                        //assign it as target.
                        currentTarget = workersList[i];
                        //force attack units to attack it:
                        attackMode = MovementManager.AttackModes.change;
                    }
                }
            }

            //launch the actual attack:
            gameMgr.MvtMgr.LaunchAttack(currentAttackUnits, currentTarget, currentTarget.GetSelection().transform.position, attackMode, false);
        }
示例#5
0
        //health related events:
        private void OnFactionEntityHealthUpdated(FactionEntity factionEntity, int value, FactionEntity source)
        {
            hoverHealthBar.Update(factionEntity);                           //update the hover health bar in case this unit is selected

            if (factionEntity.GetSelection().IsSelectedOnly)                //if this is the only selected entity
            {
                singleSelection.UpdateFactionEntityHealthUI(factionEntity); //update the health UI.
            }
        }
示例#6
0
        //a method that destroys a faction entity locally
        public virtual void DestroyFactionEntityLocal(bool upgrade)
        {
            gameMgr.SelectionMgr.Selected.Remove(factionEntity); //deselect the faction entity if it was selected

            //faction entity death:
            isDead     = true;
            CurrHealth = 0;

            //remove the minimap icon:
            factionEntity.GetSelection().DisableMinimapIcon();

            //If this is no upgrade
            if (upgrade == false)
            {
                factionEntity.Disable(true);

                CustomEvents.OnFactionEntityDead(factionEntity); //call the custom events

                if (destructionEffect != null)                   //do not show desctruction effect if it's not even assigned
                {
                    //get the destruction effect from the pool
                    EffectObj newDestructionEffect = gameMgr.EffectPool.SpawnEffectObj(destructionEffect, transform.position, Quaternion.identity);

                    //destruction sound effect
                    if (destructionAudio != null)
                    {
                        //Check if the destruction effect object has an audio source:
                        if (newDestructionEffect.GetComponent <AudioSource>() != null)
                        {
                            AudioManager.Play(newDestructionEffect.GetComponent <AudioSource>(), destructionAudio, false); //play the destruction audio
                        }
                        else
                        {
                            Debug.LogError("A destruction audio clip has been assigned but the destruction effect object doesn't have an audio source!");
                        }
                    }
                }
            }

            //Destroy the faction entity's object:
            if (destroyObject == true) //only if object destruction is allowed
            {
                Destroy(gameObject, !upgrade ? destroyObjectTime : 0.0f);
                IsDestroyed = true;
            }
        }
示例#7
0
 //called when a unit requests support from nearby units:
 void OnUnitSupportRequest(Vector3 pos, FactionEntity target)
 {
     //if the unit support feature is disabled
     if (unitSupportEnabled == false)
     {
         return; //do not proceed.
     }
     //go through the faction's attack units:
     foreach (Unit u in factionMgr.GetAttackUnits())
     {
         //check if the unit is within the required distance:
         if (Vector3.Distance(u.transform.position, pos) < unitSupportRange.getRandomValue())
         {
             //request support (as long as the unit isn't busy):
             gameMgr.MvtMgr.LaunchAttack(u, target, target.GetSelection().transform.position, MovementManager.AttackModes.none, false);
         }
     }
 }
示例#8
0
        /// <summary>
        /// Called when a faction entity requests support from nearby NPC units
        /// </summary>
        /// <param name="position">The position where the support request has been initiated.</param>
        /// <param name="target">The target that has to be eliminated.</param>
        /// <returns>True if the support request has successfully processed, otherwise false.</returns>
        public bool OnUnitSupportRequest(Vector3 position, FactionEntity target)
        {
            //if the unit support feature is disabled or the target is invalid
            if (!unitSupportEnabled || target == null)
            {
                return(false); //do not proceed.
            }
            //pick the next support range:
            float nextSupportRange = unitSupportRange.getRandomValue();

            //get attack units inside the chosen support range
            List <Unit> inRangeAttackUnits = factionMgr.GetAttackUnits()
                                             .Where(unit => Vector3.Distance(unit.transform.position, position) <= nextSupportRange).ToList();

            if (inRangeAttackUnits.Count > 0)
            {
                //request support (as long as the unit isn't busy):
                gameMgr.MvtMgr.LaunchAttack(inRangeAttackUnits, target, target.GetSelection().transform.position, MovementManager.AttackModes.none, false);
            }

            return(true);
        }
        /// <summary>
        /// Orders the NPC faction to engage its currently set target.
        /// </summary>
        public void EngageCurrentTarget()
        {
            if (!IsAttacking || //not actively attacking?
                currentTarget == null || //has a current target?
                targetFaction == null || //no target faction assigned?
                gameMgr.InPeaceTime() || //or still in peace time?
                currentAttackUnits.Count == 0)    //or no more attack units?
            {
                return;
            }

            MovementManager.AttackModes attackMode = MovementManager.AttackModes.none;

            //if the current target is a building and it is being constructed:
            if (currentTarget.Type == EntityTypes.building && (currentTarget as Building).WorkerMgr.currWorkers > 0)
            {
                Unit[] workersList = (currentTarget as Building).WorkerMgr.GetAll(); //get all workers in the worker manager
                //attack the workers first: go through the workers positions
                for (int i = 0; i < workersList.Length; i++)
                {
                    //find worker:
                    if (workersList[i] != null && workersList[i].BuilderComp.IsInProgress() == true)
                    {
                        //assign it as target.
                        currentTarget = workersList[i];
                        //force attack units to attack it:
                        attackMode = MovementManager.AttackModes.change;
                    }
                }
            }

            //launch the actual attack:
            gameMgr.MvtMgr.LaunchAttack(
                //if only idle units can be sent to attack, make sure this is the case.
                sendOnlyIdle ? currentAttackUnits.Where(unit => unit.IsIdle()).ToList() : currentAttackUnits
                , currentTarget, currentTarget.GetSelection().transform.position, attackMode, false);
        }
示例#10
0
 }                                               //the current attack target
 //the target position is either the assigned target's current position or the last registered target position
 public Vector3 GetTargetPosition()
 {
     return(Target ? Target.GetSelection().transform.position : lastTargetPosition);
 }