Merge branch 'feature-library'

This commit is contained in:
Stefan Zermatten
2017-04-24 14:57:34 +02:00
28 changed files with 1886 additions and 53 deletions

14
.codio
View File

@@ -1,14 +0,0 @@
{
// Configure your Run and Preview buttons here.
// Run button configuration
"commands": {
"Run Meteor": "cd rpg-docs \n ROOT_URL=http://period-sheriff.codio.io:3000 meteor"
},
// Preview button configuration
"preview": {
"Prieview": "http://period-sheriff-3000.codio.io",
"Ungit": "https://period-sheriff-9501.codio.io/#/repository?path=/home/codio/workspace"
}
}

View File

@@ -0,0 +1,709 @@
[
{
"name": "Abacus",
"plural": "Abaci",
"description": "",
"value": 2,
"weight": 2
},
{
"name": "Acid (vial)",
"plural": "Acid (vials)",
"description": "As an action, you can splash the contents of this vial onto a creature within 5 feet of you or throw the vial up to 20 feet, shattering it on impact. In either case, make a ranged attack against a creature or object, treating the acid as an improvised weapon. On a hit, the target takes 2d6 acid damage.",
"value": 25,
"weight": 1
},
{
"name": "Alchemists fire (flask)",
"plural": "Alchemists fire (flasks)",
"description": "This sticky, adhesive fluid ignites when exposed to air. As an action, you can throw this flask up to 20 feet, shattering it on impact. Make a ranged attack against a creature or object, treating the alchemists fire as an improvised weapon. On a hit, the target takes 1d4 fire damage at the start of each of its turns. A creature can end this damage by using its action to make a DC 10 Dexterity check to extinguish the flames.",
"value": 50,
"weight": 1
},
{
"name": "Arrows (20)",
"plural": "Arrows (20)",
"description": "",
"value": 1,
"weight": 1
},
{
"name": "Blowgun needles (5)",
"plural": "Blowgun needles (5)",
"description": "",
"value": 1,
"weight": 1
},
{
"name": "Crossbow bolts (20)",
"plural": "Crossbow bolts (20)",
"description": "",
"value": 1,
"weight": 1.5
},
{
"name": "Sling bullets (20)",
"plural": "Sling bullets (20)",
"description": "",
"value": 0.04,
"weight": 1.5
},
{
"name": "Antitoxin (vial)",
"plural": "Antitoxin (vials)",
"description": "A creature that drinks this vial of liquid gains advantage on saving throws against poison for 1 hour. It confers no benefit to undead or constructs.",
"value": 50,
"weight": 0
},
{
"name": "Arcane focus Crystal",
"plural": "Arcane focus Crystals",
"description": "An arcane focus is a special item — an orb, a crystal, a rod, a specially constructed staff, a wand-like length of wood, or some similar item — designed to channel the power of arcane spells. A sorcerer, warlock, or wizard can use such an item as a spellcasting focus.",
"value": 10,
"weight": 1
},
{
"name": "Arcane focus Orb",
"plural": "Arcane focus Orbs",
"description": "An arcane focus is a special item — an orb, a crystal, a rod, a specially constructed staff, a wand-like length of wood, or some similar item — designed to channel the power of arcane spells. A sorcerer, warlock, or wizard can use such an item as a spellcasting focus.",
"value": 20,
"weight": 3
},
{
"name": "Arcane focus Rod",
"plural": "Arcane focus Rods",
"description": "An arcane focus is a special item — an orb, a crystal, a rod, a specially constructed staff, a wand-like length of wood, or some similar item — designed to channel the power of arcane spells. A sorcerer, warlock, or wizard can use such an item as a spellcasting focus.",
"value": 10,
"weight": 2
},
{
"name": "Arcane focus Staff",
"plural": "Arcane focus Staffs",
"description": "An arcane focus is a special item — an orb, a crystal, a rod, a specially constructed staff, a wand-like length of wood, or some similar item — designed to channel the power of arcane spells. A sorcerer, warlock, or wizard can use such an item as a spellcasting focus.",
"value": 5,
"weight": 4
},
{
"name": "Arcane focus Wand",
"plural": "Arcane focus Wands",
"description": "An arcane focus is a special item — an orb, a crystal, a rod, a specially constructed staff, a wand-like length of wood, or some similar item — designed to channel the power of arcane spells. A sorcerer, warlock, or wizard can use such an item as a spellcasting focus.",
"value": 10,
"weight": 1
},
{
"name": "Backpack",
"plural": "Backpacks",
"description": "",
"value": 2,
"weight": 5
},
{
"name": "Ball bearings (bag of 1,000)",
"plural": "Ball bearings (bags of 1,000)",
"description": "As an action, you can spill these tiny metal balls from their pouch to cover a level, square area that is 10 feet on a side. A creature moving across the covered area must succeed on a DC 10 Dexterity saving throw or fall Prone. A creature moving through the area at half speed doesnt need to make the save.",
"value": 1,
"weight": 2
},
{
"name": "Barrel",
"plural": "Barrels",
"description": "",
"value": 2,
"weight": 70
},
{
"name": "Basket",
"plural": "Baskets",
"description": "",
"value": 0.4,
"weight": 2
},
{
"name": "Bedroll",
"plural": "Bedrolls",
"description": "",
"value": 1,
"weight": 7
},
{
"name": "Bell",
"plural": "Bells",
"description": "",
"value": 1,
"weight": 0
},
{
"name": "Blanket",
"plural": "Blankets",
"description": "",
"value": 0.5,
"weight": 3
},
{
"name": "Block and tackle",
"plural": "Block and tackle sets",
"description": "A set of pulleys with a cable threaded through them and a hook to attach to objects, a block and tackle allows you to hoist up to four times the weight you can normally lift.",
"value": 1,
"weight": 5
},
{
"name": "Book",
"plural": "Books",
"description": "A book might contain poetry, historical accounts, information pertaining to a particular field of lore, diagrams and notes on gnomish contraptions, or just about anything else that can be represented using text or pictures. A book of spells is a spellbook.",
"value": 25,
"weight": 5
},
{
"name": "Bottle, glass",
"plural": "Bottles, glass",
"description": "",
"value": 2,
"weight": 2
},
{
"name": "Bucket",
"plural": "Buckets",
"description": "",
"value": 0.05,
"weight": 2
},
{
"name": "Caltrops (bag of 20)",
"plural": "Caltrops (bags of 20)",
"description": "As an action, you can spread a bag of caltrops to cover a square area that is 5 feet on a side. Any creature that enters the area must succeed on a DC 15 Dexterity saving throw or stop moving this turn and take 1 piercing damage. Taking this damage reduces the creatures walking speed by 10 feet until the creature regains at least 1 hit point. A creature moving through the area at half speed doesnt need to make the save.",
"value": 1,
"weight": 2
},
{
"name": "Candle",
"plural": "Candles",
"description": "For 1 hour, a candle sheds bright light in a 5-foot radius and dim light for an additional 5 feet.",
"value": 0.01,
"weight": 0
},
{
"name": "Case, crossbow bolt",
"plural": "Cases, crossbow bolt",
"description": "This wooden case can hold up to twenty crossbow bolts.",
"value": 1,
"weight": 1
},
{
"name": "Case, map or scroll",
"plural": "Cases, map or scroll",
"description": "This cylindrical leather case can hold up to ten rolled-up sheets of paper or five rolled-up sheets of parchment.",
"value": 1,
"weight": 1
},
{
"name": "Chain (10 feet)",
"plural": "Chains (10 feet)",
"description": "A chain has 10 hit points. It can be burst with a successful DC 20 Strength check.",
"value": 5,
"weight": 10
},
{
"name": "Chalk (1 piece)",
"plural": "Pieces of chalk",
"description": "",
"value": 0.01,
"weight": 0
},
{
"name": "Chest",
"plural": "Chests",
"description": "",
"value": 5,
"weight": 25
},
{
"name": "Climbers kit",
"plural": "Climbers kits",
"description": "A climbers kit includes special pitons, boot tips, gloves, and a harness. You can use the climbers kit as an action to anchor yourself; when you do, you cant fall more than 25 feet from the point where you anchored yourself, and you cant climb more than 25 feet away from that point without undoing the anchor.",
"value": 25,
"weight": 12
},
{
"name": "Clothes, common",
"plural": "Clothes, common",
"description": "",
"value": 0.5,
"weight": 3
},
{
"name": "Clothes, costume",
"plural": "Clothes, costume",
"description": "",
"value": 5,
"weight": 4
},
{
"name": "Clothes, fine",
"plural": "Clothes, fine",
"description": "",
"value": 15,
"weight": 6
},
{
"name": "Clothes, travelers",
"plural": "Clothes, travelers",
"description": "",
"value": 2,
"weight": 4
},
{
"name": "Component pouch",
"plural": "Component pouches",
"description": "A component pouch is a small, watertight leather belt pouch that has compartments to hold all the material components and other special items you need to cast your spells, except for those components that have a specific cost (as indicated in a spells description).",
"value": 25,
"weight": 2
},
{
"name": "Crowbar",
"plural": "Crowbars",
"description": "Using a crowbar grants advantage to Strength checks where the crowbars leverage can be applied.",
"value": 2,
"weight": 5
},
{
"name": "Sprig of mistletoe",
"plural": "Sprigs of mistletoe",
"description": "A druidic focus might be a sprig of mistletoe or holly, a wand or scepter made of yew or another special wood, a staff drawn whole out of a living tree, or a totem object incorporating feathers, fur, bones, and teeth from sacred animals. A druid can use such an object as a spellcasting focus.",
"value": 1,
"weight": 0
},
{
"name": "Totem",
"plural": "Totems",
"description": "A druidic focus might be a sprig of mistletoe or holly, a wand or scepter made of yew or another special wood, a staff drawn whole out of a living tree, or a totem object incorporating feathers, fur, bones, and teeth from sacred animals. A druid can use such an object as a spellcasting focus.",
"value": 1,
"weight": 0
},
{
"name": "Wooden staff",
"plural": "Wooden staffs",
"description": "A druidic focus might be a sprig of mistletoe or holly, a wand or scepter made of yew or another special wood, a staff drawn whole out of a living tree, or a totem object incorporating feathers, fur, bones, and teeth from sacred animals. A druid can use such an object as a spellcasting focus.",
"value": 5,
"weight": 4
},
{
"name": "Yew wand",
"plural": "Yew wands",
"description": "A druidic focus might be a sprig of mistletoe or holly, a wand or scepter made of yew or another special wood, a staff drawn whole out of a living tree, or a totem object incorporating feathers, fur, bones, and teeth from sacred animals. A druid can use such an object as a spellcasting focus.",
"value": 10,
"weight": 1
},
{
"name": "Fishing tackle",
"plural": "Fishing tackles",
"description": "This kit includes a wooden rod, silken line, corkwood bobbers, steel hooks, lead sinkers, velvet lures, and narrow netting.",
"value": 1,
"weight": 4
},
{
"name": "Flask",
"plural": "Flasks",
"description": "",
"value": 0.02,
"weight": 1
},
{
"name": "Tankard",
"plural": "Tankards",
"description": "",
"value": 0.02,
"weight": 1
},
{
"name": "Grappling hook",
"plural": "Grappling hooks",
"description": "",
"value": 2,
"weight": 4
},
{
"name": "Hammer",
"plural": "Hammers",
"description": "",
"value": 1,
"weight": 3
},
{
"name": "Hammer, sledge",
"plural": "Hammers, sledge",
"description": "",
"value": 2,
"weight": 10
},
{
"name": "Healers kit",
"plural": "Healers kits",
"description": "This kit is a leather pouch containing bandages, salves, and splints. The kit has ten uses. As an action, you can expend one use of the kit to stabilize a creature that has 0 hit points, without needing to make a Wisdom (Medicine) check.",
"value": 5,
"weight": 3
},
{
"name": "Holy amulet",
"plural": "Holy amulets",
"description": "A holy symbol is a representation of a god or pantheon. It might be an amulet depicting a symbol representing a deity, the same symbol carefully engraved or inlaid as an emblem on a shield, or a tiny box holding a fragment of a sacred relic. Fantasy-Historical Pantheons lists the symbols commonly associated with many gods in the multiverse. A cleric or paladin can use a holy symbol as a spellcasting focus. To use the symbol in this way, the caster must hold it in hand, wear it visibly, or bear it on a shield.",
"value": 5,
"weight": 1
},
{
"name": "Holy emblem",
"plural": "Holy emblems",
"description": "A holy symbol is a representation of a god or pantheon. It might be an amulet depicting a symbol representing a deity, the same symbol carefully engraved or inlaid as an emblem on a shield, or a tiny box holding a fragment of a sacred relic. Fantasy-Historical Pantheons lists the symbols commonly associated with many gods in the multiverse. A cleric or paladin can use a holy symbol as a spellcasting focus. To use the symbol in this way, the caster must hold it in hand, wear it visibly, or bear it on a shield.",
"value": 5,
"weight": 0
},
{
"name": "Holy reliquary",
"plural": "Holy reliquaries",
"description": "A holy symbol is a representation of a god or pantheon. It might be an amulet depicting a symbol representing a deity, the same symbol carefully engraved or inlaid as an emblem on a shield, or a tiny box holding a fragment of a sacred relic. Fantasy-Historical Pantheons lists the symbols commonly associated with many gods in the multiverse. A cleric or paladin can use a holy symbol as a spellcasting focus. To use the symbol in this way, the caster must hold it in hand, wear it visibly, or bear it on a shield.",
"value": 5,
"weight": 2
},
{
"name": "Holy water (flask)",
"plural": "Holy water (flasks)",
"description": "As an action, you can splash the contents of this flask onto a creature within 5 feet of you or throw it up to 20 feet, shattering it on impact. In either case, make a ranged attack against a target creature, treating the holy water as an improvised weapon. If the target is a fiend or undead, it takes 2d6 radiant damage. A cleric or paladin may create holy water by performing a special ritual. The ritual takes 1 hour to perform, uses 25 gp worth of powdered silver, and requires the caster to expend a 1st-level spell slot.",
"value": 25,
"weight": 1
},
{
"name": "Hourglass",
"plural": "Hourglasses",
"description": "",
"value": 25,
"weight": 1
},
{
"name": "Hunting trap",
"plural": "Hunting traps",
"description": "When you use your action to set it, this trap forms a saw-toothed steel ring that snaps shut when a creature steps on a pressure plate in the center. The trap is affixed by a heavy chain to an immobile object, such as a tree or a spike driven into the ground. A creature that steps on the plate must succeed on a DC 13 Dexterity saving throw or take 1d4 piercing damage and stop moving. Thereafter, until the creature breaks free of the trap, its movement is limited by the length of the chain (typically 3 feet long). A creature can use its action to make a DC 13 Strength check, freeing itself or another creature within its reach on a success. Each failed check deals 1 piercing damage to the trapped creature.",
"value": 5,
"weight": 25
},
{
"name": "Ink (1 ounce bottle)",
"plural": "Ink (1 ounce bottles)",
"description": "",
"value": 10,
"weight": 0
},
{
"name": "Ink pen",
"plural": "Ink pens",
"description": "",
"value": 0.02,
"weight": 0
},
{
"name": "Jug",
"plural": "Jugs",
"description": "",
"value": 0.02,
"weight": 4
},
{
"name": "Pitcher",
"plural": "Pitchers",
"description": "",
"value": 0.02,
"weight": 4
},
{
"name": "Ladder (10-foot)",
"plural": "Ladders (10-foot)",
"description": "",
"value": 0.1,
"weight": 25
},
{
"name": "Lamp",
"plural": "Lamps",
"description": "A lamp casts bright light in a 15-foot radius and dim light for an additional 30 feet. Once lit, it burns for 6 hours on a flask (1 pint) of oil.",
"value": 0.5,
"weight": 1
},
{
"name": "Lantern, bullseye",
"plural": "Lanterns, bullseye",
"description": "A bullseye lantern casts bright light in a 60-foot cone and dim light for an additional 60 feet. Once lit, it burns for 6 hours on a flask (1 pint) of oil.",
"value": 10,
"weight": 2
},
{
"name": "Lantern, hooded",
"plural": "Lanterns, hooded",
"description": "A hooded lantern casts bright light in a 30-foot radius and dim light for an additional 30 feet. Once lit, it burns for 6 hours on a flask (1 pint) of oil. As an action, you can lower the hood, reducing the light to dim light in a 5-foot radius.",
"value": 5,
"weight": 2
},
{
"name": "Lock",
"plural": "Locks",
"description": "A key is provided with the lock. Without the key, a creature proficient with thieves tools can pick this lock with a successful DC 15 Dexterity check. Your GM may decide that better locks are available for higher prices.",
"value": 10,
"weight": 1
},
{
"name": "Magnifying glass",
"plural": "Magnifying glasses",
"description": "This lens allows a closer look at small objects. It is also useful as a substitute for flint and steel when starting fires. Lighting a fire with a magnifying glass requires light as bright as sunlight to focus, tinder to ignite, and about 5 minutes for the fire to ignite. A magnifying glass grants advantage on any ability check made to appraise or inspect an item that is small or highly detailed.",
"value": 100,
"weight": 0
},
{
"name": "Manacles",
"plural": "Sets of manacles",
"description": "These metal restraints can bind a Small or Medium creature. Escaping the manacles requires a successful DC 20 Dexterity check. Breaking them requires a successful DC 20 Strength check. Each set of manacles comes with one key. Without the key, a creature proficient with thieves tools can pick the manacles lock with a successful DC 15 Dexterity check. Manacles have 15 hit points.",
"value": 2,
"weight": 6
},
{
"name": "Mess kit",
"plural": "Mess kits",
"description": "This tin box contains a cup and simple cutlery. The box clamps together, and one side can be used as a cooking pan and the other as a plate or shallow bowl.",
"value": 0.2,
"weight": 1
},
{
"name": "Mirror, steel",
"plural": "Mirrors, steel",
"description": "",
"value": 5,
"weight": 0.5
},
{
"name": "Oil (flask)",
"plural": "Oil (flasks)",
"description": "Oil usually comes in a clay flask that holds 1 pint. As an action, you can splash the oil in this flask onto a creature within 5 feet of you or throw it up to 20 feet, shattering it on impact. Make a ranged attack against a target creature or object, treating the oil as an improvised weapon. On a hit, the target is covered in oil. If the target takes any fire damage before the oil dries (after 1 minute), the target takes an additional 5 fire damage from the burning oil. You can also pour a flask of oil on the ground to cover a 5-foot-square area, provided that the surface is level. If lit, the oil burns for 2 rounds and deals 5 fire damage to any creature that enters the area or ends its turn in the area. A creature can take this damage only once per turn.",
"value": 0.1,
"weight": 1
},
{
"name": "Paper (one sheet)",
"plural": "Sheets of paper",
"description": "",
"value": 0.2,
"weight": 0
},
{
"name": "Parchment (one sheet)",
"plural": "Sheets of parchment",
"description": "",
"value": 0.1,
"weight": 0
},
{
"name": "Perfume (vial)",
"plural": "Perfume (vials)",
"description": "",
"value": 5,
"weight": 0
},
{
"name": "Pick, miners",
"plural": "Picks, miners",
"description": "",
"value": 2,
"weight": 10
},
{
"name": "Piton",
"plural": "Pitons",
"description": "",
"value": 0.05,
"weight": 0.25
},
{
"name": "Poison, basic (vial)",
"plural": "Poison, basic (vials)",
"description": "You can use the poison in this vial to coat one slashing or piercing weapon or up to three pieces of ammunition. Applying the poison takes an action. A creature hit by the poisoned weapon or ammunition must make a DC 10 Constitution saving throw or take 1d4 poison damage. Once applied, the poison retains potency for 1 minute before drying.",
"value": 100,
"weight": 0
},
{
"name": "Pole (10-foot)",
"plural": "Poles (10-foot)",
"description": "",
"value": 0.05,
"weight": 7
},
{
"name": "Pot, iron",
"plural": "Pots, iron",
"description": "",
"value": 2,
"weight": 10
},
{
"name": "Potion of healing",
"plural": "Potions of healing",
"description": "A character who drinks the magical red fluid in this vial regains 2d4 + 2 hit points. Drinking or administering a potion takes an action.",
"value": 50,
"weight": 0.5
},
{
"name": "Pouch",
"plural": "Pouches",
"description": "A cloth or leather pouch can hold up to 20 sling bullets or 50 blowgun needles, among other things. A compartmentalized pouch for holding spell components is called a component pouch (described earlier in this section).",
"value": 0.5,
"weight": 1
},
{
"name": "Quiver",
"plural": "Quivers",
"description": "A quiver can hold up to 20 arrows.",
"value": 1,
"weight": 1
},
{
"name": "Ram, portable",
"plural": "Rams, portable",
"description": "You can use a portable ram to break down doors. When doing so, you gain a +4 bonus on the Strength check. One other character can help you use the ram, giving you advantage on this check.",
"value": 4,
"weight": 35
},
{
"name": "Rations (1 day)",
"plural": "Days of rations",
"description": "Rations consist of dry foods suitable for extended travel, including jerky, dried fruit, hardtack, and nuts.",
"value": 0.5,
"weight": 2
},
{
"name": "Robes",
"plural": "Robes",
"description": "",
"value": 1,
"weight": 4
},
{
"name": "Rope, hempen (50 feet)",
"plural": "Ropes, hempen (50 feet)",
"description": "Rope, whether made of hemp or silk, has 2 hit points and can be burst with a DC 17 Strength check.",
"value": 1,
"weight": 10
},
{
"name": "Rope, silk (50 feet)",
"plural": "Ropes, silk (50 feet)",
"description": "Rope, whether made of hemp or silk, has 2 hit points and can be burst with a DC 17 Strength check.",
"value": 10,
"weight": 5
},
{
"name": "Sack",
"plural": "Sacks",
"description": "",
"value": 0.01,
"weight": 0.5
},
{
"name": "Scale, merchants",
"plural": "Scales, merchants",
"description": "A scale includes a small balance, pans, and a suitable assortment of weights up to 2 pounds. With it, you can measure the exact weight of small objects, such as raw precious metals or trade goods, to help determine their worth.",
"value": 5,
"weight": 3
},
{
"name": "Sealing wax",
"plural": "Sealing waxes",
"description": "",
"value": 0.5,
"weight": 0
},
{
"name": "Shovel",
"plural": "Shovels",
"description": "",
"value": 2,
"weight": 5
},
{
"name": "Signal whistle",
"plural": "Signal whistles",
"description": "",
"value": 0.05,
"weight": 0
},
{
"name": "Signet ring",
"plural": "Signet rings",
"description": "",
"value": 5,
"weight": 0
},
{
"name": "Soap",
"plural": "Soaps",
"description": "",
"value": 0.02,
"weight": 0
},
{
"name": "Spellbook",
"plural": "Spellbooks",
"description": "Essential for wizards, a spellbook is a leather-bound tome with 100 blank vellum pages suitable for recording spells.",
"value": 50,
"weight": 3
},
{
"name": "Spikes, iron (10)",
"plural": "Spikes, iron (10)",
"description": "",
"value": 1,
"weight": 5
},
{
"name": "Spyglass",
"plural": "Spyglasses",
"description": "Objects viewed through a spyglass are magnified to twice their size.",
"value": 1000,
"weight": 1
},
{
"name": "Tent, two-person",
"plural": "Tents, two-person",
"description": "A simple and portable canvas shelter, a tent sleeps two.",
"value": 2,
"weight": 20
},
{
"name": "Tinderbox",
"plural": "Tinderboxes",
"description": "This small container holds flint, fire steel, and tinder (usually dry cloth soaked in light oil) used to kindle a fire. Using it to light a torch — or anything else with abundant, exposed fuel — takes an action. Lighting any other fire takes 1 minute.",
"value": 0.5,
"weight": 1
},
{
"name": "Torch",
"plural": "Torches",
"description": "A torch burns for 1 hour, providing bright light in a 20-foot radius and dim light for an additional 20 feet. If you make a melee attack with a burning torch and hit, it deals 1 fire damage.",
"value": 0.01,
"weight": 1
},
{
"name": "Vial",
"plural": "Vials",
"description": "",
"value": 1,
"weight": 0
},
{
"name": "Waterskin",
"plural": "Waterskins",
"description": "",
"value": 0.2,
"weight": 5
},
{
"name": "Whetstone",
"plural": "Whetstones",
"description": "",
"value": 0.01,
"weight": 1
}
]

