Files
habitica/website/client/mixins/spells.js
T
Mateus Etto c21726ec61 No Ethereal Surge on Mages (#10121)
* problem location identified (breaks code)

* problem identification notes

* Add class checking to ES (does not yet notify user)

* Add error message

* Add .gitattributes

Attempting to fix line ending disaster

* package stuff

so I can see what's broken

* add reminder and hopefully fix gitattributes

* Fix lint errors

* Redo surge fail notifs

* exterminate rogue comment, fix gitattributes

* Remove unused import 

As per @paglias' request.

* fix(lint): remove extraneous expression

* Delete .gitattributes

* Fix skill key surge -> mpheal

* Show notification only when there are mages in party

* Fix notification being too big and appearing outside the notification div

* Remove unused code

* Only show the notification on parties with 2 or more mages

The caster is a mage, so certainly at least 1 mage will be counted.

* Automated test: mpheal does not heal other mages

* Fix lint error

* Fix typo in test description

* Increase performance of test

* Using target instead of requestion partyMembers again

* Rename variable 'party' to 'partyMembers'

* Update strings in English

* spell -> Skill
2018-03-31 13:34:39 +02:00

179 lines
5.9 KiB
JavaScript

import isArray from 'lodash/isArray';
// @TODO: Let's separate some of the business logic out of Vue if possible
export default {
methods: {
handleCastCancelKeyUp (keyEvent) {
if (keyEvent.keyCode !== 27) return;
this.castCancel();
},
async castStart (spell, member) {
if (this.$store.state.spellOptions.castingSpell) {
this.castCancel();
return;
}
if (this.user.stats.mp < spell.mana) return this.text(this.$t('notEnoughMana'));
if (spell.immediateUse && this.user.stats.gp < spell.value) {
return this.text('Not enough gold.');
}
this.potionClickMode = true;
this.applyingAction = true;
this.$store.state.spellOptions.castingSpell = true;
this.spell = spell;
if (spell.target === 'self') {
return this.castEnd(null, spell.target);
} else if (spell.target === 'party') {
if (!this.user.party._id) {
let party = [this.user];
return this.castEnd(party, spell.target);
}
let partyMembers = this.$store.state.partyMembers.data;
if (!isArray(partyMembers)) {
partyMembers = [this.user];
}
this.castEnd(partyMembers, spell.target);
} else if (spell.target === 'tasks') {
let userTasks = this.$store.state.tasks.data;
// exclude rewards
let tasks = userTasks.habits
.concat(userTasks.dailys)
.concat(userTasks.todos);
// exclude challenge and group plan tasks
tasks = tasks.filter((task) => {
if (task.challenge && task.challenge.id && !task.challenge.broken) return false;
if (task.group && task.group.id && !task.group.broken) return false;
return true;
});
return this.castEnd(tasks, spell.target);
} else if (spell.target === 'user') {
let result = await this.castEnd(member, spell.target);
if (member.id === this.user.id) {
this.$set(this.$store.state.user.data, 'stats', member.stats);
}
return result;
} else {
// If the cast target has to be selected (and can be cancelled)
document.addEventListener('keyup', this.handleCastCancelKeyUp);
this.$root.$on('castEnd', (target, type, $event) => {
this.castEnd(target, type, $event);
});
}
},
async castEnd (target, type) {
if (!this.$store.state.spellOptions.castingSpell) return;
let beforeQuestProgress;
if (this.spell.target === 'party') beforeQuestProgress = this.questProgress();
if (!this.applyingAction) return 'No applying action';
if (this.spell.target !== type) return this.text(this.$t('invalidTarget'));
if (target && target.type && target.type === 'reward') return this.text(this.$t('invalidTarget'));
if (target && target.challenge && target.challenge.id) return this.text(this.$t('invalidTarget'));
if (target && target.group && target.group.id) return this.text(this.$t('invalidTarget'));
let spell = this.spell;
this.castCancel();
// the selected member doesn't have the flags property which sets `cardReceived`
if (spell.pinType !== 'card') {
spell.cast(this.user, target);
}
let targetId = target ? target._id : null;
let spellText = typeof spell.text === 'function' ? spell.text() : spell.text;
let apiResult = await this.$store.dispatch('user:castSpell', {key: spell.key, targetId});
let msg = '';
switch (type) {
case 'task':
msg = this.$t('youCastTarget', {
spell: spellText,
target: target.text,
});
break;
case 'user':
msg = spell.pinType === 'card' ?
this.$t('sentCardToUser', { profileName: target.profile.name }) :
this.$t('youCastTarget', {
spell: spellText,
target: target.profile.name,
});
break;
case 'party':
msg = this.$t('youCastParty', {
spell: spellText,
});
break;
default:
msg = this.$t('youCast', {
spell: spellText,
});
break;
}
if (spell.pinType === 'card') {
const newUserGp = apiResult.data.data.user.stats.gp;
this.$store.state.user.data.stats.gp = newUserGp;
}
this.markdown(msg); // @TODO: mardown directive?
// If using mpheal and there are other mages in the party, show extra notification
if (type === 'party' && spell.key === 'mpheal') {
// Counting mages
let magesCount = 0;
for (let i = 0; i < target.length; i++) {
if (target[i].stats.class === 'wizard') {
magesCount++;
}
}
// If there are mages, show message telling that the mpheal don't work on other mages
// The count must be bigger than 1 because the user casting the spell is a mage
if (magesCount > 1) {
this.markdown(this.$t('spellWizardNoEthOnMage'));
}
}
// @TODO:
if (!beforeQuestProgress) return apiResult;
let questProgress = this.questProgress() - beforeQuestProgress;
if (questProgress > 0) {
let userQuest = this.quests[this.user.party.quest.key];
if (userQuest.boss) {
this.quest('questDamage', questProgress.toFixed(1));
} else if (userQuest.collection && userQuest.collect) {
this.quest('questCollection', questProgress);
}
}
return apiResult;
// @TOOD: User.sync();
},
castCancel () {
this.potionClickMode = false;
this.applyingAction = false;
this.spell = null;
document.querySelector('body').style.cursor = 'initial';
this.$store.state.spellOptions.castingSpell = false;
// Remove listeners
this.$root.$off('castEnd');
document.removeEventListener('keyup', this.handleCastCancelKeyUp);
},
},
};