Changed how levels are handled
This commit is contained in:
@@ -433,8 +433,8 @@ Characters.helpers({
|
||||
var mod = +getMod(this.attributeValue(attribute));
|
||||
return 10 + mod;
|
||||
},
|
||||
|
||||
level: function(){
|
||||
|
||||
xpLevel: function(){
|
||||
var xp = this.experience();
|
||||
var xpTable = [0, 300, 900, 2700, 6500, 14000, 23000, 34000, 48000, 64000,
|
||||
85000, 100000, 120000, 140000, 165000, 195000, 225000, 265000,
|
||||
@@ -447,6 +447,14 @@ Characters.helpers({
|
||||
if(xp > 355000) return 20;
|
||||
return 0;
|
||||
},
|
||||
|
||||
level: function(){
|
||||
var level = 0;
|
||||
Classes.find({charId: this._id}).forEach(function(cls){
|
||||
level += cls.level;
|
||||
})
|
||||
return level;
|
||||
},
|
||||
|
||||
experience: function(){
|
||||
var xp = 0;
|
||||
|
||||
@@ -3,6 +3,7 @@ Classes = new Meteor.Collection("classes");
|
||||
Schemas.Class = new SimpleSchema({
|
||||
charId: {type: String, regEx: SimpleSchema.RegEx.Id},
|
||||
name: {type: String, trim: false},
|
||||
level: {type: Number},
|
||||
createdAt: {
|
||||
type: Date,
|
||||
autoValue: function() {
|
||||
@@ -15,6 +16,7 @@ Schemas.Class = new SimpleSchema({
|
||||
}
|
||||
}
|
||||
},
|
||||
color: {type: String, allowedValues: _.pluck(colorOptions, "key"), defaultValue: "q"}
|
||||
});
|
||||
|
||||
Classes.attachSchema(Schemas.Class);
|
||||
@@ -33,7 +33,7 @@ Schemas.Effect = new SimpleSchema({
|
||||
type: {
|
||||
type: String,
|
||||
defaultValue: "editable",
|
||||
allowedValues: ["editable", "feature", "level", "buff", "equipment", "racial", "inate"]
|
||||
allowedValues: ["editable", "feature", "class", "buff", "equipment", "racial", "inate"]
|
||||
},
|
||||
//the id of the feature, buff or item that created this effect
|
||||
sourceId: {
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
Levels = new Meteor.Collection("levels");
|
||||
|
||||
Schemas.Level = new SimpleSchema({
|
||||
charId: {type: String, regEx: SimpleSchema.RegEx.Id},
|
||||
classId: {type: String, regEx: SimpleSchema.RegEx.Id},
|
||||
value: {type: Number}
|
||||
});
|
||||
|
||||
Levels.attachSchema(Schemas.Level);
|
||||
@@ -45,7 +45,7 @@
|
||||
<!--Proficiencies-->
|
||||
<paper-shadow class="card container" hero-id="main" {{detailHero "proficiencies"}}>
|
||||
<div id="proficiencies"
|
||||
class="containerTop grey white-text"
|
||||
class="whiteTop"
|
||||
hero-id="toolbar"
|
||||
layout horizontal center
|
||||
{{detailHero "proficiencies"}}>
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<template name="classDialog">
|
||||
{{#with class}}
|
||||
{{#baseDialog title=name class=colorClass hideColor="true"}}
|
||||
<!--Name-->
|
||||
<paper-input id="classNameInput" label="Class Name" floatinglabel value={{name}}></paper-input>
|
||||
<!--Level-->
|
||||
<paper-input id="levelValueInput" label="Level" floatinglabel value={{level}}></paper-input>
|
||||
<!--Effects-->
|
||||
{{> effectsEditList sourceId=_id charId=charId type="class"}}
|
||||
{{/baseDialog}}
|
||||
{{/with}}
|
||||
</template>
|
||||
@@ -0,0 +1,20 @@
|
||||
Template.classDialog.events({
|
||||
"tap #deleteButton": function(event, instance){
|
||||
Classes.remove(instance.data.classId);
|
||||
GlobalUI.closeDetail()
|
||||
},
|
||||
"change #classNameInput": function(event){
|
||||
var value = event.currentTarget.value;
|
||||
Classes.update(this._id, {$set: {name: value}});
|
||||
},
|
||||
"change #levelValueInput": function(event){
|
||||
var value = event.currentTarget.value;
|
||||
Classes.update(this._id, {$set: {level: value}});
|
||||
}
|
||||
});
|
||||
|
||||
Template.classDialog.helpers({
|
||||
class: function(){
|
||||
return Classes.findOne(this.classId);
|
||||
}
|
||||
});
|
||||
@@ -2,10 +2,12 @@
|
||||
<div fit>
|
||||
<div id="journal" class="scroll-y" fit>
|
||||
<div class="containers">
|
||||
<!--Experience Table-->
|
||||
<paper-shadow class="card container experiencesCard" hero-id="main" {{detailHero}}>
|
||||
<div class="containerTop {{colorClass}}" hero-id="toolbar" layout horizontal center {{detailHero}}>
|
||||
<div class="whiteTop" hero-id="toolbar" layout horizontal center {{detailHero}}>
|
||||
<div class="containerName subhead" flex>Experience</div>
|
||||
<div class="subhead">{{experience}} XP</div>
|
||||
<paper-icon-button class="black54" id="addXP" icon="add"></paper-icon-button>
|
||||
</div>
|
||||
<div class="containerMain experiences">
|
||||
{{#each experiences}}
|
||||
@@ -23,35 +25,35 @@
|
||||
</div>
|
||||
{{/if}}
|
||||
</paper-shadow>
|
||||
<!--Class Table-->
|
||||
<paper-shadow class="card container" hero-id="main" {{detailHero}}>
|
||||
<div class="containerTop {{colorClass}}" hero-id="toolbar" layout horizontal center {{detailHero}}>
|
||||
<div class="whiteTop" hero-id="toolbar" layout horizontal center {{detailHero}}>
|
||||
<div flex>
|
||||
<div class="containerName subhead">Levels</div>
|
||||
<div class="containerName subhead">Level {{level}}</div>
|
||||
{{#if nextLevelXP}}
|
||||
<div class="caption">
|
||||
Next Level: {{nextLevelXP}}XP
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
<paper-icon-button class="black54" id="addClassButton" icon="add"></paper-icon-button>
|
||||
</div>
|
||||
<div class="containerMain experiences">
|
||||
<div class="list-subhead" layout horizontal center>
|
||||
Race
|
||||
</div>
|
||||
<div class="itemSlot">
|
||||
<paper-item class="inventoryItem race" hero-id="main" {{detailHero "race"}} layout horizontal>
|
||||
{{race}}
|
||||
</paper-item>
|
||||
</div>
|
||||
{{#each classes}}
|
||||
<div class="list-subhead" layout horizontal center>
|
||||
{{name}}
|
||||
<div class="itemSlot">
|
||||
<paper-item class="inventoryItem class" hero-id="main" {{detailHero}} layout horizontal>
|
||||
{{name}} {{level}}
|
||||
</paper-item>
|
||||
</div>
|
||||
{{#each levels ../_id}}
|
||||
<div class="itemSlot">
|
||||
<paper-item class="inventoryItem level" hero-id="main" {{detailHero}} layout horizontal>
|
||||
Level {{value}}
|
||||
</paper-item>
|
||||
</div>
|
||||
{{/each}}
|
||||
{{/each}}
|
||||
</div>
|
||||
</paper-shadow>
|
||||
<!--Notes-->
|
||||
{{#each notes}}
|
||||
<paper-shadow class="card container" hero-id="main" {{detailHero}}>
|
||||
<div class="containerTop {{colorClass}} noteTop" hero-id="toolbar" layout horizontal center {{detailHero}}>
|
||||
@@ -66,8 +68,11 @@
|
||||
<div class="fab-buffer"></div>
|
||||
</div>
|
||||
</div>
|
||||
<paper-fab-menu id="inventoryAddMenu" icon="add" closeIcon="close" duration="0.3">
|
||||
<paper-fab-menu-item id="addNote" icon="note-add" color="#d23f31" tooltip="Note"></paper-fab-menu-item>
|
||||
<paper-fab-menu-item id="addXP" icon="work" color="#d23f31" tooltip="Experience"></paper-fab-menu-item>
|
||||
</paper-fab-menu>
|
||||
<paper-fab id="addNote"
|
||||
class="floatyButton"
|
||||
icon="add"
|
||||
title="Add"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
hero-id="main"></paper-fab>
|
||||
</template>
|
||||
@@ -26,6 +26,12 @@ Template.journal.helpers({
|
||||
levels: function(charId){
|
||||
return Levels.find({charId: charId, classId: this._id}, {sort: {value: 1}});
|
||||
},
|
||||
nextLevelXP: function(){
|
||||
var currentLevel = this.level();
|
||||
if (currentLevel < 20){
|
||||
return xpTable[currentLevel];
|
||||
}
|
||||
},
|
||||
race: function(){
|
||||
var char = Characters.findOne(this._id, {fields: {race: 1}});
|
||||
return char && char.race;
|
||||
@@ -47,10 +53,10 @@ Template.journal.events({
|
||||
heroId: this._id
|
||||
});
|
||||
},
|
||||
"tap .level": function(event){
|
||||
"tap .class": function(event){
|
||||
GlobalUI.setDetail({
|
||||
template: "levelDialog",
|
||||
data: {levelId: this._id, charId: this.charId},
|
||||
template: "classDialog",
|
||||
data: {classId: this._id, charId: this.charId},
|
||||
heroId: this._id
|
||||
});
|
||||
},
|
||||
@@ -90,6 +96,22 @@ Template.journal.events({
|
||||
}
|
||||
})
|
||||
},
|
||||
"tap #addClassButton":function(event){
|
||||
var charId = this._id;
|
||||
Classes.insert({
|
||||
charId: charId,
|
||||
name: "new Class",
|
||||
level: 1
|
||||
}, function(error, id){
|
||||
if(!error){
|
||||
GlobalUI.setDetail({
|
||||
template: "classDialog",
|
||||
data: {classId: id, charId: charId},
|
||||
heroId: id
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
"tap #moreExperiences": function(event){
|
||||
var inst = Template.instance();
|
||||
inst.experiencesLimit.set(inst.experiencesLimit.get() + (this.settings && this.settings.experiencesInc || 10));
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
<template name="levelDialog">
|
||||
{{#with level}}
|
||||
{{#baseDialog title=name class=colorClass hideColor="true"}}
|
||||
<!--Level-->
|
||||
<paper-input id="levelValueInput" label="Level" floatinglabel value={{value}}></paper-input>
|
||||
<!--Effects-->
|
||||
{{> effectsEditList sourceId=_id charId=charId type="level"}}
|
||||
{{/baseDialog}}
|
||||
{{/with}}
|
||||
</template>
|
||||
@@ -1,16 +0,0 @@
|
||||
Template.levelDialog.events({
|
||||
"tap #deleteButton": function(event, instance){
|
||||
Levels.remove(instance.data.levelId);
|
||||
GlobalUI.closeDetail()
|
||||
},
|
||||
"change #levelValueInput": function(event){
|
||||
var value = event.currentTarget.value;
|
||||
Levels.update(this._id, {$set: {value: value}});
|
||||
}
|
||||
});
|
||||
|
||||
Template.levelDialog.helpers({
|
||||
level: function(){
|
||||
return Levels.findOne(this.levelId);
|
||||
}
|
||||
});
|
||||
3
rpg-docs/lib/constants/xpTable.js
Normal file
3
rpg-docs/lib/constants/xpTable.js
Normal file
@@ -0,0 +1,3 @@
|
||||
xpTable = [0, 300, 900, 2700, 6500, 14000, 23000, 34000, 48000, 64000,
|
||||
85000, 100000, 120000, 140000, 165000, 195000, 225000, 265000,
|
||||
305000, 355000];
|
||||
@@ -2,18 +2,26 @@
|
||||
evaluate = function(charId, string){
|
||||
if(!string) return string;
|
||||
var char = Characters.findOne(charId, {fields: {_id: 1}});
|
||||
string = string.replace(/\b[a-zA-Z]+\b/g, function(sub){
|
||||
string = string.replace(/\b[a-z]+\b/gi, function(sub){
|
||||
//fields
|
||||
if(Schemas.Character.schema(sub)){
|
||||
return char.fieldValue(sub)
|
||||
}
|
||||
//ability modifiers
|
||||
var abilityMods = ["strengthMod", "dexterityMod", "constitutionMod", "intelligenceMod", "wisdomMod", "charismaMod"]
|
||||
if( _.contains(abilityMods, sub) ){
|
||||
var abilityMods = ["STRENGTHMOD", "DEXTERITYMOD", "CONSTITUTIONMOD", "INTELLIGENCEMOD", "WISDOMMOD", "CHARISMAMOD"]
|
||||
if( _.contains(abilityMods, sub.toUpperCase()) ){
|
||||
var slice = sub.slice(0, - 3);
|
||||
return char.abilityMod(slice);
|
||||
}
|
||||
if(sub === "level"){
|
||||
//class levels
|
||||
if(/\w+levels?\b/gi.test(sub)){
|
||||
//strip out "level"
|
||||
var className = sub.replace(/levels?\b/gi, "");
|
||||
var cls = Classes.findOne({charId: charId, name: className});
|
||||
return cls && cls.level;
|
||||
}
|
||||
//character level
|
||||
if(sub.toUpperCase() === "LEVEL"){
|
||||
return char.level();
|
||||
}
|
||||
return sub;
|
||||
|
||||
@@ -11,7 +11,6 @@ Meteor.publish("singleCharacter", function(characterId, userId){
|
||||
Experiences.find({charId: characterId}),
|
||||
Features.find({charId: characterId}),
|
||||
Items.find({charId: characterId}),
|
||||
Levels.find({charId: characterId}),
|
||||
Notes.find({charId: characterId}),
|
||||
Spells.find({charId: characterId}),
|
||||
SpellLists.find({charId: characterId}),
|
||||
|
||||
Reference in New Issue
Block a user