Skip to content

Commit

Permalink
Merge pull request #433 from cohstats/build-list-unit
Browse files Browse the repository at this point in the history
Add buildable list to unit stats
  • Loading branch information
KingDarBoja authored Apr 27, 2024
2 parents 7172d2b + 0102ed0 commit ae3ed23
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 4 deletions.
51 changes: 50 additions & 1 deletion components/unit-cards/unit-upgrade-card.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
import { createStyles, Flex, Grid, Group, HoverCard, Text, Title, Tooltip } from "@mantine/core";
import {
createStyles,
Flex,
Grid,
Group,
HoverCard,
Stack,
Text,
Title,
Tooltip,
} from "@mantine/core";
import { UnitCostCard } from "./unit-cost-card";
import ImageWithFallback, { iconPlaceholder } from "../placeholders";
import { hasCost, ResourceValues } from "../../src/unitStats";
Expand Down Expand Up @@ -192,3 +202,42 @@ export const UnitUpgradeCard = ({ desc, time_cost, cfg }: UnitUpgrade) => {
</Flex>
);
};

export const ConstructableCard = ({ desc, time_cost, cfg }: UnitUpgrade) => {
return (
<Stack h="100%" align="stretch" justify="space-between" spacing={16}>
<UnitUpgradeCardHeader
desc={{
screen_name: desc.screen_name,
help_text: desc.help_text,
brief_text: desc.brief_text,
extra_text: desc.extra_text,
extra_text_formatter: desc.extra_text_formatter,
brief_text_formatter: desc.brief_text_formatter,
icon_name: desc.icon_name,
}}
cfg={cfg}
></UnitUpgradeCardHeader>
{hasBuildableCost(time_cost) ? (
UnitCostCard(time_cost)
) : (
<Stack spacing={0}>
<Title order={6} transform="uppercase">
Costs
</Title>
<Flex key="stats_costs_list" align="center" gap={8} mt={4} wrap="wrap">
<Text>Free</Text>
</Flex>
</Stack>
)}
</Stack>
);
};

/** Only for the buildable list. */
const hasBuildableCost = (time_cost: ResourceValues) => {
const hasMan = time_cost?.manpower && time_cost.manpower > 0;
const hasFuel = time_cost?.fuel && time_cost.fuel > 0;
const hasAmmo = time_cost?.munition && time_cost.munition > 0;
return hasMan || hasFuel || hasAmmo;
};
68 changes: 65 additions & 3 deletions pages/explorer/races/[raceId]/units/[unitId].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -24,7 +36,10 @@ import {
ReinforceCostCard,
UnitCostCard,
} from "../../../../../components/unit-cards/unit-cost-card";
import { UnitUpgradeCard } from "../../../../../components/unit-cards/unit-upgrade-card";
import {
ConstructableCard,
UnitUpgradeCard,
} from "../../../../../components/unit-cards/unit-upgrade-card";
import { VeterancyCard } from "../../../../../components/unit-cards/veterancy-card";
import { WeaponLoadoutCard } from "../../../../../components/unit-cards/weapon-loadout-card";
import { HitpointCard } from "../../../../../components/unit-cards/hitpoints-card";
Expand All @@ -45,6 +60,7 @@ interface UnitDetailProps {
resolvedEntities: EbpsType[];
upgrades: UpgradesType[];
abilities: AbilitiesType[];
buildables: EbpsType[];
};
}

Expand Down Expand Up @@ -117,7 +133,7 @@ const UnitDetail: NextPage<UnitDetailProps> = ({ 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 = {
Expand Down Expand Up @@ -217,6 +233,7 @@ const UnitDetail: NextPage<UnitDetailProps> = ({ calculatedData }) => {
</Grid.Col>
</Grid>
<Grid>
<Grid.Col>{UnitBuildingSection(buildables)}</Grid.Col>
<Grid.Col>{UnitWeaponSection(squadWeapons)}</Grid.Col>
</Grid>
</Container>
Expand Down Expand Up @@ -255,6 +272,48 @@ const UnitUpgradeSection = (upgrades: UpgradesType[]) => {
);
};

const UnitBuildingSection = (buildings: EbpsType[]) => {
// Resolve unit buildables.
if (!buildings || !buildings.length) return <></>;
return (
<Stack>
<Title order={4}>Can construct</Title>
<SimpleGrid
breakpoints={[
{ minWidth: "xs", cols: 1 },
{ minWidth: "sm", cols: 2 },
{ minWidth: "lg", cols: 3 },
]}
>
{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 (
<Card key={id} p="lg" radius="md" withBorder>
{ConstructableCard({
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,
})}
</Card>
);
} else {
return null;
}
})}
</SimpleGrid>
</Stack>
);
};

const UnitAbilitySection = (abilities: AbilitiesType[]) => {
// Resolve unit abilities.
if (!abilities || !abilities.length) return <></>;
Expand Down Expand Up @@ -354,6 +413,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[] = [];
Expand All @@ -374,6 +435,7 @@ const createdCalculateValuesForUnits = (
resolvedEntities,
upgrades,
abilities,
buildables,
};
};

Expand Down
12 changes: 12 additions & 0 deletions src/unitStats/faction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, EbpsType> = {};
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<string, UpgradesType> = {};
Expand Down
18 changes: 18 additions & 0 deletions src/unitStats/mappingSbps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -135,6 +139,7 @@ const mapSbpsData = (filename: string, subtree: any, jsonPath: string, parent: s
capture_revert: 0,
requirements: [],
abilities: [],
construction: [],
};

mapExtensions(subtree, sbpsEntity);
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit ae3ed23

Please sign in to comment.