Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve a clock command #460

Merged
merged 2 commits into from
Aug 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/Commands/Advance a clock.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Advances a [[Clocks|Clock]], modifying its frontmatter, and inserts a [[Mechanics Blocks#`clock`|`clock` mechanics node]] into your active journal. Clocks which are already filled, or which are completed, cannot be advanced (and will not show up at all in the picker for the command).

Advancing a Clock to completion will not automatically be marked as closed. In keeping with the spirit of Iron Vault letting the player take care of actual mechanics instead of playing the game for them, this is left up to you to manage as you see fit.
Advancing a Clock to completion will not automatically be marked as resolved. You will be asked if you wish to mark the clock as resolved. If you choose not to resolve it now, you can always resolve it as needed with the [[Resolve a clock]] command.

![[Mechanics Blocks#`clock`#Example|iv-embed]]
![[Doomsday Device|iv-embed]]
3 changes: 3 additions & 0 deletions docs/Commands/Resolve a clock.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Resolves a [[Clocks|Clock]]. This will remove it from the list of active clocks shown by, e.g., the [[Advance a clock]] command.

Note that you may resolve a clock that is not full. This is appropriate for situations where the clock is no longer relevant.
7 changes: 6 additions & 1 deletion docs/Entities/Clocks.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
---
aliases:
- Clock
- clock
---
Starforged introduced a mechanic called "clocks", which Iron Vault has direct support for. There are two main types of clock: Tension Clocks, and Campaign Clocks. Both are represented by a single "Clock" entity in Iron Vault, and it does not distinguish between them. Clocks are managed/advanced manually.

You can create a clock using the [[Create a clock]] command. To advance the clock and record the step in your journal, use the [[Advance a clock]] command. You can also click on the clock itself, but that will *not* update your journal automatically.
You can create a clock using the [[Create a clock]] command. To advance the clock and record the step in your journal, use the [[Advance a clock]] command. You can also click on the clock itself, but that will *not* update your journal automatically. Finally, you can [[Resolve a clock]] which will mark it as "incomplete" and remove it from the active clocks listed in [[Advance a clock]].

#### Example
![[Doomsday Device|iv-embed]]
Expand Down
67 changes: 57 additions & 10 deletions src/clocks/commands.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { determineCampaignContext } from "campaigns/manager";
import IronVaultPlugin from "index";
import { appendNodesToMoveOrMechanicsBlock } from "mechanics/editor";
import { createDetailsNode } from "mechanics/node-builders";
import {
clockResolvedNode,
createClockCreationNode,
createClockNode,
createDetailsNode,
} from "mechanics/node-builders";
import { Editor, MarkdownView } from "obsidian";
} from "mechanics/node-builders/clocks";
import { Editor, MarkdownFileInfo, MarkdownView, Notice } from "obsidian";
import { stripMarkdown } from "utils/strip-markdown";
import { YesNoPrompt } from "utils/ui/yesno";
import { ClockFileAdapter, clockUpdater } from "../clocks/clock-file";
import { selectClock } from "../clocks/select-clock";
import { BLOCK_TYPE__CLOCK, IronVaultKind } from "../constants";
Expand Down Expand Up @@ -38,21 +40,66 @@ export async function advanceClock(
"Select number of segments to fill.",
);

let shouldMarkResolved = false;
if (clockInfo.clock.tick(ticks).isFilled) {
shouldMarkResolved = await YesNoPrompt.asSuggest(
plugin.app,
"This clock is now filled. Do you want to mark it as resolved/inactive?",
);
}

const newClock = await clockUpdater(
vaultProcess(plugin.app, clockPath),
(clockAdapter) => {
return clockAdapter.updatingClock((clock) => {
let updatedClock = clock.tick(ticks);
if (shouldMarkResolved) {
if (updatedClock.isFilled) {
updatedClock = updatedClock.deactivate();
} else {
const msg = `Clock '${clockPath}' was no longer filled and was not marked inactive.`;
console.warn(msg);
new Notice(msg, 0);
shouldMarkResolved = false;
}
}
return updatedClock;
});
},
);

const clockName = stripMarkdown(plugin, clockInfo.name);
appendNodesToMoveOrMechanicsBlock(
editor,
...[
createClockNode(clockName, clockPath, clockInfo, newClock.clock),
...(shouldMarkResolved ? [clockResolvedNode(clockName, clockPath)] : []),
],
);
}

export async function resolveClock(
plugin: IronVaultPlugin,
editor: Editor,
view: MarkdownFileInfo,
) {
const campaignContext = await determineCampaignContext(plugin, view);
const [clockPath] = await selectClock(
campaignContext.clocks,
plugin,
([, clockInfo]) => clockInfo.clock.active,
);

const newClock = await clockUpdater(
vaultProcess(plugin.app, clockPath),
(clockAdapter) => {
return clockAdapter.updatingClock((clock) => clock.tick(ticks));
return clockAdapter.updatingClock((clock) => clock.deactivate());
},
);

appendNodesToMoveOrMechanicsBlock(
editor,
createClockNode(
stripMarkdown(plugin, clockInfo.name),
clockPath,
clockInfo,
newClock.clock,
),
clockResolvedNode(stripMarkdown(plugin, newClock.name), clockPath),
);
}

Expand Down
10 changes: 9 additions & 1 deletion src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
createNewCharacter,
pickActiveCharacter,
} from "characters/commands";
import { advanceClock, createClock } from "clocks/commands";
import { advanceClock, createClock, resolveClock } from "clocks/commands";
import { openDocsInBrowser, openDocsInTab } from "docs/commands";
import { generateEntityCommand } from "entity/command";
import { createFactionInfluenceGrid } from "factions/commands";
Expand Down Expand Up @@ -210,6 +210,14 @@ export class IronVaultCommands {
advanceClock(this.plugin, editor, ctx as MarkdownView),
},

{
id: "clock-resolve",
name: "Clock: Resolve a clock",
icon: "alarm-clock-off",
editorCallback: (editor: Editor, ctx: MarkdownView | MarkdownFileInfo) =>
resolveClock(this.plugin, editor, ctx),
},

/*
* ENTITIES
*/
Expand Down
4 changes: 2 additions & 2 deletions src/mechanics/css/dlist-clock-status.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
content: "Clock added: ";
}
}
&.clock-name:has(~ .clock-status[data-value="removed"]) {
&.clock-name:has(~ .clock-status[data-value="resolved"]) {
&:before {
content: "Clock removed: ";
content: "Clock resolved: ";
}
}
&.clock-status {
Expand Down
44 changes: 44 additions & 0 deletions src/mechanics/node-builders/clocks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Clock } from "clocks/clock";
import { ClockFileAdapter } from "clocks/clock-file";
import * as kdl from "kdljs";
import { node } from "utils/kdl";

export function createClockCreationNode(
clockName: string,
clockPath: string,
): kdl.Node {
return node("clock", {
properties: {
name: `[[${clockPath}|${clockName}]]`,
status: "added",
},
});
}

export function clockResolvedNode(
clockName: string,
clockPath: string,
): kdl.Node {
return node("clock", {
properties: {
name: `[[${clockPath}|${clockName}]]`,
status: "resolved",
},
});
}

export function createClockNode(
clockName: string,
clockPath: string,
sourceClock: ClockFileAdapter,
endValue: Clock,
): kdl.Node {
return node("clock", {
properties: {
name: `[[${clockPath}|${clockName}]]`,
from: sourceClock.clock.progress,
to: endValue.progress,
"out-of": endValue.segments,
},
});
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { Clock } from "clocks/clock";
import { ClockFileAdapter } from "clocks/clock-file";
import { createDataswornMarkdownLink } from "datastore/parsers/datasworn/id";
import * as kdl from "kdljs";
import { Document, Node } from "kdljs";
Expand Down Expand Up @@ -55,34 +53,6 @@ export function createTrackCompletionNode(
});
}

export function createClockCreationNode(
clockName: string,
clockPath: string,
): kdl.Node {
return node("clock", {
properties: {
name: `[[${clockPath}|${clockName}]]`,
status: "added",
},
});
}

export function createClockNode(
clockName: string,
clockPath: string,
sourceClock: ClockFileAdapter,
endValue: Clock,
): kdl.Node {
return node("clock", {
properties: {
name: `[[${clockPath}|${clockName}]]`,
from: sourceClock.clock.progress,
to: endValue.progress,
"out-of": endValue.segments,
},
});
}

export function createOracleNode(
roll: RollWrapper,
prompt?: string,
Expand Down
Loading