Improved typing of creature properties
This commit is contained in:
@@ -7,6 +7,7 @@ import propertySchemasIndex from '/imports/api/properties/computedPropertySchema
|
||||
import { storedIconsSchema } from '/imports/api/icons/Icons';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS';
|
||||
import { InferType, TypedSimpleSchema } from '/imports/api/utility/TypedSimpleSchema';
|
||||
import type { ComputedProperty, ComputedPropertyTypeMap } from '/imports/api/properties/Property.type';
|
||||
|
||||
const PreComputeCreaturePropertySchema = new TypedSimpleSchema({
|
||||
_id: {
|
||||
@@ -153,15 +154,15 @@ for (key in propertySchemasIndex) {
|
||||
}
|
||||
}
|
||||
|
||||
export type CreaturePropertyByType<T extends keyof typeof propertySchemasIndex> =
|
||||
InferType<typeof propertySchemasIndex[T]>
|
||||
export type CreaturePropertyByType<T extends keyof ComputedPropertyTypeMap> =
|
||||
ComputedProperty<T>
|
||||
& InferType<typeof CreaturePropertySchema>
|
||||
& InferType<typeof ColorSchema>
|
||||
& InferType<typeof ChildSchema>
|
||||
& InferType<typeof SoftRemovableSchema>
|
||||
|
||||
type ConvertToUnion<T> = T[keyof T];
|
||||
export type CreatureProperty = ConvertToUnion<{ [key in keyof typeof propertySchemasIndex]: CreaturePropertyByType<key> }>;
|
||||
export type CreatureProperty = ConvertToUnion<{ [key in keyof ComputedPropertyTypeMap]: CreaturePropertyByType<key> }>;
|
||||
|
||||
export default CreatureProperties;
|
||||
export {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { PropTask } from '/imports/api/engine/action/tasks/Task';
|
||||
import TaskResult from 'imports/api/engine/action/tasks/TaskResult';
|
||||
import TaskResult from '/imports/api/engine/action/tasks/TaskResult';
|
||||
import getPropertyTitle from '/imports/api/utility/getPropertyTitle';
|
||||
import { findLast, filter, difference, intersection } from 'lodash';
|
||||
import { getPropertiesOfType, getPropertyAncestors } from '/imports/api/engine/loadCreatures';
|
||||
@@ -53,9 +53,10 @@ export default async function applyBuffRemoverProperty(
|
||||
} else {
|
||||
// Get all the buffs targeted by tags
|
||||
const allBuffs = getPropertiesOfType(targetId, 'buff');
|
||||
const targetedBuffs = filter(allBuffs, buff => {
|
||||
const targetedBuffs = filter(allBuffs, (buff): boolean => {
|
||||
if (buff.inactive) return false;
|
||||
if (buffRemoverMatchTags(prop, buff)) return true;
|
||||
return false;
|
||||
});
|
||||
// Remove the buffs
|
||||
if (prop.removeAll) {
|
||||
@@ -65,7 +66,7 @@ export default async function applyBuffRemoverProperty(
|
||||
});
|
||||
} else {
|
||||
// Sort in reverse order
|
||||
targetedBuffs.sort((a, b) => b.order - a.order);
|
||||
targetedBuffs.sort((a, b) => b.left - a.left);
|
||||
// Remove the one with the highest order
|
||||
const buff = targetedBuffs[0];
|
||||
if (buff) {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { debounce } from 'lodash';
|
||||
import Creatures from '/imports/api/creature/creatures/Creatures';
|
||||
import CreatureVariables from '/imports/api/creature/creatures/CreatureVariables';
|
||||
import CreatureProperties, { CreatureProperty } from '/imports/api/creature/creatureProperties/CreatureProperties';
|
||||
import CreatureProperties, { CreatureProperty, CreaturePropertyByType } from '/imports/api/creature/creatureProperties/CreatureProperties';
|
||||
import computeCreature from './computeCreature';
|
||||
import { getFilter } from '/imports/api/parenting/parentingFunctions';
|
||||
import { ComputedPropertyTypeMap } from '../properties/Property.type';
|
||||
|
||||
const COMPUTE_DEBOUNCE_TIME = 100; // ms
|
||||
export const loadedCreatures: Map<string, LoadedCreature> = new Map(); // creatureId => {creature, properties, etc.}
|
||||
@@ -81,13 +82,13 @@ export function getProperties(creatureId: string): CreatureProperty[] {
|
||||
return props;
|
||||
}
|
||||
|
||||
export function getPropertiesOfType(creatureId, propType) {
|
||||
export function getPropertiesOfType<T extends keyof ComputedPropertyTypeMap>(creatureId, propType: T): CreaturePropertyByType<T>[] {
|
||||
const creature = loadedCreatures.get(creatureId);
|
||||
if (creature) {
|
||||
const props = Array.from(creature.properties.values())
|
||||
.filter(prop => !prop.removed && prop.type === propType)
|
||||
.sort((a, b) => a.left - b.left);
|
||||
return EJSON.clone(props);
|
||||
return EJSON.clone(props) as unknown as CreaturePropertyByType<T>[];
|
||||
}
|
||||
// console.time(`Cache miss on creature properties: ${creatureId}`)
|
||||
const props = CreatureProperties.find({
|
||||
@@ -98,7 +99,7 @@ export function getPropertiesOfType(creatureId, propType) {
|
||||
sort: { left: 1 },
|
||||
}).fetch();
|
||||
// console.timeEnd(`Cache miss on creature properties: ${creatureId}`);
|
||||
return props;
|
||||
return props as unknown as CreaturePropertyByType<T>[];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,7 +2,7 @@ import SimpleSchema from 'simpl-schema';
|
||||
import VARIABLE_NAME_REGEX from '/imports/constants/VARIABLE_NAME_REGEX';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS';
|
||||
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema';
|
||||
import type { Expand, InferType } from '/imports/api/utility/TypedSimpleSchema';
|
||||
import { Expand, InferType, TypedSimpleSchema } from '/imports/api/utility/TypedSimpleSchema';
|
||||
|
||||
/*
|
||||
* Attributes are numbered stats of a character
|
||||
@@ -40,7 +40,7 @@ const AttributeSchema = createPropertySchema({
|
||||
// For type hitDice, the size needs to be stored separately
|
||||
hitDiceSize: {
|
||||
type: String,
|
||||
allowedValues: ['d1', 'd2', 'd4', 'd6', 'd8', 'd10', 'd12', 'd20', 'd100'],
|
||||
allowedValues: ['d1', 'd2', 'd4', 'd6', 'd8', 'd10', 'd12', 'd20', 'd100'] as const,
|
||||
optional: true,
|
||||
},
|
||||
// For type spellSlot, the level needs to be stored separately
|
||||
@@ -297,7 +297,7 @@ const ComputedOnlyAttributeSchema = createPropertySchema({
|
||||
},
|
||||
});
|
||||
|
||||
const ComputedAttributeSchema = new SimpleSchema({})
|
||||
const ComputedAttributeSchema = new TypedSimpleSchema({})
|
||||
.extend(ComputedOnlyAttributeSchema)
|
||||
.extend(AttributeSchema);
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS';
|
||||
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema';
|
||||
import { Expand, InferType } from '/imports/api/utility/TypedSimpleSchema';
|
||||
import { Expand, InferType, TypedSimpleSchema } from '/imports/api/utility/TypedSimpleSchema';
|
||||
|
||||
const BranchSchema = createPropertySchema({
|
||||
branchType: {
|
||||
@@ -53,12 +52,12 @@ const ComputedOnlyBranchSchema = createPropertySchema({
|
||||
},
|
||||
});
|
||||
|
||||
const ComputedBranchSchema = new SimpleSchema({})
|
||||
const ComputedBranchSchema = new TypedSimpleSchema({})
|
||||
.extend(BranchSchema)
|
||||
.extend(ComputedOnlyBranchSchema);
|
||||
|
||||
export type Branch = InferType<typeof BranchSchema>;
|
||||
export type ComputedOnlyBranch = InferType<typeof ComputedOnlyBranchSchema>;
|
||||
export type ComputedBranch = Expand<InferType<typeof BranchSchema> & InferType<typeof ComputedOnlyBranchSchema>>;
|
||||
export type ComputedBranch = Expand<InferType<typeof BranchSchema> & InferType<typeof ComputedBranchSchema>>;
|
||||
|
||||
export { BranchSchema, ComputedBranchSchema, ComputedOnlyBranchSchema }
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS';
|
||||
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema';
|
||||
import { Expand, InferType, TypedSimpleSchema } from '/imports/api/utility/TypedSimpleSchema';
|
||||
|
||||
let BuffSchema = createPropertySchema({
|
||||
const BuffSchema = createPropertySchema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.name,
|
||||
},
|
||||
description: {
|
||||
type: 'inlineCalculationFieldToCompute',
|
||||
type: 'inlineCalculationFieldToCompute' as const,
|
||||
optional: true,
|
||||
},
|
||||
hideRemoveButton: {
|
||||
@@ -41,14 +42,14 @@ let BuffSchema = createPropertySchema({
|
||||
},
|
||||
});
|
||||
|
||||
let ComputedOnlyBuffSchema = createPropertySchema({
|
||||
const ComputedOnlyBuffSchema = createPropertySchema({
|
||||
description: {
|
||||
type: 'computedOnlyInlineCalculationField',
|
||||
type: 'computedOnlyInlineCalculationField' as const,
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.description,
|
||||
},
|
||||
duration: {
|
||||
type: 'computedOnlyField',
|
||||
type: 'computedOnlyField' as const,
|
||||
optional: true,
|
||||
},
|
||||
durationSpent: {
|
||||
@@ -74,8 +75,12 @@ let ComputedOnlyBuffSchema = createPropertySchema({
|
||||
},
|
||||
});
|
||||
|
||||
const ComputedBuffSchema = new SimpleSchema()
|
||||
const ComputedBuffSchema = new TypedSimpleSchema({})
|
||||
.extend(BuffSchema)
|
||||
.extend(ComputedOnlyBuffSchema);
|
||||
|
||||
export type Buff = InferType<typeof BuffSchema>;
|
||||
export type ComputedOnlyBuff = InferType<typeof ComputedOnlyBuffSchema>;
|
||||
export type ComputedBuff = Expand<InferType<typeof BuffSchema> & InferType<typeof ComputedOnlyBuffSchema>>;
|
||||
|
||||
export { BuffSchema, ComputedOnlyBuffSchema, ComputedBuffSchema };
|
||||
|
||||
115
app/imports/api/properties/Property.type.ts
Normal file
115
app/imports/api/properties/Property.type.ts
Normal file
@@ -0,0 +1,115 @@
|
||||
import { Attribute, ComputedAttribute, ComputedOnlyAttribute } from './Attributes';
|
||||
import { Branch, ComputedBranch, ComputedOnlyBranch } from './Branches';
|
||||
import { Buff, ComputedBuff, ComputedOnlyBuff } from './Buffs';
|
||||
import { Class, ComputedClass, ComputedOnlyClass } from './Classes';
|
||||
import { Constant, ComputedConstant, ComputedOnlyConstant } from './Constants';
|
||||
import { Container, ComputedContainer, ComputedOnlyContainer } from './Containers';
|
||||
import { CreatureTemplate, ComputedCreatureTemplate, ComputedOnlyCreatureTemplate } from './CreatureTemplates';
|
||||
import { Damage, ComputedDamage, ComputedOnlyDamage } from './Damages';
|
||||
import { DamageMultiplier, ComputedDamageMultiplier, ComputedOnlyDamageMultiplier } from './DamageMultipliers';
|
||||
import { Effect, ComputedEffect, ComputedOnlyEffect } from './Effects';
|
||||
import { Feature, ComputedFeature, ComputedOnlyFeature } from './Features';
|
||||
import { Folder, ComputedFolder, ComputedOnlyFolder } from './Folders';
|
||||
import { Item, ComputedItem, ComputedOnlyItem } from './Items';
|
||||
import { Note, ComputedNote, ComputedOnlyNote } from './Notes';
|
||||
import { PointBuy, ComputedPointBuy, ComputedOnlyPointBuy } from './PointBuys';
|
||||
import { Proficiency, ComputedProficiency, ComputedOnlyProficiency } from './Proficiencies';
|
||||
import { Reference, ComputedReference, ComputedOnlyReference } from './References';
|
||||
import { Roll, ComputedRoll, ComputedOnlyRoll } from './Rolls';
|
||||
import { SavingThrow, ComputedSavingThrow, ComputedOnlySavingThrow } from './SavingThrows';
|
||||
import { Skill, ComputedSkill, ComputedOnlySkill } from './Skills';
|
||||
import { Slot, ComputedSlot, ComputedOnlySlot } from './Slots';
|
||||
import { SpellList, ComputedSpellList, ComputedOnlySpellList } from './SpellLists';
|
||||
import { Spell, ComputedSpell, ComputedOnlySpell } from './Spells';
|
||||
import { Toggle, ComputedToggle, ComputedOnlyToggle } from './Toggles';
|
||||
import { Trigger, ComputedTrigger, ComputedOnlyTrigger } from './Triggers';
|
||||
|
||||
export type PropertyTypeMap = {
|
||||
'attribute': Attribute,
|
||||
'branch': Branch,
|
||||
'buff': Buff,
|
||||
'class': Class,
|
||||
'constant': Constant,
|
||||
'container': Container,
|
||||
'creatureTemplate': CreatureTemplate,
|
||||
'damage': Damage,
|
||||
'damageMultiplier': DamageMultiplier,
|
||||
'effect': Effect,
|
||||
'feature': Feature,
|
||||
'folder': Folder,
|
||||
'item': Item,
|
||||
'note': Note,
|
||||
'pointBuy': PointBuy,
|
||||
'proficiency': Proficiency,
|
||||
'reference': Reference,
|
||||
'roll': Roll,
|
||||
'savingThrow': SavingThrow,
|
||||
'skill': Skill,
|
||||
'slot': Slot,
|
||||
'spellList': SpellList,
|
||||
'spell': Spell,
|
||||
'toggle': Toggle,
|
||||
'trigger': Trigger,
|
||||
}
|
||||
|
||||
export type Property<T extends keyof PropertyTypeMap> = PropertyTypeMap[T]
|
||||
|
||||
export type ComputedPropertyTypeMap = {
|
||||
'attribute': ComputedAttribute,
|
||||
'branch': ComputedBranch,
|
||||
'buff': ComputedBuff,
|
||||
'class': ComputedClass,
|
||||
'constant': ComputedConstant,
|
||||
'container': ComputedContainer,
|
||||
'creatureTemplate': ComputedCreatureTemplate,
|
||||
'damage': ComputedDamage,
|
||||
'damageMultiplier': ComputedDamageMultiplier,
|
||||
'effect': ComputedEffect,
|
||||
'feature': ComputedFeature,
|
||||
'folder': ComputedFolder,
|
||||
'item': ComputedItem,
|
||||
'note': ComputedNote,
|
||||
'pointBuy': ComputedPointBuy,
|
||||
'proficiency': ComputedProficiency,
|
||||
'reference': ComputedReference,
|
||||
'roll': ComputedRoll,
|
||||
'savingThrow': ComputedSavingThrow,
|
||||
'skill': ComputedSkill,
|
||||
'slot': ComputedSlot,
|
||||
'spellList': ComputedSpellList,
|
||||
'spell': ComputedSpell,
|
||||
'toggle': ComputedToggle,
|
||||
'trigger': ComputedTrigger,
|
||||
}
|
||||
|
||||
export type ComputedProperty<T extends keyof ComputedPropertyTypeMap> = ComputedPropertyTypeMap[T]
|
||||
|
||||
export type ComputedOnlyPropertyTypeMap = {
|
||||
'attribute': ComputedOnlyAttribute,
|
||||
'branch': ComputedOnlyBranch,
|
||||
'buff': ComputedOnlyBuff,
|
||||
'class': ComputedOnlyClass,
|
||||
'constant': ComputedOnlyConstant,
|
||||
'container': ComputedOnlyContainer,
|
||||
'creatureTemplate': ComputedOnlyCreatureTemplate,
|
||||
'damage': ComputedOnlyDamage,
|
||||
'damageMultiplier': ComputedOnlyDamageMultiplier,
|
||||
'effect': ComputedOnlyEffect,
|
||||
'feature': ComputedOnlyFeature,
|
||||
'folder': ComputedOnlyFolder,
|
||||
'item': ComputedOnlyItem,
|
||||
'note': ComputedOnlyNote,
|
||||
'pointBuy': ComputedOnlyPointBuy,
|
||||
'proficiency': ComputedOnlyProficiency,
|
||||
'reference': ComputedOnlyReference,
|
||||
'roll': ComputedOnlyRoll,
|
||||
'savingThrow': ComputedOnlySavingThrow,
|
||||
'skill': ComputedOnlySkill,
|
||||
'slot': ComputedOnlySlot,
|
||||
'spellList': ComputedOnlySpellList,
|
||||
'spell': ComputedOnlySpell,
|
||||
'toggle': ComputedOnlyToggle,
|
||||
'trigger': ComputedOnlyTrigger,
|
||||
}
|
||||
|
||||
export type ComputedOnlyProperty<T extends keyof ComputedOnlyPropertyTypeMap> = ComputedOnlyPropertyTypeMap[T]
|
||||
@@ -1,5 +1,5 @@
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS';
|
||||
import { TypedSimpleSchema } from 'imports/api/utility/TypedSimpleSchema';
|
||||
import { TypedSimpleSchema } from '/imports/api/utility/TypedSimpleSchema';
|
||||
|
||||
const ErrorSchema = new TypedSimpleSchema({
|
||||
message: {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS';
|
||||
import { TypedSimpleSchema } from 'imports/api/utility/TypedSimpleSchema';
|
||||
import { TypedSimpleSchema } from '/imports/api/utility/TypedSimpleSchema';
|
||||
|
||||
const TagTargetingSchema = new TypedSimpleSchema({
|
||||
// True when targeting by tags instead of stats
|
||||
|
||||
Reference in New Issue
Block a user