feat: modular weapon crafting #317

Merged
Sainan merged 3 commits from modular-weapons into main 2024-06-17 17:03:08 -07:00
6 changed files with 75 additions and 8 deletions

View File

@ -0,0 +1,55 @@
import { RequestHandler } from "express";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { getJSONfromString } from "@/src/helpers/stringHelpers";
import { WeaponTypeInternal } from "@/src/services/itemDataService";
import { getInventory, updateCurrency, addWeapon, addMiscItems } from "@/src/services/inventoryService";
const modularWeaponTypes: Record<string, WeaponTypeInternal> = {
"/Lotus/Weapons/SolarisUnited/Primary/LotusModularPrimaryBeam": "LongGuns",
"/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondary": "Pistols",
"/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondaryBeam": "Pistols",
"/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondaryShotgun": "Pistols",
"/Lotus/Weapons/Ostron/Melee/LotusModularWeapon": "Melee",
"/Lotus/Weapons/Sentients/OperatorAmplifiers/OperatorAmpWeapon": "OperatorAmps"
};
interface IModularCraftRequest {
WeaponType: string;
Parts: string[];
}
export const modularWeaponCraftingController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req);
const data: IModularCraftRequest = getJSONfromString(req.body.toString());
if (!(data.WeaponType in modularWeaponTypes)) {
throw new Error(`unknown modular weapon type: ${data.WeaponType}`);
}
const category = modularWeaponTypes[data.WeaponType];
// Give weapon
const weapon = await addWeapon(category, data.WeaponType, accountId, data.Parts);
// Remove 4000 credits
const currencyChanges = await updateCurrency(4000, false, accountId);
// Remove parts
const miscItemChanges = [];
for (const part of data.Parts) {
miscItemChanges.push({
ItemType: part,
ItemCount: -1
});
}
const inventory = await getInventory(accountId);
addMiscItems(inventory, miscItemChanges);
await inventory.save();
// Tell client what we did
res.json({
InventoryChanges: {
...currencyChanges,
[category]: [weapon],
MiscItems: miscItemChanges
}
});
};

View File

@ -43,7 +43,9 @@ const getItemListsController: RequestHandler = (_req, res) => {
item.category == "Misc" || item.category == "Misc" ||
item.category == "Resources" || item.category == "Resources" ||
item.category == "Fish" || item.category == "Fish" ||
((item as any).productCategory == "Pistols" && (item as MinWeapon).totalDamage == 0) ((item as any).productCategory == "Pistols" &&
(item as MinWeapon).totalDamage == 0 &&
Review

The wonders of warframe-items. We will be rid of that shit at some point in the future, but for the time being, we have to accept the fact that we don't have correct typings.

The wonders of `warframe-items`. We will be rid of that shit at some point in the future, but for the time being, we have to accept the fact that we don't have correct typings.
!item.excludeFromCodex) // exclude Zaw Strike PvP variant
) )
), ),
mods, mods,

View File

