Skip to content

Commit f426715

Browse files
committed
dynamic fragment slots based on aspect
1 parent 902d5fc commit f426715

File tree

1 file changed

+52
-15
lines changed

1 file changed

+52
-15
lines changed

src/features/subclass/AbilitiesModification.tsx

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,6 @@ const fetchMods = async (subclass: ManifestSubclass) => {
209209
return modsData;
210210
}
211211
};
212-
213212
const AbilitiesModification: React.FC<AbilitiesModificationProps> = ({ subclass }) => {
214213
const [mods, setMods] = useState<{
215214
[key: string]: (ManifestPlug | ManifestAspect | ManifestStatPlug)[];
@@ -237,6 +236,10 @@ const AbilitiesModification: React.FC<AbilitiesModificationProps> = ({ subclass
237236
}
238237
}, [subclass]);
239238

239+
const calculateAvailableFragmentSlots = useCallback(() => {
240+
return loadout.aspects.reduce((total, aspect) => total + (aspect.energyCapacity || 0), 0);
241+
}, [loadout.aspects]);
242+
240243
const handleModSelect = (
241244
category: string,
242245
mod: ManifestPlug | ManifestAspect | ManifestStatPlug,
@@ -246,23 +249,22 @@ const AbilitiesModification: React.FC<AbilitiesModificationProps> = ({ subclass
246249

247250
switch (category) {
248251
case 'ASPECTS':
249-
updatedMods = [...loadout.aspects];
252+
updatedMods = [...loadout.aspects] as ManifestAspect[];
250253
break;
251254
case 'FRAGMENTS':
252-
updatedMods = [...loadout.fragments];
255+
updatedMods = [...loadout.fragments] as ManifestStatPlug[];
253256
break;
254257
case 'SUPERS':
255258
case 'CLASS_ABILITIES':
256259
case 'MOVEMENT_ABILITIES':
257260
case 'MELEE_ABILITIES':
258261
case 'GRENADES':
259-
updatedMods = [mod];
262+
updatedMods = [mod] as ManifestPlug[];
260263
break;
261264
default:
262265
return;
263266
}
264267

265-
// Check if the mod already exists in another slot and replace it with an empty mod
266268
if (category === 'ASPECTS' || category === 'FRAGMENTS') {
267269
const modIndex = updatedMods.findIndex(
268270
(existingMod) => existingMod.itemHash === mod.itemHash
@@ -272,13 +274,39 @@ const AbilitiesModification: React.FC<AbilitiesModificationProps> = ({ subclass
272274
updatedMods[modIndex] = category === 'ASPECTS' ? EMPTY_ASPECT : EMPTY_FRAGMENT;
273275
}
274276

275-
// Assign the mod to the selected slot
276-
updatedMods[index!] = mod;
277-
} else {
278-
// Directly assign the mod for SUPERS and abilities
279-
updatedMods[0] = mod;
277+
updatedMods[index!] = mod as (typeof updatedMods)[number];
278+
279+
// If updating aspects, we need to check if we need to empty any fragment slots
280+
if (category === 'ASPECTS') {
281+
const newAspects = updatedMods as ManifestAspect[];
282+
const newAvailableSlots = newAspects.reduce(
283+
(total, aspect) => total + (aspect.energyCapacity || 0),
284+
0
285+
);
286+
287+
// Update fragments, emptying any that exceed the new available slots
288+
const updatedFragments = loadout.fragments.map((fragment, idx) =>
289+
idx < newAvailableSlots ? fragment : EMPTY_FRAGMENT
290+
);
291+
292+
// Dispatch updates for both aspects and fragments
293+
dispatch(
294+
updateSubclassMods({
295+
category: 'ASPECTS',
296+
mods: newAspects,
297+
})
298+
);
299+
dispatch(
300+
updateSubclassMods({
301+
category: 'FRAGMENTS',
302+
mods: updatedFragments,
303+
})
304+
);
305+
return; // Exit the function early as we've already dispatched the updates
306+
}
280307
}
281308

309+
// For all other cases, dispatch the update as before
282310
dispatch(
283311
updateSubclassMods({
284312
category,
@@ -312,21 +340,26 @@ const AbilitiesModification: React.FC<AbilitiesModificationProps> = ({ subclass
312340

313341
const SlotComponent = category === 'SUPERS' ? SuperModSlot : ModSlot;
314342

343+
const availableFragmentSlots = calculateAvailableFragmentSlots();
344+
const isDisabled = category === 'FRAGMENTS' && index! >= availableFragmentSlots;
345+
315346
return (
316347
<Box key={slotId} position="relative" display="inline-block">
317348
<div onMouseEnter={(e) => handleMouseEnter(e, slotId)} onMouseLeave={handleMouseLeave}>
318349
<SlotComponent
319350
style={{
320351
backgroundImage: currentMod ? `url(${currentMod.icon})` : 'none',
352+
opacity: isDisabled ? 0.5 : 1,
353+
pointerEvents: isDisabled ? 'none' : 'auto',
321354
}}
322355
>
323356
{isEmptyMod && (
324357
<Typography variant="caption" style={{ color: 'rgba(255, 255, 255, 0.7)' }}>
325-
Empty
358+
{isDisabled ? 'Locked' : 'Empty'}
326359
</Typography>
327360
)}
328361
</SlotComponent>
329-
{isHovered && (
362+
{isHovered && !isDisabled && (
330363
<SubmenuContainer
331364
style={{
332365
top: submenuPosition.top,
@@ -347,7 +380,7 @@ const AbilitiesModification: React.FC<AbilitiesModificationProps> = ({ subclass
347380
</Box>
348381
);
349382
},
350-
[mods, handleModSelect, hoveredSlot, submenuPosition]
383+
[mods, handleModSelect, hoveredSlot, submenuPosition, calculateAvailableFragmentSlots]
351384
);
352385

353386
if (loading) {
@@ -413,9 +446,13 @@ const AbilitiesModification: React.FC<AbilitiesModificationProps> = ({ subclass
413446
<Box marginBottom={2}>
414447
<StyledTitle variant="h6">FRAGMENTS</StyledTitle>
415448
<Box display="flex" flexWrap="wrap" gap={2}>
416-
{loadout.fragments.map((fragment, index) => (
449+
{Array.from({ length: 5 }).map((_, index) => (
417450
<React.Fragment key={index}>
418-
{renderModCategory('FRAGMENTS', fragment, index)}
451+
{renderModCategory(
452+
'FRAGMENTS',
453+
loadout.fragments[index] || EMPTY_FRAGMENT,
454+
index
455+
)}
419456
</React.Fragment>
420457
))}
421458
</Box>

0 commit comments

Comments
 (0)