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:
+4
-14
@@ -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>
|
||||
|
||||
+40
-20
@@ -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>
|
||||
}
|
||||
|
||||
|
||||
+19
-34
@@ -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>
|
||||
|
||||
+46
-32
@@ -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>;
|
||||
|
||||
+22
-15
@@ -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>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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[]
|
||||
}
|
||||
+6
-1
@@ -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[],
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user