244
dataSources/srd/armor.json Normal file
View File

@@ -0,0 +1,244 @@
[
{
"name": "Padded Armor",
"value": 5,
"weight": 8,
"description": "Padded armor consists of quilted layers of cloth and batting.",
"effects": [
{
"operation": "base",
"value": 11,
"stat": "armor"
},
{
"operation": "disadvantage",
"stat": "stealth"
}
]
},
{
"name": "Leather Armor",
"value": 10,
"weight": 10,
"description": "The breastplate and shoulder protectors of this armor are made of leather that has been stiffened by being boiled in oil. The rest of the armor is made of softer and more flexible materials.",
"effects": [
{
"operation": "base",
"value": 11,
"stat": "armor"
}
]
},
{
"name": "Studded leather Armor",
"value": 45,
"weight": 13,
"description": "Made from tough but flexible leather, studded leather is reinforced with close-set rivets or spikes.",
"effects": [
{
"operation": "base",
"value": 12,
"stat": "armor"
}
]
},
{
"name": "Hide Armor",
"value": 10,
"weight": 12,
"description": "This crude armor consists of thick furs and pelts. It is commonly worn by barbarian tribes, evil humanoids, and other folk who lack access to the tools and materials needed to create better armor.",
"effects": [
{
"operation": "base",
"value": 12,
"stat": "armor"
},
{
"operation": "max",
"value": 2,
"stat": "dexterityArmor"
}
]
},
{
"name": "Chain shirt",
"value": 50,
"weight": 20,
"description": "Made of interlocking metal rings, a chain shirt is worn between layers of clothing or leather. This armor offers modest protection to the wearers upper body and allows the sound of the rings rubbing against one another to be muffled by outer layers.",
"effects": [
{
"operation": "base",
"value": 13,
"stat": "armor"
},
{
"operation": "max",
"value": 2,
"stat": "dexterityArmor"
}
]
},
{
"name": "Scale mail",
"value": 50,
"weight": 45,
"description": "This armor consists of a coat and leggings (and perhaps a separate skirt) of leather covered with overlapping pieces of metal, much like the scales of a fish. The suit includes gauntlets.",
"effects": [
{
"operation": "base",
"value": 14,
"stat": "armor"
},
{
"operation": "disadvantage",
"stat": "stealth"
},
{
"operation": "max",
"value": 2,
"stat": "dexterityArmor"
}
]
},
{
"name": "Breastplate",
"value": 400,
"weight": 20,
"description": "This armor consists of a fitted metal chest piece worn with supple leather. Although it leaves the legs and arms relatively unprotected, this armor provides good protection for the wearers vital organs while leaving the wearer relatively unencumbered.",
"effects": [
{
"operation": "base",
"value": 14,
"stat": "armor"
},
{
"operation": "max",
"value": 2,
"stat": "dexterityArmor"
}
]
},
{
"name": "Half plate",
"value": 750,
"weight": 40,
"description": "Half plate consists of shaped metal plates that cover most of the wearers body. It does not include leg protection beyond simple greaves that are attached with leather straps.",
"effects": [
{
"operation": "base",
"value": 15,
"stat": "armor"
},
{
"operation": "max",
"value": 2,
"stat": "dexterityArmor"
},
{
"operation": "disadvantage",
"stat": "stealth"
}
]
},
{
"name": "Ring mail",
"value": 30,
"weight": 40,
"description": "This armor is leather armor with heavy rings sewn into it. The rings help reinforce the armor against blows from swords and axes. Ring mail is inferior to chain mail, and its usually worn only by those who cant afford better armor.",
"effects": [
{
"operation": "base",
"value": 14,
"stat": "armor"
},
{
"operation": "mul",
"value": 0,
"stat": "dexterityArmor"
},
{
"operation": "disadvantage",
"stat": "stealth"
}
]
},
{
"name": "Chain mail",
"value": 75,
"weight": 55,
"description": "Made of interlocking metal rings, chain mail includes a layer of quilted fabric worn underneath the mail to prevent chafing and to cushion the impact of blows. The suit includes gauntlets.",
"effects": [
{
"operation": "base",
"value": 16,
"stat": "armor"
},
{
"operation": "mul",
"value": 0,
"stat": "dexterityArmor"
},
{
"operation": "disadvantage",
"stat": "stealth"
}
]
},
{
"name": "Splint Armor",
"value": 200,
"weight": 60,
"description": "This armor is made of narrow vertical strips of metal riveted to a backing of leather that is worn over cloth padding. Flexible chain mail protects the joints.",
"effects": [
{
"operation": "base",
"value": 17,
"stat": "armor"
},
{
"operation": "mul",
"value": 0,
"stat": "dexterityArmor"
},
{
"operation": "disadvantage",
"stat": "stealth"
}
]
},
{
"name": "Plate Armor",
"value": 1500,
"weight": 65,
"description": "Plate consists of shaped, interlocking metal plates to cover the entire body. A suit of plate includes gauntlets, heavy leather boots, a visored helmet, and thick layers of padding underneath the armor. Buckles and straps distribute the weight over the body.",
"effects": [
{
"operation": "base",
"value": 18,
"stat": "armor"
},
{
"operation": "mul",
"value": 0,
"stat": "dexterityArmor"
},
{
"operation": "disadvantage",
"stat": "stealth"
}
]
},
{
"name": "Shield",
"value": 10,
"weight": 6,
"description": "A shield is made from wood or metal and is carried in one hand. Wielding a shield increases your Armor Class by 2. You can benefit from only one shield at a time.",
"effects": [
{
"operation": "add",
"value": 2,
"stat": "armor"
}
]
}
]

