classes WIP

This commit is contained in:
Tyler Renelle
2013-11-16 02:22:12 -08:00
parent c2b8a62749
commit 83e3a6aff2
17 changed files with 351 additions and 39 deletions

View File

@@ -150,6 +150,8 @@
background: darken($worse, 38%)
.experience .bar
background: darken($neutral, 30%)
.mana .bar
background: darken($best, 30%)
.meter-text
position: absolute

View File

@@ -174,3 +174,12 @@ a
.modal-indented-list
margin-left: 10px;
padding-left: 10px;
// Spells
html.applying-action, html.applying-action *
cursor: copy !important
.cast-target:hover
border: 5px solid green !important
.selected-class
background-color: green

View File

@@ -3,8 +3,8 @@
/* Make user and settings available for everyone through root scope.
*/
habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$http', '$state', '$stateParams',
function($scope, $rootScope, $location, User, $http, $state, $stateParams) {
habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$http', '$state', '$stateParams', 'Notification',
function($scope, $rootScope, $location, User, $http, $state, $stateParams, Notification) {
$rootScope.modals = {};
$rootScope.modals.achievements = {};
$rootScope.User = User;
@@ -121,5 +121,50 @@ habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$
chart = new google.visualization.LineChart($("." + id + "-chart")[0]);
chart.draw(data, options);
};
/*
------------------------
Spells
------------------------
*/
$scope.castStart = function(spell) {
if (User.user.stats.mp < spell.mana) return Notification.text("Not enough mana.");
$rootScope.applyingAction = true;
$scope.spell = spell;
if (spell.target == 'self') {
debugger
var tasks = User.user.habits.concat(User.user.dailys).concat(User.user.todos);
User.user.tasks = _.object(_.pluck(tasks,'id'), tasks);
$scope.castEnd(null, 'self');
} else if (spell.target == 'party') {
//TODO $scope.castEnd()
}
}
$scope.castEnd = function(target, type, $event){
if ($scope.spell.target != type) return Notification.text("Invalid target");
$scope.spell.cast(User.user, target);
$http.post('/api/v1/user/cast/' + $scope.spell.name, {target:target, type:type}).success(function(){
var msg = "You cast " + $scope.spell.text;
switch (type) {
case 'task': msg += ' on ' + target.text;break;
case 'user': msg += ' on ' + target.profile.name;break;
case 'party': msg += ' on the Party';break;
}
Notification.text(msg);
$rootScope.applyingAction = false;
$scope.spell = null;
//User.sync(); // FIXME push a lot of the server code to also in client, so we can run updates in browser without requiring sync
})
$event && $event.stopPropagation();
}
// $rootScope.castCancel = function(){
// debugger
// $rootScope.applyingAction = false;
// $scope.spell = null;
// }
}
]);

View File

