Skip to content

Commit

Permalink
Merge pull request #72 from dragoni7/dynamic-total-stats-in-armor-mod…
Browse files Browse the repository at this point in the history
…ifcation

total stat display added to the armor customization component
  • Loading branch information
Rorschach7552 authored Sep 13, 2024
2 parents 83a8bc2 + 7eeb8fc commit 211480f
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 2 deletions.
14 changes: 12 additions & 2 deletions src/components/LoadoutCustomization.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import AbilitiesModification from '../features/subclass/AbilitiesModification';
import ShareLoadout from '../features/loadouts/components/ShareLoadout';
import { SubclassConfig } from '../types/d2l-types';
import SaveLoadout from '../features/loadouts/components/SaveLoadout';
import TotalStatsDisplay from '../features/subclass/TotalStatsDisplay';

interface LoadoutCustomizationProps {
onBackClick: () => void;
Expand Down Expand Up @@ -100,8 +101,17 @@ const LoadoutCustomization: React.FC<LoadoutCustomizationProps> = ({
<Grid item md={1}>
<AbilitiesModification subclass={subclass} />
</Grid>
<Grid item md={1} sx={{ textAlign: 'center' }}>
FREE SPACE FOR SOMETHING
<Grid
item
md={1}
sx={{
textAlign: 'center',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<TotalStatsDisplay />
</Grid>
<Grid item md={1} sx={{ textAlign: 'center' }}>
<EquipLoadout />
Expand Down
132 changes: 132 additions & 0 deletions src/features/subclass/TotalStatsDisplay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import React, { useMemo } from 'react';
import { useSelector } from 'react-redux';
import { styled } from '@mui/material/styles';
import { Box, Typography, Grid } from '@mui/material';
import { RootState } from '../../store';
import { StatName, DestinyArmor } from '../../types/d2l-types';
import { STATS } from '../../lib/bungie_api/constants';
import { ManifestArmorStatMod, ManifestStatPlug } from '../../types/manifest-types';

const StatsContainer = styled(Box)(({ theme }) => ({
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
padding: theme.spacing(1),
backgroundColor: 'rgba(0, 0, 0, 0.5)',
backdropFilter: 'blur(10px)',
borderRadius: theme.shape.borderRadius,
}));

const StatItem = styled(Box)(({ theme }) => ({
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
margin: theme.spacing(0, 1),
}));

const StatIcon = styled('img')({
width: 24,
height: 24,
});

const StatValue = styled(Typography)({
color: 'white',
fontWeight: 'bold',
});

const statIcons: Record<StatName, string> = {
mobility: 'assets/mob.png',
resilience: 'assets/res.png',
recovery: 'assets/rec.png',
discipline: 'assets/disc.png',
intellect: 'assets/int.png',
strength: 'assets/str.png',
};

function isStatsMod(mod: unknown): mod is ManifestArmorStatMod {
return (
typeof mod === 'object' &&
mod !== null &&
('mobilityMod' in mod ||
'resilienceMod' in mod ||
'recoveryMod' in mod ||
'disciplineMod' in mod ||
'intellectMod' in mod ||
'strengthMod' in mod)
);
}

const TotalStatsDisplay: React.FC = () => {
const loadout = useSelector((state: RootState) => state.loadoutConfig.loadout);

const totalStats = useMemo(() => {
const stats: Record<StatName, number> = {
mobility: 0,
resilience: 0,
recovery: 0,
discipline: 0,
intellect: 0,
strength: 0,
};

// Sum up armor stats
const armorPieces: DestinyArmor[] = [
loadout.helmet,
loadout.gauntlets,
loadout.chestArmor,
loadout.legArmor,
loadout.classArmor,
];
armorPieces.forEach((armor) => {
(STATS as StatName[]).forEach((stat) => {
stats[stat] += Number(armor[stat]) || 0;
});
});

// Add stats from armor mods in slot 0
const armorMods = [
loadout.helmetMods[0],
loadout.gauntletsMods[0],
loadout.chestArmorMods[0],
loadout.legArmorMods[0],
loadout.classArmorMods[0],
];

armorMods.forEach((mod) => {
if (isStatsMod(mod)) {
(STATS as StatName[]).forEach((stat) => {
const modStat = `${stat}Mod` as keyof ManifestStatPlug;
stats[stat] += Number(mod[modStat]) || 0;
});
}
});

// Add stats from fragments
loadout.subclassConfig.fragments.forEach((fragment) => {
(STATS as StatName[]).forEach((stat) => {
const fragmentStat = `${stat}Mod` as keyof typeof fragment;
stats[stat] += Number(fragment[fragmentStat]) || 0;
});
});

return stats;
}, [loadout]);

return (
<StatsContainer>
<Grid container spacing={1} justifyContent="center">
{(STATS as StatName[]).map((stat) => (
<Grid item key={stat}>
<StatItem>
<StatIcon src={statIcons[stat]} alt={stat} />
<StatValue variant="body2">{totalStats[stat]}</StatValue>
</StatItem>
</Grid>
))}
</Grid>
</StatsContainer>
);
};

export default TotalStatsDisplay;

0 comments on commit 211480f

Please sign in to comment.