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: thermia fractures (#2670)

Re #1103 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/2670 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>

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

代码差异

13 个文件 +235 -53
Modified config-vanilla.json +2 -0
@@ -86,6 +86,8 @@
86 86 "bellyOfTheBeastProgressOverride": 0,
87 87 "eightClaw": false,
88 88 "eightClawProgressOverride": 0,
89 "thermiaFracturesOverride": null,
90 "thermiaFracturesProgressOverride": 0,
89 91 "eidolonOverride": "",
90 92 "vallisOverride": "",
91 93 "duviriOverride": "",
Modified src/services/configService.ts +2 -0
@@ -98,6 +98,8 @@ export interface IConfig {
98 98 bellyOfTheBeastProgressOverride?: number;
99 99 eightClaw?: boolean;
100 100 eightClawProgressOverride?: number;
101 thermiaFracturesOverride?: boolean;
102 thermiaFracturesProgressOverride?: number;
101 103 eidolonOverride?: string;
102 104 vallisOverride?: string;
103 105 duviriOverride?: string;
Modified src/services/missionInventoryUpdateService.ts +107 -47
@@ -640,7 +640,7 @@ export const addMissionInventoryUpdates = async (
640 640 }
641 641
642 642 const currentNode = inventoryUpdates.RewardInfo!.node;
643 let currentMissionKey;
643 let currentMissionKey: string | undefined;
644 644 if (currentNode == goal.Node) {
645 645 currentMissionKey = goal.MissionKeyName;
646 646 } else if (goal.ConcurrentNodes && goal.ConcurrentMissionKeyNames) {
@@ -651,15 +651,15 @@ export const addMissionInventoryUpdates = async (
651 651 }
652 652 }
653 653 }
654 if (currentMissionKey && currentMissionKey in goalMessagesByKey) {
655 let countBeforeUpload = goalProgress?.Count ?? 0;
656 let totalCount = countBeforeUpload + uploadProgress.Count;
657 if (goal.Best) {
658 countBeforeUpload = goalProgress?.Best ?? 0;
659 totalCount = uploadProgress.Best;
660 }
661 let reward;
654 const rewards = [];
655 let countBeforeUpload = goalProgress?.Count ?? 0;
656 let totalCount = countBeforeUpload + uploadProgress.Count;
657 if (goal.Best) {
658 countBeforeUpload = goalProgress?.Best ?? 0;
659 totalCount = uploadProgress.Best;
660 }
662 661
662 {
663 663 if (goal.InterimGoals && goal.InterimRewards) {
664 664 for (let i = 0; i < goal.InterimGoals.length; i++) {
665 665 if (
@@ -668,70 +668,95 @@ export const addMissionInventoryUpdates = async (
668 668 (!goalProgress || countBeforeUpload < goal.InterimGoals[i]) &&
669 669 goal.InterimRewards[i]
670 670 ) {
671 reward = goal.InterimRewards[i];
671 rewards.push(goal.InterimRewards[i]);
672 672 break;
673 673 }
674 674 }
675 675 }
676 676 if (
677 !reward &&
678 677 goal.Goal &&
679 678 goal.Goal <= totalCount &&
680 679 (!goalProgress || countBeforeUpload < goal.Goal) &&
681 680 goal.Reward
682 681 ) {
683 reward = goal.Reward;
682 rewards.push(goal.Reward);
684 683 }
685 684 if (
686 !reward &&
687 685 goal.BonusGoal &&
688 686 goal.BonusGoal <= totalCount &&
689 687 (!goalProgress || countBeforeUpload < goal.BonusGoal) &&
690 688 goal.BonusReward
691 689 ) {
692 reward = goal.BonusReward;
690 rewards.push(goal.BonusReward);
693 691 }
694 if (reward) {
695 if (currentMissionKey in goalMessagesByKey) {
696 // Send reward via inbox
697 const info = goalMessagesByKey[currentMissionKey];
698 const message: IMessageCreationTemplate = {
699 sndr: info.sndr,
700 msg: info.msg,
701 sub: info.sub,
702 icon: info.icon,
703 highPriority: true
704 };
692 }
705 693
706 if (reward.items) {
707 message.att = reward.items.map(x => (isStoreItem(x) ? fromStoreItem(x) : x));
708 }
709 if (reward.countedItems) {
710 message.countedAtt = reward.countedItems;
711 }
712 if (reward.credits) {
713 message.RegularCredits = reward.credits;
714 }
715 if (info.arg) {
716 const args: Record<string, string | number> = {
717 PLAYER_NAME: account.DisplayName,
718 CREDIT_REWARD: reward.credits ?? 0
719 };
694 const messages: IMessageCreationTemplate[] = [];
695 const infos: {
696 sndr: string;
697 msg: string;
698 sub: string;
699 icon: string;
700 arg?: string[];
701 }[] = [];
720 702
721 info.arg.forEach(key => {
722 const value = args[key];
723 if (value) {
724 message.arg ??= [];
725 message.arg.push({ Key: key, Tag: value });
726 }
727 });
703 {
704 if (currentMissionKey && currentMissionKey in goalMessagesByKey) {
705 infos.push(goalMessagesByKey[currentMissionKey]);
706 } else if (goal.Tag in goalMessagesByTag) {
707 const combinedGoals = [...(goal.InterimGoals || []), goal.Goal, goal.BonusGoal];
708 combinedGoals.forEach((n, i) => {
709 if (n !== undefined && n > countBeforeUpload && n <= totalCount) {
710 infos.push(goalMessagesByTag[goal.Tag][i]);
728 711 }
712 });
713 }
714 }
729 715
730 await createMessage(inventory.accountOwnerId, [message]);
716 for (let i = 0; i < rewards.length; i++) {
717 if (infos[i]) {
718 const info = infos[i];
719 const reward = rewards[i];
720 const message: IMessageCreationTemplate = {
721 sndr: info.sndr,
722 msg: info.msg,
723 sub: info.sub,
724 icon: info.icon,
725 highPriority: true
726 };
727 if (reward.items) {
728 message.att = reward.items.map(x => (isStoreItem(x) ? fromStoreItem(x) : x));
729 }
730 if (reward.countedItems) {
731 message.countedAtt = reward.countedItems;
732 }
733 if (reward.credits) {
734 message.RegularCredits = reward.credits;
731 735 }
736 if (info.arg) {
737 const args: Record<string, string | number> = {
738 PLAYER_NAME: account.DisplayName,
739 CREDIT_REWARD: reward.credits ?? 0
740 };
741
742 for (let j = 0; j < info.arg.length; j++) {
743 const key = info.arg[j];
744 const value = args[key];
745 if (value) {
746 message.arg ??= [];
747 message.arg.push({
748 Key: key,
749 Tag: value
750 });
751 }
752 }
753 }
754 messages.push(message);
732 755 }
733 756 }
734 757
758 if (messages.length > 0) await createMessage(inventory.accountOwnerId, messages);
759
735 760 if (goalProgress) {
736 761 goalProgress.Best = Math.max(goalProgress.Best!, uploadProgress.Best);
737 762 goalProgress.Count += uploadProgress.Count;
@@ -2617,3 +2642,38 @@ const goalMessagesByKey: Record<string, { sndr: string; msg: string; sub: string
2617 2642 arg: ["PLAYER_NAME"]
2618 2643 }
2619 2644 };
2645
2646 const goalMessagesByTag: Record<string, { sndr: string; msg: string; sub: string; icon: string; arg?: string[] }[]> = {
2647 HeatFissure: [
2648 {
2649 sndr: "/Lotus/Language/Npcs/Eudico",
2650 msg: "/Lotus/Language/Messages/OrbHeistEventRewardAInboxMessageBody",
2651 sub: "/Lotus/Language/Messages/OrbHeistEventRewardAInboxMessageTitle",
2652 icon: "/Lotus/Interface/Icons/Npcs/Eudico.png"
2653 },
2654 {
2655 sndr: "/Lotus/Language/Npcs/Eudico",
2656 msg: "/Lotus/Language/Messages/OrbHeistEventRewardBInboxMessageBody",
2657 sub: "/Lotus/Language/Messages/OrbHeistEventRewardBInboxMessageTitle",
2658 icon: "/Lotus/Interface/Icons/Npcs/Eudico.png"
2659 },
2660 {
2661 sndr: "/Lotus/Language/Npcs/Eudico",
2662 msg: "/Lotus/Language/Messages/OrbHeistEventRewardCInboxMessageBody",
2663 sub: "/Lotus/Language/Messages/OrbHeistEventRewardCInboxMessageTitle",
2664 icon: "/Lotus/Interface/Icons/Npcs/Eudico.png"
2665 },
2666 {
2667 sndr: "/Lotus/Language/Npcs/Eudico",
2668 msg: "/Lotus/Language/Messages/OrbHeistEventRewardDInboxMessageBody",
2669 sub: "/Lotus/Language/Messages/OrbHeistEventRewardDInboxMessageTitle",
2670 icon: "/Lotus/Interface/Icons/Npcs/Eudico.png"
2671 },
2672 {
2673 sndr: "/Lotus/Language/Npcs/Eudico",
2674 msg: "/Lotus/Language/Messages/OrbHeistEventRewardEInboxMessageBody",
2675 sub: "/Lotus/Language/Messages/OrbHeistEventRewardEInboxMessageTitle",
2676 icon: "/Lotus/Interface/Icons/Npcs/Eudico.png"
2677 }
2678 ]
2679 };
Modified src/services/worldStateService.ts +83 -2
@@ -2629,6 +2629,87 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
2629 2629 );
2630 2630 }
2631 2631
2632 const thermiaFracturesCycleDay = day % 32;
2633 const isThermiaFracturesActive = thermiaFracturesCycleDay < 14;
2634 if (config.worldState?.thermiaFracturesOverride ?? isThermiaFracturesActive) {
2635 const activeStartDay = day - thermiaFracturesCycleDay;
2636
2637 const count = config.worldState?.thermiaFracturesProgressOverride ?? 0;
2638 const activation = config.worldState?.thermiaFracturesOverride ? 1740416400000 : getSortieTime(activeStartDay);
2639 const expiry = config.worldState?.thermiaFracturesOverride ? 2000000000000 : getSortieTime(activeStartDay + 14);
2640
2641 worldState.Goals.push({
2642 _id: { $oid: "5c7cb0d00000000000000000" },
2643 Activation: { $date: { $numberLong: activation.toString() } },
2644 Expiry: { $date: { $numberLong: expiry.toString() } },
2645 Node: "SolNode129",
2646 ScoreVar: "FissuresClosed",
2647 ScoreLocTag: "/Lotus/Language/G1Quests/HeatFissuresEventScore",
2648 Count: count,
2649 HealthPct: count / 100,
2650 Regions: [1],
2651 Desc: "/Lotus/Language/G1Quests/HeatFissuresEventName",
2652 ToolTip: "/Lotus/Language/G1Quests/HeatFissuresEventDesc",
2653 OptionalInMission: true,
2654 Tag: "HeatFissure",
2655 UpgradeIds: [{ $oid: "5c81cefa4c4566791728eaa7" }, { $oid: "5c81cefa4c4566791728eaa6" }],
2656 Personal: true,
2657 Community: true,
2658 Goal: 100,
2659 Reward: {
2660 items: ["/Lotus/StoreItems/Weapons/Corpus/LongGuns/CrpBFG/Vandal/VandalCrpBFG"]
2661 },
2662 InterimGoals: [5, 25, 50, 75],
2663 InterimRewards: [
2664 { items: ["/Lotus/StoreItems/Upgrades/Skins/Clan/OrbBadgeItem"] },
2665 {
2666 items: [
2667 "/Lotus/StoreItems/Upgrades/Mods/DualSource/Shotgun/ShotgunMedicMod",
2668 "/Lotus/StoreItems/Upgrades/Mods/DualSource/Rifle/SerratedRushMod"
2669 ]
2670 },
2671 {
2672 items: [
2673 "/Lotus/StoreItems/Upgrades/Mods/DualSource/Pistol/MultishotDodgeMod",
2674 "/Lotus/StoreItems/Upgrades/Mods/DualSource/Melee/CritDamageChargeSpeedMod"
2675 ]
2676 },
2677 { items: ["/Lotus/StoreItems/Upgrades/Skins/Sigils/OrbSigil"] }
2678 ]
2679 });
2680 worldState.NodeOverrides.push({
2681 _id: { $oid: "5c7cb0d00000000000000000" },
2682 Activation: { $date: { $numberLong: activation.toString() } },
2683 Expiry: { $date: { $numberLong: expiry.toString() } },
2684 Node: "SolNode129",
2685 Faction: "FC_CORPUS",
2686 CustomNpcEncounters: ["/Lotus/Types/Gameplay/Venus/Encounters/Heists/ExploiterHeistFissure"]
2687 });
2688 if (count >= 35) {
2689 worldState.GlobalUpgrades.push({
2690 _id: { $oid: "5c81cefa4c4566791728eaa6" },
2691 Activation: { $date: { $numberLong: activation.toString() } },
2692 ExpiryDate: { $date: { $numberLong: expiry.toString() } },
2693 UpgradeType: "GAMEPLAY_MONEY_REWARD_AMOUNT",
2694 OperationType: "MULTIPLY",
2695 Value: 2,
2696 Nodes: ["SolNode129"]
2697 });
2698 }
2699 // Not sure about that
2700 if (count == 100) {
2701 worldState.GlobalUpgrades.push({
2702 _id: { $oid: "5c81cefa4c4566791728eaa7" },
2703 Activation: { $date: { $numberLong: activation.toString() } },
2704 ExpiryDate: { $date: { $numberLong: expiry.toString() } },
2705 UpgradeType: "GAMEPLAY_PICKUP_AMOUNT",
2706 OperationType: "MULTIPLY",
2707 Value: 2,
2708 Nodes: ["SolNode129"]
2709 });
2710 }
2711 }
2712
2632 2713 // Nightwave Challenges
2633 2714 const nightwaveSyndicateTag = getNightwaveSyndicateTag(buildLabel);
2634 2715 if (nightwaveSyndicateTag) {
@@ -2727,7 +2808,7 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
2727 2808 : Date.UTC(
2728 2809 date.getUTCFullYear(),
2729 2810 date.getUTCMonth(),
2730 date.getUTCDate() + (day - ghoulsCycleDay + 17)
2811 date.getUTCDate() + activeStartDay
2731 2812 ).toString()
2732 2813 }
2733 2814 },
@@ -2738,7 +2819,7 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
2738 2819 : Date.UTC(
2739 2820 date.getUTCFullYear(),
2740 2821 date.getUTCMonth(),
2741 date.getUTCDate() + (day - ghoulsCycleDay + 21)
2822 date.getUTCDate() + activeEndDay
2742 2823 ).toString()
2743 2824 }
2744 2825 },
Modified src/types/worldStateTypes.ts +8 -4
@@ -43,7 +43,7 @@ export interface IGoal {
43 43 Count?: number;
44 44 HealthPct?: number;
45 45
46 Icon: string;
46 Icon?: string;
47 47 Desc: string;
48 48 ToolTip?: string;
49 49 Faction?: string;
@@ -94,6 +94,9 @@ export interface IGoal {
94 94 MissionKeyRotation?: string[];
95 95 MissionKeyRotationInterval?: number;
96 96
97 OptionalInMission?: boolean;
98 UpgradeIds?: IOid[];
99
97 100 NightLevel?: string;
98 101 }
99 102
@@ -128,8 +131,9 @@ export interface IGlobalUpgrade {
128 131 UpgradeType: string;
129 132 OperationType: string;
130 133 Value: number;
131 LocalizeTag: string;
132 LocalizeDescTag: string;
134 LocalizeTag?: string;
135 LocalizeDescTag?: string;
136 Nodes?: string[];
133 137 }
134 138
135 139 export interface IInvasion {
@@ -183,7 +187,7 @@ export interface INodeOverride {
183 187 Seed?: number;
184 188 LevelOverride?: string;
185 189 Faction?: string;
186 CustomNpcEncounters?: string;
190 CustomNpcEncounters?: string[];
187 191 }
188 192
189 193 export interface ISortie {
Modified static/webui/index.html +19 -0
@@ -1103,6 +1103,25 @@
1103 1103 </form>
1104 1104 </div>
1105 1105 </div>
1106 <div class="form-group mt-2 d-flex gap-2">
1107 <div class="flex-fill">
1108 <label class="form-label" for="worldState.thermiaFracturesOverride" data-loc="worldState_thermiaFractures"></label>
1109 <select class="form-control" id="worldState.thermiaFracturesOverride" data-default="null">
1110 <option value="null" data-loc="normal"></option>
1111 <option value="true" data-loc="enabled"></option>
1112 <option value="false" data-loc="disabled"></option>
1113 </select>
1114 </div>
1115 <div class="flex-fill">
1116 <form class="form-group" onsubmit="doSaveConfigInt('worldState.thermiaFracturesProgressOverride'); return false;">
1117 <label class="form-label" for="worldState.thermiaFracturesProgressOverride" data-loc="worldState_thermiaFracturesProgressOverride"></label>
1118 <div class="input-group">
1119 <input id="worldState.thermiaFracturesProgressOverride" class="form-control" type="number" min="0" max="100" data-default="0" />
1120 <button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
1121 </div>
1122 </form>
1123 </div>
1124 </div>
1106 1125 <div class="form-group mt-2">
1107 1126 <label class="form-label" for="worldState.eidolonOverride" data-loc="worldState_eidolonOverride"></label>
1108 1127 <select class="form-control" id="worldState.eidolonOverride" data-default="">
Modified static/webui/translations/de.js +2 -0
@@ -265,6 +265,8 @@ dict = {
265 265 worldState_bellyOfTheBeastProgressOverride: `[UNTRANSLATED] Belly of the Beast Progress`,
266 266 worldState_eightClaw: `Acht Klauen`,
267 267 worldState_eightClawProgressOverride: `[UNTRANSLATED] Eight Claw Progress`,
268 worldState_thermiaFractures: `Thermische Risse`,
269 worldState_thermiaFracturesProgressOverride: `[UNTRANSLATED] Thermia Fractures Progress`,
268 270 worldState_from_year: `[UNTRANSLATED] from |VAL|`,
269 271 worldState_pre_year: `[UNTRANSLATED] pre |VAL|`,
270 272 worldState_week: `[UNTRANSLATED] Week |VAL|`,
Modified static/webui/translations/en.js +2 -0
@@ -264,6 +264,8 @@ dict = {
264 264 worldState_bellyOfTheBeastProgressOverride: `Belly of the Beast Progress`,
265 265 worldState_eightClaw: `Eight Claw`,
266 266 worldState_eightClawProgressOverride: `Eight Claw Progress`,
267 worldState_thermiaFractures: `Thermia Fractures`,
268 worldState_thermiaFracturesProgressOverride: `Thermia Fractures Progress`,
267 269 worldState_from_year: `from |VAL|`,
268 270 worldState_pre_year: `pre |VAL|`,
269 271 worldState_week: `Week |VAL|`,
Modified static/webui/translations/es.js +2 -0
@@ -265,6 +265,8 @@ dict = {
265 265 worldState_bellyOfTheBeastProgressOverride: `Progreso del Vientre de la Bestia`,
266 266 worldState_eightClaw: `Octava Garra`,
267 267 worldState_eightClawProgressOverride: `Progreso de Octava Garra`,
268 worldState_thermiaFractures: `Fracturas Thermia`,
269 worldState_thermiaFracturesProgressOverride: `[UNTRANSLATED] Thermia Fractures Progress`,
268 270 worldState_from_year: `de |VAL|`,
269 271 worldState_pre_year: `antes de |VAL|`,
270 272 worldState_week: `Semana |VAL|`,
Modified static/webui/translations/fr.js +2 -0
@@ -265,6 +265,8 @@ dict = {
265 265 worldState_bellyOfTheBeastProgressOverride: `[UNTRANSLATED] Belly of the Beast Progress`,
266 266 worldState_eightClaw: `Huitième Griffe`,
267 267 worldState_eightClawProgressOverride: `[UNTRANSLATED] Eight Claw Progress`,
268 worldState_thermiaFractures: `Crevasses Thermia`,
269 worldState_thermiaFracturesProgressOverride: `[UNTRANSLATED] Thermia Fractures Progress`,
268 270 worldState_from_year: `[UNTRANSLATED] from |VAL|`,
269 271 worldState_pre_year: `[UNTRANSLATED] pre |VAL|`,
270 272 worldState_week: `[UNTRANSLATED] Week |VAL|`,
Modified static/webui/translations/ru.js +2 -0
@@ -265,6 +265,8 @@ dict = {
265 265 worldState_bellyOfTheBeastProgressOverride: `Прогресс Чрева зверя`,
266 266 worldState_eightClaw: `Восемь когтей`,
267 267 worldState_eightClawProgressOverride: `Прогресс Восьми когтей`,
268 worldState_thermiaFractures: `Разломы Термии`,
269 worldState_thermiaFracturesProgressOverride: `Прогресс Разломов Термии`,
268 270 worldState_from_year: `из |VAL|`,
269 271 worldState_pre_year: `до |VAL|`,
270 272 worldState_week: `Неделя |VAL|`,
Modified static/webui/translations/uk.js +2 -0
@@ -265,6 +265,8 @@ dict = {
265 265 worldState_bellyOfTheBeastProgressOverride: `Прогрес У лігві звіра`,
266 266 worldState_eightClaw: `Вісім кігтів`,
267 267 worldState_eightClawProgressOverride: `Прогрес Восьми кігтів`,
268 worldState_thermiaFractures: `Розломи термії`,
269 worldState_thermiaFracturesProgressOverride: `[UNTRANSLATED] Thermia Fractures Progress`,
268 270 worldState_from_year: `з |VAL|`,
269 271 worldState_pre_year: `до |VAL|`,
270 272 worldState_week: `Тиждень |VAL|`,
Modified static/webui/translations/zh.js +2 -0