@@ -132,6 +132,13 @@ habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User', '
User.log({op: 'clear-completed'});
}
/*
------------------------
Ads
------------------------
*/
/**
* See conversation on http://productforums.google.com/forum/#!topic/adsense/WYkC_VzKwbA,
* Adsense is very sensitive. It must be called once-and-only-once for every <ins>, else things break.

View File

@@ -14,6 +14,27 @@ habitrpg.controller("UserCtrl", ['$rootScope', '$scope', '$location', 'User', '$
if(value === true) $scope.editingProfile = angular.copy(User.user.profile);
});
$scope.allocate = function(stat){
var setObj = {}
setObj['stats.' + stat] = User.user.stats[stat] + 1;
setObj['stats.points'] = User.user.stats.points - 1;
User.setMultiple(setObj);
}
$scope.rerollClass = function(){
if (!confirm("Are you sure you want to re-roll? This will reset your character's class and allocated points (you'll get them all back to re-allocate)"))
return;
User.setMultiple({
'stats.class': '',
//'stats.points': this is handled on the server
'stats.str': 0,
'stats.def': 0,
'stats.per': 0,
'stats.int': 0
})
}
$scope.save = function(){
var values = {};
_.each($scope.editingProfile, function(value, key){

View File

@@ -482,6 +482,67 @@ api.deleteTag = function(req, res){
}
}
/*
------------------------------------------------------------------------
Spells
------------------------------------------------------------------------
*/
api.cast = function(req, res) {
var user = res.locals.user;
var type = req.body.type, target = req.body.target;
var spell = items.items.spells[user.stats.class][req.params.spell];
var done = function(){
var err = arguments[0];
var saved = _.size(arguments == 3) ? arguments[2] : arguments[1];
if (err) return res.json(500, {err:err});
res.json(saved);
}
switch (type) {
case 'task':
spell.cast(user, user.tasks[target.id]);
user.save(done);
break;
case 'self':
spell.cast(user);
user.save(done);
break;
case 'party':
async.waterfall([
function(cb){
Group.findOne({type: 'party', members: {'$in': [user._id]}}).populate('members').exec(cb);
},
function(group, cb) {
spell.cast(user, group.members);
var series = _.reduce(group.members, function(m,v){
m.push(function(cb2){v.save(cb2);})
return m;
}, []);
async.series(series, cb);
}
], done);
break;
case 'user':
async.waterfall([
function(cb) {
User.findById(target._id, cb);
},
function(member, cb) {
spell.cast(user, member);
member.save(cb); // not parallel because target could be user, which causes race condition when saving
},
function(saved, num, cb) {
user.save(cb);
}
], done);
break;
}
}
/*
------------------------------------------------------------------------
Batch Update

View File

@@ -188,12 +188,17 @@ var UserSchema = new Schema({
armorSet: String,
dayStart: {type:Number, 'default': 0},
gender: {type:String, 'default': 'm'},
hair: {type:String, 'default':'blond'},
hair: {
color: {type: String, 'default': 'blonde'},
base: {type: Number, 'default': 0},
bangs: {type: Number, 'default': 0}
},
hideHeader: {type:Boolean, 'default':false},
showHelm: {type:Boolean, 'default':true},
skin: {type:String, 'default':'white'},
timezoneOffset: Number,
language: String
language: String,
automaticAllocation: Boolean
},
profile: {
blurb: String,
@@ -202,9 +207,24 @@ var UserSchema = new Schema({
},
stats: {
hp: Number,
mp: Number,
exp: Number,
gp: Number,
lvl: Number
lvl: Number,
// Class System
'class': String,
points: {type: Number, 'default': 0},
str: {type: Number, 'default': 0},
def: {type: Number, 'default': 0},
int: {type: Number, 'default': 0},
per: {type: Number, 'default': 0},
buffs: {
str: Number,
def: Number,
per: Number,
stealth: Number
}
},
tags: [
{
@@ -264,6 +284,10 @@ UserSchema.pre('save', function(next) {
'Anonymous';
}
// FIXME handle this on level-up instead, and come up with how we're going to handle retroactively
// Actually, can this be used as an attr default? (schema {type: ..., 'default': function(){}})
this.stats.points = this.stats.lvl - (this.stats.def + this.stats.str + this.stats.per + this.stats.int);
var petCount = _.reduce(this.items.pets,function(m,v){return m+(v ? 1 : 0);},0);
this.achievements.beastMaster = petCount >= 90;

View File

@@ -60,6 +60,7 @@ router.post('/user/buy-gems', auth.auth, user.buyGems);
router.post('/user/buy-gems/paypal-ipn', user.buyGemsPaypalIPN);
router.post('/user/unlock', auth.auth, cron, user.unlock);
router.post('/user/reset', auth.auth, user.reset);
router.post('/user/cast/:spell', auth.auth, user.cast);
router['delete']('/user', auth.auth, user['delete']);
/* Tags */

View File

@@ -1,5 +1,6 @@
doctype 5
html
//html(ng-app="habitrpg", ng-controller="RootCtrl", ng-class='{"applying-action":applyingAction}', ui-keypress="{27:'castCancel()'}")
html(ng-app="habitrpg", ng-controller="RootCtrl", ng-class='{"applying-action":applyingAction}', ui-keypress="{27:'castCancel()'}")
head
title HabitRPG | Your Life The Role Playing Game
@@ -21,7 +22,7 @@ html
meta(name='viewport', content='width=device-width')
meta(name='apple-mobile-web-app-capable', content='yes')
body(ng-app="habitrpg", ng-controller="RootCtrl", ng-cloak)
body(ng-cloak)
div(ng-controller='GroupsCtrl')
include ./shared/modals/index
include ./shared/header/header

View File

