Initial commit: Text Adventure Game

Features:
- Combat system with AP/EP hit calculation and three-layer defense
- Auto-combat/farming mode
- Item system with stacking support
- Skill system with levels, milestones, and parent skill sync
- Shop system with dynamic pricing
- Inventory management with bulk selling
- Event system
- Game loop with offline earnings
- Save/Load system

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Claude
2026-01-21 17:13:51 +08:00
commit cb412544e9
90 changed files with 17149 additions and 0 deletions

147
tests/fixtures/enemies.js vendored Normal file
View File

@@ -0,0 +1,147 @@
/**
* 敌人测试夹具
*/
/**
* 创建模拟敌人
* @param {Object} overrides - 覆盖属性
* @returns {Object} 敌人对象
*/
export function createMockEnemy(overrides = {}) {
return {
id: 'wild_dog',
name: '野狗',
baseStats: {
health: 50,
attack: 8,
defense: 3,
strength: 8,
agility: 12,
dexterity: 6,
intuition: 4,
vitality: 6
},
expReward: 20,
drops: [],
...overrides
}
}
/**
* 创建Boss敌人
* @param {Object} overrides - 覆盖属性
* @returns {Object} Boss对象
*/
export function createMockBoss(overrides = {}) {
return {
id: 'test_boss',
name: '测试Boss',
baseStats: {
health: 200,
attack: 15,
defense: 10,
strength: 15,
agility: 10,
dexterity: 10,
intuition: 8,
vitality: 15
},
expReward: 100,
drops: [
{
itemId: 'epic_sword',
chance: 1.0,
count: 1
}
],
...overrides
}
}
/**
* 创建弱小敌人
* @returns {Object} 弱小敌人
*/
export function createWeakEnemy() {
return createMockEnemy({
id: 'rat',
name: '老鼠',
baseStats: {
health: 20,
attack: 3,
defense: 1,
strength: 3,
agility: 8,
dexterity: 4,
intuition: 2,
vitality: 3
},
expReward: 5
})
}
/**
* 创建强大敌人
* @returns {Object} 强大敌人
*/
export function createStrongEnemy() {
return createMockEnemy({
id: 'orc',
name: '兽人',
baseStats: {
health: 120,
attack: 18,
defense: 12,
strength: 18,
agility: 8,
dexterity: 10,
intuition: 6,
vitality: 16
},
expReward: 60
})
}
/**
* 创建敏捷型敌人
* @returns {Object} 敏捷型敌人
*/
export function createAgileEnemy() {
return createMockEnemy({
id: 'goblin',
name: '哥布林',
baseStats: {
health: 40,
attack: 6,
defense: 2,
strength: 6,
agility: 18,
dexterity: 14,
intuition: 6,
vitality: 6
},
expReward: 25
})
}
/**
* 创建防御型敌人
* @returns {Object} 防御型敌人
*/
export function createTankEnemy() {
return createMockEnemy({
id: 'golem',
name: '石魔像',
baseStats: {
health: 150,
attack: 10,
defense: 20,
strength: 16,
agility: 4,
dexterity: 4,
intuition: 2,
vitality: 20
},
expReward: 50
})
}

92
tests/fixtures/game.js vendored Normal file
View File

