Optimization update
- request weapons and researches only when user open accordion - add building affects data
This commit is contained in:
parent
f0fde93d7b
commit
318b5c47e9
@ -7,7 +7,7 @@
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="The word 'Caldiris' is slang for someone who drinks alcohol in large quantities. For example, the phrase 'he was caldiris all night' implies that the person drank heavily throughout the night and posted content on dawn-of-war-unification-mod.fandom.com."
|
||||
content="Autogeneration wiki"
|
||||
/>
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||
<!--
|
||||
|
||||
@ -5,6 +5,7 @@ import {IconUrl} from "../core/api";
|
||||
import {Irace} from "../types/Irace";
|
||||
import {IAffectedData} from "../types/IAffectedData";
|
||||
import {IMod} from "../types/Imod";
|
||||
import AvTimerOutlinedIcon from "@mui/icons-material/AvTimer";
|
||||
|
||||
interface IModifiersProvidesTable{
|
||||
modifiers: IModifier[],
|
||||
@ -13,7 +14,7 @@ interface IModifiersProvidesTable{
|
||||
interface IModifiersProvidesResearchTable{
|
||||
modifiers: IModifier[],
|
||||
affectedData: IAffectedData,
|
||||
mod: IMod,
|
||||
modId: number,
|
||||
race: Irace,
|
||||
}
|
||||
|
||||
@ -63,6 +64,10 @@ function getModName(mt: String){
|
||||
return 'Change armor type';
|
||||
case 'modifiers\\cost_requisition_modifier.lua':
|
||||
return 'Requisition cost';
|
||||
case 'modifiers\\cost_power_modifier.lua':
|
||||
return 'Power cost';
|
||||
case 'modifiers\\cost_time_modifier.lua':
|
||||
return 'Cost time';
|
||||
default:
|
||||
return mt.replace("modifiers\\", "").replace("modifier.lua", "").replace(".lua", "").replaceAll("_", " ");
|
||||
}
|
||||
@ -84,8 +89,19 @@ function getModIcon(mt: String){
|
||||
return <img style={{verticalAlign: "top"}} src='/images/Resource_requisition.gif'/>;
|
||||
case 'modifiers\\cost_requisition_modifier.lua':
|
||||
return <img style={{verticalAlign: "top"}} src='/images/Resource_requisition.gif'/>;
|
||||
case 'modifiers\\cost_power_modifier.lua':
|
||||
return <img style={{verticalAlign: "top"}} src='/images/Resource_power.gif'/>;
|
||||
case 'modifiers\\morale_maximum_squad_modifier.lua':
|
||||
return <img style={{verticalAlign: "top"}} src='/images/ARM_Morale.webp'/>;
|
||||
case 'modifiers\\support_cap_player_modifier.lua':
|
||||
return <img style={{verticalAlign: "top"}} src='/images/Resource_cap_vehicle.gif'/>;
|
||||
case 'modifiers\\squad_cap_player_modifier.lua':
|
||||
return <img style={{verticalAlign: "top"}} src='/images/Resource_cap_infantry.gif'/>;
|
||||
case 'modifiers\\population_cap_player_modifier.lua':
|
||||
return <img style={{verticalAlign: "top"}} src='/images/Resource_orksquadcap.gif'/>;
|
||||
case 'modifiers\\cost_time_modifier.lua':
|
||||
return <AvTimerOutlinedIcon
|
||||
style={{verticalAlign: "top", fontSize: "18px"}}/>;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
@ -142,7 +158,7 @@ export function ModifiersProvidesTable (props: IModifiersProvidesResearchTable)
|
||||
if(affectedUnit != null) {
|
||||
return <span><img style={{verticalAlign: "top", height: 25}}
|
||||
src={getIcon(affectedUnit.icon)}/><a
|
||||
href={`/mod/${props.mod.id}/race/${props.race.id}/unit/${affectedUnit.id}`}>
|
||||
href={`/mod/${props.modId}/race/${props.race.id}/unit/${affectedUnit.id}`}>
|
||||
{affectedUnit.name}
|
||||
</a></span>
|
||||
}
|
||||
@ -151,14 +167,14 @@ export function ModifiersProvidesTable (props: IModifiersProvidesResearchTable)
|
||||
return <span><img style={{verticalAlign: "top", height: 25}}
|
||||
src={getIcon(affectedSergeant.icon)}/>{affectedSergeant.name} at <img style={{verticalAlign: "top", height: 25}}
|
||||
src={getIcon(affectedSergeant.unit.icon)}/><a
|
||||
href={`/mod/${props.mod.id}/race/${props.race.id}/unit/${affectedSergeant.unit.id}`}>
|
||||
href={`/mod/${props.modId}/race/${props.race.id}/unit/${affectedSergeant.unit.id}`}>
|
||||
{affectedSergeant.unit.name}
|
||||
</a></span>
|
||||
}
|
||||
var affectedBuilding = props.affectedData.affectedBuildings.find(ab => ab.filename.replaceAll('.rgd', '') === target);
|
||||
if(affectedBuilding != null) {
|
||||
return <span><img style={{verticalAlign: "top", height: 25}} src={getIcon(affectedBuilding.icon)}/><a
|
||||
href={`/mod/${props.mod.id}/race/${props.race.id}/building/${affectedBuilding.id}`}>
|
||||
href={`/mod/${props.modId}/race/${props.race.id}/building/${affectedBuilding.id}`}>
|
||||
{affectedBuilding.name}
|
||||
</a> </span>
|
||||
}
|
||||
@ -168,7 +184,7 @@ export function ModifiersProvidesTable (props: IModifiersProvidesResearchTable)
|
||||
return <span>{affectedWeapon.name ? affectedWeapon.name : affectedWeapon.filename.replaceAll('_', ' ').replace('.rgd', '')} at {
|
||||
affectedWeapon.units.map(unit =>
|
||||
<span><img style={{verticalAlign: "top", height: 25}} src={getIcon(unit.icon)}/><a
|
||||
href={`/mod/${props.mod.id}/race/${props.race.id}/unit/${unit.id}`}>
|
||||
href={`/mod/${props.modId}/race/${props.race.id}/unit/${unit.id}`}>
|
||||
{unit.name}
|
||||
</a> </span>
|
||||
)
|
||||
@ -179,7 +195,7 @@ export function ModifiersProvidesTable (props: IModifiersProvidesResearchTable)
|
||||
src={getIcon(affectedSergeant.icon)}/>{affectedSergeant.name} at <img
|
||||
style={{verticalAlign: "top", height: 25}}
|
||||
src={getIcon(affectedSergeant.unit.icon)}/><a
|
||||
href={`/mod//${props.mod.id}/race/${props.race.id}/unit/${affectedSergeant.unit.id}`}>
|
||||
href={`/mod//${props.modId}/race/${props.race.id}/unit/${affectedSergeant.unit.id}`}>
|
||||
{affectedSergeant.unit.name}
|
||||
</a> </span>
|
||||
)
|
||||
@ -187,7 +203,7 @@ export function ModifiersProvidesTable (props: IModifiersProvidesResearchTable)
|
||||
{
|
||||
affectedWeapon.buildings.map(affectedBuilding =>
|
||||
<span><img style={{verticalAlign: "top", height: 25}} src={getIcon(affectedBuilding.icon)}/><a
|
||||
href={`/mod//${props.mod.id}/race/${props.race.id}/building/${affectedBuilding.id}`}>
|
||||
href={`/mod//${props.modId}/race/${props.race.id}/building/${affectedBuilding.id}`}>
|
||||
{affectedBuilding.name}
|
||||
</a> </span>
|
||||
)
|
||||
|
||||
@ -89,7 +89,7 @@ function Required (props: IRequiredProps) {
|
||||
</div>
|
||||
}
|
||||
{requirement.requirementBuildings.map(b =>
|
||||
<div> Building: <img style={{verticalAlign: "top", height: 25}}
|
||||
<div key={b.id}> Building: <img style={{verticalAlign: "top", height: 25}}
|
||||
src={IconUrl + b.icon.replaceAll('\\', '/')}/>
|
||||
<a href= {'/mod/'+ props.modId +'/race/'+ props.raceId +'/building/' + b.id + "/"}>{b.name}</a></div>)
|
||||
}
|
||||
|
||||
@ -1,20 +1,8 @@
|
||||
import React, {useState} from "react";
|
||||
import {IconUrl, UserUrl} from "../core/api";
|
||||
import {ISergeant, IWeapon} from "../types/IUnit";
|
||||
import {
|
||||
Accordion, AccordionDetails,
|
||||
AccordionSummary,
|
||||
Grid2,
|
||||
Paper,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableContainer,
|
||||
TableRow, Tooltip
|
||||
} from "@mui/material";
|
||||
import React from "react";
|
||||
import {ISergeant, IShortWeapon} from "../types/IUnit";
|
||||
import {Grid2, Paper, Table, TableBody, TableCell, TableContainer, TableRow, Tooltip} from "@mui/material";
|
||||
import AvTimerOutlinedIcon from "@mui/icons-material/AvTimer";
|
||||
import ArmorType from "./ArmorType";
|
||||
import {ExpandMore} from "@mui/icons-material";
|
||||
import WeaponSlot from "./WeaponSlot";
|
||||
import Vision from "./Vision";
|
||||
import {IMod} from "../types/Imod";
|
||||
@ -23,7 +11,6 @@ import {Irace} from "../types/Irace";
|
||||
import Required from "./Required";
|
||||
|
||||
|
||||
|
||||
export interface SergeantProps {
|
||||
sergeant: ISergeant,
|
||||
mod: IMod,
|
||||
@ -34,7 +21,7 @@ const Sergeant = (props: SergeantProps) => {
|
||||
|
||||
const sergeant = props.sergeant
|
||||
|
||||
let mapWithUnitWeapons: Map<number, Map<number, IWeapon>> = new Map();
|
||||
let mapWithUnitWeapons: Map<number, Map<number, IShortWeapon>> = new Map();
|
||||
|
||||
sergeant.weapons.forEach(weapon => {
|
||||
const weaponMap = mapWithUnitWeapons.get(weapon.hardpoint)
|
||||
|
||||
@ -32,17 +32,24 @@ export default function UnitsTable(prop: {modId: number}) {
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
fetch(AvailableBuildings + "/mod/" + prop.modId)
|
||||
.then(res => res.json())
|
||||
.then((resBuildings: IRaceBuildings[]) => {
|
||||
fetch(AvailableUnits + "/mod/" + prop.modId)
|
||||
.then(res => res.json())
|
||||
.then((res: IRaceUnits[]) => {
|
||||
.then(resUnits => resUnits.json())
|
||||
.then((resUnits: IRaceUnits[]) => {
|
||||
if(resUnits.length <= 10){
|
||||
fetch(AvailableBuildings + "/mod/" + prop.modId)
|
||||
.then(resBuildings => resBuildings.json())
|
||||
.then((resBuildings: IRaceBuildings[]) => {
|
||||
setUnitsTable({
|
||||
racesUnits : res,
|
||||
racesUnits : resUnits,
|
||||
racesBuildings: resBuildings
|
||||
});
|
||||
})
|
||||
});
|
||||
}else {
|
||||
setUnitsTable({
|
||||
racesUnits : resUnits,
|
||||
racesBuildings: []
|
||||
});
|
||||
}
|
||||
})
|
||||
}, []);
|
||||
|
||||
@ -149,7 +156,7 @@ export default function UnitsTable(prop: {modId: number}) {
|
||||
function generateRaceList(unitsTable: IUnitsTable){
|
||||
return unitsTable.racesUnits.sort(function (a, b) {
|
||||
return a.race.name.localeCompare(b.race.name);
|
||||
}).map(raceUnits => <h5><Link color="inherit"
|
||||
}).map(raceUnits => <h5 key={raceUnits.race.id}><Link color="inherit"
|
||||
href={"/mod/" + prop.modId + "/race/" + raceUnits.race.id}>{raceUnits.race.name}</Link><br/>
|
||||
</h5>)
|
||||
}
|
||||
|
||||
@ -1,32 +1,14 @@
|
||||
import React from "react";
|
||||
import {IWeapon, IWeaponPiercing} from "../types/IUnit";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionDetails,
|
||||
AccordionSummary,
|
||||
Grid2,
|
||||
Paper,
|
||||
styled,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
tableCellClasses,
|
||||
TableContainer,
|
||||
TableHead,
|
||||
TableRow, ToggleButton, ToggleButtonGroup
|
||||
} from "@mui/material";
|
||||
import ArmorType from "./ArmorType";
|
||||
import ArmorTypeNames from "../types/ArmorTypeValues";
|
||||
import {IShortWeapon, IWeapon} from "../types/IUnit";
|
||||
import {Accordion, AccordionDetails, AccordionSummary} from "@mui/material";
|
||||
import {IconUrl} from "../core/api";
|
||||
import {ExpandMore} from "@mui/icons-material";
|
||||
import Sergeant from "./Sergeant";
|
||||
import {IMod} from "../types/Imod";
|
||||
import {Irace} from "../types/Irace";
|
||||
import {renderAffectedResearches} from "./building/Research";
|
||||
import Required from "./Required";
|
||||
import WeaponFull from "./WeaponFull";
|
||||
|
||||
interface IWeaponProps {
|
||||
weapon: IWeapon,
|
||||
weapon: IShortWeapon,
|
||||
isDefault: Boolean,
|
||||
renderRequired: Boolean,
|
||||
mod: IMod,
|
||||
@ -46,98 +28,13 @@ class Weapon extends React.Component<IWeaponProps, any> {
|
||||
return firstUpper.replaceAll('_', ' ').replace('.rgd', '');
|
||||
}
|
||||
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
this.state = ({
|
||||
currentTable: 'dps'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
getPiercingK(armorType: string): number {
|
||||
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) => {
|
||||
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.InfantryHeavyHigh)
|
||||
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)
|
||||
|
||||
// UA mod
|
||||
const demonLowPiercing = this.getPiercingK(ArmorTypeNames.DemonLow)
|
||||
const buildingSuperPiercing = this.getPiercingK(ArmorTypeNames.BuildingSuper)
|
||||
const livingMetalPiercing = this.getPiercingK(ArmorTypeNames.LivingMetal)
|
||||
const titanPiercing = this.getPiercingK(ArmorTypeNames.Titan)
|
||||
|
||||
const getTotalDamage = (damagePiercing: number, isAir: boolean = false) => {
|
||||
|
||||
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) {
|
||||
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(244,244,244)",
|
||||
marginRight: 'auto',
|
||||
marginLeft: 'auto',
|
||||
paddingLeft: 10
|
||||
},
|
||||
[`&.${tableCellClasses.body}`]: {
|
||||
fontSize: 12,
|
||||
textAlign: 'center',
|
||||
paddingRight: 18,
|
||||
paddingLeft: 10
|
||||
},
|
||||
}));
|
||||
|
||||
return (
|
||||
<div style={{marginBottom: 10}}><Accordion>
|
||||
<div style={{marginBottom: 10}}><Accordion TransitionProps={{ unmountOnExit: true, timeout: 100 }}>
|
||||
<AccordionSummary
|
||||
expandIcon={<ExpandMore/>}
|
||||
aria-controls="panel1-content"
|
||||
@ -151,290 +48,7 @@ class Weapon extends React.Component<IWeaponProps, any> {
|
||||
)} {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: 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.setupTime != 0 ? (weapon.setupTime).toFixed(3).replace(/[,.]?0+$/, '') : "-"}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<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>
|
||||
{ this.props.mod !== undefined && this.props.mod.name.includes("Ultimate Apocalypse") ?
|
||||
<Table sx={{marginTop: "10px", textAlign: "center"}} 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.DemonLow}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.DemonMedium}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.DemonHigh}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType name={ArmorTypeNames.Air}/></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(demonLowPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(demonPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(demonHighPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(airPiercing, true)}</StyledTableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.VehicleLow}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.VehicleMedium}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.VehicleHigh}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.LivingMetal}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.Titan}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.BuildingLow}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.BuildingMedium}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.BuildingHigh}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.BuildingSuper}/></StyledTableCell>
|
||||
<StyledTableCell><img style={{verticalAlign: "top"}}
|
||||
src="/images/ARM_Morale.webp"/>
|
||||
<div style={{width: 20, fontSize: 12, height: 50}}>
|
||||
<i>Morale</i></div>
|
||||
</StyledTableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<StyledTableCell>{getTotalDamage(vehLowPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(vehMedPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(vehHighPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(livingMetalPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(titanPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(buildingLowPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(buildingMedPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(buildingHighPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(buildingSuperPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getMoraleDamage()}</StyledTableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table> :
|
||||
<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"/>
|
||||
<div style={{width: 20, fontSize: 12, height: 50}}>
|
||||
<i>Morale</i></div>
|
||||
</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>
|
||||
{weapon.requirements !== null && !this.props.isDefault && this.props.haveReinforceMenu &&
|
||||
<Grid2 size={{xs: 12, md: 12}}>
|
||||
<Required requirement={weapon.requirements} modId={this.props.mod.id} raceId={this.props.race.id}/>
|
||||
</Grid2>}
|
||||
<Grid2 size={12}>
|
||||
{renderAffectedResearches(weapon.affectedResearches, this.props.mod.id, this.props.race.id)}
|
||||
</Grid2>
|
||||
</Grid2>
|
||||
<WeaponFull weaponId={weapon.id} isDefault={this.props.isDefault} mod={this.props.mod} race={this.props.race} haveReinforceMenu={this.props.haveReinforceMenu}/>
|
||||
</AccordionDetails>
|
||||
</Accordion></div>
|
||||
);
|
||||
|
||||
430
src/classes/WeaponFull.tsx
Normal file
430
src/classes/WeaponFull.tsx
Normal file
@ -0,0 +1,430 @@
|
||||
import React, {useEffect, useState} from "react";
|
||||
import {AvailableBuildings, AvailableUnits, UserUrl, WeaponUrl} from "../core/api";
|
||||
import {IWeapon} from "../types/IUnit";
|
||||
import ArmorTypeNames from "../types/ArmorTypeValues";
|
||||
import {
|
||||
AccordionDetails,
|
||||
Grid2,
|
||||
Paper,
|
||||
styled,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
tableCellClasses,
|
||||
TableContainer, TableHead,
|
||||
TableRow, ToggleButton, ToggleButtonGroup
|
||||
} from "@mui/material";
|
||||
import ArmorType from "./ArmorType";
|
||||
import Required from "./Required";
|
||||
import {renderAffectedResearches} from "./building/Research";
|
||||
import {IMod} from "../types/Imod";
|
||||
import {Irace} from "../types/Irace";
|
||||
import {IRaceUnits} from "../types/IUnitShort";
|
||||
import {IRaceBuildings} from "../types/IBuildingShort";
|
||||
|
||||
interface IWeaponFull {
|
||||
currentTable: string;
|
||||
weapon?: IWeapon;
|
||||
}
|
||||
|
||||
export default function WeaponFull(props: {weaponId: number, isDefault: Boolean, mod: IMod, race: Irace, haveReinforceMenu: Boolean}) {
|
||||
|
||||
const [weaoponFull, setWeaponFull] = useState<IWeaponFull>({
|
||||
currentTable: "dps",
|
||||
weapon: undefined,
|
||||
});
|
||||
|
||||
const StyledTableCell = styled(TableCell)(({theme}) => ({
|
||||
[`&.${tableCellClasses.head}`]: {
|
||||
backgroundColor: "rgb(244,244,244)",
|
||||
marginRight: 'auto',
|
||||
marginLeft: 'auto',
|
||||
paddingLeft: 10
|
||||
},
|
||||
[`&.${tableCellClasses.body}`]: {
|
||||
fontSize: 12,
|
||||
textAlign: 'center',
|
||||
paddingRight: 18,
|
||||
paddingLeft: 10
|
||||
},
|
||||
}));
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
fetch(WeaponUrl + "/" + props.mod.id + "/" + props.weaponId)
|
||||
.then(res => res.json())
|
||||
.then((weapon: IWeapon) => {
|
||||
setWeaponFull({
|
||||
currentTable: "dps",
|
||||
weapon: weapon,
|
||||
})
|
||||
|
||||
});
|
||||
}, []);
|
||||
|
||||
|
||||
|
||||
|
||||
if(weaoponFull.weapon !== undefined){
|
||||
|
||||
const weapon = weaoponFull.weapon
|
||||
|
||||
function getPiercingK(armorType: string): number {
|
||||
const weaponPiercing = weapon.weaponArmorPiercing.find((p) => p.armorType.name === armorType)
|
||||
return (typeof weaponPiercing !== "undefined" ? weaponPiercing.piercingValue : 10) / 100
|
||||
}
|
||||
|
||||
function handleChange (e: React.MouseEvent, selectedDamageTable: string) {
|
||||
setWeaponFull({
|
||||
currentTable: selectedDamageTable,
|
||||
weapon: weaoponFull.weapon,
|
||||
});
|
||||
}
|
||||
|
||||
const dpsK = (weaoponFull.currentTable == "dps") ? weapon.accuracy * (1 / (weapon.reloadTime - (weapon.reloadTime % 0.125))) : 1
|
||||
|
||||
const infLowPiercing = getPiercingK(ArmorTypeNames.InfantryLow)
|
||||
const infMedPiercing = getPiercingK(ArmorTypeNames.InfantryMedium)
|
||||
const infHighPiercing = getPiercingK(ArmorTypeNames.InfantryHigh)
|
||||
const infHeavyMedPiercing = getPiercingK(ArmorTypeNames.InfantryHeavyMedium)
|
||||
const infHeavyHighPiercing = getPiercingK(ArmorTypeNames.InfantryHeavyHigh)
|
||||
const demonPiercing = getPiercingK(ArmorTypeNames.DemonMedium)
|
||||
const demonHighPiercing = getPiercingK(ArmorTypeNames.DemonHigh)
|
||||
const commanderPiercing = getPiercingK(ArmorTypeNames.Commander)
|
||||
|
||||
const airPiercing = getPiercingK(ArmorTypeNames.Air)
|
||||
const vehLowPiercing = getPiercingK(ArmorTypeNames.VehicleLow)
|
||||
const vehMedPiercing = getPiercingK(ArmorTypeNames.VehicleMedium)
|
||||
const vehHighPiercing = getPiercingK(ArmorTypeNames.VehicleHigh)
|
||||
const buildingLowPiercing = getPiercingK(ArmorTypeNames.BuildingLow)
|
||||
const buildingMedPiercing = getPiercingK(ArmorTypeNames.BuildingMedium)
|
||||
const buildingHighPiercing = getPiercingK(ArmorTypeNames.BuildingHigh)
|
||||
|
||||
// UA mod
|
||||
const demonLowPiercing = getPiercingK(ArmorTypeNames.DemonLow)
|
||||
const buildingSuperPiercing = getPiercingK(ArmorTypeNames.BuildingSuper)
|
||||
const livingMetalPiercing = getPiercingK(ArmorTypeNames.LivingMetal)
|
||||
const titanPiercing = getPiercingK(ArmorTypeNames.Titan)
|
||||
|
||||
const getTotalDamage = (damagePiercing: number, isAir: boolean = false) => {
|
||||
|
||||
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) {
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Grid2 container spacing={2}>
|
||||
<Grid2 size={12}>
|
||||
<div style={{whiteSpace: "pre-wrap"}}>
|
||||
<span
|
||||
className="weaponDescription">{props.isDefault ? "Default weapon" : weapon.description}</span>
|
||||
</div>
|
||||
</Grid2>
|
||||
|
||||
<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.setupTime != 0 ? (weapon.setupTime).toFixed(3).replace(/[,.]?0+$/, '') : "-"}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<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
|
||||
aria-label="Platform"
|
||||
value={weaoponFull.currentTable}
|
||||
onChange={handleChange}
|
||||
>
|
||||
<ToggleButton size="small" value="dps">Dps</ToggleButton>
|
||||
<ToggleButton size="small" value="one hit">One hit average damage</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
<TableContainer>
|
||||
{ props.mod !== undefined && props.mod.name.includes("Ultimate Apocalypse") ?
|
||||
<Table sx={{marginTop: "10px", textAlign: "center"}} 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.DemonLow}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.DemonMedium}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.DemonHigh}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType name={ArmorTypeNames.Air}/></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(demonLowPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(demonPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(demonHighPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(airPiercing, true)}</StyledTableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.VehicleLow}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.VehicleMedium}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.VehicleHigh}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.LivingMetal}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.Titan}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.BuildingLow}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.BuildingMedium}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.BuildingHigh}/></StyledTableCell>
|
||||
<StyledTableCell><ArmorType
|
||||
name={ArmorTypeNames.BuildingSuper}/></StyledTableCell>
|
||||
<StyledTableCell><img style={{verticalAlign: "top"}}
|
||||
src="/images/ARM_Morale.webp"/>
|
||||
<div style={{width: 20, fontSize: 12, height: 50}}>
|
||||
<i>Morale</i></div>
|
||||
</StyledTableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<StyledTableCell>{getTotalDamage(vehLowPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(vehMedPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(vehHighPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(livingMetalPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(titanPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(buildingLowPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(buildingMedPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(buildingHighPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getTotalDamage(buildingSuperPiercing)}</StyledTableCell>
|
||||
<StyledTableCell>{getMoraleDamage()}</StyledTableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table> :
|
||||
<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"/>
|
||||
<div style={{width: 20, fontSize: 12, height: 50}}>
|
||||
<i>Morale</i></div>
|
||||
</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>
|
||||
{weapon.requirements !== null && !props.isDefault && props.haveReinforceMenu &&
|
||||
<Grid2 size={{xs: 12, md: 12}}>
|
||||
<Required requirement={weapon.requirements} modId={props.mod.id} raceId={props.race.id}/>
|
||||
</Grid2>}
|
||||
<Grid2 size={12}>
|
||||
{renderAffectedResearches(weapon.affectedResearches, props.mod.id, props.race.id)}
|
||||
</Grid2>
|
||||
</Grid2>
|
||||
</div>
|
||||
)
|
||||
} else return <div>loading...</div>;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -1,12 +1,13 @@
|
||||
import Weapon from "./Weapon";
|
||||
import React from "react";
|
||||
import {IWeapon} from "../types/IUnit";
|
||||
import {IShortWeapon, IWeapon} from "../types/IUnit";
|
||||
import {IMod} from "../types/Imod";
|
||||
import {Irace} from "../types/Irace";
|
||||
import WeaponShort from "./WeaponFull";
|
||||
|
||||
export interface WeaponSlotProps {
|
||||
hardpoint: number,
|
||||
unitWeapons: Map<number, IWeapon> | undefined,
|
||||
unitWeapons: Map<number, IShortWeapon> | undefined,
|
||||
mod: IMod,
|
||||
race: Irace,
|
||||
haveReinforceMenu?: boolean ,
|
||||
|
||||
@ -87,7 +87,7 @@ function BuildingAddon(props: IBuildingAddonProps){
|
||||
{addon.description}
|
||||
</div>
|
||||
</Grid2>
|
||||
<ModifiersProvidesTable modifiers={addon.addonModifiers} affectedData={addon.affectedData} mod={props.mod} race={building.race}/>
|
||||
<ModifiersProvidesTable modifiers={addon.addonModifiers} affectedData={addon.affectedData} modId={props.mod.id} race={building.race}/>
|
||||
{addon.addonRequirement !== null &&
|
||||
<Grid2 size={{xs: 12, md: 12}}>
|
||||
<Required requirement={addon.addonRequirement} modId={building.modId} raceId={building.race.id}/>
|
||||
|
||||
@ -19,20 +19,21 @@ import Required from "../Required";
|
||||
import React from "react";
|
||||
import {IBuilding} from "../../types/IBuilding";
|
||||
import {IResearchShort} from "../../types/IResearchShort";
|
||||
import ResearchFull from "./ResearchFull";
|
||||
|
||||
|
||||
interface IResearchProps {
|
||||
research: IResearch,
|
||||
research: IResearchShort,
|
||||
building: IBuilding,
|
||||
mod: IMod,
|
||||
}
|
||||
|
||||
function ResearchFull(props: IResearchProps){
|
||||
function Research(props: IResearchProps){
|
||||
|
||||
const research = props.research
|
||||
const building = props.building
|
||||
|
||||
return <div className='addon-research-accordion' id={"research-" + research.id}><Accordion>
|
||||
return <div className='addon-research-accordion' id={"research-" + research.id}><Accordion TransitionProps={{ unmountOnExit: true, timeout: 100 }}>
|
||||
<AccordionSummary
|
||||
expandIcon={<ExpandMore/>}
|
||||
aria-controls="panel1-content"
|
||||
@ -43,61 +44,7 @@ function ResearchFull(props: IResearchProps){
|
||||
</span>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<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">
|
||||
{research.costRequisition > 0 &&
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_requisition.gif"/>
|
||||
{research.costRequisition.toFixed(0)}</span>}
|
||||
{research.costPower > 0 && <span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_power.gif"/>
|
||||
{research.costPower.toFixed(0)}</span>}
|
||||
{(research.costPopulation !== undefined && research.costPopulation > 0) &&
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_orksquadcap.gif"/>
|
||||
{research.costPopulation.toFixed(0)}</span>}
|
||||
{(research.costFaith !== undefined && research.costFaith > 0) &&
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_faith.gif"/>
|
||||
{research.costFaith}</span>}
|
||||
{(research.costSouls !== undefined && research.costSouls > 0) &&
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_souls.gif"/>
|
||||
{research.costSouls.toFixed(0)}</span>}
|
||||
{(research.costTime !== undefined && research.costTime > 0) &&
|
||||
<span> <AvTimerOutlinedIcon
|
||||
style={{verticalAlign: "top", fontSize: "18px"}}/>
|
||||
{research.costTime}s</span>}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer><br/>
|
||||
</Grid2>
|
||||
<Grid2 size={{xs: 12, md: 8}}>
|
||||
<div style={{whiteSpace: "pre-wrap"}}>
|
||||
{research.description}
|
||||
</div>
|
||||
|
||||
</Grid2>
|
||||
<Grid2 size={{xs: 12, md: 12}}>
|
||||
<ModifiersProvidesTable modifiers={research.modifiers} affectedData={research.affectedData} mod={props.mod} race={building.race}/>
|
||||
</Grid2>
|
||||
{research.requirements !== null &&
|
||||
<Grid2 size={{xs: 12, md: 12}}>
|
||||
<Required requirement={research.requirements} modId={building.modId} raceId={building.race.id}/>
|
||||
</Grid2>}
|
||||
</Grid2>
|
||||
<i className="rgdFrom">{research.filename}</i>
|
||||
<ResearchFull id={research.id} building={building}/>
|
||||
</AccordionDetails>
|
||||
</Accordion></div>
|
||||
|
||||
@ -120,5 +67,5 @@ export function renderAffectedResearches(researches: IResearchShort[], modId: nu
|
||||
}
|
||||
|
||||
|
||||
export default ResearchFull;
|
||||
export default Research;
|
||||
|
||||
|
||||
115
src/classes/building/ResearchFull.tsx
Normal file
115
src/classes/building/ResearchFull.tsx
Normal file
@ -0,0 +1,115 @@
|
||||
import {IMod} from "../../types/Imod";
|
||||
import {IResearch} from "../../types/IResearch";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionDetails,
|
||||
AccordionSummary,
|
||||
Grid2,
|
||||
Paper,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableContainer,
|
||||
TableRow
|
||||
} from "@mui/material";
|
||||
import {ExpandMore} from "@mui/icons-material";
|
||||
import {getIcon, ModifiersProvidesTable} from "../ModifiersProvideTable";
|
||||
import AvTimerOutlinedIcon from "@mui/icons-material/AvTimer";
|
||||
import Required from "../Required";
|
||||
import React, {useEffect, useState} from "react";
|
||||
import {IBuilding} from "../../types/IBuilding";
|
||||
import {IResearchShort} from "../../types/IResearchShort";
|
||||
import {ResearchUrl, WeaponUrl} from "../../core/api";
|
||||
import {IWeapon} from "../../types/IUnit";
|
||||
|
||||
|
||||
interface IResearchFull {
|
||||
research: IResearch | undefined,
|
||||
}
|
||||
|
||||
function ResearchFull(props: { id: number, building: IBuilding }){
|
||||
|
||||
const [researchFull, setResearchFull] = useState<IResearchFull>({
|
||||
research: undefined,
|
||||
});
|
||||
|
||||
const building = props.building
|
||||
const research= researchFull.research!!
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
fetch(ResearchUrl + "/" + building.modId + "/" + props.id)
|
||||
.then(res => res.json())
|
||||
.then((research: IResearch) => {
|
||||
setResearchFull({
|
||||
research:research,
|
||||
})
|
||||
|
||||
});
|
||||
}, []);
|
||||
|
||||
if(researchFull.research !== undefined) {
|
||||
|
||||
return <div className='addon-research-accordion' id={"research-" + research.id}>
|
||||
|
||||
<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">
|
||||
{research.costRequisition > 0 &&
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_requisition.gif"/>
|
||||
{research.costRequisition.toFixed(0)}</span>}
|
||||
{research.costPower > 0 && <span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_power.gif"/>
|
||||
{research.costPower.toFixed(0)}</span>}
|
||||
{(research.costPopulation !== undefined && research.costPopulation > 0) &&
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_orksquadcap.gif"/>
|
||||
{research.costPopulation.toFixed(0)}</span>}
|
||||
{(research.costFaith !== undefined && research.costFaith > 0) &&
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_faith.gif"/>
|
||||
{research.costFaith}</span>}
|
||||
{(research.costSouls !== undefined && research.costSouls > 0) &&
|
||||
<span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/Resource_souls.gif"/>
|
||||
{research.costSouls.toFixed(0)}</span>}
|
||||
{(research.costTime !== undefined && research.costTime > 0) &&
|
||||
<span> <AvTimerOutlinedIcon
|
||||
style={{verticalAlign: "top", fontSize: "18px"}}/>
|
||||
{research.costTime}s</span>}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer><br/>
|
||||
</Grid2>
|
||||
<Grid2 size={{xs: 12, md: 8}}>
|
||||
<div style={{whiteSpace: "pre-wrap"}}>
|
||||
{research.description}
|
||||
</div>
|
||||
|
||||
</Grid2>
|
||||
<Grid2 size={{xs: 12, md: 12}}>
|
||||
<ModifiersProvidesTable modifiers={research.modifiers} affectedData={research.affectedData}
|
||||
modId={building.modId} race={building.race}/>
|
||||
</Grid2>
|
||||
{research.requirements !== null &&
|
||||
<Grid2 size={{xs: 12, md: 12}}>
|
||||
<Required requirement={research.requirements} modId={building.modId} raceId={building.race.id}/>
|
||||
</Grid2>}
|
||||
</Grid2>
|
||||
</div>
|
||||
} else return <div>loading...</div>
|
||||
}
|
||||
|
||||
export default ResearchFull;
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
|
||||
export const UserUrl = process.env.REACT_APP_HOST_URL + '/api/v1/user';
|
||||
export const WeaponUrl = process.env.REACT_APP_HOST_URL + '/api/v1/weapon';
|
||||
export const ResearchUrl = process.env.REACT_APP_HOST_URL + '/api/v1/research';
|
||||
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';
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import {AvailableBuildings, AvailableMods, IconUrl} from "../core/api";
|
||||
import React, {useEffect} from "react";
|
||||
import React from "react";
|
||||
import {withRouter} from "../core/withrouter";
|
||||
import {IWeapon} from "../types/IUnit";
|
||||
import {IShortWeapon} from "../types/IUnit";
|
||||
import '../css/Building.css'
|
||||
import {
|
||||
Button,
|
||||
@ -13,7 +13,8 @@ import {
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableContainer,
|
||||
TableRow, Tooltip
|
||||
TableRow,
|
||||
Tooltip
|
||||
} from "@mui/material";
|
||||
import {ArrowBack} from "@mui/icons-material";
|
||||
import ArmorType from "../classes/ArmorType";
|
||||
@ -27,6 +28,7 @@ import BuildingAddon from "../classes/building/BuildingAddon";
|
||||
import {IUnitShort} from "../types/IUnitShort";
|
||||
import Research, {renderAffectedResearches} from "../classes/building/Research";
|
||||
import Required from "../classes/Required";
|
||||
import {ModifiersProvidesTable} from "../classes/ModifiersProvideTable";
|
||||
|
||||
interface UintPageState {
|
||||
building: IBuilding,
|
||||
@ -35,7 +37,7 @@ interface UintPageState {
|
||||
|
||||
function Unit (unit: IUnitShort, modId: number, raceId: String) {
|
||||
|
||||
return (<Grid2 size={{xs: 12, md: 3}}><Link href={"/mod/" + modId + "/race/" + raceId + "/unit/" + unit.id}><ListItem>
|
||||
return (<Grid2 key={unit.id} size={{xs: 12, md: 3}}><Link href={"/mod/" + modId + "/race/" + raceId + "/unit/" + unit.id}><ListItem>
|
||||
{unit.icon && <img className="unitIcon" src={IconUrl + unit.icon.replaceAll('\\', '/')}/> }
|
||||
{unit.name}
|
||||
{unit.canDetect && <span> <img style={{verticalAlign: "top"}}
|
||||
@ -49,7 +51,7 @@ function Building(building: IBuilding, mod: IMod) {
|
||||
document.title = building.name
|
||||
|
||||
|
||||
let mapBuildingWeapons: Map<number, Map<number, IWeapon>> = new Map();
|
||||
let mapBuildingWeapons: Map<number, Map<number, IShortWeapon>> = new Map();
|
||||
|
||||
building.weapons.forEach(weapon => {
|
||||
const weaponMap = mapBuildingWeapons.get(weapon.hardpoint)
|
||||
@ -176,6 +178,11 @@ function Building(building: IBuilding, mod: IMod) {
|
||||
<Grid2 size={{xs: 12, md: 12}}>
|
||||
<Required requirement={building.requirements} modId={building.modId} raceId={building.race.id}/>
|
||||
</Grid2>}
|
||||
{building.modifiers.length > 0 &&
|
||||
<Grid2 size={{xs: 12, md: 12}} >
|
||||
<h3>Affected on</h3>
|
||||
<ModifiersProvidesTable modifiers={building.modifiers} race={building.race} modId={building.modId} affectedData={building.affectedData} />
|
||||
</Grid2>}
|
||||
{building.units.length > 0 && <Grid2 size={12}>
|
||||
<h3>Unit production</h3>
|
||||
<Grid2 container spacing={2}>
|
||||
@ -193,7 +200,7 @@ function Building(building: IBuilding, mod: IMod) {
|
||||
{building.researches.length > 0 && <Grid2 size={12}>
|
||||
<h3>Researches</h3>
|
||||
{building.researches.map(r =>
|
||||
<Research mod={mod} research={r} building={building}/>
|
||||
<Research key={r.id} research={r} building={building} mod={mod}/>
|
||||
)}
|
||||
</Grid2> }
|
||||
<Grid2 size={12}>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import {AvailableMods, AvailableUnits, IconUrl} from "../core/api";
|
||||
import React from "react";
|
||||
import {withRouter} from "../core/withrouter";
|
||||
import {IUnit, IWeapon} from "../types/IUnit";
|
||||
import {IShortWeapon, IUnit} from "../types/IUnit";
|
||||
import '../css/Unit.css'
|
||||
import {
|
||||
Accordion,
|
||||
@ -46,7 +46,7 @@ function Unit(unit: IUnit, mod: IMod) {
|
||||
|
||||
</span> : "-"
|
||||
|
||||
let mapWithUnitWeapons: Map<number, Map<number, IWeapon>> = new Map();
|
||||
let mapWithUnitWeapons: Map<number, Map<number, IShortWeapon>> = new Map();
|
||||
|
||||
unit.weapons.forEach(weapon => {
|
||||
const weaponMap = mapWithUnitWeapons.get(weapon.hardpoint)
|
||||
|
||||
@ -33,9 +33,11 @@ export interface IBuilding {
|
||||
repairMax: number
|
||||
icon: string
|
||||
modId: number
|
||||
modifiers: IModifier[]
|
||||
affectedData: IAffectedData,
|
||||
weapons: WeaponHardpoint[]
|
||||
addons: IBuildingAddon[]
|
||||
researches: IResearch[]
|
||||
researches: IResearchShort[]
|
||||
units: IUnitShort[]
|
||||
affectedResearches: IResearchShort[],
|
||||
requirements: IRequirement,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
export interface IResearchShort {
|
||||
id: string;
|
||||
id: number;
|
||||
name: string;
|
||||
icon: string;
|
||||
buildingId: number;
|
||||
|
||||
@ -92,11 +92,19 @@ export interface ISergeant {
|
||||
|
||||
|
||||
export interface WeaponHardpoint {
|
||||
weapon: IWeapon
|
||||
weapon: IShortWeapon
|
||||
hardpoint: number
|
||||
hardpointOrder: number
|
||||
}
|
||||
|
||||
export interface IShortWeapon {
|
||||
id: number
|
||||
name: string
|
||||
filename: string
|
||||
icon: string
|
||||
isMeleeWeapon: boolean
|
||||
}
|
||||
|
||||
export interface IWeapon {
|
||||
id: number
|
||||
name: string
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user