character overview in mui

This commit is contained in:
Olivier Gagnon 2021-09-16 17:30:47 -04:00
parent 088657f162
commit f0f57150aa
6 changed files with 217 additions and 249 deletions

@ -5,120 +5,8 @@
* Styling for the Character Overview Panel (top-right panel) * Styling for the Character Overview Panel (top-right panel)
*/ */
#character-overview-wrapper { #character-overview {
position: fixed; position: fixed;
top: 0; top: 0;
right: 0; right: 0;
} }
#character-overview-container {
display: none;
position: absolute; /* Stay in place */
right: 0;
top: 0;
height: auto; /* Full height */
padding: 10px 2px;
border: 2px solid var(--my-highlight-color);
width: auto;
max-width: 280px;
overflow: auto; /* Enable scroll if needed */
background-color: rgba(57, 54, 54, 0.9); /* Fallback color */
z-index: 1;
}
#character-overview-text {
color: $my-stat-physical;
table {
border-collapse: collapse;
margin: auto;
}
td {
padding: 2px;
vertical-align: middle;
}
}
.character-stat-text {
color: #fff;
background-color: #444;
}
.character-stat-cell {
text-align: right;
}
#character-str-wrapper td,
#character-cha-wrapper td {
padding-top: 10px;
}
.character-divider td {
border-top: 1px #aaa solid;
padding-top: 10px;
}
#character-hp-wrapper {
color: $my-stat-hp-color;
}
.character-hp-cell {
color: $my-stat-hp-color;
}
#character-money-wrapper {
color: $my-stat-money-color;
}
.character-money-cell {
color: $my-stat-money-color;
}
#character-hack-wrapper {
color: $my-stat-hack-color;
}
.character-hack-cell {
color: $my-stat-hack-color;
}
#character-cha-wrapper {
color: $my-stat-cha-color;
}
.character-cha-cell {
color: $my-stat-cha-color;
}
#character-int-wrapper {
color: $my-stat-int-color;
}
.character-int-cell {
color: $my-stat-int-color;
}
.character-combat-cell {
color: $my-stat-physical;
}
#character-work-wrapper {
color: $my-stat-hack-color;
}
.character-work-cell {
color: $my-stat-hack-color;
}
.character-overview-btn {
@include borderRadius(12px);
@include boxShadow(1px 1px 3px #000);
color: #cecece;
display: inline-block;
font-size: $defaultFontSize * 0.875;
font-weight: bold;
height: 25px;
background-color: #000;
padding: 5px 8px;
}
.character-quick-options {
margin-top: 10px;
text-align: center;
}
.character-overview-btn:hover,
.character-overview-btn:focus {
color: #fff;
text-decoration: none;
cursor: pointer;
}

@ -197,12 +197,6 @@ export function prestigeSourceFile() {
} }
} }
const characterMenuHeader = document.getElementById("character-menu-header");
if (characterMenuHeader instanceof HTMLElement) {
characterMenuHeader.click();
characterMenuHeader.click();
}
this.timeWorked = 0; this.timeWorked = 0;
// Gang // Gang
@ -2065,9 +2059,6 @@ export function applyForJob(entryPosType, sing = false) {
this.jobs[company.name] = pos.name; this.jobs[company.name] = pos.name;
this.companyName = this.location; this.companyName = this.location;
document.getElementById("world-menu-header").click();
document.getElementById("world-menu-header").click();
if (sing) { if (sing) {
return true; return true;
} }
@ -2183,8 +2174,6 @@ export function applyForEmployeeJob(sing = false) {
if (this.isQualified(company, CompanyPositions[posNames.MiscCompanyPositions[1]])) { if (this.isQualified(company, CompanyPositions[posNames.MiscCompanyPositions[1]])) {
this.companyName = company.name; this.companyName = company.name;
this.jobs[company.name] = posNames.MiscCompanyPositions[1]; this.jobs[company.name] = posNames.MiscCompanyPositions[1];
document.getElementById("world-menu-header").click();
document.getElementById("world-menu-header").click();
if (sing) { if (sing) {
return true; return true;
} }
@ -2201,8 +2190,6 @@ export function applyForPartTimeEmployeeJob(sing = false) {
var company = Companies[this.location]; //Company being applied to var company = Companies[this.location]; //Company being applied to
if (this.isQualified(company, CompanyPositions[posNames.PartTimeCompanyPositions[1]])) { if (this.isQualified(company, CompanyPositions[posNames.PartTimeCompanyPositions[1]])) {
this.jobs[company.name] = posNames.PartTimeCompanyPositions[1]; this.jobs[company.name] = posNames.PartTimeCompanyPositions[1];
document.getElementById("world-menu-header").click();
document.getElementById("world-menu-header").click();
if (sing) { if (sing) {
return true; return true;
} }
@ -2220,8 +2207,6 @@ export function applyForWaiterJob(sing = false) {
if (this.isQualified(company, CompanyPositions[posNames.MiscCompanyPositions[0]])) { if (this.isQualified(company, CompanyPositions[posNames.MiscCompanyPositions[0]])) {
this.companyName = company.name; this.companyName = company.name;
this.jobs[company.name] = posNames.MiscCompanyPositions[0]; this.jobs[company.name] = posNames.MiscCompanyPositions[0];
document.getElementById("world-menu-header").click();
document.getElementById("world-menu-header").click();
if (sing) { if (sing) {
return true; return true;
} }
@ -2239,8 +2224,6 @@ export function applyForPartTimeWaiterJob(sing = false) {
if (this.isQualified(company, CompanyPositions[posNames.PartTimeCompanyPositions[0]])) { if (this.isQualified(company, CompanyPositions[posNames.PartTimeCompanyPositions[0]])) {
this.companyName = company.name; this.companyName = company.name;
this.jobs[company.name] = posNames.PartTimeCompanyPositions[0]; this.jobs[company.name] = posNames.PartTimeCompanyPositions[0];
document.getElementById("world-menu-header").click();
document.getElementById("world-menu-header").click();
if (sing) { if (sing) {
return true; return true;
} }

@ -96,6 +96,7 @@ const Engine = {
redPillContent: null, redPillContent: null,
cinematicTextContent: null, cinematicTextContent: null,
missionContent: null, missionContent: null,
overview: null,
}, },
indexedDb: undefined, indexedDb: undefined,
@ -309,7 +310,7 @@ const Engine = {
loadMissionContent: function () { loadMissionContent: function () {
Engine.hideAllContent(); Engine.hideAllContent();
document.getElementById("mainmenu-container").style.visibility = "hidden"; document.getElementById("mainmenu-container").style.visibility = "hidden";
document.getElementById("character-overview-wrapper").style.visibility = "hidden"; document.getElementById("character-overview").style.visibility = "hidden";
Engine.Display.missionContent.style.display = "block"; Engine.Display.missionContent.style.display = "block";
routing.navigateTo(Page.Mission); routing.navigateTo(Page.Mission);
}, },
@ -397,15 +398,12 @@ const Engine = {
}, },
displayCharacterOverviewInfo: function () { displayCharacterOverviewInfo: function () {
ReactDOM.render(<CharacterOverview player={Player} />, document.getElementById("character-overview-text")); ReactDOM.render(
<Theme>
const save = document.getElementById("character-overview-save-button"); <CharacterOverview player={Player} save={() => saveObject.saveGame(Engine.indexedDb)} />
const flashClass = "flashing-button"; </Theme>,
if (!Settings.AutosaveInterval) { document.getElementById("character-overview"),
save.classList.add(flashClass); );
} else {
save.classList.remove(flashClass);
}
}, },
// Main Game Loop // Main Game Loop
@ -575,11 +573,6 @@ const Engine = {
} }
} }
if (Engine.Counters.updateDisplays <= 0) {
Engine.displayCharacterOverviewInfo();
Engine.Counters.updateDisplays = 3;
}
if (Engine.Counters.checkFactionInvitations <= 0) { if (Engine.Counters.checkFactionInvitations <= 0) {
const invitedFactions = Player.checkForFactionInvitations(); const invitedFactions = Player.checkForFactionInvitations();
if (invitedFactions.length > 0) { if (invitedFactions.length > 0) {
@ -879,16 +872,12 @@ const Engine = {
// Cinematic Text // Cinematic Text
Engine.Display.cinematicTextContent = document.getElementById("cinematic-text-container"); Engine.Display.cinematicTextContent = document.getElementById("cinematic-text-container");
Engine.Display.cinematicTextContent.style.display = "none"; Engine.Display.cinematicTextContent.style.display = "none";
Engine.Display.overview = document.getElementById("character-overview");
}, },
// Initialization // Initialization
init: function () { init: function () {
// Character Overview buttons
document.getElementById("character-overview-save-button").addEventListener("click", function () {
saveObject.saveGame(Engine.indexedDb);
return false;
});
// Message at the top of terminal // Message at the top of terminal
postVersion(); postVersion();
@ -922,10 +911,9 @@ const Engine = {
} }
Engine.loadWorkInProgressContent(); Engine.loadWorkInProgressContent();
}
// Character overview screen Engine.displayCharacterOverviewInfo();
document.getElementById("character-overview-container").style.display = "block"; }
}, },
start: function () { start: function () {

@ -96,16 +96,7 @@
</div> </div>
<!-- Character Overview Screen --> <!-- Character Overview Screen -->
<div id="character-overview-wrapper"> <div id="character-overview"></div>
<div id="character-overview-container">
<div id="character-overview-text">
<!-- ReactJS Component -->
</div>
<div class="character-quick-options noselect">
<button id="character-overview-save-button" class="character-overview-btn">Save Game</button>
</div>
</div>
</div>
<!-- Status text --> <!-- Status text -->
<div id="status-text-container"> <div id="status-text-container">

@ -1,102 +1,207 @@
// Root React Component for the Corporation UI // Root React Component for the Corporation UI
import React from "react"; import React, { useState, useEffect } from "react";
import { makeStyles } from "@material-ui/core/styles";
import { IPlayer } from "../../PersonObjects/IPlayer"; import { IPlayer } from "../../PersonObjects/IPlayer";
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
import { Reputation } from "./Reputation"; import { Reputation } from "./Reputation";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableContainer from "@material-ui/core/TableContainer";
import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow";
import Paper from "@material-ui/core/Paper";
import Box from "@material-ui/core/Box";
import Typography from "@material-ui/core/Typography";
import Divider from "@material-ui/core/Divider";
import Button from "@material-ui/core/Button";
import Collapse from "@material-ui/core/Collapse";
import { colors } from "./Theme";
interface IProps { interface IProps {
player: IPlayer; player: IPlayer;
save: () => void;
} }
export function CharacterOverview(props: IProps): React.ReactElement { function Intelligence({ player }: { player: IPlayer }): React.ReactElement {
const intelligence = ( if (player.intelligence === 0) return <></>;
<tr id="character-int-wrapper"> const classes = useStyles();
<td className="character-int-cell">Int:&nbsp;</td> return (
<td id="character-int-text" className="character-int-cell character-stat-cell"> <TableRow>
{numeralWrapper.formatSkill(props.player.intelligence)} <TableCell component="th" scope="row" classes={{ root: classes.cell }}>
</td> <Typography classes={{ root: classes.int }}>Int&nbsp;</Typography>
</tr> </TableCell>
); <TableCell align="right" classes={{ root: classes.cell }}>
<Typography classes={{ root: classes.int }}>{numeralWrapper.formatSkill(player.intelligence)}</Typography>
const work = ( </TableCell>
<> </TableRow>
<tr className="character-divider">
<td colSpan={2}>Work progress:</td>
</tr>
<tr>
<td colSpan={2}>+{Reputation(props.player.workRepGained)} rep</td>
</tr>
<tr>
<td colSpan={2}>
<button
onClick={() => props.player.startFocusing()}
id="character-overview-options-button"
className="character-overview-btn"
>
Focus
</button>
</td>
</tr>
</>
); );
}
function Work({ player }: { player: IPlayer }): React.ReactElement {
if (!player.isWorking || player.focus) return <></>;
const classes = useStyles();
return ( return (
<> <>
<table> <TableRow>
<tbody> <TableCell component="th" scope="row" colSpan={2} classes={{ root: classes.cellNone }}>
<tr id="character-hp-wrapper"> <Typography>Work&nbsp;in&nbsp;progress:</Typography>
<td className="character-hp-cell">HP:</td> </TableCell>
<td id="character-hp-text" className="character-hp-cell character-stat-cell"> </TableRow>
{numeralWrapper.formatHp(props.player.hp) + " / " + numeralWrapper.formatHp(props.player.max_hp)} <TableRow>
</td> <TableCell component="th" scope="row" colSpan={2} classes={{ root: classes.cellNone }}>
</tr> <Typography>+{Reputation(player.workRepGained)} rep</Typography>
<tr id="character-money-wrapper"> </TableCell>
<td className="character-money-cell">Money:&nbsp;</td> </TableRow>
<td id="character-money-text" className="character-money-cell character-stat-cell"> <TableRow>
{numeralWrapper.formatMoney(props.player.money.toNumber())} <TableCell component="th" scope="row" align="center" colSpan={2} classes={{ root: classes.cellNone }}>
</td> <Button onClick={() => player.startFocusing()}>Focus</Button>
</tr> </TableCell>
<tr id="character-hack-wrapper"> </TableRow>
<td className="character-hack-cell">Hack:&nbsp;</td>
<td id="character-hack-text" className="character-hack-cell character-stat-cell">
{numeralWrapper.formatSkill(props.player.hacking_skill)}
</td>
</tr>
<tr id="character-str-wrapper" className="character-divider">
<td className="character-combat-cell">Str:&nbsp;</td>
<td id="character-str-text" className="character-combat-cell character-stat-cell">
{numeralWrapper.formatSkill(props.player.strength)}
</td>
</tr>
<tr id="character-def-wrapper">
<td className="character-combat-cell">Def:&nbsp;</td>
<td id="character-def-text" className="character-combat-cell character-stat-cell">
{numeralWrapper.formatSkill(props.player.defense)}
</td>
</tr>
<tr id="character-dex-wrapper">
<td className="character-combat-cell">Dex:&nbsp;</td>
<td id="character-dex-text" className="character-combat-cell character-stat-cell">
{numeralWrapper.formatSkill(props.player.dexterity)}
</td>
</tr>
<tr id="character-agi-wrapper">
<td className="character-combat-cell">Agi:&nbsp;</td>
<td id="character-agi-text" className="character-combat-cell character-stat-cell">
{numeralWrapper.formatSkill(props.player.agility)}
</td>
</tr>
<tr id="character-cha-wrapper" className="character-divider">
<td className="character-cha-cell">Cha:&nbsp;</td>
<td id="character-cha-text" className="character-cha-cell character-stat-cell">
{numeralWrapper.formatSkill(props.player.charisma)}
</td>
</tr>
{props.player.intelligence >= 1 && intelligence}
{props.player.isWorking && !props.player.focus && work}
</tbody>
</table>
</> </>
); );
} }
const useStyles = makeStyles({
cellNone: {
borderBottom: "none",
padding: 0,
margin: 0,
},
cell: {
padding: 0,
margin: 0,
},
hp: {
color: colors.hp,
},
money: {
color: colors.money,
},
hack: {
color: colors.hack,
},
combat: {
color: colors.combat,
},
cha: {
color: colors.cha,
},
int: {
color: colors.int,
},
});
export function CharacterOverview({ player, save }: IProps): React.ReactElement {
const setRerender = useState(false)[1];
useEffect(() => {
const id = setInterval(() => setRerender((old) => !old), 600);
return () => clearInterval(id);
}, []);
const classes = useStyles();
return (
<Paper square>
<Box m={1}>
<Table size="small">
<TableBody>
<TableRow>
<TableCell component="th" scope="row" classes={{ root: classes.cellNone }}>
<Typography classes={{ root: classes.hp }}>HP&nbsp;</Typography>
</TableCell>
<TableCell align="right" classes={{ root: classes.cellNone }}>
<Typography classes={{ root: classes.hp }}>
{numeralWrapper.formatHp(player.hp)}&nbsp;/&nbsp;{numeralWrapper.formatHp(player.max_hp)}
</Typography>
</TableCell>
</TableRow>
<TableRow>
<TableCell component="th" scope="row" classes={{ root: classes.cellNone }}>
<Typography classes={{ root: classes.money }}>Money&nbsp;</Typography>
</TableCell>
<TableCell align="right" classes={{ root: classes.cellNone }}>
<Typography classes={{ root: classes.money }}>
{numeralWrapper.formatMoney(player.money.toNumber())}
</Typography>
</TableCell>
</TableRow>
<TableRow>
<TableCell component="th" scope="row" classes={{ root: classes.cell }}>
<Typography classes={{ root: classes.hack }}>Hack&nbsp;</Typography>
</TableCell>
<TableCell align="right" classes={{ root: classes.cell }}>
<Typography classes={{ root: classes.hack }}>
{numeralWrapper.formatSkill(player.hacking_skill)}
</Typography>
</TableCell>
</TableRow>
<TableRow>
<TableCell component="th" scope="row" classes={{ root: classes.cellNone }}>
<Typography classes={{ root: classes.combat }}>Str&nbsp;</Typography>
</TableCell>
<TableCell align="right" classes={{ root: classes.cellNone }}>
<Typography classes={{ root: classes.combat }}>
{numeralWrapper.formatSkill(player.strength)}
</Typography>
</TableCell>
</TableRow>
<TableRow>
<TableCell component="th" scope="row" classes={{ root: classes.cellNone }}>
<Typography classes={{ root: classes.combat }}>Def&nbsp;</Typography>
</TableCell>
<TableCell align="right" classes={{ root: classes.cellNone }}>
<Typography classes={{ root: classes.combat }}>{numeralWrapper.formatSkill(player.defense)}</Typography>
</TableCell>
</TableRow>
<TableRow>
<TableCell component="th" scope="row" classes={{ root: classes.cellNone }}>
<Typography classes={{ root: classes.combat }}>Dex&nbsp;</Typography>
</TableCell>
<TableCell align="right" classes={{ root: classes.cellNone }}>
<Typography classes={{ root: classes.combat }}>
{numeralWrapper.formatSkill(player.dexterity)}
</Typography>
</TableCell>
</TableRow>
<TableRow>
<TableCell component="th" scope="row" classes={{ root: classes.cell }}>
<Typography classes={{ root: classes.combat }}>Agi&nbsp;</Typography>
</TableCell>
<TableCell align="right" classes={{ root: classes.cell }}>
<Typography classes={{ root: classes.combat }}>{numeralWrapper.formatSkill(player.agility)}</Typography>
</TableCell>
</TableRow>
<TableRow>
<TableCell component="th" scope="row" classes={{ root: classes.cellNone }}>
<Typography classes={{ root: classes.cha }}>Cha&nbsp;</Typography>
</TableCell>
<TableCell align="right" classes={{ root: classes.cellNone }}>
<Typography classes={{ root: classes.cha }}>{numeralWrapper.formatSkill(player.charisma)}</Typography>
</TableCell>
</TableRow>
<Intelligence player={player} />
<Work player={player} />
<TableRow>
<TableCell align="center" colSpan={2} classes={{ root: classes.cellNone }}>
<Button color="primary" onClick={save}>
SAVE
</Button>
</TableCell>
</TableRow>
</TableBody>
</Table>
</Box>
</Paper>
);
}

@ -18,6 +18,13 @@ export const colors = {
well: "#222", well: "#222",
white: "#fff", white: "#fff",
black: "#000", black: "#000",
hp: "#dd3434",
money: "#ffd700",
hack: "#adff2f",
combat: "#faffdf",
cha: "#a671d1",
int: "#6495ed",
}; };
export const theme = createMuiTheme({ export const theme = createMuiTheme({
@ -175,6 +182,12 @@ export const theme = createMuiTheme({
backgroundColor: colors.welllight, backgroundColor: colors.welllight,
}, },
}, },
MuiPaper: {
root: {
backgroundColor: colors.black,
border: "1px solid " + colors.welllight,
},
},
}, },
}); });