@@ -19,14 +19,37 @@ script(id='partials/options.profile.avatar.html', type='text/ng-template')
button.f_armor_0_v2.customize-option(type='button', ng-click='set("preferences.armorSet","v2")')
.span4
// hair
h3 Hair
menu(type='list')
// Color
li.customize-menu
menu(label='Hair')
button(class='{{user.preferences.gender}}_hair_blond customize-option', type='button', ng-click='set("preferences.hair","blond")')
button(class='{{user.preferences.gender}}_hair_black customize-option', type='button', ng-click='set("preferences.hair","black")')
button(class='{{user.preferences.gender}}_hair_brown customize-option', type='button', ng-click='set("preferences.hair","brown")')
button(class='{{user.preferences.gender}}_hair_white customize-option', type='button', ng-click='set("preferences.hair","white")')
button(class='{{user.preferences.gender}}_hair_red customize-option', type='button', ng-click='set("preferences.hair","red")')
menu(label='Color')
button(type='button', class='customize-option', style='width: 40px; height: 40px; background-color:#c8c8c8;', ng-click='set("preferences.hair.color", "white")')
button(type='button', class='customize-option', style='width: 40px; height: 40px; background-color:#903a00;', ng-click='set("preferences.hair.color", "brown")')
button(type='button', class='customize-option', style='width: 40px; height: 40px; background-color:#cfb853;', ng-click='set("preferences.hair.color", "blond")')
button(type='button', class='customize-option', style='width: 40px; height: 40px; background-color:#ec720f;', ng-click='set("preferences.hair.color", "red")')
button(type='button', class='customize-option', style='width: 40px; height: 40px; background-color:#2e2e2e;', ng-click='set("preferences.hair.color", "black")')
// Bangs
li.customize-menu
menu(label='Bangs')
button(class='{{user.preferences.gender}}_hair_bangs_0_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.bangs",0)')
button(class='{{user.preferences.gender}}_hair_bangs_1_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.bangs",1)')
button(class='{{user.preferences.gender}}_hair_bangs_2_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.bangs",2)')
button(class='{{user.preferences.gender}}_hair_bangs_3_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.bangs",3)')
// Base
li.customize-menu
menu(label='Base')
button(class='{{user.preferences.gender}}_hair_base_0_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.base",0)')
button(class='{{user.preferences.gender}}_hair_base_1_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.base",1)')
button(class='{{user.preferences.gender}}_hair_base_2_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.base",2)')
button(class='{{user.preferences.gender}}_hair_base_3_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.base",3)')
button(class='{{user.preferences.gender}}_hair_base_4_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.base",4)')
button(class='{{user.preferences.gender}}_hair_base_5_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.base",5)')
button(class='{{user.preferences.gender}}_hair_base_6_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.base",6)')
button(class='{{user.preferences.gender}}_hair_base_7_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.base",7)')
button(class='{{user.preferences.gender}}_hair_base_8_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.base",8)')
.span4
// skin
@@ -70,9 +93,44 @@ script(id='partials/options.profile.avatar.html', type='text/ng-template')
script(id='partials/options.profile.stats.html', type='text/ng-template')
.row-fluid
.span6.border-right
.border-right(ng-class='user.stats.lvl < 5 ? "span6" : "span4"')
include ../shared/profiles/stats
.span6.border-right
.span4.border-right(ng-show='user.stats.lvl >= 5')
h4
| {{user.stats.class}}&nbsp;
a.btn.btn-danger.btn-mini(ng-click='rerollClass()') Re-roll
h6 Points: {{user.stats.points}}
fieldset
label.checkbox
input(type='checkbox', ng-model='user.preferences.automaticAllocation', ng-change='set("preferences.automaticAllocation", user.preferences.automaticAllocation?true: false)')
| Automatic Allocation
i.icon-question-sign(popover-trigger='mouseenter', popover-placement='bottom', popover="When 'automatic' is checked, your points will be allocated to the stat representing your task focus (see Task > Edit). When unchecked, you'll have one point to allocate each level. The system makes a suggestion, but you can ignore the suggestion.")
table.table.table-striped
tr
td
i.icon-question-sign(popover-title='Strength', popover='Strength increases damage you inflict to tasks, reducing their redness', popover-trigger='mouseenter')
| &nbsp;STR: {{user.stats.str}}
td
a.btn.btn-primary(ng-show='user.stats.points', ng-click='allocate("str")') +
tr
td
i.icon-question-sign(popover-title='Defense', popover='Defense decreases damage inflicted by tasks, and increases the effectiveness of healing and buff spells', popover-trigger='mouseenter')
| &nbsp;DEF: {{user.stats.def}}
td
a.btn.btn-primary(ng-show='user.stats.points', ng-click='allocate("def")') +
tr
td
i.icon-question-sign(popover-title='Perception', popover='Perception increases the likelihood of drops, Gold bonuses, and critical hit chances', popover-trigger='mouseenter')
| &nbsp;PER: {{user.stats.per}}
td
a.btn.btn-primary(ng-show='user.stats.points', ng-click='allocate("per")') +
tr
td
i.icon-question-sign(popover-title='Intelligence', popover='Intelligence increases your overall mana, allowing you to cast more spells', popover-trigger='mouseenter')
| &nbsp;INT: {{user.stats.int}}
td
a.btn.btn-primary(ng-show='user.stats.points', ng-click='allocate("int")') +
.border-right(ng-class='user.stats.lvl < 5 ? "span6" : "span4"')
include ../shared/profiles/achievements
script(id='partials/options.profile.profile.html', type='text/ng-template')

