コード例 #1
0
ファイル: Battle.cs プロジェクト: Metasynic/PkmnEngine
        /* 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);
        }
コード例 #2
0
ファイル: TurnRun.cs プロジェクト: Metasynic/PkmnEngine
        /* When a TurnRun is executed, the engine will work out whether the user can run away. */
        public override bool Execute()
        {
            /* A byte representing the probability of a successful escape is generated using this formula.
             * It is then compared to a random integer between 0 and 255 to determine whether the escape can happen. */
            byte escapeChance = (byte)((((user.Speed * 128) / target.Speed) + (30 * user.RunCount)) % 256);
            bool canRun       = (PkmnUtils.RandomInclusive(255) < escapeChance);

            /* If the player Pokemon has tried to run away, and they have managed it, then it is written to the log.
             * The battle's EmptyLog flag is set to true so that the log is displayed to the screen, and the function returns true.
             * This means that the battle will end after this turn, since the user has run away.
             * However, if the player cannot run, this is also written to the log, EmptyLog is set to true and the function returns false since the battle will continue. */
            if (user == battleRef.CurrentPlayer)
            {
                if (canRun)
                {
                    battleRef.WriteToLog("You fled from the battle!");
                    battleRef.EmptyLog = true;
                    return(true);
                }
                else
                {
                    battleRef.WriteToLog("Couldn't escape!");
                    battleRef.EmptyLog = true;
                    return(false);
                }
            }

            /* Otherwise, the opponent Pokemon is the one trying to run away.
             * If the run has succeeded, then it's written to the log, EmptyLog is set to true, and the function returns true.
             * In the other case, the run failed, and this is written to the log. EmptyLog is again set to true and false is returned. */
            else
            {
                if (canRun)
                {
                    battleRef.WriteToLog(target.Nickname + " fled from the battle!");
                    battleRef.EmptyLog = true;
                    return(true);
                }
                else
                {
                    battleRef.WriteToLog(target.Nickname + " tried to run but couldn't escape!");
                    battleRef.EmptyLog = true;
                    return(false);
                }
            }
        }
コード例 #3
0
        /* The main constructor for a Pokemon takes its species (PokemonData), Gender, moveset, level, and a TrainerRank.
         * The TrainerRank is nullable so that null can be passed in for a wild Pokemon. */
        public Pokemon(PokemonData pokemonData, Gender gender, Move[] moves, byte level, TrainerRank?rank)
        {
            /* The nickname, type and base stats for the Pokemon are copied from the PokemonData for its species. */
            Nickname           = pokemonData.PokemonName;
            pokemonID          = pokemonData.ID;
            baseHP             = pokemonData.BaseHP;
            baseAttack         = pokemonData.BaseAttack;
            baseDefence        = pokemonData.BaseDefence;
            baseSpecialAttack  = pokemonData.BaseSpecialAttack;
            baseSpecialDefence = pokemonData.BaseSpecialDefence;
            baseSpeed          = pokemonData.BaseSpeed;
            type = new List <PkmnType>();
            type = pokemonData.Type;

            /* Gender and Level are set according to what was passed in. */
            this.gender = gender;
            this.level  = level;

            /* Fainted is false by default, as a Pokemon is initially conscious. */
            fainted = false;

            /* The moveset is copied using Array.Copy(). */
            Array.Copy(moves, this.moves, 4);

            /* The IVs for the Pokemon are randomly generated between 0 and 31. */
            iv_HP             = (byte)PkmnUtils.RandomInclusive(31);
            iv_Attack         = (byte)PkmnUtils.RandomInclusive(31);
            iv_Defence        = (byte)PkmnUtils.RandomInclusive(31);
            iv_SpecialAttack  = (byte)PkmnUtils.RandomInclusive(31);
            iv_SpecialDefence = (byte)PkmnUtils.RandomInclusive(31);
            iv_Speed          = (byte)PkmnUtils.RandomInclusive(31);

            /* The EVs of the Pokemon are set according to the TrainerRank passed in.
             * This will only happen if the Pokemon is owned by an NPC trainer.
             * The TrainerRank will be null for player Pokemon (since they earn EVs through battle and start at 0).
             * It will also be null for wild Pokemon since they have EVs of 0. */
            if (rank.HasValue)
            {
                if (rank.Value == TrainerRank.Normal)
                {
                    ev_HP = ev_Attack = ev_Defence = ev_SpecialAttack = ev_SpecialDefence = ev_Speed = 0;
                }
                else if (rank.Value == TrainerRank.Grunt)
                {
                    ev_HP = ev_Attack = ev_Defence = ev_SpecialAttack = ev_SpecialDefence = ev_Speed = 10;
                }
                else if (rank.Value == TrainerRank.Elite)
                {
                    ev_HP = ev_Attack = ev_Defence = ev_SpecialAttack = ev_SpecialDefence = ev_Speed = 20;
                }
                else if (rank.Value == TrainerRank.GymLeader)
                {
                    ev_HP = ev_Attack = ev_Defence = ev_SpecialAttack = ev_SpecialDefence = ev_Speed = 40;
                }
                else if (rank.Value == TrainerRank.EliteFour)
                {
                    ev_HP = ev_Attack = ev_Defence = ev_SpecialAttack = ev_SpecialDefence = ev_Speed = 60;
                }
                else if (rank.Value == TrainerRank.Champion)
                {
                    ev_HP = ev_Attack = ev_Defence = ev_SpecialAttack = ev_SpecialDefence = ev_Speed = 80;
                }
            }
            else
            {
                /* This block executes if the TrainerRank passed in is null.
                 * This means newly created wild Pokemon or player Pokemon have EVs of 0. */
                ev_HP = ev_Attack = ev_Defence = ev_SpecialAttack = ev_SpecialDefence = ev_Speed = 0;
            }

            /* Finally, set the health of the Pokemon using the new HP stats. */
            health = new AttributePair(HP);
        }
