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:
147
tests/fixtures/enemies.js
vendored
Normal file
147
tests/fixtures/enemies.js
vendored
Normal 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
92
tests/fixtures/game.js
vendored
Normal 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
144
tests/fixtures/items.js
vendored
Normal 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
149
tests/fixtures/player.js
vendored
Normal 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]
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user