Merge branch 'develop' into TheHollidayInn-challenges-clone
Take specHelper off of global scope
@@ -2,12 +2,12 @@
|
||||
margin-left: 1.25em;
|
||||
}*/
|
||||
|
||||
/* Comment out for holiday events */
|
||||
/* Comment out for holiday events
|
||||
.npc_ian {
|
||||
background: url("/common/img/sprites/npc_ian.gif") no-repeat;
|
||||
width: 78px;
|
||||
height: 135px;
|
||||
}
|
||||
} */
|
||||
|
||||
.Gems {
|
||||
display:inline-block;
|
||||
|
||||
2
common/dist/sprites/habitrpg-shared.css
vendored
306
common/dist/sprites/spritesmith0.css
vendored
@@ -1,216 +1,216 @@
|
||||
.achievement-alien {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1949px -479px;
|
||||
background-position: -1949px -1116px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-alpha {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1924px -182px;
|
||||
background-position: -1924px -819px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-armor {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1924px -479px;
|
||||
background-position: -1924px -1116px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-boot {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1899px -479px;
|
||||
background-position: -1899px -1116px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-bow {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1949px -452px;
|
||||
background-position: -1949px -1089px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-cactus {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1924px -452px;
|
||||
background-position: -1924px -1089px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-cake {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1899px -452px;
|
||||
background-position: -1899px -1089px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-cave {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1949px -425px;
|
||||
background-position: -1949px -1062px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-coffin {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1924px -425px;
|
||||
background-position: -1924px -1062px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-comment {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1899px -425px;
|
||||
background-position: -1899px -1062px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-costumeContest {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1949px -398px;
|
||||
background-position: -1949px -1035px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-dilatory {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1924px -398px;
|
||||
background-position: -1924px -1035px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-firefox {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1899px -398px;
|
||||
background-position: -1899px -1035px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-habitBirthday {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1949px -371px;
|
||||
background-position: -1949px -1008px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-heart {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1924px -371px;
|
||||
background-position: -1924px -1008px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-karaoke {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1899px -371px;
|
||||
background-position: -1899px -1008px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-ninja {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1949px -344px;
|
||||
background-position: -1949px -981px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-nye {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1924px -344px;
|
||||
background-position: -1924px -981px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-perfect {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1899px -182px;
|
||||
background-position: -1899px -819px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-rat {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1949px -317px;
|
||||
background-position: -1949px -954px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-shield {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1924px -317px;
|
||||
background-position: -1924px -954px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-shinySeed {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1899px -317px;
|
||||
background-position: -1899px -954px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-snowball {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1949px -290px;
|
||||
background-position: -1949px -927px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-spookDust {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1924px -290px;
|
||||
background-position: -1924px -927px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-stoikalm {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1899px -290px;
|
||||
background-position: -1899px -927px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-sun {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1949px -263px;
|
||||
background-position: -1949px -900px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-sword {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1924px -263px;
|
||||
background-position: -1924px -900px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-thermometer {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1899px -263px;
|
||||
background-position: -1899px -900px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-tree {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1949px -236px;
|
||||
background-position: -1949px -873px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-triadbingo {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1924px -236px;
|
||||
background-position: -1924px -873px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-ultimate-healer {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1899px -236px;
|
||||
background-position: -1899px -873px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-ultimate-mage {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1949px -209px;
|
||||
background-position: -1949px -846px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-ultimate-rogue {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1924px -209px;
|
||||
background-position: -1924px -846px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-ultimate-warrior {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1899px -209px;
|
||||
background-position: -1899px -846px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-valentine {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1949px -182px;
|
||||
background-position: -1949px -819px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.achievement-wolf {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1899px -344px;
|
||||
background-position: -1899px -981px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
@@ -1890,13 +1890,13 @@
|
||||
}
|
||||
.hair_mustache_1_ppurple {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -708px -592px;
|
||||
background-position: -182px -1434px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_mustache_1_ppurple {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -733px -607px;
|
||||
background-position: -207px -1449px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -1938,13 +1938,13 @@
|
||||
}
|
||||
.hair_mustache_1_rainbow {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -546px -1434px;
|
||||
background-position: -708px -592px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_mustache_1_rainbow {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -571px -1449px;
|
||||
background-position: -733px -607px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -3810,431 +3810,515 @@
|
||||
}
|
||||
.hair_bangs_3_rainbow {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -182px -1434px;
|
||||
background-position: -1899px -182px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_bangs_3_rainbow {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -207px -1449px;
|
||||
background-position: -1924px -197px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_bangs_3_red {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -637px -979px;
|
||||
background-position: -1899px -273px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_bangs_3_red {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -662px -994px;
|
||||
background-position: -1924px -288px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_bangs_3_snowy {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -546px -979px;
|
||||
background-position: -1899px -364px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_bangs_3_snowy {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -571px -994px;
|
||||
background-position: -1924px -379px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_bangs_3_white {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -455px -979px;
|
||||
background-position: -1899px -455px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_bangs_3_white {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -480px -994px;
|
||||
background-position: -1924px -470px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_bangs_3_winternight {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -364px -979px;
|
||||
background-position: -1899px -546px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_bangs_3_winternight {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -389px -994px;
|
||||
background-position: -1924px -561px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_bangs_3_winterstar {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -273px -979px;
|
||||
background-position: -1899px -637px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_bangs_3_winterstar {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -298px -994px;
|
||||
background-position: -1924px -652px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_bangs_3_yellow {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -182px -979px;
|
||||
background-position: -1899px -728px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_bangs_3_yellow {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -207px -994px;
|
||||
background-position: -1924px -743px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_bangs_3_zombie {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -91px -979px;
|
||||
background-position: -546px -1434px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_bangs_3_zombie {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -116px -994px;
|
||||
background-position: -571px -1449px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_TRUred {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: 0px -979px;
|
||||
background-position: -637px -979px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_TRUred {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -25px -994px;
|
||||
background-position: -662px -994px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_aurora {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -989px -819px;
|
||||
background-position: -546px -979px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_aurora {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1014px -834px;
|
||||
background-position: -571px -994px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_black {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -989px -728px;
|
||||
background-position: -455px -979px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_black {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1014px -743px;
|
||||
background-position: -480px -994px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_blond {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -989px -637px;
|
||||
background-position: -364px -979px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_blond {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1014px -652px;
|
||||
background-position: -389px -994px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_blue {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -989px -546px;
|
||||
background-position: -273px -979px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_blue {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1014px -561px;
|
||||
background-position: -298px -994px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_brown {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -989px -455px;
|
||||
background-position: -182px -979px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_brown {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1014px -470px;
|
||||
background-position: -207px -994px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_candycane {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -989px -364px;
|
||||
background-position: -91px -979px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_candycane {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1014px -379px;
|
||||
background-position: -116px -994px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_candycorn {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -989px -273px;
|
||||
background-position: 0px -979px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_candycorn {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1014px -288px;
|
||||
background-position: -25px -994px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_festive {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -989px -182px;
|
||||
background-position: -989px -819px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_festive {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1014px -197px;
|
||||
background-position: -1014px -834px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_frost {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -989px -91px;
|
||||
background-position: -989px -728px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_frost {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1014px -106px;
|
||||
background-position: -1014px -743px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_ghostwhite {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -989px 0px;
|
||||
background-position: -989px -637px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_ghostwhite {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1014px -15px;
|
||||
background-position: -1014px -652px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_green {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -819px -888px;
|
||||
background-position: -989px -546px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_green {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -844px -903px;
|
||||
background-position: -1014px -561px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_halloween {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -728px -888px;
|
||||
background-position: -989px -455px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_halloween {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -753px -903px;
|
||||
background-position: -1014px -470px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_holly {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -637px -888px;
|
||||
background-position: -989px -364px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_holly {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -662px -903px;
|
||||
background-position: -1014px -379px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_hollygreen {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -546px -888px;
|
||||
background-position: -989px -273px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_hollygreen {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -571px -903px;
|
||||
background-position: -1014px -288px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_midnight {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -455px -888px;
|
||||
background-position: -989px -182px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_midnight {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -480px -903px;
|
||||
background-position: -1014px -197px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_pblue {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -364px -888px;
|
||||
background-position: -989px -91px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_pblue {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -389px -903px;
|
||||
background-position: -1014px -106px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_pblue2 {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -273px -888px;
|
||||
background-position: -989px 0px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_pblue2 {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -298px -903px;
|
||||
background-position: -1014px -15px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_peppermint {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -182px -888px;
|
||||
background-position: -819px -888px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_peppermint {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -207px -903px;
|
||||
background-position: -844px -903px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_pgreen {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -91px -888px;
|
||||
background-position: -728px -888px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_pgreen {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -116px -903px;
|
||||
background-position: -753px -903px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_pgreen2 {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: 0px -888px;
|
||||
background-position: -637px -888px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_pgreen2 {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -25px -903px;
|
||||
background-position: -662px -903px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_porange {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -889px -740px;
|
||||
background-position: -546px -888px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_porange {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -914px -755px;
|
||||
background-position: -571px -903px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_porange2 {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -798px -740px;
|
||||
background-position: -455px -888px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_porange2 {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -823px -755px;
|
||||
background-position: -480px -903px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_ppink {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -707px -740px;
|
||||
background-position: -364px -888px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_ppink {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -732px -755px;
|
||||
background-position: -389px -903px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_ppink2 {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1080px 0px;
|
||||
background-position: -273px -888px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_ppink2 {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1105px -15px;
|
||||
background-position: -298px -903px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_ppurple {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -910px -979px;
|
||||
background-position: -182px -888px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_ppurple {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -935px -994px;
|
||||
background-position: -207px -903px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_ppurple2 {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -819px -979px;
|
||||
background-position: -91px -888px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_ppurple2 {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -844px -994px;
|
||||
background-position: -116px -903px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_pumpkin {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -728px -979px;
|
||||
background-position: 0px -888px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_pumpkin {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -25px -903px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_purple {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -889px -740px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_purple {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -914px -755px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_pyellow {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -798px -740px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_pyellow {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -823px -755px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_pyellow2 {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -707px -740px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_pyellow2 {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -732px -755px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_rainbow {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1080px 0px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_rainbow {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1105px -15px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_red {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -910px -979px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_red {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -935px -994px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_snowy {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -819px -979px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_snowy {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -844px -994px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_white {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -728px -979px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_white {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -753px -994px;
|
||||
width: 60px;
|
||||
|
||||
BIN
common/dist/sprites/spritesmith0.png
vendored
|
Before Width: | Height: | Size: 305 KiB After Width: | Height: | Size: 306 KiB |
5596
common/dist/sprites/spritesmith1.css
vendored
BIN
common/dist/sprites/spritesmith1.png
vendored
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 80 KiB |
5262
common/dist/sprites/spritesmith2.css
vendored
BIN
common/dist/sprites/spritesmith2.png
vendored
|
Before Width: | Height: | Size: 150 KiB After Width: | Height: | Size: 152 KiB |
1572
common/dist/sprites/spritesmith3.css
vendored
BIN
common/dist/sprites/spritesmith3.png
vendored
|
Before Width: | Height: | Size: 151 KiB After Width: | Height: | Size: 156 KiB |
992
common/dist/sprites/spritesmith4.css
vendored
BIN
common/dist/sprites/spritesmith4.png
vendored
|
Before Width: | Height: | Size: 696 KiB After Width: | Height: | Size: 733 KiB |
958
common/dist/sprites/spritesmith5.css
vendored
BIN
common/dist/sprites/spritesmith5.png
vendored
|
Before Width: | Height: | Size: 364 KiB After Width: | Height: | Size: 366 KiB |
1338
common/dist/sprites/spritesmith6.css
vendored
BIN
common/dist/sprites/spritesmith6.png
vendored
|
Before Width: | Height: | Size: 304 KiB After Width: | Height: | Size: 310 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.0 KiB |
BIN
common/img/sprites/spritesmith/npcs/npc_ian.png
Normal file
|
After Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.3 KiB |
BIN
common/img/sprites/spritesmith/npcs/seasonalshop_summer2015.png
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 30 KiB |
@@ -128,6 +128,15 @@
|
||||
"weaponSpecialSpring2015MageNotes": "Conjure yourself up a carrot with this fancy wand. Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2015 Spring Gear.",
|
||||
"weaponSpecialSpring2015HealerText": "Cat Rattle",
|
||||
"weaponSpecialSpring2015HealerNotes": "When you wave it, it makes a fascinating clickety noise that would keep ANYONE entertained for hours. Increases Intelligence by <%= int %>. Limited Edition 2015 Spring Gear.",
|
||||
|
||||
"weaponSpecialSummer2015RogueText": "Firing Coral",
|
||||
"weaponSpecialSummer2015RogueNotes": "This relative of fire coral has the ability to propel its venom through the water. Increases Strength by <%= str %>. Limited Edition 2015 Summer Gear.",
|
||||
"weaponSpecialSummer2015WarriorText": "Sun Swordfish",
|
||||
"weaponSpecialSummer2015WarriorNotes": "The Sun Swordfish is a fearsome weapon, provided that it can be induced to stop wriggling. Increases Strength by <%= str %>. Limited Edition 2015 Summer Gear.",
|
||||
"weaponSpecialSummer2015MageText": "Soothsayer Staff",
|
||||
"weaponSpecialSummer2015MageNotes": "Hidden power glimmers in the jewels of this staff. Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2015 Summer Gear.",
|
||||
"weaponSpecialSummer2015HealerText": "Wand of the Waves",
|
||||
"weaponSpecialSummer2015HealerNotes": "Cures seasickness and sea sickness! Increases Intelligence by <%= int %>. Limited Edition 2015 Summer Gear.",
|
||||
|
||||
"weaponMystery201411Text": "Pitchfork of Feasting",
|
||||
"weaponMystery201411Notes": "Stab your enemies or dig in to your favorite foods - this versatile pitchfork does it all! Confers no benefit. November 2014 Subscriber Item.",
|
||||
@@ -259,6 +268,15 @@
|
||||
"armorSpecialSpring2015MageNotes": "Your coattails match your cottontail! Increases Intelligence by <%= int %>. Limited Edition 2015 Spring Gear.",
|
||||
"armorSpecialSpring2015HealerText": "Comforting Catsuit",
|
||||
"armorSpecialSpring2015HealerNotes": "This soft catsuit is comfortable, and as comforting as mint tea. Increases Constitution by <%= con %>. Limited Edition 2015 Spring Gear.",
|
||||
|
||||
"armorSpecialSummer2015RogueText": "Ruby Tail",
|
||||
"armorSpecialSummer2015RogueNotes": "This garment of shimmering scales transforms its wearer into a real Reef Renegade! Increases Perception by <%= per %>. Limited Edition 2015 Summer Gear.",
|
||||
"armorSpecialSummer2015WarriorText": "Golden Tail",
|
||||
"armorSpecialSummer2015WarriorNotes": "This garment of shimmering scales transforms its wearer into a real Sunfish Warrior! Increases Constitution by <%= con %>. Limited Edition 2015 Summer Gear.",
|
||||
"armorSpecialSummer2015MageText": "Soothsayer Robes",
|
||||
"armorSpecialSummer2015MageNotes": "Hidden power resides in the puffs of these sleeves. Increases Intelligence by <%= int %>. Limited Edition 2015 Summer Gear.",
|
||||
"armorSpecialSummer2015HealerText": "Sailor's Armor",
|
||||
"armorSpecialSummer2015HealerNotes": "This armor lets everyone know that you are an honest merchant sailor who would never dream of behaving like a scalawag. Increases Constitution by <%= con %>. Limited Edition 2015 Summer Gear.",
|
||||
|
||||
"armorMystery201402Text": "Messenger Robes",
|
||||
"armorMystery201402Notes": "Shimmering and strong, these robes have many pockets to carry letters. Confers no benefit. February 2014 Subscriber Item.",
|
||||
@@ -406,6 +424,15 @@
|
||||
"headSpecialSpring2015HealerText": "Comforting Crown",
|
||||
"headSpecialSpring2015HealerNotes": "The pearl at the center of this crown calms and comforts those around it. Increases Intelligence by <%= int %>. Limited Edition 2015 Spring Gear.",
|
||||
|
||||
"headSpecialSummer2015RogueText": "Renegade Hat",
|
||||
"headSpecialSummer2015RogueNotes": "This pirate hat fell overboard and has been decorated with scraps of fire coral. Increases Perception by <%= per %>. Limited Edition 2015 Summer Gear.",
|
||||
"headSpecialSummer2015WarriorText": "Jeweled Oceanic Helm",
|
||||
"headSpecialSummer2015WarriorNotes": "Crafted of deep-ocean metal by the artisans of Dilatory, this helm is strong and handsome. Increases Strength by <%= str %>. Limited Edition 2015 Summer Gear.",
|
||||
"headSpecialSummer2015MageText": "Soothsayer Scarf",
|
||||
"headSpecialSummer2015MageNotes": "Hidden power shines in the threads of this scarf. Increases Perception by <%= per %>. Limited Edition 2015 Summer Gear.",
|
||||
"headSpecialSummer2015HealerText": "Sailor's Cap",
|
||||
"headSpecialSummer2015HealerNotes": "With your sailor's cap set firmly on your head, you can navigate even the stormiest seas! Increases Intelligence by <%= int %>. Limited Edition 2015 Summer Gear.",
|
||||
|
||||
"headSpecialGaymerxText": "Rainbow Warrior Helm",
|
||||
"headSpecialGaymerxNotes": "In celebration of pride season and GaymerX, this special helmet is decorated with a radiant, colorful rainbow pattern! GaymerX is a game convention celebrating LGBTQ and gaming and is open to everyone. It takes place at the InterContinental in downtown San Francisco on July 11-13! Confers no benefit.",
|
||||
|
||||
@@ -517,6 +544,13 @@
|
||||
"shieldSpecialSpring2015WarriorNotes": "Hurl it at your enemies.... or just hold it, because it will fill up with yummy kibble at dinnertime. Increases Constitution by <%= con %>. Limited Edition 2015 Spring Gear.",
|
||||
"shieldSpecialSpring2015HealerText": "Patterned Pillow",
|
||||
"shieldSpecialSpring2015HealerNotes": "You can rest your head on this soft pillow, or you can wrestle it with your fearsome claws. Rawr! Increases Constitution by <%= con %>. Limited Edition 2015 Spring Gear.",
|
||||
|
||||
"shieldSpecialSummer2015RogueText": "Firing Coral",
|
||||
"shieldSpecialSummer2015RogueNotes": "This relative of fire coral has the ability to propel its venom through the water. Increases Strength by <%= str %>. Limited Edition 2015 Summer Gear.",
|
||||
"shieldSpecialSummer2015WarriorText": "Sunfish Shield",
|
||||
"shieldSpecialSummer2015WarriorNotes": "Crafted of deep-ocean metal by the artisans of Dilatory, this shield shines like the sand and the sea. Increases Constitution by <%= con %>. Limited Edition 2015 Summer Gear.",
|
||||
"shieldSpecialSummer2015HealerText": "Strapping Shield",
|
||||
"shieldSpecialSummer2015HealerNotes": "Use this shield to bash away bilge rats. Increases Constitution by <%= con %>. Limited Edition 2015 Summer Gear.",
|
||||
|
||||
"shieldMystery301405Text": "Clock Shield",
|
||||
"shieldMystery301405Notes": "Time is on your side with this towering clock shield! Confers no benefit. June 3015 Subscriber Item.",
|
||||
@@ -524,6 +558,7 @@
|
||||
"shieldArmoireGladiatorShieldText": "Gladiator Shield",
|
||||
"shieldArmoireGladiatorShieldNotes": "To be a gladiator you must.... eh, whatever, just bash them with your shield. Increases Constitution by <%= con %> and Strength by <%= str %>. Enchanted Armoire: Gladiator Set (Item 3 of 3).",
|
||||
|
||||
"back": "Back Accessory",
|
||||
"backBase0Text": "No Back Accessory",
|
||||
"backBase0Notes": "No Back Accessory.",
|
||||
|
||||
@@ -541,6 +576,7 @@
|
||||
"backSpecialWonderconBlackText": "Sneaky Cape",
|
||||
"backSpecialWonderconBlackNotes": "Spun of shadows and whispers. Confers no benefit. Special Edition Convention Item.",
|
||||
|
||||
"body": "Body Accessory",
|
||||
"bodyBase0Text": "No Body Accessory",
|
||||
"bodyBase0Notes": "No Body Accessory.",
|
||||
|
||||
@@ -556,6 +592,15 @@
|
||||
"bodySpecialSummerHealerText": "Coral Collar",
|
||||
"bodySpecialSummerHealerNotes": "A stylish collar of live coral! Confers no benefit. Limited Edition 2014 Summer Gear.",
|
||||
|
||||
"bodySpecialSummer2015RogueText": "Renegade Sash",
|
||||
"bodySpecialSummer2015RogueNotes": "You can't be a true Renegade without panache... and a sash. Confers no benefit. Limited Edition 2015 Summer Gear.",
|
||||
"bodySpecialSummer2015WarriorText": "Oceanic Spikes",
|
||||
"bodySpecialSummer2015WarriorNotes": "Each spike drips jellyfish venom, defending the wearer. Confers no benefit. Limited Edition 2015 Summer Gear.",
|
||||
"bodySpecialSummer2015MageText": "Golden Buckle",
|
||||
"bodySpecialSummer2015MageNotes": "This buckle adds no power at all, but it's shiny. Confers no benefit. Limited Edition 2015 Summer Gear.",
|
||||
"bodySpecialSummer2015HealerText": "Sailor's Neckerchief",
|
||||
"bodySpecialSummer2015HealerNotes": "Yo ho ho? No, no, no! Confers no benefit. Limited Edition 2015 Summer Gear.",
|
||||
|
||||
"headAccessory": "head accessory",
|
||||
"accessories": "Accessories",
|
||||
"animalEars": "Animal Ears",
|
||||
@@ -609,6 +654,7 @@
|
||||
"headAccessoryMystery301405Text": "Headwear Goggles",
|
||||
"headAccessoryMystery301405Notes": "\"Goggles are for your eyes,\" they said. \"Nobody wants goggles that you can only wear on your head,\" they said. Hah! You sure showed them! Confers no benefit. August 3015 Subscriber Item.",
|
||||
|
||||
"eyewear": "Eyewear",
|
||||
"eyewearBase0Text": "No Eyewear",
|
||||
"eyewearBase0Notes": "No Eyewear.",
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
"seasonalShopTitle": "<%= linkStart %>Seasonal Sorceress<%= linkEnd %>",
|
||||
"seasonalShopClosedText": "The Seasonal Shop is currently closed!! I don't know where the Seasonal Sorceress is now, but I bet she'll be back during the next <%= linkStart %>Grand Gala<%= linkEnd %>!",
|
||||
"seasonalShopText": "Welcome to the Seasonal Shop!! We're stocking springtime <a href='http://habitrpg.wikia.com/wiki/Item_Availability' target='_blank'>Seasonal Edition</a> goodies at the moment. Everything here will be available to purchase during the Spring Fling event each year, but we're only open until April 30th, so be sure to stock up now, or you'll have to wait a year to buy these items again!",
|
||||
"seasonalShopSummerText": "Welcome to the Seasonal Shop!! We're stocking summertime <a href='http://habitrpg.wikia.com/wiki/Item_Availability' target='_blank'>Seasonal Edition</a> goodies at the moment. Everything here will be available to purchase during the Summer Splash event each year, but we're only open until July 31st, so be sure to stock up now, or you'll have to wait a year to buy these items again!",
|
||||
"seasonalShopRebirth": "If you've used the Orb of Rebirth, you can repurchase this equipment in the Rewards Column after you unlock the Item Shop. Initially, you'll only be able to purchase the items for your current class (Warrior by default), but fear not, the other class-specific items will become available if you switch to that class.",
|
||||
"candycaneSet": "Candy Cane (Mage)",
|
||||
"skiSet": "Ski-sassin (Rogue)",
|
||||
@@ -44,5 +45,9 @@
|
||||
"mightyBunnySet": "Mighty Bunny (Warrior)",
|
||||
"magicMouseSet": "Magic Mouse (Mage)",
|
||||
"lovingPupSet": "Loving Pup (Healer)",
|
||||
"stealthyKittySet": "Stealthy Kitty (Rogue)"
|
||||
"stealthyKittySet": "Stealthy Kitty (Rogue)",
|
||||
"daringSwashbucklerSet": "Daring Swashbuckler (Warrior)",
|
||||
"emeraldMermageSet": "Emerald Mermage (Mage)",
|
||||
"reefSeahealerSet": "Reef Seahealer (Healer)",
|
||||
"roguishPirateSet": "Roguish Pirate (Rogue)"
|
||||
}
|
||||
|
||||
@@ -20,6 +20,9 @@ classes = ['warrior', 'rogue', 'healer', 'wizard']
|
||||
gearTypes = [ 'weapon', 'armor', 'head', 'shield', 'body', 'back', 'headAccessory', 'eyewear']
|
||||
|
||||
events =
|
||||
# IMPORTANT: The end date should be one to two days AFTER the actual end of
|
||||
# the event, to allow people in different timezones to still buy the
|
||||
# event gear up until at least the actual end of the event.
|
||||
winter: {start:'2013-12-31',end:'2014-02-01'}
|
||||
birthday: {start:'2013-01-30',end:'2014-02-01'}
|
||||
spring: {start:'2014-03-21',end:'2014-05-01'}
|
||||
@@ -28,9 +31,7 @@ events =
|
||||
fall: {start:'2014-09-21',end:'2014-11-01'}
|
||||
winter2015: {start:'2014-12-21',end:'2015-02-02'}
|
||||
spring2015: {start:'2015-03-20',end:'2015-05-02'}
|
||||
# IMPORTANT: The end date should be one to two days AFTER the actual end of
|
||||
# the event, to allow people in different timezones to still buy the
|
||||
# event gear up until at least the actual end of the event.
|
||||
summer2015: {start:'2015-06-20',end:'2015-08-02'}
|
||||
|
||||
api.mystery =
|
||||
201402: {start:'2014-02-22',end:'2014-02-28', text:'Winged Messenger Set'}
|
||||
@@ -135,6 +136,11 @@ gear =
|
||||
spring2015Warrior: event: events.spring2015, specialClass: 'warrior', text: t('weaponSpecialSpring2015WarriorText'), notes: t('weaponSpecialSpring2015WarriorNotes', {str: 15}), value: 90, str: 15
|
||||
spring2015Mage: event: events.spring2015, specialClass: 'wizard', twoHanded:true, text: t('weaponSpecialSpring2015MageText'), notes: t('weaponSpecialSpring2015MageNotes', {int: 15, per: 7}), value: 160, int:15, per:7
|
||||
spring2015Healer: event: events.spring2015, specialClass: 'healer', text: t('weaponSpecialSpring2015HealerText'), notes: t('weaponSpecialSpring2015HealerNotes', {int: 9}), value: 90, int: 9
|
||||
# Summer 2015
|
||||
summer2015Rogue: event: events.summer2015, specialClass: 'rogue', text: t('weaponSpecialSummer2015RogueText'), notes: t('weaponSpecialSummer2015RogueNotes', {str: 8}), value: 80, str: 8
|
||||
summer2015Warrior: event: events.summer2015, specialClass: 'warrior', text: t('weaponSpecialSummer2015WarriorText'), notes: t('weaponSpecialSummer2015WarriorNotes', {str: 15}), value: 90, str: 15
|
||||
summer2015Mage: event: events.summer2015, specialClass: 'wizard', twoHanded:true, text: t('weaponSpecialSummer2015MageText'), notes: t('weaponSpecialSummer2015MageNotes', {int: 15, per: 7}), value: 160, int:15, per:7
|
||||
summer2015Healer: event: events.summer2015, specialClass: 'healer', text: t('weaponSpecialSummer2015HealerText'), notes: t('weaponSpecialSummer2015HealerNotes', {int: 9}), value: 90, int: 9
|
||||
mystery:
|
||||
201411: text: t('weaponMystery201411Text'), notes: t('weaponMystery201411Notes'), mystery:'201411', value: 0
|
||||
201502: text: t('weaponMystery201502Text'), notes: t('weaponMystery201502Notes'), mystery:'201502', value: 0
|
||||
@@ -211,6 +217,11 @@ gear =
|
||||
spring2015Warrior: event: events.spring2015, specialClass: 'warrior', text: t('armorSpecialSpring2015WarriorText'), notes: t('armorSpecialSpring2015WarriorNotes', {con: 9}), value: 90, con: 9
|
||||
spring2015Mage: event: events.spring2015, specialClass: 'wizard', text: t('armorSpecialSpring2015MageText'), notes: t('armorSpecialSpring2015MageNotes', {int: 9}), value: 90, int: 9
|
||||
spring2015Healer: event: events.spring2015, specialClass: 'healer', text: t('armorSpecialSpring2015HealerText'), notes: t('armorSpecialSpring2015HealerNotes', {con: 15}), value: 90, con: 15
|
||||
# Summer 2015
|
||||
summer2015Rogue: event: events.summer2015, specialClass: 'rogue', text: t('armorSpecialSummer2015RogueText'), notes: t('armorSpecialSummer2015RogueNotes', {per: 15}), value: 90, per: 15
|
||||
summer2015Warrior: event: events.summer2015, specialClass: 'warrior', text: t('armorSpecialSummer2015WarriorText'), notes: t('armorSpecialSummer2015WarriorNotes', {con: 9}), value: 90, con: 9
|
||||
summer2015Mage: event: events.summer2015, specialClass: 'wizard', text: t('armorSpecialSummer2015MageText'), notes: t('armorSpecialSummer2015MageNotes', {int: 9}), value: 90, int: 9
|
||||
summer2015Healer: event: events.summer2015, specialClass: 'healer', text: t('armorSpecialSummer2015HealerText'), notes: t('armorSpecialSummer2015HealerNotes', {con: 15}), value: 90, con: 15
|
||||
# Other
|
||||
gaymerx: event: events.gaymerx, text: t('armorSpecialGaymerxText'), notes: t('armorSpecialGaymerxNotes'), value: 0
|
||||
mystery:
|
||||
@@ -298,6 +309,11 @@ gear =
|
||||
spring2015Warrior: event: events.spring2015, specialClass: 'warrior', text: t('headSpecialSpring2015WarriorText'), notes: t('headSpecialSpring2015WarriorNotes', {str: 9}),value: 60,str: 9
|
||||
spring2015Mage: event: events.spring2015, specialClass: 'wizard', text: t('headSpecialSpring2015MageText'), notes: t('headSpecialSpring2015MageNotes', {per: 7}),value: 60,per: 7
|
||||
spring2015Healer: event: events.spring2015, specialClass: 'healer', text: t('headSpecialSpring2015HealerText'), notes: t('headSpecialSpring2015HealerNotes', {int: 7}), value: 60, int: 7
|
||||
# Summer 2015
|
||||
summer2015Rogue: event: events.summer2015, specialClass: 'rogue', text: t('headSpecialSummer2015RogueText'), notes: t('headSpecialSummer2015RogueNotes', {per: 9}),value: 60,per: 9
|
||||
summer2015Warrior: event: events.summer2015, specialClass: 'warrior', text: t('headSpecialSummer2015WarriorText'), notes: t('headSpecialSummer2015WarriorNotes', {str: 9}),value: 60,str: 9
|
||||
summer2015Mage: event: events.summer2015, specialClass: 'wizard', text: t('headSpecialSummer2015MageText'), notes: t('headSpecialSummer2015MageNotes', {per: 7}),value: 60,per: 7
|
||||
summer2015Healer: event: events.summer2015, specialClass: 'healer', text: t('headSpecialSummer2015HealerText'), notes: t('headSpecialSummer2015HealerNotes', {int: 7}), value: 60, int: 7
|
||||
# Other
|
||||
gaymerx: event: events.gaymerx, text: t('headSpecialGaymerxText'), notes: t('headSpecialGaymerxNotes'), value: 0
|
||||
mystery:
|
||||
@@ -375,6 +391,10 @@ gear =
|
||||
spring2015Rogue: event: events.spring2015, specialClass: 'rogue', text: t('shieldSpecialSpring2015RogueText'), notes: t('shieldSpecialSpring2015RogueNotes', {str: 8}), value: 80, str: 8
|
||||
spring2015Warrior: event: events.spring2015, specialClass: 'warrior', text: t('shieldSpecialSpring2015WarriorText'), notes: t('shieldSpecialSpring2015WarriorNotes', {con: 7}), value: 70, con: 7
|
||||
spring2015Healer: event: events.spring2015, specialClass: 'healer', text: t('shieldSpecialSpring2015HealerText'), notes: t('shieldSpecialSpring2015HealerNotes', {con: 9}), value: 70, con: 9
|
||||
# Summer 2015
|
||||
summer2015Rogue: event: events.summer2015, specialClass: 'rogue', text: t('shieldSpecialSummer2015RogueText'), notes: t('shieldSpecialSummer2015RogueNotes', {str: 8}), value: 80, str: 8
|
||||
summer2015Warrior: event: events.summer2015, specialClass: 'warrior', text: t('shieldSpecialSummer2015WarriorText'), notes: t('shieldSpecialSummer2015WarriorNotes', {con: 7}), value: 70, con: 7
|
||||
summer2015Healer: event: events.summer2015, specialClass: 'healer', text: t('shieldSpecialSummer2015HealerText'), notes: t('shieldSpecialSummer2015HealerNotes', {con: 9}), value: 70, con: 9
|
||||
mystery:
|
||||
301405: text: t('shieldMystery301405Text'), notes: t('shieldMystery301405Notes'), mystery:'301405', value: 0
|
||||
armoire:
|
||||
@@ -402,6 +422,11 @@ gear =
|
||||
# Summer
|
||||
summerHealer: event: events.summer, specialClass: 'healer', text: t('bodySpecialSummerHealerText'), notes: t('bodySpecialSummerHealerNotes'), value: 20
|
||||
summerMage: event: events.summer, specialClass: 'wizard', text: t('bodySpecialSummerMageText'), notes: t('bodySpecialSummerMageNotes'), value: 20
|
||||
# Summer 2015
|
||||
summer2015Healer: event: events.summer2015, specialClass: 'healer', text: t('bodySpecialSummer2015HealerText'), notes: t('bodySpecialSummer2015HealerNotes'), value: 20
|
||||
summer2015Mage: event: events.summer2015, specialClass: 'wizard', text: t('bodySpecialSummer2015MageText'), notes: t('bodySpecialSummer2015MageNotes'), value: 20
|
||||
summer2015Rogue: event: events.summer2015, specialClass: 'rogue', text: t('bodySpecialSummer2015RogueText'), notes: t('bodySpecialSummer2015RogueNotes'), value: 20
|
||||
summer2015Warrior: event: events.summer2015, specialClass: 'warrior', text: t('bodySpecialSummer2015WarriorText'), notes: t('bodySpecialSummer2015WarriorNotes'), value: 20
|
||||
|
||||
headAccessory:
|
||||
base:
|
||||
|
||||
@@ -698,7 +698,7 @@ api.wrap = (user, main=true) ->
|
||||
pd.push(item) unless i != -1
|
||||
|
||||
cb? null, user.pushDevices
|
||||
|
||||
|
||||
# ------
|
||||
# Inbox
|
||||
# ------
|
||||
@@ -882,6 +882,7 @@ api.wrap = (user, main=true) ->
|
||||
# the same seed would give one of the first five foods only.
|
||||
eligibleEquipment = _.filter(content.gear.flat, ((i)->i.klass is 'armoire' and !user.items.gear.owned[i.key]))
|
||||
if !_.isEmpty(eligibleEquipment) and (armoireResult < .6 or !user.flags.armoireOpened)
|
||||
eligibleEquipment.sort() # https://github.com/HabitRPG/habitrpg/issues/5376#issuecomment-111799217
|
||||
drop = user.fns.randomVal(eligibleEquipment)
|
||||
user.items.gear.owned[drop.key] = true
|
||||
user.flags.armoireOpened = true
|
||||
@@ -1579,7 +1580,7 @@ api.wrap = (user, main=true) ->
|
||||
_.merge plan.consecutive, {count:0, offset:0, gemCapExtra:0}
|
||||
user.markModified? 'purchased.plan'
|
||||
|
||||
# User is resting at the inn.
|
||||
# User is resting at the inn.
|
||||
# On cron, buffs are cleared and all dailies are reset without performing damage
|
||||
if user.preferences.sleep is true
|
||||
user.stats.buffs = clearBuffs
|
||||
@@ -1715,7 +1716,7 @@ api.wrap = (user, main=true) ->
|
||||
owned = if window? then user.items.gear.owned else user.items.gear.owned.toObject()
|
||||
user.achievements.ultimateGearSets ?= {healer: false, wizard: false, rogue: false, warrior: false}
|
||||
content.classes.forEach (klass) ->
|
||||
if user.achievements.ultimateGearSets[klass] is not true
|
||||
if user.achievements.ultimateGearSets[klass] isnt true
|
||||
user.achievements.ultimateGearSets[klass] = _.reduce ['armor', 'shield', 'head', 'weapon'], (soFarGood, type) ->
|
||||
found = _.find content.gear.tree[type][klass], {last:true}
|
||||
soFarGood and (!found or owned[found.key]==true) #!found only true when weapon is two-handed (mages)
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
/**
|
||||
* Created by Sabe on 6/3/2015.
|
||||
*/
|
||||
// var migrationName = '20150604_ultimateGearSets';
|
||||
// var authorName = 'Sabe'; // in case script author needs to know when their ...
|
||||
// var authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; //... own data is done
|
||||
|
||||
var migrationName = '20150604_ultimateGearSets';
|
||||
var authorName = process.env.AUTHOR_NAME || 'Sabe'; // in case script author needs to know when their ...
|
||||
var authorUuid = process.env.AUTHOR_UUID || '7f14ed62-5408-4e1b-be83-ada62d504931'; //... own data is done
|
||||
var migrationName = '20150620_ultimateGearSets';
|
||||
var authorName = 'Alys'; // in case script author needs to know when their ...
|
||||
var authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; //... own data is done
|
||||
|
||||
/*
|
||||
* grant the new ultimateGearSets achievement for existing users' collected equipment
|
||||
*
|
||||
*
|
||||
* Changed by Alys on 20150620 to assign false values to
|
||||
* 'achievements.ultimateGearSets' when true values are not appropriate,
|
||||
* because of https://github.com/HabitRPG/habitrpg/issues/5427
|
||||
*
|
||||
* Minimal changes were made so the code isn't as efficient or clean
|
||||
* as it could be, but it's (hopefully) one-use-only and minimal changes
|
||||
* means minimal new testing.
|
||||
*/
|
||||
|
||||
var dbserver = 'localhost:27017' // FOR TEST DATABASE
|
||||
@@ -24,25 +33,10 @@ var fields = {
|
||||
'items.gear.owned':1
|
||||
};
|
||||
|
||||
|
||||
// Changes 20150620: All users have to be processed now (non-achievers need
|
||||
// false values).
|
||||
var query = {
|
||||
// 'auth.timestamps.loggedin':{$lte:new Date('2015-05-22')},
|
||||
$or: [
|
||||
{'items.gear.owned.weapon_wizard_6': {$exists: true}},
|
||||
{'items.gear.owned.armor_wizard_5': {$exists: true}},
|
||||
{'items.gear.owned.head_wizard_5': {$exists: true}},
|
||||
{'items.gear.owned.weapon_warrior_6': {$exists: true}},
|
||||
{'items.gear.owned.armor_warrior_5': {$exists: true}},
|
||||
{'items.gear.owned.head_warrior_5': {$exists: true}},
|
||||
{'items.gear.owned.shield_warrior_5': {$exists: true}},
|
||||
{'items.gear.owned.weapon_healer_6': {$exists: true}},
|
||||
{'items.gear.owned.armor_healer_5': {$exists: true}},
|
||||
{'items.gear.owned.head_healer_5': {$exists: true}},
|
||||
{'items.gear.owned.shield_healer_5': {$exists: true}},
|
||||
{'items.gear.owned.weapon_rogue_6': {$exists: true}},
|
||||
{'items.gear.owned.armor_rogue_5': {$exists: true}},
|
||||
{'items.gear.owned.head_rogue_5': {$exists: true}},
|
||||
{'items.gear.owned.shield_rogue_6': {$exists: true}}
|
||||
]
|
||||
};
|
||||
|
||||
console.warn('Updating users...');
|
||||
@@ -58,6 +52,8 @@ dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
|
||||
|
||||
var achievements = {};
|
||||
var changeUser = false;
|
||||
// Changes 20150620: 'changeUser' now indicates that the user must have the
|
||||
// Enchanted Armoire unlocked.
|
||||
if ( (typeof user.items.gear.owned.weapon_wizard_6 !== 'undefined')
|
||||
&& (typeof user.items.gear.owned.armor_wizard_5 !== 'undefined')
|
||||
&& (typeof user.items.gear.owned.head_wizard_5 !== 'undefined')
|
||||
@@ -65,6 +61,11 @@ dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
|
||||
achievements['wizard'] = true;
|
||||
changeUser = true;
|
||||
}
|
||||
else {
|
||||
// Changes 20150620: false added for all classes (here and below)
|
||||
achievements['wizard'] = false;
|
||||
}
|
||||
|
||||
if ( (typeof user.items.gear.owned.weapon_warrior_6 !== 'undefined')
|
||||
&& (typeof user.items.gear.owned.armor_warrior_5 !== 'undefined')
|
||||
&& (typeof user.items.gear.owned.head_warrior_5 !== 'undefined')
|
||||
@@ -73,6 +74,10 @@ dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
|
||||
achievements['warrior'] = true;
|
||||
changeUser = true;
|
||||
}
|
||||
else {
|
||||
achievements['warrior'] = false;
|
||||
}
|
||||
|
||||
if ( (typeof user.items.gear.owned.weapon_healer_6 !== 'undefined')
|
||||
&& (typeof user.items.gear.owned.armor_healer_5 !== 'undefined')
|
||||
&& (typeof user.items.gear.owned.head_healer_5 !== 'undefined')
|
||||
@@ -81,6 +86,10 @@ dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
|
||||
achievements['healer'] = true;
|
||||
changeUser = true;
|
||||
}
|
||||
else {
|
||||
achievements['healer'] = false;
|
||||
}
|
||||
|
||||
if ( (typeof user.items.gear.owned.weapon_rogue_6 !== 'undefined')
|
||||
&& (typeof user.items.gear.owned.armor_rogue_5 !== 'undefined')
|
||||
&& (typeof user.items.gear.owned.head_rogue_5 !== 'undefined')
|
||||
@@ -89,12 +98,17 @@ dbUsers.findEach(query, fields, {batchSize:250}, function(err, user) {
|
||||
achievements['rogue'] = true;
|
||||
changeUser = true;
|
||||
}
|
||||
|
||||
if (changeUser) {
|
||||
var set = {'migration':migrationName, 'achievements.ultimateGearSets':achievements, 'flags.armoireEnabled':true};
|
||||
dbUsers.update({_id:user._id}, {$set:set});
|
||||
else {
|
||||
achievements['rogue'] = false;
|
||||
}
|
||||
|
||||
// Changes 20150620: $set is now run for all users.
|
||||
var set = {'migration':migrationName, 'achievements.ultimateGearSets':achievements};
|
||||
if (changeUser) { // user has at least one Ultimate Gear achievement
|
||||
set['flags.armoireEnabled'] = true;
|
||||
}
|
||||
dbUsers.update({_id:user._id}, {$set:set});
|
||||
|
||||
if (count%progressCount == 0) console.warn(count + ' ' + user._id);
|
||||
if (user._id == authorUuid) console.warn(authorName + ' processed');
|
||||
if (user._id == '9' ) console.warn('lefnire' + ' processed');
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
"www.habitrpg.com"
|
||||
],
|
||||
"engines": {
|
||||
"node": "0.10.x"
|
||||
"node": "0.12.4"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "./node_modules/.bin/gulp test",
|
||||
|
||||
114
test/api/score.coffee
Normal file
@@ -0,0 +1,114 @@
|
||||
'use strict'
|
||||
|
||||
require("../../website/src/server")
|
||||
|
||||
describe "Score", ->
|
||||
before (done) ->
|
||||
registerNewUser done, true
|
||||
|
||||
context "Todos that did not previously exist", ->
|
||||
it "creates a completed a todo when using up url", (done) ->
|
||||
request.post(baseURL + "/user/tasks/withUp/up").send(
|
||||
type: "todo"
|
||||
text: "withUp"
|
||||
).end (res) ->
|
||||
expectCode res, 200
|
||||
request.get(baseURL + "/user/tasks/withUp").end (res) ->
|
||||
upTodo = res.body
|
||||
expect(upTodo.completed).to.equal true
|
||||
done()
|
||||
|
||||
it "creates an uncompleted todo when using down url", (done) ->
|
||||
request.post(baseURL + "/user/tasks/withDown/down").send(
|
||||
type: "todo"
|
||||
text: "withDown"
|
||||
).end (res) ->
|
||||
expectCode res, 200
|
||||
request.get(baseURL + "/user/tasks/withDown").end (res) ->
|
||||
downTodo = res.body
|
||||
expect(downTodo.completed).to.equal false
|
||||
done()
|
||||
|
||||
it "creates a completed a todo overriding the complete parameter when using up url", (done) ->
|
||||
request.post(baseURL + "/user/tasks/withUpWithComplete/up").send(
|
||||
type: "todo"
|
||||
text: "withUpWithComplete"
|
||||
completed: false
|
||||
).end (res) ->
|
||||
expectCode res, 200
|
||||
request.get(baseURL + "/user/tasks/withUpWithComplete").end (res) ->
|
||||
upTodo = res.body
|
||||
expect(upTodo.completed).to.equal true
|
||||
done()
|
||||
|
||||
it "Creates an uncompleted todo overriding the completed parameter when using down url", (done) ->
|
||||
request.post(baseURL + "/user/tasks/withDownWithUncomplete/down").send(
|
||||
type: "todo"
|
||||
text: "withDownWithUncomplete"
|
||||
completed: true
|
||||
).end (res) ->
|
||||
expectCode res, 200
|
||||
request.get(baseURL + "/user/tasks/withDownWithUncomplete").end (res) ->
|
||||
downTodo = res.body
|
||||
expect(downTodo.completed).to.equal false
|
||||
done()
|
||||
|
||||
context "Todo that already exists", ->
|
||||
it "It completes a todo when using up url", (done) ->
|
||||
request.post(baseURL + "/user/tasks").send(
|
||||
type: "todo"
|
||||
text: "Sample Todo"
|
||||
).end (res) ->
|
||||
expectCode res, 200
|
||||
unCompletedTodo = res.body
|
||||
expect(unCompletedTodo.completed).to.equal false
|
||||
request.post(baseURL + "/user/tasks/"+unCompletedTodo._id+"/up").end (res) ->
|
||||
expectCode res, 200
|
||||
request.get(baseURL + "/user/tasks/"+unCompletedTodo._id).end (res) ->
|
||||
unCompletedTodo = res.body
|
||||
expect(unCompletedTodo.completed).to.equal true
|
||||
done()
|
||||
|
||||
it "It uncompletes a todo when using down url", (done) ->
|
||||
request.post(baseURL + "/user/tasks").send(
|
||||
type: "todo"
|
||||
text: "Sample Todo"
|
||||
completed: true
|
||||
).end (res) ->
|
||||
expectCode res, 200
|
||||
completedTodo = res.body
|
||||
expect(completedTodo.completed).to.equal true
|
||||
request.post(baseURL + "/user/tasks/"+completedTodo._id+"/down").end (res) ->
|
||||
expectCode res, 200
|
||||
request.get(baseURL + "/user/tasks/"+completedTodo._id).end (res) ->
|
||||
completedTodo = res.body
|
||||
expect(completedTodo.completed).to.equal false
|
||||
done()
|
||||
|
||||
it "Creates and scores up a habit when using up url", (done) ->
|
||||
upHabit = undefined
|
||||
request.post(baseURL + "/user/tasks/habitWithUp/up").send(
|
||||
type: "habit"
|
||||
text: "testTitle"
|
||||
completed: true
|
||||
).end (res) ->
|
||||
expectCode res, 200
|
||||
request.get(baseURL + "/user/tasks/habitWithUp").end (res) ->
|
||||
upHabit = res.body
|
||||
expect(upHabit.value).to.be.at.least(1)
|
||||
expect(upHabit.type).to.equal("habit")
|
||||
done()
|
||||
|
||||
it "Creates and scores down a habit when using down url", (done) ->
|
||||
downHabit = undefined
|
||||
request.post(baseURL + "/user/tasks/habitWithDown/down").send(
|
||||
type: "habit"
|
||||
text: "testTitle"
|
||||
completed: true
|
||||
).end (res) ->
|
||||
expectCode res, 200
|
||||
request.get(baseURL + "/user/tasks/habitWithDown").end (res) ->
|
||||
downHabit = res.body
|
||||
expect(downHabit.value).to.have.at.most(-1)
|
||||
expect(downHabit.type).to.equal("habit")
|
||||
done()
|
||||
@@ -160,7 +160,7 @@ describe "Todos", ->
|
||||
).end (res) ->
|
||||
expectCode res, 200
|
||||
body = res.body
|
||||
expect(body).to.be.empty
|
||||
expect(body).to.be.empty
|
||||
done()
|
||||
|
||||
it "Does not delete already deleted todo", (done) ->
|
||||
@@ -183,4 +183,3 @@ describe "Todos", ->
|
||||
body = res.body
|
||||
expect(body.err).to.equal "Task not found."
|
||||
done()
|
||||
|
||||
|
||||
30
test/common/user.fns.js
Normal file
@@ -0,0 +1,30 @@
|
||||
'use strict';
|
||||
|
||||
var shared = require('../../common/script/index.coffee');
|
||||
shared.i18n.translations = require('../../website/src/i18n.js').translations
|
||||
|
||||
require('./test_helper');
|
||||
|
||||
describe('User.fns', function() {
|
||||
describe('.ultimateGear', function() {
|
||||
|
||||
it('sets armoirEnabled when partial achievement already achieved', function() {
|
||||
var user = shared.wrap({
|
||||
items: { gear: { owned: {
|
||||
toObject: function() { return {
|
||||
armor_warrior_5: true,
|
||||
shield_warrior_5: true,
|
||||
head_warrior_5: true,
|
||||
weapon_warrior_6: true
|
||||
}}
|
||||
}}},
|
||||
achievements: {
|
||||
ultimateGearSets: {}
|
||||
},
|
||||
flags: {}
|
||||
});
|
||||
user.fns.ultimateGear();
|
||||
expect(user.flags.armoireEnabled).to.equal(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -4,13 +4,8 @@ describe('AppJS', function() {
|
||||
describe('Automatic page refresh', function(){
|
||||
var clock;
|
||||
beforeEach(function () {
|
||||
clock = sinon.useFakeTimers();
|
||||
sinon.stub(window, "refresher", function(){return true});
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
clock.restore();
|
||||
window.refresher.restore();
|
||||
clock = sandbox.useFakeTimers();
|
||||
sandbox.stub(window, "refresher", function(){return true});
|
||||
});
|
||||
|
||||
it('should not call refresher if idle time is less than 6 hours', function() {
|
||||
|
||||
@@ -10,8 +10,8 @@ describe('Auth Controller', function() {
|
||||
scope = $rootScope.$new();
|
||||
scope.loginUsername = 'user';
|
||||
scope.loginPassword = 'pass';
|
||||
$window = { location: { href: ""}, alert: sinon.spy() };
|
||||
user = { user: {}, authenticate: sinon.spy() };
|
||||
$window = { location: { href: ""}, alert: sandbox.spy() };
|
||||
user = { user: {}, authenticate: sandbox.spy() };
|
||||
|
||||
ctrl = $controller('AuthCtrl', {$scope: scope, $window: $window, User: user});
|
||||
}));
|
||||
@@ -20,16 +20,16 @@ describe('Auth Controller', function() {
|
||||
$httpBackend.expectPOST('/api/v2/user/auth/local').respond({id: 'abc', token: 'abc'});
|
||||
scope.auth();
|
||||
$httpBackend.flush();
|
||||
sinon.assert.calledOnce(user.authenticate);
|
||||
sinon.assert.notCalled($window.alert);
|
||||
expect(user.authenticate).to.be.calledOnce;
|
||||
expect($window.alert).to.not.be.called;
|
||||
});
|
||||
|
||||
it('should not log in users with incorrect uname / pass', function() {
|
||||
$httpBackend.expectPOST('/api/v2/user/auth/local').respond(404, '');
|
||||
scope.auth();
|
||||
$httpBackend.flush();
|
||||
sinon.assert.notCalled(user.authenticate);
|
||||
sinon.assert.calledOnce($window.alert);
|
||||
expect(user.authenticate).to.not.be.called;
|
||||
expect($window.alert).to.be.calledOnce;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -188,10 +188,10 @@ describe('Challenges Controller', function() {
|
||||
var challengeToClone = {
|
||||
name: 'copyChallenge',
|
||||
description: 'copyChallenge',
|
||||
habits: [newHabit()],
|
||||
dailys: [newDaily()],
|
||||
todos: [newTodo()],
|
||||
rewards: [newReward()],
|
||||
habits: [specHelper.newHabit()],
|
||||
dailys: [specHelper.newDaily()],
|
||||
todos: [specHelper.newTodo()],
|
||||
rewards: [specHelper.newReward()],
|
||||
leader: 'unique-user-id',
|
||||
group: { _id: "copyGroup" },
|
||||
timestamp: new Date("October 13, 2014 11:13:00"),
|
||||
|
||||
@@ -30,7 +30,7 @@ describe('Groups Controller', function() {
|
||||
party.type = 'party';
|
||||
party.members = []; // Ensure we wouldn't pass automatically.
|
||||
|
||||
var partyStub = sinon.stub(groups,"party", function() {
|
||||
var partyStub = sandbox.stub(groups,"party", function() {
|
||||
return party;
|
||||
});
|
||||
|
||||
@@ -44,7 +44,7 @@ describe('Groups Controller', function() {
|
||||
guild.type = 'guild';
|
||||
guild.members.push(user._id);
|
||||
|
||||
var myGuilds = sinon.stub(groups,"myGuilds", function() {
|
||||
var myGuilds = sandbox.stub(groups,"myGuilds", function() {
|
||||
return [guild];
|
||||
});
|
||||
|
||||
@@ -58,7 +58,7 @@ describe('Groups Controller', function() {
|
||||
guild._id = "unique-guild-id";
|
||||
guild.type = 'guild';
|
||||
|
||||
var myGuilds = sinon.stub(groups,"myGuilds", function() {
|
||||
var myGuilds = sandbox.stub(groups,"myGuilds", function() {
|
||||
return [];
|
||||
});
|
||||
|
||||
@@ -98,7 +98,7 @@ describe("Chat Controller", function() {
|
||||
name: "Princess Bride"
|
||||
};
|
||||
|
||||
var modalSpy = sinon.spy($rootScope, "openModal");
|
||||
var modalSpy = sandbox.spy($rootScope, "openModal");
|
||||
var message = {
|
||||
uuid: 'the-dread-pirate-roberts',
|
||||
user: 'Wesley',
|
||||
@@ -120,7 +120,7 @@ describe("Chat Controller", function() {
|
||||
name: "Princess Bride"
|
||||
};
|
||||
|
||||
var modalSpy = sinon.spy($rootScope, "openModal");
|
||||
var modalSpy = sandbox.spy($rootScope, "openModal");
|
||||
var message = {
|
||||
uuid: 'system',
|
||||
text: 'Wesley attacked the ROUS in the Fire Swamp'
|
||||
@@ -221,7 +221,7 @@ describe("Autocomplete controller", function() {
|
||||
|
||||
describe("performCompletion", function() {
|
||||
it('triggers autoComplete', function() {
|
||||
scope.autoComplete = sinon.spy();
|
||||
scope.autoComplete = sandbox.spy();
|
||||
|
||||
var msg = {user: "boo"}; // scope.autoComplete only cares about user
|
||||
scope.query = {text: "b"};
|
||||
@@ -247,7 +247,7 @@ describe("Autocomplete controller", function() {
|
||||
|
||||
describe("chatChanged", function() {
|
||||
it('if a new chat arrives, the new user name is extracted', function() {
|
||||
var chatChanged = sinon.spy(scope, 'chatChanged');
|
||||
var chatChanged = sandbox.spy(scope, 'chatChanged');
|
||||
scope.$watch('group.chat',scope.chatChanged); // reinstantiate watch so spy works
|
||||
|
||||
scope.$digest(); // trigger watch
|
||||
@@ -269,11 +269,11 @@ describe("CopyMessageModal controller", function() {
|
||||
user = specHelper.newUser();
|
||||
user._id = "unique-user-id";
|
||||
user.ops = {
|
||||
addTask: sinon.spy()
|
||||
addTask: sandbox.spy()
|
||||
};
|
||||
|
||||
scope = $rootScope.$new();
|
||||
scope.$close = sinon.spy();
|
||||
scope.$close = sandbox.spy();
|
||||
|
||||
$controller = _$controller_;
|
||||
|
||||
@@ -283,7 +283,7 @@ describe("CopyMessageModal controller", function() {
|
||||
ctrl = $controller('CopyMessageModalCtrl', {$scope: scope, User: {user: user}});
|
||||
|
||||
Notification = _Notification_;
|
||||
Notification.text = sinon.spy();
|
||||
Notification.text = sandbox.spy();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -22,15 +22,12 @@ describe('Hall of Heroes Controller', function() {
|
||||
});
|
||||
|
||||
it('populates contributor input with selected hero id', function(){
|
||||
var loadHero = sinon.spy(scope, "loadHero");
|
||||
var scrollTo = sinon.spy(window, "scrollTo");
|
||||
var loadHero = sandbox.spy(scope, "loadHero");
|
||||
var scrollTo = sandbox.spy(window, "scrollTo");
|
||||
|
||||
scope.populateContributorInput(user._id);
|
||||
expect(scope._heroID).to.eql(user._id);
|
||||
expect(loadHero.callCount).to.eql(1);
|
||||
expect(scrollTo.callCount).to.eql(1);
|
||||
|
||||
scope.loadHero.restore();
|
||||
window.scrollTo.restore();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -26,13 +26,8 @@ describe('Header Controller', function() {
|
||||
|
||||
context('inviteOrStartParty', function(){
|
||||
beforeEach(function(){
|
||||
sinon.stub($location, 'path');
|
||||
sinon.stub($rootScope, 'openModal');
|
||||
});
|
||||
|
||||
afterEach(function(){
|
||||
$location.path.restore();
|
||||
$rootScope.openModal.restore();
|
||||
sandbox.stub($location, 'path');
|
||||
sandbox.stub($rootScope, 'openModal');
|
||||
});
|
||||
|
||||
it('redirects to party page if user does not have a party', function(){
|
||||
|
||||
@@ -24,13 +24,13 @@ describe('Root Controller', function() {
|
||||
$httpBackend = _$httpBackend_;
|
||||
|
||||
notification = Notification;
|
||||
sinon.stub(notification, 'text');
|
||||
sinon.stub(notification, 'markdown');
|
||||
sandbox.stub(notification, 'text');
|
||||
sandbox.stub(notification, 'markdown');
|
||||
|
||||
user = specHelper.newUser();
|
||||
User = {user: user};
|
||||
User.save = sinon.spy();
|
||||
User.sync = sinon.spy();
|
||||
User.save = sandbox.spy();
|
||||
User.sync = sandbox.spy();
|
||||
|
||||
$httpBackend.whenGET(/partials/).respond();
|
||||
|
||||
@@ -38,13 +38,6 @@ describe('Root Controller', function() {
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
notification.text.reset();
|
||||
notification.markdown.reset();
|
||||
User.save.reset();
|
||||
User.sync.reset();
|
||||
});
|
||||
|
||||
describe('contribText', function(){
|
||||
it('shows contributor level text', function(){
|
||||
expect(scope.contribText()).to.eql(undefined);
|
||||
|
||||
@@ -16,7 +16,7 @@ describe('focusMe Directive', function() {
|
||||
|
||||
it('focuses the element when appended to the DOM', function() {
|
||||
inject(function($timeout) {
|
||||
var focusSpy = sinon.spy();
|
||||
var focusSpy = sandbox.spy();
|
||||
|
||||
element.appendTo(document.body);
|
||||
element.on('focus', focusSpy);
|
||||
|
||||
@@ -11,7 +11,7 @@ describe('fromNow Directive', function() {
|
||||
scope = $rootScope.$new();
|
||||
scope.message = {};
|
||||
|
||||
sinon.stub(window, 'moment').returns({
|
||||
sandbox.stub(window, 'moment').returns({
|
||||
fromNow: function() { return fromNow },
|
||||
diff: function() { return diff }
|
||||
});
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
describe('Task Ordering Filters', function() {
|
||||
var filter
|
||||
, orderBySpy = sinon.spy();
|
||||
var filter, orderBySpy;
|
||||
|
||||
beforeEach(function() {
|
||||
orderBySpy = sandbox.spy();
|
||||
|
||||
module(function($provide) {
|
||||
$provide.value('orderByFilter', orderBySpy);
|
||||
});
|
||||
|
||||
@@ -3,13 +3,11 @@
|
||||
describe('notificationServices', function() {
|
||||
var notification;
|
||||
|
||||
before(function(){
|
||||
sinon.stub($, 'pnotify', function(){
|
||||
beforeEach(function() {
|
||||
sandbox.stub($, 'pnotify', function(){
|
||||
return { click: function(){}}
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(function() {
|
||||
module(function($provide){
|
||||
$provide.value('User', {});
|
||||
});
|
||||
@@ -19,10 +17,6 @@ describe('notificationServices', function() {
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
$.pnotify.reset();
|
||||
});
|
||||
|
||||
it('notifies coins amount', function() {
|
||||
var SILVER_COIN = "<span class='notification-icon shop_silver'></span>";
|
||||
var GOLD_COIN = "<span class='notification-icon shop_gold'></span>";
|
||||
|
||||
@@ -22,7 +22,7 @@ describe('Tasks Service', function() {
|
||||
var task;
|
||||
|
||||
beforeEach(function(){
|
||||
task = newTask();
|
||||
task = specHelper.newTask();
|
||||
});
|
||||
|
||||
it('toggles the _editing property', function() {
|
||||
@@ -71,7 +71,7 @@ describe('Tasks Service', function() {
|
||||
|
||||
context('generic tasks', function() {
|
||||
it('clones the data from a task', function() {
|
||||
var task = newTask();
|
||||
var task = specHelper.newTask();
|
||||
var clonedTask = tasks.cloneTask(task);
|
||||
|
||||
expect(clonedTask.text).to.eql(task.text);
|
||||
@@ -83,7 +83,7 @@ describe('Tasks Service', function() {
|
||||
});
|
||||
|
||||
it('does not clone original task\'s id or _id', function() {
|
||||
var task = newTask();
|
||||
var task = specHelper.newTask();
|
||||
var clonedTask = tasks.cloneTask(task);
|
||||
|
||||
expect(clonedTask.id).to.exist;
|
||||
@@ -93,7 +93,7 @@ describe('Tasks Service', function() {
|
||||
});
|
||||
|
||||
it('does not clone original task\'s dateCreated attribute', function() {
|
||||
var task = newTask({
|
||||
var task = specHelper.newTask({
|
||||
dateCreated: new Date(2014, 5, 1, 1, 1, 1, 1),
|
||||
});
|
||||
var clonedTask = tasks.cloneTask(task);
|
||||
@@ -103,7 +103,7 @@ describe('Tasks Service', function() {
|
||||
});
|
||||
|
||||
it('does not clone original task\'s value', function() {
|
||||
var task = newTask({
|
||||
var task = specHelper.newTask({
|
||||
value: 130
|
||||
});
|
||||
var clonedTask = tasks.cloneTask(task);
|
||||
@@ -116,7 +116,7 @@ describe('Tasks Service', function() {
|
||||
context('Habits', function() {
|
||||
|
||||
it('clones a habit', function() {
|
||||
var habit = newHabit({
|
||||
var habit = specHelper.newHabit({
|
||||
up: true,
|
||||
down: false
|
||||
});
|
||||
@@ -131,7 +131,7 @@ describe('Tasks Service', function() {
|
||||
context('Dailys', function() {
|
||||
|
||||
it('clones a daily', function() {
|
||||
var daily = newDaily({
|
||||
var daily = specHelper.newDaily({
|
||||
frequency: 'daily',
|
||||
everyX: 3,
|
||||
startDate: new Date(2014, 5, 1, 1, 1, 1, 1),
|
||||
@@ -146,7 +146,7 @@ describe('Tasks Service', function() {
|
||||
});
|
||||
|
||||
it('does not clone streak', function() {
|
||||
var daily = newDaily({
|
||||
var daily = specHelper.newDaily({
|
||||
streak: 11
|
||||
});
|
||||
|
||||
@@ -159,14 +159,14 @@ describe('Tasks Service', function() {
|
||||
context('Todos', function() {
|
||||
|
||||
it('clones a todo', function() {
|
||||
var todo = newTodo();
|
||||
var todo = specHelper.newTodo();
|
||||
var clonedTodo = tasks.cloneTask(todo);
|
||||
|
||||
expect(clonedTodo.type).to.eql('todo');
|
||||
});
|
||||
|
||||
it('does not clone due date', function() {
|
||||
var todo = newTodo({
|
||||
var todo = specHelper.newTodo({
|
||||
date: '2015-06-20'
|
||||
});
|
||||
|
||||
@@ -176,7 +176,7 @@ describe('Tasks Service', function() {
|
||||
});
|
||||
|
||||
it('does not clone date completed', function() {
|
||||
var todo = newTodo({
|
||||
var todo = specHelper.newTodo({
|
||||
dateCompleted: new Date()
|
||||
});
|
||||
|
||||
@@ -189,14 +189,14 @@ describe('Tasks Service', function() {
|
||||
context('Rewards', function() {
|
||||
|
||||
it('clones a reward', function() {
|
||||
var reward = newReward();
|
||||
var reward = specHelper.newReward();
|
||||
var clonedReward = tasks.cloneTask(reward);
|
||||
|
||||
expect(clonedReward.type).to.eql('reward');
|
||||
});
|
||||
|
||||
it('does clone a reward\'s value', function() {
|
||||
var reward = newReward({
|
||||
it('does clone a reward\'s vaue', function() {
|
||||
var reward = specHelper.newReward({
|
||||
value: 20
|
||||
});
|
||||
var clonedReward = tasks.cloneTask(reward);
|
||||
@@ -207,7 +207,7 @@ describe('Tasks Service', function() {
|
||||
|
||||
context('complete', function() {
|
||||
it('does not clone completed status', function() {
|
||||
var todo = newTodo({
|
||||
var todo = specHelper.newTodo({
|
||||
completed: true
|
||||
});
|
||||
|
||||
@@ -220,7 +220,7 @@ describe('Tasks Service', function() {
|
||||
context('history', function() {
|
||||
|
||||
it('does not clone history', function() {
|
||||
var habit = newHabit({
|
||||
var habit = specHelper.newHabit({
|
||||
history: [
|
||||
{ date: Date.now, value: 3.1 },
|
||||
{ date: Date.now, value: 2.7 }
|
||||
@@ -236,7 +236,7 @@ describe('Tasks Service', function() {
|
||||
context('checklists', function() {
|
||||
|
||||
it('clones checklist text', function() {
|
||||
var todo = newTodo({
|
||||
var todo = specHelper.newTodo({
|
||||
checklist: [{
|
||||
completed: true,
|
||||
text: 'checklist 1',
|
||||
@@ -255,7 +255,7 @@ describe('Tasks Service', function() {
|
||||
});
|
||||
|
||||
it('does not clone complete or id attribute of checklist', function() {
|
||||
var todo = newTodo({
|
||||
var todo = specHelper.newTodo({
|
||||
checklist: [{
|
||||
completed: true,
|
||||
text: 'checklist 1',
|
||||
|
||||
@@ -7,7 +7,7 @@ describe('userServices', function() {
|
||||
|
||||
beforeEach(function(){
|
||||
module(function($provide){
|
||||
$window = {href: '', alert: sinon.spy(), location: {search: '', pathname: ''}};
|
||||
$window = {href: '', alert: sandbox.spy(), location: {search: '', pathname: ''}};
|
||||
$provide.value('$window', $window);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,144 +1,156 @@
|
||||
beforeEach(module('habitrpg'));
|
||||
|
||||
function newUser() {
|
||||
var buffs = {per:0, int:0, con:0, str:0, stealth: 0, streaks: false};
|
||||
user = {
|
||||
auth:{timestamps: {}},
|
||||
stats: {str:1, con:1, per:1, int:1, mp: 32, class: 'warrior', buffs: buffs, gp: 0},
|
||||
items:{
|
||||
lastDrop:{count: 0},
|
||||
hatchingPotions: {},
|
||||
eggs: {},
|
||||
food: {},
|
||||
pets: {},
|
||||
mounts: {},
|
||||
gear: {equipped: {}, costume: {}, owned: {}},
|
||||
},
|
||||
party: {
|
||||
quest: {
|
||||
progress: {down: 0}
|
||||
}
|
||||
},
|
||||
preferences: {},
|
||||
dailys: [],
|
||||
todos: [],
|
||||
rewards: [],
|
||||
flags: {},
|
||||
filters: {},
|
||||
achievements: {},
|
||||
};
|
||||
return user;
|
||||
}
|
||||
var sandbox;
|
||||
beforeEach(function() {
|
||||
sandbox = sinon.sandbox.create();
|
||||
});
|
||||
|
||||
function newGroup(leader) {
|
||||
var quest = { progress: { }, active: false };
|
||||
group = {
|
||||
"leader" : leader,
|
||||
"quest" : quest,
|
||||
"memberCount" : 1,
|
||||
"chat" : [],
|
||||
"privacy" : "public",
|
||||
"invites" : [],
|
||||
"members" : [
|
||||
leader
|
||||
]
|
||||
};
|
||||
return group;
|
||||
}
|
||||
afterEach(function() {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
function newTask(overrides) {
|
||||
var task = {
|
||||
id: 'task-id',
|
||||
_id: 'task-id',
|
||||
dateCreated: Date.now,
|
||||
text: 'task text',
|
||||
notes: 'task notes',
|
||||
tags: { },
|
||||
value: 0,
|
||||
priority: 1,
|
||||
attribute: 'str',
|
||||
challenge: { }
|
||||
};
|
||||
var specHelper = {};
|
||||
|
||||
for(var key in overrides) {
|
||||
task[key] = overrides[key];
|
||||
(function(){
|
||||
|
||||
specHelper.newUser = newUser;
|
||||
specHelper.newGroup = newGroup;
|
||||
specHelper.newTask = newTask;
|
||||
specHelper.newHabit = newHabit;
|
||||
specHelper.newDaily = newDaily;
|
||||
specHelper.newTodo = newTodo;
|
||||
specHelper.newReward = newReward;
|
||||
|
||||
function newUser() {
|
||||
var buffs = {per:0, int:0, con:0, str:0, stealth: 0, streaks: false};
|
||||
user = {
|
||||
auth:{timestamps: {}},
|
||||
stats: {str:1, con:1, per:1, int:1, mp: 32, class: 'warrior', buffs: buffs, gp: 0},
|
||||
items:{
|
||||
lastDrop:{count: 0},
|
||||
hatchingPotions: {},
|
||||
eggs: {},
|
||||
food: {},
|
||||
pets: {},
|
||||
mounts: {},
|
||||
gear: {equipped: {}, costume: {}, owned: {}},
|
||||
},
|
||||
party: {
|
||||
quest: {
|
||||
progress: {down: 0}
|
||||
}
|
||||
},
|
||||
preferences: {},
|
||||
dailys: [],
|
||||
todos: [],
|
||||
rewards: [],
|
||||
flags: {},
|
||||
filters: {},
|
||||
achievements: {},
|
||||
};
|
||||
return user;
|
||||
}
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
function newHabit(overrides) {
|
||||
var habit = newTask();
|
||||
habit.type = 'habit';
|
||||
habit.history = [];
|
||||
habit.up = true;
|
||||
habit.down = true;
|
||||
|
||||
for(var key in overrides) {
|
||||
habit[key] = overrides[key];
|
||||
function newGroup(leader) {
|
||||
var quest = { progress: { }, active: false };
|
||||
group = {
|
||||
"leader" : leader,
|
||||
"quest" : quest,
|
||||
"memberCount" : 1,
|
||||
"chat" : [],
|
||||
"privacy" : "public",
|
||||
"invites" : [],
|
||||
"members" : [
|
||||
leader
|
||||
]
|
||||
};
|
||||
return group;
|
||||
}
|
||||
|
||||
return habit;
|
||||
}
|
||||
function newTask(overrides) {
|
||||
var task = {
|
||||
id: 'task-id',
|
||||
_id: 'task-id',
|
||||
dateCreated: Date.now,
|
||||
text: 'task text',
|
||||
notes: 'task notes',
|
||||
tags: { },
|
||||
value: 0,
|
||||
priority: 1,
|
||||
attribute: 'str',
|
||||
challenge: { }
|
||||
};
|
||||
|
||||
function newDaily(overrides) {
|
||||
var daily = newTask();
|
||||
daily.type = 'daily';
|
||||
daily.frequency = 'weekly';
|
||||
daily.repeat = {
|
||||
m: true,
|
||||
t: true,
|
||||
w: true,
|
||||
th: true,
|
||||
f: true,
|
||||
s: true,
|
||||
su: true
|
||||
};
|
||||
daily.startDate = Date.now;
|
||||
daily.history = [];
|
||||
daily.completed = false;
|
||||
daily.collapseChecklist = false;
|
||||
daily.checklist = [];
|
||||
daily.streak = 0;
|
||||
for(var key in overrides) {
|
||||
task[key] = overrides[key];
|
||||
}
|
||||
|
||||
for(var key in overrides) {
|
||||
daily[key] = overrides[key];
|
||||
return task;
|
||||
}
|
||||
|
||||
return daily;
|
||||
}
|
||||
function newHabit(overrides) {
|
||||
var habit = newTask();
|
||||
habit.type = 'habit';
|
||||
habit.history = [];
|
||||
habit.up = true;
|
||||
habit.down = true;
|
||||
|
||||
function newTodo(overrides) {
|
||||
var todo = newTask();
|
||||
todo.type = 'todo';
|
||||
todo.completed = false;
|
||||
todo.collapseChecklist = false;
|
||||
todo.checklist = [];
|
||||
for(var key in overrides) {
|
||||
habit[key] = overrides[key];
|
||||
}
|
||||
|
||||
for(var key in overrides) {
|
||||
todo[key] = overrides[key];
|
||||
return habit;
|
||||
}
|
||||
|
||||
return todo;
|
||||
}
|
||||
function newDaily(overrides) {
|
||||
var daily = newTask();
|
||||
daily.type = 'daily';
|
||||
daily.frequency = 'weekly';
|
||||
daily.repeat = {
|
||||
m: true,
|
||||
t: true,
|
||||
w: true,
|
||||
th: true,
|
||||
f: true,
|
||||
s: true,
|
||||
su: true
|
||||
};
|
||||
daily.startDate = Date.now;
|
||||
daily.history = [];
|
||||
daily.completed = false;
|
||||
daily.collapseChecklist = false;
|
||||
daily.checklist = [];
|
||||
daily.streak = 0;
|
||||
|
||||
function newReward(overrides) {
|
||||
var reward = newTask();
|
||||
reward.type = 'reward';
|
||||
for(var key in overrides) {
|
||||
daily[key] = overrides[key];
|
||||
}
|
||||
|
||||
for(var key in overrides) {
|
||||
reward[key] = overrides[key];
|
||||
return daily;
|
||||
}
|
||||
|
||||
return reward;
|
||||
}
|
||||
function newTodo(overrides) {
|
||||
var todo = newTask();
|
||||
todo.type = 'todo';
|
||||
todo.completed = false;
|
||||
todo.collapseChecklist = false;
|
||||
todo.checklist = [];
|
||||
|
||||
specHelper = {
|
||||
newUser: newUser,
|
||||
newGroup: newGroup,
|
||||
newTask: newTask,
|
||||
newHabit: newHabit,
|
||||
newDaily: newDaily,
|
||||
newTodo: newTodo,
|
||||
newRward: newReward
|
||||
}
|
||||
for(var key in overrides) {
|
||||
todo[key] = overrides[key];
|
||||
}
|
||||
|
||||
return todo;
|
||||
}
|
||||
|
||||
function newReward(overrides) {
|
||||
var reward = newTask();
|
||||
reward.type = 'reward';
|
||||
|
||||
for(var key in overrides) {
|
||||
reward[key] = overrides[key];
|
||||
}
|
||||
|
||||
return reward;
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -214,9 +214,10 @@ habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$
|
||||
|
||||
var gems = User.user.balance * 4;
|
||||
|
||||
var string = (type == 'weapon') ? window.env.t('weapon') : (type == 'armor') ? window.env.t('armor') : (type == 'head') ? window.env.t('headgear') : (type == 'shield') ? window.env.t('offhand') : (type == 'headAccessory') ? window.env.t('headAccessory') : (type == 'hatchingPotions') ? window.env.t('hatchingPotion') : (type == 'eggs') ? window.env.t('eggSingular') : (type == 'quests') ? window.env.t('quest') : (item.key == 'Saddle') ? window.env.t('foodSaddleText').toLowerCase() : type; // FIXME this is ugly but temporary, once the purchase modal is done this will be removed
|
||||
var string = (type == 'weapon') ? window.env.t('weapon') : (type == 'armor') ? window.env.t('armor') : (type == 'head') ? window.env.t('headgear') : (type == 'shield') ? window.env.t('offhand') : (type == 'back') ? window.env.t('back') : (type == 'body') ? window.env.t('body') : (type == 'headAccessory') ? window.env.t('headAccessory') : (type == 'eyewear') ? window.env.t('eyewear') : (type == 'hatchingPotions') ? window.env.t('hatchingPotion') : (type == 'eggs') ? window.env.t('eggSingular') : (type == 'quests') ? window.env.t('quest') : (item.key == 'Saddle') ? window.env.t('foodSaddleText').toLowerCase() : type; // FIXME this is ugly but temporary, once the purchase modal is done this will be removed
|
||||
|
||||
var price = ((((item.specialClass == "wizard") && (item.type == "weapon")) || item.gearSet == "animal") + 1);
|
||||
if (type == 'weapon' || type == 'armor' || type == 'head' || type == 'shield' || type == 'headAccessory') {
|
||||
if (type == 'weapon' || type == 'armor' || type == 'head' || type == 'shield' || type == 'headAccessory' || type == 'body' || type == 'back' || type == 'eyewear' ) {
|
||||
if (User.user.items.gear.owned[item.key]) {
|
||||
if (User.user.preferences.costume) return User.user.ops.equip({params:{type: 'costume', key: item.key}});
|
||||
else {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
'use strict';
|
||||
// @see ../routes for routing
|
||||
|
||||
function clone(a) {
|
||||
@@ -195,7 +196,7 @@ api.create = function(req, res, next) {
|
||||
group = user = null;
|
||||
});
|
||||
|
||||
}else{
|
||||
} else{
|
||||
async.waterfall([
|
||||
function(cb){
|
||||
Group.findOne({type:'party',members:{$in:[user._id]}},cb);
|
||||
@@ -210,8 +211,8 @@ api.create = function(req, res, next) {
|
||||
], function(err, populated){
|
||||
if (err == 'Already in a party, try refreshing.') return res.json(400,{err:err});
|
||||
if (err) return next(err);
|
||||
return res.json(populated);
|
||||
group = user = null;
|
||||
return res.json(populated);
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -285,7 +286,7 @@ api.postChat = function(req, res, next) {
|
||||
|
||||
group.save(function(err, saved){
|
||||
if (err) return next(err);
|
||||
return chatUpdated ? res.json({chat: group.chat}) : res.json({message: saved.chat[0]});
|
||||
chatUpdated ? res.json({chat: group.chat}) : res.json({message: saved.chat[0]});
|
||||
group = chatUpdated = null;
|
||||
});
|
||||
}
|
||||
@@ -549,8 +550,8 @@ api.leave = function(req, res, next) {
|
||||
}
|
||||
],function(err){
|
||||
if (err) return next(err);
|
||||
return res.send(204);
|
||||
user = group = keep = null;
|
||||
return res.send(204);
|
||||
})
|
||||
}
|
||||
|
||||
@@ -786,8 +787,8 @@ api.removeMember = function(req, res, next){
|
||||
|
||||
});
|
||||
}else{
|
||||
return res.json(400, {err: "User not found among group's members!"});
|
||||
group = uuid = null;
|
||||
return res.json(400, {err: "User not found among group's members!"});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -795,7 +796,7 @@ api.removeMember = function(req, res, next){
|
||||
// Quests
|
||||
// ------------------------------------
|
||||
|
||||
questStart = function(req, res, next) {
|
||||
function questStart(req, res, next) {
|
||||
var group = res.locals.group;
|
||||
var force = req.query.force;
|
||||
|
||||
|
||||
@@ -99,9 +99,11 @@ api.score = function(req, res, next) {
|
||||
text: req.body && req.body.text,
|
||||
notes: (req.body && req.body.notes) || "This task was created by a third-party service. Feel free to edit, it won't harm the connection to that service. Additionally, multiple services may piggy-back off this task."
|
||||
};
|
||||
task = user.ops.addTask({body:task});
|
||||
|
||||
if (task.type === 'daily' || task.type === 'todo')
|
||||
task.completed = direction === 'up';
|
||||
|
||||
task = user.ops.addTask({body:task});
|
||||
}
|
||||
var delta = user.ops.score({params:{id:task.id, direction:direction}, language: req.language});
|
||||
|
||||
|
||||
@@ -296,7 +296,6 @@ var UserSchema = new Schema({
|
||||
}
|
||||
},
|
||||
preferences: {
|
||||
armorSet: String,
|
||||
dayStart: {type:Number, 'default': 0, min: 0, max: 23},
|
||||
size: {type:String, enum: ['broad','slim'], 'default': 'slim'},
|
||||
hair: {
|
||||
|
||||
@@ -28,32 +28,28 @@ script(type='text/ng-template', id='partials/options.inventory.seasonalshop.html
|
||||
.container-fluid
|
||||
.stable.row
|
||||
.col-md-2
|
||||
.seasonalshop_closed
|
||||
.seasonalshop_summer2015
|
||||
.col-md-10
|
||||
.popover.static-popover.fade.right.in
|
||||
.arrow
|
||||
h3.popover-title!=env.t('seasonalShopClosedTitle', {linkStart:"<a href='http://blog.habitrpg.com/who' target='_blank'>", linkEnd: "</a>"})
|
||||
h3.popover-title!=env.t('seasonalShopTitle', {linkStart:"<a href='http://blog.habitrpg.com/who' target='_blank'>", linkEnd: "</a>"})
|
||||
.popover-content
|
||||
p!=env.t('seasonalShopClosedText', {linkStart:"<a href='http://habitrpg.wikia.com/wiki/Grand_Galas' target='_blank'>", linkEnd: "</a>"})
|
||||
// .well(ng-if='User.user.achievements.rebirths > 0')=env.t('seasonalShopRebirth')
|
||||
// li.customize-menu.inventory-gear
|
||||
menu.pets-menu(label='{{::label}}', ng-repeat='(set,label) in ::{springWarrior:env.t("mightyBunnySet"), springMage:env.t("magicMouseSet"), springHealer:env.t("lovingPupSet"), springRogue:env.t("stealthyKittySet")}')
|
||||
// The `if true || false` conditional for applying the transparent class is necessary because
|
||||
// when a user activates the orb of rebirth, the seasonal items are still in their inventory, but
|
||||
// they have each have a value of false. The item can be purchased for gold in the rewards column,
|
||||
// not the seasonal shop. This makes that more clear.
|
||||
p!=env.t('seasonalShopSummerText')
|
||||
.well(ng-if='User.user.achievements.rebirths > 0')=env.t('seasonalShopRebirth')
|
||||
li.customize-menu.inventory-gear
|
||||
menu.pets-menu(label='{{::label}}', ng-repeat='(set,label) in ::{summerWarrior:env.t("daringSwashbucklerSet"), summerMage:env.t("emeraldMermageSet"), summerHealer:env.t("reefSeahealerSet"), summerRogue:env.t("roguishPirateSet")}')
|
||||
div(ng-repeat='item in ::getSeasonalShopArray(set)' ng-class="{transparent: user.items.gear.owned[item.key] === true ||user.items.gear.owned[item.key] === false}")
|
||||
button.customize-option(popover='{{::item.notes()}}', popover-title='{{::item.text()}}', popover-trigger='mouseenter', popover-placement='right', popover-append-to-body='true', ng-click='purchase(item.type,item)', class='shop_{{::item.key}}')
|
||||
.text-left
|
||||
| {{((item.specialClass == "wizard") && (item.type == "weapon")) + 1}}
|
||||
span.Pet_Currency_Gem1x.inline-gems
|
||||
menu.pets-menu(label=env.t('quests'))
|
||||
// menu.pets-menu(label=env.t('quests'))
|
||||
div(ng-repeat='quest in ::getSeasonalShopQuests()')
|
||||
button.customize-option(data-popover-html="{{::quest.previous && !user.achievements.quests[quest.previous] ? env.t('scrollsPre') : questPopover(quest) | markdown}}", popover-append-to-body='true', popover-title='{{::quest.text()}}', popover-trigger='mouseenter', popover-placement='right', ng-click='buyQuest(quest.key)', ng-class='(quest.previous && !user.achievements.quests[quest.previous]) ? "inventory_quest_scroll_locked inventory_quest_scroll_{{::quest.key}}_locked locked" : "inventory_quest_scroll inventory_quest_scroll_{{::quest.key}}"')
|
||||
p
|
||||
| {{::quest.value}}
|
||||
span.Pet_Currency_Gem1x.inline-gems
|
||||
menu.pets-menu(label=env.t('seasonalItems'))
|
||||
// menu.pets-menu(label=env.t('seasonalItems'))
|
||||
div
|
||||
button.customize-option(popover='{{::Content.spells.special.shinySeed.notes()}}', popover-title='{{::Content.spells.special.shinySeed.text()}}', popover-trigger='mouseenter', popover-placement='right', popover-append-to-body='true', ng-click='purchase("special", Content.spells.special.shinySeed)', class='inventory_special_shinySeed')
|
||||
p
|
||||
|
||||
@@ -1,23 +1,45 @@
|
||||
h5 6/17/2015 - CUTTLEFISH PET QUEST AND QUEST DISPLAY IMPROVEMENTS
|
||||
h5 6/20/2015 - SUMMER SPLASH EVENT: LIMITED EDITION OUTFITS, SEASONAL SHOP OPENS, AND SUMMER NPCS!
|
||||
hr
|
||||
tr
|
||||
td
|
||||
.quest_kraken.pull-right
|
||||
h5 Cuttlefish Pet Quest
|
||||
p A new pet quest is available in the <a href='/#/options/inventory/drops' target='_blank'>Market</a>: The Kraken of Inkomplete! A pleasant day sailing is ruined when a Kraken attacks. Can you strike down the tasks and tentacles that keep cropping up? If so, you'll be awarded with some cuttlefish eggs!
|
||||
p.small.muted art by Lemoness and Wolvenhalo
|
||||
p.small.muted writing by Lemoness
|
||||
h5 Summer Splash Begins!
|
||||
p The Summer Splash festival has arrived, and Habitica has moved to the undersea city of Dilatory for the summer! From today until July 31st, join us for fun in the sun.
|
||||
tr
|
||||
td
|
||||
h5 Quest Display Improvements
|
||||
p Now you can see the details of a pending quest on the Party Page by clicking the new "Quest Details" tab above the quest invitations. We hope this helps you decide whether or not you want to accept the quest!
|
||||
p.small.muted by hairlessbear
|
||||
.promo_summer_classes_2015.pull-right
|
||||
h5 Limited Edition Class Outfits
|
||||
p From now until July 31st, limited edition outfits are available in the Rewards column. Depending on your class, you can be a Reef Renegade, Sunfish Warrior, Strapping Sailor, or Ship Soothsayer! You'd better get productive to earn enough gold before they disappear. Good luck!
|
||||
p.small.muted by Lemoness
|
||||
tr
|
||||
td
|
||||
.promo_summer_classes_2014.pull-right
|
||||
h5 Seasonal Shop Opens
|
||||
p The <a href='/#/options/inventory/seasonalshop'>Seasonal Shop</a> has opened! It's stocking summertime Seasonal Edition goodies at the moment, including last year's summer outfits. Everything there will be available to purchase during the Summer Splash event each year, but it's only open until July 31st, so be sure to stock up now, or you'll have to wait a year to buy these items again.
|
||||
p.small.muted by Lemoness
|
||||
tr
|
||||
td
|
||||
.seasonalshop_summer2015.pull-right
|
||||
h5 Summer NPCs
|
||||
p Looks like the NPCs are really getting in to the summer spirit. Ian, Bailey, Matt, and the Seasonal Sorceress are having fun under the sea in the sunken city of Dilatory, and Alex and Daniel have moved down to the beach. Even the Time Travelers are getting into the fun, although... oh dear... they seem to have overshot the season...
|
||||
p.small.muted by Lemoness
|
||||
|
||||
hr
|
||||
a(href='/static/old-news', target='_blank') Read older news
|
||||
|
||||
mixin oldNews
|
||||
|
||||
h5 6/17/2015 - CUTTLEFISH PET QUEST AND QUEST DISPLAY IMPROVEMENTS
|
||||
tr
|
||||
td
|
||||
.quest_kraken.pull-right
|
||||
h5 Cuttlefish Pet Quest
|
||||
p A new pet quest is available in the <a href='/#/options/inventory/drops' target='_blank'>Market</a>: The Kraken of Inkomplete! A pleasant day sailing is ruined when a Kraken attacks. Can you strike down the tasks and tentacles that keep cropping up? If so, you'll be awarded with some cuttlefish eggs!
|
||||
p.small.muted art by Lemoness and Wolvenhalo
|
||||
p.small.muted writing by Lemoness
|
||||
tr
|
||||
td
|
||||
h5 Quest Display Improvements
|
||||
p Now you can see the details of a pending quest on the Party Page by clicking the new "Quest Details" tab above the quest invitations. We hope this helps you decide whether or not you want to accept the quest!
|
||||
p.small.muted by hairlessbear
|
||||
h5 6/16/2015 - SEARCH BAR, CHALLENGES FILTER, INTERMITTENT REFRESH, AND VISUAL TWEAKS
|
||||
tr
|
||||
td
|
||||
|
||||
@@ -75,8 +75,8 @@ html(ng-app='habitrpg', ng-controller='RootCtrl')
|
||||
a(href='/static/contact')=env.t('contactUs')
|
||||
li
|
||||
button#header-play-button.btn.btn-primary.navbar-btn.navbar-right(ng-click='playButtonClick()')= env.t('playButtonFull')
|
||||
#intro
|
||||
h1(ng-cloak) {{ variant==0 ? "#{env.t('motivate')}" : (variant==1 ? "#{env.t('motivate1')}" : "#{env.t('motivate2')}") }}
|
||||
#intro(ng-cloak)
|
||||
h1 {{ variant==0 ? "#{env.t('motivate')}" : (variant==1 ? "#{env.t('motivate1')}" : "#{env.t('motivate2')}") }}
|
||||
img.center-block.img-responsive(src='https://s3.amazonaws.com/habitrpg-assets/front/images/intro.png')
|
||||
// insert intro images
|
||||
.introcall.bg-success
|
||||
|
||||