예제 #1
0
        /// <summary>
        /// Starts turn for this brain.
        /// </summary>
        /// <param name="brainController">BrainController</param>
        public void StartTurn(BrainController brainController)
        {
            // TODO: if the enemy is too close, step back a little to attack distance.
            var brainVariables = brainController.GetComponent <FightBrainVariables>();

            brainVariables.turn      = true;
            brainVariables.turnEnded = false;
            // Check the enemy. It can be dead.
            if (brainVariables.currentEnemy.avatarController.avatarStats.IsAlive == false)
            {
                brainVariables.currentEnemy = brainVariables.fightController.GetClosestEnemy(brainController);
                Logger.LogMessage($"{brainController.gameObject.name}::StartTurn " +
                                  $"-- enemy is dead. Getting new enemy : {brainVariables.currentEnemy}");
            }
            var distanceToEnemy = Mathf.Abs(brainController.transform.position.x - brainVariables.currentEnemy.transform.position.x);

            // FIXME: Change this check if any other moving action will be implemented.
            if (distanceToEnemy > brainController.Stats.attackDistance && brainVariables.nextAction != runAction)
            {
                brainVariables.nextAction = GetNextAction(brainController);
            }
            if (brainVariables.nextAction == null)
            {
                Logger.LogMessage($"{name}::StartTurn -- nextAction is null.", LogType.Error);
                return;
            }
            brainVariables.currentAction = brainVariables.nextAction;
            Logger.LogMessage($"{brainController.gameObject.name}::StartTurn -- currentEnemy = {brainVariables.currentEnemy.gameObject.name}; " +
                              $"currentAction = {brainVariables.currentAction.name}");
            brainVariables.currentAction.InitAction(brainController);
            brainVariables.spriteSortOrder = brainController.animationController.SpriteSortOrder;
            // HACK: Hardcoded max sort order.
            // TODO: Also reorder text panels.
            brainController.animationController.SpriteSortOrder = 300;
        }
