Ejemplo n.º 1
0
        public override bool IsBattleEnd(Combat combat, CombatVariable atkVal, CombatVariable defVal)
        {
            // 防守者死亡
            if (defVal.isDead)
            {
                return(true);
            }

            // 如果防守者行动过了
            if (defVal.action)
            {
                //CombatUnit atker = GetCombatUnit(atkVal.position);
                //CombatUnit defer = GetCombatUnit(defVal.position);

                // TODO 是否继续攻击,必要时需要在 CombatVariable 加入其它控制变量
                // 比如,触发过技能或物品了
                // atker.role.skill/item 包含继续战斗的技能或物品
                // defer.role.skill/item 包含继续战斗的技能或物品
                //if ( 触发继续战斗 )
                //{
                //    // return false;
                //}

                return(true);
            }

            return(false);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 交换攻击者与防御者
        /// </summary>
        /// <param name="atkVal"></param>
        /// <param name="defVal"></param>
        public void SwapCombatVariable(ref CombatVariable atkVal, ref CombatVariable defVal)
        {
            CombatVariable tmp = atkVal;

            atkVal = defVal;
            defVal = tmp;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 战斗是否结束
        /// </summary>
        /// <param name="atkVal"></param>
        /// <param name="defVal"></param>
        /// <returns></returns>
        private bool IsBattleEnd(ref CombatVariable atkVal, ref CombatVariable defVal)
        {
            // 攻击者死亡,防守者死亡
            if (atkVal.isDead || defVal.isDead)
            {
                return(true);
            }

            // 如果防守者可反击
            if (defVal.canAtk)
            {
                // 交换攻击者与防御者
                SwapCombatVariable(ref atkVal, ref defVal);
            }

            // 如果攻击者行动过了
            if (atkVal.action)
            {
                //CombatUnit atker = GetCombatUnit(atkVal.position);
                //CombatUnit defer = GetCombatUnit(defVal.position);

                // TODO 是否继续攻击,必要时需要在 CombatVariable 加入其它控制变量
                // atker.role.skill 包含继续战斗的技能
                // defer.role.skill 包含继续战斗的技能
                //if ( condition )
                //{
                //    // atkVal.action = false;
                //}
            }

            // 攻击者行动过了
            return(atkVal.action);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 运行动画,并返回长度
        /// </summary>
        /// <param name="combat"></param>
        /// <param name="actor"></param>
        /// <param name="other"></param>
        /// <param name="dirs"></param>
        /// <returns></returns>
        protected virtual float RunAniamAndGetLengthInMap(CombatVariable actor, CombatVariable other, Direction[] dirs)
        {
            CombatUnit actorUnit = combat.GetCombatUnit(actor.position);

            if (actorUnit == null || actorUnit.mapClass == null)
            {
                return(0f);
            }

            ClassAnimatorController actorAnima = actorUnit.mapClass.animatorController;
            Direction dir    = dirs[actor.position];
            float     length = 0.5f;

            switch (actor.animaType)
            {
            case CombatAnimaType.Prepare:
                actorAnima.PlayPrepareAttack(dir, actorUnit.weaponType);
                break;

            case CombatAnimaType.Attack:
            case CombatAnimaType.Heal:
                actorAnima.PlayAttack();
                length = actorAnima.GetAttackAnimationLength(dir, actorUnit.weaponType);
                break;

            case CombatAnimaType.Evade:
                actorAnima.PlayEvade();
                length = actorAnima.GetEvadeAnimationLength(dir);
                break;

            case CombatAnimaType.Damage:
                actorAnima.PlayDamage();
                length = actorAnima.GetDamageAnimationLength(dir);

                // TODO 受到爆击的额外动画,假定是晃动
                // if (other.crit)
                // {
                //     CommonAnima.PlayShake(actorUnit.mapClass.gameObject);
                //     length = Mathf.Max(length, CommonAnima.shakeLength);
                // }

                break;

            case CombatAnimaType.Dead:
                // TODO 播放死亡动画,我把死亡忘记了
                break;

            default:
                break;
            }
            return(length);
        }
Ejemplo n.º 5
0
        public CombatVariable Clone()
        {
            CombatVariable variable = new CombatVariable()
            {
                position   = position,
                hp         = hp,
                mp         = mp,
                canAtk     = canAtk,
                durability = durability,
                animaType  = animaType,
                crit       = crit,
                action     = action
            };

            return(variable);
        }
Ejemplo n.º 6
0
        public override CombatStep CalcBattle(Combat combat, CombatVariable atkVal, CombatVariable defVal)
        {
            CombatUnit atker = combat.GetCombatUnit(0);
            CombatUnit defer = combat.GetCombatUnit(1);

            // 防守者是否可反击
            bool canDeferAtk = false;

            if (defer.role.equipedWeapon != null)
            {
                Vector3Int       offset  = defer.mapClass.cellPosition - atker.mapClass.cellPosition;
                int              dist    = Mathf.Abs(offset.x) + Mathf.Abs(offset.y);
                WeaponUniqueInfo defInfo = defer.role.equipedWeapon.uniqueInfo;

                //if (defInfo.weaponType != WeaponType.Staff)
                {
                    // 如果在反击范围内
                    if (dist >= defInfo.minRange && dist <= defInfo.maxRange)
                    {
                        canDeferAtk = true;
                    }
                }
            }

            // 根据速度初始化攻击者与防守者
            if (canDeferAtk)
            {
                if (atker.speed < defer.speed)
                {
                    CombatUnit tmp = atker;
                    atker = defer;
                    defer = tmp;
                }
            }

            // 更新信息
            this.message = "战斗开始";

            atkVal = new CombatVariable(atker.position, atker.hp, atker.mp, true, atker.durability, CombatAnimaType.Prepare);
            defVal = new CombatVariable(defer.position, defer.hp, defer.mp, canDeferAtk, defer.durability, CombatAnimaType.Prepare);

            // 准备阶段
            CombatStep firstStep = new CombatStep(atkVal, defVal);

            return(firstStep);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// 计算战斗数据
        /// </summary>
        private void CalcBattle(CombatVariable atkVal, CombatVariable defVal)
        {
            CombatUnit       atker      = GetCombatUnit(atkVal.position);
            BattleActionType actionType = GetBattleActionType(atker.weaponType);
            BattleAction     action;

            if (!m_BattleActionDict.TryGetValue(actionType, out action))
            {
                Debug.LogErrorFormat(
                    "Combat -> StartBattle: BattleActionType.{0} is not found, check the code.",
                    actionType.ToString());
                return;
            }


            CombatStep step = action.CalcBattle(this, atkVal, defVal);

            // step.message = action.message;
            steps.Add(step);

            // 如果战斗没有结束,交换攻击者与防守者
            if (!action.IsBattleEnd(this, step.atkVal, step.defVal))
            {
                if (step.defVal.canAtk)
                {
                    CalcBattle(step.defVal, step.atkVal);
                }
                else
                {
                    // 如果防守方不可反击
                    defVal        = step.defVal;
                    defVal.action = true;
                    if (!action.IsBattleEnd(this, defVal, step.atkVal))
                    {
                        CalcBattle(step.atkVal, defVal);
                    }
                }
            }
            else
            {
                // TODO 如果死亡,播放死亡动画(我把死亡动画忘记了)
                // if (step.defVal.isDead) 播放死亡动画
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// 战斗结束
        /// </summary>
        public void BattleEnd()
        {
            if (stepCount > 0)
            {
                CombatStep result = steps[stepCount - 1];

                CombatVariable unit0Result = result.GetCombatVariable(0);
                CombatVariable unit1Result = result.GetCombatVariable(1);

                // TODO 经验值战利品
                unit0.mapClass.OnBattleEnd(unit0Result.hp, unit0Result.mp, unit0.durability);
                unit1.mapClass.OnBattleEnd(unit1Result.hp, unit1Result.mp, unit1.durability);

                steps.Clear();
            }

            unit0.ClearMapClass();
            unit1.ClearMapClass();
        }
Ejemplo n.º 9
0
        public override CombatStep CalcBattle(Combat combat, CombatVariable atkVal, CombatVariable defVal)
        {
            CombatUnit atker = combat.GetCombatUnit(atkVal.position);
            CombatUnit defer = combat.GetCombatUnit(defVal.position);

            atkVal.animaType = CombatAnimaType.Attack;

            // 真实命中率 = 攻击者命中 - 防守者回避
            int realHit = atker.hit - defer.avoidance;

            // 概率是否击中
            int  hitRate = UnityEngine.Random.Range(0, 100);
            bool isHit   = hitRate <= realHit;

            if (isHit)
            {
                bool crit    = false; // TODO 是否爆击
                int  realAtk = atker.atk;

                ///////////////////
                // TODO 触发伤害技能
                // 这里写触发技能后伤害变化(比如武器特效等),
                // 或者触发某些状态(比如中毒等)
                //////////////////

                if (crit)
                {
                    realAtk *= 2; // 假定爆击造成双倍伤害
                }

                // 掉血 = 攻击者攻击力 - 防守者防御力
                // 最少掉一滴血
                int damageHp = Mathf.Max(1, realAtk - defer.def);
                if (damageHp > defVal.hp)
                {
                    damageHp = defVal.hp;
                }
                defVal.hp = defVal.hp - damageHp;

                atkVal.crit      = crit;
                defVal.animaType = CombatAnimaType.Damage;

                // 更新此次攻击信息
                this.message = string.Format(
                    "{0} 对 {1} 的攻击造成了 {2} 点伤害{3}。",
                    atker.role.character.info.name,
                    defer.role.character.info.name,
                    damageHp,
                    crit ? "(爆击)" : string.Empty);

                if (defVal.isDead)
                {
                    this.message += string.Format(" {0}被击败了。", defer.role.character.info.name);
                }
            }
            else
            {
                defVal.animaType = CombatAnimaType.Evade;

                // 更新此次躲闪信息
                this.message = string.Format(
                    "{1} 躲闪了 {0} 的攻击。",
                    atker.role.character.info.name,
                    defer.role.character.info.name);
            }

            // 只有玩家才会减低耐久度
            if (atker.role.attitudeTowards == AttitudeTowards.Player)
            {
                // 攻击者武器耐久度-1
                atkVal.durability = Mathf.Max(0, atkVal.durability - 1);
            }

            // 攻击者行动过了
            atkVal.action = true;

            CombatStep step = new CombatStep(atkVal, defVal);

            return(step);
        }
Ejemplo n.º 10
0
 public CombatStep(CombatVariable atker, CombatVariable defer)
 {
     this.atkVal = atker;
     this.defVal = defer;
 }
Ejemplo n.º 11
0
 public override bool IsBattleEnd(Combat combat, CombatVariable atkVal, CombatVariable defVal)
 {
     return(false);
 }
Ejemplo n.º 12
0
 public abstract bool IsBattleEnd(Combat combat, CombatVariable atkVal, CombatVariable defVal);
Ejemplo n.º 13
0
 public abstract CombatStep CalcBattle(Combat combat, CombatVariable atkVal, CombatVariable defVal);