View File

@@ -0,0 +1,12 @@
// Only do if the library doesn't exist yet
id = Libraries.insert({
_id: "SRDLibraryGA3XWsd",
owner: Meteor.userId(),
name: "SRD Library",
});
_.each(items, (item) => {
item.settings = {category: }; // "adventuringGear", "armor", "weapons", "tools"
item.library = "SRDLibraryGA3XWsd"
LibraryItems.insert(item)
});

View File

@@ -0,0 +1,481 @@
[
{
"name": "Club",
"value": 0.1,
"weight": 2,
"attacks": [
{
"attackBonus": "strengthMod + proficiencyBonus",
"damage": "1d4 + {strengthMod}",
"details": "Light",
"damageType": "bludgeoning"
}
]
},
{
"name": "Dagger",
"value": 2,
"weight": 1,
"attacks": [
{
"attackBonus": "max(strengthMod, dexterityMod) + proficiencyBonus",
"damage": "1d4 + {max(strengthMod, dexterityMod)}",
"details": "Finesse, light, thrown (range 20/60)",
"damageType": "piercing"
}
]
},
{
"name": "Greatclub",
"value": 0.2,
"weight": 10,
"attacks": [
{
"attackBonus": "strengthMod + proficiencyBonus",
"damage": "1d8 + {strengthMod}",
"details": "Two-handed",
"damageType": "bludgeoning"
}
]
},
{
"name": "Handaxe",
"value": 5,
"weight": 2,
"attacks": [
{
"attackBonus": "strengthMod + proficiencyBonus",
"damage": "1d6 + {strengthMod}",
"details": "Light, thrown (range 20/60)",
"damageType": "slashing"
}
]
},
{
"name": "Javelin",
"value": 0.5,
"weight": 2,
"attacks": [
{
"attackBonus": "strengthMod + proficiencyBonus",
"damage": "1d6 + {strengthMod}",
"details": "Thrown (range 30/120)",
"damageType": "piercing"
}
]
},
{
"name": "Light hammer",
"value": 2,
"weight": 2,
"attacks": [
{
"attackBonus": "strengthMod + proficiencyBonus",
"damage": "1d4 + {strengthMod}",
"details": "Light, thrown (range 20/60)",
"damageType": "bludgeoning"
}
]
},
{
"name": "Mace",
"value": 5,
"weight": 4,
"attacks": [
{
"attackBonus": "strengthMod + proficiencyBonus",
"damage": "1d6 + {strengthMod}",
"damageType": "bludgeoning"
}
]
},
{
"name": "Quarterstaff",
"value": 0.5,
"weight": 4,
"attacks": [
{
"attackBonus": "strengthMod + proficiencyBonus",
"damage": "1d6 + {strengthMod}",
"details": "Versatile (1d8)",
"damageType": "bludgeoning"
}
]
},
{
"name": "Sickle",
"value": 1,
"weight": 2,
"attacks": [
{
"attackBonus": "strengthMod + proficiencyBonus",
"damage": "1d4 + {strengthMod}",
"details": "Light",
"damageType": "slashing"
}
]
},
{
"name": "Spear",
"value": 1,
"weight": 3,
"attacks": [
{
"attackBonus": "strengthMod + proficiencyBonus",
"damage": "1d6 + {strengthMod}",
"details": "Thrown (range 20/60), versatile (1d8)",
"damageType": "piercing"
}
]
},
{
"name": "Crossbow, light",
"value": 25,
"weight": 5,
"attacks": [
{
"attackBonus": "dexterityMod + proficiencyBonus",
"damage": "1d8 + {dexterityMod}",
"details": "Ammunition (range 80/320), loading, two-handed",
"damageType": "piercing"
}
]
},
{
"name": "Dart",
"value": 0.05,
"weight": 0.25,
"attacks": [
{
"attackBonus": "max(strengthMod, dexterityMod) + proficiencyBonus",
"damage": "1d4 + {max(strengthMod, dexterityMod)}",
"details": "Finesse, thrown (range 20/60)",
"damageType": "piercing"
}
]
},
{
"name": "Shortbow",
"value": 25,
"weight": 2,
"attacks": [
{
"attackBonus": "dexterityMod + proficiencyBonus",
"damage": "1d6 + {dexterityMod}",
"details": "Ammunition (range 80/320), two-handed",
"damageType": "piercing"
}
]
},
{
"name": "Sling",
"value": 0.1,
"weight": 0,
"attacks": [
{
"attackBonus": "dexterityMod + proficiencyBonus",
"damage": "1d4 + {dexterityMod}",
"details": "Ammunition (range 30/120)",
"damageType": "bludgeoning"
}
]
},
{
"name": "Battleaxe",
"value": 10,
"weight": 4,
"attacks": [
{
"attackBonus": "strengthMod + proficiencyBonus",
"damage": "1d8 + {strengthMod}",
"details": "Versatile (1d10)",
"damageType": "slashing"
}
]
},
{
"name": "Flail",
"value": 10,
"weight": 2,
"attacks": [
{
"attackBonus": "strengthMod + proficiencyBonus",
"damage": "1d8 + {strengthMod}",
"damageType": "bludgeoning"
}
]
},
{
"name": "Glaive",
"value": 20,
"weight": 6,
"attacks": [
{
"attackBonus": "strengthMod + proficiencyBonus",
"damage": "1d10 + {strengthMod}",
"details": "Heavy, reach, two-handed",
"damageType": "slashing"
}
]
},
{
"name": "Greataxe",
"value": 30,
"weight": 7,
"attacks": [
{
"attackBonus": "strengthMod + proficiencyBonus",
"damage": "1d12 + {strengthMod}",
"details": "Heavy, two-handed",
"damageType": "slashing"
}
]
},
{
"name": "Greatsword",
"value": 50,
"weight": 6,
"attacks": [
{
"attackBonus": "strengthMod + proficiencyBonus",
"damage": "2d6 + {strengthMod}",
"details": "Heavy, two-handed",
"damageType": "slashing"
}
]
},
{
"name": "Halberd",
"value": 20,
"weight": 6,
"attacks": [
{
"attackBonus": "strengthMod + proficiencyBonus",
"damage": "1d10 + {strengthMod}",
"details": "Heavy, reach, two-handed",
"damageType": "slashing"
}
]
},
{
"name": "Lance",
"value": 10,
"weight": 6,
"description": "You have disadvantage when you use a lance to attack a target within 5 feet of you. Also, a lance requires two hands to wield when you arent mounted.",
"attacks": [
{
"attackBonus": "strengthMod + proficiencyBonus",
"damage": "1d12 + {strengthMod}",
"details": "Reach, special",
"damageType": "piercing"
}
]
},
{
"name": "Longsword",
"value": 15,
"weight": 3,
"attacks": [
{
"attackBonus": "strengthMod + proficiencyBonus",
"damage": "1d8 + {strengthMod}",
"details": "Versatile (1d10)",
"damageType": "slashing"
}
]
},
{
"name": "Maul",
"value": 10,
"weight": 10,
"attacks": [
{
"attackBonus": "strengthMod + proficiencyBonus",
"damage": "2d6 + {strengthMod}",
"details": "Heavy, two-handed",
"damageType": "bludgeoning"
}
]
},
{
"name": "Morningstar",
"value": 15,
"weight": 4,
"attacks": [
{
"attackBonus": "strengthMod + proficiencyBonus",
"damage": "1d8 + {strengthMod}",
"damageType": "piercing"
}
]
},
{
"name": "Pike",
"value": 5,
"weight": 18,
"attacks": [
{
"attackBonus": "strengthMod + proficiencyBonus",
"damage": "1d10 + {strengthMod}",
"details": "Heavy, reach, two-handed",
"damageType": "piercing"
}
]
},
{
"name": "Rapier",
"value": 25,
"weight": 2,
"attacks": [
{
"attackBonus": "max(strengthMod, dexterityMod) + proficiencyBonus",
"damage": "1d8 + {max(strengthMod, dexterityMod)}",
"details": "Finesse",
"damageType": "piercing"
}
]
},
{
"name": "Scimitar",
"value": 25,
"weight": 3,
"attacks": [
{
"attackBonus": "strengthMod + proficiencyBonus",
"damage": "1d6 + {strengthMod}",
"details": "Finesse, light",
"damageType": "slashing"
}
]
},
{
"name": "Shortsword",
"value": 10,
"weight": 2,
"attacks": [
{
"attackBonus": "max(strengthMod, dexterityMod) + proficiencyBonus",
"damage": "1d6 + {max(strengthMod, dexterityMod)}",
"details": "Finesse, light",
"damageType": "piercing"
}
]
},
{
"name": "Trident",
"value": 5,
"weight": 4,
"attacks": [
{
"attackBonus": "strengthMod + proficiencyBonus",
"damage": "1d6 + {strengthMod}",
"details": "Thrown (range 20/60), versatile (1d8)",
"damageType": "piercing"
}
]
},
{
"name": "War pick",
"value": 5,
"weight": 2,
"attacks": [
{
"attackBonus": "strengthMod + proficiencyBonus",
"damage": "1d8 + {strengthMod}",
"damageType": "piercing"
}
]
},
{
"name": "Warhammer",
"value": 15,
"weight": 2,
"attacks": [
{
"attackBonus": "strengthMod + proficiencyBonus",
"damage": "1d8 + {strengthMod}",
"details": "Versatile (1d10)",
"damageType": "bludgeoning"
}
]
},
{
"name": "Whip",
"value": 2,
"weight": 3,
"attacks": [
{
"attackBonus": "max(strengthMod, dexterityMod) + proficiencyBonus",
"damage": "1d4 + {max(strengthMod, dexterityMod)}",
"details": "Finesse, reach",
"damageType": "slashing"
}
]
},
{
"name": "Blowgun",
"value": 10,
"weight": 1,
"attacks": [
{
"attackBonus": "dexterityMod + proficiencyBonus",
"damage": "1 + {dexterityMod}",
"details": "Ammunition (range 25/100), loading",
"damageType": "piercing"
}
]
},
{
"name": "Crossbow, hand",
"value": 75,
"weight": 3,
"attacks": [
{
"attackBonus": "dexterityMod + proficiencyBonus",
"damage": "1d6 + {dexterityMod}",
"details": "Ammunition (range 30/120), light, loading",
"damageType": "piercing"
}
]
},
{
"name": "Crossbow, heavy",
"value": 50,
"weight": 18,
"attacks": [
{
"attackBonus": "dexterityMod + proficiencyBonus",
"damage": "1d10 + {dexterityMod}",
"details": "Ammunition (range 100/400), heavy, loading, two-handed",
"damageType": "piercing"
}
]
},
{
"name": "Longbow",
"value": 50,
"weight": 2,
"attacks": [
{
"attackBonus": "dexterityMod + proficiencyBonus",
"damage": "1d8 + {dexterityMod}",
"details": "Ammunition (range 150/600), heavy, two-handed",
"damageType": "piercing"
}
]
},
{
"name": "Net",
"value": 1,
"weight": 3,
"description": "A Large or smaller creature hit by a net is Restrained until it is freed. A net has no effect on creatures that are formless, or creatures that are Huge or larger. A creature can use its action to make a DC 10 Strength check, freeing itself or another creature within its reach on a success. Dealing 5 slashing damage to the net (AC 10) also frees the creature without harming it, ending the effect and destroying the net.\n\nWhen you use an action, bonus action, or reaction to attack with a net, you can make only one attack regardless of the number of attacks you can normally make.",
"attacks": [
{
"attackBonus": "strengthMod + proficiencyBonus",
"damage": "0",
"details": "Special, thrown (range 5/15)",
"damageType": "bludgeoning"
}
]
}
]

