diff --git a/src/CotMG/ActiveFragment.ts b/src/CotMG/ActiveFragment.ts
index 41467c1b2..1f0218428 100644
--- a/src/CotMG/ActiveFragment.ts
+++ b/src/CotMG/ActiveFragment.ts
@@ -51,7 +51,7 @@ export class ActiveFragment {
fragment(): Fragment {
const fragment = FragmentById(this.id);
- if (fragment === null) throw "ActiveFragment id refers to unknown Fragment.";
+ if (fragment === null) throw new Error("ActiveFragment id refers to unknown Fragment.");
return fragment;
}
@@ -68,7 +68,7 @@ export class ActiveFragment {
copy(): ActiveFragment {
// We have to do a round trip because the constructor.
const fragment = FragmentById(this.id);
- if (fragment === null) throw "ActiveFragment id refers to unknown Fragment.";
+ if (fragment === null) throw new Error("ActiveFragment id refers to unknown Fragment.");
const c = new ActiveFragment({ x: this.x, y: this.y, fragment: fragment });
c.charge = this.charge;
c.heat = this.heat;
diff --git a/src/CotMG/Fragment.ts b/src/CotMG/Fragment.ts
index 9ae0b951c..e66054fcd 100644
--- a/src/CotMG/Fragment.ts
+++ b/src/CotMG/Fragment.ts
@@ -3,287 +3,336 @@ import { FragmentType } from "./FragmentType";
export const Fragments: Fragment[] = [];
export class Fragment {
- id: number;
- shape: boolean[][];
- type: FragmentType;
- power: number;
- limit: number;
+ id: number;
+ shape: boolean[][];
+ type: FragmentType;
+ power: number;
+ limit: number;
- constructor(id: number, shape: boolean[][], type: FragmentType, power: number, limit: number) {
- this.id = id;
- this.shape = shape;
- this.type = type;
- this.power = power;
- this.limit = limit;
+ constructor(id: number, shape: boolean[][], type: FragmentType, power: number, limit: number) {
+ this.id = id;
+ this.shape = shape;
+ this.type = type;
+ this.power = power;
+ this.limit = limit;
+ }
+
+ fullAt(x: number, y: number): boolean {
+ if (y < 0) return false;
+ if (y >= this.shape.length) return false;
+ if (x < 0) return false;
+ if (x >= this.shape[y].length) return false;
+ // Yes it's ordered y first.
+ return this.shape[y][x];
+ }
+
+ width(): number {
+ // check every line for robustness.
+ return Math.max(...this.shape.map((line) => line.length));
+ }
+
+ height(): number {
+ return this.shape.length;
+ }
+
+ // List of direct neighboors of this fragment.
+ neighboors(): number[][] {
+ const candidates: number[][] = [];
+
+ const add = (x: number, y: number): void => {
+ if (this.fullAt(x, y)) return;
+ if (candidates.some((coord) => coord[0] === x && coord[1] === y)) return;
+ candidates.push([x, y]);
+ };
+ for (let y = 0; y < this.shape.length; y++) {
+ for (let x = 0; x < this.shape[y].length; x++) {
+ // This cell is full, add all it's neighboors.
+ if (!this.shape[y][x]) continue;
+ add(x - 1, y);
+ add(x + 1, y);
+ add(x, y - 1);
+ add(x, y + 1);
+ }
+ }
+ const cells: number[][] = [];
+ for (const candidate of candidates) {
+ if (cells.some((cell) => cell[0] === candidate[0] && cell[1] === candidate[1])) continue;
+ cells.push(candidate);
}
- fullAt(x: number, y: number): boolean {
- if(y < 0) return false;
- if(y >= this.shape.length) return false;
- if(x < 0) return false;
- if(x >= this.shape[y].length) return false;
- // Yes it's ordered y first.
- return this.shape[y][x];
- }
+ return cells;
+ }
- width() {
- // check every line for robustness.
- return Math.max(...this.shape.map(line => line.length));
- }
-
- height() {
- return this.shape.length;
- }
-
- // List of direct neighboors of this fragment.
- neighboors(): number[][] {
- let candidates: number[][] = [];
-
- const add = (x: number, y: number): void => {
- if(this.fullAt(x, y)) return;
- if(candidates.some(coord => coord[0] === x && coord[1] === y)) return;
- candidates.push([x, y]);
- };
- for(let y = 0; y < this.shape.length; y++) {
- for(let x = 0; x < this.shape[y].length; x++) {
- // This cell is full, add all it's neighboors.
- if(!this.shape[y][x]) continue;
- add(x-1, y);
- add(x+1, y);
- add(x, y-1);
- add(x, y+1);
- }
- }
- const cells: number[][] = [];
- for(const candidate of candidates) {
- if(cells.some(cell => cell[0] === candidate[0] && cell[1] === candidate[1])) continue;
- cells.push(candidate);
- }
-
- return cells;
- }
-
- copy(): Fragment {
- return new Fragment(this.id, this.shape.map(a => a.slice()), this.type, this.power, this.limit);
- }
+ copy(): Fragment {
+ return new Fragment(
+ this.id,
+ this.shape.map((a) => a.slice()),
+ this.type,
+ this.power,
+ this.limit,
+ );
+ }
}
export function FragmentById(id: number): Fragment | null {
- for(const fragment of Fragments) {
- if(fragment.id === id) return fragment;
- }
- return null;
+ for (const fragment of Fragments) {
+ if (fragment.id === id) return fragment;
+ }
+ return null;
}
+(function () {
+ const _ = false;
+ const X = true;
+ Fragments.push(
+ new Fragment(
+ 0, // id
+ [
+ // shape
+ [X, X, X],
+ [_, _, X],
+ [_, _, X],
+ ],
+ FragmentType.Hacking, // type
+ 10,
+ 1, // limit
+ ),
+ );
+ Fragments.push(
+ new Fragment(
+ 1, // id
+ [
+ // shape
+ [_, X, _],
+ [X, X, X],
+ [_, X, _],
+ ],
+ FragmentType.Hacking, // type
+ 10,
+ 1, // limit
+ ),
+ );
+ Fragments.push(
+ new Fragment(
+ 2, // id
+ [
+ // shape
+ [X, X, X],
+ [X, _, X],
+ [X, X, X],
+ ],
+ FragmentType.Booster, // type
+ 500,
+ 3, // limit
+ ),
+ );
+ Fragments.push(
+ new Fragment(
+ 3, // id
+ [
+ // shape
+ [X, X],
+ [X, X],
+ ],
+ FragmentType.Cooling, // type
+ 200,
+ Infinity, // limit
+ ),
+ );
+ Fragments.push(
+ new Fragment(
+ 4, // id
+ [
+ // shape
+ [X],
+ ],
+ FragmentType.Cooling, // type
+ 50,
+ 1, // limit
+ ),
+ );
+ Fragments.push(
+ new Fragment(
+ 5, // id
+ [
+ // shape
+ [X, X],
+ ],
+ FragmentType.HackingSpeed, // type
+ 50,
+ 1, // limit
+ ),
+ );
-(function() {
- const _ = false;
- const X = true;
- Fragments.push(new Fragment(
- 0, // id
- [ // shape
- [X,X,X],
- [_,_,X],
- [_,_,X],
- ],
- FragmentType.Hacking, // type
- 10,
- 1, // limit
- ));
- Fragments.push(new Fragment(
- 1, // id
- [ // shape
- [_,X,_],
- [X,X,X],
- [_,X,_],
- ],
- FragmentType.Hacking, // type
- 10,
- 1, // limit
- ));
- Fragments.push(new Fragment(
- 2, // id
- [ // shape
- [X,X,X],
- [X,_,X],
- [X,X,X],
- ],
- FragmentType.Booster, // type
- 500,
- 3, // limit
- ));
- Fragments.push(new Fragment(
- 3, // id
- [ // shape
- [X,X],
- [X,X],
- ],
- FragmentType.Cooling, // type
- 200,
- Infinity, // limit
- ));
- Fragments.push(new Fragment(
- 4, // id
- [ // shape
- [X],
- ],
- FragmentType.Cooling, // type
- 50,
- 1, // limit
- ));
- Fragments.push(new Fragment(
- 5, // id
- [ // shape
- [X, X],
- ],
- FragmentType.HackingSpeed, // type
- 50,
- 1, // limit
- ));
-
- Fragments.push(new Fragment(
- 6, // id
- [
- [X, _],
- [X, X],
- ], // shape
- FragmentType.HackingMoney, // type
- 10, // power
- 1, // limit
- ));
- Fragments.push(new Fragment(
- 7, // id
- [
- [X, X],
- [X, X],
- ], // shape
- FragmentType.HackingGrow, // type
- 30, // power
- 1, // limit
- ));
- Fragments.push(new Fragment(
- 8, // id
- [
- [X, X, X],
- [_, X, _],
- [X, X, X],
- ], // shape
- FragmentType.Hacking, // type
- 50, // power
- 1, // limit
- ));
- Fragments.push(new Fragment(
- 10, // id
- [
- [X, X],
- [_, X],
- ], // shape
- FragmentType.Strength, // type
- 50, // power
- 1, // limit
- ));
- Fragments.push(new Fragment(
- 12, // id
- [
- [_, X],
- [X, X],
- ], // shape
- FragmentType.Defense, // type
- 50, // power
- 1, // limit
- ));
- Fragments.push(new Fragment(
- 14, // id
- [
- [X, X],
- [X, _],
- ], // shape
- FragmentType.Dexterity, // type
- 50, // power
- 1, // limit
- ));
- Fragments.push(new Fragment(
- 16, // id
- [
- [X, _],
- [X, X],
- ], // shape
- FragmentType.Agility, // type
- 50, // power
- 1, // limit
- ));
- Fragments.push(new Fragment(
- 18, // id
- [
- [X, X],
- [X, _],
- ], // shape
- FragmentType.Charisma, // type
- 50, // power
- 1, // limit
- ));
- Fragments.push(new Fragment(
- 20, // id
- [
- [X, _, _],
- [X, X, _],
- [X, X, X],
- ], // shape
- FragmentType.HacknetMoney, // type
- 30, // power
- 1, // limit
- ));
- Fragments.push(new Fragment(
- 21, // id
- [
- [X, X],
- [_, X],
- [_, X],
- ], // shape
- FragmentType.HacknetCost, // type
- -10, // power
- 1, // limit
- ));
- Fragments.push(new Fragment(
- 25, // id
- [
- [X, X, X],
- [_, X, _],
- ], // shape
- FragmentType.Rep, // type
- 100, // power
- 1, // limit
- ));
- Fragments.push(new Fragment(
- 27, // id
- [
- [X, _],
- [_, X],
- ], // shape
- FragmentType.WorkMoney, // type
- 20, // power
- 1, // limit
- ));
- Fragments.push(new Fragment(
- 28, // id
- [
- [X, X],
- ], // shape
- FragmentType.Crime, // type
- 20, // power
- 1, // limit
- ));
- Fragments.push(new Fragment(
- 30, // id
- [
- [X, X, X],
- [X, X, X],
- [X, X, X],
- ], // shape
- FragmentType.Bladeburner, // type
- 50, // power
- 1, // limit
- ));
+ Fragments.push(
+ new Fragment(
+ 6, // id
+ [
+ [X, _],
+ [X, X],
+ ], // shape
+ FragmentType.HackingMoney, // type
+ 10, // power
+ 1, // limit
+ ),
+ );
+ Fragments.push(
+ new Fragment(
+ 7, // id
+ [
+ [X, X],
+ [X, X],
+ ], // shape
+ FragmentType.HackingGrow, // type
+ 30, // power
+ 1, // limit
+ ),
+ );
+ Fragments.push(
+ new Fragment(
+ 8, // id
+ [
+ [X, X, X],
+ [_, X, _],
+ [X, X, X],
+ ], // shape
+ FragmentType.Hacking, // type
+ 50, // power
+ 1, // limit
+ ),
+ );
+ Fragments.push(
+ new Fragment(
+ 10, // id
+ [
+ [X, X],
+ [_, X],
+ ], // shape
+ FragmentType.Strength, // type
+ 50, // power
+ 1, // limit
+ ),
+ );
+ Fragments.push(
+ new Fragment(
+ 12, // id
+ [
+ [_, X],
+ [X, X],
+ ], // shape
+ FragmentType.Defense, // type
+ 50, // power
+ 1, // limit
+ ),
+ );
+ Fragments.push(
+ new Fragment(
+ 14, // id
+ [
+ [X, X],
+ [X, _],
+ ], // shape
+ FragmentType.Dexterity, // type
+ 50, // power
+ 1, // limit
+ ),
+ );
+ Fragments.push(
+ new Fragment(
+ 16, // id
+ [
+ [X, _],
+ [X, X],
+ ], // shape
+ FragmentType.Agility, // type
+ 50, // power
+ 1, // limit
+ ),
+ );
+ Fragments.push(
+ new Fragment(
+ 18, // id
+ [
+ [X, X],
+ [X, _],
+ ], // shape
+ FragmentType.Charisma, // type
+ 50, // power
+ 1, // limit
+ ),
+ );
+ Fragments.push(
+ new Fragment(
+ 20, // id
+ [
+ [X, _, _],
+ [X, X, _],
+ [X, X, X],
+ ], // shape
+ FragmentType.HacknetMoney, // type
+ 30, // power
+ 1, // limit
+ ),
+ );
+ Fragments.push(
+ new Fragment(
+ 21, // id
+ [
+ [X, X],
+ [_, X],
+ [_, X],
+ ], // shape
+ FragmentType.HacknetCost, // type
+ -10, // power
+ 1, // limit
+ ),
+ );
+ Fragments.push(
+ new Fragment(
+ 25, // id
+ [
+ [X, X, X],
+ [_, X, _],
+ ], // shape
+ FragmentType.Rep, // type
+ 100, // power
+ 1, // limit
+ ),
+ );
+ Fragments.push(
+ new Fragment(
+ 27, // id
+ [
+ [X, _],
+ [_, X],
+ ], // shape
+ FragmentType.WorkMoney, // type
+ 20, // power
+ 1, // limit
+ ),
+ );
+ Fragments.push(
+ new Fragment(
+ 28, // id
+ [[X, X]], // shape
+ FragmentType.Crime, // type
+ 20, // power
+ 1, // limit
+ ),
+ );
+ Fragments.push(
+ new Fragment(
+ 30, // id
+ [
+ [X, X, X],
+ [X, X, X],
+ [X, X, X],
+ ], // shape
+ FragmentType.Bladeburner, // type
+ 50, // power
+ 1, // limit
+ ),
+ );
})();
export const NoneFragment = new Fragment(-2, [], FragmentType.None, 0, Infinity);
diff --git a/src/CotMG/ui/FragmentInspector.tsx b/src/CotMG/ui/FragmentInspector.tsx
index b1d374d8c..5e134f7d0 100644
--- a/src/CotMG/ui/FragmentInspector.tsx
+++ b/src/CotMG/ui/FragmentInspector.tsx
@@ -9,9 +9,11 @@ import Typography from "@mui/material/Typography";
type IProps = {
fragment: ActiveFragment | null;
+ x: number;
+ y: number;
};
-export function FragmentInspector(props: IProps) {
+export function FragmentInspector(props: IProps): React.ReactElement {
const [, setC] = useState(new Date());
useEffect(() => {
@@ -38,6 +40,7 @@ export function FragmentInspector(props: IProps) {
[X, Y] N/A
+ [X, Y] {props.x}, {props.y}
);
@@ -68,8 +71,9 @@ export function FragmentInspector(props: IProps) {
Effect: {effect}
- [X, Y] {props.fragment.x}, {props.fragment.y}
+ root [X, Y] {props.fragment.x}, {props.fragment.y}
+ [X, Y] {props.x}, {props.y}
);
diff --git a/src/CotMG/ui/Grid.tsx b/src/CotMG/ui/Grid.tsx
index ccde634a1..c9d005e11 100644
--- a/src/CotMG/ui/Grid.tsx
+++ b/src/CotMG/ui/Grid.tsx
@@ -1,5 +1,5 @@
import * as React from "react";
-import { Fragment, Fragments, NoneFragment } from "../Fragment";
+import { Fragment, NoneFragment } from "../Fragment";
import { ActiveFragment } from "../ActiveFragment";
import { FragmentType } from "../FragmentType";
import { IStaneksGift } from "../IStaneksGift";
@@ -7,6 +7,9 @@ import { Cell } from "./Cell";
import { FragmentInspector } from "./FragmentInspector";
import { FragmentSelector } from "./FragmentSelector";
import Button from "@mui/material/Button";
+import TableRow from "@mui/material/TableRow";
+import TableBody from "@mui/material/TableBody";
+import { Table } from "../../ui/React/Table";
function zeros(dimensions: number[]): any {
const array = [];
@@ -116,9 +119,9 @@ export function Grid(props: GridProps): React.ReactElement {
);
}
elems.push(
-