/* This function applies the correct formulae to detemine whether a move hits or not. * The attacking Pokemon's accuracy stage and the defending Pokemon's evasion stage are combined * The calculated stage is then sent to the PokemonInBattle.ApplyAccStage() function, which returns a percentage change of the attack hitting. * Finally, the percentage is compared to a random number between 0 and 99 to determine if the move actually hits. */ public static bool AccuracyCheck(byte moveAccuracy, sbyte attackerAccStage, sbyte defenderEvaStage) { sbyte stage = (sbyte)MathHelper.Clamp((attackerAccStage - defenderEvaStage), -6, 6); byte accuracy = (byte)MathHelper.Clamp((PokemonInBattle.ApplyAccStage(moveAccuracy, stage)), 0, 100); return(PkmnUtils.RandomInclusive(99) < accuracy); }
/* This function creates a default NPC turn to add to the round. */ public void AddNpcTurn(PokemonInBattle user, PokemonInBattle target) { /* A new ProportionValue<Move> array is created with a length equal to the user's move array. * The moves are assigned with equal proportions so that each move has the same chance of being used. */ ProportionValue <Move>[] moves = new ProportionValue <Move> [user.Moves.Count(m => m != null)]; for (int i = 0; i < 4; i++) { if (user.Moves[i] != null) { moves[i] = ProportionValue.Create(1.0 / user.Moves.Count(m => m != null), user.Moves[i]); // DOES NOT HANDLE UNCOMPACTED MOVE ARRAYS } } /* A new turn is created using the user, target and a move chosen randomly via ProportionValue choosing. */ turns.Add(new TurnMove(user, target, this, moves.ChooseByRandom())); }
/* The constructor initializes the lists and adds the Pokemon to each list from the arrays passed in. * LINQ is used to determine how many Pokemon are not null in each array. * The initial indexes for the battle are also set to zero. * This constructor is for a wild battle. Another constructor will be required for trainer battles. */ public Battle(Pokemon[] playerTeam, Pokemon[] opponents, Dictionary <ushort, PokemonData> pokemonSpecies, bool trainer) { this.playerTeam = new List <PokemonInBattle>(); this.opponents = new List <PokemonInBattle>(); for (int i = 0; i < playerTeam.Count(s => s != null); i++) { Pokemon p = playerTeam[i]; PokemonInBattle pb = new PokemonInBattle(pokemonSpecies[p.PokemonID], p.PokemonGender, p.Moves, p.Level, null, p.XP); pb.Health = p.Health; for (int j = 0; j < p.Moves.Count(m => m != null); j++) { pb.Moves[j].PP = p.Moves[j].PP; } this.playerTeam.Add(pb); } for (int i = 0; i < opponents.Count(s => s != null); i++) { Pokemon p = opponents[i]; this.opponents.Add(new PokemonInBattle(pokemonSpecies[p.PokemonID], p.PokemonGender, p.Moves, p.Level, null, p.XP)); } playerIndex = 0; opponentIndex = 0; logList.Clear(); if (trainer) { WriteToLog("Trainer # challenged you to a battle!"); } else { WriteToLog("A wild " + CurrentOpponent.Nickname + " appeared!"); } WriteToLog("Go! " + CurrentPlayer.Nickname + "!"); emptyLog = true; openSwitchMenu = false; battleFinished = false; turns = new List <BaseTurn>(); }
/* When a base turn is created, the user, target and battle reference are passed in. * The fields are set using the arguments. */ public BaseTurn(PokemonInBattle user, PokemonInBattle target, Battle battleRef) { this.user = user; this.target = target; this.battleRef = battleRef; }
/* The constructor takes all the parameters for a BaseTurn plus the move being used. * The other arguments are passed to the base constructor, while the move is set into the field in the object. */ public TurnMove(PokemonInBattle user, PokemonInBattle target, Battle battleRef, Move move) : base(user, target, battleRef) { this.move = move; }