- Add building page
- Rework weapon ui (hide to spoiler and adapt to mobile) - Add additional weapon params (throw force, min radius, damage radius etc) - Add squad start/max sise, unit mass, souls and faith to cost
This commit is contained in:
parent
3e78fa3807
commit
5751cec4de
3
.env
3
.env
@ -1 +1,2 @@
|
||||
REACT_APP_HOST_URL=http://localhost:8082
|
||||
REACT_APP_HOST_URL=http://wiki-backend.dawn-of-war.pro
|
||||
#REACT_APP_HOST_URL=http://localhost:8082
|
||||
BIN
public/images/Resource_faith.gif
Normal file
BIN
public/images/Resource_faith.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 973 B |
BIN
public/images/Resource_souls.gif
Normal file
BIN
public/images/Resource_souls.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 970 B |
@ -3,6 +3,7 @@ import ModsPage from "./pages/ModsPage";
|
||||
import ModPage from "./pages/ModPage";
|
||||
import RacePageFast from "./pages/RacePageFast";
|
||||
import UnitPage from "./pages/UnitPage";
|
||||
import BuildingPage from "./pages/BuildingPage";
|
||||
|
||||
export const MyRoutes = () => {
|
||||
|
||||
@ -13,6 +14,7 @@ export const MyRoutes = () => {
|
||||
<Route path="/mod/:modId" element={<ModPage/>}/>
|
||||
<Route path="/mod/:modId/race/:raceId" element={<RacePageFast/>}/>
|
||||
<Route path="/mod/:modId/race/:raceId/unit/:unitId" element={<UnitPage/>}/>
|
||||
<Route path="/mod/:modId/race/:raceId/building/:buildingId" element={<BuildingPage/>}/>
|
||||
</Routes>
|
||||
</BrowserRouter>
|
||||
)
|
||||
|
||||
@ -60,13 +60,19 @@ const Sergeant = (props: SergeantProps) => {
|
||||
{sergeant.buildCostRequisition > 0 &&
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_requisition.gif"/>
|
||||
{sergeant.buildCostRequisition}</span>}
|
||||
{sergeant.buildCostRequisition.toFixed(0)}</span>}
|
||||
{sergeant.buildCostPower > 0 && <span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_power.gif"/>
|
||||
{sergeant.buildCostPower}</span>}
|
||||
{sergeant.buildCostPower.toFixed(0)}</span>}
|
||||
{(sergeant.buildCostPopulation !== undefined && sergeant.buildCostPopulation > 0) && <span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_orksquadcap.gif"/>
|
||||
{sergeant.buildCostPopulation}</span>}
|
||||
{sergeant.buildCostPopulation.toFixed(0)}</span>}
|
||||
{(sergeant.buildCostFaith !== undefined && sergeant.buildCostFaith > 0) && <span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_orksquadcap.gif"/>
|
||||
{sergeant.buildCostFaith}</span>}
|
||||
{(sergeant.buildCostSouls !== undefined && sergeant.buildCostSouls > 0) && <span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_orksquadcap.gif"/>
|
||||
{sergeant.buildCostSouls.toFixed(0)}</span>}
|
||||
|
||||
{(sergeant.buildCostTime !== undefined && sergeant.buildCostTime > 0) && <span> <AvTimerOutlinedIcon style={{verticalAlign: "top", fontSize:"18px"}} />
|
||||
{sergeant.buildCostTime}s</span>}
|
||||
|
||||
@ -1,18 +1,21 @@
|
||||
import React, {useEffect, useState} from "react";
|
||||
import {AvailableUnits} from "../core/api";
|
||||
import {AvailableBuildings, AvailableUnits} from "../core/api";
|
||||
import {Grid2, Table, TableBody, TableCell, TableContainer, TableHead, TableRow} from "@mui/material";
|
||||
import {NavLink} from "react-router-dom";
|
||||
import {IRaceUnits, IUnitShort} from "../types/IUnitShort";
|
||||
import {IBuildingShort, IRaceBuildings} from "../types/IBuildingShort";
|
||||
|
||||
|
||||
interface IUnitsTable {
|
||||
racesUnits: IRaceUnits[];
|
||||
racesUnits: IRaceUnits[]
|
||||
racesBuildings: IRaceBuildings[]
|
||||
}
|
||||
|
||||
export default function UnitsTable(prop: {modId: number}) {
|
||||
|
||||
const [unitsTable, setUnitsTable] = useState<IUnitsTable>({
|
||||
racesUnits: []
|
||||
racesUnits: [],
|
||||
racesBuildings: []
|
||||
});
|
||||
|
||||
|
||||
@ -22,13 +25,25 @@ export default function UnitsTable(prop: {modId: number}) {
|
||||
</a><br/></span>
|
||||
}
|
||||
|
||||
function getBuildingRef(modId: number, raceId: string, building: IBuildingShort) {
|
||||
return <span style={{fontSize: 11}}><a href={"/mod/" + modId + "/race/" + raceId + "/building/" + building.id}>
|
||||
{building.name}
|
||||
<br/></a></span>
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
fetch(AvailableUnits + "/mod/" + prop.modId)
|
||||
|
||||
fetch(AvailableBuildings + "/mod/" + prop.modId)
|
||||
.then(res => res.json())
|
||||
.then((res: IRaceUnits[]) => {
|
||||
setUnitsTable({
|
||||
racesUnits : res
|
||||
});
|
||||
.then((resBuildings: IRaceBuildings[]) => {
|
||||
fetch(AvailableUnits + "/mod/" + prop.modId)
|
||||
.then(res => res.json())
|
||||
.then((res: IRaceUnits[]) => {
|
||||
setUnitsTable({
|
||||
racesUnits : res,
|
||||
racesBuildings: resBuildings
|
||||
});
|
||||
})
|
||||
})
|
||||
}, []);
|
||||
|
||||
@ -77,7 +92,7 @@ export default function UnitsTable(prop: {modId: number}) {
|
||||
)
|
||||
}
|
||||
|
||||
function generateRaceUnitTable(racesUnitsPart: IRaceUnits[]){
|
||||
function generateRaceUnitTable(racesUnitsPart: IRaceUnits[], racesBuildings: IRaceBuildings[]){
|
||||
return (<TableContainer>
|
||||
{<Table sx={{minWidth: 650}} size="small" aria-label="a dense table">
|
||||
<TableHead>
|
||||
@ -91,7 +106,7 @@ export default function UnitsTable(prop: {modId: number}) {
|
||||
<TableRow style={{verticalAlign: 'top'}}>
|
||||
{racesUnitsPart.map(raceUnits =>
|
||||
<TableCell>
|
||||
{getUnitsRef(raceUnits.infantry, raceUnits.race.id)}
|
||||
{getUnitsRef(raceUnits.infantry.concat(raceUnits.support), raceUnits.race.id)}
|
||||
</TableCell>)
|
||||
}
|
||||
</TableRow>
|
||||
@ -103,9 +118,9 @@ export default function UnitsTable(prop: {modId: number}) {
|
||||
}
|
||||
</TableRow>
|
||||
<TableRow style={{verticalAlign: 'top'}}>
|
||||
{racesUnitsPart.map(raceUnits =>
|
||||
{racesBuildings.map(raceBuilding =>
|
||||
<TableCell>
|
||||
{getUnitsRef(raceUnits.support, raceUnits.race.id)}
|
||||
{raceBuilding.buildings.map(building => getBuildingRef(prop.modId, raceBuilding.race.id, building))}
|
||||
</TableCell>)
|
||||
}
|
||||
</TableRow>
|
||||
@ -114,10 +129,20 @@ export default function UnitsTable(prop: {modId: number}) {
|
||||
</TableContainer>)
|
||||
}
|
||||
|
||||
function generateRaceUnitTables(racesUnits: IRaceUnits[], raceCount: number){
|
||||
function generateRaceUnitTables(racesUnits: IRaceUnits[], racesBuildings: IRaceBuildings[], raceCount: number){
|
||||
var elements: JSX.Element[] = []
|
||||
racesBuildings = racesBuildings.reverse()
|
||||
for(let i = 0; i < racesUnits.length;i = i + raceCount){
|
||||
elements.push(generateRaceUnitTable(racesUnits.slice(i, i + raceCount)))
|
||||
var unitsThisTable = racesUnits.slice(i, i + raceCount)
|
||||
var buildingsThisTable: IRaceBuildings[] = []
|
||||
unitsThisTable.forEach(ut => {
|
||||
var buildings = racesBuildings.find(rb => rb.race.id === ut.race.id)
|
||||
if (buildings != null) {
|
||||
buildingsThisTable.push(buildings)
|
||||
}
|
||||
})
|
||||
|
||||
elements.push(generateRaceUnitTable(unitsThisTable, buildingsThisTable))
|
||||
}
|
||||
return elements
|
||||
}
|
||||
@ -126,7 +151,7 @@ export default function UnitsTable(prop: {modId: number}) {
|
||||
return (
|
||||
<Grid2>
|
||||
<Grid2 display={{ lg: 'block', xs: 'none' }} >
|
||||
{generateRaceUnitTables(unitsTable.racesUnits, 9)}
|
||||
{generateRaceUnitTables(unitsTable.racesUnits, unitsTable.racesBuildings, 5)}
|
||||
</Grid2>
|
||||
<Grid2 display={{ lg: 'none', xs: 'block' }}>
|
||||
{unitsTable.racesUnits.map(raceUnits => <h4><NavLink state={raceUnits.race.id}
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
import React from "react";
|
||||
import {IWeapon, IWeaponPiercing} from "../types/IUnit";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionDetails,
|
||||
AccordionSummary,
|
||||
Grid2,
|
||||
Paper,
|
||||
styled,
|
||||
@ -15,13 +18,15 @@ import {
|
||||
import ArmorType from "./ArmorType";
|
||||
import ArmorTypeNames from "../types/ArmorTypeValues";
|
||||
import {IconUrl} from "../core/api";
|
||||
import {ExpandMore} from "@mui/icons-material";
|
||||
import Sergeant from "./Sergeant";
|
||||
|
||||
interface IWeaponProps{
|
||||
interface IWeaponProps {
|
||||
weapon: IWeapon,
|
||||
isDefault: Boolean,
|
||||
}
|
||||
|
||||
interface IWeaponState{
|
||||
interface IWeaponState {
|
||||
currentTable: "dps" | "one hit",
|
||||
}
|
||||
|
||||
@ -45,24 +50,23 @@ class Weapon extends React.Component<IWeaponProps, any> {
|
||||
|
||||
|
||||
getPiercingK(armorType: string): number {
|
||||
const weaponPiercing = this.props.weapon.weaponPiercings.find((p) => p.armorType.name === armorType)
|
||||
return (typeof weaponPiercing !== "undefined" ? weaponPiercing.piercingValue : 10 ) / 100
|
||||
const weaponPiercing = this.props.weapon.weaponArmorPiercing.find((p) => p.armorType.name === armorType)
|
||||
return (typeof weaponPiercing !== "undefined" ? weaponPiercing.piercingValue : 10) / 100
|
||||
}
|
||||
|
||||
handleChange = (e: React.MouseEvent, selectedDamageTable: String | null) => {
|
||||
handleChange = (e: React.MouseEvent, selectedDamageTable: String | null) => {
|
||||
this.setState({
|
||||
currentTable: selectedDamageTable
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
render() {
|
||||
|
||||
const weapon = this.props.weapon
|
||||
|
||||
|
||||
const dpsK = (this.state.currentTable == "dps") ? weapon.accuracy * (1/(weapon.reloadTime - (weapon.reloadTime % 0.125))) : 1
|
||||
const dpsK = (this.state.currentTable == "dps") ? weapon.accuracy * (1 / (weapon.reloadTime - (weapon.reloadTime % 0.125))) : 1
|
||||
|
||||
const infLowPiercing = this.getPiercingK(ArmorTypeNames.InfantryLow)
|
||||
const infMedPiercing = this.getPiercingK(ArmorTypeNames.InfantryMedium)
|
||||
@ -83,16 +87,16 @@ class Weapon extends React.Component<IWeaponProps, any> {
|
||||
|
||||
const getTotalDamage = (damagePiercing: number, isAir: boolean = false) => {
|
||||
|
||||
if(!isAir && !weapon.canAttackGround && !weapon.isMeleeWeapon) return ""
|
||||
if(isAir && !weapon.canAttackAir) return ""
|
||||
if (!isAir && !weapon.canAttackGround && !weapon.isMeleeWeapon) return ""
|
||||
if (isAir && !weapon.canAttackAir) return ""
|
||||
|
||||
var minDamage = damagePiercing * weapon.minDamage
|
||||
var maxDamage = damagePiercing * weapon.maxDamage
|
||||
|
||||
if(minDamage < weapon.minDamageValue){
|
||||
if (minDamage < weapon.minDamageValue) {
|
||||
minDamage = weapon.minDamageValue
|
||||
}
|
||||
if(maxDamage < weapon.minDamageValue){
|
||||
if (maxDamage < weapon.minDamageValue) {
|
||||
maxDamage = weapon.minDamageValue
|
||||
}
|
||||
|
||||
@ -106,7 +110,7 @@ class Weapon extends React.Component<IWeaponProps, any> {
|
||||
}
|
||||
|
||||
|
||||
const StyledTableCell = styled(TableCell)(({ theme }) => ({
|
||||
const StyledTableCell = styled(TableCell)(({theme}) => ({
|
||||
[`&.${tableCellClasses.head}`]: {
|
||||
backgroundColor: "rgb(234, 234, 234)",
|
||||
color: theme.palette.common.white,
|
||||
@ -119,162 +123,213 @@ class Weapon extends React.Component<IWeaponProps, any> {
|
||||
}));
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h4>{ weapon.name ? weapon.name : this.humanReadableName(weapon.filename)}</h4>
|
||||
<Grid2 container spacing={2}>
|
||||
<div style={{marginBottom: 10}}><Accordion>
|
||||
<AccordionSummary
|
||||
expandIcon={<ExpandMore/>}
|
||||
aria-controls="panel1-content"
|
||||
id="panel1-header"
|
||||
>
|
||||
<span style={{fontSize: 18}}> {!this.props.isDefault && weapon.icon && weapon.haveEquipButton ?
|
||||
<img className="weaponIcon" src={IconUrl + weapon.icon.replaceAll('\\', '/')}/> : (
|
||||
weapon.isMeleeWeapon ?
|
||||
<img className="weaponIcon" src="/images/MeleeStance_icon_bw.jpg"/> :
|
||||
<img className="weaponIcon" src="/images/RangedStance_icon_bw.jpg"/>
|
||||
)} {weapon.name ? weapon.name : this.humanReadableName(weapon.filename)} </span>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<Grid2 container spacing={2}>
|
||||
<Grid2 size={12}>
|
||||
<div style={{whiteSpace: "pre-wrap"}}>
|
||||
<span
|
||||
className="weaponDescription">{this.props.isDefault ? "Default weapon" : weapon.description}</span>
|
||||
</div>
|
||||
</Grid2>
|
||||
|
||||
<Grid2 size= {{xs: 12, md: 3}}>
|
||||
<TableContainer component={Paper}>
|
||||
<Table size="small" aria-label="a dense table">
|
||||
<TableBody>
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">Base damage</TableCell>
|
||||
<TableCell component="th"
|
||||
scope="row">{weapon.minDamage} {weapon.maxDamage !== weapon.minDamage && -weapon.maxDamage}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">Accuracy</TableCell>
|
||||
<TableCell component="th" scope="row">{weapon.accuracy.toFixed(2)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">Accuracy moving</TableCell>
|
||||
<TableCell component="th"
|
||||
scope="row">{weapon.setupTime === 0 ? (weapon.accuracy - weapon.accuracyReductionMoving).toFixed(2) : "-"}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">Reload time</TableCell>
|
||||
<TableCell component="th"
|
||||
scope="row">{weapon.reloadTime}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">Max range</TableCell>
|
||||
<TableCell component="th"
|
||||
scope="row">{weapon.maxRange ? (weapon.maxRange) : "-"}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">Setup time</TableCell>
|
||||
<TableCell component="th"
|
||||
scope="row">{weapon.setupTime != 0 ? (weapon.setupTime).toFixed(2) : "-"}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
{(weapon.costRequisition > 0 || weapon.costPower > 0) &&
|
||||
<Grid2 size={{xs: 12, md: 4}}>
|
||||
<TableContainer component={Paper}>
|
||||
<Table size="small" aria-label="a dense table">
|
||||
{/*<TableHead><TableRow><TableCell component="th" scope="row"><b>Damage</b></TableCell><TableCell/></TableRow></TableHead>*/}
|
||||
<TableBody>
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">Base damage</TableCell>
|
||||
<TableCell component="th"
|
||||
scope="row">{weapon.minDamage} {weapon.maxDamage !== weapon.minDamage && -weapon.maxDamage}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">Accuracy</TableCell>
|
||||
<TableCell component="th"
|
||||
scope="row">{weapon.accuracy.toFixed(3).replace(/[,.]?0+$/, '')}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">Accuracy moving</TableCell>
|
||||
<TableCell component="th"
|
||||
scope="row">{weapon.setupTime === 0 && weapon.accuracy - weapon.accuracyReductionMoving > 0 ? (weapon.accuracy - weapon.accuracyReductionMoving).toFixed(3).replace(/[,.]?0+$/, '') : "-"}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Grid2>
|
||||
<Grid2 size={{xs: 12, md: 4}}>
|
||||
<TableContainer component={Paper}>
|
||||
<Table size="small" aria-label="a dense table">
|
||||
<TableBody>
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">Reload time</TableCell>
|
||||
<TableCell component="th"
|
||||
scope="row">{weapon.reloadTime}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">Range</TableCell>
|
||||
<TableCell component="th"
|
||||
scope="row">{weapon.maxRange ? (weapon.maxRange) : "-"} {weapon.minRange ? "(min " + (weapon.minRange) + ")" : ""}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">Damage radius</TableCell>
|
||||
<TableCell component="th"
|
||||
scope="row">{weapon.damageRadius ? (weapon.damageRadius) : "-"}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Grid2>
|
||||
<Grid2 size={{xs: 12, md: 4}}>
|
||||
<TableContainer component={Paper}>
|
||||
<Table size="small" aria-label="a dense table">
|
||||
<TableBody>
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">Cost</TableCell>
|
||||
{(weapon.costRequisition > 0 || weapon.costPower > 0) ?
|
||||
<TableCell component="th"
|
||||
scope="row">
|
||||
{weapon.costRequisition > 0 &&
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_requisition.gif"/>
|
||||
{weapon.costRequisition.toFixed(0)}</span>}
|
||||
{weapon.costPower > 0 &&
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_power.gif"/>
|
||||
{weapon.costPower.toFixed(0)}</span>}
|
||||
</TableCell> : <TableCell component="th" scope="row"> - </TableCell>
|
||||
}
|
||||
</TableRow>
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">Setup time</TableCell>
|
||||
<TableCell component="th"
|
||||
scope="row">
|
||||
{weapon.costRequisition > 0 && <span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_requisition.gif"/>
|
||||
{weapon.costRequisition}</span>}
|
||||
{weapon.costPower > 0 && <span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_power.gif"/>
|
||||
{weapon.costPower}</span>}
|
||||
scope="row">{weapon.setupTime != 0 ? (weapon.setupTime).toFixed(3).replace(/[,.]?0+$/, '') : "-"}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">Throw force</TableCell>
|
||||
<TableCell component="th"
|
||||
scope="row">{weapon.throwForceMin != 0 ? weapon.throwForceMin + " - " + weapon.throwForceMax : "-"}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Grid2>
|
||||
|
||||
<Grid2 size={12}>
|
||||
<ToggleButtonGroup
|
||||
color="primary"
|
||||
exclusive
|
||||
value={this.state.currentTable}
|
||||
onChange={this.handleChange}
|
||||
aria-label="Platform"
|
||||
>
|
||||
<ToggleButton size="small" value="dps">Dps</ToggleButton>
|
||||
<ToggleButton size="small" value="one hit">One hit average damage</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
<TableContainer>
|
||||
<Table sx={{marginTop: "10px"}} size="small" aria-label="a dense table">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.InfantryLow}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.InfantryMedium}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.InfantryHigh}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.InfantryHeavyMedium}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.InfantryHeavyHigh}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.Commander}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.DemonMedium}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.DemonHigh}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType name={ArmorTypeNames.Air}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.VehicleLow}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.VehicleMedium}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.VehicleHigh}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.BuildingLow}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.BuildingMedium}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.BuildingHigh}/></StyledTableCell>
|
||||
<StyledTableCell><img style={{verticalAlign: "top"}}
|
||||
src="/images/ARM_Morale.webp"/></StyledTableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<StyledTableCell>{getTotalDamage(infLowPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(infMedPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(infHighPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(infHeavyMedPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(infHeavyHighPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(commanderPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(demonPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(demonHighPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(airPiercing, true)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(vehLowPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(vehMedPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(vehHighPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(buildingLowPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(buildingMedPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(buildingHighPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getMoraleDamage()}</StyledTableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
<i className="rgdFrom">{weapon.filename}</i>
|
||||
</Grid2>
|
||||
</Grid2>
|
||||
<Grid2 size={9}>
|
||||
<div style={{whiteSpace: "pre-wrap"}}>
|
||||
{!this.props.isDefault && weapon.icon ? <img className="unitIcon" src={IconUrl + weapon.icon.replaceAll('\\', '/')}/> : (
|
||||
weapon.isMeleeWeapon ?
|
||||
<img src="/images/MeleeStance_icon_bw.jpg"/> :
|
||||
<img src="/images/RangedStance_icon_bw.jpg"/>
|
||||
) } <br/>
|
||||
{this.props.isDefault ? "Default weapon" : weapon.description}
|
||||
</div>
|
||||
</Grid2>
|
||||
<Grid2 size={12}>
|
||||
<ToggleButtonGroup
|
||||
color="primary"
|
||||
exclusive
|
||||
value={this.state.currentTable}
|
||||
onChange={this.handleChange}
|
||||
aria-label="Platform"
|
||||
>
|
||||
<ToggleButton size="small" value="dps">Dps</ToggleButton>
|
||||
<ToggleButton size="small" value="one hit">One hit average damage</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
<TableContainer>
|
||||
<Table sx={{marginTop: "10px"}} size="small" aria-label="a dense table">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.InfantryLow}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.InfantryMedium}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.InfantryHigh}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.InfantryHeavyMedium}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.InfantryHeavyHigh}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType name={ArmorTypeNames.Commander}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.DemonMedium}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType name={ArmorTypeNames.DemonHigh}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType name={ArmorTypeNames.Air}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType name={ArmorTypeNames.VehicleLow}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.VehicleMedium}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.VehicleHigh}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.BuildingLow}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.BuildingMedium}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.BuildingHigh}/></StyledTableCell>
|
||||
<StyledTableCell><img style={{verticalAlign: "top"}}
|
||||
src="/images/ARM_Morale.webp"/></StyledTableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<StyledTableCell>{getTotalDamage(infLowPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(infMedPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(infHighPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(infHeavyMedPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(infHeavyHighPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(commanderPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(demonPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(demonHighPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(airPiercing, true)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(vehLowPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(vehMedPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(vehHighPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(buildingLowPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(buildingMedPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(buildingHighPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getMoraleDamage()}</StyledTableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
<i className="rgdFrom">{weapon.filename}</i>
|
||||
</Grid2>
|
||||
</Grid2>
|
||||
</div>
|
||||
</AccordionDetails>
|
||||
</Accordion></div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,4 +3,5 @@ export const UserUrl = process.env.REACT_APP_HOST_URL + '/api/v1/user';
|
||||
export const AvailableMods = process.env.REACT_APP_HOST_URL + '/api/v1/mods';
|
||||
export const AvailableRacesPart = process.env.REACT_APP_HOST_URL + '/api/v1/races';
|
||||
export const AvailableUnits = process.env.REACT_APP_HOST_URL + '/api/v1/units';
|
||||
export const AvailableBuildings = process.env.REACT_APP_HOST_URL + '/api/v1/buildings';
|
||||
export const IconUrl = process.env.REACT_APP_HOST_URL + '/api/v1/grapics/icon/';
|
||||
|
||||
@ -2,6 +2,10 @@
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.weaponIcon{
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
.sergeantIcon{
|
||||
padding: 0px;
|
||||
width: 40px;
|
||||
|
||||
173
src/pages/BuildingPage.tsx
Normal file
173
src/pages/BuildingPage.tsx
Normal file
@ -0,0 +1,173 @@
|
||||
import {AvailableBuildings, AvailableMods, AvailableUnits, IconUrl} from "../core/api";
|
||||
import React from "react";
|
||||
import {withRouter} from "../core/withrouter";
|
||||
import {IWeapon} from "../types/IUnit";
|
||||
import '../css/Unit.css'
|
||||
import {Button, Grid2, Paper, Table, TableBody, TableCell, TableContainer, TableRow} from "@mui/material";
|
||||
import {ArrowBack} from "@mui/icons-material";
|
||||
import ArmorType from "../classes/ArmorType";
|
||||
import AvTimerOutlinedIcon from '@mui/icons-material/AvTimer';
|
||||
import WeaponSlot from "../classes/WeaponSlot";
|
||||
import UnitsTable from "../classes/UnitsTable";
|
||||
import {IMod} from "../types/Imod";
|
||||
import {IBuilding} from "../types/IBuilding";
|
||||
|
||||
interface UintPageState {
|
||||
building: IBuilding,
|
||||
mod: IMod,
|
||||
}
|
||||
|
||||
|
||||
function Building(building: IBuilding, mod: IMod) {
|
||||
|
||||
const detect = building.detectRadius > 0 ? <span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/DETECT_YES.webp"/> {building.detectRadius}</span> :
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/DETECT_NO.webp"/></span>
|
||||
|
||||
let mapBuildingWeapons: Map<number, Map<number, IWeapon>> = new Map();
|
||||
|
||||
building.weapons.forEach(weapon => {
|
||||
const weaponMap = mapBuildingWeapons.get(weapon.hardpoint)
|
||||
if (weaponMap == null) {
|
||||
const weaponMap = new Map()
|
||||
weaponMap.set(weapon.hardpointOrder, weapon.weapon)
|
||||
mapBuildingWeapons.set(weapon.hardpoint, weaponMap)
|
||||
} else {
|
||||
weaponMap.set(weapon.hardpointOrder, weapon.weapon)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>{mod.name} ({mod.version})</h1>
|
||||
<h2>{building.icon &&
|
||||
<img className="unitIcon" src={IconUrl + building.icon.replaceAll('\\', '/')}/>} {building.name} </h2>
|
||||
|
||||
<Grid2 container spacing={2}>
|
||||
<Grid2 size={{xs: 12, md: 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">
|
||||
{building.buildCostRequisition > 0 &&
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_requisition.gif"/>
|
||||
{building.buildCostRequisition.toFixed(0)}</span>}
|
||||
{building.buildCostPower > 0 && <span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_power.gif"/>
|
||||
{building.buildCostPower.toFixed(0)}</span>}
|
||||
{(building.buildCostPopulation !== undefined && building.buildCostPopulation > 0) &&
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_orksquadcap.gif"/>
|
||||
{building.buildCostPopulation.toFixed(0)}</span>}
|
||||
{(building.buildCostFaith !== undefined && building.buildCostFaith > 0) &&
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_faith.gif"/>
|
||||
{building.buildCostFaith}</span>}
|
||||
{(building.buildCostSouls !== undefined && building.buildCostSouls > 0) &&
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_souls.gif"/>
|
||||
{building.buildCostSouls.toFixed(0)}</span>}
|
||||
{(building.buildCostTime !== undefined && building.buildCostTime > 0) &&
|
||||
<span> <AvTimerOutlinedIcon
|
||||
style={{verticalAlign: "top", fontSize: "18px"}}/>
|
||||
{building.buildCostTime}s</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 name={building.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"/>
|
||||
{building.health} {building.healthRegeneration > 0 &&
|
||||
<span>+{building.healthRegeneration}/s</span>} </span>
|
||||
</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>
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">Repair max</TableCell>
|
||||
<TableCell component="th" scope="row">
|
||||
{building.repairMax}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Grid2>
|
||||
<Grid2 size={8}>
|
||||
<div style={{whiteSpace: "pre-wrap"}}>
|
||||
{building.description}
|
||||
</div>
|
||||
</Grid2>
|
||||
<Grid2 size={12}>
|
||||
{[...mapBuildingWeapons.keys()].sort(function (a, b) {
|
||||
return a - b;
|
||||
}).map(h => <WeaponSlot unitWeapons={mapBuildingWeapons.get(h)} hardpoint={h}/>)}
|
||||
</Grid2>
|
||||
</Grid2>
|
||||
<i className="rgdFrom">{building.filename}</i>
|
||||
<hr/>
|
||||
<UnitsTable modId={mod.id}/>
|
||||
</div>)
|
||||
}
|
||||
|
||||
|
||||
class BuildingPage extends React.Component<any, UintPageState> {
|
||||
|
||||
async componentDidMount() {
|
||||
const buildingResponse = await fetch(AvailableBuildings + "/" + this.props.match.params.buildingId);
|
||||
const buildingData: IBuilding = await buildingResponse.json();
|
||||
|
||||
this.setState({
|
||||
building: buildingData
|
||||
});
|
||||
|
||||
const responseMod = await fetch(AvailableMods + "/" + this.props.match.params.modId);
|
||||
const modData: IMod = await responseMod.json();
|
||||
|
||||
this.setState({
|
||||
mod: modData
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
if (this.state != null && this.state.building != null && this.state.mod != null) {
|
||||
const backRef = "/mod/" + this.props.match.params.modId + "/race/" + this.props.match.params.raceId
|
||||
|
||||
return <div><a href={backRef}><Button id="back-button" variant="contained"
|
||||
startIcon={<ArrowBack/>}> Back</Button></a>
|
||||
{Building(this.state.building, this.state.mod)}
|
||||
</div>;
|
||||
} else {
|
||||
return "loading...";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default withRouter(BuildingPage);
|
||||
@ -1,4 +1,4 @@
|
||||
import {AvailableMods, AvailableRacesPart, AvailableUnits, IconUrl} from "../core/api";
|
||||
import {AvailableBuildings, AvailableMods, AvailableRacesPart, AvailableUnits, IconUrl} from "../core/api";
|
||||
import React, {useState} from "react";
|
||||
import {withRouter} from "../core/withrouter";
|
||||
import {IMod} from "../types/Imod";
|
||||
@ -30,6 +30,7 @@ import {ArrowBack, ArrowDropDown} from "@mui/icons-material";
|
||||
import ArmorType from "../classes/ArmorType";
|
||||
import Weapon from "../classes/Weapon";
|
||||
import {IRaceUnits, IUnitShort} from "../types/IUnitShort";
|
||||
import {IBuildingShort, IRaceBuildings} from "../types/IBuildingShort";
|
||||
|
||||
interface RacePageState {
|
||||
mod: IMod,
|
||||
@ -49,14 +50,26 @@ function Unit (unit: IUnitShort, modId: number, raceId: String) {
|
||||
</ListItem></a>)
|
||||
}
|
||||
|
||||
interface UnitsProps{
|
||||
raceId: string,
|
||||
modId: number,
|
||||
}
|
||||
function Building (building: IBuildingShort, modId: number, raceId: String) {
|
||||
|
||||
return (<a href={"/mod/" + modId + "/race/" + raceId + "/building/" + building.id}><ListItem>
|
||||
{building.icon && <img className="unitIcon" src={IconUrl + building.icon.replaceAll('\\', '/')}/>}
|
||||
{building.name}
|
||||
{building.canDetect && <span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/DETECT_YES.webp"/></span>}
|
||||
|
||||
</ListItem></a>)
|
||||
}
|
||||
|
||||
interface UnitsProps{
|
||||
raceId: string,
|
||||
modId: number,
|
||||
}
|
||||
|
||||
interface UnitsState {
|
||||
selectedUnits: String | null,
|
||||
units: IRaceUnits | null,
|
||||
buildings: IRaceBuildings | null,
|
||||
}
|
||||
|
||||
class Units extends React.Component<UnitsProps, UnitsState> {
|
||||
@ -64,26 +77,28 @@ class Units extends React.Component<UnitsProps, UnitsState> {
|
||||
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
let url = AvailableUnits + "/" + this.props.modId + "/" + this.props.raceId;
|
||||
let urlUnits = AvailableUnits + "/" + this.props.modId + "/" + this.props.raceId;
|
||||
|
||||
|
||||
fetch(url)
|
||||
fetch(urlUnits)
|
||||
.then(res => res.json())
|
||||
.then((res: IRaceUnits) => {
|
||||
this.setState({
|
||||
units: res,
|
||||
})
|
||||
})
|
||||
|
||||
let urlBuildings = AvailableBuildings + "/" + this.props.modId + "/" + this.props.raceId;
|
||||
|
||||
fetch(urlBuildings)
|
||||
.then(res => res.json())
|
||||
.then((res: IRaceBuildings) => {
|
||||
this.setState({
|
||||
buildings: res,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
handleChange = (e: React.MouseEvent, newUnitType: String | null) => {
|
||||
this.setState({
|
||||
selectedUnits: newUnitType
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
render () {
|
||||
|
||||
|
||||
@ -91,8 +106,7 @@ class Units extends React.Component<UnitsProps, UnitsState> {
|
||||
|
||||
return (<div>
|
||||
|
||||
|
||||
{this.state.units != null ?
|
||||
{this.state.units != null && this.state.buildings != null ?
|
||||
<Grid2 container spacing={2}>
|
||||
<Grid2 size= {{xs: 12, md: 4}}>
|
||||
<h3>Infantry</h3>
|
||||
@ -110,6 +124,12 @@ class Units extends React.Component<UnitsProps, UnitsState> {
|
||||
{this.state.units.support.map(unit => Unit(unit, this.props.modId, this.props.raceId))}
|
||||
</List>
|
||||
</Grid2>
|
||||
<Grid2 size={{xs: 12, md: 4}}>
|
||||
<h3>Buildings</h3>
|
||||
<List sx={{width: '100%', maxWidth: 360, bgcolor: 'background.paper'}}>
|
||||
{this.state.buildings.buildings.map(building => Building(building, this.props.modId, this.props.raceId))}
|
||||
</List>
|
||||
</Grid2>
|
||||
</Grid2>
|
||||
: "Loading"}
|
||||
|
||||
|
||||
@ -95,19 +95,27 @@ function Unit(unit: IUnit, mod: IMod) {
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">cost</TableCell>
|
||||
<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.buildCostRequisition.toFixed(0)}</span>}
|
||||
{unit.buildCostPower > 0 && <span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_power.gif"/>
|
||||
{unit.buildCostPower}</span>}
|
||||
{unit.buildCostPower.toFixed(0)}</span>}
|
||||
{(unit.buildCostPopulation !== undefined && unit.buildCostPopulation > 0) &&
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_orksquadcap.gif"/>
|
||||
{unit.buildCostPopulation}</span>}
|
||||
{unit.buildCostPopulation.toFixed(0)}</span>}
|
||||
{(unit.buildCostFaith !== undefined && unit.buildCostFaith > 0) &&
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_faith.gif"/>
|
||||
{unit.buildCostFaith}</span>}
|
||||
{(unit.buildCostSouls !== undefined && unit.buildCostSouls > 0) &&
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_souls.gif"/>
|
||||
{unit.buildCostSouls.toFixed(0)}</span>}
|
||||
|
||||
{unit.capInfantry > 0 && <span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_cap_infantry.gif"/>
|
||||
@ -121,22 +129,30 @@ function Unit(unit: IUnit, mod: IMod) {
|
||||
{unit.buildCostTime}s</span>}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
{(unit?.reinforceTime !== 0 && unit.reinforceTime !== null) &&
|
||||
{(unit?.reinforceTime !== 0 && unit.reinforceTime !== null && unit.squadMaxSize > 1) &&
|
||||
<TableRow>
|
||||
<TableCell>reinforce cost</TableCell>
|
||||
<TableCell>Reinforce cost</TableCell>
|
||||
<TableCell>
|
||||
{unit.reinforceCostRequisition && unit.reinforceCostRequisition > 0 &&
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_requisition.gif"/>
|
||||
{unit.reinforceCostRequisition}</span>}
|
||||
{unit.reinforceCostRequisition.toFixed(0)}</span>}
|
||||
{unit.reinforceCostPower !== undefined && unit.reinforceCostPower > 0 &&
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_power.gif"/>
|
||||
{unit.reinforceCostPower}</span>}
|
||||
{unit.reinforceCostPower.toFixed(0)}</span>}
|
||||
{(unit.reinforceCostPopulation !== undefined && unit.reinforceCostPopulation > 0) &&
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_orksquadcap.gif"/>
|
||||
{unit.reinforceCostPopulation}</span>}
|
||||
{unit.reinforceCostPopulation.toFixed(0)}</span>}
|
||||
{(unit.reinforceCostFaith !== undefined && unit.reinforceCostFaith > 0) &&
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_faith.gif"/>
|
||||
{unit.reinforceCostFaith}</span>}
|
||||
{(unit.reinforceCostSouls !== undefined && unit.reinforceCostSouls > 0) &&
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_souls.gif"/>
|
||||
{unit.reinforceCostSouls.toFixed(0)}</span>}
|
||||
{(unit.reinforceTime !== undefined && unit.reinforceTime > 0) &&
|
||||
<span> <AvTimerOutlinedIcon
|
||||
style={{verticalAlign: "top", fontSize: "18px"}}/>
|
||||
@ -144,10 +160,18 @@ function Unit(unit: IUnit, mod: IMod) {
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
}
|
||||
{unit.squadMaxSize > 1 &&
|
||||
<TableRow>
|
||||
<TableCell>Squad size</TableCell>
|
||||
<TableCell>
|
||||
{unit.squadStartSize} / {unit.squadMaxSize}
|
||||
</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">Armor type</TableCell>
|
||||
<TableCell component="th" scope="row">
|
||||
<ArmorType name={unit.armorType.name}/>
|
||||
</TableCell>
|
||||
@ -155,7 +179,7 @@ function Unit(unit: IUnit, mod: IMod) {
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">health</TableCell>
|
||||
<TableCell component="th" scope="row">Health</TableCell>
|
||||
<TableCell component="th" scope="row">
|
||||
<span><img style={{verticalAlign: "top"}}
|
||||
src="/images/Health_icon.webp"/>
|
||||
@ -166,7 +190,7 @@ function Unit(unit: IUnit, mod: IMod) {
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">move speed</TableCell>
|
||||
<TableCell component="th" scope="row">Move speed</TableCell>
|
||||
<TableCell component="th" scope="row">
|
||||
{unit.moveSpeed}
|
||||
</TableCell>
|
||||
@ -174,7 +198,7 @@ function Unit(unit: IUnit, mod: IMod) {
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">morale</TableCell>
|
||||
<TableCell component="th" scope="row">Morale</TableCell>
|
||||
<TableCell component="th" scope="row">
|
||||
{morale}
|
||||
</TableCell>
|
||||
@ -182,7 +206,15 @@ function Unit(unit: IUnit, mod: IMod) {
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">detect</TableCell>
|
||||
<TableCell component="th" scope="row">Mass</TableCell>
|
||||
<TableCell component="th" scope="row">
|
||||
{unit.mass}
|
||||
</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>
|
||||
|
||||
28
src/types/IBuilding.tsx
Normal file
28
src/types/IBuilding.tsx
Normal file
@ -0,0 +1,28 @@
|
||||
import {Irace} from "./Irace";
|
||||
import {IArmorType} from "./IArmorType";
|
||||
import {WeaponHardpoint} from "./IUnit";
|
||||
|
||||
export interface IBuilding {
|
||||
id: number
|
||||
race: Irace
|
||||
armorType: IArmorType
|
||||
armorType2?: IArmorType
|
||||
name: string
|
||||
filename: string
|
||||
description: string
|
||||
buildCostRequisition: number
|
||||
buildCostPower: number
|
||||
buildCostPopulation: number
|
||||
buildCostFaith: number
|
||||
buildCostSouls: number
|
||||
buildCostTime: number
|
||||
health: number
|
||||
healthRegeneration: number
|
||||
sightRadius: number
|
||||
detectRadius: number
|
||||
repairMax: number
|
||||
icon: string
|
||||
modId: number
|
||||
weapons: WeaponHardpoint[]
|
||||
}
|
||||
|
||||
14
src/types/IBuildingShort.tsx
Normal file
14
src/types/IBuildingShort.tsx
Normal file
@ -0,0 +1,14 @@
|
||||
import {Irace} from "./Irace";
|
||||
|
||||
export interface IRaceBuildings {
|
||||
race: Irace
|
||||
buildings: IBuildingShort[]
|
||||
}
|
||||
|
||||
export interface IBuildingShort {
|
||||
name: string
|
||||
icon: string
|
||||
id: number
|
||||
canDetect: boolean
|
||||
armourTypeName: string
|
||||
}
|
||||
@ -40,6 +40,7 @@ export interface IUnit {
|
||||
reinforceCostPower?: number
|
||||
reinforceCostPopulation ?: number
|
||||
reinforceCostFaith ?: number
|
||||
reinforceCostSouls ?: number
|
||||
reinforceTime?: number
|
||||
icon: string
|
||||
modId: number
|
||||
@ -90,22 +91,25 @@ export interface IWeapon {
|
||||
reloadTime: number
|
||||
setupTime: number
|
||||
accuracyReductionMoving: number
|
||||
minRange: number
|
||||
maxRange: number
|
||||
minDamage: number
|
||||
maxDamage: number
|
||||
minDamageValue: number
|
||||
moraleDamage: number
|
||||
damageRadius: number
|
||||
throwForceMin: number
|
||||
throwForceMax: number
|
||||
isMeleeWeapon: boolean
|
||||
canAttackAir: boolean
|
||||
canAttackGround: boolean
|
||||
haveEquipButton: boolean
|
||||
icon: string
|
||||
modId: number
|
||||
weaponPiercings: IWeaponPiercing[]
|
||||
weaponArmorPiercing: IWeaponPiercing[]
|
||||
}
|
||||
|
||||
export interface IWeaponPiercing {
|
||||
id: number
|
||||
armorType: IArmorType
|
||||
piercingValue: number
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user