mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 06:37:23 +01:00
convert spells to es6
This commit is contained in:
@@ -22,12 +22,14 @@ import gear from './gear';
|
|||||||
|
|
||||||
import appearances from './appearance';
|
import appearances from './appearance';
|
||||||
import backgrounds from './appearance/backgrounds.js'
|
import backgrounds from './appearance/backgrounds.js'
|
||||||
|
import spells from './spells';
|
||||||
|
|
||||||
api.mystery = mysterySets;
|
api.mystery = mysterySets;
|
||||||
|
|
||||||
api.itemList = ITEM_LIST;
|
api.itemList = ITEM_LIST;
|
||||||
|
|
||||||
api.gear = gear;
|
api.gear = gear;
|
||||||
|
api.spells = spells;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Time Traveler Store, mystery sets need their items mapped in
|
Time Traveler Store, mystery sets need their items mapped in
|
||||||
@@ -100,607 +102,6 @@ api.classes = CLASSES;
|
|||||||
|
|
||||||
api.gearTypes = GEAR_TYPES;
|
api.gearTypes = GEAR_TYPES;
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
---------------------------------------------------------------
|
|
||||||
Spells
|
|
||||||
---------------------------------------------------------------
|
|
||||||
Text, notes, and mana are obvious. The rest:
|
|
||||||
|
|
||||||
* {target}: one of [task, self, party, user]. This is very important, because if the cast() function is expecting one
|
|
||||||
thing and receives another, it will cause errors. `self` is used for self buffs, multi-task debuffs, AOEs (eg, meteor-shower),
|
|
||||||
etc. Basically, use self for anything that's not [task, party, user] and is an instant-cast
|
|
||||||
|
|
||||||
* {cast}: the function that's run to perform the ability's action. This is pretty slick - because this is exported to the
|
|
||||||
web, this function can be performed on the client and on the server. `user` param is self (needed for determining your
|
|
||||||
own stats for effectiveness of cast), and `target` param is one of [task, party, user]. In the case of `self` spells,
|
|
||||||
you act on `user` instead of `target`. You can trust these are the correct objects, as long as the `target` attr of the
|
|
||||||
spell is correct. Take a look at habitrpg/src/models/user.js and habitrpg/src/models/task.js for what attributes are
|
|
||||||
available on each model. Note `task.value` is its "redness". If party is passed in, it's an array of users,
|
|
||||||
so you'll want to iterate over them like: `_.each(target,function(member){...})`
|
|
||||||
|
|
||||||
Note, user.stats.mp is docked after automatically (it's appended to functions automatically down below in an _.each)
|
|
||||||
*/
|
|
||||||
|
|
||||||
diminishingReturns = function(bonus, max, halfway) {
|
|
||||||
if (halfway == null) {
|
|
||||||
halfway = max / 2;
|
|
||||||
}
|
|
||||||
return max * (bonus / (bonus + halfway));
|
|
||||||
};
|
|
||||||
|
|
||||||
calculateBonus = function(value, stat, crit, stat_scale) {
|
|
||||||
if (crit == null) {
|
|
||||||
crit = 1;
|
|
||||||
}
|
|
||||||
if (stat_scale == null) {
|
|
||||||
stat_scale = 0.5;
|
|
||||||
}
|
|
||||||
return (value < 0 ? 1 : value + 1) + (stat * stat_scale * crit);
|
|
||||||
};
|
|
||||||
|
|
||||||
api.spells = {
|
|
||||||
wizard: {
|
|
||||||
fireball: {
|
|
||||||
text: t('spellWizardFireballText'),
|
|
||||||
mana: 10,
|
|
||||||
lvl: 11,
|
|
||||||
target: 'task',
|
|
||||||
notes: t('spellWizardFireballNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
var base, bonus, req;
|
|
||||||
bonus = user._statsComputed.int * user.fns.crit('per');
|
|
||||||
bonus *= Math.ceil((target.value < 0 ? 1 : target.value + 1) * .075);
|
|
||||||
user.stats.exp += diminishingReturns(bonus, 75);
|
|
||||||
if ((base = user.party.quest.progress).up == null) {
|
|
||||||
base.up = 0;
|
|
||||||
}
|
|
||||||
user.party.quest.progress.up += Math.ceil(user._statsComputed.int * .1);
|
|
||||||
req = {
|
|
||||||
language: user.preferences.language
|
|
||||||
};
|
|
||||||
return user.fns.updateStats(user.stats, req);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mpheal: {
|
|
||||||
text: t('spellWizardMPHealText'),
|
|
||||||
mana: 30,
|
|
||||||
lvl: 12,
|
|
||||||
target: 'party',
|
|
||||||
notes: t('spellWizardMPHealNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
return _.each(target, function(member) {
|
|
||||||
var bonus;
|
|
||||||
bonus = user._statsComputed.int;
|
|
||||||
if (user._id !== member._id) {
|
|
||||||
return member.stats.mp += Math.ceil(diminishingReturns(bonus, 25, 125));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
earth: {
|
|
||||||
text: t('spellWizardEarthText'),
|
|
||||||
mana: 35,
|
|
||||||
lvl: 13,
|
|
||||||
target: 'party',
|
|
||||||
notes: t('spellWizardEarthNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
return _.each(target, function(member) {
|
|
||||||
var base, bonus;
|
|
||||||
bonus = user._statsComputed.int - user.stats.buffs.int;
|
|
||||||
if ((base = member.stats.buffs).int == null) {
|
|
||||||
base.int = 0;
|
|
||||||
}
|
|
||||||
return member.stats.buffs.int += Math.ceil(diminishingReturns(bonus, 30, 200));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
frost: {
|
|
||||||
text: t('spellWizardFrostText'),
|
|
||||||
mana: 40,
|
|
||||||
lvl: 14,
|
|
||||||
target: 'self',
|
|
||||||
notes: t('spellWizardFrostNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
return user.stats.buffs.streaks = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
warrior: {
|
|
||||||
smash: {
|
|
||||||
text: t('spellWarriorSmashText'),
|
|
||||||
mana: 10,
|
|
||||||
lvl: 11,
|
|
||||||
target: 'task',
|
|
||||||
notes: t('spellWarriorSmashNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
var base, bonus;
|
|
||||||
bonus = user._statsComputed.str * user.fns.crit('con');
|
|
||||||
target.value += diminishingReturns(bonus, 2.5, 35);
|
|
||||||
if ((base = user.party.quest.progress).up == null) {
|
|
||||||
base.up = 0;
|
|
||||||
}
|
|
||||||
return user.party.quest.progress.up += diminishingReturns(bonus, 55, 70);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
defensiveStance: {
|
|
||||||
text: t('spellWarriorDefensiveStanceText'),
|
|
||||||
mana: 25,
|
|
||||||
lvl: 12,
|
|
||||||
target: 'self',
|
|
||||||
notes: t('spellWarriorDefensiveStanceNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
var base, bonus;
|
|
||||||
bonus = user._statsComputed.con - user.stats.buffs.con;
|
|
||||||
if ((base = user.stats.buffs).con == null) {
|
|
||||||
base.con = 0;
|
|
||||||
}
|
|
||||||
return user.stats.buffs.con += Math.ceil(diminishingReturns(bonus, 40, 200));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
valorousPresence: {
|
|
||||||
text: t('spellWarriorValorousPresenceText'),
|
|
||||||
mana: 20,
|
|
||||||
lvl: 13,
|
|
||||||
target: 'party',
|
|
||||||
notes: t('spellWarriorValorousPresenceNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
return _.each(target, function(member) {
|
|
||||||
var base, bonus;
|
|
||||||
bonus = user._statsComputed.str - user.stats.buffs.str;
|
|
||||||
if ((base = member.stats.buffs).str == null) {
|
|
||||||
base.str = 0;
|
|
||||||
}
|
|
||||||
return member.stats.buffs.str += Math.ceil(diminishingReturns(bonus, 20, 200));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
intimidate: {
|
|
||||||
text: t('spellWarriorIntimidateText'),
|
|
||||||
mana: 15,
|
|
||||||
lvl: 14,
|
|
||||||
target: 'party',
|
|
||||||
notes: t('spellWarriorIntimidateNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
return _.each(target, function(member) {
|
|
||||||
var base, bonus;
|
|
||||||
bonus = user._statsComputed.con - user.stats.buffs.con;
|
|
||||||
if ((base = member.stats.buffs).con == null) {
|
|
||||||
base.con = 0;
|
|
||||||
}
|
|
||||||
return member.stats.buffs.con += Math.ceil(diminishingReturns(bonus, 24, 200));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
rogue: {
|
|
||||||
pickPocket: {
|
|
||||||
text: t('spellRoguePickPocketText'),
|
|
||||||
mana: 10,
|
|
||||||
lvl: 11,
|
|
||||||
target: 'task',
|
|
||||||
notes: t('spellRoguePickPocketNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
var bonus;
|
|
||||||
bonus = calculateBonus(target.value, user._statsComputed.per);
|
|
||||||
return user.stats.gp += diminishingReturns(bonus, 25, 75);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
backStab: {
|
|
||||||
text: t('spellRogueBackStabText'),
|
|
||||||
mana: 15,
|
|
||||||
lvl: 12,
|
|
||||||
target: 'task',
|
|
||||||
notes: t('spellRogueBackStabNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
var _crit, bonus, req;
|
|
||||||
_crit = user.fns.crit('str', .3);
|
|
||||||
bonus = calculateBonus(target.value, user._statsComputed.str, _crit);
|
|
||||||
user.stats.exp += diminishingReturns(bonus, 75, 50);
|
|
||||||
user.stats.gp += diminishingReturns(bonus, 18, 75);
|
|
||||||
req = {
|
|
||||||
language: user.preferences.language
|
|
||||||
};
|
|
||||||
return user.fns.updateStats(user.stats, req);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
toolsOfTrade: {
|
|
||||||
text: t('spellRogueToolsOfTradeText'),
|
|
||||||
mana: 25,
|
|
||||||
lvl: 13,
|
|
||||||
target: 'party',
|
|
||||||
notes: t('spellRogueToolsOfTradeNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
return _.each(target, function(member) {
|
|
||||||
var base, bonus;
|
|
||||||
bonus = user._statsComputed.per - user.stats.buffs.per;
|
|
||||||
if ((base = member.stats.buffs).per == null) {
|
|
||||||
base.per = 0;
|
|
||||||
}
|
|
||||||
return member.stats.buffs.per += Math.ceil(diminishingReturns(bonus, 100, 50));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
stealth: {
|
|
||||||
text: t('spellRogueStealthText'),
|
|
||||||
mana: 45,
|
|
||||||
lvl: 14,
|
|
||||||
target: 'self',
|
|
||||||
notes: t('spellRogueStealthNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
var base;
|
|
||||||
if ((base = user.stats.buffs).stealth == null) {
|
|
||||||
base.stealth = 0;
|
|
||||||
}
|
|
||||||
return user.stats.buffs.stealth += Math.ceil(diminishingReturns(user._statsComputed.per, user.dailys.length * 0.64, 55));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
healer: {
|
|
||||||
heal: {
|
|
||||||
text: t('spellHealerHealText'),
|
|
||||||
mana: 15,
|
|
||||||
lvl: 11,
|
|
||||||
target: 'self',
|
|
||||||
notes: t('spellHealerHealNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
user.stats.hp += (user._statsComputed.con + user._statsComputed.int + 5) * .075;
|
|
||||||
if (user.stats.hp > 50) {
|
|
||||||
return user.stats.hp = 50;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
brightness: {
|
|
||||||
text: t('spellHealerBrightnessText'),
|
|
||||||
mana: 15,
|
|
||||||
lvl: 12,
|
|
||||||
target: 'self',
|
|
||||||
notes: t('spellHealerBrightnessNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
return _.each(user.tasks, function(target) {
|
|
||||||
if (target.type === 'reward') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return target.value += 4 * (user._statsComputed.int / (user._statsComputed.int + 40));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
protectAura: {
|
|
||||||
text: t('spellHealerProtectAuraText'),
|
|
||||||
mana: 30,
|
|
||||||
lvl: 13,
|
|
||||||
target: 'party',
|
|
||||||
notes: t('spellHealerProtectAuraNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
return _.each(target, function(member) {
|
|
||||||
var base, bonus;
|
|
||||||
bonus = user._statsComputed.con - user.stats.buffs.con;
|
|
||||||
if ((base = member.stats.buffs).con == null) {
|
|
||||||
base.con = 0;
|
|
||||||
}
|
|
||||||
return member.stats.buffs.con += Math.ceil(diminishingReturns(bonus, 200, 200));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
heallAll: {
|
|
||||||
text: t('spellHealerHealAllText'),
|
|
||||||
mana: 25,
|
|
||||||
lvl: 14,
|
|
||||||
target: 'party',
|
|
||||||
notes: t('spellHealerHealAllNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
return _.each(target, function(member) {
|
|
||||||
member.stats.hp += (user._statsComputed.con + user._statsComputed.int + 5) * .04;
|
|
||||||
if (member.stats.hp > 50) {
|
|
||||||
return member.stats.hp = 50;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
special: {
|
|
||||||
snowball: {
|
|
||||||
text: t('spellSpecialSnowballAuraText'),
|
|
||||||
mana: 0,
|
|
||||||
value: 15,
|
|
||||||
target: 'user',
|
|
||||||
notes: t('spellSpecialSnowballAuraNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
var base;
|
|
||||||
target.stats.buffs.snowball = true;
|
|
||||||
target.stats.buffs.spookDust = false;
|
|
||||||
target.stats.buffs.shinySeed = false;
|
|
||||||
target.stats.buffs.seafoam = false;
|
|
||||||
if ((base = target.achievements).snowball == null) {
|
|
||||||
base.snowball = 0;
|
|
||||||
}
|
|
||||||
target.achievements.snowball++;
|
|
||||||
return user.items.special.snowball--;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
salt: {
|
|
||||||
text: t('spellSpecialSaltText'),
|
|
||||||
mana: 0,
|
|
||||||
value: 5,
|
|
||||||
immediateUse: true,
|
|
||||||
target: 'self',
|
|
||||||
notes: t('spellSpecialSaltNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
user.stats.buffs.snowball = false;
|
|
||||||
return user.stats.gp -= 5;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
spookDust: {
|
|
||||||
text: t('spellSpecialSpookDustText'),
|
|
||||||
mana: 0,
|
|
||||||
value: 15,
|
|
||||||
target: 'user',
|
|
||||||
notes: t('spellSpecialSpookDustNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
var base;
|
|
||||||
target.stats.buffs.snowball = false;
|
|
||||||
target.stats.buffs.spookDust = true;
|
|
||||||
target.stats.buffs.shinySeed = false;
|
|
||||||
target.stats.buffs.seafoam = false;
|
|
||||||
if ((base = target.achievements).spookDust == null) {
|
|
||||||
base.spookDust = 0;
|
|
||||||
}
|
|
||||||
target.achievements.spookDust++;
|
|
||||||
return user.items.special.spookDust--;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
opaquePotion: {
|
|
||||||
text: t('spellSpecialOpaquePotionText'),
|
|
||||||
mana: 0,
|
|
||||||
value: 5,
|
|
||||||
immediateUse: true,
|
|
||||||
target: 'self',
|
|
||||||
notes: t('spellSpecialOpaquePotionNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
user.stats.buffs.spookDust = false;
|
|
||||||
return user.stats.gp -= 5;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
shinySeed: {
|
|
||||||
text: t('spellSpecialShinySeedText'),
|
|
||||||
mana: 0,
|
|
||||||
value: 15,
|
|
||||||
target: 'user',
|
|
||||||
notes: t('spellSpecialShinySeedNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
var base;
|
|
||||||
target.stats.buffs.snowball = false;
|
|
||||||
target.stats.buffs.spookDust = false;
|
|
||||||
target.stats.buffs.shinySeed = true;
|
|
||||||
target.stats.buffs.seafoam = false;
|
|
||||||
if ((base = target.achievements).shinySeed == null) {
|
|
||||||
base.shinySeed = 0;
|
|
||||||
}
|
|
||||||
target.achievements.shinySeed++;
|
|
||||||
return user.items.special.shinySeed--;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
petalFreePotion: {
|
|
||||||
text: t('spellSpecialPetalFreePotionText'),
|
|
||||||
mana: 0,
|
|
||||||
value: 5,
|
|
||||||
immediateUse: true,
|
|
||||||
target: 'self',
|
|
||||||
notes: t('spellSpecialPetalFreePotionNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
user.stats.buffs.shinySeed = false;
|
|
||||||
return user.stats.gp -= 5;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
seafoam: {
|
|
||||||
text: t('spellSpecialSeafoamText'),
|
|
||||||
mana: 0,
|
|
||||||
value: 15,
|
|
||||||
target: 'user',
|
|
||||||
notes: t('spellSpecialSeafoamNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
var base;
|
|
||||||
target.stats.buffs.snowball = false;
|
|
||||||
target.stats.buffs.spookDust = false;
|
|
||||||
target.stats.buffs.shinySeed = false;
|
|
||||||
target.stats.buffs.seafoam = true;
|
|
||||||
if ((base = target.achievements).seafoam == null) {
|
|
||||||
base.seafoam = 0;
|
|
||||||
}
|
|
||||||
target.achievements.seafoam++;
|
|
||||||
return user.items.special.seafoam--;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
sand: {
|
|
||||||
text: t('spellSpecialSandText'),
|
|
||||||
mana: 0,
|
|
||||||
value: 5,
|
|
||||||
immediateUse: true,
|
|
||||||
target: 'self',
|
|
||||||
notes: t('spellSpecialSandNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
user.stats.buffs.seafoam = false;
|
|
||||||
return user.stats.gp -= 5;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
nye: {
|
|
||||||
text: t('nyeCard'),
|
|
||||||
mana: 0,
|
|
||||||
value: 10,
|
|
||||||
immediateUse: true,
|
|
||||||
silent: true,
|
|
||||||
target: 'user',
|
|
||||||
notes: t('nyeCardNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
var base;
|
|
||||||
if (user === target) {
|
|
||||||
if ((base = user.achievements).nye == null) {
|
|
||||||
base.nye = 0;
|
|
||||||
}
|
|
||||||
user.achievements.nye++;
|
|
||||||
} else {
|
|
||||||
_.each([user, target], function(t) {
|
|
||||||
var base1;
|
|
||||||
if ((base1 = t.achievements).nye == null) {
|
|
||||||
base1.nye = 0;
|
|
||||||
}
|
|
||||||
return t.achievements.nye++;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (!target.items.special.nyeReceived) {
|
|
||||||
target.items.special.nyeReceived = [];
|
|
||||||
}
|
|
||||||
target.items.special.nyeReceived.push(user.profile.name);
|
|
||||||
target.flags.cardReceived = true;
|
|
||||||
if (typeof target.markModified === "function") {
|
|
||||||
target.markModified('items.special.nyeReceived');
|
|
||||||
}
|
|
||||||
return user.stats.gp -= 10;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
valentine: {
|
|
||||||
text: t('valentineCard'),
|
|
||||||
mana: 0,
|
|
||||||
value: 10,
|
|
||||||
immediateUse: true,
|
|
||||||
silent: true,
|
|
||||||
target: 'user',
|
|
||||||
notes: t('valentineCardNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
var base;
|
|
||||||
if (user === target) {
|
|
||||||
if ((base = user.achievements).valentine == null) {
|
|
||||||
base.valentine = 0;
|
|
||||||
}
|
|
||||||
user.achievements.valentine++;
|
|
||||||
} else {
|
|
||||||
_.each([user, target], function(t) {
|
|
||||||
var base1;
|
|
||||||
if ((base1 = t.achievements).valentine == null) {
|
|
||||||
base1.valentine = 0;
|
|
||||||
}
|
|
||||||
return t.achievements.valentine++;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (!target.items.special.valentineReceived) {
|
|
||||||
target.items.special.valentineReceived = [];
|
|
||||||
}
|
|
||||||
target.items.special.valentineReceived.push(user.profile.name);
|
|
||||||
target.flags.cardReceived = true;
|
|
||||||
if (typeof target.markModified === "function") {
|
|
||||||
target.markModified('items.special.valentineReceived');
|
|
||||||
}
|
|
||||||
return user.stats.gp -= 10;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
greeting: {
|
|
||||||
text: t('greetingCard'),
|
|
||||||
mana: 0,
|
|
||||||
value: 10,
|
|
||||||
immediateUse: true,
|
|
||||||
silent: true,
|
|
||||||
target: 'user',
|
|
||||||
notes: t('greetingCardNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
var base;
|
|
||||||
if (user === target) {
|
|
||||||
if ((base = user.achievements).greeting == null) {
|
|
||||||
base.greeting = 0;
|
|
||||||
}
|
|
||||||
user.achievements.greeting++;
|
|
||||||
} else {
|
|
||||||
_.each([user, target], function(t) {
|
|
||||||
var base1;
|
|
||||||
if ((base1 = t.achievements).greeting == null) {
|
|
||||||
base1.greeting = 0;
|
|
||||||
}
|
|
||||||
return t.achievements.greeting++;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (!target.items.special.greetingReceived) {
|
|
||||||
target.items.special.greetingReceived = [];
|
|
||||||
}
|
|
||||||
target.items.special.greetingReceived.push(user.profile.name);
|
|
||||||
target.flags.cardReceived = true;
|
|
||||||
if (typeof target.markModified === "function") {
|
|
||||||
target.markModified('items.special.greetingReceived');
|
|
||||||
}
|
|
||||||
return user.stats.gp -= 10;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
thankyou: {
|
|
||||||
text: t('thankyouCard'),
|
|
||||||
mana: 0,
|
|
||||||
value: 10,
|
|
||||||
immediateUse: true,
|
|
||||||
silent: true,
|
|
||||||
target: 'user',
|
|
||||||
notes: t('thankyouCardNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
var base;
|
|
||||||
if (user === target) {
|
|
||||||
if ((base = user.achievements).thankyou == null) {
|
|
||||||
base.thankyou = 0;
|
|
||||||
}
|
|
||||||
user.achievements.thankyou++;
|
|
||||||
} else {
|
|
||||||
_.each([user, target], function(t) {
|
|
||||||
var base1;
|
|
||||||
if ((base1 = t.achievements).thankyou == null) {
|
|
||||||
base1.thankyou = 0;
|
|
||||||
}
|
|
||||||
return t.achievements.thankyou++;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (!target.items.special.thankyouReceived) {
|
|
||||||
target.items.special.thankyouReceived = [];
|
|
||||||
}
|
|
||||||
target.items.special.thankyouReceived.push(user.profile.name);
|
|
||||||
target.flags.cardReceived = true;
|
|
||||||
if (typeof target.markModified === "function") {
|
|
||||||
target.markModified('items.special.thankyouReceived');
|
|
||||||
}
|
|
||||||
return user.stats.gp -= 10;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
birthday: {
|
|
||||||
text: t('birthdayCard'),
|
|
||||||
mana: 0,
|
|
||||||
value: 10,
|
|
||||||
immediateUse: true,
|
|
||||||
silent: true,
|
|
||||||
target: 'user',
|
|
||||||
notes: t('birthdayCardNotes'),
|
|
||||||
cast: function(user, target) {
|
|
||||||
var base;
|
|
||||||
if (user === target) {
|
|
||||||
if ((base = user.achievements).birthday == null) {
|
|
||||||
base.birthday = 0;
|
|
||||||
}
|
|
||||||
user.achievements.birthday++;
|
|
||||||
} else {
|
|
||||||
_.each([user, target], function(t) {
|
|
||||||
var base1;
|
|
||||||
if ((base1 = t.achievements).birthday == null) {
|
|
||||||
base1.birthday = 0;
|
|
||||||
}
|
|
||||||
return t.achievements.birthday++;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (!target.items.special.birthdayReceived) {
|
|
||||||
target.items.special.birthdayReceived = [];
|
|
||||||
}
|
|
||||||
target.items.special.birthdayReceived.push(user.profile.name);
|
|
||||||
target.flags.cardReceived = true;
|
|
||||||
if (typeof target.markModified === "function") {
|
|
||||||
target.markModified('items.special.birthdayReceived');
|
|
||||||
}
|
|
||||||
return user.stats.gp -= 10;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
api.cardTypes = {
|
api.cardTypes = {
|
||||||
greeting: {
|
greeting: {
|
||||||
key: 'greeting',
|
key: 'greeting',
|
||||||
@@ -727,21 +128,8 @@ api.cardTypes = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
_.each(api.spells, function(spellClass) {
|
|
||||||
return _.each(spellClass, function(spell, key) {
|
|
||||||
var _cast;
|
|
||||||
spell.key = key;
|
|
||||||
_cast = spell.cast;
|
|
||||||
return spell.cast = function(user, target) {
|
|
||||||
_cast(user, target);
|
|
||||||
return user.stats.mp -= spell.mana;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
api.special = api.spells.special;
|
api.special = api.spells.special;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
---------------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
Drops
|
Drops
|
||||||
|
|||||||
509
common/script/content/spells.js
Normal file
509
common/script/content/spells.js
Normal file
@@ -0,0 +1,509 @@
|
|||||||
|
import t from './translation';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------
|
||||||
|
Spells
|
||||||
|
---------------------------------------------------------------
|
||||||
|
Text, notes, and mana are obvious. The rest:
|
||||||
|
|
||||||
|
* {target}: one of [task, self, party, user]. This is very important, because if the cast() function is expecting one
|
||||||
|
thing and receives another, it will cause errors. `self` is used for self buffs, multi-task debuffs, AOEs (eg, meteor-shower),
|
||||||
|
etc. Basically, use self for anything that's not [task, party, user] and is an instant-cast
|
||||||
|
|
||||||
|
* {cast}: the function that's run to perform the ability's action. This is pretty slick - because this is exported to the
|
||||||
|
web, this function can be performed on the client and on the server. `user` param is self (needed for determining your
|
||||||
|
own stats for effectiveness of cast), and `target` param is one of [task, party, user]. In the case of `self` spells,
|
||||||
|
you act on `user` instead of `target`. You can trust these are the correct objects, as long as the `target` attr of the
|
||||||
|
spell is correct. Take a look at habitrpg/src/models/user.js and habitrpg/src/models/task.js for what attributes are
|
||||||
|
available on each model. Note `task.value` is its "redness". If party is passed in, it's an array of users,
|
||||||
|
so you'll want to iterate over them like: `_.each(target,function(member){...})`
|
||||||
|
|
||||||
|
Note, user.stats.mp is docked after automatically (it's appended to functions automatically down below in an _.each)
|
||||||
|
*/
|
||||||
|
|
||||||
|
function diminishingReturns (bonus, max, halfway) {
|
||||||
|
if (!halfway) halfway = max / 2;
|
||||||
|
return max * (bonus / (bonus + halfway));
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateBonus (value, stat, crit = 1, statScale = 0.5) {
|
||||||
|
return (value < 0 ? 1 : value + 1) + stat * statScale * crit;
|
||||||
|
}
|
||||||
|
|
||||||
|
let spells = {};
|
||||||
|
|
||||||
|
spells.wizard = {
|
||||||
|
fireball: {
|
||||||
|
text: t('spellWizardFireballText'),
|
||||||
|
mana: 10,
|
||||||
|
lvl: 11,
|
||||||
|
target: 'task',
|
||||||
|
notes: t('spellWizardFireballNotes'),
|
||||||
|
cast (user, target) {
|
||||||
|
let bonus = user._statsComputed.int * user.fns.crit('per');
|
||||||
|
bonus *= Math.ceil((target.value < 0 ? 1 : target.value + 1) * 0.075);
|
||||||
|
user.stats.exp += diminishingReturns(bonus, 75);
|
||||||
|
if (!user.party.quest.progress) user.party.quest.progress = 0;
|
||||||
|
user.party.quest.progress.up += Math.ceil(user._statsComputed.int * 9.1);
|
||||||
|
// TODO change, pass req to spell?
|
||||||
|
let req = {language: user.preferences.language};
|
||||||
|
user.fns.updateStats(user.stats, req);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mpheal: {
|
||||||
|
text: t('spellWizardMPHealText'),
|
||||||
|
mana: 30,
|
||||||
|
lvl: 12,
|
||||||
|
target: 'party',
|
||||||
|
notes: t('spellWizardMPHealNotes'),
|
||||||
|
cast (user, target) {
|
||||||
|
_.each(target, (member) => {
|
||||||
|
let bonus = user._statsComputed.int;
|
||||||
|
if (user._id !== member._id) {
|
||||||
|
member.stats.mp += Math.ceil(diminishingReturns(bonus, 25, 125));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
earth: {
|
||||||
|
text: t('spellWizardEarthText'),
|
||||||
|
mana: 35,
|
||||||
|
lvl: 13,
|
||||||
|
target: 'party',
|
||||||
|
notes: t('spellWizardEarthNotes'),
|
||||||
|
cast (user, target) {
|
||||||
|
_.each(target, (member) => {
|
||||||
|
let bonus = user._statsComputed.int - user.stats.buffs.int;
|
||||||
|
if (!member.stats.buffs.int) member.stats.buffs.int = 0;
|
||||||
|
member.stats.buffs.int += Math.ceil(diminishingReturns(bonus, 30, 200));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
frost: {
|
||||||
|
text: t('spellWizardFrostText'),
|
||||||
|
mana: 40,
|
||||||
|
lvl: 14,
|
||||||
|
target: 'self',
|
||||||
|
notes: t('spellWizardFrostNotes'),
|
||||||
|
cast (user) {
|
||||||
|
user.stats.buffs.streaks = true;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
spells.warrior = {
|
||||||
|
smash: {
|
||||||
|
text: t('spellWarriorSmashText'),
|
||||||
|
mana: 10,
|
||||||
|
lvl: 11,
|
||||||
|
target: 'task',
|
||||||
|
notes: t('spellWarriorSmashNotes'),
|
||||||
|
cast (user, target) {
|
||||||
|
let bonus = user._statsComputed.str * user.fns.crit('con');
|
||||||
|
target.value += diminishingReturns(bonus, 2.5, 35);
|
||||||
|
if (!user.party.quest.progress.up) user.party.quest.progress.base = 0;
|
||||||
|
user.party.quest.progress.up += diminishingReturns(bonus, 55, 70);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defensiveStance: {
|
||||||
|
text: t('spellWarriorDefensiveStanceText'),
|
||||||
|
mana: 25,
|
||||||
|
lvl: 12,
|
||||||
|
target: 'self',
|
||||||
|
notes: t('spellWarriorDefensiveStanceNotes'),
|
||||||
|
cast (user) {
|
||||||
|
let bonus = user._statsComputed.con - user.stats.buffs.con;
|
||||||
|
if (!user.stats.buffs.con) user.stats.buffs.con = 0;
|
||||||
|
user.stats.buffs.con += Math.ceil(diminishingReturns(bonus, 40, 200));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valorousPresence: {
|
||||||
|
text: t('spellWarriorValorousPresenceText'),
|
||||||
|
mana: 20,
|
||||||
|
lvl: 13,
|
||||||
|
target: 'party',
|
||||||
|
notes: t('spellWarriorValorousPresenceNotes'),
|
||||||
|
cast (user, target) {
|
||||||
|
_.each(target, (member) => {
|
||||||
|
let bonus = user._statsComputed.str - user.stats.buffs.str;
|
||||||
|
if (!member.stats.buffs.str) member.stats.buffs.str = 0;
|
||||||
|
member.stats.buffs.str += Math.ceil(diminishingReturns(bonus, 20, 200));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
intimidate: {
|
||||||
|
text: t('spellWarriorIntimidateText'),
|
||||||
|
mana: 15,
|
||||||
|
lvl: 14,
|
||||||
|
target: 'party',
|
||||||
|
notes: t('spellWarriorIntimidateNotes'),
|
||||||
|
cast (user, target) {
|
||||||
|
_.each(target, (member) => {
|
||||||
|
let bonus = user._statsComputed.con - user.stats.buffs.con;
|
||||||
|
if (!member.stats.buffs.con) member.stats.buffs.con = 0;
|
||||||
|
member.stats.buffs.con += Math.ceil(diminishingReturns(bonus, 24, 200));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
spells.rogue = {
|
||||||
|
pickPocket: {
|
||||||
|
text: t('spellRoguePickPocketText'),
|
||||||
|
mana: 10,
|
||||||
|
lvl: 11,
|
||||||
|
target: 'task',
|
||||||
|
notes: t('spellRoguePickPocketNotes'),
|
||||||
|
cast (user, target) {
|
||||||
|
let bonus = calculateBonus(target.value, user._statsComputed.per);
|
||||||
|
user.stats.gp += diminishingReturns(bonus, 25, 75);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
backStab: {
|
||||||
|
text: t('spellRogueBackStabText'),
|
||||||
|
mana: 15,
|
||||||
|
lvl: 12,
|
||||||
|
target: 'task',
|
||||||
|
notes: t('spellRogueBackStabNotes'),
|
||||||
|
cast (user, target) {
|
||||||
|
let _crit = user.fns.crit('str', 0.3);
|
||||||
|
let bonus = calculateBonus(target.value, user._statsComputed.str, _crit);
|
||||||
|
user.stats.exp += diminishingReturns(bonus, 75, 50);
|
||||||
|
user.stats.gp += diminishingReturns(bonus, 18, 75);
|
||||||
|
let req = {language: user.preferences.language};
|
||||||
|
user.fns.updateStats(user.stats, req);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
toolsOfTrade: {
|
||||||
|
text: t('spellRogueToolsOfTradeText'),
|
||||||
|
mana: 25,
|
||||||
|
lvl: 13,
|
||||||
|
target: 'party',
|
||||||
|
notes: t('spellRogueToolsOfTradeNotes'),
|
||||||
|
cast (user, target) {
|
||||||
|
_.each(target, (member) => {
|
||||||
|
let bonus = user._statsComputed.per - user.stats.buffs.per;
|
||||||
|
if (!member.stats.buffs.per) member.stats.buffs.per = 0;
|
||||||
|
member.stats.buffs.per += Math.ceil(diminishingReturns(bonus, 100, 50));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
stealth: {
|
||||||
|
text: t('spellRogueStealthText'),
|
||||||
|
mana: 45,
|
||||||
|
lvl: 14,
|
||||||
|
target: 'self',
|
||||||
|
notes: t('spellRogueStealthNotes'),
|
||||||
|
cast (user) {
|
||||||
|
if (!user.stats.buffs.stealth) user.stats.buffs.stealth = 0;
|
||||||
|
user.stats.buffs.stealth += Math.ceil(diminishingReturns(user._statsComputed.per, user.dailys.length * 0.64, 55));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
spells.healer = {
|
||||||
|
heal: {
|
||||||
|
text: t('spellHealerHealText'),
|
||||||
|
mana: 15,
|
||||||
|
lvl: 11,
|
||||||
|
target: 'self',
|
||||||
|
notes: t('spellHealerHealNotes'),
|
||||||
|
cast (user) {
|
||||||
|
user.stats.hp += (user._statsComputed.con + user._statsComputed.int + 5) * 0.075;
|
||||||
|
if (user.stats.hp > 50) user.stats.hp = 50;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
brightness: {
|
||||||
|
text: t('spellHealerBrightnessText'),
|
||||||
|
mana: 15,
|
||||||
|
lvl: 12,
|
||||||
|
target: 'self',
|
||||||
|
notes: t('spellHealerBrightnessNotes'),
|
||||||
|
cast (user) {
|
||||||
|
_.each(user.tasks, (task) => {
|
||||||
|
if (task.type !== 'reward') {
|
||||||
|
task.value += 4 * (user._statsComputed.int / (user._statsComputed.int + 40));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
protectAura: {
|
||||||
|
text: t('spellHealerProtectAuraText'),
|
||||||
|
mana: 30,
|
||||||
|
lvl: 13,
|
||||||
|
target: 'party',
|
||||||
|
notes: t('spellHealerProtectAuraNotes'),
|
||||||
|
cast (user, target) {
|
||||||
|
_.each(target, (member) => {
|
||||||
|
let bonus = user._statsComputed.con - user.stats.buffs.con;
|
||||||
|
if (!member.stats.buffs.con) member.stats.buffs.con = 0;
|
||||||
|
member.stats.buffs.con += Math.ceil(diminishingReturns(bonus, 200, 200));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
heallAll: {
|
||||||
|
text: t('spellHealerHealAllText'),
|
||||||
|
mana: 25,
|
||||||
|
lvl: 14,
|
||||||
|
target: 'party',
|
||||||
|
notes: t('spellHealerHealAllNotes'),
|
||||||
|
cast (user, target) {
|
||||||
|
_.each(target, (member) => {
|
||||||
|
member.stats.hp += (user._statsComputed.con + user._statsComputed.int + 5) * 0.04;
|
||||||
|
if (member.stats.hp > 50) member.stats.hp = 50;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
spells.special = {
|
||||||
|
snowball: {
|
||||||
|
text: t('spellSpecialSnowballAuraText'),
|
||||||
|
mana: 0,
|
||||||
|
value: 15,
|
||||||
|
target: 'user',
|
||||||
|
notes: t('spellSpecialSnowballAuraNotes'),
|
||||||
|
cast (user, target) {
|
||||||
|
target.stats.buffs.snowball = true;
|
||||||
|
target.stats.buffs.spookDust = false;
|
||||||
|
target.stats.buffs.shinySeed = false;
|
||||||
|
target.stats.buffs.seafoam = false;
|
||||||
|
if (!target.achievements.snowball) target.achievements.snowball = 0;
|
||||||
|
target.achievements.snowball++;
|
||||||
|
user.items.special.snowball--;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
salt: {
|
||||||
|
text: t('spellSpecialSaltText'),
|
||||||
|
mana: 0,
|
||||||
|
value: 5,
|
||||||
|
immediateUse: true,
|
||||||
|
target: 'self',
|
||||||
|
notes: t('spellSpecialSaltNotes'),
|
||||||
|
cast (user) {
|
||||||
|
user.stats.buffs.snowball = false;
|
||||||
|
user.stats.gp -= 5;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
spookDust: {
|
||||||
|
text: t('spellSpecialSpookDustText'),
|
||||||
|
mana: 0,
|
||||||
|
value: 15,
|
||||||
|
target: 'user',
|
||||||
|
notes: t('spellSpecialSpookDustNotes'),
|
||||||
|
cast (user, target) {
|
||||||
|
target.stats.buffs.snowball = false;
|
||||||
|
target.stats.buffs.spookDust = true;
|
||||||
|
target.stats.buffs.shinySeed = false;
|
||||||
|
target.stats.buffs.seafoam = false;
|
||||||
|
if (!target.achievements.spookDust) target.achievements.spookDust = 0;
|
||||||
|
target.achievements.spookDust++;
|
||||||
|
user.items.special.spookDust--;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
opaquePotion: {
|
||||||
|
text: t('spellSpecialOpaquePotionText'),
|
||||||
|
mana: 0,
|
||||||
|
value: 5,
|
||||||
|
immediateUse: true,
|
||||||
|
target: 'self',
|
||||||
|
notes: t('spellSpecialOpaquePotionNotes'),
|
||||||
|
cast (user) {
|
||||||
|
user.stats.buffs.spookDust = false;
|
||||||
|
user.stats.gp -= 5;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
shinySeed: {
|
||||||
|
text: t('spellSpecialShinySeedText'),
|
||||||
|
mana: 0,
|
||||||
|
value: 15,
|
||||||
|
target: 'user',
|
||||||
|
notes: t('spellSpecialShinySeedNotes'),
|
||||||
|
cast (user, target) {
|
||||||
|
target.stats.buffs.snowball = false;
|
||||||
|
target.stats.buffs.spookDust = false;
|
||||||
|
target.stats.buffs.shinySeed = true;
|
||||||
|
target.stats.buffs.seafoam = false;
|
||||||
|
if (!target.achievements.shinySeed) target.achievements.shinySeed = 0;
|
||||||
|
target.achievements.shinySeed++;
|
||||||
|
user.items.special.shinySeed--;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
petalFreePotion: {
|
||||||
|
text: t('spellSpecialPetalFreePotionText'),
|
||||||
|
mana: 0,
|
||||||
|
value: 5,
|
||||||
|
immediateUse: true,
|
||||||
|
target: 'self',
|
||||||
|
notes: t('spellSpecialPetalFreePotionNotes'),
|
||||||
|
cast (user) {
|
||||||
|
user.stats.buffs.shinySeed = false;
|
||||||
|
user.stats.gp -= 5;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
seafoam: {
|
||||||
|
text: t('spellSpecialSeafoamText'),
|
||||||
|
mana: 0,
|
||||||
|
value: 15,
|
||||||
|
target: 'user',
|
||||||
|
notes: t('spellSpecialSeafoamNotes'),
|
||||||
|
cast (user, target) {
|
||||||
|
target.stats.buffs.snowball = false;
|
||||||
|
target.stats.buffs.spookDust = false;
|
||||||
|
target.stats.buffs.shinySeed = false;
|
||||||
|
target.stats.buffs.seafoam = true;
|
||||||
|
if (!target.achievements.seafoam) target.achievements.seafoam = 0;
|
||||||
|
target.achievements.seafoam++;
|
||||||
|
user.items.special.seafoam--;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
sand: {
|
||||||
|
text: t('spellSpecialSandText'),
|
||||||
|
mana: 0,
|
||||||
|
value: 5,
|
||||||
|
immediateUse: true,
|
||||||
|
target: 'self',
|
||||||
|
notes: t('spellSpecialSandNotes'),
|
||||||
|
cast (user) {
|
||||||
|
user.stats.buffs.seafoam = false;
|
||||||
|
user.stats.gp -= 5;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nye: {
|
||||||
|
text: t('nyeCard'),
|
||||||
|
mana: 0,
|
||||||
|
value: 10,
|
||||||
|
immediateUse: true,
|
||||||
|
silent: true,
|
||||||
|
target: 'user',
|
||||||
|
notes: t('nyeCardNotes'),
|
||||||
|
cast (user, target) {
|
||||||
|
if (user === target) {
|
||||||
|
if (!user.achievements.nye) user.achievements.nye = 0;
|
||||||
|
user.achievements.nye++;
|
||||||
|
} else {
|
||||||
|
_.each([user, target], (u) => {
|
||||||
|
if (!u.achievements.nye) u.achievements.nye = 0;
|
||||||
|
u.achievements.nye++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!target.items.special.nyeReceived) target.items.special.nyeReceived = [];
|
||||||
|
target.items.special.nyeReceived.push(user.profile.name);
|
||||||
|
target.flags.cardReceived = true;
|
||||||
|
user.stats.gp -= 10;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
valentine: {
|
||||||
|
text: t('valentineCard'),
|
||||||
|
mana: 0,
|
||||||
|
value: 10,
|
||||||
|
immediateUse: true,
|
||||||
|
silent: true,
|
||||||
|
target: 'user',
|
||||||
|
notes: t('valentineCardNotes'),
|
||||||
|
cast (user, target) {
|
||||||
|
if (user === target) {
|
||||||
|
if (!user.achievements.valentine) user.achievements.valentine = 0;
|
||||||
|
user.achievements.valentine++;
|
||||||
|
} else {
|
||||||
|
_.each([user, target], (u) => {
|
||||||
|
if (!u.achievements.valentine) u.achievements.valentine = 0;
|
||||||
|
u.achievements.valentine++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!target.items.special.valentineReceived) target.items.special.valentineReceived = [];
|
||||||
|
target.items.special.valentineReceived.push(user.profile.name);
|
||||||
|
target.flags.cardReceived = true;
|
||||||
|
user.stats.gp -= 10;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
greeting: {
|
||||||
|
text: t('greetingCard'),
|
||||||
|
mana: 0,
|
||||||
|
value: 10,
|
||||||
|
immediateUse: true,
|
||||||
|
silent: true,
|
||||||
|
target: 'user',
|
||||||
|
notes: t('greetingCardNotes'),
|
||||||
|
cast (user, target) {
|
||||||
|
if (user === target) {
|
||||||
|
user.achievements.greeting++;
|
||||||
|
} else {
|
||||||
|
_.each([user, target], (u) => {
|
||||||
|
if (!u.achievements.greeting) u.achievements.greeting = 0;
|
||||||
|
u.achievements.greeting++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!target.items.special.greetingReceived) target.items.special.greetingReceived = [];
|
||||||
|
target.items.special.greetingReceived.push(user.profile.name);
|
||||||
|
target.flags.cardReceived = true;
|
||||||
|
user.stats.gp -= 10;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
thankyou: {
|
||||||
|
text: t('thankyouCard'),
|
||||||
|
mana: 0,
|
||||||
|
value: 10,
|
||||||
|
immediateUse: true,
|
||||||
|
silent: true,
|
||||||
|
target: 'user',
|
||||||
|
notes: t('thankyouCardNotes'),
|
||||||
|
cast (user, target) {
|
||||||
|
if (user === target) {
|
||||||
|
if (!user.achievements.thankyou) user.achievements.thankyou = 0;
|
||||||
|
user.achievements.thankyou++;
|
||||||
|
} else {
|
||||||
|
_.each([user, target], (u) => {
|
||||||
|
if (!u.achievements.thankyou) u.achievements.thankyou = 0;
|
||||||
|
u.achievements.thankyou++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!target.items.special.thankyouReceived) target.items.special.thankyouReceived = [];
|
||||||
|
target.items.special.thankyouReceived.push(user.profile.name);
|
||||||
|
target.flags.cardReceived = true;
|
||||||
|
user.stats.gp -= 10;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
birthday: {
|
||||||
|
text: t('birthdayCard'),
|
||||||
|
mana: 0,
|
||||||
|
value: 10,
|
||||||
|
immediateUse: true,
|
||||||
|
silent: true,
|
||||||
|
target: 'user',
|
||||||
|
notes: t('birthdayCardNotes'),
|
||||||
|
cast (user, target) {
|
||||||
|
if (user === target) {
|
||||||
|
if (!user.achievements.birthday) user.achievements.birthday = 0;
|
||||||
|
user.achievements.birthday++;
|
||||||
|
} else {
|
||||||
|
_.each([user, target], (u) => {
|
||||||
|
if (!u.achievements.birthday) u.achievements.birthday = 0;
|
||||||
|
u.achievements.birthday++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!target.items.special.birthdayReceived) target.items.special.birthdayReceived = [];
|
||||||
|
target.items.special.birthdayReceived.push(user.profile.name);
|
||||||
|
target.flags.cardReceived = true;
|
||||||
|
user.stats.gp -= 10;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
_.each(spells, (spellClass) => {
|
||||||
|
_.each(spellClass, (spell, key) => {
|
||||||
|
spell.key = key;
|
||||||
|
let _cast = spell.cast;
|
||||||
|
spell.cast = function castSpell (user, target) {
|
||||||
|
_cast(user, target);
|
||||||
|
user.stats.mp -= spell.mana;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
export default spells;
|
||||||
Reference in New Issue
Block a user