mirror of
https://github.com/sudoxnym/habitica-self-host.git
synced 2026-07-14 02:02:19 +00:00
Merge branch 'classes' into develop
Conflicts: public/js/controllers/tasksCtrl.js views/shared/modals/settings.jade
This commit is contained in:
commit
76565384d3
33 changed files with 648 additions and 204 deletions
26
migrations/20131204_classes.js
Normal file
26
migrations/20131204_classes.js
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* Probably the biggest migration of all! This adds the following features:
|
||||
* - Customization Redo: https://trello.com/c/YKXmHNjY/306-customization-redo
|
||||
* - Armory: https://trello.com/c/83M5RqQB/299-armory
|
||||
* - Classes
|
||||
*/
|
||||
|
||||
db.users.find().forEach(function(user){
|
||||
|
||||
user.stats.class = 'warrior';
|
||||
|
||||
// grant backer/contrib gear, 300, rather than using js logic
|
||||
|
||||
// customizations redo: https://trello.com/c/YKXmHNjY/306-customization-redo
|
||||
|
||||
// migrate current owned items
|
||||
|
||||
// gender => size
|
||||
user.preferences.size = (user.preferences.gender == 'f') ? 'slim' : 'broad';
|
||||
delete user.preferences.gender;
|
||||
|
||||
// Delete armorSet
|
||||
delete user.preferences.armorSet;
|
||||
|
||||
db.users.update({_id:user._id}, user);
|
||||
});
|
||||
|
|
@ -150,6 +150,8 @@
|
|||
background: darken($worse, 38%)
|
||||
.experience .bar
|
||||
background: darken($neutral, 30%)
|
||||
.mana .bar
|
||||
background: darken($best, 30%)
|
||||
|
||||
.meter-text
|
||||
position: absolute
|
||||
|
|
|
|||
|
|
@ -179,3 +179,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
|
||||
|
|
@ -1,36 +1,27 @@
|
|||
.NPC-Alex, .NPC-Bailey, .NPC-Bailey-Head, .NPC-Daniel, .NPC-Justin, .NPC-Justin-Head, .NPC-Matt {background: url("/bower_components/habitrpg-shared/img/npcs/NPC-SpriteSheet.png") no-repeat}
|
||||
.npc_alex_container
|
||||
margin-bottom: 20px
|
||||
|
||||
.NPC-Alex {background-position: 0 0; width: 162px; height: 138px;}
|
||||
.NPC-Alex-container{margin-bottom: 20px;}
|
||||
.NPC-Daniel {background-position: -222px 0; width: 135px; height: 123px}
|
||||
.NPC-Justin {background-position: -357px 0; width: 84px; height: 119px}
|
||||
.NPC-Justin-Head {background-position: -396px 0; width: 36px; height: 96px}
|
||||
.NPC-Matt {background-position: -441px 0; width: 100%; padding-left: 208px; padding-bottom: 20px;}
|
||||
.npc_matt
|
||||
margin-bottom: 20px
|
||||
|
||||
// Bailey
|
||||
.NPC-Bailey
|
||||
background-position: -162px -42px
|
||||
width: 60px
|
||||
height: 72px
|
||||
float:left
|
||||
.NPC-Bailey-Head
|
||||
background-position: -162px -42px
|
||||
width: 60px
|
||||
height: 30px
|
||||
position: absolute
|
||||
top: 117px // 147 (header-height) - 30 (bailey height)
|
||||
right: 50px
|
||||
cursor: pointer
|
||||
|
||||
|
||||
.static-popover
|
||||
z-index 0
|
||||
display block
|
||||
position:relative
|
||||
.npc_bailey
|
||||
float:left
|
||||
.npc_bailey_head
|
||||
height: 30px !important
|
||||
position: absolute
|
||||
top: 117px // 147 (header-height) - 30 (bailey height)
|
||||
right: 50px
|
||||
cursor: pointer
|
||||
|
||||
// Tour (Justin)
|
||||
.NPC-Justin.float-left
|
||||
.npc_justin.float-left
|
||||
float: left
|
||||
margin-right: 5px
|
||||
margin-bottom: 5px
|
||||
|
||||
.static-popover
|
||||
z-index 0
|
||||
display block
|
||||
position:relative
|
||||
|
||||
.popover-navigation {clear:both;}
|
||||
|
|
@ -402,4 +402,4 @@ form
|
|||
color: #333
|
||||
&:hover
|
||||
border-top: 0
|
||||
margin-top: 2px
|
||||
margin-top: 2px
|
||||
|
|
@ -2,6 +2,7 @@ habitrpg.controller("InventoryCtrl", ['$rootScope', '$scope', 'User', 'API_URL',
|
|||
function($rootScope, $scope, User, API_URL, $http, Notification) {
|
||||
|
||||
var user = User.user;
|
||||
var Items = window.habitrpgShared.items;
|
||||
|
||||
// convenience vars since these are accessed frequently
|
||||
|
||||
|
|
@ -17,11 +18,22 @@ habitrpg.controller("InventoryCtrl", ['$rootScope', '$scope', 'User', 'API_URL',
|
|||
$scope.$watch('user.items.hatchingPotions', function(pots){ $scope.potCount = countStacks(pots); }, true);
|
||||
$scope.$watch('user.items.food', function(food){ $scope.foodCount = countStacks(food); }, true);
|
||||
|
||||
$scope.$watch('user.items.gear', function(gear){
|
||||
$scope.gear = {
|
||||
base: _.where(Items.items.gear.flat, {klass: 'base'})
|
||||
};
|
||||
_.each(gear.owned, function(bool,key){
|
||||
var item = Items.items.gear.flat[key];
|
||||
if (!$scope.gear[item.klass]) $scope.gear[item.klass] = [];
|
||||
$scope.gear[item.klass].push(item);
|
||||
})
|
||||
}, true)
|
||||
|
||||
$scope.chooseEgg = function(egg){
|
||||
if ($scope.selectedEgg && $scope.selectedEgg.name == egg) {
|
||||
return $scope.selectedEgg = null; // clicked same egg, unselect
|
||||
}
|
||||
var eggData = _.findWhere(window.habitrpgShared.items.items.eggs, {name:egg});
|
||||
var eggData = _.findWhere(Items.items.eggs, {name:egg});
|
||||
if (!$scope.selectedPotion) {
|
||||
$scope.selectedEgg = eggData;
|
||||
} else {
|
||||
|
|
@ -34,7 +46,7 @@ habitrpg.controller("InventoryCtrl", ['$rootScope', '$scope', 'User', 'API_URL',
|
|||
return $scope.selectedPotion = null; // clicked same egg, unselect
|
||||
}
|
||||
// we really didn't think through the way these things are stored and getting passed around...
|
||||
var potionData = _.findWhere(window.habitrpgShared.items.items.hatchingPotions, {name:potion});
|
||||
var potionData = _.findWhere(Items.items.hatchingPotions, {name:potion});
|
||||
if (!$scope.selectedEgg) {
|
||||
$scope.selectedPotion = potionData;
|
||||
} else {
|
||||
|
|
@ -171,5 +183,18 @@ habitrpg.controller("InventoryCtrl", ['$rootScope', '$scope', 'User', 'API_URL',
|
|||
User.set('items.currentMount', (user.items.currentMount == mount) ? '' : mount);
|
||||
}
|
||||
|
||||
$scope.equip = function(user, item, costume) {
|
||||
var equipTo = costume ? 'costume' : 'equipped';
|
||||
if (item.type == 'shield') {
|
||||
var weapon = Items.items.gear.flat[user.items.gear[equipTo].weapon];
|
||||
if (weapon && weapon.twoHanded) return Notification.text(weapon.text + ' is two-handed');
|
||||
}
|
||||
var setVars = {};
|
||||
setVars['items.gear.' + equipTo + '.' + item.type] = item.key;
|
||||
if (item.twoHanded)
|
||||
setVars['items.gear.' + equipTo + '.shield'] = 'warrior_shield_0';
|
||||
User.setMultiple(setVars);
|
||||
}
|
||||
|
||||
}
|
||||
]);
|
||||
|
|
@ -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', 'Groups',
|
||||
function($scope, $rootScope, $location, User, $http, $state, $stateParams, Notification, Groups) {
|
||||
$rootScope.modals = {};
|
||||
$rootScope.modals.achievements = {};
|
||||
$rootScope.User = User;
|
||||
|
|
@ -137,5 +137,51 @@ 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') {
|
||||
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') {
|
||||
var party = Groups.party();
|
||||
party = (_.isArray(party) ? party : []).concat(User.user);
|
||||
$scope.castEnd(party, 'party');
|
||||
}
|
||||
}
|
||||
|
||||
$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;
|
||||
// }
|
||||
}
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -74,24 +74,24 @@ habitrpg.controller('SettingsCtrl',
|
|||
$rootScope.$watch('modals.restore', function(value){
|
||||
if(value === true){
|
||||
$scope.restoreValues.stats = angular.copy(User.user.stats);
|
||||
$scope.restoreValues.items = angular.copy(User.user.items);
|
||||
// $scope.restoreValues.items = angular.copy(User.user.items);
|
||||
$scope.restoreValues.achievements = {streak: User.user.achievements.streak || 0};
|
||||
}
|
||||
})
|
||||
|
||||
$scope.restore = function(){
|
||||
var stats = $scope.restoreValues.stats,
|
||||
items = $scope.restoreValues.items,
|
||||
// items = $scope.restoreValues.items,
|
||||
achievements = $scope.restoreValues.achievements;
|
||||
User.setMultiple({
|
||||
"stats.hp": stats.hp,
|
||||
"stats.exp": stats.exp,
|
||||
"stats.gp": stats.gp,
|
||||
"stats.lvl": stats.lvl,
|
||||
"items.weapon": items.weapon,
|
||||
"items.armor": items.armor,
|
||||
"items.head": items.head,
|
||||
"items.shield": items.shield,
|
||||
// "items.weapon": items.weapon,
|
||||
// "items.armor": items.armor,
|
||||
// "items.head": items.head,
|
||||
// "items.shield": items.shield,
|
||||
"achievements.streak": achievements.streak
|
||||
});
|
||||
$rootScope.modals.restore = false;
|
||||
|
|
|
|||
|
|
@ -104,24 +104,14 @@ habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User', '
|
|||
------------------------
|
||||
*/
|
||||
|
||||
var updateStore = function(){
|
||||
var sorted, updated;
|
||||
updated = window.habitrpgShared.items.updateStore(User.user);
|
||||
/* Figure out whether we wanna put this in habitrpg-shared
|
||||
*/
|
||||
$scope.itemStore = window.habitrpgShared.items.updateStore(User.user);
|
||||
|
||||
sorted = [updated.weapon, updated.armor, updated.head, updated.shield, updated.potion];
|
||||
$scope.itemStore = sorted;
|
||||
}
|
||||
|
||||
updateStore();
|
||||
|
||||
$scope.buy = function(type) {
|
||||
var hasEnough = window.habitrpgShared.items.buyItem(User.user, type);
|
||||
$scope.buy = function(item) {
|
||||
var hasEnough = window.habitrpgShared.items.buyItem(User.user, item);
|
||||
if (hasEnough) {
|
||||
User.log({op: "buy",type: type});
|
||||
User.log({op: "buy", key: item.key});
|
||||
Notification.text("Item purchased.");
|
||||
updateStore();
|
||||
$scope.itemStore = window.habitrpgShared.items.updateStore(User.user);
|
||||
} else {
|
||||
Notification.text("Not enough Gold!");
|
||||
}
|
||||
|
|
@ -132,6 +122,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.
|
||||
|
|
|
|||
|
|
@ -11,6 +11,59 @@ 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({
|
||||
'flags.classSelected': false,
|
||||
//'stats.points': this is handled on the server
|
||||
'stats.str': 0,
|
||||
'stats.def': 0,
|
||||
'stats.per': 0,
|
||||
'stats.int': 0
|
||||
})
|
||||
}
|
||||
$scope.rerollSubmit = function(){
|
||||
var klass = $scope.selectedClass;
|
||||
var setVars = {
|
||||
"stats.class": klass,
|
||||
"flags.classSelected": true
|
||||
};
|
||||
|
||||
// Clear their gear and equip their new class's gear (can still equip old gear from inventory)
|
||||
// If they've rolled this class before, restore their progress
|
||||
_.each(['weapon', 'armor','shield','head'], function(type){
|
||||
var foundKey = false;
|
||||
_.findLast(User.user.items.gear.owned, function(v,k){
|
||||
if (~k.indexOf(type + '_' + klass)) {
|
||||
foundKey = k;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
setVars['items.gear.equipped.' + type] =
|
||||
foundKey ? foundKey : // restore progress from when they last rolled this class
|
||||
(type == 'weapon') ? 'weapon_' + klass + '_0' : // weapon_0 is significant, don't reset to base_0
|
||||
(type == 'shield' && klass == 'rogue') ? 'shield_rogue_0' : // rogues start with an off-hand weapon
|
||||
type + '_base_0'; // naked for the rest!
|
||||
|
||||
// Grant them their new class's gear
|
||||
if (type == 'weapon' || (type == 'shield' && klass == 'rogue'))
|
||||
setVars['items.gear.owned.' + type + '_' + klass + '_0'] = true;
|
||||
});
|
||||
|
||||
User.setMultiple(setVars);
|
||||
$scope.selectedClass = undefined;
|
||||
|
||||
//FIXME run updateStore (we need to access a different scope)
|
||||
}
|
||||
|
||||
$scope.save = function(){
|
||||
var values = {};
|
||||
_.each($scope.editingProfile, function(value, key){
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ angular.module('guideServices', []).
|
|||
}
|
||||
];
|
||||
_.each(tourSteps, function(step){
|
||||
step.content = "<div><div class='NPC-Justin float-left'></div>" + step.content + "</div>"; // add Justin NPC img
|
||||
step.content = "<div><div class='npc_justin float-left'></div>" + step.content + "</div>"; // add Justin NPC img
|
||||
});
|
||||
$('.main-herobox').popover('destroy');
|
||||
var tour = new Tour({
|
||||
|
|
@ -97,7 +97,7 @@ angular.module('guideServices', []).
|
|||
if (!placement) placement = 'bottom';
|
||||
$(selector).popover('destroy');
|
||||
var button = "<button class='btn btn-sm btn-default' onClick=\"$('" + selector + "').popover('hide');return false;\">Close</button>";
|
||||
html = "<div><div class='NPC-Justin float-left'></div>" + html + '<br/>' + button + '</div>';
|
||||
html = "<div><div class='npc_justin float-left'></div>" + html + '<br/>' + button + '</div>';
|
||||
$(selector).popover({
|
||||
title: title,
|
||||
placement: placement,
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ angular.module('userServices', []).
|
|||
//first we populate user with schema
|
||||
_.extend(user, $window.habitrpgShared.helpers.newUser());
|
||||
user.apiToken = user._id = ''; // we use id / apitoken to determine if registered
|
||||
$window.habitrpgShared.algos.defineComputed(user);
|
||||
|
||||
//than we try to load localStorage
|
||||
if (localStorage.getItem(STORAGE_USER_ID)) {
|
||||
|
|
|
|||
|
|
@ -203,13 +203,12 @@ api.clearCompleted = function(req, res, next) {
|
|||
------------------------------------------------------------------------
|
||||
*/
|
||||
api.buy = function(req, res, next) {
|
||||
var hasEnough, type, user;
|
||||
user = res.locals.user;
|
||||
type = req.params.type;
|
||||
if (type !== 'weapon' && type !== 'armor' && type !== 'head' && type !== 'shield' && type !== 'potion') {
|
||||
return res.json(400, {err: ":type must be in one of: 'weapon', 'armor', 'head', 'shield', 'potion'"});
|
||||
var user = res.locals.user;
|
||||
var key = req.params.key;
|
||||
if (key !== 'potion' && !items.items.gear.flat[key]) {
|
||||
return res.json(400, {err: ":item must be a supported key, see https://github.com/HabitRPG/habitrpg-shared/blob/master/script/items.coffee"});
|
||||
}
|
||||
hasEnough = items.buyItem(user, type);
|
||||
var hasEnough = items.buyItem(user, items.items.gear.flat[key]);
|
||||
if (hasEnough) {
|
||||
return user.save(function(err, saved) {
|
||||
if (err) return res.json(500, {err: err});
|
||||
|
|
@ -484,6 +483,70 @@ 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) {
|
||||
if (!group) group = {members:[user]};
|
||||
spell.cast(user, group.members);
|
||||
var series = _.transform(group.members, function(m,v,k){
|
||||
m[k] = function(cb2){v.save(cb2);}
|
||||
});
|
||||
async.series(series, cb);
|
||||
},
|
||||
function(whatever, cb){
|
||||
user.save(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
|
||||
|
|
@ -502,6 +565,7 @@ api.batchUpdate = function(req, res, next) {
|
|||
req.params.id = action.data && action.data.id;
|
||||
req.params.direction = action.dir;
|
||||
req.params.type = action.type;
|
||||
req.params.key = action.key;
|
||||
req.body = action.data;
|
||||
res.send = res.json = function(code, data) {
|
||||
if (_.isNumber(code) && code >= 400) {
|
||||
|
|
|
|||
|
|
@ -94,7 +94,8 @@ var UserSchema = new Schema({
|
|||
rewrite: {type: Boolean, 'default': true},
|
||||
partyEnabled: Boolean, // FIXME do we need this?
|
||||
rest: {type: Boolean, 'default': false}, // fixme - change to preferences.resting once we're off derby
|
||||
contributor: Boolean
|
||||
contributor: Boolean,
|
||||
classSelected: {type: Boolean, 'default': false}
|
||||
},
|
||||
history: {
|
||||
exp: Array, // [{date: Date, value: Number}], // big peformance issues if these are defined
|
||||
|
|
@ -107,10 +108,26 @@ var UserSchema = new Schema({
|
|||
party: Schema.Types.Mixed
|
||||
},
|
||||
items: {
|
||||
armor: Number,
|
||||
weapon: Number,
|
||||
head: Number,
|
||||
shield: Number,
|
||||
gear: {
|
||||
owned: _.transform(items.items.gear.flat, function(m,v,k){
|
||||
m[v.key] = {type: Boolean};
|
||||
if (v.key.match(/[weapon|armor|head|shield]_warrior_0/))
|
||||
m[v.key]['default'] = true;
|
||||
}),
|
||||
|
||||
equipped: {
|
||||
weapon: {type: String, 'default': 'weapon_warrior_0'},
|
||||
armor: {type: String, 'default': 'armor_base_0'},
|
||||
head: {type: String, 'default': 'head_base_0'},
|
||||
shield: {type: String, 'default': 'shield_base_0'}
|
||||
},
|
||||
costume: {
|
||||
weapon: {type: String, 'default': 'weapon_base_0'},
|
||||
armor: {type: String, 'default': 'armor_base_0'},
|
||||
head: {type: String, 'default': 'head_base_0'},
|
||||
shield: {type: String, 'default': 'shield_base_0'}
|
||||
},
|
||||
},
|
||||
|
||||
// -------------- Animals -------------------
|
||||
// Complex bit here. The result looks like:
|
||||
|
|
@ -185,16 +202,20 @@ var UserSchema = new Schema({
|
|||
preferences: {
|
||||
armorSet: String,
|
||||
dayStart: {type:Number, 'default': 0},
|
||||
gender: {type:String, 'default': 'm'},
|
||||
hair: {type:String, 'default':'blond'},
|
||||
size: {type:String, enum: ['broad','slim'], 'default': 'broad'},
|
||||
hair: {
|
||||
color: {type: String, 'default': 'blond'},
|
||||
base: {type: Number, 'default': 0},
|
||||
bangs: {type: Number, 'default': 0},
|
||||
beard: {type: Number, 'default': 0},
|
||||
mustach: {type: Number, 'default': 0},
|
||||
},
|
||||
hideHeader: {type:Boolean, 'default':false},
|
||||
showHelm: {type:Boolean, 'default':true},
|
||||
showWeapon: {type:Boolean, 'default':true},
|
||||
showShield: {type:Boolean, 'default':true},
|
||||
showArmor: {type:Boolean, 'default':true},
|
||||
skin: {type:String, 'default':'white'},
|
||||
timezoneOffset: Number,
|
||||
language: String
|
||||
language: String,
|
||||
automaticAllocation: Boolean,
|
||||
useCostume: Boolean
|
||||
},
|
||||
profile: {
|
||||
blurb: String,
|
||||
|
|
@ -202,10 +223,25 @@ var UserSchema = new Schema({
|
|||
name: String,
|
||||
},
|
||||
stats: {
|
||||
hp: Number,
|
||||
exp: Number,
|
||||
gp: Number,
|
||||
lvl: Number
|
||||
hp: {type: Number, 'default': 50},
|
||||
mp: {type: Number, 'default': 10},
|
||||
exp: {type: Number, 'default': 0},
|
||||
gp: {type: Number, 'default': 0},
|
||||
lvl: {type: Number, 'default': 1},
|
||||
|
||||
// Class System
|
||||
'class': {type: String, enum: ['warrior','rogue','wizard','healer'], 'default': 'warrior'},
|
||||
points: {type: Number, 'default': 0},
|
||||
str: {type: Number, 'default': 0},
|
||||
con: {type: Number, 'default': 0},
|
||||
int: {type: Number, 'default': 0},
|
||||
per: {type: Number, 'default': 0},
|
||||
buffs: {
|
||||
str: Number,
|
||||
def: Number,
|
||||
per: Number,
|
||||
stealth: Number
|
||||
}
|
||||
},
|
||||
tags: [
|
||||
{
|
||||
|
|
@ -268,10 +304,15 @@ 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.con + this.stats.str + this.stats.per + this.stats.int);
|
||||
|
||||
var petCount = helpers.countPets(_.reduce(this.items.pets,function(m,v){
|
||||
//HOTFIX - Remove when solution is found, the first argument passed to reduce is a function
|
||||
if(_.isFunction(v)) return m;
|
||||
return m+(v?1:0)},0), this.items.pets);
|
||||
|
||||
this.achievements.beastMaster = petCount >= 90;
|
||||
|
||||
//our own version incrementer
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ if (nconf.get('NODE_ENV') == 'development') {
|
|||
}
|
||||
|
||||
/* Items*/
|
||||
router.post('/user/buy/:type', auth.auth, cron, user.buy);
|
||||
router.post('/user/buy/:key', auth.auth, cron, user.buy);
|
||||
|
||||
/* User*/
|
||||
router.get('/user', auth.auth, cron, user.getUser);
|
||||
|
|
@ -61,6 +61,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 */
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
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
|
||||
|
||||
// ?v=1 needed to force refresh
|
||||
link(rel='shortcut icon' href='#{env.getBuildUrl("favicon.ico")}?v=2')
|
||||
link(rel='shortcut icon', href='#{env.getBuildUrl("favicon.ico")}?v=2')
|
||||
|
||||
script(type='text/javascript').
|
||||
window.env = !{JSON.stringify(env)};
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -5,6 +5,20 @@ script(type='text/ng-template', id='partials/options.inventory.inventory.html')
|
|||
p.well Click an egg to see usable potions highlighted in green and then click one of the highlighted potions to hatch your pet. If no potions are highlighted, click that egg again to deselect it, and instead click a potion first to have the usable eggs highlighted. You can also sell unwanted drops to Alexander the Merchant.
|
||||
menu.inventory-list(type='list')
|
||||
|
||||
h4 Gear
|
||||
li.customize-menu
|
||||
menu.pets-menu(label='{{label}}', ng-repeat='(klass,label) in {base:"Base", warrior:"Warrior", wizard:"Wizard", rogue:"Rogue", special:"Special"}', ng-show='gear[klass]')
|
||||
div(ng-repeat='item in gear[klass]')
|
||||
button.customize-option(popover='{{item.notes}}', popover-title='{{item.text}}', popover-trigger='mouseenter', popover-placement='right', ng-click='equip(user,item)', class='shop_{{item.key}}', ng-class='{selectableInventory: user.items.gear.equipped[item.type] == item.key}')
|
||||
label.checkbox.inline
|
||||
input(type="checkbox", ng-model="user.preferences.costume")
|
||||
| Use Costume
|
||||
i.icon-question-sign(popover="Show something different on your avatar than the gear you have equipped for battle", popover-trigger='mouseenter', popover-placement='right')
|
||||
li.customize-menu(ng-if='user.preferences.costume')
|
||||
menu.pets-menu(label='{{label}}', ng-repeat='(klass,label) in {base:"Base", warrior:"Warrior", wizard:"Wizard", rogue:"Rogue", special:"Special"}', ng-show='gear[klass]')
|
||||
div(ng-repeat='item in gear[klass]')
|
||||
button.customize-option(popover='{{item.notes}}', popover-title='{{item.text}}', popover-trigger='mouseenter', popover-placement='right', ng-click='equip(user,item, true)', class='shop_{{item.key}}', ng-class='{selectableInventory: user.items.gear.costume[item.type] == item.key}')
|
||||
|
||||
li.customize-menu
|
||||
menu.pets-menu(label='Eggs ({{eggCount}})')
|
||||
p(ng-show='eggCount < 1') You don't have any eggs.
|
||||
|
|
@ -33,10 +47,10 @@ script(type='text/ng-template', id='partials/options.inventory.inventory.html')
|
|||
.span6
|
||||
h2 Market
|
||||
.row-fluid
|
||||
table.NPC-Alex-container
|
||||
table.npc_alex_container
|
||||
tr
|
||||
td
|
||||
.NPC-Alex.pull-left
|
||||
.npc_alex.pull-left
|
||||
td
|
||||
.popover.static-popover.fade.right.in
|
||||
.arrow
|
||||
|
|
|
|||
|
|
@ -12,15 +12,19 @@ script(type='text/ng-template', id='partials/options.inventory.stable.html')
|
|||
|
||||
script(type='text/ng-template', id='partials/options.inventory.stable.mounts.html')
|
||||
.stable
|
||||
.NPC-Matt
|
||||
.popover.static-popover.fade.right.in(style='max-width: 550px; margin-left: 10px;')
|
||||
.arrow
|
||||
h3.popover-title
|
||||
a(target='_blank', href='http://www.kickstarter.com/profile/mattboch') Matt Boch
|
||||
.popover-content
|
||||
p.
|
||||
Shall I bring you your steed, {{user.profile.name}}? Click a mount to saddle up.
|
||||
h4 {{mountCount}} / {{totalPets}} Mounts Tamed
|
||||
table(style='width:100%')
|
||||
tr
|
||||
td(style='width:144px')
|
||||
.npc_matt
|
||||
td
|
||||
.popover.static-popover.fade.right.in(style='max-width: 550px; margin-left: 10px;')
|
||||
.arrow
|
||||
h3.popover-title
|
||||
a(target='_blank', href='http://www.kickstarter.com/profile/mattboch') Matt Boch
|
||||
.popover-content
|
||||
p.
|
||||
Shall I bring you your steed, {{user.profile.name}}? Click a mount to saddle up.
|
||||
h4 {{mountCount}} / {{totalPets}} Mounts Tamed
|
||||
menu.pets(type='list')
|
||||
li.customize-menu(ng-repeat='egg in Items.eggs')
|
||||
menu
|
||||
|
|
@ -28,7 +32,7 @@ script(type='text/ng-template', id='partials/options.inventory.stable.mounts.htm
|
|||
button(class="pet-button Mount_Head_{{mount}}", ng-show='user.items.mounts[mount]', ng-class='{active: user.items.currentMount == mount}', ng-click='chooseMount(egg.name, potion.name)')
|
||||
//div(class='Mount_Head_{{mount}}')
|
||||
button(class="pet-button pet-not-owned", ng-hide='user.items.mounts[mount]')
|
||||
img(src='/bower_components/habitrpg-shared/img/PixelPaw.png')
|
||||
.PixelPaw
|
||||
|
||||
h4 Rare Mounts
|
||||
menu
|
||||
|
|
@ -40,15 +44,19 @@ script(type='text/ng-template', id='partials/options.inventory.stable.mounts.htm
|
|||
|
||||
script(type='text/ng-template', id='partials/options.inventory.stable.pets.html')
|
||||
.stable
|
||||
.NPC-Matt
|
||||
.popover.static-popover.fade.right.in(style='max-width: 550px; margin-left: 10px;')
|
||||
.arrow
|
||||
h3.popover-title
|
||||
a(target='_blank', href='http://www.kickstarter.com/profile/mattboch') Matt Boch
|
||||
.popover-content
|
||||
p.
|
||||
Welcome to the Stable! I'm Matt, the beast master. Choose a pet here to venture at your side. Feed them and they'll grow into powerful steeds. <a target='_blank' href='https://f.cloud.github.com/assets/2374703/164631/3ed5fa6c-78cd-11e2-8743-f65ac477b55e.png'>Have a look-see</a> at all the pets you can collect.
|
||||
h4 {{petCount}} / {{totalPets}} Pets Found
|
||||
table(style='width:100%')
|
||||
tr
|
||||
td(style='width:144px')
|
||||
.npc_matt
|
||||
td
|
||||
.popover.static-popover.fade.right.in(style='max-width: 550px; margin-left: 10px;')
|
||||
.arrow
|
||||
h3.popover-title
|
||||
a(target='_blank', href='http://www.kickstarter.com/profile/mattboch') Matt Boch
|
||||
.popover-content
|
||||
p.
|
||||
Welcome to the Stable! I'm Matt, the beast master. Choose a pet here to venture at your side. Feed them and they'll grow into powerful steeds. <a target='_blank' href='https://f.cloud.github.com/assets/2374703/164631/3ed5fa6c-78cd-11e2-8743-f65ac477b55e.png'>Have a look-see</a> at all the pets you can collect.
|
||||
h4 {{petCount}} / {{totalPets}} Pets Found
|
||||
|
||||
menu.pets(type='list')
|
||||
li.customize-menu(ng-repeat='egg in Items.eggs')
|
||||
|
|
@ -58,7 +66,7 @@ script(type='text/ng-template', id='partials/options.inventory.stable.pets.html'
|
|||
.progress(ng-class='{"progress-success": user.items.pets[pet]<50}')
|
||||
.bar(style="width: {{user.items.pets[pet]/.5}}%;")
|
||||
button(class="pet-button pet-not-owned", ng-if='!user.items.pets[pet]')
|
||||
img(src='/bower_components/habitrpg-shared/img/PixelPaw.png')
|
||||
.PixelPaw
|
||||
|
||||
h4 Rare Pets
|
||||
menu
|
||||
|
|
@ -69,7 +77,7 @@ script(type='text/ng-template', id='partials/options.inventory.stable.pets.html'
|
|||
button(ng-if='user.items.pets["Turkey-Base"]', class="pet-button Pet-Turkey-Base", ng-class='{active: user.items.currentPet == "Turkey-Base"}', ng-click='choosePet("Turkey", "Base")', popover='Turkey', popover-trigger='mouseenter', popover-placement='bottom')
|
||||
a(target='_blank', href='http://habitrpg.wikia.com/wiki/Contributing_to_HabitRPG')
|
||||
button(ng-if='!user.items.pets["Dragon-Hydra"]', class="pet-button pet-not-owned", popover-trigger='mouseenter', popover-placement='right', popover="Click the gold paw to learn more about how you can obtain this rare pet through contributing to HabitRPG!", popover-title='How to Get this Pet!')
|
||||
img(src='/bower_components/habitrpg-shared/img/PixelPaw-Gold.png')
|
||||
.PixelPaw-Gold
|
||||
|
||||
.well.food-tray
|
||||
p(ng-show='foodCount < 1') You don't have any food yet.
|
||||
|
|
|
|||
|
|
@ -6,66 +6,83 @@ script(id='partials/options.profile.avatar.html', type='text/ng-template')
|
|||
li.customize-menu
|
||||
menu(label='Head')
|
||||
menu
|
||||
button.m_head_0.customize-option(type='button', ng-click='set("preferences.gender","m")')
|
||||
button.f_head_0.customize-option(type='button', ng-click='set("preferences.gender","f")')
|
||||
label.checkbox
|
||||
input(type='checkbox', ng-model='user.preferences.showHelm', ng-change='set("preferences.showHelm", user.preferences.showHelm?true: false)')
|
||||
| Show Helm
|
||||
menu(type='list')
|
||||
li.customize-menu
|
||||
menu(label='Clothing')
|
||||
button.f_armor_0_v1.customize-option(ng-show='user.preferences.gender=="f"', type='button', ng-click='set("preferences.armorSet","v1")')
|
||||
button.f_armor_0_v2.customize-option(ng-show='user.preferences.gender=="f"', type='button', ng-click='set("preferences.armorSet","v2")')
|
||||
label.checkbox
|
||||
input(type='checkbox', ng-model='user.preferences.showArmor', ng-change='set("preferences.showArmor", user.preferences.showArmor?true: false)')
|
||||
| Show Armor
|
||||
menu(type='list')
|
||||
li.customize-menu
|
||||
menu(label='Other')
|
||||
label.checkbox
|
||||
input(type='checkbox', ng-model='user.preferences.showWeapon', ng-change='set("preferences.showWeapon", user.preferences.showWeapon?true: false)')
|
||||
| Show Weapon
|
||||
label.checkbox
|
||||
input(type='checkbox', ng-model='user.preferences.showShield', ng-change='set("preferences.showShield", user.preferences.showShield?true: false)')
|
||||
| Show Shield
|
||||
|
||||
button.broad_armor_base_0.customize-option(type='button', ng-click='set("preferences.size","broad")')
|
||||
button.slim_armor_base_0.customize-option(type='button', ng-click='set("preferences.size","slim")')
|
||||
|
||||
.span4
|
||||
// hair
|
||||
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")')
|
||||
h3 Hair
|
||||
menu(type='list')
|
||||
// Color
|
||||
li.customize-menu
|
||||
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='head_base_0 customize-option', type='button', ng-click='set("preferences.hair.bangs",0)')
|
||||
button(class='hair_bangs_1_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.bangs",1)')
|
||||
button(class='hair_bangs_2_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.bangs",2)')
|
||||
button(class='hair_bangs_3_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.bangs",3)')
|
||||
|
||||
// Beard
|
||||
li.customize-menu
|
||||
menu(label='Beard')
|
||||
button(class='head_base_0 customize-option', type='button', ng-click='set("preferences.hair.beard",0)')
|
||||
button(class='hair_beard_1_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.beard",1)')
|
||||
button(class='hair_beard_2_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.beard",2)')
|
||||
button(class='hair_beard_3_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.beard",3)')
|
||||
|
||||
// Mustache
|
||||
li.customize-menu
|
||||
menu(label='Mustache')
|
||||
button(class='head_base_0 customize-option', type='button', ng-click='set("preferences.hair.mustache",0)')
|
||||
button(class='hair_mustache_1_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.mustache",1)')
|
||||
button(class='hair_mustache_2_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.mustache",2)')
|
||||
|
||||
// Base
|
||||
li.customize-menu
|
||||
menu(label='Base')
|
||||
button(class='head_base_0 customize-option', type='button', ng-click='set("preferences.hair.base",0)')
|
||||
button(class='hair_base_1_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.base",1)')
|
||||
button(class='hair_base_2_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.base",2)')
|
||||
button(class='hair_base_3_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.base",3)')
|
||||
button(class='hair_base_4_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.base",4)')
|
||||
button(class='hair_base_5_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.base",5)')
|
||||
button(class='hair_base_6_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.base",6)')
|
||||
button(class='hair_base_7_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.base",7)')
|
||||
button(class='hair_base_8_{{user.preferences.hair.color}} customize-option', type='button', ng-click='set("preferences.hair.base",8)')
|
||||
|
||||
.span4
|
||||
// skin
|
||||
li.customize-menu
|
||||
menu(label='Basic Skins')
|
||||
button.customize-option(type='button', class='{{user.preferences.gender}}_skin_asian', ng-click='set("preferences.skin","asian")')
|
||||
button.customize-option(type='button', class='{{user.preferences.gender}}_skin_white', ng-click='set("preferences.skin","white")')
|
||||
button.customize-option(type='button', class='{{user.preferences.gender}}_skin_ea8349', ng-click='set("preferences.skin","ea8349")')
|
||||
button.customize-option(type='button', class='{{user.preferences.gender}}_skin_c06534', ng-click='set("preferences.skin","c06534")')
|
||||
button.customize-option(type='button', class='{{user.preferences.gender}}_skin_98461a', ng-click='set("preferences.skin","98461a")')
|
||||
button.customize-option(type='button', class='{{user.preferences.gender}}_skin_black', ng-click='set("preferences.skin","black")')
|
||||
button.customize-option(type='button', class='{{user.preferences.gender}}_skin_dead', ng-click='set("preferences.skin","dead")')
|
||||
button.customize-option(type='button', class='{{user.preferences.gender}}_skin_orc', ng-click='set("preferences.skin","orc")')
|
||||
button.customize-option(type='button', class='skin_asian', ng-click='set("preferences.skin","asian")')
|
||||
button.customize-option(type='button', class='skin_white', ng-click='set("preferences.skin","white")')
|
||||
button.customize-option(type='button', class='skin_ea8349', ng-click='set("preferences.skin","ea8349")')
|
||||
button.customize-option(type='button', class='skin_c06534', ng-click='set("preferences.skin","c06534")')
|
||||
button.customize-option(type='button', class='skin_98461a', ng-click='set("preferences.skin","98461a")')
|
||||
button.customize-option(type='button', class='skin_black', ng-click='set("preferences.skin","black")')
|
||||
button.customize-option(type='button', class='skin_dead', ng-click='set("preferences.skin","dead")')
|
||||
button.customize-option(type='button', class='skin_orc', ng-click='set("preferences.skin","orc")')
|
||||
|
||||
// Rainbow Skin
|
||||
h5.
|
||||
Rainbow Skins - 2<span class="Pet_Currency_Gem1x inline-gems"/>/skin
|
||||
//menu(label='Rainbow Skins (2G / skin)')
|
||||
menu
|
||||
button.customize-option(type='button', class='{{user.preferences.gender}}_skin_eb052b', ng-class='{locked: !user.purchased.skin.eb052b}', ng-click='unlock("skin.eb052b")')
|
||||
button.customize-option(type='button', class='{{user.preferences.gender}}_skin_f69922', ng-class='{locked: !user.purchased.skin.f69922}', ng-click='unlock("skin.f69922")')
|
||||
button.customize-option(type='button', class='{{user.preferences.gender}}_skin_f5d70f', ng-class='{locked: !user.purchased.skin.f5d70f}', ng-click='unlock("skin.f5d70f")')
|
||||
button.customize-option(type='button', class='{{user.preferences.gender}}_skin_0ff591', ng-class='{locked: !user.purchased.skin.0ff591}', ng-click='unlock("skin.0ff591")')
|
||||
button.customize-option(type='button', class='{{user.preferences.gender}}_skin_2b43f6', ng-class='{locked: !user.purchased.skin.2b43f6}', ng-click='unlock("skin.2b43f6")')
|
||||
button.customize-option(type='button', class='{{user.preferences.gender}}_skin_d7a9f7', ng-class='{locked: !user.purchased.skin.d7a9f7}', ng-click='unlock("skin.d7a9f7")')
|
||||
button.customize-option(type='button', class='{{user.preferences.gender}}_skin_800ed0', ng-class='{locked: !user.purchased.skin.800ed0}', ng-click='unlock("skin.800ed0")')
|
||||
button.customize-option(type='button', class='{{user.preferences.gender}}_skin_rainbow', ng-class='{locked: !user.purchased.skin.rainbow}', ng-click='unlock("skin.rainbow")')
|
||||
button.customize-option(type='button', class='skin_eb052b', ng-class='{locked: !user.purchased.skin.eb052b}', ng-click='unlock("skin.eb052b")')
|
||||
button.customize-option(type='button', class='skin_f69922', ng-class='{locked: !user.purchased.skin.f69922}', ng-click='unlock("skin.f69922")')
|
||||
button.customize-option(type='button', class='skin_f5d70f', ng-class='{locked: !user.purchased.skin.f5d70f}', ng-click='unlock("skin.f5d70f")')
|
||||
button.customize-option(type='button', class='skin_0ff591', ng-class='{locked: !user.purchased.skin.0ff591}', ng-click='unlock("skin.0ff591")')
|
||||
button.customize-option(type='button', class='skin_2b43f6', ng-class='{locked: !user.purchased.skin.2b43f6}', ng-click='unlock("skin.2b43f6")')
|
||||
button.customize-option(type='button', class='skin_d7a9f7', ng-class='{locked: !user.purchased.skin.d7a9f7}', ng-click='unlock("skin.d7a9f7")')
|
||||
button.customize-option(type='button', class='skin_800ed0', ng-class='{locked: !user.purchased.skin.800ed0}', ng-click='unlock("skin.800ed0")')
|
||||
button.customize-option(type='button', class='skin_rainbow', ng-class='{locked: !user.purchased.skin.rainbow}', ng-click='unlock("skin.rainbow")')
|
||||
button.btn.btn-small.btn-primary(ng-hide='user.purchased.skin.eb052b && user.purchased.skin.f69922 && user.purchased.skin.f5d70f && user.purchased.skin.0ff591 && user.purchased.skin.2b43f6 && user.purchased.skin.d7a9f7 && user.purchased.skin.800ed0 && user.purchased.skin.rainbow', ng-click='unlock(["skin.eb052b", "skin.f69922", "skin.f5d70f", "skin.0ff591", "skin.2b43f6", "skin.d7a9f7", "skin.800ed0", "skin.rainbow"])') Unlock Set - 5<span class="Pet_Currency_Gem1x inline-gems"/>
|
||||
|
||||
// Special Events
|
||||
|
|
@ -73,18 +90,53 @@ script(id='partials/options.profile.avatar.html', type='text/ng-template')
|
|||
div(ng-if='user.purchased.skin.monster || user.purchased.skin.pumpkin || user.purchased.skin.skeleton || user.purchased.skin.zombie || user.purchased.skin.ghost || user.purchased.skin.shadow')
|
||||
h5 Spooky Skins
|
||||
menu
|
||||
button.customize-option(type='button', class='{{user.preferences.gender}}_skin_monster', ng-if='user.purchased.skin.monster', ng-click='unlock("skin.monster")')
|
||||
button.customize-option(type='button', class='{{user.preferences.gender}}_skin_pumpkin', ng-if='user.purchased.skin.pumpkin', ng-click='unlock("skin.pumpkin")')
|
||||
button.customize-option(type='button', class='{{user.preferences.gender}}_skin_skeleton', ng-if='user.purchased.skin.skeleton', ng-click='unlock("skin.skeleton")')
|
||||
button.customize-option(type='button', class='{{user.preferences.gender}}_skin_zombie', ng-if='user.purchased.skin.zombie', ng-click='unlock("skin.zombie")')
|
||||
button.customize-option(type='button', class='{{user.preferences.gender}}_skin_ghost', ng-if='user.purchased.skin.ghost', ng-click='unlock("skin.ghost")')
|
||||
button.customize-option(type='button', class='{{user.preferences.gender}}_skin_shadow', ng-if='user.purchased.skin.shadow', ng-click='unlock("skin.shadow")')
|
||||
button.customize-option(type='button', class='skin_monster', ng-if='user.purchased.skin.monster', ng-click='unlock("skin.monster")')
|
||||
button.customize-option(type='button', class='skin_pumpkin', ng-if='user.purchased.skin.pumpkin', ng-click='unlock("skin.pumpkin")')
|
||||
button.customize-option(type='button', class='skin_skeleton', ng-if='user.purchased.skin.skeleton', ng-click='unlock("skin.skeleton")')
|
||||
button.customize-option(type='button', class='skin_zombie', ng-if='user.purchased.skin.zombie', ng-click='unlock("skin.zombie")')
|
||||
button.customize-option(type='button', class='skin_ghost', ng-if='user.purchased.skin.ghost', ng-click='unlock("skin.ghost")')
|
||||
button.customize-option(type='button', class='skin_shadow', ng-if='user.purchased.skin.shadow', ng-click='unlock("skin.shadow")')
|
||||
|
||||
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}}
|
||||
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')
|
||||
| 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')
|
||||
| DEF: {{user.stats.def}}
|
||||
td
|
||||
a.btn.btn-primary(ng-show='user.stats.points', ng-click='allocate("con")') +
|
||||
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')
|
||||
| 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')
|
||||
| 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')
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
a.pull-right.gem-wallet(popover-trigger='mouseenter', popover-title='Guild Bank', popover='Gems which your guild leader can use for challenge prizes.', popover-placement='left', popover-html='true')
|
||||
// <span class="task-action-btn tile flush bright add-gems-btn">+</span>
|
||||
span.task-action-btn.tile.flush.neutral
|
||||
.Gems
|
||||
.Pet_Currency_Gem2x.Gems
|
||||
| {{group.balance * 4 | number:0 }} Guild Gems
|
||||
.row-fluid
|
||||
.span4
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
table
|
||||
tr
|
||||
td
|
||||
.NPC-Daniel
|
||||
.npc_daniel
|
||||
td
|
||||
.popover.static-popover.fade.right.in
|
||||
.arrow
|
||||
|
|
@ -62,23 +62,23 @@
|
|||
<span class='achievement achievement-firefox'></span> When your <strong>first</strong> submission is deployed, you will receive the HabitRPG Contributor's badge. Your name in Tavern chat will proudly display that you are a contributor. As a bounty for your work, you will also receive <strong>2 Gems</strong>.
|
||||
hr
|
||||
p.
|
||||
<span class='shop_armor_7 shop-sprite item-img'></span> When your <strong>second</strong> submission is deployed, the <strong>Crystal Armor</strong> will be available for purchase in the Rewards shop after the Golden Armor. As a bounty for your continued work, you will also receive <strong>2 Gems</strong>.
|
||||
<span class='shop_armor_special_1 shop-sprite item-img'></span> When your <strong>second</strong> submission is deployed, the <strong>Crystal Armor</strong> will be available for purchase in the Rewards shop after the Golden Armor. As a bounty for your continued work, you will also receive <strong>2 Gems</strong>.
|
||||
tr
|
||||
td
|
||||
a.label.label-contributor-3(ng-click='toggleUserTier($event)') Elite (3-4)
|
||||
div(style='display:none;')
|
||||
p.
|
||||
<span class='shop_head_7 shop-sprite item-img'></span> When your <strong>third</strong> submission is deployed, the <strong>Crystal Helmet</strong> will be available for purchase in the Rewards shop after the Golden Helmet. As a bounty for your great work, you will also receive <strong>2 Gems</strong>.
|
||||
<span class='shop_head_special_1 shop-sprite item-img'></span> When your <strong>third</strong> submission is deployed, the <strong>Crystal Helmet</strong> will be available for purchase in the Rewards shop after the Golden Helmet. As a bounty for your great work, you will also receive <strong>2 Gems</strong>.
|
||||
hr
|
||||
p.
|
||||
<span class='shop_weapon_8 shop-sprite item-img'></span> When your <strong>fourth</strong> submission is deployed, the <strong>Crystal Sword</strong> will be available for purchase in the Rewards shop after the Golden Sword. You will once again receive a bounty of <strong>2 Gems</strong>.
|
||||
<span class='shop_weapon_special_1 shop-sprite item-img'></span> When your <strong>fourth</strong> submission is deployed, the <strong>Crystal Sword</strong> will be available for purchase in the Rewards shop after the Golden Sword. You will once again receive a bounty of <strong>2 Gems</strong>.
|
||||
|
||||
tr
|
||||
td
|
||||
a.label.label-contributor-5(ng-click='toggleUserTier($event)') Champion (5-6)
|
||||
div(style='display:none;')
|
||||
p.
|
||||
<span class='shop_shield_7 shop-sprite item-img'></span> When your <em>fifth</em> submission is deployed, the <strong>Crystal Shield</strong> will be available for purchase in the Reward shop after the Golden Shield. You will also receive <strong>2 Gems</strong>.
|
||||
<span class='shop_shield_special_1 shop-sprite item-img'></span> When your <em>fifth</em> submission is deployed, the <strong>Crystal Shield</strong> will be available for purchase in the Reward shop after the Golden Shield. You will also receive <strong>2 Gems</strong>.
|
||||
hr
|
||||
p.
|
||||
<div class='Pet-Dragon-Hydra pull-left'></div> When your <em>sixth</em> submission is deployed, you will receive a <strong>Hydra Pet</strong>. You will also receive <strong>2 Gems</strong>.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
a.pull-right.gem-wallet(ng-click='modals.buyGems = true', popover-trigger='mouseenter', popover-title='Gems', popover="Used for buying special items and services (eggs, hatching potions, Fortify, etc.). You'll need to unlock those features before being able to use Gems.", popover-placement='bottom')
|
||||
span.task-action-btn.tile.flush.bright.add-gems-btn +
|
||||
span.task-action-btn.tile.flush.neutral
|
||||
.Gems
|
||||
.Pet_Currency_Gem2x.Gems
|
||||
| {{user.balance * 4 | number:0}} Gems
|
||||
|
|
@ -3,28 +3,40 @@
|
|||
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, isLeader: party.leader==profile._id}')
|
||||
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, isLeader: party.leader==profile._id}')
|
||||
.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", 0, profile.preferences, profile.backer, profile.contributor)}}')
|
||||
span(class='{{equipped("armor", profile.items.armor, profile.preferences, profile.backer, profile.contributor)}}', ng-show='profile.preferences.showArmor')
|
||||
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)}}', ng-show='profile.preferences.showShield')
|
||||
span(class='{{equipped("weapon",profile.items.weapon,profile.preferences, profile.backer, profile.contributor)}}', ng-show='profile.preferences.showWeapon')
|
||||
span(class='skin_{{profile.preferences.skin}}')
|
||||
|
||||
span(class='{{profile.preferences.size}}_{{profile.items.gear.equipped.armor}}', ng-if='!profile.preferences.costume')
|
||||
span(class='{{profile.preferences.size}}_{{profile.items.gear.costume.armor}}', ng-if='profile.preferences.costume')
|
||||
|
||||
span(class='head_base_0')
|
||||
span(class='hair_base_{{profile.preferences.hair.base}}_{{profile.preferences.hair.color}}')
|
||||
span(class='hair_bangs_{{profile.preferences.hair.bangs}}_{{profile.preferences.hair.color}}')
|
||||
|
||||
span(class='hair_beard_{{profile.preferences.hair.beard}}_{{profile.preferences.hair.color}}')
|
||||
span(class='hair_mustache_{{profile.preferences.hair.mustache}}_{{profile.preferences.hair.color}}')
|
||||
|
||||
span(class='{{profile.items.gear.equipped.head}}', ng-if='!profile.preferences.costume')
|
||||
span(class='{{profile.items.gear.costume.head}}', ng-if='profile.preferences.costume')
|
||||
|
||||
|
||||
span(class='{{profile.items.gear.equipped.shield}}', ng-if='!profile.preferences.costume')
|
||||
span(class='{{profile.items.gear.costume.shield}}', ng-if='profile.preferences.costume')
|
||||
|
||||
span(class='{{profile.items.gear.equipped.weapon}}', ng-if='!profile.preferences.costume')
|
||||
span(class='{{profile.items.gear.costume.weapon}}', ng-if='profile.preferences.costume')
|
||||
|
||||
|
||||
// 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(ng-class='userLevelStyle(profile,"label")')
|
||||
|
|
|
|||
|
|
@ -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,10 +24,16 @@
|
|||
span(ng-show='user.history.exp')
|
||||
a(ng-click='toggleChart("exp")', tooltip='Progress')
|
||||
i.icon-signal
|
||||
.meter.mana(title='Mana', ng-if='user.flags.classSelected')
|
||||
.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')
|
||||
include avatar
|
||||
|
||||
.NPC-Bailey-Head(ng-show='user.flags.newStuff', tooltip='Psst', tooltip-placement='top', ng-click='modals.newStuff=true')
|
||||
.npc_bailey.npc_bailey_head(ng-show='user.flags.newStuff', tooltip='Psst', tooltip-placement='top', ng-click='modals.newStuff=true')
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ div(modal='user.flags.contributor')
|
|||
.modal-header
|
||||
h3 Contributor Achievement!
|
||||
.modal-body
|
||||
.NPC-Justin.float-left
|
||||
.npc_justin.float-left
|
||||
p.
|
||||
{{user.profile.name}}, you awesome person! You're now a level {{user.contributor.level}} contributor for helping HabitRPG. See <a href='http://habitrpg.wikia.com/wiki/Contributor_Rewards' target='_blank'>what prizes you've earned for your contribution!</a>
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ div(modal='modals.buyGems')
|
|||
table
|
||||
tr
|
||||
td
|
||||
.NPC-Justin
|
||||
.npc_justin
|
||||
td
|
||||
.popover.static-popover.fade.right.in.wide-popover
|
||||
.arrow
|
||||
|
|
|
|||
69
views/shared/modals/classes.jade
Normal file
69
views/shared/modals/classes.jade
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
.modal(ng-if='!user.flags.classSelected && user.stats.lvl >= 5', data-backdrop=true, ng-controller='UserCtrl')
|
||||
.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='skin_{{user.preferences.skin}}')
|
||||
span(class='{{user.preferences.size}}_armor_warrior_5')
|
||||
span(class='head_base_0')
|
||||
span(class='hair_base_{{user.preferences.hair.base}}_{{user.preferences.hair.color}}')
|
||||
span(class='hair_bangs_{{user.preferences.hair.bangs}}_{{user.preferences.hair.color}}')
|
||||
span(class='hair_beard_{{user.preferences.hair.beard}}_{{user.preferences.hair.color}}')
|
||||
span(class='hair_mustache_{{user.preferences.hair.mustache}}_{{user.preferences.hair.color}}')
|
||||
span(class='head_warrior_5')
|
||||
span(class='shield_warrior_5')
|
||||
span(class='weapon_warrior_6')
|
||||
.span3(ng-click='selectedClass = "wizard"')
|
||||
h5 Wizard
|
||||
figure.herobox(ng-class='{"selected-class": selectedClass=="wizard"}')
|
||||
.character-sprites
|
||||
span(class='skin_{{user.preferences.skin}}')
|
||||
span(class='{{user.preferences.size}}_armor_wizard_5')
|
||||
span(class='head_base_0')
|
||||
span(class='hair_base_{{user.preferences.hair.base}}_{{user.preferences.hair.color}}')
|
||||
span(class='hair_bangs_{{user.preferences.hair.bangs}}_{{user.preferences.hair.color}}')
|
||||
span(class='hair_beard_{{user.preferences.hair.beard}}_{{user.preferences.hair.color}}')
|
||||
span(class='hair_mustache_{{user.preferences.hair.mustache}}_{{user.preferences.hair.color}}')
|
||||
span(class='head_wizard_5')
|
||||
span(class='shield_wizard_5')
|
||||
span(class='weapon_wizard_6')
|
||||
.span3(ng-click='selectedClass = "rogue"')
|
||||
h5 Rogue
|
||||
figure.herobox(ng-class='{"selected-class": selectedClass=="rogue"}')
|
||||
.character-sprites
|
||||
span(class='skin_{{user.preferences.skin}}')
|
||||
span(class='{{user.preferences.size}}_armor_rogue_5')
|
||||
span(class='head_base_0')
|
||||
span(class='hair_base_{{user.preferences.hair.base}}_{{user.preferences.hair.color}}')
|
||||
span(class='hair_bangs_{{user.preferences.hair.bangs}}_{{user.preferences.hair.color}}')
|
||||
span(class='hair_beard_{{user.preferences.hair.beard}}_{{user.preferences.hair.color}}')
|
||||
span(class='hair_mustache_{{user.preferences.hair.mustache}}_{{user.preferences.hair.color}}')
|
||||
span(class='head_rogue_5')
|
||||
span(class='shield_rogue_5')
|
||||
span(class='weapon_rogue_6')
|
||||
.span3(ng-click='selectedClass = "healer"')
|
||||
h5 Healer
|
||||
figure.herobox(ng-class='{"selected-class": selectedClass=="healer"}')
|
||||
.character-sprites
|
||||
span(class='skin_{{user.preferences.skin}}')
|
||||
span(class='{{user.preferences.size}}_armor_healer_5')
|
||||
span(class='head_base_0')
|
||||
span(class='hair_base_{{user.preferences.hair.base}}_{{user.preferences.hair.color}}')
|
||||
span(class='hair_bangs_{{user.preferences.hair.bangs}}_{{user.preferences.hair.color}}')
|
||||
span(class='hair_beard_{{user.preferences.hair.beard}}_{{user.preferences.hair.color}}')
|
||||
span(class='hair_mustache_{{user.preferences.hair.mustache}}_{{user.preferences.hair.color}}')
|
||||
span(class='head_healer_5')
|
||||
span(class='shield_healer_5')
|
||||
span(class='weapon_healer_6')
|
||||
|
||||
.modal-footer
|
||||
button.btn.btn-default.cancel(ng-click='rerollSubmit()') Select
|
||||
|
|
@ -3,7 +3,7 @@ div(modal='user.stats.hp <= 0', options='{backdrop:true, keyboard:false, backdro
|
|||
.row-fluid
|
||||
.span4
|
||||
figure.notification-character
|
||||
img(src='/bower_components/habitrpg-shared/img/sprites/dead.png')
|
||||
.GrimReaper
|
||||
.span8
|
||||
h2 You Died!
|
||||
.row-fluid
|
||||
|
|
|
|||
|
|
@ -6,4 +6,5 @@ include ./new-stuff
|
|||
include ./buy-gems
|
||||
include ./members
|
||||
include ./settings
|
||||
include ./pets
|
||||
include ./pets
|
||||
include ./classes
|
||||
|
|
@ -5,7 +5,7 @@ div(modal='modals.newStuff')
|
|||
table
|
||||
tr
|
||||
td
|
||||
.NPC-Bailey
|
||||
.npc_bailey
|
||||
td
|
||||
.popover.static-popover.fade.right.in.wide-popover
|
||||
.arrow
|
||||
|
|
|
|||
|
|
@ -31,19 +31,21 @@ div(ng-controller='SettingsCtrl')
|
|||
.option-group.option-medium
|
||||
input.option-content(type='number', data-for='stats.lvl', ng-model='restoreValues.stats.lvl')
|
||||
span.input-suffix Level
|
||||
h3 Equipment
|
||||
.option-group.option-medium
|
||||
input.option-content(type='number', data-for='items.weapon', ng-model='restoreValues.items.weapon')
|
||||
span.input-suffix Weapon
|
||||
.option-group.option-medium
|
||||
input.option-content(type='number', data-for='items.armor', ng-model='restoreValues.items.armor')
|
||||
span.input-suffix Armor
|
||||
.option-group.option-medium
|
||||
input.option-content(type='number', data-for='items.head', ng-model='restoreValues.items.head')
|
||||
span.input-suffix Helm
|
||||
.option-group.option-medium
|
||||
input.option-content(type='number', data-for='items.shield', ng-model='restoreValues.items.shield')
|
||||
span.input-suffix Shield
|
||||
//-
|
||||
//- Commenting out since it doesn't make sense to restore equipment with Armory anymore. They can just restore GP & buy
|
||||
h3 Equipment
|
||||
.option-group.option-medium
|
||||
input.option-content(type='number', data-for='items.weapon', ng-model='restoreValues.items.weapon')
|
||||
span.input-suffix Weapon
|
||||
.option-group.option-medium
|
||||
input.option-content(type='number', data-for='items.armor', ng-model='restoreValues.items.armor')
|
||||
span.input-suffix Armor
|
||||
.option-group.option-medium
|
||||
input.option-content(type='number', data-for='items.head', ng-model='restoreValues.items.head')
|
||||
span.input-suffix Helm
|
||||
.option-group.option-medium
|
||||
input.option-content(type='number', data-for='items.shield', ng-model='restoreValues.items.shield')
|
||||
span.input-suffix Shield
|
||||
h3 Achievements
|
||||
.option-group.option-medium
|
||||
input.option-content(type='number', data-for='achievements.streak', ng-model='restoreValues.achievements.streak')
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@ script(id='templates/habitrpg-tasks.html', type="text/ng-template")
|
|||
include ./task
|
||||
|
||||
// Static Rewards
|
||||
ul.items(bo-if='main && list.type=="reward" && user.flags.itemsEnabled')
|
||||
li.task.reward-item(ng-hide='item.hide', ng-repeat='item in itemStore')
|
||||
ul.items.rewards(bo-if='main && list.type=="reward" && user.flags.itemsEnabled')
|
||||
li.task.reward-item(ng-repeat='item in itemStore')
|
||||
// right-hand side control buttons
|
||||
.task-meta-controls
|
||||
span.task-notes(popover-trigger='mouseenter', popover-placement='left', popover='{{item.notes}}', popover-title='{{item.text}}')
|
||||
|
|
@ -55,13 +55,29 @@ script(id='templates/habitrpg-tasks.html', type="text/ng-template")
|
|||
.task-controls
|
||||
a.task-action-btn.btn-reroll(bo-if='item.type=="reroll"', ng-click='modals.reroll = true')
|
||||
i.icon-repeat
|
||||
a.money.btn-buy.item-btn(bo-if='item.type!="reroll"', ng-click='buy(item.type)')
|
||||
a.money.btn-buy.item-btn(bo-if='item.type!="reroll"', ng-click='buy(item)')
|
||||
span.reward-cost {{item.value}}
|
||||
span.shop_gold
|
||||
// main content
|
||||
span(bo-class='{"shop_{{item.classes}} shop-sprite item-img": true}')
|
||||
span(bo-class='{"shop_{{item.key}} 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]', ng-show='user.stats.lvl >= spell.lvl')
|
||||
.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}}
|
||||
| MP
|
||||
// main content
|
||||
span(ng-class='{"shop_{{spell.key}} shop-sprite item-img": true}')
|
||||
p.task-text {{spell.text}}
|
||||
|
||||
br
|
||||
|
||||
// Ads
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
li(bindonce='list', 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(bindonce='list', 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
|
||||
|
||||
|
|
@ -161,6 +161,14 @@ li(bindonce='list', ng-repeat='task in obj[list.type+"s"]', class='task {{taskCl
|
|||
span(ng-if='task.type=="daily"')
|
||||
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]')
|
||||
|
|
|
|||
Loading…
Reference in a new issue