Remove movement speed, fix golemancy, cleanup
All checks were successful
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m56s
All checks were successful
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m56s
- Remove movement speed references (spire_runner, swift_descent enchantments) - Remove slow effect from Mud Golem variant (changed to drown effect) - Delete unused attunements.ts file (legacy code) - Add max golem limit: 1 per Fabricator attunement level - Add max 1 golem of each type restriction - Display mana/hr and damage/hr in golemancy UI - Display active golem limit in header - Show special effects for golem variants - Keep expeditious_retreat enchantment for teleporting down floors 🤖 Generated with [Claude Code](https://claude.ai/code)
This commit is contained in:
@@ -984,6 +984,18 @@ export function CraftingTab({ store }: CraftingTabProps) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Additional Stats */}
|
||||||
|
<div className="grid grid-cols-2 gap-2 text-xs mb-2 p-2 bg-gray-900/50 rounded">
|
||||||
|
<div className="flex justify-between">
|
||||||
|
<span className="text-gray-400">DMG/hr:</span>
|
||||||
|
<span className="text-red-300 font-semibold">{golemDef.baseDamage * golemDef.attackSpeed}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-between">
|
||||||
|
<span className="text-gray-400">Mana/hr:</span>
|
||||||
|
<span className="text-blue-300 font-semibold">{golemDef.drainRate} {elementDef?.name || golemDef.element}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
className="w-full"
|
className="w-full"
|
||||||
size="sm"
|
size="sm"
|
||||||
@@ -1014,10 +1026,10 @@ export function CraftingTab({ store }: CraftingTabProps) {
|
|||||||
<CardTitle className="text-amber-400 text-sm flex items-center justify-between">
|
<CardTitle className="text-amber-400 text-sm flex items-center justify-between">
|
||||||
<span className="flex items-center gap-2">
|
<span className="flex items-center gap-2">
|
||||||
<span className="text-lg">⚡</span>
|
<span className="text-lg">⚡</span>
|
||||||
Active Golems ({activeGolems.length})
|
Active Golems ({activeGolems.length}/{Math.max(1, store.attunements?.fabricator?.level || 0)})
|
||||||
</span>
|
</span>
|
||||||
{golemancySkill >= 1 && (
|
{golemancySkill >= 1 && (
|
||||||
<span className="text-xs text-gray-400">Duration: {golemDuration} floors</span>
|
<span className="text-xs text-gray-400">Duration: {golemDuration} floors | Max 1 per Fabricator level</span>
|
||||||
)}
|
)}
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
@@ -1089,7 +1101,32 @@ export function CraftingTab({ store }: CraftingTabProps) {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="text-xs text-gray-400">
|
{/* Stats */}
|
||||||
|
<div className="grid grid-cols-2 gap-2 text-xs mt-2 pt-2 border-t border-gray-700">
|
||||||
|
<div>
|
||||||
|
<span className="text-gray-400">Mana/hr:</span>{' '}
|
||||||
|
<span className="text-blue-300">{golemDef?.drainRate || 0} {ELEMENTS[golemDef?.requiredManaType || 'earth']?.name || 'mana'}</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span className="text-gray-400">DMG/hr:</span>{' '}
|
||||||
|
<span className="text-red-300">
|
||||||
|
{(() => {
|
||||||
|
const dmg = (variantDef?.damageMultiplier || 1) * (golemDef?.baseDamage || 0);
|
||||||
|
const speed = golemDef?.attackSpeed || 1;
|
||||||
|
return fmt(dmg * speed);
|
||||||
|
})()}
|
||||||
|
<span className="text-gray-500 text-xs">({golemDef?.attackSpeed || 1}×{golemDef?.baseDamage || 0})</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{variantDef && (
|
||||||
|
<div className="text-xs mt-2 p-1.5 bg-gray-900/50 rounded">
|
||||||
|
<span className="text-purple-400">Effect:</span> <span className="text-gray-300 capitalize">{variantDef.effect}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="text-xs text-gray-400 mt-2">
|
||||||
<span className="text-green-400">Total Damage:</span> {fmt(golem.damageDealt)}
|
<span className="text-green-400">Total Damage:</span> {fmt(golem.damageDealt)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,567 +0,0 @@
|
|||||||
// ─── Attunement System ─────────────────────────────────────────────────────────
|
|
||||||
// Attunements are powerful magical bonds tied to specific body locations
|
|
||||||
// Each grants a unique capability, primary mana type, and skill tree
|
|
||||||
|
|
||||||
import type { SkillDef } from './types';
|
|
||||||
|
|
||||||
// ─── Body Slots ───────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
export type AttunementSlot =
|
|
||||||
| 'rightHand'
|
|
||||||
| 'leftHand'
|
|
||||||
| 'head'
|
|
||||||
| 'back'
|
|
||||||
| 'chest'
|
|
||||||
| 'leftLeg'
|
|
||||||
| 'rightLeg';
|
|
||||||
|
|
||||||
export const ATTUNEMENT_SLOTS: AttunementSlot[] = [
|
|
||||||
'rightHand',
|
|
||||||
'leftHand',
|
|
||||||
'head',
|
|
||||||
'back',
|
|
||||||
'chest',
|
|
||||||
'leftLeg',
|
|
||||||
'rightLeg',
|
|
||||||
];
|
|
||||||
|
|
||||||
// Slot display names
|
|
||||||
export const ATTUNEMENT_SLOT_NAMES: Record<AttunementSlot, string> = {
|
|
||||||
rightHand: 'Right Hand',
|
|
||||||
leftHand: 'Left Hand',
|
|
||||||
head: 'Head',
|
|
||||||
back: 'Back',
|
|
||||||
chest: 'Heart',
|
|
||||||
leftLeg: 'Left Leg',
|
|
||||||
rightLeg: 'Right Leg',
|
|
||||||
};
|
|
||||||
|
|
||||||
// ─── Mana Types ───────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
export type ManaType =
|
|
||||||
// Primary mana types from attunements
|
|
||||||
| 'transference' // Enchanter - moving/enchanting
|
|
||||||
| 'form' // Caster - shaping spells
|
|
||||||
| 'vision' // Seer - perception/revelation
|
|
||||||
| 'barrier' // Warden - protection/defense
|
|
||||||
| 'flow' // Strider - movement/swiftness
|
|
||||||
| 'stability' // Anchor - grounding/endurance
|
|
||||||
// Guardian pact types (Invoker)
|
|
||||||
| 'fire'
|
|
||||||
| 'water'
|
|
||||||
| 'earth'
|
|
||||||
| 'air'
|
|
||||||
| 'light'
|
|
||||||
| 'dark'
|
|
||||||
| 'life'
|
|
||||||
| 'death'
|
|
||||||
// Raw mana
|
|
||||||
| 'raw';
|
|
||||||
|
|
||||||
// ─── Attunement Types ─────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
export type AttunementType =
|
|
||||||
| 'enchanter'
|
|
||||||
| 'caster'
|
|
||||||
| 'seer'
|
|
||||||
| 'warden'
|
|
||||||
| 'invoker'
|
|
||||||
| 'strider'
|
|
||||||
| 'anchor';
|
|
||||||
|
|
||||||
// ─── Attunement Definition ────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
export interface AttunementDef {
|
|
||||||
id: AttunementType;
|
|
||||||
name: string;
|
|
||||||
slot: AttunementSlot;
|
|
||||||
description: string;
|
|
||||||
capability: string; // What this attunement unlocks
|
|
||||||
primaryManaType: ManaType | null; // null for Invoker (uses guardian types)
|
|
||||||
rawManaRegen: number; // Base raw mana regen bonus
|
|
||||||
autoConvertRate: number; // Raw mana -> primary mana per hour
|
|
||||||
skills: Record<string, SkillDef>; // Attunement-specific skills
|
|
||||||
icon: string; // Lucide icon name
|
|
||||||
color: string; // Theme color
|
|
||||||
}
|
|
||||||
|
|
||||||
// ─── Attunement State ─────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
export interface AttunementState {
|
|
||||||
unlocked: boolean;
|
|
||||||
level: number; // Attunement level (from challenges)
|
|
||||||
manaPool: number; // Current primary mana
|
|
||||||
maxMana: number; // Max primary mana pool
|
|
||||||
}
|
|
||||||
|
|
||||||
// ─── Attunement Definitions ───────────────────────────────────────────────────
|
|
||||||
|
|
||||||
export const ATTUNEMENTS: Record<AttunementType, AttunementDef> = {
|
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
|
||||||
// ENCHANTER - Right Hand
|
|
||||||
// The starting attunement. Grants access to enchanting and transference magic.
|
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
|
||||||
enchanter: {
|
|
||||||
id: 'enchanter',
|
|
||||||
name: 'Enchanter',
|
|
||||||
slot: 'rightHand',
|
|
||||||
description: 'Channel mana through your right hand to imbue equipment with magical properties.',
|
|
||||||
capability: 'Unlock enchanting. Apply enchantments using transference mana.',
|
|
||||||
primaryManaType: 'transference',
|
|
||||||
rawManaRegen: 0.5,
|
|
||||||
autoConvertRate: 0.2, // 0.2 transference per hour per raw regen
|
|
||||||
icon: 'Wand2',
|
|
||||||
color: '#8B5CF6', // Purple
|
|
||||||
skills: {
|
|
||||||
// Core enchanting skills
|
|
||||||
enchanting: {
|
|
||||||
name: 'Enchanting',
|
|
||||||
desc: 'Apply magical effects to equipment',
|
|
||||||
cat: 'enchanter',
|
|
||||||
max: 10,
|
|
||||||
base: 100,
|
|
||||||
studyTime: 8,
|
|
||||||
},
|
|
||||||
efficientEnchant: {
|
|
||||||
name: 'Efficient Enchanting',
|
|
||||||
desc: 'Reduce enchantment mana costs',
|
|
||||||
cat: 'enchanter',
|
|
||||||
max: 5,
|
|
||||||
base: 200,
|
|
||||||
studyTime: 12,
|
|
||||||
req: { enchanting: 3 },
|
|
||||||
},
|
|
||||||
disenchanting: {
|
|
||||||
name: 'Disenchanting',
|
|
||||||
desc: 'Remove enchantments and recover some mana',
|
|
||||||
cat: 'enchanter',
|
|
||||||
max: 5,
|
|
||||||
base: 150,
|
|
||||||
studyTime: 10,
|
|
||||||
req: { enchanting: 2 },
|
|
||||||
},
|
|
||||||
enchantSpeed: {
|
|
||||||
name: 'Swift Enchanting',
|
|
||||||
desc: 'Faster enchantment application',
|
|
||||||
cat: 'enchanter',
|
|
||||||
max: 5,
|
|
||||||
base: 175,
|
|
||||||
studyTime: 10,
|
|
||||||
req: { enchanting: 2 },
|
|
||||||
},
|
|
||||||
transferenceMastery: {
|
|
||||||
name: 'Transference Mastery',
|
|
||||||
desc: 'Increased transference mana pool and regen',
|
|
||||||
cat: 'enchanter',
|
|
||||||
max: 10,
|
|
||||||
base: 250,
|
|
||||||
studyTime: 15,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
|
||||||
// CASTER - Left Hand
|
|
||||||
// Shapes raw mana into spell patterns. Enhanced spell damage.
|
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
|
||||||
caster: {
|
|
||||||
id: 'caster',
|
|
||||||
name: 'Caster',
|
|
||||||
slot: 'leftHand',
|
|
||||||
description: 'Shape mana into devastating spell patterns through your left hand.',
|
|
||||||
capability: 'Form mana shaping. +25% spell damage bonus.',
|
|
||||||
primaryManaType: 'form',
|
|
||||||
rawManaRegen: 0.3,
|
|
||||||
autoConvertRate: 0.15,
|
|
||||||
icon: 'Hand',
|
|
||||||
color: '#3B82F6', // Blue
|
|
||||||
skills: {
|
|
||||||
spellShaping: {
|
|
||||||
name: 'Spell Shaping',
|
|
||||||
desc: 'Increase spell damage and efficiency',
|
|
||||||
cat: 'caster',
|
|
||||||
max: 10,
|
|
||||||
base: 100,
|
|
||||||
studyTime: 8,
|
|
||||||
},
|
|
||||||
quickCast: {
|
|
||||||
name: 'Quick Cast',
|
|
||||||
desc: 'Faster spell casting speed',
|
|
||||||
cat: 'caster',
|
|
||||||
max: 10,
|
|
||||||
base: 120,
|
|
||||||
studyTime: 8,
|
|
||||||
},
|
|
||||||
spellEcho: {
|
|
||||||
name: 'Spell Echo',
|
|
||||||
desc: 'Chance to cast spells twice',
|
|
||||||
cat: 'caster',
|
|
||||||
max: 5,
|
|
||||||
base: 300,
|
|
||||||
studyTime: 15,
|
|
||||||
req: { spellShaping: 5 },
|
|
||||||
},
|
|
||||||
formMastery: {
|
|
||||||
name: 'Form Mastery',
|
|
||||||
desc: 'Increased form mana pool and regen',
|
|
||||||
cat: 'caster',
|
|
||||||
max: 10,
|
|
||||||
base: 250,
|
|
||||||
studyTime: 15,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
|
||||||
// SEER - Head
|
|
||||||
// Perception and revelation. Critical hit bonus and weakness detection.
|
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
|
||||||
seer: {
|
|
||||||
id: 'seer',
|
|
||||||
name: 'Seer',
|
|
||||||
slot: 'head',
|
|
||||||
description: 'See beyond the veil. Reveal hidden truths and enemy weaknesses.',
|
|
||||||
capability: 'Reveal floor weaknesses. +20% critical hit chance.',
|
|
||||||
primaryManaType: 'vision',
|
|
||||||
rawManaRegen: 0.2,
|
|
||||||
autoConvertRate: 0.1,
|
|
||||||
icon: 'Eye',
|
|
||||||
color: '#F59E0B', // Amber
|
|
||||||
skills: {
|
|
||||||
insight: {
|
|
||||||
name: 'Insight',
|
|
||||||
desc: 'Increased critical hit chance',
|
|
||||||
cat: 'seer',
|
|
||||||
max: 10,
|
|
||||||
base: 100,
|
|
||||||
studyTime: 8,
|
|
||||||
},
|
|
||||||
revealWeakness: {
|
|
||||||
name: 'Reveal Weakness',
|
|
||||||
desc: 'Show enemy elemental weaknesses',
|
|
||||||
cat: 'seer',
|
|
||||||
max: 5,
|
|
||||||
base: 200,
|
|
||||||
studyTime: 12,
|
|
||||||
},
|
|
||||||
criticalMastery: {
|
|
||||||
name: 'Critical Mastery',
|
|
||||||
desc: 'Increased critical damage multiplier',
|
|
||||||
cat: 'seer',
|
|
||||||
max: 5,
|
|
||||||
base: 250,
|
|
||||||
studyTime: 15,
|
|
||||||
req: { insight: 5 },
|
|
||||||
},
|
|
||||||
visionMastery: {
|
|
||||||
name: 'Vision Mastery',
|
|
||||||
desc: 'Increased vision mana pool and regen',
|
|
||||||
cat: 'seer',
|
|
||||||
max: 10,
|
|
||||||
base: 250,
|
|
||||||
studyTime: 15,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
|
||||||
// WARDEN - Back
|
|
||||||
// Mana efficiency and resource management (no player health mechanics)
|
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
|
||||||
warden: {
|
|
||||||
id: 'warden',
|
|
||||||
name: 'Warden',
|
|
||||||
slot: 'back',
|
|
||||||
description: 'Master the flow of mana. Reduce costs and extend your reserves.',
|
|
||||||
capability: 'Reduced mana costs. Extended mana reserves.',
|
|
||||||
primaryManaType: 'barrier',
|
|
||||||
rawManaRegen: 0.25,
|
|
||||||
autoConvertRate: 0.12,
|
|
||||||
icon: 'Shield',
|
|
||||||
color: '#10B981', // Green
|
|
||||||
skills: {
|
|
||||||
manaEfficiency: {
|
|
||||||
name: 'Mana Efficiency',
|
|
||||||
desc: 'Reduced mana costs for all actions',
|
|
||||||
cat: 'warden',
|
|
||||||
max: 10,
|
|
||||||
base: 100,
|
|
||||||
studyTime: 8,
|
|
||||||
},
|
|
||||||
manaReserves: {
|
|
||||||
name: 'Mana Reserves',
|
|
||||||
desc: 'Increased max mana pool',
|
|
||||||
cat: 'warden',
|
|
||||||
max: 10,
|
|
||||||
base: 150,
|
|
||||||
studyTime: 10,
|
|
||||||
},
|
|
||||||
manaRetention: {
|
|
||||||
name: 'Mana Retention',
|
|
||||||
desc: 'Reduced mana loss on loop reset',
|
|
||||||
cat: 'warden',
|
|
||||||
max: 5,
|
|
||||||
base: 300,
|
|
||||||
studyTime: 15,
|
|
||||||
req: { manaEfficiency: 5 },
|
|
||||||
},
|
|
||||||
barrierMastery: {
|
|
||||||
name: 'Barrier Mastery',
|
|
||||||
desc: 'Increased barrier mana pool and regen',
|
|
||||||
cat: 'warden',
|
|
||||||
max: 10,
|
|
||||||
base: 250,
|
|
||||||
studyTime: 15,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
|
||||||
// INVOKER - Chest/Heart
|
|
||||||
// Pact with guardians. No primary mana - uses guardian elemental types.
|
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
|
||||||
invoker: {
|
|
||||||
id: 'invoker',
|
|
||||||
name: 'Invoker',
|
|
||||||
slot: 'chest',
|
|
||||||
description: 'Form pacts with spire guardians and channel their elemental power.',
|
|
||||||
capability: 'Pact with guardians. Gain mana types from pacted guardians.',
|
|
||||||
primaryManaType: null, // Uses guardian types instead
|
|
||||||
rawManaRegen: 0.4,
|
|
||||||
autoConvertRate: 0, // No auto-convert; mana comes from guardian pacts
|
|
||||||
icon: 'Heart',
|
|
||||||
color: '#EF4444', // Red
|
|
||||||
skills: {
|
|
||||||
pactMaking: {
|
|
||||||
name: 'Pact Making',
|
|
||||||
desc: 'Form stronger pacts with guardians',
|
|
||||||
cat: 'invoker',
|
|
||||||
max: 10,
|
|
||||||
base: 100,
|
|
||||||
studyTime: 8,
|
|
||||||
},
|
|
||||||
guardianChannel: {
|
|
||||||
name: 'Guardian Channeling',
|
|
||||||
desc: 'Channel guardian powers more effectively',
|
|
||||||
cat: 'invoker',
|
|
||||||
max: 10,
|
|
||||||
base: 150,
|
|
||||||
studyTime: 10,
|
|
||||||
},
|
|
||||||
elementalBurst: {
|
|
||||||
name: 'Elemental Burst',
|
|
||||||
desc: 'Unleash stored guardian energy',
|
|
||||||
cat: 'invoker',
|
|
||||||
max: 5,
|
|
||||||
base: 300,
|
|
||||||
studyTime: 15,
|
|
||||||
req: { pactMaking: 5, guardianChannel: 3 },
|
|
||||||
},
|
|
||||||
soulResonance: {
|
|
||||||
name: 'Soul Resonance',
|
|
||||||
desc: 'Deep bond with pacted guardians',
|
|
||||||
cat: 'invoker',
|
|
||||||
max: 5,
|
|
||||||
base: 400,
|
|
||||||
studyTime: 20,
|
|
||||||
req: { pactMaking: 8 },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
|
||||||
// STRIDER - Left Leg
|
|
||||||
// Movement and swiftness. Attack speed and mobility.
|
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
|
||||||
strider: {
|
|
||||||
id: 'strider',
|
|
||||||
name: 'Strider',
|
|
||||||
slot: 'leftLeg',
|
|
||||||
description: 'Move with supernatural speed and grace.',
|
|
||||||
capability: 'Enhanced mobility. +15% attack speed.',
|
|
||||||
primaryManaType: 'flow',
|
|
||||||
rawManaRegen: 0.3,
|
|
||||||
autoConvertRate: 0.15,
|
|
||||||
icon: 'Zap',
|
|
||||||
color: '#06B6D4', // Cyan
|
|
||||||
skills: {
|
|
||||||
swiftness: {
|
|
||||||
name: 'Swiftness',
|
|
||||||
desc: 'Increased attack and movement speed',
|
|
||||||
cat: 'strider',
|
|
||||||
max: 10,
|
|
||||||
base: 100,
|
|
||||||
studyTime: 8,
|
|
||||||
},
|
|
||||||
evasive: {
|
|
||||||
name: 'Fluid Motion',
|
|
||||||
desc: 'Increased combo duration before decay',
|
|
||||||
cat: 'strider',
|
|
||||||
max: 5,
|
|
||||||
base: 200,
|
|
||||||
studyTime: 12,
|
|
||||||
},
|
|
||||||
momentum: {
|
|
||||||
name: 'Momentum',
|
|
||||||
desc: 'Build speed over consecutive attacks',
|
|
||||||
cat: 'strider',
|
|
||||||
max: 5,
|
|
||||||
base: 250,
|
|
||||||
studyTime: 15,
|
|
||||||
req: { swiftness: 5 },
|
|
||||||
},
|
|
||||||
flowMastery: {
|
|
||||||
name: 'Flow Mastery',
|
|
||||||
desc: 'Increased flow mana pool and regen',
|
|
||||||
cat: 'strider',
|
|
||||||
max: 10,
|
|
||||||
base: 250,
|
|
||||||
studyTime: 15,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
|
||||||
// ANCHOR - Right Leg
|
|
||||||
// Stability and endurance. Max mana and knockback resistance.
|
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
|
||||||
anchor: {
|
|
||||||
id: 'anchor',
|
|
||||||
name: 'Anchor',
|
|
||||||
slot: 'rightLeg',
|
|
||||||
description: 'Stand firm against any force. Your foundation is unshakeable.',
|
|
||||||
capability: 'Increased stability. +100 max mana.',
|
|
||||||
primaryManaType: 'stability',
|
|
||||||
rawManaRegen: 0.35,
|
|
||||||
autoConvertRate: 0.18,
|
|
||||||
icon: 'Mountain',
|
|
||||||
color: '#78716C', // Stone gray
|
|
||||||
skills: {
|
|
||||||
grounding: {
|
|
||||||
name: 'Grounding',
|
|
||||||
desc: 'Increased max mana and stability',
|
|
||||||
cat: 'anchor',
|
|
||||||
max: 10,
|
|
||||||
base: 100,
|
|
||||||
studyTime: 8,
|
|
||||||
},
|
|
||||||
endurance: {
|
|
||||||
name: 'Endurance',
|
|
||||||
desc: 'Reduced mana costs when below 50% mana',
|
|
||||||
cat: 'anchor',
|
|
||||||
max: 5,
|
|
||||||
base: 200,
|
|
||||||
studyTime: 12,
|
|
||||||
},
|
|
||||||
ironWill: {
|
|
||||||
name: 'Iron Will',
|
|
||||||
desc: 'Prevent mana drain effects',
|
|
||||||
cat: 'anchor',
|
|
||||||
max: 5,
|
|
||||||
base: 250,
|
|
||||||
studyTime: 15,
|
|
||||||
req: { grounding: 5 },
|
|
||||||
},
|
|
||||||
stabilityMastery: {
|
|
||||||
name: 'Stability Mastery',
|
|
||||||
desc: 'Increased stability mana pool and regen',
|
|
||||||
cat: 'anchor',
|
|
||||||
max: 10,
|
|
||||||
base: 250,
|
|
||||||
studyTime: 15,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// ─── Helper Functions ─────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the attunement for a specific body slot
|
|
||||||
*/
|
|
||||||
export function getAttunementForSlot(slot: AttunementSlot): AttunementDef | undefined {
|
|
||||||
return Object.values(ATTUNEMENTS).find(a => a.slot === slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the starting attunement (Enchanter - right hand)
|
|
||||||
*/
|
|
||||||
export function getStartingAttunement(): AttunementDef {
|
|
||||||
return ATTUNEMENTS.enchanter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if an attunement is unlocked for the player
|
|
||||||
*/
|
|
||||||
export function isAttunementUnlocked(
|
|
||||||
attunementStates: Record<AttunementType, AttunementState>,
|
|
||||||
attunementType: AttunementType
|
|
||||||
): boolean {
|
|
||||||
return attunementStates[attunementType]?.unlocked ?? false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get total raw mana regen from all unlocked attunements
|
|
||||||
*/
|
|
||||||
export function getTotalAttunementRegen(
|
|
||||||
attunementStates: Record<AttunementType, AttunementState>
|
|
||||||
): number {
|
|
||||||
let total = 0;
|
|
||||||
for (const [type, state] of Object.entries(attunementStates)) {
|
|
||||||
if (state.unlocked) {
|
|
||||||
const def = ATTUNEMENTS[type as AttunementType];
|
|
||||||
if (def) {
|
|
||||||
total += def.rawManaRegen * (1 + state.level * 0.1); // +10% per level
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get mana type display name
|
|
||||||
*/
|
|
||||||
export function getManaTypeName(type: ManaType): string {
|
|
||||||
const names: Record<ManaType, string> = {
|
|
||||||
raw: 'Raw Mana',
|
|
||||||
transference: 'Transference',
|
|
||||||
form: 'Form',
|
|
||||||
vision: 'Vision',
|
|
||||||
barrier: 'Barrier',
|
|
||||||
flow: 'Flow',
|
|
||||||
stability: 'Stability',
|
|
||||||
fire: 'Fire',
|
|
||||||
water: 'Water',
|
|
||||||
earth: 'Earth',
|
|
||||||
air: 'Air',
|
|
||||||
light: 'Light',
|
|
||||||
dark: 'Dark',
|
|
||||||
life: 'Life',
|
|
||||||
death: 'Death',
|
|
||||||
};
|
|
||||||
return names[type] || type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get mana type color
|
|
||||||
*/
|
|
||||||
export function getManaTypeColor(type: ManaType): string {
|
|
||||||
const colors: Record<ManaType, string> = {
|
|
||||||
raw: '#A78BFA', // Light purple
|
|
||||||
transference: '#8B5CF6', // Purple
|
|
||||||
form: '#3B82F6', // Blue
|
|
||||||
vision: '#F59E0B', // Amber
|
|
||||||
barrier: '#10B981', // Green
|
|
||||||
flow: '#06B6D4', // Cyan
|
|
||||||
stability: '#78716C', // Stone
|
|
||||||
fire: '#EF4444', // Red
|
|
||||||
water: '#3B82F6', // Blue
|
|
||||||
earth: '#A16207', // Brown
|
|
||||||
air: '#94A3B8', // Slate
|
|
||||||
light: '#FCD34D', // Yellow
|
|
||||||
dark: '#6B7280', // Gray
|
|
||||||
life: '#22C55E', // Green
|
|
||||||
death: '#7C3AED', // Violet
|
|
||||||
};
|
|
||||||
return colors[type] || '#A78BFA';
|
|
||||||
}
|
|
||||||
@@ -1130,9 +1130,9 @@ export const GOLEM_VARIANTS: Record<string, {
|
|||||||
baseGolem: 'earthGolem',
|
baseGolem: 'earthGolem',
|
||||||
requiredElement: 'water',
|
requiredElement: 'water',
|
||||||
name: 'Mud Golem',
|
name: 'Mud Golem',
|
||||||
desc: 'A viscous, slowing golem that entraps enemies.',
|
desc: 'A viscous golem that suffocates enemies in clinging mud.',
|
||||||
damageMultiplier: 1.2,
|
damageMultiplier: 1.2,
|
||||||
effect: 'slow',
|
effect: 'drown',
|
||||||
},
|
},
|
||||||
|
|
||||||
// Metal Golem + Fire = Forge Golem
|
// Metal Golem + Fire = Forge Golem
|
||||||
|
|||||||
@@ -583,26 +583,6 @@ export const ENCHANTMENT_EFFECTS: Record<string, EnchantmentEffectDef> = {
|
|||||||
allowedEquipmentCategories: LEGS_ONLY,
|
allowedEquipmentCategories: LEGS_ONLY,
|
||||||
effect: { type: 'special', specialId: 'expeditiousRetreat' }
|
effect: { type: 'special', specialId: 'expeditiousRetreat' }
|
||||||
},
|
},
|
||||||
swift_descent: {
|
|
||||||
id: 'swift_descent',
|
|
||||||
name: 'Swift Descent',
|
|
||||||
description: '+20% faster floor descent when exiting spire',
|
|
||||||
category: 'utility',
|
|
||||||
baseCapacityCost: 30,
|
|
||||||
maxStacks: 3,
|
|
||||||
allowedEquipmentCategories: LEGS_ONLY,
|
|
||||||
effect: { type: 'bonus', stat: 'descentSpeed', value: 20 }
|
|
||||||
},
|
|
||||||
spire_runner: {
|
|
||||||
id: 'spire_runner',
|
|
||||||
name: 'Spire Runner',
|
|
||||||
description: '+10% movement speed in spire (faster floor transitions)',
|
|
||||||
category: 'utility',
|
|
||||||
baseCapacityCost: 25,
|
|
||||||
maxStacks: 4,
|
|
||||||
allowedEquipmentCategories: ['legs', 'feet'],
|
|
||||||
effect: { type: 'multiplier', stat: 'spireSpeed', value: 1.10 }
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ─── Helper Functions ────────────────────────────────────────────────────────────
|
// ─── Helper Functions ────────────────────────────────────────────────────────────
|
||||||
|
|||||||
@@ -1970,9 +1970,14 @@ export const useGameStore = create<GameStore>()(
|
|||||||
const elem = state.elements[manaType];
|
const elem = state.elements[manaType];
|
||||||
if (!elem?.unlocked || elem.current < golemDef.summonCost) return false;
|
if (!elem?.unlocked || elem.current < golemDef.summonCost) return false;
|
||||||
|
|
||||||
// Check if we already have this type of golem active (one of each type)
|
// Check if we already have this type of golem active (max 1 of each type)
|
||||||
if (state.activeGolems.some(g => g.golemId === golemId)) return false;
|
if (state.activeGolems.some(g => g.golemId === golemId)) return false;
|
||||||
|
|
||||||
|
// Check max golem limit: 1 per Fabricator attunement level
|
||||||
|
const fabricatorLevel = state.attunements?.fabricator?.level || 0;
|
||||||
|
const maxGolems = Math.max(1, fabricatorLevel); // 1 golem per fabricator level, minimum 1
|
||||||
|
if (state.activeGolems.length >= maxGolems) return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -1988,8 +1993,13 @@ export const useGameStore = create<GameStore>()(
|
|||||||
if (!elem?.unlocked || elem.current < golemDef.summonCost) return;
|
if (!elem?.unlocked || elem.current < golemDef.summonCost) return;
|
||||||
if (state.activeGolems.some(g => g.golemId === golemId)) return;
|
if (state.activeGolems.some(g => g.golemId === golemId)) return;
|
||||||
|
|
||||||
|
// Check max golem limit
|
||||||
|
const fabricatorLevel = state.attunements?.fabricator?.level || 0;
|
||||||
|
const maxGolems = Math.max(1, fabricatorLevel);
|
||||||
|
if (state.activeGolems.length >= maxGolems) return;
|
||||||
|
|
||||||
// Deduct mana cost
|
// Deduct mana cost
|
||||||
const duration = Math.min(10, 1 + (state.attunements?.fabricator?.level || 0));
|
const duration = Math.min(10, 1 + fabricatorLevel);
|
||||||
const maxHP = golemDef.baseHP * (1 + (state.skills.golemVitality || 0) * 0.2);
|
const maxHP = golemDef.baseHP * (1 + (state.skills.golemVitality || 0) * 0.2);
|
||||||
const hasGolemancyMaster = state.skills.golemancyMaster === 1;
|
const hasGolemancyMaster = state.skills.golemancyMaster === 1;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user