Added spellcasting to the stats page, click the icon next to a spell slot to cast
This commit is contained in:
@@ -22,6 +22,7 @@ import { storedIconsSchema } from '/imports/api/icons/Icons.js';
|
||||
import { reorderDocs } from '/imports/api/parenting/order.js';
|
||||
|
||||
import '/imports/api/creature/actions/doAction.js';
|
||||
import '/imports/api/creature/actions/castSpellWithSlot.js';
|
||||
import '/imports/api/creature/creatureProperties/manageEquipment.js';
|
||||
|
||||
let CreatureProperties = new Mongo.Collection('creatureProperties');
|
||||
|
||||
75
app/imports/api/creature/actions/castSpellWithSlot.js
Normal file
75
app/imports/api/creature/actions/castSpellWithSlot.js
Normal file
@@ -0,0 +1,75 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import CreatureProperties, { getCreature, damagePropertyWork } from '/imports/api/creature/CreatureProperties.js';
|
||||
import { assertEditPermission } from '/imports/api/creature/creaturePermissions.js';
|
||||
import { recomputeCreatureByDoc } from '/imports/api/creature/computation/recomputeCreature.js';
|
||||
import { doActionWork } from '/imports/api/creature/actions/doAction.js';
|
||||
|
||||
const castSpellWithSlot = new ValidatedMethod({
|
||||
name: 'creatureProperties.castSpellWithSlot',
|
||||
validate: new SimpleSchema({
|
||||
spellId: SimpleSchema.RegEx.Id,
|
||||
slotId: {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
optional: true,
|
||||
},
|
||||
targetId: {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
optional: true,
|
||||
},
|
||||
}).validator(),
|
||||
mixins: [RateLimiterMixin],
|
||||
rateLimit: {
|
||||
numRequests: 10,
|
||||
timeInterval: 5000,
|
||||
},
|
||||
run({spellId, slotId, targetId}) {
|
||||
let spell = CreatureProperties.findOne(spellId);
|
||||
// Check permissions
|
||||
let creature = getCreature(spell);
|
||||
assertEditPermission(creature, this.userId);
|
||||
let target = undefined;
|
||||
if (targetId) {
|
||||
target = getCreature(targetId);
|
||||
assertEditPermission(target, this.userId);
|
||||
}
|
||||
let slotLevel = spell.level || 0;
|
||||
if (slotLevel !== 0){
|
||||
let slot = CreatureProperties.findOne(slotId);
|
||||
if (!slot){
|
||||
throw new Meteor.Error('No slot',
|
||||
'Slot not found to cast spell');
|
||||
}
|
||||
if (!slot.currentValue){
|
||||
throw new Meteor.Error('No slot',
|
||||
'Slot depleted');
|
||||
}
|
||||
if (!(slot.spellSlotLevelValue >= spell.level)){
|
||||
throw new Meteor.Error('Slot too small',
|
||||
'Slot is not large enough to cast spell');
|
||||
}
|
||||
slotLevel = slot.spellSlotLevelValue;
|
||||
damagePropertyWork({
|
||||
property: slot,
|
||||
operation: 'increment',
|
||||
value: 1,
|
||||
});
|
||||
}
|
||||
doActionWork({
|
||||
action: spell,
|
||||
context: {slotLevel},
|
||||
creature,
|
||||
target,
|
||||
});
|
||||
// Note this only recomputes the top-level creature, not the nearest one
|
||||
recomputeCreatureByDoc(creature);
|
||||
if (target){
|
||||
recomputeCreatureByDoc(target);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export default castSpellWithSlot;
|
||||
@@ -41,8 +41,7 @@ const doAction = new ValidatedMethod({
|
||||
},
|
||||
});
|
||||
|
||||
function doActionWork({action, creature, target}){
|
||||
let actionContext = {};
|
||||
export function doActionWork({action, creature, target, context = {}}){
|
||||
let decendantForest = nodesToTree({
|
||||
collection: CreatureProperties,
|
||||
ancestorId: action._id,
|
||||
@@ -53,9 +52,9 @@ function doActionWork({action, creature, target}){
|
||||
}];
|
||||
applyProperties({
|
||||
forest: startingForest,
|
||||
actionContext: context,
|
||||
creature,
|
||||
target,
|
||||
actionContext
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user