Compare commits
12 Commits
c7034b5e6d
...
cf68201ce5
Author | SHA1 | Date | |
---|---|---|---|
cf68201ce5 | |||
5d81e03e1a | |||
3165d9f459 | |||
28d7ca8ca0 | |||
3f0a2bec48 | |||
d28437b658 | |||
a6d2c8b18a | |||
0c884576bd | |||
380f0662a4 | |||
bd83738168 | |||
fa68a1357d | |||
43f3917b09 |
@ -1,14 +1,12 @@
|
|||||||
import { Inventory } from "@/src/models/inventoryModels/inventoryModel";
|
import { Inventory } from "@/src/models/inventoryModels/inventoryModel";
|
||||||
import { generateRewardSeed } from "@/src/services/inventoryService";
|
import { generateRewardSeed } from "@/src/services/inventoryService";
|
||||||
import { getAccountIdForRequest } from "@/src/services/loginService";
|
import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||||
import { logger } from "@/src/utils/logger";
|
|
||||||
import { RequestHandler } from "express";
|
import { RequestHandler } from "express";
|
||||||
|
|
||||||
export const getNewRewardSeedController: RequestHandler = async (req, res) => {
|
export const getNewRewardSeedController: RequestHandler = async (req, res) => {
|
||||||
const accountId = await getAccountIdForRequest(req);
|
const accountId = await getAccountIdForRequest(req);
|
||||||
|
|
||||||
const rewardSeed = generateRewardSeed();
|
const rewardSeed = generateRewardSeed();
|
||||||
logger.debug(`generated new reward seed: ${rewardSeed}`);
|
|
||||||
await Inventory.updateOne(
|
await Inventory.updateOne(
|
||||||
{
|
{
|
||||||
accountOwnerId: accountId
|
accountOwnerId: accountId
|
||||||
|
20
src/controllers/api/giveShipDecoAndLoreFragmentController.ts
Normal file
20
src/controllers/api/giveShipDecoAndLoreFragmentController.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { getJSONfromString } from "@/src/helpers/stringHelpers";
|
||||||
|
import { addLoreFragmentScans, addShipDecorations, getInventory } from "@/src/services/inventoryService";
|
||||||
|
import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||||
|
import { ILoreFragmentScan, ITypeCount } from "@/src/types/inventoryTypes/inventoryTypes";
|
||||||
|
import { RequestHandler } from "express";
|
||||||
|
|
||||||
|
export const giveShipDecoAndLoreFragmentController: RequestHandler = async (req, res) => {
|
||||||
|
const accountId = await getAccountIdForRequest(req);
|
||||||
|
const inventory = await getInventory(accountId, "LoreFragmentScans ShipDecorations");
|
||||||
|
const data = getJSONfromString<IGiveShipDecoAndLoreFragmentRequest>(String(req.body));
|
||||||
|
addLoreFragmentScans(inventory, data.LoreFragmentScans);
|
||||||
|
addShipDecorations(inventory, data.ShipDecorations);
|
||||||
|
await inventory.save();
|
||||||
|
res.end();
|
||||||
|
};
|
||||||
|
|
||||||
|
interface IGiveShipDecoAndLoreFragmentRequest {
|
||||||
|
LoreFragmentScans: ILoreFragmentScan[];
|
||||||
|
ShipDecorations: ITypeCount[];
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import { getAccountIdForRequest } from "@/src/services/loginService";
|
import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||||
import { ISetPlacedDecoInfoRequest } from "@/src/types/shipTypes";
|
import { IPictureFrameInfo, ISetPlacedDecoInfoRequest } from "@/src/types/shipTypes";
|
||||||
import { RequestHandler } from "express";
|
import { RequestHandler } from "express";
|
||||||
import { handleSetPlacedDecoInfo } from "@/src/services/shipCustomizationsService";
|
import { handleSetPlacedDecoInfo } from "@/src/services/shipCustomizationsService";
|
||||||
|
|
||||||
@ -7,5 +7,17 @@ export const setPlacedDecoInfoController: RequestHandler = async (req, res) => {
|
|||||||
const accountId = await getAccountIdForRequest(req);
|
const accountId = await getAccountIdForRequest(req);
|
||||||
const payload = JSON.parse(req.body as string) as ISetPlacedDecoInfoRequest;
|
const payload = JSON.parse(req.body as string) as ISetPlacedDecoInfoRequest;
|
||||||
await handleSetPlacedDecoInfo(accountId, payload);
|
await handleSetPlacedDecoInfo(accountId, payload);
|
||||||
res.end();
|
res.json({
|
||||||
|
DecoId: payload.DecoId,
|
||||||
|
IsPicture: true,
|
||||||
|
PictureFrameInfo: payload.PictureFrameInfo,
|
||||||
|
BootLocation: payload.BootLocation
|
||||||
|
} satisfies ISetPlacedDecoInfoResponse);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface ISetPlacedDecoInfoResponse {
|
||||||
|
DecoId: string;
|
||||||
|
IsPicture: boolean;
|
||||||
|
PictureFrameInfo?: IPictureFrameInfo;
|
||||||
|
BootLocation?: string;
|
||||||
|
}
|
||||||
|
@ -25,7 +25,13 @@ export const upgradesController: RequestHandler = async (req, res) => {
|
|||||||
operation.UpgradeRequirement == "/Lotus/Types/Items/MiscItems/CustomizationSlotUnlocker"
|
operation.UpgradeRequirement == "/Lotus/Types/Items/MiscItems/CustomizationSlotUnlocker"
|
||||||
) {
|
) {
|
||||||
updateCurrency(inventory, 10, true);
|
updateCurrency(inventory, 10, true);
|
||||||
} else if (operation.OperationType != "UOT_ABILITY_OVERRIDE") {
|
} else if (
|
||||||
|
operation.OperationType != "UOT_SWAP_POLARITY" &&
|
||||||
|
operation.OperationType != "UOT_ABILITY_OVERRIDE"
|
||||||
|
) {
|
||||||
|
if (!operation.UpgradeRequirement) {
|
||||||
|
throw new Error(`${operation.OperationType} operation should be free?`);
|
||||||
|
}
|
||||||
addMiscItems(inventory, [
|
addMiscItems(inventory, [
|
||||||
{
|
{
|
||||||
ItemType: operation.UpgradeRequirement,
|
ItemType: operation.UpgradeRequirement,
|
||||||
|
@ -1213,7 +1213,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
|
|||||||
accountOwnerId: Schema.Types.ObjectId,
|
accountOwnerId: Schema.Types.ObjectId,
|
||||||
SubscribedToEmails: { type: Number, default: 0 },
|
SubscribedToEmails: { type: Number, default: 0 },
|
||||||
SubscribedToEmailsPersonalized: { type: Number, default: 0 },
|
SubscribedToEmailsPersonalized: { type: Number, default: 0 },
|
||||||
RewardSeed: Number,
|
RewardSeed: BigInt,
|
||||||
|
|
||||||
//Credit
|
//Credit
|
||||||
RegularCredits: { type: Number, default: 0 },
|
RegularCredits: { type: Number, default: 0 },
|
||||||
|
@ -62,6 +62,7 @@ import { gildWeaponController } from "@/src/controllers/api/gildWeaponController
|
|||||||
import { giveKeyChainTriggeredItemsController } from "@/src/controllers/api/giveKeyChainTriggeredItemsController";
|
import { giveKeyChainTriggeredItemsController } from "@/src/controllers/api/giveKeyChainTriggeredItemsController";
|
||||||
import { giveKeyChainTriggeredMessageController } from "@/src/controllers/api/giveKeyChainTriggeredMessageController";
|
import { giveKeyChainTriggeredMessageController } from "@/src/controllers/api/giveKeyChainTriggeredMessageController";
|
||||||
import { giveQuestKeyRewardController } from "@/src/controllers/api/giveQuestKey";
|
import { giveQuestKeyRewardController } from "@/src/controllers/api/giveQuestKey";
|
||||||
|
import { giveShipDecoAndLoreFragmentController } from "@/src/controllers/api/giveShipDecoAndLoreFragmentController";
|
||||||
import { giveStartingGearController } from "@/src/controllers/api/giveStartingGearController";
|
import { giveStartingGearController } from "@/src/controllers/api/giveStartingGearController";
|
||||||
import { guildTechController } from "@/src/controllers/api/guildTechController";
|
import { guildTechController } from "@/src/controllers/api/guildTechController";
|
||||||
import { hostSessionController } from "@/src/controllers/api/hostSessionController";
|
import { hostSessionController } from "@/src/controllers/api/hostSessionController";
|
||||||
@ -239,6 +240,7 @@ apiRouter.post("/gildWeapon.php", gildWeaponController);
|
|||||||
apiRouter.post("/giveKeyChainTriggeredItems.php", giveKeyChainTriggeredItemsController);
|
apiRouter.post("/giveKeyChainTriggeredItems.php", giveKeyChainTriggeredItemsController);
|
||||||
apiRouter.post("/giveKeyChainTriggeredMessage.php", giveKeyChainTriggeredMessageController);
|
apiRouter.post("/giveKeyChainTriggeredMessage.php", giveKeyChainTriggeredMessageController);
|
||||||
apiRouter.post("/giveQuestKeyReward.php", giveQuestKeyRewardController);
|
apiRouter.post("/giveQuestKeyReward.php", giveQuestKeyRewardController);
|
||||||
|
apiRouter.post("/giveShipDecoAndLoreFragment.php", giveShipDecoAndLoreFragmentController);
|
||||||
apiRouter.post("/giveStartingGear.php", giveStartingGearController);
|
apiRouter.post("/giveStartingGear.php", giveStartingGearController);
|
||||||
apiRouter.post("/guildTech.php", guildTechController);
|
apiRouter.post("/guildTech.php", guildTechController);
|
||||||
apiRouter.post("/hostSession.php", hostSessionController);
|
apiRouter.post("/hostSession.php", hostSessionController);
|
||||||
|
@ -21,7 +21,8 @@ import {
|
|||||||
ICalendarProgress,
|
ICalendarProgress,
|
||||||
IDroneClient,
|
IDroneClient,
|
||||||
IUpgradeClient,
|
IUpgradeClient,
|
||||||
TPartialStartingGear
|
TPartialStartingGear,
|
||||||
|
ILoreFragmentScan
|
||||||
} from "@/src/types/inventoryTypes/inventoryTypes";
|
} from "@/src/types/inventoryTypes/inventoryTypes";
|
||||||
import { IGenericUpdate, IUpdateNodeIntrosResponse } from "../types/genericUpdate";
|
import { IGenericUpdate, IUpdateNodeIntrosResponse } from "../types/genericUpdate";
|
||||||
import { IKeyChainRequest, IMissionInventoryUpdateRequest } from "../types/requestTypes";
|
import { IKeyChainRequest, IMissionInventoryUpdateRequest } from "../types/requestTypes";
|
||||||
@ -1350,6 +1351,17 @@ export const addFocusXpIncreases = (inventory: TInventoryDatabaseDocument, focus
|
|||||||
inventory.DailyFocus -= focusXpPlus.reduce((a, b) => a + b, 0);
|
inventory.DailyFocus -= focusXpPlus.reduce((a, b) => a + b, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const addLoreFragmentScans = (inventory: TInventoryDatabaseDocument, arr: ILoreFragmentScan[]): void => {
|
||||||
|
arr.forEach(clientFragment => {
|
||||||
|
const fragment = inventory.LoreFragmentScans.find(x => x.ItemType == clientFragment.ItemType);
|
||||||
|
if (fragment) {
|
||||||
|
fragment.Progress += clientFragment.Progress;
|
||||||
|
} else {
|
||||||
|
inventory.LoreFragmentScans.push(clientFragment);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export const addChallenges = (
|
export const addChallenges = (
|
||||||
inventory: TInventoryDatabaseDocument,
|
inventory: TInventoryDatabaseDocument,
|
||||||
ChallengeProgress: IChallengeProgress[],
|
ChallengeProgress: IChallengeProgress[],
|
||||||
|
@ -9,7 +9,7 @@ import {
|
|||||||
} from "warframe-public-export-plus";
|
} from "warframe-public-export-plus";
|
||||||
import { IMissionInventoryUpdateRequest, IRewardInfo } from "../types/requestTypes";
|
import { IMissionInventoryUpdateRequest, IRewardInfo } from "../types/requestTypes";
|
||||||
import { logger } from "@/src/utils/logger";
|
import { logger } from "@/src/utils/logger";
|
||||||
import { IRngResult, getRandomElement, getRandomReward } from "@/src/services/rngService";
|
import { IRngResult, SRng, getRandomElement, getRandomReward } from "@/src/services/rngService";
|
||||||
import { equipmentKeys, TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes";
|
import { equipmentKeys, TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes";
|
||||||
import {
|
import {
|
||||||
addBooster,
|
addBooster,
|
||||||
@ -23,6 +23,7 @@ import {
|
|||||||
addGearExpByCategory,
|
addGearExpByCategory,
|
||||||
addItem,
|
addItem,
|
||||||
addLevelKeys,
|
addLevelKeys,
|
||||||
|
addLoreFragmentScans,
|
||||||
addMiscItems,
|
addMiscItems,
|
||||||
addMissionComplete,
|
addMissionComplete,
|
||||||
addMods,
|
addMods,
|
||||||
@ -30,6 +31,7 @@ import {
|
|||||||
addShipDecorations,
|
addShipDecorations,
|
||||||
addStanding,
|
addStanding,
|
||||||
combineInventoryChanges,
|
combineInventoryChanges,
|
||||||
|
generateRewardSeed,
|
||||||
updateCurrency,
|
updateCurrency,
|
||||||
updateSyndicate
|
updateSyndicate
|
||||||
} from "@/src/services/inventoryService";
|
} from "@/src/services/inventoryService";
|
||||||
@ -53,7 +55,22 @@ import { Loadout } from "../models/inventoryModels/loadoutModel";
|
|||||||
import { ILoadoutConfigDatabase } from "../types/saveLoadoutTypes";
|
import { ILoadoutConfigDatabase } from "../types/saveLoadoutTypes";
|
||||||
import { getWorldState } from "./worldStateService";
|
import { getWorldState } from "./worldStateService";
|
||||||
|
|
||||||
const getRotations = (rotationCount: number, tierOverride: number | undefined): number[] => {
|
const getRotations = (rewardInfo: IRewardInfo, tierOverride: number | undefined): number[] => {
|
||||||
|
// For Spy missions, e.g. 3 vaults cracked = A, B, C
|
||||||
|
if (rewardInfo.VaultsCracked) {
|
||||||
|
const rotations: number[] = [];
|
||||||
|
for (let i = 0; i != rewardInfo.VaultsCracked; ++i) {
|
||||||
|
rotations.push(i);
|
||||||
|
}
|
||||||
|
return rotations;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For Rescue missions
|
||||||
|
if (rewardInfo.rewardTier) {
|
||||||
|
return [rewardInfo.rewardTier];
|
||||||
|
}
|
||||||
|
|
||||||
|
const rotationCount = rewardInfo.rewardQualifications?.length || 0;
|
||||||
if (rotationCount === 0) return [0];
|
if (rotationCount === 0) return [0];
|
||||||
|
|
||||||
const rotationPattern =
|
const rotationPattern =
|
||||||
@ -69,7 +86,12 @@ const getRotations = (rotationCount: number, tierOverride: number | undefined):
|
|||||||
return rotatedValues;
|
return rotatedValues;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getRandomRewardByChance = (pool: IReward[]): IRngResult | undefined => {
|
const getRandomRewardByChance = (pool: IReward[], rng?: SRng): IRngResult | undefined => {
|
||||||
|
if (rng) {
|
||||||
|
const res = rng.randomReward(pool as IRngResult[]);
|
||||||
|
rng.randomFloat(); // something related to rewards multiplier
|
||||||
|
return res;
|
||||||
|
}
|
||||||
return getRandomReward(pool as IRngResult[]);
|
return getRandomReward(pool as IRngResult[]);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -291,14 +313,7 @@ export const addMissionInventoryUpdates = async (
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "LoreFragmentScans":
|
case "LoreFragmentScans":
|
||||||
value.forEach(clientFragment => {
|
addLoreFragmentScans(inventory, value);
|
||||||
const fragment = inventory.LoreFragmentScans.find(x => x.ItemType == clientFragment.ItemType);
|
|
||||||
if (fragment) {
|
|
||||||
fragment.Progress += clientFragment.Progress;
|
|
||||||
} else {
|
|
||||||
inventory.LoreFragmentScans.push(clientFragment);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case "LibraryScans":
|
case "LibraryScans":
|
||||||
value.forEach(scan => {
|
value.forEach(scan => {
|
||||||
@ -554,6 +569,11 @@ export const addMissionRewards = async (
|
|||||||
return { MissionRewards: [] };
|
return { MissionRewards: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rewardInfo.rewardSeed) {
|
||||||
|
// We're using a reward seed, so give the client a new one in the response. On live, missionInventoryUpdate seems to always provide a fresh one in the response.
|
||||||
|
inventory.RewardSeed = generateRewardSeed();
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: check double reward merging
|
//TODO: check double reward merging
|
||||||
const MissionRewards: IMissionReward[] = getRandomMissionDrops(rewardInfo, wagerTier);
|
const MissionRewards: IMissionReward[] = getRandomMissionDrops(rewardInfo, wagerTier);
|
||||||
logger.debug("random mission drops:", MissionRewards);
|
logger.debug("random mission drops:", MissionRewards);
|
||||||
@ -592,7 +612,14 @@ export const addMissionRewards = async (
|
|||||||
const node = ExportRegions[missions.Tag];
|
const node = ExportRegions[missions.Tag];
|
||||||
|
|
||||||
//node based credit rewards for mission completion
|
//node based credit rewards for mission completion
|
||||||
if (node.missionIndex !== 28) {
|
if (
|
||||||
|
node.missionIndex != 23 && // junction
|
||||||
|
node.missionIndex != 28 && // open world
|
||||||
|
missions.Tag != "SolNode761" && // the index
|
||||||
|
missions.Tag != "SolNode762" && // the index
|
||||||
|
missions.Tag != "SolNode763" && // the index
|
||||||
|
missions.Tag != "CrewBattleNode556" // free flight
|
||||||
|
) {
|
||||||
const levelCreditReward = getLevelCreditRewards(node);
|
const levelCreditReward = getLevelCreditRewards(node);
|
||||||
missionCompletionCredits += levelCreditReward;
|
missionCompletionCredits += levelCreditReward;
|
||||||
inventory.RegularCredits += levelCreditReward;
|
inventory.RegularCredits += levelCreditReward;
|
||||||
@ -910,6 +937,12 @@ function getLevelCreditRewards(node: IRegion): number {
|
|||||||
|
|
||||||
function getRandomMissionDrops(RewardInfo: IRewardInfo, tierOverride: number | undefined): IMissionReward[] {
|
function getRandomMissionDrops(RewardInfo: IRewardInfo, tierOverride: number | undefined): IMissionReward[] {
|
||||||
const drops: IMissionReward[] = [];
|
const drops: IMissionReward[] = [];
|
||||||
|
if (RewardInfo.periodicMissionTag?.startsWith("HardDaily")) {
|
||||||
|
drops.push({
|
||||||
|
StoreItem: "/Lotus/StoreItems/Types/Items/MiscItems/SteelEssence",
|
||||||
|
ItemCount: 5
|
||||||
|
});
|
||||||
|
}
|
||||||
if (RewardInfo.node in ExportRegions) {
|
if (RewardInfo.node in ExportRegions) {
|
||||||
const region = ExportRegions[RewardInfo.node];
|
const region = ExportRegions[RewardInfo.node];
|
||||||
let rewardManifests: string[] =
|
let rewardManifests: string[] =
|
||||||
@ -934,7 +967,7 @@ function getRandomMissionDrops(RewardInfo: IRewardInfo, tierOverride: number | u
|
|||||||
|
|
||||||
if (syndicateEntry.Tag === "EntratiSyndicate") {
|
if (syndicateEntry.Tag === "EntratiSyndicate") {
|
||||||
const vault = syndicateEntry.Jobs.find(j => j.locationTag === locationTag);
|
const vault = syndicateEntry.Jobs.find(j => j.locationTag === locationTag);
|
||||||
if (vault) job = vault;
|
if (vault && locationTag) job = vault;
|
||||||
// if (
|
// if (
|
||||||
// [
|
// [
|
||||||
// "DeimosRuinsExterminateBounty",
|
// "DeimosRuinsExterminateBounty",
|
||||||
@ -1009,8 +1042,11 @@ function getRandomMissionDrops(RewardInfo: IRewardInfo, tierOverride: number | u
|
|||||||
(RewardInfo.JobStage === job.xpAmounts.length - 1 || job.isVault) &&
|
(RewardInfo.JobStage === job.xpAmounts.length - 1 || job.isVault) &&
|
||||||
!isEndlessJob
|
!isEndlessJob
|
||||||
) {
|
) {
|
||||||
rewardManifests.push(job.rewards);
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
rotations.push(ExportRewards[job.rewards].length - 1);
|
if (ExportRewards[job.rewards]) {
|
||||||
|
rewardManifests.push(job.rewards);
|
||||||
|
rotations.push(ExportRewards[job.rewards].length - 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1053,29 +1089,28 @@ function getRandomMissionDrops(RewardInfo: IRewardInfo, tierOverride: number | u
|
|||||||
} else {
|
} else {
|
||||||
logger.error(`Unknown syndicate or tier: ${RewardInfo.challengeMissionId}`);
|
logger.error(`Unknown syndicate or tier: ${RewardInfo.challengeMissionId}`);
|
||||||
}
|
}
|
||||||
} else if (RewardInfo.VaultsCracked) {
|
|
||||||
// For Spy missions, e.g. 3 vaults cracked = A, B, C
|
|
||||||
for (let i = 0; i != RewardInfo.VaultsCracked; ++i) {
|
|
||||||
rotations.push(i);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
const rotationCount = RewardInfo.rewardQualifications?.length || 0;
|
rotations = getRotations(RewardInfo, tierOverride);
|
||||||
rotations = getRotations(rotationCount, tierOverride);
|
|
||||||
}
|
}
|
||||||
if (rewardManifests.length != 0) {
|
if (rewardManifests.length != 0) {
|
||||||
logger.debug(`generating random mission rewards`, { rewardManifests, rotations });
|
logger.debug(`generating random mission rewards`, { rewardManifests, rotations });
|
||||||
}
|
}
|
||||||
rewardManifests
|
const rng = new SRng(BigInt(RewardInfo.rewardSeed ?? generateRewardSeed()) ^ 0xffffffffffffffffn);
|
||||||
.map(name => ExportRewards[name])
|
rewardManifests.forEach(name => {
|
||||||
.forEach(table => {
|
const table = ExportRewards[name];
|
||||||
for (const rotation of rotations) {
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
const rotationRewards = table[rotation];
|
if (!table) {
|
||||||
const drop = getRandomRewardByChance(rotationRewards);
|
logger.error(`unknown droptable: ${name}`);
|
||||||
if (drop) {
|
return;
|
||||||
drops.push({ StoreItem: drop.type, ItemCount: drop.itemCount });
|
}
|
||||||
}
|
for (const rotation of rotations) {
|
||||||
|
const rotationRewards = table[rotation];
|
||||||
|
const drop = getRandomRewardByChance(rotationRewards, rng);
|
||||||
|
if (drop) {
|
||||||
|
drops.push({ StoreItem: drop.type, ItemCount: drop.itemCount });
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (region.cacheRewardManifest && RewardInfo.EnemyCachesFound) {
|
if (region.cacheRewardManifest && RewardInfo.EnemyCachesFound) {
|
||||||
const deck = ExportRewards[region.cacheRewardManifest];
|
const deck = ExportRewards[region.cacheRewardManifest];
|
||||||
|
@ -31,7 +31,7 @@ const getRewardAtPercentage = <T extends { probability: number }>(pool: T[], per
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new Error("What the fuck?");
|
return pool[pool.length - 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getRandomReward = <T extends { probability: number }>(pool: T[]): T | undefined => {
|
export const getRandomReward = <T extends { probability: number }>(pool: T[]): T | undefined => {
|
||||||
@ -142,4 +142,8 @@ export class SRng {
|
|||||||
this.state = (0x5851f42d4c957f2dn * this.state + 0x14057b7ef767814fn) & 0xffffffffffffffffn;
|
this.state = (0x5851f42d4c957f2dn * this.state + 0x14057b7ef767814fn) & 0xffffffffffffffffn;
|
||||||
return (Number(this.state >> 38n) & 0xffffff) * 0.000000059604645;
|
return (Number(this.state >> 38n) & 0xffffff) * 0.000000059604645;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
randomReward<T extends { probability: number }>(pool: T[]): T | undefined {
|
||||||
|
return getRewardAtPercentage(pool, this.randomFloat());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,7 +194,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
|
|||||||
Mailbox?: IMailboxClient;
|
Mailbox?: IMailboxClient;
|
||||||
SubscribedToEmails: number;
|
SubscribedToEmails: number;
|
||||||
Created: IMongoDate;
|
Created: IMongoDate;
|
||||||
RewardSeed: number;
|
RewardSeed: number | bigint;
|
||||||
RegularCredits: number;
|
RegularCredits: number;
|
||||||
PremiumCredits: number;
|
PremiumCredits: number;
|
||||||
PremiumCreditsFree: number;
|
PremiumCreditsFree: number;
|
||||||
|
@ -130,7 +130,7 @@ export type IMissionInventoryUpdateRequest = {
|
|||||||
export interface IRewardInfo {
|
export interface IRewardInfo {
|
||||||
node: string;
|
node: string;
|
||||||
VaultsCracked?: number; // for Spy missions
|
VaultsCracked?: number; // for Spy missions
|
||||||
rewardTier?: number;
|
rewardTier?: number; // for Rescue missions
|
||||||
nightmareMode?: boolean;
|
nightmareMode?: boolean;
|
||||||
useVaultManifest?: boolean;
|
useVaultManifest?: boolean;
|
||||||
EnemyCachesFound?: number;
|
EnemyCachesFound?: number;
|
||||||
@ -141,7 +141,7 @@ export interface IRewardInfo {
|
|||||||
EOM_AFK?: number;
|
EOM_AFK?: number;
|
||||||
rewardQualifications?: string; // did a Survival for 5 minutes and this was "1"
|
rewardQualifications?: string; // did a Survival for 5 minutes and this was "1"
|
||||||
PurgatoryRewardQualifications?: string;
|
PurgatoryRewardQualifications?: string;
|
||||||
rewardSeed?: number;
|
rewardSeed?: number | bigint;
|
||||||
periodicMissionTag?: string;
|
periodicMissionTag?: string;
|
||||||
|
|
||||||
// for bounties, only EOM_AFK and node are given from above, plus:
|
// for bounties, only EOM_AFK and node are given from above, plus:
|
||||||
|
@ -139,7 +139,7 @@ dict = {
|
|||||||
cheats_noVendorPurchaseLimits: `Keine Kaufbeschränkungen bei Händlern`,
|
cheats_noVendorPurchaseLimits: `Keine Kaufbeschränkungen bei Händlern`,
|
||||||
cheats_noKimCooldowns: `Keine Wartezeit bei KIM`,
|
cheats_noKimCooldowns: `Keine Wartezeit bei KIM`,
|
||||||
cheats_instantResourceExtractorDrones: `Sofortige Ressourcen-Extraktor-Drohnen`,
|
cheats_instantResourceExtractorDrones: `Sofortige Ressourcen-Extraktor-Drohnen`,
|
||||||
cheats_noResourceExtractorDronesDamage: `[UNTRANSLATED] No Resource Extractor Drones Damage`,
|
cheats_noResourceExtractorDronesDamage: `Kein Schaden für Ressourcen-Extraktor-Drohnen`,
|
||||||
cheats_noDojoRoomBuildStage: `Kein Dojo-Raum-Bauvorgang`,
|
cheats_noDojoRoomBuildStage: `Kein Dojo-Raum-Bauvorgang`,
|
||||||
cheats_noDojoDecoBuildStage: `Kein Dojo-Deko-Bauvorgang`,
|
cheats_noDojoDecoBuildStage: `Kein Dojo-Deko-Bauvorgang`,
|
||||||
cheats_fastDojoRoomDestruction: `Schnelle Dojo-Raum-Zerstörung`,
|
cheats_fastDojoRoomDestruction: `Schnelle Dojo-Raum-Zerstörung`,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user