feat: show mana type and base cost on discipline cards
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m22s

This commit is contained in:
2026-05-25 12:50:01 +02:00
parent e9eb7d8b14
commit 2c58186a67
3 changed files with 40 additions and 8 deletions
+37 -5
View File
@@ -1,6 +1,8 @@
import React, { useEffect, useState, useCallback } from 'react';
import { useDisciplineStore } from '@/lib/game/stores/discipline-slice';
import type { DisciplineDefinition } from '@/lib/game/types/disciplines';
import type { ManaType } from '@/lib/game/types/elements';
import { ELEMENTS } from '@/lib/game/constants/elements';
import { baseDisciplines } from '@/lib/game/data/disciplines/base';
import { elementalRegenDisciplines } from '@/lib/game/data/disciplines/elemental-regen';
import { elementalRegenAdvancedDisciplines } from '@/lib/game/data/disciplines/elemental-regen-advanced';
@@ -33,6 +35,8 @@ export interface DisciplineCardDefinition {
id: string;
name: string;
description: string;
manaType: ManaType;
baseCost: number;
perkThresholds?: number[];
perkValues?: number[];
perkTypes?: string[];
@@ -63,7 +67,7 @@ interface DisciplineCardProps {
const DisciplineCard: React.FC<DisciplineCardProps> = ({ definition, runtime, callbacks }) => {
const {
id, name, description, perkThresholds, perkValues, perkTypes,
id, name, description, manaType, baseCost, perkThresholds, perkValues, perkTypes,
statBonus, baseValue, drainBase, difficultyFactor, scalingFactor,
} = definition;
const { xp, paused: isPaused, concurrentLimit } = runtime;
@@ -75,6 +79,11 @@ const DisciplineCard: React.FC<DisciplineCardProps> = ({ definition, runtime, ca
const activeStatBonus = calculateStatBonus(baseValue, displayXp, scalingFactor);
const estimatedDrain = calculateManaDrain(drainBase, displayXp, difficultyFactor);
const elementDef = ELEMENTS[manaType];
const manaColor = elementDef?.color ?? '#888888';
const manaIcon = elementDef?.sym ?? '✦';
const manaName = elementDef?.name ?? manaType;
const unlockedPerks = perkTypes?.reduce<string[]>((acc, typ, idx) => {
const threshold = perkThresholds?.[idx];
if (threshold === undefined) return acc;
@@ -94,7 +103,21 @@ const DisciplineCard: React.FC<DisciplineCardProps> = ({ definition, runtime, ca
return (
<div key={id} className="border rounded-lg p-4 shadow-sm space-y-3">
<h3 className="text-lg font-medium">{name}</h3>
<div className="flex items-center justify-between gap-2">
<h3 className="text-lg font-medium">{name}</h3>
<span
className="inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium"
style={{
backgroundColor: `${manaColor}20`,
borderColor: `${manaColor}60`,
borderWidth: 1,
color: manaColor,
}}
>
<span>{manaIcon}</span>
<span>{manaName}</span>
</span>
</div>
<p className="text-sm text-gray-400">{description}</p>
<div className="flex items-center gap-2">
@@ -107,9 +130,16 @@ const DisciplineCard: React.FC<DisciplineCardProps> = ({ definition, runtime, ca
</div>
</div>
<div className="text-sm text-gray-400">
<strong>Drain:</strong> {estimatedDrain.toFixed(1)} {' '}
<strong>XP:</strong> {displayXp}
<div className="flex flex-wrap gap-x-4 gap-y-1 text-sm text-gray-400">
<span>
<strong>Drain:</strong> {estimatedDrain.toFixed(1)}/tick
</span>
<span>
<strong>Base Cost:</strong> {baseCost}
</span>
<span>
<strong>XP:</strong> {displayXp}
</span>
</div>
<div className="mt-2 text-sm">
@@ -215,6 +245,8 @@ export const DisciplinesTab: React.FC = () => {
perkThresholds: disc.perks?.map((p) => p.threshold),
perkValues: disc.perks?.map((p) => p.value),
perkTypes: disc.perks?.map((p) => p.type),
manaType: disc.manaType,
baseCost: disc.baseCost,
statBonus: disc.statBonus.stat,
baseValue: disc.statBonus.baseValue,
drainBase: disc.drainBase,