Hid silenced content from the logs

This commit is contained in:
Thaum Rystra
2024-10-30 17:53:39 +02:00
parent 2a5a97f04a
commit 84282cef6c
23 changed files with 163 additions and 46 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -27,7 +27,7 @@ export default async function applyActionProperty(
result.appendLog({
name: getPropertyTitle(prop),
...prop.summary && { value: prop.summary.value },
...prop.silent && { silenced: true },
silenced: prop.silent,
}, targetIds);
// Check Uses
@@ -35,7 +35,7 @@ export default async function applyActionProperty(
result.appendLog({
name: 'Error',
value: `${getPropertyTitle(prop)} does not have enough uses left`,
...prop.silent && { silenced: true },
silenced: prop.silent,
}, targetIds);
return;
}
@@ -45,7 +45,7 @@ export default async function applyActionProperty(
result.appendLog({
name: 'Error',
value: 'This creature doesn\'t have sufficient resources to perform this action',
...prop.silent && { silenced: true },
silenced: prop.silent,
}, targetIds);
return;
}

View File

@@ -32,7 +32,8 @@ export default async function applyBranchProperty(
if (!isFinite(prop.condition?.value)) {
result.appendLog({
name: 'Branch Error',
value: `Index did not resolve into a valid number, got \`${prop.condition?.value}\` instead`
value: `Index did not resolve into a valid number, got \`${prop.condition?.value}\` instead`,
silenced: prop.silent,
}, targets);
return applyAfterTasksSkipChildren(action, prop, targets, userInput);
}
@@ -47,7 +48,8 @@ export default async function applyBranchProperty(
if (scope['~attackHit']?.value) {
if (!targets.length && !prop.silent) {
result.appendLog({
value: '**On hit**'
value: '**On hit**',
silenced: prop.silent,
}, targets);
}
return applyDefaultAfterPropTasks(action, prop, targets, userInput);
@@ -60,7 +62,8 @@ export default async function applyBranchProperty(
if (scope['~attackMiss']?.value) {
if (!targets.length && !prop.silent) {
result.appendLog({
value: '**On miss**'
value: '**On miss**',
silenced: prop.silent,
}, targets);
}
return applyDefaultAfterPropTasks(action, prop, targets, userInput);
@@ -73,7 +76,8 @@ export default async function applyBranchProperty(
if (scope['~saveFailed']?.value) {
if (!targets.length && !prop.silent) {
result.appendLog({
value: '**On failed save**'
value: '**On failed save**',
silenced: prop.silent,
}, targets);
}
return applyDefaultAfterPropTasks(action, prop, targets, userInput);
@@ -86,7 +90,8 @@ export default async function applyBranchProperty(
if (scope['~saveSucceeded']?.value) {
if (!targets.length && !prop.silent) {
result.appendLog({
value: '**On save**'
value: '**On save**',
silenced: prop.silent,
}, targets);
}
return applyDefaultAfterPropTasks(action, prop, targets, userInput);
@@ -123,4 +128,4 @@ export default async function applyBranchProperty(
return applyAfterPropTasksForSomeChildren(action, prop, chosenChildren, targets, userInput);
}
}
}
}

View File

@@ -62,7 +62,8 @@ export default async function applyBuffProperty(
}
result.appendLog({
name: getPropertyTitle(prop),
value: logValue
value: logValue,
silenced: prop.silent,
}, [target]);
// remove all the computed fields
@@ -114,6 +115,7 @@ async function crystalizeVariables(
result.appendLog({
name: 'Error',
value: 'Variable `~target` should not be used without a property: ~target.property',
silenced: prop.silent,
}, task.targetIds);
}
return node;

View File

@@ -19,7 +19,7 @@ export default async function applyBuffRemoverProperty(
// Log Name
result.appendLog({
name: getPropertyTitle(prop),
...prop.silent && { silenced: true },
silenced: prop.silent,
}, task.targetIds)
}
@@ -41,6 +41,7 @@ export default async function applyBuffRemoverProperty(
result.appendLog({
name: 'Error',
value: 'Buff remover does not have a parent buff to remove',
silenced: prop.silent,
}, [targetId]);
return;
}

View File

@@ -17,12 +17,14 @@ export default async function applyCreatureTemplateProperty(
// Creatures are always summoned as children of the action's creature
result.appendLog({
name: getPropertyTitle(prop),
value: logValue
value: logValue,
silenced: prop.silent,
}, []);
result.appendLog({
name: 'Warning',
value: 'Creature summoning is not yet implemented...'
value: 'Creature summoning is not yet implemented...',
silenced: prop.silent,
}, []);
return;

View File

@@ -188,6 +188,7 @@ export default async function applyDamageProperty(
name: logName,
value: logValue.join('\n'),
inline: true,
silenced: prop.silent,
}, damageTargets);
return applyDefaultAfterPropTasks(action, prop, damageTargets, inputProvider);
}

View File

@@ -9,8 +9,9 @@ export default async function applyNoteProperty(
task: PropTask, action: EngineAction, result: TaskResult, inputProvider: InputProvider
): Promise<void> {
const prop = task.prop;
let contents: LogContent[] | undefined = undefined;
const logContent: LogContent = {};
const logContent: LogContent & { silenced: boolean } = {
silenced: prop.silent,
};
if (prop.name) logContent.name = prop.name;
if (prop.summary?.text) {
await recalculateInlineCalculations(prop.summary, action, 'reduce', inputProvider);
@@ -18,19 +19,15 @@ export default async function applyNoteProperty(
}
if (logContent.name || logContent.value) {
contents = [logContent];
result.appendLog(logContent, task.targetIds);
}
// Log description
if (prop.description?.text) {
await recalculateInlineCalculations(prop.description, action, 'reduce', inputProvider);
if (!contents) contents = [];
contents.push({ value: prop.description.value });
}
if (contents) {
result.mutations.push({
contents,
targetIds: task.targetIds,
});
result.appendLog({
value: prop.description.value,
silenced: prop.silent,
}, task.targetIds);
}
return applyDefaultAfterPropTasks(action, prop, task.targetIds, inputProvider);
}
}

View File

@@ -27,7 +27,11 @@ export default async function applyRollProperty(
logValue.push(toString(rolled));
}
errors?.forEach(error => {
result.appendLog({ name: 'Error', value: error.message }, task.targetIds);
result.appendLog({
name: 'Error',
value: error.message,
silenced: prop.silent,
}, task.targetIds);
});
// Store the result
@@ -52,7 +56,7 @@ export default async function applyRollProperty(
name: prop.name,
value: logValue.join('\n'),
inline: true,
...prop.silent && { silenced: true },
silenced: prop.silent,
}, task.targetIds);
// Apply children

View File

@@ -28,6 +28,7 @@ export default async function applySavingThrowProperty(
result.appendLog({
name: 'Error',
value: 'Saving throw requires a DC',
silenced: prop.silent,
}, saveTargetIds);
return applyDefaultAfterPropTasks(action, prop, saveTargetIds, inputProvider);
}
@@ -37,7 +38,7 @@ export default async function applySavingThrowProperty(
name: getPropertyTitle(prop),
value: `DC **${dc}**`,
inline: true,
...prop.silent && { silenced: prop.silent }
silenced: prop.silent,
}, saveTargetIds);
const targetId = saveTargetIds[0];
@@ -60,6 +61,7 @@ export default async function applySavingThrowProperty(
result.appendLog({
name: 'Saving throw error',
value: 'No saving throw found: ' + prop.stat,
silenced: prop.silent,
}, [targetId]);
return applyDefaultAfterPropTasks(action, prop, [targetId], inputProvider);
}
@@ -103,10 +105,11 @@ export default async function applySavingThrowProperty(
result.pushScope['~saveFailed'] = { value: true };
result.pushScope['~saveSucceeded'] = { value: false };
}
if (!prop.silent) result.appendLog({
result.appendLog({
name: saveSuccess ? 'Successful save' : 'Failed save',
value: resultPrefix + '\n**' + resultValue + '**',
inline: true,
silenced: prop.silent,
}, [targetId]);
return applyDefaultAfterPropTasks(action, prop, [targetId], inputProvider);
}

View File

@@ -1,3 +1,4 @@
import TaskResult, { LogContent } from '../tasks/TaskResult';
import { EngineAction } from '/imports/api/engine/action/EngineActions';
import { applyDefaultAfterPropTasks } from '/imports/api/engine/action/functions/applyTaskGroups';
import recalculateInlineCalculations from '/imports/api/engine/action/functions/recalculateInlineCalculations';
@@ -5,12 +6,12 @@ import { PropTask } from '/imports/api/engine/action/tasks/Task';
import getPropertyTitle from '/imports/api/utility/getPropertyTitle';
export default async function applyTriggerProperty(
task: PropTask, action: EngineAction, result, userInput
task: PropTask, action: EngineAction, result: TaskResult, userInput
): Promise<void> {
const prop = task.prop;
const logContent = {
const logContent: LogContent & { silenced: boolean } = {
name: getPropertyTitle(prop),
...prop.silent && { silenced: true },
silenced: prop.silent,
}
// Add the trigger description to the log
@@ -21,6 +22,6 @@ export default async function applyTriggerProperty(
}
}
result.appendLog(logContent);
result.appendLog(logContent, task.targetIds);
return applyDefaultAfterPropTasks(action, prop, task.targetIds, userInput);
}

View File

@@ -0,0 +1,50 @@
import { assert } from 'chai';
import {
allMutations,
createTestCreature,
getRandomIds,
removeAllCreaturesAndProps,
runActionById
} from '/imports/api/engine/action/functions/actionEngineTest.testFn';
const [
creatureId, silencedNoteId
] = getRandomIds(2);
const actionTestCreature = {
_id: creatureId,
props: [
{
_id: silencedNoteId,
type: 'note',
name: 'Note Name',
summary: { text: 'Note summary {1 + 2}' },
silent: true,
},
],
}
describe('Apply silenced properties', function () {
// Increase timeout
this.timeout(8000);
before(async function () {
await removeAllCreaturesAndProps();
await createTestCreature(actionTestCreature);
});
it('Hides the note text', async function () {
const action = await runActionById(silencedNoteId);
assert.exists(action);
assert.deepEqual(allMutations(action), [{
contents: [
{
name: 'Note Name',
value: 'Note summary 3',
silenced: true,
},
],
targetIds: [],
}]);
});
});

View File

@@ -26,7 +26,13 @@ export default class TaskResult {
this.scope = {};
}
// Appends the log content to the latest mutation
appendLog(content: LogContent, targetIds: string[]) {
appendLog(content: LogContent & { silenced: boolean }, targetIds: string[]) {
// Create a shallow copy of the content
const logContent: LogContent = { ...content };
// remove false silenced properties
if (!logContent.silenced) {
delete logContent.silenced;
}
if (!this.mutations.length) {
this.mutations.push({ targetIds, contents: [] });
}
@@ -34,7 +40,7 @@ export default class TaskResult {
if (!latestMutation.contents) {
latestMutation.contents = [];
}
latestMutation.contents.push(content);
latestMutation.contents.push(logContent);
}
appendParserContextErrors(context: Context, targetIds) {
if (!context.errors?.length) return;

View File

@@ -22,6 +22,7 @@ export default async function applySpellProperty(
result.appendLog({
name: 'Error casting spell',
value: 'No spell was selected',
silenced: false,
}, [action.creatureId]);
return;
}
@@ -32,6 +33,7 @@ export default async function applySpellProperty(
result.appendLog({
name: 'Error casting spell',
value: 'The chosen spell was not found',
silenced: false,
}, [action.creatureId]);
return;
}
@@ -80,7 +82,8 @@ function logCastingMessage(slotLevel: number, castOptions, result: TaskResult, p
// Post the message
if (message) {
result.appendLog({
name: `Casting at level ${slotLevel}`
name: `Casting at level ${slotLevel}`,
silenced: prop.silent,
}, targetIds);
}
}

View File

@@ -74,7 +74,7 @@ export default async function applyCheckTask(
name: checkName,
inline: true,
...dc !== null && { value: `DC **${dc}**` },
...task?.silent && { silenced: task.silent }
silenced: task.silent ?? false,
}, [targetId]);
// Roll the dice
@@ -108,7 +108,7 @@ export default async function applyCheckTask(
name: rollName,
value: `${resultPrefix}\n**${totalValue}**`,
inline: true,
...task?.silent && { silenced: task.silent }
silenced: task.silent ?? false,
}, [targetId]);
// After check triggers

View File

@@ -73,7 +73,7 @@ export default async function applyDamagePropTask(
value: `${statName}${operation === 'set' ? ' set to' : ''}` +
` ${value}`,
inline: true,
...task.silent && { silenced: true },
silenced: task.silent ?? false,
}, task.targetIds);
}

View File

@@ -20,10 +20,16 @@ export default async function applyResetTask(
// Print a title for rest events
switch (task.eventName) {
case 'shortRest':
result.appendLog({ name: 'Short Rest' }, task.targetIds);
result.appendLog({
name: 'Short Rest',
silenced: task.silent ?? false,
}, task.targetIds);
break;
case 'longRest':
result.appendLog({ name: 'Long Rest' }, task.targetIds);
result.appendLog({
name: 'Long Rest',
silenced: task.silent ?? false,
}, task.targetIds);
break;
}

View File

@@ -16,6 +16,11 @@ let NoteSchema = createPropertySchema({
type: 'inlineCalculationFieldToCompute',
optional: true,
},
// Prevent the property from showing up in the log
silent: {
type: Boolean,
optional: true,
},
});
let ComputedOnlyNoteSchema = createPropertySchema({

View File

@@ -32,6 +32,11 @@ const ToggleSchema = createPropertySchema({
type: 'fieldToCompute',
optional: true,
},
// Prevent the property from showing up in the log
silent: {
type: Boolean,
optional: true,
},
}).extend(TagTargetingSchema);
const ComputedOnlyToggleSchema = createPropertySchema({

View File

@@ -1,7 +1,7 @@
<template lang="html">
<div class="log-content">
<div
v-for="(content, index) in model"
v-for="(content, index) in filteredModel"
:key="index"
class="content-line"
>
@@ -36,7 +36,16 @@ export default {
type: Array,
default: () => [],
},
showSilenced: {
type: Boolean,
default: false,
},
},
computed: {
filteredModel() {
return this.model.filter(content => !content.silenced || this.showSilenced);
}
}
}
</script>

View File

@@ -64,6 +64,10 @@ export default {
type: Array,
default: () => [],
},
showSilenced: {
type: Boolean,
default: false,
},
},
meteor: {
contentByTargetId() {
@@ -76,7 +80,9 @@ export default {
});
};
let currentContent = undefined;
for (const contentItem of this.model) {
const filteredModel = this.model
.filter(contentItem => !contentItem.silenced || this.showSilenced);
for (const contentItem of filteredModel) {
if (!currentContent || !isEqual(currentContent.targetIds, contentItem.targetIds)) {
if (currentContent) {
content.push(currentContent);
@@ -90,7 +96,7 @@ export default {
currentContent.content.push(contentItem);
}
}
content.push(currentContent);
currentContent && content.push(currentContent);
return content;
}
}

View File

@@ -30,7 +30,10 @@
v-if="model.text || (model.content && model.content.length)"
class="px-2 pt-0 pb-2"
>
<tabletop-log-content :model="model.content" />
<tabletop-log-content
:model="model.content"
:show-silenced="showSilenced"
/>
</v-card-text>
</v-card>
</template>
@@ -39,6 +42,9 @@
import TabletopLogContent from '/imports/client/ui/log/TabletopLogContent.vue';
import Creatures from '/imports/api/creature/creatures/Creatures';
// TODO move content filtering to this component so we can determine if any content was hidden
// then show a button to reveal silenced content at a lower opacity
export default {
components: {
TabletopLogContent,
@@ -50,6 +56,11 @@ export default {
},
showName: Boolean,
},
data() {
return {
showSilenced: false,
};
},
meteor: {
creature() {
return Creatures.findOne(this.model.creatureId);

View File

@@ -9,7 +9,7 @@
},
"author": "Thaum Rystra",
"scripts": {
"serve": "meteor run --raw-logs",
"serve": "meteor run --raw-logs --settings settings.json",
"debug": "meteor --inspect",
"bundle-viz": "meteor --extra-packages bundle-visualizer --production",
"lint": "eslint .",