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: evil baro (#3061)

Closes #3034 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/3061 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>

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

代码差异

13 个文件 +108 -8
Modified config-vanilla.json +1 -0
@@ -31,6 +31,7 @@
31 31 "baroTennoConRelay": false,
32 32 "baroAlwaysAvailable": false,
33 33 "baroFullyStocked": false,
34 "evilBaroStage": 0,
34 35 "varziaFullyStocked": false,
35 36 "wolfHunt": null,
36 37 "orphixVenom": false,
Modified src/controllers/api/inboxController.ts +42 -4
@@ -25,6 +25,7 @@ import type { IOid } from "../../types/commonTypes.ts";
25 25 import { unixTimesInMs } from "../../constants/timeConstants.ts";
26 26 import { config } from "../../services/configService.ts";
27 27 import { Types } from "mongoose";
28 import { version_compare } from "../../helpers/inventoryHelpers.ts";
28 29
29 30 export const inboxController: RequestHandler = async (req, res) => {
30 31 const { deleteId, lastMessage: latestClientMessageId, messageId } = req.query;
@@ -145,15 +146,38 @@ const createNewEventMessages = async (req: Request): Promise<void> => {
145 146 // Baro
146 147 const baroIndex = Math.trunc((Date.now() - 910800000) / (unixTimesInMs.day * 14));
147 148 const baroStart = baroIndex * (unixTimesInMs.day * 14) + 910800000;
149 const prevBaroEnd = (baroIndex - 1) * (unixTimesInMs.day * 14) + 910800000;
150 const baroEnd = baroStart + unixTimesInMs.day * 14;
148 151 const baroActualStart = baroStart + unixTimesInMs.day * (config.worldState?.baroAlwaysAvailable ? 0 : 12);
152 const evilBaroStage =
153 account.BuildLabel && version_compare(account.BuildLabel, "2025.10.14.16.10") < 0
154 ? 0
155 : (config.worldState?.evilBaroStage ?? 0);
156 const evilBaroTransmission = [
157 "",
158 "/Lotus/Sounds/Dialog/BaroHalloween/Week1InboxMessage/DWeek1InboxMessage01290Baro",
159 "/Lotus/Sounds/Dialog/BaroHalloween/Week2InboxMessage/DWeek2InboxMessage0060Baro",
160 "/Lotus/Sounds/Dialog/BaroHalloween/Week3InboxMessage/DWeek3InboxMessage0120Baro",
161 "/Lotus/Sounds/Dialog/BaroHalloween/Week4InboxMessage/DWeek4InboxMessage0170Baro"
162 ][evilBaroStage];
149 163 if (Date.now() >= baroActualStart && account.LatestEventMessageDate.getTime() < baroActualStart) {
150 164 newEventMessages.push({
151 165 sndr: "/Lotus/Language/G1Quests/VoidTraderName",
152 sub: "/Lotus/Language/CommunityMessages/VoidTraderAppearanceTitle",
153 msg: "/Lotus/Language/CommunityMessages/VoidTraderAppearanceMessage",
154 icon: "/Lotus/Interface/Icons/Npcs/BaroKiTeerPortrait.png",
166 sub:
167 evilBaroStage > 0
168 ? "/Lotus/Language/BaroHalloween/HalloweenInboxTitle"
169 : "/Lotus/Language/CommunityMessages/VoidTraderAppearanceTitle",
170 msg:
171 evilBaroStage > 0
172 ? `/Lotus/Language/BaroHalloween/HalloweenInboxWeek${evilBaroStage}Body`
173 : "/Lotus/Language/CommunityMessages/VoidTraderAppearanceMessage",
174 icon:
175 evilBaroStage > 0
176 ? "/Lotus/Interface/Icons/Npcs/EvilBaro.png"
177 : "/Lotus/Interface/Icons/Npcs/BaroKiTeerPortrait.png",
178 transmission: evilBaroTransmission,
155 179 startDate: new Date(baroActualStart),
156 endDate: new Date(baroStart + unixTimesInMs.day * 14),
180 endDate: new Date(baroEnd),
157 181 CrossPlatform: true,
158 182 arg: [
159 183 {
@@ -164,6 +188,20 @@ const createNewEventMessages = async (req: Request): Promise<void> => {
164 188 date: new Date(baroActualStart)
165 189 });
166 190 }
191 if (Date.now() >= prevBaroEnd && account.LatestEventMessageDate.getTime() < prevBaroEnd && evilBaroStage == 4) {
192 newEventMessages.push({
193 sndr: "/Lotus/Language/G1Quests/VoidTraderName",
194 sub: "/Lotus/Language/BaroHalloween/HalloweenInboxEndingTitle",
195 msg: "/Lotus/Language/BaroHalloween/HalloweenInboxEndingBody",
196 icon: "/Lotus/Interface/Icons/Npcs/BaroKiTeerPortrait.png",
197 transmission: "/Lotus/Sounds/Dialog/BaroHalloween/EndingInboxMessage/DEndingInboxMessage0230Baro",
198 startDate: new Date(prevBaroEnd),
199 endDate: new Date(baroActualStart),
200 att: ["/Lotus/Types/StoreItems/AvatarImages/ImageBaroKiteerEvil"],
201 CrossPlatform: true,
202 date: new Date(prevBaroEnd)
203 });
204 }
167 205
168 206 // BUG: Deleting the inbox message manually means it'll just be automatically re-created. This is because we don't use startDate/endDate for these config-toggled events.
169 207 const promises = [];
Modified src/services/configService.ts +1 -0
@@ -38,6 +38,7 @@ export interface IConfig {
38 38 baroTennoConRelay?: boolean;
39 39 baroAlwaysAvailable?: boolean;
40 40 baroFullyStocked?: boolean;
41 evilBaroStage?: number;
41 42 varziaFullyStocked?: boolean;
42 43 wolfHunt?: number;
43 44 orphixVenom?: boolean;
Modified src/services/worldStateService.ts +36 -4
@@ -1269,7 +1269,12 @@ const getIdealTimeSatsifyingConstraints = (constraints: ITimeConstraint[]): numb
1269 1269 return timeSecs;
1270 1270 };
1271 1271
1272 const fullyStockBaro = (vt: IVoidTrader): void => {
1272 const fullyStockBaro = (vt: IVoidTrader, buildLabel?: string): void => {
1273 if (buildLabel && version_compare(buildLabel, "2025.10.14.16.10") >= 0) {
1274 for (const item of baro.evilBaro as IVoidTraderOffer[]) {
1275 vt.Manifest.push(item);
1276 }
1277 }
1273 1278 for (const armorSet of baro.armorSets) {
1274 1279 if (Array.isArray(armorSet[0])) {
1275 1280 for (const set of armorSet as IVoidTraderOffer[][]) {
@@ -1569,7 +1574,7 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
1569 1574 Manifest: []
1570 1575 };
1571 1576 worldState.VoidTraders.push(vt);
1572 fullyStockBaro(vt);
1577 fullyStockBaro(vt, buildLabel);
1573 1578 }
1574 1579
1575 1580 if (config.worldState) {
@@ -3395,18 +3400,25 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
3395 3400 const baroActualStart = baroStart + unixTimesInMs.day * (config.worldState?.baroAlwaysAvailable ? 0 : 12);
3396 3401 const baroEnd = baroStart + unixTimesInMs.day * 14;
3397 3402 const baroNode = ["EarthHUB", "MercuryHUB", "SaturnHUB", "PlutoHUB"][baroIndex % 4];
3403 const evilBaroStage =
3404 buildLabel && version_compare(buildLabel, "2025.10.14.16.10") < 0
3405 ? 0
3406 : (config.worldState?.evilBaroStage ?? 0);
3407 const baroCharacter = ["Baro'Ki Teel", "EvilBaroWeek1", "EvilBaroWeek2", "EvilBaroWeek3", "EvilBaroWeek4"][
3408 evilBaroStage
3409 ];
3398 3410 const vt: IVoidTrader = {
3399 3411 _id: { $oid: ((baroStart / 1000) & 0xffffffff).toString(16).padStart(8, "0") + "493c96d6067610bc" },
3400 3412 Activation: { $date: { $numberLong: baroActualStart.toString() } },
3401 3413 Expiry: { $date: { $numberLong: baroEnd.toString() } },
3402 Character: "Baro'Ki Teel",
3414 Character: baroCharacter,
3403 3415 Node: baroNode,
3404 3416 Manifest: []
3405 3417 };
3406 3418 worldState.VoidTraders.push(vt);
3407 3419 if (isBeforeNextExpectedWorldStateRefresh(timeMs, baroActualStart)) {
3408 3420 if (config.worldState?.baroFullyStocked) {
3409 fullyStockBaro(vt);
3421 fullyStockBaro(vt, buildLabel);
3410 3422 } else {
3411 3423 const rng = new SRng(new SRng(baroIndex).randomInt(0, 100_000));
3412 3424 // TOVERIFY: Constraint for upgrades amount?
@@ -3436,6 +3448,26 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
3436 3448 for (const armor of armorSet) {
3437 3449 vt.Manifest.push(armor as IVoidTraderOffer);
3438 3450 }
3451
3452 {
3453 const evilBaroStock: string[] = [];
3454 if (evilBaroStage >= 1) evilBaroStock.push("EvilBaroArcaArmorA", "BaroEvilEphemera");
3455 if (evilBaroStage >= 2) evilBaroStock.push("GrimoireEvilBaroSkin", "EvilBaroArcaArmorC");
3456 if (evilBaroStage >= 3) evilBaroStock.push("EvilBaroArcaArmorL", "EvilBaroSilvaAndAegis");
3457 if (evilBaroStage >= 4) {
3458 evilBaroStock.push(
3459 "EvilBaroNecraloidSigil",
3460 "DissolveEnemyMod",
3461 "EvilBaroFloatingCandlesShipDeco"
3462 );
3463 }
3464
3465 vt.Manifest.unshift(
3466 ...(baro.evilBaro as IVoidTraderOffer[]).filter(item =>
3467 evilBaroStock.some(end => item.ItemType.endsWith(end))
3468 )
3469 );
3470 }
3439 3471 }
3440 3472 for (const item of baro.evergreen) {
3441 3473 vt.Manifest.push(item);
Modified static/fixed_responses/worldState/baro.json +11 -0
@@ -1,4 +1,15 @@
1 1 {
2 "evilBaro": [
3 { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Armor/CrpHighArmor/EvilBaroArcaArmorC", "PrimePrice": 196, "RegularPrice": 294000 },
4 { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Armor/CrpHighArmor/EvilBaroArcaArmorA", "PrimePrice": 109, "RegularPrice": 278000 },
5 { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Armor/CrpHighArmor/EvilBaroArcaArmorL", "PrimePrice": 184, "RegularPrice": 251000 },
6 { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Effects/BaroEvilEphemera", "PrimePrice": 69, "RegularPrice": 109000 },
7 { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Weapons/Grimoire/GrimoireEvilBaroSkin", "PrimePrice": 227, "RegularPrice": 302000 },
8 { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/VoidTrader/EvilBaroSilvaAndAegis", "PrimePrice": 132, "RegularPrice": 298000 },
9 { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Sigils/EvilBaroNecraloidSigil", "PrimePrice": 34, "RegularPrice": 61000 },
10 { "ItemType": "/Lotus/StoreItems/Upgrades/CosmeticEnhancers/Peculiars/DissolveEnemyMod", "PrimePrice": 228, "RegularPrice": 1000001 },
11 { "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/Props/EvilBaroFloatingCandlesShipDeco", "PrimePrice": 21, "RegularPrice": 88000 }
12 ],
2 13 "evergreen": [
3 14 { "ItemType": "/Lotus/StoreItems/Types/Keys/MummyQuestKeyBlueprint", "PrimePrice": 100, "RegularPrice": 25000 },
4 15 { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Effects/FootstepsMaple", "PrimePrice": 15, "RegularPrice": 1000 },
Modified static/webui/index.html +10 -0
@@ -1273,6 +1273,16 @@
1273 1273 <input class="form-check-input" type="checkbox" id="worldState.qtccAlerts" />
1274 1274 <label class="form-check-label" for="worldState.qtccAlerts" data-loc="worldState_qtccAlerts"></label>
1275 1275 </div>
1276 <div class="form-group mt-2">
1277 <label class="form-label" for="worldState.evilBaroStage" data-loc="worldState_evilBaroStage"></label>
1278 <select class="form-control" id="worldState.evilBaroStage" data-default="0">
1279 <option value="0" data-loc="disabled"></option>
1280 <option value="1" data-loc="worldState_week" data-loc-replace="1"></option>
1281 <option value="2" data-loc="worldState_week" data-loc-replace="2"></option>
1282 <option value="3" data-loc="worldState_week" data-loc-replace="3"></option>
1283 <option value="4" data-loc="worldState_week" data-loc-replace="4"></option>
1284 </select>
1285 </div>
1276 1286 <div class="form-group mt-2">
1277 1287 <label class="form-label" for="worldState.wolfHunt" data-loc="worldState_wolfHunt"></label>
1278 1288 <abbr data-loc-inc="worldState_galleonOfGhouls|worldState_orphixVenom|worldState_anniversary"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr>
Modified static/webui/translations/de.js +1 -0
@@ -321,6 +321,7 @@ dict = {
321 321 worldState_thermiaFractures: `Thermische Risse`,
322 322 worldState_thermiaFracturesProgressOverride: `Thermische Risse-Fortschritt`,
323 323 worldState_qtccAlerts: `Quest zum Kampf gegen Krebs-Alarmierungen`,
324 worldState_evilBaroStage: `[UNTRANSLATED] Evil Baro`,
324 325 worldState_from_year: `Von |VAL|`,
325 326 worldState_pre_year: `Vor |VAL|`,
326 327 worldState_week: `Woche |VAL|`,
Modified static/webui/translations/en.js +1 -0
@@ -320,6 +320,7 @@ dict = {
320 320 worldState_thermiaFractures: `Thermia Fractures`,
321 321 worldState_thermiaFracturesProgressOverride: `Thermia Fractures Progress`,
322 322 worldState_qtccAlerts: `Quest to Conquer Cancer Alerts`,
323 worldState_evilBaroStage: `Evil Baro`,
323 324 worldState_from_year: `From |VAL|`,
324 325 worldState_pre_year: `Pre-|VAL|`,
325 326 worldState_week: `Week |VAL|`,
Modified static/webui/translations/es.js +1 -0
@@ -321,6 +321,7 @@ dict = {
321 321 worldState_thermiaFractures: `Fracturas Thermia`,
322 322 worldState_thermiaFracturesProgressOverride: `Progreso de Fracturas Thermia`,
323 323 worldState_qtccAlerts: `[UNTRANSLATED] Quest to Conquer Cancer Alerts`,
324 worldState_evilBaroStage: `[UNTRANSLATED] Evil Baro`,
324 325 worldState_from_year: `De |VAL|`,
325 326 worldState_pre_year: `Antes de |VAL|`,
326 327 worldState_week: `Semana |VAL|`,
Modified static/webui/translations/fr.js +1 -0
@@ -321,6 +321,7 @@ dict = {
321 321 worldState_thermiaFractures: `Crevasses Thermia`,
322 322 worldState_thermiaFracturesProgressOverride: `Progrès des Fractures Thermia`,
323 323 worldState_qtccAlerts: `Alertes Quête pour Vaincre le Cancer`,
324 worldState_evilBaroStage: `[UNTRANSLATED] Evil Baro`,
324 325 worldState_from_year: `De |VAL|`,
325 326 worldState_pre_year: `Pre-|VAL|`,
326 327 worldState_week: `Semaine |VAL|`,
Modified static/webui/translations/ru.js +1 -0
@@ -321,6 +321,7 @@ dict = {
321 321 worldState_thermiaFractures: `Разломы Термии`,
322 322 worldState_thermiaFracturesProgressOverride: `Прогресс Разломов Термии`,
323 323 worldState_qtccAlerts: `Тревоги Quest to Conquer Cancer`,
324 worldState_evilBaroStage: `Злой Баро`,
324 325 worldState_from_year: `Из |VAL|`,
325 326 worldState_pre_year: `До |VAL|`,
326 327 worldState_week: `Неделя |VAL|`,
Modified static/webui/translations/uk.js +1 -0
@@ -321,6 +321,7 @@ dict = {
321 321 worldState_thermiaFractures: `Розломи термії`,
322 322 worldState_thermiaFracturesProgressOverride: `Прогрес Розломів термії`,
323 323 worldState_qtccAlerts: `[UNTRANSLATED] Quest to Conquer Cancer Alerts`,
324 worldState_evilBaroStage: `[UNTRANSLATED] Evil Baro`,
324 325 worldState_from_year: `З |VAL|`,
325 326 worldState_pre_year: `До |VAL|`,
326 327 worldState_week: `Тиждень |VAL|`,
Modified static/webui/translations/zh.js +1 -0