コード例 #4
0
ファイル: WorldScreen.cs プロジェクト: Metasynic/PkmnEngine
        /* The CheckSpawn() function checks if a wild Pokemon battle will be triggered on this frame.
         * It is only called when the player's StepCheck bit is true, so it is only called once every step. */
        private void CheckSpawn()
        {
            /* This Random object will be needed for a lot of things later. */
            Random r = new Random();

            /* Each MapLayer in the map needs to be checked for a Tile with its Spawn bit set to true. */
            foreach (MapLayer layer in world.CurrentMap.MapLayers)
            {
                /* If tile that the player is standing on in the layer has its Spawn bit set to true, a battle may happen. */
                if (layer.GetTile(player.Sprite.TileLocation.X, player.Sprite.TileLocation.Y).Spawn)
                {
                    /* This condition determines whether an actual battle happens or not.
                     * If a random double between 0 and 187.5 is less than the level's grass encounter rate, then a battle will happen.
                     * The most likely a battle can be to happen is a VeryCommon encounter rate, which is 10.0.
                     * With a VeryCommon encounter rate, the chance of a battle occurring is 10/187.5.
                     * The least likely a battle can be to happen is with a VeryRare encounter rate, which has a chance of 1.25/187.5.
                     * Note the the encounter rate is not how likely it is for a certain Pokemon to be battled - it is how likely that a battle will happen at all. */
                    if ((r.NextDouble() * 187.5) < World.CurrentLevel.GrassEncounterRate)
                    {
                        /* A new array of ProportionValue<PokemonSpawn> objects is created with the length of the GrassSpawns in the current level.
                         * GrassSpawns is a list of PokemonSpawn objects for the level's grass, stating what Pokemon at what level can be encountered.
                         * The spawns array is filled with ProportionValues created using the PokemonSpawn's Percentage property, and the PokemonSpawn object itself. */
                        ProportionValue <PokemonSpawn>[] spawns = new ProportionValue <PokemonSpawn> [World.CurrentLevel.GrassSpawns.Count];
                        for (int i = 0; i < spawns.Length; i++) // NOTE TO SELF: IT WOULD BE MORE EFFICIENT TO CREATE THE ARRAY IN A HIGHER SCOPE, SINCE IT IS PART OF THE LEVEL, BUT THIS WILL DO FOR NOW.
                        {
                            spawns[i] = ProportionValue.Create(World.CurrentLevel.GrassSpawns[i].Percentage, World.CurrentLevel.GrassSpawns[i]);
                        }

                        /* The encounter for the spawn is found proportionally from the array using ChooseByRandom().
                         * A new Pokemon object is created using the encounter data's ID, gender, and minimum/maximum levels.
                         * The wild Pokemon's level is chosen randomly between the minimum and maximum level in the selected PokemonSpawn.
                         * The moveset is currently just "Scratch". Although dynamic moveset generation is not part of the user requirements,
                         * I could add it if I have time by choosing the last four moves that the species can learn before it reaches its level. */
                        PokemonSpawn encounter = spawns.ChooseByRandom();
                        Pokemon      p         = new Pokemon(DataManager.PokemonSpecies[encounter.ID], Pokemon.GetGender(DataManager.PokemonSpecies[encounter.ID].GenderRatio), new[] { DataManager.Moves["Scratch"], null, null, null }, (byte)PkmnUtils.RandomInclusive(encounter.MinLevel, encounter.MaxLevel), null);

                        /* A wild battle is essentially a fight against an enemy team of one Pokemon.
                         * The BattleScreen.InitBattle() is called, which sends the player and enemy to the screen and sets the battle background index to zero.
                         * Finally, the BattleScreen is pushed on to the state stack. */
                        GameRef.BattleScreen.InitBattle(player.Team, p, 0);
                        Change(ChangeType.Push, GameRef.BattleScreen);
                    }
                }
            }
        }