This commit is contained in:
parent
e5041ec5f0
commit
f061ba2455
28
PkmnLib.Dynamic/Events/EvolutionEvent.cs
Normal file
28
PkmnLib.Dynamic/Events/EvolutionEvent.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using PkmnLib.Dynamic.Models;
|
||||
using PkmnLib.Static.Species;
|
||||
|
||||
namespace PkmnLib.Dynamic.Events;
|
||||
|
||||
public record EvolutionEvent : IEventData
|
||||
{
|
||||
public IPokemon Pokemon { get; }
|
||||
public ISpecies Species { get; }
|
||||
public IForm OriginalForm { get; }
|
||||
public ISpecies NewSpecies { get; }
|
||||
public IForm NewForm { get; }
|
||||
public IEvolution Evolution { get; }
|
||||
|
||||
public EvolutionEvent(IPokemon pokemon, ISpecies species, IForm originalForm, ISpecies newSpecies, IForm newForm,
|
||||
IEvolution evolution)
|
||||
{
|
||||
Pokemon = pokemon;
|
||||
Species = species;
|
||||
NewSpecies = newSpecies;
|
||||
Evolution = evolution;
|
||||
OriginalForm = originalForm;
|
||||
NewForm = newForm;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public EventBatchId BatchId { get; init; }
|
||||
}
|
@ -204,7 +204,7 @@ public interface IPokemon : IScriptSource, IDeepCloneable
|
||||
/// <summary>
|
||||
/// Marks the Pokemon as caught. This makes it so that the Pokemon is not considered valid in battle anymore.
|
||||
/// </summary>
|
||||
public void MarkAsCaught();
|
||||
void MarkAsCaught();
|
||||
|
||||
/// <summary>
|
||||
/// The script for the held item.
|
||||
@ -293,7 +293,7 @@ public interface IPokemon : IScriptSource, IDeepCloneable
|
||||
/// <summary>
|
||||
/// Suppresses the ability of the Pokémon.
|
||||
/// </summary>
|
||||
public void SuppressAbility();
|
||||
void SuppressAbility();
|
||||
|
||||
/// <summary>
|
||||
/// Returns the currently active ability.
|
||||
@ -313,15 +313,21 @@ public interface IPokemon : IScriptSource, IDeepCloneable
|
||||
/// </summary>
|
||||
void RecalculateBoostedStats();
|
||||
|
||||
/// <summary>
|
||||
/// Evolves the Pokemon to a specific evolution. This will not check whether the evolution is valid, so
|
||||
/// you should check that before calling this method.
|
||||
/// </summary>
|
||||
bool EvolveTo(IEvolution evolution, EventHook? eventHook = null);
|
||||
|
||||
/// <summary>
|
||||
/// Change the species of the Pokemon.
|
||||
/// </summary>
|
||||
void ChangeSpecies(ISpecies species, IForm form);
|
||||
void ChangeSpecies(ISpecies species, IForm form, EventHook? eventHook = null);
|
||||
|
||||
/// <summary>
|
||||
/// Change the form of the Pokemon.
|
||||
/// </summary>
|
||||
void ChangeForm(IForm form, EventBatchId batchId = default);
|
||||
void ChangeForm(IForm form, EventBatchId batchId = default, EventHook? eventHook = null);
|
||||
|
||||
/// <summary>
|
||||
/// Whether the Pokemon is useable in a battle.
|
||||
@ -606,7 +612,7 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||
public IDynamicLibrary Library { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ISpecies Species { get; }
|
||||
public ISpecies Species { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IForm Form { get; private set; }
|
||||
@ -985,8 +991,25 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||
public void RecalculateBoostedStats() => Library.StatCalculator.CalculateBoostedStats(this, BoostedStats);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ChangeSpecies(ISpecies species, IForm form)
|
||||
public bool EvolveTo(IEvolution evolution, EventHook? eventHook = null)
|
||||
{
|
||||
if (!Species.EvolutionData.Contains(evolution))
|
||||
return false;
|
||||
if (!Library.StaticLibrary.Species.TryGet(evolution.ToSpecies, out var species))
|
||||
return false;
|
||||
|
||||
// TODO: Consider how forms work with evolution items.
|
||||
var newForm = species.GetDefaultForm();
|
||||
eventHook?.Invoke(new EvolutionEvent(this, Species, Form, species, newForm, evolution));
|
||||
|
||||
ChangeSpecies(species, newForm, eventHook);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ChangeSpecies(ISpecies species, IForm form, EventHook? eventHook = null)
|
||||
{
|
||||
eventHook ??= BattleData?.Battle.EventHook;
|
||||
if (Species == species)
|
||||
{
|
||||
if (form != Form)
|
||||
@ -1007,18 +1030,20 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||
}
|
||||
|
||||
var batchId = new EventBatchId();
|
||||
BattleData?.Battle.EventHook.Invoke(new SpeciesChangeEvent(this, species, form)
|
||||
eventHook?.Invoke(new SpeciesChangeEvent(this, species, form)
|
||||
{
|
||||
BatchId = batchId,
|
||||
});
|
||||
Species = species;
|
||||
ChangeForm(form, batchId);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ChangeForm(IForm form, EventBatchId batchId = default)
|
||||
public void ChangeForm(IForm form, EventBatchId batchId = default, EventHook? eventHook = null)
|
||||
{
|
||||
if (form == Form)
|
||||
return;
|
||||
eventHook ??= BattleData?.Battle.EventHook;
|
||||
|
||||
var oldAbility = Form.GetAbility(AbilityIndex);
|
||||
|
||||
@ -1068,7 +1093,7 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||
|
||||
// TODO: form specific moves?
|
||||
|
||||
BattleData?.Battle.EventHook.Invoke(new FormChangeEvent(this, form)
|
||||
eventHook?.Invoke(new FormChangeEvent(this, form)
|
||||
{
|
||||
BatchId = batchId,
|
||||
});
|
||||
|
@ -46,12 +46,12 @@ public abstract class ItemScript : IDeepCloneable
|
||||
/// <summary>
|
||||
/// Returns whether the item can be held by a Pokémon.
|
||||
/// </summary>
|
||||
public virtual bool IsHoldable => false;
|
||||
public virtual bool IsHoldable => true;
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the item can be held by the given target.
|
||||
/// </summary>
|
||||
public virtual bool CanTargetHold(IPokemon pokemon) => false;
|
||||
public virtual bool CanTargetHold(IPokemon pokemon) => true;
|
||||
|
||||
/// <summary>
|
||||
/// Handles the use of the item.
|
||||
|
@ -12,6 +12,7 @@ public class ScriptResolver
|
||||
private IReadOnlyDictionary<(ScriptCategory, StringKey), Func<Script>> _scriptCtors;
|
||||
private IReadOnlyDictionary<StringKey, Func<IItem, ItemScript>> _itemScriptCtors;
|
||||
private readonly Dictionary<IItem, ItemScript> _itemBattleScripts = new();
|
||||
private readonly Dictionary<IItem, ItemScript> _itemScripts = new();
|
||||
|
||||
/// <inheritdoc cref="ScriptResolver"/>
|
||||
public ScriptResolver(IReadOnlyDictionary<(ScriptCategory, StringKey), Func<Script>> scriptCtors,
|
||||
@ -67,4 +68,32 @@ public class ScriptResolver
|
||||
_itemBattleScripts[item] = script;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try and resolve an item script for the given item. If the item does not have a script, return false.
|
||||
/// </summary>
|
||||
public bool TryResolveItemScript(IItem item, [MaybeNullWhen(false)] out ItemScript script)
|
||||
{
|
||||
if (_itemScripts.TryGetValue(item, out script))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var effect = item.Effect;
|
||||
if (effect == null)
|
||||
{
|
||||
script = null;
|
||||
return false;
|
||||
}
|
||||
if (!_itemScriptCtors.TryGetValue(effect.Name, out var scriptCtor))
|
||||
{
|
||||
script = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
script = scriptCtor(item);
|
||||
script.OnInitialize(effect.Parameters);
|
||||
_itemScripts[item] = script;
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1840,6 +1840,9 @@
|
||||
"price": 3000,
|
||||
"additionalData": {
|
||||
"flingPower": 30
|
||||
},
|
||||
"effect": {
|
||||
"name": "evolution_use"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -4591,6 +4594,12 @@
|
||||
"parameters": {
|
||||
"heal_amount": 20
|
||||
}
|
||||
},
|
||||
"battleEffect": {
|
||||
"name": "healing_item",
|
||||
"parameters": {
|
||||
"healAmount": 20
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
54
Plugins/PkmnLib.Plugin.Gen7/Scripts/Items/EvolutionItem.cs
Normal file
54
Plugins/PkmnLib.Plugin.Gen7/Scripts/Items/EvolutionItem.cs
Normal file
@ -0,0 +1,54 @@
|
||||
using PkmnLib.Static.Species;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Scripts.Items;
|
||||
|
||||
[ItemScript("evolution_use")]
|
||||
public class EvolutionItem : ItemScript
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public EvolutionItem(IItem item) : base(item)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsItemUsable => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool RequiresTarget => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsTargetValid(IPokemon target)
|
||||
{
|
||||
foreach (var x in target.Species.EvolutionData)
|
||||
{
|
||||
switch (x)
|
||||
{
|
||||
case ItemUseEvolution itemUseEvolution when itemUseEvolution.Item == Item.Name:
|
||||
return true;
|
||||
case ItemGenderEvolution itemGenderEvolution when itemGenderEvolution.Item == Item.Name:
|
||||
return itemGenderEvolution.Gender == target.Gender;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnUseWithTarget(IPokemon target, EventHook eventHook)
|
||||
{
|
||||
var evolutionData = target.Species.EvolutionData.FirstOrDefault(x =>
|
||||
{
|
||||
switch (x)
|
||||
{
|
||||
case ItemUseEvolution itemUseEvolution when itemUseEvolution.Item == Item.Name:
|
||||
case ItemGenderEvolution itemGenderEvolution when itemGenderEvolution.Item == Item.Name:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (evolutionData == null)
|
||||
return;
|
||||
|
||||
target.EvolveTo(evolutionData, eventHook);
|
||||
}
|
||||
}
|
@ -29,7 +29,7 @@ public class HealingItem : ItemScript
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsTargetValid(IPokemon target) => !target.IsFainted;
|
||||
public override bool IsTargetValid(IPokemon target) => !target.IsFainted && target.CurrentHealth < target.MaxHealth;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnUseWithTarget(IPokemon target, EventHook eventHook)
|
||||
|
Loading…
x
Reference in New Issue
Block a user