/** * Implements the Re-sleeving mechanic for BitNode-10. * This allows the player to purchase and "use" new sleeves at VitaLife. * These new sleeves come with different starting experience and Augmentations * The cost of these new sleeves scales based on the exp and Augs. * * Note that this is different from the "Sleeve mechanic". The "Sleeve" mechanic * provides new sleeves, essentially clones. This Re-sleeving mechanic lets * the player purchase a new body with pre-existing Augmentations and experience * * As of right now, this feature is only available in BitNode 10 */ import { Resleeve } from "./Resleeve"; import { IPlayer } from "../IPlayer"; import { Augmentation } from "../../Augmentation/Augmentation"; import { Augmentations } from "../../Augmentation/Augmentations"; import { IPlayerOwnedAugmentation, PlayerOwnedAugmentation } from "../../Augmentation/PlayerOwnedAugmentation"; import { AugmentationNames } from "../../Augmentation/data/AugmentationNames"; import { getRandomInt } from "../../utils/helpers/getRandomInt"; // Executes the actual re-sleeve when one is purchased export function purchaseResleeve(r: Resleeve, p: IPlayer): boolean { const cost: number = r.getCost(); if (!p.canAfford(cost)) { return false; } p.loseMoney(cost, "other"); // Set the player's exp p.hacking_exp = r.hacking_exp; p.strength_exp = r.strength_exp; p.defense_exp = r.defense_exp; p.dexterity_exp = r.dexterity_exp; p.agility_exp = r.agility_exp; p.charisma_exp = r.charisma_exp; // Reset Augmentation "owned" data for (const augKey in Augmentations) { Augmentations[augKey].owned = false; } // Clear all of the player's augmentations, except the NeuroFlux Governor // which is kept for (let i = p.augmentations.length - 1; i >= 0; --i) { if (p.augmentations[i].name !== AugmentationNames.NeuroFluxGovernor) { p.augmentations.splice(i, 1); } else { // NeuroFlux Governor Augmentations[AugmentationNames.NeuroFluxGovernor].owned = true; } } for (let i = 0; i < r.augmentations.length; ++i) { p.augmentations.push(new PlayerOwnedAugmentation(r.augmentations[i].name)); Augmentations[r.augmentations[i].name].owned = true; } // The player's purchased Augmentations should remain the same, but any purchased // Augmentations that are given by the resleeve should be removed so there are no duplicates for (let i = p.queuedAugmentations.length - 1; i >= 0; --i) { const name: string = p.queuedAugmentations[i].name; if ( p.augmentations.filter((e: IPlayerOwnedAugmentation) => { return e.name !== AugmentationNames.NeuroFluxGovernor && e.name === name; }).length >= 1 ) { p.queuedAugmentations.splice(i, 1); } } p.reapplyAllAugmentations(true); p.reapplyAllSourceFiles(); //Multipliers get reset, so have to re-process source files too return true; } // Creates all of the Re-sleeves that will be available for purchase at VitaLife export function generateResleeves(): Resleeve[] { const NumResleeves = 40; // Total number of Resleeves to generate const ret: Resleeve[] = []; for (let i = 0; i < NumResleeves; ++i) { // i will be a number indicating how "powerful" the Re-sleeve should be const r: Resleeve = new Resleeve(); // Generate experience const expMult: number = 5 * i + 1; r.hacking_exp = expMult * getRandomInt(1000, 5000); r.strength_exp = expMult * getRandomInt(1000, 5000); r.defense_exp = expMult * getRandomInt(1000, 5000); r.dexterity_exp = expMult * getRandomInt(1000, 5000); r.agility_exp = expMult * getRandomInt(1000, 5000); r.charisma_exp = expMult * getRandomInt(1000, 5000); // Generate Augs // Augmentation prequisites will be ignored for this const baseNumAugs: number = Math.max(2, Math.ceil((i + 3) / 2)); const numAugs: number = getRandomInt(baseNumAugs, baseNumAugs + 2); const augKeys: string[] = Object.keys(Augmentations); for (let a = 0; a < numAugs; ++a) { // Get a random aug const randIndex: number = getRandomInt(0, augKeys.length - 1); const randKey: string = augKeys[randIndex]; // Forbidden augmentations const forbidden = [ AugmentationNames.TheRedPill, AugmentationNames.NeuroFluxGovernor, AugmentationNames.StaneksGift1, AugmentationNames.StaneksGift2, AugmentationNames.StaneksGift3, ]; if (forbidden.includes(randKey)) { continue; } const randAug: Augmentation | null = Augmentations[randKey]; if (randAug === null) throw new Error(`null augmentation: ${randKey}`); r.augmentations.push({ name: randAug.name, level: 1 }); r.applyAugmentation(Augmentations[randKey]); r.updateStatLevels(); // Remove Augmentation so that there are no duplicates augKeys.splice(randIndex, 1); } ret.push(r); } return ret; }