init
This commit is contained in:
16
.codio
Normal file
16
.codio
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
// Configure your Run and Preview buttons here.
|
||||||
|
|
||||||
|
// Run button configuration
|
||||||
|
"commands": {
|
||||||
|
"Node version": "node --version"
|
||||||
|
},
|
||||||
|
|
||||||
|
// Preview button configuration
|
||||||
|
"preview": {
|
||||||
|
"Project Index (static)": "https://{{domain}}/{{index}}",
|
||||||
|
"Current File (static)": "https://{{domain}}/{{filepath}}",
|
||||||
|
"Box URL": "http://{{domain}}:3000/",
|
||||||
|
"Box URL SSL": "https://{{domain}}:9500/"
|
||||||
|
}
|
||||||
|
}
|
||||||
26
.guides/sections.md
Normal file
26
.guides/sections.md
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
title: Example section
|
||||||
|
files: []
|
||||||
|
editable: true
|
||||||
|
layout: 2-panels-tree
|
||||||
|
|
||||||
|
---
|
||||||
|
Some **awesome** content 1
|
||||||
|
|
||||||
|
---
|
||||||
|
title: Example section 3
|
||||||
|
files: []
|
||||||
|
editable: true
|
||||||
|
layout: ""
|
||||||
|
|
||||||
|
---
|
||||||
|
Some **awesome** content 3
|
||||||
|
|
||||||
|
---
|
||||||
|
title: Example section 4
|
||||||
|
files: []
|
||||||
|
editable: true
|
||||||
|
layout: ""
|
||||||
|
|
||||||
|
---
|
||||||
|
Some **awesome** content 4
|
||||||
1
.guides/styles.css
Normal file
1
.guides/styles.css
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/* Place you styles here */
|
||||||
37
TODO.md
Normal file
37
TODO.md
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
Character.js is under construction... expect broken character sheets
|
||||||
|
|
||||||
|
issues
|
||||||
|
------
|
||||||
|
|
||||||
|
* hot code pushes don't apply transforms correctly
|
||||||
|
|
||||||
|
Characters attributes and buffs
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
Characters currently have attributes and skills that can take bonuses and multipliers.
|
||||||
|
When a feature is activated or enabled on a characer or a piece of equipment is equipped
|
||||||
|
the buffs and effects should be applied to the correct attribute or skill. When the
|
||||||
|
equipment or feature is removed or deactivated, the effects should be removed as well.
|
||||||
|
|
||||||
|
Effects need the following data as a bare minimum:
|
||||||
|
|
||||||
|
* attribute or skill to effect
|
||||||
|
* name
|
||||||
|
* value
|
||||||
|
|
||||||
|
For example, plate would be an object like this:
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "Plate Armor" ,
|
||||||
|
effects: [
|
||||||
|
{stat: "skills.dexArmor.min", value: 0},
|
||||||
|
{stat: "skills.dexArmor.max", value: 0},
|
||||||
|
{stat: "attributes.armor.min", value: 18},
|
||||||
|
{stat: "skills.stealth.disadvantage", value 1} //disadvantage doesn't need a value
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
See Conditions for this implemented.
|
||||||
|
|
||||||
|
The effects ultimately need to be pushed to the correct array when applied: `attributes.armor.min.push({name: "Plate Armor", type: "Equpiment", value: 18})`
|
||||||
|
They will also need to be removed correctly by the thing that applied them, or after some time.
|
||||||
6
rpg-docs/.meteor/.finished-upgraders
Normal file
6
rpg-docs/.meteor/.finished-upgraders
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# This file contains information which helps Meteor properly upgrade your
|
||||||
|
# app when you run 'meteor update'. You should check it into version control
|
||||||
|
# with your project.
|
||||||
|
|
||||||
|
notices-for-0.9.0
|
||||||
|
notices-for-0.9.1
|
||||||
1
rpg-docs/.meteor/.gitignore
vendored
Normal file
1
rpg-docs/.meteor/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
local
|
||||||
7
rpg-docs/.meteor/.id
Normal file
7
rpg-docs/.meteor/.id
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# This file contains a token that is unique to your project.
|
||||||
|
# Check it into your repository along with the rest of this directory.
|
||||||
|
# It can be used for purposes such as:
|
||||||
|
# - ensuring you don't accidentally deploy one app on top of another
|
||||||
|
# - providing package authors with aggregated statistics
|
||||||
|
|
||||||
|
1xg0ir21aq4e081rfkzg3
|
||||||
1
rpg-docs/.meteor/cordova-plugins
Normal file
1
rpg-docs/.meteor/cordova-plugins
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
13
rpg-docs/.meteor/packages
Normal file
13
rpg-docs/.meteor/packages
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# Meteor packages used by this project, one per line.
|
||||||
|
#
|
||||||
|
# 'meteor add' and 'meteor remove' will edit this file for you,
|
||||||
|
# but you can also edit it by hand.
|
||||||
|
|
||||||
|
meteor-platform
|
||||||
|
autopublish
|
||||||
|
insecure
|
||||||
|
iron:router
|
||||||
|
accounts-password
|
||||||
|
accounts-ui
|
||||||
|
random
|
||||||
|
|
||||||
1
rpg-docs/.meteor/release
Normal file
1
rpg-docs/.meteor/release
Normal file
@@ -0,0 +1 @@
|
|||||||
|
METEOR@0.9.2.2
|
||||||
66
rpg-docs/.meteor/versions
Normal file
66
rpg-docs/.meteor/versions
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
accounts-base@1.1.0
|
||||||
|
accounts-password@1.0.1
|
||||||
|
accounts-ui-unstyled@1.1.1
|
||||||
|
accounts-ui@1.1.0
|
||||||
|
application-configuration@1.0.2
|
||||||
|
autopublish@1.0.0
|
||||||
|
autoupdate@1.1.0
|
||||||
|
base64@1.0.0
|
||||||
|
binary-heap@1.0.0
|
||||||
|
blaze-tools@1.0.0
|
||||||
|
blaze@2.0.0
|
||||||
|
boilerplate-generator@1.0.0
|
||||||
|
callback-hook@1.0.0
|
||||||
|
check@1.0.0
|
||||||
|
ctl-helper@1.0.3
|
||||||
|
ctl@1.0.1
|
||||||
|
ddp@1.0.8
|
||||||
|
deps@1.0.3
|
||||||
|
ejson@1.0.2
|
||||||
|
email@1.0.2
|
||||||
|
fastclick@1.0.0
|
||||||
|
follower-livedata@1.0.1
|
||||||
|
geojson-utils@1.0.0
|
||||||
|
html-tools@1.0.0
|
||||||
|
htmljs@1.0.1
|
||||||
|
http@1.0.5
|
||||||
|
id-map@1.0.0
|
||||||
|
insecure@1.0.0
|
||||||
|
iron:core@0.3.4
|
||||||
|
iron:dynamic-template@0.4.1
|
||||||
|
iron:layout@0.4.1
|
||||||
|
iron:router@0.9.4
|
||||||
|
jquery@1.0.0
|
||||||
|
json@1.0.0
|
||||||
|
less@1.0.8
|
||||||
|
livedata@1.0.9
|
||||||
|
localstorage@1.0.0
|
||||||
|
logging@1.0.3
|
||||||
|
meteor-platform@1.1.0
|
||||||
|
meteor@1.1.0
|
||||||
|
minifiers@1.1.0
|
||||||
|
minimongo@1.0.3
|
||||||
|
mobile-status-bar@1.0.0
|
||||||
|
mongo@1.0.5
|
||||||
|
npm-bcrypt@0.7.7
|
||||||
|
observe-sequence@1.0.2
|
||||||
|
ordered-dict@1.0.0
|
||||||
|
random@1.0.0
|
||||||
|
reactive-dict@1.0.2
|
||||||
|
reactive-var@1.0.1
|
||||||
|
reload@1.1.0
|
||||||
|
retry@1.0.0
|
||||||
|
routepolicy@1.0.1
|
||||||
|
service-configuration@1.0.1
|
||||||
|
session@1.0.1
|
||||||
|
sha@1.0.0
|
||||||
|
spacebars-compiler@1.0.2
|
||||||
|
spacebars@1.0.1
|
||||||
|
srp@1.0.0
|
||||||
|
templating@1.0.6
|
||||||
|
tracker@1.0.2
|
||||||
|
ui@1.0.2
|
||||||
|
underscore@1.0.0
|
||||||
|
url@1.0.0
|
||||||
|
webapp-hashing@1.0.0
|
||||||
|
webapp@1.1.1
|
||||||
9
rpg-docs/Model/Character/Armor.js
Normal file
9
rpg-docs/Model/Character/Armor.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Armor = function(name, value){
|
||||||
|
this.name = name;
|
||||||
|
this.value = value;
|
||||||
|
this.equipped = true;
|
||||||
|
this.dexModMax = 20;
|
||||||
|
this.dexModMin = -20;
|
||||||
|
this.strengthNeeded = 0;
|
||||||
|
this.stealthDisadvantage = false;
|
||||||
|
}
|
||||||
324
rpg-docs/Model/Character/Characters.js
Normal file
324
rpg-docs/Model/Character/Characters.js
Normal file
@@ -0,0 +1,324 @@
|
|||||||
|
//set up the collection for characters
|
||||||
|
Characters = new Meteor.Collection("characters", {
|
||||||
|
//transform function alters the object returned by the database
|
||||||
|
transform: function (doc) {
|
||||||
|
//extend character with its protoypal functions
|
||||||
|
var newInstance = Object.create(protoCharacter);
|
||||||
|
doc = _.extend(newInstance, doc);
|
||||||
|
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Attributes are numerical values
|
||||||
|
Attribute = function(base){
|
||||||
|
this.base = base; //the unmodified value of the attribute
|
||||||
|
//effects of the form {name: "Ring of Protection", value: 1}
|
||||||
|
this.add = []; //bonuses added to the attribute
|
||||||
|
this.mul = []; //multipliers to the attribute (after adding bonuses)
|
||||||
|
this.min = []; //effects setting the minimum value of the attribute
|
||||||
|
this.max = []; //effects setting the maximum value of the attribute
|
||||||
|
this.conditional = []; //conditional modifiers
|
||||||
|
}
|
||||||
|
|
||||||
|
var attributes = [
|
||||||
|
"strength",
|
||||||
|
"dexterity",
|
||||||
|
"constitution",
|
||||||
|
"intelligence",
|
||||||
|
"wisdom",
|
||||||
|
"charisma",
|
||||||
|
"hitPoints",
|
||||||
|
"proficiencyBonus",
|
||||||
|
"speed",
|
||||||
|
"armor",
|
||||||
|
"weight",
|
||||||
|
"weightCarried",
|
||||||
|
"age",
|
||||||
|
"ageRate",
|
||||||
|
"level1SpellSlots",
|
||||||
|
"level2SpellSlots",
|
||||||
|
"level3SpellSlots",
|
||||||
|
"level4SpellSlots",
|
||||||
|
"level5SpellSlots",
|
||||||
|
"level6SpellSlots",
|
||||||
|
"level7SpellSlots",
|
||||||
|
"level8SpellSlots",
|
||||||
|
"level9SpellSlots",
|
||||||
|
"ki",
|
||||||
|
"sorceryPoints",
|
||||||
|
"rages"
|
||||||
|
];
|
||||||
|
|
||||||
|
//Skills are bonuses to rolls: "+2" etc.
|
||||||
|
//They are based off of some ability
|
||||||
|
Skill = function(ability){
|
||||||
|
//proficiencies of the form {name: "Jack of all Trades", value: 0.5}
|
||||||
|
//only the highest is used
|
||||||
|
this.proficiency = [];
|
||||||
|
//ability name that this skill uses as base for roll
|
||||||
|
this.ability = ability;
|
||||||
|
this.add = [];
|
||||||
|
this.mul = [];
|
||||||
|
this.min = [];
|
||||||
|
this.max = [];
|
||||||
|
this.advantage = []; //effects granting advantage
|
||||||
|
this.disadvantage = [];
|
||||||
|
this.passiveAdd = []; //only added to passive checks
|
||||||
|
this.fail = []; //all checks are failed
|
||||||
|
this.conditional = []; //conditional modifiers
|
||||||
|
}
|
||||||
|
|
||||||
|
var skills = [
|
||||||
|
{skill: "strengthSave", ability: "strength"},
|
||||||
|
{skill: "dexteritySave", ability: "dexterity"},
|
||||||
|
{skill: "constitutionSave", ability: "constitution"},
|
||||||
|
{skill: "intelligenceSave", ability: "intelligence"},
|
||||||
|
{skill: "wisdomSave", ability: "wisdom"},
|
||||||
|
{skill: "charismaSave", ability: "charisma"},
|
||||||
|
|
||||||
|
{skill: "acrobatics", ability: "dexterity"},
|
||||||
|
{skill: "animalHandling", ability: "wisdom"},
|
||||||
|
{skill: "arcana",ability: "intelligence"},
|
||||||
|
{skill: "athletics", ability: "strength"},
|
||||||
|
{skill: "deception", ability: "charisma"},
|
||||||
|
{skill: "history", ability: "intelligence"},
|
||||||
|
{skill: "insight", ability: "wisdom"},
|
||||||
|
{skill: "intimidation", ability: "charisma"},
|
||||||
|
{skill: "investigation", ability: "intelligence"},
|
||||||
|
{skill: "medicine", ability: "wisdom"},
|
||||||
|
{skill: "nature", ability: "intelligence"},
|
||||||
|
{skill: "perception", ability: "wisdom"},
|
||||||
|
{skill: "performance", ability: "charisma"},
|
||||||
|
{skill: "persuasion", ability: "charisma"},
|
||||||
|
{skill: "religion", ability: "intelligence"},
|
||||||
|
{skill: "sleightOfHand", ability: "dexterity"},
|
||||||
|
{skill: "stealth", ability: "dexterity"},
|
||||||
|
{skill: "survival", ability: "wisdom"},
|
||||||
|
|
||||||
|
{skill: "initiative", ability: "dexterity"},
|
||||||
|
{skill: "strengthAttack", ability: "strength"},
|
||||||
|
{skill: "dexterityAttack", ability: "dexterity"},
|
||||||
|
{skill: "rangedAttack", ability: "dexterity"},
|
||||||
|
{skill: "dexterityArmor", ability: "dexterity"}
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
//Plain text fields for the character
|
||||||
|
var strings = [
|
||||||
|
"name",
|
||||||
|
"alignment",
|
||||||
|
"gender",
|
||||||
|
"race",
|
||||||
|
"description",
|
||||||
|
"personality",
|
||||||
|
"ideals",
|
||||||
|
"bonds",
|
||||||
|
"flaws"
|
||||||
|
];
|
||||||
|
|
||||||
|
//Data structure for the character
|
||||||
|
//no functions can be added to this constructor
|
||||||
|
Character = function(owner){
|
||||||
|
//attributes
|
||||||
|
this.attributes = {};
|
||||||
|
for(var i = 0, l = attributes.length; i < l; i++){
|
||||||
|
this.attributes[attributes[i]] = new Attribute(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//add 10 and dex bonus to armor
|
||||||
|
this.attributes.armor.add.push({name: "Base Armor Class", value: 10});
|
||||||
|
this.attributes.armor.add.push({name: "Dexterity Modifier", value: "skillMod skills.dexterityArmor"});
|
||||||
|
|
||||||
|
//skills
|
||||||
|
this.skills = {};
|
||||||
|
for(var i = 0, l = skills.length; i < l; i++){
|
||||||
|
this.skills[skills[i].skill] = new Skill(skills[i].ability);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.deathSave = {
|
||||||
|
success : 0,
|
||||||
|
fail: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
this.hitDice = [];
|
||||||
|
|
||||||
|
this.weaponProficiencies = [];
|
||||||
|
this.toolProficiencies = [];
|
||||||
|
this.languages = [];
|
||||||
|
|
||||||
|
this.features = [];
|
||||||
|
|
||||||
|
this.spells = [];
|
||||||
|
|
||||||
|
this.classes = [];
|
||||||
|
|
||||||
|
this.experience = new Experience();
|
||||||
|
|
||||||
|
this.vulnerability = {};
|
||||||
|
for(var i = 0, l = DamageTypes.length; i < l; i++){
|
||||||
|
this.vulnerability[DamageTypes[i]] = new Attribute(1);
|
||||||
|
this.vulnerability[DamageTypes[i]].min.push({name: "Resistance doesn't stack", value: 0.5});
|
||||||
|
this.vulnerability[DamageTypes[i]].max.push({name: "Vulnerability doesn't stack", value: 2});
|
||||||
|
}
|
||||||
|
|
||||||
|
//admin
|
||||||
|
this.owner = owner;
|
||||||
|
this.readers = [];
|
||||||
|
this.writers = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
//functions and calculated values go here
|
||||||
|
var protoCharacter = {
|
||||||
|
attributeValue: function(attribute){
|
||||||
|
if (attribute === undefined) return;
|
||||||
|
//base value
|
||||||
|
var value = attribute.base;
|
||||||
|
|
||||||
|
//add all values in add array
|
||||||
|
for(var i = 0, l = attribute.add.length; i < l; i++){
|
||||||
|
var add = pop(attribute.add[i].value, this);
|
||||||
|
value += add ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//multiply all values in mul array
|
||||||
|
for(var i = 0, l = attribute.mul.length; i < l; i++){
|
||||||
|
var mul = pop(attribute.mul[i], this);
|
||||||
|
value *= mul;
|
||||||
|
}
|
||||||
|
|
||||||
|
//largest min
|
||||||
|
for(var i = 0, l = attribute.min.length; i < l; i++){
|
||||||
|
var min = pop(attribute.min[i], this);
|
||||||
|
value = value > min? value : min;
|
||||||
|
}
|
||||||
|
|
||||||
|
//smallest max
|
||||||
|
for(var i = 0, l = attribute.max.length; i < l; i++){
|
||||||
|
var max = pop(attribute.max[i], this);
|
||||||
|
value = value < max? value : max;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
|
||||||
|
skillMod: function(skill){
|
||||||
|
//get the final value of the ability score
|
||||||
|
var ability = this.attributeValue(this.attributes[skill.ability]);
|
||||||
|
|
||||||
|
//base modifier
|
||||||
|
var mod = +getMod(ability)
|
||||||
|
|
||||||
|
//multiply proficiency bonus by largest value in proficiency array
|
||||||
|
var prof = 0;
|
||||||
|
for(var i = 0, l = skill.proficiency.length; i < l; i++){
|
||||||
|
var newProf = pop(skill.proficiency[i].value, this);
|
||||||
|
if (newProf > prof){
|
||||||
|
prof = newProf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//add multiplied proficiency bonus to modifier
|
||||||
|
mod += prof * this.attributeValue(this.attributes.proficiencyBonus);
|
||||||
|
|
||||||
|
//add all values in add array
|
||||||
|
for(var i = 0, l = skill.add.length; i < l; i++){
|
||||||
|
mod += pop(skill.add[i].value, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//multiply all values in mul array
|
||||||
|
for(var i = 0, l = skill.mul.length; i < l; i++){
|
||||||
|
mod *= pop(skill.mul[i].value, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//largest min
|
||||||
|
for(var i = 0, l = skill.min.length; i < l; i++){
|
||||||
|
var min = pop(skill.min[i], this);
|
||||||
|
mod = mod > min? mod : min;
|
||||||
|
}
|
||||||
|
|
||||||
|
//smallest max
|
||||||
|
for(var i = 0, l = skill.max.length; i < l; i++){
|
||||||
|
var max = pop(skill.max[i], this);
|
||||||
|
mod = mod < max? mod : max;
|
||||||
|
}
|
||||||
|
|
||||||
|
return signedString(mod);
|
||||||
|
},
|
||||||
|
|
||||||
|
passiveSkill: function(skill){
|
||||||
|
var mod = +this.skillMod(skill);
|
||||||
|
var value = 10 + mod;
|
||||||
|
for(var i = 0, l = skill.passiveAdd.length; i < l; i++){
|
||||||
|
value += pop(skill.passiveAdd[i].value, this);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
//TODO decide whether (dis)advantage gives (-)+5 to passive checks
|
||||||
|
},
|
||||||
|
|
||||||
|
abilityMod: function(attribute){
|
||||||
|
return signedString(getMod(this.attributeValue(attribute)));
|
||||||
|
},
|
||||||
|
|
||||||
|
passiveAbility: function(attribute){
|
||||||
|
var mod = +getMod(this.attributeValue(attribute));
|
||||||
|
return 10 + mod;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getMod = function(score){
|
||||||
|
return Math.floor((score-10)/2);
|
||||||
|
}
|
||||||
|
|
||||||
|
signedString = function(number){
|
||||||
|
return number > 0? "+" + number : "" + number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// turns dot notation strings into keys of root
|
||||||
|
// argument formats:
|
||||||
|
// 157, anything -> 157
|
||||||
|
// "some.number", object -> object.some.number
|
||||||
|
// "some.function", object -> object.some.function()
|
||||||
|
// "some.function arg1 arg2", object -> object.some.function(arg1, arg2)
|
||||||
|
pop = function(input, root){
|
||||||
|
|
||||||
|
if(typeof(input) === "string"){
|
||||||
|
//we need root for this part
|
||||||
|
if(root === undefined) return;
|
||||||
|
|
||||||
|
//this is a likely to fail if the string is malformed
|
||||||
|
try{
|
||||||
|
//split over spaces
|
||||||
|
var parts = input.split(" ");
|
||||||
|
|
||||||
|
//for each word
|
||||||
|
for (var i = 0; i < parts.length; i++){
|
||||||
|
//split over dots
|
||||||
|
var str = parts[i].split(".");
|
||||||
|
|
||||||
|
//start at root
|
||||||
|
parts[i] = root;
|
||||||
|
|
||||||
|
//for each word between dots
|
||||||
|
for (var j = 0; j < str.length; j++){
|
||||||
|
parts[i] = parts[i][str[j]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//pull the first word out, might be a function
|
||||||
|
var func = parts.splice(0, 1)[0];
|
||||||
|
|
||||||
|
//if it's a function, apply the arguments to it
|
||||||
|
if(_.isFunction(func)) return +func.apply(root, parts);
|
||||||
|
|
||||||
|
//if it's a number, return it
|
||||||
|
if(!isNaN(func)) return +func;
|
||||||
|
} catch (err) {
|
||||||
|
//TODO pokemon catch statement is bad
|
||||||
|
//"gotta catch em all"
|
||||||
|
console.log(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return +input;
|
||||||
|
}
|
||||||
118
rpg-docs/Model/Character/Conditions.js
Normal file
118
rpg-docs/Model/Character/Conditions.js
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
DamageTypes = [
|
||||||
|
"acid", "bludgeoning", "cold", "fire", "force",
|
||||||
|
"lightning", "necrotic", "piercing", "poison", "psychic",
|
||||||
|
"radiant", "slashing", "thunder"
|
||||||
|
]
|
||||||
|
Conditions = {};
|
||||||
|
|
||||||
|
Conditions.Blinded = {
|
||||||
|
description: ["a blinded creature can't see and automatically fails any ability check that requires sight.",
|
||||||
|
"Attack rolls against the creature have advantage, and the creature's attack rolls have disadvantage."]
|
||||||
|
}
|
||||||
|
|
||||||
|
Conditions.Charmed = {
|
||||||
|
description: ["A charmed creature can't attack the charmer or target the charmer with harmful abilities or magical effects",
|
||||||
|
"The charmer has advantage on any ability check to interact socially with the creature."]
|
||||||
|
}
|
||||||
|
|
||||||
|
Conditions.Deafened = {
|
||||||
|
description: ["A deafened creature can't hear and automatically fails any ability check that requires hearing"]
|
||||||
|
}
|
||||||
|
|
||||||
|
Conditions.Frightened = {
|
||||||
|
description: []
|
||||||
|
}
|
||||||
|
|
||||||
|
Conditions.Grappled = {
|
||||||
|
description: [
|
||||||
|
"A grappled creature's speed becomes 0, and it can't benefit from any bonuses to its speed",
|
||||||
|
"The condition ends if the grappler is incapacitated",
|
||||||
|
"The conditions also ends if if an effect removes the\
|
||||||
|
grappled creature from the reach of the grappler or grappling\
|
||||||
|
effect, such as when a creature is hurled\
|
||||||
|
away by the thunderwave spell."
|
||||||
|
],
|
||||||
|
effects: [
|
||||||
|
{stat: "attributes.speed.maximum", value: 0}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Conditions.Incapacitated = {
|
||||||
|
effects: [
|
||||||
|
{stat: "attributes.actions.maximum", value: 0},
|
||||||
|
{stat: "attributes.reactions.maximum", value: 0},
|
||||||
|
{stat: "attributes.bonusActions.maximum", value: 0}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Conditions.Invisible = {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Conditions.Paralyzed = {
|
||||||
|
//implies incapacitated
|
||||||
|
effects: [
|
||||||
|
{stat: "skills.strengthSave.fail", value: 1},
|
||||||
|
{stat: "skills.dexteritySave.fail", value: 1},
|
||||||
|
{stat: "attributes.speed.maximum", value: 0}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
_.extend(Conditions.Paralyzed, Conditions.Incapacitated);
|
||||||
|
|
||||||
|
Conditions.Petrified = {
|
||||||
|
|
||||||
|
effects: [
|
||||||
|
{stat: "attributes.weight.mul", value: 10},
|
||||||
|
{stat: "attributes.ageRate.max", value: 0},
|
||||||
|
{stat: "attributes.ageRate.min", value: 0},
|
||||||
|
{stat: "skills.strengthSave.fail", value: 1},
|
||||||
|
{stat: "skills.dexteritySave.fail", value: 1},
|
||||||
|
{stat: "attributes.speed.maximum", value: 0}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
for(var i = 0, l = DamageTypes.length; i < l; i++){
|
||||||
|
var str = "vulnerability." + DamageTypes[i] + ".mul"
|
||||||
|
Conditions.Petrified.effects.push({stat: str, value: 0.5});
|
||||||
|
}
|
||||||
|
_.extend(Conditions.Petrified, Conditions.Incapacitated);
|
||||||
|
|
||||||
|
Conditions.Poisoned = {
|
||||||
|
description: []
|
||||||
|
}
|
||||||
|
|
||||||
|
Conditions.Prone = {
|
||||||
|
description: [],
|
||||||
|
effects: [
|
||||||
|
{stat: "skills.strengthAttack.disadvantage", value: 1},
|
||||||
|
{stat: "skills.dexterityAttack.disadvantage", value: 1},
|
||||||
|
{stat: "skills.rangedAttack.disadvantage", value: 1}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Conditions.Restrained = {
|
||||||
|
effects: [
|
||||||
|
{stat: "attributes.speed.maximum", value: 0}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Conditions.Stunned = {
|
||||||
|
//implies incapacitated
|
||||||
|
effects: [
|
||||||
|
{stat: "attributes.speed.maximum", value: 0},
|
||||||
|
{stat: "skills.strengthSave.fail", value: 1},
|
||||||
|
{stat: "skills.dexteritySave.fail", value: 1}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
_.extend(Conditions.Stunned, Conditions.Incapacitated);
|
||||||
|
|
||||||
|
Conditions.Unconscious = {
|
||||||
|
//implies incapacitated
|
||||||
|
//implies prone
|
||||||
|
effects: [
|
||||||
|
{stat: "attributes.speed.maximum", value: 0},
|
||||||
|
{stat: "skills.strengthSave.fail", value: 1},
|
||||||
|
{stat: "skills.dexteritySave.fail", value: 1}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
_.extend(Conditions.Unconscious, Conditions.Incapacitated);
|
||||||
|
_.extend(Conditions.Unconscious, Conditions.Prone);
|
||||||
52
rpg-docs/Model/Character/Experience.js
Normal file
52
rpg-docs/Model/Character/Experience.js
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
Experience = function(){
|
||||||
|
this.total = 0;
|
||||||
|
this.events = [];
|
||||||
|
this.level = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Experience.prototype.addEvent = function(description, value){
|
||||||
|
this.events.push({
|
||||||
|
"description": description,
|
||||||
|
"value": value
|
||||||
|
})
|
||||||
|
this.total += value;
|
||||||
|
this.level = this.getLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
Experience.prototype.removeEvent = function(index){
|
||||||
|
this.total -= this.events[index].value;
|
||||||
|
this.events.splice(index,1);
|
||||||
|
this.level = this.getLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
Experience.prototype.refreshTotal = function(){
|
||||||
|
this.total = 0;
|
||||||
|
for(var i = 0, length = this.events.length; i < length; i++){
|
||||||
|
this.total += this.events[i].value;
|
||||||
|
}
|
||||||
|
this.level = this.getLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
Experience.prototype.getLevel = function(){
|
||||||
|
var xp = this.total;
|
||||||
|
if(xp > 355000) return 20;
|
||||||
|
if(xp > 305000) return 19;
|
||||||
|
if(xp > 265000) return 18;
|
||||||
|
if(xp > 225000) return 17;
|
||||||
|
if(xp > 195000) return 16;
|
||||||
|
if(xp > 165000) return 15;
|
||||||
|
if(xp > 140000) return 14;
|
||||||
|
if(xp > 120000) return 13;
|
||||||
|
if(xp > 100000) return 12;
|
||||||
|
if(xp > 85000) return 11;
|
||||||
|
if(xp > 64000) return 10;
|
||||||
|
if(xp > 48000) return 9;
|
||||||
|
if(xp > 34000) return 8;
|
||||||
|
if(xp > 23000) return 7;
|
||||||
|
if(xp > 14000) return 6;
|
||||||
|
if(xp > 6500) return 5;
|
||||||
|
if(xp > 2700) return 4;
|
||||||
|
if(xp > 900) return 3;
|
||||||
|
if(xp > 300) return 2;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
4
rpg-docs/Model/Character/Feature.js
Normal file
4
rpg-docs/Model/Character/Feature.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
Feature = function(name){
|
||||||
|
this.name = name;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
6
rpg-docs/Model/Character/HitDice.js
Normal file
6
rpg-docs/Model/Character/HitDice.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
HitDice = function(sides){
|
||||||
|
this.sides = sides;
|
||||||
|
this.bonus = 0;
|
||||||
|
this.number = 0;
|
||||||
|
this.max = 0;
|
||||||
|
}
|
||||||
11
rpg-docs/Model/Character/Spell.js
Normal file
11
rpg-docs/Model/Character/Spell.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
Spell = function(name){
|
||||||
|
this.name = name;
|
||||||
|
this.level = 0;
|
||||||
|
this.school = "";
|
||||||
|
this.range = "";
|
||||||
|
this.verbal = false;
|
||||||
|
this.somatic = false;
|
||||||
|
this.material = false;
|
||||||
|
this.duration = "";
|
||||||
|
this.description = "";
|
||||||
|
}
|
||||||
7
rpg-docs/Model/Inventory/Containers.js
Normal file
7
rpg-docs/Model/Inventory/Containers.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Containers = new Meteor.Collection('containers');
|
||||||
|
|
||||||
|
Container = function(name, owner){
|
||||||
|
this.name = name;
|
||||||
|
this.owner = owner;
|
||||||
|
this.isCarried = true;
|
||||||
|
}
|
||||||
10
rpg-docs/Model/Inventory/Items.js
Normal file
10
rpg-docs/Model/Inventory/Items.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Items = new Meteor.Collection('items');
|
||||||
|
|
||||||
|
Item = function(name, container){
|
||||||
|
this.name = name;
|
||||||
|
this.container = container;
|
||||||
|
this.quantity = 1;
|
||||||
|
this.weight = 0.0;
|
||||||
|
this.value = 0;//value in gold pieces
|
||||||
|
this.description = "";
|
||||||
|
}
|
||||||
44
rpg-docs/Model/Utility/dice.js
Normal file
44
rpg-docs/Model/Utility/dice.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
roll = function (n, d){
|
||||||
|
if(!isNaN(n)){
|
||||||
|
//first digit is a number
|
||||||
|
if(d === undefined){
|
||||||
|
d = n;
|
||||||
|
n = 1;
|
||||||
|
}
|
||||||
|
if(n > 500){
|
||||||
|
console.log(n + " > 500, cannot lift that many dice to roll them");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var result = {sum: 0, rolls: []};
|
||||||
|
for (var i = 0; i < n; i++){
|
||||||
|
var roll = Math.floor(Random.fraction() * d + 1)
|
||||||
|
result.sum += roll;
|
||||||
|
result.rolls.push(roll);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
console.log("rolling dice failed for inputs: ", n, d);
|
||||||
|
return {sum: 0, rolls: []};
|
||||||
|
}
|
||||||
|
|
||||||
|
rollDropLow = function(n, d, drop){
|
||||||
|
var r = roll(n,d)
|
||||||
|
r.rolls.sort(function(a, b){return a-b}); //sort ascending
|
||||||
|
r.rolls.splice(0, drop); //remove the lowest elements
|
||||||
|
r.sum = 0;
|
||||||
|
for (var i = 0, l = r.rolls.length; i , l ; i++){
|
||||||
|
sum += r.rolls[i];
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
rollDropHigh = function(n, d, drop){
|
||||||
|
var r = roll(n,d)
|
||||||
|
r.rolls.sort(function(a, b){return b-a}); //sort descending
|
||||||
|
r.rolls.splice(0, drop); //remove the highest elements
|
||||||
|
r.sum = 0;
|
||||||
|
for (var i = 0, l = r.rolls.length; i , l ; i++){
|
||||||
|
sum += r.rolls[i];
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
20
rpg-docs/Routes/Routes.js
Normal file
20
rpg-docs/Routes/Routes.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
Router.map( function () {
|
||||||
|
this.route('home', {
|
||||||
|
path: '/',
|
||||||
|
data: { characters: function(){
|
||||||
|
console.log('id ' + Meteor.userId());
|
||||||
|
return Characters.find({owner: Meteor.userId()})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.route('character', {
|
||||||
|
path: '/character/:_id',
|
||||||
|
notFoundTemplate: 'characterNotFound',
|
||||||
|
data: function() {
|
||||||
|
character = Characters.findOne({_id: this.params._id});
|
||||||
|
if (character) character.items = Items.find({owner: this.params._id});
|
||||||
|
return character;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
81
rpg-docs/client/css/character.css
Normal file
81
rpg-docs/client/css/character.css
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
.flexContainer {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#abilityScores {
|
||||||
|
text-align: center;
|
||||||
|
flex-basis: 120px;
|
||||||
|
flex-grow: 1;
|
||||||
|
max-width: 340px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Float boxes are indivisble, have shadows*/
|
||||||
|
.floatBox{
|
||||||
|
border: 2px solid black;
|
||||||
|
border-radius: 0px 0px 10px 10px;
|
||||||
|
padding: 5px;
|
||||||
|
margin: 5px;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* headings in floatboxes */
|
||||||
|
.floatBox h2{
|
||||||
|
background: black;
|
||||||
|
color: white;
|
||||||
|
font-size: 1em;
|
||||||
|
margin: 0px -5px 0px -5px;
|
||||||
|
padding: 2px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.floatBox h2:first-child{
|
||||||
|
margin: -5px -5px 0px -5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.floatBox.rounded {
|
||||||
|
border-radius: 10px;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ability scores */
|
||||||
|
.floatBox.ability {
|
||||||
|
border-radius: 10px;
|
||||||
|
width: 85px;
|
||||||
|
text-align: center;
|
||||||
|
margin: 5px 5px 20px 5px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.abilityName {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.abilityScore {
|
||||||
|
font-size: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.abilityMod {
|
||||||
|
margin: 0 auto -15px;
|
||||||
|
padding: 2px;
|
||||||
|
border: 2px solid black;
|
||||||
|
border-radius: 5px;
|
||||||
|
background: white;
|
||||||
|
width: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stats */
|
||||||
|
#armorClassBox {
|
||||||
|
width: 90px;
|
||||||
|
height: 100px;
|
||||||
|
background-image: url('/svg/ac.svg');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statValue {
|
||||||
|
font-size: 2em;
|
||||||
|
}
|
||||||
7
rpg-docs/client/css/general.css
Normal file
7
rpg-docs/client/css/general.css
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
root {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
68
rpg-docs/client/views/character/abilities.html
Normal file
68
rpg-docs/client/views/character/abilities.html
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<template name = "abilities">
|
||||||
|
<div class="ability floatBox">
|
||||||
|
<div class ="abilityName">
|
||||||
|
Strength
|
||||||
|
</div>
|
||||||
|
<div class="abilityScore">
|
||||||
|
{{attributeValue attributes.strength}}
|
||||||
|
</div>
|
||||||
|
<div class="abilityMod">
|
||||||
|
{{abilityMod attributes.strength}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ability floatBox">
|
||||||
|
<div class ="abilityName">
|
||||||
|
Dexterity
|
||||||
|
</div>
|
||||||
|
<div class="abilityScore">
|
||||||
|
{{attributeValue attributes.dexterity}}
|
||||||
|
</div>
|
||||||
|
<div class="abilityMod">
|
||||||
|
{{abilityMod attributes.dexterity}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ability floatBox">
|
||||||
|
<div class ="abilityName">
|
||||||
|
Constitution
|
||||||
|
</div>
|
||||||
|
<div class="abilityScore">
|
||||||
|
{{attributeValue attributes.constitution}}
|
||||||
|
</div>
|
||||||
|
<div class="abilityMod">
|
||||||
|
{{abilityMod attributes.constitution}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ability floatBox">
|
||||||
|
<div class ="abilityName">
|
||||||
|
Intelligence
|
||||||
|
</div>
|
||||||
|
<div class="abilityScore">
|
||||||
|
{{attributeValue attributes.intelligence}}
|
||||||
|
</div>
|
||||||
|
<div class="abilityMod">
|
||||||
|
{{abilityMod attributes.intelligence}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ability floatBox">
|
||||||
|
<div class ="abilityName">
|
||||||
|
Wisdom
|
||||||
|
</div>
|
||||||
|
<div class="abilityScore">
|
||||||
|
{{attributeValue attributes.wisdom}}
|
||||||
|
</div>
|
||||||
|
<div class="abilityMod">
|
||||||
|
{{abilityMod attributes.wisdom}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ability floatBox">
|
||||||
|
<div class ="abilityName">
|
||||||
|
Charisma
|
||||||
|
</div>
|
||||||
|
<div class="abilityScore">
|
||||||
|
{{attributeValue attributes.charisma}}
|
||||||
|
</div>
|
||||||
|
<div class="abilityMod">
|
||||||
|
{{abilityMod attributes.charisma}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
21
rpg-docs/client/views/character/character.html
Normal file
21
rpg-docs/client/views/character/character.html
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<template name="character">
|
||||||
|
<div>
|
||||||
|
{{> characterName}}
|
||||||
|
</div>
|
||||||
|
<div class="flexContainer">
|
||||||
|
<div id="abilityScores" class="flexItem">
|
||||||
|
{{> abilities}}
|
||||||
|
</div>
|
||||||
|
<div class="flexItem">
|
||||||
|
<div>
|
||||||
|
Proficiency Bonus {{proficiencyBonus}}
|
||||||
|
</div>
|
||||||
|
<div id="savesAndSkills" class="floatBox">
|
||||||
|
{{> savesAndSkills}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="stats" class="flexItem">
|
||||||
|
{{> characterStats}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
11
rpg-docs/client/views/character/characterName.html
Normal file
11
rpg-docs/client/views/character/characterName.html
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<template name="characterName">
|
||||||
|
<div id="level">
|
||||||
|
{{experience.level}}
|
||||||
|
</div>
|
||||||
|
<div id="name">
|
||||||
|
{{name}}
|
||||||
|
</div>
|
||||||
|
<div id="role">
|
||||||
|
{{alignment}} {{gender}} {{race}} {{#each class}} {{this}} {{/each}}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
50
rpg-docs/client/views/character/characterStats.html
Normal file
50
rpg-docs/client/views/character/characterStats.html
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<template name="characterStats">
|
||||||
|
<div id="hitPointBox">
|
||||||
|
Hit Points
|
||||||
|
<div id="hitPoints">
|
||||||
|
<input type="number" value={{attributeValue attributes.hitPoints}}>
|
||||||
|
</div>
|
||||||
|
<div id="maxHitPoints">
|
||||||
|
{{attributeValue attributes.maxHitPoints}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="armorClassBox">
|
||||||
|
<div id="armorClass">
|
||||||
|
<div id="armorClassValue" class="statValue">
|
||||||
|
{{attributeValue attributes.armor}}
|
||||||
|
</div>
|
||||||
|
<div id="armorClassLabel">
|
||||||
|
Armor<br>Class
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="amorBox">
|
||||||
|
</div>
|
||||||
|
<div id="initiativeBox" class="floatBox rounded">
|
||||||
|
<div class="statValue">
|
||||||
|
{{skillMod skills.initiative}}
|
||||||
|
</div>
|
||||||
|
Initiative
|
||||||
|
</div>
|
||||||
|
<div id="speedBox" class="floatBox rounded">
|
||||||
|
<div class="statValue">
|
||||||
|
{{attributeValue attributes.speed}}
|
||||||
|
</div>
|
||||||
|
Speed
|
||||||
|
</div>
|
||||||
|
<div id="passivePerceptionBox" class="floatBox rounded">
|
||||||
|
<div class="statValue">
|
||||||
|
{{passiveSkill skills.perception}}
|
||||||
|
</div>
|
||||||
|
Passive Perception
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
Death Saves
|
||||||
|
</div><div>
|
||||||
|
Successes {{deathSaveSuccess}}
|
||||||
|
</div><div>
|
||||||
|
Failures {{deathSaveFail}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
52
rpg-docs/client/views/character/savesAndSkills.html
Normal file
52
rpg-docs/client/views/character/savesAndSkills.html
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
<template name="savesAndSkills">
|
||||||
|
<h2>Saving Throws</h2>
|
||||||
|
<div>
|
||||||
|
Strength Save {{skillMod skills.strengthSave}}
|
||||||
|
</div><div>
|
||||||
|
Dexterity Save {{skillMod skills.dexteritySave}}
|
||||||
|
</div><div>
|
||||||
|
Constitution Save {{skillMod skills.constitutionSave}}
|
||||||
|
</div><div>
|
||||||
|
Intelligence Save {{skillMod skills.intelligenceSave}}
|
||||||
|
</div><div>
|
||||||
|
Wisdom Save {{skillMod skills.wisdomSave}}
|
||||||
|
</div><div>
|
||||||
|
Charisma Save {{skillMod skills.charismaSave}}
|
||||||
|
</div>
|
||||||
|
<h2>Skills</h2>
|
||||||
|
<div>
|
||||||
|
Acrobatics {{skillMod skills.acrobatics}}
|
||||||
|
</div><div>
|
||||||
|
Animal Handling {{skillMod skills.animalHandling}}
|
||||||
|
</div><div>
|
||||||
|
Arcana {{skillMod skills.arcana}}
|
||||||
|
</div><div>
|
||||||
|
Athletics {{skillMod skills.athletics}}
|
||||||
|
</div><div>
|
||||||
|
Deception {{skillMod skills.deception}}
|
||||||
|
</div><div>
|
||||||
|
History {{skillMod skills.history}}
|
||||||
|
</div><div>
|
||||||
|
Insight {{skillMod skills.insight}}
|
||||||
|
</div><div>
|
||||||
|
Intimidation {{skillMod skills.intimidation}}
|
||||||
|
</div><div>
|
||||||
|
Investigation {{skillMod skills.investigation}}
|
||||||
|
</div><div>
|
||||||
|
Medicine {{skillMod skills.medicine}}
|
||||||
|
</div><div>
|
||||||
|
Nature {{skillMod skills.nature}}
|
||||||
|
</div><div>
|
||||||
|
Perception {{skillMod skills.perception}}
|
||||||
|
</div><div>
|
||||||
|
Persuasion {{skillMod skills.persuasion}}
|
||||||
|
</div><div>
|
||||||
|
Religion {{skillMod skills.religion}}
|
||||||
|
</div><div>
|
||||||
|
Sleight of Hand {{skillMod skills.sleightOfHand}}
|
||||||
|
</div><div>
|
||||||
|
Stealth {{skillMod skills.stealth}}
|
||||||
|
</div><div>
|
||||||
|
Survival {{skillMod skills.survival}}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
10
rpg-docs/client/views/home/home.html
Normal file
10
rpg-docs/client/views/home/home.html
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<template name="home">
|
||||||
|
{{>loginButtons}}
|
||||||
|
<div>
|
||||||
|
{{# each characters}}
|
||||||
|
<li><a href="{{ pathFor 'character' }} ">{{_id}}</a></li>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
<input id="addCharacter" type="button" value="Add Character">
|
||||||
|
<input id="nukeCharacters" type="button" value="Clear all characters">
|
||||||
|
</template>
|
||||||
11
rpg-docs/client/views/home/home.js
Normal file
11
rpg-docs/client/views/home/home.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
Template.home.events({
|
||||||
|
"click #addCharacter": function (event, template) {
|
||||||
|
Characters.insert(new Character(Meteor.userId()));
|
||||||
|
},
|
||||||
|
"click #nukeCharacters": function(event, template){
|
||||||
|
while(true){
|
||||||
|
if(!Characters.findOne()) break;
|
||||||
|
Characters.remove(Characters.findOne()._id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
4
rpg-docs/client/views/index.html
Normal file
4
rpg-docs/client/views/index.html
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<head>
|
||||||
|
<title>RPG Docs</title>
|
||||||
|
<meta name="viewport" content="width=device-width">
|
||||||
|
</head>
|
||||||
36
rpg-docs/public/svg/ac.svg
Normal file
36
rpg-docs/public/svg/ac.svg
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
version="1.1"
|
||||||
|
width="90"
|
||||||
|
height="100"
|
||||||
|
id="svg2">
|
||||||
|
<defs
|
||||||
|
id="defs4" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
transform="translate(0,-952.36218)"
|
||||||
|
id="layer1">
|
||||||
|
<path
|
||||||
|
d="m 15,962.36218 c -0.870551,10.48175 -8.4321358,17.45735 -13,18 l 0,23.00002 c 5.0277793,16.7056 22.831231,42.1683 43,47 19.444592,-3.432 35.858861,-26.1733 43,-47 l 0,-23.00002 c -7.815979,-1.16093 -10.356092,-11.69154 -12,-18 l -31,-8 z"
|
||||||
|
id="path2985"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
2
startup.sh
Normal file
2
startup.sh
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
cd rpg-docs
|
||||||
|
export MONGO_URL=mongodb://thaum:pandas@linus.mongohq.com:10050/green_meteor
|
||||||
Reference in New Issue
Block a user