From d69e7e66ee441b858bb40fef3c698fd27a9cc44c Mon Sep 17 00:00:00 2001 From: Sabe Jones Date: Tue, 13 Feb 2018 19:21:39 -0600 Subject: [PATCH] World Boss 2018 (Server) (#9995) * feat(world-boss): barebones API * fix(world): use Express respond for better JSON * fix(api): respond with code 200 * feat(content): canonical Dysheartener desc and Rage * fix(world-boss): enable progress * WIP(test): world state API * WIP(test): refactor world boss setup * WIP(test): better expectations * fix(test): more expect polishing * feat(event): server side World Boss * fix(strings): accidental deletion * fix(content): include encouragement after Rage * refactor(world-boss): address comments --- .../world-state/GET-world-state.test.js | 35 +++++++ website/common/locales/en/pets.json | 2 + website/common/locales/en/questsContent.json | 14 ++- website/common/script/content/quests.js | 86 ++++++++++++++++++ website/common/script/content/stable.js | 2 + .../body/Mount_Body_Hippogriff-Hopeful.png | Bin 0 -> 1396 bytes .../head/Mount_Head_Hippogriff-Hopeful.png | Bin 0 -> 1919 bytes .../icon/Mount_Icon_Hippogriff-Hopeful.png | Bin 0 -> 829 bytes .../stable/pets/Pet-Hippogriff-Hopeful.png | Bin 0 -> 1474 bytes website/server/controllers/api-v3/world.js | 44 +++++++++ website/server/middlewares/cron.js | 2 +- website/server/models/group.js | 14 ++- 12 files changed, 194 insertions(+), 5 deletions(-) create mode 100644 test/api/v3/integration/world-state/GET-world-state.test.js create mode 100644 website/raw_sprites/spritesmith/stable/mounts/body/Mount_Body_Hippogriff-Hopeful.png create mode 100644 website/raw_sprites/spritesmith/stable/mounts/head/Mount_Head_Hippogriff-Hopeful.png create mode 100644 website/raw_sprites/spritesmith/stable/mounts/icon/Mount_Icon_Hippogriff-Hopeful.png create mode 100644 website/raw_sprites/spritesmith/stable/pets/Pet-Hippogriff-Hopeful.png create mode 100644 website/server/controllers/api-v3/world.js diff --git a/test/api/v3/integration/world-state/GET-world-state.test.js b/test/api/v3/integration/world-state/GET-world-state.test.js new file mode 100644 index 0000000000..fac08ad639 --- /dev/null +++ b/test/api/v3/integration/world-state/GET-world-state.test.js @@ -0,0 +1,35 @@ +import { TAVERN_ID } from '../../../../../website/server/models/group'; +import { updateDocument } from '../../../../helpers/mongo'; +import { + requester, + resetHabiticaDB, +} from '../../../../helpers/api-v3-integration.helper'; + +describe('GET /world-state', () => { + before(async () => { + await resetHabiticaDB(); + }); + + it('returns empty worldBoss object when world boss is not active (and does not require authentication)', async () => { + const res = await requester().get('/world-state'); + expect(res.worldBoss).to.eql({}); + }); + + it('returns Tavern quest data when world boss is active', async () => { + await updateDocument('groups', {_id: TAVERN_ID}, {quest: {active: true, key: 'dysheartener', progress: {hp: 50000, rage: 9999}}}); + + const res = await requester().get('/world-state'); + expect(res).to.have.deep.property('worldBoss'); + + expect(res.worldBoss).to.eql({ + active: true, + extra: {}, + key: 'dysheartener', + progress: { + collect: {}, + hp: 50000, + rage: 9999, + }, + }); + }); +}); diff --git a/website/common/locales/en/pets.json b/website/common/locales/en/pets.json index e85feb199f..bd0653c9ae 100644 --- a/website/common/locales/en/pets.json +++ b/website/common/locales/en/pets.json @@ -27,6 +27,8 @@ "royalPurpleGryphon": "Royal Purple Gryphon", "phoenix": "Phoenix", "magicalBee": "Magical Bee", + "hopefulHippogriffPet": "Hopeful Hippogriff", + "hopefulHippogriffMount": "Hopeful Hippogriff", "royalPurpleJackalope": "Royal Purple Jackalope", "invisibleAether": "Invisible Aether", "rarePetPop1": "Click the gold paw to learn more about how you can obtain this rare pet through contributing to Habitica!", diff --git a/website/common/locales/en/questsContent.json b/website/common/locales/en/questsContent.json index 8d99996e68..9a5d5ca37b 100644 --- a/website/common/locales/en/questsContent.json +++ b/website/common/locales/en/questsContent.json @@ -654,5 +654,17 @@ "questBadgerCompletion": "You finally drive away the the Badgering Bother and hurry into its burrow. At the end of a tunnel, you find its hoard of the faeries’ “Hibernate” To-Dos. The den is otherwise abandoned, except for three eggs that look ready to hatch.", "questBadgerBoss": "The Badgering Bother", "questBadgerDropBadgerEgg": "Badger (Egg)", - "questBadgerUnlockText": "Unlocks purchasable Badger eggs in the Market" + "questBadgerUnlockText": "Unlocks purchasable Badger eggs in the Market", + + "questDysheartenerText": "The Dysheartener", + "questDysheartenerNotes": "The sun is rising on Valentine’s Day when a shocking crash splinters the air. A blaze of sickly pink light lances through all the buildings, and bricks crumble as a deep crack rips through Habit City’s main street. An unearthly shrieking rises through the air, shattering windows as a hulking form slithers forth from the gaping earth.

Mandibles snap and a carapace glitters; legs upon legs unfurl in the air. The crowd begins to scream as the insectoid creature rears up, revealing itself to be none other than that cruelest of creatures: the fearsome Dysheartener itself. It howls in anticipation and lunges forward, hungering to gnaw on the hopes of hard-working Habiticans. With each rasping scrape of its spiny forelegs, you feel a vise of despair tightening in your chest.

“Take heart, everyone!” Lemoness shouts. “It probably thinks that we’re easy targets because so many of us have daunting New Year’s Resolutions, but it’s about to discover that Habiticans know how to stick to their goals!”

AnnDeLune raises her staff. “Let’s tackle our tasks and take this monster down!”", + "questDysheartenerCompletion": "The Dysheartener is DEFEATED!

Together, everyone in Habitica strikes a final blow to their tasks, and the Dysheartener rears back, shrieking with dismay. “What's wrong, Dysheartener?” AnnDeLune calls, eyes sparkling. “Feeling discouraged?”

Glowing pink fractures crack across the Dysheartener's carapace, and it shatters in a puff of pink smoke. As a renewed sense of vigor and determination sweeps across the land, a flurry of delightful sweets rains down upon everyone.

The crowd cheers wildly, hugging each other as their pets happily chew on the belated Valentine's treats. Suddenly, a joyful chorus of song cascades through the air, and gleaming silhouettes soar across the sky.

Our newly-invigorated optimism has attracted a flock of Hopeful Hippogriffs! The graceful creatures alight upon the ground, ruffling their feathers with interest and prancing about. “It looks like we've made some new friends to help keep our spirits high, even when our tasks are daunting,” Lemoness says.

Beffymaroo already has her arms full with feathered fluffballs. “Maybe they'll help us rebuild the damaged areas of Habitica!”

Crooning and singing, the Hippogriffs lead the way as all the Habitcans work together to restore our beloved home.", + "questDysheartenerCompletionChat": "`The Dysheartener is DEFEATED!`\n\nTogether, everyone in Habitica strikes a final blow to their tasks, and the Dysheartener rears back, shrieking with dismay. “What's wrong, Dysheartener?” AnnDeLune calls, eyes sparkling. “Feeling discouraged?”\n\nGlowing pink fractures crack across the Dysheartener's carapace, and it shatters in a puff of pink smoke. As a renewed sense of vigor and determination sweeps across the land, a flurry of delightful sweets rains down upon everyone.\n\nThe crowd cheers wildly, hugging each other as their pets happily chew on the belated Valentine's treats. Suddenly, a joyful chorus of song cascades through the air, and gleaming silhouettes soar across the sky.\n\nOur newly-invigorated optimism has attracted a flock of Hopeful Hippogriffs! The graceful creatures alight upon the ground, ruffling their feathers with interest and prancing about. “It looks like we've made some new friends to help keep our spirits high, even when our tasks are daunting,” Lemoness says.\n\nBeffymaroo already has her arms full with feathered fluffballs. “Maybe they'll help us rebuild the damaged areas of Habitica!”\n\nCrooning and singing, the Hippogriffs lead the way as all the Habitcans work together to restore our beloved home.", + "questDysheartenerBossRageTitle": "Shattering Heartbreak", + "questDysheartenerBossRageDescription": "When this gauge fills, the Dysheartener will unleash its Shattering Heartbreak on Habitica!", + "questDysheartenerBossRageSeasonal": "`The Dysheartener uses SHATTERING HEARTBREAK!`\n\nOh, no! After feasting on our undone Dailies, the Dysheartener has gained the strength to unleash its Shattering Heartbreak attack. With a shrill shriek, it brings its spiny forelegs down upon the gazebo that houses the Seasonal Shop! The concussive blast of magic shreds the wood, and the Seasonal Sorceress is overcome by sorrow at the sight.\n\nQuickly, let's keep doing our Dailies so that the beast won't strike again!", + "questDysheartenerBossRageMarket": "`The Dysheartener uses SHATTERING HEARTBREAK!`\n\nHelp! After feasting on our incomplete Dailies, the Dysheartener lets out another Shattering Heartbreak attack, smashing the walls and floor of the Market! As stone rains down, Alex the Merchant weeps at his crushed merchandise, stricken by the destruction.\n\nWe can't let this happen again! Be sure to do all our your Dailies to prevent the Dysheartener from using its final strike.", + "questDysheartenerBossRageQuests": "`The Dysheartener uses SHATTERING HEARTBREAK!`\n\nAaaah! We've left our Dailies undone again, and the Dysheartener has mustered the energy for one final blow against our beloved shopkeepers. The countryside around Ian the Quest Master is ripped apart by its Shattering Heartbreak attack, and Ian is struck to the core by the horrific vision. We're so close to defeating this monster.... Hurry! Don't stop now!", + "questDysheartenerDropHippogriffPet": "Hopeful Hippogriff (Pet)", + "questDysheartenerDropHippogriffMount": "Hopeful Hippogriff (Mount)" } diff --git a/website/common/script/content/quests.js b/website/common/script/content/quests.js index 913bb96e5c..26dfcd28da 100644 --- a/website/common/script/content/quests.js +++ b/website/common/script/content/quests.js @@ -3099,6 +3099,92 @@ let quests = { unlock: t('questBadgerUnlockText'), }, }, + dysheartener: { + text: t('questDysheartenerText'), + notes: t('questDysheartenerNotes'), + completion: t('questDysheartenerCompletion'), + completionChat: t('questDysheartenerCompletionChat'), + value: 0, + canBuy () { + return false; + }, + category: 'world', + boss: { + name: t('questDysheartenerText'), + hp: 17000000, + str: 1.25, + def: 1, + rage: { + title: t('questDysheartenerBossRageTitle'), + description: t('questDysheartenerBossRageDescription'), + value: 500000, + seasonalShop: t('questDysheartenerBossRageSeasonal'), + market: t('questDysheartenerBossRageMarket'), + quests: t('questDysheartenerBossRageQuests'), + }, + }, + colors: { + dark: '#410F2A', + medium: '#5C1130', + light: '#931F4D', + extralight: '#DC4069', + }, + drop: { + items: [ + { + type: 'pets', + key: 'Hippogriff-Hopeful', + text: t('questDysheartenerDropHippogriffPet'), + }, { + type: 'mounts', + key: 'Hippogriff-Hopeful', + text: t('questDysheartenerDropHippogriffMount'), + }, { + type: 'food', + key: 'Cake_Base', + text: t('foodCakeBase'), + }, { + type: 'food', + key: 'Candy_White', + text: t('foodCandyWhite'), + }, { + type: 'food', + key: 'Cake_Desert', + text: t('foodCakeDesert'), + }, { + type: 'food', + key: 'Candy_Red', + text: t('foodCandyRed'), + }, { + type: 'food', + key: 'Cake_Shade', + text: t('foodCakeShade'), + }, { + type: 'food', + key: 'Candy_Skeleton', + text: t('foodCandySkeleton'), + }, { + type: 'food', + key: 'Cake_Zombie', + text: t('foodCakeZombie'), + }, { + type: 'food', + key: 'Candy_CottonCandyPink', + text: t('foodCandyCottonCandyPink'), + }, { + type: 'food', + key: 'Candy_CottonCandyBlue', + text: t('foodCandyCottonCandyBlue'), + }, { + type: 'food', + key: 'Cake_Golden', + text: t('foodCakeGolden'), + }, + ], + gp: 0, + exp: 0, + }, + }, }; each(quests, (v, key) => { diff --git a/website/common/script/content/stable.js b/website/common/script/content/stable.js index 3bfa8ed814..72507a0049 100644 --- a/website/common/script/content/stable.js +++ b/website/common/script/content/stable.js @@ -70,6 +70,7 @@ let specialPets = { 'Jackalope-RoyalPurple': 'royalPurpleJackalope', 'Orca-Base': 'orca', 'Bear-Veteran': 'veteranBear', + 'Hippogriff-Hopeful': 'hopefulHippogriffPet', }; let specialMounts = { @@ -87,6 +88,7 @@ let specialMounts = { 'Jackalope-RoyalPurple': 'royalPurpleJackalope', 'Aether-Invisible': 'invisibleAether', 'JackOLantern-Ghost': 'ghostJackolantern', + 'Hippogriff-Hopeful': 'hopefulHippogriffMount', }; each(specialPets, (translationString, key) => { diff --git a/website/raw_sprites/spritesmith/stable/mounts/body/Mount_Body_Hippogriff-Hopeful.png b/website/raw_sprites/spritesmith/stable/mounts/body/Mount_Body_Hippogriff-Hopeful.png new file mode 100644 index 0000000000000000000000000000000000000000..23e80a612212d3b939198ec669bebc988e01c81c GIT binary patch literal 1396 zcma)6X;2af6vlHqR?VD&v^C5#Pu3$dS!KOSOwCviyk)#nJo5k{ma<$XwKUDKJjmO9?=hdm)HJf+WJ@)T znnQC;Cwg-7Z2E>a2ovM@L-OAhQy5YfTZ#j7Fq|wlKDv1a#s7>!ATUm62)ZkUQ8dmaV4lA+A)dnU=)n#SX-M^YQM+)ogQqgM7<4s`1>{t?uTR!HB z%^h6VYmQgaqqkCur(v_T!b#Y@nBAi1-r%ckp%}sm^642LgwK8c>jp}Fh_m4(N+V{W zb$2NOn1IQXNSf}Mn!(e_k$0v`uJSlq;OO=nh~$?q^13Q#s;T~2CfOF)wZd(@@&hTcodIzLM)BVW$abkIz6|!a}yi@slE{2M#oy|KumH9(x#Kx2Q zme~%bAC=@SOkK`N72YJLTlCI7gwb4?t{6xzslphb3I_z6X-54V8nJrih$tXPN916M zF5E;PL(YYq?r&HX)>f_~FRd2@LqSZ_rKdjo0r|#&r7rp^-u2G#%AX`!06v9Snl0`h zvOj0t$h57t3!T|~QPT7jlLRGnIJ#AZgCW?1MuhVg6TVuOaKNrI0GTDmnm&gI4xGY; z{?Y!Pc3}jFge(7Asv1)}`_Yh+L5Ob^xHdxu?D>gotYqM=+-XC%M>*r>Gr|u- z@3k!>Luj$vl+hq9{*X|ZQS{(V#M?;)aq!zs%k01!y^S>_v7FhjSU~Y0Da7H-Ly!4F z(5R>lVcmp93GfMp4&V3JfuVlP<-beW*Qy+ka`5c&_m-l$yt~_=s<}AA%ppI1qD3jh z3sv+V$^3ZC$p(GOFowEff^Ln_x%~y~FJTQN2xn+2X!IKBbzPn!hN~u&5J8mUK_gQ`qb{eGM4ZTp$+#@D!JRFM-4-yk$~1!(LsWfz*-khU zNV^{%cT4#j+uhK#_@HAVvt|F{V)`{d|5PLW2*KOw$B&HXCly)S`$T3&+Fh=SMF2#K zmrXJ#n2CMf0(v7Fwd#N1t6JSq_FsF6(#5&{^_|(YiF9+xe7Ky*jmxZwvx7SWM|*TN zNy1b@)I5+R6kon*uzN6>{+X5HE{OGbt2)IkqF4SVttS&dzVhK=g3}Ewp>O0G)Xynd z9@?}ywEpTv5X&vMk4NiZ+{f!JF=!v6ag=BOYI4EymDqo1-7U+@J<&%d?X>89nQ29H z(pmbvR#e?Hz9^A^UXQf~4?RrcESM7lxyL)pvpsGXSoMkrjym0{P~CCr_1vM24+s*q zg4%!P3g!26Vl-PhKEpHGUFi=N@zU#iL4)WYGIGGv$;}jR&oOeYbiY z{oPolmC49P*Q41?J(d<*8um~z(oP6_pjj#|gk%$Xn`Qj-1cp@LKrLY=Mh+R$b=31! d0f0fELaDf=+YSbFF!=h!;9mZo?d~!8{{Zmzrs4nq literal 0 HcmV?d00001 diff --git a/website/raw_sprites/spritesmith/stable/mounts/head/Mount_Head_Hippogriff-Hopeful.png b/website/raw_sprites/spritesmith/stable/mounts/head/Mount_Head_Hippogriff-Hopeful.png new file mode 100644 index 0000000000000000000000000000000000000000..6437ef511b75d36382ff0dbac735192c036edd35 GIT binary patch literal 1919 zcmZXVX*3(!7RO__hzgHBsj=ww)KFZiN;GOHK}0oDb)$z4rgVe`_C{qdg2HEF%m606^AO z*PM>dpua;%;Al6*f*=5Zpr!RSQls~l@+=IcR}~tU_jP;@ zfk=pqlB!jXl#hS(kW&O2ZBme%tFAd~2EWK|oy#;$zf~1l@z=O2sA&xN=>%A6dXRj zZf>eTUEpgWH(1sLhd+0qs_lNVdB4~@cS9Jt?|+yWkaRk;v|+?O+ymNhxj$LdPRM;z z8kE#o(Vld}l?@v6*2VEiC<_>{1qteu@GT4rXSPl0x|*-t-^KIKTee0rkGFXC05 zuDqLO_POIymOi-Y=Yb2R=*}^Bx1Ddp_C7$<=hY{lo%R+a%_KfbEH7%G`1sUL9YVmp zLPgkov2%eTLm(qya zkweNuA5e-s)pZ7lFAFNKR0z%whZj+LRw_Cs*xv!w%b;*_Z1@OQ)O_*OH z@vHThRW<0fOY-D}vOL68E;r!r^JkHg3}f)-okk=`o69+W4SLtp?j-G#fdG;~JC6<2T=sjV@q}41Vm=eWwU!=gnKjNUOz4M_90A zufHA`{~`p@RpIDE58wF{CaRb186|xgk3o;bkGrE77&RJRc~*~fhv-oRq%Fd&Zu}z` z9btOxm`8&V^S2lbzS{e++@qRQc_7T~aEpi7n9a(uYKGK zK8~0YBO+c*|B4tWMiirkyaxx3lvYDxJ2n2R5-y3^;%B7*ghmJa`#=3)n2qjNJ# zcnC8*!~KKlHL&2_aPwmaw(V|3dXA>wkaG#7_F3*eB;t<7!-(}7`5dS5lB zA|&0-up3JT*(aO{);A4hm@?++X6+$?k`;9ZZLGA?`@r~iDSp`@;EaktG3V{=^V!0VBJ3Zw z-?|jRD#+DUb)vs{!OAI3dS5PdIQ7_ud{{8=Nd3WiT=PWzt3Jordb~a8%%3T$v$jK` zH6Y`P(v#z^{)`9Zrz!~f@2fp1`RVo9bxZG`f0?>z=2^REZ~fGEy8x|30k`LhU+sI` zxn$$r@3np0txlV-|MTzt^C-DGTK>tmsI8Z>r-$vnQhld!f(z@yX`6K(u3X72^Zc{- zu}y2kPRW>0Q@4;iwb$s|{<7Sb$FKFjpRWB_`0TUy|C)98g^qiKG^l75#GTvJQvBFi zMqgYy=Fp~`rFq^KpEu;)QJd()dOJn!=M4EXXCwEQn;Qs;Ds*zO#gyDS8CvoApX1|n zYfb;iXWMd9?5}!l=zU&Uq_&{Q>M+F2pmURS9{R02G`HgK3+3Z8V=m-bi=J4$nOmZh z3+T?Q$+?xTe)9aMmVeoI=II`b`u^MQ{{Go-XXWmRd{Xi26>s0u{KpYG$BxgD$Po~{ z*q(2@euto-+afNNz{bf%YD&qR%d^aT=gaQfbMbTCb}_f!w@-iQ_WA!3e;QqLW_sTn zHKj%B^XtCvsb3_p%;Nv%y2;b#)TdEQ#s=6&Yvd{la@gB?Kj>jKwZDg`Xl;68|KkxbL!m1p|IBCTJPs`u?7!MtNG5N}*7muEuJoc)o zYQElrIiNtFGhg^A@3d{&TmPKZo_^YBbF$3(yOHL3`a9!3Z8``JaE`BP=l$f?Z&=%M zT4>u{v7psqN|j4kz}72#aW}Z-d+Kp#%I&RdSDd=W1`_2!N@5rGPOCqAPR{PY$5YSs z7uL^w%T*tu3G_YB2_d^}`W64mRlD+;f$ClA8NN54?-6{rc^gQ#r>mdKI;Vst09JQ} AL;wH) literal 0 HcmV?d00001 diff --git a/website/raw_sprites/spritesmith/stable/pets/Pet-Hippogriff-Hopeful.png b/website/raw_sprites/spritesmith/stable/pets/Pet-Hippogriff-Hopeful.png new file mode 100644 index 0000000000000000000000000000000000000000..3b58f5f20ba52aa336f7b15408694865ffd928aa GIT binary patch literal 1474 zcmV;z1wHzSP)6vrPjh0=mJNCjq$Xo*eu5GbHSDWnvVqG$sqx{*YUmgvTXxbh<|+~7(VCT@sP z7L5yCV8q6@79rCXCYAv#AJPVpq(IRWXu%FpDelfWWA5#|TQ8)E|KIA&?S1z>PR{?H zbMJkxjspMy0000000000000000000000000000000AQ<#GrgcB?Y^ye4x%QIMs`;#e=6IH z52VuHIoNyM=wTq|Z30fTfXDO#H{tCD-L%lqP(sqHXbLH_vrgu1!hXCpkL+q+k8+&q z=l0OOx;xcVfg2Es7Jw5ia8GCF&|Fa2A&^z&sQP#kD##AEWRfkVEvfePu&t3cvhy|p zCt4tGbCVO->Q@8GPS3tyYc%N6s#!rRsXLrc_Q{_|VoF;|*p%h98nUId9Wl*8&f5f> zXaQ}pEhSu4UrBcG#93wGS`bJk2@HqSW4e*KlyKWCd#GJzY^=UPASD(fVCa;lTsBby(P-MDv9c?18!bdq`Sf?9@2t4m~8W=6>F zpI)Q;no3w^+wR#zWJ?Llf?RH+?axi2Xa3?`>?sJ5XaP9U0^02CM#Aymu>^E|3UjAp z9yS#osw4UI1%IOUryClnz1E*bv%dEahMNV7zEoKZD#}`_~p+%>4yKq6OeY z3&hp+bGT-zfX&3TBykQ-_<$ zUO&u|Eb{e{J$9U@qeUl?`(*IW)@#AP$&Q-T3_&DX08X@kXLw?rBq`UevZyY2s+crz zdVESLVJWxjBQGj%_EvLa%sx7j=Es%o@_=b*ww&w=acK3ecpc@1_8UfrP;NjZS^!S8 zK-A8*l&~zSPmf@MMwUb!NVTh9 zcWHfsGk9H3?CmcJBGCeHq6IvTMoO2ja3Pwt!E523m($5Ee`%j`&}-Ab^N$@|3}^Uq zl>JL{cvk73;QPvqEZ4J(4lfEMvhbGZKB#;$m(SVXyttz5;|4^c1>i&rc;t4I`~*Yy z*@cv_l#ks0x|xtfw)ZB#z&Z9Fzic`136HbCWr;Fu^6CmrFY@$Se#x~c+RG2{yW&N@ zJ{o68yx1w<78?`AxyoX8ndW@IVnsRb^EclYxDI^uP>e{UUci%EJu=3?9HtjT}6>oqkZ(E@Oy z1+-xs`7%tl=?9XM$}(Q(p1rVaG!=Bsavqj)*2&xvlJqC>JT(*9jM?rOeiSJ|Bw7GY c1ONc$A3R&|kb)|&TmS$707*qoM6N<$f@dq#HUIzs literal 0 HcmV?d00001 diff --git a/website/server/controllers/api-v3/world.js b/website/server/controllers/api-v3/world.js new file mode 100644 index 0000000000..7af83eede8 --- /dev/null +++ b/website/server/controllers/api-v3/world.js @@ -0,0 +1,44 @@ +import { + model as Group, + TAVERN_ID as tavernId, +} from '../../models/group'; + +let api = {}; + +async function getWorldBoss () { + let tavern = await Group + .findById(tavernId) + .select('quest.progress quest.key quest.active quest.extra') + .exec(); + if (tavern && tavern.quest && tavern.quest.active) { + return tavern.quest; + } + return {}; +} + +/** + * @api {get} /api/v3/world-state Get the state for the game world + * @apiDescription Does not require authentication. + * @apiName WorldStateGet + * @apiGroup WorldState + * + * @apiSuccess {Object} data.worldBoss.active Boolean, true if world boss quest is underway + * @apiSuccess {Object} data.worldBoss.extra.worldDmg Object with NPC names as Boolean properties, true if they are affected by Rage Strike + * @apiSuccess {Object} data.worldBoss.key Quest content key for the world boss + * @apiSuccess {Object} data.worldBoss.progress.hp Current Health of the world boss + * @apiSuccess {Object} data.worldBoss.progress.rage Current Rage of the world boss + * + */ +api.getWorldState = { + method: 'GET', + url: '/world-state', + async handler (req, res) { + let worldState = {}; + + worldState.worldBoss = await getWorldBoss(); + + res.respond(200, worldState); + }, +}; + +module.exports = api; diff --git a/website/server/middlewares/cron.js b/website/server/middlewares/cron.js index 8b5abb970e..0264c985de 100644 --- a/website/server/middlewares/cron.js +++ b/website/server/middlewares/cron.js @@ -92,7 +92,7 @@ async function cronAsync (req, res) { res.locals.wasModified = true; // TODO remove after v2 is retired - // Group.tavernBoss(user, progress); + Group.tavernBoss(user, progress); // Save user and tasks let toSave = [user.save()]; diff --git a/website/server/models/group.js b/website/server/models/group.js index 177163ae84..49006ac0e3 100644 --- a/website/server/models/group.js +++ b/website/server/models/group.js @@ -1053,9 +1053,17 @@ schema.statics.tavernBoss = async function tavernBoss (user, progress) { if (!tavern.quest.extra.worldDmg) tavern.quest.extra.worldDmg = {}; let wd = tavern.quest.extra.worldDmg; - // Burnout attacks Ian, Seasonal Sorceress, tavern - // Be-Wilder attacks Alex, Matt, Bailey - let scene = wd.market ? wd.stables ? wd.bailey ? false : 'bailey' : 'stables' : 'market'; // eslint-disable-line no-nested-ternary + // Dysheartener attacks Seasonal Sorceress, Alex, Ian + let scene; + if (wd.quests) { + scene = false; + } else if (wd.market) { + scene = 'quests'; + } else if (wd.seasonalShop) { + scene = 'market'; + } else { + scene = 'seasonalShop'; + } if (!scene) { tavern.sendChat(`\`${quest.boss.name('en')} tries to unleash ${quest.boss.rage.title('en')} but is too tired.\``);