ported from perforce

This commit is contained in:
2026-04-19 00:43:27 +02:00
commit 6c0c33f5d4
700 changed files with 19735 additions and 0 deletions

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace RobotAndDonkey.Game.Cards;
public class AvailableCards
{
static AvailableCards()
{
Instance = new();
var cardTypes = Instance.GetType().Assembly.GetTypes().Where(t => !t.IsAbstract && t.BaseType?.BaseType == typeof(Card) || t.BaseType?.BaseType?.BaseType == typeof(Card));
foreach (var type in cardTypes)
{
var card = (Card)Activator.CreateInstance(type)!;
Instance.Cards.Add(card.Id, card);
}
}
public static AvailableCards Instance { get; }
public Dictionary<ECard, Card> Cards { get; } = [];
public Card Create(ECard card)
{
return Cards[card].DeepClone();
}
}

View File

@@ -0,0 +1,43 @@
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Modifiers;
namespace RobotAndDonkey.Game.Cards;
public record Card(ECard Id, ECardType CardType, ERarity Rarity, int ShopCost, int BasePlayCost) : Entity
{
public Card DeepClone()
{
var result = (Card)Activator.CreateInstance(GetType())!;
result.PlayCost = PlayCost;
result.CardId = CardId;
foreach (var modifier in Modifiers)
result.AddModifier(modifier.DeepClone(), []);
return result;
}
public virtual void CreateIntents(Cell? avatarCell, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
if (PlayCost > 0)
intents.Add(new CardCostIntent(this, PlayCost));
}
public int PlayCost { get; set; } = BasePlayCost;
public virtual string Name => Id.ToString();
public virtual string ToolTip => Name;
public sealed override string ToString()
{
return $"{Id}" + base.ToString();
}
public int OccupiedSpace => Modifiers.Any(m => m.Id == EModifierId.Efficient) ? 0 : 1;
public Guid CardId { get; private set; } = Guid.NewGuid();
public virtual Modifier[] TooltipModifiers => [];
}

View File

@@ -0,0 +1,42 @@
namespace RobotAndDonkey.Game.Cards;
public enum ECard
{
// Glitches
Bitflip, // corrupt one instruction, permanent
ShortCircuit, // unreliable one instruction, permanent
Slipstream, // race condition one instruction, permanent
Latency, // throttle one instruction, permanent
Rain, // 1 in X grass cells become mud, dry grass becomes grass, permanent
Drought, // fertile becomes grass, 1 in X grass cells become dry, #Temporary
Pest, // delivery malus, temporary
Gravity, // carry malus, temporary
HeatWave, // energy malus, temporary
//SandStorm, // JAM, preview malus, temporary
SolarFlare, // corrupt everything, temporary
LightningStorm, // unreliable everything, temporary
MeteorStorm, // race condition everything, temporary
WindStorm, // throttle everything, temporary
// Patches
Move = 0x1000,
TurnLeft,
TurnRight,
Interact,
NoOp,
Potentiate, // adds effective
Optimize, // adds optimized
Streamline, // adds efficient
Persist, // adds persistent
Remember, // adds memory
Reason, // adds hand size
DetoxiumPrime, // Converts #Forward mud into grass or grass into fertile
FlyingDisk, // Move #Forward into 1 blocked cell
AluminumHat, // instructions are #Immune to the effects of unreliable, #ShortTerm
EMField, // instructions are #Immune to the effects of corrupt #ShortTerm
AtomicClock, // instructions are #Immune to the effects of race condition #ShortTerm
Jump, // move #Forward 2 cells, ignoring blocking
Repeat, // copy #Next
Rest, // restores energy
Stabilize // nullifies the effect of any modifiers of #Next
}

View File

@@ -0,0 +1,7 @@
namespace RobotAndDonkey.Game.Cards;
public enum ECardType
{
Glitch,
Patch,
}

View File

@@ -0,0 +1,10 @@
namespace RobotAndDonkey.Game.Cards;
public enum ERarity
{
Common,
Magic,
Uncommon,
Rare,
Legendary
}

View File

