116 lines
4.9 KiB
C#
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)
|
|
}
|
|
}
|
|
}
|
|
} |