Restore Cyrillic comments corrupted by PowerShell re-encoding

Two files were rewritten with Get-Content/Set-Content and lost their UTF-8 encoding. Restored the clean versions and re-applied the changes with an encoding-safe editor.
This commit is contained in:
MpakobecEx 2026-10-21 13:39:44 +05:00
parent ff7774b236
commit 1965816808
2 changed files with 55 additions and 48 deletions

View File

@ -1,8 +1,8 @@
using Vanguard.Rules.Cards; using Vanguard.Rules.Cards;
namespace Vanguard.Rules.Engine.Abilities; namespace Vanguard.Rules.Engine.Abilities;
/// <summary>Скрипты карт первого сета, подключённые Рє РґРІРёР¶РєСѓ.</summary> /// <summary>Скрипты карт первого сета, подключённые к движку.</summary>
public static class CardScripts public static class CardScripts
{ {
public static IReadOnlyDictionary<string, CardScript> Default { get; } = public static IReadOnlyDictionary<string, CardScript> Default { get; } =
@ -25,7 +25,7 @@ public static class CardScripts
} }
/// <summary> /// <summary>
/// Knight of Rose, Morgana: РїСЂРё атаке РјРѕР¶РЅРѕ сбросить карту РёР· СЂСѓРєРё Рё получить +4000 РґРѕ конца С…РѕРґР°. /// Knight of Rose, Morgana: при атаке можно сбросить карту из руки и получить +4000 до конца хода.
/// </summary> /// </summary>
public sealed class MorganaScript : CardScript public sealed class MorganaScript : CardScript
{ {
@ -42,21 +42,26 @@ public sealed class MorganaScript : CardScript
CanPay = ctx => ctx.State.Players[ctx.Owner].Hand.Count > 0, CanPay = ctx => ctx.State.Players[ctx.Owner].Hand.Count > 0,
Resolve = ctx => ctx.Engine.AskHandCardChoice( Resolve = ctx => ctx.Engine.AskHandCardChoice(
ctx.Owner, ctx.Owner,
"Сбросьте карту РёР· СЂСѓРєРё", "Сбросьте карту из руки",
null, null,
card => card =>
{ {
var p = ctx.State.Players[ctx.Owner]; var p = ctx.State.Players[ctx.Owner];
p.Hand.Remove(card); p.Hand.Remove(card);
p.Drop.Add(card); p.Drop.Add(card);
ctx.Engine.AddPower(ctx.Source, 4000, ctx.Source, "morgana", ModifierDuration.UntilEndOfTurn); ctx.Engine.AddPower(
ctx.Source,
4000,
ctx.Source,
"morgana",
ModifierDuration.UntilEndOfTurn);
}), }),
}; };
} }
} }
} }
/// <summary>Tyrant, Deathrex: РєРѕРіРґР° эта карта атакует, получает +5000 РґРѕ конца Р±РѕСЏ.</summary> /// <summary>Tyrant, Deathrex: когда эта карта атакует, получает +5000 до конца боя.</summary>
public sealed class DeathrexScript : CardScript public sealed class DeathrexScript : CardScript
{ {
public override string NameId => "tyrant-deathrex"; public override string NameId => "tyrant-deathrex";
@ -74,7 +79,7 @@ public sealed class DeathrexScript : CardScript
} }
} }
/// <summary>Demon Eater: РІ начале РћСЃРЅРѕРІРЅРѕР№ фазы Soul Charge 1 Рё +2000 РґРѕ конца С…РѕРґР°.</summary> /// <summary>Demon Eater: в начале Основной фазы Soul Charge 1 и +2000 до конца хода.</summary>
public sealed class DemonEaterScript : CardScript public sealed class DemonEaterScript : CardScript
{ {
public override string NameId => "demon-eater"; public override string NameId => "demon-eater";
@ -89,14 +94,19 @@ public sealed class DemonEaterScript : CardScript
Resolve = ctx => Resolve = ctx =>
{ {
ctx.Engine.SoulCharge(ctx.Owner, 1); ctx.Engine.SoulCharge(ctx.Owner, 1);
ctx.Engine.AddPower(ctx.Source, 2000, ctx.Source, "demon-eater", ModifierDuration.UntilEndOfTurn); ctx.Engine.AddPower(
ctx.Source,
2000,
ctx.Source,
"demon-eater",
ModifierDuration.UntilEndOfTurn);
}, },
}; };
} }
} }
} }
/// <summary>Maiden of Libra: РєРѕРіРґР° атака попадает, Counter Blast 2 Рё взять карту.</summary> /// <summary>Maiden of Libra: когда атака попадает, Counter Blast 2 и взять карту.</summary>
public sealed class MaidenOfLibraScript : CardScript public sealed class MaidenOfLibraScript : CardScript
{ {
public override string NameId => "maiden-of-libra"; public override string NameId => "maiden-of-libra";
@ -118,8 +128,8 @@ public sealed class MaidenOfLibraScript : CardScript
} }
/// <summary> /// <summary>
/// Battle Sister, Cocoa: РїСЂРё размещении РЅР° VC/RC, если Авангард Oracle Think Tank, /// Battle Sister, Cocoa: при размещении на VC/RC, если Авангард Oracle Think Tank,
/// посмотреть верхнюю карту Рё оставить её РЅР° верху или отправить РІ РЅРёР·. /// посмотреть верхнюю карту и оставить её на верху или отправить в низ.
/// </summary> /// </summary>
public sealed class CocoaScript : CardScript public sealed class CocoaScript : CardScript
{ {
@ -133,15 +143,15 @@ public sealed class CocoaScript : CardScript
{ {
Trigger = AbilityTrigger.OnPlace, Trigger = AbilityTrigger.OnPlace,
Condition = ctx => ctx.Engine.VanguardClan(ctx.Owner) == Clan.OracleThinkTank, Condition = ctx => ctx.Engine.VanguardClan(ctx.Owner) == Clan.OracleThinkTank,
Resolve = ctx => ctx.Engine.LookTopAndReorder(ctx.Owner, "Верхняя карта колоды"), Resolve = ctx => ctx.Engine.LookTopAndReorder(ctx.Owner, "Верхняя карта колоды"),
}; };
} }
} }
} }
/// <summary> /// <summary>
/// Lizard Soldier, Conroe: [ACT](RC): Counter Blast 1 Рё уничтожить эту карту в†’ /// Lizard Soldier, Conroe: [ACT](RC): Counter Blast 1 и уничтожить эту карту →
/// найти РІ колоде Kagero 1 ранга или РЅРёР¶Рµ Рё добавить РІ СЂСѓРєСѓ. /// найти в колоде Kagero 1 ранга или ниже и добавить в руку.
/// </summary> /// </summary>
public sealed class ConroeScript : CardScript public sealed class ConroeScript : CardScript
{ {
@ -160,7 +170,7 @@ public sealed class ConroeScript : CardScript
ctx.Engine.CounterBlast(ctx.Owner, 1); ctx.Engine.CounterBlast(ctx.Owner, 1);
ctx.Engine.SearchDeckToHand( ctx.Engine.SearchDeckToHand(
ctx.Owner, ctx.Owner,
"Найдите Kagero 1 ранга или РЅРёР¶Рµ", "Найдите Kagero 1 ранга или ниже",
d => d.Clan == Clan.Kagero && d.Grade <= 1); d => d.Clan == Clan.Kagero && d.Grade <= 1);
}, },
}; };
@ -169,8 +179,8 @@ public sealed class ConroeScript : CardScript
} }
/// <summary> /// <summary>
/// В«[ACT]: повернуть эту карту Рё сбросить карту РёР· СЂСѓРєРё в†’ взять карту». /// «[ACT]: повернуть эту карту и сбросить карту из руки → взять карту».
/// Общий СЃРєСЂРёРїС‚ для Lake Maiden, Lien, Dragon Monk, Gojo Рё Shout. /// Общий скрипт для Lake Maiden, Lien, Dragon Monk, Gojo и Shout.
/// </summary> /// </summary>
public sealed class DrawOneScript : CardScript public sealed class DrawOneScript : CardScript
{ {
@ -194,8 +204,8 @@ public sealed class DrawOneScript : CardScript
} }
/// <summary> /// <summary>
/// Blaster Blade: РїСЂРё размещении оплатить Counter Blast 2 Рё уничтожить Арьергард противника. /// Blaster Blade: при размещении оплатить Counter Blast 2 и уничтожить Арьергард противника.
/// РќР° Авангарде — любой, РЅР° Арьергарде — только 2 ранга или выше Рё РїСЂРё Авангарде Royal Paladin. /// На Авангарде — любой, на Арьергарде — только 2 ранга или выше и при Авангарде Royal Paladin.
/// </summary> /// </summary>
public sealed class BlasterBladeScript : CardScript public sealed class BlasterBladeScript : CardScript
{ {
@ -222,7 +232,7 @@ public sealed class BlasterBladeScript : CardScript
ctx.Engine.AskUnitChoice( ctx.Engine.AskUnitChoice(
ctx.Owner, ctx.Owner,
opponent, opponent,
"Выберите Арьергард противника", "Выберите Арьергард противника",
slots, slots,
slot => ctx.Engine.RetireRearGuard(opponent, slot)); slot => ctx.Engine.RetireRearGuard(opponent, slot));
}, },
@ -247,7 +257,7 @@ public sealed class BlasterBladeScript : CardScript
ctx.Engine.AskUnitChoice( ctx.Engine.AskUnitChoice(
ctx.Owner, ctx.Owner,
opponent, opponent,
"Выберите Арьергард противника 2 ранга или выше", "Выберите Арьергард противника 2 ранга или выше",
slots, slots,
slot => ctx.Engine.RetireRearGuard(opponent, slot)); slot => ctx.Engine.RetireRearGuard(opponent, slot));
}, },
@ -257,7 +267,7 @@ public sealed class BlasterBladeScript : CardScript
} }
/// <summary> /// <summary>
/// Barcgal: РєРѕРіРґР° РґСЂСѓРіРѕР№ Royal Paladin сменяет эту карту, РІС‹ можете призвать её РІ РєСЂСѓРі Арьергарда. /// Barcgal: когда другой Royal Paladin сменяет эту карту, вы можете призвать её в круг Арьергарда.
/// </summary> /// </summary>
public sealed class BarcgalScript : CardScript public sealed class BarcgalScript : CardScript
{ {
@ -281,7 +291,7 @@ public sealed class BarcgalScript : CardScript
} }
/// <summary> /// <summary>
/// Wingal: РєРѕРіРґР° эта карта поддерживает Blaster Blade, усиленная карта получает +4000 РґРѕ конца Р±РѕСЏ. /// Wingal: когда эта карта поддерживает Blaster Blade, усиленная карта получает +4000 до конца боя.
/// </summary> /// </summary>
public sealed class WingalScript : CardScript public sealed class WingalScript : CardScript
{ {
@ -306,8 +316,8 @@ public sealed class WingalScript : CardScript
} }
/// <summary> /// <summary>
/// King of Knights, Alfred: РІ СЃРІРѕР№ С…РѕРґ РЅР° РєСЂСѓРіРµ Авангарда получает +2000 /// King of Knights, Alfred: в свой ход на круге Авангарда получает +2000
/// Р·Р° каждый СЃРІРѕР№ Арьергард Royal Paladin. /// за каждый свой Арьергард Royal Paladin.
/// </summary> /// </summary>
public sealed class AlfredScript : CardScript public sealed class AlfredScript : CardScript
{ {
@ -341,11 +351,10 @@ public sealed class AlfredScript : CardScript
ctx.Engine.CounterBlast(ctx.Owner, 3); ctx.Engine.CounterBlast(ctx.Owner, 3);
ctx.Engine.SearchDeckToCall( ctx.Engine.SearchDeckToCall(
ctx.Owner, ctx.Owner,
"Найдите Royal Paladin 2 ранга или РЅРёР¶Рµ", "Найдите Royal Paladin 2 ранга или ниже",
d => d.Clan == Clan.RoyalPaladin && d.Grade <= 2); d => d.Clan == Clan.RoyalPaladin && d.Grade <= 2);
}, },
}; };
} }
} }
} }