@ -921,6 +921,7 @@ type InventoryDocumentProps = {
LongGuns: Types.DocumentArray<IEquipmentDatabase>; LongGuns: Types.DocumentArray<IEquipmentDatabase>;
Pistols: Types.DocumentArray<IEquipmentDatabase>; Pistols: Types.DocumentArray<IEquipmentDatabase>;
Melee: Types.DocumentArray<IEquipmentDatabase>; Melee: Types.DocumentArray<IEquipmentDatabase>;
OperatorAmps: Types.DocumentArray<IEquipmentDatabase>;
FlavourItems: Types.DocumentArray<IFlavourItem>; FlavourItems: Types.DocumentArray<IFlavourItem>;
RawUpgrades: Types.DocumentArray<IRawUpgrade>; RawUpgrades: Types.DocumentArray<IRawUpgrade>;
Upgrades: Types.DocumentArray<ICrewShipSalvagedWeaponSkin>; Upgrades: Types.DocumentArray<ICrewShipSalvagedWeaponSkin>;

View File

@ -56,6 +56,7 @@ import { syndicateSacrificeController } from "../controllers/api/syndicateSacrif
import { startDojoRecipeController } from "@/src/controllers/api/startDojoRecipeController"; import { startDojoRecipeController } from "@/src/controllers/api/startDojoRecipeController";
import { queueDojoComponentDestructionController } from "@/src/controllers/api/queueDojoComponentDestructionController"; import { queueDojoComponentDestructionController } from "@/src/controllers/api/queueDojoComponentDestructionController";
import { nameWeaponController } from "@/src/controllers/api/nameWeaponController"; import { nameWeaponController } from "@/src/controllers/api/nameWeaponController";
import { modularWeaponCraftingController } from "@/src/controllers/api/modularWeaponCraftingController";
const apiRouter = express.Router(); const apiRouter = express.Router();
@ -122,5 +123,6 @@ apiRouter.post("/guildTech.php", guildTechController);
apiRouter.post("/syndicateSacrifice.php", syndicateSacrificeController); apiRouter.post("/syndicateSacrifice.php", syndicateSacrificeController);
apiRouter.post("/startDojoRecipe.php", startDojoRecipeController); apiRouter.post("/startDojoRecipe.php", startDojoRecipeController);
apiRouter.post("/nameWeapon.php", nameWeaponController); apiRouter.post("/nameWeapon.php", nameWeaponController);
apiRouter.post("/modularWeaponCrafting.php", modularWeaponCraftingController);
export { apiRouter }; export { apiRouter };

View File

@ -386,20 +386,23 @@ export const syndicateSacrifice = async (
export const addWeapon = async ( export const addWeapon = async (
weaponType: WeaponTypeInternal, weaponType: WeaponTypeInternal,
weaponName: string, weaponName: string,
accountId: string accountId: string,
modularParts: string[] | undefined = undefined
): Promise<IEquipmentClient> => { ): Promise<IEquipmentClient> => {
const inventory = await getInventory(accountId); const inventory = await getInventory(accountId);
let weaponIndex; let weaponIndex;
switch (weaponType) { switch (weaponType) {
case "LongGuns": case "LongGuns":
weaponIndex = inventory.LongGuns.push({ ItemType: weaponName, Configs: [], XP: 0 });
break;
case "Pistols": case "Pistols":
weaponIndex = inventory.Pistols.push({ ItemType: weaponName, Configs: [], XP: 0 });
break;
case "Melee": case "Melee":
weaponIndex = inventory.Melee.push({ ItemType: weaponName, Configs: [], XP: 0 }); case "OperatorAmps":
weaponIndex = inventory[weaponType].push({
ItemType: weaponName,
Configs: [],
XP: 0,
ModularParts: modularParts
});
break; break;
default: default:
throw new Error("unknown weapon type: " + weaponType); throw new Error("unknown weapon type: " + weaponType);

View File

@ -96,6 +96,10 @@ window.itemListPromise = new Promise(resolve => {
"/Lotus/Weapons/Tenno/Rifle/LotusRifle": { name: "Rifle" }, "/Lotus/Weapons/Tenno/Rifle/LotusRifle": { name: "Rifle" },
"/Lotus/Weapons/Tenno/Shotgun/LotusShotgun": { name: "Shotgun" }, "/Lotus/Weapons/Tenno/Shotgun/LotusShotgun": { name: "Shotgun" },
// Modular weapons // Modular weapons
"/Lotus/Weapons/SolarisUnited/Primary/LotusModularPrimaryBeam": { name: "Kitgun" },
"/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondary": { name: "Kitgun" },
"/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondaryBeam": { name: "Kitgun" },
"/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondaryShotgun": { name: "Kitgun" },
"/Lotus/Weapons/Ostron/Melee/LotusModularWeapon": { name: "Zaw" }, "/Lotus/Weapons/Ostron/Melee/LotusModularWeapon": { name: "Zaw" },
// Missing in data sources // Missing in data sources
"/Lotus/Upgrades/CosmeticEnhancers/Peculiars/CyoteMod": { name: "Traumatic Peculiar" } "/Lotus/Upgrades/CosmeticEnhancers/Peculiars/CyoteMod": { name: "Traumatic Peculiar" }
@ -524,7 +528,7 @@ function doAcquireMiscItems() {
MiscItems: [ MiscItems: [
{ {
ItemType: uniqueName, ItemType: uniqueName,
ItemCount: $("#miscitem-count").val() ItemCount: parseInt($("#miscitem-count").val())
} }
] ]
}) })