逆向:程序研究/AT1/事件处理例程

来自歌颂之丘
跳转到导航 跳转到搜索

AT的事件处理/触发例程。

AT有一个EventCheck函数来检查事件的触发。该例程接受一个枚举值来确认触发的类型。

EventCheck 通常由一个包装函数调用,该包装函数会设置触发类型的枚举值。并对另一参数设定一个值。

此外,夜会话也有一套处理例程来管理其触发。并且部分会触发事件[1]而非夜会话事件[2]

EventCheck

日版地址:197214。

首先读取半字A7A7C8,如果大于0则表示事件执行中,该函数会报错:Event Doing... EventCheck Canceled. %d并退出。%d为此次触发的事件类型,是ECC枚举值的数值表示。

如果提供的检查参数大于等于 ECC_ALL,则不进行判断,直接开始事件执行【?需要检查】 、

a3 - 若为0 ,则EventCheck不会调用EventExecFile。

EventCheck检查一个EventCondList,EventCondList和evd一一对应。每个EventCondList记录对应一个evd的触发条件。

ECC 枚举值

  1. ECC_WORLDMAP
  2. ECC_WORLDMAP_P
  3. ECC_WORLDMAP_A
  4. ECC_GET_ITEM
  5. ECC_QVM QvMap任何事件触发时触发
  6. ECC_MIX
  7. ECC_PROGRAM
  8. ECC_TOWN
  9. ECC_QVM_CHG :QvMap 变更时触发。a1:变更前地图编号,a2:变更后地图编号,a3:总是为1
  10. ECC_QVM_CHG_BEFORE
  11. ECC_QVM_T
  12. ECC_QVM_T_BEFORE
  13. ECC_EVENT_END
  14. ECC_W_QVM
  15. ECC_W_QVM_BEFORE
  16. ECC_QVM_W_BEFORE
  17. ECC_W_T
  18. ECC_T_W
  19. ECC_T_W_BEFORE
  20. ECC_T_QVM
  21. ECC_T_QVM_BEFORE
  22. ECC_QVCHARA
  23. ECC_QVG_HIT
  24. ECC_QVG_BREAK
  25. ECC_QVG_EXEC
  26. ECC_SHOP_END
  27. ECC_WARP
  28. ECC_SPIRITUAL
  29. ECC_SPIRITUAL_IN
  30. ECC_SPIRITUAL_REJECT
  31. ECC_SPIRITUAL_OUT
  32. ECC_TALK
  33. ECC_SLEEP
  34. ECC_ALL
  35. ECC_NO_CHECK
  36. MAX_ECC

EventCondList

日版位置:0x74CA50


    <struct name='EventTriggerGroup'>
        <field type='int8' name='grp' />
        <field type='int8' name='enable' />
        <field type='int8' name='repeatable' />
        <field type='int8' name='qvtrigger' />
        <field type='int8' name='ukn_flg1' />
        <field type='int8' name='ukn_flg2' />
        <field type='int8' name='rt_chk_flg' />
        <field type='int8' name='ukn_flg3' />
        <field type='EventCond[]*' name='grp1' />
        <field type='EventCond[]*' name='grp2' />
        <field type='EventCond[]*' name='grp3' />
        <field type='EventCond[]*' name='grp4' />
        <field type='EventCond[]*' name='grp5' />
    </struct>

