work a bit more on movement.

This commit is contained in:
Your Name 2023-07-22 21:27:58 -04:00
parent 6924d27ba7
commit d0eab203c7
11 changed files with 185 additions and 69 deletions

@ -9,6 +9,7 @@ export * from "./Faction/Enums";
export * from "./Literature/Enums";
export * from "./Locations/Enums";
export * from "./Message/Enums";
export * from "./Myrian/Enums";
export * from "./Programs/Enums";
export * from "./StockMarket/Enums";
export * from "./ui/Enums";

3
src/Myrian/Enums.ts Normal file

@ -0,0 +1,3 @@
export enum MyrianActions {
MOVE = "MOVE",
}

@ -1,7 +1,7 @@
import { SleeveMyrianWork } from "../PersonObjects/Sleeve/Work/SleeveMyrianWork";
import { DefaultWorld } from "./World";
import { constructorsForReviver, Generic_toJSON, Generic_fromJSON, IReviverValue } from "../utils/JSONReviver";
import { Player } from "@player";
import { DefaultWorld } from "./World";
interface MyrianSleeve {
index: number;
@ -38,7 +38,8 @@ export class Myrian {
/** Initializes a Myrian object from a JSON save state. */
static fromJSON(value: IReviverValue): Myrian {
return Generic_fromJSON(Myrian, value.data);
const v = Generic_fromJSON(Myrian, value.data);
return v;
}
}

@ -1,12 +1,38 @@
const e = ''; // empty
const c = 'c'; // core
const b = 'b'; // battery
const d = 'd'; // depleted
const e = " "; // empty
const c = "c"; // core
const b = "b"; // battery
const d = "d"; // depleted
export const DefaultWorld = [
[b, b, b, b, b],
[e, e, e, e, e],
[e, e, c, e, e],
[e, e, e, e, e],
[b, b, b, d, d],
];
const raw = `
mmmmmmm
mmmmmmmm
mmmmmmmmmmmm
bbbb mmmmm
mmmm
c mmmm
mmmm
ddddd mmmm
mmmmmmmmmm
mmmmmmmm
mmmmmmmm mmmm
`;
export const DefaultWorld = raw.split("\n").map((l) => l.split(""));
console.log(DefaultWorld);

@ -7,6 +7,7 @@ import PersonIcon from "@mui/icons-material/Person";
import BatteryFullIcon from "@mui/icons-material/BatteryFull";
import Battery20Icon from "@mui/icons-material/Battery20";
import FavoriteIcon from "@mui/icons-material/Favorite";
import LandscapeIcon from "@mui/icons-material/Landscape";
const iterator = (i: number): number[] => {
return Array(i).fill(0);
@ -26,17 +27,20 @@ const Cell = ({ tile }: ICellProps): React.ReactElement => {
return (
<div
style={{
minWidth: x + "px",
width: x + "px",
minHeight: x + "px",
height: x + "px",
margin: "0px",
padding: "0px",
}}
>
{tile === "" && <div />}
{tile === "&nbsp;" && <div />}
{tile === "b" && <BatteryFullIcon sx={sx} />}
{tile === "d" && <Battery20Icon sx={sx} />}
{tile === "c" && <FavoriteIcon sx={sx} />}
{tile === "s" && <PersonIcon sx={sx} />}
{tile === "m" && <LandscapeIcon sx={sx} />}
</div>
);
};
@ -49,7 +53,7 @@ export function MyrianRoot({ myrian }: IProps): React.ReactElement {
const [, setRerender] = useState(false);
const rerender = () => setRerender((old) => !old);
useEffect(() => {
const intervalID = setInterval(rerender, 200);
const intervalID = setInterval(rerender, 20);
return () => clearInterval(intervalID);
}, []);

30
src/Myrian/world.txt Normal file

@ -0,0 +1,30 @@
mmmmmmm
mmmmmmmm
mmmmmmmmmmmm
bbbb mmmmm
mmmm
c mmmm
mmmm
ddddd mmmm
mmmmmmmmmm
mmmmmmmm
mmmmmmmm mmmm

@ -1,9 +1,23 @@
import { Player } from "@player";
import { NSFull } from "../NetscriptFunctions";
import { NS } from "@nsdefs";
import { INetscriptExtra } from "../NetscriptFunctions/Extra";
// Made with the help of this question
// https://stackoverflow.com/questions/76723668/how-to-make-a-typescript-utility-type-representing-only-the-functions-of-an-obje?noredirect=1#comment135264239_76723668
type EmptyObjToNever<T> = {} extends T ? never : T;
type PickFuncs<T> = T extends Function
? T
: T extends readonly any[]
? never
: T extends object
? EmptyObjToNever<{ [K in keyof T as PickFuncs<T[K]> extends never ? never : K]: PickFuncs<T[K]> }>
: never;
/** The API does not include enums, args, or pid. */
export type RamCostTree<API> = {
[key in keyof API]: API[key] extends () => unknown ? number | (() => number) : RamCostTree<API[key]>;
[key in keyof PickFuncs<API>]: PickFuncs<API>[key] extends () => unknown
? number | (() => number)
: RamCostTree<PickFuncs<API>[key]>;
};
/** Constants for assigning costs to ns functions */
@ -326,15 +340,16 @@ const stanek = {
} as const;
const myr = {
ianUse: 5.9,
ianMove: 3.4,
ianAct: 5.9,
ianGetTile: 1.4,
ianWorldSize: 3.333,
ianGetSleeve: 2,
ianGetTask: 1.1,
ianCancelTask: 1.2,
ianEnter: 0.2,
ianLeave: 0.2,
ianDeploy: 4.1,
ianApplyPowerup: 10.9,
};
} as const;
// UI API
const ui = {
@ -424,7 +439,7 @@ const corporation = {
* An error will be generated if there are missing OR additional ram costs defined.
* To avoid errors, define every function in NetscriptDefinition.d.ts and NetscriptFunctions,
* and have a ram cost associated here. */
export const RamCosts: RamCostTree<NSFull> = {
export const RamCosts: RamCostTree<NS & INetscriptExtra> = {
corporation,
hacknet,
stock,

@ -24,6 +24,7 @@ import {
LocationName,
ToastVariant,
UniversityClassType,
MyrianActions,
} from "@enums";
import { PromptEvent } from "./ui/React/PromptManager";
import { GetServer, DeleteServer, AddToAllServers, createUniqueRandomIp } from "./Server/AllServers";
@ -112,6 +113,7 @@ export const enums: NSEnums = {
LocationName,
ToastVariant,
UniversityClassType,
MyrianActions,
};
for (const val of Object.values(enums)) Object.freeze(val);
Object.freeze(enums);

@ -1,28 +1,56 @@
import { Myr as IMyrian } from "@nsdefs";
import { InternalAPI } from "src/Netscript/APIWrapper";
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
import { helpers } from "../Netscript/NetscriptHelpers";
import { Player as player } from "../Player";
import { myrian } from "../Myrian/Helpers";
import { MyrianActions } from "@enums";
const move = (ctx: NetscriptContext, id: number, x: number, y: number) => {
if (!player.sleeves[id]) throw new Error(`No sleeve with index ${id}`);
const myrSleeve = myrian.sleeves.find((s) => s.index === id);
if (!myrSleeve) throw new Error("Invalid move");
const dist = Math.abs(myrSleeve.x - x) + Math.abs(myrSleeve.y - y);
if (dist > 1) throw new Error("Invalid move");
return helpers.netscriptDelay(ctx, 100).then(function () {
myrSleeve.x = x;
myrSleeve.y = y;
return Promise.resolve();
});
};
export function NetscriptMyrian(): InternalAPI<IMyrian> {
return {
ianUse: (ctx) => (_sleeveId, _x, _y) => {
throw new Error("Unimplemented");
},
ianMove: (ctx) => async (_sleeveId, _x, _y) => {
const id = helpers.number(ctx, "sleeveId", _sleeveId);
ianAct: (ctx) => (_action, _sleeveId, _x, _y) => {
const action = helpers.string(ctx, "action", _action);
const x = helpers.number(ctx, "x", _x);
const y = helpers.number(ctx, "y", _y);
if (!player.sleeves[id]) throw new Error(`No sleeve with index ${id}`);
const myrSleeve = myrian.sleeves.find((s) => s.index === id);
if (!myrSleeve) return Promise.resolve();
const dist = Math.abs(myrSleeve.x - x) + Math.abs(myrSleeve.y - y);
if (dist > 1) return Promise.resolve();
return helpers.netscriptDelay(ctx, 1000).then(function () {
myrSleeve.x = x;
myrSleeve.y = y;
return Promise.resolve();
});
const sleeveId = helpers.number(ctx, "sleeveId", _sleeveId);
switch (action) {
case MyrianActions.MOVE:
return move(ctx, sleeveId, x, y);
}
return Promise.reject("Invalid action");
},
ianWorldSize: (ctx) => () => {
return [myrian.world.length, myrian.world[0].length];
},
ianGetSleeve: (ctx) => (_sleeveId) => {
const sleeveId = helpers.number(ctx, "sleeveId", _sleeveId);
const sl = myrian.sleeves.find((s) => s.index === sleeveId);
if (!sl) {
return { inside: false, x: 0, y: 0 };
}
return { inside: true, x: sl.x, y: sl.y };
},
ianGetTile: (ctx) => (_x, _y) => {
const x = helpers.number(ctx, "x", _x);
const y = helpers.number(ctx, "y", _y);
return {
Content: myrian.world[y][x],
};
},
ianGetTask: (ctx) => (_sleeveId) => {
throw new Error("Unimplemented");
@ -41,9 +69,6 @@ export function NetscriptMyrian(): InternalAPI<IMyrian> {
ianLeave: (ctx) => (_sleeveId?) => {
throw new Error("Unimplemented");
},
ianDeploy: (ctx) => (_sleeveId, _deploymentId, _x, _y) => {
throw new Error("Unimplemented");
},
ianApplyPowerup: (ctx) => (_sleeveId, _stat) => {
throw new Error("Unimplemented");
},

@ -1,5 +1,7 @@
/** All netscript definitions */
import { string } from "prop-types";
/** @public */
interface HP {
current: number;
@ -2710,6 +2712,20 @@ export interface Hacknet {
getTrainingMult(): number;
}
export interface MyrianTile {
Content: string;
}
export interface MyrianSleeve {
x: number;
y: number;
inside: boolean;
}
export declare enum MyrianActions {
MOVE = "MOVE",
}
/**
* Myrian API
* @remarks
@ -2719,28 +2735,18 @@ export interface Hacknet {
*/
export interface Myr {
/**
* Interact with an object in The Myrian.
* @remarks
* Take an action in The Myrian.
*
* The effect is different depending on the object.
* Interacting with an enemy will attack it.
* With a resource node will mine it.
* With a power up will collect it.
* With a rock will try to break it.
*
* @returns Amount of milliseconds the operation will take.
* @returns A promise to be resolved when the action is over.
*/
ianUse(sleeveId: number, x: number, y: number): number;
ianAct(action: MyrianActions, sleeveId: number, x: number, y: number): Promise<void>;
/**
* Move a sleeve in the Myrian.
* @remarks
* Get the content of a tile.
*
* The target tile must be 1 tile away from the sleeves current tile.
*
* @returns Amount of milliseconds the operation will take.
* @returns The content of the tile.
*/
ianMove(sleeveId: number, x: number, y: number): Promise<void>;
ianGetTile(x: number, y: number): MyrianTile;
/**
* Get that sleeves current task in the Myrian.
@ -2759,6 +2765,18 @@ export interface Myr {
*/
ianCancelTask(sleeveId): boolean;
/**
* Get the size of the world.
* @returns [width, height] of the world.
*/
ianWorldSize(): [number, number];
/**
* Get information about a sleeve and it's property related to The Myrian.
* @returns Information about a sleeve in The Myrian.
*/
ianGetSleeve(sleeveId: number): MyrianSleeve;
/**
* Makes the player or a sleeve enter The Myrian.
* @remarks
@ -2777,16 +2795,6 @@ export interface Myr {
*/
ianLeave(sleeveId?: number): boolean;
/**
* Deploy an entity in The Myrian.
* @remarks
*
* Sleeves must be 1 tile away from the target tile and the player must have enough resources to build the entity.
*
* @returns The amount of milliseconds needed to complete the operation. or -1 if failed.
*/
ianDeploy(sleeveId: number, deploymentId: number, x: number, y: number): number;
/**
* Apply a Myrian powerup to a sleeve.
* @remarks
@ -6964,6 +6972,7 @@ export type NSEnums = {
LocationName: typeof LocationName;
ToastVariant: typeof ToastVariant;
UniversityClassType: typeof UniversityClassType;
MyrianActions: typeof MyrianActions;
};
/**

@ -15,7 +15,7 @@
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"target": "es2022"
"target": "es2022"
},
"include": ["src/**/*", "electron/**/*", "node_modules/monaco-editor/monaco.d.ts"]
}