示例#1
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);
        }
        /// <summary>
        /// Launches an attack on the NPC faction's current target faction.
        /// </summary>
        /// <returns>True if the attack has been successfully launched, otherwise false.</returns>
        public bool LaunchAttack()
        {
            //making sure there's a valid target faction or we're in the peace time
            if (targetFaction == null || gameMgr.InPeaceTime())
            {
                return(false);
            }

            //mark as attacking:
            IsAttacking = true;

            RefreshCurrentAttackUnits();

            //we'll be searching for the next building to attack starting from the last attack pos, initially set it as the capital building
            lastAttackPos = gameMgr.GetFaction(factionMgr.FactionID).CapitalPosition;

            currentTarget = null;
            //pick a target building:
            SetTargetEntity(targetFaction.GetBuildings().Cast <FactionEntity>(), true);

            //start the attack order timer:
            attackOrderTimer = attackOrderReloadRange.getRandomValue();

            return(true);
        }
示例#3
0
        //a method that picks a target entity to attack:
        private bool SetTargetEntity(IEnumerable <FactionEntity> factionEntities)
        {
            //search the target faction's entities and see if there's a match:
            float lastDistance = 0; //we wanna get the closest entity to the last attack position:

            foreach (FactionEntity entity in factionEntities)
            {
                //if the building is valid and not destroyed yet
                if (entity != null && entity.EntityHealthComp.IsDestroyed == false)
                {
                    //and the building's code matches or this is an eliminate all game:
                    if (gameMgr.GetDefeatCondition() == DefeatConditions.eliminateAll || targetBuildingCodes.Contains(entity.GetCode()))
                    {
                        //get the closest building:
                        if (currentTarget == null || Vector3.Distance(currentTarget.transform.position, lastAttackPos) < lastDistance)
                        {
                            currentTarget = entity;
                            lastDistance  = Vector3.Distance(entity.transform.position, lastAttackPos);
                        }
                    }
                }
            }

            return(currentTarget != null);
        }
示例#4
0
        //method to launch the attack:
        void LaunchAttack()
        {
            //making sure there's a valid target faction:
            if (targetFaction == null)
            {
                return;
            }

            //mark as attacking:
            isAttacking = true;

            //clear the current attack units list:
            currentAttackUnits.Clear();
            currentAttackUnits.AddRange(factionMgr.GetAttackUnits(1 - npcMgr.defenseManager_NPC.defenseRatioRange.getRandomValue())); //get the required units for this attack.

            //we'll be searching for the next building to attack starting from the last attack pos, initially set it as the capital building
            lastAttackPos = gameMgr.GetFaction(factionMgr.FactionID).CapitalPosition;

            currentTarget = null;
            //pick a target building:
            SetTargetEntity(targetFaction.GetBuildings().Cast <FactionEntity>());

            //start the attack order timer:
            attackOrderTimer = attackOrderReloadRange.getRandomValue();
        }
示例#5
0
        //a method called when the faction entity's health hits null:
        public virtual void OnZeroHealth(int value, FactionEntity source)
        {
            //set it back to 0.0f as we don't allow negative health values.
            CurrHealth = 0;

            //if the faction entity isn't already dead:
            if (isDead == false)
            {
                isDead   = true;   //mark as dead
                KilledBy = source; //assign the source that caused the death of this faction entity

                //is there a valid source that caused the death of this faction entity?
                if (source != null)
                {
                    //award the destroy award to the source if the source is not the same faction ID:
                    if (destroyAward.Length > 0 && source.FactionID != factionEntity.FactionID)
                    {
                        for (int i = 0; i < destroyAward.Length; i++)
                        {
                            //award destroy resources to source:
                            gameMgr.ResourceMgr.UpdateResource(source.FactionID, destroyAward[i].Name, destroyAward[i].Amount);
                        }
                    }
                }


                //destroy the faction entity
                DestroyFactionEntity(false);
            }
        }
        /// <summary>
        /// Sets the current target of the NPC faction to the closest from an enumerable of FactionEntity instances.
        /// </summary>
        /// <param name="factionEntities">The enumerable of FactionEntity instances to pick a target from.</param>
        /// <param name="clearCurrentTarget">False if you want to keep the current target if no valid target is found.</param>
        /// <returns>True if the target has been successfully set, otherwise false.</returns>
        public bool SetTargetEntity(IEnumerable <FactionEntity> factionEntities, bool clearCurrentTarget)
        {
            if (clearCurrentTarget)
            {
                ResetCurrentTarget();
            }

            //search the target faction's entities and see if there's a match:
            float lastDistance = 0; //we wanna get the closest entity to the last attack position:

            foreach (FactionEntity entity in factionEntities)
            {
                if (!IsValidTarget(entity)) //can't be a valid target?
                {
                    continue;               //move to next one
                }
                //get the closest possible entity
                if (currentTarget == null || Vector3.Distance(currentTarget.transform.position, lastAttackPos) < lastDistance)
                {
                    currentTarget = entity;
                    lastDistance  = Vector3.Distance(entity.transform.position, lastAttackPos);
                }
            }

            return(currentTarget != null);
        }