@@ -0,0 +1,3 @@
namespace RobotAndDonkey.Game.Cards.Glitches;
public record Bitflip() : ModifyInstructionPermanently(EModifierId.Corrupt, ECard.Bitflip);

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Data;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Modifiers;
namespace RobotAndDonkey.Game.Cards.Glitches;
public record Drought() : GlitchCard(ECard.Drought)
{
public override void CreateIntents(Cell? avatarCell, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
var cells = coreLoop.Board.Cells;
foreach (var cell in cells)
{
if (cell.Type == ECellType.Fertile)
{
intents.Add(new ModifyCell(cell, EModifierId.Drought, EModifierDuration.Temporary));
}
else if (cell.Type == ECellType.Grass)
{
if (coreLoop.Random.NextSingle() < Balancing.Instance.DroughtTransformProbability)
intents.Add(new ModifyCell(cell, EModifierId.Drought, EModifierDuration.Temporary));
}
}
}
public override string ToolTip => "Fertility in the land is drastically reduced.";
public override Modifier[] TooltipModifiers => [new DroughtModifier(EModifierDuration.Temporary)];
}

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
namespace RobotAndDonkey.Game.Cards.Glitches;
public record GlitchCard(ECard Id) : Card(Id, ECardType.Glitch, ERarity.Common, 0, 0)
{
public override void CreateIntents(Cell? avatarCell, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
base.CreateIntents(avatarCell, coreLoop, requestId, intents, results);
}
}

View File

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Modifiers;
namespace RobotAndDonkey.Game.Cards.Glitches;
public record Gravity() : GlitchCard(ECard.Gravity)
{
public override void CreateIntents(Cell? avatarCell, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
intents.Add(new ModifyRobot(EModifierId.Gravity, EModifierDuration.Temporary));
}
public override string ToolTip => "Carry capacity temporarily reduced.";
public override Modifier[] TooltipModifiers => [new GravityModifier(EModifierDuration.Temporary)];
}

View File

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Modifiers;
namespace RobotAndDonkey.Game.Cards.Glitches;
public record HeatWave() : GlitchCard(ECard.HeatWave)
{
public override void CreateIntents(Cell? avatarCell, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
intents.Add(new ModifyRobot(EModifierId.HeatWave, EModifierDuration.Temporary));
}
public override string ToolTip => "Energy consumption temporarily increased.";
public override Modifier[] TooltipModifiers => [new HeatWaveModifier(EModifierDuration.Temporary)];
}

View File

@@ -0,0 +1,7 @@
using System;
using System.Collections.Generic;
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Execution.Results;
namespace RobotAndDonkey.Game.Cards.Glitches;
public record Latency() : ModifyInstructionPermanently(EModifierId.Throttled, ECard.Latency);

View File

@@ -0,0 +1,3 @@
namespace RobotAndDonkey.Game.Cards.Glitches;
public record LightningStorm() : ModifyInstructionsTemporarily(EModifierId.Unreliable, ECard.LightningStorm);

View File

@@ -0,0 +1,3 @@
namespace RobotAndDonkey.Game.Cards.Glitches;
public record MeteorStorm() : ModifyInstructionsTemporarily(EModifierId.RaceCondition, ECard.MeteorStorm);

View File

@@ -0,0 +1,21 @@
using RobotAndDonkey.Game;
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Cards;
using RobotAndDonkey.Game.Cards.Glitches;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Modifiers;
public abstract record ModifyInstructionPermanently(EModifierId Modifier, ECard Id) : GlitchCard(Id)
{
public override void CreateIntents(Cell? avatarCell, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
var victim = coreLoop.PatchDeck[coreLoop.Random.Next(coreLoop.PatchDeck.Count)];
intents.Add(new ModifyCard(victim, Modifier, EModifierDuration.Permanent, ECardLocation.Deck));
}
public override string ToolTip => $"Adds {Modifier} to one instruction, permanently.";
public override Modifier[] TooltipModifiers => [ModifyCard.Create(Modifier, EModifierDuration.Permanent)];
}

View File

@@ -0,0 +1,20 @@
using RobotAndDonkey.Game;
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Cards;
using RobotAndDonkey.Game.Cards.Glitches;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Modifiers;
public abstract record ModifyInstructionsTemporarily(EModifierId Modifier, ECard Id) : GlitchCard(Id)
{
public override void CreateIntents(Cell? avatarCell, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
intents.AddRange(coreLoop.PatchDeck.Select(victim => new ModifyCard(victim, Modifier, EModifierDuration.Temporary, ECardLocation.Deck)));
}
public override string ToolTip => $"Adds {Modifier} to all instructions, temporarily.";
public override Modifier[] TooltipModifiers => [ModifyCard.Create(Modifier, EModifierDuration.Temporary)];
}

View File

