mirror of
https://github.com/kwsch/pk3DS.git
synced 2026-03-25 19:34:13 -05:00
127 lines
4.0 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|