示例#7
0
        public override void Init(GameManager gameMgr, FactionEntity source)
        {
            base.Init(gameMgr, source);

            unit       = (Unit)source;
            CurrHealth = MaxHealth; //unit has maximum health by default
        }
示例#8
0
        public void UpdateTaskLauncherTasks(FactionEntity sourceEntity, TaskLauncher taskLauncher)
        {
            if (taskLauncher == null || taskLauncher.Initiated == false || taskLauncher.GetTasksCount() == 0) //if the task launcher is invalid or the source can't manage a task
            {
                return;
            }

            for (int taskID = 0; taskID < taskLauncher.GetTasksCount(); taskID++) //go through all tasks
            {
                FactionEntityTask task = taskLauncher.GetTask(taskID);
                if (task.IsEnabled() == true)
                {
                    TaskUI taskUI = Add(new TaskUIAttributes
                    {
                        ID           = taskID,
                        type         = task.GetTaskType(),
                        icon         = task.GetIcon(),
                        source       = sourceEntity,
                        taskLauncher = taskLauncher
                    }, task.GetTaskPanelCategory());

                    if (task.GetTaskType() == TaskTypes.createUnit) //if this is a unit creation task, check if it has reached its limit and change task ui image color accordinly
                    {
                        taskUI.GetComponent <Image>().color = sourceEntity.FactionMgr.HasReachedLimit(task.UnitCode, task.UnitCategory) == true ? Color.red : Color.white;
                    }
                }
            }

            UpdateInProgressTasks(taskLauncher); //show the in progress tasks
        }
示例#9
0
 //trigger unit/building upgrades locally:
 private void LaunchTriggerUpgrades(IEnumerable <Upgrade> upgrades, FactionEntity upgradeLauncher)
 {
     foreach (Upgrade u in upgrades)
     {
         LaunchUpgrade(u, 0, upgradeLauncher, false); //will trigger the upgrade for the first target only!
     }
 }
示例#10
0
        //when the building's health is updated
        public override void OnHealthUpdated(int value, FactionEntity source)
        {
            base.OnHealthUpdated(value, source);
            CustomEvents.OnBuildingHealthUpdated(building, value, source);

            CheckState(value > 0); //check the building's state
        }
示例#11
0
        //a method that launches the attack movement of a list of units
        public void LaunchAttack(List <Unit> units, FactionEntity targetEntity, Vector3 targetPosition, AttackModes attackMode, bool playerCommand)
        {
            if (units.Count == 1) //one unit only?
            {
                //use the one-unit attack movement
                LaunchAttack(units[0], targetEntity, targetPosition, attackMode, playerCommand);
                return;
            }

            if (GameManager.MultiplayerGame == false) //single player game, directly prepare the unit's attack movement
            {
                PrepareMove(units, targetPosition, targetEntity ? targetEntity.GetRadius() : 0.0f, targetEntity,
                            InputMode.attack, playerCommand, true, attackMode, targetEntity);
            }
            else if (RTSHelper.IsLocalPlayer(units[0]) == true) //multiplayer game and this is the local player
            {
                //send input action to the input manager
                NetworkInput newInput = new NetworkInput()
                {
                    sourceMode     = (byte)InputMode.unitGroup,
                    targetMode     = (byte)InputMode.attack,
                    targetPosition = targetPosition,
                    value          = (int)attackMode,
                    groupSourceID  = InputManager.UnitListToString(units)
                };

                //sent input
                InputManager.SendInput(newInput, null, targetEntity);
            }
        }
