Files
zfxaction25/RobotAndDonkey.Game/Modifiers/CorruptModifier.cs
2026-04-19 00:43:27 +02:00

116 lines
4.9 KiB
C#

using RobotAndDonkey.Game.Cards;
using RobotAndDonkey.Game.Execution;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Pois;
using RobotAndDonkey.Game.Utils;
using Interact = RobotAndDonkey.Game.Intents.Interact;
using Move = RobotAndDonkey.Game.Intents.Move;
using Rest = RobotAndDonkey.Game.Intents.Rest;
namespace RobotAndDonkey.Game.Modifiers;
public record CorruptCellModifier(EModifierDuration Duration) : CorruptModifierBase(EModifierKind.Cell, Duration)
{
protected override CorruptCellModifier CreateInstance() => new(Duration);
public override string ToolTip => "While in this area, instructions will have the opposite effect.";
}
public record CorruptCardModifier(EModifierDuration Duration) : CorruptModifierBase(EModifierKind.Card, Duration)
{
protected override CorruptCardModifier CreateInstance() => new(Duration);
public override string ToolTip => "The instruction will have the opposite effect.";
}
public abstract record CorruptModifierBase(EModifierKind Kind, EModifierDuration Duration) : Modifier(Kind, EModifierId.Corrupt, Duration)
{
public override void Before(Guid requestId, ReadOnlySpan<Intent> intents, CoreLoop coreLoop, Entity owner, List<Intent> newIntents, List<Result> results)
{
if (coreLoop.RunPhase != ERunPhase.ExecuteProgram)
return;
foreach (var intent in intents)
{
switch (intent)
{
case Move m:
{
m.Direction = m.Direction.Opposite();
break;
}
case Turn t:
{
t.Delta = -t.Delta;
break;
}
case Rest rest when owner is Card card:
{
rest.DebuffSources.Add(this);
var board = coreLoop.Board;
var avatarCell = board.Cells.First(c => c.Poi is Avatar);
newIntents.Add(new Move(avatarCell, card, ((Avatar)avatarCell.Poi!).Direction.Opposite(), false, 1));
break;
}
case Interact interact:
{
var board = coreLoop.Board;
var avatarCell = board.Cells.First(c => c.Poi is Avatar);
var targetHex = avatarCell.Hex.GetNeighbour(interact.Direction);
var cellIndex = board.FindCellIndex(targetHex);
var cell = cellIndex >= 0 ? board.Cells[cellIndex] : null;
if (cell != null)
{
interact.DebuffSources.Add(this);
if (cell.Poi is Shed)
{
results.Add(new InvalidInstructionResult(requestId, EInvalidReason.NoTarget, owner as Card, cell));
newIntents.Add(new ModifyCurrency(new(-interact.EnergyCost, 0, 0, 0, 0, 0)));
}
else if (cell.Poi is Crate crate)
{
var carrying = coreLoop.Currency.Carry;
newIntents.Add(new PickUp(cell, crate, -carrying, interact.EnergyCost));
}
else if (cell.Poi == null && coreLoop.HasDonkey && owner is Card card)
newIntents.Add(new DonkeyIntent(card, cell, interact.EnergyCost));
else if (cell.Poi is Tower tower)
newIntents.Add(new TowerIntent(cell, tower, true, interact.EnergyCost));
else
{
results.Add(new InvalidInstructionResult(requestId, EInvalidReason.NoTarget, owner as Card, cell));
newIntents.Add(new ModifyCurrency(new(-interact.EnergyCost, 0, 0, 0, 0, 0)));
}
}
break;
}
case ImmunizeCard { CanCorrupt: true } immunizeCard:
{
immunizeCard.DebuffState = false;
break;
}
case TowerIntent tower:
{
tower.Active = true;
break;
}
case ModifyCurrency { CanCorrupt: true, Delta: { } delta } modifyCurrency:
{
modifyCurrency.Delta = new(delta.Energy * -1, delta.MaxCarry * -1, delta.Carry * -1, delta.Delivery * -1, delta.TapeLength * -1, delta.HandSize * -1);
break;
}
case DetoxiumPrime detoxiumPrime:
{
detoxiumPrime.Heal = false;
break;
}
// #Next: handled in the cards that reference tape order (Repeat / Stabilize)
}
}
}
}