@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Data;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Modifiers;
namespace RobotAndDonkey.Game.Cards.Glitches;
public record Pest() : GlitchCard(ECard.Pest)
{
public override void CreateIntents(Cell? avatarCell, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
intents.Add(new ModifyRobot(EModifierId.Pest, EModifierDuration.Temporary));
}
public override string ToolTip => $"Deliveries temporarily reduced by {Balancing.Instance.PestDeliveryMultiplier * 100:N0}%.";
public override Modifier[] TooltipModifiers => [new PestModifier(EModifierDuration.Temporary)];
}

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Data;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Modifiers;
namespace RobotAndDonkey.Game.Cards.Glitches;
public record Rain() : GlitchCard(ECard.Rain)
{
public override void CreateIntents(Cell? avatarCell, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
var cells = coreLoop.Board.Cells;
foreach (var cell in cells)
{
if (cell.Type == ECellType.Rocky)
{
intents.Add(new ModifyCell(cell, EModifierId.Rain, EModifierDuration.Temporary));
}
else if (cell.Type == ECellType.Grass)
{
if (coreLoop.Random.NextSingle() < Balancing.Instance.RainTransformProbability)
intents.Add(new ModifyCell(cell, EModifierId.Rain, EModifierDuration.Temporary));
}
}
}
public override string ToolTip => "Increases fertility throughout the map.";
public override Modifier[] TooltipModifiers => [new RainModifier(EModifierDuration.Temporary)];
}

View File

@@ -0,0 +1,3 @@
namespace RobotAndDonkey.Game.Cards.Glitches;
public record ShortCircuit() : ModifyInstructionPermanently(EModifierId.Unreliable, ECard.ShortCircuit);

View File

@@ -0,0 +1,3 @@
namespace RobotAndDonkey.Game.Cards.Glitches;
public record Slipstream() : ModifyInstructionPermanently(EModifierId.RaceCondition, ECard.Slipstream);

View File

@@ -0,0 +1,3 @@
namespace RobotAndDonkey.Game.Cards.Glitches;
public record SolarFlare() : ModifyInstructionsTemporarily(EModifierId.Corrupt, ECard.SolarFlare);

View File

@@ -0,0 +1,3 @@
namespace RobotAndDonkey.Game.Cards.Glitches;
public record WindStorm() : ModifyInstructionsTemporarily(EModifierId.Throttled, ECard.WindStorm);

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Data;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Modifiers;
using RobotAndDonkey.Game.Pois;
namespace RobotAndDonkey.Game.Cards.Patches;
public record AluminumHat() : PatchCard(ECard.AluminumHat, Balancing.Instance.AluminumHatCost, Balancing.Instance.CardPlayEnergyCost, ERarity.Uncommon)
{
protected override void CreateIntents(Cell avatarCell, Avatar avatar, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
var tape = coreLoop.GetTapeCards();
var index = tape.IndexOf(this);
if (index < 0)
{
results.Add(new InvalidInstructionResult(requestId, EInvalidReason.NotFound, this, avatarCell));
return;
}
for (int i = index + 1; i < tape.Count; ++i)
{
intents.Add(new ImmunizeCard(this, tape[i], EModifierId.Unreliable, EModifierDuration.ShortTerm));
}
}
public override string ToolTip => "Instructions on tape become #Immune to the effects of unreliable";
public override Modifier[] TooltipModifiers => [new UnreliableCardModifier(EModifierDuration.Temporary)];
}

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Data;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Modifiers;
using RobotAndDonkey.Game.Pois;
namespace RobotAndDonkey.Game.Cards.Patches;
public record AtomicClock() : PatchCard(ECard.AtomicClock, Balancing.Instance.AtomicClockCost, Balancing.Instance.CardPlayEnergyCost, ERarity.Uncommon)
{
protected override void CreateIntents(Cell avatarCell, Avatar avatar, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
var tape = coreLoop.GetTapeCards();
var index = tape.IndexOf(this);
if (index < 0)
{
results.Add(new InvalidInstructionResult(requestId, EInvalidReason.NotFound, this, avatarCell));
return;
}
for (int i = index + 1; i < tape.Count; ++i)
{
intents.Add(new ImmunizeCard(this, tape[i], EModifierId.RaceCondition, EModifierDuration.ShortTerm));
}
}
public override string ToolTip => "Instructions on tape become #Immune to the effects of race condition";
public override Modifier[] TooltipModifiers => [new RaceConditionModifier(EModifierDuration.Temporary)];
}

