Project1

标题: 写了一个满足条件自动触发技能的插件,但是有点问题 [打印本页]

作者: 恍惚窒箱    时间: 2024-12-8 03:26
标题: 写了一个满足条件自动触发技能的插件,但是有点问题

求问各位大佬
起初我设计了一个技能,当角色处于异常状态时自动触发,为角色驱散所有的负面状态。测试中发现这个驱散的时机要在onTurnEnd的regenerateAll前面才行,不然中毒状态会扣一次血。于是把时机挪到了onTurnEnd的最开始。在chatgpt的帮助下写了一个插件,实现了角色处于特定状态时,在回合结束的时候自动释放技能,能够正确计算技能消耗MP。但这样又出现了几个问题。首先是技能指定目标完全是随机的,没有读取Skill.json里面写的scope,导致有时候驱散在怪身上了。然后是如果有多个技能同时满足条件时,动画会同时播放,技能释放的文本提示(就那个xxx吟唱了xxx)也是同时出现在同一个文本框中。最后是被这种方式触发的技能打死的怪不会播放死亡动画。
萌新刚接触RPGmakerMV没几天,请各位大佬指点!


JAVASCRIPT 代码复制下载
  1. /*:
  2.  * @plugindesc 自动释放技能插件,根据特定条件触发技能。
  3.  * @author chatgpt
  4.  *
  5.  * @param Trigger Skills
  6.  * @text 技能触发设置
  7.  * @desc 该设置用于定义哪些技能会触发,以及它们的触发条件。
  8.  *
  9.  * @help
  10.  * 该插件通过条件来自动触发技能。技能的条件包括:
  11.  * - 角色处于特定状态
  12.  * - 角色的生命值低于或高于一定百分比
  13.  * - 战斗进行了一定回合数
  14.  * - 技能每回合有一定概率触发
  15.  *
  16.  * 技能备注示例:
  17.  * <autoSkill: 1, state: 3>  // 角色处于状态 ID 3 时,自动释放技能 ID 1
  18.  * <autoSkill: 2, state: 3,5,7>  // 角色处于状态 ID 3、5、7 时,自动释放技能 ID 2
  19.  * <autoSkill: 3, state: 5-10>  // 角色处于状态 ID 从 5 到 10 时,自动释放技能 ID 3
  20.  * <autoSkill: 4, hpBelow: 50>  // 角色生命值低于 50% 时,自动释放技能 ID 4
  21.  * <autoSkill: 5, turnCount: 5>  // 战斗进行到第 5 回合时,自动释放技能 ID 5
  22.  * <autoSkill: 6, chance: 20>  // 每回合有 20% 的概率自动释放技能 ID 6
  23.  *
  24.  * 插件通过解析技能备注来判断是否满足条件并触发技能。
  25.  */
  26.  
  27. (function() {
  28.  
  29.     // 读取配置并生成技能触发条件列表
  30.     var autoSkills = [];
  31.  
  32.     // 解析状态ID的条件,支持单值、多值、范围
  33.     function parseStateCondition(stateStr) {
  34.         var states = [];
  35.         var parts = stateStr.split(',');
  36.         parts.forEach(part => {
  37.             if (part.includes('-')) { // 范围
  38.                 var range = part.split('-').map(Number);
  39.                 for (var i = range[0]; i <= range[1]; i++) {
  40.                     states.push(i);
  41.                 }
  42.             } else { // 单值
  43.                 states.push(Number(part));
  44.             }
  45.         });
  46.         return states;
  47.     }
  48.  
  49.     // 初始化从技能备注中读取条件
  50.     function parseSkillConditions(skill) {
  51.         var note = skill.note;
  52.         var conditions = [];
  53.  
  54.         // 条件 A: 角色处于指定状态
  55.         if (note.match(/<autoSkill:\s*state:\s*([\d,-]+)>/)) {
  56.             conditions.push({
  57.                 type: 'state',
  58.                 stateIds: parseStateCondition(RegExp.$1),
  59.                 skillId: skill.id // 记录技能 ID
  60.             });
  61.         }
  62.  
  63.         // 条件 B: 角色生命值低于或高于百分比
  64.         if (note.match(/<autoSkill:\s*hpBelow:\s*(\d+)>/)) {
  65.             conditions.push({
  66.                 type: 'hpBelow',
  67.                 hpPercentage: parseInt(RegExp.$1),
  68.                 skillId: skill.id
  69.             });
  70.         }
  71.  
  72.         if (note.match(/<autoSkill:\s*hpAbove:\s*(\d+)>/)) {
  73.             conditions.push({
  74.                 type: 'hpAbove',
  75.                 hpPercentage: parseInt(RegExp.$1),
  76.                 skillId: skill.id
  77.             });
  78.         }
  79.  
  80.         // 条件 C: 战斗进行的回合数
  81.         if (note.match(/<autoSkill:\s*turnCount:\s*(\d+)>/)) {
  82.             conditions.push({
  83.                 type: 'turnCount',
  84.                 turnCount: parseInt(RegExp.$1),
  85.                 skillId: skill.id
  86.             });
  87.         }
  88.  
  89.         // 条件 D: 每回合有一定概率触发
  90.         if (note.match(/<autoSkill:\s*chance:\s*(\d+)>/)) {
  91.             conditions.push({
  92.                 type: 'chance',
  93.                 chance: parseInt(RegExp.$1),
  94.                 skillId: skill.id
  95.             });
  96.         }
  97.  
  98.         return conditions;
  99.     }
  100.  
  101.     // 读取所有技能并解析其条件
  102.     Game_Battler.prototype.loadAutoSkills = function() {
  103.         if (autoSkills.length === 0) {
  104.             $dataSkills.forEach(skill => {
  105.                 if (skill) {
  106.                     var conditions = parseSkillConditions(skill);
  107.                     conditions.forEach(condition => {
  108.                         autoSkills.push(condition);
  109.                     });
  110.                 }
  111.             });
  112.         }
  113.     };
  114.  
  115. // 增加对 _autoSkillsToTrigger 的检查,确保它是数组
  116. var _Game_Battler_onTurnEnd = Game_Battler.prototype.onTurnEnd;
  117. Game_Battler.prototype.onTurnEnd = function() {
  118.     this.loadAutoSkills();
  119.  
  120.     // 初始化 _autoSkillsToTrigger 如果它是 undefined
  121.     if (!this._autoSkillsToTrigger) {
  122.         this._autoSkillsToTrigger = [];
  123.     }
  124.  
  125.     // 遍历技能触发条件
  126.     autoSkills.forEach(condition => {
  127.         switch (condition.type) {
  128.             case 'state':
  129.                 if (condition.stateIds.some(stateId => this.isStateAffected(stateId))) {
  130.                     this._autoSkillsToTrigger.push(condition.skillId); // 记录待触发的技能ID
  131.                 }
  132.                 break;
  133.             case 'hpBelow':
  134.                 if (this.hpRate() <= condition.hpPercentage / 100) {
  135.                     this._autoSkillsToTrigger.push(condition.skillId);
  136.                 }
  137.                 break;
  138.             case 'hpAbove':
  139.                 if (this.hpRate() > condition.hpPercentage / 100) {
  140.                     this._autoSkillsToTrigger.push(condition.skillId);
  141.                 }
  142.                 break;
  143.             case 'turnCount':
  144.                 if ($gameTroop.turnCount >= condition.turnCount) {
  145.                     this._autoSkillsToTrigger.push(condition.skillId);
  146.                 }
  147.                 break;
  148.             case 'chance':
  149.                 if (Math.random() * 100 < condition.chance) {
  150.                     this._autoSkillsToTrigger.push(condition.skillId);
  151.                 }
  152.                 break;
  153.         }
  154.     });
  155.  
  156.     // 在 onTurnEnd 前触发技能
  157.     // 依次触发所有技能
  158.     this._autoSkillsToTrigger.forEach(skillId => {
  159.         var skill = $dataSkills[skillId];
  160.         if (skill) {
  161.             var action = new Game_Action(this);
  162.             action.setSkill(skillId);
  163.  
  164.             // 选择目标(根据技能的 scope)
  165.  
  166.             var targets = action.makeTargets();
  167.  
  168.             if (targets.length > 0) {
  169.                 // 触发技能动画
  170.                 targets.forEach(target => {
  171.                     target.startAnimation(skill.animationId); // 播放技能动画
  172.                 });
  173.  
  174.                 // 应用技能效果
  175.                 action.apply(targets[0]);
  176.  
  177.                 // 显示技能文本
  178.                 if (skill.message1) {
  179.                     $gameMessage.add(skill.message1); // 显示释放文本
  180.                 }
  181.                 if (skill.message2) {
  182.                     $gameMessage.setPositionType(0)
  183.                     $gameMessage.add(skill.message2); // 显示释放文本
  184.                 }
  185.  
  186.                 // 消耗技能的资源(例如 MP)
  187.                 this.paySkillCost(skill);
  188.  
  189.                 // 如果技能有触发的公共事件,执行
  190.                 if (skill.meta.TriggerEvent) {
  191.                     $gameTemp.reserveCommonEvent(Number(skill.meta.TriggerEvent)); // 执行公共事件
  192.                 }
  193.             }
  194.         }
  195.     });
  196.  
  197.     // 清空待触发技能
  198.     this._autoSkillsToTrigger = null;
  199.  
  200.     // 执行原本的 onTurnEnd 逻辑
  201.     _Game_Battler_onTurnEnd.call(this);
  202. };
  203.  
  204. })();

插件内容

作者: 恍惚窒箱    时间: 2024-12-8 03:31
貌似我上传的代码起始行有点问题,非常抱歉!
如果已经有现成的插件可以实现我想实现的功能的话,请告诉我!
做完这个技能后,我还想搞搞领域之类的技能,例如释放后三回合内,每回合开始/结束执行一定效果。我要学习的还有很多啊……
作者: qq1217066367    时间: 2024-12-12 19:42
yep状态分类插件,前置yep状态插件;设计一个被动,当角色获得异常状态时,自动解除异常状态,异常状态的分类名字和包括的状态都可以通过这插件自己写
作者: qq1217066367    时间: 2024-12-12 20:23
或者反着来,将驱散异常的状态分类为驱散,在异常状态里备注如果有驱散,则移除所有异常状态
作者: 恍惚窒箱    时间: 2024-12-12 20:37
qq1217066367 发表于 2024-12-12 20:23
或者反着来,将驱散异常的状态分类为驱散,在异常状态里备注如果有驱散,则移除所有异常状态 ...

感谢!这几天我自己学了一下YEP,已经实现了!




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1