View File

@@ -3,27 +3,35 @@
Removing it will remove the user's name, but will allow more room for mounts & helms. IMO this is the lesser of two evils, revisit
//-figure.herobox(ng-click='clickMember(profile._id)', data-name='{{profile.profile.name}}', ng-class='{isUser: profile.id==user.id, hasPet: profile.items.currentPet}', data-level='{{profile.stats.lvl}}', data-uid='{{profile.id}}', rel='popover', data-placement='bottom', data-trigger='hover', data-html='true', data-content="<div ng-hide='profile.id == user.id'> <div class='progress progress-danger' style='height:5px;'> <div class='bar' style='height: 5px; width: {{percent(profile.stats.hp, 50)}}%;'></div> </div> <div class='progress progress-warning' style='height:5px;'> <div class='bar' style='height: 5px; width: {{percent(profile.stats.exp, tnl(profile.stats.lvl))}}%;'></div> </div> <div>Level: {{profile.stats.lvl}}</div> <div>GP: {{profile.stats.gp | number:0}}</div> <div>{{count(profile.items.pets)}} / 90 Pets Found</div> </div>")
figure.herobox(ng-click='clickMember(profile._id)', data-name='{{profile.profile.name}}', ng-class='{isUser: user._id==profile._id && !(user.items.currentMount && user.items.currentPet), hasPet: profile.items.currentPet && profile.items.currentMount}')
figure.herobox(ng-click='spell ? castEnd(profile, "user", $event) : clickMember(profile._id)', data-name='{{profile.profile.name}}', ng-class='{isUser: user._id==profile._id && !(user.items.currentMount && user.items.currentPet), hasPet: profile.items.currentPet && profile.items.currentMount, "cast-target": applyingAction}')
.character-sprites
// Mount Body
span(ng-if='profile.items.currentMount', class='Mount_Body_{{profile.items.currentMount}}')
// Avatar
span(class='{{profile.preferences.gender}}_skin_{{profile.preferences.skin}}')
span(class='{{profile.preferences.gender}}_hair_{{profile.preferences.hair}}')
span(class='{{equipped("armor", profile.items.armor, profile.preferences, profile.backer, profile.contributor)}}')
span(class='{{profile.preferences.gender}}_head_0', ng-hide='profile.preferences.showHelm')
span(class='{{equipped("head", profile.items.head, profile.preferences, profile.backer, profile.contributor)}}', ng-show='profile.preferences.showHelm')
span(class='{{equipped("shield",profile.items.shield,profile.preferences, profile.backer, profile.contributor)}}')
span(class='{{equipped("weapon",profile.items.weapon,profile.preferences, profile.backer, profile.contributor)}}')
//span(class='{{profile.preferences.gender}}_skin_{{profile.preferences.skin}}')
//span(class='{{profile.preferences.gender}}_head_0')
//span(class='{{profile.preferences.gender}}_hair_base_{{profile.preferences.hair.base}}_{{profile.preferences.hair.color}}')
//span(class='{{profile.preferences.gender}}_hair_bangs_{{profile.preferences.hair.bangs}}_{{profile.preferences.hair.color}}')
//span(class='{{equipped("armor", profile.items.armor, profile.preferences, profile.backer, profile.contributor)}}-{{profile.stats.class}}')
//span(class='{{equipped("head", profile.items.head, profile.preferences, profile.backer, profile.contributor)}}-{{profile.stats.class}}', ng-show='profile.preferences.showHelm')
//span(class='{{equipped("shield",profile.items.shield,profile.preferences, profile.backer, profile.contributor)}}-{{profile.stats.class}}')
//span(class='{{equipped("weapon",profile.items.weapon,profile.preferences, profile.backer, profile.contributor)}}-{{profile.stats.class}}')
span(class='m_skin_{{profile.preferences.skin}}')
span(class='m_head_0')
span(class='m_hair_base_{{profile.preferences.hair.base}}_{{profile.preferences.hair.color}}')
span(class='m_hair_bangs_{{profile.preferences.hair.bangs}}_{{profile.preferences.hair.color}}')
span(class='m_armor_{{profile.items.armor}}-{{profile.stats.class}}')
span(class='m_head_{{profile.items.head}}-{{profile.stats.class}}', ng-show='profile.preferences.showHelm')
span(class='m_shield_{{profile.items.shield}}-{{profile.stats.class}}')
span(class='m_weapon_{{profile.items.weapon}}-{{profile.stats.class}}')
// Mount Head
span(ng-if='profile.items.currentMount', class='Mount_Head_{{profile.items.currentMount}}')
// Resting
span(ng-class='{zzz:profile.flags.rest}')
// Pet
// FIXME handle @minimal, this might have to be a directive
span.current-pet(class='Pet-{{profile.items.currentPet}}', ng-show='profile.items.currentPet && !minimal')
.avatar-level Lvl {{profile.stats.lvl}}

