Started work on character log for rolls to be stored
This commit is contained in:
@@ -40,7 +40,12 @@ let CreatureSettingsSchema = new SimpleSchema({
|
|||||||
optional: true,
|
optional: true,
|
||||||
min: 0,
|
min: 0,
|
||||||
max: 1,
|
max: 1,
|
||||||
}
|
},
|
||||||
|
discordWebhook: {
|
||||||
|
type: String,
|
||||||
|
optional: true,
|
||||||
|
max: 200,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let CreatureSchema = new SimpleSchema({
|
let CreatureSchema = new SimpleSchema({
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
import spendResources from '/imports/api/creature/actions/spendResources.js'
|
import spendResources from '/imports/api/creature/actions/spendResources.js'
|
||||||
|
import {insertCreatureLog} from '/imports/api/creature/log/CreatureLogs.js';
|
||||||
|
|
||||||
export default function applyAction({prop}){
|
export default function applyAction({prop, creature}){
|
||||||
spendResources(prop);
|
spendResources(prop);
|
||||||
|
insertCreatureLog({
|
||||||
|
log: prop.name,
|
||||||
|
creature,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import math from '/imports/math.js';
|
import math from '/imports/math.js';
|
||||||
//if (Meteor.isServer){
|
import {insertCreatureLog} from '/imports/api/creature/log/CreatureLogs.js';
|
||||||
// var sendWebhook = require('/imports/server/discord/webhook.js').default;
|
|
||||||
//}
|
|
||||||
|
|
||||||
export default function applyAttack({
|
export default function applyAttack({
|
||||||
prop,
|
prop,
|
||||||
@@ -11,11 +9,8 @@ export default function applyAttack({
|
|||||||
//actionContext
|
//actionContext
|
||||||
}){
|
}){
|
||||||
let result = math.roll(1, 20) + prop.rollBonusResult;
|
let result = math.roll(1, 20) + prop.rollBonusResult;
|
||||||
if (Meteor.isClient){
|
insertCreatureLog({
|
||||||
console.log(`${creature.name} makes a ${prop.name} attack! Rolls ${result} to hit`);
|
log: `${prop.name} attack. ${result} to hit`,
|
||||||
}
|
creature,
|
||||||
//if (Meteor.isServer) sendWebhook({
|
});
|
||||||
// webhook: creature.webhook,
|
|
||||||
// message: `${creature.name} makes a ${prop.name} attack! Rolls ${result} to hit`,
|
|
||||||
//});
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ function applyProperty(options){
|
|||||||
applyAction(options);
|
applyAction(options);
|
||||||
return true;
|
return true;
|
||||||
case 'attack':
|
case 'attack':
|
||||||
applyAttack(options);
|
|
||||||
applyAction(options);
|
applyAction(options);
|
||||||
|
applyAttack(options);
|
||||||
return true;
|
return true;
|
||||||
case 'damage':
|
case 'damage':
|
||||||
applyDamage(options);
|
applyDamage(options);
|
||||||
|
|||||||
54
app/imports/api/creature/log/CreatureLogs.js
Normal file
54
app/imports/api/creature/log/CreatureLogs.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import SimpleSchema from 'simpl-schema';
|
||||||
|
if (Meteor.isServer){
|
||||||
|
var sendWebhookAsCreature = require('/imports/server/discord/sendWebhook.js').sendWebhookAsCreature;
|
||||||
|
}
|
||||||
|
|
||||||
|
let CreatureLogs = new Mongo.Collection('creatureLogs');
|
||||||
|
|
||||||
|
let CreatureLogSchema = new SimpleSchema({
|
||||||
|
text: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
allowedValues: ['roll', 'change', 'damage', 'info'],
|
||||||
|
defaultValue: 'info',
|
||||||
|
},
|
||||||
|
// The real-world date that it occured, usually sorted by date
|
||||||
|
date: {
|
||||||
|
type: Date,
|
||||||
|
autoValue: function() {
|
||||||
|
// If the date isn't set, set it to now
|
||||||
|
if (!this.isSet) {
|
||||||
|
return new Date();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
index: 1,
|
||||||
|
},
|
||||||
|
creatureId: {
|
||||||
|
type: String,
|
||||||
|
regEx: SimpleSchema.RegEx.Id,
|
||||||
|
index: 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
CreatureLogs.attachSchema(CreatureLogSchema);
|
||||||
|
|
||||||
|
// This function should only be called by trusted code. No permission checks
|
||||||
|
const insertCreatureLog = function({log, creature}){
|
||||||
|
if (typeof log === 'string'){
|
||||||
|
log = {text: log};
|
||||||
|
}
|
||||||
|
log.creatureId = creature._id;
|
||||||
|
let id = CreatureLogs.insert(log);
|
||||||
|
if (Meteor.isServer){
|
||||||
|
sendWebhookAsCreature({
|
||||||
|
creature,
|
||||||
|
content: log.text,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CreatureLogs;
|
||||||
|
export { CreatureLogSchema, insertCreatureLog};
|
||||||
24
app/imports/server/discord/sendWebhook.js
Normal file
24
app/imports/server/discord/sendWebhook.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import Discord from 'discord.js'
|
||||||
|
export default function sendWebhook({webhookURL, message}){
|
||||||
|
//webhookURL = https://discordapp.com/api/webhooks/<id>/<token>
|
||||||
|
let urlArray = webhookURL.split('/');
|
||||||
|
let token = urlArray.pop();
|
||||||
|
let id = urlArray.pop();
|
||||||
|
// const hook = new Discord.WebhookClient(webhook.id, webhook.token);
|
||||||
|
const hook = new Discord.WebhookClient(id, token);
|
||||||
|
// Send a message using the webhook
|
||||||
|
hook.send(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sendWebhookAsCreature({creature, content, embeds}){
|
||||||
|
if (!creature || !creature.discordWebhook) return;
|
||||||
|
sendWebhook({
|
||||||
|
webhookURL: creature.discordWebhook,
|
||||||
|
message: {
|
||||||
|
username: creature.name,
|
||||||
|
avatar_url: creature.avatarPicture,
|
||||||
|
content,
|
||||||
|
embeds,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import Discord from 'discord.js'
|
|
||||||
export default function sendWebhook({webhook, message}){
|
|
||||||
// const hook = new Discord.WebhookClient(webhook.id, webhook.token);
|
|
||||||
const hook = new Discord.WebhookClient('420492135716880394', 'KHmRsf9QHd81C4LZOyQe_cUw5ua4ugSaIlpDMNWo3vcNHs0p0JBOHfeGWtHKqPXMYgkk');
|
|
||||||
// Send a message using the webhook
|
|
||||||
hook.send(message);
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import SimpleSchema from 'simpl-schema';
|
import SimpleSchema from 'simpl-schema';
|
||||||
import Creatures from '/imports/api/creature/Creatures.js';
|
import Creatures from '/imports/api/creature/Creatures.js';
|
||||||
import CreatureProperties from '/imports/api/creature/CreatureProperties.js';
|
import CreatureProperties from '/imports/api/creature/CreatureProperties.js';
|
||||||
|
import CreatureLogs from '/imports/api/creature/log/CreatureLogs.js';
|
||||||
|
|
||||||
let schema = new SimpleSchema({
|
let schema = new SimpleSchema({
|
||||||
creatureId: {
|
creatureId: {
|
||||||
@@ -28,6 +29,12 @@ Meteor.publish('singleCharacter', function(creatureId){
|
|||||||
CreatureProperties.find({
|
CreatureProperties.find({
|
||||||
'ancestors.id': creatureId,
|
'ancestors.id': creatureId,
|
||||||
}),
|
}),
|
||||||
|
CreatureLogs.find({
|
||||||
|
creatureId,
|
||||||
|
}, {
|
||||||
|
limit: 20,
|
||||||
|
sort: {date: -1},
|
||||||
|
}),
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,24 +4,18 @@
|
|||||||
label="Name"
|
label="Name"
|
||||||
:value="model.name"
|
:value="model.name"
|
||||||
:error-messages="errors.name"
|
:error-messages="errors.name"
|
||||||
:debounce-time="debounceTime"
|
|
||||||
:disabled="disabled"
|
|
||||||
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
|
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
|
||||||
/>
|
/>
|
||||||
<text-field
|
<text-field
|
||||||
label="Alignment"
|
label="Alignment"
|
||||||
:value="model.alignment"
|
:value="model.alignment"
|
||||||
:error-messages="errors.alignment"
|
:error-messages="errors.alignment"
|
||||||
:debounce-time="debounceTime"
|
|
||||||
:disabled="disabled"
|
|
||||||
@change="(value, ack) => $emit('change', {path: ['alignment'], value, ack})"
|
@change="(value, ack) => $emit('change', {path: ['alignment'], value, ack})"
|
||||||
/>
|
/>
|
||||||
<text-field
|
<text-field
|
||||||
label="Gender"
|
label="Gender"
|
||||||
:value="model.gender"
|
:value="model.gender"
|
||||||
:error-messages="errors.gender"
|
:error-messages="errors.gender"
|
||||||
:debounce-time="debounceTime"
|
|
||||||
:disabled="disabled"
|
|
||||||
@change="(value, ack) => $emit('change', {path: ['gender'], value, ack})"
|
@change="(value, ack) => $emit('change', {path: ['gender'], value, ack})"
|
||||||
/>
|
/>
|
||||||
<text-field
|
<text-field
|
||||||
@@ -29,8 +23,6 @@
|
|||||||
hint="A link to a high resolution image"
|
hint="A link to a high resolution image"
|
||||||
:value="model.picture"
|
:value="model.picture"
|
||||||
:error-messages="errors.picture"
|
:error-messages="errors.picture"
|
||||||
:debounce-time="debounceTime"
|
|
||||||
:disabled="disabled"
|
|
||||||
@change="(value, ack) => $emit('change', {path: ['picture'], value, ack})"
|
@change="(value, ack) => $emit('change', {path: ['picture'], value, ack})"
|
||||||
/>
|
/>
|
||||||
<text-field
|
<text-field
|
||||||
@@ -38,8 +30,6 @@
|
|||||||
hint="A link to a smaller, square image to use as an avatar"
|
hint="A link to a smaller, square image to use as an avatar"
|
||||||
:value="model.avatarPicture"
|
:value="model.avatarPicture"
|
||||||
:error-messages="errors.avatarPicture"
|
:error-messages="errors.avatarPicture"
|
||||||
:debounce-time="debounceTime"
|
|
||||||
:disabled="disabled"
|
|
||||||
@change="(value, ack) => $emit('change', {path: ['avatarPicture'], value, ack})"
|
@change="(value, ack) => $emit('change', {path: ['avatarPicture'], value, ack})"
|
||||||
/>
|
/>
|
||||||
<form-sections>
|
<form-sections>
|
||||||
@@ -47,7 +37,6 @@
|
|||||||
<v-switch
|
<v-switch
|
||||||
label="Hide redundant stats"
|
label="Hide redundant stats"
|
||||||
:input-value="model.settings.hideUnusedStats"
|
:input-value="model.settings.hideUnusedStats"
|
||||||
:disabled="disabled"
|
|
||||||
@change="value => $emit('change', {path: ['settings','hideUnusedStats'], value: !!value})"
|
@change="value => $emit('change', {path: ['settings','hideUnusedStats'], value: !!value})"
|
||||||
/>
|
/>
|
||||||
<text-field
|
<text-field
|
||||||
@@ -59,30 +48,32 @@
|
|||||||
max="1"
|
max="1"
|
||||||
step="0.1"
|
step="0.1"
|
||||||
:value="model.settings.hitDiceResetMultiplier"
|
:value="model.settings.hitDiceResetMultiplier"
|
||||||
:debounce-time="debounceTime"
|
|
||||||
:disabled="disabled"
|
|
||||||
@change="(value, ack) => $emit('change', {path: ['settings','hitDiceResetMultiplier'], value, ack})"
|
@change="(value, ack) => $emit('change', {path: ['settings','hitDiceResetMultiplier'], value, ack})"
|
||||||
/>
|
/>
|
||||||
|
<text-field
|
||||||
|
label="Discord Webhook URL"
|
||||||
|
hint="This creature's logs will be posted to the discord channel"
|
||||||
|
placeholder="https://discordapp.com/api/webhooks/<id>/<token>"
|
||||||
|
:value="model.settings.discordWebhook"
|
||||||
|
@change="(value, ack) => $emit('change', {path: ['settings','discordWebhook'], value, ack})"
|
||||||
|
/>
|
||||||
<!--
|
<!--
|
||||||
<v-switch
|
<v-switch
|
||||||
label="Use variant encumbrance"
|
label="Use variant encumbrance"
|
||||||
:input-value="model.settings.useVariantEncumbrance"
|
:input-value="model.settings.useVariantEncumbrance"
|
||||||
:error-messages="errors.useVariantEncumbrance"
|
:error-messages="errors.useVariantEncumbrance"
|
||||||
:disabled="disabled"
|
|
||||||
@change="value => $emit('change', {path: ['settings','useVariantEncumbrance'], value})"
|
@change="value => $emit('change', {path: ['settings','useVariantEncumbrance'], value})"
|
||||||
/>
|
/>
|
||||||
<v-switch
|
<v-switch
|
||||||
label="Hide spells tab"
|
label="Hide spells tab"
|
||||||
:input-value="model.settings.hideSpellcasting"
|
:input-value="model.settings.hideSpellcasting"
|
||||||
:error-messages="errors.hideSpellcasting"
|
:error-messages="errors.hideSpellcasting"
|
||||||
:disabled="disabled"
|
|
||||||
@change="value => $emit('change', {path: ['settings','hideSpellcasting'], value})"
|
@change="value => $emit('change', {path: ['settings','hideSpellcasting'], value})"
|
||||||
/>
|
/>
|
||||||
<v-switch
|
<v-switch
|
||||||
label="Swap ability scores and modifiers"
|
label="Swap ability scores and modifiers"
|
||||||
:input-value="model.settings.swapStatAndModifier"
|
:input-value="model.settings.swapStatAndModifier"
|
||||||
:error-messages="errors.swapStatAndModifier"
|
:error-messages="errors.swapStatAndModifier"
|
||||||
:disabled="disabled"
|
|
||||||
@change="value => $emit('change', {path: ['settings','swapStatAndModifier'], value})"
|
@change="value => $emit('change', {path: ['settings','swapStatAndModifier'], value})"
|
||||||
/>
|
/>
|
||||||
-->
|
-->
|
||||||
@@ -114,7 +105,6 @@ export default {
|
|||||||
attackForm: {
|
attackForm: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
},
|
},
|
||||||
debounceTime: Number,
|
|
||||||
disabled: Boolean,
|
disabled: Boolean,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -37,6 +37,9 @@
|
|||||||
<v-tabs-items
|
<v-tabs-items
|
||||||
v-model="activeTab"
|
v-model="activeTab"
|
||||||
>
|
>
|
||||||
|
<v-tab-item>
|
||||||
|
<log-tab :creature-id="creatureId" />
|
||||||
|
</v-tab-item>
|
||||||
<v-tab-item>
|
<v-tab-item>
|
||||||
<stats-tab :creature-id="creatureId" />
|
<stats-tab :creature-id="creatureId" />
|
||||||
</v-tab-item>
|
</v-tab-item>
|
||||||
@@ -58,6 +61,19 @@
|
|||||||
</v-tabs-items>
|
</v-tabs-items>
|
||||||
</div>
|
</div>
|
||||||
</v-fade-transition>
|
</v-fade-transition>
|
||||||
|
<v-snackbar
|
||||||
|
v-for="(snackbar, index) in snackbars"
|
||||||
|
:key="index"
|
||||||
|
v-model="snackbar.open"
|
||||||
|
>
|
||||||
|
{{ snackbar.text }}
|
||||||
|
<v-btn
|
||||||
|
flat
|
||||||
|
@click="snackbar.open = false"
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</v-btn>
|
||||||
|
</v-snackbar>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -65,6 +81,7 @@
|
|||||||
//TODO add a "no character found" screen if shown on a false address
|
//TODO add a "no character found" screen if shown on a false address
|
||||||
// or on a character the user does not have permission to view
|
// or on a character the user does not have permission to view
|
||||||
import Creatures from '/imports/api/creature/Creatures.js';
|
import Creatures from '/imports/api/creature/Creatures.js';
|
||||||
|
import LogTab from '/imports/ui/creature/character/characterSheetTabs/LogTab.vue';
|
||||||
import StatsTab from '/imports/ui/creature/character/characterSheetTabs/StatsTab.vue';
|
import StatsTab from '/imports/ui/creature/character/characterSheetTabs/StatsTab.vue';
|
||||||
import FeaturesTab from '/imports/ui/creature/character/characterSheetTabs/FeaturesTab.vue';
|
import FeaturesTab from '/imports/ui/creature/character/characterSheetTabs/FeaturesTab.vue';
|
||||||
import InventoryTab from '/imports/ui/creature/character/characterSheetTabs/InventoryTab.vue';
|
import InventoryTab from '/imports/ui/creature/character/characterSheetTabs/InventoryTab.vue';
|
||||||
@@ -72,9 +89,11 @@
|
|||||||
import PersonaTab from '/imports/ui/creature/character/characterSheetTabs/PersonaTab.vue';
|
import PersonaTab from '/imports/ui/creature/character/characterSheetTabs/PersonaTab.vue';
|
||||||
import TreeTab from '/imports/ui/creature/character/characterSheetTabs/TreeTab.vue';
|
import TreeTab from '/imports/ui/creature/character/characterSheetTabs/TreeTab.vue';
|
||||||
import { assertEditPermission } from '/imports/api/creature/creaturePermissions.js';
|
import { assertEditPermission } from '/imports/api/creature/creaturePermissions.js';
|
||||||
|
import CreatureLogs from '/imports/api/creature/log/CreatureLogs.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
LogTab,
|
||||||
StatsTab,
|
StatsTab,
|
||||||
FeaturesTab,
|
FeaturesTab,
|
||||||
InventoryTab,
|
InventoryTab,
|
||||||
@@ -92,18 +111,13 @@
|
|||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
data(){return {
|
||||||
|
snackbars: new Set(),
|
||||||
|
}},
|
||||||
reactiveProvide: {
|
reactiveProvide: {
|
||||||
name: 'context',
|
name: 'context',
|
||||||
include: ['creature', 'editPermission'],
|
include: ['creature', 'editPermission'],
|
||||||
},
|
},
|
||||||
onMounted(){
|
|
||||||
this.$store.commit('setPageTitle', this.creature && this.creature.name || 'Character Sheet');
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
'creature.name'(value){
|
|
||||||
this.$store.commit('setPageTitle', value || 'Character Sheet');
|
|
||||||
},
|
|
||||||
},
|
|
||||||
computed: {
|
computed: {
|
||||||
activeTab: {
|
activeTab: {
|
||||||
get(){
|
get(){
|
||||||
@@ -113,6 +127,25 @@
|
|||||||
this.$emit('update:tabs', newTab);
|
this.$emit('update:tabs', newTab);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'creature.name'(value){
|
||||||
|
this.$store.commit('setPageTitle', value || 'Character Sheet');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted(){
|
||||||
|
this.$store.commit('setPageTitle', this.creature && this.creature.name || 'Character Sheet');
|
||||||
|
let that = this;
|
||||||
|
let observer = CreatureLogs.find({
|
||||||
|
creatureId: this.creatureId,
|
||||||
|
}).observe({
|
||||||
|
added(doc){
|
||||||
|
console.log({added: doc});
|
||||||
|
that.snackbars.add(doc);
|
||||||
|
setTimeout(function(){that.snackbars.remove(doc)}, 8000);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
console.log(observer);
|
||||||
},
|
},
|
||||||
meteor: {
|
meteor: {
|
||||||
$subscribe: {
|
$subscribe: {
|
||||||
|
|||||||
@@ -91,6 +91,9 @@
|
|||||||
max="100px"
|
max="100px"
|
||||||
@change="e => $emit('input', e)"
|
@change="e => $emit('input', e)"
|
||||||
>
|
>
|
||||||
|
<v-tab>
|
||||||
|
Log
|
||||||
|
</v-tab>
|
||||||
<v-tab>
|
<v-tab>
|
||||||
Stats
|
Stats
|
||||||
</v-tab>
|
</v-tab>
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<template lang="html">
|
||||||
|
<div class="log layout column reverse">
|
||||||
|
<div
|
||||||
|
v-for="log in logs"
|
||||||
|
:key="log._id"
|
||||||
|
>
|
||||||
|
{{ log.text }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import CreatureLogs from '/imports/api/creature/log/CreatureLogs.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
creatureId: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
meteor: {
|
||||||
|
logs(){
|
||||||
|
return CreatureLogs.find({
|
||||||
|
creatureId: this.creatureId,
|
||||||
|
}, {
|
||||||
|
limit: 20,
|
||||||
|
sort: {date: -1},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user