feat: belly of the beast / eight claw (#2621)
Re #1103 Reviewed-on: OpenWF/SpaceNinjaServer#2621 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>
This commit is contained in:
		
							parent
							
								
									e345fc35b6
								
							
						
					
					
						commit
						bf04755c36
					
				@ -79,6 +79,10 @@
 | 
			
		||||
    "starDaysOverride": null,
 | 
			
		||||
    "dogDaysOverride": null,
 | 
			
		||||
    "dogDaysRewardsOverride": null,
 | 
			
		||||
    "bellyOfTheBeast": false,
 | 
			
		||||
    "bellyOfTheBeastProgressOverride": 0,
 | 
			
		||||
    "eightClaw": false,
 | 
			
		||||
    "eightClawProgressOverride": 0,
 | 
			
		||||
    "eidolonOverride": "",
 | 
			
		||||
    "vallisOverride": "",
 | 
			
		||||
    "duviriOverride": "",
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										25
									
								
								src/controllers/api/getGuildEventScore.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/controllers/api/getGuildEventScore.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,25 @@
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
import { getAccountForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { Guild } from "@/src/models/guildModel";
 | 
			
		||||
 | 
			
		||||
export const getGuildEventScoreController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const account = await getAccountForRequest(req);
 | 
			
		||||
    const inventory = await getInventory(account._id.toString(), "GuildId");
 | 
			
		||||
    const guild = await Guild.findById(inventory.GuildId);
 | 
			
		||||
    const goalId = req.query.goalId as string;
 | 
			
		||||
    if (guild && guild.GoalProgress && goalId) {
 | 
			
		||||
        const goal = guild.GoalProgress.find(x => x.goalId.toString() == goalId);
 | 
			
		||||
        if (goal) {
 | 
			
		||||
            return res.json({
 | 
			
		||||
                Tier: guild.Tier,
 | 
			
		||||
                GoalProgress: {
 | 
			
		||||
                    Count: goal.Count,
 | 
			
		||||
                    Tag: goal.Tag,
 | 
			
		||||
                    _id: { $oid: goal.goalId }
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return res.json({});
 | 
			
		||||
};
 | 
			
		||||
@ -19,6 +19,8 @@ import {
 | 
			
		||||
import { Document, Model, model, Schema, Types } from "mongoose";
 | 
			
		||||
import { fusionTreasuresSchema, typeCountSchema } from "@/src/models/inventoryModels/inventoryModel";
 | 
			
		||||
import { pictureFrameInfoSchema } from "@/src/models/personalRoomsModel";
 | 
			
		||||
import { IGoalProgressClient, IGoalProgressDatabase } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { toOid } from "@/src/helpers/inventoryHelpers";
 | 
			
		||||
 | 
			
		||||
const dojoDecoSchema = new Schema<IDojoDecoDatabase>({
 | 
			
		||||
    Type: String,
 | 
			
		||||
@ -174,6 +176,28 @@ const guildLogEntryNumberSchema = new Schema<IGuildLogEntryNumber>(
 | 
			
		||||
    { _id: false }
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const goalProgressSchema = new Schema<IGoalProgressDatabase>(
 | 
			
		||||
    {
 | 
			
		||||
        Count: Number,
 | 
			
		||||
        Tag: String,
 | 
			
		||||
        goalId: Types.ObjectId
 | 
			
		||||
    },
 | 
			
		||||
    { _id: false }
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
goalProgressSchema.set("toJSON", {
 | 
			
		||||
    virtuals: true,
 | 
			
		||||
    transform(_doc, obj: Record<string, any>) {
 | 
			
		||||
        const db = obj as IGoalProgressDatabase;
 | 
			
		||||
        const client = obj as IGoalProgressClient;
 | 
			
		||||
 | 
			
		||||
        client._id = toOid(db.goalId);
 | 
			
		||||
 | 
			
		||||
        delete obj.goalId;
 | 
			
		||||
        delete obj.__v;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const guildSchema = new Schema<IGuildDatabase>(
 | 
			
		||||
    {
 | 
			
		||||
        Name: { type: String, required: true, unique: true },
 | 
			
		||||
@ -206,7 +230,8 @@ const guildSchema = new Schema<IGuildDatabase>(
 | 
			
		||||
        RoomChanges: { type: [guildLogRoomChangeSchema], default: undefined },
 | 
			
		||||
        TechChanges: { type: [guildLogEntryContributableSchema], default: undefined },
 | 
			
		||||
        RosterActivity: { type: [guildLogEntryRosterSchema], default: undefined },
 | 
			
		||||
        ClassChanges: { type: [guildLogEntryNumberSchema], default: undefined }
 | 
			
		||||
        ClassChanges: { type: [guildLogEntryNumberSchema], default: undefined },
 | 
			
		||||
        GoalProgress: { type: [goalProgressSchema], default: undefined }
 | 
			
		||||
    },
 | 
			
		||||
    { id: false }
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
@ -85,8 +85,8 @@ import {
 | 
			
		||||
    IAccolades,
 | 
			
		||||
    IHubNpcCustomization,
 | 
			
		||||
    IEndlessXpReward,
 | 
			
		||||
    IPersonalGoalProgressDatabase,
 | 
			
		||||
    IPersonalGoalProgressClient,
 | 
			
		||||
    IGoalProgressDatabase,
 | 
			
		||||
    IGoalProgressClient,
 | 
			
		||||
    IKubrowPetPrintClient,
 | 
			
		||||
    IKubrowPetPrintDatabase
 | 
			
		||||
} from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
@ -445,7 +445,7 @@ const discoveredMarkerSchema = new Schema<IDiscoveredMarker>(
 | 
			
		||||
    { _id: false }
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const personalGoalProgressSchema = new Schema<IPersonalGoalProgressDatabase>(
 | 
			
		||||
const personalGoalProgressSchema = new Schema<IGoalProgressDatabase>(
 | 
			
		||||
    {
 | 
			
		||||
        Best: Number,
 | 
			
		||||
        Count: Number,
 | 
			
		||||
@ -458,8 +458,8 @@ const personalGoalProgressSchema = new Schema<IPersonalGoalProgressDatabase>(
 | 
			
		||||
personalGoalProgressSchema.set("toJSON", {
 | 
			
		||||
    virtuals: true,
 | 
			
		||||
    transform(_doc, obj: Record<string, any>) {
 | 
			
		||||
        const db = obj as IPersonalGoalProgressDatabase;
 | 
			
		||||
        const client = obj as IPersonalGoalProgressClient;
 | 
			
		||||
        const db = obj as IGoalProgressDatabase;
 | 
			
		||||
        const client = obj as IGoalProgressClient;
 | 
			
		||||
 | 
			
		||||
        client._id = toOid(db.goalId);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -62,6 +62,7 @@ import { getFriendsController } from "@/src/controllers/api/getFriendsController
 | 
			
		||||
import { getGuildContributionsController } from "@/src/controllers/api/getGuildContributionsController";
 | 
			
		||||
import { getGuildController } from "@/src/controllers/api/getGuildController";
 | 
			
		||||
import { getGuildDojoController } from "@/src/controllers/api/getGuildDojoController";
 | 
			
		||||
import { getGuildEventScoreController } from "@/src/controllers/api/getGuildEventScore";
 | 
			
		||||
import { getGuildLogController } from "@/src/controllers/api/getGuildLogController";
 | 
			
		||||
import { getIgnoredUsersController } from "@/src/controllers/api/getIgnoredUsersController";
 | 
			
		||||
import { getNewRewardSeedController } from "@/src/controllers/api/getNewRewardSeedController";
 | 
			
		||||
@ -192,6 +193,7 @@ apiRouter.get("/getFriends.php", getFriendsController);
 | 
			
		||||
apiRouter.get("/getGuild.php", getGuildController);
 | 
			
		||||
apiRouter.get("/getGuildContributions.php", getGuildContributionsController);
 | 
			
		||||
apiRouter.get("/getGuildDojo.php", getGuildDojoController);
 | 
			
		||||
apiRouter.get("/getGuildEventScore.php", getGuildEventScoreController);
 | 
			
		||||
apiRouter.get("/getGuildLog.php", getGuildLogController);
 | 
			
		||||
apiRouter.get("/getIgnoredUsers.php", getIgnoredUsersController);
 | 
			
		||||
apiRouter.get("/getMessages.php", inboxController); // unsure if this is correct, but needed for U17
 | 
			
		||||
 | 
			
		||||
@ -91,6 +91,10 @@ export interface IConfig {
 | 
			
		||||
        starDaysOverride?: boolean;
 | 
			
		||||
        dogDaysOverride?: boolean;
 | 
			
		||||
        dogDaysRewardsOverride?: number;
 | 
			
		||||
        bellyOfTheBeast?: boolean;
 | 
			
		||||
        bellyOfTheBeastProgressOverride?: number;
 | 
			
		||||
        eightClaw?: boolean;
 | 
			
		||||
        eightClawProgressOverride?: number;
 | 
			
		||||
        eidolonOverride?: string;
 | 
			
		||||
        vallisOverride?: string;
 | 
			
		||||
        duviriOverride?: string;
 | 
			
		||||
 | 
			
		||||
@ -115,7 +115,14 @@ export const getGuildClient = async (
 | 
			
		||||
        NumContributors: guild.CeremonyContributors?.length ?? 0,
 | 
			
		||||
        CeremonyResetDate: guild.CeremonyResetDate ? toMongoDate(guild.CeremonyResetDate) : undefined,
 | 
			
		||||
        AutoContributeFromVault: guild.AutoContributeFromVault,
 | 
			
		||||
        AllianceId: guild.AllianceId ? toOid2(guild.AllianceId, account.BuildLabel) : undefined
 | 
			
		||||
        AllianceId: guild.AllianceId ? toOid2(guild.AllianceId, account.BuildLabel) : undefined,
 | 
			
		||||
        GoalProgress: guild.GoalProgress
 | 
			
		||||
            ? guild.GoalProgress.map(gp => ({
 | 
			
		||||
                  Count: gp.Count,
 | 
			
		||||
                  Tag: gp.Tag,
 | 
			
		||||
                  _id: { $oid: gp.goalId.toString() }
 | 
			
		||||
              }))
 | 
			
		||||
            : undefined
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -809,3 +816,85 @@ export const getAllianceClient = async (
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const handleGuildGoalProgress = async (
 | 
			
		||||
    guild: TGuildDatabaseDocument,
 | 
			
		||||
    upload: { Count: number; Tag: string; goalId: Types.ObjectId }
 | 
			
		||||
): Promise<void> => {
 | 
			
		||||
    guild.GoalProgress ??= [];
 | 
			
		||||
    const goalProgress = guild.GoalProgress.find(x => x.goalId.equals(upload.goalId));
 | 
			
		||||
    if (!goalProgress) {
 | 
			
		||||
        guild.GoalProgress.push({
 | 
			
		||||
            Count: upload.Count,
 | 
			
		||||
            Tag: upload.Tag,
 | 
			
		||||
            goalId: upload.goalId
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    const totalCount = (goalProgress?.Count ?? 0) + upload.Count;
 | 
			
		||||
    const guildRewards = goalGuildRewardByTag[upload.Tag].rewards;
 | 
			
		||||
    const tierGoals = goalGuildRewardByTag[upload.Tag].guildGoals[guild.Tier - 1];
 | 
			
		||||
    const rewards = [];
 | 
			
		||||
    if (tierGoals.length && guildRewards.length) {
 | 
			
		||||
        for (let i = 0; i < tierGoals.length; i++) {
 | 
			
		||||
            if (
 | 
			
		||||
                tierGoals[i] &&
 | 
			
		||||
                tierGoals[i] <= totalCount &&
 | 
			
		||||
                (!goalProgress || goalProgress.Count < tierGoals[i]) &&
 | 
			
		||||
                guildRewards[i]
 | 
			
		||||
            ) {
 | 
			
		||||
                rewards.push(guildRewards[i]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (rewards.length) {
 | 
			
		||||
            logger.debug(`guild goal rewards`, rewards);
 | 
			
		||||
            guild.VaultDecoRecipes ??= [];
 | 
			
		||||
            rewards.forEach(type => {
 | 
			
		||||
                guild.VaultDecoRecipes!.push({
 | 
			
		||||
                    ItemType: type,
 | 
			
		||||
                    ItemCount: 1
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (goalProgress) {
 | 
			
		||||
        goalProgress.Count += upload.Count;
 | 
			
		||||
    }
 | 
			
		||||
    await guild.save();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const goalGuildRewardByTag: Record<string, { guildGoals: number[][]; rewards: string[] }> = {
 | 
			
		||||
    JadeShadowsEvent: {
 | 
			
		||||
        guildGoals: [
 | 
			
		||||
            // I don't know what ClanGoal means
 | 
			
		||||
            [15, 30, 45, 60],
 | 
			
		||||
            [45, 90, 135, 180],
 | 
			
		||||
            [150, 300, 450, 600],
 | 
			
		||||
            [450, 900, 1350, 1800],
 | 
			
		||||
            [1500, 3000, 4500, 6000]
 | 
			
		||||
        ],
 | 
			
		||||
        rewards: [
 | 
			
		||||
            "/Lotus/Levels/ClanDojo/ComponentPropRecipes/JadeShadowsEventPewterTrophyRecipe",
 | 
			
		||||
            "/Lotus/Levels/ClanDojo/ComponentPropRecipes/JadeShadowsEventBronzeTrophyRecipe",
 | 
			
		||||
            "/Lotus/Levels/ClanDojo/ComponentPropRecipes/JadeShadowsEventSilverTrophyRecipe",
 | 
			
		||||
            "/Lotus/Levels/ClanDojo/ComponentPropRecipes/JadeShadowsEventGoldTrophyRecipe"
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    DuviriMurmurEvent: {
 | 
			
		||||
        guildGoals: [
 | 
			
		||||
            // I don't know what ClanGoal means
 | 
			
		||||
            [260, 519, 779, 1038],
 | 
			
		||||
            [779, 1557, 2336, 3114],
 | 
			
		||||
            [2595, 5190, 7785, 10380],
 | 
			
		||||
            [7785, 15570, 23355, 31140],
 | 
			
		||||
            [29950, 51900, 77850, 103800]
 | 
			
		||||
        ],
 | 
			
		||||
        rewards: [
 | 
			
		||||
            "/Lotus/Levels/ClanDojo/ComponentPropRecipes/DuviriMurmurEventClayTrophyRecipe",
 | 
			
		||||
            "/Lotus/Levels/ClanDojo/ComponentPropRecipes/DuviriMurmurEventBronzeTrophyRecipe",
 | 
			
		||||
            "/Lotus/Levels/ClanDojo/ComponentPropRecipes/DuviriMurmurEventSilverTrophyRecipe",
 | 
			
		||||
            "/Lotus/Levels/ClanDojo/ComponentPropRecipes/DuviriMurmurEventGoldTrophyRecipe"
 | 
			
		||||
        ]
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -81,6 +81,8 @@ import { fromOid } from "@/src/helpers/inventoryHelpers";
 | 
			
		||||
import { TAccountDocument } from "@/src/services/loginService";
 | 
			
		||||
import { ITypeCount } from "@/src/types/commonTypes";
 | 
			
		||||
import { IEquipmentClient } from "@/src/types/equipmentTypes";
 | 
			
		||||
import { Guild } from "@/src/models/guildModel";
 | 
			
		||||
import { handleGuildGoalProgress } from "@/src/services/guildService";
 | 
			
		||||
 | 
			
		||||
const getRotations = (rewardInfo: IRewardInfo, tierOverride?: number): number[] => {
 | 
			
		||||
    // Disruption missions just tell us (https://onlyg.it/OpenWF/SpaceNinjaServer/issues/2599)
 | 
			
		||||
@ -712,10 +714,20 @@ export const addMissionInventoryUpdates = async (
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (goalProgress) {
 | 
			
		||||
                            goalProgress.Best = Math.max(goalProgress.Best, uploadProgress.Best);
 | 
			
		||||
                            goalProgress.Best = Math.max(goalProgress.Best!, uploadProgress.Best);
 | 
			
		||||
                            goalProgress.Count += uploadProgress.Count;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    if (goal && goal.ClanGoal && inventory.GuildId) {
 | 
			
		||||
                        const guild = await Guild.findById(inventory.GuildId, "GoalProgress Tier VaultDecoRecipes");
 | 
			
		||||
                        if (guild) {
 | 
			
		||||
                            await handleGuildGoalProgress(guild, {
 | 
			
		||||
                                Count: uploadProgress.Count,
 | 
			
		||||
                                Tag: goal.Tag,
 | 
			
		||||
                                goalId: new Types.ObjectId(goal._id.$oid)
 | 
			
		||||
                            });
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -36,6 +36,9 @@ import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/invento
 | 
			
		||||
import { fromStoreItem, toStoreItem } from "@/src/services/itemDataService";
 | 
			
		||||
import { DailyDeal } from "@/src/models/worldStateModel";
 | 
			
		||||
import { fromMongoDate, toMongoDate } from "@/src/helpers/inventoryHelpers";
 | 
			
		||||
import { Guild } from "@/src/models/guildModel";
 | 
			
		||||
import { handleGuildGoalProgress } from "@/src/services/guildService";
 | 
			
		||||
import { Types } from "mongoose";
 | 
			
		||||
 | 
			
		||||
export const getStoreItemCategory = (storeItem: string): string => {
 | 
			
		||||
    const storeItemString = getSubstringFromKeyword(storeItem, "StoreItems/");
 | 
			
		||||
@ -137,6 +140,22 @@ export const handlePurchase = async (
 | 
			
		||||
                    updateCurrency(inventory, offer.PremiumPrice[0], true, prePurchaseInventoryChanges);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (
 | 
			
		||||
                inventory.GuildId &&
 | 
			
		||||
                offer.ItemPrices &&
 | 
			
		||||
                manifest.VendorInfo.TypeName ==
 | 
			
		||||
                    "/Lotus/Types/Game/VendorManifests/Events/DuviriMurmurInvasionVendorManifest"
 | 
			
		||||
            ) {
 | 
			
		||||
                const guild = await Guild.findById(inventory.GuildId, "GoalProgress Tier VaultDecoRecipes");
 | 
			
		||||
                const goal = getWorldState().Goals.find(x => x.Tag == "DuviriMurmurEvent");
 | 
			
		||||
                if (guild && goal) {
 | 
			
		||||
                    await handleGuildGoalProgress(guild, {
 | 
			
		||||
                        Count: offer.ItemPrices[0].ItemCount * purchaseRequest.PurchaseParams.Quantity,
 | 
			
		||||
                        Tag: goal.Tag,
 | 
			
		||||
                        goalId: new Types.ObjectId(goal._id.$oid)
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (!config.dontSubtractPurchaseItemCost) {
 | 
			
		||||
                if (offer.ItemPrices) {
 | 
			
		||||
                    handleItemPrices(
 | 
			
		||||
 | 
			
		||||
@ -2265,6 +2265,49 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
 | 
			
		||||
            BonusReward: { items: ["/Lotus/StoreItems/Upgrades/Skins/Clan/BountyHunterBadgeItem"] }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    if (config.worldState?.bellyOfTheBeast) {
 | 
			
		||||
        worldState.Goals.push({
 | 
			
		||||
            _id: { $oid: "67a5035c2a198564d62e165e" },
 | 
			
		||||
            Activation: { $date: { $numberLong: "1738868400000" } },
 | 
			
		||||
            Expiry: { $date: { $numberLong: "2000000000000" } },
 | 
			
		||||
            Count: config.worldState.bellyOfTheBeastProgressOverride ?? 0,
 | 
			
		||||
            HealthPct: (config.worldState.bellyOfTheBeastProgressOverride ?? 0) / 100,
 | 
			
		||||
            Goal: 0,
 | 
			
		||||
            Personal: true,
 | 
			
		||||
            Community: true,
 | 
			
		||||
            ClanGoal: [72, 216, 648, 1944, 5832],
 | 
			
		||||
            Tag: "JadeShadowsEvent",
 | 
			
		||||
            Faction: "FC_MITW",
 | 
			
		||||
            Desc: "/Lotus/Language/JadeShadows/JadeShadowsEventName",
 | 
			
		||||
            ToolTip: "/Lotus/Language/JadeShadows/JadeShadowsShortEventDesc",
 | 
			
		||||
            Icon: "/Lotus/Interface/Icons/WorldStatePanel/JadeShadowsEventBadge.png",
 | 
			
		||||
            ScoreLocTag: "/Lotus/Language/JadeShadows/JadeShadowsEventScore",
 | 
			
		||||
            Node: "SolNode723",
 | 
			
		||||
            MissionKeyName: "/Lotus/Types/Keys/JadeShadowsEventMission",
 | 
			
		||||
            ItemType: "/Lotus/Types/Gameplay/JadeShadows/Resources/AscensionEventResourceItem"
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    if (config.worldState?.eightClaw) {
 | 
			
		||||
        worldState.Goals.push({
 | 
			
		||||
            _id: { $oid: "685c15f80000000000000000" },
 | 
			
		||||
            Activation: { $date: { $numberLong: "1750865400000" } },
 | 
			
		||||
            Expiry: { $date: { $numberLong: "2000000000000" } },
 | 
			
		||||
            Count: config.worldState.eightClawProgressOverride ?? 0,
 | 
			
		||||
            HealthPct: (config.worldState.eightClawProgressOverride ?? 0) / 100,
 | 
			
		||||
            Goal: 0,
 | 
			
		||||
            Personal: true,
 | 
			
		||||
            Community: true,
 | 
			
		||||
            ClanGoal: [72, 216, 648, 1944, 5832],
 | 
			
		||||
            Tag: "DuviriMurmurEvent",
 | 
			
		||||
            Faction: "FC_MITW",
 | 
			
		||||
            Desc: "/Lotus/Language/Isleweaver/DuviriMurmurEventTitle",
 | 
			
		||||
            ToolTip: "/Lotus/Language/Isleweaver/DuviriMurmurEventDescription",
 | 
			
		||||
            Icon: "/Lotus/Interface/Icons/WorldStatePanel/EightClawEventBadge.png",
 | 
			
		||||
            ScoreLocTag: "/Lotus/Language/Isleweaver/DuviriMurmurEventScore",
 | 
			
		||||
            Node: "SolNode236",
 | 
			
		||||
            MissionKeyName: "/Lotus/Types/Keys/DuviriMITW/DuviriMITWEventKey"
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Nightwave Challenges
 | 
			
		||||
    const nightwaveSyndicateTag = getNightwaveSyndicateTag(buildLabel);
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,11 @@
 | 
			
		||||
import { Types } from "mongoose";
 | 
			
		||||
import { IOid, IMongoDate, IOidWithLegacySupport, ITypeCount } from "@/src/types/commonTypes";
 | 
			
		||||
import { IFusionTreasure, IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import {
 | 
			
		||||
    IFusionTreasure,
 | 
			
		||||
    IMiscItem,
 | 
			
		||||
    IGoalProgressDatabase,
 | 
			
		||||
    IGoalProgressClient
 | 
			
		||||
} from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { IPictureFrameInfo } from "@/src/types/personalRoomsTypes";
 | 
			
		||||
import { IFriendInfo } from "@/src/types/friendTypes";
 | 
			
		||||
 | 
			
		||||
@ -23,6 +28,8 @@ export interface IGuildClient {
 | 
			
		||||
    CrossPlatformEnabled?: boolean;
 | 
			
		||||
    AutoContributeFromVault?: boolean;
 | 
			
		||||
    AllianceId?: IOidWithLegacySupport;
 | 
			
		||||
 | 
			
		||||
    GoalProgress?: IGoalProgressClient[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IGuildDatabase {
 | 
			
		||||
@ -63,6 +70,8 @@ export interface IGuildDatabase {
 | 
			
		||||
    TechChanges?: IGuildLogEntryContributable[];
 | 
			
		||||
    RosterActivity?: IGuildLogEntryRoster[];
 | 
			
		||||
    ClassChanges?: IGuildLogEntryNumber[];
 | 
			
		||||
 | 
			
		||||
    GoalProgress?: IGoalProgressDatabase[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ILongMOTD {
 | 
			
		||||
 | 
			
		||||
@ -109,7 +109,7 @@ export interface IInventoryDatabase
 | 
			
		||||
    QualifyingInvasions: IInvasionProgressDatabase[];
 | 
			
		||||
    LastInventorySync?: Types.ObjectId;
 | 
			
		||||
    EndlessXP?: IEndlessXpProgressDatabase[];
 | 
			
		||||
    PersonalGoalProgress?: IPersonalGoalProgressDatabase[];
 | 
			
		||||
    PersonalGoalProgress?: IGoalProgressDatabase[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IQuestKeyDatabase {
 | 
			
		||||
@ -318,7 +318,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
 | 
			
		||||
    HWIDProtectEnabled?: boolean;
 | 
			
		||||
    KubrowPetPrints: IKubrowPetPrintClient[];
 | 
			
		||||
    AlignmentReplay?: IAlignment;
 | 
			
		||||
    PersonalGoalProgress?: IPersonalGoalProgressClient[];
 | 
			
		||||
    PersonalGoalProgress?: IGoalProgressClient[];
 | 
			
		||||
    ThemeStyle: string;
 | 
			
		||||
    ThemeBackground: string;
 | 
			
		||||
    ThemeSounds: string;
 | 
			
		||||
@ -895,8 +895,8 @@ export interface IPeriodicMissionCompletionResponse extends Omit<IPeriodicMissio
 | 
			
		||||
    date: IMongoDate;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IPersonalGoalProgressClient {
 | 
			
		||||
    Best: number;
 | 
			
		||||
export interface IGoalProgressClient {
 | 
			
		||||
    Best?: number;
 | 
			
		||||
    Count: number;
 | 
			
		||||
    Tag: string;
 | 
			
		||||
    _id: IOid;
 | 
			
		||||
@ -904,7 +904,7 @@ export interface IPersonalGoalProgressClient {
 | 
			
		||||
    //ReceivedClanReward1?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IPersonalGoalProgressDatabase extends Omit<IPersonalGoalProgressClient, "_id"> {
 | 
			
		||||
export interface IGoalProgressDatabase extends Omit<IGoalProgressClient, "_id"> {
 | 
			
		||||
    goalId: Types.ObjectId;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -39,32 +39,44 @@ export interface IGoal {
 | 
			
		||||
    _id: IOid;
 | 
			
		||||
    Activation: IMongoDate;
 | 
			
		||||
    Expiry: IMongoDate;
 | 
			
		||||
 | 
			
		||||
    Count?: number;
 | 
			
		||||
    HealthPct?: number;
 | 
			
		||||
 | 
			
		||||
    Icon: string;
 | 
			
		||||
    Desc: string;
 | 
			
		||||
    ToolTip?: string;
 | 
			
		||||
    Faction?: string;
 | 
			
		||||
 | 
			
		||||
    Goal?: number;
 | 
			
		||||
    InterimGoals?: number[];
 | 
			
		||||
    BonusGoal?: number;
 | 
			
		||||
    HealthPct?: number;
 | 
			
		||||
    ClanGoal?: number[];
 | 
			
		||||
 | 
			
		||||
    Success?: number;
 | 
			
		||||
    Personal?: boolean;
 | 
			
		||||
    Best?: boolean;
 | 
			
		||||
    Community?: boolean;
 | 
			
		||||
    Best?: boolean; // Fist one on Event Tab
 | 
			
		||||
    Bounty?: boolean; // Tactical Alert
 | 
			
		||||
    Faction?: string;
 | 
			
		||||
    ClampNodeScores?: boolean;
 | 
			
		||||
    Desc: string;
 | 
			
		||||
    ToolTip?: string;
 | 
			
		||||
 | 
			
		||||
    Transmission?: string;
 | 
			
		||||
    InstructionalItem?: string;
 | 
			
		||||
    Icon: string;
 | 
			
		||||
    ItemType?: string;
 | 
			
		||||
 | 
			
		||||
    Tag: string;
 | 
			
		||||
    PrereqGoalTags?: string[];
 | 
			
		||||
 | 
			
		||||
    Node?: string;
 | 
			
		||||
    VictimNode?: string;
 | 
			
		||||
 | 
			
		||||
    ConcurrentMissionKeyNames?: string[];
 | 
			
		||||
    ConcurrentNodeReqs?: number[];
 | 
			
		||||
    ConcurrentNodes?: string[];
 | 
			
		||||
    RegionIdx?: number;
 | 
			
		||||
    Regions?: number[];
 | 
			
		||||
    MissionKeyName?: string;
 | 
			
		||||
 | 
			
		||||
    Reward?: IMissionReward;
 | 
			
		||||
    InterimRewards?: IMissionReward[];
 | 
			
		||||
    BonusReward?: IMissionReward;
 | 
			
		||||
@ -77,6 +89,8 @@ export interface IGoal {
 | 
			
		||||
 | 
			
		||||
    ScoreVar?: string;
 | 
			
		||||
    ScoreMaxTag?: string;
 | 
			
		||||
    ScoreLocTag?: string;
 | 
			
		||||
 | 
			
		||||
    NightLevel?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1040,6 +1040,32 @@
 | 
			
		||||
                                        </select>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                </div>
 | 
			
		||||
                                <div class="form-group mt-2 d-flex gap-2">
 | 
			
		||||
                                    <div class="flex-fill">
 | 
			
		||||
                                        <label class="form-label" for="worldState.bellyOfTheBeast" data-loc="worldState_bellyOfTheBeast"></label>
 | 
			
		||||
                                        <select class="form-control" id="worldState.bellyOfTheBeast" data-default="false">
 | 
			
		||||
                                            <option value="true" data-loc="enabled"></option>
 | 
			
		||||
                                            <option value="false" data-loc="disabled"></option>
 | 
			
		||||
                                        </select>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                    <div class="flex-fill">
 | 
			
		||||
                                        <label class="form-label" for="worldState.bellyOfTheBeastProgressOverride" data-loc="worldState_bellyOfTheBeastProgressOverride"></label>
 | 
			
		||||
                                        <input id="worldState.bellyOfTheBeastProgressOverride" class="form-control" type="number" min="0" max="100" data-default="0" />
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                </div>
 | 
			
		||||
                                <div class="form-group mt-2 d-flex gap-2">
 | 
			
		||||
                                    <div class="flex-fill">
 | 
			
		||||
                                        <label class="form-label" for="worldState.eightClaw" data-loc="worldState_eightClaw"></label>
 | 
			
		||||
                                        <select class="form-control" id="worldState.eightClaw" data-default="false">
 | 
			
		||||
                                            <option value="true" data-loc="enabled"></option>
 | 
			
		||||
                                            <option value="false" data-loc="disabled"></option>
 | 
			
		||||
                                        </select>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                    <div class="flex-fill">
 | 
			
		||||
                                        <label class="form-label" for="worldState.eightClawProgressOverride" data-loc="worldState_eightClawProgressOverride"></label>
 | 
			
		||||
                                        <input id="worldState.eightClawProgressOverride" class="form-control" type="number" min="0" max="100" data-default="0" />
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                </div>
 | 
			
		||||
                                <div class="form-group mt-2">
 | 
			
		||||
                                    <label class="form-label" for="worldState.eidolonOverride" data-loc="worldState_eidolonOverride"></label>
 | 
			
		||||
                                    <select class="form-control" id="worldState.eidolonOverride" data-default="">
 | 
			
		||||
 | 
			
		||||
@ -257,6 +257,10 @@ dict = {
 | 
			
		||||
    worldState_hallowedNightmaresRewards: `[UNTRANSLATED] Hallowed Nightmares Rewards`,
 | 
			
		||||
    worldState_proxyRebellion: `Proxy-Rebellion`,
 | 
			
		||||
    worldState_proxyRebellionRewards: `[UNTRANSLATED] Proxy Rebellion Rewards`,
 | 
			
		||||
    worldState_bellyOfTheBeast: `Das Innere der Bestie`,
 | 
			
		||||
    worldState_bellyOfTheBeastProgressOverride: `[UNTRANSLATED] Belly of the Beast Progress`,
 | 
			
		||||
    worldState_eightClaw: `Acht Klauen`,
 | 
			
		||||
    worldState_eightClawProgressOverride: `[UNTRANSLATED] Eight Claw Progress`,
 | 
			
		||||
    worldState_from_year: `[UNTRANSLATED] from |YEAR|`,
 | 
			
		||||
    worldState_pre_year: `[UNTRANSLATED] pre |YEAR|`,
 | 
			
		||||
    worldState_incompatibleWith: `[UNTRANSLATED] Incompatible with:`,
 | 
			
		||||
 | 
			
		||||
@ -256,6 +256,10 @@ dict = {
 | 
			
		||||
    worldState_hallowedNightmaresRewards: `Hallowed Nightmares Rewards`,
 | 
			
		||||
    worldState_proxyRebellion: `Proxy Rebellion`,
 | 
			
		||||
    worldState_proxyRebellionRewards: `Proxy Rebellion Rewards`,
 | 
			
		||||
    worldState_bellyOfTheBeast: `Belly of the Beast`,
 | 
			
		||||
    worldState_bellyOfTheBeastProgressOverride: `Belly of the Beast Progress`,
 | 
			
		||||
    worldState_eightClaw: `Eight Claw`,
 | 
			
		||||
    worldState_eightClawProgressOverride: `Eight Claw Progress`,
 | 
			
		||||
    worldState_from_year: `from |YEAR|`,
 | 
			
		||||
    worldState_pre_year: `pre |YEAR|`,
 | 
			
		||||
    worldState_incompatibleWith: `Incompatible with:`,
 | 
			
		||||
 | 
			
		||||
@ -257,6 +257,10 @@ dict = {
 | 
			
		||||
    worldState_hallowedNightmaresRewards: `Recompensas de Pesadillas Sagradas`,
 | 
			
		||||
    worldState_proxyRebellion: `Rebelión Proxy`,
 | 
			
		||||
    worldState_proxyRebellionRewards: `Recompensas de Rebelión Proxy`,
 | 
			
		||||
    worldState_bellyOfTheBeast: `Vientre de la Bestia`,
 | 
			
		||||
    worldState_bellyOfTheBeastProgressOverride: `[UNTRANSLATED] Belly of the Beast Progress`,
 | 
			
		||||
    worldState_eightClaw: `Octava Garra`,
 | 
			
		||||
    worldState_eightClawProgressOverride: `[UNTRANSLATED] Eight Claw Progress`,
 | 
			
		||||
    worldState_from_year: `de |YEAR|`,
 | 
			
		||||
    worldState_pre_year: `antes de |YEAR|`,
 | 
			
		||||
    worldState_incompatibleWith: `No compatible con:`,
 | 
			
		||||
 | 
			
		||||
@ -257,6 +257,10 @@ dict = {
 | 
			
		||||
    worldState_hallowedNightmaresRewards: `[UNTRANSLATED] Hallowed Nightmares Rewards`,
 | 
			
		||||
    worldState_proxyRebellion: `Rébellion Proxy`,
 | 
			
		||||
    worldState_proxyRebellionRewards: `[UNTRANSLATED] Proxy Rebellion Rewards`,
 | 
			
		||||
    worldState_bellyOfTheBeast: `Ventre de la Bête`,
 | 
			
		||||
    worldState_bellyOfTheBeastProgressOverride: `[UNTRANSLATED] Belly of the Beast Progress`,
 | 
			
		||||
    worldState_eightClaw: `Huitième Griffe`,
 | 
			
		||||
    worldState_eightClawProgressOverride: `[UNTRANSLATED] Eight Claw Progress`,
 | 
			
		||||
    worldState_from_year: `[UNTRANSLATED] from |YEAR|`,
 | 
			
		||||
    worldState_pre_year: `[UNTRANSLATED] pre |YEAR|`,
 | 
			
		||||
    worldState_incompatibleWith: `[UNTRANSLATED] Incompatible with:`,
 | 
			
		||||
 | 
			
		||||
@ -257,6 +257,10 @@ dict = {
 | 
			
		||||
    worldState_hallowedNightmaresRewards: `Награды Священных Кошмаров`,
 | 
			
		||||
    worldState_proxyRebellion: `Восстание Роботов`,
 | 
			
		||||
    worldState_proxyRebellionRewards: `Награды Восстания Роботов`,
 | 
			
		||||
    worldState_bellyOfTheBeast: `Чрево зверя`,
 | 
			
		||||
    worldState_bellyOfTheBeastProgressOverride: `Прогресс Чрева зверя`,
 | 
			
		||||
    worldState_eightClaw: `Восемь Когтей`,
 | 
			
		||||
    worldState_eightClawProgressOverride: `Прогресс Восьми Когтей`,
 | 
			
		||||
    worldState_from_year: `из |YEAR|`,
 | 
			
		||||
    worldState_pre_year: `до |YEAR|`,
 | 
			
		||||
    worldState_incompatibleWith: `Несовместимо с:`,
 | 
			
		||||
 | 
			
		||||
@ -257,6 +257,10 @@ dict = {
 | 
			
		||||
    worldState_hallowedNightmaresRewards: `Нагороди Священних Жахіть`,
 | 
			
		||||
    worldState_proxyRebellion: `Повстання роботів`,
 | 
			
		||||
    worldState_proxyRebellionRewards: `Нагороди Повстання роботів`,
 | 
			
		||||
    worldState_bellyOfTheBeast: `У лігві звіра`,
 | 
			
		||||
    worldState_bellyOfTheBeastProgressOverride: `[UNTRANSLATED] Belly of the Beast Progress`,
 | 
			
		||||
    worldState_eightClaw: `Вісім кігтів`,
 | 
			
		||||
    worldState_eightClawProgressOverride: `[UNTRANSLATED] Eight Claw Progress`,
 | 
			
		||||
    worldState_from_year: `з |YEAR|`,
 | 
			
		||||
    worldState_pre_year: `до |YEAR|`,
 | 
			
		||||
    worldState_incompatibleWith: `Несумісне з:`,
 | 
			
		||||
 | 
			
		||||
@ -257,6 +257,10 @@ dict = {
 | 
			
		||||
    worldState_hallowedNightmaresRewards: `[UNTRANSLATED] Hallowed Nightmares Rewards`,
 | 
			
		||||
    worldState_proxyRebellion: `机械叛乱`,
 | 
			
		||||
    worldState_proxyRebellionRewards: `[UNTRANSLATED] Proxy Rebellion Rewards`,
 | 
			
		||||
    worldState_bellyOfTheBeast: `兽之腹`,
 | 
			
		||||
    worldState_bellyOfTheBeastProgressOverride: `[UNTRANSLATED] Belly of the Beast Progress`,
 | 
			
		||||
    worldState_eightClaw: `八爪`,
 | 
			
		||||
    worldState_eightClawProgressOverride: `[UNTRANSLATED] Eight Claw Progress`,
 | 
			
		||||
    worldState_from_year: `[UNTRANSLATED] from |YEAR|`,
 | 
			
		||||
    worldState_pre_year: `[UNTRANSLATED] pre |YEAR|`,
 | 
			
		||||
    worldState_incompatibleWith: `[UNTRANSLATED] Incompatible with:`,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user