Units wiki
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
import {AvailableMods, AvailableRacesPart} from "../core/api";
|
||||
import React, {useEffect, useRef, useState} from "react";
|
||||
import {NavLink, useLocation, useParams} from "react-router-dom";
|
||||
import {withRouter} from "../core/withrouter";
|
||||
import {IMod} from "../types/Imod";
|
||||
import {Irace} from "../types/Irace";
|
||||
|
||||
|
||||
interface ModPageState {
|
||||
mod: IMod,
|
||||
races: Irace[],
|
||||
modId: Number,
|
||||
}
|
||||
|
||||
class ModPage extends React.Component<any, ModPageState> {
|
||||
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
console.log(this.props.match.params.id);
|
||||
this.setState({
|
||||
modId : this.props.match.params.id
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
async componentDidMount() {
|
||||
|
||||
const responseMod = await fetch(AvailableMods + "/" + this.props.match.params.id);
|
||||
const modData: IMod = await responseMod.json();
|
||||
console.log(modData);
|
||||
this.setState({
|
||||
mod : modData
|
||||
});
|
||||
|
||||
const response = await fetch(AvailableRacesPart + "/mod/" + this.props.match.params.id);
|
||||
const racesData: Irace[] = await response.json();
|
||||
|
||||
this.setState({
|
||||
races : racesData
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
if(this.state != null && this.state.races != null ){
|
||||
return <div><h1>{this.state.mod.name} ({this.state.mod.version})</h1>
|
||||
{this.state.races.map(race => <ul><NavLink state={race.id} to= {"/mod/" + this.state.mod.id + "/race/" + race.id} >{race.name}</NavLink></ul>)}
|
||||
</div>;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default withRouter(ModPage);
|
||||
@@ -0,0 +1,67 @@
|
||||
import {AvailableMods} from "../core/api";
|
||||
import React, {useEffect, useState} from "react";
|
||||
import {NavLink} from "react-router-dom";
|
||||
import {IMod} from "../types/Imod";
|
||||
|
||||
function Mods (mods: IMod[]) {
|
||||
|
||||
let mapWithModVersions: Map<String, IMod[]> = new Map();
|
||||
|
||||
mods.forEach( mod => {
|
||||
const versionList = mapWithModVersions.get(mod.name)
|
||||
if(versionList == null){
|
||||
mapWithModVersions.set(mod.name, new Array(mod))
|
||||
} else {
|
||||
versionList.push(mod)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
function Mod (modName: String) {
|
||||
let sameMods = mapWithModVersions.get(modName) ?? []
|
||||
|
||||
return(
|
||||
<div>
|
||||
<h1>{modName}</h1>
|
||||
{sameMods.map(mod => <ul><NavLink state={mod.id} to= {"/mod/" + mod.id} >{mod.version}</NavLink></ul>)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
mapWithModVersions.keys()
|
||||
|
||||
|
||||
return(
|
||||
[...mapWithModVersions.keys()].map(m => Mod(m))
|
||||
)
|
||||
}
|
||||
|
||||
interface ModsPageState {
|
||||
mods: IMod[]
|
||||
}
|
||||
|
||||
class ModsPage extends React.Component<any, ModsPageState> {
|
||||
|
||||
constructor({props}: { props: any }) {
|
||||
super(props);
|
||||
this.state = {
|
||||
mods: []
|
||||
}
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const response = await fetch(AvailableMods);
|
||||
const data: IMod[] = await response.json();
|
||||
console.log(data);
|
||||
this.setState({
|
||||
mods : data
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div>{Mods(this.state.mods)}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
export default ModsPage
|
||||
@@ -0,0 +1,252 @@
|
||||
import {AvailableMods, AvailableRacesPart, AvailableUnits, IconUrl} from "../core/api";
|
||||
import React, {useState} from "react";
|
||||
import {withRouter} from "../core/withrouter";
|
||||
import {IMod} from "../types/Imod";
|
||||
import {Irace} from "../types/Irace";
|
||||
import {IUnit, IUnitResponse} from "../types/IUnit";
|
||||
import '../css/Unit.css'
|
||||
import {
|
||||
Accordion, AccordionDetails,
|
||||
AccordionSummary,
|
||||
Button,
|
||||
ButtonGroup, Grid2, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow,
|
||||
ToggleButton,
|
||||
ToggleButtonClassKey,
|
||||
ToggleButtonGroup, Typography
|
||||
} from "@mui/material";
|
||||
import {ArrowDropDown} from "@mui/icons-material";
|
||||
import ArmorType from "../classes/ArmorType";
|
||||
import Item from "../classes/Item";
|
||||
|
||||
interface RacePageState {
|
||||
mod: IMod,
|
||||
modId: Number,
|
||||
race: Irace,
|
||||
units: IUnitResponse,
|
||||
}
|
||||
|
||||
|
||||
|
||||
function humanReadableUnitName(unit: string) {
|
||||
const firstUpper = String(unit).charAt(0).toUpperCase() + String(unit).slice(1);
|
||||
return firstUpper.replaceAll('_', ' ').replace('.rgd', '');
|
||||
}
|
||||
|
||||
function Unit (unit: IUnit) {
|
||||
|
||||
const morale = (unit.moraleMax !== null) ? <span>
|
||||
<img style={{verticalAlign: "top"}} src="/images/ARM_Morale.webp"/> {unit.moraleMax}
|
||||
+{unit.moraleRegeneration}/s
|
||||
{unit.moraleDeathPenalty > 0 && <span> <img style={{verticalAlign: "top"}} src="/images/Kills_icon.webp"/> -{unit.moraleDeathPenalty}</span>}
|
||||
|
||||
</span> : "-"
|
||||
|
||||
const detect = unit.detectRadius > 0 ? <span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/DETECT_YES.webp"/> {unit.detectRadius}</span> :
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/DETECT_NO.webp"/></span>
|
||||
|
||||
|
||||
return (
|
||||
<Accordion>
|
||||
<AccordionSummary
|
||||
expandIcon={<ArrowDropDown/>}
|
||||
aria-controls="panel1-content"
|
||||
id={unit.filename}
|
||||
>
|
||||
<img className="unitIcon" src={IconUrl + unit.icon.replaceAll('\\', '/')}/>
|
||||
<h2> {unit.name}</h2>
|
||||
{unit.detectRadius > 0 && <span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/DETECT_YES.webp"/></span>}
|
||||
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<Grid2 container spacing={2}>
|
||||
<Grid2 size={4}>
|
||||
<TableContainer component={Paper}>
|
||||
<Table size="small" aria-label="a dense table">
|
||||
<TableBody id="unit-stats-table">
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">cost</TableCell>
|
||||
<TableCell component="th" scope="row">
|
||||
{unit.buildCostRequisition > 0 && <span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_requisition.gif"/>
|
||||
{unit.buildCostRequisition}</span>}
|
||||
{unit.buildCostPower > 0 && <span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_power.gif"/>
|
||||
{unit.buildCostPower}</span>}
|
||||
{unit.capInfantry > 0 && <span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_cap_infantry.gif"/>
|
||||
{unit.capInfantry}</span>}
|
||||
{unit.capSupport > 0 && <span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_cap_vehicle.gif"/>
|
||||
{unit.capSupport}</span>}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">armor type</TableCell>
|
||||
<TableCell component="th" scope="row">
|
||||
<ArmorType value={unit.armorType.name}/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">health</TableCell>
|
||||
<TableCell component="th" scope="row">
|
||||
<span><img style={{verticalAlign: "top"}}
|
||||
src="/images/Health_icon.webp"/>
|
||||
{unit.health} {unit.healthRegeneration > 0 &&
|
||||
<span>+{unit.healthRegeneration}/s</span>} </span>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">move speed</TableCell>
|
||||
<TableCell component="th" scope="row">
|
||||
{unit.moveSpeed}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">morale</TableCell>
|
||||
<TableCell component="th" scope="row">
|
||||
{morale}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">detect</TableCell>
|
||||
<TableCell component="th" scope="row">
|
||||
{detect}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Grid2>
|
||||
<Grid2 size={8}>
|
||||
<div style={{whiteSpace: "pre-wrap"}} >
|
||||
{unit.description}
|
||||
</div>
|
||||
</Grid2>
|
||||
</Grid2>
|
||||
<i>{unit.filename}</i>
|
||||
</AccordionDetails>
|
||||
</Accordion>)
|
||||
}
|
||||
|
||||
interface UnitsState {
|
||||
selectedUnits: String | null,
|
||||
}
|
||||
|
||||
class Units extends React.Component<IUnitResponse, UnitsState> {
|
||||
|
||||
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
this.state = ({
|
||||
selectedUnits: 'infantry'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
handleChange = (e: React.MouseEvent, newUnitType: String | null) => {
|
||||
this.setState({
|
||||
selectedUnits: newUnitType
|
||||
});
|
||||
{this.props.units.map(unit => Unit(unit))}
|
||||
}
|
||||
|
||||
render () {
|
||||
|
||||
let unitsToRender: IUnit[] = [];
|
||||
|
||||
if(this.state.selectedUnits === 'infantry'){
|
||||
unitsToRender = this.props.units.filter(unit => unit.capInfantry > 0)
|
||||
} else if (this.state.selectedUnits === 'tech'){
|
||||
unitsToRender = this.props.units.filter(unit => unit.capSupport > 0)
|
||||
} else {
|
||||
unitsToRender = this.props.units.filter(unit => unit.capSupport == 0 && unit.capInfantry == 0)
|
||||
}
|
||||
|
||||
|
||||
if (this.state) {
|
||||
return (<div>
|
||||
<ToggleButtonGroup
|
||||
color="primary"
|
||||
exclusive
|
||||
onChange={this.handleChange}
|
||||
value={this.state.selectedUnits}
|
||||
aria-label="Platform"
|
||||
>
|
||||
<ToggleButton value="infantry">Infantry</ToggleButton>
|
||||
<ToggleButton value="tech">Tech</ToggleButton>
|
||||
<ToggleButton value="support">Support</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
<div id = 'filtered-units'>
|
||||
{unitsToRender.map(unit => Unit(unit))}
|
||||
</div>
|
||||
|
||||
</div>)
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RacePage extends React.Component<any, RacePageState> {
|
||||
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
console.log(this.props.match.params.id);
|
||||
this.setState({
|
||||
modId: this.props.match.params.id
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
async componentDidMount() {
|
||||
|
||||
const responseMod = await fetch(AvailableMods + "/" + this.props.match.params.modId);
|
||||
const modData: IMod = await responseMod.json();
|
||||
|
||||
this.setState({
|
||||
mod: modData
|
||||
});
|
||||
|
||||
const response = await fetch(AvailableRacesPart + "/" + this.props.match.params.raceId);
|
||||
const racesData: Irace = await response.json();
|
||||
|
||||
this.setState({
|
||||
race : racesData
|
||||
});
|
||||
|
||||
const unitsResponse = await fetch(AvailableUnits + "/" + this.state.mod.id + "/" + this.props.match.params.raceId);
|
||||
const unitsData: IUnitResponse = await unitsResponse.json();
|
||||
console.log(unitsData);
|
||||
|
||||
this.setState({
|
||||
units : unitsData
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
if(this.state != null && this.state.units != null ){
|
||||
return <div><h1>{this.state.mod.name} ({this.state.mod.version}) - {this.state.race.name}</h1>
|
||||
<Units race={this.state.race.name} units={this.state.units.units}/>
|
||||
</div>;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default withRouter(RacePage);
|
||||
Reference in New Issue
Block a user