steamsheep-ts-game-engine 3.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1429,17 +1429,23 @@ interface ActionDef<S extends string, I extends string, F extends string, X = Re
1429
1429
  * 如果是函数,它会在所有效果(包括 afterEffects)执行完成后调用,
1430
1430
  * 因此可以基于最终状态生成准确的反馈文本。
1431
1431
  *
1432
+ * ⚠️ 增强功能:函数可以接收第二个参数(原始状态)
1433
+ *
1434
+ * 这允许你比较执行前后的状态变化,生成更准确的反馈文本,
1435
+ * 而无需通过 afterEffects + extra 的方式传递信息。
1436
+ *
1432
1437
  * 注意事项:
1433
1438
  * 1. 不应在这里修改游戏状态(使用 afterEffects 代替)
1434
- * 2. 函数接收的是所有效果执行后的最终状态
1435
- * 3. 返回的文本会作为 'result' 类型的日志添加到游戏日志中
1439
+ * 2. 第一个参数是所有效果执行后的最终状态
1440
+ * 3. 第二个参数是动作执行前的原始状态(可选)
1441
+ * 4. 返回的文本会作为 'result' 类型的日志添加到游戏日志中
1436
1442
  *
1437
1443
  * @example
1438
1444
  * ```typescript
1439
1445
  * // 静态文本
1440
1446
  * resultText: '你完成了探索'
1441
1447
  *
1442
- * // 动态文本 - 基于最终状态
1448
+ * // 动态文本 - 基于最终状态(单参数,向后兼容)
1443
1449
  * resultText: (state) => {
1444
1450
  * const sanity = state.stats.sanity;
1445
1451
  * if (sanity < 20) {
@@ -1451,35 +1457,78 @@ interface ActionDef<S extends string, I extends string, F extends string, X = Re
1451
1457
  * }
1452
1458
  * }
1453
1459
  *
1454
- * // 基于标记生成文本
1455
- * resultText: (state) => {
1456
- * if (state.flags.scholar_achievement) {
1457
- * return '你的知识达到了新的高度!【成就解锁:博学者】';
1458
- * }
1459
- * return '你学到了新的知识。';
1460
+ * // 比较前后状态(双参数,推荐)
1461
+ * resultText: (state, original) => {
1462
+ * const gainedGnosis = state.stats.gnosis > original.stats.gnosis;
1463
+ * return gainedGnosis
1464
+ * ? '你在冥想中获得了灵知!'
1465
+ * : '你平静地冥想了一会儿。';
1460
1466
  * }
1461
1467
  *
1462
- * // 基于多个状态生成复杂文本
1463
- * resultText: (state) => {
1464
- * const parts: string[] = ['你凝视着星空'];
1468
+ * // 显示具体的变化量
1469
+ * resultText: (state, original) => {
1470
+ * const hpChange = state.stats.hp - original.stats.hp;
1471
+ * const goldChange = state.stats.gold - original.gold;
1465
1472
  *
1466
- * if (state.world.time === 0) {
1467
- * parts.push('午夜的星空格外诡异');
1468
- * }
1473
+ * const parts: string[] = ['战斗结束'];
1469
1474
  *
1470
- * if (state.stats.sanity < 30) {
1471
- * parts.push('你看到了不该看到的东西');
1475
+ * if (hpChange < 0) {
1476
+ * parts.push(`失去了 ${-hpChange} 点生命值`);
1472
1477
  * }
1473
1478
  *
1474
- * if (state.flags.going_mad) {
1475
- * parts.push('理智正在崩溃...');
1479
+ * if (goldChange > 0) {
1480
+ * parts.push(`获得了 ${goldChange} 金币`);
1476
1481
  * }
1477
1482
  *
1478
1483
  * return parts.join(',') + '。';
1479
1484
  * }
1485
+ *
1486
+ * // 检测是否触发了特殊效果
1487
+ * resultText: (state, original) => {
1488
+ * const leveledUp = state.stats.level > original.stats.level;
1489
+ * const gotAchievement = state.flags.new_achievement && !original.flags.new_achievement;
1490
+ *
1491
+ * if (leveledUp && gotAchievement) {
1492
+ * return '恭喜升级!同时解锁了新成就!';
1493
+ * } else if (leveledUp) {
1494
+ * return '恭喜升级!';
1495
+ * } else if (gotAchievement) {
1496
+ * return '解锁了新成就!';
1497
+ * } else {
1498
+ * return '获得了经验值。';
1499
+ * }
1500
+ * }
1501
+ *
1502
+ * // 显示物品变化
1503
+ * resultText: (state, original) => {
1504
+ * const itemsGained = state.inventory.length - original.inventory.length;
1505
+ *
1506
+ * if (itemsGained > 0) {
1507
+ * const newItems = state.inventory.slice(-itemsGained);
1508
+ * return `获得了物品:${newItems.join('、')}`;
1509
+ * }
1510
+ *
1511
+ * return '打开了宝箱,但里面是空的。';
1512
+ * }
1513
+ *
1514
+ * // 条件效果的结果反馈
1515
+ * resultText: (state, original) => {
1516
+ * // 检查是否触发了条件效果
1517
+ * const triggeredMadness = state.flags.going_mad && !original.flags.going_mad;
1518
+ * const gotCursedItem = state.inventory.includes('cursed_artifact') &&
1519
+ * !original.inventory.includes('cursed_artifact');
1520
+ *
1521
+ * if (triggeredMadness && gotCursedItem) {
1522
+ * return '仪式完成了,但你感到理智正在崩溃,手中多了一件诅咒物品...';
1523
+ * } else if (triggeredMadness) {
1524
+ * return '仪式完成了,但代价是你的理智...';
1525
+ * } else {
1526
+ * return '仪式顺利完成。';
1527
+ * }
1528
+ * }
1480
1529
  * ```
