PkmnLibRSharp/PkmnLibRSharp/StaticData/Libraries/TypeLibrary.cs

88 lines
3.4 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using PkmnLibSharp.FFI;
using PkmnLibSharp.Utils;
using Interface = PkmnLibSharp.FFI.StaticData.Libraries.TypeLibrary;
namespace PkmnLibSharp.StaticData.Libraries
{
/// <summary>
/// All data related to types and effectiveness.
/// </summary>
public class TypeLibrary : HandleType
{
private Dictionary<string, TypeIdentifier> _typeCache = new(StringComparer.InvariantCultureIgnoreCase);
/// <inheritdoc cref="TypeLibrary"/>
protected TypeLibrary(FFIHandle handle) : base(handle)
{
}
/// <summary>
/// Instantiates a new type library with a specific capacity.
/// </summary>
public static TypeLibrary Create(ulong capacity)
{
var handle = Interface.type_library_new(capacity);
var lib = Resolver.Instance.ResolveTypeLibrary(handle.Resolve());
lib._typeCache =
new Dictionary<string, TypeIdentifier>((int)capacity, StringComparer.InvariantCultureIgnoreCase);
return lib;
}
/// <summary>
/// Gets the type identifier for a type with a name.
/// </summary>
public TypeIdentifier GetTypeId(string name)
{
if (_typeCache.TryGetValue(name, out var typeIdentifier))
return typeIdentifier;
throw new KeyNotFoundException($"No type found with name `{name}`");
}
/// <summary>
/// Gets the type name from the type identifier.
/// </summary>
public string GetTypeName(TypeIdentifier typeIdentifier)
{
var fd = _typeCache.FirstOrDefault(x => x.Value == typeIdentifier);
if (fd.Key != null)
return fd.Key;
throw new KeyNotFoundException($"No type found for given identifier");
}
/// <summary>
/// Gets the effectiveness for a single attacking type against a single defending type.
/// </summary>
public float GetSingleEffectiveness(TypeIdentifier attacking, TypeIdentifier defending) =>
Interface.type_library_get_single_effectiveness(Handle, attacking, defending);
/// <summary>
/// Gets the effectiveness for a single attacking type against an amount of defending types.
/// This is equivalent to running <see cref="GetSingleEffectiveness"/> on each defending type, and
/// multiplying the results with each other.
/// </summary>
public float GetEffectiveness(TypeIdentifier attacking, TypeIdentifier[] defending)
{
var arrayPtr = defending.ArrayPtr();
return Interface.type_library_get_effectiveness(Handle, attacking, arrayPtr, (ulong)defending.Length);
}
/// <summary>
/// Registers a new type in the library.
/// </summary>
public TypeIdentifier RegisterType(string name)
{
var typeId = Interface.type_library_register_type(Handle, name.ToPtr());
_typeCache.Add(name, typeId);
return typeId;
}
/// <summary>
/// Sets the effectiveness for an attacking type against a defending type.
/// </summary>
public void SetEffectiveness(TypeIdentifier attacking, TypeIdentifier defending, float effectiveness) =>
Interface.type_library_set_effectiveness(Handle, attacking, defending, effectiveness);
}
}