Stripped all derby related code.

Added require.js wrapper.
Alogos is still BROKEN. I'm deploying them here for testing.
This commit is contained in:
yangit
2013-05-15 12:51:21 +08:00
parent 26086d2f32
commit 8897cc338a
7 changed files with 528 additions and 2308 deletions
+4 -3
View File
@@ -4,11 +4,12 @@ Shared resources useful for the multiple HabitRPG repositories, that way all the
* Algorithms - level up algorithm, scoring functions, etc
* Item definitions - weapons, armor, pets
Note: We can't load CommonJS format into the browser. There's a way to pull it in with RequireJS (r.js?), but I couldn't get that working. Instead I created a `Makefile` which runs Browserify to compile `index-browser.js`, which you include in a `<script/>` tag in your index.html. Let's fix this sometime.
##Installation
* `npm install`
* `make`
* Node.js - just include files as usual.
* Browser - user requre.js with "cs" plugin to include files directly into your index.html
#TODO add and example of require.js config.
##CSS
Shared CSS between the website and the mobile app is a fuzzy area. For now we'll have the website define canonical CSS, and share that down the mobile app.
+378
View File
@@ -0,0 +1,378 @@
({ define: (
if typeof define == "function"
define
else
(F)->
F(require, exports, module)
)}).define (require, exports, module)->
XP = 15
HP = 2
obj = module.exports =
{};
obj.priorityValue = (priority = '!') ->
switch priority
when '!' then 1
when '!!' then 1.5
when '!!!' then 2
else
1
obj.tnl = (level) ->
if level >= 100
value = 0
else
value = Math.round(((Math.pow(level, 2) * 0.25) + (10 * level) + 139.75) / 10) * 10
# round to nearest 10
return value
###
Calculates Exp modificaiton based on level and weapon strength
{value} task.value for exp gain
{weaponStrength) weapon strength
{level} current user level
{priority} user-defined priority multiplier
###
obj.expModifier = (value, weaponStr, level, priority = '!') ->
str = (level - 1) / 2
# ultimately get this from user
totalStr = (str + weaponStr) / 100
strMod = 1 + totalStr
exp = value * XP * strMod * obj.priorityValue(priority)
return Math.round(exp)
###
Calculates HP modification based on level and armor defence
{value} task.value for hp loss
{armorDefense} defense from armor
{helmDefense} defense from helm
{level} current user level
{priority} user-defined priority multiplier
###
obj.hpModifier = (value, armorDef, helmDef, shieldDef, level, priority = '!') ->
def = (level - 1) / 2
# ultimately get this from user?
totalDef = (def + armorDef + helmDef + shieldDef) / 100
#ultimate get this from user
defMod = 1 - totalDef
hp = value * HP * defMod * obj.priorityValue(priority)
return Math.round(hp * 10) / 10
# round to 1dp
###
Future use
{priority} user-defined priority multiplier
###
obj.gpModifier = (value, modifier, priority = '!', streak, user) ->
val = value * modifier * obj.priorityValue(priority)
if streak and user
streakBonus = streak / 100 + 1
# eg, 1-day streak is 1.1, 2-day is 1.2, etc
afterStreak = val * streakBonus
user.streakBonus = afterStreak - val if (val > 0)
# can we do this without model? just global emit?
return afterStreak
else
return val
###
Calculates the next task.value based on direction
Uses a capped inverse log y=.95^x, y>= -5
{currentValue} the current value of the task
{direction} up or down
###
obj.taskDeltaFormula = (currentValue, direction) ->
if currentValue < -47.27 then currentValue = -47.27
else if currentValue > 21.27 then currentValue = 21.27
delta = Math.pow(0.9747, currentValue)
return delta if direction is 'up'
return -delta
###
Drop System
###
randomDrop = (user, delta, priority, streak = 0) ->
# limit drops to 2 / day
if !user.items.lastDrop?
user.items =
{
date: +moment().subtract('d', 1) # trick - set it to yesterday on first run, that way they can get drops today
count: 0
}
reachedDropLimit = (helpers.daysBetween(user.items.lastDrop.date,
+new Date) is 0) and user.items.lastDrop.count >= 2
return if reachedDropLimit
# % chance of getting a pet or meat
chanceMultiplier = Math.abs(delta)
chanceMultiplier *= obj.priorityValue(priority)
# multiply chance by reddness
chanceMultiplier += streak
# streak bonus
console.log chanceMultiplier
if user.flags.dropsEnabled and Math.random() < (.05 * chanceMultiplier)
# current breakdown - 3% (adjustable) chance on drop
# If they got a drop: 50% chance of egg, 50% Hatching Potion. If hatchingPotion, broken down further even further
rarity = Math.random()
# Egg, 40% chance
if rarity > .6
drop = randomVal(pets)
user.items.eggs.push drop
drop.type = 'Egg'
drop.dialog = "You've found a #{drop.text} Egg! #{drop.notes}"
# Hatching Potion, 60% chance - break down by rarity even more. FIXME this may not be the best method, so revisit
else
acceptableDrops = []
# Tier 5 (Blue Moon Rare)
if rarity < .1
acceptableDrops =
['Base', 'White', 'Desert', 'Red', 'Shade', 'Skeleton', 'Zombie', 'CottonCandyPink', 'CottonCandyBlue',
'Golden']
# Tier 4 (Very Rare)
else if rarity < .2
acceptableDrops =
['Base', 'White', 'Desert', 'Red', 'Shade', 'Skeleton', 'Zombie', 'CottonCandyPink', 'CottonCandyBlue']
# Tier 3 (Rare)
else if rarity < .3
acceptableDrops = ['Base', 'White', 'Desert', 'Red', 'Shade', 'Skeleton']
# Tier 2 (Scarce)
else if rarity < .4
acceptableDrops = ['Base', 'White', 'Desert']
# Tier 1 (Common)
else
acceptableDrops = ['Base']
acceptableDrops = hatchingPotions.filter (hatchingPotion) ->
hatchingPotion.name in acceptableDrops
drop = randomVal acceptableDrops
user.items.hatchingPotions.push drop.name
drop.type = 'HatchingPotion'
drop.dialog = "You've found a #{drop.text} Hatching Potion! #{drop.notes}"
user.drop = drop
user.items.lastDrop.date = +new Date
user.items.lastDrop.count++
# {task} task you want to score
# {direction} 'up' or 'down'
obj.score = (user, task, direction, items) ->
{gp, hp, exp, lvl} = user.stats
{type, value, streak} = task
priority = task.priority or '!'
# If they're trying to purhcase a too-expensive reward, confirm they want to take a hit for it
if task.value > user.stats.gp and task.type is 'reward'
r = confirm "Not enough GP to purchase this reward, buy anyway and lose HP? (Punishment for taking a reward you didn't earn)."
unless r
#TODO if this rule is working OK.
return
delta = 0
calculateDelta = (adjustvalue = true) ->
# Each iteration calculate the delta (nextDelta), which is then accumulated in delta
# (aka, the total delta). This weirdness won't be necessary when calculating mathematically
# rather than iteratively
nextDelta = obj.taskDeltaFormula(value, direction)
value += nextDelta if adjustvalue
delta += nextDelta
addPoints = ->
level = user.stats.lvl
weaponStrength = items.items.weapon[user.items.weapon].strength
exp += obj.expModifier(delta, weaponStrength, level, priority) / 2
# / 2 hack for now bcause people leveling too fast
if streak
gp += obj.gpModifier(delta, 1, priority, streak, user)
else
gp += obj.gpModifier(delta, 1, priority)
subtractPoints = ->
level = user.stats.lvl
armorDefense = items.items.armor[user.items.armor].defense
helmDefense = items.items.head[user.items.head].defense
shieldDefense = items.items.shield[user.items.shield].defense
hp += obj.hpModifier(delta, armorDefense, helmDefense, shieldDefense, level, priority)
switch type
when 'habit'
calculateDelta()
# Add habit value to habit-history (if different)
if (delta > 0) then addPoints() else subtractPoints()
task.history ?= []
if task.value != value
historyEntry = { date: +new Date, value: value }
task.history.push historyEntry
when 'daily'
calculateDelta(false)
if delta != 0
addPoints()
# obviously for delta>0, but also a trick to undo accidental checkboxes
if direction is 'up'
streak = if streak then streak + 1 else 1
else
streak = if streak then streak - 1 else 0
task.streak = streak
when 'todo'
calculateDelta()
addPoints() # obviously for delta>0, but also a trick to undo accidental checkboxes
when 'reward'
# Don't adjust values for rewards
calculateDelta(false)
# purchase item
gp -= Math.abs(task.value)
num = parseFloat(task.value).toFixed(2)
# if too expensive, reduce health & zero gp
if gp < 0
hp += gp
# hp - gp difference
gp = 0
task.value = value
updateStats user, { hp, exp, gp }
# Drop system
# randomDrop(user, delta, priority, streak) if direction is 'up'
return delta
###
Updates user stats with new stats. Handles death, leveling up, etc
{stats} new stats
{update} if aggregated changes, pass in userObj as update. otherwise commits will be made immediately
###
updateStats = (user, newStats) ->
# if user is dead, dont do anything
return if user.stats.hp <= 0
if newStats.hp?
# Game Over
if newStats.hp <= 0
user.stats.hp = 0
# signifies dead
return
else
user.stats.hp = newStats.hp
if newStats.exp?
tnl = obj.tnl(user.stats.lvl)
#silent = false
# if we're at level 100, turn xp to gold
if user.stats.lvl >= 100
newStats.gp += newStats.exp / 15
newStats.exp = 0
user.stats.lvl = 100
else
# level up & carry-over exp
if newStats.exp >= tnl
#silent = true # push through the negative xp silently
user.stats.exp = newStats.exp
# push normal + notification
while newStats.exp >= tnl and user.stats.lvl < 100 # keep levelling up
newStats.exp -= tnl
user.stats.lvl++
tnl = obj.tnl(user.stats.lvl)
if user.stats.lvl == 100
newStats.exp = 0
user.stats.hp = 50
user.stats.exp = newStats.exp
#if silent
#console.log("pushing silent :" + obj.stats.exp)
# Set flags when they unlock features
if !user.flags.customizationsNotification and (user.stats.exp > 10 or user.stats.lvl > 1)
user.flags.customizationsNotification = true
if !user.flags.itemsEnabled and user.stats.lvl >= 2
user.flags.itemsEnabled = true
if !user.flags.partyEnabled and user.stats.lvl >= 3
user.flags.partyEnabled = true
if !user.flags.dropsEnabled and user.stats.lvl >= 4
user.flags.dropsEnabled = true
if newStats.gp?
#FIXME what was I doing here? I can't remember, gp isn't defined
gp = 0.0 if (!gp? or gp < 0)
user.stats.gp = newStats.gp
###
At end of day, add value to all incomplete Daily & Todo tasks (further incentive)
For incomplete Dailys, deduct experience
Make sure to run this function once in a while as server will not take care of overnight calculations.
And you have to run it every time client connects.
###
obj.cron = (user) ->
today = +new Date
daysPassed = helpers.daysBetween(user.lastCron, today, user.preferences.dayStart)
if daysPassed > 0
user.lastCron = today
if user.flags.rest is true
user.dailys.forEach (daily) ->
daily.completed = false
return
# Tally each task
todoTally = 0
user.todos.concat(user.dailys).forEach (task) ->
{id, type, completed, repeat} = task
# Deduct experience for missed Daily tasks,
# but not for Todos (just increase todo's value)
unless completed
# for todos & typical dailies, these are equivalent
daysFailed = daysPassed
# however, for dailys which have repeat dates, need
# to calculate how many they've missed according to their own schedule
if type == 'daily' && repeat
daysFailed = 0
for i in [1..daysPassed] by 1
thatDay = moment().subtract('days', i + 1)
if repeat[helpers.dayMapping[thatDay.day()]] == true
daysFailed++
score user, task, 'down'
if type == 'daily'
if completed #set OHV for completed dailies
task.value = task.value + taskDeltaFormula(task.value, 'up')
task.history ?= []
task.history.push { date: +new Date, value: task.value }
task.completed = false
else
#get updated value
absVal = if (completed) then Math.abs(task.value) else task.value
todoTally += absVal
user.habits.forEach (task) -> # slowly reset 'onlies' value to 0
if task.up == false or task.down == false
if Math.abs(task.value) < 0.1
task.value = 0
else
task.value = task.value / 2
# Finished tallying
user.history ?= {};
user.history.todos ?= [];
user.history.exp ?= []
user.history.todos.push { date: today, value: todoTally }
# tally experience
expTally = user.stats.exp
lvl = 0
#iterator
while lvl < (user.stats.lvl - 1)
lvl++
expTally += obj.tnl(lvl)
user.history.exp.push { date: today, value: expTally }
user
-256
View File
@@ -1,256 +0,0 @@
var HP = 15
, XP = 2
, Items = require('./items');
function priorityValue(priority) {
if (priority == null) {
priority = '!';
}
switch (priority) {
case '!':
return 1;
case '!!':
return 1.5;
case '!!!':
return 2;
default:
return 1;
}
};
function tnl(level) {
var value;
if (level >= 100) {
value = 0;
} else {
value = Math.round(((Math.pow(level, 2) * 0.25) + (10 * level) + 139.75) / 10) * 10;
}
return value;
};
/*
Calculates Exp modificaiton based on level and weapon strength
{value} task.value for exp gain
{weaponStrength) weapon strength
{level} current user level
{priority} user-defined priority multiplier
*/
function expModifier(value, weaponStr, level, priority) {
var exp, str, strMod, totalStr;
if (priority == null) {
priority = '!';
}
str = (level - 1) / 2;
totalStr = (str + weaponStr) / 100;
strMod = 1 + totalStr;
exp = value * XP * strMod * priorityValue(priority);
return Math.round(exp);
};
/*
Calculates HP modification based on level and armor defence
{value} task.value for hp loss
{armorDefense} defense from armor
{helmDefense} defense from helm
{level} current user level
{priority} user-defined priority multiplier
*/
function hpModifier(value, armorDef, helmDef, shieldDef, level, priority) {
var def, defMod, hp, totalDef;
if (priority == null) {
priority = '!';
}
def = (level - 1) / 2;
totalDef = (def + armorDef + helmDef + shieldDef) / 100;
defMod = 1 - totalDef;
hp = value * HP * defMod * priorityValue(priority);
return Math.round(hp * 10) / 10;
};
/*
Future use
{priority} user-defined priority multiplier
*/
function gpModifier(value, modifier, priority) {
if (priority == null) {
priority = '!';
}
return value * modifier * priorityValue(priority);
};
/*
Calculates the next task.value based on direction
Uses a capped inverse log y=.95^x, y>= -5
{currentValue} the current value of the task
{direction} up or down
*/
function taskDeltaFormula(currentValue, direction) {
var delta;
if (currentValue < -47.27) {
currentValue = -47.27;
} else if (currentValue > 21.27) {
currentValue = 21.27;
}
delta = Math.pow(0.9747, currentValue);
if (direction === 'up') {
return delta;
}
return -delta;
};
function score(user, taskId, direction, times, cron) {
var task = _.findWhere(user.tasks, {id: taskId})
, type = task.type
, value = task.value
, priority = task.priority || '!'
, delta = 0
, times = times? times: 1;
if (task.value > user.stats.gp && task.type === 'reward') {
r = confirm("Not enough GP to purchase this reward, buy anyway and lose HP? (Punishment for taking a reward you didn't earn).");
if (!r) return;
}
function calculateDelta(adjustvalue) {
adjustvalue = adjustvalue? adjustvalue: true;
_.times(times, function(n) {
var nextDelta;
nextDelta = taskDeltaFormula(value, direction);
if (adjustvalue) {
value += nextDelta;
}
delta += nextDelta;
});
};
function addPoints() {
var level, weaponStrength;
level = user.stats.lvl;
weaponStrength = Items.items.weapon[user.items.weapon].strength;
user.stats.exp += expModifier(delta, weaponStrength, level, priority);
user.stats.gp += gpModifier(delta, 1, priority);
};
function subtractPoints() {
var armorDefense, helmDefense, level, shieldDefense;
level = user.stats.lvl;
armorDefense = Items.items.armor[user.items.armor].defense;
helmDefense = Items.items.head[user.items.head].defense;
shieldDefense = Items.items.shield[user.items.shield].defense;
user.stats.hp += hpModifier(delta, armorDefense, helmDefense, shieldDefense, level, priority);
};
switch (type) {
case 'habit':
calculateDelta();
if (delta > 0) {
addPoints();
} else {
subtractPoints();
}
task.history = task.history? task.history: [];
if (task.value !== value) {
task.history.push({
date: +(new Date),
value: value
});
}
break;
case 'daily':
if (cron != null) {
calculateDelta();
subtractPoints();
} else {
calculateDelta(false);
if (delta !== 0) {
addPoints();
}
}
break;
case 'todo':
if (cron != null) {
calculateDelta();
} else {
calculateDelta();
addPoints();
}
break;
case 'reward':
calculateDelta(false);
user.stats.gp -= Math.abs(task.value);
var num = parseFloat(task.value).toFixed(2);
if (user.stats.gp < 0) {
user.stats.hp += user.stats.gp;
user.stats.gp = 0;
}
}
task.value = value;
updateStats(user);
return delta;
};
/*
Updates user stats with new stats. Handles death, leveling up, etc
{stats} new stats
{update} if aggregated changes, pass in userObj as update. otherwise commits will be made immediately
*/
function updateStats(user) {
if (user.stats.lvl === 0) return;
if (user.stats.hp <= 0) {
user.stats.lvl = 0; // signifies dead
user.stats.hp = 0;
return;
}
if (user.stats.lvl >= 100) {
user.stats.gp += user.stats.exp / 15;
user.stats.exp = 0;
user.stats.lvl = 100;
} else {
var currTnl = user.stats.tnl = tnl(user.stats.lvl);
if (user.stats.exp >= currTnl) {
while (user.stats.exp >= currTnl && user.stats.lvl < 100) {
user.stats.exp -= currTnl;
user.stats.lvl++;
user.stats.tnl = tnl(user.stats.lvl);
}
if (user.stats.lvl === 100) {
user.stats.exp = 0;
}
user.stats.hp = 50;
}
}
if (!user.flags.customizationsNotification && (user.stats.exp > 10 || user.stats.lvl > 1)) {
user.flags.customizationsNotification = true;
user.flags.customizationsNotification = true;
}
if (!user.flags.itemsEnabled && user.stats.lvl >= 2) {
user.flags.itemsEnabled = true;
user.flags.itemsEnabled = true;
}
if (!user.flags.partyEnabled && user.stats.lvl >= 3) {
user.flags.partyEnabled = true;
user.flags.partyEnabled = true;
}
if (!user.flags.petsEnabled && user.stats.lvl >= 4) {
user.flags.petsEnabled = true;
user.flags.petsEnabled = true;
}
if (user.stats.gp < 0) user.stats.gp = 0.0;
};
module.exports = {
tnl: tnl,
score: score
}
-2037
View File
File diff suppressed because it is too large Load Diff
-10
View File
@@ -1,10 +0,0 @@
exports.algos = require('./algos')
exports.items = require('./items')
exports.helpers = require('./helpers')
// This is how we're exporting this module to the browser. A preferable way would be http://requirejs.org/docs/api.html#packages
// but I couldn't get that working
try {
window;
window.habitrpgShared = exports;
} catch(e) {}
+146
View File
@@ -0,0 +1,146 @@
({ define: (
if typeof define == "function"
define
else
(F)->
F(require, exports, module)
)}).define (require, exports, module)->
obj = module.exports = {};
items = obj.items =
{
weapon: [
{index: 0, text: "Training Sword", classes: "weapon_0", notes: 'Training weapon.', strength: 0, value: 0}
{index: 1, text: "Sword", classes: 'weapon_1', notes: 'Increases experience gain by 3%.', strength: 3, value: 20}
{index: 2, text: "Axe", classes: 'weapon_2', notes: 'Increases experience gain by 6%.', strength: 6, value: 30}
{index: 3, text: "Morningstar", classes: 'weapon_3', notes: 'Increases experience gain by 9%.', strength: 9, value: 45}
{index: 4, text: "Blue Sword", classes: 'weapon_4', notes: 'Increases experience gain by 12%.', strength: 12, value: 65}
{index: 5, text: "Red Sword", classes: 'weapon_5', notes: 'Increases experience gain by 15%.', strength: 15, value: 90}
{index: 6, text: "Golden Sword", classes: 'weapon_6', notes: 'Increases experience gain by 18%.', strength: 18, value: 120}
{index: 7, text: "Dark Souls Blade", classes: 'weapon_7', notes: 'Increases experience gain by 21%.', strength: 21, value: 150}
]
armor: [
{index: 0, text: "Cloth Armor", classes: 'armor_0', notes: 'Training armor.', defense: 0, value: 0}
{index: 1, text: "Leather Armor", classes: 'armor_1', notes: 'Decreases HP loss by 4%.', defense: 4, value: 30}
{index: 2, text: "Chain Mail", classes: 'armor_2', notes: 'Decreases HP loss by 6%.', defense: 6, value: 45}
{index: 3, text: "Plate Mail", classes: 'armor_3', notes: 'Decreases HP loss by 7%.', defense: 7, value: 65}
{index: 4, text: "Red Armor", classes: 'armor_4', notes: 'Decreases HP loss by 8%.', defense: 8, value: 90}
{index: 5, text: "Golden Armor", classes: 'armor_5', notes: 'Decreases HP loss by 10%.', defense: 10, value: 120}
{index: 6, text: "Shade Armor", classes: 'armor_6', notes: 'Decreases HP loss by 12%.', defense: 12, value: 150}
]
head: [
{index: 0, text: "No Helm", classes: 'head_0', notes: 'Training helm.', defense: 0, value: 0}
{index: 1, text: "Leather Helm", classes: 'head_1', notes: 'Decreases HP loss by 2%.', defense: 2, value: 15}
{index: 2, text: "Chain Coif", classes: 'head_2', notes: 'Decreases HP loss by 3%.', defense: 3, value: 25}
{index: 3, text: "Plate Helm", classes: 'head_3', notes: 'Decreases HP loss by 4%.', defense: 4, value: 45}
{index: 4, text: "Red Helm", classes: 'head_4', notes: 'Decreases HP loss by 5%.', defense: 5, value: 60}
{index: 5, text: "Golden Helm", classes: 'head_5', notes: 'Decreases HP loss by 6%.', defense: 6, value: 80}
{index: 6, text: "Shade Helm", classes: 'head_6', notes: 'Decreases HP loss by 7%.', defense: 7, value: 100}
]
shield: [
{index: 0, text: "No Shield", classes: 'shield_0', notes: 'No Shield.', defense: 0, value: 0}
{index: 1, text: "Wooden Shield", classes: 'shield_1', notes: 'Decreases HP loss by 3%', defense: 3, value: 20}
{index: 2, text: "Buckler", classes: 'shield_2', notes: 'Decreases HP loss by 4%.', defense: 4, value: 35}
{index: 3, text: "Enforced Shield", classes: 'shield_3', notes: 'Decreases HP loss by 5%.', defense: 5, value: 55}
{index: 4, text: "Red Shield", classes: 'shield_4', notes: 'Decreases HP loss by 7%.', defense: 7, value: 70}
{index: 5, text: "Golden Shield", classes: 'shield_5', notes: 'Decreases HP loss by 8%.', defense: 8, value: 90}
{index: 6, text: "Tormented Skull", classes: 'shield_6', notes: 'Decreases HP loss by 9%.', defense: 9, value: 120}
]
potion:
{type: 'potion', text: "Potion", notes: "Recover 15 HP", value: 25, classes: 'potion'}
reroll:
{type: 'reroll', text: "Re-Roll", classes: 'reroll', notes: "Resets your task values back to 0 (yellow). Useful when everything's red and it's hard to stay alive.", value: 0 }
pets: [
{text: 'Wolf', name: 'Wolf', value: 3}
{text: 'Tiger Cub', name: 'TigerCub', value: 3}
#{text: 'Polar Bear Cub', name: 'PolarBearCub', value: 3} #commented out because there are no polarbear modifiers yet, special drop?
{text: 'Panda Cub', name: 'PandaCub', value: 3}
{text: 'Lion Cub', name: 'LionCub', value: 3}
{text: 'Fox', name: 'Fox', value: 3}
{text: 'Flying Pig', name: 'FlyingPig', value: 3}
{text: 'Dragon', name: 'Dragon', value: 3}
{text: 'Cactus', name: 'Cactus', value: 3}
{text: 'Bear Cub', name: 'BearCub', value: 3}
]
hatchingPotions: [
{text: 'Base', name: 'Base', notes: "Hatches your pet in it's base form.", value: 1}
{text: 'White', name: 'White', notes: 'Turns your animal into a White pet.', value: 2}
{text: 'Desert', name: 'Desert', notes: 'Turns your animal into a Desert pet.', value: 2}
{text: 'Red', name: 'Red', notes: 'Turns your animal into a Red pet.', value: 3}
{text: 'Shade', name: 'Shade', notes: 'Turns your animal into a Shade pet.', value: 3}
{text: 'Skeleton', name: 'Skeleton', notes: 'Turns your animal into a Skeleton.', value: 3}
{text: 'Zombie', name: 'Zombie', notes: 'Turns your animal into a Zombie.', value: 4}
{text: 'Cotton Candy Pink', name: 'CottonCandyPink', notes: 'Turns your animal into a Cotton Candy Pink pet.', value: 4}
{text: 'Cotton Candy Blue', name: 'CottonCandyBlue', notes: 'Turns your animal into a Cotton Candy Blue pet.', value: 4}
{text: 'Golden', name: 'Golden', notes: 'Turns your animal into a Golden pet.', value: 5}
]
}
# add "type" to each item, so we can reference that as "weapon" or "armor" in the html
['weapon', 'armor', 'head', 'shield'].forEach (key)->
items[key].forEach (item)->
item.type = key
items.pets.forEach (pet)->
pet.notes = 'Find a hatching potion to pour on this egg, and one day it will hatch into a loyal pet.'
items.hatchingPotions.forEach (hatchingPotion)->
hatchingPotion.notes = "Pour this on an egg, and it will hatch as a #{hatchingPotion.text} pet."
###
app exports
###
obj.app = (appExports, user) ->
appExports.buyItem = (e, el, next) ->
#TODO: this should be working but it's not. so instead, i'm passing all needed values as data-attrs
# item = model.at(e.target)
gp = user.stats.gp
[type, value, index] = [ $(el).attr('data-type'), $(el).attr('data-value'), $(el).attr('data-index') ]
return if gp < value
# make sure deduction doesn't happen unless purchase was successful, see https://github.com/lefnire/habitrpg/issues/233
deductGP = ->
user.stats.gp = gp - value
if type == 'weapon'
user.set 'items.weapon', index, deductGP
updateStore model
else if type == 'armor'
user.set 'items.armor', index, deductGP
updateStore model
else if type == 'head'
user.set 'items.head', index, deductGP
updateStore model
else if type == 'shield'
user.set 'items.shield', index, deductGP
updateStore model
else if type == 'potion'
hp = user.get 'stats.hp'
hp += 15
hp = 50 if hp > 50
user.set 'stats.hp', hp, deductGP
###
update store
###
obj.updateStore = updateStore = (user) ->
if !items.next?
items.next =
{}
equipped = user.items
['weapon', 'armor', 'shield', 'head'].forEach (type) ->
i = parseInt(equipped? [type] || 0) + 1
showNext = true
if i is items[type].length - 1
if (type in ['armor', 'shield', 'head'])
showNext = user.backer.tier >= 45 # backer armor
else
showNext = user.backer.tier >= 70 # backer weapon
else if i is items[type].length
showNext = false
items.next[type] = if showNext then items[type][i] else {hide: true}
-2
View File
@@ -2,7 +2,5 @@
"name": "habitrpg-shared",
"version": "0.0.0",
"dependencies": {
"browserify": "*",
"moment": "*"
}
}