Remove all skill system files - preparing for fresh design phase
Build and Publish Mana Loop Docker Image / build-and-publish (push) Failing after 32s

This commit is contained in:
2026-05-15 18:50:41 +02:00
parent 5cbe672b8f
commit 1a688394e4
27 changed files with 0 additions and 3750 deletions
-343
View File
@@ -1,343 +0,0 @@
// ─── Skill Store ──────────────────────────────────────────────────────────────
// Handles skills, upgrades, tiers, and study progress
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
import { SKILLS_DEF, getStudySpeedMultiplier, getStudyCostMultiplier } from '../constants';
import type { StudyTarget, SkillUpgradeChoice } from '../types';
import { SKILL_EVOLUTION_PATHS, getBaseSkillId } from '../skill-evolution';
import { useCombatStore } from './combatStore';
import { useManaStore } from './manaStore';
export interface SkillState {
// Skills
skills: Record<string, number>;
skillProgress: Record<string, number>; // Saved study progress for skills
skillUpgrades: Record<string, string[]>; // Selected upgrade IDs per skill
skillTiers: Record<string, number>; // Current tier for each base skill
paidStudySkills: Record<string, number>; // skillId -> level that was paid for
// Study
currentStudyTarget: StudyTarget | null;
parallelStudyTarget: StudyTarget | null;
// Actions - Skills
setSkillLevel: (skillId: string, level: number) => void;
incrementSkillLevel: (skillId: string) => void;
clearPaidStudySkill: (skillId: string) => void;
setPaidStudySkill: (skillId: string, level: number) => void;
// Actions - Study
startStudyingSkill: (skillId: string, rawMana: number) => { started: boolean; cost: number };
startStudyingSpell: (spellId: string, rawMana: number, studyTime: number) => { started: boolean; cost: number };
updateStudyProgress: (progressGain: number) => { completed: boolean; target: StudyTarget | null };
cancelStudy: (retentionBonus: number) => void;
setStudyTarget: (target: StudyTarget | null) => void;
setCurrentStudyTarget: (target: StudyTarget | null) => void;
// Actions - Upgrades
selectSkillUpgrade: (skillId: string, upgradeId: string) => void;
deselectSkillUpgrade: (skillId: string, upgradeId: string) => void;
commitSkillUpgrades: (skillId: string, upgradeIds: string[]) => void;
tierUpSkill: (skillId: string) => void;
// Computed
getSkillUpgradeChoices: (skillId: string, milestone: 5 | 10) => { available: SkillUpgradeChoice[]; selected: string[] };
// Reset
resetSkills: (
skills?: Record<string, number>,
skillUpgrades?: Record<string, string[]>,
skillTiers?: Record<string, number>
) => void;
}
export const useSkillStore = create<SkillState>()(
persist(
(set, get) => ({
skills: {},
skillProgress: {},
skillUpgrades: {},
skillTiers: {},
paidStudySkills: {},
currentStudyTarget: null,
parallelStudyTarget: null,
setSkillLevel: (skillId: string, level: number) => {
set((state) => ({
skills: { ...state.skills, [skillId]: level },
}));
},
incrementSkillLevel: (skillId: string) => {
set((state) => ({
skills: { ...state.skills, [skillId]: (state.skills[skillId] || 0) + 1 },
skillProgress: { ...state.skillProgress, [skillId]: 0 },
}));
},
clearPaidStudySkill: (skillId: string) => {
set((state) => {
const { [skillId]: _, ...remaining } = state.paidStudySkills;
return { paidStudySkills: remaining };
});
},
setPaidStudySkill: (skillId: string, level: number) => {
set((state) => ({
paidStudySkills: { ...state.paidStudySkills, [skillId]: level },
}));
},
startStudyingSkill: (skillId: string, rawMana: number) => {
const state = get();
const sk = SKILLS_DEF[skillId];
if (!sk) return { started: false, cost: 0 };
const currentLevel = state.skills[skillId] || 0;
if (currentLevel >= sk.max) return { started: false, cost: 0 };
// Check prerequisites
if (sk.req) {
for (const [r, rl] of Object.entries(sk.req)) {
if ((state.skills[r] || 0) < rl) return { started: false, cost: 0 };
}
}
// Check if already paid for this level
const paidForLevel = state.paidStudySkills[skillId];
const isAlreadyPaid = paidForLevel === currentLevel;
// Calculate cost
const costMult = getStudyCostMultiplier(state.skills);
const cost = Math.floor(sk.base * (currentLevel + 1) * costMult);
if (!isAlreadyPaid && rawMana < cost) return { started: false, cost };
// Get saved progress
const savedProgress = state.skillProgress[skillId] || 0;
// Mark as paid (this is done here so resume works for free)
const newPaidSkills = isAlreadyPaid
? state.paidStudySkills
: { ...state.paidStudySkills, [skillId]: currentLevel };
// Start studying
set({
paidStudySkills: newPaidSkills,
currentStudyTarget: {
type: 'skill',
id: skillId,
progress: savedProgress,
required: sk.studyTime,
},
});
useCombatStore.getState().setAction('study');
if (!isAlreadyPaid && cost > 0) {
useManaStore.getState().spendRawMana(cost);
}
return { started: true, cost: isAlreadyPaid ? 0 : cost };
},
startStudyingSpell: (spellId: string, rawMana: number, studyTime: number) => {
const state = get();
// Start studying the spell
set({
currentStudyTarget: {
type: 'spell',
id: spellId,
progress: 0,
required: studyTime,
},
});
useCombatStore.getState().setAction('study');
// Spell study has no mana cost upfront - cost is paid via study time
return { started: true, cost: 0 };
},
updateStudyProgress: (progressGain: number) => {
const state = get();
if (!state.currentStudyTarget) return { completed: false, target: null };
const newProgress = state.currentStudyTarget.progress + progressGain;
const completed = newProgress >= state.currentStudyTarget.required;
const newTarget = completed ? null : {
...state.currentStudyTarget,
progress: newProgress,
};
set({ currentStudyTarget: newTarget });
return {
completed,
target: completed ? state.currentStudyTarget : null
};
},
cancelStudy: (retentionBonus: number) => {
const state = get();
if (!state.currentStudyTarget) return;
// Save progress with retention bonus
const savedProgress = Math.min(
state.currentStudyTarget.progress,
state.currentStudyTarget.required * retentionBonus
);
if (state.currentStudyTarget.type === 'skill') {
set({
currentStudyTarget: null,
skillProgress: {
...state.skillProgress,
[state.currentStudyTarget.id]: savedProgress,
},
});
} else {
set({ currentStudyTarget: null });
}
},
setStudyTarget: (target: StudyTarget | null) => {
set({ currentStudyTarget: target });
},
setCurrentStudyTarget: (target: StudyTarget | null) => {
set({ currentStudyTarget: target });
},
selectSkillUpgrade: (skillId: string, upgradeId: string) => {
set((state) => {
const current = state.skillUpgrades?.[skillId] || [];
if (current.includes(upgradeId)) return state;
if (current.length >= 2) return state; // Max 2 upgrades per milestone
return {
skillUpgrades: {
...state.skillUpgrades,
[skillId]: [...current, upgradeId],
},
};
});
},
deselectSkillUpgrade: (skillId: string, upgradeId: string) => {
set((state) => {
const current = state.skillUpgrades?.[skillId] || [];
return {
skillUpgrades: {
...state.skillUpgrades,
[skillId]: current.filter(id => id !== upgradeId),
},
};
});
},
commitSkillUpgrades: (skillId: string, upgradeIds: string[]) => {
set((state) => {
// Determine which milestone we're committing
const isL5 = upgradeIds.some(id => id.includes('_l5'));
const isL10 = upgradeIds.some(id => id.includes('_l10'));
const existingUpgrades = state.skillUpgrades?.[skillId] || [];
let preservedUpgrades: string[];
if (isL5) {
preservedUpgrades = existingUpgrades.filter(id => id.includes('_l10'));
} else if (isL10) {
preservedUpgrades = existingUpgrades.filter(id => id.includes('_l5'));
} else {
preservedUpgrades = [];
}
const mergedUpgrades = [...preservedUpgrades, ...upgradeIds];
return {
skillUpgrades: {
...state.skillUpgrades,
[skillId]: mergedUpgrades,
},
};
});
},
tierUpSkill: (skillId: string) => {
const state = get();
const baseSkillId = skillId.includes('_t') ? skillId.split('_t')[0] : skillId;
const currentTier = state.skillTiers?.[baseSkillId] || 1;
const nextTier = currentTier + 1;
if (nextTier > 5) return;
const nextTierSkillId = `${baseSkillId}_t${nextTier}`;
const currentLevel = state.skills[skillId] || 0;
set({
skillTiers: {
...state.skillTiers,
[baseSkillId]: nextTier,
},
skills: {
...state.skills,
[nextTierSkillId]: currentLevel,
[skillId]: 0,
},
skillUpgrades: {
...state.skillUpgrades,
[nextTierSkillId]: [],
},
});
},
getSkillUpgradeChoices: (skillId: string, milestone: 5 | 10) => {
const state = get();
const baseSkillId = getBaseSkillId(skillId);
const tier = state.skillTiers?.[baseSkillId] || 1;
const path = SKILL_EVOLUTION_PATHS[baseSkillId];
if (!path) return { available: [], selected: [] };
const tierDef = path.tiers.find(t => t.tier === tier);
if (!tierDef) return { available: [], selected: [] };
const available = tierDef.upgrades.filter(u => u.milestone === milestone);
const selected = state.skillUpgrades?.[skillId]?.filter(id =>
available.some(u => u.id === id)
) || [];
return { available, selected };
},
resetSkills: (
skills: Record<string, number> = {},
skillUpgrades: Record<string, string[]> = {},
skillTiers: Record<string, number> = {}
) => {
set({
skills,
skillProgress: {},
skillUpgrades,
skillTiers,
paidStudySkills: {},
currentStudyTarget: null,
parallelStudyTarget: null,
});
},
}),
{
name: 'mana-loop-skills',
partialize: (state) => ({
skills: state.skills,
skillProgress: state.skillProgress,
skillUpgrades: state.skillUpgrades,
skillTiers: state.skillTiers,
paidStudySkills: state.paidStudySkills,
}),
}
)
);