Merge branch 'sabrecat/quests-page' into develop
2
common/dist/sprites/habitrpg-shared.css
vendored
190
common/dist/sprites/spritesmith0.css
vendored
|
|
@ -1974,13 +1974,13 @@
|
|||
}
|
||||
.hair_mustache_1_red {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: 0px -888px;
|
||||
background-position: -1092px -1434px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_mustache_1_red {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -25px -903px;
|
||||
background-position: -1117px -1449px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
|
|
@ -1998,13 +1998,13 @@
|
|||
}
|
||||
.hair_mustache_1_white {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1274px -1434px;
|
||||
background-position: 0px -888px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_mustache_1_white {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1299px -1449px;
|
||||
background-position: -25px -903px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
|
|
@ -3990,443 +3990,479 @@
|
|||
}
|
||||
.hair_base_10_brown {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1092px -1434px;
|
||||
background-position: 0px -1889px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_brown {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1117px -1449px;
|
||||
background-position: -25px -1904px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_candycane {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -910px -979px;
|
||||
background-position: -91px -1889px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_candycane {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -935px -994px;
|
||||
background-position: -116px -1904px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_candycorn {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -819px -979px;
|
||||
background-position: -182px -1889px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_candycorn {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -844px -994px;
|
||||
background-position: -207px -1904px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_festive {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -728px -979px;
|
||||
background-position: -1274px -1434px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_festive {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -753px -994px;
|
||||
background-position: -1299px -1449px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_frost {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -637px -979px;
|
||||
background-position: -910px -979px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_frost {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -662px -994px;
|
||||
background-position: -935px -994px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_ghostwhite {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -546px -979px;
|
||||
background-position: -819px -979px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_ghostwhite {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -571px -994px;
|
||||
background-position: -844px -994px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_green {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -455px -979px;
|
||||
background-position: -728px -979px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_green {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -480px -994px;
|
||||
background-position: -753px -994px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_halloween {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -364px -979px;
|
||||
background-position: -637px -979px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_halloween {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -389px -994px;
|
||||
background-position: -662px -994px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_holly {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -273px -979px;
|
||||
background-position: -546px -979px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_holly {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -298px -994px;
|
||||
background-position: -571px -994px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_hollygreen {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -182px -979px;
|
||||
background-position: -455px -979px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_hollygreen {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -207px -994px;
|
||||
background-position: -480px -994px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_midnight {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -91px -979px;
|
||||
background-position: -364px -979px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_midnight {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -116px -994px;
|
||||
background-position: -389px -994px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_pblue {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: 0px -979px;
|
||||
background-position: -273px -979px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_pblue {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -25px -994px;
|
||||
background-position: -298px -994px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_pblue2 {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -990px -819px;
|
||||
background-position: -182px -979px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_pblue2 {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1015px -834px;
|
||||
background-position: -207px -994px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_peppermint {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -990px -728px;
|
||||
background-position: -91px -979px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_peppermint {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1015px -743px;
|
||||
background-position: -116px -994px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_pgreen {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -990px -637px;
|
||||
background-position: 0px -979px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_pgreen {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1015px -652px;
|
||||
background-position: -25px -994px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_pgreen2 {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -990px -546px;
|
||||
background-position: -990px -819px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_pgreen2 {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1015px -561px;
|
||||
background-position: -1015px -834px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_porange {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -990px -455px;
|
||||
background-position: -990px -728px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_porange {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1015px -470px;
|
||||
background-position: -1015px -743px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_porange2 {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -990px -364px;
|
||||
background-position: -990px -637px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_porange2 {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1015px -379px;
|
||||
background-position: -1015px -652px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_ppink {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -990px -273px;
|
||||
background-position: -990px -546px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_ppink {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1015px -288px;
|
||||
background-position: -1015px -561px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_ppink2 {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -990px -182px;
|
||||
background-position: -990px -455px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_ppink2 {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1015px -197px;
|
||||
background-position: -1015px -470px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_ppurple {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -990px -91px;
|
||||
background-position: -990px -364px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_ppurple {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1015px -106px;
|
||||
background-position: -1015px -379px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_ppurple2 {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -990px 0px;
|
||||
background-position: -990px -273px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_ppurple2 {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1015px -15px;
|
||||
background-position: -1015px -288px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_pumpkin {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -819px -888px;
|
||||
background-position: -990px -182px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_pumpkin {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -844px -903px;
|
||||
background-position: -1015px -197px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_purple {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -728px -888px;
|
||||
background-position: -990px -91px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_purple {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -753px -903px;
|
||||
background-position: -1015px -106px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_pyellow {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -637px -888px;
|
||||
background-position: -990px 0px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_pyellow {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -662px -903px;
|
||||
background-position: -1015px -15px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_pyellow2 {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -546px -888px;
|
||||
background-position: -819px -888px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_pyellow2 {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -571px -903px;
|
||||
background-position: -844px -903px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_rainbow {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -455px -888px;
|
||||
background-position: -728px -888px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_rainbow {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -480px -903px;
|
||||
background-position: -753px -903px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_red {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -364px -888px;
|
||||
background-position: -637px -888px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_red {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -389px -903px;
|
||||
background-position: -662px -903px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_snowy {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -273px -888px;
|
||||
background-position: -546px -888px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_snowy {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -298px -903px;
|
||||
background-position: -571px -903px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_white {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -182px -888px;
|
||||
background-position: -455px -888px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_white {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -207px -903px;
|
||||
background-position: -480px -903px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_winternight {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -91px -888px;
|
||||
background-position: -364px -888px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_winternight {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -116px -903px;
|
||||
background-position: -389px -903px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_winterstar {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1081px -455px;
|
||||
background-position: -273px -888px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_winterstar {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1106px -470px;
|
||||
background-position: -298px -903px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_yellow {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1081px -364px;
|
||||
background-position: -182px -888px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_yellow {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1106px -379px;
|
||||
background-position: -207px -903px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_10_zombie {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1081px -273px;
|
||||
background-position: -91px -888px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_10_zombie {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1106px -288px;
|
||||
background-position: -116px -903px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_11_TRUred {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1081px -182px;
|
||||
background-position: -1081px -455px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_11_TRUred {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1106px -197px;
|
||||
background-position: -1106px -470px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_11_aurora {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1081px -91px;
|
||||
background-position: -1081px -364px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_11_aurora {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1106px -106px;
|
||||
background-position: -1106px -379px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_11_black {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1081px 0px;
|
||||
background-position: -1081px -273px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_11_black {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1106px -288px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_11_blond {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1081px -182px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_11_blond {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1106px -197px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_11_blue {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1081px -91px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_11_blue {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1106px -106px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.hair_base_11_brown {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1081px 0px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.customize-option.hair_base_11_brown {
|
||||
background-image: url(spritesmith0.png);
|
||||
background-position: -1106px -15px;
|
||||
width: 60px;
|
||||
|
|
|
|||
BIN
common/dist/sprites/spritesmith0.png
vendored
|
Before Width: | Height: | Size: 220 KiB After Width: | Height: | Size: 221 KiB |
5780
common/dist/sprites/spritesmith1.css
vendored
BIN
common/dist/sprites/spritesmith1.png
vendored
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
5410
common/dist/sprites/spritesmith2.css
vendored
BIN
common/dist/sprites/spritesmith2.png
vendored
|
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 109 KiB |
924
common/dist/sprites/spritesmith3.css
vendored
BIN
common/dist/sprites/spritesmith3.png
vendored
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 88 KiB |
986
common/dist/sprites/spritesmith4.css
vendored
BIN
common/dist/sprites/spritesmith4.png
vendored
|
Before Width: | Height: | Size: 533 KiB After Width: | Height: | Size: 554 KiB |
924
common/dist/sprites/spritesmith5.css
vendored
BIN
common/dist/sprites/spritesmith5.png
vendored
|
Before Width: | Height: | Size: 231 KiB After Width: | Height: | Size: 234 KiB |
1352
common/dist/sprites/spritesmith6.css
vendored
BIN
common/dist/sprites/spritesmith6.png
vendored
|
Before Width: | Height: | Size: 197 KiB After Width: | Height: | Size: 199 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 3 KiB |
|
After Width: | Height: | Size: 3 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 696 B |
BIN
common/img/sprites/spritesmith/promo/promo_dilatoryDistress.png
Normal file
|
After Width: | Height: | Size: 4 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 7.3 KiB |
|
After Width: | Height: | Size: 7.2 KiB |
|
After Width: | Height: | Size: 7.3 KiB |
|
After Width: | Height: | Size: 7.2 KiB |
|
After Width: | Height: | Size: 7.2 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 7.3 KiB |
|
After Width: | Height: | Size: 7.3 KiB |
|
After Width: | Height: | Size: 7.3 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 683 B |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
|
@ -74,6 +74,8 @@
|
|||
"weaponSpecial3Notes": "Meetings, monsters, malaise: managed! Mash! Increases Strength, Intelligence, and Constitution by <%= attrs %> each.",
|
||||
"weaponSpecialCriticalText": "Critical Hammer of Bug-Crushing",
|
||||
"weaponSpecialCriticalNotes": "This champion slew a critical Github foe where many warriors fell. Fashioned from the bones of Bug, this hammer deals a mighty critical hit. Increases Strength and Perception by <%= attrs %> each.",
|
||||
"weaponSpecialTridentOfCrashingTidesText": "Trident of Crashing Tides",
|
||||
"weaponSpecialTridentOfCrashingTidesNotes": "Gives you the ability to command fish, and also deliver some mighty stabs to your tasks. Increases Intelligence by <%= int %>.",
|
||||
|
||||
"weaponSpecialYetiText": "Yeti-Tamer Spear",
|
||||
"weaponSpecialYetiNotes": "This spear allows its user to command any yeti. Increases Strength by <%= str %>. Limited Edition 2013-2014 Winter Gear.",
|
||||
|
|
@ -151,6 +153,8 @@
|
|||
"weaponArmoireBasicCrossbowNotes": "This crossbow can pierce a task's armor from very far away! Increases Strength by <%= str %>, Perception by <%= per %>, and Constitution by <%= con %>. Enchanted Armoire: Independent Item.",
|
||||
"weaponArmoireLunarSceptreText": "Soothing Lunar Sceptre",
|
||||
"weaponArmoireLunarSceptreNotes": "The healing power of this wand waxes and wanes. Increases Constitution by <%= con %> and Intelligence by <%= int %>. Enchanted Armoire: Soothing Lunar Set (Item 3 of 3).",
|
||||
"weaponArmoireRancherLassoText": "Rancher Lasso",
|
||||
"weaponArmoireRancherLassoNotes": "Lassos: the ideal tool for rounding up and wrangling. Increases Strength by <%= str %>, Perception by <%= per %>, and Intelligence by <%= int %>. Enchanted Armoire: Rancher Set (Item 3 of 3).",
|
||||
|
||||
"armor": "armor",
|
||||
|
||||
|
|
@ -207,6 +211,8 @@
|
|||
"armorSpecial1Notes": "Its tireless power inures the wearer to mundane discomfort. Increases all attributes by <%= attrs %>.",
|
||||
"armorSpecial2Text": "Jean Chalard's Noble Tunic",
|
||||
"armorSpecial2Notes": "Makes you extra fluffy! Increases Constitution and Intelligence by <%= attrs %> each.",
|
||||
"armorSpecialFinnedOceanicArmorText": "Finned Oceanic Armor",
|
||||
"armorSpecialFinnedOceanicArmorNotes": "Although delicate, this armor makes your skin as harmful to the touch as a fire coral. Increases Strength by <%= str %>.",
|
||||
|
||||
"armorSpecialYetiText": "Yeti-Tamer Robe",
|
||||
"armorSpecialYetiNotes": "Fuzzy and fierce. Increases Constitution by <%= con %>. Limited Edition 2013-2014 Winter Gear.",
|
||||
|
|
@ -311,6 +317,8 @@
|
|||
"armorArmoireLunarArmorNotes": "The light of the moon will make you strong and savvy. Increases Strength by <%= str %> and Intelligence by <%= int %>. Enchanted Armoire: Soothing Lunar Set (Item 2 of 3).",
|
||||
"armorArmoireGladiatorArmorText": "Gladiator Armor",
|
||||
"armorArmoireGladiatorArmorNotes": "To be a gladiator you must be not only cunning... but strong. Increases Perception by <%= per %> and Strength by <%= str %>. Enchanted Armoire: Gladiator Set (Item 2 of 3).",
|
||||
"armorArmoireRancherRobesText": "Rancher Robes",
|
||||
"armorArmoireRancherRobesNotes": "Wrangle your mounts and round up your pets while wearing these magical Rancher Robes! Increases Strength by <%= str %>, Perception by <%= per %>, and Intelligence by <%= int %>. Enchanted Armoire: Rancher Set (Item 2 of 3).",
|
||||
|
||||
"headgear": "headgear",
|
||||
|
||||
|
|
@ -367,6 +375,8 @@
|
|||
"headSpecial1Notes": "The favored crown of those who lead by example. Increases all attributes by <%= attrs %>.",
|
||||
"headSpecial2Text": "Nameless Helm",
|
||||
"headSpecial2Notes": "A testament to those who gave of themselves while asking nothing in return. Increases Intelligence and Strength by <%= attrs %> each.",
|
||||
"headSpecialFireCoralCircletText": "Fire Coral Circlet",
|
||||
"headSpecialFireCoralCircletNotes": "This circlet, designed by Habitica's greatest alchemists, allows you to breathe water and dive for treasure! Increases Perception by <%= per %>.",
|
||||
|
||||
"headSpecialNyeText": "Absurd Party Hat",
|
||||
"headSpecialNyeNotes": "You've received an Absurd Party Hat! Wear it with pride while ringing in the New Year! Confers no benefit.",
|
||||
|
|
@ -464,13 +474,17 @@
|
|||
"headArmoireLunarCrownText": "Soothing Lunar Crown",
|
||||
"headArmoireLunarCrownNotes": "This crown strengthens health and sharpens senses, especially when the moon is full. Increases Constitution by <%= con %> and Perception by <%= per %>. Enchanted Armoire: Soothing Lunar Set (Item 1 of 3).",
|
||||
"headArmoireRedHairbowText": "Red Hairbow",
|
||||
"headArmoireRedHairbowNotes": "Become strong, tough and smart while wearing this beautiful Red Hairbow! Increases Strength by <%= str %>, Constitution by <%= con %>, and Intelligence by <%= int %>. Enchanted Armoire: Independent Item.",
|
||||
"headArmoireRedHairbowNotes": "Become strong, tough, and smart while wearing this beautiful Red Hairbow! Increases Strength by <%= str %>, Constitution by <%= con %>, and Intelligence by <%= int %>. Enchanted Armoire: Independent Item.",
|
||||
"headArmoireVioletFloppyHatText": "Violet Floppy Hat",
|
||||
"headArmoireVioletFloppyHatNotes": "Many spells have been sewn into this simple hat, giving it a pleasing purple color. Increases Perception by <%= per %>, Intelligence by <%= int %>, and Constitution by <%= con %>. Enchanted Armoire: Independent Item.",
|
||||
"headArmoireGladiatorHelmText": "Gladiator Helm",
|
||||
"headArmoireGladiatorHelmNotes": "To be a gladiator you must be not only strong.... but cunning. Increases Intelligence by <%= int %> and Perception by <%= per %>. Enchanted Armoire: Gladiator Set (Item 1 of 3).",
|
||||
"headArmoireRancherHatText": "Rancher Hat",
|
||||
"headArmoireRancherHatNotes": "Round up your pets and wrangle your mounts while wearing this magical Rancher Hat! Increases Strength by <%= str %>, Perception by <%= per %>, and Intelligence by <%= int %>. Enchanted Armoire: Independent Item.",
|
||||
"headArmoireRancherHatNotes": "Round up your pets and wrangle your mounts while wearing this magical Rancher Hat! Increases Strength by <%= str %>, Perception by <%= per %>, and Intelligence by <%= int %>. Enchanted Armoire: Rancher Set (Item 1 of 3).",
|
||||
"headArmoireBlueHairbowText": "Blue Hairbow",
|
||||
"headArmoireBlueHairbowNotes": "Become perceptive, tough, and smart while wearing this beautiful Blue Hairbow! Increases Perception by <%= per %>, Constitution by <%= con %>, and Intelligence by <%= int %>. Enchanted Armoire: Independent Item.",
|
||||
"headArmoireRoyalCrownText": "Royal Crown",
|
||||
"headArmoireRoyalCrownNotes": "Hooray for the ruler, mighty and strong! Increases Strength by <%= str %>. Enchanted Armoire: Independent Item.",
|
||||
|
||||
"offhand": "shield-hand item",
|
||||
|
||||
|
|
@ -503,6 +517,8 @@
|
|||
"shieldSpecial0Notes": "Sees beyond the veil of death, and displays what it finds there for enemies to fear. Increases Perception by <%= per %>.",
|
||||
"shieldSpecial1Text": "Crystal Shield",
|
||||
"shieldSpecial1Notes": "Shatters arrows and deflects the words of naysayers. Increases all attributes by <%= attrs %>.",
|
||||
"shieldSpecialMoonpearlShieldText": "Moonpearl Shield",
|
||||
"shieldSpecialMoonpearlShieldNotes": "Designed for fast swimming, and also some defense. Increases Constitution by <%= con %>.",
|
||||
|
||||
"shieldSpecialGoldenknightText": "Mustaine's Milestone Mashing Morning Star",
|
||||
"shieldSpecialGoldenknightNotes": "Meetings, monsters, malaise: managed! Mash! Increases Constitution and Perception by <%= attrs %> each.",
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
"sellPotionForGold": "Sell <%= itemType %> Potion for <%= gold %> Gold",
|
||||
"buyGems": "Buy Gems",
|
||||
"justin": "Justin",
|
||||
"ian": "Ian",
|
||||
"ianText": "Welcome to the Quest Shop! Here you can use Quest Scrolls to battle monsters with your friends. Be sure to check out our fine array of Quest Scrolls for purchase on the right!",
|
||||
"USD": "USD",
|
||||
"newStuff": "New Stuff",
|
||||
"cool": "Tell Me Later",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
{
|
||||
"quests": "Quests",
|
||||
"quest": "quest",
|
||||
"yourQuests": "Your Quests",
|
||||
"questsForSale": "Quests for Sale",
|
||||
"petQuests": "Pet and Mount Quests",
|
||||
"unlockableQuests": "Unlockable Quests",
|
||||
"goldQuests": "Gold-Purchasable Quests",
|
||||
"questDetails": "Quest Details",
|
||||
"invitations": "Invitations",
|
||||
"completed": "Completed!",
|
||||
|
|
@ -37,11 +42,13 @@
|
|||
"noScrolls": "You don't have any quest scrolls.",
|
||||
"scrollsText1": "Quests require parties. If you want to quest solo,",
|
||||
"scrollsText2": "create an empty party",
|
||||
"scrollsPre": "You need to complete the previous quest to start this one!",
|
||||
"scrollsPre": "You haven't unlocked this quest yet!",
|
||||
"completedQuests": "Completed the following quests",
|
||||
"mustComplete": "You must first complete <%= quest %>.",
|
||||
"mustLevel": "You must be level <%= level %>.",
|
||||
"mustLvlQuest": "You must be level <%= level %> to buy this quest!",
|
||||
"mustInviteFriend": "To earn this Quest, invite a friend to your Party. Invite someone now?",
|
||||
"unlockByQuesting": "To earn this Quest, complete <%= title %>.",
|
||||
"sureCancel": "Are you sure you want to cancel this quest? All invitation acceptances will be lost. The quest owner will retain possession of the quest scroll.",
|
||||
"sureAbort": "Are you sure you want to abort this mission? It will abort it for everyone in your party and all progress will be lost. The quest scroll will be returned to the quest owner.",
|
||||
"doubleSureAbort": "Are you double sure? Make sure they won't hate you forever!",
|
||||
|
|
|
|||
|
|
@ -68,17 +68,17 @@
|
|||
"questSpiderDropSpiderEgg": "Spider (Egg)",
|
||||
"questSpiderUnlockText": "Unlocks purchasable spider eggs in the Market",
|
||||
|
||||
"questVice1Text": "Free Yourself of the Dragon's Influence",
|
||||
"questVice1Text": "Vice, Part 1: Free Yourself of the Dragon's Influence",
|
||||
"questVice1Notes": "<p>They say there lies a terrible evil in the caverns of Mt. Habitica. A monster whose presence twists the wills of the strong heroes of the land, turning them towards bad habits and laziness! The beast is a grand dragon of immense power and comprised of the shadows themselves: Vice, the treacherous Shadow Wyrm. Brave Habiteers, stand up and defeat this foul beast once and for all, but only if you believe you can stand against its immense power. </p><h3>Vice Part 1: </h3><p>How can you expect to fight the beast if it already has control over you? Don't fall victim to laziness and vice! Work hard to fight against the dragon's dark influence and dispel his hold on you! </p>",
|
||||
"questVice1Boss": "Vice's Shade",
|
||||
"questVice1DropVice2Quest": "Vice Part 2 (Scroll)",
|
||||
|
||||
"questVice2Text": "Find the Lair of the Wyrm",
|
||||
"questVice2Text": "Vice, Part 2: Find the Lair of the Wyrm",
|
||||
"questVice2Notes": "With Vice's influence over you dispelled, you feel a surge of strength you didn't know you had return to you. Confident in yourselves and your ability to withstand the wyrm's influence, your party makes its way to Mt. Habitica. You approach the entrance to the mountain's caverns and pause. Swells of shadows, almost like fog, wisp out from the opening. It is near impossible to see anything in front of you. The light from your lanterns seem to end abruptly where the shadows begin. It is said that only magical light can pierce the dragon's infernal haze. If you can find enough light crystals, you could make your way to the dragon.",
|
||||
"questVice2CollectLightCrystal": "Light Crystals",
|
||||
"questVice2DropVice3Quest": "Vice Part 3 (Scroll)",
|
||||
|
||||
"questVice3Text": "Vice Awakens",
|
||||
"questVice3Text": "Vice, Part 3: Vice Awakens",
|
||||
"questVice3Notes": "After much effort, your party has discovered Vice's lair. The hulking monster eyes your party with distaste. As shadows swirl around you, a voice whispers through your head, \"More foolish citizens of Habitica come to stop me? Cute. You'd have been wise not to come.\" The scaly titan rears back its head and prepares to attack. This is your chance! Give it everything you've got and defeat Vice once and for all!",
|
||||
"questVice3Completion": "The shadows dissipate from the cavern and a steely silence falls. My word, you've done it! You have defeated Vice! You and your party may finally breath a sigh of relief. Enjoy your victory, brave Habiteers, but take the lessons you've learned from battling Vice and move forward. There are still Habits to be done and potentially worse evils to conquer!",
|
||||
"questVice3Boss": "Vice, the Shadow Wyrm",
|
||||
|
|
@ -86,34 +86,34 @@
|
|||
"questVice3DropDragonEgg": "Dragon (Egg)",
|
||||
"questVice3DropShadeHatchingPotion": "Shade Hatching Potion",
|
||||
|
||||
"questMoonstone1Text": "The Moonstone Chain",
|
||||
"questMoonstone1Text": "The Moonstone Chain, Part 1: The Moonstone Chain",
|
||||
"questMoonstone1Notes": "<p>A terrible affliction has struck Habiticans. Bad Habits thought long-dead are rising back up with a vengeance. Dishes lie unwashed, textbooks linger unread, and procrastination runs rampant!</p><br/><p>You track some of your own returning Bad Habits to the Swamps of Stagnation and discover the culprit: the ghostly Necromancer, Recidivate. You rush in, weapons swinging, but they slide through her specter uselessly.</p><br/><p>\"Don’t bother,\" she hisses with a dry rasp. \"Without a chain of moonstones, nothing can harm me – and master jeweler @aurakami scattered all the moonstones across Habitica long ago!\" Panting, you retreat... but you know what you must do.</p>",
|
||||
"questMoonstone1CollectMoonstone": "Moonstones",
|
||||
"questMoonstone1DropMoonstone2Quest": "The Moonstone Chain Part 2: Recidivate the Necromancer (Scroll)",
|
||||
|
||||
"questMoonstone2Text": "Recidivate The Necromancer",
|
||||
"questMoonstone2Text": "The Moonstone Chain, Part 2: Recidivate The Necromancer",
|
||||
"questMoonstone2Notes": "<p>The brave weaponsmith @Inventrix helps you fashion the enchanted moonstones into a chain. You’re ready to confront Recidivate at last, but as you enter the Swamps of Stagnation, a terrible chill sweeps over you.</p><br/><p>Rotting breath whispers in your ear. \"Back again? How delightful...\" You spin and lunge, and under the light of the moonstone chain, your weapon strikes solid flesh. \"You may have bound me to the world once more,\" Recidivate snarls, \"but now it is time for you to leave it!\"</p>",
|
||||
"questMoonstone2Boss": "The Necromancer",
|
||||
"questMoonstone2DropMoonstone3Quest": "The Moonstone Chain Part 3: Recidivate Transformed (Scroll)",
|
||||
|
||||
"questMoonstone3Text": "Recidivate Transformed",
|
||||
"questMoonstone3Text": "The Moonstone Chain, Part 3: Recidivate Transformed",
|
||||
"questMoonstone3Notes": "<p>Recidivate crumples to the ground, and you strike at her with the moonstone chain. To your horror, Recidivate seizes the gems, eyes burning with triumph.</p><br/><p>\"Foolish creature of flesh!\" she shouts. \"These moonstones will restore me to a physical form, true, but not as you imagined. As the full moon waxes from the dark, so too does my power flourish, and from the shadows I summon the specter of your most feared foe!\"</p><br/><p>A sickly green fog rises from the swamp, and Recidivate’s body writhes and contorts into a shape that fills you with dread – the undead body of Vice, horribly reborn.</p>",
|
||||
"questMoonstone3Completion": "<p>Your breath comes hard and sweat stings your eyes as the undead Wyrm collapses. The remains of Recidivate dissipate into a thin grey mist that clears quickly under the onslaught of a refreshing breeze, and you hear the distant, rallying cries of Habiticans defeating their Bad Habits for once and for all.</p><br/><p>@Baconsaur the beast master swoops down on a gryphon. \"I saw the end of your battle from the sky, and I was greatly moved. Please, take this enchanted tunic – your bravery speaks of a noble heart, and I believe you were meant to have it.\"</p>",
|
||||
"questMoonstone3Boss": "Necro-Vice",
|
||||
"questMoonstone3DropRottenMeat": "Rotten Meat (Food)",
|
||||
"questMoonstone3DropZombiePotion": "Zombie Hatching Potion",
|
||||
|
||||
"questGoldenknight1Text": "A Stern Talking-To",
|
||||
"questGoldenknight1Text": "The Golden Knight, Part 1: A Stern Talking-To",
|
||||
"questGoldenknight1Notes": "<p>The Golden Knight has been getting on poor Habiticans' cases. Didn't do all of your Dailies? Checked off a negative Habit? She will use this as a reason to harass you about how you should follow her example. She is the shining example of a perfect Habitican, and you are naught but a failure. Well, that is not nice at all! Everyone makes mistakes. They should not have to be met with such negativity for it. Perhaps it is time you gather some testimonies from hurt Habiticans and give the Golden Knight a stern talking-to!</p>",
|
||||
"questGoldenknight1CollectTestimony": "Testimonies",
|
||||
"questGoldenknight1DropGoldenknight2Quest": "The Golden Knight Chain Part 2: Tarnished Gold (Scroll)",
|
||||
|
||||
"questGoldenknight2Text": "Gold Knight",
|
||||
"questGoldenknight2Text": "The Golden Knight, Part 2: Gold Knight",
|
||||
"questGoldenknight2Notes": "<p>Armed with hundreds of Habitican's testimonies, you finally confront the Golden Knight. You begin to recite the Habitcan's complaints to her, one by one. \"And @Pfeffernusse says that your constant bragging-\" The knight raises her hand to silence you and scoffs, \"Please, these people are merely jealous of my success. Instead of complaining, they should simply work as hard as I! Perhaps I shall show you the power you can attain through diligence such as mine!\" She raises her morningstar and prepares to attack you!</p>",
|
||||
"questGoldenknight2Boss": "Gold Knight",
|
||||
"questGoldenknight2DropGoldenknight3Quest": "The Golden Knight Chain Part 3: The Iron Knight (Scroll)",
|
||||
|
||||
"questGoldenknight3Text": "The Iron Knight",
|
||||
"questGoldenknight3Text": "The Golden Knight, Part 3: The Iron Knight",
|
||||
"questGoldenknight3Notes": "<p>@Jon Arinbjorn cries out to you to get your attention. In the aftermath of your battle, a new figure has appeared. A knight coated in stained-black iron slowly approaches you with sword in hand. The Golden Knight shouts to the figure, \"Father, no!\" but knight shows no signs of stopping. She turns to you and says, \"I am sorry. I have been a fool, with a head too big to see how cruel I have been. But my father is crueler than I could ever be. If he isn't stopped he'll destroy us all. Here, use my morningstar and halt the Iron Knight!\"</p>",
|
||||
"questGoldenknight3Completion": "<p>With a satisfying clang, the Iron Knight falls to his knees and slumps over. \"You are quite strong,\" he pants. \"I have been humbled, today.\" The Golden Knight approaches you and says, \"Thank you. I believe we have gained some humility from our encounter with you. I will speak with my father and explain the complaints against us. Perhaps, we should begin apologizing to the other Habiticans.\" She mulls over in thought before turning back to you. \"Here: as our gift to you, I want you to keep my morningstar. It is yours now.\"</p>",
|
||||
"questGoldenknight3Boss": "The Iron Knight",
|
||||
|
|
@ -151,17 +151,17 @@
|
|||
"questSeahorseDropSeahorseEgg": "Seahorse (Egg)",
|
||||
"questSeahorseUnlockText": "Unlocks purchasable seahorse eggs in the Market",
|
||||
|
||||
"questAtom1Text": "Attack of the Mundane Questline, Pt. 1: Dish Disaster!",
|
||||
"questAtom1Text": "Attack of the Mundane, Part 1: Dish Disaster!",
|
||||
"questAtom1Notes": "You reach the shores of Washed-Up Lake for some well-earned relaxation... But the lake is polluted with unwashed dishes! How did this happen? Well, you simply cannot allow the lake to be in this state. There is only one thing you can do: clean the dishes and save your vacation spot! Better find some soap to clean up this mess. A lot of soap...",
|
||||
"questAtom1CollectSoapBars": "Bars of Soap",
|
||||
"questAtom1Drop": "The SnackLess Monster (Scroll)",
|
||||
"questAtom1Drop": "The SnackLess Monster (Quest Scroll)",
|
||||
|
||||
"questAtom2Text": "Attack of the Mundane Questline, Pt. 2: The SnackLess Monster",
|
||||
"questAtom2Text": "Attack of the Mundane, Part 2: The SnackLess Monster",
|
||||
"questAtom2Notes": "Phew, this place is looking a lot nicer with all these dishes cleaned. Maybe, you can finally have some fun now. Oh - there seems to be a pizza box floating in the lake. Well, what's one more thing to clean really? But alas, it is no mere pizza box! With a sudden rush the box lifts from the water to reveal itself to be the head of a monster. It cannot be! The fabled SnackLess Monster?! It is said it has existed hidden in the lake since prehistoric times: a creature spawned from the leftover food and trash of the ancient Habiticans. Yuck!",
|
||||
"questAtom2Boss": "The SnackLess Monster",
|
||||
"questAtom2Drop": "The Laundromancer Scroll (Scroll)",
|
||||
"questAtom2Drop": "The Laundromancer (Quest Scroll)",
|
||||
|
||||
"questAtom3Text": "Attack of the Mundane Questline, Pt. 3: The Laundromancer",
|
||||
"questAtom3Text": "Attack of the Mundane, Part 3: The Laundromancer",
|
||||
"questAtom3Notes": "With a deafening cry, and five delicious types of cheese bursting from its mouth, the SnackLess Monster falls to pieces. \"HOW DARE YOU!\" booms a voice from beneath the water's surface. A robed, blue figure emerges from the water, wielding a magic toilet brush. Filthy laundry begins to bubble up to the surface of the lake. \"I am the Laundromancer!\" he angrily announces. \"You have some nerve - washing my delightfully dirty dishes, destroying my pet, and entering my domain with such clean clothes. Prepare to feel the soggy wrath of my anti-laundry magic!\"",
|
||||
"questAtom3Completion": "The wicked Laundromancer has been defeated! Clean laundry falls in piles all around you. Things are looking much better around here. As you begin to wade through the freshly pressed armor, a glint of metal catches your eye, and your gaze falls upon a gleaming helm. The original owner of this shining item may be unknown, but as you put it on, you feel the warming presence of a generous spirit. Too bad they didn't sew on a nametag.",
|
||||
"questAtom3Boss": "The Laundromancer",
|
||||
|
|
@ -251,6 +251,31 @@
|
|||
"questWhaleBoss": "Wailing Whale",
|
||||
"questWhaleCompletion": "After much hard work, the whale finally ceases her thunderous cry. \"Looks like she was drowning in waves of negative habits,\" @zoebeagle explains. \"Thanks to your consistent effort, we were able to turn the tides!\" As you step into the submarine, several whale eggs bob towards you, and you scoop them up.",
|
||||
"questWhaleDropWhaleEgg": "Whale (Egg)",
|
||||
"questWhaleUnlockText": "Unlocks purchasable whale eggs in the Market"
|
||||
"questWhaleUnlockText": "Unlocks purchasable whale eggs in the Market",
|
||||
|
||||
"questDilatoryDistress1Text": "Dilatory Distress, Part 1: Message in a Bottle",
|
||||
"questDilatoryDistress1Notes": "A message in a bottle arrived from the newly rebuilt city of Dilatory! It reads: \"Dear Habiticans, we need your help once again. Our princess has disappeared and the city is under siege by some unknown watery demons! The mantis shrimps are holding the attackers at bay. Please aid us!\" To make the long journey to the sunken city, one must be able to breathe water. Fortunately, the alchemists @Benga and @hazel can make it all possible! You only have to find the proper ingredients.",
|
||||
"questDilatoryDistress1Completion": "You don the the finned armor and swim to Dilatory as quickly as you can. The merfolk and their mantis shrimp allies have managed to keep the monsters outside the city for the moment, but they are losing. No sooner are you within the castle walls than the horrifying siege descends!",
|
||||
"questDilatoryDistress1CollectFireCoral": "Fire Coral",
|
||||
"questDilatoryDistress1CollectBlueFins": "Blue Fins",
|
||||
"questDilatoryDistress1DropArmor": "Finned Oceanic Armor (Armor)",
|
||||
|
||||
"questDilatoryDistress2Text": "Dilatory Distress, Part 2: Creatures of the Crevasse",
|
||||
"questDilatoryDistress2Notes": "The siege can be seen from miles away: thousands of disembodied skulls rushing through a portal in the crevasse walls and making their way towards Dilatory.<br><br>When you meet King Manta in his war room, his eyes seem sunken, and his face is worried. \"My daughter Adva disappeared into the Dark Crevasse just before this siege began. Please find her and bring her back home safely! I will lend you my Fire Coral Circlet to aid you. If you succeed, it is yours.\"",
|
||||
"questDilatoryDistress2Completion": "You vanquish the nightmarish horde of skulls, but you feel no closer to finding Adva. You speak to @Kiwibot, the royal tracker, to see if she has any ideas. \"The mantis shrimps that defend the city must have seen Adva escape,\" @Kiwibot says. \"Try following them into the Dark Crevasse.\"",
|
||||
"questDilatoryDistress2Boss": "Water Skull Swarm",
|
||||
"questDilatoryDistress2RageTitle": "Swarm Respawn",
|
||||
"questDilatoryDistress2RageDescription": "Swarm Respawn: This bar fills when you don't complete your Dailies. When it is full, the Water Skull Swarm will heal 30% of its remaining health!",
|
||||
"questDilatoryDistress2RageEffect": "`Water Skull Swarm uses SWARM RESPAWN!`\n\nEmboldened by their victories, more skulls pour forth from the crevasse, bolstering the swarm!",
|
||||
"questDilatoryDistress2DropSkeletonPotion": "Skeleton Hatching Potion",
|
||||
"questDilatoryDistress2DropCottonCandyBluePotion": "Cotton Candy Blue Hatching Potion",
|
||||
"questDilatoryDistress2DropHeadgear": "Fire Coral Circlet (Headgear)",
|
||||
|
||||
"questDilatoryDistress3Text": "Dilatory Distress, Part 3: Not a Mere Maid",
|
||||
"questDilatoryDistress3Notes": "You follow the mantis shrimps deep into the Crevasse, and discover an underwater fortress. Princess Adva, escorted by more watery skulls, awaits you inside the main hall. \"My father has sent you, has he not? Tell him I refuse to return. I am content to stay here and practice my sorcery. Leave now, or you shall feel the wrath of the ocean's new queen!\" Adva seems very adamant, but as she speaks you notice a strange, ruby pendant on her neck glowing ominously... Perhaps her delusions would cease should you break it?",
|
||||
"questDilatoryDistress3Completion": "Finally, you manage to pull the bewitched pendant from Adva's neck and throw it away. Adva clutches her head. \"Where am I? What happened here?\" After hearing your story, she frowns. \"This necklace was given to me by a strange ambassador - a lady called 'Tzina'. I don't remember anything after that!\"<br><br>Back at Dilatory, Manta is overjoyed by your success. \"Allow me to reward you with this trident and shield! I ordered them from @aiseant and @starsystemic as a gift for Adva, but... I'd rather not put weapons in her hands any time soon.\"",
|
||||
"questDilatoryDistress3Boss": "Adva, the Usurping Mermaid",
|
||||
"questDilatoryDistress3DropFish": "Fish (Food)",
|
||||
"questDilatoryDistress3DropWeapon": "Trident of Crashing Tides (Weapon)",
|
||||
"questDilatoryDistress3DropShield": "Moonpearl Shield (Shield-Hand Item)"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,27 +117,29 @@ gear =
|
|||
5: text: t('weaponHealer5Text'), notes: t('weaponHealer5Notes', {int: 9}), int: 9, value:90
|
||||
6: text: t('weaponHealer6Text'), notes: t('weaponHealer6Notes', {int: 11}), int: 11, value:120, last: true
|
||||
special:
|
||||
# Backer, Contributor, and Quest Rewards
|
||||
0: text: t('weaponSpecial0Text'), notes: t('weaponSpecial0Notes', {str: 20}), str: 20, value:150, canOwn: ((u)-> +u.backer?.tier >= 70)
|
||||
1: text: t('weaponSpecial1Text'), notes: t('weaponSpecial1Notes', {attrs: 6}), str: 6, per: 6, con: 6, int: 6, value:170, canOwn: ((u)-> +u.contributor?.level >= 4)
|
||||
2: text: t('weaponSpecial2Text'), notes: t('weaponSpecial2Notes', {attrs: 25}), str: 25, per: 25, value:200, canOwn: ((u)-> (+u.backer?.tier >= 300) or u.items.gear.owned.weapon_special_2?)
|
||||
3: text: t('weaponSpecial3Text'), notes: t('weaponSpecial3Notes', {attrs: 17}), str: 17, int: 17, con: 17, value:200, canOwn: ((u)-> (+u.backer?.tier >= 300) or u.items.gear.owned.weapon_special_3?)
|
||||
critical: text: t('weaponSpecialCriticalText'), notes: t('weaponSpecialCriticalNotes', {attrs: 40}), str: 40, per: 40, value:200, canOwn: ((u)-> !!u.contributor?.critical)
|
||||
# Winter event gear
|
||||
tridentOfCrashingTides: text: t('weaponSpecialTridentOfCrashingTidesText'), notes: t('weaponSpecialTridentOfCrashingTidesNotes', {int: 15}), int: 15, value: 130, canOwn: ((u)-> u.items.gear.owned.weapon_special_tridentOfCrashingTides?)
|
||||
# Winter Wonderland
|
||||
yeti: event: events.winter, specialClass: 'warrior', text: t('weaponSpecialYetiText'), notes: t('weaponSpecialYetiNotes', {str: 15}), str: 15, value:90
|
||||
ski: event: events.winter, specialClass: 'rogue', text: t('weaponSpecialSkiText'), notes: t('weaponSpecialSkiNotes', {str: 8}), str: 8, value: 90
|
||||
candycane: event: events.winter, specialClass: 'wizard', twoHanded: true, text: t('weaponSpecialCandycaneText'), notes: t('weaponSpecialCandycaneNotes', {int: 15, per: 7}), int: 15, per: 7, value:160
|
||||
snowflake: event: events.winter, specialClass: 'healer', text: t('weaponSpecialSnowflakeText'), notes: t('weaponSpecialSnowflakeNotes', {int: 9}), int: 9, value:90
|
||||
#Spring Fling
|
||||
# Spring Fling
|
||||
springRogue: event: events.spring, specialClass: 'rogue', text: t('weaponSpecialSpringRogueText'), notes: t('weaponSpecialSpringRogueNotes', {str: 8}), value: 80, str: 8
|
||||
springWarrior: event: events.spring, specialClass: 'warrior', text: t('weaponSpecialSpringWarriorText'), notes: t('weaponSpecialSpringWarriorNotes', {str: 15}), value: 90, str: 15
|
||||
springMage: event: events.spring, specialClass: 'wizard', twoHanded:true, text: t('weaponSpecialSpringMageText'), notes: t('weaponSpecialSpringMageNotes', {int: 15, per: 7}), value: 160, int:15, per:7
|
||||
springHealer: event: events.spring, specialClass: 'healer', text: t('weaponSpecialSpringHealerText'), notes: t('weaponSpecialSpringHealerNotes', {int: 9}), value: 90, int: 9
|
||||
#Summer
|
||||
# Summer Splash
|
||||
summerRogue: event: events.summer, specialClass: 'rogue', text: t('weaponSpecialSummerRogueText'), notes: t('weaponSpecialSummerRogueNotes', {str: 8}), value: 80, str: 8
|
||||
summerWarrior: event: events.summer, specialClass: 'warrior', text: t('weaponSpecialSummerWarriorText'), notes: t('weaponSpecialSummerWarriorNotes', {str: 15}), value: 90, str: 15
|
||||
summerMage: event: events.summer, specialClass: 'wizard', twoHanded:true, text: t('weaponSpecialSummerMageText'), notes: t('weaponSpecialSummerMageNotes', {int: 15, per: 7}), value: 160, int:15, per:7
|
||||
summerHealer: event: events.summer, specialClass: 'healer', text: t('weaponSpecialSummerHealerText'), notes: t('weaponSpecialSummerHealerNotes', {int: 9}), value: 90, int: 9
|
||||
#Fall
|
||||
# Fall Festival
|
||||
fallRogue: event: events.fall, specialClass: 'rogue', text: t('weaponSpecialFallRogueText'), notes: t('weaponSpecialFallRogueNotes', {str: 8}), value: 80, str: 8
|
||||
fallWarrior: event: events.fall, specialClass: 'warrior', text: t('weaponSpecialFallWarriorText'), notes: t('weaponSpecialFallWarriorNotes', {str: 15}), value: 90, str: 15
|
||||
fallMage: event: events.fall, specialClass: 'wizard', twoHanded:true, text: t('weaponSpecialFallMageText'), notes: t('weaponSpecialFallMageNotes', {int: 15, per: 7}), value: 160, int:15, per:7
|
||||
|
|
@ -165,43 +167,42 @@ gear =
|
|||
armoire:
|
||||
basicCrossbow: text: t('weaponArmoireBasicCrossbowText'), notes: t('weaponArmoireBasicCrossbowNotes', {str: 5, per: 5, con: 5}), value: 100, str: 5, per: 5, con: 5, canOwn: ((u)-> u.items.gear.owned.weapon_armoire_basicCrossbow?)
|
||||
lunarSceptre: text: t('weaponArmoireLunarSceptreText'), notes: t('weaponArmoireLunarSceptreNotes', {con: 7, int: 7}), value: 100, con: 7, int: 7, set: 'soothing', canOwn: ((u)-> u.items.gear.owned.weapon_armoire_lunarSceptre?)
|
||||
rancherLasso: text: t('weaponArmoireRancherLassoText'), notes: t('weaponArmoireRancherLassoNotes', twoHanded:true, {str: 5, per: 5, int: 5}), value: 100, str: 5, per: 5, int: 5, set: 'rancher', canOwn: ((u)-> u.items.gear.owned.weapon_armoire_rancherLasso?)
|
||||
|
||||
armor:
|
||||
base:
|
||||
0: text: t('armorBase0Text'), notes: t('armorBase0Notes'), value:0
|
||||
warrior:
|
||||
#0: text: "Plain Clothing", notes:'Ordinary clothing. Confers no benefit.', value:0
|
||||
1: text: t('armorWarrior1Text'), notes: t('armorWarrior1Notes', {con: 3}), con: 3, value:30
|
||||
2: text: t('armorWarrior2Text'), notes: t('armorWarrior2Notes', {con: 5}), con: 5, value:45
|
||||
3: text: t('armorWarrior3Text'), notes: t('armorWarrior3Notes', {con: 7}), con: 7, value:65
|
||||
4: text: t('armorWarrior4Text'), notes: t('armorWarrior4Notes', {con: 9}), con: 9, value:90
|
||||
5: text: t('armorWarrior5Text'), notes: t('armorWarrior5Notes', {con: 11}), con: 11, value:120, last: true
|
||||
rogue:
|
||||
#0: text: "Plain Clothing", notes:'Ordinary clothing. Confers no benefit.', value:0
|
||||
1: text: t('armorRogue1Text'), notes: t('armorRogue1Notes', {per: 6}), per: 6, value:30
|
||||
2: text: t('armorRogue2Text'), notes: t('armorRogue2Notes', {per: 9}), per: 9, value:45
|
||||
3: text: t('armorRogue3Text'), notes: t('armorRogue3Notes', {per: 12}), per: 12, value:65
|
||||
4: text: t('armorRogue4Text'), notes: t('armorRogue4Notes', {per: 15}), per: 15, value:90
|
||||
5: text: t('armorRogue5Text'), notes: t('armorRogue5Notes', {per: 18}), per: 18, value:120, last: true
|
||||
wizard:
|
||||
#0: text: "Apprentice Garb", notes:'For students of magic. Confers no benefit.', value:0
|
||||
1: text: t('armorWizard1Text'), notes: t('armorWizard1Notes', {int: 2}), int: 2, value:30
|
||||
2: text: t('armorWizard2Text'), notes: t('armorWizard2Notes', {int: 4}), int: 4, value:45
|
||||
3: text: t('armorWizard3Text'), notes: t('armorWizard3Notes', {int: 6}), int: 6, value:65
|
||||
4: text: t('armorWizard4Text'), notes: t('armorWizard4Notes', {int: 9}), int: 9, value:90
|
||||
5: text: t('armorWizard5Text'), notes: t('armorWizard5Notes', {int: 12}), int: 12, value:120, last: true
|
||||
healer:
|
||||
#0: text: "Novice Robe", notes:'For healers in training. Confers no benefit.', value:0
|
||||
1: text: t('armorHealer1Text'), notes: t('armorHealer1Notes', {con: 6}), con: 6, value:30
|
||||
2: text: t('armorHealer2Text'), notes: t('armorHealer2Notes', {con: 9}), con: 9, value:45
|
||||
3: text: t('armorHealer3Text'), notes: t('armorHealer3Notes', {con: 12}), con: 12, value:65
|
||||
4: text: t('armorHealer4Text'), notes: t('armorHealer4Notes', {con: 15}), con: 15, value:90
|
||||
5: text: t('armorHealer5Text'), notes: t('armorHealer5Notes', {con: 18}), con: 18, value:120, last: true
|
||||
special:
|
||||
# Backer, Contributor, and Quest Rewards
|
||||
0: text: t('armorSpecial0Text'), notes: t('armorSpecial0Notes', {con: 20}), con: 20, value:150, canOwn: ((u)-> +u.backer?.tier >= 45)
|
||||
1: text: t('armorSpecial1Text'), notes: t('armorSpecial1Notes', {attrs: 6}), con: 6, str: 6, per: 6, int: 6, value:170, canOwn: ((u)-> +u.contributor?.level >= 2)
|
||||
2: text: t('armorSpecial2Text'), notes: t('armorSpecial2Notes', {attrs: 25}), int: 25, con: 25, value:200, canOwn: ((u)-> +u.backer?.tier >= 300 or u.items.gear.owned.armor_special_2?)
|
||||
#Winter event
|
||||
finnedOceanicArmor: text: t('armorSpecialFinnedOceanicArmorText'), notes: t('armorSpecialFinnedOceanicArmorNotes', {str: 15}), str: 15, value: 130, canOwn: ((u)-> u.items.gear.owned.armor_special_finnedOceanicArmor?)
|
||||
# Winter Wonderland
|
||||
yeti: event: events.winter, specialClass: 'warrior', text: t('armorSpecialYetiText'), notes: t('armorSpecialYetiNotes', {con: 9}), con: 9, value:90
|
||||
ski: event: events.winter, specialClass: 'rogue', text: t('armorSpecialSkiText'), notes: t('armorSpecialSkiNotes', {per: 15}), per: 15, value:90
|
||||
candycane: event: events.winter, specialClass: 'wizard', text: t('armorSpecialCandycaneText'), notes: t('armorSpecialCandycaneNotes', {int: 9}), int: 9, value:90
|
||||
|
|
@ -212,12 +213,12 @@ gear =
|
|||
springWarrior: event: events.spring, specialClass: 'warrior', text: t('armorSpecialSpringWarriorText'), notes: t('armorSpecialSpringWarriorNotes', {con: 9}), value: 90, con: 9
|
||||
springMage: event: events.spring, specialClass: 'wizard', text: t('armorSpecialSpringMageText'), notes: t('armorSpecialSpringMageNotes', {int: 9}), value: 90, int: 9
|
||||
springHealer: event: events.spring, specialClass: 'healer', text: t('armorSpecialSpringHealerText'), notes: t('armorSpecialSpringHealerNotes', {con: 15}), value: 90, con: 15
|
||||
# Summer
|
||||
# Summer Splash
|
||||
summerRogue: event: events.summer, specialClass: 'rogue', text: t('armorSpecialSummerRogueText'), notes: t('armorSpecialSummerRogueNotes', {per: 15}), value: 90, per: 15
|
||||
summerWarrior: event: events.summer, specialClass: 'warrior', text: t('armorSpecialSummerWarriorText'), notes: t('armorSpecialSummerWarriorNotes', {con: 9}), value: 90, con: 9
|
||||
summerMage: event: events.summer, specialClass: 'wizard', text: t('armorSpecialSummerMageText'), notes: t('armorSpecialSummerMageNotes', {int: 9}), value: 90, int: 9
|
||||
summerHealer: event: events.summer, specialClass: 'healer', text: t('armorSpecialSummerHealerText'), notes: t('armorSpecialSummerHealerNotes', {con: 15}), value: 90, con: 15
|
||||
# Fall
|
||||
# Fall Festival
|
||||
fallRogue: event: events.fall, specialClass: 'rogue', text: t('armorSpecialFallRogueText'), notes: t('armorSpecialFallRogueNotes', {per: 15}), value: 90, per: 15
|
||||
fallWarrior: event: events.fall, specialClass: 'warrior', text: t('armorSpecialFallWarriorText'), notes: t('armorSpecialFallWarriorNotes', {con: 9}), value: 90, con: 9
|
||||
fallMage: event: events.fall, specialClass: 'wizard', text: t('armorSpecialFallMageText'), notes: t('armorSpecialFallMageNotes', {int: 9}), value: 90, int: 9
|
||||
|
|
@ -258,43 +259,42 @@ gear =
|
|||
armoire:
|
||||
lunarArmor: text: t('armorArmoireLunarArmorText'), notes: t('armorArmoireLunarArmorNotes', {str: 7, int: 7}), value: 100, str: 7, int: 7, set: 'soothing', canOwn: ((u)-> u.items.gear.owned.armor_armoire_lunarArmor?)
|
||||
gladiatorArmor: text: t('armorArmoireGladiatorArmorText'), notes: t('armorArmoireGladiatorArmorNotes', {str: 7, per: 7}), value: 100, str: 7, per: 7, set: 'gladiator', canOwn: ((u)-> u.items.gear.owned.armor_armoire_gladiatorArmor?)
|
||||
rancherRobes: text: t('armorArmoireRancherRobesText'), notes: t('armorArmoireRancherRobesNotes', {str: 5, per: 5, int: 5}), value: 100, str: 5, per: 5, int: 5, set: 'rancher', canOwn: ((u)-> u.items.gear.owned.armor_armoire_rancherRobes?)
|
||||
|
||||
head:
|
||||
base:
|
||||
0: text: t('headBase0Text'), notes: t('headBase0Notes'), value:0
|
||||
warrior:
|
||||
#0: text: "No Helm", notes:'No headgear.', value:0
|
||||
1: text: t('headWarrior1Text'), notes: t('headWarrior1Notes', {str: 2}), str: 2, value:15
|
||||
2: text: t('headWarrior2Text'), notes: t('headWarrior2Notes', {str: 4}), str: 4, value:25
|
||||
3: text: t('headWarrior3Text'), notes: t('headWarrior3Notes', {str: 6}), str: 6, value:40
|
||||
4: text: t('headWarrior4Text'), notes: t('headWarrior4Notes', {str: 9}), str: 9, value:60
|
||||
5: text: t('headWarrior5Text'), notes: t('headWarrior5Notes', {str: 12}), str: 12, value:80, last: true
|
||||
rogue:
|
||||
#0: text: "No Hood", notes:'No headgear.', value:0
|
||||
1: text: t('headRogue1Text'), notes: t('headRogue1Notes', {per: 2}), per: 2, value:15
|
||||
2: text: t('headRogue2Text'), notes: t('headRogue2Notes', {per: 4}), per: 4, value:25
|
||||
3: text: t('headRogue3Text'), notes: t('headRogue3Notes', {per: 6}), per: 6, value:40
|
||||
4: text: t('headRogue4Text'), notes: t('headRogue4Notes', {per: 9}), per: 9, value:60
|
||||
5: text: t('headRogue5Text'), notes: t('headRogue5Notes', {per: 12}), per: 12, value:80, last: true
|
||||
wizard:
|
||||
#0: text: "No Hat", notes:'No headgear.', value:0
|
||||
1: text: t('headWizard1Text'), notes: t('headWizard1Notes', {per: 2}), per: 2, value:15
|
||||
2: text: t('headWizard2Text'), notes: t('headWizard2Notes', {per: 3}), per: 3, value:25
|
||||
3: text: t('headWizard3Text'), notes: t('headWizard3Notes', {per: 5}), per: 5, value:40
|
||||
4: text: t('headWizard4Text'), notes: t('headWizard4Notes', {per: 7}), per: 7, value:60
|
||||
5: text: t('headWizard5Text'), notes: t('headWizard5Notes', {per: 10}), per: 10, value:80, last: true
|
||||
healer:
|
||||
#0: text: "No Circlet", notes:'No headgear.', value:0
|
||||
1: text: t('headHealer1Text'), notes: t('headHealer1Notes', {int: 2}), int: 2, value:15
|
||||
2: text: t('headHealer2Text'), notes: t('headHealer2Notes', {int: 3}), int: 3, value:25
|
||||
3: text: t('headHealer3Text'), notes: t('headHealer3Notes', {int: 5}), int: 5, value:40
|
||||
4: text: t('headHealer4Text'), notes: t('headHealer4Notes', {int: 7}), int: 7, value:60
|
||||
5: text: t('headHealer5Text'), notes: t('headHealer5Notes', {int: 9}), int: 9, value:80, last: true
|
||||
special:
|
||||
# Backer, Contributor, and Quest Rewards
|
||||
0: text: t('headSpecial0Text'), notes: t('headSpecial0Notes', {int: 20}), int: 20, value:150, canOwn: ((u)-> +u.backer?.tier >= 45)
|
||||
1: text: t('headSpecial1Text'), notes: t('headSpecial1Notes', {attrs: 6}), con: 6, str: 6, per: 6, int: 6, value:170, canOwn: ((u)-> +u.contributor?.level >= 3)
|
||||
2: text: t('headSpecial2Text'), notes: t('headSpecial2Notes', {attrs: 25}), int: 25, str: 25, value:200, canOwn: ((u)-> (+u.backer?.tier >= 300) or u.items.gear.owned.head_special_2?)
|
||||
#Winter event
|
||||
fireCoralCirclet: text: t('headSpecialFireCoralCircletText'), notes: t('headSpecialFireCoralCircletNotes', {per: 15}), per: 15, value: 130, canOwn: ((u)-> u.items.gear.owned.head_special_fireCoralCirclet?)
|
||||
# Winter Wonderland
|
||||
nye: event: events.winter, text: t('headSpecialNyeText'), notes: t('headSpecialNyeNotes'), value: 0
|
||||
yeti: event: events.winter, specialClass: 'warrior', text: t('headSpecialYetiText'), notes: t('headSpecialYetiNotes', {str: 9}), str: 9, value:60
|
||||
ski: event: events.winter, specialClass: 'rogue', text: t('headSpecialSkiText'), notes: t('headSpecialSkiNotes', {per: 9}), per: 9, value:60
|
||||
|
|
@ -305,12 +305,12 @@ gear =
|
|||
springWarrior: event: events.spring, specialClass: 'warrior', text: t('headSpecialSpringWarriorText'), notes: t('headSpecialSpringWarriorNotes', {str: 9}),value: 60,str: 9
|
||||
springMage: event: events.spring, specialClass: 'wizard', text: t('headSpecialSpringMageText'), notes: t('headSpecialSpringMageNotes', {per: 7}),value: 60,per: 7
|
||||
springHealer: event: events.spring, specialClass: 'healer', text: t('headSpecialSpringHealerText'), notes: t('headSpecialSpringHealerNotes', {int: 7}), value: 60, int: 7
|
||||
# Summer
|
||||
# Summer Splash
|
||||
summerRogue: event: events.summer, specialClass: 'rogue', text: t('headSpecialSummerRogueText'), notes: t('headSpecialSummerRogueNotes', {per: 9}),value: 60,per: 9
|
||||
summerWarrior: event: events.summer, specialClass: 'warrior', text: t('headSpecialSummerWarriorText'), notes: t('headSpecialSummerWarriorNotes', {str: 9}),value: 60,str: 9
|
||||
summerMage: event: events.summer, specialClass: 'wizard', text: t('headSpecialSummerMageText'), notes: t('headSpecialSummerMageNotes', {per: 7}),value: 60,per: 7
|
||||
summerHealer: event: events.summer, specialClass: 'healer', text: t('headSpecialSummerHealerText'), notes: t('headSpecialSummerHealerNotes', {int: 7}), value: 60, int: 7
|
||||
# Fall
|
||||
# Fall Festival
|
||||
fallRogue: event: events.fall, specialClass: 'rogue', text: t('headSpecialFallRogueText'), notes: t('headSpecialFallRogueNotes', {per: 9}),value: 60,per: 9
|
||||
fallWarrior: event: events.fall, specialClass: 'warrior', text: t('headSpecialFallWarriorText'), notes: t('headSpecialFallWarriorNotes', {str: 9}),value: 60,str: 9
|
||||
fallMage: event: events.fall, specialClass: 'wizard', text: t('headSpecialFallMageText'), notes: t('headSpecialFallMageNotes', {per: 7}),value: 60,per: 7
|
||||
|
|
@ -350,7 +350,9 @@ gear =
|
|||
redHairbow: text: t('headArmoireRedHairbowText'), notes: t('headArmoireRedHairbowNotes', {str: 5, int: 5, con: 5}), value: 100, str: 5, int: 5, con: 5, canOwn: ((u)-> u.items.gear.owned.head_armoire_redHairbow?)
|
||||
violetFloppyHat: text: t('headArmoireVioletFloppyHatText'), notes: t('headArmoireVioletFloppyHatNotes', {per: 5, int: 5, con: 5}), value: 100, per: 5, int: 5, con: 5, canOwn: ((u)-> u.items.gear.owned.head_armoire_violetFloppyHat?)
|
||||
gladiatorHelm: text: t('headArmoireGladiatorHelmText'), notes: t('headArmoireGladiatorHelmNotes', {per: 7, int: 7}), value: 100, per: 7, int: 7, set: 'gladiator', canOwn: ((u)-> u.items.gear.owned.head_armoire_gladiatorHelm?)
|
||||
rancherHat: text: t('headArmoireRancherHatText'), notes: t('headArmoireRancherHatNotes', {str: 5, per: 5, int: 5}), value: 100, str: 5, per: 5, int: 5, canOwn: ((u)-> u.items.gear.owned.head_armoire_rancherHat?)
|
||||
rancherHat: text: t('headArmoireRancherHatText'), notes: t('headArmoireRancherHatNotes', {str: 5, per: 5, int: 5}), value: 100, str: 5, per: 5, int: 5, set: 'rancher', canOwn: ((u)-> u.items.gear.owned.head_armoire_rancherHat?)
|
||||
royalCrown: text: t('headArmoireRoyalCrownText'), notes: t('headArmoireRoyalCrownNotes', {str: 10}), value: 100, str: 10, canOwn: ((u)-> u.items.gear.owned.head_armoire_royalCrown?)
|
||||
blueHairbow: text: t('headArmoireBlueHairbowText'), notes: t('headArmoireBlueHairbowNotes', {per: 5, int: 5, con: 5}), value: 100, per: 5, int: 5, con: 5, canOwn: ((u)-> u.items.gear.owned.head_armoire_blueHairbow?)
|
||||
|
||||
shield:
|
||||
base:
|
||||
|
|
@ -381,22 +383,24 @@ gear =
|
|||
4: text: t('shieldHealer4Text'), notes: t('shieldHealer4Notes', {con: 9}), con: 9, value:70
|
||||
5: text: t('shieldHealer5Text'), notes: t('shieldHealer5Notes', {con: 12}), con: 12, value:90, last: true
|
||||
special:
|
||||
# Backer, Contributor, and Quest Rewards
|
||||
0: text: t('shieldSpecial0Text'), notes: t('shieldSpecial0Notes', {per: 20}), per: 20, value:150, canOwn: ((u)-> +u.backer?.tier >= 45)
|
||||
1: text: t('shieldSpecial1Text'), notes: t('shieldSpecial1Notes', {attrs: 6}), con: 6, str: 6, per: 6, int:6, value:170, canOwn: ((u)-> +u.contributor?.level >= 5)
|
||||
goldenknight: text: t('shieldSpecialGoldenknightText'), notes: t('shieldSpecialGoldenknightNotes', {attrs: 25}), con: 25, per: 25, value:200, canOwn: ((u)-> u.items.gear.owned.shield_special_goldenknight?)
|
||||
#Winter event
|
||||
moonpearlShield: text: t('shieldSpecialMoonpearlShieldText'), notes: t('shieldSpecialMoonpearlShieldNotes', {con: 15}), con: 15, value: 130, canOwn: ((u)-> u.items.gear.owned.shield_special_moonpearlShield?)
|
||||
# Winter Wonderland
|
||||
yeti: event: events.winter, specialClass: 'warrior', text: t('shieldSpecialYetiText'), notes: t('shieldSpecialYetiNotes', {con: 7}), con: 7, value: 70
|
||||
ski: event: events.winter, specialClass: 'rogue', text: t('weaponSpecialSkiText'), notes: t('weaponSpecialSkiNotes', {str: 8}), str: 8, value: 90
|
||||
snowflake: event: events.winter, specialClass: 'healer', text: t('shieldSpecialSnowflakeText'), notes: t('shieldSpecialSnowflakeNotes', {con: 9}), con: 9, value: 70
|
||||
#Spring Fling
|
||||
# Spring Fling
|
||||
springRogue: event: events.spring, specialClass: 'rogue', text: t('shieldSpecialSpringRogueText'), notes: t('shieldSpecialSpringRogueNotes', {str: 8}), value: 80, str: 8
|
||||
springWarrior: event: events.spring, specialClass: 'warrior', text: t('shieldSpecialSpringWarriorText'), notes: t('shieldSpecialSpringWarriorNotes', {con: 7}), value: 70, con: 7
|
||||
springHealer: event: events.spring, specialClass: 'healer', text: t('shieldSpecialSpringHealerText'), notes: t('shieldSpecialSpringHealerNotes', {con: 9}), value: 70, con: 9
|
||||
#Summer
|
||||
# Summer Splash
|
||||
summerRogue: event: events.summer, specialClass: 'rogue', text: t('shieldSpecialSummerRogueText'), notes: t('shieldSpecialSummerRogueNotes', {str: 8}), value: 80, str: 8
|
||||
summerWarrior: event: events.summer, specialClass: 'warrior', text: t('shieldSpecialSummerWarriorText'), notes: t('shieldSpecialSummerWarriorNotes', {con: 7}), value: 70, con: 7
|
||||
summerHealer: event: events.summer, specialClass: 'healer', text: t('shieldSpecialSummerHealerText'), notes: t('shieldSpecialSummerHealerNotes', {con: 9}), value: 70, con: 9
|
||||
#Fall
|
||||
# Fall Festival
|
||||
fallRogue: event: events.fall, specialClass: 'rogue', text: t('shieldSpecialFallRogueText'), notes: t('shieldSpecialFallRogueNotes', {str: 8}), value: 80, str: 8
|
||||
fallWarrior: event: events.fall, specialClass: 'warrior', text: t('shieldSpecialFallWarriorText'), notes: t('shieldSpecialFallWarriorNotes', {con: 7}), value: 70, con: 7
|
||||
fallHealer: event: events.fall, specialClass: 'healer', text: t('shieldSpecialFallHealerText'), notes: t('shieldSpecialFallHealerNotes', {con: 9}), value: 70, con: 9
|
||||
|
|
@ -1112,6 +1116,7 @@ api.quests =
|
|||
completion: t("questDilatoryCompletion")
|
||||
value: 0
|
||||
canBuy: false
|
||||
category: 'world'
|
||||
boss:
|
||||
name: t("questDilatoryBoss")
|
||||
# We ran an average of progress{up,down} on users over 5 days: {up:805025,down:1324423}. /5*30 (we want the
|
||||
|
|
@ -1154,6 +1159,7 @@ api.quests =
|
|||
completionChat: t("questStressbeastCompletionChat")
|
||||
value: 0
|
||||
canBuy: false
|
||||
category: 'world'
|
||||
boss:
|
||||
name: t("questStressbeastBoss")
|
||||
hp: 2750000
|
||||
|
|
@ -1197,7 +1203,7 @@ api.quests =
|
|||
notes: t('questEvilSantaNotes')
|
||||
completion: t('questEvilSantaCompletion')
|
||||
value: 4 # Gem cost to buy, GP sell-back
|
||||
#mechanic: enum['perfectDailies', ...]
|
||||
category: 'pet'
|
||||
boss:
|
||||
name: t('questEvilSantaBoss') # name of the boss himself (eg, Vice)
|
||||
hp: 300
|
||||
|
|
@ -1216,6 +1222,7 @@ api.quests =
|
|||
completion: t('questEvilSanta2Completion')
|
||||
value: 4
|
||||
previous: 'evilsanta'
|
||||
category: 'pet'
|
||||
collect:
|
||||
tracks: text: t('questEvilSanta2CollectTracks'), count: 20
|
||||
branches: text: t('questEvilSanta2CollectBranches'), count: 10
|
||||
|
|
@ -1231,6 +1238,7 @@ api.quests =
|
|||
notes: t('questGryphonNotes')
|
||||
completion: t('questGryphonCompletion')
|
||||
value: 4 # Gem cost to buy, GP sell-back
|
||||
category: 'pet'
|
||||
boss:
|
||||
name: t('questGryphonBoss') # name of the boss himself (eg, Vice)
|
||||
hp: 300
|
||||
|
|
@ -1250,6 +1258,7 @@ api.quests =
|
|||
notes: t('questHedgehogNotes')
|
||||
completion: t('questHedgehogCompletion')
|
||||
value: 4 # Gem cost to buy, GP sell-back
|
||||
category: 'pet'
|
||||
boss:
|
||||
name: t('questHedgehogBoss') # name of the boss himself (eg, Vice)
|
||||
hp: 400
|
||||
|
|
@ -1269,6 +1278,7 @@ api.quests =
|
|||
notes: t('questGhostStagNotes')
|
||||
completion: t('questGhostStagCompletion')
|
||||
value: 4
|
||||
category: 'pet'
|
||||
boss:
|
||||
name: t('questGhostStagBoss')
|
||||
hp: 1200
|
||||
|
|
@ -1288,6 +1298,7 @@ api.quests =
|
|||
notes: t('questVice1Notes')
|
||||
value: 4
|
||||
lvl: 30
|
||||
category: 'unlockable'
|
||||
boss:
|
||||
name: t('questVice1Boss')
|
||||
hp: 750
|
||||
|
|
@ -1303,7 +1314,8 @@ api.quests =
|
|||
text: t('questVice2Text')
|
||||
notes: t('questVice2Notes')
|
||||
value: 4
|
||||
lvl: 35
|
||||
lvl: 30
|
||||
category: 'unlockable'
|
||||
previous: 'vice1'
|
||||
collect:
|
||||
lightCrystal: text: t('questVice2CollectLightCrystal'), count: 45
|
||||
|
|
@ -1320,7 +1332,8 @@ api.quests =
|
|||
completion: t('questVice3Completion')
|
||||
previous: 'vice2'
|
||||
value: 4
|
||||
lvl: 40
|
||||
lvl: 30
|
||||
category: 'unlockable'
|
||||
boss:
|
||||
name: t('questVice3Boss')
|
||||
hp: 1500
|
||||
|
|
@ -1342,6 +1355,7 @@ api.quests =
|
|||
completion: t('questEggHuntCompletion')
|
||||
value: 1
|
||||
canBuy: false
|
||||
category: 'pet'
|
||||
collect:
|
||||
plainEgg: text: t('questEggHuntCollectPlainEgg'), count: 100
|
||||
drop:
|
||||
|
|
@ -1365,6 +1379,7 @@ api.quests =
|
|||
notes: t('questRatNotes')
|
||||
completion: t('questRatCompletion')
|
||||
value: 4
|
||||
category: 'pet'
|
||||
boss:
|
||||
name: t('questRatBoss')
|
||||
hp: 1200
|
||||
|
|
@ -1384,6 +1399,7 @@ api.quests =
|
|||
notes: t('questOctopusNotes')
|
||||
completion: t('questOctopusCompletion')
|
||||
value: 4
|
||||
category: 'pet'
|
||||
boss:
|
||||
name: t('questOctopusBoss')
|
||||
hp: 1200
|
||||
|
|
@ -1403,6 +1419,7 @@ api.quests =
|
|||
notes: t('questSeahorseNotes')
|
||||
completion: t('questSeahorseCompletion')
|
||||
value: 4
|
||||
category: 'pet'
|
||||
boss:
|
||||
name: t('questSeahorseBoss')
|
||||
hp: 300
|
||||
|
|
@ -1422,6 +1439,7 @@ api.quests =
|
|||
notes: t('questAtom1Notes')
|
||||
value: 4
|
||||
lvl: 15
|
||||
category: 'unlockable'
|
||||
collect:
|
||||
soapBars: text: t('questAtom1CollectSoapBars'), count: 20
|
||||
drop:
|
||||
|
|
@ -1436,6 +1454,7 @@ api.quests =
|
|||
previous: 'atom1'
|
||||
value: 4
|
||||
lvl: 15
|
||||
category: 'unlockable'
|
||||
boss:
|
||||
name: t('questAtom2Boss')
|
||||
hp: 300
|
||||
|
|
@ -1453,6 +1472,7 @@ api.quests =
|
|||
completion: t('questAtom3Completion')
|
||||
value: 4
|
||||
lvl: 15
|
||||
category: 'unlockable'
|
||||
boss:
|
||||
name: t('questAtom3Boss')
|
||||
hp: 800
|
||||
|
|
@ -1471,6 +1491,7 @@ api.quests =
|
|||
notes: t('questHarpyNotes')
|
||||
completion: t('questHarpyCompletion')
|
||||
value: 4
|
||||
category: 'pet'
|
||||
boss:
|
||||
name: t('questHarpyBoss')
|
||||
hp: 600
|
||||
|
|
@ -1490,6 +1511,7 @@ api.quests =
|
|||
notes: t('questRoosterNotes')
|
||||
completion: t('questRoosterCompletion')
|
||||
value: 4
|
||||
category: 'pet'
|
||||
boss:
|
||||
name: t('questRoosterBoss')
|
||||
hp: 300
|
||||
|
|
@ -1509,6 +1531,7 @@ api.quests =
|
|||
notes: t('questSpiderNotes')
|
||||
completion: t('questSpiderCompletion')
|
||||
value: 4
|
||||
category: 'pet'
|
||||
boss:
|
||||
name: t('questSpiderBoss')
|
||||
hp: 400
|
||||
|
|
@ -1528,6 +1551,7 @@ api.quests =
|
|||
notes: t('questMoonstone1Notes')
|
||||
value: 4
|
||||
lvl: 60
|
||||
category: 'unlockable'
|
||||
collect:
|
||||
moonstone: text: t('questMoonstone1CollectMoonstone'), count: 500
|
||||
drop:
|
||||
|
|
@ -1540,8 +1564,9 @@ api.quests =
|
|||
text: t('questMoonstone2Text')
|
||||
notes: t('questMoonstone2Notes')
|
||||
value: 4
|
||||
lvl: 65
|
||||
lvl: 60
|
||||
previous: 'moonstone1'
|
||||
category: 'unlockable'
|
||||
boss:
|
||||
name: t('questMoonstone2Boss')
|
||||
hp: 1500
|
||||
|
|
@ -1558,7 +1583,8 @@ api.quests =
|
|||
completion: t('questMoonstone3Completion')
|
||||
previous: 'moonstone2'
|
||||
value: 4
|
||||
lvl: 70
|
||||
lvl: 60
|
||||
category: 'unlockable'
|
||||
boss:
|
||||
name: t('questMoonstone3Boss')
|
||||
hp: 2000
|
||||
|
|
@ -1583,6 +1609,7 @@ api.quests =
|
|||
notes: t('questGoldenknight1Notes')
|
||||
value: 4
|
||||
lvl: 40
|
||||
category: 'unlockable'
|
||||
collect:
|
||||
testimony: text: t('questGoldenknight1CollectTestimony'), count: 300
|
||||
drop:
|
||||
|
|
@ -1596,7 +1623,8 @@ api.quests =
|
|||
notes: t('questGoldenknight2Notes')
|
||||
value: 4
|
||||
previous: 'goldenknight1'
|
||||
lvl: 45
|
||||
lvl: 40
|
||||
category: 'unlockable'
|
||||
boss:
|
||||
name: t('questGoldenknight2Boss')
|
||||
hp: 1000
|
||||
|
|
@ -1613,7 +1641,8 @@ api.quests =
|
|||
completion: t('questGoldenknight3Completion')
|
||||
previous: 'goldenknight2'
|
||||
value: 4
|
||||
lvl: 50
|
||||
lvl: 40
|
||||
category: 'unlockable'
|
||||
boss:
|
||||
name: t('questGoldenknight3Boss')
|
||||
hp: 1700
|
||||
|
|
@ -1634,8 +1663,11 @@ api.quests =
|
|||
text: t('questBasilistText')
|
||||
notes: t('questBasilistNotes')
|
||||
completion: t('questBasilistCompletion')
|
||||
canBuy: false
|
||||
value: 4
|
||||
category: 'unlockable'
|
||||
unlockCondition:
|
||||
condition: 'party invite'
|
||||
text: t('inviteFriends')
|
||||
boss:
|
||||
name: t('questBasilistBoss')
|
||||
hp: 100
|
||||
|
|
@ -1649,6 +1681,7 @@ api.quests =
|
|||
notes: t('questOwlNotes')
|
||||
completion: t('questOwlCompletion')
|
||||
value: 4
|
||||
category: 'pet'
|
||||
boss:
|
||||
name: t('questOwlBoss')
|
||||
hp: 500
|
||||
|
|
@ -1668,6 +1701,7 @@ api.quests =
|
|||
notes: t('questPenguinNotes')
|
||||
completion: t('questPenguinCompletion')
|
||||
value: 4
|
||||
category: 'pet'
|
||||
boss:
|
||||
name: t('questPenguinBoss')
|
||||
hp: 400
|
||||
|
|
@ -1687,6 +1721,7 @@ api.quests =
|
|||
notes: t('questTRexNotes')
|
||||
completion: t('questTRexCompletion')
|
||||
value: 4
|
||||
category: 'pet'
|
||||
boss:
|
||||
name: t('questTRexBoss')
|
||||
hp: 800
|
||||
|
|
@ -1706,6 +1741,7 @@ api.quests =
|
|||
notes: t('questTRexUndeadNotes')
|
||||
completion: t('questTRexUndeadCompletion')
|
||||
value: 4
|
||||
category: 'pet'
|
||||
boss:
|
||||
name: t('questTRexUndeadBoss')
|
||||
hp: 500
|
||||
|
|
@ -1731,6 +1767,7 @@ api.quests =
|
|||
notes: t('questRockNotes')
|
||||
completion: t('questRockCompletion')
|
||||
value: 4
|
||||
category: 'pet'
|
||||
boss:
|
||||
name: t('questRockBoss')
|
||||
hp: 400
|
||||
|
|
@ -1750,6 +1787,7 @@ api.quests =
|
|||
notes: t('questBunnyNotes')
|
||||
completion: t('questBunnyCompletion')
|
||||
value: 4
|
||||
category: 'pet'
|
||||
boss:
|
||||
name: t('questBunnyBoss')
|
||||
hp: 300
|
||||
|
|
@ -1769,6 +1807,7 @@ api.quests =
|
|||
notes: t('questSlimeNotes')
|
||||
completion: t('questSlimeCompletion')
|
||||
value: 4
|
||||
category: 'pet'
|
||||
boss:
|
||||
name: t('questSlimeBoss')
|
||||
hp: 400
|
||||
|
|
@ -1788,6 +1827,7 @@ api.quests =
|
|||
notes: t('questSheepNotes')
|
||||
completion: t('questSheepCompletion')
|
||||
value: 4
|
||||
category: 'pet'
|
||||
boss:
|
||||
name: t('questSheepBoss')
|
||||
hp: 300
|
||||
|
|
@ -1807,6 +1847,7 @@ api.quests =
|
|||
notes: t('questKrakenNotes')
|
||||
completion: t('questKrakenCompletion')
|
||||
value: 4
|
||||
category: 'pet'
|
||||
boss:
|
||||
name: t('questKrakenBoss')
|
||||
hp: 800
|
||||
|
|
@ -1826,6 +1867,7 @@ api.quests =
|
|||
notes: t('questWhaleNotes')
|
||||
completion: t('questWhaleCompletion')
|
||||
value: 4
|
||||
category: 'pet'
|
||||
boss:
|
||||
name: t('questWhaleBoss')
|
||||
hp: 500
|
||||
|
|
@ -1840,6 +1882,70 @@ api.quests =
|
|||
exp: 275
|
||||
unlock: t('questWhaleUnlockText')
|
||||
|
||||
dilatoryDistress1:
|
||||
text: t('questDilatoryDistress1Text')
|
||||
notes: t('questDilatoryDistress1Notes')
|
||||
completion: t('questDilatoryDistress1Completion')
|
||||
value: 4
|
||||
goldValue: 200
|
||||
category: 'gold'
|
||||
collect:
|
||||
fireCoral: text: t('questDilatoryDistress1CollectFireCoral'), count: 25
|
||||
blueFins: text: t('questDilatoryDistress1CollectBlueFins'), count: 25
|
||||
drop:
|
||||
items: [
|
||||
{type: 'gear', key: "armor_special_finnedOceanicArmor", text: t('questDilatoryDistress1DropArmor')}
|
||||
]
|
||||
gp: 0
|
||||
exp: 75
|
||||
dilatoryDistress2:
|
||||
text: t('questDilatoryDistress2Text')
|
||||
notes: t('questDilatoryDistress2Notes')
|
||||
completion: t('questDilatoryDistress2Completion')
|
||||
previous: 'dilatoryDistress1'
|
||||
value: 4
|
||||
goldValue: 300
|
||||
category: 'gold'
|
||||
boss:
|
||||
name: t('questDilatoryDistress2Boss')
|
||||
hp: 500
|
||||
rage:
|
||||
title: t("questDilatoryDistress2RageTitle")
|
||||
description: t("questDilatoryDistress2RageDescription")
|
||||
value: 50
|
||||
healing: .3
|
||||
effect:t('questDilatoryDistress2RageEffect')
|
||||
drop:
|
||||
items: [
|
||||
{type: 'hatchingPotions', key: 'Skeleton', text: t('questDilatoryDistress2DropSkeletonPotion')}
|
||||
{type: 'hatchingPotions', key: 'CottonCandyBlue', text: t('questDilatoryDistress2DropCottonCandyBluePotion')}
|
||||
{type: 'gear', key: "head_special_fireCoralCirclet", text: t('questDilatoryDistress2DropHeadgear')}
|
||||
]
|
||||
gp: 0
|
||||
exp: 500
|
||||
dilatoryDistress3:
|
||||
text: t('questDilatoryDistress3Text')
|
||||
notes: t('questDilatoryDistress3Notes')
|
||||
completion: t('questDilatoryDistress3Completion')
|
||||
previous: 'dilatoryDistress2'
|
||||
value: 4
|
||||
goldValue: 400
|
||||
category: 'gold'
|
||||
boss:
|
||||
name: t('questDilatoryDistress3Boss')
|
||||
hp: 1000
|
||||
str: 2
|
||||
drop:
|
||||
items: [
|
||||
{type: 'food', key: 'Fish', text: t('questDilatoryDistress3DropFish')}
|
||||
{type: 'food', key: 'Fish', text: t('questDilatoryDistress3DropFish')}
|
||||
{type: 'food', key: 'Fish', text: t('questDilatoryDistress3DropFish')}
|
||||
{type: 'gear', key: "weapon_special_tridentOfCrashingTides", text: t('questDilatoryDistress3DropWeapon')}
|
||||
{type: 'gear', key: "shield_special_moonpearlShield", text: t('questDilatoryDistress3DropShield')}
|
||||
]
|
||||
gp: 0
|
||||
exp: 650
|
||||
|
||||
_.each api.quests, (v,key) ->
|
||||
_.defaults v, {key,canBuy:true}
|
||||
b = v.boss
|
||||
|
|
@ -1848,6 +1954,10 @@ _.each api.quests, (v,key) ->
|
|||
if b.rage
|
||||
_.defaults b.rage, {title:t('bossRageTitle'),description:t('bossRageDescription')}
|
||||
|
||||
api.questsByLevel =
|
||||
_.sortBy api.quests, (quest) ->
|
||||
quest.lvl || 0
|
||||
|
||||
api.backgrounds =
|
||||
backgrounds062014:
|
||||
beach:
|
||||
|
|
|
|||
|
|
@ -883,7 +883,7 @@ api.wrap = (user, main=true) ->
|
|||
item = if key is 'potion' then content.potion
|
||||
else if key is 'armoire' then content.armoire
|
||||
else content.gear.flat[key]
|
||||
return cb?({code:404, message:"Item '#{key} not found (see https://github.com/HabitRPG/habitrpg-shared/blob/develop/script/content.coffee)"}) unless item
|
||||
return cb?({code:404, message:"Item '#{key} not found (see https://github.com/HabitRPG/habitrpg/blob/develop/common/script/content.coffee)"}) unless item
|
||||
return cb?({code:401, message: i18n.t('messageNotEnoughGold', req.language)}) if user.stats.gp < item.value
|
||||
return cb?({code:401, message: "You can't buy this item"}) if item.canOwn? and !item.canOwn(user)
|
||||
if item.key is 'potion'
|
||||
|
|
@ -921,6 +921,18 @@ api.wrap = (user, main=true) ->
|
|||
mixpanel?.track("Acquire Item",{'itemName':key,'acquireMethod':'Gold','goldCost':item.value})
|
||||
cb? {code:200, message}, _.pick(user,$w 'items achievements stats flags')
|
||||
|
||||
buyQuest: (req, cb) ->
|
||||
{key} = req.params
|
||||
item = content.quests[key]
|
||||
return cb?({code:404, message:"Quest '#{key} not found (see https://github.com/HabitRPG/habitrpg/blob/develop/common/script/content.coffee)"}) unless item
|
||||
return cb?({code:404, message:"Quest '#{key} is not a Gold-purchasable quest (see https://github.com/HabitRPG/habitrpg/blob/develop/common/script/content.coffee)"}) unless item.category is 'gold' and item.goldValue
|
||||
return cb?({code:401, message: i18n.t('messageNotEnoughGold', req.language)}) if user.stats.gp < item.goldValue
|
||||
message = i18n.t('messageBought', {itemText: item.text(req.language)}, req.language)
|
||||
user.items.quests[item.key] ?= 0
|
||||
user.items.quests[item.key] += 1
|
||||
user.stats.gp -= item.goldValue
|
||||
cb? {code:200, message}, user.items.quests
|
||||
|
||||
buyMysterySet: (req, cb)->
|
||||
return cb?({code:401, message:"You don't have enough Mystic Hourglasses"}) unless user.purchased.plan.consecutive.trinkets>0
|
||||
mysterySet = content.timeTravelerStore(user.items.gear.owned)?[req.params.key]
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ module.exports = function(config) {
|
|||
"website/public/js/services/challengeServices.js",
|
||||
"website/public/js/services/taskServices.js",
|
||||
"website/public/js/services/paymentServices.js",
|
||||
"website/public/js/services/questServices.js",
|
||||
|
||||
"website/public/js/filters/money.js",
|
||||
"website/public/js/filters/roundLargeNumbers.js",
|
||||
|
|
|
|||
5
migrations/restock_armoire.js
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
db.users.update(
|
||||
{'flags.armoireEmpty':true},
|
||||
{$set:{'flags.armoireEmpty':false}},
|
||||
{multi:true}
|
||||
);
|
||||
|
|
@ -25,6 +25,7 @@ newUser = (addTasks=true)->
|
|||
equipped: {}
|
||||
costume: {}
|
||||
owned: {}
|
||||
quests: {}
|
||||
party:
|
||||
quest:
|
||||
progress:
|
||||
|
|
@ -386,13 +387,41 @@ describe 'User', ->
|
|||
expect(user.items.gear.equipped).to.eql { armor: 'armor_warrior_1', weapon: 'weapon_base_0', head: 'head_base_0', shield: 'shield_base_0' }
|
||||
expect(user).toHaveGP 1
|
||||
|
||||
it 'do not buy equipment without enough money', ->
|
||||
it 'does not buy equipment without enough Gold', ->
|
||||
user = newUser()
|
||||
user.stats.gp = 1
|
||||
user.ops.buy {params: {key: 'armor_warrior_1'}}
|
||||
expect(user.items.gear.equipped).to.eql { armor: 'armor_base_0', weapon: 'weapon_base_0', head: 'head_base_0', shield: 'shield_base_0' }
|
||||
expect(user).toHaveGP 1
|
||||
|
||||
it 'buys a Quest scroll', ->
|
||||
user = newUser()
|
||||
user.stats.gp = 205
|
||||
user.ops.buyQuest {params: {key: 'dilatoryDistress1'}}
|
||||
expect(user.items.quests).to.eql {dilatoryDistress1: 1}
|
||||
expect(user).toHaveGP 5
|
||||
|
||||
it 'does not buy Quests without enough Gold', ->
|
||||
user = newUser()
|
||||
user.stats.gp = 1
|
||||
user.ops.buyQuest {params: {key: 'dilatoryDistress1'}}
|
||||
expect(user.items.quests).to.eql {}
|
||||
expect(user).toHaveGP 1
|
||||
|
||||
it 'does not buy nonexistent Quests', ->
|
||||
user = newUser()
|
||||
user.stats.gp = 9999
|
||||
user.ops.buyQuest {params: {key: 'snarfblatter'}}
|
||||
expect(user.items.quests).to.eql {}
|
||||
expect(user).toHaveGP 9999
|
||||
|
||||
it 'does not buy Gem-premium Quests', ->
|
||||
user = newUser()
|
||||
user.stats.gp = 9999
|
||||
user.ops.buyQuest {params: {key: 'kraken'}}
|
||||
expect(user.items.quests).to.eql {}
|
||||
expect(user).toHaveGP 9999
|
||||
|
||||
describe 'Gem purchases', ->
|
||||
it 'does not purchase items without enough Gems', ->
|
||||
user = newUser()
|
||||
|
|
@ -484,7 +513,22 @@ describe 'User', ->
|
|||
|
||||
describe 'Enchanted Armoire', ->
|
||||
user = newUser()
|
||||
fullArmoire = {'weapon_warrior_0': true, 'armor_armoire_gladiatorArmor':true,'armor_armoire_lunarArmor':true,'head_armoire_gladiatorHelm':true,'head_armoire_lunarCrown':true,'head_armoire_rancherHat':true,'head_armoire_redHairbow':true,'head_armoire_violetFloppyHat':true,'shield_armoire_gladiatorShield':true,'weapon_armoire_basicCrossbow':true,'weapon_armoire_lunarSceptre':true}
|
||||
fullArmoire =
|
||||
'weapon_warrior_0': true,
|
||||
'armor_armoire_gladiatorArmor':true,
|
||||
'armor_armoire_lunarArmor':true,
|
||||
'armor_armoire_rancherRobes':true,
|
||||
'head_armoire_blueHairbow':true,
|
||||
'head_armoire_gladiatorHelm':true,
|
||||
'head_armoire_lunarCrown':true,
|
||||
'head_armoire_rancherHat':true,
|
||||
'head_armoire_redHairbow':true,
|
||||
'head_armoire_royalCrown':true,
|
||||
'head_armoire_violetFloppyHat':true,
|
||||
'shield_armoire_gladiatorShield':true,
|
||||
'weapon_armoire_basicCrossbow':true,
|
||||
'weapon_armoire_lunarSceptre':true,
|
||||
'weapon_armoire_rancherLasso':true
|
||||
|
||||
beforeEach ->
|
||||
# too many predictableRandom calls to stub, let's return the last element
|
||||
|
|
@ -545,7 +589,7 @@ describe 'User', ->
|
|||
it 'gives more equipment', ->
|
||||
sinon.stub(user.fns, 'predictableRandom', cycle [.5,.5])
|
||||
user.ops.buy({params: {key: 'armoire'}})
|
||||
expect(user.items.gear.owned).to.eql {'weapon_warrior_0': true, 'shield_armoire_gladiatorShield':true,'head_armoire_rancherHat':true}
|
||||
expect(user.items.gear.owned).to.eql {'weapon_warrior_0': true, 'shield_armoire_gladiatorShield':true, 'head_armoire_blueHairbow':true}
|
||||
expect(shared.countArmoire(user.items.gear.owned)).to.eql (_.size(fullArmoire) - 3)
|
||||
expect(user.items.food).to.eql {'Honey': 1}
|
||||
expect(user.stats.exp).to.eql 30
|
||||
|
|
@ -574,6 +618,7 @@ describe 'User', ->
|
|||
expect(quest.value).to.be.greaterThan 0 if quest.canBuy
|
||||
expect(quest.drop.gp).to.not.be.lessThan 0
|
||||
expect(quest.drop.exp).to.not.be.lessThan 0
|
||||
expect(quest.category).to.match(/pet|unlockable|gold|world/)
|
||||
if quest.drop.items
|
||||
expect(quest.drop.items).to.be.an(Array)
|
||||
if quest.boss
|
||||
|
|
|
|||
119
test/spec/services/questServicesSpec.js
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
'use strict';
|
||||
|
||||
describe('Quests Service', function() {
|
||||
var scope, rootScope, groupsService, quest, questsService, user, content;
|
||||
|
||||
beforeEach(function() {
|
||||
user = specHelper.newUser();
|
||||
user.ops = {
|
||||
buyQuest: sandbox.spy()
|
||||
};
|
||||
|
||||
user.achievements.quests = {};
|
||||
quest = {lvl:20};
|
||||
|
||||
module(function($provide) {
|
||||
$provide.value('User', {user: user});
|
||||
});
|
||||
|
||||
inject(function($rootScope, $controller, Quests, Groups, Content) {
|
||||
scope = $rootScope.$new();
|
||||
rootScope = $rootScope;
|
||||
$controller('RootCtrl', {$scope: scope, User: {user: user}});
|
||||
questsService = Quests;
|
||||
groupsService = Groups;
|
||||
content = Content;
|
||||
});
|
||||
|
||||
sandbox.stub(groupsService, 'inviteOrStartParty');
|
||||
sandbox.stub(rootScope, 'openModal');
|
||||
sandbox.stub(window,'confirm',function(){return true});
|
||||
sandbox.stub(window,'alert');
|
||||
});
|
||||
|
||||
context('functions', function() {
|
||||
|
||||
describe('lock quest', function() {
|
||||
|
||||
it('locks quest when user does not meet level requirement', function() {
|
||||
user.stats.lvl = 15;
|
||||
|
||||
expect(questsService.lockQuest(quest)).to.be.ok;
|
||||
});
|
||||
|
||||
it('does not lock quest if we ignore level requirement', function() {
|
||||
user.stats.lvl = 15;
|
||||
|
||||
expect(questsService.lockQuest(quest,true)).to.not.be.ok;
|
||||
});
|
||||
|
||||
it('does not lock quest if user meets level requirement', function() {
|
||||
user.stats.lvl = 20;
|
||||
|
||||
expect(questsService.lockQuest(quest)).to.not.be.ok;
|
||||
});
|
||||
|
||||
it('locks quest if user has not completed previous quest in series', function() {
|
||||
quest.previous = 'priorQuest';
|
||||
user.stats.lvl = 25;
|
||||
|
||||
expect(questsService.lockQuest(quest)).to.be.ok;
|
||||
});
|
||||
|
||||
it('does not lock quest if user has completed previous quest in series', function() {
|
||||
quest.previous = 'priorQuest';
|
||||
user.stats.lvl = 25;
|
||||
user.achievements.quests.priorQuest = 1;
|
||||
|
||||
expect(questsService.lockQuest(quest)).to.not.be.ok;
|
||||
});
|
||||
});
|
||||
|
||||
describe('buy quest', function() {
|
||||
|
||||
it('prompts user to invite friends to party for invite reward quests', function() {
|
||||
questsService.buyQuest('basilist');
|
||||
|
||||
expect(window.confirm).to.have.been.calledOnce;
|
||||
expect(groupsService.inviteOrStartParty).to.have.been.calledOnce;
|
||||
expect(rootScope.openModal).to.have.been.notCalled;
|
||||
});
|
||||
|
||||
it('does not allow user to buy quests whose previous quests are incomplete', function() {
|
||||
user.stats.lvl = 100;
|
||||
|
||||
questsService.buyQuest('goldenknight2');
|
||||
|
||||
expect(window.alert).to.have.been.calledOnce;
|
||||
expect(rootScope.openModal).to.have.been.notCalled;
|
||||
});
|
||||
|
||||
it('does not allow user to buy quests beyond their level', function() {
|
||||
user.stats.lvl = 1;
|
||||
|
||||
questsService.buyQuest('vice1');
|
||||
|
||||
expect(window.alert).to.have.been.calledOnce;
|
||||
expect(rootScope.openModal).to.have.been.notCalled;
|
||||
});
|
||||
|
||||
it('opens purchase modal if all prerequisites are met', function() {
|
||||
user.stats.lvl = 100;
|
||||
user.achievements.quests.atom1 = 2;
|
||||
|
||||
questsService.buyQuest('atom2');
|
||||
|
||||
expect(scope.selectedQuest).to.eql(content.quests.atom2);
|
||||
expect(rootScope.openModal).to.have.been.calledOnce;
|
||||
expect(rootScope.openModal).to.have.been.calledWith('buyQuest');
|
||||
});
|
||||
|
||||
it('calls user ops buyQuest if quest is Gold-purchasable', function() {
|
||||
questsService.buyQuest('dilatoryDistress1');
|
||||
|
||||
expect(user.ops.buyQuest).to.have.been.calledOnce;
|
||||
expect(rootScope.openModal).to.have.been.notCalled;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -24,7 +24,7 @@ var specHelper = {};
|
|||
food: {},
|
||||
pets: {},
|
||||
mounts: {},
|
||||
gear: {equipped: {}, costume: {}, owned: {}},
|
||||
gear: {equipped: {}, costume: {}, owned: {}}
|
||||
},
|
||||
party: {
|
||||
quest: {
|
||||
|
|
@ -37,7 +37,7 @@ var specHelper = {};
|
|||
rewards: [],
|
||||
flags: {},
|
||||
filters: {},
|
||||
achievements: {},
|
||||
achievements: {}
|
||||
};
|
||||
return user;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,8 +74,8 @@ menu.pets div
|
|||
padding:.3em
|
||||
width:6em
|
||||
margin-top:1em
|
||||
p
|
||||
text-align:center
|
||||
p
|
||||
//width:6em
|
||||
margin-top:-.3em
|
||||
.hatchingPotion-menu > div
|
||||
|
|
|
|||
|
|
@ -193,6 +193,10 @@ window.habitrpg = angular.module('habitrpg',
|
|||
url: '/drops',
|
||||
templateUrl: "partials/options.inventory.drops.html"
|
||||
})
|
||||
.state('options.inventory.quests', {
|
||||
url: '/quests',
|
||||
templateUrl: "partials/options.inventory.quests.html"
|
||||
})
|
||||
.state('options.inventory.pets', {
|
||||
url: '/pets',
|
||||
templateUrl: "partials/options.inventory.pets.html"
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
"use strict";
|
||||
|
||||
habitrpg.controller("HeaderCtrl", ['$scope', 'Groups', 'User', '$location', '$rootScope', 'Analytics',
|
||||
function($scope, Groups, User, $location, $rootScope, Analytics) {
|
||||
habitrpg.controller("HeaderCtrl", ['$scope', 'Groups', 'User',
|
||||
function($scope, Groups, User) {
|
||||
|
||||
$scope.Math = window.Math;
|
||||
$scope.user = User.user;
|
||||
|
||||
$scope.inviteOrStartParty = Groups.inviteOrStartParty;
|
||||
|
||||
$scope.party = Groups.party(function(){
|
||||
var triggerResort = function() {
|
||||
$scope.partyMinusSelf = resortParty();
|
||||
|
|
@ -16,20 +18,6 @@ habitrpg.controller("HeaderCtrl", ['$scope', 'Groups', 'User', '$location', '$ro
|
|||
$scope.$watch('user.party.orderAscending', triggerResort);
|
||||
});
|
||||
|
||||
$scope.inviteOrStartParty = function(group) {
|
||||
if (group.type === "party") {
|
||||
$rootScope.openModal('invite-friends', {
|
||||
controller:'InviteToGroupCtrl',
|
||||
resolve: {
|
||||
injectedGroup: function(){ return group; }
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Analytics.track({'hitType':'event','eventCategory':'button','eventAction':'click','eventLabel':'Invite Friends'});
|
||||
$location.path("/options/groups/party");
|
||||
}
|
||||
}
|
||||
|
||||
function resortParty() {
|
||||
var result = _.sortBy(
|
||||
_.filter($scope.party.members, function(member){
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
habitrpg.controller("InventoryCtrl",
|
||||
['$rootScope', '$scope', 'Shared', '$window', 'User', 'Content', 'Analytics',
|
||||
function($rootScope, $scope, Shared, $window, User, Content, Analytics) {
|
||||
['$rootScope', '$scope', 'Shared', '$window', 'User', 'Content', 'Analytics', 'Quests',
|
||||
function($rootScope, $scope, Shared, $window, User, Content, Analytics, Quests) {
|
||||
|
||||
var user = User.user;
|
||||
|
||||
|
|
@ -11,6 +11,13 @@ habitrpg.controller("InventoryCtrl",
|
|||
$scope.totalPets = _.size(Content.dropEggs) * _.size(Content.hatchingPotions);
|
||||
$scope.totalMounts = _.size(Content.dropEggs) * _.size(Content.hatchingPotions);
|
||||
|
||||
// Functions from Quests service
|
||||
$scope.lockQuest = Quests.lockQuest;
|
||||
$scope.buyQuest = Quests.buyQuest;
|
||||
$scope.questPopover = Quests.questPopover;
|
||||
$scope.showQuest = Quests.showQuest;
|
||||
$scope.closeQuest = Quests.closeQuest;
|
||||
|
||||
// count egg, food, hatchingPotion stack totals
|
||||
var countStacks = function(items) { return _.reduce(items,function(m,v){return m+v;},0);}
|
||||
|
||||
|
|
@ -139,46 +146,6 @@ habitrpg.controller("InventoryCtrl",
|
|||
User.user.ops.equip({params:{type: 'mount', key: egg + '-' + potion}});
|
||||
}
|
||||
|
||||
$scope.questPopover = function(quest) {
|
||||
// The popover gets parsed as markdown (hence the double \n for line breaks
|
||||
var text = '';
|
||||
if(quest.boss) {
|
||||
text += '**' + window.env.t('bossHP') + ':** ' + quest.boss.hp + '\n\n';
|
||||
text += '**' + window.env.t('bossStrength') + ':** ' + quest.boss.str + '\n\n';
|
||||
} else if(quest.collect) {
|
||||
var count = 0;
|
||||
for (var key in quest.collect) {
|
||||
text += '**' + window.env.t('collect') + ':** ' + quest.collect[key].count + ' ' + quest.collect[key].text() + '\n\n';
|
||||
}
|
||||
}
|
||||
text += '---\n\n';
|
||||
text += '**' + window.env.t('rewards') + ':**\n\n';
|
||||
if(quest.drop.items) {
|
||||
for (var item in quest.drop.items) {
|
||||
text += quest.drop.items[item].text() + '\n\n';
|
||||
}
|
||||
}
|
||||
if(quest.drop.exp)
|
||||
text += quest.drop.exp + ' ' + window.env.t('experience') + '\n\n';
|
||||
if(quest.drop.gp)
|
||||
text += quest.drop.gp + ' ' + window.env.t('gold') + '\n\n';
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
$scope.showQuest = function(quest) {
|
||||
var item = Content.quests[quest];
|
||||
var completedPrevious = !item.previous || (User.user.achievements.quests && User.user.achievements.quests[item.previous]);
|
||||
if (!completedPrevious)
|
||||
return alert(window.env.t('mustComplete', {quest: $rootScope.Content.quests[item.previous].text()}));
|
||||
if (item.lvl && item.lvl > user.stats.lvl)
|
||||
return alert(window.env.t('mustLevel', {level: item.lvl}));
|
||||
$rootScope.selectedQuest = item;
|
||||
$rootScope.openModal('showQuest', {controller:'InventoryCtrl'});
|
||||
}
|
||||
$scope.closeQuest = function(){
|
||||
$rootScope.selectedQuest = undefined;
|
||||
}
|
||||
$scope.questInit = function(){
|
||||
Analytics.track({'hitType':'event','eventCategory':'behavior','eventAction':'quest','owner':true,'response':'accept','questName':$scope.selectedQuest.key});
|
||||
$rootScope.party.$questAccept({key:$scope.selectedQuest.key}, function(){
|
||||
|
|
@ -187,17 +154,6 @@ habitrpg.controller("InventoryCtrl",
|
|||
$scope.closeQuest();
|
||||
}
|
||||
|
||||
$scope.buyQuest = function(quest) {
|
||||
var item = Content.quests[quest];
|
||||
if (item.lvl && item.lvl > user.stats.lvl)
|
||||
return alert(window.env.t('mustLvlQuest', {level: item.lvl}));
|
||||
var completedPrevious = !item.previous || (User.user.achievements.quests && User.user.achievements.quests[item.previous]);
|
||||
if (!completedPrevious)
|
||||
return $scope.purchase("quests", item);
|
||||
$rootScope.selectedQuest = item;
|
||||
$rootScope.openModal('buyQuest', {controller:'InventoryCtrl'});
|
||||
}
|
||||
|
||||
$scope.getSeasonalShopArray = function(set){
|
||||
var flatGearArray = _.toArray(Content.gear.flat);
|
||||
|
||||
|
|
|
|||
|
|
@ -219,7 +219,6 @@ habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User','N
|
|||
$scope.buy = function(item) {
|
||||
User.user.ops.buy({params:{key:item.key}});
|
||||
$rootScope.playSound('Reward');
|
||||
Guide.goto('intro', 4);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
*/
|
||||
|
||||
angular.module('habitrpg').factory('Groups',
|
||||
['ApiUrl', '$resource', '$q', '$http', 'User', 'Challenges',
|
||||
function(ApiUrl, $resource, $q, $http, User, Challenges) {
|
||||
['$rootScope','ApiUrl', '$resource', '$q', '$http', 'User', 'Challenges', 'Analytics', '$location',
|
||||
function($rootScope, ApiUrl, $resource, $q, $http, User, Challenges, Analytics, $location) {
|
||||
var Group = $resource(ApiUrl.get() + '/api/v2/groups/:gid',
|
||||
{gid:'@_id', messageId: '@_messageId'},
|
||||
{
|
||||
|
|
@ -83,6 +83,20 @@ function(ApiUrl, $resource, $q, $http, User, Challenges) {
|
|||
.then(syncUser, logError);
|
||||
},
|
||||
|
||||
inviteOrStartParty: function(group) {
|
||||
if (group.type === "party") {
|
||||
$rootScope.openModal('invite-friends', {
|
||||
controller:'InviteToGroupCtrl',
|
||||
resolve: {
|
||||
injectedGroup: function(){ return group; }
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Analytics.track({'hitType':'event','eventCategory':'button','eventAction':'click','eventLabel':'Invite Friends'});
|
||||
$location.path("/options/groups/party");
|
||||
}
|
||||
},
|
||||
|
||||
// Pass reference to party, myGuilds, publicGuilds, tavern; inside data in order to
|
||||
// be able to modify them directly (otherwise will be stick with cached version)
|
||||
data: data,
|
||||
|
|
|
|||
98
website/public/js/services/questServices.js
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/**
|
||||
* Created by Sabe on 7/7/2015.
|
||||
*/
|
||||
(function(){
|
||||
angular
|
||||
.module('habitrpg')
|
||||
.factory('Quests', questsFactory);
|
||||
|
||||
questsFactory.$inject = [
|
||||
'$rootScope',
|
||||
'Content',
|
||||
'Groups',
|
||||
'User'
|
||||
];
|
||||
|
||||
function questsFactory($rootScope,Content,Groups,User) {
|
||||
|
||||
var user = User.user;
|
||||
|
||||
function lockQuest(quest,ignoreLevel) {
|
||||
if (!ignoreLevel){
|
||||
if (quest.lvl && user.stats.lvl < quest.lvl) return true;
|
||||
}
|
||||
if (user.achievements.quests) return (quest.previous && !user.achievements.quests[quest.previous]);
|
||||
return (quest.previous);
|
||||
}
|
||||
|
||||
function buyQuest(quest) {
|
||||
var item = Content.quests[quest];
|
||||
|
||||
if (item.unlockCondition && item.unlockCondition.condition === 'party invite') {
|
||||
if (!confirm(window.env.t('mustInviteFriend'))) return;
|
||||
return Groups.inviteOrStartParty(Groups.party());
|
||||
}
|
||||
if (item.previous && (!User.user.achievements.quests || (User.user.achievements.quests && !User.user.achievements.quests[item.previous]))){
|
||||
return alert(window.env.t('unlockByQuesting', {title: Content.quests[item.previous].text()}));
|
||||
}
|
||||
if (item.lvl && item.lvl > user.stats.lvl) {
|
||||
return alert(window.env.t('mustLvlQuest', {level: item.lvl}));
|
||||
}
|
||||
if (item.category === 'gold') {
|
||||
return User.user.ops.buyQuest({params:{key:item.key}});
|
||||
}
|
||||
$rootScope.selectedQuest = item;
|
||||
$rootScope.openModal('buyQuest', {controller:'InventoryCtrl'});
|
||||
}
|
||||
|
||||
function questPopover(quest) {
|
||||
// The popover gets parsed as markdown (hence the double \n for line breaks
|
||||
var text = '';
|
||||
if(quest.boss) {
|
||||
text += '**' + window.env.t('bossHP') + ':** ' + quest.boss.hp + '\n\n';
|
||||
text += '**' + window.env.t('bossStrength') + ':** ' + quest.boss.str + '\n\n';
|
||||
} else if(quest.collect) {
|
||||
var count = 0;
|
||||
for (var key in quest.collect) {
|
||||
text += '**' + window.env.t('collect') + ':** ' + quest.collect[key].count + ' ' + quest.collect[key].text() + '\n\n';
|
||||
}
|
||||
}
|
||||
text += '---\n\n';
|
||||
text += '**' + window.env.t('rewards') + ':**\n\n';
|
||||
if(quest.drop.items) {
|
||||
for (var item in quest.drop.items) {
|
||||
text += quest.drop.items[item].text() + '\n\n';
|
||||
}
|
||||
}
|
||||
if(quest.drop.exp)
|
||||
text += quest.drop.exp + ' ' + window.env.t('experience') + '\n\n';
|
||||
if(quest.drop.gp)
|
||||
text += quest.drop.gp + ' ' + window.env.t('gold') + '\n\n';
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
function showQuest(quest) {
|
||||
var item = Content.quests[quest];
|
||||
var completedPrevious = !item.previous || (User.user.achievements.quests && User.user.achievements.quests[item.previous]);
|
||||
if (!completedPrevious)
|
||||
return alert(window.env.t('mustComplete', {quest: $rootScope.Content.quests[item.previous].text()}));
|
||||
if (item.lvl && item.lvl > user.stats.lvl)
|
||||
return alert(window.env.t('mustLevel', {level: item.lvl}));
|
||||
$rootScope.selectedQuest = item;
|
||||
$rootScope.openModal('showQuest', {controller:'InventoryCtrl'});
|
||||
}
|
||||
|
||||
function closeQuest(){
|
||||
$rootScope.selectedQuest = undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
lockQuest: lockQuest,
|
||||
buyQuest: buyQuest,
|
||||
questPopover: questPopover,
|
||||
showQuest: showQuest,
|
||||
closeQuest: closeQuest
|
||||
}
|
||||
}
|
||||
}());
|
||||
|
|
@ -51,6 +51,7 @@
|
|||
"js/services/taskServices.js",
|
||||
"js/services/challengeServices.js",
|
||||
"js/services/paymentServices.js",
|
||||
"js/services/questServices.js",
|
||||
|
||||
"js/filters/money.js",
|
||||
"js/filters/roundLargeNumbers.js",
|
||||
|
|
|
|||
|
|
@ -31,18 +31,6 @@
|
|||
ng-click='choosePotion(pot)')
|
||||
.badge.badge-info.stack-count {{points}}
|
||||
|
||||
li.customize-menu
|
||||
menu.pets-menu(label=(env.t('quests') + ' ({{questCount}})'))
|
||||
p.muted(ng-show='questCount < 1')=env.t('noScrolls')
|
||||
p.muted!=env.t('scrollsText1') + ' <a href="/#/options/groups/party">' + env.t('scrollsText2') + '</a>'
|
||||
div(ng-repeat='(quest_key,points) in ownedItems(user.items.quests)', ng-init='quest = Content.quests[quest_key]')
|
||||
button.customize-option(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}}"',
|
||||
data-popover-html="{{:: quest.previous && !user.achievements.quests[quest.previous] ? env.t('scrollsPre') : questPopover(quest) | markdown}}",
|
||||
popover-title='{{::quest.text()}}', popover-trigger='mouseenter',
|
||||
popover-placement='right', popover-append-to-body='true',
|
||||
ng-click='showQuest(quest_key)')
|
||||
.badge.badge-info.stack-count {{points}}
|
||||
|
||||
li.customize-menu
|
||||
menu.pets-menu(label=env.t('food') + ' ({{foodCount}})')
|
||||
p.muted(ng-show='foodCount < 1')=env.t('noFood')
|
||||
|
|
@ -179,19 +167,6 @@
|
|||
| {{::food.value}}
|
||||
span.Pet_Currency_Gem1x.inline-gems
|
||||
|
||||
li.customize-menu
|
||||
menu.pets-menu(label=env.t('quests'))
|
||||
p.muted!=env.t('scrollsText1') + ' <a href="/#/options/groups/party">' + env.t('scrollsText2') + '</a>'
|
||||
div(ng-repeat='quest in Content.quests', ng-if='quest.canBuy')
|
||||
button.customize-option(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}}"',
|
||||
data-popover-html="{{::quest.previous && !user.achievements.quests[quest.previous] ? env.t('scrollsPre') : questPopover(quest) | markdown}}",
|
||||
popover-title='{{::quest.text()}}', popover-append-to-body="true",
|
||||
popover-trigger='mouseenter',
|
||||
ng-click='buyQuest(quest.key)')
|
||||
p
|
||||
| {{::quest.value}}
|
||||
span.Pet_Currency_Gem1x.inline-gems
|
||||
|
||||
li.customize-menu
|
||||
menu.pets-menu(label=env.t('special'))
|
||||
div
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
menu.pets-menu(label='{{::label}}', ng-show='gear[klass]',
|
||||
ng-repeat='(klass,label) in {warrior:env.t("warrior"), wizard:env.t("mage"), rogue:env.t("rogue"), healer:env.t("healer"), special:env.t("special"), mystery:env.t("mystery"), armoire:env.t("armoireText")}')
|
||||
div(ng-repeat='item in gear[klass]')
|
||||
button.customize-option(class='shop_{{::item.key}}',
|
||||
button.customize-option(, class='shop_{{::item.key}}',
|
||||
ng-class='{selectableInventory: user.items.gear.equipped[item.type] == item.key}',
|
||||
ng-click='equip(item.key, "equipped")',
|
||||
popover='{{::item.notes()}}', popover-title='{{::item.text()}}',
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
label
|
||||
input(type="checkbox", ng-model="user.preferences.costume",
|
||||
ng-change='set({"preferences.costume":user.preferences.costume ? true : false})')
|
||||
|
|
||||
|
|
||||
=env.t('useCostume')
|
||||
|
||||
div
|
||||
|
|
@ -47,7 +47,7 @@
|
|||
div(ng-repeat='item in gear[klass]')
|
||||
button.customize-option(class='shop_{{::item.key}}',
|
||||
ng-class='{selectableInventory: user.items.gear.costume[item.type] == item.key}',
|
||||
popover='{{::item.notes()}}',
|
||||
popover-title='{{::item.text()}}', popover-trigger='mouseenter',
|
||||
popover-placement='right', popover-append-to-body='true',
|
||||
ng-click='equip(item.key, "costume")')
|
||||
ng-click='equip(item.key, "costume")',
|
||||
popover='{{::item.notes()}}', popover-title='{{::item.text()}}',
|
||||
popover-trigger='mouseenter', popover-placement='right',
|
||||
popover-append-to-body='true')
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ script(type='text/ng-template', id='partials/options.inventory.timetravelers.htm
|
|||
script(type='text/ng-template', id='partials/options.inventory.drops.html')
|
||||
include ./drops
|
||||
|
||||
script(type='text/ng-template', id='partials/options.inventory.quests.html')
|
||||
include ./quests
|
||||
|
||||
script(type='text/ng-template', id='partials/options.inventory.pets.html')
|
||||
include ./pets
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@ ul.options-menu
|
|||
li(ng-class="{ active: $state.includes('options.inventory.drops') }")
|
||||
a(ui-sref='options.inventory.drops')
|
||||
=env.t('market')
|
||||
li(ng-class="{ active: $state.includes('options.inventory.quests') }")
|
||||
a(ui-sref='options.inventory.quests')
|
||||
=env.t('quests')
|
||||
li(ng-class="{ active: $state.includes('options.inventory.pets') }")
|
||||
a(ui-sref='options.inventory.pets')
|
||||
=env.t('pets')
|
||||
|
|
|
|||
39
website/views/options/inventory/quests.jade
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
.container-fluid
|
||||
.row
|
||||
.col-md-2
|
||||
.npc_ian
|
||||
.col-md-10
|
||||
.popover.static-popover.fade.right.in
|
||||
.arrow
|
||||
h3.popover-title=env.t('ian')
|
||||
.popover-content
|
||||
p=env.t('ianText')
|
||||
.row
|
||||
- var questCategories = {'unlockable':'unlockableQuests','pet':'petQuests','gold':'goldQuests'}
|
||||
.col-md-6
|
||||
h3.equipment-title=env.t('yourQuests')
|
||||
menu.inventory-list
|
||||
li.customize-menu
|
||||
p.muted(ng-show='questCount < 1')=env.t('noScrolls')
|
||||
each caption,type in questCategories
|
||||
menu.pets-menu(label=env.t(caption))
|
||||
div(ng-repeat='(quest_key,points) in ownedItems(user.items.quests)', ng-init='quest = Content.quests[quest_key]', ng-if='Content.quests[quest_key].category === "#{type}"')
|
||||
button.customize-option(data-popover-html="{{::lockQuest(quest) ? env.t('scrollsPre') : questPopover(quest) | markdown}}", popover-title='{{::quest.text()}}', popover-trigger='mouseenter', popover-placement='right', popover-append-to-body='true', ng-click='showQuest(quest_key)', ng-class='lockQuest(quest) ? "inventory_quest_scroll_locked inventory_quest_scroll_{{::quest.key}}_locked locked" : "inventory_quest_scroll inventory_quest_scroll_{{::quest.key}}"')
|
||||
.badge.badge-info.stack-count {{points}}
|
||||
.col-md-6.border-left
|
||||
li.customize-menu
|
||||
h3.equipment-title=env.t('questsForSale')
|
||||
each caption,type in questCategories
|
||||
menu.pets-menu(label=env.t(caption))
|
||||
div(ng-repeat='quest in Content.questsByLevel', ng-if='quest.canBuy && quest.category === "#{type}"')
|
||||
button.customize-option(data-popover-html="{{::lockQuest(quest,true) ? env.t('scrollsPre') : questPopover(quest) | markdown}}", popover-title='{{::quest.text()}}', popover-append-to-body="true", popover-trigger='mouseenter', ng-click='buyQuest(quest.key)', ng-class='lockQuest(quest) ? "inventory_quest_scroll_locked inventory_quest_scroll_{{::quest.key}}_locked locked" : "inventory_quest_scroll inventory_quest_scroll_{{::quest.key}}"')
|
||||
p(ng-if='quest.unlockCondition')
|
||||
| {{::quest.unlockCondition.text()}}
|
||||
p(ng-if='!quest.unlockCondition && quest.category !== "gold" && !lockQuest(quest)')
|
||||
| {{::quest.value}}
|
||||
span.Pet_Currency_Gem1x.inline-gems
|
||||
p(ng-if='quest.category === "gold" && !lockQuest(quest)')
|
||||
| {{::quest.goldValue}}
|
||||
span.shop_gold
|
||||
p(ng-if='quest.lvl && lockQuest(quest)')=env.t('level')
|
||||
| {{::quest.lvl}}
|
||||
|
|
@ -2,13 +2,16 @@
|
|||
.stable.row
|
||||
.col-md-2
|
||||
.seasonalshop_summer2015
|
||||
|
||||
.col-md-10
|
||||
.popover.static-popover.fade.right.in
|
||||
.arrow
|
||||
h3.popover-title!=env.t('seasonalShopTitle', {linkStart:"<a href='http://blog.habitrpg.com/who' target='_blank'>", linkEnd: "</a>"})
|
||||
.popover-content
|
||||
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)',
|
||||
|
|
@ -21,11 +24,15 @@
|
|||
.text-left
|
||||
| {{((item.specialClass == "wizard") && (item.type == "weapon")) + 1}}
|
||||
span.Pet_Currency_Gem1x.inline-gems
|
||||
|
||||
// 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}}
|
||||
button.customize-option(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}}"'
|
||||
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)')
|
||||
p {{::quest.value}}
|
||||
span.Pet_Currency_Gem1x.inline-gems
|
||||
menu.pets-menu(label=env.t('seasonalItems'))
|
||||
div
|
||||
|
|
@ -37,8 +44,8 @@
|
|||
ng-click='purchase("special", Content.spells.special.seafoam)')
|
||||
p {{::Content.spells.special.seafoam.value}}
|
||||
span(class='shop_gold')
|
||||
|
||||
// div
|
||||
button.customize-option(popover='{{::Content.spells.special.nye.notes()}}', popover-title='{{::Content.spells.special.nye.text()}}', popover-trigger='mouseenter', popover-placement='right', popover-append-to-body='true', ng-click='castStart(Content.spells.special.nye)', class='inventory_special_nye')
|
||||
p
|
||||
| {{Content.spells.special.nye.value}}
|
||||
p {{Content.spells.special.nye.value}}
|
||||
span(class='shop_gold')
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ else
|
|||
div(class="quest_{{::group.quest.key}}")
|
||||
|
||||
.hero-stats
|
||||
h4 {{::Content.quests[group.quest.key].boss.name()}}
|
||||
.meter-label(tooltip=env.t('bossHP'))
|
||||
span.glyphicon.glyphicon-heart
|
||||
.meter.health
|
||||
|
|
@ -16,7 +17,7 @@ else
|
|||
span.glyphicon.glyphicon-fire
|
||||
.meter.mana(popover="{{::boss.rage.description()}}",
|
||||
popover-title="{{::boss.rage.title()}}",
|
||||
popover-trigger='mouseenter', popover-placement='right')
|
||||
popover-trigger='mouseenter', popover-placement='bottom')
|
||||
.bar(ng-style='{width: Shared.percent(progress.rage, boss.rage.value) + "%"}')
|
||||
span.meter-text.value
|
||||
| {{Math.ceil(progress.rage) | roundLargeNumbers}}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ nav.toolbar(ng-controller='MenuCtrl', ng-class='{active: isToolbarHidden}')
|
|||
ul.toolbar-submenu
|
||||
li
|
||||
a(ui-sref='options.inventory.drops')=env.t('market')
|
||||
li
|
||||
a(ui-sref='options.inventory.quests')=env.t('quests')
|
||||
li
|
||||
a(ui-sref='options.inventory.pets')=env.t('pets')
|
||||
li
|
||||
|
|
@ -125,6 +127,8 @@ nav.toolbar(ng-controller='MenuCtrl', ng-class='{active: isToolbarHidden}')
|
|||
ul.toolbar-submenu(ng-click='expandMenu(null)')
|
||||
li
|
||||
a(ui-sref='options.inventory.drops')=env.t('market')
|
||||
li
|
||||
a(ui-sref='options.inventory.quests')=env.t('quests')
|
||||
li
|
||||
a(ui-sref='options.inventory.pets')=env.t('pets')
|
||||
li
|
||||
|
|
|
|||
|
|
@ -1,5 +1,39 @@
|
|||
h5 7/9/2015 - DERBY DAY! FREE ORCA MOUNT AND WHALE QUEST
|
||||
h5 7/14/2015 - GOLD-PURCHASABLE QUESTS, NEW EQUIPMENT IN THE ENCHANTED ARMOIRE, AND TRIVIAL TASK DIFFICULTY SETTING!
|
||||
hr
|
||||
tr
|
||||
td
|
||||
.promo_dilatoryDistress.pull-right
|
||||
h5 Gold-Purchasable Quest Line: Dilatory Distress
|
||||
p We've moved the quests to <a href='/#/options/inventory/quests'>their own separate page</a>, and added a new category: GOLD PURCHASABLE QUESTS!
|
||||
br
|
||||
p Now you can use Gold to purchase the Dilatory Distress Quest Line! King Manta's daughter has disappeared, and monsters are laying siege to the underwater city of Dilatory. Can you intervene to save them all? If so, you'll earn the exclusive Oceanic Armor Set.
|
||||
br
|
||||
p As time goes on, we'll be adding more gold-purchasable quests. Dilatory Distress is not a limited-edition quest line, so you have plenty of time to save up!
|
||||
p.small.muted by SabreCat and Lemoness
|
||||
p.small.muted Writing by liorsamuel
|
||||
p.small.muted Art by Kiwibot, aiseant, starsystemic, hazel40, and benga
|
||||
tr
|
||||
td
|
||||
.promo_enchanted_armoire_201507.pull-right
|
||||
h5 New Equipment in the Enchanted Armoire
|
||||
p There is new equipment in Enchanted Armoire, a 100 GP Reward in the Rewards Column which unlocks after you've attained Ultimate Gear!
|
||||
br
|
||||
p Click on the Enchanted Armoire for a random chance at special Equipment, including the Rancher Robes, Rancher Lasso, Blue Hairbow, and Royal Crown! It may also give you random XP or food items. We'll be adding new equipment to it during the first week of each month, but even when you've exhausted the current supply, you can keep clicking for a chance at food and XP.
|
||||
br
|
||||
p Now go spend all that accumulated gold! May the Random Number Generator smile upon you...
|
||||
p.small.muted by Lemoness and SabreCat
|
||||
p.small.muted Art by podcod, Kiwibot, and Megan
|
||||
tr
|
||||
td
|
||||
h5 Trivial Task Difficulty
|
||||
p There's a new difficulty for Tasks available under task edit: Trivial! Trivial tasks reward you or damage you at the rate of one tenth of the amount that Easy tasks would. Likewise, Trivial tasks cause much less damage during boss battles!
|
||||
p.small.muted by efim
|
||||
|
||||
hr
|
||||
a(href='/static/old-news', target='_blank') Read older news
|
||||
|
||||
mixin oldNews
|
||||
h5 7/9/2015 - DERBY DAY! FREE ORCA MOUNT AND WHALE QUEST
|
||||
tr
|
||||
td
|
||||
h5 Derby Day!
|
||||
|
|
@ -17,11 +51,6 @@ h5 7/9/2015 - DERBY DAY! FREE ORCA MOUNT AND WHALE QUEST
|
|||
p Want more whales? Check out the The Wail of the Whale, a new pet quest in the <a href='/#/options/inventory/drops'>Market</a>! On your way to the Dilatory Derby, you encounter a whale in distress. Can you calm her down? If so, you may gain some whale eggs...
|
||||
p.small.muted Art by krazjega, zoebeagle, and Uncommon Criminal
|
||||
p.small.muted Writing by Calae
|
||||
|
||||
hr
|
||||
a(href='/static/old-news', target='_blank') Read older news
|
||||
|
||||
mixin oldNews
|
||||
h5 7/7/2015 - NEW iOS APP: HABITICA!
|
||||
tr
|
||||
td
|
||||
|
|
|
|||