示例#12
0
        public void Init(FactionEntity factionEntity)
        {
            this.factionEntity = factionEntity;

            AttackEntities = GetComponents <AttackEntity>(); //get all attack entity components attached to the faction entity
            if (AttackEntities.Length < 1)                   //if there's no more than one attack entity component
            {
                Destroy(this);                               //no need to have this component
                return;
            }

            activeAttack = null;
            for (int i = 0; i < AttackEntities.Length; i++) //go through the attack components
            {
                AttackEntities[i].ID = i;                   //set the attack entity ID for each attack component (will be used by UI task buttons to refer to the attack components).
                if (AttackEntities[i].IsBasic() == true)    //if this is the basic attack
                {
                    BasicAttackID = i;
                    SetActiveAttack(i);
                }
                else
                {
                    AttackEntities[i].Toggle(false);
                }
            }
        }
示例#13
0
        //check if the attacker can engage target:
        public ErrorMessage CanEngageTarget(FactionEntity potentialTarget)
        {
            if (gameMgr.InPeaceTime() == true)
            {
                return(ErrorMessage.peaceTime);
            }
            else if (potentialTarget == null)                                                   //if there's no target assigned
            {
                return(!requireTarget ? ErrorMessage.none : ErrorMessage.attackTargetRequired); //see if the attack entity can attack without target
            }
            else if (potentialTarget.FactionID == FactionEntity.FactionID && engageFriendly == false)
            {
                return(ErrorMessage.targetSameFaction);
            }
            else if (potentialTarget.EntityHealthComp.CanBeAttacked == false) //peace time, same faction ID or target can't be attacked? -> nope
            {
                return(ErrorMessage.targetNoAttack);
            }

            if (engageAllTypes) //attack all types then yes!
            {
                return(ErrorMessage.none);
            }

            //if the target can't attack units/buildings and this is the case then nope
            if ((potentialTarget.Type == EntityTypes.building && engageBuildings == false) ||
                (potentialTarget.Type == EntityTypes.unit && engageUnits == false))
            {
                return(ErrorMessage.entityNotAllowed);
            }

            return(codesList.Contains(potentialTarget.GetCode(), potentialTarget.GetCategory()) == engageInList ? ErrorMessage.none : ErrorMessage.entityNotAllowed);
        }
示例#14
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
            }
        }
示例#15
0
        //called each time a unit/building is dead, only called when the mission type is set to "eliminate" or "produce"
        private void OnFactionEntityEvent (FactionEntity factionEntity)
        {
            //if the faction entity is dead and there are entities that the player is supposed to defend
            if(factionEntity.FactionID == GameManager.PlayerFactionID //only if the dead faction entity belongs to the player faction
                && defendFactionEntities.Length > 0 && factionEntity.EntityHealthComp.IsDead()) 
            {
                foreach(CodeCategoryField codeCategory in defendFactionEntities) //go through the entities that shouldn't be dead
                {
                    if (codeCategory.Contains(factionEntity.GetCode(), factionEntity.GetCategory())) //if the code/category matches
                    {
                        Forfeit(); //mission failed
                        return;
                    }
                }
            }

            if((factionEntity.EntityHealthComp.IsDead() && type == Type.eliminate && factionEntity.FactionID != GameManager.PlayerFactionID) //if this is an elimination mission and the entity doesn't belong to the player's faction
                || (!factionEntity.EntityHealthComp.IsDead() && type == Type.produce && factionEntity.FactionID == GameManager.PlayerFactionID)) //produce mission type and the entity belongs to the player faction
            foreach (CodeCategoryField codeCategory in targetCode) //go through all assigned codes
            {
                if (codeCategory.Contains(factionEntity.GetCode(), factionEntity.GetCategory())) //if the code/category matches
                {
                    OnProgress(1); //positive mission progress
                    break;
                }
            }
        }
示例#16
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
                }
            }
        }
