pk3DS/pk3DS.Core/Randomizers/MoveRandomizer.cs
2017-09-23 06:51:14 -07:00

127 lines
4.0 KiB
C#

using System;
using System.Linq;
using pk3DS.Core.Structures;
using pk3DS.Core.Structures.PersonalInfo;
namespace pk3DS.Core.Randomizers
{
public class MoveRandomizer : IRandomizer
{
private readonly GameConfig Config;
private readonly int MaxMoveID;
private readonly Move[] MoveData;
private readonly PersonalInfo[] SpeciesStat;
private readonly GenericRandomizer RandMove;
public MoveRandomizer(GameConfig config)
{
Config = config;
MaxMoveID = config.Info.MaxMoveID;
MoveData = config.Moves;
SpeciesStat = config.Personal.Table;
RandMove = new GenericRandomizer(Enumerable.Range(1, MaxMoveID-1).ToArray());
}
public void Execute()
{
throw new NotImplementedException();
}
public bool rDMG = true;
public int rDMGCount = 2;
public bool rSTAB = true;
public int rSTABCount = 2;
public decimal rSTABPercent = 100;
public int[] BannedMoves = new int[0];
private int loopctr = 0;
public int[] GetRandomLearnset(int index, int movecount) => GetRandomLearnset(SpeciesStat[index].Types, movecount);
public int[] GetRandomLearnset(int[] Types, int movecount)
{
var oldSTABCount = rSTABCount;
rSTABCount = (int)(rSTABPercent * movecount / 100);
int[] moves = GetRandomMoveset(Types, movecount);
rSTABCount = oldSTABCount;
return moves;
}
public int[] GetRandomMoveset(int index, int movecount = 4) => GetRandomMoveset(SpeciesStat[index].Types, movecount);
public int[] GetRandomMoveset(int[] Types, int movecount = 4)
{
loopctr = 0;
const int maxLoop = 666;
int[] moves;
do { moves = GetRandomMoves(Types, movecount); }
while (!IsMovesetMeetingRequirements(moves, movecount) && loopctr++ <= maxLoop);
return moves;
}
private int[] GetRandomMoves(int[] Types, int movecount = 4)
{
int i = 0;
int[] moves = new int[movecount];
if (rSTAB)
for (; i < rSTABCount; i++)
moves[i] = GetRandomSTABMove(Types);
for (; i < moves.Length; i++) // remainder of moves
moves[i] = RandMove.Next();
return moves;
}
private int GetRandomSTABMove(int[] types)
{
int move;
do { move = RandMove.Next(); }
while (!types.Contains(MoveData[move].Type));
return move;
}
private bool IsMovesetMeetingRequirements(int[] moves, int count)
{
if (rDMG && rDMGCount > moves.Count(move => MoveData[move].Category != 0))
return false;
if (moves.Any(BannedMoves.Contains))
return false;
return moves.Distinct().Count() == count;
}
private static readonly int[] firstMoves =
{
1, // Pound
40, // Poison Sting
52, // Ember
55, // Water Gun
64, // Peck
71, // Absorb
84, // Thunder Shock
98, // Quick Attack
122, // Lick
141, // Leech Life
};
private static readonly GenericRandomizer first = new GenericRandomizer(firstMoves);
public int GetRandomFirstMoveAny()
{
first.Reset();
return first.Next();
}
public int GetRandomFirstMove(int index) => GetRandomFirstMove(SpeciesStat[index].Types);
public int GetRandomFirstMove(int[] types)
{
first.Reset();
int ctr = 0;
int move;
do
{
move = first.Next();
if (++ctr == firstMoves.Length)
return move;
} while (!types.Contains(MoveData[move].Type));
return move;
}
}
}