Imlements baneful bunker, data fixes

This commit is contained in:
2025-01-10 12:55:25 +01:00
parent 6434f9925c
commit 92ab67ddf8
12 changed files with 209 additions and 17 deletions

View File

@@ -0,0 +1,15 @@
using PkmnLib.Dynamic.ScriptHandling;
using PkmnLib.Dynamic.ScriptHandling.Registry;
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
[Script(ScriptCategory.Move, "baneful_bunker")]
public class BanefulBunker : ProtectionScript
{
/// <inheritdoc />
protected override ProtectionEffectScript GetEffectScript()
{
return new BanefulBunkerEffect();
}
}

View File

@@ -0,0 +1,47 @@
using System;
using PkmnLib.Dynamic.Models;
using PkmnLib.Dynamic.ScriptHandling;
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
public abstract class ProtectionScript : Script
{
protected abstract ProtectionEffectScript GetEffectScript();
/// <inheritdoc />
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
{
var battleData = target.BattleData;
if (battleData == null)
return;
// If the user goes last in the turn, the move will fail
if (battleData.Battle.ChoiceQueue is not null && !battleData.Battle.ChoiceQueue.HasNext())
{
move.GetHitData(target, hit).Fail();
return;
}
var failure = target.Volatile.Get<ProtectionFailureScript>();
if (failure == null)
{
failure = new ProtectionFailureScript();
target.Volatile.Add(failure);
}
var successive = failure.ProtectTurns;
// Each time, the chance of success is divided by 3.
var chance = 1.0 / Math.Pow(3, successive);
var random = target.BattleData!.Battle.Random.GetFloat();
if (random < chance)
{
failure.ProtectTurns++;
failure.UsedProtect = true;
target.Volatile.Add(GetEffectScript());
}
else
{
move.GetHitData(target, hit).Fail();
}
}
}

View File

@@ -0,0 +1,17 @@
using PkmnLib.Dynamic.Models;
using PkmnLib.Static.Moves;
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
public class BanefulBunkerEffect : ProtectionEffectScript
{
/// <inheritdoc />
public override void BlockIncomingHit(IExecutingMove executingMove, IPokemon target, byte hitIndex, ref bool block)
{
base.BlockIncomingHit(executingMove, target, hitIndex, ref block);
if (executingMove.UseMove.Category != MoveCategory.Status && executingMove.UseMove.HasFlag("contact"))
{
executingMove.User.SetStatus("poisoned");
}
}
}

View File

@@ -0,0 +1,28 @@
using PkmnLib.Dynamic.Models;
using PkmnLib.Dynamic.ScriptHandling;
using PkmnLib.Static.Moves;
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
public abstract class ProtectionEffectScript : Script
{
/// <inheritdoc />
public override void BlockIncomingHit(IExecutingMove executingMove, IPokemon target, byte hitIndex, ref bool block)
{
if (target.BattleData == null)
return;
var originalTarget = executingMove.MoveChoice.TargetPosition;
var targetPosition = target.BattleData.Position;
// We only want to block the hit if it's explicitly targeting the Pokemon.
if (targetPosition != originalTarget)
return;
if (executingMove.UseMove.Target is MoveTarget.All or MoveTarget.SelfUse or MoveTarget.AllAlly
or MoveTarget.AllAdjacent)
return;
block = true;
}
}

View File

@@ -0,0 +1,32 @@
using PkmnLib.Dynamic.Models;
using PkmnLib.Dynamic.Models.Choices;
using PkmnLib.Dynamic.ScriptHandling;
using PkmnLib.Dynamic.ScriptHandling.Registry;
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
/// <summary>
/// Attached script for <see cref="ProtectionEffectScript"/> to keep track of the consecutive turns of using Protect,
/// or protect-like moves.
/// </summary>
[Script(ScriptCategory.Pokemon, "protection_failure")]
public class ProtectionFailureScript : Script
{
public int ProtectTurns { get; set; }
public bool UsedProtect { get; set; }
/// <inheritdoc />
public override void OnBeforeTurnStart(ITurnChoice choice)
{
UsedProtect = false;
}
/// <inheritdoc />
public override void OnEndTurn(IBattle battle)
{
if (!UsedProtect)
{
RemoveSelf();
}
}
}

View File

@@ -0,0 +1,10 @@
using PkmnLib.Dynamic.ScriptHandling;
using PkmnLib.Dynamic.ScriptHandling.Registry;
namespace PkmnLib.Plugin.Gen7.Scripts.Status;
[Script(ScriptCategory.Status, "poisoned")]
public class Poisoned : Script
{
// TODO: Implement the Poisoned status effect.
}