Began adding creature templates to libraries
This commit is contained in:
@@ -117,7 +117,7 @@ function insertPropertyFromNode(nodeId, root, parentId) {
|
||||
return node;
|
||||
}
|
||||
|
||||
function storeLibraryNodeReferences(nodes) {
|
||||
export function storeLibraryNodeReferences(nodes) {
|
||||
nodes.forEach(node => {
|
||||
if (node.libraryNodeId) return;
|
||||
node.libraryNodeId = node._id;
|
||||
@@ -126,7 +126,7 @@ function storeLibraryNodeReferences(nodes) {
|
||||
|
||||
// Covert node references into actual nodes
|
||||
// TODO: check permissions for each library a reference node references
|
||||
function reifyNodeReferences(nodes, visitedRefs = new Set(), depth = 0) {
|
||||
export function reifyNodeReferences(nodes, visitedRefs = new Set(), depth = 0) {
|
||||
depth += 1;
|
||||
// New nodes added this function
|
||||
let newNodes = [];
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import { EngineAction } from '/imports/api/engine/action/EngineActions';
|
||||
import { PropTask } from '/imports/api/engine/action/tasks/Task';
|
||||
import recalculateInlineCalculations from '/imports/api/engine/action/functions/recalculateInlineCalculations';
|
||||
import getPropertyTitle from '/imports/api/utility/getPropertyTitle';
|
||||
|
||||
export default async function applyCreatureTemplateProperty(
|
||||
task: PropTask, action: EngineAction, result, userInput
|
||||
): Promise<void> {
|
||||
const prop = task.prop;
|
||||
//Log the Creature that is about to be summoned
|
||||
let logValue = prop.description?.value
|
||||
if (prop.description?.text) {
|
||||
recalculateInlineCalculations(prop.description, action, 'reduce', userInput);
|
||||
logValue = prop.description?.value;
|
||||
}
|
||||
// There are no targets for creature templates
|
||||
// Creatures are always summoned as children of the action's creature
|
||||
result.appendLog({
|
||||
name: getPropertyTitle(prop),
|
||||
value: logValue
|
||||
}, []);
|
||||
|
||||
result.appendLog({
|
||||
name: 'Warning',
|
||||
value: 'Creature summoning is not yet implemented...'
|
||||
}, []);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import adjustment from './applyAdjustmentProperty';
|
||||
import branch from './applyBranchProperty';
|
||||
import buff from './applyBuffProperty';
|
||||
import buffRemover from './applyBuffRemoverProperty';
|
||||
import creature from './applyCreatureTemplateProperty';
|
||||
import damage from './applyDamageProperty';
|
||||
import folder from './applyFolderProperty';
|
||||
import note from './applyNoteProperty';
|
||||
@@ -24,6 +25,7 @@ const applyPropertyByType: {
|
||||
branch,
|
||||
buff,
|
||||
buffRemover,
|
||||
creature,
|
||||
damage,
|
||||
folder,
|
||||
note,
|
||||
|
||||
40
app/imports/api/properties/CreatureTemplates.ts
Normal file
40
app/imports/api/properties/CreatureTemplates.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS';
|
||||
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema';
|
||||
|
||||
// Creature templates represent creatures that don't yet exist
|
||||
// Used to store creatures in the library, or as templates for another creature to summon
|
||||
const CreatureTemplateSchema = createPropertySchema({
|
||||
name: {
|
||||
type: String,
|
||||
max: STORAGE_LIMITS.name,
|
||||
optional: true,
|
||||
},
|
||||
description: {
|
||||
type: 'inlineCalculationFieldToCompute',
|
||||
optional: true,
|
||||
},
|
||||
picture: {
|
||||
type: String,
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.url,
|
||||
},
|
||||
avatarPicture: {
|
||||
type: String,
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.url,
|
||||
},
|
||||
});
|
||||
|
||||
const ComputedOnlyCreatureTemplateSchema = createPropertySchema({
|
||||
description: {
|
||||
type: 'computedOnlyInlineCalculationField',
|
||||
optional: true,
|
||||
},
|
||||
});
|
||||
|
||||
const ComputedCreatureTemplateSchema = new SimpleSchema({})
|
||||
.extend(CreatureTemplateSchema)
|
||||
.extend(ComputedOnlyCreatureTemplateSchema);
|
||||
|
||||
export { CreatureTemplateSchema, ComputedCreatureTemplateSchema, ComputedOnlyCreatureTemplateSchema };
|
||||
@@ -2,15 +2,16 @@ import SimpleSchema from 'simpl-schema';
|
||||
import { ComputedOnlyActionSchema } from '/imports/api/properties/Actions';
|
||||
import { ComputedOnlyAdjustmentSchema } from '/imports/api/properties/Adjustments';
|
||||
import { ComputedOnlyAttributeSchema } from '/imports/api/properties/Attributes';
|
||||
import { ComputedOnlyBuffSchema } from '/imports/api/properties/Buffs';
|
||||
import { ComputedOnlyBuffRemoverSchema } from '/imports/api/properties/BuffRemovers';
|
||||
import { ComputedOnlyBranchSchema } from '/imports/api/properties/Branches';
|
||||
import { ComputedOnlyClassSchema } from '/imports/api/properties/Classes';
|
||||
import { ComputedOnlyBuffRemoverSchema } from '/imports/api/properties/BuffRemovers';
|
||||
import { ComputedOnlyBuffSchema } from '/imports/api/properties/Buffs';
|
||||
import { ComputedOnlyClassLevelSchema } from '/imports/api/properties/ClassLevels';
|
||||
import { ComputedOnlyClassSchema } from '/imports/api/properties/Classes';
|
||||
import { ComputedOnlyConstantSchema } from '/imports/api/properties/Constants';
|
||||
import { ComputedOnlyContainerSchema } from '/imports/api/properties/Containers';
|
||||
import { ComputedOnlyDamageSchema } from '/imports/api/properties/Damages';
|
||||
import { ComputedOnlyCreatureTemplateSchema } from '/imports/api/properties/CreatureTemplates';
|
||||
import { ComputedOnlyDamageMultiplierSchema } from '/imports/api/properties/DamageMultipliers';
|
||||
import { ComputedOnlyDamageSchema } from '/imports/api/properties/Damages';
|
||||
import { ComputedOnlyEffectSchema } from '/imports/api/properties/Effects';
|
||||
import { ComputedOnlyFeatureSchema } from '/imports/api/properties/Features';
|
||||
import { ComputedOnlyFolderSchema } from '/imports/api/properties/Folders';
|
||||
@@ -23,8 +24,8 @@ import { ComputedOnlyRollSchema } from '/imports/api/properties/Rolls';
|
||||
import { ComputedOnlySavingThrowSchema } from '/imports/api/properties/SavingThrows';
|
||||
import { ComputedOnlySkillSchema } from '/imports/api/properties/Skills';
|
||||
import { ComputedOnlySlotSchema } from '/imports/api/properties/Slots';
|
||||
import { ComputedOnlySpellSchema } from '/imports/api/properties/Spells';
|
||||
import { ComputedOnlySpellListSchema } from '/imports/api/properties/SpellLists';
|
||||
import { ComputedOnlySpellSchema } from '/imports/api/properties/Spells';
|
||||
import { ComputedOnlyToggleSchema } from '/imports/api/properties/Toggles';
|
||||
import { ComputedOnlyTriggerSchema } from '/imports/api/properties/Triggers';
|
||||
|
||||
@@ -32,13 +33,14 @@ const propertySchemasIndex = {
|
||||
action: ComputedOnlyActionSchema,
|
||||
adjustment: ComputedOnlyAdjustmentSchema,
|
||||
attribute: ComputedOnlyAttributeSchema,
|
||||
branch: ComputedOnlyBranchSchema,
|
||||
buff: ComputedOnlyBuffSchema,
|
||||
buffRemover: ComputedOnlyBuffRemoverSchema,
|
||||
branch: ComputedOnlyBranchSchema,
|
||||
class: ComputedOnlyClassSchema,
|
||||
classLevel: ComputedOnlyClassLevelSchema,
|
||||
constant: ComputedOnlyConstantSchema,
|
||||
container: ComputedOnlyContainerSchema,
|
||||
creature: ComputedOnlyCreatureTemplateSchema,
|
||||
damage: ComputedOnlyDamageSchema,
|
||||
damageMultiplier: ComputedOnlyDamageMultiplierSchema,
|
||||
effect: ComputedOnlyEffectSchema,
|
||||
@@ -53,8 +55,8 @@ const propertySchemasIndex = {
|
||||
roll: ComputedOnlyRollSchema,
|
||||
savingThrow: ComputedOnlySavingThrowSchema,
|
||||
skill: ComputedOnlySkillSchema,
|
||||
spellList: ComputedOnlySpellListSchema,
|
||||
spell: ComputedOnlySpellSchema,
|
||||
spellList: ComputedOnlySpellListSchema,
|
||||
toggle: ComputedOnlyToggleSchema,
|
||||
trigger: ComputedOnlyTriggerSchema,
|
||||
any: new SimpleSchema({}),
|
||||
|
||||
@@ -10,6 +10,7 @@ import { ComputedClassSchema } from '/imports/api/properties/Classes';
|
||||
import { ComputedClassLevelSchema } from '/imports/api/properties/ClassLevels';
|
||||
import { ConstantSchema } from '/imports/api/properties/Constants';
|
||||
import { ComputedContainerSchema } from '/imports/api/properties/Containers';
|
||||
import { ComputedCreatureTemplateSchema } from '/imports/api/properties/CreatureTemplates';
|
||||
import { ComputedDamageSchema } from '/imports/api/properties/Damages';
|
||||
import { DamageMultiplierSchema } from '/imports/api/properties/DamageMultipliers';
|
||||
import { ComputedEffectSchema } from '/imports/api/properties/Effects';
|
||||
@@ -33,17 +34,20 @@ const propertySchemasIndex = {
|
||||
action: ComputedActionSchema,
|
||||
adjustment: ComputedAdjustmentSchema,
|
||||
attribute: ComputedAttributeSchema,
|
||||
branch: ComputedBranchSchema,
|
||||
buff: ComputedBuffSchema,
|
||||
buffRemover: ComputedBuffRemoverSchema,
|
||||
branch: ComputedBranchSchema,
|
||||
class: ComputedClassSchema,
|
||||
classLevel: ComputedClassLevelSchema,
|
||||
constant: ConstantSchema,
|
||||
container: ComputedContainerSchema,
|
||||
creature: ComputedCreatureTemplateSchema,
|
||||
damage: ComputedDamageSchema,
|
||||
damageMultiplier: DamageMultiplierSchema,
|
||||
effect: ComputedEffectSchema,
|
||||
feature: ComputedFeatureSchema,
|
||||
folder: ComputedFolderSchema,
|
||||
item: ComputedItemSchema,
|
||||
note: ComputedNoteSchema,
|
||||
pointBuy: ComputedPointBuySchema,
|
||||
proficiency: ProficiencySchema,
|
||||
@@ -52,12 +56,10 @@ const propertySchemasIndex = {
|
||||
roll: ComputedRollSchema,
|
||||
savingThrow: ComputedSavingThrowSchema,
|
||||
skill: ComputedSkillSchema,
|
||||
spellList: ComputedSpellListSchema,
|
||||
spell: ComputedSpellSchema,
|
||||
spellList: ComputedSpellListSchema,
|
||||
toggle: ComputedToggleSchema,
|
||||
trigger: ComputedTriggerSchema,
|
||||
container: ComputedContainerSchema,
|
||||
item: ComputedItemSchema,
|
||||
any: new SimpleSchema({}),
|
||||
};
|
||||
|
||||
|
||||
@@ -2,17 +2,20 @@ import SimpleSchema from 'simpl-schema';
|
||||
import { ActionSchema } from '/imports/api/properties/Actions';
|
||||
import { AdjustmentSchema } from '/imports/api/properties/Adjustments';
|
||||
import { AttributeSchema } from '/imports/api/properties/Attributes';
|
||||
import { BuffSchema } from '/imports/api/properties/Buffs';
|
||||
import { BuffRemoverSchema } from '/imports/api/properties/BuffRemovers';
|
||||
import { BranchSchema } from '/imports/api/properties/Branches';
|
||||
import { ClassSchema } from '/imports/api/properties/Classes';
|
||||
import { BuffRemoverSchema } from '/imports/api/properties/BuffRemovers';
|
||||
import { BuffSchema } from '/imports/api/properties/Buffs';
|
||||
import { ClassLevelSchema } from '/imports/api/properties/ClassLevels';
|
||||
import { ClassSchema } from '/imports/api/properties/Classes';
|
||||
import { ConstantSchema } from '/imports/api/properties/Constants';
|
||||
import { DamageSchema } from '/imports/api/properties/Damages';
|
||||
import { ContainerSchema } from '/imports/api/properties/Containers';
|
||||
import { CreatureTemplateSchema } from '/imports/api/properties/CreatureTemplates';
|
||||
import { DamageMultiplierSchema } from '/imports/api/properties/DamageMultipliers';
|
||||
import { DamageSchema } from '/imports/api/properties/Damages';
|
||||
import { EffectSchema } from '/imports/api/properties/Effects';
|
||||
import { FeatureSchema } from '/imports/api/properties/Features';
|
||||
import { FolderSchema } from '/imports/api/properties/Folders';
|
||||
import { ItemSchema } from '/imports/api/properties/Items';
|
||||
import { NoteSchema } from '/imports/api/properties/Notes';
|
||||
import { PointBuySchema } from '/imports/api/properties/PointBuys';
|
||||
import { ProficiencySchema } from '/imports/api/properties/Proficiencies';
|
||||
@@ -25,24 +28,25 @@ import { SpellListSchema } from '/imports/api/properties/SpellLists';
|
||||
import { SpellSchema } from '/imports/api/properties/Spells';
|
||||
import { ToggleSchema } from '/imports/api/properties/Toggles';
|
||||
import { TriggerSchema } from '/imports/api/properties/Triggers';
|
||||
import { ContainerSchema } from '/imports/api/properties/Containers';
|
||||
import { ItemSchema } from '/imports/api/properties/Items';
|
||||
|
||||
const propertySchemasIndex = {
|
||||
action: ActionSchema,
|
||||
adjustment: AdjustmentSchema,
|
||||
attribute: AttributeSchema,
|
||||
branch: BranchSchema,
|
||||
buff: BuffSchema,
|
||||
buffRemover: BuffRemoverSchema,
|
||||
branch: BranchSchema,
|
||||
class: ClassSchema,
|
||||
classLevel: ClassLevelSchema,
|
||||
constant: ConstantSchema,
|
||||
container: ContainerSchema,
|
||||
creature: CreatureTemplateSchema,
|
||||
damage: DamageSchema,
|
||||
damageMultiplier: DamageMultiplierSchema,
|
||||
effect: EffectSchema,
|
||||
feature: FeatureSchema,
|
||||
folder: FolderSchema,
|
||||
item: ItemSchema,
|
||||
note: NoteSchema,
|
||||
pointBuy: PointBuySchema,
|
||||
proficiency: ProficiencySchema,
|
||||
@@ -51,12 +55,10 @@ const propertySchemasIndex = {
|
||||
roll: RollSchema,
|
||||
savingThrow: SavingThrowSchema,
|
||||
skill: SkillSchema,
|
||||
spellList: SpellListSchema,
|
||||
spell: SpellSchema,
|
||||
spellList: SpellListSchema,
|
||||
toggle: ToggleSchema,
|
||||
trigger: TriggerSchema,
|
||||
container: ContainerSchema,
|
||||
item: ItemSchema,
|
||||
any: new SimpleSchema({}),
|
||||
};
|
||||
|
||||
|
||||
@@ -111,5 +111,6 @@ import '/imports/api/tabletop/methods/insertTabletop';
|
||||
import '/imports/api/tabletop/methods/updateTabletop';
|
||||
import '/imports/api/tabletop/methods/addCreaturesToTabletop';
|
||||
import '/imports/api/tabletop/methods/updateTabletopSharing';
|
||||
import '/imports/api/tabletop/methods/addCreaturesFromLibraryToTabletop';
|
||||
|
||||
export default Tabletops;
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import { assertUserInTabletop } from './shared/tabletopPermissions';
|
||||
import { assertUserHasPaidBenefits } from '/imports/api/users/patreon/tiers';
|
||||
import Creatures from '/imports/api/creature/creatures/Creatures';
|
||||
import LibraryNodes from '/imports/api/library/LibraryNodes';
|
||||
import { getFilter, renewDocIds } from '/imports/api/parenting/parentingFunctions';
|
||||
import { reifyNodeReferences, storeLibraryNodeReferences } from '/imports/api/creature/creatureProperties/methods/insertPropertyFromLibraryNode';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
|
||||
|
||||
const addCreaturesFromLibraryToTabletop = new ValidatedMethod({
|
||||
|
||||
name: 'tabletops.addCreaturesFromLibraryToTabletop',
|
||||
|
||||
validate: new SimpleSchema({
|
||||
'libraryNodeIds': {
|
||||
type: Array,
|
||||
},
|
||||
'libraryNodeIds.$': {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
},
|
||||
tabletopId: {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
},
|
||||
}).validator(),
|
||||
|
||||
mixins: [RateLimiterMixin],
|
||||
rateLimit: {
|
||||
numRequests: 1,
|
||||
timeInterval: 5_000,
|
||||
},
|
||||
|
||||
run({ libraryNodeIds, tabletopId }) {
|
||||
if (!this.userId) {
|
||||
throw new Meteor.Error('tabletops.addCreatures.denied',
|
||||
'You need to be logged in to remove a tabletop');
|
||||
}
|
||||
assertUserHasPaidBenefits(this.userId);
|
||||
assertUserInTabletop(tabletopId, this.userId);
|
||||
|
||||
for (const nodeId of libraryNodeIds) {
|
||||
const creatureNode = LibraryNodes.findOne({
|
||||
_id: nodeId,
|
||||
type: 'creature',
|
||||
removed: { $ne: true },
|
||||
});
|
||||
|
||||
if (!creatureNode) {
|
||||
if (Meteor.isClient) return {};
|
||||
else {
|
||||
throw new Meteor.Error(
|
||||
'Insert property from library failed',
|
||||
`No library creature with id '${nodeId}' was found`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const creatureId = Creatures.insert({
|
||||
...creatureNode,
|
||||
type: 'monster',
|
||||
tabletopId,
|
||||
owner: this.userId,
|
||||
writers: [this.userId],
|
||||
dirty: true,
|
||||
});
|
||||
insertSubProperties(creatureNode, creatureId);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
function insertSubProperties(node, creatureId: string) {
|
||||
let nodes = LibraryNodes.find({
|
||||
...getFilter.descendants(node),
|
||||
removed: { $ne: true },
|
||||
}).fetch();
|
||||
|
||||
for (const node of nodes) {
|
||||
node.root = {
|
||||
'_id': creatureId,
|
||||
collection: 'creatures',
|
||||
};
|
||||
}
|
||||
|
||||
// Convert all references into actual nodes
|
||||
nodes = reifyNodeReferences(nodes);
|
||||
|
||||
// set libraryNodeIds
|
||||
storeLibraryNodeReferences(nodes);
|
||||
|
||||
// Give the docs new IDs without breaking internal references
|
||||
renewDocIds({
|
||||
docArray: nodes,
|
||||
collectionMap: { 'libraryNodes': 'creatureProperties' }
|
||||
});
|
||||
|
||||
// Insert the creature properties
|
||||
// @ts-expect-error Batch insert not defined
|
||||
CreatureProperties.batchInsert(nodes);
|
||||
return node;
|
||||
}
|
||||
|
||||
export default addCreaturesFromLibraryToTabletop;
|
||||
Reference in New Issue
Block a user