Refactored character insertion and continued work on creation dialog
This commit is contained in:
@@ -51,3 +51,4 @@ static-html
|
||||
aldeed:collection2@3.0.0
|
||||
aldeed:schema-index
|
||||
akryum:vue-component
|
||||
autopublish
|
||||
|
||||
@@ -12,6 +12,7 @@ akryum:vue-router2@0.2.2
|
||||
aldeed:collection2@3.0.0
|
||||
aldeed:schema-index@3.0.0
|
||||
allow-deny@1.1.0
|
||||
autopublish@1.0.7
|
||||
autoupdate@1.4.1
|
||||
babel-compiler@7.1.1
|
||||
babel-runtime@1.2.7
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import Effects from "/imports/api/creature/Effects.js"
|
||||
import Effects from "/imports/api/creature/properties/Effects.js"
|
||||
import deathSaveSchema from "/imports/api/creature/subSchemas/DeathSavesSchema.js"
|
||||
import ColorSchema from "/imports/api/creature/subSchemas/ColorSchema.js";
|
||||
import getDefaultCreatureDocs from "/imports/api/creature/CreatureDefaults.js";
|
||||
import getDefaultCreatureDocs from "/imports/api/creature/getDefaultCreatureDocs.js";
|
||||
|
||||
//set up the collection for creatures
|
||||
Creatures = new Mongo.Collection("creatures");
|
||||
@@ -62,55 +62,6 @@ let creatureSchema = new SimpleSchema({
|
||||
Creatures.attachSchema(creatureSchema);
|
||||
Creatures.attachSchema(ColorSchema);
|
||||
|
||||
Creatures.calculate = {
|
||||
xpLevel: function(charId){
|
||||
var xp = Creatures.calculate.experience(charId);
|
||||
for (var i = 0; i < 19; i++){
|
||||
if (xp < XP_TABLE[i]){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
if (xp > 355000) return 20;
|
||||
return 0;
|
||||
},
|
||||
};
|
||||
|
||||
const insertCharacter = new ValidatedMethod({
|
||||
|
||||
name: "Creatures.methods.insertCharacter", // DDP method name
|
||||
|
||||
validate: new SimpleSchema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
}).validator(),
|
||||
|
||||
run({name}) {
|
||||
if (!this.userId) {
|
||||
throw new Meteor.Error("Creatures.methods.insert.denied",
|
||||
"You need to be logged in to insert a creature");
|
||||
}
|
||||
|
||||
// Create the creature document
|
||||
let charId = Creatures.insert({name, owner: this.userId});
|
||||
this.unblock();
|
||||
//Add all the required attributes to it
|
||||
if (Meteor.isServer){
|
||||
addDefaultStats(charId);
|
||||
}
|
||||
return charId;
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
const addDefaultStats = function(charId){
|
||||
const defaultDocs = getDefaultCreatureDocs(charId);
|
||||
Attributes.rawCollection().insert(defaultDocs.attributes, {ordered: false});
|
||||
Skills.rawCollection().insert(defaultDocs.skills, {ordered: false});
|
||||
DamageMultipliers.rawCollection().insert(defaultDocs.damageMultipliers, {ordered: false});
|
||||
};
|
||||
|
||||
//clean up all data related to that creature before removing it
|
||||
if (Meteor.isServer){
|
||||
Creatures.after.remove(function(userId, creature) {
|
||||
@@ -145,91 +96,6 @@ if (Meteor.isServer){
|
||||
doc.settings.newUserExperience = true;
|
||||
}
|
||||
});
|
||||
|
||||
//give characters default items
|
||||
Creatures.after.insert(function(userId, char) {
|
||||
if (Meteor.isServer){
|
||||
var containerId = Containers.insert({
|
||||
name: "Coin Pouch",
|
||||
charId: char._id,
|
||||
isCarried: true,
|
||||
description: "A sturdy pouch for coins",
|
||||
color: "d",
|
||||
});
|
||||
Items.insert({
|
||||
name: "Gold piece",
|
||||
plural: "Gold pieces",
|
||||
charId: char._id,
|
||||
quantity: 0,
|
||||
weight: 0.02,
|
||||
value: 1,
|
||||
color: "n",
|
||||
parent: {
|
||||
id: containerId,
|
||||
collection: "Containers",
|
||||
},
|
||||
settings: {
|
||||
showIncrement: true,
|
||||
},
|
||||
});
|
||||
Items.insert({
|
||||
name: "Silver piece",
|
||||
plural: "Silver pieces",
|
||||
charId: char._id,
|
||||
quantity: 0,
|
||||
weight: 0.02,
|
||||
value: 0.1,
|
||||
color: "q",
|
||||
parent: {
|
||||
id: containerId,
|
||||
collection: "Containers",
|
||||
},
|
||||
settings: {
|
||||
showIncrement: true,
|
||||
},
|
||||
});
|
||||
Items.insert({
|
||||
name: "Copper piece",
|
||||
plural: "Copper pieces",
|
||||
charId: char._id,
|
||||
quantity: 0,
|
||||
weight: 0.02,
|
||||
value: 0.01,
|
||||
color: "s",
|
||||
parent: {
|
||||
id: containerId,
|
||||
collection: "Containers",
|
||||
},
|
||||
settings: {
|
||||
showIncrement: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Creatures.allow({
|
||||
insert: function(userId, doc) {
|
||||
// the user must be logged in, and the document must be owned by the user
|
||||
return (userId && doc.owner === userId);
|
||||
},
|
||||
update: function(userId, doc, fields, modifier) {
|
||||
// can only change documents you have write access to
|
||||
return doc.owner === userId ||
|
||||
_.contains(doc.writers, userId);
|
||||
},
|
||||
remove: function(userId, doc) {
|
||||
// can only remove your own documents
|
||||
return doc.owner === userId;
|
||||
},
|
||||
fetch: ["owner", "writers"],
|
||||
});
|
||||
|
||||
Creatures.deny({
|
||||
update: function(userId, docs, fields, modifier) {
|
||||
// can't change owners
|
||||
return _.contains(fields, "owner");
|
||||
}
|
||||
});
|
||||
|
||||
export default Creatures;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
export default {
|
||||
"attributes": [
|
||||
{"name": "Strength", "variableName": "strength", "baseValue": 10, "type": "ability"},
|
||||
{"name": "Dexterity", "variableName": "dexterity", "baseValue": 10, "type": "ability"},
|
||||
@@ -1,18 +1,34 @@
|
||||
import DEFAULT_CHARACTER_STATS from '/imports/api/creature/DEFAULT_CHARACTER_STATS.js';
|
||||
|
||||
getDefaultCreatureDocs = function(charId, creatureType = "pc"){
|
||||
let docs = {attributes: [], skills: [], damageMultipliers: [], effects: []};
|
||||
// Setup the docs object which will be returned
|
||||
let docs = {
|
||||
attributes: [],
|
||||
skills: [],
|
||||
damageMultipliers: [],
|
||||
effects: []
|
||||
};
|
||||
|
||||
// Get the default character stats
|
||||
let stats;
|
||||
if (creatureType === "pc"){
|
||||
const stats = DEFAULT_CHARACTER_STATS;
|
||||
stats = DEFAULT_CHARACTER_STATS;
|
||||
} else {
|
||||
stats = null;
|
||||
throw new Meteor.Error("Not implemented",
|
||||
"Default stats for non-player characters aren't implemented yet");
|
||||
}
|
||||
|
||||
// Setup the variables we'll need to share
|
||||
let order = 0;
|
||||
const baseParent = {
|
||||
collection: "Characters",
|
||||
id: charId,
|
||||
group: "default",
|
||||
};
|
||||
let name, variableName, parent, attribute, skill, ability, dm, type, baseValue;
|
||||
let name, variableName, parent, attribute, skill, dm, type, baseValue;
|
||||
|
||||
// Attributes
|
||||
for (type in stats.attributes){
|
||||
for (let i in stats.attributes[type]){
|
||||
attribute = stats.attributes[type][i];
|
||||
@@ -32,6 +48,8 @@ getDefaultCreatureDocs = function(charId, creatureType = "pc"){
|
||||
order++;
|
||||
}
|
||||
}
|
||||
|
||||
// Skills
|
||||
order = 0;
|
||||
for (type in stats.skills){
|
||||
for (let i in stats.skills[type]){
|
||||
@@ -49,26 +67,36 @@ getDefaultCreatureDocs = function(charId, creatureType = "pc"){
|
||||
order++;
|
||||
}
|
||||
}
|
||||
|
||||
// Damage Multipliers
|
||||
order = 0;
|
||||
for (let i in stats.damageMultipliers){
|
||||
dm = stats.damageMultipliers[i];
|
||||
docs.damageMultipliers.push({
|
||||
_id: Random.id,
|
||||
charId,
|
||||
order,
|
||||
name: dm.name,
|
||||
variableName: dm.variableName,
|
||||
parent: _.clone(baseParent),
|
||||
});
|
||||
order++;
|
||||
}
|
||||
|
||||
// Effects
|
||||
order = 0;
|
||||
for (let i in stats.effects){
|
||||
eff = stats.effects[i];
|
||||
docs.effects.push({
|
||||
_id: Random.id,
|
||||
charId,
|
||||
order,
|
||||
name: eff.name,
|
||||
stat: eff.stat,
|
||||
operation: eff.operation,
|
||||
calculation:eff.calculation,
|
||||
});
|
||||
order++;
|
||||
}
|
||||
return docs;
|
||||
}
|
||||
39
app/imports/api/creature/insertCreature.js
Normal file
39
app/imports/api/creature/insertCreature.js
Normal file
@@ -0,0 +1,39 @@
|
||||
import getDefaultCreatureDocs from '/imports/api/creature/getDefaultCreatureDocs.js';
|
||||
|
||||
const addDefaultStats = function(charId){
|
||||
const defaultDocs = getDefaultCreatureDocs(charId);
|
||||
Attributes.rawCollection().insert(getDefa.attributes, {ordered: false});
|
||||
Skills.rawCollection().insert(getDefa.skills, {ordered: false});
|
||||
DamageMultipliers.rawCollection().insert(getDefa.damageMultipliers, {ordered: false});
|
||||
};
|
||||
|
||||
const insertCreature = new ValidatedMethod({
|
||||
|
||||
name: "Creatures.methods.insertCharacter", // DDP method name
|
||||
|
||||
validate: new SimpleSchema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
}).validator(),
|
||||
|
||||
run({name}) {
|
||||
if (!this.userId) {
|
||||
throw new Meteor.Error("Creatures.methods.insert.denied",
|
||||
"You need to be logged in to insert a creature");
|
||||
}
|
||||
|
||||
// Create the creature document
|
||||
let charId = Creatures.insert({name, owner: this.userId});
|
||||
this.unblock();
|
||||
//Add all the required attributes to it
|
||||
if (Meteor.isServer){
|
||||
addDefaultStats(charId);
|
||||
}
|
||||
return charId;
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
export default insertCreature;
|
||||
@@ -1,5 +1,5 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import Attributes from "/imports/api/creature/Attributes.js";
|
||||
import Attributes from "/imports/api/creature/properties/Attributes.js";
|
||||
import ColorSchema from "/imports/api/creature/subSchemas/ColorSchema.js";
|
||||
import {makeParent} from "/imports/api/parenting.js";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Creatures from "/imports/api/creature/Creatures.js";
|
||||
import Parties from "/imports/api/campaign/Party.js";
|
||||
import Parties from '/imports/api/campaign/Parties.js';
|
||||
|
||||
Meteor.publish("characterList", function(){
|
||||
var userId = this.userId;
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import Characters from "/imports/api/creature/Creatures.js";
|
||||
import Actions from "/imports/api/creature/Actions.js";
|
||||
import Attacks from "/imports/api/creature/Attacks.js";
|
||||
import Attributes from "/imports/api/creature/Attributes.js";
|
||||
import Buffs from "/imports/api/creature/Buffs.js";
|
||||
import Classes from "/imports/api/creature/Classes.js";
|
||||
import Conditions from "/imports/api/creature/Conditions.js";
|
||||
import CustomBuffs from "/imports/api/creature/CustomBuffs.js";
|
||||
import DamageMultipliers from "/imports/api/creature/DamageMultipliers.js";
|
||||
import Effects from "/imports/api/creature/Effects.js";
|
||||
import Experiences from "/imports/api/creature/Experiences.js";
|
||||
import Features from "/imports/api/creature/Features.js";
|
||||
import Notes from "/imports/api/creature/Notes.js";
|
||||
import Skills from "/imports/api/creature/Skills.js";
|
||||
import Spells from "/imports/api/creature/Spells.js";
|
||||
import SpellLists from "/imports/api/creature/SpellLists.js";
|
||||
import Proficiencies from "/imports/api/creature/Proficiencies.js";
|
||||
import Actions from "/imports/api/creature/properties/Actions.js";
|
||||
import Attacks from "/imports/api/creature/properties/Attacks.js";
|
||||
import Attributes from "/imports/api/creature/properties/Attributes.js";
|
||||
import Buffs from "/imports/api/creature/properties/Buffs.js";
|
||||
import Classes from "/imports/api/creature/properties/Classes.js";
|
||||
import Conditions from "/imports/api/creature/properties/Conditions.js";
|
||||
import CustomBuffs from "/imports/api/creature/properties/CustomBuffs.js";
|
||||
import DamageMultipliers from "/imports/api/creature/properties/DamageMultipliers.js";
|
||||
import Effects from "/imports/api/creature/properties/Effects.js";
|
||||
import Experiences from "/imports/api/creature/properties/Experiences.js";
|
||||
import Features from "/imports/api/creature/properties/Features.js";
|
||||
import Notes from "/imports/api/creature/properties/Notes.js";
|
||||
import Skills from "/imports/api/creature/properties/Skills.js";
|
||||
import Spells from "/imports/api/creature/properties/Spells.js";
|
||||
import SpellLists from "/imports/api/creature/properties/SpellLists.js";
|
||||
import Proficiencies from "/imports/api/creature/properties/Proficiencies.js";
|
||||
import Containers from "/imports/api/inventory/Containers.js";
|
||||
import Items from "/imports/api/inventory/Items.js";
|
||||
|
||||
|
||||
@@ -198,10 +198,10 @@
|
||||
14: 7,
|
||||
15: 9,
|
||||
};
|
||||
if (costs[score]){
|
||||
if (costs[score] || costs[score] === 0){
|
||||
return costs[score];
|
||||
} else {
|
||||
return null;
|
||||
return NaN;
|
||||
}
|
||||
};
|
||||
export default {
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
</v-list>
|
||||
<v-list dense>
|
||||
<v-list-tile
|
||||
v-for="character in charactersWithNoParty"
|
||||
v-for="character in CreaturesWithNoParty"
|
||||
:href="character.url"
|
||||
:key="character._id"
|
||||
>
|
||||
@@ -63,6 +63,9 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Creatures from '/imports/api/creature/Creatures.js';
|
||||
import Parties from '/imports/api/campaign/Parties.js';
|
||||
|
||||
export default {
|
||||
meteor: {
|
||||
$subscribe: {
|
||||
@@ -78,7 +81,7 @@
|
||||
links(){
|
||||
return [
|
||||
{title: "Home", icon: "home", to: "/"},
|
||||
{title: "Characters", icon: "group", to: "characterList", vif: Meteor.userId()},
|
||||
{title: "Creatures", icon: "group", to: "characterList", vif: Meteor.userId()},
|
||||
{title: "Send Feedback", icon: "bug_report", to: "feedback"},
|
||||
{title: "Patreon", icon: "", href: "https://www.patreon.com/dicecloud"},
|
||||
{title: "Github", icon: "", href: "https://github.com/ThaumRystra/DiceCloud1"},
|
||||
@@ -89,9 +92,9 @@
|
||||
{owner: Meteor.userId()},
|
||||
{sort: {name: 1}},
|
||||
).map(party => {
|
||||
party.characterDocs = Characters.find(
|
||||
party.characterDocs = Creatures.find(
|
||||
{
|
||||
_id: {$in: party.characters},
|
||||
_id: {$in: party.Creatures},
|
||||
$or: [{readers: userId}, {writers: userId}, {owner: userId}],
|
||||
}, {
|
||||
sort: {name: 1},
|
||||
@@ -104,11 +107,11 @@
|
||||
return party;
|
||||
});
|
||||
},
|
||||
charactersWithNoParty() {
|
||||
CreaturesWithNoParty() {
|
||||
var userId = Meteor.userId();
|
||||
var charArrays = Parties.find({owner: userId}).map(p => p.characters);
|
||||
var charArrays = Parties.find({owner: userId}).map(p => p.Creatures);
|
||||
var partyChars = _.uniq(_.flatten(charArrays));
|
||||
return Characters.find(
|
||||
return Creatures.find(
|
||||
{
|
||||
_id: {$nin: partyChars},
|
||||
$or: [{readers: userId}, {writers: userId}, {owner: userId}],
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
import store from "/imports/ui/vuexStore.js";
|
||||
|
||||
const offset = 16;
|
||||
const duration = 400;
|
||||
let dialogStack = {};
|
||||
dialogStack.dialogs = [];
|
||||
|
||||
@@ -32,14 +28,17 @@ const dialogStackStore = {
|
||||
if (!dialog) return;
|
||||
if (dialog.callback) dialog.callback(result);
|
||||
},
|
||||
setCurrentResult (state, result){
|
||||
state.currentResult = result;
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
popDialogStack(context, result){
|
||||
if (history && history.state && history.state.openDialogs){
|
||||
context.state.currentResult = result;
|
||||
context.commit("setCurrentResult", result);
|
||||
history.back();
|
||||
} else {
|
||||
context.commit("popDialogStackMutation", result)
|
||||
context.commit("popDialogStackMutation", result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<toolbar-layout>
|
||||
<span slot="toolbar">Characters</span>
|
||||
<span slot="toolbar">Creatures</span>
|
||||
<v-card class="ma-4">
|
||||
<v-list v-if="charactersWithNoParty.length">
|
||||
<v-list v-if="CreaturesWithNoParty.length">
|
||||
<v-list-tile
|
||||
v-for="character in charactersWithNoParty"
|
||||
v-for="character in CreaturesWithNoParty"
|
||||
:key="character._id"
|
||||
:to="character.url"
|
||||
>
|
||||
@@ -72,6 +72,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Creatures from '/imports/api/creature/Creatures.js';
|
||||
import Parties from '/imports/api/campaign/Parties.js';
|
||||
import store from "/imports/ui/vuexStore.js";
|
||||
import ToolbarLayout from "/imports/ui/layouts/ToolbarLayout.vue";
|
||||
import LabeledFab from "/imports/ui/components/LabeledFab.vue";
|
||||
@@ -96,9 +98,9 @@
|
||||
{owner: Meteor.userId()},
|
||||
{sort: {name: 1}},
|
||||
).map(party => {
|
||||
party.characterDocs = Characters.find(
|
||||
party.characterDocs = Creatures.find(
|
||||
{
|
||||
_id: {$in: party.characters},
|
||||
_id: {$in: party.Creatures},
|
||||
$or: [{readers: userId}, {writers: userId}, {owner: userId}],
|
||||
}, {
|
||||
sort: {name: 1},
|
||||
@@ -107,11 +109,11 @@
|
||||
return party;
|
||||
});
|
||||
},
|
||||
charactersWithNoParty() {
|
||||
CreaturesWithNoParty() {
|
||||
var userId = Meteor.userId();
|
||||
var charArrays = Parties.find({owner: userId}).map(p => p.characters);
|
||||
var charArrays = Parties.find({owner: userId}).map(p => p.Creatures);
|
||||
var partyChars = _.uniq(_.flatten(charArrays));
|
||||
return Characters.find(
|
||||
return Creatures.find(
|
||||
{
|
||||
_id: {$nin: partyChars},
|
||||
$or: [{readers: userId}, {writers: userId}, {owner: userId}],
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import Attacks from "/imports/api/creature/Attacks.js";
|
||||
import Buffs from "/imports/api/creature/Buffs.js";
|
||||
import Classes from "/imports/api/creature/Classes.js";
|
||||
import CustomBuffs from "/imports/api/creature/CustomBuffs.js";
|
||||
import Effects from "/imports/api/creature/Effects.js";
|
||||
import Experiences from "/imports/api/creature/Experiences.js";
|
||||
import Features from "/imports/api/creature/Features.js";
|
||||
import Notes from "/imports/api/creature/Notes.js";
|
||||
import Proficiencies from "/imports/api/creature/Proficiencies.js";
|
||||
import SpellLists from "/imports/api/creature/SpellLists.js";
|
||||
import Spells from "/imports/api/creature/Spells.js";
|
||||
import Attacks from "/imports/api/creature/properties/Attacks.js";
|
||||
import Buffs from "/imports/api/creature/properties/Buffs.js";
|
||||
import Classes from "/imports/api/creature/properties/Classes.js";
|
||||
import CustomBuffs from "/imports/api/creature/properties/CustomBuffs.js";
|
||||
import Effects from "/imports/api/creature/properties/Effects.js";
|
||||
import Experiences from "/imports/api/creature/properties/Experiences.js";
|
||||
import Features from "/imports/api/creature/properties/Features.js";
|
||||
import Notes from "/imports/api/creature/properties/Notes.js";
|
||||
import Proficiencies from "/imports/api/creature/properties/Proficiencies.js";
|
||||
import SpellLists from "/imports/api/creature/properties/SpellLists.js";
|
||||
import Spells from "/imports/api/creature/properties/Spells.js";
|
||||
import Containers from "/imports/api/inventory/Containers.js";
|
||||
import Items from "/imports/api/inventory/Items.js";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user