View File

@@ -24,18 +24,18 @@ var checkMovePermission = function(itemId, parent) {
var item = Items.findOne(itemId);
if (!item)
throw new Meteor.Error("No such item",
"An item could not be found to move");
"An item could not be found to move");
//handle permissions
var permission = Meteor.call("canWriteCharacter", item.charId);
if (!permission){
throw new Meteor.Error("Access denied",
"Not permitted to move items from this character");
"Not permitted to move items from this character");
}
if (parent.collection === "Characters"){
permission = Meteor.call("canWriteCharacter", parent.id);
if (!permission){
throw new Meteor.Error("Access denied",
"Not permitted to move items to this character");
"Not permitted to move items to this character");
}
} else {
var parentCollectionObject = global[parent.collection];
@@ -53,7 +53,7 @@ var checkMovePermission = function(itemId, parent) {
permission = Meteor.call("canWriteCharacter", parentObject.charId);
if (!permission){
throw new Meteor.Error("Access denied",
"Not permitted to move items to this character");
"Not permitted to move items to this character");
}
}
}

View File

@@ -0,0 +1,47 @@
Libraries = new Mongo.Collection("library");
Schemas.Library = new SimpleSchema({
name: {type: String},
owner: {type: String, regEx: SimpleSchema.RegEx.Id},
readers: {type: [String], regEx: SimpleSchema.RegEx.Id, defaultValue: []},
writers: {type: [String], regEx: SimpleSchema.RegEx.Id, defaultValue: []},
public: {type: Boolean, defaultValue: false},
});
Libraries.attachSchema(Schemas.Library);
Libraries.allow({
insert(userId, doc) {
return userId && doc.owner === userId;
},
update(userId, doc, fields, modifier) {
return canEdit(userId, doc);
},
remove(userId, doc) {
return canEdit(userId, doc);
},
fetch: ["owner", "writers"],
});
Libraries.deny({
// For now, only admins can manage libraries
insert(userId, doc){
var user = Meteor.users.findOne(userId);
return !user || !_.contains(user.roles, "admin");
},
update(userId, doc, fields, modifier) {
// Can't change owners
return _.contains(fields, "owner")
},
fetch: [],
});
const canEdit = function(userId, library){
if (!userId || !library) return;
return library.owner === userId || _.contains(library.writers, userId);
};
Libraries.canEdit = function(userId, libraryId){
const library = Libraries.findOne(libraryId);
return canEdit(userId, library);
};