View File

@@ -1,5 +1,4 @@
//.header-wrap(ng-controller='HeaderCtrl', data-spy="affix", data-offset-top="148")
.header-wrap(ng-controller='HeaderCtrl')
.header-wrap(ng-controller='HeaderCtrl', data-spy="affix", data-offset-top="148")
a.label.undo-button(x-bind='click:undo', ng-show='_undo') Undo
div(ng-if='!user.preferences.hideHeader')
include menu
@@ -25,6 +24,12 @@
span(ng-show='user.history.exp')
a(ng-click='toggleChart("exp")', tooltip='Progress')
i.icon-signal
.meter.mana(title='Mana', ng-if='user.stats.class')
.bar(style='width: {{percent(user.stats.mp, user.stats.int+10)}}%;')
span.meter-text
i.icon-fire
| {{user.stats.mp || 0 | number:0}} / {{user.stats.int+10}}
// party
span(ng-controller='PartyCtrl')
.herobox-wrap(ng-repeat='profile in partyMinusSelf')

View File

@@ -0,0 +1,45 @@
.modal(ng-if='user.stats.lvl >= 10 && !user.stats.class', data-backdrop=true)
.modal-header
h3 Class System Unlocked!
.modal-body
.well Select your class. Upon level-up, you will now be able to allocate points to various stats. Alternatively, you can choose which stat your tasks represent (physical, mental, social, or "other") and drive your class automatically.
.well(ng-show='selectedClass=="warrior"') Warriors deal moderate damage to tasks and have moderate defense against tasks.
.well(ng-show='selectedClass=="wizard"') Wizards deal high damage to task, and can cast debuff spells on multiple tasks.
.well(ng-show='selectedClass=="rogue"') Rogues finds more drops, Gold, and have a high chance of dealing "critical hits," which grant large GP & Exp bonuses. Rogues can also "go stealth" to avoid and entire day of dailies.
.well(ng-show='selectedClass=="healer"') Healers have high defense against damage, and can heal themselves and other players in the party, as well as buff players.
.row-fluid
.span3(ng-click='selectedClass = "warrior"')
h5 Warrior
figure.herobox(ng-class='{"selected-class": selectedClass=="warrior"}')
.character-sprites
span(class='{{user.preferences.gender}}_skin_{{user.preferences.skin}}')
span(class='{{user.preferences.gender}}_hair_{{user.preferences.hair}}')
span(class='{{user.preferences.gender}}_armor_5-warrior')
span(class='{{user.preferences.gender}}_head_5-warrior')
.span3(ng-click='selectedClass = "wizard"')
h5 Wizard
figure.herobox(ng-class='{"selected-class": selectedClass=="wizard"}')
.character-sprites
span(class='{{user.preferences.gender}}_skin_{{user.preferences.skin}}')
span(class='{{user.preferences.gender}}_hair_{{user.preferences.hair}}')
span(class='{{user.preferences.gender}}_armor_5-wizard')
span(class='{{user.preferences.gender}}_head_5-wizard')
.span3(ng-click='selectedClass = "rogue"')
h5 Rogue
figure.herobox(ng-class='{"selected-class": selectedClass=="rogue"}')
.character-sprites
span(class='{{user.preferences.gender}}_skin_{{user.preferences.skin}}')
span(class='{{user.preferences.gender}}_hair_{{user.preferences.hair}}')
span(class='{{user.preferences.gender}}_armor_5-rogue')
span(class='{{user.preferences.gender}}_head_5-rogue')
.span3(ng-click='selectedClass = "healer"')
h5 Healer
figure.herobox(ng-class='{"selected-class": selectedClass=="healer"}')
.character-sprites
span(class='{{user.preferences.gender}}_skin_{{user.preferences.skin}}')
span(class='{{user.preferences.gender}}_hair_{{user.preferences.hair}}')
span(class='{{user.preferences.gender}}_armor_5-healer')
span(class='{{user.preferences.gender}}_head_5-healer')
.modal-footer
button.btn.btn-default.cancel(ng-click='set("stats.class", selectedClass)') Select

