diff --git a/pages/explorer/races/[raceId].tsx b/pages/explorer/races/[raceId].tsx index dec8587c..70730818 100644 --- a/pages/explorer/races/[raceId].tsx +++ b/pages/explorer/races/[raceId].tsx @@ -182,26 +182,6 @@ const BuildingMapping = ( ); }; -// function getBuildingTrainableUnits( -// building: EbpsType, -// sbpsData: SbpsType[], -// ebpsData: EbpsType[], -// ): BuildingSchema["units"] { -// return Object.entries(getResolvedSquads(building.spawnItems, sbpsData, ebpsData)).map( -// ([id, { ui, time_cost }]) => ({ -// id, -// desc: { -// screen_name: ui.screenName, -// help_text: ui.helpText, -// brief_text: ui.briefText, -// symbol_icon_name: ui.symbolIconName, -// icon_name: ui.iconName, -// }, -// time_cost, -// }), -// ); -// } - function getBuildingUpgrades( building: EbpsType, upgradesData: UpgradesType[], diff --git a/pages/explorer/races/[raceId]/units/[unitId].tsx b/pages/explorer/races/[raceId]/units/[unitId].tsx index b1dc3237..2d7be7c2 100644 --- a/pages/explorer/races/[raceId]/units/[unitId].tsx +++ b/pages/explorer/races/[raceId]/units/[unitId].tsx @@ -2,11 +2,23 @@ import { GetStaticPaths, GetStaticProps, NextPage } from "next"; import Head from "next/head"; import Error from "next/error"; import { useRouter } from "next/router"; -import { Card, Container, Flex, Grid, List, Space, Stack, Text, Title } from "@mantine/core"; +import { + Card, + Container, + Flex, + Grid, + List, + SimpleGrid, + Space, + Stack, + Text, + Title, +} from "@mantine/core"; import { AbilitiesType, EbpsType, getResolvedAbilities, + getResolvedConstruction, getResolvedUpgrades, getSquadTotalCost, getSquadTotalUpkeepCost, @@ -45,6 +57,7 @@ interface UnitDetailProps { resolvedEntities: EbpsType[]; upgrades: UpgradesType[]; abilities: AbilitiesType[]; + buildables: EbpsType[]; }; } @@ -117,7 +130,7 @@ const UnitDetail: NextPage = ({ calculatedData }) => { const { totalUpkeepCost } = calculatedData; // Obtain the squad weapons loadout (ignoring non-damage dealing ones like smoke). - const { squadWeapons, upgrades, abilities } = calculatedData; + const { squadWeapons, upgrades, abilities, buildables } = calculatedData; // Use default weapon for max range. const rangeValues = { @@ -217,6 +230,7 @@ const UnitDetail: NextPage = ({ calculatedData }) => { + {UnitBuildingSection(buildables)} {UnitWeaponSection(squadWeapons)} @@ -255,6 +269,42 @@ const UnitUpgradeSection = (upgrades: UpgradesType[]) => { ); }; +const UnitBuildingSection = (buildings: EbpsType[]) => { + // Resolve unit buildables. + if (!buildings || !buildings.length) return <>; + return ( + + Can construct + + {Object.values(buildings).map(({ id, ui, cost }) => { + // If we are missing the name of the ability --> it's most likely broken + if (ui.screenName) { + return ( + + {UnitUpgradeCard({ + id, + desc: { + screen_name: ui.screenName, + help_text: ui.helpText, + extra_text: ui.extraText, + brief_text: ui.briefText, + icon_name: ui.iconName, + extra_text_formatter: "", + brief_text_formatter: "", + }, + time_cost: cost, + })} + + ); + } else { + return null; + } + })} + + + ); +}; + const UnitAbilitySection = (abilities: AbilitiesType[]) => { // Resolve unit abilities. if (!abilities || !abilities.length) return <>; @@ -354,6 +404,8 @@ const createdCalculateValuesForUnits = ( const abilities = Object.values(getResolvedAbilities(resolvedSquad.abilities, abilitiesData)); + const buildables = Object.values(getResolvedConstruction(resolvedSquad.construction, ebpsData)); + // console.log('Calculated abilities', resolvedSquad); const resolvedEntities: EbpsType[] = []; @@ -374,6 +426,7 @@ const createdCalculateValuesForUnits = ( resolvedEntities, upgrades, abilities, + buildables, }; }; diff --git a/src/unitStats/faction.ts b/src/unitStats/faction.ts index c496170d..566bfe9a 100644 --- a/src/unitStats/faction.ts +++ b/src/unitStats/faction.ts @@ -18,6 +18,18 @@ export function getResolvedAbilities(refs: string[], abilities: AbilitiesType[]) return foundAbilities; } +export function getResolvedConstruction(refs: string[], ebpsData: EbpsType[]) { + // The key is the ebps id. + const foundConstructions: Record = {}; + for (const refId of refs) { + const foundItem = ebpsData.find((x) => x.id === refId); + if (!foundItem) continue; + + foundConstructions[refId] ??= foundItem; + } + return foundConstructions; +} + export function getResolvedUpgrades(refs: string[], upgradesData: UpgradesType[]) { // The key is the upgrade id. const researchableUpgrades: Record = {}; diff --git a/src/unitStats/mappingSbps.ts b/src/unitStats/mappingSbps.ts index 263b4344..3601d5d8 100644 --- a/src/unitStats/mappingSbps.ts +++ b/src/unitStats/mappingSbps.ts @@ -43,6 +43,10 @@ type SbpsType = { requirements: string[]; /** Found at `squad_ability_ext`. This contains unit abilities references. */ abilities: string[]; + /** Found at `squad_engineer_ext/construction_groups/construction_items` list. + * This conatins the ebps reference to the building list this squad can + * construct. */ + construction: string[]; /** Found at `squad_reinforce_ext`. This contains reinforcement * information */ @@ -135,6 +139,7 @@ const mapSbpsData = (filename: string, subtree: any, jsonPath: string, parent: s capture_revert: 0, requirements: [], abilities: [], + construction: [], }; mapExtensions(subtree, sbpsEntity); @@ -282,6 +287,19 @@ const mapExtensions = (root: any, sbps: SbpsType) => { } } break; + case "squad_engineer_ext": + if (!extension.construction_groups?.length) break; + for (const conGroup of extension.construction_groups) { + if (!conGroup.construction_group.construction_items?.length) break; + for (const conItem of conGroup.construction_group.construction_items) { + if (conItem.construction_item.ebp.instance_reference) { + sbps.construction.push( + conItem.construction_item.ebp.instance_reference.split("/").slice(-1)[0], + ); + } + } + } + break; default: break; }