View File

@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Data;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Modifiers;
using RobotAndDonkey.Game.Pois;
namespace RobotAndDonkey.Game.Cards.Patches;
public record DetoxiumPrime() : PatchCard(ECard.DetoxiumPrime, Balancing.Instance.DetoxiumPrimeCost, Balancing.Instance.CardPlayEnergyCost, ERarity.Uncommon)
{
protected override void CreateIntents(Cell avatarCell, Avatar avatar, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
intents.Add(new Intents.DetoxiumPrime(avatarCell, this, avatar.Direction));
}
public override string Name => "Detoxium Prime";
public override string ToolTip => "Heals the cell in front";
}

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Data;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Modifiers;
using RobotAndDonkey.Game.Pois;
namespace RobotAndDonkey.Game.Cards.Patches;
public record EMField() : PatchCard(ECard.EMField, Balancing.Instance.EMFieldCost, Balancing.Instance.CardPlayEnergyCost, ERarity.Uncommon)
{
protected override void CreateIntents(Cell avatarCell, Avatar avatar, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
var tape = coreLoop.GetTapeCards();
var index = tape.IndexOf(this);
if (index < 0)
{
results.Add(new InvalidInstructionResult(requestId, EInvalidReason.NotFound, this, avatarCell));
return;
}
for (int i = index + 1; i < tape.Count; ++i)
{
intents.Add(new ImmunizeCard(this, tape[i], EModifierId.Corrupt, EModifierDuration.Temporary));
}
}
public override string ToolTip => "Instructions on tape become #Immune to the effects of corrupt";
public override Modifier[] TooltipModifiers => [new CorruptCardModifier(EModifierDuration.Temporary)];
}

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Data;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Pois;
namespace RobotAndDonkey.Game.Cards.Patches;
public record FlyingDisk() : PatchCard(ECard.FlyingDisk, Balancing.Instance.FlyingDiskCost, Balancing.Instance.CardPlayEnergyCost, ERarity.Uncommon)
{
protected override void CreateIntents(Cell avatarCell, Avatar avatar, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
intents.Add(new Intents.Move(avatarCell, this, avatar.Direction, true, 1));
}
public override string ToolTip => "Fly forward 1 cell, ignoring blocked areas";
}

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Data;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Pois;
namespace RobotAndDonkey.Game.Cards.Patches;
public record Interact() : PatchCard(ECard.Interact, Balancing.Instance.InteractCost, Balancing.Instance.CardPlayEnergyCost, ERarity.Common)
{
protected override void CreateIntents(Cell avatarCell, Avatar avatar, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
intents.Add(new Intents.Interact(avatarCell, this, avatar.Direction));
}
public override string ToolTip => "Interact with the forward cell";
}

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Data;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Pois;
namespace RobotAndDonkey.Game.Cards.Patches;
public record Jump() : PatchCard(ECard.Jump, Balancing.Instance.JumpCost, Balancing.Instance.CardPlayEnergyCost, ERarity.Legendary)
{
protected override void CreateIntents(Cell avatarCell, Avatar avatar, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
intents.Add(new Intents.Move(avatarCell, this, avatar.Direction, true, 2));
}
public override string ToolTip => "Move forward 2 cells, ignoring obstacles";
}

View File