View File

@@ -7,3 +7,4 @@ include ./buy-gems
include ./members
include ./settings
include ./pets
include ./classes

View File

@@ -45,7 +45,7 @@ script(id='templates/habitrpg-tasks.html', type="text/ng-template")
include ./task
// Static Rewards
ul.items(ng-show='main && list.type=="reward" && user.flags.itemsEnabled')
ul.items.rewards(ng-if='main && list.type=="reward" && user.flags.itemsEnabled')
li.task.reward-item(ng-hide='item.hide', ng-repeat='item in itemStore')
// right-hand side control buttons
.task-meta-controls
@@ -62,6 +62,22 @@ script(id='templates/habitrpg-tasks.html', type="text/ng-template")
span(ng-class='{"shop_{{item.classes}} shop-sprite item-img": true}')
p.task-text {{item.text}}
// Spells
ul.items(ng-if='main && list.type=="reward" && user.stats.class')
li.task.reward-item(ng-repeat='(k,spell) in Items.spells[user.stats.class]')
.task-meta-controls
span.task-notes(popover-trigger='mouseenter', popover-placement='left', popover='{{spell.notes}}', popover-title='{{spell.text}}')
i.icon-comment
//left-hand size commands
.task-controls
a.money.btn-buy.item-btn(ng-click='castStart(spell)')
span.reward-cost
strong {{spell.mana}}
| &nbsp;MP
// main content
span(ng-class='{"shop_{{spell.classes}} shop-sprite item-img": true}')
p.task-text {{spell.text}}
br
// Ads

View File

@@ -1,4 +1,4 @@
li(ng-repeat='task in obj[list.type+"s"]', class='task {{taskClasses(task, user.filters, user.preferences.dayStart, user.lastCron, list.showCompleted, main)}}', data-id='{{task.id}}')
li(ng-repeat='task in obj[list.type+"s"]', class='task {{taskClasses(task, user.filters, user.preferences.dayStart, user.lastCron, list.showCompleted, main)}}', ng-click='spell && castEnd(task, "task", $event)', ng-class='{"cast-target":spell}')
// right-hand side control buttons
.task-meta-controls
@@ -159,6 +159,14 @@ li(ng-repeat='task in obj[list.type+"s"]', class='task {{taskClasses(task, user.
span(ng-if='task.type=="daily" && !task.challenge.id')
legend.option-title Restore Streak
input.option-content(type='number', ng-model='task.streak')
legend.option-title Attributes
.task-controls.tile-group
button.task-action-btn.tile(type='button') Physical
button.task-action-btn.tile(type='button') Mental
button.task-action-btn.tile(type='button') Social
button.task-action-btn.tile(type='button') Other
button.task-action-btn.tile.spacious(type='submit') Save & Close
div(class='{{obj._id}}{{task.id}}-chart', ng-show='charts[obj._id+task.id]')