diff --git a/src/components/PetDisplay.tsx b/src/components/PetDisplay.tsx index c9b8b06..6ddd443 100755 --- a/src/components/PetDisplay.tsx +++ b/src/components/PetDisplay.tsx @@ -1,5 +1,5 @@ import { Pet } from '../types/Pet'; -import { Brain, Dumbbell, Heart, Sparkles, Coins, Pizza, Trash2, Trophy } from 'lucide-react'; +import { Brain, Dumbbell, Smile, Sparkles, Coins, Pizza, Trash2, Trophy, Heart, Star } from 'lucide-react'; import { PET_CLASSES } from '../data/petClasses'; import { useState } from 'react'; import InventoryModal from './modal/InventoryModal'; @@ -11,12 +11,13 @@ interface PetDisplayProps { } export default function PetDisplay({ pet, onPetUpdate }: PetDisplayProps) { - const StatBar = ({ value, maxValue, label, icon: Icon }: { value: number; maxValue: number; label: string; icon: any }) => ( -
+ const StatBar = ({ value, maxValue, label, icon: Icon }: + { value: number; maxValue: number; label: string; icon: any; }) => ( +
@@ -54,6 +55,14 @@ export default function PetDisplay({ pet, onPetUpdate }: PetDisplayProps) {
+
+ +
@@ -108,6 +117,7 @@ export default function PetDisplay({ pet, onPetUpdate }: PetDisplayProps) { {showSkillTreeModal && ( setShowSkillTreeModal(false) } diff --git a/src/components/modal/SkillTreeModal.tsx b/src/components/modal/SkillTreeModal.tsx index 47db427..07144d6 100644 --- a/src/components/modal/SkillTreeModal.tsx +++ b/src/components/modal/SkillTreeModal.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import { Pet } from '../../types/Pet'; +import { Pet, Resources } from '../../types/Pet'; import { Skill, PetSkill, SkillType } from '../../types/Skills'; import { fetchPets, getAllSkills, getPetSkills, postAllocatePetSkill } from '../../services/api/api'; import { Loader2 } from 'lucide-react'; @@ -8,10 +8,11 @@ import styles from './SkillTreeModal.module.css'; interface SkillTreeModalProps { onClose: () => void; petId: string; + petResources: Resources; onPetUpdate: (updatedPet: Pet) => void; } -export default function SkillTreeModal({ onClose, petId, onPetUpdate }: SkillTreeModalProps) { +export default function SkillTreeModal({ onClose, petId, petResources, onPetUpdate }: SkillTreeModalProps) { const [skills, setSkills] = useState([]); const [petSkills, setPetSkills] = useState([]); const [loading, setLoading] = useState(true); @@ -55,87 +56,110 @@ export default function SkillTreeModal({ onClose, petId, onPetUpdate }: SkillTre }; const canAllocateSkill = (skill: Skill) => { - if (!skill.skillsIdRequired) return true; - return petSkills.some(ps => ps.skillId === skill.skillsIdRequired![0]); + // check if all required skills are owned, and has all the required resources + const requiredSkills = skills.filter(s => skill.skillsIdRequired?.includes(s.id)); + const requiredSkillIds = requiredSkills.map(s => s.id); + const ownedRequiredSkills = petSkills.filter(ps => requiredSkillIds.includes(ps.skillId)); + const hasAllRequiredSkills = requiredSkills.length === ownedRequiredSkills.length; + + const hasAllResources = skill.skillRequirements.every(req => { + const resourceValue = petResources[req.resource.toLowerCase() as keyof Resources]; + return resourceValue >= req.cost; + }); + + return hasAllRequiredSkills && hasAllResources; }; - const getRequiredSkillName = (skillId: number[] | null) => { + const getRequiredSkillNames = (skillId: number[] | null) => { if (!skillId) return null; - return skills.find(s => s.id === skillId[0])?.name; + return skills.filter(s => skillId.includes(s.id)).map(s => s.name); + }; + + const getNextTierEffect = (currentTier?: string) => { + if (!currentTier) return 'I'; + if (currentTier === 'I') return 'II'; + if (currentTier === 'II') return 'III'; + return null; }; const renderSkillNode = (skill: Skill) => { - console.log('Rendering skill:', skill); - const owned = petSkills.some(ps => ps.skillId === skill.id); const tier = getSkillTier(skill.id); - const canAllocate = canAllocateSkill(skill); - const requiredSkillName = getRequiredSkillName(skill.skillsIdRequired); + const isMaxTier = tier === 'III'; + const canAllocate = !isMaxTier && canAllocateSkill(skill); + const nextTierEffect = getNextTierEffect(tier); + const requiredSkillNames = getRequiredSkillNames(skill.skillsIdRequired); return (
-
- {/* {skill.name} */} - {skill.icon} -

{skill.name}

- {tier && ( - - Tier {tier} - - )} -
-

{skill.description}

- {!canAllocate && requiredSkillName && ( -

Required skill: {requiredSkillName}

- )} -
- {skill.effects.map((effect, idx) => ( -
- Tier {effect.tier}: {effect.effect} ({effect.value}) -
- ))} -
- {!owned && ( - - )} - {owned && ( +
+

{skill.description}

+ +
+ {!isMaxTier && nextTierEffect && ( +
+ Next: Tier {nextTierEffect} +
+ )} + + {!isMaxTier && nextTierEffect && ( +
+
Requirements:
+ {requiredSkillNames && requiredSkillNames.map((name, idx) => ( +
+ • Requires: {name} +
+ ))} + {skill.skillRequirements.map((req, idx) => ( +
= req.cost + ? 'text-green-400' : 'text-red-400' + }`}> + • {req.resource}: {req.cost} +
+ ))} +
+ )} +
+
+ + {isMaxTier ? ( +
+ Mastered +
+ ) : ( )} diff --git a/src/types/Pet.ts b/src/types/Pet.ts index 0dc6904..c146560 100755 --- a/src/types/Pet.ts +++ b/src/types/Pet.ts @@ -25,7 +25,6 @@ export interface Pet { stats: PetStats; resources: Resources; level: number; - experience: number; health: number; maxHealth: number; petGatherAction: PetGatherAction; diff --git a/src/types/Skills.ts b/src/types/Skills.ts index c3d0c97..7f1719b 100644 --- a/src/types/Skills.ts +++ b/src/types/Skills.ts @@ -5,12 +5,17 @@ export interface Skill { name: string; description: string; type: SkillType; - pointsCost: number; + skillRequirements: SkillRequirement[]; icon: string; skillsIdRequired: number[] | null; effects: SkillEffect[]; } +export interface SkillRequirement { + cost: number; + resource: string; +} + export interface SkillEffect { id: number; skillId: number;