Optimization update
- request weapons and researches only when user open accordion - add building affects data
This commit is contained in:
@@ -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)
|
||||
|
||||
+18
-11
@@ -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[]) => {
|
||||
setUnitsTable({
|
||||
racesUnits : res,
|
||||
racesBuildings: resBuildings
|
||||
fetch(AvailableUnits + "/mod/" + prop.modId)
|
||||
.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 : 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>)
|
||||
}
|
||||
|
||||
+6
-392
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
+9
-1
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user