Fixed merge conflicts. Rebalanced new Hacknet Node mechanics. Adjusted Hacknet API so that it'll work with hacknet Servers. Fixed Corporation bug with Issuing new Shares

This commit is contained in:
danielyxie
2019-03-29 16:13:58 -07:00
137 changed files with 10196 additions and 3142 deletions
+40 -40
View File
@@ -8,47 +8,47 @@ const Component = React.Component;
export class CharacterOverviewComponent extends Component {
render() {
let intelligence = "";
if (Player.intelligence >= 1) {
intelligence=(
<tr id="character-int-wrapper">
<td>Int:&nbsp;</td><td id="character-int-text" className="character-stat-cell">{(Player.intelligence).toLocaleString()}</td>
</tr>
);
}
const intelligence = (
<tr id="character-int-wrapper">
<td>Int:&nbsp;</td><td id="character-int-text" className="character-stat-cell">{(Player.intelligence).toLocaleString()}</td>
</tr>
);
return (
<div id="character-overview-text">
<table>
<tbody>
<tr id="character-hp-wrapper">
<td>Hp:</td><td id="character-hp-text" className="character-stat-cell">{Player.hp + " / " + Player.max_hp}</td>
</tr>
<tr id="character-money-wrapper">
<td>Money:&nbsp;</td><td id="character-money-text" className="character-stat-cell">{numeralWrapper.format(Player.money.toNumber(), '$0.000a')}</td>
</tr>
<tr id="character-hack-wrapper">
<td>Hack:&nbsp;</td><td id="character-hack-text" className="character-stat-cell">{(Player.hacking_skill).toLocaleString()}</td>
</tr>
<tr id="character-str-wrapper">
<td>Str:&nbsp;</td><td id="character-str-text" className="character-stat-cell">{(Player.strength).toLocaleString()}</td>
</tr>
<tr id="character-def-wrapper">
<td>Def:&nbsp;</td><td id="character-def-text" className="character-stat-cell">{(Player.defense).toLocaleString()}</td>
</tr>
<tr id="character-dex-wrapper">
<td>Dex:&nbsp;</td><td id="character-dex-text" className="character-stat-cell">{(Player.dexterity).toLocaleString()}</td>
</tr>
<tr id="character-agi-wrapper">
<td>Agi:&nbsp;</td><td id="character-agi-text" className="character-stat-cell">{(Player.agility).toLocaleString()}</td>
</tr>
<tr id="character-cha-wrapper">
<td>Cha:&nbsp;</td><td id="character-cha-text" className="character-stat-cell">{(Player.charisma).toLocaleString()}</td>
</tr>
{intelligence}
</tbody>
</table>
</div>
<div id="character-overview-text">
<table>
<tbody>
<tr id="character-hp-wrapper">
<td>Hp:</td><td id="character-hp-text" className="character-stat-cell">{Player.hp + " / " + Player.max_hp}</td>
</tr>
<tr id="character-money-wrapper">
<td>Money:&nbsp;</td><td id="character-money-text" className="character-stat-cell">{numeralWrapper.format(Player.money.toNumber(), '$0.000a')}</td>
</tr>
<tr id="character-hack-wrapper">
<td>Hack:&nbsp;</td><td id="character-hack-text" className="character-stat-cell">{(Player.hacking_skill).toLocaleString()}</td>
</tr>
<tr id="character-str-wrapper">
<td>Str:&nbsp;</td><td id="character-str-text" className="character-stat-cell">{(Player.strength).toLocaleString()}</td>
</tr>
<tr id="character-def-wrapper">
<td>Def:&nbsp;</td><td id="character-def-text" className="character-stat-cell">{(Player.defense).toLocaleString()}</td>
</tr>
<tr id="character-dex-wrapper">
<td>Dex:&nbsp;</td><td id="character-dex-text" className="character-stat-cell">{(Player.dexterity).toLocaleString()}</td>
</tr>
<tr id="character-agi-wrapper">
<td>Agi:&nbsp;</td><td id="character-agi-text" className="character-stat-cell">{(Player.agility).toLocaleString()}</td>
</tr>
<tr id="character-cha-wrapper">
<td>Cha:&nbsp;</td><td id="character-cha-text" className="character-stat-cell">{(Player.charisma).toLocaleString()}</td>
</tr>
{
Player.intelligence >= 1 &&
intelligence
}
</tbody>
</table>
</div>
)
}
}
}
+23
View File
@@ -0,0 +1,23 @@
/**
* Text (p Element) with Tooltip
*/
import * as React from "react";
export interface IParagraphWithTooltipProps {
style?: object;
text: string;
tooltip: string;
}
export class ParagraphWithTooltip extends React.Component<IParagraphWithTooltipProps, any> {
render() {
return (
<p className={"tooltip"}>
{this.props.text}
<span className={"tooltiptext"}>
{this.props.tooltip}
</span>
</p>
)
}
}
+24
View File
@@ -0,0 +1,24 @@
/**
* React component for a popup content container
*
* Takes in a prop for rendering the content inside the popup
*/
import * as React from "react";
type ReactComponent = new(...args: any[]) => React.Component<any, any>
interface IProps {
content: ReactComponent;
id: string;
props: object;
}
export class Popup extends React.Component<IProps, any> {
render() {
return (
<div className={"popup-box-content"} id={`${this.props.id}-content`}>
{React.createElement(this.props.content, this.props.props)}
</div>
)
}
}
+67
View File
@@ -0,0 +1,67 @@
/**
* Close button for popup dialog boxes
* It creates an event handler such that pressing Esc will close the binded popup
*
* Should only be used in other React components, otherwise it may not be properly
* unmounted
*/
import * as React from "react";
import * as ReactDOM from "react-dom";
import { KEY } from "../../../utils/helpers/keyCodes";
import { removeElement } from "../../../utils/uiHelpers/removeElement";
export interface IPopupCloseButtonProps {
class?: string;
popup: HTMLElement | string;
style?: object;
text: string;
}
export class PopupCloseButton extends React.Component<IPopupCloseButtonProps, any> {
constructor(props: IPopupCloseButtonProps) {
super(props);
this.closePopup = this.closePopup.bind(this);
this.keyListener = this.keyListener.bind(this);
}
componentDidMount() {
document.addEventListener("keydown", this.keyListener);
}
componentWillUnmount() {
document.removeEventListener("keydown", this.keyListener);
}
closePopup() {
let popup: HTMLElement | null;
if (typeof this.props.popup === "string") {
popup = document.getElementById(this.props.popup);
} else {
popup = this.props.popup;
}
// TODO Check if this is okay? This is essentially calling to unmount a parent component
if (popup instanceof HTMLElement) {
ReactDOM.unmountComponentAtNode(popup); // Removes everything inside the wrapper container
removeElement(popup); // Removes the wrapper container
}
}
keyListener(e: KeyboardEvent) {
if (e.keyCode === KEY.ESC) {
this.closePopup();
}
}
render() {
const className = this.props.class ? this.props.class : "std-button";
return (
<button className={className} onClick={this.closePopup} style={this.props.style}>
{this.props.text}
</button>
)
}
}
+65
View File
@@ -0,0 +1,65 @@
/**
* Creates a dropdown (select HTML element) with server hostnames as options
*
* Configurable to only contain certain types of servers
*/
import React from "react";
import { AllServers } from "../../Server/AllServers";
import { HacknetServer } from "../../Hacknet/HacknetServer";
// TODO make this an enum when this gets converted to TypeScript
export const ServerType = {
All: 0,
Foreign: 1, // Hackable, non-owned servers
Owned: 2, // Home Computer, Purchased Servers, and Hacknet Servers
Purchased: 3, // Everything from Owned except home computer
}
export class ServerDropdown extends React.Component {
/**
* Checks if the server should be shown in the dropdown menu, based on the
* 'serverType' property
*/
isValidServer(s) {
const type = this.props.serverType;
switch (type) {
case ServerType.All:
return true;
case ServerType.Foreign:
return (s.hostname !== "home" && !s.purchasedByPlayer);
case ServerType.Owned:
return s.purchasedByPlayer || (s instanceof HacknetServer) || s.hostname === "home";
case ServerType.Purchased:
return s.purchasedByPlayer || (s instanceof HacknetServer);
default:
console.warn(`Invalid ServerType specified for ServerDropdown component: ${type}`);
return false;
}
}
/**
* Given a Server object, creates a Option element
*/
renderOption(s) {
return (
<option key={s.hostname} value={s.hostname}>{s.hostname}</option>
)
}
render() {
const servers = [];
for (const serverName in AllServers) {
const server = AllServers[serverName];
if (this.isValidServer(server)) {
servers.push(this.renderOption(server));
}
}
return (
<select className={"dropdown"} onChange={this.props.onChange} style={this.props.style}>
{servers}
</select>
)
}
}
+24
View File
@@ -0,0 +1,24 @@
/**
* Basic stateless button
* Uses the 'std-button' css class
*/
import * as React from "react";
export interface IStdButtonProps {
disabled?: boolean;
onClick?: (e: React.MouseEvent<HTMLElement>) => any;
style?: object;
text: string;
}
export class StdButton extends React.Component<IStdButtonProps, any> {
render() {
const className = this.props.disabled ? "std-button-disabled" : "std-button";
return (
<button className={className} onClick={this.props.onClick} style={this.props.style}>
{this.props.text}
</button>
)
}
}
+28
View File
@@ -0,0 +1,28 @@
/**
* Basic stateless button with a tooltip
* Uses the 'std-button' css class
*/
import * as React from "react";
export interface IStdButtonWithTooltipProps {
disabled?: boolean;
onClick?: (e: React.MouseEvent<HTMLElement>) => any;
style?: object;
text: string;
tooltip: string;
}
export class StdButtonWithTooltip extends React.Component<IStdButtonWithTooltipProps, any> {
render() {
const className = this.props.disabled ? "std-button-disabled tooltip" : "std-button tooltip";
return (
<button className={className} onClick={this.props.onClick} style={this.props.style}>
{this.props.text}
<span className={"tooltiptext"}>
{this.props.tooltip}
</span>
</button>
)
}
}
+60
View File
@@ -0,0 +1,60 @@
/**
* Create a pop-up dialog box using React.
*
* Calling this function with the same ID and React Root Component will trigger a re-render
*
* @param id The (hopefully) unique identifier for the popup container
* @param rootComponent Root React Component for the content (NOT the popup containers themselves)
*/
import * as React from "react";
import * as ReactDOM from "react-dom";
import { Popup } from "./Popup";
import { createElement } from "../../../utils/uiHelpers/createElement";
import { removeElementById } from "../../../utils/uiHelpers/removeElementById";
type ReactComponent = new(...args: any[]) => React.Component<any, any>;
let gameContainer: HTMLElement;
function getGameContainer() {
let container = document.getElementById("entire-game-container");
if (container == null) {
throw new Error(`Failed to find game container DOM element`)
}
gameContainer = container;
document.removeEventListener("DOMContentLoaded", getGameContainer);
}
document.addEventListener("DOMContentLoaded", getGameContainer);
export function createPopup(id: string, rootComponent: ReactComponent, props: object): HTMLElement | null {
let container = document.getElementById(id);
if (container == null) {
container = createElement("div", {
class: "popup-box-container",
display: "flex",
id: id,
});
gameContainer.appendChild(container);
}
ReactDOM.render(<Popup content={rootComponent} id={id} props={props} />, container);
return container;
}
/**
* Closes a popup created with the createPopup() function above
*/
export function removePopup(id: string): void {
let content = document.getElementById(`${id}`);
if (content == null) { return; }
ReactDOM.unmountComponentAtNode(content);
removeElementById(id);
}