@@ -0,0 +1,35 @@
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Modifiers;
using RobotAndDonkey.Game.Pois;
namespace RobotAndDonkey.Game.Cards.Patches;
public abstract record ModifyCardBase(ECard Id, int ShopCost, int PlayCost, ERarity Rarity, EModifierId Modifier) : PatchCard(Id, ShopCost, PlayCost, Rarity)
{
protected override void CreateIntents(Cell avatarCell, Avatar avatar, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
var tape = coreLoop.GetTapeCards();
var tapeIndex = tape.IndexOf(this);
if (tapeIndex < 0)
results.Add(new InvalidInstructionResult(requestId, EInvalidReason.NotFound, this, null));
else
{
var corrupt = Modifiers.Any(m => m is CorruptModifierBase { DebuffSources.Count: 0 });
for (var i = tapeIndex + 1; i < tape.Count; ++i)
{
var victim = tape[i];
if (corrupt)
intents.Add(new ImmunizeCard(this, victim, Modifier, EModifierDuration.Temporary, false));
else
intents.Add(new ModifyCard(victim, Modifier, EModifierDuration.Temporary, ECardLocation.Tape));
}
}
}
public override string ToolTip => $"All following instructions in tape become {Modifier} temporarily";
public override Modifier[] TooltipModifiers => [ModifyCard.Create(Modifier, EModifierDuration.Temporary)];
}

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Data;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Pois;
namespace RobotAndDonkey.Game.Cards.Patches;
public record Move() : PatchCard(ECard.Move, Balancing.Instance.MoveCost, Balancing.Instance.CardPlayEnergyCost, ERarity.Common)
{
protected override void CreateIntents(Cell avatarCell, Avatar avatar, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
intents.Add(new Intents.Move(avatarCell, this, avatar.Direction, false, 1));
}
public override string ToolTip => "Move one cell forward if it's free";
}

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Data;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Pois;
namespace RobotAndDonkey.Game.Cards.Patches;
public record NoOp() : PatchCard(ECard.NoOp, Balancing.Instance.InteractCost, 0, ERarity.Common)
{
protected override void CreateIntents(Cell avatarCell, Avatar avatar, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
intents.Add(new Intents.Rest(avatarCell, Balancing.Instance.CardNoOpEnergyReplenish));
}
public override string ToolTip => $"Take a break, do nothing. Restore {Balancing.Instance.CardNoOpEnergyReplenish} energy.";
}

View File

@@ -0,0 +1,5 @@
using RobotAndDonkey.Game.Data;
namespace RobotAndDonkey.Game.Cards.Patches;
public record Optimize() : ModifyCardBase(ECard.Optimize, Balancing.Instance.OptimizeCost, Balancing.Instance.CardPlayEnergyCost, ERarity.Magic, EModifierId.Optimized);

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Pois;
namespace RobotAndDonkey.Game.Cards.Patches;
public record PatchCard(ECard Id, int ShopCost, int PlayCost, ERarity Rarity) : Card(Id, ECardType.Patch, Rarity, ShopCost, PlayCost)
{
public override void CreateIntents(Cell? avatarCell, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
if (avatarCell?.Poi is not Avatar avatar)
return;
base.CreateIntents(avatarCell, coreLoop, requestId, intents, results);
CreateIntents(avatarCell, avatar, coreLoop, requestId, intents, results);
}
protected virtual void CreateIntents(Cell avatarCell, Avatar avatar, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
}
}

View File

@@ -0,0 +1,5 @@
using RobotAndDonkey.Game.Data;
namespace RobotAndDonkey.Game.Cards.Patches;
public record Persist() : ModifyCardBase(ECard.Persist, Balancing.Instance.PersistCost, Balancing.Instance.CardPlayEnergyCost, ERarity.Magic, EModifierId.Persistent);

View File

@@ -0,0 +1,5 @@
using RobotAndDonkey.Game.Data;
namespace RobotAndDonkey.Game.Cards.Patches;
public record Potentiate() : ModifyCardBase(ECard.Potentiate, Balancing.Instance.PotentiateCost, Balancing.Instance.CardPlayEnergyCost, ERarity.Magic, EModifierId.Effective);

View File

@@ -0,0 +1,18 @@
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Data;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Pois;
namespace RobotAndDonkey.Game.Cards.Patches;
public record Reason() : PatchCard(ECard.Reason, Balancing.Instance.ReasonCost, Balancing.Instance.CardPlayEnergyCost, ERarity.Rare)
{
protected override void CreateIntents(Cell avatarCell, Avatar avatar, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
intents.Add(new ModifyCurrency(new(0, 0, 0, 0, 0, HandSize: 1), true));
}
public override string ToolTip => "Adds hand size, permanently.";
}

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Data;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Pois;
namespace RobotAndDonkey.Game.Cards.Patches;
public record Remember() : PatchCard(ECard.Remember, Balancing.Instance.RememberCost, Balancing.Instance.CardPlayEnergyCost, ERarity.Rare)
{
protected override void CreateIntents(Cell avatarCell, Avatar avatar, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
intents.Add(new ModifyCurrency(new(0, 0, 0, 0, TapeLength: 1, 0), true));
}
public override string ToolTip => "Increases tape length, permanently.";
}

View File

