feat: handle NemesisKillConvert at missionInventoryUpdate (#1880)
Closes #1848 Reviewed-on: #1880 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
This commit is contained in:
parent
9e94083875
commit
ee1a49f5f2
@ -133,7 +133,14 @@ export const claimCompletedRecipeController: RequestHandler = async (req, res) =
|
|||||||
if (recipe.secretIngredientAction != "SIA_UNBRAND") {
|
if (recipe.secretIngredientAction != "SIA_UNBRAND") {
|
||||||
InventoryChanges = {
|
InventoryChanges = {
|
||||||
...InventoryChanges,
|
...InventoryChanges,
|
||||||
...(await addItem(inventory, recipe.resultType, recipe.num, false))
|
...(await addItem(
|
||||||
|
inventory,
|
||||||
|
recipe.resultType,
|
||||||
|
recipe.num,
|
||||||
|
false,
|
||||||
|
undefined,
|
||||||
|
pendingRecipe.TargetFingerprint
|
||||||
|
))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
await inventory.save();
|
await inventory.save();
|
||||||
|
@ -3,6 +3,7 @@ import {
|
|||||||
encodeNemesisGuess,
|
encodeNemesisGuess,
|
||||||
getInfNodes,
|
getInfNodes,
|
||||||
getNemesisPasscode,
|
getNemesisPasscode,
|
||||||
|
getWeaponsForManifest,
|
||||||
IKnifeResponse
|
IKnifeResponse
|
||||||
} from "@/src/helpers/nemesisHelpers";
|
} from "@/src/helpers/nemesisHelpers";
|
||||||
import { getJSONfromString } from "@/src/helpers/stringHelpers";
|
import { getJSONfromString } from "@/src/helpers/stringHelpers";
|
||||||
@ -170,18 +171,7 @@ export const nemesisController: RequestHandler = async (req, res) => {
|
|||||||
|
|
||||||
let weaponIdx = -1;
|
let weaponIdx = -1;
|
||||||
if (body.target.Faction != "FC_INFESTATION") {
|
if (body.target.Faction != "FC_INFESTATION") {
|
||||||
let weapons: readonly string[];
|
const weapons = getWeaponsForManifest(body.target.manifest);
|
||||||
if (body.target.manifest == "/Lotus/Types/Game/Nemesis/KuvaLich/KuvaLichManifestVersionSix") {
|
|
||||||
weapons = kuvaLichVersionSixWeapons;
|
|
||||||
} else if (
|
|
||||||
body.target.manifest == "/Lotus/Types/Enemies/Corpus/Lawyers/LawyerManifestVersionFour" ||
|
|
||||||
body.target.manifest == "/Lotus/Types/Enemies/Corpus/Lawyers/LawyerManifestVersionThree"
|
|
||||||
) {
|
|
||||||
weapons = corpusVersionThreeWeapons;
|
|
||||||
} else {
|
|
||||||
throw new Error(`unknown nemesis manifest: ${body.target.manifest}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const initialWeaponIdx = new SRng(body.target.fp).randomInt(0, weapons.length - 1);
|
const initialWeaponIdx = new SRng(body.target.fp).randomInt(0, weapons.length - 1);
|
||||||
weaponIdx = initialWeaponIdx;
|
weaponIdx = initialWeaponIdx;
|
||||||
do {
|
do {
|
||||||
@ -283,39 +273,3 @@ interface INemesisRequiemRequest {
|
|||||||
HiddenWhenHolstered: boolean;
|
HiddenWhenHolstered: boolean;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const kuvaLichVersionSixWeapons = [
|
|
||||||
"/Lotus/Weapons/Grineer/KuvaLich/LongGuns/Drakgoon/KuvaDrakgoon",
|
|
||||||
"/Lotus/Weapons/Grineer/KuvaLich/LongGuns/Karak/KuvaKarak",
|
|
||||||
"/Lotus/Weapons/Grineer/Melee/GrnKuvaLichScythe/GrnKuvaLichScytheWeapon",
|
|
||||||
"/Lotus/Weapons/Grineer/KuvaLich/LongGuns/Kohm/KuvaKohm",
|
|
||||||
"/Lotus/Weapons/Grineer/KuvaLich/LongGuns/Ogris/KuvaOgris",
|
|
||||||
"/Lotus/Weapons/Grineer/KuvaLich/LongGuns/Quartakk/KuvaQuartakk",
|
|
||||||
"/Lotus/Weapons/Grineer/KuvaLich/LongGuns/Tonkor/KuvaTonkor",
|
|
||||||
"/Lotus/Weapons/Grineer/KuvaLich/Secondaries/Brakk/KuvaBrakk",
|
|
||||||
"/Lotus/Weapons/Grineer/KuvaLich/Secondaries/Kraken/KuvaKraken",
|
|
||||||
"/Lotus/Weapons/Grineer/KuvaLich/Secondaries/Seer/KuvaSeer",
|
|
||||||
"/Lotus/Weapons/Grineer/KuvaLich/Secondaries/Stubba/KuvaStubba",
|
|
||||||
"/Lotus/Weapons/Grineer/HeavyWeapons/GrnHeavyGrenadeLauncher",
|
|
||||||
"/Lotus/Weapons/Grineer/LongGuns/GrnKuvaLichRifle/GrnKuvaLichRifleWeapon",
|
|
||||||
"/Lotus/Weapons/Grineer/Bows/GrnBow/GrnBowWeapon",
|
|
||||||
"/Lotus/Weapons/Grineer/KuvaLich/LongGuns/Hind/KuvaHind",
|
|
||||||
"/Lotus/Weapons/Grineer/KuvaLich/Secondaries/Nukor/KuvaNukor",
|
|
||||||
"/Lotus/Weapons/Grineer/KuvaLich/LongGuns/Hek/KuvaHekWeapon",
|
|
||||||
"/Lotus/Weapons/Grineer/KuvaLich/LongGuns/Zarr/KuvaZarr",
|
|
||||||
"/Lotus/Weapons/Grineer/KuvaLich/HeavyWeapons/Grattler/KuvaGrattler",
|
|
||||||
"/Lotus/Weapons/Grineer/KuvaLich/LongGuns/Sobek/KuvaSobek"
|
|
||||||
];
|
|
||||||
|
|
||||||
const corpusVersionThreeWeapons = [
|
|
||||||
"/Lotus/Weapons/Corpus/LongGuns/CrpBriefcaseLauncher/CrpBriefcaseLauncher",
|
|
||||||
"/Lotus/Weapons/Corpus/BoardExec/Primary/CrpBEArcaPlasmor/CrpBEArcaPlasmor",
|
|
||||||
"/Lotus/Weapons/Corpus/BoardExec/Primary/CrpBEFluxRifle/CrpBEFluxRifle",
|
|
||||||
"/Lotus/Weapons/Corpus/BoardExec/Primary/CrpBETetra/CrpBETetra",
|
|
||||||
"/Lotus/Weapons/Corpus/BoardExec/Secondary/CrpBECycron/CrpBECycron",
|
|
||||||
"/Lotus/Weapons/Corpus/BoardExec/Secondary/CrpBEDetron/CrpBEDetron",
|
|
||||||
"/Lotus/Weapons/Corpus/Pistols/CrpIgniterPistol/CrpIgniterPistol",
|
|
||||||
"/Lotus/Weapons/Corpus/Pistols/CrpBriefcaseAkimbo/CrpBriefcaseAkimboPistol",
|
|
||||||
"/Lotus/Weapons/Corpus/BoardExec/Secondary/CrpBEPlinx/CrpBEPlinxWeapon",
|
|
||||||
"/Lotus/Weapons/Corpus/BoardExec/Primary/CrpBEGlaxion/CrpBEGlaxion"
|
|
||||||
];
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ExportRegions } from "warframe-public-export-plus";
|
import { ExportRegions, ExportWarframes } from "warframe-public-export-plus";
|
||||||
import { IInfNode } from "@/src/types/inventoryTypes/inventoryTypes";
|
import { IInfNode } from "@/src/types/inventoryTypes/inventoryTypes";
|
||||||
import { SRng } from "@/src/services/rngService";
|
import { SRng } from "@/src/services/rngService";
|
||||||
import { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel";
|
import { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel";
|
||||||
@ -129,3 +129,147 @@ export const consumeModCharge = (
|
|||||||
response.UpgradeNew.push(true);
|
response.UpgradeNew.push(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const kuvaLichVersionSixWeapons = [
|
||||||
|
"/Lotus/Weapons/Grineer/KuvaLich/LongGuns/Drakgoon/KuvaDrakgoon",
|
||||||
|
"/Lotus/Weapons/Grineer/KuvaLich/LongGuns/Karak/KuvaKarak",
|
||||||
|
"/Lotus/Weapons/Grineer/Melee/GrnKuvaLichScythe/GrnKuvaLichScytheWeapon",
|
||||||
|
"/Lotus/Weapons/Grineer/KuvaLich/LongGuns/Kohm/KuvaKohm",
|
||||||
|
"/Lotus/Weapons/Grineer/KuvaLich/LongGuns/Ogris/KuvaOgris",
|
||||||
|
"/Lotus/Weapons/Grineer/KuvaLich/LongGuns/Quartakk/KuvaQuartakk",
|
||||||
|
"/Lotus/Weapons/Grineer/KuvaLich/LongGuns/Tonkor/KuvaTonkor",
|
||||||
|
"/Lotus/Weapons/Grineer/KuvaLich/Secondaries/Brakk/KuvaBrakk",
|
||||||
|
"/Lotus/Weapons/Grineer/KuvaLich/Secondaries/Kraken/KuvaKraken",
|
||||||
|
"/Lotus/Weapons/Grineer/KuvaLich/Secondaries/Seer/KuvaSeer",
|
||||||
|
"/Lotus/Weapons/Grineer/KuvaLich/Secondaries/Stubba/KuvaStubba",
|
||||||
|
"/Lotus/Weapons/Grineer/HeavyWeapons/GrnHeavyGrenadeLauncher",
|
||||||
|
"/Lotus/Weapons/Grineer/LongGuns/GrnKuvaLichRifle/GrnKuvaLichRifleWeapon",
|
||||||
|
"/Lotus/Weapons/Grineer/Bows/GrnBow/GrnBowWeapon",
|
||||||
|
"/Lotus/Weapons/Grineer/KuvaLich/LongGuns/Hind/KuvaHind",
|
||||||
|
"/Lotus/Weapons/Grineer/KuvaLich/Secondaries/Nukor/KuvaNukor",
|
||||||
|
"/Lotus/Weapons/Grineer/KuvaLich/LongGuns/Hek/KuvaHekWeapon",
|
||||||
|
"/Lotus/Weapons/Grineer/KuvaLich/LongGuns/Zarr/KuvaZarr",
|
||||||
|
"/Lotus/Weapons/Grineer/KuvaLich/HeavyWeapons/Grattler/KuvaGrattler",
|
||||||
|
"/Lotus/Weapons/Grineer/KuvaLich/LongGuns/Sobek/KuvaSobek"
|
||||||
|
];
|
||||||
|
|
||||||
|
const corpusVersionThreeWeapons = [
|
||||||
|
"/Lotus/Weapons/Corpus/LongGuns/CrpBriefcaseLauncher/CrpBriefcaseLauncher",
|
||||||
|
"/Lotus/Weapons/Corpus/BoardExec/Primary/CrpBEArcaPlasmor/CrpBEArcaPlasmor",
|
||||||
|
"/Lotus/Weapons/Corpus/BoardExec/Primary/CrpBEFluxRifle/CrpBEFluxRifle",
|
||||||
|
"/Lotus/Weapons/Corpus/BoardExec/Primary/CrpBETetra/CrpBETetra",
|
||||||
|
"/Lotus/Weapons/Corpus/BoardExec/Secondary/CrpBECycron/CrpBECycron",
|
||||||
|
"/Lotus/Weapons/Corpus/BoardExec/Secondary/CrpBEDetron/CrpBEDetron",
|
||||||
|
"/Lotus/Weapons/Corpus/Pistols/CrpIgniterPistol/CrpIgniterPistol",
|
||||||
|
"/Lotus/Weapons/Corpus/Pistols/CrpBriefcaseAkimbo/CrpBriefcaseAkimboPistol",
|
||||||
|
"/Lotus/Weapons/Corpus/BoardExec/Secondary/CrpBEPlinx/CrpBEPlinxWeapon",
|
||||||
|
"/Lotus/Weapons/Corpus/BoardExec/Primary/CrpBEGlaxion/CrpBEGlaxion"
|
||||||
|
];
|
||||||
|
|
||||||
|
export const getWeaponsForManifest = (manifest: string): readonly string[] => {
|
||||||
|
switch (manifest) {
|
||||||
|
case "/Lotus/Types/Game/Nemesis/KuvaLich/KuvaLichManifestVersionSix":
|
||||||
|
return kuvaLichVersionSixWeapons;
|
||||||
|
case "/Lotus/Types/Enemies/Corpus/Lawyers/LawyerManifestVersionThree":
|
||||||
|
case "/Lotus/Types/Enemies/Corpus/Lawyers/LawyerManifestVersionFour":
|
||||||
|
return corpusVersionThreeWeapons;
|
||||||
|
}
|
||||||
|
throw new Error(`unknown nemesis manifest: ${manifest}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: This sucks.
|
||||||
|
export const getInnateDamageTag = (
|
||||||
|
KillingSuit: string
|
||||||
|
):
|
||||||
|
| "InnateElectricityDamage"
|
||||||
|
| "InnateFreezeDamage"
|
||||||
|
| "InnateHeatDamage"
|
||||||
|
| "InnateImpactDamage"
|
||||||
|
| "InnateMagDamage"
|
||||||
|
| "InnateRadDamage"
|
||||||
|
| "InnateToxinDamage" => {
|
||||||
|
const baseSuitType = ExportWarframes[KillingSuit].parentName;
|
||||||
|
switch (baseSuitType) {
|
||||||
|
case "/Lotus/Powersuits/Volt/VoltBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Excalibur/ExcaliburBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/AntiMatter/NovaBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Banshee/BansheeBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Berserker/BerserkerBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Magician/MagicianBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Sentient/SentientBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Gyre/GyreBaseSuit":
|
||||||
|
return "InnateElectricityDamage";
|
||||||
|
case "/Lotus/Powersuits/Ember/EmberBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Dragon/DragonBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Nezha/NezhaBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Sandman/SandmanBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Trapper/TrapperBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Wisp/WispBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Odalisk/OdaliskBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/PaxDuviricus/PaxDuviricusBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Choir/ChoirBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Temple/TempleBaseSuit":
|
||||||
|
return "InnateHeatDamage";
|
||||||
|
case "/Lotus/Powersuits/Frost/FrostBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Glass/GlassBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Fairy/FairyBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/IronFrame/IronFrameBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Revenant/RevenantBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Trinity/TrinityBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Hoplite/HopliteBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Koumei/KoumeiBaseSuit":
|
||||||
|
return "InnateFreezeDamage";
|
||||||
|
case "/Lotus/Powersuits/Saryn/SarynBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Paladin/PaladinBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Brawler/BrawlerBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Infestation/InfestationBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Necro/NecroBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Khora/KhoraBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Ranger/RangerBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Dagath/DagathBaseSuit":
|
||||||
|
return "InnateToxinDamage";
|
||||||
|
case "/Lotus/Powersuits/Mag/MagBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Pirate/PirateBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Cowgirl/CowgirlBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Priest/PriestBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/BrokenFrame/BrokenFrameBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Alchemist/AlchemistBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Yareli/YareliBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Geode/GeodeBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Frumentarius/FrumentariusBaseSuit":
|
||||||
|
return "InnateMagDamage";
|
||||||
|
case "/Lotus/Powersuits/Loki/LokiBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Ninja/NinjaBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Jade/JadeBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Bard/BardBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Harlequin/HarlequinBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Garuda/GarudaBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/YinYang/YinYangBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Werewolf/WerewolfBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/ConcreteFrame/ConcreteFrameBaseSuit":
|
||||||
|
return "InnateRadDamage";
|
||||||
|
case "/Lotus/Powersuits/Rhino/RhinoBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Tengu/TenguBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/MonkeyKing/MonkeyKingBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Runner/RunnerBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Pacifist/PacifistBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Devourer/DevourerBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Wraith/WraithBaseSuit":
|
||||||
|
case "/Lotus/Powersuits/Pagemaster/PagemasterBaseSuit":
|
||||||
|
return "InnateImpactDamage";
|
||||||
|
}
|
||||||
|
logger.warn(`unknown innate damage type for ${KillingSuit}, using heat as a fallback`);
|
||||||
|
return "InnateHeatDamage";
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: For -1399275245665749231n, the value should be 75306944, but we're off by 59 with 75307003.
|
||||||
|
export const getInnateDamageValue = (fp: bigint): number => {
|
||||||
|
const rng = new SRng(fp);
|
||||||
|
rng.randomFloat(); // used for the weapon index
|
||||||
|
const WeaponUpgradeValueAttenuationExponent = 2.25;
|
||||||
|
let value = Math.pow(rng.randomFloat(), WeaponUpgradeValueAttenuationExponent);
|
||||||
|
if (value >= 0.941428) {
|
||||||
|
value = 1;
|
||||||
|
}
|
||||||
|
return Math.trunc(value * 0x40000000);
|
||||||
|
};
|
||||||
|
@ -1039,6 +1039,8 @@ const pendingRecipeSchema = new Schema<IPendingRecipeDatabase>(
|
|||||||
{
|
{
|
||||||
ItemType: String,
|
ItemType: String,
|
||||||
CompletionDate: Date,
|
CompletionDate: Date,
|
||||||
|
TargetItemId: String,
|
||||||
|
TargetFingerprint: String,
|
||||||
LongGuns: { type: [EquipmentSchema], default: undefined },
|
LongGuns: { type: [EquipmentSchema], default: undefined },
|
||||||
Pistols: { type: [EquipmentSchema], default: undefined },
|
Pistols: { type: [EquipmentSchema], default: undefined },
|
||||||
Melee: { type: [EquipmentSchema], default: undefined },
|
Melee: { type: [EquipmentSchema], default: undefined },
|
||||||
@ -1260,11 +1262,11 @@ const nemesisSchema = new Schema<INemesisDatabase>(
|
|||||||
PrevOwners: Number,
|
PrevOwners: Number,
|
||||||
SecondInCommand: Boolean,
|
SecondInCommand: Boolean,
|
||||||
Weakened: Boolean,
|
Weakened: Boolean,
|
||||||
InfNodes: [infNodeSchema],
|
InfNodes: { type: [infNodeSchema], default: undefined },
|
||||||
HenchmenKilled: Number,
|
HenchmenKilled: Number,
|
||||||
HintProgress: Number,
|
HintProgress: Number,
|
||||||
Hints: [Number],
|
Hints: { type: [Number], default: undefined },
|
||||||
GuessHistory: [Number],
|
GuessHistory: { type: [Number], default: undefined },
|
||||||
MissionCount: Number,
|
MissionCount: Number,
|
||||||
LastEnc: Number
|
LastEnc: Number
|
||||||
},
|
},
|
||||||
@ -1609,7 +1611,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
|
|||||||
//CorpusLich or GrineerLich
|
//CorpusLich or GrineerLich
|
||||||
NemesisAbandonedRewards: { type: [String], default: [] },
|
NemesisAbandonedRewards: { type: [String], default: [] },
|
||||||
Nemesis: nemesisSchema,
|
Nemesis: nemesisSchema,
|
||||||
NemesisHistory: [Schema.Types.Mixed],
|
NemesisHistory: { type: [nemesisSchema], default: undefined },
|
||||||
LastNemesisAllySpawnTime: Schema.Types.Mixed,
|
LastNemesisAllySpawnTime: Schema.Types.Mixed,
|
||||||
|
|
||||||
//TradingRulesConfirmed,ShowFriendInvNotifications(Option->Social)
|
//TradingRulesConfirmed,ShowFriendInvNotifications(Option->Social)
|
||||||
|
@ -26,7 +26,9 @@ import {
|
|||||||
Status,
|
Status,
|
||||||
IKubrowPetDetailsDatabase,
|
IKubrowPetDetailsDatabase,
|
||||||
ITraits,
|
ITraits,
|
||||||
ICalendarProgress
|
ICalendarProgress,
|
||||||
|
INemesisWeaponTargetFingerprint,
|
||||||
|
INemesisPetTargetFingerprint
|
||||||
} 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";
|
||||||
@ -79,6 +81,7 @@ import { getRandomElement, getRandomInt, getRandomWeightedReward, SRng } from ".
|
|||||||
import { createMessage } from "./inboxService";
|
import { createMessage } from "./inboxService";
|
||||||
import { getMaxStanding } from "@/src/helpers/syndicateStandingHelper";
|
import { getMaxStanding } from "@/src/helpers/syndicateStandingHelper";
|
||||||
import { getWorldState } from "./worldStateService";
|
import { getWorldState } from "./worldStateService";
|
||||||
|
import { getInnateDamageTag, getInnateDamageValue } from "../helpers/nemesisHelpers";
|
||||||
|
|
||||||
export const createInventory = async (
|
export const createInventory = async (
|
||||||
accountOwnerId: Types.ObjectId,
|
accountOwnerId: Types.ObjectId,
|
||||||
@ -327,7 +330,8 @@ export const addItem = async (
|
|||||||
typeName: string,
|
typeName: string,
|
||||||
quantity: number = 1,
|
quantity: number = 1,
|
||||||
premiumPurchase: boolean = false,
|
premiumPurchase: boolean = false,
|
||||||
seed?: bigint
|
seed?: bigint,
|
||||||
|
targetFingerprint?: string
|
||||||
): Promise<IInventoryChanges> => {
|
): Promise<IInventoryChanges> => {
|
||||||
// Bundles are technically StoreItems but a) they don't have a normal counterpart, and b) they are used in non-StoreItem contexts, e.g. email attachments.
|
// Bundles are technically StoreItems but a) they don't have a normal counterpart, and b) they are used in non-StoreItem contexts, e.g. email attachments.
|
||||||
if (typeName in ExportBundles) {
|
if (typeName in ExportBundles) {
|
||||||
@ -530,6 +534,12 @@ export const addItem = async (
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (targetFingerprint) {
|
||||||
|
const targetFingerprintObj = JSON.parse(targetFingerprint) as INemesisWeaponTargetFingerprint;
|
||||||
|
defaultOverwrites.UpgradeType = targetFingerprintObj.ItemType;
|
||||||
|
defaultOverwrites.UpgradeFingerprint = JSON.stringify(targetFingerprintObj.UpgradeFingerprint);
|
||||||
|
defaultOverwrites.ItemName = targetFingerprintObj.Name;
|
||||||
|
}
|
||||||
const inventoryChanges = addEquipment(inventory, weapon.productCategory, typeName, defaultOverwrites);
|
const inventoryChanges = addEquipment(inventory, weapon.productCategory, typeName, defaultOverwrites);
|
||||||
if (weapon.additionalItems) {
|
if (weapon.additionalItems) {
|
||||||
for (const item of weapon.additionalItems) {
|
for (const item of weapon.additionalItems) {
|
||||||
@ -544,6 +554,27 @@ export const addItem = async (
|
|||||||
premiumPurchase
|
premiumPurchase
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
} else if (targetFingerprint) {
|
||||||
|
// Sister's Hound
|
||||||
|
const targetFingerprintObj = JSON.parse(targetFingerprint) as INemesisPetTargetFingerprint;
|
||||||
|
const head = targetFingerprintObj.Parts[0];
|
||||||
|
const defaultOverwrites: Partial<IEquipmentDatabase> = {
|
||||||
|
ModularParts: targetFingerprintObj.Parts,
|
||||||
|
ItemName: targetFingerprintObj.Name,
|
||||||
|
Configs: applyDefaultUpgrades(inventory, ExportWeapons[head].defaultUpgrades)
|
||||||
|
};
|
||||||
|
const itemType = {
|
||||||
|
"/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetParts/ZanukaPetPartHeadA":
|
||||||
|
"/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetAPowerSuit",
|
||||||
|
"/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetParts/ZanukaPetPartHeadB":
|
||||||
|
"/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetBPowerSuit",
|
||||||
|
"/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetParts/ZanukaPetPartHeadC":
|
||||||
|
"/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetCPowerSuit"
|
||||||
|
}[head] as string;
|
||||||
|
return {
|
||||||
|
...addEquipment(inventory, "MoaPets", itemType, defaultOverwrites),
|
||||||
|
...occupySlot(inventory, InventorySlot.SENTINELS, premiumPurchase)
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
// Modular weapon parts
|
// Modular weapon parts
|
||||||
const miscItemChanges = [
|
const miscItemChanges = [
|
||||||
@ -1851,3 +1882,78 @@ export const getCalendarProgress = (inventory: TInventoryDatabaseDocument): ICal
|
|||||||
|
|
||||||
return inventory.CalendarProgress;
|
return inventory.CalendarProgress;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const giveNemesisWeaponRecipe = (
|
||||||
|
inventory: TInventoryDatabaseDocument,
|
||||||
|
weaponType: string,
|
||||||
|
nemesisName: string = "AGOR ROK",
|
||||||
|
weaponLoc?: string,
|
||||||
|
KillingSuit: string = "/Lotus/Powersuits/Ember/Ember",
|
||||||
|
fp: bigint = generateRewardSeed()
|
||||||
|
): void => {
|
||||||
|
if (!weaponLoc) {
|
||||||
|
weaponLoc = ExportWeapons[weaponType].name;
|
||||||
|
}
|
||||||
|
const recipeType = Object.entries(ExportRecipes).find(arr => arr[1].resultType == weaponType)![0];
|
||||||
|
addRecipes(inventory, [
|
||||||
|
{
|
||||||
|
ItemType: recipeType,
|
||||||
|
ItemCount: 1
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
inventory.PendingRecipes.push({
|
||||||
|
CompletionDate: new Date(),
|
||||||
|
ItemType: recipeType,
|
||||||
|
TargetFingerprint: JSON.stringify({
|
||||||
|
ItemType: "/Lotus/Weapons/Grineer/KuvaLich/Upgrades/InnateDamageRandomMod",
|
||||||
|
UpgradeFingerprint: {
|
||||||
|
compat: weaponType,
|
||||||
|
buffs: [
|
||||||
|
{
|
||||||
|
Tag: getInnateDamageTag(KillingSuit),
|
||||||
|
Value: getInnateDamageValue(fp)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
Name: weaponLoc + "|" + nemesisName
|
||||||
|
} satisfies INemesisWeaponTargetFingerprint)
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const giveNemesisPetRecipe = (inventory: TInventoryDatabaseDocument, nemesisName: string = "AGOR ROK"): void => {
|
||||||
|
const head = getRandomElement([
|
||||||
|
"/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetParts/ZanukaPetPartHeadA",
|
||||||
|
"/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetParts/ZanukaPetPartHeadB",
|
||||||
|
"/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetParts/ZanukaPetPartHeadC"
|
||||||
|
]);
|
||||||
|
const body = getRandomElement([
|
||||||
|
"/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetParts/ZanukaPetPartBodyA",
|
||||||
|
"/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetParts/ZanukaPetPartBodyB",
|
||||||
|
"/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetParts/ZanukaPetPartBodyC"
|
||||||
|
]);
|
||||||
|
const legs = getRandomElement([
|
||||||
|
"/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetParts/ZanukaPetPartLegsA",
|
||||||
|
"/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetParts/ZanukaPetPartLegsB",
|
||||||
|
"/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetParts/ZanukaPetPartLegsC"
|
||||||
|
]);
|
||||||
|
const tail = getRandomElement([
|
||||||
|
"/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetParts/ZanukaPetPartTailA",
|
||||||
|
"/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetParts/ZanukaPetPartTailB",
|
||||||
|
"/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetParts/ZanukaPetPartTailC"
|
||||||
|
]);
|
||||||
|
const recipeType = Object.entries(ExportRecipes).find(arr => arr[1].resultType == head)![0];
|
||||||
|
addRecipes(inventory, [
|
||||||
|
{
|
||||||
|
ItemType: recipeType,
|
||||||
|
ItemCount: 1
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
inventory.PendingRecipes.push({
|
||||||
|
CompletionDate: new Date(),
|
||||||
|
ItemType: recipeType,
|
||||||
|
TargetFingerprint: JSON.stringify({
|
||||||
|
Parts: [head, body, legs, tail],
|
||||||
|
Name: "/Lotus/Language/Pets/ZanukaPetName|" + nemesisName
|
||||||
|
} satisfies INemesisPetTargetFingerprint)
|
||||||
|
});
|
||||||
|
};
|
||||||
|
@ -35,6 +35,8 @@ import {
|
|||||||
combineInventoryChanges,
|
combineInventoryChanges,
|
||||||
generateRewardSeed,
|
generateRewardSeed,
|
||||||
getCalendarProgress,
|
getCalendarProgress,
|
||||||
|
giveNemesisPetRecipe,
|
||||||
|
giveNemesisWeaponRecipe,
|
||||||
updateCurrency,
|
updateCurrency,
|
||||||
updateSyndicate
|
updateSyndicate
|
||||||
} from "@/src/services/inventoryService";
|
} from "@/src/services/inventoryService";
|
||||||
@ -53,7 +55,7 @@ import kuriaMessage50 from "@/static/fixed_responses/kuriaMessages/fiftyPercent.
|
|||||||
import kuriaMessage75 from "@/static/fixed_responses/kuriaMessages/seventyFivePercent.json";
|
import kuriaMessage75 from "@/static/fixed_responses/kuriaMessages/seventyFivePercent.json";
|
||||||
import kuriaMessage100 from "@/static/fixed_responses/kuriaMessages/oneHundredPercent.json";
|
import kuriaMessage100 from "@/static/fixed_responses/kuriaMessages/oneHundredPercent.json";
|
||||||
import conservationAnimals from "@/static/fixed_responses/conservationAnimals.json";
|
import conservationAnimals from "@/static/fixed_responses/conservationAnimals.json";
|
||||||
import { getInfNodes } from "@/src/helpers/nemesisHelpers";
|
import { getInfNodes, getWeaponsForManifest } from "@/src/helpers/nemesisHelpers";
|
||||||
import { Loadout } from "../models/inventoryModels/loadoutModel";
|
import { Loadout } from "../models/inventoryModels/loadoutModel";
|
||||||
import { ILoadoutConfigDatabase } from "../types/saveLoadoutTypes";
|
import { ILoadoutConfigDatabase } from "../types/saveLoadoutTypes";
|
||||||
import { getLiteSortie, getWorldState, idToWeek } from "./worldStateService";
|
import { getLiteSortie, getWorldState, idToWeek } from "./worldStateService";
|
||||||
@ -612,6 +614,52 @@ export const addMissionInventoryUpdates = async (
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "NemesisKillConvert":
|
||||||
|
if (inventory.Nemesis) {
|
||||||
|
inventory.NemesisHistory ??= [];
|
||||||
|
inventory.NemesisHistory.push({
|
||||||
|
// Copy over all 'base' values
|
||||||
|
fp: inventory.Nemesis.fp,
|
||||||
|
d: inventory.Nemesis.d,
|
||||||
|
manifest: inventory.Nemesis.manifest,
|
||||||
|
KillingSuit: inventory.Nemesis.KillingSuit,
|
||||||
|
killingDamageType: inventory.Nemesis.killingDamageType,
|
||||||
|
ShoulderHelmet: inventory.Nemesis.ShoulderHelmet,
|
||||||
|
WeaponIdx: inventory.Nemesis.WeaponIdx,
|
||||||
|
AgentIdx: inventory.Nemesis.AgentIdx,
|
||||||
|
BirthNode: inventory.Nemesis.BirthNode,
|
||||||
|
Faction: inventory.Nemesis.Faction,
|
||||||
|
Rank: inventory.Nemesis.Rank,
|
||||||
|
Traded: inventory.Nemesis.Traded,
|
||||||
|
PrevOwners: inventory.Nemesis.PrevOwners,
|
||||||
|
SecondInCommand: inventory.Nemesis.SecondInCommand,
|
||||||
|
Weakened: inventory.Nemesis.Weakened,
|
||||||
|
// And set killed flag
|
||||||
|
k: value.killed
|
||||||
|
});
|
||||||
|
|
||||||
|
if (value.killed) {
|
||||||
|
if (value.weaponLoc) {
|
||||||
|
const weaponType = getWeaponsForManifest(inventory.Nemesis.manifest)[
|
||||||
|
inventory.Nemesis.WeaponIdx
|
||||||
|
];
|
||||||
|
giveNemesisWeaponRecipe(
|
||||||
|
inventory,
|
||||||
|
weaponType,
|
||||||
|
value.nemesisName,
|
||||||
|
value.weaponLoc,
|
||||||
|
inventory.Nemesis.KillingSuit,
|
||||||
|
inventory.Nemesis.fp
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (value.petLoc) {
|
||||||
|
giveNemesisPetRecipe(inventory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inventory.Nemesis = undefined;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// Equipment XP updates
|
// Equipment XP updates
|
||||||
if (equipmentKeys.includes(key as TEquipmentKey)) {
|
if (equipmentKeys.includes(key as TEquipmentKey)) {
|
||||||
|
@ -43,6 +43,7 @@ export interface IInventoryDatabase
|
|||||||
| "RecentVendorPurchases"
|
| "RecentVendorPurchases"
|
||||||
| "NextRefill"
|
| "NextRefill"
|
||||||
| "Nemesis"
|
| "Nemesis"
|
||||||
|
| "NemesisHistory"
|
||||||
| "EntratiVaultCountResetDate"
|
| "EntratiVaultCountResetDate"
|
||||||
| "BrandedSuits"
|
| "BrandedSuits"
|
||||||
| "LockedWeaponGroup"
|
| "LockedWeaponGroup"
|
||||||
@ -79,6 +80,7 @@ export interface IInventoryDatabase
|
|||||||
RecentVendorPurchases?: IRecentVendorPurchaseDatabase[];
|
RecentVendorPurchases?: IRecentVendorPurchaseDatabase[];
|
||||||
NextRefill?: Date;
|
NextRefill?: Date;
|
||||||
Nemesis?: INemesisDatabase;
|
Nemesis?: INemesisDatabase;
|
||||||
|
NemesisHistory?: INemesisBaseDatabase[];
|
||||||
EntratiVaultCountResetDate?: Date;
|
EntratiVaultCountResetDate?: Date;
|
||||||
BrandedSuits?: Types.ObjectId[];
|
BrandedSuits?: Types.ObjectId[];
|
||||||
LockedWeaponGroup?: ILockedWeaponGroupDatabase;
|
LockedWeaponGroup?: ILockedWeaponGroupDatabase;
|
||||||
@ -313,7 +315,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
|
|||||||
EquippedInstrument?: string;
|
EquippedInstrument?: string;
|
||||||
InvasionChainProgress: IInvasionChainProgress[];
|
InvasionChainProgress: IInvasionChainProgress[];
|
||||||
Nemesis?: INemesisClient;
|
Nemesis?: INemesisClient;
|
||||||
NemesisHistory: INemesisBaseClient[];
|
NemesisHistory?: INemesisBaseClient[];
|
||||||
LastNemesisAllySpawnTime?: IMongoDate;
|
LastNemesisAllySpawnTime?: IMongoDate;
|
||||||
Settings?: ISettings;
|
Settings?: ISettings;
|
||||||
PersonalTechProjects: IPersonalTechProjectClient[];
|
PersonalTechProjects: IPersonalTechProjectClient[];
|
||||||
@ -902,8 +904,8 @@ export interface IPendingRecipeDatabase {
|
|||||||
ItemType: string;
|
ItemType: string;
|
||||||
CompletionDate: Date;
|
CompletionDate: Date;
|
||||||
ItemId: IOid;
|
ItemId: IOid;
|
||||||
TargetItemId?: string; // likely related to liches
|
TargetItemId?: string; // unsure what this is for
|
||||||
TargetFingerprint?: string; // likely related to liches
|
TargetFingerprint?: string;
|
||||||
LongGuns?: IEquipmentDatabase[];
|
LongGuns?: IEquipmentDatabase[];
|
||||||
Pistols?: IEquipmentDatabase[];
|
Pistols?: IEquipmentDatabase[];
|
||||||
Melee?: IEquipmentDatabase[];
|
Melee?: IEquipmentDatabase[];
|
||||||
@ -951,6 +953,17 @@ export interface ICrewShipComponentFingerprint extends IInnateDamageFingerprint
|
|||||||
SubroutineIndex?: number;
|
SubroutineIndex?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface INemesisWeaponTargetFingerprint {
|
||||||
|
ItemType: string;
|
||||||
|
UpgradeFingerprint: IInnateDamageFingerprint;
|
||||||
|
Name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface INemesisPetTargetFingerprint {
|
||||||
|
Parts: string[];
|
||||||
|
Name: string;
|
||||||
|
}
|
||||||
|
|
||||||
export enum GettingSlotOrderInfo {
|
export enum GettingSlotOrderInfo {
|
||||||
Empty = "",
|
Empty = "",
|
||||||
LotusUpgradesModsRandomizedPlayerMeleeWeaponRandomModRare0 = "/Lotus/Upgrades/Mods/Randomized/PlayerMeleeWeaponRandomModRare:0",
|
LotusUpgradesModsRandomizedPlayerMeleeWeaponRandomModRare0 = "/Lotus/Upgrades/Mods/Randomized/PlayerMeleeWeaponRandomModRare:0",
|
||||||
|
@ -22,7 +22,8 @@ import {
|
|||||||
ILoadOutPresets,
|
ILoadOutPresets,
|
||||||
IInvasionProgressClient,
|
IInvasionProgressClient,
|
||||||
IWeaponSkinClient,
|
IWeaponSkinClient,
|
||||||
IKubrowPetEggClient
|
IKubrowPetEggClient,
|
||||||
|
INemesisClient
|
||||||
} from "./inventoryTypes/inventoryTypes";
|
} from "./inventoryTypes/inventoryTypes";
|
||||||
import { IGroup } from "./loginTypes";
|
import { IGroup } from "./loginTypes";
|
||||||
|
|
||||||
@ -74,6 +75,14 @@ export type IMissionInventoryUpdateRequest = {
|
|||||||
PS: string;
|
PS: string;
|
||||||
ActiveDojoColorResearch: string;
|
ActiveDojoColorResearch: string;
|
||||||
RewardInfo?: IRewardInfo;
|
RewardInfo?: IRewardInfo;
|
||||||
|
NemesisKillConvert?: {
|
||||||
|
nemesisName: string;
|
||||||
|
weaponLoc: string;
|
||||||
|
petLoc: "" | "/Lotus/Language/Pets/ZanukaPetName";
|
||||||
|
fingerprint: bigint | number;
|
||||||
|
killed: boolean;
|
||||||
|
};
|
||||||
|
target?: INemesisClient;
|
||||||
ReceivedCeremonyMsg: boolean;
|
ReceivedCeremonyMsg: boolean;
|
||||||
LastCeremonyResetDate: number;
|
LastCeremonyResetDate: number;
|
||||||
MissionPTS: number;
|
MissionPTS: number;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user