View File

@@ -0,0 +1,43 @@
Schemas.LibraryAttacks = new SimpleSchema({
name: {
type: String,
defaultValue: "New Attack",
trim: false,
},
details: {
type: String,
optional: true,
trim: false,
},
attackBonus: {
type: String,
defaultValue: "strengthMod + proficiencyBonus",
optional: true,
trim: false,
},
damage: {
type: String,
defaultValue: "1d8 + {strengthMod}",
optional: true,
trim: false,
},
damageType: {
type: String,
allowedValues: [
"bludgeoning",
"piercing",
"slashing",
"acid",
"cold",
"fire",
"force",
"lightning",
"necrotic",
"poison",
"psychic",
"radiant",
"thunder",
],
defaultValue: "slashing",
},
});

View File

@@ -0,0 +1,40 @@
Schemas.LibraryEffects = new SimpleSchema({
name: {
type: String,
optional: true, //TODO make necessary if there is no owner
trim: false,
},
operation: {
type: String,
defaultValue: "add",
allowedValues: [
"base",
"proficiency",
"add",
"mul",
"min",
"max",
"advantage",
"disadvantage",
"passiveAdd",
"fail",
"conditional",
],
},
// Effects either have a value OR a calculation
value: {
type: Number,
decimal: true,
optional: true,
},
calculation: {
type: String,
optional: true,
trim: false,
},
//which stat the effect is applied to
stat: {
type: String,
optional: true,
},
});