예제 #2
0
        /// <summary>
        /// Update function to be called once each update.
        /// </summary>
        /// <param name="brainController">BrainController</param>
        /// <returns>actionEnded</returns>
        public override void UpdateBrain(BrainController brainController)
        {
            var brainVariables = brainController.GetComponent <FightBrainVariables>();

            if (brainVariables.turn != false)
            {
                //Logger.LogMessage($"{brainController.gameObject.name}::UpdateBrain -- ")
                if (brainVariables.turnEnded)
                {
                    EndTurn(brainController);
                }
                else if (brainVariables.currentAction != null)
                {
                    brainVariables.turnEnded = brainVariables.currentAction.Act(brainController);
                }
            }
            else if (brainVariables.currentAction != null)
            {
                if (brainVariables.currentAction.Act(brainController))
                {
                    brainVariables.currentAction = null;
                    //brainController.animationController.TriggerAnimation(ildeAnimationTrigger);
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Act function to be called once each update.
        /// </summary>
        /// <param name="brainController">BrainController</param>
        /// <returns>actionEnded</returns>
        public override bool Act(BrainController brainController)
        {
            var brainVariables = brainController.GetComponent <FightBrainVariables>();

            if (brainController.animationEventHandler.damageDealt &&
                brainController.animationEventHandler.animationTrigger == animationTrigger)
            {
                DealDamage(brainController);
                brainController.animationEventHandler.damageDealt = false;
            }
            var animationEnded       = brainController.animationEventHandler.animationEnded;
            var sameAnimationTrigger = brainController.animationEventHandler.animationTrigger == animationTrigger;

            Logger.LogMessage($"{brainController.gameObject.name}::FightAttackAction::Act -- animationEnded = {animationEnded}, " +
                              $"sameAnimationTrigger = {sameAnimationTrigger}");
            bool enemyIsActing       = false;
            var  enemyFightVariables = brainVariables.currentEnemy.GetComponent <FightBrainVariables>();

            if (enemyFightVariables == null)
            {
                Logger.LogMessage($"{brainVariables.currentEnemy.gameObject.name} is in fight but has no FightBrainVariables", LogType.Error);
            }
            else
            {
                enemyIsActing = enemyFightVariables.currentAction != null;
            }
            return(animationEnded && sameAnimationTrigger && enemyIsActing == false);
        }
예제 #4
0
        /// <summary>
        /// Initializing function for brain.
        /// </summary>
        /// <param name="brainController">BrainController</param>
        public override void InitBrain(BrainController brainController)
        {
            var brainVariables = brainController.GetComponent <FightBrainVariables>();

            if (brainVariables == null)
            {
                brainVariables = brainController.gameObject.AddComponent <FightBrainVariables>();
            }
            if (actionList.Length == 0)
            {
                Logger.LogMessage($"{name}::InitBrain -- actionList is empty.", LogType.Error);
            }
            if (runAction == null)
            {
                Logger.LogMessage($"{name}::InitBrain -- runAction is not set.", LogType.Error);
            }
            if (string.IsNullOrEmpty(ildeAnimationTrigger))
            {
                Logger.LogMessage($"{name}::InitBrain -- ildeAnimationTrigger is not set.", LogType.Error);
            }
            // FIXME: Make initiative roll dependent on some stat like dexterity.
            brainVariables.initiative = UnityEngine.Random.value;
            brainController.animationController.TriggerAnimation(ildeAnimationTrigger);
            // Set combat runSpeed to min run speed of Avatar.
            brainVariables.runSpeed = brainController.Stats.runSpeed.x;
            // HACK: We can't call GetNextAction yet, cause we dont have fightController passed to brain.
            // We will call first GetNextAction in SetFightController.
            // ---- brainVariables.nextAction = GetNextAction(brainController);
            brainVariables.turnEnded = false;
            brainController.avatarController.avatarStats.ShowHP = true;
            // FIXME: For first combat build. Add hp regeneration later.
            brainController.avatarController.avatarStats.ResetHP();
        }
예제 #5
0
        protected virtual bool CheckClipEvents(BrainController brainController)
        {
            var eventsList = brainController.animationController.GetClipAnimationEvents(animationTrigger);

            if (eventsList == null)
            {
                return(false);
            }
            Dictionary <string, bool> eventDictionary = new Dictionary <string, bool>();

            foreach (var eventFunctionName in eventFunctionNames)
            {
                eventDictionary.Add(eventFunctionName, false);
            }
            foreach (var clipEvent in eventsList)
            {
                if (eventDictionary.ContainsKey(clipEvent.functionName))
                {
                    eventDictionary[clipEvent.functionName] = true;
                }
            }
            bool result = true;

            foreach (var hasEvent in eventDictionary)
            {
                if (hasEvent.Value == false)
                {
                    result = false;
                    Logger.LogMessage($"{brainController.gameObject.name}::FightAttackAction " +
                                      $"-- {hasEvent.Key} animation event is missing.", LogType.Error);
                }
            }
            return(result);
        }
예제 #6
0
        public void OnDeath(BrainController deadFighter)
        {
            int teamID = GetFighterTeamID(deadFighter);

            if (turnQueue.Contains(deadFighter))
            {
                turnQueue = new Queue <BrainController>(turnQueue.Where(t => t != deadFighter));
            }
            turnTimersDictionary.Remove(deadFighter);
            Logger.LogMessage($"FightController::{deadFighter.gameObject.name} removed from turnTimersDictionary");
            fighters = turnTimersDictionary.Keys.ToArray();
            initiativeDictionary.Remove(deadFighter);
            Logger.LogMessage($"FightController::{deadFighter.gameObject.name} removed from initiativeDictionary");
            teamsDictionary[teamID].Remove(deadFighter);
            Logger.LogMessage($"FightController::{deadFighter.gameObject.name} removed from teamsDictionary");
            // FIXME: DictionaryKeyNotFound excepntion beggining from second combat.
            if (teamsDictionary[teamID].Count <= 0)
            {
                teamsDictionary.Remove(teamID);
                if (teamsDictionary.Count <= 1)
                {
                    fightEnded = true;
                }
            }
        }
예제 #7
0
 private void Awake()
 {
     animationController = GetComponent <AnimationController>();
     messageQueue        = GetComponent <MessageQueue>();
     avatarStats         = GetComponent <AvatarStats>();
     brainController     = GetComponent <BrainController>();
     zombify             = GetComponent <Zombify>();
 }
예제 #8
0
        public void EndFight(BrainController brainController)
        {
            var brainVariables = brainController.GetComponent <FightBrainVariables>();

            // brainController.animationController.TriggerAnimation(ildeAnimationTrigger);
            brainController.avatarController.avatarStats.ShowHP = false;
            brainVariables.TeamID = 0;
        }
예제 #9
0
        /// <summary>
        /// Initializing function for action.
        /// </summary>
        /// <param name="brainController">BrainController</param>
        public override void InitAction(BrainController brainController)
        {
            var brainVariables = brainController.GetComponent <IdleBrainVariables>();
            //brainController.animationController.Direction = Random.Range(-1, 1) > 0 ? 1 : -1;
            Vector2 idleTime = brainController.Stats.idleTime;

            brainVariables.currentDistance = Random.Range(idleTime.x, idleTime.y);
            brainController.animationController.TriggerAnimation(animationTrigger);
        }
예제 #10
0
        /// <summary>
        /// Gets random brainController from opposing team.
        /// </summary>
        /// <param name="brainController">Current fighter.</param>
        /// <returns>Random enemy.</returns>
        public BrainController GetRandomEnemy(BrainController brainController)
        {
            List <BrainController> possibleEnemies = GetPossibleEnemiesList(brainController);
            int             enemyID = UnityEngine.Random.Range(0, possibleEnemies.Count);
            BrainController enemy   = possibleEnemies.ToArray()[enemyID];

            Debug.Log(brainController.gameObject.name + " chooses to attack " + enemy.gameObject.name);
            return(enemy);
        }
예제 #11
0
        /// <summary>
        /// Saves current FightController to variables and rolls for initiative.
        /// </summary>
        /// <param name="brainController">BrainController</param>
        /// <param name="fightController">FightController</param>
        /// <returns>Initiative</returns>
        public float SetFightController(BrainController brainController, FightController fightController, int teamID)
        {
            var brainVariables = brainController.GetComponent <FightBrainVariables>();

            brainVariables.fightController = fightController;
            brainVariables.nextAction      = GetNextAction(brainController);
            brainVariables.TeamID          = teamID;
            brainController.avatarController.avatarStats.OnDeath += fightController.OnDeath;
            return(brainVariables.initiative);
        }
예제 #12
0
        private void DealDamage(BrainController brainController)
        {
            var        brainVariables = brainController.GetComponent <FightBrainVariables>();
            FightBrain fightBrain     = (FightBrain)brainController.currentBrain;
            var        avatarStats    = brainController.Stats;
            int        crit           = Random.value <= avatarStats.critChance ? 1 : 0;
            float      damage         = Random.Range(avatarStats.damage.x, avatarStats.damage.y) * (1 + crit * (avatarStats.critMultiplayer - 1));

            fightBrain.TakeDamage(brainVariables.currentEnemy, damage, crit == 1);
        }
예제 #13
0
        private void EndTurn(BrainController brainController)
        {
            var brainVariables = brainController.GetComponent <FightBrainVariables>();

            brainVariables.nextAction    = GetNextAction(brainController);
            brainVariables.currentAction = null;
            brainVariables.turn          = false;
            //brainController.animationController.TriggerAnimation(ildeAnimationTrigger);
            brainController.animationController.SpriteSortOrder = brainVariables.spriteSortOrder;
            brainVariables.fightController.EndTurn(lastFighter: brainController, cooldown: brainVariables.ActionCooldown);
        }
예제 #14
0
 private void Awake()
 {
     brainController = GetComponent <BrainController>();
     if (hpText == null)
     {
         Logger.LogMessage($"{gameObject.name}::AvatarStats -- hpText feild is not set.", LogType.Error);
     }
     if (hpPanel == null)
     {
         Logger.LogMessage($"{gameObject.name}::AvatarStats -- hpPanel feild is not set.", LogType.Error);
     }
 }
예제 #15
0
        /// <summary>
        /// Act function to be called once each update.
        /// </summary>
        /// <param name="brainController">BrainController</param>
        /// <returns>actionEnded</returns>
        public override bool Act(BrainController brainController)
        {
            var brainVariables = brainController.GetComponent <IdleBrainVariables>();

            if (brainVariables.currentDistance > 0)
            {
                brainVariables.currentDistance -= Time.deltaTime;
                return(false);
            }
            else
            {
                return(true);
            }
        }
예제 #16
0
        private List <BrainController> GetPossibleEnemiesList(BrainController brainController)
        {
            List <BrainController> possibleEnemies = new List <BrainController>();
            int fighterTeamID = GetFighterTeamID(brainController);

            foreach (var teamID in teamsDictionary.Keys)
            {
                if (teamID != fighterTeamID)
                {
                    possibleEnemies.AddRange(teamsDictionary[teamID]);
                }
            }
            return(possibleEnemies);
        }
예제 #17
0
 private int GetFighterTeamID(BrainController brainController)
 {
     foreach (var team in teamsDictionary)
     {
         foreach (var fighter in team.Value)
         {
             if (fighter == brainController)
             {
                 return(team.Key);
             }
         }
     }
     return(0);
 }
예제 #18
0
        /// <summary>
        /// Update function to be called once each update.
        /// </summary>
        /// <param name="brainController">BrainController</param>
        /// <returns>actionEnded</returns>
        public override void UpdateBrain(BrainController brainController)
        {
            var brainVariables = brainController.GetComponent <IdleBrainVariables>();

            if (brainVariables == null)
            {
                Logger.LogMessage($"{name}::Update -- brainVariables are not found. Brain has not been initialized", LogType.Error);
                return;
            }
            if (brainVariables.currentAction.Act(brainController))
            {
                brainVariables.currentAction = GetRandomAction();
                brainVariables.currentAction.InitAction(brainController);
            }
        }
예제 #19
0
        // TODO: Check if enemy is close enough or set weight to 0.

        /// <summary>
        /// Initializing function for action.
        /// </summary>
        /// <param name="brainController">BrainController.</param>
        public override void InitAction(BrainController brainController)
        {
            var brainVariables = brainController.GetComponent <FightBrainVariables>();

            if (CheckClipEvents(brainController) == false)
            {
                return;
            }
            brainController.animationController.TriggerAnimation(animationTrigger);
            float attackDirection = brainController.transform.position.x > brainVariables.currentEnemy.transform.position.x ? -1 : 1;

            brainController.animationController.Direction = attackDirection;
            brainController.animationEventHandler.Init();
            CheckClipEvents(brainController);
        }
예제 #20
0
        /// <summary>
        /// Act function to be called once each update.
        /// </summary>
        /// <param name="brainController">BrainController</param>
        /// <returns>actionEnded</returns>
        public override bool Act(BrainController brainController)
        {
            var   brainVariables = brainController.GetComponent <FightBrainVariables>();
            float runDistance    = Mathf.Min(brainVariables.runSpeed * Time.deltaTime, brainVariables.distanceToRun);

            brainVariables.distanceToRun -= runDistance;
            brainController.transform.Translate(runDistance * brainVariables.runDirection, 0, 0);
            bool actionEnded = brainVariables.distanceToRun <= 0;

            if (actionEnded)
            {
                brainController.animationController.TriggerAnimation(ildeAnimationTrigger);
            }
            // TODO: Decide what to do with small side steps.
            return(actionEnded);
        }
예제 #21
0
        /// <summary>
        /// Gets closest enemy brainController.
        /// </summary>
        /// <param name="brainController">Current fighter.</param>
        /// <returns>Closest enemy.</returns>
        public BrainController GetClosestEnemy(BrainController brainController)
        {
            float           nearestRange = Mathf.Infinity;
            BrainController closestEnemy = null;

            foreach (var enemy in GetPossibleEnemiesList(brainController))
            {
                var range = Mathf.Abs(enemy.transform.position.x - brainController.transform.position.x);
                if (range < nearestRange)
                {
                    nearestRange = range;
                    closestEnemy = enemy;
                }
            }
            return(closestEnemy);
        }
예제 #22
0
        /// <summary>
        /// Initializing function for brain.
        /// </summary>
        /// <param name="brainController">BrainController</param>
        public override void InitBrain(BrainController brainController)
        {
            var brainVariables = brainController.GetComponent <IdleBrainVariables>();

            if (brainVariables == null)
            {
                brainVariables = brainController.gameObject.AddComponent <IdleBrainVariables>();
            }
            if (actionList.Length == 0)
            {
                Logger.LogMessage($"{name}::InitBrain -- actionList is empty.", LogType.Error);
            }
            else
            {
                brainVariables.currentAction = GetRandomAction();
                brainVariables.currentAction.InitAction(brainController);
            }
        }
예제 #23
0
        /// <summary>
        /// Initializing function for action.
        /// </summary>
        /// <param name="brainController">BrainController</param>
        public override void InitAction(BrainController brainController)
        {
            var     brainVariables = brainController.GetComponent <IdleBrainVariables>();
            var     avatarStats    = brainController.Stats;
            Vector2 position       = brainController.transform.position;
            float   leftBorder     = BackgroundController.Instance.leftBorder.position.x;
            float   rightBorder    = BackgroundController.Instance.rightBorder.position.x;
            float   newDistance    = Random.Range(avatarStats.walkTravelDistance.x, avatarStats.walkTravelDistance.y)
                                     * (Random.value > 0.5 ? 1 : -1);
            float newDestinationPoint = position.x + newDistance;

            newDestinationPoint = Mathf.Clamp(newDestinationPoint, leftBorder, rightBorder);
            newDistance         = newDestinationPoint - position.x;
            brainController.animationController.Direction = newDistance >= 0 ? 1 : -1;
            brainVariables.currentDistance = Mathf.Abs(newDistance);
            brainVariables.currentSpeed    = Random.Range(avatarStats.walkSpeed.x, avatarStats.walkSpeed.y);
            brainController.animationController.TriggerAnimation(animationTrigger);
        }
예제 #24
0
        /// <summary>
        /// Act function to be called once each update.
        /// </summary>
        /// <param name="brainController">BrainController</param>
        /// <returns>actionEnded</returns>
        public override bool Act(BrainController brainController)
        {
            var brainVariables = brainController.GetComponent <IdleBrainVariables>();

            if (brainVariables.currentDistance > 0)
            {
                Vector2 newTransform = brainController.transform.position;
                float   movement     = Mathf.Min(brainVariables.currentDistance, brainVariables.currentSpeed * Time.deltaTime);
                newTransform.x += brainController.animationController.Direction * movement;
                brainController.transform.position = newTransform;
                brainVariables.currentDistance    -= movement;
                return(false);
            }
            else
            {
                return(true);
            }
        }
예제 #25
0
        /// <summary>
        /// Initializing function for action.
        /// </summary>
        /// <param name="brainController">BrainController.</param>
        public override void InitAction(BrainController brainController)
        {
            var brainVariables = brainController.GetComponent <FightBrainVariables>();

            brainController.animationController.TriggerAnimation(animationTrigger);
            float distanceToEnemy = brainVariables.currentEnemy.transform.position.x - brainController.transform.position.x;

            brainVariables.runDirection = Mathf.Sign(distanceToEnemy);
            if (Mathf.Abs(distanceToEnemy) < brainController.Stats.attackDistance)
            {
                brainVariables.distanceToRun = 0;
            }
            else
            {
                brainVariables.distanceToRun =
                    Mathf.Min(Mathf.Abs(distanceToEnemy) - brainController.Stats.attackDistance, brainController.Stats.maxCombatRunDistance);
            }
            brainController.animationController.Direction = brainVariables.runDirection;
        }
예제 #26
0
        private AvatarCombatAction GetNextAction(BrainController brainController)
        {
            var brainVariables = brainController.GetComponent <FightBrainVariables>();
            AvatarCombatAction nextAction;

            // FIXME: Check if Avatar need to attack other closest enemy.
            if (brainVariables.currentEnemy == null)
            {
                brainVariables.currentEnemy = brainVariables.fightController.GetClosestEnemy(brainController);
            }
            // FIXME: Rewrite this code using new clever action weight property.
            var distanceToEnemy = Mathf.Abs(brainController.transform.position.x - brainVariables.currentEnemy.transform.position.x);

            if (distanceToEnemy > brainController.Stats.attackDistance)
            {
                nextAction = runAction;
            }
            else
            {
                nextAction = (AvatarCombatAction)GetRandomAction();
            }
            return(nextAction);
        }
예제 #27
0
        public void TakeDamage(BrainController brainController, float damage, bool crit)
        {
            var brainVariables = brainController.GetComponent <FightBrainVariables>();

            if (crit)
            {
                Logger.LogMessage($"{brainController.gameObject.name} has taken {damage} damage! Its a crit!");
            }
            else
            {
                Logger.LogMessage($"{brainController.gameObject.name} has taken {damage} damage.");
            }
            if (brainController.avatarController.avatarStats.TakeDamage(damage) == 0)
            {
                brainVariables.TeamID        = 0;
                brainVariables.currentAction = deathAction;
            }
            else
            {
                brainVariables.currentAction = hurtAction;
            }
            brainVariables.currentAction.InitAction(brainController);
        }
예제 #28
0
 /// <summary>
 /// Update function to be called once each update.
 /// </summary>
 /// <param name="brainController">BrainController</param>
 /// <returns>actionEnded</returns>
 public abstract void UpdateBrain(BrainController brainController);
예제 #29
0
 /// <summary>
 /// Initializing function for brain.
 /// </summary>
 /// <param name="brainController">BrainController</param>
 public abstract void InitBrain(BrainController brainController);
예제 #30
0
 /// <summary>
 /// Act function to be called once each update.
 /// </summary>
 /// <param name="brainController">BrainController</param>
 /// <returns>actionEnded</returns>
 public abstract bool Act(BrainController brainController);