forked from OpenWF/SpaceNinjaServer
Compare commits
9 Commits
f5c1b83598
...
b1cf1012f5
| Author | SHA1 | Date | |
|---|---|---|---|
| b1cf1012f5 | |||
| 610a432e46 | |||
| 2ca895a5f8 | |||
| fd2286c253 | |||
| 5a582daa1a | |||
| 6a571e5e78 | |||
| 0349c4a32c | |||
| e1563bf298 | |||
| af6f422fec |
@ -41,6 +41,10 @@
|
||||
"naberusNightsOverride": null,
|
||||
"proxyRebellion": false,
|
||||
"proxyRebellionRewardsOverride": 0,
|
||||
"voidCorruption2025Week1": false,
|
||||
"voidCorruption2025Week2": false,
|
||||
"voidCorruption2025Week3": false,
|
||||
"voidCorruption2025Week4": false,
|
||||
"galleonOfGhouls": 0,
|
||||
"ghoulEmergenceOverride": null,
|
||||
"plagueStarOverride": null,
|
||||
|
||||
2
package-lock.json
generated
2
package-lock.json
generated
@ -9,6 +9,7 @@
|
||||
"version": "0.1.0",
|
||||
"license": "GNU",
|
||||
"dependencies": {
|
||||
"body-parser": "^2.2.0",
|
||||
"chokidar": "^4.0.3",
|
||||
"crc-32": "^1.2.2",
|
||||
"express": "^5",
|
||||
@ -37,6 +38,7 @@
|
||||
"node": ">=20.18.1"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@types/body-parser": "^1.19.6",
|
||||
"@types/express": "^5",
|
||||
"@types/morgan": "^1.9.9",
|
||||
"@types/websocket": "^1.0.10",
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
"license": "GNU",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"body-parser": "^2.2.0",
|
||||
"chokidar": "^4.0.3",
|
||||
"crc-32": "^1.2.2",
|
||||
"express": "^5",
|
||||
@ -42,6 +43,7 @@
|
||||
"ws": "^8.18.2"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@types/body-parser": "^1.19.6",
|
||||
"@types/express": "^5",
|
||||
"@types/morgan": "^1.9.9",
|
||||
"@types/websocket": "^1.0.10",
|
||||
|
||||
@ -31,12 +31,13 @@ export const abortDojoComponentController: RequestHandler = async (req, res) =>
|
||||
|
||||
if (request.DecoId) {
|
||||
removeDojoDeco(guild, request.ComponentId, request.DecoId);
|
||||
await guild.save();
|
||||
res.json(await getDojoClient(guild, 0, request.ComponentId));
|
||||
} else {
|
||||
await removeDojoRoom(guild, request.ComponentId);
|
||||
await guild.save();
|
||||
res.json(await getDojoClient(guild, 0));
|
||||
}
|
||||
|
||||
await guild.save();
|
||||
res.json(await getDojoClient(guild, 0, request.ComponentId));
|
||||
};
|
||||
|
||||
interface IAbortDojoComponentRequest {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { fromDbOid, version_compare } from "../../helpers/inventoryHelpers.ts";
|
||||
import { fromDbOid, toMongoDate, version_compare } from "../../helpers/inventoryHelpers.ts";
|
||||
import type { IKnifeResponse } from "../../helpers/nemesisHelpers.ts";
|
||||
import {
|
||||
antivirusMods,
|
||||
@ -310,6 +310,15 @@ export const nemesisController: RequestHandler = async (req, res) => {
|
||||
res.json({
|
||||
target: inventory.toJSON().Nemesis
|
||||
});
|
||||
} else if ((req.query.mode as string) == "t") {
|
||||
const inventory = await getInventory(account._id.toString(), "LastNemesisAllySpawnTime");
|
||||
//const body = getJSONfromString<IUpdateAllySpawnTimeRequest>(String(req.body));
|
||||
const now = new Date(Math.trunc(Date.now() / 1000) * 1000);
|
||||
inventory.LastNemesisAllySpawnTime = now;
|
||||
await inventory.save();
|
||||
res.json({
|
||||
NewTime: toMongoDate(now)
|
||||
} satisfies IUpdateAllySpawnTimeResponse);
|
||||
} else if ((req.query.mode as string) == "d") {
|
||||
const inventory = await getInventory(account._id.toString(), "NemesisHistory");
|
||||
const body = getJSONfromString<IRelinquishAdversariesRequest>(String(req.body));
|
||||
@ -462,3 +471,11 @@ const consumeModCharge = (
|
||||
interface IRelinquishAdversariesRequest {
|
||||
nemesisFingerprints: (bigint | number)[];
|
||||
}
|
||||
|
||||
// interface IUpdateAllySpawnTimeRequest {
|
||||
// LastSpawnTime: IMongoDate;
|
||||
// }
|
||||
|
||||
interface IUpdateAllySpawnTimeResponse {
|
||||
NewTime: IMongoDate;
|
||||
}
|
||||
|
||||
@ -1743,7 +1743,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
|
||||
NemesisAbandonedRewards: { type: [String], default: [] },
|
||||
Nemesis: nemesisSchema,
|
||||
NemesisHistory: { type: [nemesisSchema], default: undefined },
|
||||
//LastNemesisAllySpawnTime: Schema.Types.Mixed,
|
||||
LastNemesisAllySpawnTime: { type: Date, default: undefined },
|
||||
|
||||
//TradingRulesConfirmed,ShowFriendInvNotifications(Option->Social)
|
||||
Settings: settingsSchema,
|
||||
@ -1864,6 +1864,9 @@ inventorySchema.set("toJSON", {
|
||||
if (inventoryDatabase.BlessingCooldown) {
|
||||
inventoryResponse.BlessingCooldown = toMongoDate(inventoryDatabase.BlessingCooldown);
|
||||
}
|
||||
if (inventoryDatabase.LastNemesisAllySpawnTime) {
|
||||
inventoryResponse.LastNemesisAllySpawnTime = toMongoDate(inventoryDatabase.LastNemesisAllySpawnTime);
|
||||
}
|
||||
if (inventoryDatabase.NextRefill) {
|
||||
inventoryResponse.NextRefill = toMongoDate(inventoryDatabase.NextRefill);
|
||||
}
|
||||
|
||||
@ -51,6 +51,10 @@ export interface IConfig {
|
||||
naberusNightsOverride?: boolean;
|
||||
proxyRebellion?: boolean;
|
||||
proxyRebellionRewardsOverride?: number;
|
||||
voidCorruption2025Week1?: boolean;
|
||||
voidCorruption2025Week2?: boolean;
|
||||
voidCorruption2025Week3?: boolean;
|
||||
voidCorruption2025Week4?: boolean;
|
||||
galleonOfGhouls?: number;
|
||||
ghoulEmergenceOverride?: boolean;
|
||||
plagueStarOverride?: boolean;
|
||||
|
||||
@ -73,6 +73,7 @@ import type {
|
||||
ITailorShop,
|
||||
ITailorShopDatabase
|
||||
} from "../types/personalRoomsTypes.ts";
|
||||
import { fromMongoDate } from "../helpers/inventoryHelpers.ts";
|
||||
|
||||
const convertDate = (value: IMongoDate): Date => {
|
||||
return new Date(parseInt(value.$date.$numberLong));
|
||||
@ -326,7 +327,15 @@ export const importInventory = (db: TInventoryDatabaseDocument, client: Partial<
|
||||
"GiftsRemaining",
|
||||
"ChallengesFixVersion",
|
||||
"Founder",
|
||||
"Guide"
|
||||
"Guide",
|
||||
"BountyScore",
|
||||
"EntratiVaultCountLastPeriod",
|
||||
"EntratiLabConquestUnlocked",
|
||||
"EntratiLabConquestHardModeStatus",
|
||||
"EntratiLabConquestCacheScoreMission",
|
||||
"EchoesHexConquestUnlocked",
|
||||
"EchoesHexConquestHardModeStatus",
|
||||
"EchoesHexConquestCacheScoreMission"
|
||||
] as const) {
|
||||
if (client[key] !== undefined) {
|
||||
db[key] = client[key];
|
||||
@ -354,12 +363,28 @@ export const importInventory = (db: TInventoryDatabaseDocument, client: Partial<
|
||||
"NodeIntrosCompleted",
|
||||
"DeathMarks",
|
||||
"Wishlist",
|
||||
"NemesisAbandonedRewards"
|
||||
"NemesisAbandonedRewards",
|
||||
"EntratiLabConquestActiveFrameVariants",
|
||||
"EchoesHexConquestActiveFrameVariants",
|
||||
"EchoesHexConquestActiveStickers"
|
||||
] as const) {
|
||||
if (client[key] !== undefined) {
|
||||
db[key] = client[key];
|
||||
}
|
||||
}
|
||||
// IMongoDate
|
||||
for (const key of [
|
||||
"Created",
|
||||
"TrainingDate",
|
||||
"BlessingCooldown",
|
||||
"LastNemesisAllySpawnTime",
|
||||
"NextRefill",
|
||||
"EntratiVaultCountResetDate"
|
||||
] as const) {
|
||||
if (client[key] !== undefined) {
|
||||
db[key] = fromMongoDate(client[key]);
|
||||
}
|
||||
}
|
||||
// IRewardAtten[]
|
||||
for (const key of ["SortieRewardAttenuation", "SpecialItemRewardAttenuation"] as const) {
|
||||
if (client[key] !== undefined) {
|
||||
|
||||
@ -1489,7 +1489,13 @@ export const addSkin = (
|
||||
inventoryChanges: IInventoryChanges = {}
|
||||
): IInventoryChanges => {
|
||||
if (inventory.WeaponSkins.some(x => x.ItemType == typeName)) {
|
||||
logger.debug(`refusing to add WeaponSkin ${typeName} because account already owns it`);
|
||||
if (typeName == "/Lotus/Upgrades/Skins/Clan/BountyHunterBadgeItem") {
|
||||
logger.debug(`account already owns stratos emblem, increasing bounty score instead`);
|
||||
inventory.BountyScore ??= 0;
|
||||
inventory.BountyScore += 1;
|
||||
} else {
|
||||
logger.debug(`refusing to add WeaponSkin ${typeName} because account already owns it`);
|
||||
}
|
||||
} else {
|
||||
const index =
|
||||
inventory.WeaponSkins.push({
|
||||
|
||||
@ -1151,6 +1151,27 @@ export const addMissionRewards = async (
|
||||
let ConquestCompletedMissionsCount;
|
||||
|
||||
let missionCompletionCredits = 0;
|
||||
|
||||
if (rewardInfo.alertId) {
|
||||
const alert = getWorldState().Alerts.find(x => x._id.$oid == rewardInfo.alertId);
|
||||
if (!alert) {
|
||||
logger.warn(`mission completed unknown alert`, { alertId: rewardInfo.alertId });
|
||||
} else {
|
||||
if (inventory.CompletedAlerts.includes(alert._id.$oid)) {
|
||||
logger.debug(`alert ${alert._id.$oid} already completed, skipping alert reward`);
|
||||
} else {
|
||||
inventory.CompletedAlerts.push(alert._id.$oid);
|
||||
if (alert.MissionInfo.missionReward) {
|
||||
missionCompletionCredits += addFixedLevelRewards(
|
||||
alert.MissionInfo.missionReward,
|
||||
MissionRewards,
|
||||
rewardInfo
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//inventory change is what the client has not rewarded itself, also the client needs to know the credit changes for display
|
||||
|
||||
if (rewardInfo.goalId) {
|
||||
|
||||
@ -19,6 +19,7 @@ import type {
|
||||
ICalendarDay,
|
||||
ICalendarEvent,
|
||||
ICalendarSeason,
|
||||
IAlert,
|
||||
IGoal,
|
||||
IInvasion,
|
||||
ILiteSortie,
|
||||
@ -112,6 +113,89 @@ const sortieBossNode: Record<Exclude<TSortieBoss, "SORTIE_BOSS_CORRUPTED_VOR">,
|
||||
SORTIE_BOSS_VOR: "SolNode108"
|
||||
};
|
||||
|
||||
const configAlerts: Record<string, IAlert> = {
|
||||
voidCorruption2025Week1: {
|
||||
_id: { $oid: "677d452e2f324ee7b90f8ccf" },
|
||||
Activation: { $date: { $numberLong: "1736524800000" } },
|
||||
Expiry: { $date: { $numberLong: "2000000000000" } },
|
||||
MissionInfo: {
|
||||
location: "SolNode61",
|
||||
missionType: "MT_SABOTAGE",
|
||||
faction: "FC_CORPUS",
|
||||
difficulty: 1,
|
||||
missionReward: {
|
||||
credits: 30000,
|
||||
items: ["/Lotus/StoreItems/Upgrades/Mods/Pistol/DualStat/CorruptedFireRateDamagePistol"]
|
||||
},
|
||||
levelOverride: "/Lotus/Levels/Proc/Corpus/CorpusShipCoreSabotage",
|
||||
enemySpec: "/Lotus/Types/Game/EnemySpecs/CorpusShipEnemySpecs/CorpusShipSquadA",
|
||||
extraEnemySpec: "/Lotus/Types/Game/EnemySpecs/GamemodeExtraEnemySpecs/CorpusSabotageTiersA",
|
||||
minEnemyLevel: 10,
|
||||
maxEnemyLevel: 15
|
||||
}
|
||||
},
|
||||
voidCorruption2025Week2: {
|
||||
_id: { $oid: "677d45811daeae9de40e8c0f" },
|
||||
Activation: { $date: { $numberLong: "1737129600000" } },
|
||||
Expiry: { $date: { $numberLong: "2000000000000" } },
|
||||
MissionInfo: {
|
||||
location: "SettlementNode11",
|
||||
missionType: "MT_DEFENSE",
|
||||
faction: "FC_CORPUS",
|
||||
difficulty: 1,
|
||||
missionReward: {
|
||||
credits: 30000,
|
||||
items: ["/Lotus/StoreItems/Upgrades/Mods/Pistol/DualStat/CorruptedCritChanceFireRatePistol"]
|
||||
},
|
||||
levelOverride: "/Lotus/Levels/Proc/Corpus/CorpusShipDefense",
|
||||
enemySpec: "/Lotus/Types/Game/EnemySpecs/CorpusShipEnemySpecs/CorpusShipSquadDefenseB",
|
||||
minEnemyLevel: 20,
|
||||
maxEnemyLevel: 25,
|
||||
maxWaveNum: 6
|
||||
}
|
||||
},
|
||||
voidCorruption2025Week3: {
|
||||
_id: { $oid: "677d45a494ad716c90006b9a" },
|
||||
Activation: { $date: { $numberLong: "1737734400000" } },
|
||||
Expiry: { $date: { $numberLong: "2000000000000" } },
|
||||
MissionInfo: {
|
||||
location: "SolNode118",
|
||||
missionType: "MT_ARTIFACT",
|
||||
faction: "FC_CORPUS",
|
||||
difficulty: 1,
|
||||
missionReward: {
|
||||
credits: 30000,
|
||||
items: ["/Lotus/StoreItems/Upgrades/Mods/Pistol/DualStat/CorruptedCritDamagePistol"]
|
||||
},
|
||||
levelOverride: "/Lotus/Levels/Proc/Corpus/CorpusShipDisruption",
|
||||
enemySpec: "/Lotus/Types/Game/EnemySpecs/CorpusShipEnemySpecs/CorpusShipSurvivalA",
|
||||
extraEnemySpec: "/Lotus/Types/Game/EnemySpecs/SpecialMissionSpecs/DisruptionCorpusShip",
|
||||
customAdvancedSpawners: ["/Lotus/Types/Enemies/AdvancedSpawners/ErrantSpecterInvasion"],
|
||||
minEnemyLevel: 30,
|
||||
maxEnemyLevel: 35
|
||||
}
|
||||
},
|
||||
voidCorruption2025Week4: {
|
||||
_id: { $oid: "677d4700682d173abb0e19fe" },
|
||||
Activation: { $date: { $numberLong: "1738339200000" } },
|
||||
Expiry: { $date: { $numberLong: "2000000000000" } },
|
||||
MissionInfo: {
|
||||
location: "SolNode4",
|
||||
missionType: "MT_EXTERMINATION",
|
||||
faction: "FC_CORPUS",
|
||||
difficulty: 1,
|
||||
missionReward: {
|
||||
credits: 30000,
|
||||
items: ["/Lotus/StoreItems/Upgrades/Mods/Pistol/DualStat/CorruptedDamageRecoilPistol"]
|
||||
},
|
||||
levelOverride: "/Lotus/Levels/Proc/Corpus/CorpusShipExterminate",
|
||||
enemySpec: "/Lotus/Types/Game/EnemySpecs/CorpusShipEnemySpecs/CorpusShipExterminateMixed",
|
||||
minEnemyLevel: 40,
|
||||
maxEnemyLevel: 45
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const eidolonJobs: readonly string[] = [
|
||||
"/Lotus/Types/Gameplay/Eidolon/Jobs/AssassinateBountyAss",
|
||||
"/Lotus/Types/Gameplay/Eidolon/Jobs/AssassinateBountyCap",
|
||||
@ -1481,6 +1565,15 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
|
||||
worldState.VoidTraders.push(vt);
|
||||
fullyStockBaro(vt);
|
||||
}
|
||||
|
||||
if (config.worldState) {
|
||||
for (const [key, alert] of Object.entries(configAlerts)) {
|
||||
if (config.worldState[key as keyof typeof config.worldState]) {
|
||||
worldState.Alerts.push(alert);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const isFebruary = date.getUTCMonth() == 1;
|
||||
if (config.worldState?.starDaysOverride ?? isFebruary) {
|
||||
worldState.Goals.push({
|
||||
@ -2316,22 +2409,22 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
|
||||
// 2016
|
||||
[
|
||||
{
|
||||
items: ["/Lotus/StoreItems/Upgrades/Skins/Sigils/OrokinCatalyst"]
|
||||
},
|
||||
{
|
||||
items: ["/Lotus/StoreItems/Upgrades/Skins/Sigils/DotD2016Sigil"]
|
||||
items: ["/Lotus/StoreItems/Types/Items/MiscItems/OrokinCatalyst"]
|
||||
},
|
||||
{
|
||||
items: [
|
||||
"/Lotus/StoreItems/Types/Items/MiscItems/OrokinReactor",
|
||||
"/Lotus/StoreItems/Upgrades/Skins/Sigils/DotD2016Sigil",
|
||||
"/Lotus/StoreItems/Upgrades/Skins/Clan/BountyHunterBadgeItem"
|
||||
]
|
||||
},
|
||||
{
|
||||
items: ["/Lotus/StoreItems/Types/Items/MiscItems/OrokinReactor"]
|
||||
}
|
||||
],
|
||||
// 2015
|
||||
[
|
||||
{
|
||||
items: ["/Lotus/StoreItems/Upgrades/Skins/Sigils/OrokinCatalyst"]
|
||||
items: ["/Lotus/StoreItems/Types/Items/MiscItems/OrokinCatalyst"]
|
||||
},
|
||||
{
|
||||
items: ["/Lotus/StoreItems/Upgrades/Skins/Clan/BountyHunterBadgeItem"]
|
||||
|
||||
@ -92,6 +92,7 @@ export interface IInventoryDatabase
|
||||
| "NextRefill"
|
||||
| "Nemesis"
|
||||
| "NemesisHistory"
|
||||
| "LastNemesisAllySpawnTime"
|
||||
| "EntratiVaultCountResetDate"
|
||||
| "BrandedSuits"
|
||||
| "LockedWeaponGroup"
|
||||
@ -136,6 +137,7 @@ export interface IInventoryDatabase
|
||||
NextRefill?: Date;
|
||||
Nemesis?: INemesisDatabase;
|
||||
NemesisHistory?: INemesisBaseDatabase[];
|
||||
LastNemesisAllySpawnTime?: Date;
|
||||
EntratiVaultCountResetDate?: Date;
|
||||
BrandedSuits?: Types.ObjectId[];
|
||||
LockedWeaponGroup?: ILockedWeaponGroupDatabase;
|
||||
@ -360,7 +362,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
|
||||
ThemeStyle: string;
|
||||
ThemeBackground: string;
|
||||
ThemeSounds: string;
|
||||
BountyScore: number;
|
||||
BountyScore?: number;
|
||||
//ChallengeInstanceStates: IChallengeInstanceState[];
|
||||
LoginMilestoneRewards: string[];
|
||||
RecentVendorPurchases?: IRecentVendorPurchaseClient[];
|
||||
@ -372,7 +374,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
|
||||
//InvasionChainProgress: IInvasionChainProgress[];
|
||||
Nemesis?: INemesisClient;
|
||||
NemesisHistory?: INemesisBaseClient[];
|
||||
//LastNemesisAllySpawnTime?: IMongoDate;
|
||||
LastNemesisAllySpawnTime?: IMongoDate;
|
||||
Settings?: ISettings;
|
||||
PersonalTechProjects: IPersonalTechProjectClient[];
|
||||
PlayerSkills: IPlayerSkills;
|
||||
|
||||
@ -178,6 +178,7 @@ export interface IRewardInfo {
|
||||
goalManifest?: string;
|
||||
invasionId?: string;
|
||||
invasionAllyFaction?: "FC_GRINEER" | "FC_CORPUS";
|
||||
alertId?: string;
|
||||
sortieId?: string;
|
||||
sortieTag?: "Mission1" | "Mission2" | "Final";
|
||||
sortiePrereqs?: string[];
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import type { IMissionReward } from "warframe-public-export-plus";
|
||||
import type { IMissionReward, TFaction } from "warframe-public-export-plus";
|
||||
import type { IMongoDate, IOid } from "./commonTypes.ts";
|
||||
|
||||
export interface IWorldState {
|
||||
@ -7,7 +7,7 @@ export interface IWorldState {
|
||||
Time: number;
|
||||
InGameMarket: IInGameMarket;
|
||||
Goals: IGoal[];
|
||||
Alerts: [];
|
||||
Alerts: IAlert[];
|
||||
Sorties: ISortie[];
|
||||
LiteSorties: ILiteSortie[];
|
||||
SyndicateMissions: ISyndicateMissionInfo[];
|
||||
@ -35,6 +35,28 @@ export interface IWorldState {
|
||||
Tmp?: string;
|
||||
}
|
||||
|
||||
export interface IAlert {
|
||||
_id: IOid;
|
||||
Activation: IMongoDate;
|
||||
Expiry: IMongoDate;
|
||||
MissionInfo: IAlertMissionInfo;
|
||||
}
|
||||
|
||||
export interface IAlertMissionInfo {
|
||||
location: string;
|
||||
missionType: string;
|
||||
faction: TFaction;
|
||||
difficulty: number;
|
||||
missionReward?: IMissionReward;
|
||||
levelOverride?: string;
|
||||
enemySpec?: string;
|
||||
extraEnemySpec?: string;
|
||||
customAdvancedSpawners?: string[];
|
||||
minEnemyLevel?: number;
|
||||
maxEnemyLevel?: number;
|
||||
maxWaveNum?: number;
|
||||
}
|
||||
|
||||
export interface IGoal {
|
||||
_id: IOid;
|
||||
Activation: IMongoDate;
|
||||
|
||||
@ -1232,6 +1232,27 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
<label class="form-label" data-loc="worldState_voidCorruption" data-loc-replace="2025"></label>
|
||||
<div class="d-flex flex-wrap gap-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="worldState.voidCorruption2025Week1" />
|
||||
<label class="form-check-label" for="worldState.voidCorruption2025Week1" data-loc="worldState_week" data-loc-replace="1"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="worldState.voidCorruption2025Week2" />
|
||||
<label class="form-check-label" for="worldState.voidCorruption2025Week2" data-loc="worldState_week" data-loc-replace="2"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="worldState.voidCorruption2025Week3" />
|
||||
<label class="form-check-label" for="worldState.voidCorruption2025Week3" data-loc="worldState_week" data-loc-replace="3"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="worldState.voidCorruption2025Week4" />
|
||||
<label class="form-check-label" for="worldState.voidCorruption2025Week4" data-loc="worldState_week" data-loc-replace="4"></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group mt-2">
|
||||
<label class="form-label" for="worldState.galleonOfGhouls" data-loc="worldState_galleonOfGhouls"></label>
|
||||
<abbr data-loc-inc="worldState_wolfHunt|worldState_anniversary|worldState_orphixVenom"><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>
|
||||
|
||||
@ -1771,7 +1771,7 @@ function updateInventory() {
|
||||
a.href = "#";
|
||||
a.onclick = function (event) {
|
||||
event.preventDefault();
|
||||
fundGuildTechProject(item.ItemType);
|
||||
debounce(fundGuildTechProject, item.ItemType);
|
||||
};
|
||||
a.title = loc("code_fund");
|
||||
a.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M214.6 17.4c-12.5-12.5-32.8-12.5-45.3 0l-160 160c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 117.3 160 488c0 17.7 14.3 32 32 32s32-14.3 32-32l0-370.7 105.4 105.4c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-160-160z"/></svg>`;
|
||||
@ -1788,7 +1788,7 @@ function updateInventory() {
|
||||
a.href = "#";
|
||||
a.onclick = function (event) {
|
||||
event.preventDefault();
|
||||
completeGuildTechProject(item.ItemType);
|
||||
debounce(completeGuildTechProject, item.ItemType);
|
||||
};
|
||||
a.title = loc("code_complete");
|
||||
a.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M371.7 43.1C360.1 32 343 28.9 328.3 35.2S304 56 304 72l0 136.3-172.3-165.1C120.1 32 103 28.9 88.3 35.2S64 56 64 72l0 368c0 16 9.6 30.5 24.3 36.8s31.8 3.2 43.4-7.9L304 303.7 304 440c0 16 9.6 30.5 24.3 36.8s31.8 3.2 43.4-7.9l192-184c7.9-7.5 12.3-18 12.3-28.9s-4.5-21.3-12.3-28.9l-192-184z"/></svg>`;
|
||||
@ -1801,7 +1801,7 @@ function updateInventory() {
|
||||
a.onclick = function (event) {
|
||||
event.preventDefault();
|
||||
reAddToItemList(itemMap, "TechProjects", item.ItemType);
|
||||
removeGuildTechProject(item.ItemType);
|
||||
debounce(removeGuildTechProject, item.ItemType);
|
||||
};
|
||||
a.title = loc("code_remove");
|
||||
a.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M135.2 17.7L128 32H32C14.3 32 0 46.3 0 64S14.3 96 32 96H416c17.7 0 32-14.3 32-32s-14.3-32-32-32H320l-7.2-14.3C307.4 6.8 296.3 0 284.2 0H163.8c-12.1 0-23.2 6.8-28.6 17.7zM416 128H32L53.2 467c1.6 25.3 22.6 45 47.9 45H346.9c25.3 0 46.3-19.7 47.9-45L416 128z"/></svg>`;
|
||||
@ -2844,8 +2844,8 @@ function removeCountItems(uniqueName, count) {
|
||||
|
||||
function addItemByItemType() {
|
||||
const ItemType = document.getElementById("typeName-type").value;
|
||||
// Must start with "/Lotus/", contain only A–Z letters, no "//", and not end with "/"
|
||||
if (!ItemType || !/^\/Lotus\/(?:[A-Za-z]+(?:\/[A-Za-z]+)*)$/.test(ItemType)) {
|
||||
// Must start with "/Lotus/", contain only letters A–Z, digits 0–9, no "//", and not end with "/"
|
||||
if (!ItemType || !/^\/Lotus\/(?:[A-Za-z0-9]+(?:\/[A-Za-z0-9]+)*)$/.test(ItemType)) {
|
||||
$("#typeName-type").addClass("is-invalid").focus();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -279,6 +279,7 @@ dict = {
|
||||
worldState_dogDays: `Hitzefrei`,
|
||||
worldState_dogDaysRewards: `[UNTRANSLATED] Dog Days Rewards`,
|
||||
worldState_wolfHunt: `Wolfsjagd (2025)`,
|
||||
worldState_voidCorruption: `[UNTRANSLATED] Void Corruption (|VAL|)`,
|
||||
worldState_orphixVenom: `Orphix Gift`,
|
||||
worldState_longShadow: `Lange Schatten`,
|
||||
worldState_hallowedFlame: `Geweihte Flamme`,
|
||||
|
||||
@ -278,6 +278,7 @@ dict = {
|
||||
worldState_dogDays: `Dog Days`,
|
||||
worldState_dogDaysRewards: `Dog Days Rewards`,
|
||||
worldState_wolfHunt: `Wolf Hunt (2025)`,
|
||||
worldState_voidCorruption: `Void Corruption (|VAL|)`,
|
||||
worldState_orphixVenom: `Orphix Venom`,
|
||||
worldState_longShadow: `Long Shadow`,
|
||||
worldState_hallowedFlame: `Hallowed Flame`,
|
||||
|
||||
@ -279,6 +279,7 @@ dict = {
|
||||
worldState_dogDays: `Canícula`,
|
||||
worldState_dogDaysRewards: `Recompensas de Canícula`,
|
||||
worldState_wolfHunt: `Cacería del Lobo (2025)`,
|
||||
worldState_voidCorruption: `Corrupción del Vacío (|VAL|)`,
|
||||
worldState_orphixVenom: `Veneno de Orphix`,
|
||||
worldState_longShadow: `Sombra Prolongada`,
|
||||
worldState_hallowedFlame: `Llama Sagrada`,
|
||||
|
||||
@ -279,6 +279,7 @@ dict = {
|
||||
worldState_dogDays: `Bataille d'Eau`,
|
||||
worldState_dogDaysRewards: `Récompenses de la Bataille d'Eau`,
|
||||
worldState_wolfHunt: `Chasse au Loup (2025)`,
|
||||
worldState_voidCorruption: `[UNTRANSLATED] Void Corruption (|VAL|)`,
|
||||
worldState_orphixVenom: `Venin Orphix`,
|
||||
worldState_longShadow: `La Propagation des Ombres`,
|
||||
worldState_hallowedFlame: `Flamme Hantée`,
|
||||
|
||||
@ -279,6 +279,7 @@ dict = {
|
||||
worldState_dogDays: `Знойные дни`,
|
||||
worldState_dogDaysRewards: `Награды Знойных дней`,
|
||||
worldState_wolfHunt: `Волчья Охота (2025)`,
|
||||
worldState_voidCorruption: `[UNTRANSLATED] Void Corruption (|VAL|)`,
|
||||
worldState_orphixVenom: `Яд Орфикса`,
|
||||
worldState_longShadow: `Длинная Тень`,
|
||||
worldState_hallowedFlame: `Священное пламя`,
|
||||
|
||||
@ -279,6 +279,7 @@ dict = {
|
||||
worldState_dogDays: `Спекотні дні`,
|
||||
worldState_dogDaysRewards: `Нагороди Спекотних днів`,
|
||||
worldState_wolfHunt: `Полювання на Вовка (2025)`,
|
||||
worldState_voidCorruption: `[UNTRANSLATED] Void Corruption (|VAL|)`,
|
||||
worldState_orphixVenom: `Орфіксова отрута`,
|
||||
worldState_longShadow: `Довга тінь`,
|
||||
worldState_hallowedFlame: `Священне полум'я`,
|
||||
|
||||
@ -279,6 +279,7 @@ dict = {
|
||||
worldState_dogDays: `三伏天`,
|
||||
worldState_dogDaysRewards: `三伏天奖励设置`,
|
||||
worldState_wolfHunt: `恶狼狩猎 (2025)`,
|
||||
worldState_voidCorruption: `[UNTRANSLATED] Void Corruption (|VAL|)`,
|
||||
worldState_orphixVenom: `奥影之毒`,
|
||||
worldState_longShadow: `暗夜长影`,
|
||||
worldState_hallowedFlame: `万圣之焰`,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user