1481
1530
  */
1482
- resultText: string | ((state: GameState<S, I, F, X>) => string);
1531
+ resultText: string | ((state: GameState<S, I, F, X>, original?: GameState<S, I, F, X>) => string);
1483
1532
  }
1484
1533
  /**
1485
1534
  * 地点定义接口 - 定义游戏中的一个地点/场景
@@ -1429,17 +1429,23 @@ interface ActionDef<S extends string, I extends string, F extends string, X = Re
1429
1429
  * 如果是函数,它会在所有效果(包括 afterEffects)执行完成后调用,
1430
1430
  * 因此可以基于最终状态生成准确的反馈文本。
1431
1431
  *
1432
+ * ⚠️ 增强功能:函数可以接收第二个参数(原始状态)
1433
+ *
1434
+ * 这允许你比较执行前后的状态变化,生成更准确的反馈文本,
1435
+ * 而无需通过 afterEffects + extra 的方式传递信息。
1436
+ *
1432
1437
  * 注意事项:
1433
1438
  * 1. 不应在这里修改游戏状态(使用 afterEffects 代替)
1434
- * 2. 函数接收的是所有效果执行后的最终状态
1435
- * 3. 返回的文本会作为 'result' 类型的日志添加到游戏日志中
1439
+ * 2. 第一个参数是所有效果执行后的最终状态
1440
+ * 3. 第二个参数是动作执行前的原始状态(可选)
1441
+ * 4. 返回的文本会作为 'result' 类型的日志添加到游戏日志中
1436
1442
  *
1437
1443
  * @example
1438
1444
  * ```typescript
1439
1445
  * // 静态文本
1440
1446
  * resultText: '你完成了探索'
1441
1447
  *
1442
- * // 动态文本 - 基于最终状态
1448
+ * // 动态文本 - 基于最终状态(单参数,向后兼容)
1443
1449
  * resultText: (state) => {
1444
1450
  * const sanity = state.stats.sanity;
1445
1451
  * if (sanity < 20) {
@@ -1451,35 +1457,78 @@ interface ActionDef<S extends string, I extends string, F extends string, X = Re
1451
1457
  * }
1452
1458
  * }
1453
1459
  *
1454
- * // 基于标记生成文本
1455
- * resultText: (state) => {
1456
- * if (state.flags.scholar_achievement) {
1457
- * return '你的知识达到了新的高度!【成就解锁:博学者】';
1458
- * }
1459
- * return '你学到了新的知识。';
1460
+ * // 比较前后状态(双参数,推荐)
1461
+ * resultText: (state, original) => {
1462
+ * const gainedGnosis = state.stats.gnosis > original.stats.gnosis;
1463
+ * return gainedGnosis
1464
+ * ? '你在冥想中获得了灵知!'
1465
+ * : '你平静地冥想了一会儿。';
1460
1466
  * }
1461
1467
  *
1462
- * // 基于多个状态生成复杂文本
1463
- * resultText: (state) => {
1464
- * const parts: string[] = ['你凝视着星空'];
1468
+ * // 显示具体的变化量
1469
+ * resultText: (state, original) => {
1470
+ * const hpChange = state.stats.hp - original.stats.hp;
1471
+ * const goldChange = state.stats.gold - original.gold;
1465
1472
  *
1466
- * if (state.world.time === 0) {
1467
- * parts.push('午夜的星空格外诡异');
1468
- * }
1473
+ * const parts: string[] = ['战斗结束'];
1469
1474
  *
1470
- * if (state.stats.sanity < 30) {
1471
- * parts.push('你看到了不该看到的东西');
1475
+ * if (hpChange < 0) {
1476
+ * parts.push(`失去了 ${-hpChange} 点生命值`);
1472
1477
  * }
1473
1478
  *
1474
- * if (state.flags.going_mad) {
1475
- * parts.push('理智正在崩溃...');
1479
+ * if (goldChange > 0) {
1480
+ * parts.push(`获得了 ${goldChange} 金币`);
1476
1481
  * }
1477
1482
  *
1478
1483
  * return parts.join(',') + '。';
1479
1484
  * }
1485
+ *
1486
+ * // 检测是否触发了特殊效果
1487
+ * resultText: (state, original) => {
1488
+ * const leveledUp = state.stats.level > original.stats.level;
1489
+ * const gotAchievement = state.flags.new_achievement && !original.flags.new_achievement;
1490
+ *
1491
+ * if (leveledUp && gotAchievement) {
1492
+ * return '恭喜升级!同时解锁了新成就!';
1493
+ * } else if (leveledUp) {
1494
+ * return '恭喜升级!';
1495
+ * } else if (gotAchievement) {
1496
+ * return '解锁了新成就!';
1497
+ * } else {
1498
+ * return '获得了经验值。';
1499
+ * }
1500
+ * }
1501
+ *
1502
+ * // 显示物品变化
1503
+ * resultText: (state, original) => {
1504
+ * const itemsGained = state.inventory.length - original.inventory.length;
1505
+ *
1506
+ * if (itemsGained > 0) {
1507
+ * const newItems = state.inventory.slice(-itemsGained);
1508
+ * return `获得了物品:${newItems.join('、')}`;
1509
+ * }
1510
+ *
1511
+ * return '打开了宝箱,但里面是空的。';
1512
+ * }
1513
+ *
1514
+ * // 条件效果的结果反馈
1515
+ * resultText: (state, original) => {
1516
+ * // 检查是否触发了条件效果
1517
+ * const triggeredMadness = state.flags.going_mad && !original.flags.going_mad;
1518
+ * const gotCursedItem = state.inventory.includes('cursed_artifact') &&
1519
+ * !original.inventory.includes('cursed_artifact');
1520
+ *
1521
+ * if (triggeredMadness && gotCursedItem) {
1522
+ * return '仪式完成了,但你感到理智正在崩溃,手中多了一件诅咒物品...';
1523
+ * } else if (triggeredMadness) {
1524
+ * return '仪式完成了,但代价是你的理智...';
1525
+ * } else {
1526
+ * return '仪式顺利完成。';
1527
+ * }
1528
+ * }
1480
1529
  * ```
1481
1530
  */
1482
- resultText: string | ((state: GameState<S, I, F, X>) => string);
1531
+ resultText: string | ((state: GameState<S, I, F, X>, original?: GameState<S, I, F, X>) => string);
1483
1532
  }
1484
1533
  /**
1485
1534
  * 地点定义接口 - 定义游戏中的一个地点/场景
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { L as LogEntry } from '../types-C3Q7UPWy.mjs';
2
+ import { L as LogEntry } from '../types-D-nDlnv3.mjs';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
 
5
5
  interface LayoutProps {
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { L as LogEntry } from '../types-C3Q7UPWy.js';
2
+ import { L as LogEntry } from '../types-D-nDlnv3.js';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
 
5
5
  interface LayoutProps {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "steamsheep-ts-game-engine",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "通用游戏引擎框架 - 基于 TypeScript 和 Zustand 构建的文字冒险/RPG 游戏引擎",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",