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>
|
||||
|
||||
{/* 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
|
||||
className="w-full"
|
||||
size="sm"
|
||||
@@ -1014,10 +1026,10 @@ export function CraftingTab({ store }: CraftingTabProps) {
|
||||
<CardTitle className="text-amber-400 text-sm flex items-center justify-between">
|
||||
<span className="flex items-center gap-2">
|
||||
<span className="text-lg">⚡</span>
|
||||
Active Golems ({activeGolems.length})
|
||||
Active Golems ({activeGolems.length}/{Math.max(1, store.attunements?.fabricator?.level || 0)})
|
||||
</span>
|
||||
{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>
|
||||
</CardHeader>
|
||||
@@ -1089,7 +1101,32 @@ export function CraftingTab({ store }: CraftingTabProps) {
|
||||
/>
|
||||
</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)}
|
||||
</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',
|
||||
requiredElement: 'water',
|
||||
name: 'Mud Golem',
|
||||
desc: 'A viscous, slowing golem that entraps enemies.',
|
||||
desc: 'A viscous golem that suffocates enemies in clinging mud.',
|
||||
damageMultiplier: 1.2,
|
||||
effect: 'slow',
|
||||
effect: 'drown',
|
||||
},
|
||||
|
||||
// Metal Golem + Fire = Forge Golem
|
||||
|
||||
@@ -583,26 +583,6 @@ export const ENCHANTMENT_EFFECTS: Record<string, EnchantmentEffectDef> = {
|
||||
allowedEquipmentCategories: LEGS_ONLY,
|
||||
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 ────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -1970,9 +1970,14 @@ export const useGameStore = create<GameStore>()(
|
||||
const elem = state.elements[manaType];
|
||||
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;
|
||||
|
||||
// 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;
|
||||
},
|
||||
|
||||
@@ -1988,8 +1993,13 @@ export const useGameStore = create<GameStore>()(
|
||||
if (!elem?.unlocked || elem.current < golemDef.summonCost) 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
|
||||
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 hasGolemancyMaster = state.skills.golemancyMaster === 1;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user