View File

@ -1,4 +1,4 @@
using Vanguard.Rules.Cards; using Vanguard.Rules.Cards;
using Vanguard.Rules.Engine; using Vanguard.Rules.Engine;
using Vanguard.Rules.Engine.Abilities; using Vanguard.Rules.Engine.Abilities;
using Xunit; using Xunit;
@ -9,7 +9,7 @@ public class GameEngineTests
{ {
private readonly CardCatalog _catalog = TestCatalog.Instance; private readonly CardCatalog _catalog = TestCatalog.Instance;
private const string Barcgal = "BT01/003EN"; // grade 0, без триггера — стартовый Авангард private const string Barcgal = "BT01/003EN"; // grade 0, без триггера — стартовый Авангард
private const string Marron = "BT01/042EN"; // grade 1, 8000 private const string Marron = "BT01/042EN"; // grade 1, 8000
private const string Gallatin = "BT01/021EN"; // grade 2, 10000 private const string Gallatin = "BT01/021EN"; // grade 2, 10000
private const string Alfred = "BT01/001EN"; // grade 3 private const string Alfred = "BT01/001EN"; // grade 3
@ -19,11 +19,11 @@ public class GameEngineTests
private const string Iseult = "BT01/011EN"; // Sentinel, Royal Paladin private const string Iseult = "BT01/011EN"; // Sentinel, Royal Paladin
private const string Nehalem = "BT01/022EN"; // Kagero private const string Nehalem = "BT01/022EN"; // Kagero
private const string Overlord = "BT01/004EN"; // Kagero, 11000 private const string Overlord = "BT01/004EN"; // Kagero, 11000
private const string Conroe = "BT01/016EN"; // Kagero, grade 0 без триггера private const string Conroe = "BT01/016EN"; // Kagero, grade 0 без триггера
private const string BlasterBlade = "BT01/002EN"; private const string BlasterBlade = "BT01/002EN";
private const string Wingal = "BT01/044EN"; private const string Wingal = "BT01/044EN";
private const string Lien = "BT01/043EN"; // activated: rest + discard в†’ draw private const string Lien = "BT01/043EN"; // activated: rest + discard → draw
private const string Cocoa = "BT01/007EN"; // OTT, смотрит верхнюю карту private const string Cocoa = "BT01/007EN"; // OTT, смотрит верхнюю карту
private const string Libra = "BT01/017EN"; // OTT, grade 2 private const string Libra = "BT01/017EN"; // OTT, grade 2
private const string Deathrex = "BT01/033EN"; // Tachikaze, 10000 private const string Deathrex = "BT01/033EN"; // Tachikaze, 10000
private const string DemonEater = "BT01/036EN"; // Dark Irregulars, 10000 private const string DemonEater = "BT01/036EN"; // Dark Irregulars, 10000
@ -180,7 +180,7 @@ public class GameEngineTests
Assert.NotNull(pending); Assert.NotNull(pending);
Assert.Equal(TriggerContext.DamageCheck, pending!.Context); Assert.Equal(TriggerContext.DamageCheck, pending!.Context);
// РґРѕ разрешения карта лежит РІ Р·РѕРЅРµ триггера, Р° РЅРµ РІ СѓСЂРѕРЅРµ // до разрешения карта лежит в зоне триггера, а не в уроне
Assert.Empty(engine.State.Players[1].Damage); Assert.Empty(engine.State.Players[1].Damage);
Assert.Contains(engine.State.Players[1].Trigger, c => c.PrintingId == Nike); Assert.Contains(engine.State.Players[1].Trigger, c => c.PrintingId == Nike);
@ -336,8 +336,8 @@ public class GameEngineTests
Assert.True(engine.Execute(new PassGuardCommand()).Accepted); Assert.True(engine.Execute(new PassGuardCommand()).Accepted);
var defender = engine.State.Players[1]; var defender = engine.State.Players[1];
Assert.NotNull(defender.RearGuards[0]); // цель выжила Assert.NotNull(defender.RearGuards[0]); // цель выжила
Assert.Null(defender.RearGuards[3]); // перехватчик РїРѕРєРёРЅСѓР» РєСЂСѓРі Assert.Null(defender.RearGuards[3]); // перехватчик покинул круг
Assert.Contains(defender.Drop, c => c.PrintingId == Gallatin); Assert.Contains(defender.Drop, c => c.PrintingId == Gallatin);
Assert.Contains(engine.Events, e => e is InterceptedEvent); Assert.Contains(engine.Events, e => e is InterceptedEvent);
Assert.Contains(engine.Events, e => e is BattleResolvedEvent { Hit: false }); Assert.Contains(engine.Events, e => e is BattleResolvedEvent { Hit: false });
@ -477,7 +477,7 @@ public class GameEngineTests
[Fact] [Fact]
public void Move_Is_Available_Only_In_Main_Phase() public void Move_Is_Available_Only_In_Main_Phase()
{ {
var engine = StartedEngine(); // фаза Смены var engine = StartedEngine(); // фаза Смены
Assert.False(engine.Execute(new MoveCommand(0, 3)).Accepted); Assert.False(engine.Execute(new MoveCommand(0, 3)).Accepted);
} }
@ -705,7 +705,7 @@ public class GameEngineTests
Assert.True(lien.Rested); Assert.True(lien.Rested);
Assert.Contains(engine.State.Players[0].Drop, c => c.PrintingId == Marron); Assert.Contains(engine.State.Players[0].Drop, c => c.PrintingId == Marron);
Assert.Equal(handBefore, engine.State.Players[0].Hand.Count); // -1 СЃР±СЂРѕСЃ, +1 РґРѕР±РѕСЂ Assert.Equal(handBefore, engine.State.Players[0].Hand.Count); // -1 сброс, +1 добор
} }
[Fact] [Fact]
@ -738,7 +738,7 @@ public class GameEngineTests
var engine = StartedEngine(); var engine = StartedEngine();
var handBefore = engine.State.Players[0].Hand.Count; var handBefore = engine.State.Players[0].Hand.Count;
engine.SearchDeckToHand(0, "Карта X", d => d.NameId == "no-such-card"); engine.SearchDeckToHand(0, "Карта X", d => d.NameId == "no-such-card");
Assert.Contains(engine.Events, e => e is SearchFailedEvent); Assert.Contains(engine.Events, e => e is SearchFailedEvent);
Assert.Null(engine.State.PendingChoice); Assert.Null(engine.State.PendingChoice);
@ -937,7 +937,7 @@ public class GameEngineTests
Assert.True(engine.Execute(new AttackCommand(-1, -1)).Accepted); Assert.True(engine.Execute(new AttackCommand(-1, -1)).Accepted);
Assert.True(engine.Execute(new PassGuardCommand()).Accepted); Assert.True(engine.Execute(new PassGuardCommand()).Accepted);
// СѓСЂРѕРЅ СѓР¶Рµ нанесён, Рё только теперь спрашивают РїСЂРѕ эффект попадания // урон уже нанесён, и только теперь спрашивают про эффект попадания
Assert.Single(engine.State.Players[1].Damage); Assert.Single(engine.State.Players[1].Damage);
Assert.NotNull(engine.State.PendingAbility); Assert.NotNull(engine.State.PendingAbility);
} }
@ -1205,7 +1205,7 @@ public class GameEngineTests
engine.Start(); engine.Start();
engine.Execute(new FinishMulliganCommand()); engine.Execute(new FinishMulliganCommand());
// фиксируем стартовый Авангард, чтобы Barcgal РЅРµ срабатывал РІ обычных тестах // фиксируем стартовый Авангард, чтобы Barcgal не срабатывал в обычных тестах
SetVanguard(engine, 0, Conroe); SetVanguard(engine, 0, Conroe);
return engine; return engine;
} }
@ -1261,14 +1261,14 @@ public class GameEngineTests
Give(engine, 0, Marron); Give(engine, 0, Marron);
engine.Execute(new RideCommand(Marron)); engine.Execute(new RideCommand(Marron));
// сзади слева — поддержка (1 ранг), впереди слева — атакующий (2 ранг) // сзади слева — поддержка (1 ранг), впереди слева — атакующий (2 ранг)
Give(engine, 0, Marron); Give(engine, 0, Marron);
engine.Execute(new CallCommand(Marron, 0)); engine.Execute(new CallCommand(Marron, 0));
Give(engine, 0, Gallatin); Give(engine, 0, Gallatin);
engine.Execute(new CallCommand(Gallatin, 3)); engine.Execute(new CallCommand(Gallatin, 3));
// призванные карты РІС…РѕРґСЏС‚ повёрнутыми — для теста поддержки поднимаем РѕР±Рµ // призванные карты входят повёрнутыми — для теста поддержки поднимаем обе
engine.State.Players[0].RearGuards[0]!.Rested = false; engine.State.Players[0].RearGuards[0]!.Rested = false;
engine.State.Players[0].RearGuards[3]!.Rested = false; engine.State.Players[0].RearGuards[3]!.Rested = false;
@ -1344,7 +1344,7 @@ public class GameEngineTests
{ {
var p = engine.State.Players[player]; var p = engine.State.Players[player];
var index = p.Deck.FindIndex(c => c.PrintingId == printingId); var index = p.Deck.FindIndex(c => c.PrintingId == printingId);
Assert.True(index >= 0, $"Р’ колоде нет {printingId}"); Assert.True(index >= 0, $"В колоде нет {printingId}");
var card = p.Deck[index]; var card = p.Deck[index];
p.Deck.RemoveAt(index); p.Deck.RemoveAt(index);
@ -1357,7 +1357,7 @@ public class GameEngineTests
foreach (var printingId in printingIds) foreach (var printingId in printingIds)
{ {
var index = player.Deck.FindIndex(c => c.PrintingId == printingId); var index = player.Deck.FindIndex(c => c.PrintingId == printingId);
Assert.True(index >= 0, $"Р’ колоде нет {printingId}"); Assert.True(index >= 0, $"В колоде нет {printingId}");
cards.Add(player.Deck[index]); cards.Add(player.Deck[index]);
player.Deck.RemoveAt(index); player.Deck.RemoveAt(index);
@ -1395,7 +1395,7 @@ public class GameEngineTests
{ {
var p = engine.State.Players[player]; var p = engine.State.Players[player];
var index = p.Deck.FindIndex(c => c.PrintingId == printingId); var index = p.Deck.FindIndex(c => c.PrintingId == printingId);
Assert.True(index >= 0, $"Р’ колоде нет {printingId}"); Assert.True(index >= 0, $"В колоде нет {printingId}");
var card = p.Deck[index]; var card = p.Deck[index];
p.Deck.RemoveAt(index); p.Deck.RemoveAt(index);
@ -1405,7 +1405,7 @@ public class GameEngineTests
private static CardInstance TakeFromDeck(PlayerState player, string printingId) private static CardInstance TakeFromDeck(PlayerState player, string printingId)
{ {
var index = player.Deck.FindIndex(c => c.PrintingId == printingId); var index = player.Deck.FindIndex(c => c.PrintingId == printingId);
Assert.True(index >= 0, $"Р’ колоде нет {printingId}"); Assert.True(index >= 0, $"В колоде нет {printingId}");
var card = player.Deck[index]; var card = player.Deck[index];
player.Deck.RemoveAt(index); player.Deck.RemoveAt(index);
@ -1420,5 +1420,3 @@ public class GameEngineTests
return card; return card;
} }
} }