Major gameplay improvements - barriers, HP regen, descent mechanic
All checks were successful
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 2m28s
All checks were successful
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 2m28s
- Fix transference mana display (show unlocked elements even with 0 mana) - Remove blocking/dodging mechanics (player has no health): - Replace Seer's foresight with criticalMastery - Replace Warden's defensive skills with mana efficiency skills - Replace Strider's evasive with fluidMotion - Add guardian barriers (50% of HP, doesn't regenerate) - Add floor HP regeneration (scales with floor level, 0 for guardians) - Implement climb-down mechanic: - Cannot switch away from climb while above floor 1 - Must fight through each floor to exit - Exit Spire button triggers descent - Update UI to show barrier bar and descent status
This commit is contained in:
@@ -26,8 +26,14 @@ export function SpireTab({ store }: SpireTabProps) {
|
||||
const isGuardianFloor = !!GUARDIANS[store.currentFloor];
|
||||
const currentGuardian = GUARDIANS[store.currentFloor];
|
||||
const climbDirection = store.climbDirection || 'up';
|
||||
const isDescending = store.isDescending || false;
|
||||
const clearedFloors = store.clearedFloors || {};
|
||||
|
||||
// Barrier state
|
||||
const floorBarrier = store.floorBarrier || 0;
|
||||
const floorMaxBarrier = store.floorMaxBarrier || 0;
|
||||
const hasBarrier = floorBarrier > 0;
|
||||
|
||||
// Check if current floor is cleared (for respawn indicator)
|
||||
const isFloorCleared = clearedFloors[store.currentFloor];
|
||||
|
||||
@@ -88,6 +94,24 @@ export function SpireTab({ store }: SpireTabProps) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Barrier Bar (Guardians only) */}
|
||||
{isGuardianFloor && floorMaxBarrier > 0 && (
|
||||
<div className="space-y-1">
|
||||
<div className="flex items-center justify-between text-xs">
|
||||
<span className="text-gray-400">🛡️ Barrier</span>
|
||||
<span className="text-gray-500 game-mono">{fmt(floorBarrier)} / {fmt(floorMaxBarrier)}</span>
|
||||
</div>
|
||||
<div className="h-2 bg-gray-800 rounded-full overflow-hidden">
|
||||
<div
|
||||
className="h-full rounded-full transition-all duration-300 bg-gray-500"
|
||||
style={{
|
||||
width: `${Math.max(0, (floorBarrier / floorMaxBarrier) * 100)}%`,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* HP Bar */}
|
||||
<div className="space-y-1">
|
||||
<div className="h-3 bg-gray-800 rounded-full overflow-hidden">
|
||||
@@ -95,8 +119,8 @@ export function SpireTab({ store }: SpireTabProps) {
|
||||
className="h-full rounded-full transition-all duration-300"
|
||||
style={{
|
||||
width: `${Math.max(0, (store.floorHP / store.floorMaxHP) * 100)}%`,
|
||||
background: `linear-gradient(90deg, ${floorElemDef?.color}99, ${floorElemDef?.color})`,
|
||||
boxShadow: `0 0 10px ${floorElemDef?.glow}`,
|
||||
background: hasBarrier ? `linear-gradient(90deg, #6B728099, #6B7280)` : `linear-gradient(90deg, ${floorElemDef?.color}99, ${floorElemDef?.color})`,
|
||||
boxShadow: hasBarrier ? 'none' : `0 0 10px ${floorElemDef?.glow}`,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
@@ -137,6 +161,13 @@ export function SpireTab({ store }: SpireTabProps) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{isDescending && (
|
||||
<div className="text-xs text-blue-400 text-center flex items-center justify-center gap-1">
|
||||
<ChevronDown className="w-3 h-3 animate-bounce" />
|
||||
Descending... Fight through each floor to exit!
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isFloorCleared && (
|
||||
<div className="text-xs text-amber-400 text-center flex items-center justify-center gap-1">
|
||||
<RotateCcw className="w-3 h-3" />
|
||||
@@ -147,6 +178,18 @@ export function SpireTab({ store }: SpireTabProps) {
|
||||
|
||||
<Separator className="bg-gray-700" />
|
||||
|
||||
{/* Exit Spire Button */}
|
||||
{store.currentAction === 'climb' && store.currentFloor > 1 && !isDescending && (
|
||||
<Button
|
||||
variant="outline"
|
||||
className="w-full border-blue-600 text-blue-400 hover:bg-blue-900/20"
|
||||
onClick={() => store.exitSpire?.()}
|
||||
>
|
||||
<X className="w-4 h-4 mr-2" />
|
||||
Exit Spire (Descend from Floor {store.currentFloor})
|
||||
</Button>
|
||||
)}
|
||||
|
||||
<div className="text-sm text-gray-400">
|
||||
Best: Floor <strong className="text-gray-200">{store.maxFloorReached}</strong> •
|
||||
Pacts: <strong className="text-amber-400">{store.signedPacts.length}</strong>
|
||||
|
||||
Reference in New Issue
Block a user