mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-19 15:48:04 +01:00
Quests: hurt boss via score method, refactor chat function, change all content.*.name to content.*.key for consistency
This commit is contained in:
@@ -29,7 +29,7 @@
|
|||||||
"bootstrap": "v2.3.2",
|
"bootstrap": "v2.3.2",
|
||||||
"bootstrap-datepicker": "~1.2.0",
|
"bootstrap-datepicker": "~1.2.0",
|
||||||
"bootstrap-growl": "~1.1.0",
|
"bootstrap-growl": "~1.1.0",
|
||||||
"habitrpg-shared": "git://github.com/HabitRPG/habitrpg-shared.git#develop",
|
"habitrpg-shared": "git://github.com/HabitRPG/habitrpg-shared.git#bosses",
|
||||||
"BrowserQuest": "https://github.com/mozilla/BrowserQuest.git",
|
"BrowserQuest": "https://github.com/mozilla/BrowserQuest.git",
|
||||||
"github-buttons": "git://github.com/mdo/github-buttons.git",
|
"github-buttons": "git://github.com/mdo/github-buttons.git",
|
||||||
"marked": "~0.2.9",
|
"marked": "~0.2.9",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"version": "0.0.0-152",
|
"version": "0.0.0-152",
|
||||||
"main": "./src/server.js",
|
"main": "./src/server.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"habitrpg-shared": "git://github.com/HabitRPG/habitrpg-shared#develop",
|
"habitrpg-shared": "git://github.com/HabitRPG/habitrpg-shared#bosses",
|
||||||
"derby-auth": "git://github.com/lefnire/derby-auth#master",
|
"derby-auth": "git://github.com/lefnire/derby-auth#master",
|
||||||
"connect-mongo": "*",
|
"connect-mongo": "*",
|
||||||
"passport-facebook": "~1.0.0",
|
"passport-facebook": "~1.0.0",
|
||||||
|
|||||||
@@ -32,10 +32,10 @@ habitrpg.controller("InventoryCtrl", ['$rootScope', '$scope', 'User',
|
|||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
$scope.chooseEgg = function(egg){
|
$scope.chooseEgg = function(egg){
|
||||||
if ($scope.selectedEgg && $scope.selectedEgg.name == egg) {
|
if ($scope.selectedEgg && $scope.selectedEgg.key == egg) {
|
||||||
return $scope.selectedEgg = null; // clicked same egg, unselect
|
return $scope.selectedEgg = null; // clicked same egg, unselect
|
||||||
}
|
}
|
||||||
var eggData = _.findWhere(Content.eggs, {name:egg});
|
var eggData = _.findWhere(Content.eggs, {key:egg});
|
||||||
if (!$scope.selectedPotion) {
|
if (!$scope.selectedPotion) {
|
||||||
$scope.selectedEgg = eggData;
|
$scope.selectedEgg = eggData;
|
||||||
} else {
|
} else {
|
||||||
@@ -44,11 +44,11 @@ habitrpg.controller("InventoryCtrl", ['$rootScope', '$scope', 'User',
|
|||||||
}
|
}
|
||||||
|
|
||||||
$scope.choosePotion = function(potion){
|
$scope.choosePotion = function(potion){
|
||||||
if ($scope.selectedPotion && $scope.selectedPotion.name == potion) {
|
if ($scope.selectedPotion && $scope.selectedPotion.key == potion) {
|
||||||
return $scope.selectedPotion = null; // clicked same egg, unselect
|
return $scope.selectedPotion = null; // clicked same egg, unselect
|
||||||
}
|
}
|
||||||
// we really didn't think through the way these things are stored and getting passed around...
|
// we really didn't think through the way these things are stored and getting passed around...
|
||||||
var potionData = _.findWhere(Content.hatchingPotions, {name:potion});
|
var potionData = _.findWhere(Content.hatchingPotions, {key:potion});
|
||||||
if (!$scope.selectedEgg) {
|
if (!$scope.selectedEgg) {
|
||||||
$scope.selectedPotion = potionData;
|
$scope.selectedPotion = potionData;
|
||||||
} else {
|
} else {
|
||||||
@@ -57,7 +57,7 @@ habitrpg.controller("InventoryCtrl", ['$rootScope', '$scope', 'User',
|
|||||||
}
|
}
|
||||||
|
|
||||||
$scope.chooseFood = function(food){
|
$scope.chooseFood = function(food){
|
||||||
if ($scope.selectedFood && $scope.selectedFood.name == food) return $scope.selectedFood = null;
|
if ($scope.selectedFood && $scope.selectedFood.key == food) return $scope.selectedFood = null;
|
||||||
$scope.selectedFood = Content.food[food];
|
$scope.selectedFood = Content.food[food];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,8 +65,8 @@ habitrpg.controller("InventoryCtrl", ['$rootScope', '$scope', 'User',
|
|||||||
var selected = $scope.selectedEgg ? 'selectedEgg' : $scope.selectedPotion ? 'selectedPotion' : $scope.selectedFood ? 'selectedFood' : undefined;
|
var selected = $scope.selectedEgg ? 'selectedEgg' : $scope.selectedPotion ? 'selectedPotion' : $scope.selectedFood ? 'selectedFood' : undefined;
|
||||||
if (selected) {
|
if (selected) {
|
||||||
var type = $scope.selectedEgg ? 'eggs' : $scope.selectedPotion ? 'hatchingPotions' : $scope.selectedFood ? 'food' : undefined;
|
var type = $scope.selectedEgg ? 'eggs' : $scope.selectedPotion ? 'hatchingPotions' : $scope.selectedFood ? 'food' : undefined;
|
||||||
user.ops.sell({params:{type:type, key: $scope[selected].name}});
|
user.ops.sell({params:{type:type, key: $scope[selected].key}});
|
||||||
if (user.items[type][$scope[selected].name] < 1) {
|
if (user.items[type][$scope[selected].key] < 1) {
|
||||||
$scope[selected] = null;
|
$scope[selected] = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,8 +77,8 @@ habitrpg.controller("InventoryCtrl", ['$rootScope', '$scope', 'User',
|
|||||||
}
|
}
|
||||||
|
|
||||||
$scope.hatch = function(egg, potion){
|
$scope.hatch = function(egg, potion){
|
||||||
if (!confirm('Hatch a ' + potion.name + ' ' + egg.name + '?')) return;
|
if (!confirm('Hatch a ' + potion.key + ' ' + egg.key + '?')) return;
|
||||||
user.ops.hatch({params:{egg:egg.name, hatchingPotion:potion.name}});
|
user.ops.hatch({params:{egg:egg.key, hatchingPotion:potion.key}});
|
||||||
$scope.selectedEgg = null;
|
$scope.selectedEgg = null;
|
||||||
$scope.selectedPotion = null;
|
$scope.selectedPotion = null;
|
||||||
}
|
}
|
||||||
@@ -89,7 +89,7 @@ habitrpg.controller("InventoryCtrl", ['$rootScope', '$scope', 'User',
|
|||||||
var string = (type == 'hatchingPotion') ? 'hatching potion' : type; // give hatchingPotion a space
|
var string = (type == 'hatchingPotion') ? 'hatching potion' : type; // give hatchingPotion a space
|
||||||
var message = "Buy this " + string + " with " + item.value + " of your " + gems + " Gems?"
|
var message = "Buy this " + string + " with " + item.value + " of your " + gems + " Gems?"
|
||||||
if(confirm(message))
|
if(confirm(message))
|
||||||
User.user.ops.purchase({params:{type:type,key:item.name}});
|
User.user.ops.purchase({params:{type:type,key:item.key}});
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.choosePet = function(egg, potion){
|
$scope.choosePet = function(egg, potion){
|
||||||
@@ -98,12 +98,12 @@ habitrpg.controller("InventoryCtrl", ['$rootScope', '$scope', 'User',
|
|||||||
// Feeding Pet
|
// Feeding Pet
|
||||||
if ($scope.selectedFood) {
|
if ($scope.selectedFood) {
|
||||||
var food = $scope.selectedFood
|
var food = $scope.selectedFood
|
||||||
if (food.name == 'Saddle') {
|
if (food.key == 'Saddle') {
|
||||||
if (!confirm('Saddle ' + pet + '?')) return;
|
if (!confirm('Saddle ' + pet + '?')) return;
|
||||||
} else if (!confirm('Feed ' + pet + ' a ' + food.name + '?')) {
|
} else if (!confirm('Feed ' + pet + ' a ' + food.key + '?')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
User.user.ops.feed({params:{pet: pet, food: food.name}});
|
User.user.ops.feed({params:{pet: pet, food: food.key}});
|
||||||
$scope.selectedFood = null;
|
$scope.selectedFood = null;
|
||||||
|
|
||||||
// Selecting Pet
|
// Selecting Pet
|
||||||
@@ -125,7 +125,9 @@ habitrpg.controller("InventoryCtrl", ['$rootScope', '$scope', 'User',
|
|||||||
$rootScope.modals.showQuest = false;
|
$rootScope.modals.showQuest = false;
|
||||||
}
|
}
|
||||||
$scope.questInit = function(){
|
$scope.questInit = function(){
|
||||||
$rootScope.party.$questAccept({key:$scope.selectedQuest.name});
|
$rootScope.party.$questAccept({key:$scope.selectedQuest.key}, function(){
|
||||||
|
$rootScope.party.$get();
|
||||||
|
});
|
||||||
$scope.closeQuest();
|
$scope.closeQuest();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,10 +37,10 @@ habitrpg.controller('NotificationCtrl',
|
|||||||
var type = (after.type == 'Food') ? 'food' :
|
var type = (after.type == 'Food') ? 'food' :
|
||||||
(after.type == 'HatchingPotion') ? 'hatchingPotions' : // can we use camelcase and remove this line?
|
(after.type == 'HatchingPotion') ? 'hatchingPotions' : // can we use camelcase and remove this line?
|
||||||
(after.type.toLowerCase() + 's');
|
(after.type.toLowerCase() + 's');
|
||||||
if(!User.user.items[type][after.name]){
|
if(!User.user.items[type][after.key]){
|
||||||
User.user.items[type][after.name] = 0;
|
User.user.items[type][after.key] = 0;
|
||||||
}
|
}
|
||||||
User.user.items[type][after.name]++;
|
User.user.items[type][after.key]++;
|
||||||
$rootScope.modals.drop = true;
|
$rootScope.modals.drop = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$
|
|||||||
if ($scope.spell.target != type) return Notification.text("Invalid target");
|
if ($scope.spell.target != type) return Notification.text("Invalid target");
|
||||||
$scope.spell.cast(User.user, target);
|
$scope.spell.cast(User.user, target);
|
||||||
User.save();
|
User.save();
|
||||||
$http.post('/api/v2/user/class/cast/' + $scope.spell.name, {target:target, type:type}).success(function(){
|
$http.post('/api/v2/user/class/cast/' + $scope.spell.key, {target:target, type:type}).success(function(){
|
||||||
var msg = "You cast " + $scope.spell.text;
|
var msg = "You cast " + $scope.spell.text;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'task': msg += ' on ' + target.text;break;
|
case 'task': msg += ' on ' + target.text;break;
|
||||||
|
|||||||
@@ -215,30 +215,18 @@ api.attachGroupPopulated = function(req, res, next) {
|
|||||||
api.postChat = function(req, res, next) {
|
api.postChat = function(req, res, next) {
|
||||||
var user = res.locals.user
|
var user = res.locals.user
|
||||||
var group = res.locals.group;
|
var group = res.locals.group;
|
||||||
var message = {
|
|
||||||
id: shared.uuid(),
|
|
||||||
uuid: user._id,
|
|
||||||
contributor: user.contributor && user.contributor.toObject(),
|
|
||||||
backer: user.backer && user.backer.toObject(),
|
|
||||||
text: req.query.message, // FIXME this should be body, but ngResource is funky
|
|
||||||
user: user.profile.name,
|
|
||||||
timestamp: +(new Date)
|
|
||||||
};
|
|
||||||
|
|
||||||
var lastClientMsg = req.query.previousMsg;
|
var lastClientMsg = req.query.previousMsg;
|
||||||
var chatUpdated = (lastClientMsg && group.chat && group.chat[0] && group.chat[0].id !== lastClientMsg) ? true : false;
|
var chatUpdated = (lastClientMsg && group.chat && group.chat[0] && group.chat[0].id !== lastClientMsg) ? true : false;
|
||||||
|
|
||||||
group.chat.unshift(message);
|
group.sendChat(req.query.message, user); // FIXME this should be body, but ngResource is funky
|
||||||
group.chat.splice(200);
|
|
||||||
|
|
||||||
if (group.type === 'party') {
|
if (group.type === 'party') {
|
||||||
user.party.lastMessageSeen = message.id;
|
user.party.lastMessageSeen = group.chat[0].id;
|
||||||
user.save();
|
user.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
group.save(function(err, saved){
|
group.save(function(err, saved){
|
||||||
if (err) return res.json(500, {err:err});
|
if (err) return res.json(500, {err:err});
|
||||||
|
|
||||||
return chatUpdated ? res.json({chat: group.chat}) : res.json({message: saved.chat[0]});
|
return chatUpdated ? res.json({chat: group.chat}) : res.json({message: saved.chat[0]});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -431,20 +419,22 @@ questStart = function(req, res) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var parallel = [];
|
var parallel = [];
|
||||||
|
var key = group.quest.key;
|
||||||
// TODO will this handle appropriately when people leave/join party between quest invite?
|
// TODO will this handle appropriately when people leave/join party between quest invite?
|
||||||
_.each(group.members, function(m){
|
_.each(group.members, function(m){
|
||||||
if (m._id == user._id) m.items.quests[m.party.quest]--;
|
if (m._id == user._id) m.items.quests[key]--;
|
||||||
if (group.quest.members[m._id] == true) {
|
if (group.quest.members[m._id] == true) {
|
||||||
m.party.quest = group.quest.key;
|
m.party.quest.key = key;
|
||||||
} else {
|
} else {
|
||||||
m.party.quest = undefined;
|
_.merge(m.party.quest, {key:undefined,collection:{}});
|
||||||
delete group.quest.members[m._id];
|
delete group.quest.members[m._id];
|
||||||
}
|
}
|
||||||
|
m._v++;
|
||||||
parallel.push(function(cb2){m.save(cb2);});
|
parallel.push(function(cb2){m.save(cb2);});
|
||||||
})
|
})
|
||||||
|
|
||||||
group.quest.active = true;
|
group.quest.active = true;
|
||||||
group.quest.hp = shared.content.quests[group.quest.key].hp;
|
group.quest.progress.hp = shared.content.quests[group.quest.key].stats.hp;
|
||||||
parallel.push(function(cb2){group.save(cb2);});
|
parallel.push(function(cb2){group.save(cb2);});
|
||||||
|
|
||||||
async.parallel(parallel,function(err, results){
|
async.parallel(parallel,function(err, results){
|
||||||
@@ -502,5 +492,4 @@ api.questReject = function(req, res, next) {
|
|||||||
|
|
||||||
|
|
||||||
//TODO
|
//TODO
|
||||||
function questEnd(){}
|
|
||||||
function questAbort(){}
|
function questAbort(){}
|
||||||
|
|||||||
@@ -82,11 +82,11 @@ api.score = function(req, res, next) {
|
|||||||
task = user.ops.addTask({body:task});
|
task = user.ops.addTask({body:task});
|
||||||
}
|
}
|
||||||
var delta = user.ops.score({params:{id:task.id, direction:direction}});
|
var delta = user.ops.score({params:{id:task.id, direction:direction}});
|
||||||
//user.markModified('flags');
|
|
||||||
user.save(function(err,saved){
|
user.save(function(err,saved){
|
||||||
if (err) return res.json(500, {err: err});
|
if (err) return res.json(500, {err: err});
|
||||||
res.json(200, _.extend({
|
res.json(200, _.extend({
|
||||||
delta: delta
|
delta: delta,
|
||||||
}, saved.toJSON().stats));
|
}, saved.toJSON().stats));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -194,10 +194,43 @@ api.update = function(req, res, next) {
|
|||||||
|
|
||||||
api.cron = function(req, res, next) {
|
api.cron = function(req, res, next) {
|
||||||
var user = res.locals.user;
|
var user = res.locals.user;
|
||||||
user.fns.cron();
|
tally = user.fns.cron();
|
||||||
if (user.isModified())
|
if (user.isModified()) res.locals.wasModified = true;
|
||||||
res.locals.wasModified = true;
|
|
||||||
|
// If user is on a quest, roll for boss & player
|
||||||
|
if (user.party.quest.key && tally && (tally.up || tally.down)) {
|
||||||
|
async.waterfall([
|
||||||
|
function(cb){
|
||||||
|
Group.findOne({type: 'party', members: {'$in': [user._id]}})
|
||||||
|
.populate({
|
||||||
|
path: 'members',
|
||||||
|
match: {'party.quest.key':user.party.quest.key}
|
||||||
|
})
|
||||||
|
.exec(cb);
|
||||||
|
},
|
||||||
|
function(group, cb){
|
||||||
|
var quest = shared.content.quests[group.quest.key];
|
||||||
|
var down = tally.down * quest.stats.str; // multiply by boss strength
|
||||||
|
var parallel = [];
|
||||||
|
_.each(group.members, function(m){
|
||||||
|
parallel.push(function(cb2){
|
||||||
|
m.stats.hp += down;
|
||||||
|
m._v++;
|
||||||
|
m.save(cb2);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
// Use http://js2coffee.org/ for building this string. Man I wish JS had interpolation...
|
||||||
|
group.sendChat("`<" + user.profile.name + "> attacks <" + quest.name + "> for " + (tally.up.toFixed(1)) + " damage, <" + quest.name + "> attacks party for " + (tally.down.toFixed(1)) + " damage.`");
|
||||||
|
parallel.push(function(cb2){
|
||||||
|
group.hurtBoss(tally.up,cb2);
|
||||||
|
});
|
||||||
|
async.parallel(parallel,cb);
|
||||||
|
}
|
||||||
|
], next);
|
||||||
|
|
||||||
|
} else {
|
||||||
user.save(next);
|
user.save(next);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// api.reroll // Shared.ops
|
// api.reroll // Shared.ops
|
||||||
@@ -347,15 +380,8 @@ api.cast = function(req, res) {
|
|||||||
|
|
||||||
if (group) {
|
if (group) {
|
||||||
series.push(function(cb2){
|
series.push(function(cb2){
|
||||||
group.chat.unshift({
|
var message = '`<'+user.profile.name+'> casts '+spell.text + (type=='user' ? ' on @'+found.profile.name : ' for the party')+'.`';
|
||||||
id: shared.uuid(),
|
group.sendChat(message);
|
||||||
uuid: user._id,
|
|
||||||
contributor: user.contributor && user.contributor.toObject(),
|
|
||||||
backer: user.backer && user.backer.toObject(),
|
|
||||||
text: '`casts ' + spell.text + (type == 'user' ? ' on @'+found.profile.name : ' for the party') + '.`',
|
|
||||||
user: '<'+user.profile.name+'>',
|
|
||||||
timestamp: +new Date
|
|
||||||
});
|
|
||||||
group.save(cb2);
|
group.save(cb2);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ var mongoose = require("mongoose");
|
|||||||
var Schema = mongoose.Schema;
|
var Schema = mongoose.Schema;
|
||||||
var shared = require('habitrpg-shared');
|
var shared = require('habitrpg-shared');
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
|
var async = require('async');
|
||||||
|
|
||||||
var GroupSchema = new Schema({
|
var GroupSchema = new Schema({
|
||||||
_id: {type: String, 'default': shared.uuid},
|
_id: {type: String, 'default': shared.uuid},
|
||||||
@@ -33,14 +34,15 @@ var GroupSchema = new Schema({
|
|||||||
challenges: [{type:'String', ref:'Challenge'}], // do we need this? could depend on back-ref instead (Challenge.find({group:GID}))
|
challenges: [{type:'String', ref:'Challenge'}], // do we need this? could depend on back-ref instead (Challenge.find({group:GID}))
|
||||||
quest: {
|
quest: {
|
||||||
key: String,
|
key: String,
|
||||||
hp: Number,
|
|
||||||
active: {type:Boolean, 'default':false},
|
active: {type:Boolean, 'default':false},
|
||||||
|
progress:{
|
||||||
|
hp: Number,
|
||||||
|
collected: Schema.Types.Mixed,
|
||||||
|
},
|
||||||
|
|
||||||
/*
|
//Shows boolean for each party-member who has accepted the quest. Eg {UUID: true, UUID: false}. Once all users click
|
||||||
Shows boolean for each party-member who has accepted the quest. Eg {UUID: true, UUID: false}. Once all users click
|
//'Accept', the quest begins. If a false user waits too long, probably a good sign to prod them or boot them.
|
||||||
'Accept', the quest begins. If a false user waits too long, probably a good sign to prod them or boot them.
|
//TODO when booting user, remove from .joined and check again if we can now start the quest
|
||||||
TODO when booting user, remove from .joined and check again if we can now start the quest
|
|
||||||
*/
|
|
||||||
members: Schema.Types.Mixed
|
members: Schema.Types.Mixed
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
@@ -83,5 +85,88 @@ GroupSchema.methods.toJSON = function(){
|
|||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GroupSchema.methods.sendChat = function(message, user){
|
||||||
|
var group = this;
|
||||||
|
var message = {
|
||||||
|
id: shared.uuid(),
|
||||||
|
text: message,
|
||||||
|
timestamp: +(new Date)
|
||||||
|
};
|
||||||
|
if (user) {
|
||||||
|
_.defaults(message, {
|
||||||
|
uuid: user._id,
|
||||||
|
contributor: user.contributor && user.contributor.toObject(),
|
||||||
|
backer: user.backer && user.backer.toObject(),
|
||||||
|
user: user.profile.name,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
message.uuid = 'system';
|
||||||
|
}
|
||||||
|
group.chat.unshift(message);
|
||||||
|
group.chat.splice(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
GroupSchema.methods.hurtBoss = function(delta, cb) {
|
||||||
|
var group = this;
|
||||||
|
group.quest.progress.hp -= delta;
|
||||||
|
var hp = group.quest.progress.hp;
|
||||||
|
if (group.quest.progress.hp <= 0) {
|
||||||
|
var key = group.quest.key,
|
||||||
|
quest = shared.content.quests[key];
|
||||||
|
|
||||||
|
var parallel = _.reduce(group.members, function(m,v,k){
|
||||||
|
|
||||||
|
// Achievement
|
||||||
|
_.defaults(v.achievements, {quests:{}})
|
||||||
|
if (!v.achievements.quests[key]) v.achievements.quests[key] = 0;
|
||||||
|
v.achievements.quests[key]++;
|
||||||
|
v.markModified('achievements');
|
||||||
|
|
||||||
|
// Drops
|
||||||
|
v.stats.gp += +quest.drop.gp;
|
||||||
|
v.stats.exp += +quest.drop.exp;
|
||||||
|
switch (quest.drop.type) {
|
||||||
|
case 'gear':
|
||||||
|
// TODO This means they can lose their new gear on death, is that what we want?
|
||||||
|
v.items.gear.owned[quest.drop.key] = true;
|
||||||
|
break;
|
||||||
|
case 'eggs':
|
||||||
|
case 'food':
|
||||||
|
case 'hatchingPotions':
|
||||||
|
if (!v.items.hatchingPotions[quest.drop.key]) v.items.hatchingPotions[quest.drop.key] = 0;
|
||||||
|
v.items.hatchingPotions[quest.drop.key]++;
|
||||||
|
break;
|
||||||
|
case 'pets':
|
||||||
|
if (!v.items.pets[quest.drop.key]) v.items.pets[quest.drop.key] = 5;
|
||||||
|
break;
|
||||||
|
case 'mounts':
|
||||||
|
v.items.mounts[quest.drop.key] = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
v.party.quest.key = undefined;
|
||||||
|
v.party.quest.collection = {};
|
||||||
|
v.markModified('party.quest');
|
||||||
|
|
||||||
|
v._v++;
|
||||||
|
m.push(function(cb3){ v.save(cb3); })
|
||||||
|
return m;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Finish the quest
|
||||||
|
group.quest = {};group.markModified('quest');
|
||||||
|
group.sendChat('`' + quest.name + ' has been slain! Party has received their rewards`');
|
||||||
|
|
||||||
|
parallel.push(function(cb3){
|
||||||
|
group.save(cb3);
|
||||||
|
})
|
||||||
|
async.parallel(parallel,cb);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
group.save(cb);
|
||||||
|
}
|
||||||
|
return hp;
|
||||||
|
}
|
||||||
|
|
||||||
module.exports.schema = GroupSchema;
|
module.exports.schema = GroupSchema;
|
||||||
module.exports.model = mongoose.model("Group", GroupSchema);
|
module.exports.model = mongoose.model("Group", GroupSchema);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ var Challenge = require('./challenge').model;
|
|||||||
|
|
||||||
var eggPotionMapping = _.transform(shared.content.eggs, function(m, egg){
|
var eggPotionMapping = _.transform(shared.content.eggs, function(m, egg){
|
||||||
_.defaults(m, _.transform(shared.content.hatchingPotions, function(m2, pot){
|
_.defaults(m, _.transform(shared.content.hatchingPotions, function(m2, pot){
|
||||||
m2[egg.name + '-' + pot.name] = true;
|
m2[egg.key + '-' + pot.key] = true;
|
||||||
}));
|
}));
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -45,7 +45,8 @@ var UserSchema = new Schema({
|
|||||||
veteran: Boolean,
|
veteran: Boolean,
|
||||||
snowball: Number,
|
snowball: Number,
|
||||||
streak: Number,
|
streak: Number,
|
||||||
challenges: Array
|
challenges: Array,
|
||||||
|
quests: Schema.Types.Mixed
|
||||||
},
|
},
|
||||||
auth: {
|
auth: {
|
||||||
facebook: Schema.Types.Mixed,
|
facebook: Schema.Types.Mixed,
|
||||||
@@ -200,13 +201,17 @@ var UserSchema = new Schema({
|
|||||||
},
|
},
|
||||||
|
|
||||||
party: {
|
party: {
|
||||||
//party._id // FIXME make these populate docs?
|
// id // FIXME can we use a populated doc instead of fetching party separate from user?
|
||||||
current: String, // party._id
|
|
||||||
invitation: String, // party._id
|
|
||||||
lastMessageSeen: String,
|
lastMessageSeen: String,
|
||||||
leader: Boolean,
|
|
||||||
order: {type:String, 'default':'level'},
|
order: {type:String, 'default':'level'},
|
||||||
quest: String
|
quest: {
|
||||||
|
key: String,
|
||||||
|
tally: {
|
||||||
|
up: {type: Number, 'default': 0},
|
||||||
|
down: {type: Number, 'default': 0},
|
||||||
|
collection: {type: Schema.Types.Mixed, 'default': {}} // {feather:1, ingot:2}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
preferences: {
|
preferences: {
|
||||||
armorSet: String,
|
armorSet: String,
|
||||||
@@ -250,13 +255,13 @@ var UserSchema = new Schema({
|
|||||||
int: {type: Number, 'default': 0},
|
int: {type: Number, 'default': 0},
|
||||||
per: {type: Number, 'default': 0},
|
per: {type: Number, 'default': 0},
|
||||||
buffs: {
|
buffs: {
|
||||||
str: Number,
|
str: {type: Number, 'default': 0},
|
||||||
def: Number,
|
def: {type: Number, 'default': 0},
|
||||||
per: Number,
|
per: {type: Number, 'default': 0},
|
||||||
con: Number,
|
con: {type: Number, 'default': 0},
|
||||||
stealth: Number,
|
stealth: {type: Number, 'default': 0},
|
||||||
streaks: Boolean,
|
streaks: {type: Boolean, 'default': false},
|
||||||
snowball: Boolean
|
snowball: {type: Boolean, 'default': false}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
tags: [
|
tags: [
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ script(type='text/ng-template', id='partials/options.inventory.drops.html')
|
|||||||
p(ng-show='eggCount < 1') You don't have any eggs.
|
p(ng-show='eggCount < 1') You don't have any eggs.
|
||||||
div(ng-repeat='(egg,points) in ownedItems(user.items.eggs)')
|
div(ng-repeat='(egg,points) in ownedItems(user.items.eggs)')
|
||||||
//TODO move positioning this styling to css
|
//TODO move positioning this styling to css
|
||||||
button.customize-option(popover='{{Content.eggs[egg].notes}}', popover-title='{{Content.eggs[egg].text}} Egg', popover-trigger='mouseenter', popover-placement='right', ng-click='chooseEgg(egg)', class='Pet_Egg_{{egg}}', ng-class='{selectableInventory: selectedPotion && !user.items.pets[egg+"-"+selectedPotion.name]}')
|
button.customize-option(popover='{{Content.eggs[egg].notes}}', popover-title='{{Content.eggs[egg].text}} Egg', popover-trigger='mouseenter', popover-placement='right', ng-click='chooseEgg(egg)', class='Pet_Egg_{{egg}}', ng-class='{selectableInventory: selectedPotion && !user.items.pets[egg+"-"+selectedPotion.key]}')
|
||||||
.badge.badge-info.stack-count {{points}}
|
.badge.badge-info.stack-count {{points}}
|
||||||
//-p {{Content.eggs[egg].text}}
|
//-p {{Content.eggs[egg].text}}
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ script(type='text/ng-template', id='partials/options.inventory.drops.html')
|
|||||||
menu.hatchingPotion-menu(label='Hatching Potions ({{potCount}})')
|
menu.hatchingPotion-menu(label='Hatching Potions ({{potCount}})')
|
||||||
p(ng-show='potCount < 1') You don't have any hatching potions.
|
p(ng-show='potCount < 1') You don't have any hatching potions.
|
||||||
div(ng-repeat='(pot,points) in ownedItems(user.items.hatchingPotions)')
|
div(ng-repeat='(pot,points) in ownedItems(user.items.hatchingPotions)')
|
||||||
button.customize-option(popover='{{Content.hatchingPotions[pot].notes}}', popover-title='{{Content.hatchingPotions[pot].text}} Potion', popover-trigger='mouseenter', popover-placement='right', ng-click='choosePotion(pot)', class='Pet_HatchingPotion_{{pot}}', ng-class='{selectableInventory: selectedEgg && !user.items.pets[selectedEgg.name+"-"+pot]}')
|
button.customize-option(popover='{{Content.hatchingPotions[pot].notes}}', popover-title='{{Content.hatchingPotions[pot].text}} Potion', popover-trigger='mouseenter', popover-placement='right', ng-click='choosePotion(pot)', class='Pet_HatchingPotion_{{pot}}', ng-class='{selectableInventory: selectedEgg && !user.items.pets[selectedEgg.key+"-"+pot]}')
|
||||||
.badge.badge-info.stack-count {{points}}
|
.badge.badge-info.stack-count {{points}}
|
||||||
|
|
||||||
li.customize-menu
|
li.customize-menu
|
||||||
@@ -79,17 +79,17 @@ script(type='text/ng-template', id='partials/options.inventory.drops.html')
|
|||||||
| Welcome to the Market! Buy hard-to-find eggs and potions! Sell your extras! Commission useful services! Come see what we have to offer.
|
| Welcome to the Market! Buy hard-to-find eggs and potions! Sell your extras! Commission useful services! Come see what we have to offer.
|
||||||
p
|
p
|
||||||
button.btn.btn-primary(ng-show='selectedEgg', ng-click='sellInventory()')
|
button.btn.btn-primary(ng-show='selectedEgg', ng-click='sellInventory()')
|
||||||
| Sell {{selectedEgg.name}} for {{selectedEgg.value}} Gold
|
| Sell {{selectedEgg.key}} for {{selectedEgg.value}} Gold
|
||||||
button.btn.btn-primary(ng-show='selectedPotion', ng-click='sellInventory()')
|
button.btn.btn-primary(ng-show='selectedPotion', ng-click='sellInventory()')
|
||||||
| Sell {{selectedPotion.name}} for {{selectedPotion.value}} Gold
|
| Sell {{selectedPotion.key}} for {{selectedPotion.value}} Gold
|
||||||
button.btn.btn-primary(ng-show='selectedFood', ng-click='sellInventory()')
|
button.btn.btn-primary(ng-show='selectedFood', ng-click='sellInventory()')
|
||||||
| Sell {{selectedFood.name}} for {{selectedFood.value}} Gold
|
| Sell {{selectedFood.key}} for {{selectedFood.value}} Gold
|
||||||
|
|
||||||
menu.inventory-list(type='list')
|
menu.inventory-list(type='list')
|
||||||
li.customize-menu
|
li.customize-menu
|
||||||
menu.pets-menu(label='Eggs')
|
menu.pets-menu(label='Eggs')
|
||||||
div(ng-repeat='egg in Content.eggs')
|
div(ng-repeat='egg in Content.eggs')
|
||||||
button.customize-option(popover='{{egg.notes}}', popover-title='{{egg.text}} Egg', popover-trigger='mouseenter', popover-placement='left', ng-click='purchase("eggs", egg)', class='Pet_Egg_{{egg.name}}')
|
button.customize-option(popover='{{egg.notes}}', popover-title='{{egg.text}} Egg', popover-trigger='mouseenter', popover-placement='left', ng-click='purchase("eggs", egg)', class='Pet_Egg_{{egg.key}}')
|
||||||
p
|
p
|
||||||
| {{egg.value}}
|
| {{egg.value}}
|
||||||
span.Pet_Currency_Gem1x.inline-gems
|
span.Pet_Currency_Gem1x.inline-gems
|
||||||
@@ -97,15 +97,15 @@ script(type='text/ng-template', id='partials/options.inventory.drops.html')
|
|||||||
li.customize-menu
|
li.customize-menu
|
||||||
menu.pets-menu(label='Hatching Potions')
|
menu.pets-menu(label='Hatching Potions')
|
||||||
div(ng-repeat='pot in Content.hatchingPotions')
|
div(ng-repeat='pot in Content.hatchingPotions')
|
||||||
button.customize-option(popover='{{pot.notes}}', popover-title='{{pot.text}} Potion', popover-trigger='mouseenter', popover-placement='left', ng-click='purchase("hatchingPotions", pot)', class='Pet_HatchingPotion_{{pot.name}}')
|
button.customize-option(popover='{{pot.notes}}', popover-title='{{pot.text}} Potion', popover-trigger='mouseenter', popover-placement='left', ng-click='purchase("hatchingPotions", pot)', class='Pet_HatchingPotion_{{pot.key}}')
|
||||||
p
|
p
|
||||||
| {{pot.value}}
|
| {{pot.value}}
|
||||||
span.Pet_Currency_Gem1x.inline-gems
|
span.Pet_Currency_Gem1x.inline-gems
|
||||||
|
|
||||||
li.customize-menu
|
li.customize-menu
|
||||||
menu.pets-menu(label='Food')
|
menu.pets-menu(label='Food')
|
||||||
div(ng-repeat='food in Content.food', ng-show='food.name !== "Saddle"')
|
div(ng-repeat='food in Content.food', ng-show='food.key !== "Saddle"')
|
||||||
button.customize-option(popover='{{food.notes}}', popover-title='{{food.text}}', popover-trigger='mouseenter', popover-placement='left', ng-click='purchase("food", food)', class='Pet_Food_{{food.name}}')
|
button.customize-option(popover='{{food.notes}}', popover-title='{{food.text}}', popover-trigger='mouseenter', popover-placement='left', ng-click='purchase("food", food)', class='Pet_Food_{{food.key}}')
|
||||||
p
|
p
|
||||||
| {{food.value}}
|
| {{food.value}}
|
||||||
span.Pet_Currency_Gem1x.inline-gems
|
span.Pet_Currency_Gem1x.inline-gems
|
||||||
@@ -121,7 +121,7 @@ script(type='text/ng-template', id='partials/options.inventory.drops.html')
|
|||||||
li.customize-menu
|
li.customize-menu
|
||||||
menu.pets-menu(label='Special')
|
menu.pets-menu(label='Special')
|
||||||
div
|
div
|
||||||
button.customize-option(popover='{{Content.food.Saddle.notes}}', popover-title='{{Content.food.Saddle.text}}', popover-trigger='mouseenter', popover-placement='left', ng-click='purchase("food", Content.food.Saddle)', class='Pet_Food_{{Content.food.Saddle.name}}')
|
button.customize-option(popover='{{Content.food.Saddle.notes}}', popover-title='{{Content.food.Saddle.text}}', popover-trigger='mouseenter', popover-placement='left', ng-click='purchase("food", Content.food.Saddle)', class='Pet_Food_{{Content.food.Saddle.key}}')
|
||||||
p
|
p
|
||||||
| {{Content.food.Saddle.value}}
|
| {{Content.food.Saddle.value}}
|
||||||
span.Pet_Currency_Gem1x.inline-gems
|
span.Pet_Currency_Gem1x.inline-gems
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ script(type='text/ng-template', id='partials/options.inventory.mounts.html')
|
|||||||
menu.pets(type='list')
|
menu.pets(type='list')
|
||||||
li.customize-menu(ng-repeat='egg in Content.eggs')
|
li.customize-menu(ng-repeat='egg in Content.eggs')
|
||||||
menu
|
menu
|
||||||
div(ng-repeat='potion in Content.hatchingPotions', popover-trigger='mouseenter', popover='{{potion.text}} {{egg.mountText}}', popover-placement='bottom', ng-init='mount = egg.name+"-"+potion.name')
|
div(ng-repeat='potion in Content.hatchingPotions', popover-trigger='mouseenter', popover='{{potion.text}} {{egg.mountText}}', popover-placement='bottom', ng-init='mount = egg.key+"-"+potion.key')
|
||||||
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)')
|
button(class="pet-button Mount_Head_{{mount}}", ng-show='user.items.mounts[mount]', ng-class='{active: user.items.currentMount == mount}', ng-click='chooseMount(egg.key, potion.key)')
|
||||||
//div(class='Mount_Head_{{mount}}')
|
//div(class='Mount_Head_{{mount}}')
|
||||||
button(class="pet-button pet-not-owned", ng-hide='user.items.mounts[mount]')
|
button(class="pet-button pet-not-owned", ng-hide='user.items.mounts[mount]')
|
||||||
.PixelPaw
|
.PixelPaw
|
||||||
@@ -49,8 +49,8 @@ script(type='text/ng-template', id='partials/options.inventory.pets.html')
|
|||||||
menu.pets(type='list')
|
menu.pets(type='list')
|
||||||
li.customize-menu(ng-repeat='egg in Content.eggs')
|
li.customize-menu(ng-repeat='egg in Content.eggs')
|
||||||
menu
|
menu
|
||||||
div(ng-repeat='potion in Content.hatchingPotions', popover-trigger='mouseenter', popover='{{potion.text}} {{egg.text}}', popover-placement='bottom', ng-init='pet = egg.name+"-"+potion.name')
|
div(ng-repeat='potion in Content.hatchingPotions', popover-trigger='mouseenter', popover='{{potion.text}} {{egg.text}}', popover-placement='bottom', ng-init='pet = egg.key+"-"+potion.key')
|
||||||
button(class="pet-button Pet-{{pet}}", ng-if='user.items.pets[pet]>0', ng-class='{active: user.items.currentPet == pet, selectableInventory: selectedFood}', ng-click='choosePet(egg.name, potion.name)')
|
button(class="pet-button Pet-{{pet}}", ng-if='user.items.pets[pet]>0', ng-class='{active: user.items.currentPet == pet, selectableInventory: selectedFood}', ng-click='choosePet(egg.key, potion.key)')
|
||||||
.progress(ng-class='{"progress-success": user.items.pets[pet]<50}')
|
.progress(ng-class='{"progress-success": user.items.pets[pet]<50}')
|
||||||
.bar(style="width: {{user.items.pets[pet]/.5}}%;")
|
.bar(style="width: {{user.items.pets[pet]/.5}}%;")
|
||||||
button(class="pet-button pet-not-owned", ng-if='!user.items.pets[pet]')
|
button(class="pet-button pet-not-owned", ng-if='!user.items.pets[pet]')
|
||||||
@@ -61,8 +61,9 @@ script(type='text/ng-template', id='partials/options.inventory.pets.html')
|
|||||||
div
|
div
|
||||||
button(ng-if='user.items.pets["Wolf-Veteran"]', class="pet-button Pet-Wolf-Veteran", ng-class='{active: user.items.currentPet == "Wolf-Veteran"}', ng-click='choosePet("Wolf", "Veteran")', popover='Veteran Wolf', popover-trigger='mouseenter', popover-placement='bottom')
|
button(ng-if='user.items.pets["Wolf-Veteran"]', class="pet-button Pet-Wolf-Veteran", ng-class='{active: user.items.currentPet == "Wolf-Veteran"}', ng-click='choosePet("Wolf", "Veteran")', popover='Veteran Wolf', popover-trigger='mouseenter', popover-placement='bottom')
|
||||||
button(ng-if='user.items.pets["Wolf-Cerberus"]', class="pet-button Pet-Wolf-Cerberus", ng-class='{active: user.items.currentPet == "Wolf-Cerberus"}', ng-click='choosePet("Wolf", "Cerberus")', popover='Cerberus Pup', popover-trigger='mouseenter', popover-placement='bottom')
|
button(ng-if='user.items.pets["Wolf-Cerberus"]', class="pet-button Pet-Wolf-Cerberus", ng-class='{active: user.items.currentPet == "Wolf-Cerberus"}', ng-click='choosePet("Wolf", "Cerberus")', popover='Cerberus Pup', popover-trigger='mouseenter', popover-placement='bottom')
|
||||||
button(ng-if='user.items.pets["Dragon-Hydra"]', class="pet-button Pet-Dragon-Hydra", ng-class='{active: user.items.currentPet == "Dragon-Hydra"}', ng-click='choosePet("Dragon", "Hydra")', popover='Hydra', popover-trigger='mouseenter', popover-placement='bottom')
|
|
||||||
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')
|
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')
|
||||||
|
button(ng-if='user.items.pets["BearCub-Polar"]', class="pet-button Pet-BearCub-Polar", ng-class='{active: user.items.currentPet == "BearCub-Polar"}', ng-click='choosePet("BearCub", "Polar")', popover='Polar Bear Cub', popover-trigger='mouseenter', popover-placement='bottom')
|
||||||
|
button(ng-if='user.items.pets["Dragon-Hydra"]', class="pet-button Pet-Dragon-Hydra", ng-class='{active: user.items.currentPet == "Dragon-Hydra"}', ng-click='choosePet("Dragon", "Hydra")', popover='Hydra', popover-trigger='mouseenter', popover-placement='bottom')
|
||||||
a(target='_blank', href='http://habitrpg.wikia.com/wiki/Contributing_to_HabitRPG')
|
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!')
|
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!')
|
||||||
.PixelPaw-Gold
|
.PixelPaw-Gold
|
||||||
|
|||||||
@@ -14,5 +14,3 @@ form.chat-form(ng-submit='postChat(group,message.content)')
|
|||||||
td
|
td
|
||||||
button.btn(type="button", ng-click='sync(group)', tooltip='Fetch Recent Messages')
|
button.btn(type="button", ng-click='sync(group)', tooltip='Fetch Recent Messages')
|
||||||
i(class='pull-right icon-refresh')
|
i(class='pull-right icon-refresh')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,5 +9,5 @@ li(bindonce='group.chat', ng-repeat='message in group.chat', bo-class='{highligh
|
|||||||
a(bo-show='user.contributor.admin || message.uuid == user.id', ng-click='deleteChatMessage(group, message)')
|
a(bo-show='user.contributor.admin || message.uuid == user.id', ng-click='deleteChatMessage(group, message)')
|
||||||
|
|
|
|
||||||
i.icon-remove(tooltip='Delete')
|
i.icon-remove(tooltip='Delete')
|
||||||
a.label.chat-message(class='float-label', bo-class='{"label-npc": message.backer.npc, "label-contributor-{{message.contributor.level}}":message.contributor.level}', ng-click='clickMember(message.uuid, true)')
|
a.label.chat-message(bo-show='message.user', class='float-label', bo-class='{"label-npc": message.backer.npc, "label-contributor-{{message.contributor.level}}":message.contributor.level}', ng-click='clickMember(message.uuid, true)')
|
||||||
span(tooltip='{{contribText(message.contributor, message.backer)}}') {{message.user}}
|
span(tooltip='{{contribText(message.contributor, message.backer)}}') {{message.user}}
|
||||||
@@ -31,10 +31,10 @@ a.pull-right.gem-wallet(popover-trigger='mouseenter', popover-title='Guild Bank'
|
|||||||
| {{group.quest.hp | number:0}} / {{Content.quests[group.quest.key].hp}}
|
| {{group.quest.hp | number:0}} / {{Content.quests[group.quest.key].hp}}
|
||||||
.hero-stats
|
.hero-stats
|
||||||
.meter.health(title='Boss Health')
|
.meter.health(title='Boss Health')
|
||||||
.bar(style='width: {{Shared.percent(group.quest.hp, Content.quests[group.quest.key].hp)}}%;')
|
.bar(style='width: {{Shared.percent(group.quest.progress.hp, Content.quests[group.quest.key].stats.hp)}}%;')
|
||||||
span.meter-text
|
span.meter-text
|
||||||
i.icon-heart
|
i.icon-heart
|
||||||
| {{group.quest.hp | number:0}} / {{Content.quests[group.quest.key].hp}}
|
| {{group.quest.progress.hp | number:0}} / {{Content.quests[group.quest.key].stats.hp}}
|
||||||
p {{Content.quests[group.quest.key].notes}}
|
p {{Content.quests[group.quest.key].notes}}
|
||||||
|
|
||||||
// ------ Information -------
|
// ------ Information -------
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ div(modal='modals.dropsEnabled')
|
|||||||
h3 Drops Enabled!
|
h3 Drops Enabled!
|
||||||
.modal-body
|
.modal-body
|
||||||
//-p // TODO how to handle random first drop?
|
//-p // TODO how to handle random first drop?
|
||||||
span.item-drop-icon(class='Pet_Egg_{{user.items.eggs.0.name}}', style='margin-left: 0px')
|
span.item-drop-icon(class='Pet_Egg_{{user.items.eggs.0.key}}', style='margin-left: 0px')
|
||||||
| You've unlocked the Drop System! Now when you complete tasks, you have a small chance of finding an item. You just found a
|
| You've unlocked the Drop System! Now when you complete tasks, you have a small chance of finding an item. You just found a
|
||||||
strong {{user.items.eggs.0.text}} Egg
|
strong {{user.items.eggs.0.text}} Egg
|
||||||
| ! {{user.items.eggs.0.notes}}.
|
| ! {{user.items.eggs.0.notes}}.
|
||||||
@@ -22,7 +22,7 @@ div(modal='modals.drop')
|
|||||||
h3 An item has dropped!
|
h3 An item has dropped!
|
||||||
.modal-body
|
.modal-body
|
||||||
p
|
p
|
||||||
span.item-drop-icon(class='Pet_{{user._tmp.drop.type}}_{{user._tmp.drop.name}}')
|
span.item-drop-icon(class='Pet_{{user._tmp.drop.type}}_{{user._tmp.drop.key}}')
|
||||||
| {{user._tmp.drop.dialog}}
|
| {{user._tmp.drop.dialog}}
|
||||||
.modal-footer
|
.modal-footer
|
||||||
button.btn.btn-default.cancel(ng-click='modals.drop = false') Close
|
button.btn.btn-default.cancel(ng-click='modals.drop = false') Close
|
||||||
@@ -6,8 +6,18 @@ div(modal='modals.showQuest', ng-controller='InventoryCtrl')
|
|||||||
tr
|
tr
|
||||||
td
|
td
|
||||||
p {{selectedQuest.notes}}
|
p {{selectedQuest.notes}}
|
||||||
|
br
|
||||||
|
.well
|
||||||
|
h5 Rewards
|
||||||
|
table.table.table-striped
|
||||||
|
tr
|
||||||
|
td {{selectedQuest.drop.text}}
|
||||||
|
tr
|
||||||
|
td {{selectedQuest.drop.exp}} Experience
|
||||||
|
tr
|
||||||
|
td {{selectedQuest.drop.gp}} Gold
|
||||||
td
|
td
|
||||||
div(class='quest_{{selectedQuest.name}}')
|
div(class='quest_{{selectedQuest.key}}')
|
||||||
hr
|
hr
|
||||||
div(style='clear:left;clear:right')
|
div(style='clear:left;clear:right')
|
||||||
.npc_ian.pull-left
|
.npc_ian.pull-left
|
||||||
@@ -18,10 +28,21 @@ div(modal='modals.showQuest', ng-controller='InventoryCtrl')
|
|||||||
|
|
||||||
div(modal='party.quest.key && !questHold && party.quest.members[user._id] == undefined')
|
div(modal='party.quest.key && !questHold && party.quest.members[user._id] == undefined')
|
||||||
.modal-header
|
.modal-header
|
||||||
h3 Quest Invitation
|
h3 Quest Invitation: {{Content.quests[party.quest.key].text}}
|
||||||
.modal-body
|
.modal-body
|
||||||
p You have been invited to {{Content.quests[party.quest.key].text}}!
|
p You have been invited to "{{Content.quests[party.quest.key].text}}"!
|
||||||
p (TODO list rewards)
|
br
|
||||||
|
p {{Content.quests[party.quest.key].notes}}
|
||||||
|
br
|
||||||
|
.well
|
||||||
|
h5 Rewards
|
||||||
|
table.table.table-striped
|
||||||
|
tr
|
||||||
|
td {{Content.quests[party.quest.key].drop.text}}
|
||||||
|
tr
|
||||||
|
td {{Content.quests[party.quest.key].drop.exp}} Experience
|
||||||
|
tr
|
||||||
|
td {{Content.quests[party.quest.key].drop.gp}} Gold
|
||||||
.modal-footer
|
.modal-footer
|
||||||
button.btn.btn-default.btn-small.btn-cancel(ng-click='questHold = true') Ask Later
|
button.btn.btn-default.btn-small.btn-cancel(ng-click='questHold = true') Ask Later
|
||||||
button.btn.btn-default.btn-small.btn-cancel(ng-click='party.$questReject()') Reject
|
button.btn.btn-default.btn-small.btn-cancel(ng-click='party.$questReject()') Reject
|
||||||
|
|||||||
Reference in New Issue
Block a user