From 662fc91e173b7601e4b78dfb68fd2d2aaaca2a59 Mon Sep 17 00:00:00 2001 From: Thaum Rystra Date: Sat, 25 Aug 2018 20:19:17 +0200 Subject: [PATCH] New characters get the appropriate attributes/skills/damageMultipliers --- app/Model/Creature/Attributes.js | 1 + app/Model/Creature/CharacterComputation.js | 4 +- app/Model/Creature/Characters.js | 88 ++++++++++++++++- app/Model/Creature/DamageMultipliers.js | 1 + app/Model/Creature/Skills.js | 6 ++ .../{ => subSchemas}/LibraryAttacks.js | 0 .../{ => subSchemas}/LibraryEffects.js | 0 app/lib/constants/defaultCharacterStats.js | 96 +++++++++++++++++++ app/server/publications/singleCharacter.js | 3 + 9 files changed, 194 insertions(+), 5 deletions(-) rename app/Model/Library/{ => subSchemas}/LibraryAttacks.js (100%) rename app/Model/Library/{ => subSchemas}/LibraryEffects.js (100%) create mode 100644 app/lib/constants/defaultCharacterStats.js diff --git a/app/Model/Creature/Attributes.js b/app/Model/Creature/Attributes.js index 9885564d..26bf8de8 100644 --- a/app/Model/Creature/Attributes.js +++ b/app/Model/Creature/Attributes.js @@ -36,6 +36,7 @@ Schemas.Attribute = new SimpleSchema({ value: { type: Number, decimal: true, + defaultValue: 0, }, adjustment: { type: Number, diff --git a/app/Model/Creature/CharacterComputation.js b/app/Model/Creature/CharacterComputation.js index ad9f00a9..a41055b5 100644 --- a/app/Model/Creature/CharacterComputation.js +++ b/app/Model/Creature/CharacterComputation.js @@ -1,7 +1,5 @@ // TODO recalculate carried weight method -// TODO Add attribute, skill, damageMultiplier and bundle library models -// Bundle libraries should support races, classes, and rulesets -// TODO Add monster library +// TODO actually write the recomputed character to the database import { ValidatedMethod } from 'meteor/mdg:validated-method'; diff --git a/app/Model/Creature/Characters.js b/app/Model/Creature/Characters.js index 263ff862..c2b2db37 100644 --- a/app/Model/Creature/Characters.js +++ b/app/Model/Creature/Characters.js @@ -1,3 +1,5 @@ +import { ValidatedMethod } from 'meteor/mdg:validated-method'; + //set up the collection for characters Characters = new Mongo.Collection("characters"); @@ -17,8 +19,9 @@ Schemas.Character = new SimpleSchema({ backstory: {type: String, defaultValue: "", trim: false, optional: true}, //mechanics - deathSave: {type: Schemas.DeathSave}, - xp: {type: Number, defaultValue: 0}, + deathSave: {type: Schemas.DeathSave}, + xp: {type: Number, defaultValue: 0}, + carriedWeight: {type: Number, defaultValue: 0}, //permissions party: {type: String, regEx: SimpleSchema.RegEx.Id, optional: true}, @@ -68,6 +71,87 @@ Characters.calculate = { }, }; +const insertCharacterMethod = new ValidatedMethod({ + + name: "Characters.methods.insert", // DDP method name + + validate: new SimpleSchema({ + name: { + type: String, + optional: true, + }, + }).validator(), + + run({name}) { + if (!this.userId) { + throw new Meteor.Error("Characters.methods.insert.denied", + "You need to be logged in to insert a character"); + } + + // Create the character document + Characters.insert({name, owner: this.userId}); + //Add all the required attributes to it + addDefaultAttributes(charId); + }, + +}); + +const addDefaultAttributes function(charId){ + const stats = DEFAULT_CHARACTER_STATS; + let order = 0; + const baseParent = { + collection: "Characters", + id: charId, + group: "default", + }; + let name, variableName, parent, attribute, skill, ability, dm; + for (type in stats.attributes){ + for (let i in stats.attributes[type]){ + attribute = stats.attributes[type][i]; + if (_.isString(attribute)){ + name = attribute; + variableName = attribute.toLowerCase(); + } else { + name = attribute.name; + variableName = attribute.variableName; + } + parent = _.clone(baseParent); + // TODO Inserting documets in a for-loop is slow + // conider using the raw collection to bulk insert + // Including a callback makes the operation async, 3x faster + Attributes.insert({ + charId, name, variableName, order, type, parent + }, function(error, _id){})); + order++; + } + } + order = 0; + for (type in stats.skills){ + for (let i in stats.skills[type]){ + skill = stats.skills[type][i]; + Skills.insert({ + charId, + type, + order, + name: skill.name, + variableName: skill.variableName, + ability: skill.ability, + parent: _.clone(baseParent), + }, function(error, _id){})); + order++; + } + } + for (let i in stats.damageMultipliers){ + dm = stats.damageMultipliers[i]; + DamageMultipliers.insert({ + charId, + name: dm.name, + variableName = dm.variableName, + parent: _.clone(baseParent), + }, function(error, _id){})); + } +}; + //clean up all data related to that character before removing it if (Meteor.isServer){ Characters.after.remove(function(userId, character) { diff --git a/app/Model/Creature/DamageMultipliers.js b/app/Model/Creature/DamageMultipliers.js index 41b0ab31..dd4adf18 100644 --- a/app/Model/Creature/DamageMultipliers.js +++ b/app/Model/Creature/DamageMultipliers.js @@ -20,6 +20,7 @@ Schemas.DamageMultiplier = new SimpleSchema({ value: { type: Number, decimal: true, + defaultValue: 1, }, parent: { type: Schemas.Parent diff --git a/app/Model/Creature/Skills.js b/app/Model/Creature/Skills.js index 42bb8b8f..672deeed 100644 --- a/app/Model/Creature/Skills.js +++ b/app/Model/Creature/Skills.js @@ -34,9 +34,14 @@ Schemas.Skill = new SimpleSchema({ "utility", //not displayed anywhere ], }, + // Skills need to store their order to keep the sheet consistent + order: { + type: Number, + }, value: { type: Number, decimal: true, + defaultValue: 0, }, advantage: { type: Number, @@ -50,6 +55,7 @@ Schemas.Skill = new SimpleSchema({ proficiency: { type: Number, allowedValues: [0, 0.5, 1, 2], + defaultValue: 0, }, conditionalBenefits: { type: Number, diff --git a/app/Model/Library/LibraryAttacks.js b/app/Model/Library/subSchemas/LibraryAttacks.js similarity index 100% rename from app/Model/Library/LibraryAttacks.js rename to app/Model/Library/subSchemas/LibraryAttacks.js diff --git a/app/Model/Library/LibraryEffects.js b/app/Model/Library/subSchemas/LibraryEffects.js similarity index 100% rename from app/Model/Library/LibraryEffects.js rename to app/Model/Library/subSchemas/LibraryEffects.js diff --git a/app/lib/constants/defaultCharacterStats.js b/app/lib/constants/defaultCharacterStats.js new file mode 100644 index 00000000..3086b521 --- /dev/null +++ b/app/lib/constants/defaultCharacterStats.js @@ -0,0 +1,96 @@ +DEFAULT_CHARACTER_STATS = { + "attributes": { + "ability": [ + "Strength", "Dexterity", "Constitution", "Intelligence", "Wisdom", "Charisma" + ], + "stat": [ + "Speed", + {"name": "Armor Class", "variableName": "armor"}, + ], + "hitDice": [ + {"name": "d6 Hit Dice", "variableName": "d6HitDice"}, + {"name": "d8 Hit Dice", "variableName": "d8HitDice"}, + {"name": "d10 Hit Dice", "variableName": "d10HitDice"}, + {"name": "d12 Hit Dice", "variableName": "d12HitDice"}, + ], + "healthBar": [ + {"name": "Hit Points", "variableName": "hitPoints"}, + {"name": "Temporary Hit Points", "variableName": "tempHitPoints"}, + ], + "resource": [ + "Ki", "Rages", + {"name": "Sourcery Points", "variableName": "sorceryPoints"}, + {"name": "Superiority Dice", "variableName": "superiorityDice"}, + {"name": "Expertise Dice", "variableName": "expertiseDice"}, + ], + "spellSlot": [ + {"name": "Level 1 Spell Slots", "variableName": "level1SpellSlots"}, + {"name": "Level 2 Spell Slots", "variableName": "level2SpellSlots"}, + {"name": "Level 3 Spell Slots", "variableName": "level3SpellSlots"}, + {"name": "Level 4 Spell Slots", "variableName": "level4SpellSlots"}, + {"name": "Level 5 Spell Slots", "variableName": "level5SpellSlots"}, + {"name": "Level 6 Spell Slots", "variableName": "level6SpellSlots"}, + {"name": "Level 7 Spell Slots", "variableName": "level7SpellSlots"}, + {"name": "Level 8 Spell Slots", "variableName": "level8SpellSlots"}, + {"name": "Level 9 Spell Slots", "variableName": "level9SpellSlots"}, + ], + "utility": [ + {"name": "Carry Capacity Multiplier", "variableName": "carryMultiplier"}, + {"name": "Rage Damage", "variableName": "rageDamage"}, + ], + }, + + "skills": { + "skill": [ + {"name": "Acrobatics", "variableName": "acrobatics", "ability": "dexterity"}, + {"name": "Animal Handling", "variableName": "animalHandling", "ability": "wisdom"}, + {"name": "Arcana", "variableName": "arcana", "ability": "intelligence"}, + {"name": "Athletics", "variableName": "athletics", "ability": "strength"}, + {"name": "Deception", "variableName": "deception", "ability": "charisma"}, + {"name": "History", "variableName": "history", "ability": "intelligence"}, + {"name": "Insight", "variableName": "insight", "ability": "wisdom"}, + {"name": "Intimidation", "variableName": "intimidation", "ability": "charisma"}, + {"name": "Investigation", "variableName": "investigation", "ability": "intelligence"}, + {"name": "Medicine", "variableName": "medicine", "ability": "wisdom"}, + {"name": "Nature", "variableName": "nature", "ability": "intelligence"}, + {"name": "Perception", "variableName": "perception", "ability": "wisdom"}, + {"name": "Performance", "variableName": "performance", "ability": "charisma"}, + {"name": "Persuasion", "variableName": "persuasion", "ability": "charisma"}, + {"name": "Religion", "variableName": "religion", "ability": "intelligence"}, + {"name": "Sleight of Hand", "variableName": "sleightOfHand", "ability": "dexterity"}, + {"name": "Stealth", "variableName": "stealth", "ability": "dexterity"}, + {"name": "Survival", "variableName": "survival", "ability": "wisdom"}, + ], + "save": [ + {"name": "Strength Save", "variableName": "strengthSave", "ability": "strength"}, + {"name": "Dexterity Save", "variableName": "dexteritySave", "ability": "dexterity"}, + {"name": "Constitution Save", "variableName": "constitutionSave", "ability": "constitution"}, + {"name": "Intelligence Save", "variableName": "intelligenceSave", "ability": "intelligence"}, + {"name": "Wisdom Save", "variableName": "wisdomSave", "ability": "wisdom"}, + {"name": "Charisma Save", "variableName": "charismaSave", "ability": "charisma"}, + ], + "stat": [ + {"name": "Proficiency Bonus", "variableName": "proficiencyBonus"}, + {"name": "initiative", "variableName": "initiative"}, + ], + "utility": [ + {"name": "Dexterity Armor", "variableName": "dexterityArmor", "ability": "dexterity"}, + ], + }, + + "damageMultipliers": [ + {"name": "Acid Multiplier", "variableName":"acidMultiplier"}, + {"name": "Bludgeoning Multiplier", "variableName":"bludgeoningMultiplier"}, + {"name": "Cold Multiplier", "variableName":"coldMultiplier"}, + {"name": "Fire Multiplier", "variableName":"fireMultiplier"}, + {"name": "Force Multiplier", "variableName":"forceMultiplier"}, + {"name": "Lightning Multiplier", "variableName":"lightningMultiplier"}, + {"name": "Necrotic Multiplier", "variableName":"necroticMultiplier"}, + {"name": "Piercing Multiplier", "variableName":"piercingMultiplier"}, + {"name": "Poison Multiplier", "variableName":"poisonMultiplier"}, + {"name": "Psychic Multiplier", "variableName":"psychicMultiplier"}, + {"name": "Radiant Multiplier", "variableName":"radiantMultiplier"}, + {"name": "Slashing Multiplier", "variableName":"slashingMultiplier"}, + {"name": "Thunder Multiplier", "variableName":"thunderMultiplier"}, + ] +} diff --git a/app/server/publications/singleCharacter.js b/app/server/publications/singleCharacter.js index 777a2ecb..17d0c8af 100644 --- a/app/server/publications/singleCharacter.js +++ b/app/server/publications/singleCharacter.js @@ -15,16 +15,19 @@ Meteor.publish("singleCharacter", function(characterId){ //get all the assets for this character including soft deleted ones Actions.find ({charId: characterId}, {removed: true}), Attacks.find ({charId: characterId}, {removed: true}), + Attributes.find ({charId: characterId}, {removed: true}), Buffs.find ({charId: characterId}, {removed: true}), Classes.find ({charId: characterId}, {removed: true}), Conditions.find ({charId: characterId}, {removed: true}), Containers.find ({charId: characterId}, {removed: true}), CustomBuffs.find ({charId: characterId}, {removed: true}), + DamageMultipliers.find ({charId: characterId}, {removed: true}), Effects.find ({charId: characterId}, {removed: true}), Experiences.find ({charId: characterId}, {removed: true}), Features.find ({charId: characterId}, {removed: true}), Items.find ({charId: characterId}, {removed: true}), Notes.find ({charId: characterId}, {removed: true}), + Skills.find ({charId: characterId}, {removed: true}), Spells.find ({charId: characterId}, {removed: true}), SpellLists.find ({charId: characterId}, {removed: true}), TemporaryHitPoints.find ({charId: characterId}, {removed: true}),