示例#17
0
        public void UpdateMultipleAttackTasks(FactionEntity sourceEntity, MultipleAttackManager multipleAttackComp)
        {
            if (multipleAttackComp == null)
            {
                return;
            }

            for (int attackID = 0; attackID < multipleAttackComp.AttackEntities.Length; attackID++) //go through all the attack entities
            {
                AttackEntity attackComp = multipleAttackComp.AttackEntities[attackID];
                if (!attackComp.IsLocked && !attackComp.IsActive()) //as long as the attack entity is not active and not locked, show a task to activate it:
                {
                    TaskUI taskUI = Add(new TaskUIAttributes
                    {
                        ID     = attackID,
                        type   = TaskTypes.attackTypeSelection,
                        icon   = attackComp.GetIcon(),
                        source = sourceEntity
                    }, multipleAttackComp.GetTaskPanelCategory());

                    if (attackComp.CoolDownActive == true) //if the attack type is in cool down mode
                    {
                        Color nextColor = taskUI.GetComponent <Image>().color;
                        nextColor.a = 0.5f; //make it semi-transparent to indicate cooldown to player
                        taskUI.GetComponent <Image>().color = nextColor;
                    }
                }
            }
        }
示例#18
0
        private bool triggerAnimationInDelay = false;                           //true => the attack animation is triggered when the delay starts. if false, it will only be triggered when the attack is triggered

        public override void Init(GameManager gameMgr, FactionEntity factionEntity, MultipleAttackManager multipleAttackMgr)
        {
            base.Init(gameMgr, factionEntity, multipleAttackMgr);
            this.unit = (Unit)factionEntity;

            RangeType = gameMgr.AttackMgr.GetRangeType(rangeTypeCode);
        }
示例#19
0
 //called each time a faction entity switches its attack:
 private void OnAttackSwitch(AttackEntity attackEntity, FactionEntity target, Vector3 targetPosition)
 {
     //only if the source faction entity is the only player entity selected
     if (SelectionManager.IsSelected(attackEntity.FactionEntity.GetSelection(), true, true))
     {
         Update();
     }
 }
示例#20
0
 public bool IsFree() //is the entity managed by this selection component a faction entity or a free one?
 {
     if (FactionEntity != null)
     {
         return(FactionEntity.IsFree());
     }
     return(false);
 }
 /// <summary>
 /// Tests whether a FactionEntity can be a potential target for the NPC faction.
 /// </summary>
 /// <param name="potentialTarget">The FactionEntity instance to test.</param>
 /// <returns>True if the potential target can be assigned as a target, otherwise false.</returns>
 public bool IsValidTarget(FactionEntity potentialTarget)
 {
     return(potentialTarget != null && //must be valid
            !potentialTarget.EntityHealthComp.IsDead() && //must be still alive
            targetFaction != null && //there must be a target faction
            potentialTarget.FactionID == targetFaction.FactionID //factionID must match the target faction's ID
                                                                 //if the entity can be targeted by the NPC faction or this is an eliminate all game:
            && (gameMgr.GetDefeatCondition() == DefeatConditions.eliminateAll || targetPicker.IsValidTarget(potentialTarget)));
 }
示例#22
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.
            }
        }
示例#23
0
        //the method that updates the health bar of the unit/building that the player has their mouse on.
        public void Update(FactionEntity source)
        {
            if (enabled == false || source != currSource) //if the hover health bar is disabled
            {
                return;
            }

            healthBar.Update(source.EntityHealthComp.CurrHealth / (float)source.EntityHealthComp.MaxHealth);
        }
示例#24
0
        public virtual void Init(GameManager gameMgr, FactionEntity source)
        {
            this.gameMgr  = gameMgr;
            factionEntity = source; //get the Faction Entity component.
            //initial settings:
            isDead = false;         //faction entity is not dead by default.

            DotComps = new List <DamageOverTime>();
        }