View File

@@ -0,0 +1,43 @@
LibraryItems = new Mongo.Collection("libraryItems");
Schemas.LibraryItems = new SimpleSchema({
name: {type: String, defaultValue: "New Item", trim: false},
plural: {type: String, optional: true, trim: false},
description:{type: String, optional: true, trim: false},
quantity: {type: Number, min: 0, defaultValue: 1},
weight: {type: Number, min: 0, defaultValue: 0, decimal: true},
value: {type: Number, min: 0, defaultValue: 0, decimal: true},
requiresAttunement: {type: Boolean, defaultValue: false},
library: {type: String, regEx: SimpleSchema.RegEx.Id, index: 1},
"settings.category": {
type: String,
optional: true,
allowedValues: [
"adventuringGear", "armor", "weapons", "tools",
],
},
"settings.showIncrement": {
type: Boolean,
defaultValue: false,
},
effects: {type: [Schemas.LibraryEffects], defaultValue: []},
attacks: {type: [Schemas.LibraryAttacks], defaultValue: []},
});
LibraryItems.attachSchema(Schemas.LibraryItems);
LibraryItems.allow({
insert(userId, doc) {
return Libraries.canEdit(userId, doc.library);
},
update(userId, doc, fields, modifier) {
return Libraries.canEdit(userId, doc.library);
},
remove(userId, doc) {
return Libraries.canEdit(userId, doc.library);
},
fetch: ["library"],
});

View File

