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

View File

@@ -32,7 +32,8 @@ export default async function applyBranchProperty(
if (!isFinite(prop.condition?.value)) { if (!isFinite(prop.condition?.value)) {
result.appendLog({ result.appendLog({
name: 'Branch Error', 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); }, targets);
return applyAfterTasksSkipChildren(action, prop, targets, userInput); return applyAfterTasksSkipChildren(action, prop, targets, userInput);
} }
@@ -47,7 +48,8 @@ export default async function applyBranchProperty(
if (scope['~attackHit']?.value) { if (scope['~attackHit']?.value) {
if (!targets.length && !prop.silent) { if (!targets.length && !prop.silent) {
result.appendLog({ result.appendLog({
value: '**On hit**' value: '**On hit**',
silenced: prop.silent,
}, targets); }, targets);
} }
return applyDefaultAfterPropTasks(action, prop, targets, userInput); return applyDefaultAfterPropTasks(action, prop, targets, userInput);
@@ -60,7 +62,8 @@ export default async function applyBranchProperty(
if (scope['~attackMiss']?.value) { if (scope['~attackMiss']?.value) {
if (!targets.length && !prop.silent) { if (!targets.length && !prop.silent) {
result.appendLog({ result.appendLog({
value: '**On miss**' value: '**On miss**',
silenced: prop.silent,
}, targets); }, targets);
} }
return applyDefaultAfterPropTasks(action, prop, targets, userInput); return applyDefaultAfterPropTasks(action, prop, targets, userInput);
@@ -73,7 +76,8 @@ export default async function applyBranchProperty(
if (scope['~saveFailed']?.value) { if (scope['~saveFailed']?.value) {
if (!targets.length && !prop.silent) { if (!targets.length && !prop.silent) {
result.appendLog({ result.appendLog({
value: '**On failed save**' value: '**On failed save**',
silenced: prop.silent,
}, targets); }, targets);
} }
return applyDefaultAfterPropTasks(action, prop, targets, userInput); return applyDefaultAfterPropTasks(action, prop, targets, userInput);
@@ -86,7 +90,8 @@ export default async function applyBranchProperty(
if (scope['~saveSucceeded']?.value) { if (scope['~saveSucceeded']?.value) {
if (!targets.length && !prop.silent) { if (!targets.length && !prop.silent) {
result.appendLog({ result.appendLog({
value: '**On save**' value: '**On save**',
silenced: prop.silent,
}, targets); }, targets);
} }
return applyDefaultAfterPropTasks(action, prop, targets, userInput); return applyDefaultAfterPropTasks(action, prop, targets, userInput);
@@ -123,4 +128,4 @@ export default async function applyBranchProperty(
return applyAfterPropTasksForSomeChildren(action, prop, chosenChildren, targets, userInput); return applyAfterPropTasksForSomeChildren(action, prop, chosenChildren, targets, userInput);
} }
} }
} }

View File

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

View File

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

View File

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

View File

@@ -188,6 +188,7 @@ export default async function applyDamageProperty(
name: logName, name: logName,
value: logValue.join('\n'), value: logValue.join('\n'),
inline: true, inline: true,
silenced: prop.silent,
}, damageTargets); }, damageTargets);
return applyDefaultAfterPropTasks(action, prop, damageTargets, inputProvider); 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 task: PropTask, action: EngineAction, result: TaskResult, inputProvider: InputProvider
): Promise<void> { ): Promise<void> {
const prop = task.prop; const prop = task.prop;
let contents: LogContent[] | undefined = undefined; const logContent: LogContent & { silenced: boolean } = {
const logContent: LogContent = {}; silenced: prop.silent,
};
if (prop.name) logContent.name = prop.name; if (prop.name) logContent.name = prop.name;
if (prop.summary?.text) { if (prop.summary?.text) {
await recalculateInlineCalculations(prop.summary, action, 'reduce', inputProvider); await recalculateInlineCalculations(prop.summary, action, 'reduce', inputProvider);
@@ -18,19 +19,15 @@ export default async function applyNoteProperty(
} }
if (logContent.name || logContent.value) { if (logContent.name || logContent.value) {
contents = [logContent]; result.appendLog(logContent, task.targetIds);
} }
// Log description // Log description
if (prop.description?.text) { if (prop.description?.text) {
await recalculateInlineCalculations(prop.description, action, 'reduce', inputProvider); await recalculateInlineCalculations(prop.description, action, 'reduce', inputProvider);
if (!contents) contents = []; result.appendLog({
contents.push({ value: prop.description.value }); value: prop.description.value,
} silenced: prop.silent,
if (contents) { }, task.targetIds);
result.mutations.push({
contents,
targetIds: task.targetIds,
});
} }
return applyDefaultAfterPropTasks(action, prop, task.targetIds, inputProvider); return applyDefaultAfterPropTasks(action, prop, task.targetIds, inputProvider);
} }

View File

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

View File

@@ -28,6 +28,7 @@ export default async function applySavingThrowProperty(
result.appendLog({ result.appendLog({
name: 'Error', name: 'Error',
value: 'Saving throw requires a DC', value: 'Saving throw requires a DC',
silenced: prop.silent,
}, saveTargetIds); }, saveTargetIds);
return applyDefaultAfterPropTasks(action, prop, saveTargetIds, inputProvider); return applyDefaultAfterPropTasks(action, prop, saveTargetIds, inputProvider);
} }
@@ -37,7 +38,7 @@ export default async function applySavingThrowProperty(
name: getPropertyTitle(prop), name: getPropertyTitle(prop),
value: `DC **${dc}**`, value: `DC **${dc}**`,
inline: true, inline: true,
...prop.silent && { silenced: prop.silent } silenced: prop.silent,
}, saveTargetIds); }, saveTargetIds);
const targetId = saveTargetIds[0]; const targetId = saveTargetIds[0];
@@ -60,6 +61,7 @@ export default async function applySavingThrowProperty(
result.appendLog({ result.appendLog({
name: 'Saving throw error', name: 'Saving throw error',
value: 'No saving throw found: ' + prop.stat, value: 'No saving throw found: ' + prop.stat,
silenced: prop.silent,
}, [targetId]); }, [targetId]);
return applyDefaultAfterPropTasks(action, prop, [targetId], inputProvider); return applyDefaultAfterPropTasks(action, prop, [targetId], inputProvider);
} }
@@ -103,10 +105,11 @@ export default async function applySavingThrowProperty(
result.pushScope['~saveFailed'] = { value: true }; result.pushScope['~saveFailed'] = { value: true };
result.pushScope['~saveSucceeded'] = { value: false }; result.pushScope['~saveSucceeded'] = { value: false };
} }
if (!prop.silent) result.appendLog({ result.appendLog({
name: saveSuccess ? 'Successful save' : 'Failed save', name: saveSuccess ? 'Successful save' : 'Failed save',
value: resultPrefix + '\n**' + resultValue + '**', value: resultPrefix + '\n**' + resultValue + '**',
inline: true, inline: true,
silenced: prop.silent,
}, [targetId]); }, [targetId]);
return applyDefaultAfterPropTasks(action, prop, [targetId], inputProvider); 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 { EngineAction } from '/imports/api/engine/action/EngineActions';
import { applyDefaultAfterPropTasks } from '/imports/api/engine/action/functions/applyTaskGroups'; import { applyDefaultAfterPropTasks } from '/imports/api/engine/action/functions/applyTaskGroups';
import recalculateInlineCalculations from '/imports/api/engine/action/functions/recalculateInlineCalculations'; 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'; import getPropertyTitle from '/imports/api/utility/getPropertyTitle';
export default async function applyTriggerProperty( export default async function applyTriggerProperty(
task: PropTask, action: EngineAction, result, userInput task: PropTask, action: EngineAction, result: TaskResult, userInput
): Promise<void> { ): Promise<void> {
const prop = task.prop; const prop = task.prop;
const logContent = { const logContent: LogContent & { silenced: boolean } = {
name: getPropertyTitle(prop), name: getPropertyTitle(prop),
...prop.silent && { silenced: true }, silenced: prop.silent,
} }
// Add the trigger description to the log // 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); 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 = {}; this.scope = {};
} }
// Appends the log content to the latest mutation // 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) { if (!this.mutations.length) {
this.mutations.push({ targetIds, contents: [] }); this.mutations.push({ targetIds, contents: [] });
} }
@@ -34,7 +40,7 @@ export default class TaskResult {
if (!latestMutation.contents) { if (!latestMutation.contents) {
latestMutation.contents = []; latestMutation.contents = [];
} }
latestMutation.contents.push(content); latestMutation.contents.push(logContent);
} }
appendParserContextErrors(context: Context, targetIds) { appendParserContextErrors(context: Context, targetIds) {
if (!context.errors?.length) return; if (!context.errors?.length) return;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -64,6 +64,10 @@ export default {
type: Array, type: Array,
default: () => [], default: () => [],
}, },
showSilenced: {
type: Boolean,
default: false,
},
}, },
meteor: { meteor: {
contentByTargetId() { contentByTargetId() {
@@ -76,7 +80,9 @@ export default {
}); });
}; };
let currentContent = undefined; 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 || !isEqual(currentContent.targetIds, contentItem.targetIds)) {
if (currentContent) { if (currentContent) {
content.push(currentContent); content.push(currentContent);
@@ -90,7 +96,7 @@ export default {
currentContent.content.push(contentItem); currentContent.content.push(contentItem);
} }
} }
content.push(currentContent); currentContent && content.push(currentContent);
return content; return content;
} }
} }

View File

@@ -30,7 +30,10 @@
v-if="model.text || (model.content && model.content.length)" v-if="model.text || (model.content && model.content.length)"
class="px-2 pt-0 pb-2" 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-text>
</v-card> </v-card>
</template> </template>
@@ -39,6 +42,9 @@
import TabletopLogContent from '/imports/client/ui/log/TabletopLogContent.vue'; import TabletopLogContent from '/imports/client/ui/log/TabletopLogContent.vue';
import Creatures from '/imports/api/creature/creatures/Creatures'; 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 { export default {
components: { components: {
TabletopLogContent, TabletopLogContent,
@@ -50,6 +56,11 @@ export default {
}, },
showName: Boolean, showName: Boolean,
}, },
data() {
return {
showSilenced: false,
};
},
meteor: { meteor: {
creature() { creature() {
return Creatures.findOne(this.model.creatureId); return Creatures.findOne(this.model.creatureId);

View File

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