Skip to content

Commit 907867f

Browse files
committed
WIP redo timings without singletons
#2035 (comment)
1 parent 1f8a4f0 commit 907867f

24 files changed

+421
-316
lines changed

Assets/Scripts/AsyncAction.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System.Threading.Tasks;
22

3+
public delegate Task AsyncAction();
34
public delegate Task AsyncAction<in T1>(T1 arg1);
45
public delegate Task AsyncAction<in T1, in T2>(T1 arg1, T2 arg2);
5-
6-

Assets/Scripts/Model/Cards/Corp/AdvancedAssemblyLines.cs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using model.choices.trash;
77
using model.costs;
88
using model.play;
9+
using model.timing;
910
using model.zones;
1011

1112
namespace model.cards.corp
@@ -18,7 +19,7 @@ public AdvancedAssemblyLines(Game game) : base(game) { }
1819
override public Faction Faction => Factions.HAAS_BIOROID;
1920
override public int InfluenceCost => 2;
2021
override public ICost PlayCost => game.corp.credits.PayingForPlaying(this, 1);
21-
override public IEffect Activation => new AdvancedAssemblyLinesActivation(this, game.corp);
22+
override public IEffect Activation => new AdvancedAssemblyLinesActivation(this, game);
2223
override public IType Type => new Asset(game);
2324
override public IList<ITrashOption> TrashOptions() => new List<ITrashOption> {
2425
new Leave(),
@@ -30,21 +31,25 @@ private class AdvancedAssemblyLinesActivation : IEffect
3031
public bool Impactful => true;
3132
public event Action<IEffect, bool> ChangedImpact = delegate { };
3233
private readonly Card aal;
33-
private readonly Corp corp;
34+
private readonly Game game;
3435
IEnumerable<string> IEffect.Graphics => new string[] { };
3536

36-
public AdvancedAssemblyLinesActivation(Card aal, Corp corp)
37+
public AdvancedAssemblyLinesActivation(Card aal, Game game)
3738
{
3839
this.aal = aal;
39-
this.corp = corp;
40+
this.game = game;
4041
}
4142

4243
async Task IEffect.Resolve()
4344
{
44-
await corp.credits.Gaining(3).Resolve();
45-
var paidWindow = corp.paidWindow;
46-
var archives = corp.zones.archives.Zone;
47-
var aalInstall = new AdvancedAssemblyLinesInstall(corp);
45+
await game.corp.credits.Gaining(3).Resolve();
46+
game.Timing.PaidWindowDefined += DefineTrashAbility;
47+
}
48+
49+
private void DefineTrashAbility(PaidWindow paidWindow)
50+
{
51+
var archives = game.corp.zones.archives.Zone;
52+
var aalInstall = new AdvancedAssemblyLinesInstall(game.corp);
4853
var pop = new Ability(
4954
cost: new Conjunction(paidWindow.Permission(), new Trash(aal, archives), new Active(aal)),
5055
effect: aalInstall
@@ -58,7 +63,7 @@ async Task IEffect.Resolve()
5863
}
5964
}
6065

61-
private class AdvancedAssemblyLinesInstall : IEffect
66+
private class AdvancedAssemblyLinesInstall : IEffect, IDisposable
6267
{
6368
public bool Impactful => Installables().Count > 0;
6469
public event Action<IEffect, bool> ChangedImpact = delegate { };
@@ -84,7 +89,7 @@ private void UpdateInstallables(Zone hqZone)
8489
ChangedImpact(this, Impactful);
8590
}
8691

87-
internal void Dispose()
92+
public void Dispose()
8893
{
8994
corp.zones.hq.Zone.Changed -= UpdateInstallables;
9095
}

Assets/Scripts/Model/Cards/Corp/HaarpsichordStudios.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ private class HaarpsichordEffect : IEffect
3131
async Task IEffect.Resolve()
3232
{
3333
var memory = new HaarpsichordMemory();
34-
game.corp.turn.Started += memory.Reset;
35-
game.runner.turn.Started += memory.Reset;
34+
game.corp.turn.Opened += memory.Reset;
35+
game.runner.turn.Opened += memory.Reset;
3636
var mod = new HaarpsichordModifier(memory);
3737
game.runner.Stealing.ModifyStealing(mod);
3838
await Task.CompletedTask;

Assets/Scripts/Model/Cards/Corp/PadCampaign.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
using System.Threading.Tasks;
44
using model.cards.types;
55
using model.choices.trash;
6+
using model.timing;
7+
using model.timing.corp;
68

79
namespace model.cards.corp
810
{
@@ -14,7 +16,7 @@ public PadCampaign(Game game) : base(game) { }
1416
override public Faction Faction => Factions.SHADOW;
1517
override public int InfluenceCost => 0;
1618
override public ICost PlayCost => game.corp.credits.PayingForPlaying(this, 2);
17-
override public IEffect Activation => new PadCampaignActivation(game.corp);
19+
override public IEffect Activation => new PadCampaignActivation(game);
1820
override public IType Type => new Asset(game);
1921
override public IList<ITrashOption> TrashOptions() => new List<ITrashOption> {
2022
new Leave(),
@@ -26,15 +28,20 @@ private class PadCampaignActivation : IEffect
2628
public bool Impactful => true;
2729
public event Action<IEffect, bool> ChangedImpact = delegate { };
2830
IEnumerable<string> IEffect.Graphics => new string[] { };
29-
private Corp corp;
31+
private Game game;
3032

31-
public PadCampaignActivation(Corp corp) => this.corp = corp;
33+
public PadCampaignActivation(Game game) => this.game = game;
3234

3335
async Task IEffect.Resolve()
3436
{
35-
corp.turn.WhenBegins(corp.credits.Gaining(1));
37+
game.Timing.CorpTurnDefined += RegisterDrip;
3638
await Task.CompletedTask;
3739
}
40+
41+
private void RegisterDrip(CorpTurn turn)
42+
{
43+
turn.WhenBegins(game.corp.credits.Gaining(1));
44+
}
3845
}
3946
}
4047
}

Assets/Scripts/Model/Corp.cs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using model.player;
66
using model.rez;
77
using model.timing;
8-
using model.timing.corp;
98
using model.zones;
109
using model.zones.corp;
1110

@@ -14,8 +13,6 @@ namespace model
1413
public class Corp
1514
{
1615
public readonly IPilot pilot;
17-
public readonly CorpTurn turn;
18-
public readonly PaidWindow paidWindow;
1916
public readonly zones.corp.Zones zones;
2017
public readonly ClickPool clicks;
2118
public readonly CreditPool credits;
@@ -25,16 +22,12 @@ public class Corp
2522

2623
public Corp(
2724
IPilot pilot,
28-
CorpTurn turn,
29-
PaidWindow paidWindow,
3025
Zone playArea,
3126
Shuffling shuffling,
3227
Random random
3328
)
3429
{
3530
this.pilot = pilot;
36-
this.turn = turn;
37-
this.paidWindow = paidWindow;
3831
clicks = new ClickPool(3);
3932
credits = new CreditPool();
4033
zones = new Zones(this, playArea, shuffling);

Assets/Scripts/Model/Game.cs

Lines changed: 5 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.Threading.Tasks;
42
using model.player;
53
using model.timing;
64
using model.zones;
@@ -11,143 +9,24 @@ public class Game
119
{
1210
public readonly Corp corp;
1311
public readonly Runner runner;
12+
public readonly Timing Timing;
1413
private readonly Zone playArea;
15-
public readonly Checkpoint checkpoint;
16-
public event Action<ITurn> CurrentTurn = delegate { };
17-
public event Action<ITurn> NextTurn = delegate { };
18-
public event Action<GameFinish> Finished = delegate { };
19-
private bool ended = false;
20-
private Queue<ITurn> turns = new Queue<ITurn>();
2114
private Shuffling shuffling;
2215

2316
public Game(IPilot corpPilot, IPilot runnerPilot, Shuffling shuffling)
2417
{
2518
this.shuffling = shuffling;
2619
playArea = new Zone("Play area", true);
27-
corp = CreateCorp(corpPilot);
28-
runner = CreateRunner(runnerPilot);
29-
this.checkpoint = new Checkpoint(this);
30-
corp.zones.rd.Decked += DeckCorp;
31-
runner.zones.score.StolenEnough += StealEnough;
32-
}
33-
34-
private Corp CreateCorp(IPilot pilot)
35-
{
36-
var turn = new timing.corp.CorpTurn(this);
37-
var paidWindow = new PaidWindow("corp");
38-
return new Corp(pilot, turn, paidWindow, playArea, shuffling, new Random());
39-
}
40-
41-
private Runner CreateRunner(IPilot pilot)
42-
{
43-
var turn = new timing.runner.RunnerTurn(this);
44-
var paidWindow = new PaidWindow("runner");
45-
return new Runner(pilot, turn, paidWindow, playArea, shuffling, this);
20+
corp = new Corp(corpPilot, playArea, shuffling, new Random());
21+
runner = new Runner(runnerPilot, playArea, shuffling, this);
22+
this.Timing = new Timing(this);
4623
}
4724

4825
async public void Start(Deck corpDeck, Deck runnerDeck)
4926
{
5027
await corp.Start(this, corpDeck);
5128
await runner.Start(this, runnerDeck);
52-
await StartTurns();
53-
}
54-
55-
async private Task StartTurns()
56-
{
57-
turns.Enqueue(corp.turn);
58-
turns.Enqueue(runner.turn);
59-
try
60-
{
61-
while (!ended)
62-
{
63-
turns.Enqueue(corp.turn);
64-
turns.Enqueue(runner.turn);
65-
await StartNextTurn();
66-
await StartNextTurn();
67-
}
68-
}
69-
catch (Exception e)
70-
{
71-
if (ended)
72-
{
73-
UnityEngine.Debug.Log("The game is over! " + e.Message);
74-
}
75-
else
76-
{
77-
throw new Exception("Failed a turn", e);
78-
}
79-
}
80-
}
81-
82-
private async Task StartNextTurn()
83-
{
84-
var currentTurn = turns.Dequeue();
85-
CurrentTurn(currentTurn);
86-
NextTurn(turns.Peek());
87-
await currentTurn.Start();
88-
}
89-
90-
async public Task OpenPaidWindow(PaidWindow acting, PaidWindow reacting)
91-
{
92-
var bothPlayersCouldAct = false;
93-
while (true)
94-
{
95-
var actingDeclined = await acting.AwaitPass();
96-
if (actingDeclined && bothPlayersCouldAct)
97-
{
98-
break;
99-
}
100-
var reactingDeclined = await reacting.AwaitPass();
101-
bothPlayersCouldAct = true;
102-
if (reactingDeclined && bothPlayersCouldAct)
103-
{
104-
break;
105-
}
106-
}
107-
}
108-
109-
private void DeckCorp(Corp corp)
110-
{
111-
Finish(new GameFinish(
112-
winner: "The Runner",
113-
loser: "The Corp",
114-
reason: "Corp R&D is empty"
115-
));
116-
}
117-
118-
private void StealEnough()
119-
{
120-
Finish(new GameFinish(
121-
winner: "The Runner",
122-
loser: "The Corp",
123-
reason: "Runner has stolen enough"
124-
));
125-
}
126-
127-
private void Finish(GameFinish finish)
128-
{
129-
ended = true;
130-
Finished(finish);
131-
throw new Exception("Game over, " + finish.reason);
132-
}
133-
134-
async public Task Checkpoint()
135-
{
136-
await checkpoint.Check();
137-
}
138-
}
139-
140-
public class GameFinish
141-
{
142-
public string winner;
143-
public string loser;
144-
public string reason;
145-
146-
public GameFinish(string winner, string loser, string reason)
147-
{
148-
this.winner = winner;
149-
this.loser = loser;
150-
this.reason = reason;
29+
await Timing.StartTurns();
15130
}
15231
}
15332
}

Assets/Scripts/Model/Runner.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ namespace model
1414
public class Runner
1515
{
1616
public readonly IPilot pilot;
17-
public readonly RunnerTurn turn;
18-
public readonly PaidWindow paidWindow;
1917
public int tags = 0;
2018
public readonly Zones zones;
2119
public readonly ClickPool clicks;
@@ -27,16 +25,12 @@ public class Runner
2725

2826
public Runner(
2927
IPilot pilot,
30-
RunnerTurn turn,
31-
PaidWindow paidWindow,
3228
Zone playArea,
3329
Shuffling shuffling,
3430
Game game
3531
)
3632
{
3733
this.pilot = pilot;
38-
this.turn = turn;
39-
this.paidWindow = paidWindow;
4034
zones = new Zones(
4135
new Grip(),
4236
new Stack(shuffling),
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System.Threading.Tasks;
2+
using model.play;
3+
4+
namespace model.timing.corp
5+
{
6+
public class CorpActionPhase : ITimingStructure<CorpActionPhase>
7+
{
8+
private Corp corp;
9+
private Timing timing;
10+
public string Name => "Corp action phase";
11+
public event AsyncAction<CorpActionPhase> Opened;
12+
public event AsyncAction<CorpActionPhase> Closed;
13+
public event AsyncAction TakingAction;
14+
public event AsyncAction<Ability> ActionTaken;
15+
16+
public CorpActionPhase(Corp corp, Timing timing)
17+
{
18+
this.corp = corp;
19+
this.timing = timing;
20+
}
21+
22+
public async Task Open()
23+
{
24+
Opened?.Invoke(this);
25+
var paidWindow = timing.DefinePaidWindow(rezzing: true, scoring: true)
26+
await paidWindow.Open(); // CR: 5.6.2.a
27+
while (corp.clicks.Remaining > 0) // CR: 5.6.2.c
28+
{
29+
await TakeAction(); // CR: 5.6.2.b
30+
}
31+
await timing.Checkpoint(); // CR: 5.6.2.d
32+
}
33+
34+
async private Task TakeAction()
35+
{
36+
var actionTaking = corp.Acting.TakeAction();
37+
TakingAction?.Invoke();
38+
var action = await actionTaking;
39+
ActionTaken?.Invoke(action);
40+
await timing.OpenPaidWindow(rezzing: true, scoring: true);
41+
}
42+
}
43+
}

0 commit comments

Comments
 (0)