@@ -0,0 +1,92 @@
/**
* Game Store 测试夹具
*/
/**
* 创建模拟游戏数据
* @param {Object} overrides - 覆盖的属性
* @returns {Object} 模拟游戏对象
*/
export function createMockGame(overrides = {}) {
return {
currentTab: 'status',
drawerState: {
inventory: false,
event: false,
...overrides.drawerState
},
logs: overrides.logs || [],
gameTime: {
day: 1,
hour: 8,
minute: 0,
totalMinutes: 480,
...overrides.gameTime
},
inCombat: overrides.inCombat || false,
combatState: overrides.combatState || null,
activeTasks: overrides.activeTasks || [],
negativeStatus: overrides.negativeStatus || [],
marketPrices: overrides.marketPrices || {
lastRefreshDay: 1,
prices: {}
},
currentEvent: overrides.currentEvent || null,
scheduledEvents: overrides.scheduledEvents || []
}
}
/**
* 创建战斗中的游戏状态
* @param {Object} enemy - 敌人对象
* @returns {Object} 模拟游戏对象
*/
export function createGameInCombat(enemy) {
return createMockGame({
inCombat: true,
combatState: {
enemyId: enemy.id,
enemy,
stance: 'balance',
environment: 'normal',
startTime: Date.now(),
ticks: 0
}
})
}
/**
* 创建有活动任务的游戏状态
* @param {Array} tasks - 任务数组
* @returns {Object} 模拟游戏对象
*/
export function createGameWithTasks(tasks) {
return createMockGame({
activeTasks: tasks.map(task => ({
id: Date.now() + Math.random(),
type: task.type,
data: task.data || {},
startTime: Date.now(),
progress: 0,
totalDuration: task.duration || 0,
lastTickTime: Date.now(),
...task
}))
})
}
/**
* 创建有日志的游戏状态
* @param {Array} logs - 日志数组
* @returns {Object} 模拟游戏对象
*/
export function createGameWithLogs(logs) {
return createMockGame({
logs: logs.map((log, index) => ({
id: Date.now() + index,
time: '08:00',
message: log,
type: 'info'
}))
})
}

144
tests/fixtures/items.js vendored Normal file
View File

@@ -0,0 +1,144 @@
/**
* 物品测试夹具
*/
/**
* 创建模拟武器
* @param {Object} overrides - 覆盖属性
* @returns {Object} 武器对象
*/
export function createMockWeapon(overrides = {}) {
return {
id: 'wooden_sword',
name: '木剑',
type: 'weapon',
subtype: 'one_handed',
baseDamage: 10,
baseDefense: 0,
baseShield: 0,
baseValue: 100,
quality: 100,
attackSpeed: 1.0,
uniqueId: `wooden_sword_${Date.now()}_test`,
count: 1,
equipped: false,
obtainedAt: Date.now(),
...overrides
}
}
/**
* 创建模拟防具
* @param {Object} overrides - 覆盖属性
* @returns {Object} 防具对象
*/
export function createMockArmor(overrides = {}) {
return {
id: 'leather_armor',
name: '皮甲',
type: 'armor',
subtype: 'light',
baseDamage: 0,
baseDefense: 15,
baseShield: 0,
baseValue: 150,
quality: 100,
uniqueId: `leather_armor_${Date.now()}_test`,
count: 1,
equipped: false,
obtainedAt: Date.now(),
...overrides
}
}
/**
* 创建模拟盾牌
* @param {Object} overrides - 覆盖属性
* @returns {Object} 盾牌对象
*/
export function createMockShield(overrides = {}) {
return {
id: 'wooden_shield',
name: '木盾',
type: 'shield',
baseDamage: 0,
baseDefense: 0,
baseShield: 20,
baseValue: 80,
quality: 100,
uniqueId: `wooden_shield_${Date.now()}_test`,
count: 1,
equipped: false,
obtainedAt: Date.now(),
...overrides
}
}
/**
* 创建模拟消耗品
* @param {Object} overrides - 覆盖属性
* @returns {Object} 消耗品对象
*/
export function createMockConsumable(overrides = {}) {
return {
id: 'health_potion',
name: '生命药水',
type: 'consumable',
baseValue: 50,
quality: 100,
effect: {
health: 30,
stamina: 0,
sanity: 0
},
stackable: true,
maxStack: 99,
uniqueId: `health_potion_${Date.now()}_test`,
count: 1,
obtainedAt: Date.now(),
...overrides
}
}
/**
* 创建模拟书籍
* @param {Object} overrides - 覆盖属性
* @returns {Object} 书籍对象
*/
export function createMockBook(overrides = {}) {
return {
id: 'skill_book_basics',
name: '技能基础',
type: 'book',
baseValue: 200,
quality: 100,
readingTime: 60,
expReward: {
sword: 50
},
completionBonus: {
intuition: 1
},
uniqueId: `skill_book_${Date.now()}_test`,
count: 1,
obtainedAt: Date.now(),
...overrides
}
}
/**
* 创建高品质物品
* @param {string} type - 物品类型
* @param {number} quality - 品质值
* @returns {Object} 高品质物品
*/
export function createHighQualityItem(type, quality = 180) {
const itemCreators = {
weapon: createMockWeapon,
armor: createMockArmor,
shield: createMockShield
}
const creator = itemCreators[type] || createMockWeapon
return creator({ quality })
}

