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); }
/// <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; }
/// <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); }
/// <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); }
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); }
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); }
/// <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) 播放死亡动画 } }
/// <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(); }
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); }
public CombatStep(CombatVariable atker, CombatVariable defer) { this.atkVal = atker; this.defVal = defer; }
public override bool IsBattleEnd(Combat combat, CombatVariable atkVal, CombatVariable defVal) { return(false); }
public abstract bool IsBattleEnd(Combat combat, CombatVariable atkVal, CombatVariable defVal);
public abstract CombatStep CalcBattle(Combat combat, CombatVariable atkVal, CombatVariable defVal);