Global update
- add requirements for units, sergeants, buildings and weapons - add uiIndexHint for units, buildings, researches and addons - add addon affects - improve campaign entities clear - add dds converter definitive edition - add all files lowercase function before mod parse - add addon modifiers info - add advanced build menu grid - add title according building/unit/mod/race
This commit is contained in:
parent
851bb71601
commit
f0fde93d7b
BIN
public/images/shakal.png
Normal file
BIN
public/images/shakal.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
@ -7,7 +7,7 @@
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Web site created using create-react-app"
|
||||
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."
|
||||
/>
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||
<!--
|
||||
|
||||
18
src/App.tsx
18
src/App.tsx
@ -1,16 +1,6 @@
|
||||
import './App.css';
|
||||
import React from "react";
|
||||
import {
|
||||
AppBar,
|
||||
Button,
|
||||
Container,
|
||||
createTheme,
|
||||
Grid2,
|
||||
IconButton,
|
||||
ThemeProvider,
|
||||
Toolbar,
|
||||
Typography
|
||||
} from "@mui/material";
|
||||
import {AppBar, Container, createTheme, IconButton, ThemeProvider, Toolbar, Typography} from "@mui/material";
|
||||
import {MyRoutes} from "./Routes";
|
||||
|
||||
function App() {
|
||||
@ -43,11 +33,11 @@ function App() {
|
||||
>
|
||||
</IconButton>
|
||||
<Typography variant="h6" component="div" sx={{flexGrow: 1}}>
|
||||
Autogeneration wiki (by Anibus)
|
||||
Autogeneration wiki
|
||||
</Typography>
|
||||
<Button color="inherit" onClick={steamLogin}>
|
||||
{/*<Button color="inherit" onClick={steamLogin}>
|
||||
Log in through Steam
|
||||
</Button>
|
||||
</Button>*/}
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
<Container>
|
||||
|
||||
@ -2,8 +2,9 @@ import {Paper, Table, TableCell, TableContainer, TableRow} from "@mui/material";
|
||||
import React from "react";
|
||||
import {IModifier} from "../types/IModifier";
|
||||
import {IconUrl} from "../core/api";
|
||||
import {IResearch} from "../types/IResearch";
|
||||
import {Irace} from "../types/Irace";
|
||||
import {IAffectedData} from "../types/IAffectedData";
|
||||
import {IMod} from "../types/Imod";
|
||||
|
||||
interface IModifiersProvidesTable{
|
||||
modifiers: IModifier[],
|
||||
@ -11,7 +12,8 @@ interface IModifiersProvidesTable{
|
||||
|
||||
interface IModifiersProvidesResearchTable{
|
||||
modifiers: IModifier[],
|
||||
research: IResearch,
|
||||
affectedData: IAffectedData,
|
||||
mod: IMod,
|
||||
race: Irace,
|
||||
}
|
||||
|
||||
@ -130,43 +132,43 @@ export function ModifiersProvidesAddonTable (props: IModifiersProvidesTable) {
|
||||
)
|
||||
}
|
||||
|
||||
export function ModifiersProvidesResearchTable (props: IModifiersProvidesResearchTable) {
|
||||
export function ModifiersProvidesTable (props: IModifiersProvidesResearchTable) {
|
||||
|
||||
let mods = props.modifiers
|
||||
|
||||
function getTarget(target: String, research: IResearch, race: Irace) {
|
||||
console.log(research.affectedUnits.map(au => au.filename))
|
||||
var affectedUnit = research.affectedUnits.find(au => au.filename.replaceAll('.rgd', '').split(";")[0] === target || au.filename.replaceAll('.rgd', '').split(";")[1] === target);
|
||||
function getTarget(target: String) {
|
||||
console.log(props.affectedData.affectedUnits.map(au => au.filename))
|
||||
var affectedUnit = props.affectedData.affectedUnits.find(au => au.filename.replaceAll('.rgd', '').split(";")[0] === target || au.filename.replaceAll('.rgd', '').split(";")[1] === target);
|
||||
if(affectedUnit != null) {
|
||||
return <span><img style={{verticalAlign: "top", height: 25}}
|
||||
src={getIcon(affectedUnit.icon)}/><a
|
||||
href={`/mod/${research.modId}/race/${race.id}/unit/${affectedUnit.id}`}>
|
||||
href={`/mod/${props.mod.id}/race/${props.race.id}/unit/${affectedUnit.id}`}>
|
||||
{affectedUnit.name}
|
||||
</a></span>
|
||||
}
|
||||
var affectedSergeant = research.affectedSergeants.find(as => as.filename.replaceAll('.rgd', '') === target);
|
||||
var affectedSergeant = props.affectedData.affectedSergeants.find(as => as.filename.replaceAll('.rgd', '') === target);
|
||||
if(affectedSergeant != null) {
|
||||
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/${research.modId}/race/${race.id}/unit/${affectedSergeant.unit.id}`}>
|
||||
href={`/mod/${props.mod.id}/race/${props.race.id}/unit/${affectedSergeant.unit.id}`}>
|
||||
{affectedSergeant.unit.name}
|
||||
</a></span>
|
||||
}
|
||||
var affectedBuilding = research.affectedBuildings.find(ab => ab.filename.replaceAll('.rgd', '') === target);
|
||||
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/${research.modId}/race/${race.id}/building/${affectedBuilding.id}`}>
|
||||
href={`/mod/${props.mod.id}/race/${props.race.id}/building/${affectedBuilding.id}`}>
|
||||
{affectedBuilding.name}
|
||||
</a> </span>
|
||||
}
|
||||
|
||||
var affectedWeapon = research.affectedWeapons.find(aw => aw.filename.replaceAll('.rgd', '') === target);
|
||||
var affectedWeapon = props.affectedData.affectedWeapons.find(aw => aw.filename.replaceAll('.rgd', '') === target);
|
||||
if (affectedWeapon != null) {
|
||||
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/${research.modId}/race/${race.id}/unit/${unit.id}`}>
|
||||
href={`/mod/${props.mod.id}/race/${props.race.id}/unit/${unit.id}`}>
|
||||
{unit.name}
|
||||
</a> </span>
|
||||
)
|
||||
@ -177,7 +179,7 @@ export function ModifiersProvidesResearchTable (props: IModifiersProvidesResearc
|
||||
src={getIcon(affectedSergeant.icon)}/>{affectedSergeant.name} at <img
|
||||
style={{verticalAlign: "top", height: 25}}
|
||||
src={getIcon(affectedSergeant.unit.icon)}/><a
|
||||
href={`/mod/${research.modId}/race/${race.id}/unit/${affectedSergeant.unit.id}`}>
|
||||
href={`/mod//${props.mod.id}/race/${props.race.id}/unit/${affectedSergeant.unit.id}`}>
|
||||
{affectedSergeant.unit.name}
|
||||
</a> </span>
|
||||
)
|
||||
@ -185,7 +187,7 @@ export function ModifiersProvidesResearchTable (props: IModifiersProvidesResearc
|
||||
{
|
||||
affectedWeapon.buildings.map(affectedBuilding =>
|
||||
<span><img style={{verticalAlign: "top", height: 25}} src={getIcon(affectedBuilding.icon)}/><a
|
||||
href={`/mod/${research.modId}/race/${race.id}/building/${affectedBuilding.id}`}>
|
||||
href={`/mod//${props.mod.id}/race/${props.race.id}/building/${affectedBuilding.id}`}>
|
||||
{affectedBuilding.name}
|
||||
</a> </span>
|
||||
)
|
||||
@ -194,7 +196,7 @@ export function ModifiersProvidesResearchTable (props: IModifiersProvidesResearc
|
||||
}
|
||||
|
||||
|
||||
return <span>Unknown target <i>{target}</i></span>;
|
||||
return <span><i>{target}</i></span>;
|
||||
}
|
||||
|
||||
return (
|
||||
@ -204,7 +206,7 @@ export function ModifiersProvidesResearchTable (props: IModifiersProvidesResearc
|
||||
<TableRow
|
||||
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||
>
|
||||
<TableCell component="th" scope="row">{getTarget(m.target, props.research, props.race)}</TableCell>
|
||||
<TableCell component="th" scope="row">{getTarget(m.target)}</TableCell>
|
||||
<TableCell style={{minWidth: 120}} component="th" scope="row">{getModName(m.reference)}</TableCell>
|
||||
<TableCell component="th" scope="row">{getModIcon(m.reference)} {getChangeDescription(m.usageType, m.value)}</TableCell>
|
||||
</TableRow>
|
||||
|
||||
@ -1,58 +1,74 @@
|
||||
import {Paper, Table, TableCell, TableContainer, TableRow} from "@mui/material";
|
||||
import React from "react";
|
||||
import {IModifier} from "../types/IModifier";
|
||||
import {IBuildingShort} from "../types/IBuildingShort";
|
||||
import {IBuilding, IBuildingAddonShort} from "../types/IBuilding";
|
||||
import {IBuildingAddonShort} from "../types/IBuilding";
|
||||
import {IconUrl} from "../core/api";
|
||||
import {IResearchRequirements} from "../types/IResearchRequirements";
|
||||
import {goToAddon} from "../pages/BuildingPage";
|
||||
import {IRequirement} from "../types/IRequirement";
|
||||
import {IRequirement, IRequirementLimitByBuildingDto} from "../types/IRequirement";
|
||||
|
||||
interface IRequiredProps{
|
||||
requirement: IRequirement,
|
||||
building: IBuilding,
|
||||
raceId: String,
|
||||
modId: number,
|
||||
}
|
||||
|
||||
function Required (props: IRequiredProps) {
|
||||
|
||||
function renderRequirementGlobalAddons(rgas: IBuildingAddonShort[], building: IBuilding, modId: number) {
|
||||
function renderRequirementGlobalAddons(rgas: IBuildingAddonShort[],) {
|
||||
|
||||
return <div> {rgas.map(rga =>
|
||||
|
||||
<span> Global addon: <img style={{verticalAlign: "top", height: 25}}
|
||||
src={getIcon(rga.icon)}/>
|
||||
<a href={`/mod/${modId}/race/${building.race.id}/building/${rga.buildingId}#addon-${rga.id}`}>
|
||||
<a href={`/mod/${props.modId}/race/${props.raceId}/building/${rga.buildingId}#addon-${rga.id}`}>
|
||||
{rga.name}
|
||||
</a></span>
|
||||
)}</div>
|
||||
}
|
||||
|
||||
function renderRequirementBuilding(requirementBuildings: IBuildingShort[], building: IBuilding, modId: number) {
|
||||
function renderRequirementBuilding(requirementBuildings: IBuildingShort[],) {
|
||||
return requirementBuildings.length > 0 && (
|
||||
<div> Buildings: <img style={{verticalAlign: "top", height: 25}}
|
||||
src={IconUrl + requirementBuildings[0].icon.replaceAll('\\', '/')}/>
|
||||
{" "}<a href={`/mod/${modId}/race/${building.race.id}/building/${requirementBuildings[0].id}`}>
|
||||
{" "}<a href={`/mod/${props.modId}/race/${props.raceId}/building/${requirementBuildings[0].id}`}>
|
||||
{requirementBuildings[0].name}
|
||||
</a> {requirementBuildings[1] !== undefined && <span>or <img style={{verticalAlign: "top", height: 25}}
|
||||
src={IconUrl + requirementBuildings[1].icon.replaceAll('\\', '/')}/>
|
||||
{" "}<a href={`/mod/${modId}/race/${building.race.id}/building/${requirementBuildings[1].id}`}>
|
||||
{" "}<a href={`/mod/${props.modId}/race/${props.raceId}/building/${requirementBuildings[1].id}`}>
|
||||
{requirementBuildings[1].name}</a></span> } </div>
|
||||
);
|
||||
}
|
||||
|
||||
function renderRequirementResearches(requirementResearches: IResearchRequirements[], modId: number, raceId: string) {
|
||||
function renderRequirementOwnership(requirementOwnership: string[],) {
|
||||
return requirementOwnership.length > 0 && <span> Owner: {requirementOwnership.map(o => {
|
||||
switch(o) {
|
||||
case 'relic_struct':
|
||||
return "Relic point ";
|
||||
default:
|
||||
return o;
|
||||
}
|
||||
}
|
||||
)} </span>
|
||||
}
|
||||
|
||||
function renderLimitPerBuilding(limitPerBuilding: IRequirementLimitByBuildingDto,) {
|
||||
return <span> One <img style={{verticalAlign: "top", height: 25}}
|
||||
src={IconUrl + limitPerBuilding.building.icon.replaceAll('\\', '/')}/>
|
||||
{" "}<a href={`/mod/${props.modId}/race/${props.raceId}/building/${limitPerBuilding.building.id}`}>
|
||||
{limitPerBuilding.building.name} </a> allow produce max {limitPerBuilding.limit}</span>
|
||||
}
|
||||
|
||||
function renderRequirementResearches(requirementResearches: IResearchRequirements[],) {
|
||||
return <div> {requirementResearches.map(rs =>
|
||||
|
||||
<span> Research {rs.researchMustNotBeComplete ? "not" : ""}: <img style={{verticalAlign: "top", height: 25}}
|
||||
src={getIcon(rs.researchShortDto.icon)}/>
|
||||
<a href={`/mod/${modId}/race/${raceId}/building/${rs.researchShortDto.buildingId}#research-${rs.researchShortDto.id}`}>
|
||||
<a href={`/mod/${props.modId}/race/${props.raceId}/building/${rs.researchShortDto.buildingId}#research-${rs.researchShortDto.id}`}>
|
||||
{rs.researchShortDto.name}
|
||||
</a></span>
|
||||
)}</div>
|
||||
}
|
||||
|
||||
const requirement = props.requirement
|
||||
const building = props.building
|
||||
|
||||
|
||||
return (
|
||||
@ -65,22 +81,26 @@ function Required (props: IRequiredProps) {
|
||||
}
|
||||
{requirement.requireAddon !== null &&
|
||||
<div> Addon: <img style={{verticalAlign: "top", height: 25}}
|
||||
src={IconUrl + requirement.requireAddon.icon.replaceAll('\\', '/')}/>
|
||||
<a href={"#addon-" + requirement.requireAddon.id} onClick={() => goToAddon(`#addon-` + requirement.requireAddon.id)}>{requirement.requireAddon.name}</a>
|
||||
src={IconUrl + requirement.requireAddon.icon.replaceAll('\\', '/')}/>
|
||||
<a href={`/mod/${props.modId}/race/${props.raceId}/building/${requirement.requireAddon.buildingId}#addon-${requirement.requireAddon.id}`}>
|
||||
{requirement.requireAddon.name}
|
||||
</a>
|
||||
{requirement.replaceWhenDone && <i> (old provides replace)</i>}
|
||||
</div>
|
||||
}
|
||||
{requirement.requirementBuildings.map(b =>
|
||||
<div> Building: <img style={{verticalAlign: "top", height: 25}}
|
||||
src={IconUrl + b.icon.replaceAll('\\', '/')}/>
|
||||
<a href= {'/mod/'+ building.modId +'/race/'+ building.race.id +'/building/' + b.id + "/"}>{b.name}</a></div>)
|
||||
<a href= {'/mod/'+ props.modId +'/race/'+ props.raceId +'/building/' + b.id + "/"}>{b.name}</a></div>)
|
||||
}
|
||||
{requirement.requirementResearches.length !== 0 &&
|
||||
renderRequirementResearches(requirement.requirementResearches, building.modId, building.race.id)}
|
||||
renderRequirementResearches(requirement.requirementResearches,)}
|
||||
{requirement.requirementBuildingsEither.length !== 0 &&
|
||||
renderRequirementBuilding(requirement.requirementBuildingsEither, building, building.modId)}
|
||||
renderRequirementBuilding(requirement.requirementBuildingsEither,)}
|
||||
{requirement.limitByBuilding !== undefined && requirement.limitByBuilding !== null && renderLimitPerBuilding(requirement.limitByBuilding)}
|
||||
{requirement.requirementsGlobalAddons.length !== 0 &&
|
||||
renderRequirementGlobalAddons(requirement.requirementsGlobalAddons, building, building.modId)}
|
||||
renderRequirementGlobalAddons(requirement.requirementsGlobalAddons,)}
|
||||
{renderRequirementOwnership(requirement.requiredOwnership)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ import {
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableContainer,
|
||||
TableRow
|
||||
TableRow, Tooltip
|
||||
} from "@mui/material";
|
||||
import AvTimerOutlinedIcon from "@mui/icons-material/AvTimer";
|
||||
import ArmorType from "./ArmorType";
|
||||
@ -20,6 +20,7 @@ import Vision from "./Vision";
|
||||
import {IMod} from "../types/Imod";
|
||||
import {renderAffectedResearches} from "./building/Research";
|
||||
import {Irace} from "../types/Irace";
|
||||
import Required from "./Required";
|
||||
|
||||
|
||||
|
||||
@ -103,9 +104,8 @@ const Sergeant = (props: SergeantProps) => {
|
||||
>
|
||||
<TableCell component="th" scope="row">Armor type</TableCell>
|
||||
<TableCell component="th" scope="row">
|
||||
<ArmorType name={sergeant.armorType.name} compact={false}/>
|
||||
{sergeant.armorType2 && <span style={{fontSize: 12}} ><br/><i>after upgrade can become:<br/><ArmorType
|
||||
name={sergeant.armorType2.name} compact={false}/></i></span> }
|
||||
{sergeant.armorType2 == null ? <ArmorType name={sergeant.armorType.name} compact={false}/>
|
||||
: <Tooltip title={"upgrade/debuff can turns to " + sergeant.armorType2.name}><span><ArmorType name={sergeant.armorType.name} compact={false}/></span></Tooltip> }
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow
|
||||
@ -145,11 +145,15 @@ const Sergeant = (props: SergeantProps) => {
|
||||
{sergeant.description}
|
||||
</div>
|
||||
</Grid2>
|
||||
{sergeant.requirements !== null &&
|
||||
<Grid2 size={{xs: 12, md: 12}}>
|
||||
<Required requirement={sergeant.requirements} modId={props.mod.id} raceId={props.race.id}/>
|
||||
</Grid2>}
|
||||
|
||||
<Grid2 size={12}>
|
||||
{[...mapWithUnitWeapons.keys()].sort(function (a, b) {
|
||||
return a - b;
|
||||
}).map(h => <WeaponSlot race={props.race} mod={props.mod} unitWeapons={mapWithUnitWeapons.get(h)} hardpoint={h}/>)}
|
||||
}).map(h => <WeaponSlot key ={h} race={props.race} mod={props.mod} unitWeapons={mapWithUnitWeapons.get(h)} hardpoint={h}/>)}
|
||||
</Grid2>
|
||||
<Grid2 size={12}>
|
||||
{renderAffectedResearches(sergeant.affectedResearches, props.mod.id, props.race.id)}
|
||||
|
||||
@ -23,22 +23,22 @@ import Sergeant from "./Sergeant";
|
||||
import {IMod} from "../types/Imod";
|
||||
import {Irace} from "../types/Irace";
|
||||
import {renderAffectedResearches} from "./building/Research";
|
||||
import Required from "./Required";
|
||||
|
||||
interface IWeaponProps {
|
||||
weapon: IWeapon,
|
||||
isDefault: Boolean,
|
||||
renderRequired: Boolean,
|
||||
mod: IMod,
|
||||
race: Irace,
|
||||
}
|
||||
|
||||
interface IWeaponState {
|
||||
currentTable: "dps" | "one hit",
|
||||
haveReinforceMenu: Boolean,
|
||||
}
|
||||
|
||||
class Weapon extends React.Component<IWeaponProps, any> {
|
||||
|
||||
public static defaultProps = {
|
||||
isDefault: false
|
||||
isDefault: false,
|
||||
renderRequired: true,
|
||||
};
|
||||
|
||||
humanReadableName(unit: string) {
|
||||
@ -427,6 +427,10 @@ class Weapon extends React.Component<IWeaponProps, any> {
|
||||
</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>
|
||||
|
||||
@ -9,7 +9,7 @@ export interface WeaponSlotProps {
|
||||
unitWeapons: Map<number, IWeapon> | undefined,
|
||||
mod: IMod,
|
||||
race: Irace,
|
||||
showOnlyDefault?: boolean ,
|
||||
haveReinforceMenu?: boolean ,
|
||||
}
|
||||
|
||||
const WeaponSlot= (props: WeaponSlotProps) => {
|
||||
@ -26,26 +26,16 @@ const WeaponSlot= (props: WeaponSlotProps) => {
|
||||
|
||||
let onlyDummy = weaponsSorted.filter(wp => !wp[1].filename.includes("dummy")).length === 0
|
||||
|
||||
let haveReinforceMenu = props.haveReinforceMenu === true
|
||||
|
||||
if(onlyDummy) return (<div></div>)
|
||||
|
||||
if(props.showOnlyDefault){
|
||||
|
||||
if(firstWeapon.filename.includes("dummy")) return (<div></div>);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h3>{header}</h3>
|
||||
<div style={{marginLeft: 20}}><Weapon race={props.race} mod={props.mod} isDefault={true} weapon={firstWeapon}/></div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h3>{header}</h3>
|
||||
{weaponsSorted.filter(wp => !wp[1].filename.includes("dummy")).map(wp =>
|
||||
|
||||
<div style={{marginLeft: 20}}><Weapon race={props.race} mod={props.mod} isDefault={!haveDummy || wp[1].filename === firstWeapon.filename} weapon={wp[1]}/></div>
|
||||
<div style={{marginLeft: 20}}><Weapon race={props.race} mod={props.mod} isDefault={!haveDummy || wp[1].filename === firstWeapon.filename} weapon={wp[1]} haveReinforceMenu={haveReinforceMenu}/></div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
|
||||
@ -12,53 +12,11 @@ import {
|
||||
TableRow
|
||||
} from "@mui/material";
|
||||
import {IBuilding, IBuildingAddon} from "../../types/IBuilding";
|
||||
import {WeaponHardpoint} from "../../types/IUnit";
|
||||
import AvTimerOutlinedIcon from "@mui/icons-material/AvTimer";
|
||||
import WeaponSlot from "../WeaponSlot";
|
||||
import {ExpandMore} from "@mui/icons-material";
|
||||
import {IMod} from "../../types/Imod";
|
||||
import {IModifier} from "../../types/IModifier";
|
||||
import {getIcon, ModifiersProvidesAddonTable,} from "../ModifiersProvideTable";
|
||||
import {getIcon, ModifiersProvidesTable,} from "../ModifiersProvideTable";
|
||||
import Required from "../Required";
|
||||
import {Irace} from "../../types/Irace";
|
||||
|
||||
|
||||
interface IAddonModifiersProvidesWeapons{
|
||||
modifiers: IModifier[],
|
||||
replacedAddonModifiers: IModifier[],
|
||||
weapons: WeaponHardpoint[],
|
||||
mod: IMod,
|
||||
race: Irace
|
||||
}
|
||||
|
||||
function AddonModifiersProvidesWeapons (props: IAddonModifiersProvidesWeapons) {
|
||||
|
||||
|
||||
function getWeaponByAddonMod(ar: IModifier){
|
||||
|
||||
let hardpoint = Number(ar.reference.replace("modifiers\\default_weapon_modifier_hardpoint", "").replace(".lua", ""));
|
||||
let value = ar.value;
|
||||
|
||||
//let prevAddonWeaponMod = props.replacedAddonModifiers.find(m => m.reference && m.reference.includes("modifiers\\default_weapon_modifier_hardpoint" + hardpoint))?.value ?? 0
|
||||
|
||||
let weapon = props.weapons.find(w => w.hardpoint === hardpoint && w.hardpointOrder === 1 + value )?.weapon
|
||||
if (weapon != null){
|
||||
return <WeaponSlot race={props.race} mod={props.mod} unitWeapons={new Map().set(hardpoint, weapon)} hardpoint={hardpoint}/>;
|
||||
}else{
|
||||
return "Can't find weapon, replaced by addon:" + value + " - "
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let weaponMods = props.modifiers.filter(m => m.reference.includes("default_weapon_modifier_hardpoint"))
|
||||
|
||||
return (
|
||||
<div>
|
||||
{weaponMods.map(w => getWeaponByAddonMod(w))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
interface IBuildingAddonProps {
|
||||
addon: IBuildingAddon,
|
||||
@ -72,12 +30,6 @@ function BuildingAddon(props: IBuildingAddonProps){
|
||||
const building = props.building
|
||||
|
||||
|
||||
const prevAddonModifiers: IModifier[] = (function() {
|
||||
if (addon.addonRequirement && addon.addonRequirement.requireAddon !== null && !addon.addonRequirement.replaceWhenDone){
|
||||
return building.addons.find(a => a.id === addon.addonRequirement.requireAddon.id)?.addonModifiers ?? [];
|
||||
} else return [];
|
||||
})()
|
||||
|
||||
|
||||
return <div className='addon-research-accordion' id={"addon-" + addon.id} ><Accordion>
|
||||
<AccordionSummary
|
||||
@ -129,20 +81,16 @@ function BuildingAddon(props: IBuildingAddonProps){
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer><br/>
|
||||
<ModifiersProvidesAddonTable modifiers={addon.addonModifiers}/>
|
||||
</Grid2>
|
||||
<Grid2 size={{xs: 12, md: 8}}>
|
||||
<div style={{whiteSpace: "pre-wrap"}}>
|
||||
{addon.description}
|
||||
</div>
|
||||
</Grid2>
|
||||
{addon.addonModifiers !== null &&
|
||||
<Grid2 size={{xs: 12, md: 12}}>
|
||||
<AddonModifiersProvidesWeapons race={building.race} mod={props.mod} modifiers={addon.addonModifiers} replacedAddonModifiers={prevAddonModifiers} weapons={building.weapons}/>
|
||||
</Grid2>}
|
||||
<ModifiersProvidesTable modifiers={addon.addonModifiers} affectedData={addon.affectedData} mod={props.mod} race={building.race}/>
|
||||
{addon.addonRequirement !== null &&
|
||||
<Grid2 size={{xs: 12, md: 12}}>
|
||||
<Required requirement={addon.addonRequirement} building={building}/>
|
||||
<Required requirement={addon.addonRequirement} modId={building.modId} raceId={building.race.id}/>
|
||||
</Grid2>}
|
||||
</Grid2>
|
||||
<i className="rgdFrom">{addon.filename}</i>
|
||||
|
||||
@ -13,7 +13,7 @@ import {
|
||||
TableRow
|
||||
} from "@mui/material";
|
||||
import {ExpandMore} from "@mui/icons-material";
|
||||
import {getIcon, ModifiersProvidesResearchTable} from "../ModifiersProvideTable";
|
||||
import {getIcon, ModifiersProvidesTable} from "../ModifiersProvideTable";
|
||||
import AvTimerOutlinedIcon from "@mui/icons-material/AvTimer";
|
||||
import Required from "../Required";
|
||||
import React from "react";
|
||||
@ -90,11 +90,11 @@ function ResearchFull(props: IResearchProps){
|
||||
|
||||
</Grid2>
|
||||
<Grid2 size={{xs: 12, md: 12}}>
|
||||
<ModifiersProvidesResearchTable modifiers={research.modifiers} research={research} race={building.race}/>
|
||||
<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} building={building}/>
|
||||
<Required requirement={research.requirements} modId={building.modId} raceId={building.race.id}/>
|
||||
</Grid2>}
|
||||
</Grid2>
|
||||
<i className="rgdFrom">{research.filename}</i>
|
||||
@ -114,8 +114,8 @@ export function renderAffectedResearches(researches: IResearchShort[], modId: nu
|
||||
}
|
||||
|
||||
return <div> {researches.map(rs =>
|
||||
rs.buildingId == null ? <span></span> :
|
||||
<span>Research affect: {researchLink(rs)}<br/></span>
|
||||
rs.buildingId == null ? <span key={rs.id}></span> :
|
||||
<span key={rs.id}>Research affect: {researchLink(rs)}<br/></span>
|
||||
)}</div>
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import {AvailableBuildings, AvailableMods, IconUrl} from "../core/api";
|
||||
import React from "react";
|
||||
import React, {useEffect} from "react";
|
||||
import {withRouter} from "../core/withrouter";
|
||||
import {IWeapon} from "../types/IUnit";
|
||||
import '../css/Building.css'
|
||||
@ -13,7 +13,7 @@ import {
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableContainer,
|
||||
TableRow
|
||||
TableRow, Tooltip
|
||||
} from "@mui/material";
|
||||
import {ArrowBack} from "@mui/icons-material";
|
||||
import ArmorType from "../classes/ArmorType";
|
||||
@ -26,6 +26,7 @@ import Vision from "../classes/Vision";
|
||||
import BuildingAddon from "../classes/building/BuildingAddon";
|
||||
import {IUnitShort} from "../types/IUnitShort";
|
||||
import Research, {renderAffectedResearches} from "../classes/building/Research";
|
||||
import Required from "../classes/Required";
|
||||
|
||||
interface UintPageState {
|
||||
building: IBuilding,
|
||||
@ -34,18 +35,19 @@ interface UintPageState {
|
||||
|
||||
function Unit (unit: IUnitShort, modId: number, raceId: String) {
|
||||
|
||||
return (<Link href={"/mod/" + modId + "/race/" + raceId + "/unit/" + unit.id}><ListItem>
|
||||
return (<Grid2 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"}}
|
||||
src="/images/DETECT_YES.webp"/></span>}
|
||||
|
||||
</ListItem></Link>)
|
||||
</ListItem></Link></Grid2>)
|
||||
}
|
||||
|
||||
|
||||
function Building(building: IBuilding, mod: IMod) {
|
||||
|
||||
document.title = building.name
|
||||
|
||||
|
||||
let mapBuildingWeapons: Map<number, Map<number, IWeapon>> = new Map();
|
||||
|
||||
@ -130,8 +132,8 @@ function Building(building: IBuilding, mod: IMod) {
|
||||
>
|
||||
<TableCell component="th" scope="row">Armor type</TableCell>
|
||||
<TableCell component="th" scope="row">
|
||||
<ArmorType name={building.armorType.name} compact={false}/>
|
||||
{building.armorType2 && <span><br/><ArmorType name={building.armorType2.name} compact={false}/></span> }
|
||||
{building.armorType2 == null ? <ArmorType name={building.armorType.name} compact={false}/>
|
||||
: <Tooltip title={"upgrade/debuff can turns to " + building.armorType2.name}><span><ArmorType name={building.armorType.name} compact={false}/></span></Tooltip> }
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow
|
||||
@ -170,11 +172,17 @@ function Building(building: IBuilding, mod: IMod) {
|
||||
{building.description}
|
||||
</div>
|
||||
</Grid2>
|
||||
{building.requirements !== null &&
|
||||
<Grid2 size={{xs: 12, md: 12}}>
|
||||
<Required requirement={building.requirements} modId={building.modId} raceId={building.race.id}/>
|
||||
</Grid2>}
|
||||
{building.units.length > 0 && <Grid2 size={12}>
|
||||
<h3>Unit production</h3>
|
||||
{building.units.map(unit =>
|
||||
Unit(unit, mod.id, building.race.id)
|
||||
)}
|
||||
<Grid2 container spacing={2}>
|
||||
{building.units.map(unit =>
|
||||
Unit(unit, mod.id, building.race.id)
|
||||
)}
|
||||
</Grid2>
|
||||
</Grid2>}
|
||||
{building.addons.length > 0 && <Grid2 size={12}>
|
||||
<h3>Addons</h3>
|
||||
@ -191,7 +199,7 @@ function Building(building: IBuilding, mod: IMod) {
|
||||
<Grid2 size={12}>
|
||||
{[...mapBuildingWeapons.keys()].sort(function (a, b) {
|
||||
return a - b;
|
||||
}).map(h => <WeaponSlot race={building.race} mod={mod} showOnlyDefault={true} unitWeapons={mapBuildingWeapons.get(h)} hardpoint={h}/>)}
|
||||
}).map(h => <WeaponSlot race={building.race} mod={mod} unitWeapons={mapBuildingWeapons.get(h)} hardpoint={h}/>)}
|
||||
</Grid2>
|
||||
<Grid2 size={12}>
|
||||
{renderAffectedResearches(building.affectedResearches, mod.id, building.race.id)}
|
||||
@ -203,25 +211,6 @@ function Building(building: IBuilding, mod: IMod) {
|
||||
</div>)
|
||||
}
|
||||
|
||||
function goToAddon(addonHash: string) {
|
||||
let addonId = addonHash.replace("#", "");
|
||||
[].forEach.call(document.querySelectorAll('div'), function (el: HTMLElement) {
|
||||
el?.classList?.remove('selected-addon');
|
||||
});
|
||||
document?.getElementById(addonId)?.classList?.add("selected-addon");
|
||||
document?.getElementById(addonId)?.scrollIntoView()
|
||||
}
|
||||
|
||||
function goToResearch(researchHash: string) {
|
||||
let researchId = researchHash.replace("#", "");
|
||||
[].forEach.call(document.querySelectorAll('div'), function (el: HTMLElement) {
|
||||
el?.classList?.remove('selected-research');
|
||||
});
|
||||
document?.getElementById(researchId)?.classList?.add("selected-research");
|
||||
document?.getElementById(researchId)?.scrollIntoView()
|
||||
}
|
||||
|
||||
|
||||
class BuildingPage extends React.Component<any, UintPageState> {
|
||||
|
||||
async componentDidMount() {
|
||||
@ -238,8 +227,6 @@ class BuildingPage extends React.Component<any, UintPageState> {
|
||||
this.setState({
|
||||
mod: modData
|
||||
});
|
||||
goToAddon(window.location.hash);
|
||||
goToResearch(window.location.hash);
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -258,5 +245,3 @@ class BuildingPage extends React.Component<any, UintPageState> {
|
||||
}
|
||||
|
||||
export default withRouter(BuildingPage);
|
||||
|
||||
export { goToAddon, goToResearch };
|
||||
@ -35,6 +35,8 @@ class ModPage extends React.Component<any, ModPageState> {
|
||||
render() {
|
||||
if(this.state != null && this.state.mod != null ){
|
||||
|
||||
document.title = this.state.mod.name
|
||||
|
||||
return <div>
|
||||
<a href="/"><Button id="back-button" variant="contained"
|
||||
startIcon={<ArrowBack/>}> Back</Button></a>
|
||||
|
||||
@ -39,18 +39,18 @@ interface RacePageState {
|
||||
}
|
||||
|
||||
|
||||
function Unit (unit: IUnitShort, modId: number, raceId: String) {
|
||||
function Unit(unit: IUnitShort, modId: number, raceId: String) {
|
||||
|
||||
return (<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"}}
|
||||
src="/images/DETECT_YES.webp"/></span>}
|
||||
{unit.icon && <img className="unitIcon" src={IconUrl + unit.icon.replaceAll('\\', '/')}/>}
|
||||
{unit.name}
|
||||
{unit.canDetect && <span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/DETECT_YES.webp"/></span>}
|
||||
|
||||
</ListItem></Link>)
|
||||
}
|
||||
|
||||
function UnitSmall (unit: IUnitShort, modId: number, raceId: String) {
|
||||
function UnitSmall(unit: IUnitShort, modId: number, raceId: String) {
|
||||
|
||||
var unitName = ""
|
||||
if (unit.name.length > 21) {
|
||||
@ -63,10 +63,10 @@ function UnitSmall (unit: IUnitShort, modId: number, raceId: String) {
|
||||
{unit.icon && <img className="unitIconSmall" src={IconUrl + unit.icon.replaceAll('\\', '/')}/>}
|
||||
<span style={{fontSize: 12}}>{unitName}</span>
|
||||
{unit.canDetect && <span> <img
|
||||
src="/images/DETECT_YES.webp"/></span>}<br/></Link>)
|
||||
src="/images/DETECT_YES.webp"/></span>}<br/></Link>)
|
||||
}
|
||||
|
||||
function Building (building: IBuildingShort, modId: number, raceId: String) {
|
||||
function Building(building: IBuildingShort, modId: number, raceId: String) {
|
||||
|
||||
return (<Grid2 size={{xs: 12, md: 3}}><Link href={"/mod/" + modId + "/race/" + raceId + "/building/" + building.id}><ListItem>
|
||||
{building.icon && <img className="unitIcon" src={IconUrl + building.icon.replaceAll('\\', '/')}/>}
|
||||
@ -74,16 +74,15 @@ function Building (building: IBuildingShort, modId: number, raceId: String) {
|
||||
{building.canDetect && <span> <img style={{verticalAlign: "top"}}
|
||||
src="/images/DETECT_YES.webp"/></span>}
|
||||
|
||||
|
||||
</ListItem></Link>
|
||||
{building.units.map(unit => UnitSmall(unit, modId, raceId))}
|
||||
</Grid2>)
|
||||
}
|
||||
}
|
||||
|
||||
interface UnitsProps{
|
||||
raceId: string,
|
||||
modId: number,
|
||||
}
|
||||
interface UnitsProps {
|
||||
raceId: string,
|
||||
modId: number,
|
||||
}
|
||||
|
||||
interface UnitsState {
|
||||
selectedUnits: String | null,
|
||||
@ -95,8 +94,9 @@ class Units extends React.Component<UnitsProps, UnitsState> {
|
||||
|
||||
|
||||
constructor(props: any) {
|
||||
|
||||
super(props);
|
||||
let urlUnits = AvailableUnits + "/" + this.props.modId + "/" + this.props.raceId;
|
||||
let urlUnits = AvailableUnits + "/" + this.props.modId + "/" + this.props.raceId;
|
||||
|
||||
|
||||
fetch(urlUnits)
|
||||
@ -107,7 +107,7 @@ class Units extends React.Component<UnitsProps, UnitsState> {
|
||||
})
|
||||
})
|
||||
|
||||
let urlBuildings = AvailableBuildings + "/" + this.props.modId + "/" + this.props.raceId;
|
||||
let urlBuildings = AvailableBuildings + "/" + this.props.modId + "/" + this.props.raceId;
|
||||
|
||||
fetch(urlBuildings)
|
||||
.then(res => res.json())
|
||||
@ -118,18 +118,24 @@ class Units extends React.Component<UnitsProps, UnitsState> {
|
||||
})
|
||||
}
|
||||
|
||||
render () {
|
||||
render() {
|
||||
|
||||
|
||||
if (this.state && this.state.units) {
|
||||
|
||||
return (<div>
|
||||
if(this.state.buildings?.race.name !== undefined){
|
||||
document.title = this.state.buildings?.race.name
|
||||
}
|
||||
|
||||
{this.state.units != null && this.state.buildings != null ?
|
||||
return (this.state.buildings != null ?
|
||||
<div>
|
||||
<Grid2 container spacing={2}>
|
||||
|
||||
|
||||
{this.state.buildings.buildings.map(building => Building(building, this.props.modId, this.props.raceId))}
|
||||
{this.state.buildings.buildings.map(building => Building(building, this.props.modId, this.props.raceId))}
|
||||
</Grid2>
|
||||
{this.state.buildings.buildingsAdvanced.length > 0 && <div><hr/><Grid2 container spacing={2}>
|
||||
{this.state.buildings.buildingsAdvanced.map(building => Building(building, this.props.modId, this.props.raceId))}
|
||||
</Grid2><br/></div>}
|
||||
<Grid2>
|
||||
<Grid2 size={{xs: 12, md: 12}}>
|
||||
<Accordion>
|
||||
<AccordionSummary
|
||||
@ -141,19 +147,27 @@ class Units extends React.Component<UnitsProps, UnitsState> {
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<Grid2 container spacing={2}>
|
||||
<Grid2 size= {{xs: 12, md: 4}}>
|
||||
<Grid2 size={{xs: 12, md: 4}}>
|
||||
<h3>Infantry</h3>
|
||||
{this.state.units.infantry.map(unit => Unit(unit, this.props.modId, this.props.raceId))}
|
||||
</Grid2>
|
||||
<Grid2 size={{xs: 12, md: 4}}>
|
||||
<h3>Tech</h3>
|
||||
<List sx={{width: '100%', maxWidth: 360, bgcolor: 'background.paper'}}>
|
||||
<List sx={{
|
||||
width: '100%',
|
||||
maxWidth: 360,
|
||||
bgcolor: 'background.paper'
|
||||
}}>
|
||||
{this.state.units.tech.map(unit => Unit(unit, this.props.modId, this.props.raceId))}
|
||||
</List>
|
||||
</Grid2>
|
||||
<Grid2 size={{xs: 12, md: 4}}>
|
||||
<h3>Support</h3>
|
||||
<List sx={{width: '100%', maxWidth: 360, bgcolor: 'background.paper'}}>
|
||||
<List sx={{
|
||||
width: '100%',
|
||||
maxWidth: 360,
|
||||
bgcolor: 'background.paper'
|
||||
}}>
|
||||
{this.state.units.support.map(unit => Unit(unit, this.props.modId, this.props.raceId))}
|
||||
</List>
|
||||
</Grid2>
|
||||
@ -162,9 +176,8 @@ class Units extends React.Component<UnitsProps, UnitsState> {
|
||||
</Accordion>
|
||||
</Grid2><br/>
|
||||
</Grid2>
|
||||
: "Loading"}
|
||||
|
||||
</div>)
|
||||
</div> : "Loading"
|
||||
)
|
||||
} else {
|
||||
return "Loading...";
|
||||
}
|
||||
@ -188,20 +201,21 @@ class RacePageFast extends React.Component<any, RacePageState> {
|
||||
mod: modData
|
||||
});
|
||||
|
||||
const response = await fetch(AvailableRacesPart + "/" + this.props.match.params.raceId);
|
||||
const response = await fetch(AvailableRacesPart + "/" + this.props.match.params.raceId);
|
||||
const racesData: Irace = await response.json();
|
||||
|
||||
this.setState({
|
||||
race : racesData
|
||||
race: racesData
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
if(this.state != null && this.state.mod != null && this.state.race != null ){
|
||||
if (this.state != null && this.state.mod != null && this.state.race != null) {
|
||||
const backRef = "/mod/" + this.state.mod.id
|
||||
|
||||
return <div><Link href={backRef}><Button id="back-button" variant="contained" startIcon={<ArrowBack/>}> Back</Button></Link>
|
||||
return <div><Link href={backRef}><Button id="back-button" variant="contained"
|
||||
startIcon={<ArrowBack/>}> Back</Button></Link>
|
||||
<h1>{this.state.mod.name} ({this.state.mod.version}) - {this.state.race.name}</h1>
|
||||
<Units raceId={this.state.race.id} modId={this.state.mod.id}/>
|
||||
</div>;
|
||||
|
||||
@ -14,7 +14,8 @@ import {
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableContainer,
|
||||
TableRow
|
||||
TableRow,
|
||||
Tooltip
|
||||
} from "@mui/material";
|
||||
import {ArrowBack, ExpandMore} from "@mui/icons-material";
|
||||
import ArmorType from "../classes/ArmorType";
|
||||
@ -24,9 +25,7 @@ import WeaponSlot from "../classes/WeaponSlot";
|
||||
import UnitsTable from "../classes/UnitsTable";
|
||||
import {IMod} from "../types/Imod";
|
||||
import Vision from "../classes/Vision";
|
||||
import {IResearchRequirements} from "../types/IResearchRequirements";
|
||||
import {getIcon} from "../classes/Required";
|
||||
import {IResearchShort} from "../types/IResearchShort";
|
||||
import Required from "../classes/Required";
|
||||
import {renderAffectedResearches} from "../classes/building/Research";
|
||||
|
||||
interface UintPageState {
|
||||
@ -37,6 +36,8 @@ interface UintPageState {
|
||||
|
||||
function Unit(unit: IUnit, mod: IMod) {
|
||||
|
||||
document.title = unit.name
|
||||
|
||||
const morale = (unit.moraleMax !== null) ? <span>
|
||||
<img style={{verticalAlign: "top"}} src="/images/ARM_Morale.webp"/> {unit.moraleMax}
|
||||
+{unit.moraleRegeneration}/s
|
||||
@ -77,10 +78,6 @@ function Unit(unit: IUnit, mod: IMod) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
console.log(unit);
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>{mod.name} ({mod.version})</h1>
|
||||
@ -192,9 +189,7 @@ function Unit(unit: IUnit, mod: IMod) {
|
||||
>
|
||||
<TableCell component="th" scope="row">Armor type</TableCell>
|
||||
<TableCell component="th" scope="row">
|
||||
<ArmorType name={unit.armorType.name} compact={false}/>
|
||||
{unit.armorType2 && <span style={{fontSize: 12}} ><br/><i>after upgrade can become:<br/><ArmorType
|
||||
name={unit.armorType2.name} compact={false}/></i></span> }
|
||||
{unit.armorType2 == null ? <ArmorType name={unit.armorType.name} compact={false}/> : <Tooltip title={"upgrade/debuff can turns to " + unit.armorType2.name}><span><ArmorType name={unit.armorType.name} compact={false}/></span></Tooltip> }
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow
|
||||
@ -257,6 +252,14 @@ function Unit(unit: IUnit, mod: IMod) {
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
}
|
||||
{unit.squadLimit !== undefined && unit.squadLimit !== null &&
|
||||
<TableRow>
|
||||
<TableCell>Limit</TableCell>
|
||||
<TableCell>
|
||||
{unit.squadLimit}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
@ -266,9 +269,13 @@ function Unit(unit: IUnit, mod: IMod) {
|
||||
{unit.description}
|
||||
</div>
|
||||
</Grid2>
|
||||
{unit.requirements !== null &&
|
||||
<Grid2 size={{xs: 12, md: 12}}>
|
||||
<Required requirement={unit.requirements} modId={unit.modId} raceId={unit.race.id}/>
|
||||
</Grid2>}
|
||||
<Grid2 size={12}>
|
||||
{unit.sergeants.map(s =>
|
||||
<Accordion>
|
||||
<Accordion key={s.id}>
|
||||
<AccordionSummary
|
||||
expandIcon={<ExpandMore/>}
|
||||
aria-controls="panel1-content"
|
||||
@ -286,7 +293,7 @@ function Unit(unit: IUnit, mod: IMod) {
|
||||
<Grid2 size={12}>
|
||||
{[...mapWithUnitWeapons.keys()].sort(function (a, b) {
|
||||
return a - b;
|
||||
}).map(h => <WeaponSlot race={unit.race} mod={mod} unitWeapons={mapWithUnitWeapons.get(h)} hardpoint={h}/>)}
|
||||
}).map(h => <WeaponSlot haveReinforceMenu={unit.haveReinforceMenu} key ={h} race={unit.race} mod={mod} unitWeapons={mapWithUnitWeapons.get(h)} hardpoint={h}/>)}
|
||||
</Grid2>
|
||||
<Grid2 size={12}>
|
||||
{renderAffectedResearches(unit.affectedResearches, mod.id, unit.race.id)}
|
||||
@ -325,12 +332,12 @@ class UnitPage extends React.Component<any, UintPageState> {
|
||||
if (this.state != null && this.state.unit != null && this.state.mod != null) {
|
||||
const backRef = "/mod/" + this.props.match.params.modId + "/race/" + this.props.match.params.raceId
|
||||
|
||||
return <div><a href={backRef}><Button id="back-button" variant="contained"
|
||||
return <div key={this.state.unit.id}><a href={backRef}><Button id="back-button" variant="contained"
|
||||
startIcon={<ArrowBack/>}> Back</Button></a>
|
||||
{Unit(this.state.unit, this.state.mod)}
|
||||
</div>;
|
||||
} else {
|
||||
return "loading...";
|
||||
return <div key = {'loading'}>loading...</div>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
10
src/types/IAffectedData.tsx
Normal file
10
src/types/IAffectedData.tsx
Normal file
@ -0,0 +1,10 @@
|
||||
import {IModifier} from "./IModifier";
|
||||
import {IRequirement} from "./IRequirement";
|
||||
import {IAffectedEntity, ISergeantUnitShortDto, IWeaponUnitShortDto} from "./IAffectedEntity";
|
||||
|
||||
export interface IAffectedData {
|
||||
affectedUnits: IAffectedEntity[]
|
||||
affectedSergeants: ISergeantUnitShortDto[]
|
||||
affectedBuildings: IAffectedEntity[]
|
||||
affectedWeapons: IWeaponUnitShortDto[]
|
||||
}
|
||||
@ -6,6 +6,7 @@ import {IModifier} from "./IModifier";
|
||||
import {IRequirement} from "./IRequirement";
|
||||
import {IResearch} from "./IResearch";
|
||||
import {IResearchShort} from "./IResearchShort";
|
||||
import {IAffectedData} from "./IAffectedData";
|
||||
|
||||
export interface IBuilding {
|
||||
id: number
|
||||
@ -37,6 +38,7 @@ export interface IBuilding {
|
||||
researches: IResearch[]
|
||||
units: IUnitShort[]
|
||||
affectedResearches: IResearchShort[],
|
||||
requirements: IRequirement,
|
||||
}
|
||||
|
||||
export interface IBuildingAddon {
|
||||
@ -50,6 +52,7 @@ export interface IBuildingAddon {
|
||||
addonCostFaith: number;
|
||||
addonCostSouls: number;
|
||||
addonCostTime: number;
|
||||
affectedData: IAffectedData;
|
||||
addonModifiers: IModifier[];
|
||||
addonRequirement: IRequirement;
|
||||
icon?: string;
|
||||
|
||||
@ -4,6 +4,7 @@ import {IUnitShort} from "./IUnitShort";
|
||||
export interface IRaceBuildings {
|
||||
race: Irace
|
||||
buildings: IBuildingShort[]
|
||||
buildingsAdvanced: IBuildingShort[]
|
||||
}
|
||||
|
||||
export interface IBuildingShort {
|
||||
@ -12,5 +13,6 @@ export interface IBuildingShort {
|
||||
id: number
|
||||
units: IUnitShort[]
|
||||
canDetect: boolean
|
||||
armorTypeName: string
|
||||
armorTypeName: string,
|
||||
uiIndexHint: number,
|
||||
}
|
||||
|
||||
@ -10,4 +10,13 @@ export interface IRequirement {
|
||||
replaceWhenDone: Boolean;
|
||||
requireAddon: IBuildingAddonShort;
|
||||
requiredTotalPop?: number;
|
||||
limitSquad?:number;
|
||||
limitTech?:number;
|
||||
limitByBuilding ?: IRequirementLimitByBuildingDto;
|
||||
requiredOwnership: string[];
|
||||
}
|
||||
|
||||
export interface IRequirementLimitByBuildingDto{
|
||||
building: IBuildingShort;
|
||||
limit: number;
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
import {IModifier} from "./IModifier";
|
||||
import {IRequirement} from "./IRequirement";
|
||||
import {IAffectedEntity, ISergeantUnitShortDto, IWeaponUnitShortDto} from "./IAffectedEntity";
|
||||
import {IAffectedData} from "./IAffectedData";
|
||||
|
||||
export interface IResearch {
|
||||
id: number
|
||||
@ -15,10 +15,7 @@ export interface IResearch {
|
||||
costTime: number
|
||||
icon: string
|
||||
modId: number
|
||||
affectedUnits: IAffectedEntity[]
|
||||
affectedSergeants: ISergeantUnitShortDto[]
|
||||
affectedBuildings: IAffectedEntity[]
|
||||
affectedWeapons: IWeaponUnitShortDto[]
|
||||
affectedData: IAffectedData
|
||||
requirements: IRequirement
|
||||
modifiers: IModifier[]
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
import {Irace} from "./Irace";
|
||||
import {IArmorType} from "./IArmorType";
|
||||
import {IResearchShort} from "./IResearchShort";
|
||||
import {IRequirement} from "./IRequirement";
|
||||
|
||||
export interface IUnitResponse {
|
||||
race: string
|
||||
@ -52,6 +53,8 @@ export interface IUnit {
|
||||
requisitionIncome?: number
|
||||
icon: string
|
||||
modId: number
|
||||
requirements: IRequirement
|
||||
haveReinforceMenu: boolean,
|
||||
sergeants: ISergeant[]
|
||||
weapons: WeaponHardpoint[]
|
||||
affectedResearches: IResearchShort[],
|
||||
@ -82,6 +85,7 @@ export interface ISergeant {
|
||||
sightRadius: number
|
||||
detectRadius: number
|
||||
icon: string
|
||||
requirements: IRequirement,
|
||||
weapons: WeaponHardpoint[]
|
||||
affectedResearches: IResearchShort[],
|
||||
}
|
||||
@ -117,9 +121,10 @@ export interface IWeapon {
|
||||
isMeleeWeapon: boolean
|
||||
canAttackAir: boolean
|
||||
canAttackGround: boolean
|
||||
haveEquipButton: boolean
|
||||
showInReinforce: boolean
|
||||
icon: string
|
||||
modId: number
|
||||
requirements: IRequirement
|
||||
weaponArmorPiercing: IWeaponPiercing[]
|
||||
affectedResearches: IResearchShort[],
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user