示例#25
0
        //a method that upgrades a faction entity instance locally
        public void UpgradeInstance(FactionEntity instance, FactionEntity target, int factionID, EffectObj upgradeEffect)
        {
            switch (instance.Type)
            {
            case EntityTypes.building:

                Building currBuilding = instance as Building;
                Unit[]   currBuilders = currBuilding.WorkerMgr.GetAll(); //get the current builders of this building if there are any
                foreach (Unit unit in currBuilders)                      //and make them stop building the instance of the building since it will be destroyed.
                {
                    unit.BuilderComp.Stop();
                }

                //create upgraded instance of the building
                Building upgradedBuilding = gameMgr.BuildingMgr.CreatePlacedInstanceLocal(
                    (Building)target,
                    instance.transform.position,
                    target.transform.rotation.eulerAngles.y,
                    ((Building)instance).CurrentCenter,
                    factionID,
                    currBuilding.IsBuilt,     //depends on the current state of the instance to destroy
                    ((Building)instance).FactionCapital);

                foreach (Unit unit in currBuilders)
                {
                    unit.BuilderComp.SetTarget(upgradedBuilding);
                }

                CustomEvents.OnBuildingInstanceUpgraded((Building)instance);     //trigger custom event
                break;

            case EntityTypes.unit:

                //create upgraded instance of the unit
                gameMgr.UnitMgr.CreateUnit(
                    (Unit)target,
                    instance.transform.position,
                    instance.transform.rotation,
                    instance.transform.position,
                    factionID,
                    null);

                CustomEvents.OnUnitInstanceUpgraded((Unit)instance);     //trigger custom event
                break;
            }

            //if there's a valid upgrade effect assigned:
            if (upgradeEffect != null)
            {
                //show the upgrade effect for the player:
                gameMgr.EffectPool.SpawnEffectObj(upgradeEffect, instance.transform.position, upgradeEffect.transform.rotation);
            }

            instance.EntityHealthComp.DestroyFactionEntity(true); //destroy the instance
        }
示例#26
0
        public void Init(GameManager gameMgr, FactionEntity source)
        {
            this.gameMgr  = gameMgr;
            FactionEntity = source;

            if (interactionPosition == null)     //no interaction position is assigned
            {
                interactionPosition = transform; //assign the interaction position to the faction entity's position
            }
            currCapacity = 0;
        }
示例#27
0
        //a method called by the Selection Manager to attempt to select the object associated with this selection entity
        public virtual void OnSelected()
        {
            if (FactionEntity)                                                                     //if this is a faction entity
            {
                FactionEntity.OnMouseClick();                                                      //trigger a mouse click in the faction entity's main component
            }
            AudioManager.Play(gameMgr.GetGeneralAudioSource(), Source.GetSelectionAudio(), false); //play the selection audio
            Source.EnableSelectionPlane();                                                         //enable the selection plane of the source

            IsSelected = true;
            CustomEvents.OnEntitySelected(Source);
        }
示例#28
0
        //when the building reaches its max health:
        public override void OnMaxHealthReached(int value, FactionEntity source)
        {
            base.OnMaxHealthReached(value, source);

            Unit[] workersList = building.WorkerMgr.GetAll(); //get all workers in the worker manager

            for (int i = 0; i < workersList.Length; i++)
            {
                workersList[i].BuilderComp.Stop(); //stop constructing
            }
            CompleteConstruction();
        }
示例#29
0
        //a method called when the faction entity's health has been updated:
        public virtual void OnHealthUpdated(int value, FactionEntity source)
        {
            if (value < 0.0)
            {
                //if this is the local player's faction ID and the attack warning manager is active:
                if (factionEntity.FactionID == GameManager.PlayerFactionID)
                {
                    gameMgr.AttackWarningMgr?.Add(transform.position); //show attack warning on minimap
                }
            }

            CustomEvents.OnFactionEntityHealthUpdated(factionEntity, value, source); //trigger custom event
        }
示例#30
0
        //a method that returns the damage that is supposed to be dealt to a target.
        public int GetDamage(FactionEntity target)
        {
            foreach (CustomDamage cd in customDamages)                        //see if the target's code is in the custom damages list
            {
                if (cd.code.Contains(target.GetCode(), target.GetCategory())) //if the target is found then pick the custom damage
                {
                    return(cd.damage);
                }
            }

            //no custom damage? pick either the damage for units or for buildings
            return(target.Type == EntityTypes.unit ? unitDamage : buildingDamage);
        }