private IEnumerator CleanUpTurn(BattleMonster attackingMonster) { // Skip if battle is over. if (_state == BattleState.BattleOver) { yield break; } // Skip if monster is downed. if (_isMonsterDown) { _isMonsterDown = false; yield return(new WaitUntil(() => _state == BattleState.ExecutingTurn)); yield break; } // Wait for monster switch, etc. yield return(new WaitUntil(() => _state == BattleState.ExecutingTurn)); // Check for status changes like poison and update Monster/HUD. attackingMonster.Monster.CheckForStatusDamage(); yield return(ShowStatusChanges(attackingMonster.Monster)); yield return(attackingMonster.Hud.UpdateHp()); if (attackingMonster.Monster.CurrentHp > 0) { yield break; } // Attacking monster was downed from status effects. yield return(HandleDownedMonster(attackingMonster)); yield return(new WaitUntil(() => _state == BattleState.ExecutingTurn)); }
public void OnDungeonInfo() { MonsterCount = DungeonUi.GetMonsterCount + 1; Difficulty_Lv = DungeonUi.GetDungeonLv; Debug.Log("Create DungeonLV " + Difficulty_Lv); Debug.Log("Create Monster Count " + MonsterCount); for (int i = 0; i < MonsterCount; i++) { m_PrefabMonster = Resources.Load("monster") as GameObject; GameObject go = Instantiate(m_PrefabMonster) as GameObject; BattleMonster bm = go.GetComponent <BattleMonster>(); m_monster.Add(bm); } foreach (var i in m_monster) { i.init(); } m_DungeonStart = false; DungeonUi.transform.gameObject.SetActive(false); }
private void CheckIfBattleIsOver(BattleMonster downedMonster) { if (downedMonster.IsPlayerMonster) { MonsterObj nextMonster = _playerParty.GetHealthyMonster(); if (nextMonster != null) { OpenPartyScreen(); } else { BattleOver(BattleResult.Lost); } } else { if (!_isCharBattle) { BattleOver(BattleResult.Won); } else { MonsterObj nextEnemyMonster = _battlerParty.GetHealthyMonster(); if (nextEnemyMonster != null) { StartCoroutine(ChoiceSelection(nextEnemyMonster)); } else { BattleOver(BattleResult.Won); } } } }
public Monster(int pid, int num, RuntimeMonster RTData, MonsterData config) { this.pid = pid; this.num = num; this.RTData = RTData; InitConfig(); this.inTeam = false; this.isNew = true; //create the 战斗时候的运算数据对象 this.BTData = new BattleMonster(baseAttack, enhanceAttack, baseDefend, enhanceDefend); }
public void CancelSequence() { sequenceIndex = -1; // Hack to get the next to be 0 target = null; attackingPlayer = null; attackValue = 0; modAttackValue = 0; attackSuccessful = false; diceCountChosen = 0; if (CheckQuestComplete()) { QuestVictory(); } else { NextSequence(); } }
/// <summary> /// 设置当前场景 /// </summary> public void SetState(SceneState sceneState, bool isNow = true, bool isAsync = false) { ISceneState State; switch (sceneState) { case SceneState.StartState: State = new StartState(this); break; case SceneState.MainScene: State = new MainScene(this); break; case SceneState.TrainScene: State = new TrainScene(this); break; case SceneState.VillageScene: State = new VillageScene(this); break; case SceneState.TutorialScene: State = new TutorialScene(this); break; case SceneState.BattleEyeball: State = new BattleEyeball(this); break; case SceneState.BattleMonster: State = new BattleMonster(this); break; case SceneState.BattleStrongKnight: State = new BattleStrongKnight(this); break; case SceneState.BattleFantasy: State = new BattleFantasy(this); break; case SceneState.BattleForestNight: State = new BattleForestNight(this); break; case SceneState.BattleForestDay: State = new BattleForestDay(this); break; default: return; } Debug.Log("切换场景:" + State.ToString()); isSceneBegin = false; // 通知前一個State結束 if (CurState != null) { CurState.StateEnd(); } // 载入场景 if (isNow) { if (isAsync) { UILoading.nextScene = State.StateName; LoadScene("Loading"); } else { LoadScene(State.StateName); } } //设置当前场景 CurState = State; }
/// <summary> /// Play the Capture Crystal animation. /// </summary> /// <param name="playerMonster">Player's monster</param> /// <param name="enemyMonster">Enemy's monster</param> /// <param name="beamCount">Count returned by capture algo determines the animation length.</param> /// <returns></returns> public IEnumerator PlayCrystalAnimation(BattleMonster playerMonster, BattleMonster enemyMonster, int beamCount) { // Factory or Flyweight pattern for this? /* * TODO - refactor this animation, i'm sure there's a better way to do this * My thinking was I wanted absolute control over where to position things and it seemed easiest * to just create this massive block of code to achieve it, but I'm sure my inexperience is showing here big time. * If it seems stupid, but it works, then I guess its not so stupid. */ //TODO - instantiate these under _Dynamic // Build the animation points. Vector3 enemyPosition = enemyMonster.transform.position; Vector3 origin = playerMonster.transform.position - new Vector3(2, 0); Vector3 destination = enemyPosition - new Vector3(5, 2); // Deploy the capture crystal. _crystalObj = Instantiate(_crystalSprite, origin, Quaternion.identity); var crystal = _crystalObj.GetComponent <SpriteRenderer>(); crystal.transform.localScale = new Vector3(0.2f, 0.2f); crystal.transform.DOScale(1, 1f); yield return(crystal.transform.DOJump(destination, 2f, 1, 1f).WaitForCompletion()); enemyMonster.PlayCaptureAnimation(); // Send the first beam and instantiate the burst. _beamObj1 = Instantiate(_beamSprite, destination + new Vector3(0, 2), Quaternion.Euler(0, 0, 270)); var beam1 = _beamObj1.GetComponent <SpriteRenderer>(); yield return(beam1.transform.DOLocalMove(enemyPosition, 0.5f)); beam1.DOFade(0, 0.5f); _burstObj = Instantiate(_burstSprite, enemyPosition, Quaternion.identity); var burst = _burstObj.GetComponent <SpriteRenderer>(); yield return(YieldHelper.TwoSeconds); // Quit after 1 beam. if (beamCount == 0 || beamCount == 1) { yield break; } // Send the second beam and grow the burst. _beamObj2 = Instantiate(_beamSprite, destination + new Vector3(0, -2), Quaternion.Euler(0, 0, 310)); var beam2 = _beamObj2.GetComponent <SpriteRenderer>(); yield return(beam2.transform.DOLocalMove(enemyPosition, 0.5f)); beam2.DOFade(0, 0.5f); burst.transform.DOScale(5f, 0.5f); yield return(YieldHelper.TwoSeconds); // Quit after 2 beams. if (beamCount == 2) { yield break; } // Send the final beam and grow the burst to max size. _beamObj3 = Instantiate(_beamSprite, destination, Quaternion.Euler(0, 0, 290)); var beam3 = _beamObj3.GetComponent <SpriteRenderer>(); yield return(beam3.transform.DOLocalMove(enemyPosition, 0.5f)); burst.transform.DOScale(10f, 0.5f); beam3.DOFade(0, 0.5f); yield return(YieldHelper.TwoSeconds); // Quit after 3 beams. if (beamCount == 3) { yield break; } // Play the capture animation. enemyMonster.Image.DOFade(0, 0.1f); burst.transform.DOLocalMove(destination, 1f); yield return(burst.DOFade(0, 1f)); crystal.transform.DOScale(2f, 1.5f); yield return(YieldHelper.OneSecond); crystal.transform.DOLocalMove(origin, 1.5f); crystal.DOFade(0f, 1.5f); yield return(YieldHelper.TwoSeconds); }
private IEnumerator HandleDownedMonster(BattleMonster downedMonster) { _isMonsterDown = true; if (downedMonster.IsPlayerMonster) { yield return(_dialogBox.TypeDialog($"{downedMonster.Monster.Base.Name} has been taken down!")); } else { yield return(_dialogBox.TypeDialog($"Enemy {downedMonster.Monster.Base.Name} has been taken down!")); } downedMonster.PlayDownedAnimation(); yield return(YieldHelper.TwoSeconds); if (!downedMonster.IsPlayerMonster) { // Setup exp gain variables. int expBase = downedMonster.Monster.Base.ExpGiven; int enemyLevel = downedMonster.Monster.Level; float battlerBonus = _isCharBattle ? 1.5f : 1f; // Handle exp gain. int expGain = Mathf.FloorToInt(expBase * enemyLevel * battlerBonus / 7); _playerMonster.Monster.Exp += expGain; yield return(_dialogBox.TypeDialog($"{_playerMonster.Monster.Base.Name} has gained {expGain.ToString()} experience!")); yield return(_playerMonster.Hud.SlideExp()); // While loop in case the monster gains more than 1 level. while (_playerMonster.Monster.CheckForLevelUp()) { _playerMonster.Hud.SetLevel(); yield return(_dialogBox.TypeDialog($"{_playerMonster.Monster.Base.Name} has leveled up, they are now level {_playerMonster.Monster.Level.ToString()}!")); yield return(_playerMonster.Hud.SlideExp(true)); // Learn a new move. LearnableMove newMove = _playerMonster.Monster.GetLearnableMove(); if (newMove == null) { continue; } if (_playerMonster.Monster.Moves.Count < MonsterBase.MaxNumberOfMoves) { _playerMonster.Monster.LearnMove(newMove); _dialogBox.SetMoveList(_playerMonster.Monster.Moves); yield return(_dialogBox.TypeDialog($"{_playerMonster.Monster.Base.Name} has learned {newMove.Base.Name}!")); } else { // Forget an existing move first. yield return(ForgetMoveSelection(_playerMonster.Monster, newMove)); } } yield return(YieldHelper.OneSecond); } // Wait until move learning is finished before calling CheckIfBattleIsOver. yield return(new WaitUntil(() => _state == BattleState.ExecutingTurn)); CheckIfBattleIsOver(downedMonster); }
private IEnumerator UseMove(BattleMonster attackingMonster, BattleMonster defendingMonster, MoveObj move) { // Check for statuses like paralyze or sleep before trying to attack. bool canAttack = attackingMonster.Monster.CheckIfCanAttack(); if (!canAttack) { yield return(ShowStatusChanges(attackingMonster.Monster)); yield return(attackingMonster.Hud.UpdateHp()); yield break; } // Clear the StatusChanges queue and decrease the move energy. yield return(ShowStatusChanges(attackingMonster.Monster)); move.Energy--; if (attackingMonster.IsPlayerMonster) { yield return(_dialogBox.TypeDialog($"{attackingMonster.Monster.Base.Name} used {move.Base.Name}!")); } else { yield return(_dialogBox.TypeDialog($"Enemy {attackingMonster.Monster.Base.Name} used {move.Base.Name}!")); } if (CheckIfMoveHits(move, attackingMonster.Monster, defendingMonster.Monster)) { attackingMonster.PlayAttackAnimation(); yield return(YieldHelper.HalfSecond); defendingMonster.PlayHitAnimation(); // If status move then don't deal damage, switch to UseMoveEffects coroutine. if (move.Base.Category == MoveCategory.Status) { yield return(UseMoveEffects(move.Base.Effects, attackingMonster.Monster, defendingMonster.Monster, move.Base.Target)); } else { DamageDetails damageDetails = defendingMonster.Monster.TakeDamage(move, attackingMonster.Monster); yield return(defendingMonster.Hud.UpdateHp()); yield return(ShowDamageDetails(damageDetails)); } // Check for secondary move effects. if (move.Base.MoveSecondaryEffects != null && move.Base.MoveSecondaryEffects.Count > 0 && attackingMonster.Monster.CurrentHp > 0) { foreach (MoveSecondaryEffects effect in move.Base.MoveSecondaryEffects) { int rng = UnityEngine.Random.Range(1, 101); if (rng <= effect.Chance) { yield return(UseMoveEffects(effect, attackingMonster.Monster, defendingMonster.Monster, effect.Target)); } } } // Handle downed monster and check if we should continue. if (defendingMonster.Monster.CurrentHp <= 0) { yield return(HandleDownedMonster(defendingMonster)); } } else { // Handle a missed attack. if (attackingMonster.IsPlayerMonster) { yield return(_dialogBox.TypeDialog($"{attackingMonster.Monster.Base.Name} missed their attack!")); } else { yield return(_dialogBox.TypeDialog($"Enemy {attackingMonster.Monster.Base.Name} missed their attack!")); } } }
private IEnumerator ExecuteTurn(BattleAction playerAction) { _state = BattleState.ExecutingTurn; if (playerAction == BattleAction.Move) { // Get the monster moves. _playerMonster.Monster.CurrentMove = _playerMonster.Monster.Moves[_currentMove]; _enemyMonster.Monster.CurrentMove = _enemyMonster.Monster.GetRandomMove(); if (_playerMonster.Monster.CurrentMove == null || _enemyMonster.Monster.CurrentMove == null) { BattleOver(BattleResult.Error); yield break; } int playerPriority = _playerMonster.Monster.CurrentMove.Base.Priority; int enemyPriority = _enemyMonster.Monster.CurrentMove.Base.Priority; // Check who goes first. var isPlayerFirst = true; if (enemyPriority > playerPriority) { isPlayerFirst = false; } else if (playerPriority == enemyPriority) { isPlayerFirst = _playerMonster.Monster.Speed >= _enemyMonster.Monster.Speed; } BattleMonster firstMonster = (isPlayerFirst) ? _playerMonster : _enemyMonster; BattleMonster secondMonster = (isPlayerFirst) ? _enemyMonster : _playerMonster; // Store in case it gets downed and switched out before its move. MonsterObj lastMonster = secondMonster.Monster; // Execute the first move. yield return(UseMove(firstMonster, secondMonster, firstMonster.Monster.CurrentMove)); yield return(CleanUpTurn(firstMonster)); if (_state == BattleState.BattleOver) { yield break; } // Execute the second move. if (lastMonster.CurrentHp > 0) { yield return(UseMove(secondMonster, firstMonster, secondMonster.Monster.CurrentMove)); yield return(CleanUpTurn(secondMonster)); if (_state == BattleState.BattleOver) { yield break; } } } else if (playerAction == BattleAction.SwitchMonster) { // Switch the monster. MonsterObj selectedMember = _playerParty.Monsters[_currentMember]; _state = BattleState.Busy; yield return(SwitchMonster(selectedMember)); // Now it's the enemy's turn. MoveObj enemyMove = _enemyMonster.Monster.GetRandomMove(); if (enemyMove == null) { BattleOver(BattleResult.Error); yield break; } yield return(UseMove(_enemyMonster, _playerMonster, enemyMove)); yield return(CleanUpTurn(_enemyMonster)); if (_state == BattleState.BattleOver) { yield break; } } else if (playerAction == BattleAction.UseItem) { //TODO - refactor this when item system is implemented. // Use the item. _dialogBox.EnableActionSelector(false); yield return(ActivateCrystal()); } else if (playerAction == BattleAction.Run) { // Run from the battle. yield return(AttemptRun()); } // Return to ActionSelection. if (_state != BattleState.BattleOver) { ActionSelection(); } }