PkmnLibSharp/PkmnLibSharp/Library/Species/Species.cs

168 lines
5.8 KiB
C#
Raw Normal View History

2020-05-03 14:26:14 +00:00
using System;
2020-05-04 19:16:42 +00:00
using System.Collections.Generic;
2020-08-10 17:13:17 +00:00
using System.Linq;
using Creaturelib.Generated;
2020-05-02 17:54:07 +00:00
using Pkmnlib.Generated;
2020-05-02 20:58:08 +00:00
using PkmnLibSharp.Utilities;
using EvolutionData = PkmnLibSharp.Library.Evolution.EvolutionData;
2020-07-18 14:49:11 +00:00
using Random = PkmnLibSharp.Utilities.Random;
2020-05-02 17:54:07 +00:00
namespace PkmnLibSharp.Library
{
public class Species : PointerWrapper
{
public Species(ushort id, string name, Forme defaultForme, float genderRatio, string growthRate,
2020-08-10 17:13:17 +00:00
byte captureRate, byte baseHappiness, IReadOnlyCollection<string> eggGroups, IReadOnlyCollection<string> tags)
{
var ptr = IntPtr.Zero;
2020-08-10 17:13:17 +00:00
var tagsConverted = tags.Select(x => x.ToPtr()).ToArray();
var eggGroupsConverted = eggGroups.Select(x => x.ToPtr()).ToArray();
var eggGroupsPtr = eggGroupsConverted.ArrayPtr();
var tagsPtr = tagsConverted.ArrayPtr();
PokemonSpecies.Construct(ref ptr, id, name.ToPtr(), defaultForme.Ptr, genderRatio,
2020-08-10 17:13:17 +00:00
growthRate.ToPtr(), captureRate, baseHappiness, eggGroupsPtr, (ulong) eggGroups.Count,
tagsPtr, (ulong) tags.Count).Assert();
2020-08-09 09:01:43 +00:00
_formeCache.Add("default", defaultForme);
Initialize(ptr);
}
2020-05-04 19:16:42 +00:00
public ushort Id => CreatureSpecies.GetId(Ptr);
public float GenderRate => CreatureSpecies.GetGenderRate(Ptr);
public byte CaptureRate => CreatureSpecies.GetCaptureRate(Ptr);
public string Name => _name ??= CreatureSpecies.GetName(Ptr).PtrString()!;
public string GrowthRate => _growthRate ??= CreatureSpecies.GetGrowthRate(Ptr).PtrString()!;
2020-05-04 19:16:42 +00:00
2020-08-10 17:13:17 +00:00
public string[] EggGroups
{
get
{
if (_eggGroups != null) return _eggGroups;
var count = Pkmnlib.Generated.PokemonSpecies.GetEggGroupCount(Ptr);
_eggGroups = new string[count];
for (ulong i = 0; i < count; i++)
{
_eggGroups[i] = PokemonSpecies.GetEggGroup(Ptr, i).PtrString()!;
}
return _eggGroups;
}
}
2020-08-09 09:01:43 +00:00
public ReadOnlyNativePtrArray<Forme> Formes
{
get
{
if (_formes != null) return _formes;
var startPtr = CreatureSpecies.GetVariants(Ptr);
var size = CreatureSpecies.GetVariantsCount(Ptr);
2020-08-24 16:33:04 +00:00
_formes = new ReadOnlyNativePtrArray<Forme>(startPtr, (int) size, Constructor.GenericType.Forme);
2020-08-09 09:01:43 +00:00
return _formes;
}
}
public ReadOnlyNativePtrArray<EvolutionData> Evolutions
{
get
{
if (_evolutions != null) return _evolutions;
var ptr = IntPtr.Zero;
PokemonSpecies.GetEvolutions(Ptr, ref ptr);
var length = PokemonSpecies.GetEvolutionCount(Ptr);
2020-08-24 16:33:04 +00:00
_evolutions = new ReadOnlyNativePtrArray<EvolutionData>(ptr, (int) length, Constructor.GenericType.EvolutionData);
return _evolutions;
}
}
2020-05-04 19:16:42 +00:00
public bool HasForme(string s)
{
return CreatureSpecies.HasVariant(Ptr, s.ToPtr()) == MarshalHelper.True;
}
public bool TryGetForme(string s, out Forme? forme)
2020-05-04 19:16:42 +00:00
{
2020-08-09 09:01:43 +00:00
if (_formeCache.TryGetValue(s, out forme))
2020-05-04 19:16:42 +00:00
return true;
var ptr = IntPtr.Zero;
if (CreatureSpecies.TryGetVariant(Ptr, s.ToPtr(), ref ptr) == MarshalHelper.True)
{
if (TryResolvePointer(ptr, out forme))
{
2020-08-09 09:01:43 +00:00
_formeCache.Add(s, forme!);
2020-05-04 19:16:42 +00:00
return true;
}
forme = Constructor.Active.ConstructForme(ptr)!;
2020-08-09 09:01:43 +00:00
_formeCache.Add(s, forme);
2020-05-04 19:16:42 +00:00
return true;
}
return false;
}
public Forme GetForme(string s)
{
2020-08-09 09:01:43 +00:00
if (_formeCache.TryGetValue(s, out var forme))
2020-05-04 19:16:42 +00:00
return forme;
var ptr = IntPtr.Zero;
CreatureSpecies.GetVariant(ref ptr, Ptr, s.ToPtr()).Assert();
if (TryResolvePointer(ptr, out Forme? f))
2020-05-04 19:16:42 +00:00
{
2020-08-09 09:01:43 +00:00
_formeCache.Add(s, f!);
return f!;
2020-05-04 19:16:42 +00:00
}
forme = Constructor.Active.ConstructForme(ptr)!;
2020-08-09 09:01:43 +00:00
_formeCache.Add(s, forme);
2020-05-04 19:16:42 +00:00
return forme;
}
public void SetForme(string s, Forme forme)
{
2020-08-09 09:01:43 +00:00
_formeCache.Add(s, forme);
2020-05-04 19:16:42 +00:00
CreatureSpecies.SetVariant(Ptr, s.ToPtr(), forme.Ptr).Assert();
}
2020-07-18 14:49:11 +00:00
public Gender GetRandomGender(Random random)
{
return (Gender) CreatureSpecies.GetRandomGender(Ptr, random.Ptr);
}
public void AddEvolution(EvolutionData evolutionData)
2020-05-02 17:54:07 +00:00
{
Pkmnlib.Generated.PokemonSpecies.AddEvolution(Ptr, evolutionData.Ptr);
2020-05-02 17:54:07 +00:00
}
2020-08-10 17:13:17 +00:00
public bool HasFlag(string flag)
{
return CreatureSpecies.HasFlag(Ptr, flag.ToPtr()) == 1;
}
private string? _name;
private string? _growthRate;
2020-05-02 17:54:07 +00:00
2020-08-09 09:01:43 +00:00
private readonly Dictionary<string, Forme> _formeCache =
new Dictionary<string, Forme>(StringComparer.InvariantCultureIgnoreCase);
private ReadOnlyNativePtrArray<EvolutionData>? _evolutions;
2020-08-09 09:01:43 +00:00
private ReadOnlyNativePtrArray<Forme>? _formes;
2020-08-10 17:13:17 +00:00
private string[]? _eggGroups;
2020-05-03 14:26:14 +00:00
public override string ToString()
{
return $"(#{Ptr}) -> Species: {Name}";
}
protected internal override void MarkAsDeleted()
{
base.MarkAsDeleted();
2020-08-09 09:01:43 +00:00
foreach (var forme in _formeCache)
{
forme.Value.MarkAsDeleted();
}
}
protected override void DeletePtr()
2020-05-02 17:54:07 +00:00
{
2020-05-03 14:26:14 +00:00
PokemonSpecies.Destruct(Ptr);
2020-05-02 17:54:07 +00:00
}
}
}