diff --git a/src/App.vue b/src/App.vue
index 185892a..85c5744 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -5,6 +5,7 @@ import DeviceScreen from './components/DeviceScreen.vue';
import PetGame from './components/PetGame.vue';
import Menu from './components/Menu.vue';
import { usePetSystem } from './composables/usePetSystem';
+import { useEventSystem } from './composables/useEventSystem';
const currentScreen = ref('game');
const petGameRef = ref(null);
@@ -12,6 +13,7 @@ const showStats = ref(false); // Stats visibility
const debugAction = ref(null); // For passing debug commands to PetGame
// Initialize Pet System
+const petSystem = usePetSystem();
const {
stage,
state,
@@ -24,8 +26,19 @@ const {
hatchEgg,
reset,
achievements,
- unlockAllAchievements
-} = usePetSystem();
+ unlockAllAchievements,
+ resurrect,
+ reincarnate
+} = petSystem;
+
+// Initialize Event System
+const { currentEvent, checkEventTriggers, triggerRandomEvent } = useEventSystem(petSystem);
+
+// Start Event Loop
+setInterval(() => {
+ checkEventTriggers();
+}, 10000); // Check every 10 seconds
+
// Handle Action Menu Events
function handleAction(action) {
@@ -88,6 +101,12 @@ function handleAction(action) {
console.log('求籤功能');
// TODO: 實作求籤邏輯
break;
+ case 'resurrect':
+ resurrect();
+ break;
+ case 'reincarnate':
+ reincarnate();
+ break;
default:
console.log('Action not implemented:', action);
}
@@ -117,6 +136,7 @@ function triggerDebugAction(action, payload = null) {
:showStats="showStats"
:debugAction="debugAction"
:achievements="achievements"
+ :currentEvent="currentEvent"
@update:state="state = $event"
@action="handleAction"
/>
diff --git a/src/components/JiaobeiAnimation.vue b/src/components/JiaobeiAnimation.vue
index c413428..899d240 100644
--- a/src/components/JiaobeiAnimation.vue
+++ b/src/components/JiaobeiAnimation.vue
@@ -35,7 +35,7 @@
-
+
@@ -45,6 +45,11 @@
+
+
+
+
+
diff --git a/src/components/PetGame.vue b/src/components/PetGame.vue
index 3713d49..70b3978 100644
--- a/src/components/PetGame.vue
+++ b/src/components/PetGame.vue
@@ -100,8 +100,21 @@
💀
-
-
+
+
+
+
+
+
+
{{ currentEvent.text }}
+
@@ -169,6 +193,7 @@
@result="handleJiaobeiResult"
@retry-fortune="handleRetryFortune"
@finish-fortune="handleFinishFortune"
+ @resurrect-confirm="handleResurrectConfirm"
/>
@@ -195,6 +220,12 @@
:hunger="stats?.hunger || 100"
:happiness="stats?.happiness || 100"
:health="stats?.health || 100"
+ :str="stats?.str || 0"
+ :int="stats?.int || 0"
+ :dex="stats?.dex || 0"
+ :generation="stats?.generation || 1"
+ :deityFavor="stats?.deityFavor || 0"
+ :destiny="stats?.destiny || null"
:achievements="achievements"
@close="showPetInfo = false"
/>
@@ -301,6 +332,10 @@ const props = defineProps({
achievements: {
type: Array,
default: () => []
+ },
+ currentEvent: {
+ type: Object,
+ default: null
}
});
@@ -315,6 +350,8 @@ const showFortuneResult = ref(false);
const currentLotData = ref(null);
const currentLotNumber = ref(null);
const consecutiveSaintCount = ref(0);
+const lastJiaobeiResult = ref(null); // 記錄最後的擲筊結果用於招魂確認
+
const showPetInfo = ref(false);
const showInventory = ref(false);
const showPlayMenu = ref(false);
@@ -416,6 +453,7 @@ function handleTrainingAttack() {
function handleGameComplete(won) {
console.log('Game completed, won:', won);
+ const gameType = currentGame.value; // Capture before clearing
currentGame.value = '';
if (won) {
@@ -434,6 +472,20 @@ function handleGameComplete(won) {
// 增加一些數值作為獎勵
stats.value.happiness = Math.min(100, stats.value.happiness + 10);
stats.value.hunger = Math.max(0, stats.value.hunger - 5); // 運動會餓
+
+ // V2 Stats Growth
+ let statGain = 1;
+ // Destiny Effect: Diligence (勤奮) - +20% rewards (rounded up to +1 extra for small values)
+ if (stats.value.destiny?.id === 'diligence') {
+ statGain += 1;
+ }
+
+ if (gameType === 'training') {
+ stats.value.str = (stats.value.str || 0) + statGain;
+ // Training also gives Deity Favor slightly? Maybe not.
+ } else if (gameType === 'guessing') {
+ stats.value.int = (stats.value.int || 0) + statGain;
+ }
}
}
@@ -460,6 +512,13 @@ function handleBallGameComplete(won) {
stats.value.happiness = Math.min(100, stats.value.happiness + 15);
stats.value.hunger = Math.max(0, stats.value.hunger - 10);
+
+ // V2 Stats Growth: DEX
+ let statGain = 1;
+ if (stats.value.destiny?.id === 'diligence') {
+ statGain += 1;
+ }
+ stats.value.dex = (stats.value.dex || 0) + statGain;
}
}
@@ -480,17 +539,65 @@ function handleFortuneStickClose() {
consecutiveSaintCount.value = 0;
}
+function handleResurrectAttempt() {
+ // 招魂:需要擲筊
+ fortuneMode.value = 'resurrect';
+ showJiaobeiAnimation.value = true;
+ consecutiveSaintCount.value = 0;
+}
+
+function handleReincarnate() {
+ emit('action', 'reincarnate');
+}
+
function handleJiaobeiResult(type) {
if (fortuneMode.value === 'fortune') {
if (type === 'saint') {
consecutiveSaintCount.value++;
- } else {
- // 如果不是聖筊,計數歸零(邏輯上失敗了,需要重新求籤)
+ // V2: Pet Reaction
+ triggerState('happy', 1000);
+ eventAnimation.value = { type: 'float-up', iconClass: 'pixel-heart' };
+ setTimeout(() => eventAnimation.value = null, 1000);
+ } else if (type === 'laugh') {
+ // 笑筊
consecutiveSaintCount.value = 0;
+ triggerState('refuse', 1000); // Confused
+ eventAnimation.value = { type: 'float-up', iconClass: 'pixel-question' };
+ setTimeout(() => eventAnimation.value = null, 1000);
+ } else {
+ // 陰筊
+ consecutiveSaintCount.value = 0;
+ triggerState('sad', 1000); // Scared
+ eventAnimation.value = { type: 'float-up', iconClass: 'pixel-skull' };
+ setTimeout(() => eventAnimation.value = null, 1000);
}
+ } else if (fortuneMode.value === 'resurrect') {
+ // 招魂模式:記錄結果,等待用戶點擊"確認"
+ lastJiaobeiResult.value = type;
}
}
+function handleResurrectConfirm() {
+ // 用戶點擊招魂的"確認"按鈕
+ const result = lastJiaobeiResult.value;
+
+ showJiaobeiAnimation.value = false;
+ fortuneMode.value = 'normal';
+ lastJiaobeiResult.value = null;
+
+ if (result === 'saint') {
+ // 聖筊 - 復活
+ emit('action', 'resurrect');
+ eventAnimation.value = { type: 'float-up', iconClass: 'pixel-heart' };
+ setTimeout(() => eventAnimation.value = null, 2000);
+ } else {
+ // 非聖筊 - 直接輪迴
+ emit('action', 'reincarnate');
+ }
+}
+
+
+
function handleRetryFortune() {
// 重新開始搖籤
showJiaobeiAnimation.value = false;
@@ -505,6 +612,39 @@ function handleFinishFortune() {
currentLotData.value = lot;
showJiaobeiAnimation.value = false;
showFortuneResult.value = true;
+
+ // --- V2 Fortune Impact ---
+ // Increase Deity Favor for completing the ritual
+ stats.value.deityFavor = (stats.value.deityFavor || 0) + 1;
+
+ const grade = lot.grade; // e.g., "上上", "上吉", "中平", "下下"
+
+ if (grade.includes('上上')) {
+ triggerState('happy', 3000);
+ stats.value.happiness = Math.min(100, stats.value.happiness + 20);
+ stats.value.health = Math.min(100, stats.value.health + 10);
+ eventAnimation.value = { type: 'float-up', iconClass: 'pixel-heart' };
+ } else if (grade.includes('上') || grade.includes('大吉')) {
+ triggerState('happy', 2000);
+ stats.value.happiness = Math.min(100, stats.value.happiness + 10);
+ } else if (grade.includes('下下')) {
+ triggerState('sad', 3000);
+ // Trigger Bad Event
+ if (triggerRandomEvent) {
+ // Force a bad event or just increase risk
+ // For now, let's just lower stats
+ stats.value.happiness = Math.max(0, stats.value.happiness - 10);
+ }
+ } else if (grade.includes('下')) {
+ triggerState('sad', 2000);
+ stats.value.health = Math.max(0, stats.value.health - 5);
+ }
+
+ // Destiny Effect: Luck (福運) - Bonus happiness
+ if (stats.value.destiny?.id === 'luck' && (grade.includes('上') || grade.includes('吉'))) {
+ stats.value.happiness = Math.min(100, stats.value.happiness + 5);
+ }
+
} else {
console.error('Lot not found:', currentLotNumber.value);
handleJiaobeiClose();
@@ -1690,6 +1830,69 @@ defineExpose({
50% { transform: translate(-50%, -50%) translateY(-4px); }
}
+/* Death Screen */
+.death-screen {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: rgba(0, 0, 0, 0.7);
+ z-index: 100;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+}
+
+.death-menu {
+ margin-top: -30px; /* Overlay on top of tombstone */
+ background: rgba(224, 224, 224, 0.95);
+ border: 4px solid #555;
+ padding: 10px;
+ border-radius: 8px;
+ text-align: center;
+ box-shadow: 0 4px 0 #333;
+ max-width: 180px;
+ width: 90%;
+ z-index: 1;
+ position: relative;
+ box-sizing: border-box;
+}
+
+.death-title {
+ font-family: 'DotGothic16', monospace;
+ font-size: 14px;
+ font-weight: bold;
+ color: #333;
+ margin-bottom: 8px;
+}
+
+.death-actions {
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+}
+
+.action-btn {
+ font-family: 'DotGothic16', monospace;
+ padding: 6px 10px;
+ background: #fff;
+ border: 2px solid #888;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 11px;
+ transition: all 0.1s;
+ white-space: normal;
+ line-height: 1.2;
+ word-wrap: break-word;
+}
+
+.action-btn:active {
+ transform: translateY(2px);
+ background: #ddd;
+}
+
@@ -1773,6 +1976,51 @@ defineExpose({
background: transparent;
}
+.pixel-note {
+ width: 1px;
+ height: 1px;
+ background: transparent;
+ transform: scale(2);
+ color: #ff1493;
+ box-shadow:
+ -2px -2px, -1px -2px, 1px -2px, 2px -2px,
+ -3px -1px, -2px -1px, -1px -1px, 0px -1px, 1px -1px, 2px -1px, 3px -1px,
+ -3px 0px, -2px 0px, -1px 0px, 0px 0px, 1px 0px, 2px 0px, 3px 0px,
+ -2px 1px, -1px 1px, 0px 1px, 1px 1px, 2px 1px,
+ -1px 2px, 0px 2px, 1px 2px,
+ 0px 3px;
+}
+
+.pixel-question {
+ width: 1px;
+ height: 1px;
+ background: transparent;
+ transform: scale(2);
+ color: #9C27B0;
+ box-shadow:
+ -1px -3px, 0px -3px, 1px -3px,
+ -2px -2px, 2px -2px,
+ 2px -1px,
+ 1px 0px,
+ 0px 1px,
+ 0px 3px;
+}
+
+.pixel-skull {
+ width: 1px;
+ height: 1px;
+ background: transparent;
+ transform: scale(2);
+ color: #555;
+ box-shadow:
+ -2px -3px, -1px -3px, 0px -3px, 1px -3px, 2px -3px,
+ -3px -2px, 3px -2px,
+ -3px -1px, -1px -1px, 1px -1px, 3px -1px,
+ -3px 0px, 3px 0px,
+ -2px 1px, -1px 1px, 0px 1px, 1px 1px, 2px 1px,
+ -1px 2px, 1px 2px;
+}
+
.pixel-toy {
box-shadow:
-1px -2px #32cd32, 0px -2px #32cd32, 1px -2px #32cd32,
diff --git a/src/components/PetInfoScreen.vue b/src/components/PetInfoScreen.vue
index 47e0d90..695697d 100644
--- a/src/components/PetInfoScreen.vue
+++ b/src/components/PetInfoScreen.vue
@@ -105,6 +105,43 @@
+
+
+
+
命格
+
+ {{ destiny.name }}
+ {{ destiny.description }}
+
+
+
+ 命格
+ ???
+
+
+
+
+
+
+ 力量 (STR)
+ {{ str }}
+
+
+ 智力 (INT)
+ {{ int }}
+
+
+ 敏捷 (DEX)
+ {{ dex }}
+
+
+ 世代
+ 第 {{ generation }} 代
+
+
+ 神明好感
+ {{ deityFavor }}
+
HP
@@ -170,6 +207,13 @@ const props = defineProps({
type: Number,
default: 100
},
+ // v2 Stats
+ str: { type: Number, default: 0 },
+ int: { type: Number, default: 0 },
+ dex: { type: Number, default: 0 },
+ generation: { type: Number, default: 1 },
+ deityFavor: { type: Number, default: 0 },
+ destiny: { type: Object, default: null },
achievements: {
type: Array,
default: () => []
@@ -532,6 +576,31 @@ const weight = computed(() => {
font-weight: 600;
}
+.destiny-item {
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 4px;
+}
+
+.destiny-content {
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ padding-left: 4px;
+ gap: 2px;
+}
+
+.destiny-name {
+ color: #d32f2f; /* Red for emphasis */
+ font-size: 12px;
+}
+
+.destiny-desc {
+ font-family: 'DotGothic16', monospace;
+ font-size: 10px;
+ color: #665544;
+}
+
/* Achievements */
.achievements-view {
padding: 12px;
diff --git a/src/composables/useEventSystem.js b/src/composables/useEventSystem.js
new file mode 100644
index 0000000..34d2100
--- /dev/null
+++ b/src/composables/useEventSystem.js
@@ -0,0 +1,144 @@
+import { ref } from 'vue';
+
+export function useEventSystem(petSystem) {
+ const { stats, state, triggerState } = petSystem;
+
+ const currentEvent = ref(null);
+ const eventHistory = ref([]);
+
+ // --- Event Database ---
+ // Categories: 'good', 'bad', 'weird'
+ const EVENT_DATABASE = [
+ // --- Good Events ---
+ {
+ id: 'found_charm',
+ type: 'good',
+ text: '撿到小符',
+ effect: (s) => { s.happiness = Math.min(100, s.happiness + 5); },
+ condition: () => true,
+ icon: 'pixel-charm'
+ },
+ {
+ id: 'self_clean',
+ type: 'good',
+ text: '自己掃地',
+ effect: (s) => { if (s.poopCount > 0) s.poopCount--; },
+ condition: (s) => s.poopCount > 0,
+ icon: 'pixel-broom'
+ },
+ {
+ id: 'dance',
+ type: 'good',
+ text: '開心地跳舞',
+ effect: (s) => { s.happiness = Math.min(100, s.happiness + 10); },
+ condition: (s) => s.happiness > 70,
+ icon: 'pixel-note'
+ },
+ {
+ id: 'gift_apple',
+ type: 'good',
+ text: '給你一顆果子',
+ effect: (s) => { /* Add to inventory logic later */ s.hunger = Math.min(100, s.hunger + 5); },
+ condition: () => Math.random() < 0.3,
+ icon: 'pixel-apple'
+ },
+
+ // --- Bad Events ---
+ {
+ id: 'night_noise',
+ type: 'bad',
+ text: '半夜亂叫',
+ effect: (s) => { s.happiness = Math.max(0, s.happiness - 5); },
+ condition: (s) => isNight(),
+ icon: 'pixel-angry'
+ },
+ {
+ id: 'overeat',
+ type: 'bad',
+ text: '偷吃太多',
+ effect: (s) => { s.hunger = Math.min(100, s.hunger + 20); s.health = Math.max(0, s.health - 5); },
+ condition: (s) => s.hunger > 80,
+ icon: 'pixel-meat'
+ },
+ {
+ id: 'stomach_ache',
+ type: 'bad',
+ text: '胃痛',
+ effect: (s) => { s.health = Math.max(0, s.health - 10); },
+ condition: (s) => s.health < 50,
+ icon: 'pixel-skull'
+ },
+
+ // --- Weird Events ---
+ {
+ id: 'stare',
+ type: 'weird',
+ text: '盯著螢幕外面看...',
+ effect: () => { },
+ condition: () => true,
+ icon: 'pixel-eye'
+ },
+ {
+ id: 'corner_squat',
+ type: 'weird',
+ text: '走到角落蹲著',
+ effect: (s) => { s.happiness = Math.max(0, s.happiness - 5); },
+ condition: () => true,
+ icon: 'pixel-cloud'
+ },
+ {
+ id: 'glitch',
+ type: 'weird',
+ text: '#@!$%^&*',
+ effect: (s) => { if (s.int > 5) s.int++; },
+ condition: () => Math.random() < 0.1,
+ icon: 'pixel-glitch'
+ }
+ ];
+
+ function isNight() {
+ const hour = new Date().getHours();
+ return hour >= 22 || hour < 6;
+ }
+
+ function checkEventTriggers() {
+ if (state.value === 'sleep' || state.value === 'dead') return;
+
+ // 10% chance to trigger an event per check
+ // Destiny Effect: Luck (福運) - Good events more likely?
+ // Destiny Effect: Spiritual (靈視) - Night events more likely
+
+ if (Math.random() < 0.1) {
+ triggerRandomEvent();
+ }
+ }
+
+ function triggerRandomEvent() {
+ // Filter valid events
+ const validEvents = EVENT_DATABASE.filter(e => e.condition(stats.value));
+ if (validEvents.length === 0) return;
+
+ const event = validEvents[Math.floor(Math.random() * validEvents.length)];
+
+ // Apply effect
+ event.effect(stats.value);
+
+ // Set current event for UI
+ currentEvent.value = event;
+ eventHistory.value.unshift({ ...event, time: new Date() });
+
+ // Auto-clear event after 3 seconds
+ setTimeout(() => {
+ currentEvent.value = null;
+ }, 4000);
+
+ console.log('Event Triggered:', event.text);
+ }
+
+ return {
+ currentEvent,
+ eventHistory,
+ checkEventTriggers,
+ triggerRandomEvent
+ };
+}
diff --git a/src/composables/usePetSystem.js b/src/composables/usePetSystem.js
index 9569504..101cd02 100644
--- a/src/composables/usePetSystem.js
+++ b/src/composables/usePetSystem.js
@@ -5,6 +5,17 @@ export function usePetSystem() {
const stage = ref('egg'); // egg, baby, adult
const state = ref('idle'); // idle, sleep, eating, sick, dead, refuse
+ // --- Destiny Data ---
+ const DESTINIES = [
+ { id: 'luck', name: '福運', description: '籤詩好籤率 +10%', rarity: 1 },
+ { id: 'diligence', name: '勤奮', description: '訓練遊戲獎勵 +20%', rarity: 1 },
+ { id: 'gluttony', name: '暴食', description: '飢餓下降速度 +30%', rarity: 1 },
+ { id: 'playful', name: '愛玩', description: 'Happiness 更快下降/更快上升', rarity: 1 },
+ { id: 'purification', name: '淨化', description: '生病機率 -20%', rarity: 1 },
+ { id: 'thirdeye', name: '天眼', description: '擲筊出聖筊機率微升', rarity: 2 },
+ { id: 'medium', name: '冥感', description: '死亡後招魂成功率提升', rarity: 2 }
+ ];
+
// --- Stats ---
const stats = ref({
hunger: 100, // 0-100 (0 = Starving)
@@ -12,7 +23,14 @@ export function usePetSystem() {
health: 100, // 0-100 (0 = Sick risk)
weight: 500, // grams
age: 1, // days (start at day 1)
- poopCount: 0 // Number of poops on screen
+ poopCount: 0, // Number of poops on screen
+ // v2 Stats
+ str: 0, // 力量 (Fireball Game)
+ int: 0, // 智力 (Guessing Game)
+ dex: 0, // 敏捷 (Catch Ball)
+ generation: 1, // 輪迴世代
+ deityFavor: 0, // 神明好感度
+ destiny: null // 天生命格 (Object)
});
const achievements = ref([
@@ -32,6 +50,24 @@ export function usePetSystem() {
// --- Actions ---
+ function assignDestiny() {
+ // Simple weighted random or just random for now
+ // Rarity 2 has lower chance
+ const roll = Math.random();
+ let pool = DESTINIES;
+
+ // 20% chance for rare destiny
+ if (roll < 0.2) {
+ pool = DESTINIES.filter(d => d.rarity === 2);
+ } else {
+ pool = DESTINIES.filter(d => d.rarity === 1);
+ }
+
+ const picked = pool[Math.floor(Math.random() * pool.length)];
+ stats.value.destiny = picked;
+ console.log('Assigned Destiny:', picked);
+ }
+
function feed() {
if (state.value === 'sleep' || state.value === 'dead' || stage.value === 'egg' || isCleaning.value) return false;
@@ -47,6 +83,7 @@ export function usePetSystem() {
stats.value.weight += 50;
// Chance to poop after eating (降低機率)
+ // Destiny Effect: Gluttony (暴食) might increase poop chance? Or just hunger decay.
if (Math.random() < 0.15) { // 從 0.3 降到 0.15
setTimeout(() => {
if (stats.value.poopCount < 4) {
@@ -98,18 +135,32 @@ export function usePetSystem() {
if (state.value === 'dead' || stage.value === 'egg') return;
// Decrease stats naturally
- // 目標:飢餓值約 30-60 分鐘下降 10%,快樂值約 20-40 分鐘下降 10%
- // TICK_RATE = 3000ms (3秒), 600 ticks = 30分鐘
- // 飢餓值每 tick -0.05 → 600 ticks = -30 (30分鐘下降30%)
- // 快樂值每 tick -0.08 → 600 ticks = -48 (30分鐘下降48%)
+ // Destiny Effect: Gluttony (暴食) - Hunger decreases faster (+30%)
+ let hungerDecay = 0.05;
+ if (stats.value.destiny?.id === 'gluttony') {
+ hungerDecay *= 1.3;
+ }
+
+ // Destiny Effect: Playful (愛玩) - Happiness decreases faster
+ let happinessDecay = 0.08;
+ if (stats.value.destiny?.id === 'playful') {
+ happinessDecay *= 1.2; // Faster decay
+ }
+
+ // Destiny Effect: DEX (敏捷) - Hunger decreases slower
+ // DEX 10 = -10% decay, DEX 50 = -50% decay
+ if (stats.value.dex > 0) {
+ const reduction = Math.min(0.5, stats.value.dex * 0.01); // Max 50% reduction
+ hungerDecay *= (1 - reduction);
+ }
if (state.value !== 'sleep') {
- stats.value.hunger = Math.max(0, stats.value.hunger - 0.05);
- stats.value.happiness = Math.max(0, stats.value.happiness - 0.08);
+ stats.value.hunger = Math.max(0, stats.value.hunger - hungerDecay);
+ stats.value.happiness = Math.max(0, stats.value.happiness - happinessDecay);
} else {
// Slower decay when sleeping (約 1/3 速度)
- stats.value.hunger = Math.max(0, stats.value.hunger - 0.015);
- stats.value.happiness = Math.max(0, stats.value.happiness - 0.025);
+ stats.value.hunger = Math.max(0, stats.value.hunger - (hungerDecay * 0.3));
+ stats.value.happiness = Math.max(0, stats.value.happiness - (happinessDecay * 0.3));
}
// Random poop generation (更低的機率:約 0.5% per tick)
@@ -137,8 +188,14 @@ export function usePetSystem() {
}
// Sickness Check (更低的生病機率)
+ // Destiny Effect: Purification (淨化) - Sickness chance -20%
+ let sickChance = 0.1;
+ if (stats.value.destiny?.id === 'purification') {
+ sickChance *= 0.8;
+ }
+
if (stats.value.health < 30 && state.value !== 'sick') {
- if (Math.random() < 0.1) { // 從 0.3 降到 0.1
+ if (Math.random() < sickChance) {
state.value = 'sick';
}
}
@@ -224,6 +281,10 @@ export function usePetSystem() {
stats.value.happiness = 50;
stats.value.health = 100;
stats.value.poopCount = 0;
+
+ // v2: Assign Destiny
+ assignDestiny();
+
isCleaning.value = false;
}
}
@@ -238,11 +299,56 @@ export function usePetSystem() {
health: 100,
weight: 500,
age: 1,
- poopCount: 0
+ poopCount: 0,
+ // v2 Reset
+ str: 0,
+ int: 0,
+ dex: 0,
+ generation: 1,
+ deityFavor: 0,
+ destiny: null
};
tickCount = 0;
}
+ function resurrect() {
+ if (state.value !== 'dead') return;
+
+ state.value = 'idle';
+ stats.value.health = 50; // Revive with half health
+ stats.value.happiness = 50;
+ stats.value.hunger = 50;
+
+ // Penalty or Ghost Buff?
+ // For now just a console log, maybe visual effect later
+ console.log('Pet Resurrected!');
+ }
+
+ function reincarnate() {
+ // Inherit logic
+ const prevDestiny = stats.value.destiny;
+ const prevFavor = stats.value.deityFavor;
+ const nextGen = (stats.value.generation || 1) + 1;
+
+ // Reset everything
+ reset();
+
+ // Apply Inheritance
+ stats.value.generation = nextGen;
+
+ // 20% Favor inheritance
+ stats.value.deityFavor = Math.floor(prevFavor * 0.2);
+
+ // Destiny Inheritance (Optional: Maybe keep if it was a rare one?)
+ // For now, let's say if you had a Rare (2) destiny, you keep it.
+ // Otherwise, you get a new one on hatch.
+ if (prevDestiny && prevDestiny.rarity === 2) {
+ stats.value.destiny = prevDestiny;
+ }
+
+ console.log('Pet Reincarnated to Gen', nextGen);
+ }
+
// --- Lifecycle ---
onMounted(() => {
gameLoopId = setInterval(tick, TICK_RATE);
@@ -264,6 +370,9 @@ export function usePetSystem() {
hatchEgg,
reset,
achievements,
- unlockAllAchievements
+ unlockAllAchievements,
+ assignDestiny, // Export for debug if needed
+ resurrect,
+ reincarnate
};
}