じ☆ve冰风 发表于 2026-2-20 05:16:42

行吧,也算转MZ了,发个插件玩玩(数据库狂野模式)

JAVASCRIPT 代码
/*:zh
* @target MZ
* @plugindesc 利用备注中的 meta 数据,覆盖数据库对象的原有属性
* @author SailCat
* @help WildMetaData.js
* v 1.0.0
*
* 此插件会在数据库对象(如角色、职业、敌人、物品等)加载完成后,
* 遍历其 meta 对象中的每个键值对。
* 如果该键名是对象本身已有的属性名,则用 meta 中对应的值覆盖该属性,
* 若值无法转成原属性所需求的类型,则无事发生。
* 此插件的意义在于突破编辑器对部分字段的值限制。
*
* 例如,在角色的备注中写 ,
* 插件会将 $dataActors.initialLevel 的值从原来的数字改为 30。
* 在职业的备注中写 ,
* 插件会将这个职业的经验值曲线改为每级需要固定100点。
*
* 注意:覆盖后可能影响游戏平衡,请谨慎使用。
*
*/

(() => {
    'use strict';

    // 保存原始的 DataManager.extractArrayMetadata 方法
    const sailcat_mz_DataManager_extractMetaData = DataManager.extractMetadata;

    /**
   * 重写 DataManager.onLoad,在处理完数据库对象后应用 meta 覆盖。
   */
    DataManager.extractMetadata = function(data){
      // 先调用原方法,保证对象的 meta 已经被正确提取
      sailcat_mz_DataManager_extractMetaData.call(this, data);

      // 对加载的对象应用 meta 覆盖
      applyMetaOverrides(data);
    };

    /**
   * 对单个对象应用 meta 覆盖。
   * @param {Object} obj - 数据库对象(如角色、物品、地图等)
   */
    function applyMetaOverrides(obj){
      // 如果对象没有 meta 或者 meta 为空,直接返回
      if(!obj || typeof obj !== 'object' || !obj.meta)return;

      const meta = obj.meta;

      // 遍历 meta 的每个键
      for(const key in meta){
            if(!meta.hasOwnProperty(key))continue;

            // 检查该键名是否是对象本身的属性(即已存在的属性)
            if(obj.hasOwnProperty(key)){
                const originalValue = obj;
                const metaValueStr = meta;   // meta 中的值永远是字符串

                // 将字符串转换为与原属性相同的类型
                const convertedValue = convertValue(originalValue, metaValueStr);

                // 如果转换成功(不是 undefined),则覆盖原属性
                if(convertedValue !== undefined){
                  obj = convertedValue;
                }
            }
      }
    }

    /**
   * 将字符串值转换为与原始值相同的类型。
   * @param {*} original - 对象的原属性值
   * @param {string} str - meta 中读取的字符串
   * @returns {*} 转换后的值,如果无法转换则返回 undefined
   */
    function convertValue(original, str){
      // 根据原始值的类型进行转换
      const type = typeof original;

      if(type === 'number'){
            const num = Number(str);
            return isNaN(num) ? undefined : num;
      }

      if(type === 'string'){
            return String(str);
      }

      if(type === 'boolean'){
            // 常见布尔字符串表示:true/false, 1/0, yes/no, y/n, t/f
            const lower = str.toLowerCase();
            if(lower === 'true' || lower === '1' || lower === 'yes' || lower === 't' || lower === 'y')returntrue;
            if(lower === 'false' || lower === '0' || lower === 'no' || lower === 'f' || lower === 'n')returnfalse;
            return undefined; // 无法识别
      }

      if(Array.isArray(original)){
            try{
                // 尝试解析为数组,例如 ""
                const parsed = JSON.parse(str);
                if(Array.isArray(parsed))return parsed;
            }catch(e){
                // 解析失败,忽略
            }
            return undefined;
      }

      if(type === 'object' && original !== null){
            try{
                // 尝试解析为对象,例如 "{"x":1}"
                const parsed = JSON.parse(str);
                if(typeof parsed === 'object' && parsed !== null)return parsed;
            }catch(e){
                // 解析失败
            }
            return undefined;
      }

      // 对于 null、undefined 或其他无法处理的类型,直接返回 undefined 表示不覆盖
      return undefined;
    }

})();

            本帖来自P1论坛作者来自网络,因Project1站服务器在国外有时候访问缓慢不方便作者交流学习,经联系P1站长fux2同意署名转载一起分享游戏制作经验,共同为国内独立游戏作者共同创造良好交流环境,原文地址:https://rpg.blue/forum.php?mod=viewthread&tid=498615若有侵权,发帖作者可联系底部站长QQ在线咨询功能删除,谢谢。
页: [1]
查看完整版本: 行吧,也算转MZ了,发个插件玩玩(数据库狂野模式)