Skip to content

Commit

Permalink
closes #18
Browse files Browse the repository at this point in the history
  • Loading branch information
seiyria committed Aug 15, 2024
1 parent 6d49a7a commit b5319a4
Show file tree
Hide file tree
Showing 24 changed files with 638 additions and 12 deletions.
7 changes: 4 additions & 3 deletions src/app/helpers/export/item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ function fillInItemProperties(itemData: IItemDefinition) {
}

export function formatItems(items: IItemDefinition[]): IItemDefinition[] {
return items.map((item: any) => {
return structuredClone(items).map((item: any) => {
if (!item.sellValue) delete item.sellValue;
if (!item.maxUpgrades) delete item.maxUpgrades;
if (!item.secondaryType) delete item.secondaryType;
Expand All @@ -193,8 +193,9 @@ export function formatItems(items: IItemDefinition[]): IItemDefinition[] {
if (item.cosmetic && !item.cosmetic.name) delete item.cosmetic;
if (item.containedItems && !item.containedItems.length)
delete item.containedItems;
if (!item.trait.name) delete item.trait;
if (item.randomTrait.name.length === 0) delete item.randomTrait;
if (item.trait && !item.trait.name) delete item.trait;
if (item.randomTrait && item.randomTrait.name.length === 0)
delete item.randomTrait;
if (item.useEffect && !item.useEffect.name) delete item.useEffect;
if (item.strikeEffect && !item.strikeEffect.name) delete item.strikeEffect;
if (item.breakEffect && !item.breakEffect.name) delete item.breakEffect;
Expand Down
2 changes: 1 addition & 1 deletion src/app/helpers/export/npc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ function fillInNPCProperties(npc: INPCDefinition): INPCDefinition {
}

export function formatNPCs(npcs: INPCDefinition[]): INPCDefinition[] {
return npcs.map((npc: any) => {
return structuredClone(npcs).map((npc: any) => {
delete npc.hp;
delete npc.mp;
delete npc.giveXp;
Expand Down
95 changes: 95 additions & 0 deletions src/app/helpers/schemas/_helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { difference, get, isNumber, isUndefined } from 'lodash';
import { HasIdentification, Schema } from '../../../interfaces';

export function isInteger(num: any): boolean {
return isNumber(num) && Math.floor(num) === num;
}

export function isCosmetic(cos: any): boolean {
return !!cos.name;
}

export function isRequirement(req: any): boolean {
return !!(req.level || req.baseClass || req.alignment || req.quest);
}

export function isSuccor(suc: any): boolean {
return suc.map && isInteger(suc.x) && isInteger(suc.y);
}

export function isOptionalRollable(rol: any): boolean {
if (!rol || rol.length === 0) return true;

return !!(rol[0].chance && rol[0].result);
}

export function isRollable(rol: any): boolean {
return !!(rol.length > 0 && rol[0].chance && rol[0].result);
}

export function isTrait(trait: any): boolean {
return !!(trait.name && isNumber(trait.level));
}

export function isIntegerBetween(min: any, max: any): (val: any) => boolean {
return (num) => num >= min && num <= max && isInteger(num);
}

export function isEffect(eff: any): boolean {
return eff.name && isNumber(eff.potency);
}

export function isEncrust(enc: any): boolean {
return !!(enc.stats || enc.equipEffect || enc.strikeEffect);
}

export function isDropPool(pool: any): boolean {
return (
isInteger(pool.choose.min) &&
isInteger(pool.choose.max) &&
isRollable(pool.items)
);
}

export function isRandomNumber(num: any) {
return isInteger(num.min) && isInteger(num.max);
}

export function validateSchema<T extends HasIdentification>(
label: string,
obj: T,
schema: Schema
): string[] {
const errors: string[] = [];

schema.forEach(([prop, required, validator]) => {
const value = get(obj, prop);

if (isUndefined(value)) {
if (required)
errors.push(
`Property '${prop}' is required, but absent in '${label}'.`
);
return;
}

if (!validator(value))
errors.push(
`Property '${prop}' does not pass validation for '${label}'.`
);
});

const basePropsSchema = schema
.filter((x) => !x[0].includes('.'))
.map((x) => x[0]);
const baseObjProps = Object.keys(obj).filter((x) => !['_id'].includes(x));

const diff = difference(baseObjProps, basePropsSchema);
if (diff.length > 0) {
errors.push(
`Properties ${diff.join(',')} are in '${label}' but not in schema.`
);
}

return errors;
}
23 changes: 23 additions & 0 deletions src/app/helpers/schemas/dialog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { isArray, isNumber, isObject, isString } from 'lodash';
import { Schema } from '../../../interfaces';
import { isRandomNumber } from './_helpers';

export const dialogSchema: Schema = [
['tag', true, isString],

['name', false, isString],
['affiliation', false, isString],
['allegiance', false, isString],
['alignment', false, isString],
['hostility', false, isString],
['level', false, isNumber],
['hp', false, isRandomNumber],
['mp', false, isRandomNumber],

['otherStats', false, isObject],
['usableSkills', false, isArray],
['items', false, isObject],
['items.equipment', false, isObject],
['dialog', false, isObject],
['behaviors', false, isArray],
];
9 changes: 9 additions & 0 deletions src/app/helpers/schemas/droptable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { isArray, isBoolean, isString } from 'lodash';
import { Schema } from '../../../interfaces';

export const droptableSchema: Schema = [
['mapName', false, isString],
['regionName', false, isString],
['isGlobal', false, isBoolean],
['drops', true, isArray],
];
7 changes: 7 additions & 0 deletions src/app/helpers/schemas/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export * from './dialog';
export * from './droptable';
export * from './item';
export * from './npc';
export * from './quest';
export * from './recipe';
export * from './spawner';
120 changes: 120 additions & 0 deletions src/app/helpers/schemas/item.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { isArray, isBoolean, isInteger, isObject, isString } from 'lodash';
import { Schema } from '../../../interfaces';
import {
isCosmetic,
isEffect,
isEncrust,
isIntegerBetween,
isRequirement,
isRollable,
isSuccor,
isTrait,
} from './_helpers';

export const itemSchema: Schema = [
['name', true, isString],
['sprite', true, isInteger],
['animation', false, isInteger],
['value', true, isInteger],
['desc', true, isString],
['itemClass', true, isString],
['type', true, isString],

['binds', false, isBoolean],
['tellsBind', false, isBoolean],
['extendedDesc', false, isString],
['isBeltable', false, isBoolean],
['isSackable', false, isBoolean],
['isHeavy', false, isBoolean],
['secondaryType', false, isString],
['stats', false, isObject],
['maxUpgrades', false, isInteger],
['canUpgradeWith', false, isBoolean],
['recipe', false, isString],

['cosmetic', false, isCosmetic],
['cosmetic.isPermanent', false, isBoolean],
['cosmetic.name', false, isString],

['requirements', false, isRequirement],
['requirements.alignment', false, isString],
['requirements.baseClass', false, isString],
['requirements.quest', false, isString],
['requirements.level', false, isInteger],

['equipEffect', false, isEffect],
['equipEffect.name', false, isString],
['equipEffect.potency', false, isInteger],
['equipEffect.duration', false, isInteger],
['equipEffect.range', false, isIntegerBetween(0, 5)],

['strikeEffect', false, isEffect],
['strikeEffect.name', false, isString],
['strikeEffect.potency', false, isInteger],
['strikeEffect.chance', false, isIntegerBetween(0, 100)],
['strikeEffect.duration', false, isInteger],
['strikeEffect.range', false, isIntegerBetween(0, 5)],

['useEffect', false, isEffect],
['useEffect.name', false, isString],
['useEffect.potency', false, isInteger],
['useEffect.canApply', false, isBoolean],
['useEffect.duration', false, isInteger],
['useEffect.uses', false, isInteger],
['useEffect.range', false, isIntegerBetween(0, 5)],

['trapEffect', false, isEffect],
['trapEffect.name', false, isString],
['trapEffect.potency', false, isInteger],
['trapEffect.duration', false, isInteger],
['trapEffect.uses', false, isInteger],
['trapEffect.range', false, isIntegerBetween(0, 5)],

['breakEffect', false, isEffect],
['breakEffect.name', false, isString],
['breakEffect.potency', false, isInteger],

['effect.extra', false, isObject],

['encrustGive', false, isEncrust],

['tier', false, isInteger],
['destroyOnDrop', false, isBoolean],
['twoHanded', false, isBoolean],
['canShoot', false, isBoolean],
['attackRange', false, isIntegerBetween(0, 5)],
['offhand', false, isBoolean],
['proneChance', false, isIntegerBetween(0, 100)],
['returnsOnThrow', false, isBoolean],

['shots', false, isInteger],
['damageClass', false, isString],

['trapUses', false, isInteger],

['containedItems', false, isRollable],

['succorInfo', false, isSuccor],
['succorInfo.map', false, isString],
['succorInfo.x', false, isInteger],
['succorInfo.y', false, isInteger],

['trait', false, isTrait],
['trait.name', false, isString],
['trait.level', false, isInteger],

['bookFindablePages', false, isInteger],
['bookItemFilter', false, isString],
['bookPage', false, isInteger],
['bookCurrentPage', false, isInteger],
['bookPages', false, isArray],

['ounces', false, isInteger],
['notUsableAfterHours', false, isInteger],

['quality', false, isInteger],
['sellValue', false, isInteger],

['randomStats', false, isObject],
['randomTrait', false, isObject],
];
59 changes: 59 additions & 0 deletions src/app/helpers/schemas/npc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { isArray, isBoolean, isInteger, isObject, isString } from 'lodash';
import { Schema } from '../../../interfaces';
import {
isDropPool,
isOptionalRollable,
isRandomNumber,
isRollable,
} from './_helpers';

export const npcSchema: Schema = [
['npcId', true, isString],
['sprite', true, isArray],
['cr', true, isInteger],
['hp', true, isRandomNumber],
['mp', false, isRandomNumber],
['giveXp', true, isRandomNumber],
['gold', true, isRandomNumber],
['skillOnKill', true, isInteger],

['name', false, isArray],
['alignment', false, isString],
['affiliation', false, isString],
['allegiance', false, isString],
['allegianceReputation', false, isObject],
['aquaticOnly', false, isBoolean],
['avoidWater', false, isBoolean],
['baseClass', false, isString],
['baseEffects', false, isArray],
['copyDrops', false, isRollable],
['dropPool', false, isDropPool],
['drops', false, isRollable],
['forceAI', false, isString],
['items', false, isObject],
['items.equipment', false, isObject],
['items.sack', false, isOptionalRollable],

['level', true, isInteger],
['hpMult', false, isInteger],

['monsterClass', false, isString],
['monsterGroup', false, isString],
['hostility', false, isString],
['noCorpseDrop', false, isBoolean],
['noItemDrop', false, isBoolean],
['repMod', false, isArray],

['stats', true, isObject],
['skills', true, isObject],

['summonStatModifiers', false, isObject],
['summonSkillModifiers', false, isObject],

['tanSkillRequired', false, isInteger],
['tansFor', false, isString],
['traitLevels', false, isObject],
['triggers', false, isObject],

['usableSkills', false, isArray],
];
30 changes: 30 additions & 0 deletions src/app/helpers/schemas/quest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { isArray, isBoolean, isNumber, isObject, isString } from 'lodash';
import { Schema } from '../../../interfaces';

export const questSchema: Schema = [
['name', true, isString],
['giver', true, isString],
['desc', true, isString],

['isDaily', false, isBoolean],
['isRepeatable', false, isBoolean],

['messages', false, isObject],
['messages.kill', false, isString],
['messages.complete', false, isString],
['messages.incomplete', false, isString],
['messages.alreadyHas', false, isString],
['messages.permComplete', false, isString],

['requirements', false, isObject],
['requirements.type', false, isString],
['requirements.npcIds', false, isArray],
['requirements.item', false, isString],
['requirements.fromHands', false, isBoolean],
['requirements.fromSack', false, isBoolean],
['requirements.killsRequired', false, isNumber],
['requirements.countRequired', false, isNumber],
['requirements.itemssRequired', false, isNumber],

['rewards', false, isArray],
];
Loading

0 comments on commit b5319a4

Please sign in to comment.