diff --git a/rpg-docs/Model/Character/Spells.js b/rpg-docs/Model/Character/Spells.js index 58f21cd2..2b5876b2 100644 --- a/rpg-docs/Model/Character/Spells.js +++ b/rpg-docs/Model/Character/Spells.js @@ -83,3 +83,170 @@ Spells.after.update(function (userId, spell, fieldNames) { Spells.allow(CHARACTER_SUBSCHEMA_ALLOW); Spells.deny(CHARACTER_SUBSCHEMA_DENY); + + + + +var checkMovePermission = function(spellId, parent, destinationOnly) { + var spell = Spells.findOne(spellId); + if (!spell) + throw new Meteor.Error("No such spell", + "An spell could not be found to move"); + //handle permissions + var permission; + + if (!destinationOnly) { //if we're not modifying the origin, only the destination + permission = Meteor.call("canWriteCharacter", spell.charId); + if (!permission){ + throw new Meteor.Error("Access denied", + "Not permitted to move spells 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 spells to this character"); + } + } else { + var parentCollectionObject = global[parent.collection]; + var parentObject = null; + if (parentCollectionObject) + parentObject = parentCollectionObject.findOne( + parent.id, {fields: {_id: 1, charId: 1}} + ); + if (!parentObject) throw new Meteor.Error( + "Invalid parent", + "The destination parent " + parent.id + + " does not exist in the collection " + parent.collection + ); + if (parentObject.charId){ + permission = Meteor.call("canWriteCharacter", parentObject.charId); + if (!permission){ + throw new Meteor.Error("Access denied", + "Not permitted to move spells to this character"); + } + } + } +}; + +var moveSpell = function(spellId, targetCollection, targetId) { + var spell = Spells.findOne(spellId); + if (!spell) return; + targetCollection = targetCollection || spell.parent.collection; + targetId = targetId || spell.parent.id; + + if (Meteor.isServer) { + checkMovePermission(spellId, {collection: targetCollection, id: targetId}, false); + } + + if (targetCollection == "Characters") { //then we are copying the spell to a different character. + targetList = SpellLists.findOne({"charId": targetId}); + targetListId = targetList && targetList._id; + if (!targetListId) { + targetListId = SpellLists.insert({ //create a spell list if we don't already have one + name: "New SpellList", + charId: targetId, + saveDC: "8 + intelligenceMod + proficiencyBonus", + attackBonus: "intelligenceMod + proficiencyBonus", + }); + } + + Spells.update( + spellId, + {$set: { + charId: targetId, + "parent.collection": "SpellLists", + "parent.id": targetListId, + }} + ); + } + else { //we are moving the spell within the same character + //update the spell provided the update will actually change something + if ( + spell.parent.collection !== targetCollection || + spell.parent.id !== targetId + ){ + Spells.update( + spellId, + {$set: { + "parent.collection": targetCollection, + "parent.id": targetId, + }} + ); + } + } +}; + +var copySpell = function(spellId, targetCollection, targetId) { + var spell = Spells.findOne(spellId); + if (!spell) return; + targetCollection = targetCollection || spell.parent.collection; + targetId = targetId || spell.parent.id; + + if (Meteor.isServer) { + checkMovePermission(spellId, {collection: targetCollection, id: targetId}, true); //we're only reading from the source character + } + + + if (targetCollection == "Characters") { //then we are copying the spell to a different character. + targetList = SpellLists.findOne({"charId": targetId}); + targetListId = targetList && targetList._id; + if (!targetListId) { + targetListId = SpellLists.insert({ //create a spell list if we don't already have one + name: "New SpellList", + charId: targetId, + saveDC: "8 + intelligenceMod + proficiencyBonus", + attackBonus: "intelligenceMod + proficiencyBonus", + }); + } + + newSpell = _.clone(spell); + delete newSpell._id; + newSpellId = Spells.insert(newSpell); //add a new copy of the spell + Spells.update( + newSpellId, + {$set: { + charId: targetId, + "parent.collection": "SpellLists", + "parent.id": targetListId, + }} + ); + } + else { //else we are copying the spell within the same character + newSpell = _.clone(spell); + delete newSpell._id; + newSpellId = Spells.insert(newSpell); //add a new copy of the spell + Spells.update( + newSpellId, + {$set: { + "parent.collection": targetCollection, + "parent.id": targetId, + }} + ); + } +}; + + +Meteor.methods({ + moveSpellToList: function(spellId, spellListId) { + check(spellId, String); + check(spellListId, String); + moveSpell(spellId, "SpellLists", spellListId); + }, + copySpellToList: function(spellId, spellListId) { + check(spellId, String); + check(spellListId, String); + copySpell(spellId, "SpellLists", spellListId); + }, + moveSpellToCharacter: function(spellId, charId) { + check(spellId, String); + check(charId, String); + moveSpell(spellId, "Characters", charId); + }, + copySpellToCharacter: function(spellId, charId) { + check(spellId, String); + check(charId, String); + copySpell(spellId, "Characters", charId); + }, +}); \ No newline at end of file diff --git a/rpg-docs/client/views/character/inventory/inventory.js b/rpg-docs/client/views/character/inventory/inventory.js index 5a06a21f..bddd2014 100644 --- a/rpg-docs/client/views/character/inventory/inventory.js +++ b/rpg-docs/client/views/character/inventory/inventory.js @@ -334,21 +334,23 @@ Template.layout.events({ Session.set("inventory.dragItemId", null); }, "drop .characterRepresentative": function(event, instance) { - var itemId = event.originalEvent.dataTransfer.getData("dicecloud-id/items"); - if (event.ctrlKey){ - //split the stack to the container - pushDialogStack({ - template: "splitStackDialog", - data: { - id: itemId, - parentCollection: "Characters", - parentId: this._id, - }, - }); - } else { - //move item to the character - Meteor.call("moveItemToCharacter", itemId, this._id); + if (_.contains(event.originalEvent.dataTransfer.types, "dicecloud-id/items")){ + var itemId = event.originalEvent.dataTransfer.getData("dicecloud-id/items"); + if (event.ctrlKey){ + //split the stack to the container + pushDialogStack({ + template: "splitStackDialog", + data: { + id: itemId, + parentCollection: "Characters", + parentId: this._id, + }, + }); + } else { + //move item to the character + Meteor.call("moveItemToCharacter", itemId, this._id); + } + Session.set("inventory.dragItemId", null); } - Session.set("inventory.dragItemId", null); }, }); diff --git a/rpg-docs/client/views/character/spells/spells.html b/rpg-docs/client/views/character/spells/spells.html index 7158c8c3..b5011f82 100644 --- a/rpg-docs/client/views/character/spells/spells.html +++ b/rpg-docs/client/views/character/spells/spells.html @@ -83,7 +83,9 @@ {{#each spells ../_id ../../_id}} {{#if showSpell ../../_id}}