--- import { getCollection } from "astro:content"; import Layout from "../layouts/Layout.astro"; import Card from "../components/Card.astro"; import EventCard from "../components/EventCard.astro"; // 1. Récupération des données const allHumans = await getCollection("humans", ({ id }) => { return id.startsWith("latchimynicolas/"); }); const allEvents = await getCollection("events"); // 2. Tris temporels const sortedAll = allHumans.sort( (a, b) => new Date(b.data.date).getTime() - new Date(a.data.date).getTime(), ); const latestEvent = allEvents.sort( (a, b) => new Date(a.data.date).getTime() - new Date(b.data.date).getTime(), )[0]; // 3. Logique de Streak (Série) const getStreak = (name, entries) => { const userDates = entries .filter((e) => e.data.name === name) .map((e) => ({ date: new Date(e.data.date).toISOString().split("T")[0], hasHyg: e.data.manifestations?.some((m) => m.cercle === "HYG") || false, })); const uniqueDates = [...new Set(userDates.map((d) => d.date))] .sort() .reverse(); let streak = 0; let today = new Date(); let checkDate = new Date( Date.UTC(today.getFullYear(), today.getMonth(), today.getDate()), ); let todaySkipped = false; for (let i = 0; i < 31; i++) { const dateStr = checkDate.toISOString().split("T")[0]; if (uniqueDates.includes(dateStr)) { streak++; checkDate.setUTCDate(checkDate.getUTCDate() - 1); } else { if (i === 0) { checkDate.setUTCDate(checkDate.getUTCDate() - 1); if ( uniqueDates.includes(checkDate.toISOString().split("T")[0]) ) { todaySkipped = true; continue; } } break; } } const shiftDays = todaySkipped ? 1 : 0; const last7Days = Array.from({ length: 7 }, (_, j) => { let d = new Date( Date.UTC(today.getFullYear(), today.getMonth(), today.getDate()), ); d.setUTCDate(d.getUTCDate() - (j + shiftDays)); return d.toISOString().split("T")[0]; }); const hygCount = userDates.filter( (e) => last7Days.includes(e.date) && e.hasHyg, ).length; if (hygCount < 3 && streak > 0) streak = Math.max(0, streak - 1); return streak; }; // 4. Sélection de la carte principale const latestPerUser = Array.from( sortedAll .reduce((map, obj) => { if (!map.has(obj.data.name)) map.set(obj.data.name, obj); return map; }, new Map()) .values(), ); // 5. CALCUL DE SYNERGIE const activeSynergies = latestPerUser.map((user) => { const matchingManifestation = user.data.manifestations?.find( (m) => m.cercle === latestEvent?.data.circle, ); return { userName: user.data.name, hasSynergy: !!matchingManifestation, cercle: latestEvent?.data.circle, type: matchingManifestation?.type, }; }); ---

Ambient

🛠️ Chantier Ergonomique (en cours)

"Repenser la visualisation des cartes pour un parcours utilisateur en totale concordance avec les besoins du type d'utilisateur."

🎴 Ergonomie des Cartes

  • Optimiser le ratio d'aspect pour une lecture mobile-first sur Samsung/Android.
  • Intégrer les indicateurs de "Synergie" directement sur le visuel de la carte.
  • Refondre le système de rareté (Shiny/Légendaire) avec des effets CSS avancés.

🛤️ Parcours Utilisateur

  • Simplifier la transition entre la vue "Dashboard" et la "Collection" complète.
  • Créer des points d'entrée contextuels selon le cercle dominant (PRO, SAN, etc.).
  • Améliorer la narration visuelle entre le manuel de jeu et les logs d'événements.

⚙️ Technique & Backlog

  • Automatiser la mise à jour des versions (Changelog) via les fichiers Markdown.
  • Améliorer la performance du rendu Astro sur le serveur Raspberry Pi 4.
  • Finaliser les composants EventCard pour les correctifs (Fixes).
{ latestPerUser.map((entry) => { const currentStreak = getStreak(entry.data.name, allHumans); return (
); }) } { latestEvent && (
) }

📖 Manuel de Jeu : TCG (Ruleset Complet)

Traduction technique des algorithmes du moteur de jeu

✨ Rareté & Évolution

  • SHINY : Streak ≥ 3 + 3 cercles uniques.
  • LÉGENDAIRE : Streak ≥ 10 + Harmonie ≥ 4.
  • MYTHIQUE : Streak ≥ 20 + 0 Hallucinations.

⚔️ Système de Combat

  • Puissance (ATK) : (PRO × 2) + (Motiv/4) + (Énergie/3) + Bonus Harmonie + StreakBonus. Le travail (PRO) est ton multiplicateur principal.
  • Résilience (DEF) : 10 + (Hygiène/2) - Stress - Hallu - Pénalité Sommeil + StreakBonus. L'hygiène est ton armure, le stress ta faille.
  • Coût d'Invocation : Nombre total de manifestations divisé par 2 (arrondi au supérieur).

📈 Séries & Rareté (Streak)

  • Streak Bonus : +1 ATK/DEF tous les 7 jours de série consécutifs.
  • Éveil Shiny : Activé dès 3 jours de série + 3 cercles différents activés.
  • Échelle de Rareté :
    PEU COMMUNE : 3 jours de série.
    RARE : 6 jours de série.
    LÉGENDAIRE : 10 jours + Harmonie ≥ 4.
    MYTHIQUE : 20 jours + 0 Hallucinations.

🌍 Influence des Biomes

  • ÉTANG (L'Inerte) : Priorité Somatique. S'active si Stress ≥ 7, Hallu ≥ 2 ou Harmonie ≤ -3.
  • BELOUVE (La Racine) : État d'Harmonie. S'active si 3+ cercles sont présents avec au moins un log SAN.
  • OCEAN (Le Flux) : S'active si le Social (SOC) domine le Pro ou si le Flux (FLX) est > 2.
  • FOURNAISE (La Forge) : S'active par dominance technique (PRO ≥ 2 et PRO ≥ SOC).
  • SAVANE (La Clarté) : Biome d'équilibre par défaut.

🔧 Maintenance & Malus

  • Pénalité Sommeil : Si (Sommeil - Malus Travail) < 6h, ta DEF baisse de 2. (Le malus travail s'active si PRO ≥ 5).
  • Harmonie des Cercles : Posséder les 5 cercles (SAN, FLX, PRO, SOC, HYG) sur un log octroie un bonus massif de **+2** au Score d'Harmonie.
  • Règle HYG (Prévention) : Si moins de 3 logs "HYG" sont détectés sur les 7 derniers jours, la série (Streak) est amputée d'un point de pénalité.

🎭 Objets & Équipements

  • VÉLO : Convertit 2 points de Stress en 1 point d'Énergie au petit matin.
  • ARIPIPRAZOLE : Fixe Hallucinations à 0. Ajoute le trait "Stabilité".