more work on bn13

This commit is contained in:
Olivier Gagnon 2021-11-13 23:45:26 -05:00
parent 56ddcd9a45
commit 43a6521403
11 changed files with 213 additions and 182 deletions

103
dist/vendor.bundle.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -67,7 +67,6 @@ export class ActiveFragment {
} }
cool(): void { cool(): void {
console.log(Math.log(this.numCharge + 1) / (Math.log(50) * 10));
this.numCharge = this.numCharge - Math.log(this.numCharge + 1) / (Math.log(50) * 10); this.numCharge = this.numCharge - Math.log(this.numCharge + 1) / (Math.log(50) * 10);
if (this.numCharge < 0) { if (this.numCharge < 0) {
this.numCharge = 0; this.numCharge = 0;

@ -7,14 +7,14 @@ export interface IStaneksGift {
fragments: ActiveFragment[]; fragments: ActiveFragment[];
width(): number; width(): number;
height(): number; height(): number;
charge(rootX: number, rootY: number, ram: number): number; charge(fragment: ActiveFragment, threads: number): void;
process(p: IPlayer, n: number): void; process(p: IPlayer, n: number): void;
effect(fragment: ActiveFragment): number; effect(fragment: ActiveFragment): number;
canPlace(x: number, y: number, rotation: number, fragment: Fragment): boolean; canPlace(x: number, y: number, rotation: number, fragment: Fragment): boolean;
place(x: number, y: number, rotation: number, fragment: Fragment): boolean; place(x: number, y: number, rotation: number, fragment: Fragment): boolean;
findFragment(rootX: number, rootY: number): ActiveFragment | undefined; findFragment(rootX: number, rootY: number): ActiveFragment | undefined;
fragmentAt(worldX: number, worldY: number): ActiveFragment | undefined; fragmentAt(rootX: number, rootY: number): ActiveFragment | undefined;
deleteAt(worldX: number, worldY: number): boolean; delete(rootX: number, rootY: number): boolean;
clear(): void; clear(): void;
count(fragment: Fragment): number; count(fragment: Fragment): number;
inBonus(): boolean; inBonus(): boolean;

@ -29,16 +29,11 @@ export class StaneksGift implements IStaneksGift {
return Math.floor(this.baseSize() / 2 + 0.6); return Math.floor(this.baseSize() / 2 + 0.6);
} }
charge(rootX: number, rootY: number, threads: number): number { charge(af: ActiveFragment, threads: number): void {
const af = this.findFragment(rootX, rootY);
if (af === undefined) return 0;
af.avgCharge = (af.numCharge * af.avgCharge + threads) / (af.numCharge + 1); af.avgCharge = (af.numCharge * af.avgCharge + threads) / (af.numCharge + 1);
af.numCharge++; af.numCharge++;
Factions["Church of the Machine God"].playerReputation += Math.log(threads) / Math.log(2); Factions["Church of the Machine God"].playerReputation += Math.log(threads) / Math.log(2);
return threads;
} }
inBonus(): boolean { inBonus(): boolean {
@ -74,21 +69,21 @@ export class StaneksGift implements IStaneksGift {
return CalculateEffect(fragment.avgCharge, fragment.numCharge, fragment.fragment().power, boost); return CalculateEffect(fragment.avgCharge, fragment.numCharge, fragment.fragment().power, boost);
} }
canPlace(worldX: number, worldY: number, rotation: number, fragment: Fragment): boolean { canPlace(rootX: number, rootY: number, rotation: number, fragment: Fragment): boolean {
if (worldX < 0 || worldY < 0) return false; if (rootX < 0 || rootY < 0) return false;
if (worldX + fragment.width(rotation) > this.width()) return false; if (rootX + fragment.width(rotation) > this.width()) return false;
if (worldY + fragment.height(rotation) > this.height()) return false; if (rootY + fragment.height(rotation) > this.height()) return false;
if (this.count(fragment) >= fragment.limit) return false; if (this.count(fragment) >= fragment.limit) return false;
const newFrag = new ActiveFragment({ x: worldX, y: worldY, rotation: rotation, fragment: fragment }); const newFrag = new ActiveFragment({ x: rootX, y: rootY, rotation: rotation, fragment: fragment });
for (const aFrag of this.fragments) { for (const aFrag of this.fragments) {
if (aFrag.collide(newFrag)) return false; if (aFrag.collide(newFrag)) return false;
} }
return true; return true;
} }
place(worldX: number, worldY: number, rotation: number, fragment: Fragment): boolean { place(rootX: number, rootY: number, rotation: number, fragment: Fragment): boolean {
if (!this.canPlace(worldX, worldY, rotation, fragment)) return false; if (!this.canPlace(rootX, rootY, rotation, fragment)) return false;
this.fragments.push(new ActiveFragment({ x: worldX, y: worldY, rotation: rotation, fragment: fragment })); this.fragments.push(new ActiveFragment({ x: rootX, y: rootY, rotation: rotation, fragment: fragment }));
return true; return true;
} }
@ -114,9 +109,9 @@ export class StaneksGift implements IStaneksGift {
return amt; return amt;
} }
deleteAt(worldX: number, worldY: number): boolean { delete(rootX: number, rootY: number): boolean {
for (let i = 0; i < this.fragments.length; i++) { for (let i = 0; i < this.fragments.length; i++) {
if (this.fragments[i].fullAt(worldX, worldY)) { if (this.fragments[i].x === rootX && this.fragments[i].y === rootY) {
this.fragments.splice(i, 1); this.fragments.splice(i, 1);
return true; return true;
} }

@ -80,7 +80,9 @@ export function MainBoard(props: IProps): React.ReactElement {
} }
function deleteAt(worldX: number, worldY: number): boolean { function deleteAt(worldX: number, worldY: number): boolean {
return props.gift.deleteAt(worldX, worldY); const f = props.gift.fragmentAt(worldX, worldY);
if (f === undefined) return false;
return props.gift.delete(f.x, f.y);
} }
function clickAt(worldX: number, worldY: number): void { function clickAt(worldX: number, worldY: number): void {

@ -336,12 +336,12 @@ export const RamCosts: IMap<any> = {
stanek: { stanek: {
charge: RamCostConstants.ScriptStanekCharge, charge: RamCostConstants.ScriptStanekCharge,
fragmentDefinitions: RamCostConstants.ScriptStanekFragmentDefinitions, fragmentDefinitions: RamCostConstants.ScriptStanekFragmentDefinitions,
placedFragments: RamCostConstants.ScriptStanekPlacedFragments, activeFragments: RamCostConstants.ScriptStanekPlacedFragments,
clear: RamCostConstants.ScriptStanekClear, clear: RamCostConstants.ScriptStanekClear,
canPlace: RamCostConstants.ScriptStanekCanPlace, canPlace: RamCostConstants.ScriptStanekCanPlace,
place: RamCostConstants.ScriptStanekPlace, place: RamCostConstants.ScriptStanekPlace,
fragmentAt: RamCostConstants.ScriptStanekFragmentAt, get: RamCostConstants.ScriptStanekFragmentAt,
deleteAt: RamCostConstants.ScriptStanekDeleteAt, remove: RamCostConstants.ScriptStanekDeleteAt,
}, },
heart: { heart: {

@ -70,7 +70,13 @@ import { NetscriptCorporation } from "./NetscriptFunctions/Corporation";
import { NetscriptFormulas } from "./NetscriptFunctions/Formulas"; import { NetscriptFormulas } from "./NetscriptFunctions/Formulas";
import { NetscriptStockMarket } from "./NetscriptFunctions/StockMarket"; import { NetscriptStockMarket } from "./NetscriptFunctions/StockMarket";
import { NS as INS, Player as INetscriptPlayer } from "./ScriptEditor/NetscriptDefinitions"; import {
NS as INS,
Player as INetscriptPlayer,
Gang as IGang,
Bladeburner as IBladeburner,
Stanek as IStanek,
} from "./ScriptEditor/NetscriptDefinitions";
import { NetscriptSingularity } from "./NetscriptFunctions/Singularity"; import { NetscriptSingularity } from "./NetscriptFunctions/Singularity";
import { toNative } from "./NetscriptFunctions/toNative"; import { toNative } from "./NetscriptFunctions/toNative";
@ -82,6 +88,9 @@ import { Flags } from "./NetscriptFunctions/Flags";
interface NS extends INS { interface NS extends INS {
[key: string]: any; [key: string]: any;
gang: IGang;
bladeburner: IBladeburner;
stanek: IStanek;
} }
export function NetscriptFunctions(workerScript: WorkerScript): NS { export function NetscriptFunctions(workerScript: WorkerScript): NS {

@ -7,25 +7,20 @@ import { getRamCost } from "../Netscript/RamCostGenerator";
import { staneksGift } from "../CotMG/Helper"; import { staneksGift } from "../CotMG/Helper";
import { Fragments, FragmentById } from "../CotMG/Fragment"; import { Fragments, FragmentById } from "../CotMG/Fragment";
export interface INetscriptStanek { import {
width(): number; Stanek as IStanek,
height(): number; Fragment as IFragment,
charge(rootX: number, rootY: number): any; ActiveFragment as IActiveFragment,
fragmentDefinitions(): any; } from "../ScriptEditor/NetscriptDefinitions";
placedFragments(): any; import { AugmentationNames } from "../Augmentation/data/AugmentationNames";
clear(): void;
canPlace(worldX: number, worldY: number, rotation: number, fragmentId: number): boolean; export function NetscriptStanek(player: IPlayer, workerScript: WorkerScript, helper: INetscriptHelper): IStanek {
place(worldX: number, worldY: number, rotation: number, fragmentId: number): boolean; function checkStanekAPIAccess(func: string): void {
findFragment(rootX: any, rootY: any): any; if (!player.hasAugmentation(AugmentationNames.StaneksGift1, true)) {
fragmentAt(worldX: number, worldY: number): any; helper.makeRuntimeErrorMsg(func, "Requires Stanek's Gift installed.");
deleteAt(worldX: number, worldY: number): boolean; }
} }
export function NetscriptStanek(
player: IPlayer,
workerScript: WorkerScript,
helper: INetscriptHelper,
): INetscriptStanek {
return { return {
width: function (): number { width: function (): number {
return staneksGift.width(); return staneksGift.width();
@ -33,9 +28,12 @@ export function NetscriptStanek(
height: function (): number { height: function (): number {
return staneksGift.height(); return staneksGift.height();
}, },
charge: function (rootX: any, rootY: any): any { charge: function (arootX: any, arootY: any): Promise<void> {
const rootX = helper.number("stanek.charge", "rootX", arootX);
const rootY = helper.number("stanek.charge", "rootY", arootY);
helper.updateDynamicRam("charge", getRamCost("stanek", "charge")); helper.updateDynamicRam("charge", getRamCost("stanek", "charge"));
//checkStanekAPIAccess("charge"); checkStanekAPIAccess("charge");
const fragment = staneksGift.findFragment(rootX, rootY); const fragment = staneksGift.findFragment(rootX, rootY);
if (!fragment) throw helper.makeRuntimeErrorMsg("stanek.charge", `No fragment with root (${rootX}, ${rootY}).`); if (!fragment) throw helper.makeRuntimeErrorMsg("stanek.charge", `No fragment with root (${rootX}, ${rootY}).`);
const time = staneksGift.inBonus() ? 200 : 1000; const time = staneksGift.inBonus() ? 200 : 1000;
@ -43,65 +41,69 @@ export function NetscriptStanek(
if (workerScript.env.stopFlag) { if (workerScript.env.stopFlag) {
return Promise.reject(workerScript); return Promise.reject(workerScript);
} }
const ram = workerScript.scriptRef.ramUsage * workerScript.scriptRef.threads; const charge = staneksGift.charge(fragment, workerScript.scriptRef.threads);
const charge = staneksGift.charge(rootX, rootY, workerScript.scriptRef.threads);
workerScript.log("stanek.charge", `Charged fragment for ${charge} charge.`); workerScript.log("stanek.charge", `Charged fragment for ${charge} charge.`);
return Promise.resolve(charge); return Promise.resolve();
}); });
}, },
fragmentDefinitions: function () { fragmentDefinitions: function (): IFragment[] {
helper.updateDynamicRam("fragmentDefinitions", getRamCost("stanek", "fragmentDefinitions")); helper.updateDynamicRam("fragmentDefinitions", getRamCost("stanek", "fragmentDefinitions"));
//checkStanekAPIAccess("fragmentDefinitions"); checkStanekAPIAccess("fragmentDefinitions");
workerScript.log("stanek.fragmentDefinitions", `Returned ${Fragments.length} fragments`); workerScript.log("stanek.fragmentDefinitions", `Returned ${Fragments.length} fragments`);
return Fragments.map((f) => f.copy()); return Fragments.map((f) => f.copy());
}, },
placedFragments: function () { activeFragments: function (): IActiveFragment[] {
helper.updateDynamicRam("placedFragments", getRamCost("stanek", "placedFragments")); helper.updateDynamicRam("activeFragments", getRamCost("stanek", "activeFragments"));
//checkStanekAPIAccess("placedFragments"); checkStanekAPIAccess("activeFragments");
workerScript.log("stanek.placedFragments", `Returned ${staneksGift.fragments.length} fragments`); workerScript.log("stanek.activeFragments", `Returned ${staneksGift.fragments.length} fragments`);
return staneksGift.fragments.map((af) => { return staneksGift.fragments.map((af) => {
return { ...af.copy(), ...af.fragment().copy() }; return { ...af.copy(), ...af.fragment().copy() };
}); });
}, },
clear: function () { clear: function (): void {
helper.updateDynamicRam("clear", getRamCost("stanek", "clear")); helper.updateDynamicRam("clear", getRamCost("stanek", "clear"));
//checkStanekAPIAccess("clear"); checkStanekAPIAccess("clear");
workerScript.log("stanek.clear", `Cleared Stanek's Gift.`); workerScript.log("stanek.clear", `Cleared Stanek's Gift.`);
staneksGift.clear(); staneksGift.clear();
}, },
canPlace: function (worldX: any, worldY: any, rotation: any, fragmentId: any): any { canPlace: function (arootX: any, arootY: any, arotation: any, afragmentId: any): boolean {
const rootX = helper.number("stanek.canPlace", "rootX", arootX);
const rootY = helper.number("stanek.canPlace", "rootY", arootY);
const rotation = helper.number("stanek.canPlace", "rotation", arotation);
const fragmentId = helper.number("stanek.canPlace", "fragmentId", afragmentId);
helper.updateDynamicRam("canPlace", getRamCost("stanek", "canPlace")); helper.updateDynamicRam("canPlace", getRamCost("stanek", "canPlace"));
//checkStanekAPIAccess("canPlace"); checkStanekAPIAccess("canPlace");
const fragment = FragmentById(fragmentId); const fragment = FragmentById(fragmentId);
if (!fragment) throw helper.makeRuntimeErrorMsg("stanek.canPlace", `Invalid fragment id: ${fragmentId}`); if (!fragment) throw helper.makeRuntimeErrorMsg("stanek.canPlace", `Invalid fragment id: ${fragmentId}`);
const can = staneksGift.canPlace(worldX, worldY, rotation, fragment); const can = staneksGift.canPlace(rootX, rootY, rotation, fragment);
return can; return can;
}, },
place: function (worldX: any, worldY: any, rotation: any, fragmentId: any): any { place: function (arootX: any, arootY: any, arotation: any, afragmentId: any): boolean {
const rootX = helper.number("stanek.place", "rootX", arootX);
const rootY = helper.number("stanek.place", "rootY", arootY);
const rotation = helper.number("stanek.place", "rotation", arotation);
const fragmentId = helper.number("stanek.place", "fragmentId", afragmentId);
helper.updateDynamicRam("place", getRamCost("stanek", "place")); helper.updateDynamicRam("place", getRamCost("stanek", "place"));
//checkStanekAPIAccess("place"); checkStanekAPIAccess("place");
const fragment = FragmentById(fragmentId); const fragment = FragmentById(fragmentId);
if (!fragment) throw helper.makeRuntimeErrorMsg("stanek.place", `Invalid fragment id: ${fragmentId}`); if (!fragment) throw helper.makeRuntimeErrorMsg("stanek.place", `Invalid fragment id: ${fragmentId}`);
return staneksGift.place(worldX, worldY, rotation, fragment); return staneksGift.place(rootX, rootY, rotation, fragment);
}, },
findFragment: function (rootX: any, rootY: any): any { get: function (arootX: any, arootY: any): IActiveFragment | undefined {
helper.updateDynamicRam("findFragment", getRamCost("stanek", "findFragment")); const rootX = helper.number("stanek.get", "rootX", arootX);
//checkStanekAPIAccess("fragmentAt"); const rootY = helper.number("stanek.get", "rootY", arootY);
helper.updateDynamicRam("get", getRamCost("stanek", "get"));
checkStanekAPIAccess("get");
const fragment = staneksGift.findFragment(rootX, rootY); const fragment = staneksGift.findFragment(rootX, rootY);
if (fragment !== undefined) return fragment.copy(); if (fragment !== undefined) return fragment.copy();
return undefined; return undefined;
}, },
fragmentAt: function (worldX: any, worldY: any): any { remove: function (arootX: any, arootY: any): boolean {
helper.updateDynamicRam("fragmentAt", getRamCost("stanek", "fragmentAt")); const rootX = helper.number("stanek.remove", "rootX", arootX);
//checkStanekAPIAccess("fragmentAt"); const rootY = helper.number("stanek.remove", "rootY", arootY);
const fragment = staneksGift.fragmentAt(worldX, worldY); helper.updateDynamicRam("remove", getRamCost("stanek", "remove"));
if (fragment !== undefined) return fragment.copy(); checkStanekAPIAccess("remove");
return undefined; return staneksGift.delete(rootX, rootY);
},
deleteAt: function (worldX: any, worldY: any): any {
helper.updateDynamicRam("deleteAt", getRamCost("stanek", "deleteAt"));
//checkStanekAPIAccess("deleteAt");
return staneksGift.deleteAt(worldX, worldY);
}, },
}; };
} }

@ -3360,20 +3360,123 @@ export interface Formulas {
hacknetServers: HacknetServersFormulas; hacknetServers: HacknetServersFormulas;
} }
export interface Fragment {
id: number;
shape: boolean[][];
type: number;
power: number;
limit: number;
}
export interface ActiveFragment {
id: number;
avgCharge: number;
numCharge: number;
rotation: number;
x: number;
y: number;
}
/** /**
* Stanek's Gift API. * Stanek's Gift API.
* @public * @public
*/ */
interface Stanek { interface Stanek {
/** /**
* @ramCost cost: 0.5 GB * Stanek's Gift width.
* @param {number} rootX Root X against which to align the top left of the fragment. * @remarks
* @param {number} rootY Root Y against which to align the top left of the fragment. * RAM cost: 0.4 GB
* @param {number} rotation A number from 0 to 3, the mount of 90 degree turn to take. * @returns The width of the gift.
* @param {number} fragmentId ID of the fragment to place. */
* @returns {boolean} true if the fragment can be placed at that position. false otherwise. width(): number;
/**
* Stanek's Gift height.
* @remarks
* RAM cost: 0.4 GB
* @returns The height of the gift.
*/
height(): number;
/**
* Charge a fragment, increasing it's power.
* @remarks
* RAM cost: 0.4 GB
* @param rootX - rootX Root X against which to align the top left of the fragment.
* @param rootY - rootY Root Y against which to align the top left of the fragment.
* @returns Promise that lasts until the charge action is over.
*/
charge(rootX: number, rootY: number): Promise<void>;
/**
* List possible fragments.
* @remarks
* RAM cost: cost: 0 GB
*
* @returns List of possible fragments.
*/
fragmentDefinitions(): Fragment[];
/**
* List of fragments in Stanek's Gift.
* @remarks
* RAM cost: cost: 5 GB
*
* @returns List of active fragments placed on Stanek's Gift.
*/
activeFragments(): ActiveFragment[];
/**
* Clear the board of all fragments.
* @remarks
* RAM cost: cost: 0 GB
*/
clear(): void;
/**
* Check if fragment can be placed at specified location.
* @remarks
* RAM cost: cost: 0.5 GB
*
* @param rootX - rootX Root X against which to align the top left of the fragment.
* @param rootY - rootY Root Y against which to align the top left of the fragment.
* @param rotation - rotation A number from 0 to 3, the mount of 90 degree turn to take.
* @param fragmentId - fragmentId ID of the fragment to place.
* @returns true if the fragment can be placed at that position. false otherwise.
*/ */
canPlace(rootX: number, rootY: number, rotation: number, fragmentId: number): boolean; canPlace(rootX: number, rootY: number, rotation: number, fragmentId: number): boolean;
/**
* Place fragment on Stanek's Gift.
* @remarks
* RAM cost: cost: 5 GB
*
* @param rootX - X against which to align the top left of the fragment.
* @param rootY - Y against which to align the top left of the fragment.
* @param rotation - A number from 0 to 3, the mount of 90 degree turn to take.
* @param fragmentId - ID of the fragment to place.
* @returns true if the fragment can be placed at that position. false otherwise.
*/
place(rootX: number, rootY: number, rotation: number, fragmentId: number): boolean;
/**
* Get placed fragment at location.
* @remarks
* RAM cost: cost: 5 GB
*
* @param rootX - X against which to align the top left of the fragment.
* @param rootY - Y against which to align the top left of the fragment.
* @returns The fragment at [rootX, rootY], if any.
*/
get(rootX: number, rootY: number): ActiveFragment | undefined;
/**
* Remove fragment at location.
* @remarks
* RAM cost: cost: 0.15 GB
*
* @param rootX - X against which to align the top left of the fragment.
* @param rootY - Y against which to align the top left of the fragment.
* @returns The fragment at [rootX, rootY], if any.
*/
remove(rootX: number, rootY: number): boolean;
} }
/** /**