Redesign skill system around attunements
All checks were successful
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 3m31s

- Add attunementLevel field to SkillDef type
- Organize skills into Core, Enchanter, Invoker, and Fabricator trees
- Core skills (mana, study, ascension) available to all players
- Enchanter skills require Enchanter attunement and scale with level
- Invoker skills for pact mastery and invocation (requires Invoker attunement)
- Fabricator skills for golemancy and fabrication (requires Fabricator attunement)
- Add attunement level requirements for advanced skills (Lv 3, 5, 7, 8)
- Update SkillsTab UI to show attunement requirements
- Update store to validate attunement requirements before studying
This commit is contained in:
Z User
2026-03-28 06:57:02 +00:00
parent a0595e6077
commit 3c79e66b87
4 changed files with 164 additions and 73 deletions

View File

@@ -186,6 +186,21 @@ export function SkillsTab({ store }: SkillsTabProps) {
const tierDef = SKILL_EVOLUTION_PATHS[id]?.tiers.find(t => t.tier === currentTier);
const skillDisplayName = tierDef?.name || def.name;
// Check attunement requirements
let attunementMet = true;
let attunementReqText = '';
if (def.attunement) {
const attState = store.attunements?.[def.attunement];
const requiredLevel = def.attunementLevel || 1;
if (!attState?.active) {
attunementMet = false;
attunementReqText = `Requires ${def.attunement.charAt(0).toUpperCase() + def.attunement.slice(1)} attunement`;
} else if ((attState.level || 1) < requiredLevel) {
attunementMet = false;
attunementReqText = `Requires ${def.attunement.charAt(0).toUpperCase() + def.attunement.slice(1)} Lv.${requiredLevel}`;
}
}
// Check prerequisites
let prereqMet = true;
if (def.req) {
@@ -212,7 +227,7 @@ export function SkillsTab({ store }: SkillsTabProps) {
const cost = Math.floor(baseCost * costMult);
// Can start studying?
const canStudy = !maxed && prereqMet && store.rawMana >= cost && !isStudying;
const canStudy = !maxed && attunementMet && prereqMet && store.rawMana >= cost && !isStudying;
// Check for milestone upgrades
const milestoneInfo = hasMilestoneUpgrade(tieredSkillId, level, store.skillTiers || {}, store.skillUpgrades);
@@ -254,6 +269,11 @@ export function SkillsTab({ store }: SkillsTabProps) {
)}
</div>
<div className="text-xs text-gray-400 italic">{def.desc}{currentTier > 1 && ` (Tier ${currentTier}: ${fmtDec(tierMultiplier, 0)}x effect)`}</div>
{!attunementMet && attunementReqText && (
<div className="text-xs text-orange-400 mt-1">
🔒 {attunementReqText}
</div>
)}
{!prereqMet && def.req && (
<div className="text-xs text-red-400 mt-1">
Requires: {Object.entries(def.req).map(([r, rl]) => `${SKILLS_DEF[r]?.name} Lv.${rl}`).join(', ')}