Wiki full
This commit is contained in:
parent
27308c2c88
commit
2b4352ff21
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
1
.idea/.name
generated
Normal file
1
.idea/.name
generated
Normal file
@ -0,0 +1 @@
|
||||
dow-wiki-frontend
|
||||
13
.idea/codeStyles/Project.xml
generated
Normal file
13
.idea/codeStyles/Project.xml
generated
Normal file
@ -0,0 +1,13 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<JetCodeStyleSettings>
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</JetCodeStyleSettings>
|
||||
<ScalaCodeStyleSettings>
|
||||
<option name="MULTILINE_STRING_CLOSING_QUOTES_ON_NEW_LINE" value="true" />
|
||||
</ScalaCodeStyleSettings>
|
||||
<codeStyleSettings language="kotlin">
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
||||
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
@ -0,0 +1,5 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||
</state>
|
||||
</component>
|
||||
9
.idea/dow-wiki-frontend.iml
generated
Normal file
9
.idea/dow-wiki-frontend.iml
generated
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
6
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
6
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
</profile>
|
||||
</component>
|
||||
6
.idea/misc.xml
generated
Normal file
6
.idea/misc.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_16">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/dow-wiki-frontend.iml" filepath="$PROJECT_DIR$/.idea/dow-wiki-frontend.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/sbt.xml
generated
Normal file
6
.idea/sbt.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ScalaSbtSettings">
|
||||
<option name="customVMPath" />
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
11
index.html
Normal file
11
index.html
Normal file
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Webpack App</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello world!</h1>
|
||||
<h2>Tip: Check your console</h2>
|
||||
</body>
|
||||
</html>
|
||||
18412
package-lock.json
generated
Normal file
18412
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
BIN
public/images/ARM_Dmn_Hi.webp
Normal file
BIN
public/images/ARM_Dmn_Hi.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 80 B |
BIN
public/images/ARM_Dmn_Mid.webp
Normal file
BIN
public/images/ARM_Dmn_Mid.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 82 B |
BIN
public/images/ARM_Hvy_Inf_Mid.webp
Normal file
BIN
public/images/ARM_Hvy_Inf_Mid.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 84 B |
@ -0,0 +1,3 @@
|
||||
#back-button{
|
||||
margin-top: 10px;
|
||||
}
|
||||
@ -1,14 +1,56 @@
|
||||
import React from "react";
|
||||
|
||||
interface IArmorType{
|
||||
value: string
|
||||
name: string,
|
||||
withName: boolean
|
||||
}
|
||||
|
||||
class ArmorType extends React.Component<IArmorType, any> {
|
||||
|
||||
public static defaultProps = {
|
||||
withName: false
|
||||
};
|
||||
|
||||
renderArmorImage(armorType: String): string {
|
||||
switch(armorType) {
|
||||
case 'Infantry Low':
|
||||
return '/images/ARM_Inf_Lo.webp';
|
||||
case 'Infantry Medium':
|
||||
return '/images/ARM_Inf_Mid.webp';
|
||||
case 'Infantry High':
|
||||
return '/images/ARM_Inf_Hi.webp';
|
||||
case 'Infantry Heavy Medium':
|
||||
return '/images/ARM_Hvy_Inf_Mid.webp';
|
||||
case 'Infantry Heavy High':
|
||||
return '/images/ARM_Hvy_Inf_Hi.webp';
|
||||
case 'Commander':
|
||||
return '/images/ARM_Cmdr.webp';
|
||||
case 'Vehicle Low':
|
||||
return '/images/ARM_Veh_Lo.webp';
|
||||
case 'Vehicle Medium':
|
||||
return '/images/ARM_Veh_Mid.webp';
|
||||
case 'Vehicle High':
|
||||
return '/images/ARM_Veh_Hi.webp';
|
||||
case 'Air':
|
||||
return '/images/ARM_Air.webp';
|
||||
case 'Building Low':
|
||||
return '/images/ARM_Bld_Lo.webp';
|
||||
case 'Building Medium':
|
||||
return '/images/ARM_Bld_Mid.webp';
|
||||
case 'Building High':
|
||||
return '/images/ARM_Bld_Hi.webp';
|
||||
case 'Demon Medium':
|
||||
return '/images/ARM_Dmn_Mid.webp';
|
||||
case 'Demon High':
|
||||
return '/images/ARM_Dmn_Hi.webp';
|
||||
default:
|
||||
return 'Unknown armor';
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return this.props.value;
|
||||
|
||||
return (<span> <img style={{verticalAlign: "top"}} src={this.renderArmorImage(this.props.name)}/> {this.props.withName && this.props.name} </span>);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
240
src/classes/Weapon.tsx
Normal file
240
src/classes/Weapon.tsx
Normal file
@ -0,0 +1,240 @@
|
||||
import React from "react";
|
||||
import {IWeapon, WeaponPiercing} from "../types/IUnit";
|
||||
import {
|
||||
Grid2,
|
||||
Paper,
|
||||
styled,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
tableCellClasses,
|
||||
TableContainer,
|
||||
TableHead,
|
||||
TableRow, ToggleButton, ToggleButtonGroup
|
||||
} from "@mui/material";
|
||||
import ArmorType from "./ArmorType";
|
||||
import ArmorTypeNames from "../types/ArmorTypeValues";
|
||||
|
||||
interface IWeaponProps{
|
||||
weapon: IWeapon,
|
||||
}
|
||||
|
||||
interface IWeaponState{
|
||||
currentTable: "dps" | "one hit",
|
||||
}
|
||||
|
||||
class Weapon extends React.Component<IWeaponProps, any> {
|
||||
|
||||
humanReadableName(unit: string) {
|
||||
const firstUpper = String(unit).charAt(0).toUpperCase() + String(unit).slice(1);
|
||||
return firstUpper.replaceAll('_', ' ').replace('.rgd', '');
|
||||
}
|
||||
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
this.state = ({
|
||||
currentTable: 'dps'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
getPiercingK(armorType: string): number {
|
||||
const weaponPiercing = this.props.weapon.weaponPiercings.find((p) => p.armorType.name === armorType)
|
||||
return (typeof weaponPiercing !== "undefined" ? weaponPiercing.piercingValue : 10 ) / 100
|
||||
}
|
||||
|
||||
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 infLowPiercing = this.getPiercingK(ArmorTypeNames.InfantryLow)
|
||||
const infMedPiercing = this.getPiercingK(ArmorTypeNames.InfantryMedium)
|
||||
const infHighPiercing = this.getPiercingK(ArmorTypeNames.InfantryHigh)
|
||||
const infHeavyMedPiercing = this.getPiercingK(ArmorTypeNames.InfantryHeavyMedium)
|
||||
const infHeavyHighPiercing = this.getPiercingK(ArmorTypeNames.InfantryHeavyMedium)
|
||||
const demonPiercing = this.getPiercingK(ArmorTypeNames.DemonMedium)
|
||||
const demonHighPiercing = this.getPiercingK(ArmorTypeNames.DemonHigh)
|
||||
const commanderPiercing = this.getPiercingK(ArmorTypeNames.Commander)
|
||||
|
||||
const airPiercing = this.getPiercingK(ArmorTypeNames.Air)
|
||||
const vehLowPiercing = this.getPiercingK(ArmorTypeNames.VehicleLow)
|
||||
const vehMedPiercing = this.getPiercingK(ArmorTypeNames.VehicleMedium)
|
||||
const vehHighPiercing = this.getPiercingK(ArmorTypeNames.VehicleHigh)
|
||||
const buildingLowPiercing = this.getPiercingK(ArmorTypeNames.BuildingLow)
|
||||
const buildingMedPiercing = this.getPiercingK(ArmorTypeNames.BuildingMedium)
|
||||
const buildingHighPiercing = this.getPiercingK(ArmorTypeNames.BuildingHigh)
|
||||
|
||||
const getTotalDamage = (damagePiercing: number, isAir: boolean = false) => {
|
||||
|
||||
var minDamage = damagePiercing * weapon.minDamage
|
||||
var maxDamage = damagePiercing * weapon.maxDamage
|
||||
|
||||
if(minDamage < weapon.minDamageValue){
|
||||
minDamage = weapon.minDamageValue
|
||||
}
|
||||
if(maxDamage < weapon.minDamageValue){
|
||||
maxDamage = weapon.minDamageValue
|
||||
}
|
||||
|
||||
const averageDmg = (minDamage + maxDamage) / 2
|
||||
|
||||
return (averageDmg * dpsK).toFixed(2)
|
||||
}
|
||||
|
||||
const getMoraleDamage = () => {
|
||||
return (weapon.moraleDamage * dpsK / 2).toFixed(2)
|
||||
}
|
||||
|
||||
|
||||
const StyledTableCell = styled(TableCell)(({ theme }) => ({
|
||||
[`&.${tableCellClasses.head}`]: {
|
||||
backgroundColor: "rgb(234, 234, 234)",
|
||||
color: theme.palette.common.white,
|
||||
},
|
||||
[`&.${tableCellClasses.body}`]: {
|
||||
fontSize: 14,
|
||||
},
|
||||
}));
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h4>{this.humanReadableName(weapon.name)}</h4>
|
||||
<Grid2 container spacing={2}>
|
||||
|
||||
<Grid2 size={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>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Grid2>
|
||||
<Grid2 size={9}>
|
||||
<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={{minWidth: 600, 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.DemonMedium}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType name={ArmorTypeNames.DemonHigh}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType name={ArmorTypeNames.Commander}/></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(demonPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(demonHighPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(commanderPiercing)}</StyledTableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
<TableHead>
|
||||
<TableRow >
|
||||
<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(airPiercing)}</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>
|
||||
</Grid2>
|
||||
</Grid2>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Weapon;
|
||||
@ -4,6 +4,8 @@ import {NavLink, useLocation, useParams} from "react-router-dom";
|
||||
import {withRouter} from "../core/withrouter";
|
||||
import {IMod} from "../types/Imod";
|
||||
import {Irace} from "../types/Irace";
|
||||
import {Button} from "@mui/material";
|
||||
import {ArrowBack} from "@mui/icons-material";
|
||||
|
||||
|
||||
interface ModPageState {
|
||||
@ -42,8 +44,14 @@ class ModPage extends React.Component<any, ModPageState> {
|
||||
|
||||
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>)}
|
||||
|
||||
return <div>
|
||||
<a href="/"><Button id="back-button" variant="contained"
|
||||
startIcon={<ArrowBack/>}> Back</Button></a>
|
||||
<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 "";
|
||||
|
||||
@ -29,9 +29,6 @@ function Mods (mods: IMod[]) {
|
||||
)
|
||||
}
|
||||
|
||||
mapWithModVersions.keys()
|
||||
|
||||
|
||||
return(
|
||||
[...mapWithModVersions.keys()].map(m => Mod(m))
|
||||
)
|
||||
|
||||
@ -3,20 +3,33 @@ 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 {IUnit, IUnitResponse, IWeapon} from "../types/IUnit";
|
||||
import '../css/Unit.css'
|
||||
import {
|
||||
Accordion, AccordionDetails,
|
||||
Accordion,
|
||||
AccordionDetails,
|
||||
AccordionSummary,
|
||||
Button,
|
||||
ButtonGroup, Grid2, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow,
|
||||
ButtonGroup,
|
||||
Grid2,
|
||||
List,
|
||||
ListItem,
|
||||
ListSubheader,
|
||||
Paper,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableContainer,
|
||||
TableHead,
|
||||
TableRow,
|
||||
ToggleButton,
|
||||
ToggleButtonClassKey,
|
||||
ToggleButtonGroup, Typography
|
||||
ToggleButtonGroup,
|
||||
Typography
|
||||
} from "@mui/material";
|
||||
import {ArrowDropDown} from "@mui/icons-material";
|
||||
import {ArrowBack, ArrowDropDown} from "@mui/icons-material";
|
||||
import ArmorType from "../classes/ArmorType";
|
||||
import Item from "../classes/Item";
|
||||
import Weapon from "../classes/Weapon";
|
||||
|
||||
interface RacePageState {
|
||||
mod: IMod,
|
||||
@ -26,12 +39,6 @@ interface RacePageState {
|
||||
}
|
||||
|
||||
|
||||
|
||||
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>
|
||||
@ -46,6 +53,31 @@ function Unit (unit: IUnit) {
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/DETECT_NO.webp"/></span>
|
||||
|
||||
let mapWithUnitWeapons: Map<number, IWeapon[]> = new Map();
|
||||
|
||||
unit.weapons.forEach( weapon => {
|
||||
const weaponList = mapWithUnitWeapons.get(weapon.hardpoint)
|
||||
if(weaponList == null){
|
||||
mapWithUnitWeapons.set(weapon.hardpoint, new Array(weapon.weapon))
|
||||
} else {
|
||||
weaponList.push(weapon.weapon)
|
||||
}
|
||||
})
|
||||
|
||||
function WeaponSlot (hardpoint: number) {
|
||||
let weaponThisSlot = mapWithUnitWeapons.get(hardpoint) ?? []
|
||||
|
||||
let header = "Weapon slot " + hardpoint
|
||||
|
||||
return(
|
||||
<div>
|
||||
<h3>{header}</h3>
|
||||
{weaponThisSlot.map(weapon => <div><Weapon weapon={weapon}/>
|
||||
</div>)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<Accordion>
|
||||
@ -90,7 +122,7 @@ function Unit (unit: IUnit) {
|
||||
>
|
||||
<TableCell component="th" scope="row">armor type</TableCell>
|
||||
<TableCell component="th" scope="row">
|
||||
<ArmorType value={unit.armorType.name}/>
|
||||
<ArmorType name={unit.armorType.name} withName={true}/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow
|
||||
@ -137,6 +169,11 @@ function Unit (unit: IUnit) {
|
||||
{unit.description}
|
||||
</div>
|
||||
</Grid2>
|
||||
<Grid2 size={12}>
|
||||
{[...mapWithUnitWeapons.keys()].sort(function(a, b) {
|
||||
return a - b;
|
||||
}).map(h => WeaponSlot(h))}
|
||||
</Grid2>
|
||||
</Grid2>
|
||||
<i>{unit.filename}</i>
|
||||
</AccordionDetails>
|
||||
@ -162,7 +199,6 @@ class Units extends React.Component<IUnitResponse, UnitsState> {
|
||||
this.setState({
|
||||
selectedUnits: newUnitType
|
||||
});
|
||||
{this.props.units.map(unit => Unit(unit))}
|
||||
}
|
||||
|
||||
render () {
|
||||
@ -173,8 +209,10 @@ class Units extends React.Component<IUnitResponse, UnitsState> {
|
||||
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 {
|
||||
} else if (this.state.selectedUnits === 'support'){
|
||||
unitsToRender = this.props.units.filter(unit => unit.capSupport == 0 && unit.capInfantry == 0)
|
||||
} else {
|
||||
unitsToRender = this.props.units
|
||||
}
|
||||
|
||||
|
||||
@ -239,12 +277,18 @@ class RacePage extends React.Component<any, RacePageState> {
|
||||
}
|
||||
|
||||
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>
|
||||
const backRef = "/mod/" + this.state.mod.id
|
||||
|
||||
return <div><a href={backRef}><Button id="back-button" variant="contained" startIcon={<ArrowBack/>}> Back</Button></a>
|
||||
<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 "";
|
||||
return "loading...";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
19
src/types/ArmorTypeValues.ts
Normal file
19
src/types/ArmorTypeValues.ts
Normal file
@ -0,0 +1,19 @@
|
||||
enum ArmorTypeValues {
|
||||
InfantryLow = 'Infantry Low',
|
||||
InfantryMedium = 'Infantry Medium',
|
||||
InfantryHigh = 'Infantry High',
|
||||
InfantryHeavyMedium = 'Infantry Heavy Medium',
|
||||
InfantryHeavyHigh = 'Infantry Heavy High',
|
||||
Commander = 'Commander',
|
||||
VehicleLow = 'Vehicle Low',
|
||||
VehicleMedium = 'Vehicle Medium',
|
||||
VehicleHigh = 'Vehicle High',
|
||||
Air = 'Air',
|
||||
BuildingLow = 'Building Low',
|
||||
BuildingMedium = 'Building Medium',
|
||||
BuildingHigh = 'Building High',
|
||||
DemonMedium = 'Demon Medium',
|
||||
DemonHigh = 'Demon High',
|
||||
}
|
||||
|
||||
export default ArmorTypeValues;
|
||||
@ -42,11 +42,11 @@ export interface IUnit {
|
||||
|
||||
|
||||
export interface WeaponHardpoint {
|
||||
weapon: Weapon
|
||||
weapon: IWeapon
|
||||
hardpoint: number
|
||||
}
|
||||
|
||||
export interface Weapon {
|
||||
export interface IWeapon {
|
||||
id: number
|
||||
name: string
|
||||
costRequisition: number
|
||||
@ -56,9 +56,14 @@ export interface Weapon {
|
||||
reloadTime: number
|
||||
setupTime: number
|
||||
accuracyReductionMoving: number
|
||||
maxRange: number
|
||||
minDamage: number
|
||||
maxDamage: number
|
||||
minDamageValue: number
|
||||
moraleDamage: number
|
||||
isMeleeWeapon: boolean
|
||||
canAttackAir: boolean
|
||||
canAttackGround: boolean
|
||||
modId: number
|
||||
weaponPiercings: WeaponPiercing[]
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user