XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

SpaceNinjaServer

A simple server for a small space ninja game

公开
关注 0 Fork 1 Star 0
返回提交历史

XFEstudio/SpaceNinjaServer

feat: remove quest related items (#2957)

if I haven't missed anything, this should close #1116 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/2957 Reviewed-by: Sainan <63328889+sainan@users.noreply.github.com> Co-authored-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com> Co-committed-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>

f2145ed9
AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
提交于

代码差异

2 个文件 +358 -15
Modified src/services/loginService.ts +1 -12
@@ -41,8 +41,8 @@ export const createAccount = async (accountData: IDatabaseAccountRequiredFields)
41 41 await account.save();
42 42 const loadoutId = await createLoadout(account._id);
43 43 const shipId = await createShip(account._id);
44 await createInventory(account._id, { loadOutPresetId: loadoutId, ship: shipId });
45 44 await createPersonalRooms(account._id, shipId);
45 await createInventory(account._id, { loadOutPresetId: loadoutId, ship: shipId });
46 46 await createStats(account._id.toString());
47 47 return account.toJSON();
48 48 } catch (error) {
@@ -64,17 +64,6 @@ export const createPersonalRooms = async (accountId: Types.ObjectId, shipId: Typ
64 64 personalRoomsOwnerId: accountId,
65 65 activeShipId: shipId
66 66 });
67 if (config.skipTutorial) {
68 // unlocked during Vor's Prize and The Teacher quests
69 const defaultFeatures = [
70 "/Lotus/Types/Items/ShipFeatureItems/MercuryNavigationFeatureItem",
71 "/Lotus/Types/Items/ShipFeatureItems/ArsenalFeatureItem",
72 "/Lotus/Types/Items/ShipFeatureItems/SocialMenuFeatureItem",
73 "/Lotus/Types/Items/ShipFeatureItems/FoundryFeatureItem",
74 "/Lotus/Types/Items/ShipFeatureItems/ModsFeatureItem"
75 ];
76 personalRooms.Ship.Features.push(...defaultFeatures);
77 }
78 67 await personalRooms.save();
79 68 };
80 69
Modified src/services/questService.ts +357 -3
@@ -2,16 +2,25 @@ import type { IKeyChainRequest } from "../types/requestTypes.ts";
2 2 import { isEmptyObject } from "../helpers/general.ts";
3 3 import type { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel.ts";
4 4 import { createMessage } from "./inboxService.ts";
5 import { addItem, addItems, addKeyChainItems, setupKahlSyndicate } from "./inventoryService.ts";
5 import {
6 addEquipment,
7 addItem,
8 addItems,
9 addKeyChainItems,
10 addPowerSuit,
11 setupKahlSyndicate
12 } from "./inventoryService.ts";
6 13 import { fromStoreItem, getKeyChainMessage, getLevelKeyRewards } from "./itemDataService.ts";
7 14 import type { IQuestKeyClient, IQuestKeyDatabase, IQuestStage } from "../types/inventoryTypes/inventoryTypes.ts";
8 15 import { logger } from "../utils/logger.ts";
9 import { ExportKeys } from "warframe-public-export-plus";
16 import { ExportKeys, ExportRecipes } from "warframe-public-export-plus";
10 17 import { addFixedLevelRewards } from "./missionInventoryUpdateService.ts";
11 18 import type { IInventoryChanges } from "../types/purchaseTypes.ts";
12 19 import questCompletionItems from "../../static/fixed_responses/questCompletionRewards.json" with { type: "json" };
13 20 import type { ITypeCount } from "../types/commonTypes.ts";
14 21 import { addString } from "../helpers/stringHelpers.ts";
22 import { unlockShipFeature } from "./personalRoomsService.ts";
23 import { EquipmentFeatures } from "../types/equipmentTypes.ts";
15 24
16 25 export interface IUpdateQuestRequest {
17 26 QuestKeys: IQuestKeyClient[];
@@ -193,6 +202,7 @@ export const completeQuest = async (
193 202 stage.c = run;
194 203 await giveKeyChainStageTriggered(inventory, { KeyChain: questKey, ChainStage: i }, sendMessages);
195 204 await giveKeyChainMissionReward(inventory, { KeyChain: questKey, ChainStage: i });
205 await installShipFeatures(inventory, { KeyChain: questKey, ChainStage: i });
196 206 }
197 207 }
198 208
@@ -329,6 +339,9 @@ const handleQuestCompletion = async (
329 339 logger.debug(`quest completion items`, questCompletionItems);
330 340 if (questCompletionItems) {
331 341 await addItems(inventory, questCompletionItems, inventoryChanges);
342 for (const item of questCompletionItems) {
343 await removeRequiredItems(inventory, item.ItemType);
344 }
332 345 }
333 346 };
334 347
@@ -378,7 +391,12 @@ export const giveKeyChainMessage = async (
378 391 await createMessage(inventory.accountOwnerId, [keyChainMessage]);
379 392 } else {
380 393 if (keyChainMessage.countedAtt?.length) await addItems(inventory, keyChainMessage.countedAtt);
381 if (keyChainMessage.att?.length) await addItems(inventory, keyChainMessage.att);
394 if (keyChainMessage.att?.length) {
395 await addItems(inventory, keyChainMessage.att);
396 for (const reward of keyChainMessage.att) {
397 await removeRequiredItems(inventory, reward);
398 }
399 }
382 400 }
383 401
384 402 updateQuestStage(inventory, keyChainInfo, { m: true });
@@ -403,6 +421,7 @@ export const giveKeyChainMissionReward = async (
403 421
404 422 for (const reward of missionRewards) {
405 423 await addItem(inventory, fromStoreItem(reward.StoreItem), reward.ItemCount);
424 await removeRequiredItems(inventory, fromStoreItem(reward.StoreItem));
406 425 }
407 426
408 427 updateQuestStage(inventory, keyChainInfo, { c: run });
@@ -416,6 +435,7 @@ export const giveKeyChainMissionReward = async (
416 435 await addItem(inventory, fromStoreItem(reward.itemType), reward.amount);
417 436 } else {
418 437 await addItem(inventory, fromStoreItem(reward.itemType));
438 await removeRequiredItems(inventory, fromStoreItem(reward.itemType));
419 439 }
420 440 }
421 441
@@ -444,3 +464,337 @@ export const giveKeyChainStageTriggered = async (
444 464 }
445 465 }
446 466 };
467
468 export const installShipFeatures = async (
469 inventory: TInventoryDatabaseDocument,
470 keyChainInfo: IKeyChainRequest
471 ): Promise<void> => {
472 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
473 const chainStages = ExportKeys[keyChainInfo.KeyChain]?.chainStages;
474 const questKey = inventory.QuestKeys.find(qk => qk.ItemType === keyChainInfo.KeyChain);
475 if (chainStages && questKey) {
476 if (keyChainInfo.ChainStage - 1 >= 0) {
477 const prevStage = chainStages[keyChainInfo.ChainStage - 1];
478 for (const item of prevStage.itemsToGiveWhenTriggered) {
479 if (item.startsWith("/Lotus/StoreItems/Types/Items/ShipFeatureItems/")) {
480 logger.debug(`installing ship feature ${fromStoreItem(item)}`);
481 await unlockShipFeature(inventory, fromStoreItem(item));
482 }
483 }
484 if (prevStage.key) {
485 const fixedLevelRewards = getLevelKeyRewards(prevStage.key);
486 if (fixedLevelRewards.levelKeyRewards?.items) {
487 for (const item of fixedLevelRewards.levelKeyRewards.items) {
488 if (item.startsWith("/Lotus/StoreItems/Types/Items/ShipFeatureItems/")) {
489 logger.debug(`installing ship feature ${fromStoreItem(item)}`);
490 await unlockShipFeature(inventory, fromStoreItem(item));
491 }
492 }
493 }
494 if (fixedLevelRewards.levelKeyRewards2) {
495 for (const item of fixedLevelRewards.levelKeyRewards2) {
496 if (
497 item.rewardType == "RT_STORE_ITEM" &&
498 item.itemType.startsWith("/Lotus/StoreItems/Types/Items/ShipFeatureItems/")
499 ) {
500 logger.debug(`installing ship feature ${fromStoreItem(item.itemType)}`);
501 await unlockShipFeature(inventory, fromStoreItem(item.itemType));
502 }
503 }
504 }
505 }
506 }
507 }
508 };
509
510 export const removeRequiredItems = async (inventory: TInventoryDatabaseDocument, typeName: string): Promise<void> => {
511 switch (typeName) {
512 case "/Lotus/Types/Recipes/WarframeRecipes/MagicianHelmetBlueprint": {
513 const recipeItem = inventory.Recipes.find(
514 i => i.ItemType == "/Lotus/Types/Keys/LimboQuest/LimboHelmetKeyBlueprint"
515 );
516 if (recipeItem && recipeItem.ItemCount > 0) {
517 const recipe = ExportRecipes[recipeItem.ItemType];
518 if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
519 await addItem(inventory, recipe.resultType);
520 if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, -1);
521 }
522 }
523 break;
524 }
525 case "/Lotus/Types/Recipes/WarframeRecipes/MagicianSystemsBlueprint": {
526 const recipeItem = inventory.Recipes.find(
527 i => i.ItemType == "/Lotus/Types/Keys/LimboQuest/LimboSystemsKeyBlueprint"
528 );
529 if (recipeItem && recipeItem.ItemCount > 0) {
530 const recipe = ExportRecipes[recipeItem.ItemType];
531 if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
532 await addItem(inventory, recipe.resultType);
533 if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, -1);
534 }
535 }
536 break;
537 }
538 case "/Lotus/Types/Recipes/WarframeRecipes/MagicianChassisBlueprint": {
539 const recipeItem = inventory.Recipes.find(
540 i => i.ItemType == "/Lotus/Types/Keys/LimboQuest/LimboChassisKeyBlueprint"
541 );
542 if (recipeItem && recipeItem.ItemCount > 0) {
543 const recipe = ExportRecipes[recipeItem.ItemType];
544 if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
545 await addItem(inventory, recipe.resultType);
546 if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, -1);
547 }
548 }
549 break;
550 }
551
552 case "/Lotus/Types/Recipes/WarframeRecipes/BrawlerBlueprint": {
553 const recipeItem = inventory.Recipes.find(
554 i => i.ItemType == "/Lotus/Types/Recipes/Components/InfestedIrradiatedBaitBallBlueprint"
555 );
556 if (recipeItem && recipeItem.ItemCount > 0) {
557 const recipe = ExportRecipes[recipeItem.ItemType];
558 if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
559 await addItem(inventory, recipe.resultType);
560 await addItem(inventory, recipe.resultType, -1, false, undefined, undefined, true);
561 if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, -1);
562 }
563 }
564 break;
565 }
566
567 case "/Lotus/Types/Game/CrewShip/RailJack/DefaultHarness": {
568 const recipeItem = inventory.Recipes.find(
569 i => i.ItemType == "/Lotus/Types/Recipes/ArchwingRecipes/StandardArchwing/StandardArchwingBlueprint"
570 );
571 if (recipeItem && recipeItem.ItemCount > 0) {
572 const recipe = ExportRecipes[recipeItem.ItemType];
573 if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
574 await addItem(inventory, recipe.resultType);
575 if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, recipeItem.ItemCount * -1);
576 await addItems(inventory, [
577 {
578 ItemType:
579 "/Lotus/Types/Recipes/ArchwingRecipes/StandardArchwing/StandardArchwingWingsBlueprint",
580 ItemCount: -1
581 },
582 {
583 ItemType:
584 "/Lotus/Types/Recipes/ArchwingRecipes/StandardArchwing/StandardArchwingChassisBlueprint",
585 ItemCount: -1
586 },
587 {
588 ItemType:
589 "/Lotus/Types/Recipes/ArchwingRecipes/StandardArchwing/StandardArchwingSystemsBlueprint",
590 ItemCount: -1
591 }
592 ]);
593 }
594 }
595 break;
596 }
597
598 case "/Lotus/Types/Keys/ModQuest/ModQuestKeyChain": {
599 const recipeItem = inventory.Recipes.find(
600 i => i.ItemType == "/Lotus/Types/Recipes/Components/VorBoltRemoverBlueprint"
601 );
602 if (recipeItem && recipeItem.ItemCount > 0) {
603 const recipe = ExportRecipes[recipeItem.ItemType];
604 if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
605 await addItem(inventory, recipe.resultType);
606 if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, -1);
607 }
608 }
609 break;
610 }
611
612 case "/Lotus/Types/Recipes/WarframeRecipes/ChromaBlueprint": {
613 await addItems(inventory, [
614 {
615 ItemType: "/Lotus/Types/Recipes/WarframeRecipes/ChromaBeaconABlueprint",
616 ItemCount: -1
617 },
618 {
619 ItemType: "/Lotus/Types/Recipes/WarframeRecipes/ChromaBeaconBBlueprint",
620 ItemCount: -1
621 },
622 {
623 ItemType: "/Lotus/Types/Recipes/WarframeRecipes/ChromaBeaconCBlueprint",
624 ItemCount: -1
625 }
626 ]);
627
628 break;
629 }
630
631 case "/Lotus/Types/Recipes/WarframeRecipes/OctaviaBlueprint": {
632 const recipeItem = inventory.Recipes.find(
633 i => i.ItemType == "/Lotus/Types/Keys/BardQuest/BardQuestSequencerBlueprint"
634 );
635 if (recipeItem && recipeItem.ItemCount > 0) {
636 const recipe = ExportRecipes[recipeItem.ItemType];
637 if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
638 await addItem(inventory, recipe.resultType);
639 if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, -1);
640 await addItems(inventory, [
641 {
642 ItemType: "/Lotus/Types/Keys/BardQuest/BardQuestSequencerPartA",
643 ItemCount: -1
644 },
645 {
646 ItemType: "/Lotus/Types/Keys/BardQuest/BardQuestSequencerPartB",
647 ItemCount: -1
648 },
649 {
650 ItemType: "/Lotus/Types/Keys/BardQuest/BardQuestSequencerPartC",
651 ItemCount: -1
652 }
653 ]);
654 }
655 }
656 break;
657 }
658
659 case "/Lotus/Types/Game/CrewShip/Ships/RailJack": {
660 const recipeItem = inventory.Recipes.find(
661 i => i.ItemType == "/Lotus/Types/Recipes/Railjack/RailjackCephalonBlueprint"
662 );
663 if (recipeItem && recipeItem.ItemCount > 0) {
664 const recipe = ExportRecipes[recipeItem.ItemType];
665 if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
666 await addItem(inventory, recipe.resultType);
667 if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, recipeItem.ItemCount * -1);
668 await unlockShipFeature(inventory, recipe.resultType);
669 }
670 }
671 break;
672 }
673
674 case "/Lotus/Types/Items/ShipDecos/MummyQuestVessel": {
675 const gearItem = inventory.Consumables.find(
676 i => i.ItemType == "/Lotus/Types/Keys/MummyQuest/MummyArtifact01GearItem"
677 );
678 if (gearItem && gearItem.ItemCount > 0) {
679 await addItem(inventory, gearItem.ItemType, gearItem.ItemCount * -1);
680 }
681 break;
682 }
683
684 case "/Lotus/Types/Recipes/WarframeRecipes/ConcreteFrameBlueprint": {
685 const recipeItem = inventory.Recipes.find(
686 i => i.ItemType == "/Lotus/Types/Gameplay/EntratiLab/Quest/GargoyleRecipeItem"
687 );
688 if (recipeItem && recipeItem.ItemCount > 0) {
689 const recipe = ExportRecipes[recipeItem.ItemType];
690 if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
691 await addItem(inventory, recipe.resultType);
692 if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, recipeItem.ItemCount * -1);
693 }
694 }
695 break;
696 }
697
698 case "/Lotus/Upgrades/Skins/Umbra/UmbraAltHelmet": {
699 const recipeItem = inventory.Recipes.find(
700 i => i.ItemType == "/Lotus/Types/Recipes/WarframeRecipes/ExcaliburUmbraBlueprint"
701 );
702 if (recipeItem && recipeItem.ItemCount > 0) {
703 const recipe = ExportRecipes[recipeItem.ItemType];
704 if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
705 const umbraModA = (
706 await addItem(
707 inventory,
708 "/Lotus/Upgrades/Mods/Sets/Umbra/WarframeUmbraModA",
709 1,
710 false,
711 undefined,
712 `{"lvl":5}`
713 )
714 ).Upgrades![0];
715 const umbraModB = (
716 await addItem(
717 inventory,
718 "/Lotus/Upgrades/Mods/Sets/Umbra/WarframeUmbraModB",
719 1,
720 false,
721 undefined,
722 `{"lvl":5}`
723 )
724 ).Upgrades![0];
725 const umbraModC = (
726 await addItem(
727 inventory,
728 "/Lotus/Upgrades/Mods/Sets/Umbra/WarframeUmbraModC",
729 1,
730 false,
731 undefined,
732 `{"lvl":5}`
733 )
734 ).Upgrades![0];
735 const sacrificeModA = (
736 await addItem(
737 inventory,
738 "/Lotus/Upgrades/Mods/Sets/Sacrifice/MeleeSacrificeModA",
739 1,
740 false,
741 undefined,
742 `{"lvl":5}`
743 )
744 ).Upgrades![0];
745 const sacrificeModB = (
746 await addItem(
747 inventory,
748 "/Lotus/Upgrades/Mods/Sets/Sacrifice/MeleeSacrificeModB",
749 1,
750 false,
751 undefined,
752 `{"lvl":5}`
753 )
754 ).Upgrades![0];
755
756 await addPowerSuit(inventory, "/Lotus/Powersuits/Excalibur/ExcaliburUmbra", {
757 Configs: [
758 {
759 Upgrades: [
760 "",
761 "",
762 "",
763 "",
764 "",
765 umbraModA.ItemId.$oid,
766 umbraModB.ItemId.$oid,
767 umbraModC.ItemId.$oid
768 ]
769 }
770 ],
771 XP: 900_000,
772 Features: EquipmentFeatures.DOUBLE_CAPACITY
773 });
774 inventory.XPInfo.push({
775 ItemType: "/Lotus/Powersuits/Excalibur/ExcaliburUmbra",
776 XP: 900_000
777 });
778
779 addEquipment(inventory, "Melee", "/Lotus/Weapons/Tenno/Melee/Swords/UmbraKatana/UmbraKatana", {
780 Configs: [
781 {
782 Upgrades: ["", "", "", "", "", "", sacrificeModA.ItemId.$oid, sacrificeModB.ItemId.$oid]
783 }
784 ],
785 XP: 450_000,
786 Features: EquipmentFeatures.DOUBLE_CAPACITY
787 });
788 inventory.XPInfo.push({
789 ItemType: "/Lotus/Weapons/Tenno/Melee/Swords/UmbraKatana/UmbraKatana",
790 XP: 450_000
791 });
792 if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, recipeItem.ItemCount * -1);
793 }
794 }
795 break;
796 }
797 default:
798 break;
799 }
800 };