@@ -62,6 +62,17 @@ Router.map(function() {
fastRender: true,
});
this.route("library", {
path: "/library",
waitOn: function(){
return subsManager.subscribe("standardLibraries");
},
onAfterAction: function() {
document.title = appName + " - Library";
},
fastRender: true,
});
this.route("loading", {
path: "/loading"
});

View File

@@ -138,6 +138,13 @@
</paper-fab>
<paper-tooltip position="left"> New container </paper-tooltip>
</div>
<div>
<paper-fab icon="av:library-books"
class="libraryItem"
mini>
</paper-fab>
<paper-tooltip position="left"> Library item </paper-tooltip>
</div>
<div>
<paper-fab icon="note-add"
class="addItem"

View File

@@ -139,6 +139,43 @@ Template.inventory.events({
returnElement: () => $(`[data-id='${itemId}']`).get(0),
});
},
"click .libraryItem": function(event, instance){
var charId = this._id;
var itemId = Items.insert({
charId: charId,
parent:{
id: charId,
collection: "Characters",
},
});
pushDialogStack({
template: "itemLibraryDialog",
element: event.currentTarget,
callback: (result) => {
if (!result) {
Items.remove(itemId);
return;
}
// Make the library item into a regular item
let item = _.omit(result, "library", "attacks", "effects");
delete item.settings.category;
// Update the item to match library item
Items.update(itemId, {$set: item});
// Copy over attacks and effects
_.each(result.attacks, (attack) => {
attack.charId = charId;
attack.parent = {id: itemId, collection: "Items"};
Attacks.insert(attack);
});
_.each(result.effects, (effect) => {
effect.charId = charId;
effect.parent = {id: itemId, collection: "Items"};
Effects.insert(effect);
});
},
returnElement: () => $(`[data-id='${itemId}']`).get(0),
})
},
"click .addContainer": function(event, instance){
var containerId = Containers.insert({
name: "New Container",

View File

@@ -0,0 +1,7 @@
.item-library-dialog .item.selected {
background-color: #e4e4e4;
}
.item-library-dialog .paper-font-subhead {
color: rgba(0,0,0,0.54);
}

View File

@@ -0,0 +1,54 @@
<template name="itemLibraryDialog">
<div class="fit item-library-dialog layout vertical">
<app-toolbar class="app-grey white-text">
<paper-icon-button id="backButton"
icon="arrow-back">
</paper-icon-button>
<div main-title>Items</div>
<paper-input label="Search" class="search-input">
<iron-icon icon="search" prefix></iron-icon>
</paper-input>
</app-toolbar>
<div class="flex scroll-y">
{{#if ready}}
<div class="items" style="padding:8px">
{{#if searchTerm}}
{{#if searchItems.count}}
{{#each item in searchItems}}
{{>libraryItem item=item selected=(isSelected item)}}
{{/each}}
{{else}}
No items match "{{searchTerm}}"
{{/if}}
{{else}}
{{#each category in categories}}
<div class="paper-font-subhead">
{{category.name}}
</div>
{{#each item in (itemsInCategory category.key)}}
{{>libraryItem item=item selected=(isSelected item)}}
{{/each}}
{{/each}}
{{/if}}
</div>
{{else}}
<div class="fit layout vertical center center-justified">
<paper-spinner active></paper-spinner>
</div>
{{/if}}
</div>
<div class="layout horizontal end-justified">
<paper-button class="cancelButton">Cancel</paper-button>
<paper-button class="okButton">OK</paper-button>
</div>
</div>
</template>
<template name="libraryItem">
<div class="item library-item layout horizontal center {{#if selected}}selected{{/if}}">
<paper-ripple></paper-ripple>
<div class="itemName flex">
{{item.name}}
</div>
</div>
</template>

View File

@@ -0,0 +1,65 @@
const librarySubs = new SubsManager();
Template.itemLibraryDialog.onCreated(function(){
this.selectedItem = new ReactiveVar();
this.searchTerm = new ReactiveVar();
this.ready = new ReactiveVar();
this.autorun(() => {
var handle = librarySubs.subscribe("standardLibraries");
this.ready.set(handle.ready());
});
});
Template.itemLibraryDialog.helpers({
ready(){
return Template.instance().ready.get();
},
categories(){
return [
{name: "Weapons", key: "weapons"},
{name: "Armor", key: "armor"},
{name: "Adventuring Gear", key: "adventuringGear"},
];
},
itemsInCategory(categoryKey){
return LibraryItems.find({
library: "SRDLibraryGA3XWsd",
"settings.category": categoryKey,
});
},
isSelected(item){
const selected = Template.instance().selectedItem.get();
return selected && selected._id === item._id;
},
searchTerm(){
return Template.instance().searchTerm.get();
},
searchItems(){
const searchTerm = Template.instance().searchTerm.get();
return LibraryItems.find({
library: "SRDLibraryGA3XWsd",
name: {
$regex: new RegExp(".*" + searchTerm + ".*", "gi")
},
});
},
});
Template.itemLibraryDialog.events({
"click .cancelButton": function(event, template){
popDialogStack();
},
"click .okButton": function(event, template){
popDialogStack(template.selectedItem.get());
},
"click .library-item": function(event, template){
template.selectedItem.set(this.item);
},
"click #backButton": function(event, template){
popDialogStack();
},
"input .search-input, change .search-input": function(event, template){
const value = event.currentTarget.value;
template.searchTerm.set(value);
},
});

View File

@@ -1,6 +1,7 @@
<head>
<meta name="viewport" content="width=device-width initial-scale=1.0, user-scalable=no">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<link href='https://fonts.googleapis.com/css?family=Roboto:400,300,300italic,400italic,500,500italic,700,700italic,900,900italic,100italic,100&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
<link rel="apple-touch-icon" sizes="57x57" href="/apple-touch-icon-57x57.png?v=lk6WXp6Pmj">

View File

@@ -41,6 +41,12 @@
Characters
</paper-icon-item>
</a>
<a href="/library" tabindex="-1">
<paper-icon-item id="library">
<iron-icon icon="av:library-books" item-icon></iron-icon>
Library
</paper-icon-item>
</a>
<a href="/guide" tabindex="-1">
<paper-icon-item id="guide">
<iron-icon icon="social:school" item-icon></iron-icon>
@@ -51,10 +57,16 @@
<iron-icon icon="bug-report" item-icon></iron-icon>
Send Feedback
</paper-icon-item>
<a href="changeLog" tabindex="-1">
<paper-icon-item id="changeLog">
<iron-icon icon="list" item-icon></iron-icon>
Change Log
<a class="patreon" href="https://www.patreon.com/dicecloud" target="_blank" tabindex="-1">
<paper-icon-item>
<iron-icon icon="dicecloud:patreon" item-icon></iron-icon>
Patreon
</paper-icon-item>
</a>
<a class="github" href="https://github.com/ThaumRystra/DiceCloud1" target="_blank" tabindex="-1">
<paper-icon-item>
<iron-icon icon="dicecloud:github" item-icon></iron-icon>
Github
</paper-icon-item>
</a>
<hr style="margin: 16px 0 24px 0;">

View File

@@ -36,4 +36,10 @@ Template.appDrawer.events({
});
closeDrawer(instance);
},
"click .patreon": function(event, instance){
ga("send", "event", "externalLink", "patreon");
},
"click .github": function(event, instance){
ga("send", "event", "externalLink", "github");
},
});

View File

@@ -0,0 +1,5 @@
<template name="itemLibrary">
{{#each items}}
{{> libraryItem}}
{{/each}}
</template>

View File

@@ -0,0 +1,7 @@
Template.itemLibrary.helpers({
items(){
return Items.find({charId: {$in: [
"SRDLibrary",
]}});
},
});

View File

@@ -0,0 +1,26 @@
<template name="library">
<div class="fit layout vertical character-sheet">
<app-header fixed effects="waterfall">
<app-toolbar class="medium-tall app-grey white-text">
<div top-item class="layout horizontal center">
<paper-icon-button icon="menu" drawer-toggle></paper-icon-button>
<div class="flex">
Library
</div>
</div>
<div bottom-item>
<paper-tabs id="characterSheetTabs" selected={{selectedTab}} class="app-grey white-text">
<paper-tab name="items">Items</paper-tab>
<paper-tab name="spells">Spells</paper-tab>
</paper-tabs>
</div>
</app-toolbar>
</app-header>
<div class="flex" style="position: relative;">
<iron-pages id="tabPages" class="fit" selected={{selectedTab}}>
<div name="items" class="tab-page fit">{{> itemLibrary}}</div>
<div name="spells" class="tab-page fit">{{! {{> spellLibrary}} }}</div>
</iron-pages>
</div>
</div>
</template>

View File

@@ -28,7 +28,7 @@ function CacheObject(func, address, args, cache, context){
return;
}
//if we haven't run this before this flush, reset the counter after the flush
if(self.numRun === 0){
if (self.numRun === 0){
Tracker.afterFlush(function(){
self.numRun = 0;
});
@@ -38,10 +38,10 @@ function CacheObject(func, address, args, cache, context){
//even if we don't use its value, we need to track its dependencies
var newValue = func.apply(context, args);
//prevent dependency loops, the memoized function shouldn't re-run
//more than once per flush
if (self.numRun > 1){
//more than 10 times per flush
if (self.numRun > 10){
newValue = NaN;
if(_.isNaN(self.currentValue)) return;
if (_.isNaN(self.currentValue)) return;
}
//if the value changed, store the new value
if (self.currentValue !== newValue){

View File

@@ -12,8 +12,8 @@
"author": "Stefan Zermatten",
"dependencies": {
"@polymer/polymer": "^1.2.5-npm-test.2",
"babel-runtime": "^6.18.0",
"bcrypt": "^1.0.1",
"babel-runtime": "^6.23.0",
"bcrypt": "^1.0.2",
"bower": "^1.7.9"
}
}

View File

@@ -5,5 +5,11 @@
<g id="code-braces">
<path d="M8,3A2,2 0 0,0 6,5V9A2,2 0 0,1 4,11H3V13H4A2,2 0 0,1 6,15V19A2,2 0 0,0 8,21H10V19H8V14A2,2 0 0,0 6,12A2,2 0 0,0 8,10V5H10V3M16,3A2,2 0 0,1 18,5V9A2,2 0 0,0 20,11H21V13H20A2,2 0 0,0 18,15V19A2,2 0 0,1 16,21H14V19H16V14A2,2 0 0,1 18,12A2,2 0 0,1 16,10V5H14V3H16Z" />
</g>
<g id="github">
<path d="M12,2A10,10 0 0,0 2,12C2,16.42 4.87,20.17 8.84,21.5C9.34,21.58 9.5,21.27 9.5,21C9.5,20.77 9.5,20.14 9.5,19.31C6.73,19.91 6.14,17.97 6.14,17.97C5.68,16.81 5.03,16.5 5.03,16.5C4.12,15.88 5.1,15.9 5.1,15.9C6.1,15.97 6.63,16.93 6.63,16.93C7.5,18.45 8.97,18 9.54,17.76C9.63,17.11 9.89,16.67 10.17,16.42C7.95,16.17 5.62,15.31 5.62,11.5C5.62,10.39 6,9.5 6.65,8.79C6.55,8.54 6.2,7.5 6.75,6.15C6.75,6.15 7.59,5.88 9.5,7.17C10.29,6.95 11.15,6.84 12,6.84C12.85,6.84 13.71,6.95 14.5,7.17C16.41,5.88 17.25,6.15 17.25,6.15C17.8,7.5 17.45,8.54 17.35,8.79C18,9.5 18.38,10.39 18.38,11.5C18.38,15.32 16.04,16.16 13.81,16.41C14.17,16.72 14.5,17.33 14.5,18.26C14.5,19.6 14.5,20.68 14.5,21C14.5,21.27 14.66,21.59 15.17,21.5C19.14,20.16 22,16.42 22,12A10,10 0 0,0 12,2Z" />
</g>
<g id="patreon">
<path d="M 0,11.704583 C 0,6.129988 4.5275823,0.90539433 10.497051,0.15752807 c 4.277795,-0.49807892 7.513064,1.14423533 9.752176,3.28462863 2.088042,1.9893242 3.332492,4.529078 3.631638,7.5160563 0.248292,2.991465 -0.397865,5.579082 -2.138897,8.017126 C 20.000935,21.368511 16.566733,24.001 12.288938,24.001 H 6.4675474 V 12.512279 c 0.050855,-2.5382585 0.8974395,-4.7295066 3.9786486,-5.7735279 2.687831,-0.7972254 5.822887,0.6955156 6.768189,3.5329199 0.987184,3.036337 -0.448719,5.076516 -2.138897,6.320966 -1.705135,1.244449 -4.337624,1.244449 -6.072674,0.04936 v 3.933777 c 1.136757,0.553421 2.587617,0.702994 3.63463,0.643165 3.769246,-0.538464 6.715839,-2.677362 7.957297,-5.923101 1.28633,-3.425228 0.38889,-7.4188334 -2.288471,-9.9017494 C 15.075488,2.746641 11.530602,2.1034761 7.761356,3.9432271 5.1139094,5.2893863 3.2741585,8.0265768 2.8254387,11.018042 V 23.999504 H 0.04487198 L 0,11.704583 z" style="fill-rule:nonzero"/>
</g>
</defs></svg>
</iron-iconset-svg>

View File

@@ -0,0 +1,9 @@
Meteor.publish("standardLibraries", function(){
const standardLibraryIds = [
"SRDLibraryGA3XWsd",
];
return [
LibraryItems.find({library: {$in: standardLibraryIds}}),
Libraries.find({_id: {$in: standardLibraryIds}}),
];
});

View File

@@ -1 +0,0 @@
ungit --port=9501

View File

@@ -1,24 +0,0 @@
MSYS-1.0.12 Build:2012-07-05 14:56
Exception: STATUS_NONCONTINUABLE_EXCEPTION at eip=77C10864
eax=0028EDB0 ebx=0028FEE0 ecx=00000000 edx=C0000008 esi=0028EE2C edi=00000000
ebp=0028EE14 esp=0028EDA4 program=us
cs=0023 ds=002B es=002B fs=0053 gs=002B ss=002B
Stack trace:
Frame Function Args
0028EE14 77C10864 (0028EE2C, 0028EE7C, 0028EE2C, 0028EE7C)
0028F2E0 77B90133 (00320114, 00000000, 00320238, 00000000)
0028F2F8 77BB8EE2 (00320114, 0028F358, 0028F588, 6803B9F5)
0028F588 6803BA01 (00320000, 00330F38, 68037457, 00000022)
0028FC38 6803AF8F (00320000, 00660065, 006E0061, 005A002E)
0028FCD8 6803ADC4 (00320000, 0028FD20, 0028FD28, 6803B334)
0028FD28 6803B33E (00320000, 0028FD88, 00000000, 68029DE3)
0028FD48 68039AE6 (00320000, 680F7174, 00011044, 00000000)
0028FE98 68052117 (680A4C64, 00000000, 0028FEE8, 680044EA)
0028FEE8 68004709 (00000000, 00000000, 0028FF28, 0048BC00)
0028FF08 68004C5F (00401248, 00000000, 00000000, 00000000)
0028FF28 68004C98 (00000000, 00000000, 00000000, 00000000)
0028FF58 0048BB08 (00401248, 00000000, 00000000, 00000000)
0028FF88 0040103D (7EFDE000, 0028FFD4, 77BB9F72, 7EFDE000)
0028FF94 755F33AA (7EFDE000, 7D5558E1, 00000000, 00000000)
0028FFD4 77BB9F72 (00401000, 7EFDE000, 00000000, 00000000)
End of stack trace (more stack frames may be present)