149
tests/fixtures/player.js vendored Normal file
View File

@@ -0,0 +1,149 @@
/**
* Player Store 测试夹具
*/
/**
* 创建模拟玩家数据
* @param {Object} overrides - 覆盖的属性
* @returns {Object} 模拟玩家对象
*/
export function createMockPlayer(overrides = {}) {
return {
baseStats: {
strength: 10,
agility: 8,
dexterity: 8,
intuition: 10,
vitality: 10,
...overrides.baseStats
},
currentStats: {
health: 100,
maxHealth: 100,
stamina: 100,
maxStamina: 100,
sanity: 100,
maxSanity: 100,
...overrides.currentStats
},
level: {
current: 1,
exp: 0,
maxExp: 100,
...overrides.level
},
skills: overrides.skills || {},
equipment: {
weapon: null,
armor: null,
shield: null,
accessory: null,
...overrides.equipment
},
inventory: overrides.inventory || [],
currency: {
copper: 0,
...overrides.currency
},
currentLocation: 'camp',
flags: overrides.flags || {},
milestoneBonuses: overrides.milestoneBonuses || {},
globalBonus: overrides.globalBonus || {
critRate: 0,
attackBonus: 0,
expRate: 1,
critMult: 0,
darkPenaltyReduce: 0,
globalExpRate: 0,
readingSpeed: 1
},
equipmentStats: overrides.equipmentStats || null,
killCount: overrides.killCount || {}
}
}
/**
* 创建已解锁技能的玩家
* @param {string} skillId - 技能ID
* @param {number} level - 技能等级
* @returns {Object} 模拟玩家对象
*/
export function createPlayerWithSkill(skillId, level = 1) {
return createMockPlayer({
skills: {
[skillId]: {
level,
exp: 0,
unlocked: true
}
}
})
}
/**
* 创建高等级玩家
* @param {number} level - 玩家等级
* @returns {Object} 模拟玩家对象
*/
export function createHighLevelPlayer(level = 10) {
return createMockPlayer({
level: {
current: level,
exp: 0,
maxExp: level * 100 * Math.pow(1.5, level - 1)
},
baseStats: {
strength: 10 + level * 2,
agility: 8 + level * 2,
dexterity: 8 + level * 2,
intuition: 10 + level * 2,
vitality: 10 + level * 2
}
})
}
/**
* 创建受伤的玩家
* @param {number} healthPercent - 生命值百分比
* @returns {Object} 模拟玩家对象
*/
export function createInjuredPlayer(healthPercent = 30) {
return createMockPlayer({
currentStats: {
health: 100 * healthPercent / 100,
maxHealth: 100,
stamina: 50,
maxStamina: 100,
sanity: 80,
maxSanity: 100
}
})
}
/**
* 创建富有的玩家
* @param {number} copper - 铜币数量
* @returns {Object} 模拟玩家对象
*/
export function createRichPlayer(copper = 10000) {
return createMockPlayer({
currency: { copper }
})
}
/**
* 创建已装备武器的玩家
* @param {Object} weapon - 武器对象
* @returns {Object} 模拟玩家对象
*/
export function createPlayerWithWeapon(weapon) {
return createMockPlayer({
equipment: {
weapon: null,
armor: null,
shield: null,
accessory: null
},
inventory: [weapon]
})
}