@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Data;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Modifiers;
using RobotAndDonkey.Game.Pois;
using RobotAndDonkey.Game.Utils;
namespace RobotAndDonkey.Game.Cards.Patches;
public record Repeat() : PatchCard(ECard.Repeat, Balancing.Instance.RepeatCost, 0, ERarity.Legendary)
{
protected override void CreateIntents(Cell avatarCell, Avatar avatar, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
var tape = coreLoop.GetTapeCards();
var index = tape.IndexOf(this);
if (index < 0)
{
results.Add(new InvalidInstructionResult(requestId, EInvalidReason.NotFound, this, avatarCell));
return;
}
var targetIndex = CardExtensions.NextIndexConsideringCorruption(index, coreLoop);
if (targetIndex < 0 || targetIndex >= tape.Count)
{
results.Add(new InvalidInstructionResult(requestId, EInvalidReason.OutOfBounds, this, avatarCell));
return;
}
var targetCard = tape[targetIndex];
if (!m_RepeatedCards.Add(targetCard))
{
results.Add(new InvalidInstructionResult(requestId, EInvalidReason.AlreadyExecuted, this, avatarCell));
return;
}
targetCard.CreateIntents(avatarCell, coreLoop, requestId, intents, results);
m_RepeatedCards.Remove(targetCard);
}
public override string ToolTip => "Behaves exactly like the next instruction.";
private readonly HashSet<Card> m_RepeatedCards = [];
}

View File

@@ -0,0 +1,18 @@
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Data;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Pois;
namespace RobotAndDonkey.Game.Cards.Patches;
public record Rest() : PatchCard(ECard.Rest, Balancing.Instance.RestCost, 0, ERarity.Legendary)
{
protected override void CreateIntents(Cell avatarCell, Avatar avatar, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
intents.Add(new Intents.Rest(avatarCell, Balancing.Instance.CardRestEnergyReplenish));
}
public override string ToolTip => $"Reboot the system and restore {Balancing.Instance.CardRestEnergyReplenish} energy.";
}

View File

@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Data;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Modifiers;
using RobotAndDonkey.Game.Pois;
namespace RobotAndDonkey.Game.Cards.Patches;
public record Stabilize() : PatchCard(ECard.Stabilize, Balancing.Instance.StabilizeCost, Balancing.Instance.CardPlayEnergyCost, ERarity.Legendary)
{
protected override void CreateIntents(Cell avatarCell, Avatar avatar, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
var tape = coreLoop.GetTapeCards();
var index = tape.IndexOf(this);
if (index < 0)
{
results.Add(new InvalidInstructionResult(requestId, EInvalidReason.NotFound, this, avatarCell));
return;
}
var targetIndex = index + 1;
if (targetIndex >= tape.Count)
{
results.Add(new InvalidInstructionResult(requestId, EInvalidReason.OutOfBounds, this, avatarCell));
return;
}
intents.Add(new ImmunizeCard(this, tape[targetIndex], EModifierId._Invalid, EModifierDuration.ShortTerm));
}
public override string ToolTip => "Temporarily nullifies all modifiers of the next card.";
}

View File

@@ -0,0 +1,5 @@
using RobotAndDonkey.Game.Data;
namespace RobotAndDonkey.Game.Cards.Patches;
public record Streamline() : ModifyCardBase(ECard.Streamline, Balancing.Instance.StreamlineCost, Balancing.Instance.CardPlayEnergyCost, ERarity.Magic, EModifierId.Efficient);

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Data;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Pois;
namespace RobotAndDonkey.Game.Cards.Patches;
public record TurnLeft() : PatchCard(ECard.TurnLeft, Balancing.Instance.TurnLeftCost, Balancing.Instance.CardPlayEnergyCost, ERarity.Common)
{
protected override void CreateIntents(Cell avatarCell, Avatar avatar, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
intents.Add(new Turn(avatarCell, 1));
}
public override string ToolTip => "Change the orientation by 60 degrees counter-clockwise";
}

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using RobotAndDonkey.Game.Board;
using RobotAndDonkey.Game.Data;
using RobotAndDonkey.Game.Execution.Results;
using RobotAndDonkey.Game.GameState;
using RobotAndDonkey.Game.Intents;
using RobotAndDonkey.Game.Pois;
namespace RobotAndDonkey.Game.Cards.Patches;
public record TurnRight() : PatchCard(ECard.TurnRight, Balancing.Instance.TurnRightCost, Balancing.Instance.CardPlayEnergyCost, ERarity.Common)
{
protected override void CreateIntents(Cell avatarCell, Avatar avatar, CoreLoop coreLoop, Guid requestId, List<Intent> intents, List<Result> results)
{
intents.Add(new Turn(avatarCell, -1));
}
public override string ToolTip => "Change the orientation by 60 degrees clockwise";
}