grp,编组,目前不知道有何作用,似乎从未被使用(看上去可以用来优化判断??

enable,启用,未使用,所有事件都处于启用状态

repeatable,事件是否可重复触发。若为0则只可被触发一次。

qvtrigger?未确认,Qv上的检查检查此项,若为0则会忽略此触发。【在需要Qv触发的记录中找到0,该项可能有其他意义】

grp1-5,触发条件组。任意一组条件为真则该规则为真,触发对应事件。若为NULL则为假。(DNF

触发条件组

一个以0x7FFFFF49为结束的列表。0x7FFFFF00以上的为条件宏。后跟数量不定的参数。每个条件宏的求值结果均需为真则此条件组才为真。

触发条件宏
  1. EVENT_FLAG 检查指定事件的旗标是否设置
  2. EVENT_RISE 检查指定事件是否已经实行
  3. EVENT_RISE_N 检查指定事件是否尚未被实行
  4. EVENT_RISE_U 指定事件执行次数大于
  5. EVENT_RISE_D ~小于
  6. EVENT_RISE_EQ ~等于
  7. FRIEND_PRM_U
  8. FRIEND_PRM_D
  9. FRIEND_PRM_EQ
  10. ITEM_CNT_U 物品数量大于
  11. ITEM_CNT_D ~小于
  12. ITEM_CNT_EQ ~等于
  13. MYPARAM_U
  14. MYPARAM_D
  15. MYPARAM_EQ
  16. PARTY_EXIST 指定角色在队
  17. PARTY_EXIST_N 指定角色不在队
  18. QV
  19. QV_XYZ_AREA Qv地图XYZ区域
  20. FIELD_POINTER
  21. ASSIST_MIXING
  22. RT_GD_U
  23. RT_GD_D
  24. RT_GD_EQ
  25. RT_MP_U
  26. RT_MP_D
  27. RT_MP_EQ
  28. RT_MAGIC_Y
  29. RT_MAGIC_N
  30. RT_ACC_SLV_U
  31. RT_ACC_SLV_D
  32. RT_ACC_SLV_EQ
  33. MISYA_CHIBI 检查弥纱是否是小的
  34. MISYA_DEKA 检查弥纱是否是大的
  35. WIN_MIKO_U 检查光之巫女战胜次数大于
  36. WIN_MIKO_D ~小于
  37. WIN_MIKO_EQ ~等于
  38. ZTRG_ZTRG_FIELD
  39. ZTRG_ZTRG_FIELD_POINTER
  40. ZTRG_ZTRG_FIELD_POINTER_A
  41. ZTRG_ZTRG_ITEM_GET 获得指定物品触发
  42. ZTRG_ZTRG_MASTER_DIR_A
  43. ZTRG_ZTRG_MIX
  44. ZTRG_ZTRG_PROGRAM 由程序直接进行触发
  45. ZTRG_ZTRG_QV
  46. ZTRG_ZTRG_TOWN
  47. ZTRG_ZTRG_QV_A2B
  48. ZTRG_ZTRG_QV_TOWN_A2B
  49. ZTRG_ZTRG_QV_CHG
  50. ZTRG_ZTRG_QV_TOWN_CHG
  51. ZTRG_ZTRG_QV_BASE
  52. ZTRG_ZTRG_EVENT_FINISH
  53. ZTRG_ZTRG_QV_FROM_FIELD
  54. ZTRG_ZTRG_TOWN_FROM_FIELD
  55. ZTRG_ZTRG_QV_TO_FIELD
  56. ZTRG_ZTRG_FIELD_FROM_TOWN
  57. ZTRG_ZTRG_FIELD_TOWN_A2B
  58. ZTRG_ZTRG_QV_FROM_TOWN
  59. ZTRG_ZTRG_TOWN_QV_A2B
  60. ZTRG_ZTRG_QVC_XYZ 进入指定QvMap区域触发
  61. ZTRG_ZTRG_QVC_TALK
  62. ZTRG_ZTRG_QVC_TALK_XYZ
  63. ZTRG_ZTRG_SHOP_END 指定的商店触发
  64. ZTRG_ZTRG_WARP
  65. ZTRG_ZTRG_SLEEP
  66. ZTRG_ZTRG_GIMMICK_BREAK 场景(区域地图)物件被破坏时触发
  67. ZTRG_ZTRG_GIMMICK_ATTACK
  68. ZTRG_ZTRG_GIMMICK_EXEC 场景物件被调查时触发
  69. ZTRG_ZTRG_DPOINT_ACCESS
  70. ZTRG_ZTRG_SWORLD_ACCESS
  71. ZTRG_ZTRG_SWORLD_ACCESS_REJECT
  72. ZTRG_ZTRG_SWORLD_EXIT
  73. ZTRG_ZTRG_TALK_ON

EventExecFile

加载一个逆向:程序研究/AT1/Evd文件并执行其中的宏序列。

主动夜会话触发检查

夜会话也有一套触发检查用的数据。登记为mk_trig_metadata。还有触发之后的数据记录,MkTrigSaveData。

MkTrigSaveData

保存数据之一。位置可通过保存数据表确认。

struct MkTrigSaveDatum {uint32_t flg; uint32_t expire;}

记录两个数据。flg用于记录该事件是否被标记需要触发/抑制等信息。休息时检查这个标志,如果为2就会触发对应的对话。expire记录事件过期时间,和ManaClock做比较。ManaClock似乎总是0,该机制如何生效仍需进一步检查。

mk_trig_metadata

日版位置:0x7359B0

下记条件登记为-1的表示不检查此条件。

<struct name='MusumeKaiwaTrigCond'>
  <field type='uint16' name='character' />
  <field type='uint16' name='mkdata_id' /> <!-- 触发时调用的mkdata,为-1表示不适用 -->
  <field type='uint16' name='evd_id' /> <!-- 触发时调用的evd,为-1表示不适用 -->
  <field type='uint16' name='chk_type' /> <!-- 类型?排他性标记?优先级? -->
  <field type='uint16' name='ukn' />
  <field type='uint16' name='evd_not_cond' /> <!-- 抑制evd,为-1表示不检查。一旦指定evd被调用此会话就不再可以触发 -->
  <field type='uint16' name='evd_req_cond' /> <!-- 前置evd,为-1表示不检查,否则前置evd必须首先运行才可触发本会话 -->
  <field type='uint16' name='ukn' />
  <field type='uint16' name='ukn' />
  <field type='uint16' name='para1' /> <!-- 含义变化的参数/chk_type==0xA, 持有指定物品 -->
  <field type='uint16' name='para2' /> <!-- 含义变化的参数/check_tyep==0xA时:持有指定数量 -->
</struct>

chk_type

方式1

计算和RT对应的TriggerData中,连续五个字节的记录值,小于para1的个数。计数结果若小于para2,则不动作。否则设定对应项为准备触发。

  • para1 比较对象(标记需要小于此值才通过)
  • para2 数量要求
方式10

检查物品ID为para1的物品数量是否有para2个。若有则标记需要触发。

注释

  1. 指保存在evd中的事件
  2. 指保存在ELF中的对话数据