mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-26 19:14:32 +02:00
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:
@@ -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: </td><td id="character-int-text" className="character-stat-cell">{(Player.intelligence).toLocaleString()}</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
const intelligence = (
|
||||
<tr id="character-int-wrapper">
|
||||
<td>Int: </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: </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: </td><td id="character-hack-text" className="character-stat-cell">{(Player.hacking_skill).toLocaleString()}</td>
|
||||
</tr>
|
||||
<tr id="character-str-wrapper">
|
||||
<td>Str: </td><td id="character-str-text" className="character-stat-cell">{(Player.strength).toLocaleString()}</td>
|
||||
</tr>
|
||||
<tr id="character-def-wrapper">
|
||||
<td>Def: </td><td id="character-def-text" className="character-stat-cell">{(Player.defense).toLocaleString()}</td>
|
||||
</tr>
|
||||
<tr id="character-dex-wrapper">
|
||||
<td>Dex: </td><td id="character-dex-text" className="character-stat-cell">{(Player.dexterity).toLocaleString()}</td>
|
||||
</tr>
|
||||
<tr id="character-agi-wrapper">
|
||||
<td>Agi: </td><td id="character-agi-text" className="character-stat-cell">{(Player.agility).toLocaleString()}</td>
|
||||
</tr>
|
||||
<tr id="character-cha-wrapper">
|
||||
<td>Cha: </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: </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: </td><td id="character-hack-text" className="character-stat-cell">{(Player.hacking_skill).toLocaleString()}</td>
|
||||
</tr>
|
||||
<tr id="character-str-wrapper">
|
||||
<td>Str: </td><td id="character-str-text" className="character-stat-cell">{(Player.strength).toLocaleString()}</td>
|
||||
</tr>
|
||||
<tr id="character-def-wrapper">
|
||||
<td>Def: </td><td id="character-def-text" className="character-stat-cell">{(Player.defense).toLocaleString()}</td>
|
||||
</tr>
|
||||
<tr id="character-dex-wrapper">
|
||||
<td>Dex: </td><td id="character-dex-text" className="character-stat-cell">{(Player.dexterity).toLocaleString()}</td>
|
||||
</tr>
|
||||
<tr id="character-agi-wrapper">
|
||||
<td>Agi: </td><td id="character-agi-text" className="character-stat-cell">{(Player.agility).toLocaleString()}</td>
|
||||
</tr>
|
||||
<tr id="character-cha-wrapper">
|
||||
<td>Cha: </td><td id="character-cha-text" className="character-stat-cell">{(Player.charisma).toLocaleString()}</td>
|
||||
</tr>
|
||||
{
|
||||
Player.intelligence >= 1 &&
|
||||
intelligence
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user