Add addon requirements
This commit is contained in:
parent
5751cec4de
commit
ba699a0199
1364
package-lock.json
generated
1364
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.2 KiB |
@ -24,9 +24,10 @@
|
|||||||
work correctly both with client-side routing and a non-root public URL.
|
work correctly both with client-side routing and a non-root public URL.
|
||||||
Learn how to configure a non-root public URL by running `npm run build`.
|
Learn how to configure a non-root public URL by running `npm run build`.
|
||||||
-->
|
-->
|
||||||
<title>React App</title>
|
<title>Wiki Soulstorm</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<!-- Yandex.Metrika counter --> <script type="text/javascript" > (function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)}; m[i].l=1*new Date(); for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }} k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)}) (window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym"); ym(99502794, "init", { clickmap:true, trackLinks:true, accurateTrackBounce:true, webvisor:true }); </script> <noscript><div><img src="https://mc.yandex.ru/watch/99502794" style="position:absolute; left:-9999px;" alt="" /></div></noscript> <!-- /Yandex.Metrika counter -->
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
<script type="text/babel" src="./index_bundle.js"></script>
|
<script type="text/babel" src="./index_bundle.js"></script>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
#back-button{
|
#back-button{
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
|
||||||
}
|
}
|
||||||
10
src/App.tsx
10
src/App.tsx
@ -21,12 +21,17 @@ function App() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const theme = createTheme({
|
const theme = createTheme({
|
||||||
cssVariables: true,
|
palette: {
|
||||||
|
primary: {
|
||||||
|
main: "#191919",
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div >
|
<div >
|
||||||
|
<ThemeProvider theme={theme}>
|
||||||
<AppBar position="static">
|
<AppBar position="static">
|
||||||
<Toolbar>
|
<Toolbar>
|
||||||
<IconButton
|
<IconButton
|
||||||
@ -38,7 +43,7 @@ function App() {
|
|||||||
>
|
>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<Typography variant="h6" component="div" sx={{flexGrow: 1}}>
|
<Typography variant="h6" component="div" sx={{flexGrow: 1}}>
|
||||||
Soulstorm autogeneration wiki
|
Autogeneration wiki (by Anibus)
|
||||||
</Typography>
|
</Typography>
|
||||||
<Button color="inherit" onClick={steamLogin}>
|
<Button color="inherit" onClick={steamLogin}>
|
||||||
Log in through Steam
|
Log in through Steam
|
||||||
@ -48,6 +53,7 @@ function App() {
|
|||||||
<Container>
|
<Container>
|
||||||
<MyRoutes/>
|
<MyRoutes/>
|
||||||
</Container>
|
</Container>
|
||||||
|
</ThemeProvider>
|
||||||
|
|
||||||
|
|
||||||
<form action="https://steamcommunity.com/openid/login" method="post">
|
<form action="https://steamcommunity.com/openid/login" method="post">
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import React, {useEffect, useState} from "react";
|
import React, {useEffect, useState} from "react";
|
||||||
import {AvailableBuildings, AvailableUnits} from "../core/api";
|
import {AvailableBuildings, AvailableUnits} from "../core/api";
|
||||||
import {Grid2, Table, TableBody, TableCell, TableContainer, TableHead, TableRow} from "@mui/material";
|
import {Grid2, Link, Table, TableBody, TableCell, TableContainer, TableHead, TableRow} from "@mui/material";
|
||||||
import {NavLink} from "react-router-dom";
|
|
||||||
import {IRaceUnits, IUnitShort} from "../types/IUnitShort";
|
import {IRaceUnits, IUnitShort} from "../types/IUnitShort";
|
||||||
import {IBuildingShort, IRaceBuildings} from "../types/IBuildingShort";
|
import {IBuildingShort, IRaceBuildings} from "../types/IBuildingShort";
|
||||||
|
|
||||||
@ -20,15 +19,15 @@ export default function UnitsTable(prop: {modId: number}) {
|
|||||||
|
|
||||||
|
|
||||||
function getUnitRef(modId: number, raceId: string, unit: IUnitShort) {
|
function getUnitRef(modId: number, raceId: string, unit: IUnitShort) {
|
||||||
return <span style={{fontSize: 11}}><a href={"/mod/" + modId + "/race/" + raceId + "/unit/" + unit.id}>
|
return <span style={{fontSize: 11}}><Link href={"/mod/" + modId + "/race/" + raceId + "/unit/" + unit.id}>
|
||||||
{unit.name}
|
{unit.name}
|
||||||
</a><br/></span>
|
</Link><br/></span>
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBuildingRef(modId: number, raceId: string, building: IBuildingShort) {
|
function getBuildingRef(modId: number, raceId: string, building: IBuildingShort) {
|
||||||
return <span style={{fontSize: 11}}><a href={"/mod/" + modId + "/race/" + raceId + "/building/" + building.id}>
|
return <span style={{fontSize: 11}}><Link href={"/mod/" + modId + "/race/" + raceId + "/building/" + building.id}>
|
||||||
{building.name}
|
{building.name}
|
||||||
<br/></a></span>
|
<br/></Link></span>
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -97,8 +96,8 @@ export default function UnitsTable(prop: {modId: number}) {
|
|||||||
{<Table sx={{minWidth: 650}} size="small" aria-label="a dense table">
|
{<Table sx={{minWidth: 650}} size="small" aria-label="a dense table">
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
{racesUnitsPart.map(raceUnits => <TableCell><h2><NavLink state={raceUnits.race.id}
|
{racesUnitsPart.map(raceUnits => <TableCell><h2><Link color="inherit"
|
||||||
to={"/mod/" + prop.modId + "/race/" + raceUnits.race.id}>{raceUnits.race.name}</NavLink>
|
href={"/mod/" + prop.modId + "/race/" + raceUnits.race.id}>{raceUnits.race.name}</Link>
|
||||||
</h2></TableCell>)}
|
</h2></TableCell>)}
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
@ -147,19 +146,30 @@ export default function UnitsTable(prop: {modId: number}) {
|
|||||||
return elements
|
return elements
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function generateRaceList(unitsTable: IUnitsTable){
|
||||||
|
return unitsTable.racesUnits.sort(function (a, b) {
|
||||||
|
return a.race.name.localeCompare(b.race.name);
|
||||||
|
}).map(raceUnits => <h5><Link color="inherit"
|
||||||
|
href={"/mod/" + prop.modId + "/race/" + raceUnits.race.id}>{raceUnits.race.name}</Link><br/>
|
||||||
|
</h5>)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
if(unitsTable.racesUnits.length > 10){
|
||||||
<Grid2>
|
return <Grid2>
|
||||||
<Grid2 display={{ lg: 'block', xs: 'none' }} >
|
{generateRaceList(unitsTable)}
|
||||||
{generateRaceUnitTables(unitsTable.racesUnits, unitsTable.racesBuildings, 5)}
|
|
||||||
</Grid2>
|
|
||||||
<Grid2 display={{ lg: 'none', xs: 'block' }}>
|
|
||||||
{unitsTable.racesUnits.map(raceUnits => <h4><NavLink state={raceUnits.race.id}
|
|
||||||
to={"/mod/" + prop.modId + "/race/" + raceUnits.race.id}>{raceUnits.race.name}</NavLink>
|
|
||||||
</h4>)}
|
|
||||||
</Grid2>
|
|
||||||
</Grid2>
|
</Grid2>
|
||||||
)
|
} else {
|
||||||
|
return (
|
||||||
|
<Grid2>
|
||||||
|
<Grid2 display={{ lg: 'block', xs: 'none' }} >
|
||||||
|
{generateRaceUnitTables(unitsTable.racesUnits, unitsTable.racesBuildings, 5)}
|
||||||
|
</Grid2>
|
||||||
|
<Grid2 display={{ lg: 'none', xs: 'block' }}>
|
||||||
|
{generateRaceList(unitsTable)}
|
||||||
|
</Grid2>
|
||||||
|
</Grid2>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -129,7 +129,7 @@ class Weapon extends React.Component<IWeaponProps, any> {
|
|||||||
aria-controls="panel1-content"
|
aria-controls="panel1-content"
|
||||||
id="panel1-header"
|
id="panel1-header"
|
||||||
>
|
>
|
||||||
<span style={{fontSize: 18}}> {!this.props.isDefault && weapon.icon && weapon.haveEquipButton ?
|
<span style={{fontSize: 18}}> {!this.props.isDefault && weapon.icon && !weapon.icon.endsWith("upgrade.png") ?
|
||||||
<img className="weaponIcon" src={IconUrl + weapon.icon.replaceAll('\\', '/')}/> : (
|
<img className="weaponIcon" src={IconUrl + weapon.icon.replaceAll('\\', '/')}/> : (
|
||||||
weapon.isMeleeWeapon ?
|
weapon.isMeleeWeapon ?
|
||||||
<img className="weaponIcon" src="/images/MeleeStance_icon_bw.jpg"/> :
|
<img className="weaponIcon" src="/images/MeleeStance_icon_bw.jpg"/> :
|
||||||
|
|||||||
16
src/css/Building.css
Normal file
16
src/css/Building.css
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
.addon-accordion{
|
||||||
|
margin-top: 10px;
|
||||||
|
scroll-margin-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes blink2 {
|
||||||
|
100% { color: rgba(34, 34, 34, 0); }
|
||||||
|
}
|
||||||
|
@keyframes blink2 {
|
||||||
|
100% { color: rgba(34, 34, 34, 0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected-addon div > h3 {
|
||||||
|
-webkit-animation: blink2 1s linear infinite;
|
||||||
|
animation: blink2 1s linear infinite;
|
||||||
|
}
|
||||||
@ -1,16 +1,29 @@
|
|||||||
import {AvailableBuildings, AvailableMods, AvailableUnits, IconUrl} from "../core/api";
|
import {AvailableBuildings, AvailableMods, AvailableUnits, IconUrl} from "../core/api";
|
||||||
import React from "react";
|
import React, {MutableRefObject, useEffect, useRef} from "react";
|
||||||
import {withRouter} from "../core/withrouter";
|
import {withRouter} from "../core/withrouter";
|
||||||
import {IWeapon} from "../types/IUnit";
|
import {IWeapon} from "../types/IUnit";
|
||||||
import '../css/Unit.css'
|
import '../css/Building.css'
|
||||||
import {Button, Grid2, Paper, Table, TableBody, TableCell, TableContainer, TableRow} from "@mui/material";
|
import {
|
||||||
import {ArrowBack} from "@mui/icons-material";
|
Accordion,
|
||||||
|
AccordionDetails,
|
||||||
|
AccordionSummary,
|
||||||
|
Button,
|
||||||
|
Grid2,
|
||||||
|
Paper,
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableContainer,
|
||||||
|
TableRow
|
||||||
|
} from "@mui/material";
|
||||||
|
import {ArrowBack, ExpandMore} from "@mui/icons-material";
|
||||||
import ArmorType from "../classes/ArmorType";
|
import ArmorType from "../classes/ArmorType";
|
||||||
import AvTimerOutlinedIcon from '@mui/icons-material/AvTimer';
|
import AvTimerOutlinedIcon from '@mui/icons-material/AvTimer';
|
||||||
import WeaponSlot from "../classes/WeaponSlot";
|
import WeaponSlot from "../classes/WeaponSlot";
|
||||||
import UnitsTable from "../classes/UnitsTable";
|
import UnitsTable from "../classes/UnitsTable";
|
||||||
import {IMod} from "../types/Imod";
|
import {IMod} from "../types/Imod";
|
||||||
import {IBuilding} from "../types/IBuilding";
|
import {IBuilding, IBuildingAddon, IBuildingAddonShort} from "../types/IBuilding";
|
||||||
|
import {IBuildingShort} from "../types/IBuildingShort";
|
||||||
|
|
||||||
interface UintPageState {
|
interface UintPageState {
|
||||||
building: IBuilding,
|
building: IBuilding,
|
||||||
@ -39,6 +52,118 @@ function Building(building: IBuilding, mod: IMod) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function BuildingAddon(addon: IBuildingAddon){
|
||||||
|
|
||||||
|
return <div className='addon-accordion' id={"addon-" + addon.id} ><Accordion>
|
||||||
|
<AccordionSummary
|
||||||
|
expandIcon={<ExpandMore/>}
|
||||||
|
aria-controls="panel1-content"
|
||||||
|
>
|
||||||
|
<span style={{fontSize: 20}}>
|
||||||
|
{addon.icon && <img className="sergeantIcon" src={IconUrl + addon.icon.replaceAll('\\', '/')}/>}
|
||||||
|
{addon.name}
|
||||||
|
</span>
|
||||||
|
</AccordionSummary>
|
||||||
|
<AccordionDetails>
|
||||||
|
<Grid2 container spacing={2}>
|
||||||
|
<Grid2 size={{xs: 12, md: 4}}>
|
||||||
|
<TableContainer component={Paper}>
|
||||||
|
<Table size="small" aria-label="a dense table">
|
||||||
|
<TableBody id="unit-stats-table">
|
||||||
|
<TableRow
|
||||||
|
sx={{'&:last-child td, &:last-child th': {border: 0}}}
|
||||||
|
>
|
||||||
|
<TableCell component="th" scope="row">Cost</TableCell>
|
||||||
|
<TableCell component="th" scope="row">
|
||||||
|
{addon.addonCostRequisition > 0 &&
|
||||||
|
<span> <img style={{verticalAlign: "top"}}
|
||||||
|
src="/images/Resource_requisition.gif"/>
|
||||||
|
{addon.addonCostRequisition.toFixed(0)}</span>}
|
||||||
|
{addon.addonCostPower > 0 && <span> <img style={{verticalAlign: "top"}}
|
||||||
|
src="/images/Resource_power.gif"/>
|
||||||
|
{addon.addonCostPower.toFixed(0)}</span>}
|
||||||
|
{(addon.addonCostPopulation !== undefined && addon.addonCostPopulation > 0) &&
|
||||||
|
<span> <img style={{verticalAlign: "top"}}
|
||||||
|
src="/images/Resource_orksquadcap.gif"/>
|
||||||
|
{addon.addonCostPopulation.toFixed(0)}</span>}
|
||||||
|
{(addon.addonCostFaith !== undefined && addon.addonCostFaith > 0) &&
|
||||||
|
<span> <img style={{verticalAlign: "top"}}
|
||||||
|
src="/images/Resource_faith.gif"/>
|
||||||
|
{addon.addonCostFaith}</span>}
|
||||||
|
{(addon.addonCostSouls !== undefined && addon.addonCostSouls > 0) &&
|
||||||
|
<span> <img style={{verticalAlign: "top"}}
|
||||||
|
src="/images/Resource_souls.gif"/>
|
||||||
|
{addon.addonCostSouls.toFixed(0)}</span>}
|
||||||
|
{(addon.addonCostTime !== undefined && addon.addonCostTime > 0) &&
|
||||||
|
<span> <AvTimerOutlinedIcon
|
||||||
|
style={{verticalAlign: "top", fontSize: "18px"}}/>
|
||||||
|
{addon.addonCostTime}s</span>}
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
</Grid2>
|
||||||
|
<Grid2 size={{xs: 12, md: 8}}>
|
||||||
|
<div style={{whiteSpace: "pre-wrap"}}>
|
||||||
|
{addon.description}
|
||||||
|
</div>
|
||||||
|
</Grid2>
|
||||||
|
{addon.addonRequirement !== null &&
|
||||||
|
<Grid2 size={{xs: 12, md: 12}}>
|
||||||
|
<h4>Required: </h4>
|
||||||
|
{addon.addonRequirement.requiredTotalPop !== undefined && addon.addonRequirement.requiredTotalPop !== null &&
|
||||||
|
<div> Population: <img style={{verticalAlign: "top", height: 25}}
|
||||||
|
src="/images/Resource_orksquadcap.gif"/>
|
||||||
|
{addon.addonRequirement.requiredTotalPop}</div>
|
||||||
|
}
|
||||||
|
{addon.addonRequirement.requireAddon !== null &&
|
||||||
|
<div> Addon: <img style={{verticalAlign: "top", height: 25}}
|
||||||
|
src={IconUrl + addon.addonRequirement.requireAddon.icon.replaceAll('\\', '/')}/>
|
||||||
|
<a href={"#addon-" + addon.addonRequirement.requireAddon.id} onClick={() => goToAddon(`#addon-` + addon.addonRequirement.requireAddon.id)}>{addon.addonRequirement.requireAddon.name}</a></div>
|
||||||
|
}
|
||||||
|
{addon.addonRequirement.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>)
|
||||||
|
}
|
||||||
|
{addon.addonRequirement.requirementBuildingsEither.length !== 0 &&
|
||||||
|
renderRequirementBuilding(addon.addonRequirement.requirementBuildingsEither, building)}
|
||||||
|
{addon.addonRequirement.requirementsGlobalAddons.length !== 0 &&
|
||||||
|
renderRequirementGlobalAddons(addon.addonRequirement.requirementsGlobalAddons, building)}
|
||||||
|
</Grid2>}
|
||||||
|
</Grid2>
|
||||||
|
<i className="rgdFrom">{addon.filename}</i>
|
||||||
|
</AccordionDetails>
|
||||||
|
</Accordion></div>
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderRequirementBuilding(requirementBuildings: IBuildingShort[], building: IBuilding) {
|
||||||
|
return requirementBuildings.length > 0 && (
|
||||||
|
<div> Buildings: <img style={{verticalAlign: "top", height: 25}}
|
||||||
|
src={IconUrl + requirementBuildings[0].icon.replaceAll('\\', '/')}/>
|
||||||
|
{" "}<a href={`/mod/${building.modId}/race/${building.race.id}/building/${requirementBuildings[0].id}`}>
|
||||||
|
{requirementBuildings[0].name}
|
||||||
|
</a> or <img style={{verticalAlign: "top", height: 25}}
|
||||||
|
src={IconUrl + requirementBuildings[1].icon.replaceAll('\\', '/')}/>
|
||||||
|
{" "}<a href={`/mod/${building.modId}/race/${building.race.id}/building/${requirementBuildings[1].id}`}>
|
||||||
|
{requirementBuildings[1].name}</a></div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderRequirementGlobalAddons(rgas: IBuildingAddonShort[], building: IBuilding) {
|
||||||
|
return <div> {rgas.map(rga =>
|
||||||
|
<span> Global addon: <img style={{verticalAlign: "top", height: 25}}
|
||||||
|
src={IconUrl + rga.icon.replaceAll('\\', '/')}/>
|
||||||
|
<a href={`/mod/${building.modId}/race/${building.race.id}/building/${rga.buildingId}#addon-${rga.id}`}>
|
||||||
|
{rga.name}
|
||||||
|
</a></span>
|
||||||
|
)}</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h1>{mod.name} ({mod.version})</h1>
|
<h1>{mod.name} ({mod.version})</h1>
|
||||||
@ -124,6 +249,12 @@ function Building(building: IBuilding, mod: IMod) {
|
|||||||
{building.description}
|
{building.description}
|
||||||
</div>
|
</div>
|
||||||
</Grid2>
|
</Grid2>
|
||||||
|
{building.addons.length > 0 && <Grid2 size={12}>
|
||||||
|
<h3>Addons</h3>
|
||||||
|
{building.addons.map(b =>
|
||||||
|
BuildingAddon(b)
|
||||||
|
)}
|
||||||
|
</Grid2> }
|
||||||
<Grid2 size={12}>
|
<Grid2 size={12}>
|
||||||
{[...mapBuildingWeapons.keys()].sort(function (a, b) {
|
{[...mapBuildingWeapons.keys()].sort(function (a, b) {
|
||||||
return a - b;
|
return a - b;
|
||||||
@ -136,6 +267,16 @@ function Building(building: IBuilding, mod: IMod) {
|
|||||||
</div>)
|
</div>)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function goToAddon(addonHash: string) {
|
||||||
|
let addonId = addonHash.replace("#", "");
|
||||||
|
console.log(addonId);
|
||||||
|
[].forEach.call(document.querySelectorAll('div'), function (el: HTMLElement) {
|
||||||
|
el?.classList?.remove('selected-addon');
|
||||||
|
});
|
||||||
|
document?.getElementById(addonId)?.classList?.add("selected-addon");
|
||||||
|
document?.getElementById(addonId)?.scrollIntoView()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class BuildingPage extends React.Component<any, UintPageState> {
|
class BuildingPage extends React.Component<any, UintPageState> {
|
||||||
|
|
||||||
@ -153,6 +294,7 @@ class BuildingPage extends React.Component<any, UintPageState> {
|
|||||||
this.setState({
|
this.setState({
|
||||||
mod: modData
|
mod: modData
|
||||||
});
|
});
|
||||||
|
goToAddon(window.location.hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import {
|
|||||||
AccordionSummary,
|
AccordionSummary,
|
||||||
Button,
|
Button,
|
||||||
ButtonGroup,
|
ButtonGroup,
|
||||||
Grid2,
|
Grid2, Link,
|
||||||
List,
|
List,
|
||||||
ListItem,
|
ListItem,
|
||||||
ListSubheader,
|
ListSubheader,
|
||||||
@ -41,24 +41,24 @@ interface RacePageState {
|
|||||||
|
|
||||||
function Unit (unit: IUnitShort, modId: number, raceId: String) {
|
function Unit (unit: IUnitShort, modId: number, raceId: String) {
|
||||||
|
|
||||||
return (<a href={"/mod/" + modId + "/race/" + raceId + "/unit/" + unit.id}><ListItem>
|
return (<Link href={"/mod/" + modId + "/race/" + raceId + "/unit/" + unit.id}><ListItem>
|
||||||
{unit.icon && <img className="unitIcon" src={IconUrl + unit.icon.replaceAll('\\', '/')}/> }
|
{unit.icon && <img className="unitIcon" src={IconUrl + unit.icon.replaceAll('\\', '/')}/> }
|
||||||
{unit.name}
|
{unit.name}
|
||||||
{unit.canDetect && <span> <img style={{verticalAlign: "top"}}
|
{unit.canDetect && <span> <img style={{verticalAlign: "top"}}
|
||||||
src="/images/DETECT_YES.webp"/></span>}
|
src="/images/DETECT_YES.webp"/></span>}
|
||||||
|
|
||||||
</ListItem></a>)
|
</ListItem></Link>)
|
||||||
}
|
}
|
||||||
|
|
||||||
function Building (building: IBuildingShort, modId: number, raceId: String) {
|
function Building (building: IBuildingShort, modId: number, raceId: String) {
|
||||||
|
|
||||||
return (<a href={"/mod/" + modId + "/race/" + raceId + "/building/" + building.id}><ListItem>
|
return (<Link href={"/mod/" + modId + "/race/" + raceId + "/building/" + building.id}><ListItem>
|
||||||
{building.icon && <img className="unitIcon" src={IconUrl + building.icon.replaceAll('\\', '/')}/>}
|
{building.icon && <img className="unitIcon" src={IconUrl + building.icon.replaceAll('\\', '/')}/>}
|
||||||
{building.name}
|
{building.name}
|
||||||
{building.canDetect && <span> <img style={{verticalAlign: "top"}}
|
{building.canDetect && <span> <img style={{verticalAlign: "top"}}
|
||||||
src="/images/DETECT_YES.webp"/></span>}
|
src="/images/DETECT_YES.webp"/></span>}
|
||||||
|
|
||||||
</ListItem></a>)
|
</ListItem></Link>)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UnitsProps{
|
interface UnitsProps{
|
||||||
@ -170,7 +170,7 @@ class RacePageFast extends React.Component<any, RacePageState> {
|
|||||||
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
|
const backRef = "/mod/" + this.state.mod.id
|
||||||
|
|
||||||
return <div><a href={backRef}><Button id="back-button" variant="contained" startIcon={<ArrowBack/>}> Back</Button></a>
|
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>
|
<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}/>
|
<Units raceId={this.state.race.id} modId={this.state.mod.id}/>
|
||||||
</div>;
|
</div>;
|
||||||
|
|||||||
@ -133,10 +133,10 @@ function Unit(unit: IUnit, mod: IMod) {
|
|||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell>Reinforce cost</TableCell>
|
<TableCell>Reinforce cost</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
{unit.reinforceCostRequisition && unit.reinforceCostRequisition > 0 &&
|
{unit.reinforceCostRequisition && unit.reinforceCostRequisition > 0 ?
|
||||||
<span> <img style={{verticalAlign: "top"}}
|
<span> <img style={{verticalAlign: "top"}}
|
||||||
src="/images/Resource_requisition.gif"/>
|
src="/images/Resource_requisition.gif"/>
|
||||||
{unit.reinforceCostRequisition.toFixed(0)}</span>}
|
{unit.reinforceCostRequisition.toFixed(0)}</span>:<span/>}
|
||||||
{unit.reinforceCostPower !== undefined && unit.reinforceCostPower > 0 &&
|
{unit.reinforceCostPower !== undefined && unit.reinforceCostPower > 0 &&
|
||||||
<span> <img style={{verticalAlign: "top"}}
|
<span> <img style={{verticalAlign: "top"}}
|
||||||
src="/images/Resource_power.gif"/>
|
src="/images/Resource_power.gif"/>
|
||||||
@ -219,6 +219,14 @@ function Unit(unit: IUnit, mod: IMod) {
|
|||||||
{detect}
|
{detect}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
|
{unit.repairMax !== undefined &&
|
||||||
|
<TableRow>
|
||||||
|
<TableCell>Repair max</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
{unit.repairMax}
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
</TableContainer>
|
</TableContainer>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import {Irace} from "./Irace";
|
import {Irace} from "./Irace";
|
||||||
import {IArmorType} from "./IArmorType";
|
import {IArmorType} from "./IArmorType";
|
||||||
import {WeaponHardpoint} from "./IUnit";
|
import {WeaponHardpoint} from "./IUnit";
|
||||||
|
import {IBuildingShort} from "./IBuildingShort";
|
||||||
|
|
||||||
export interface IBuilding {
|
export interface IBuilding {
|
||||||
id: number
|
id: number
|
||||||
@ -24,5 +25,43 @@ export interface IBuilding {
|
|||||||
icon: string
|
icon: string
|
||||||
modId: number
|
modId: number
|
||||||
weapons: WeaponHardpoint[]
|
weapons: WeaponHardpoint[]
|
||||||
|
addons: IBuildingAddon[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IBuildingAddon {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
filename: string;
|
||||||
|
addonCostRequisition: number;
|
||||||
|
addonCostPower: number;
|
||||||
|
addonCostPopulation: number;
|
||||||
|
addonCostFaith: number;
|
||||||
|
addonCostSouls: number;
|
||||||
|
addonCostTime: number;
|
||||||
|
addonModifiers: IAddonModifier[];
|
||||||
|
addonRequirement: IAddonRequirement;
|
||||||
|
icon?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IBuildingAddonShort {
|
||||||
|
id: number;
|
||||||
|
buildingId: number;
|
||||||
|
name: string;
|
||||||
|
icon: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IAddonRequirement {
|
||||||
|
requirementBuildings: IBuildingShort[];
|
||||||
|
requirementBuildingsEither: IBuildingShort[];
|
||||||
|
requirementsGlobalAddons: IBuildingAddonShort[];
|
||||||
|
requireAddon: IBuildingAddonShort;
|
||||||
|
requiredTotalPop?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IAddonModifier {
|
||||||
|
id: number;
|
||||||
|
reference: string;
|
||||||
|
usageType: string;
|
||||||
|
value: number;
|
||||||
|
}
|
||||||
@ -28,6 +28,7 @@ export interface IUnit {
|
|||||||
health: number
|
health: number
|
||||||
healthRegeneration: number
|
healthRegeneration: number
|
||||||
moraleDeathPenalty: number
|
moraleDeathPenalty: number
|
||||||
|
repairMax: number
|
||||||
moraleMax?: number
|
moraleMax?: number
|
||||||
moraleBroken?: number
|
moraleBroken?: number
|
||||||
moraleRegeneration?: number
|
moraleRegeneration?: number
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user