diff --git a/_server/comment.js b/_server/comment.js index e7e80b72..72474062 100644 --- a/_server/comment.js +++ b/_server/comment.js @@ -1,14 +1,14 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = { - "_leaf": false, + "_type": "object", "_data": { "items": { - "_leaf": false, + "_type": "object", "_data": { "items": { - "_leaf": false, + "_type": "object", "_data": { "cls": { @@ -89,7 +89,7 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = }, "items_template" : {'cls': 'items', 'name': '新物品'}, "enemys": { - "_leaf": false, + "_type": "object", "_data": { "name": { @@ -197,7 +197,7 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = }, "enemys_template" : {'name': '新敌人', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, "maps": { - "_leaf": false, + "_type": "object", "_data": { "id": { @@ -271,11 +271,11 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = } }, "floors": { - "_leaf": false, + "_type": "object", "_data": { "floor": { - "_leaf": false, + "_type": "object", "_data": { "floorId": { @@ -407,7 +407,7 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = } }, "loc": { - "_leaf": false, + "_type": "object", "_data": { "events": { diff --git a/_server/data.comment.js b/_server/data.comment.js index 17cad58a..8f157bcf 100644 --- a/_server/data.comment.js +++ b/_server/data.comment.js @@ -1,10 +1,10 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = { - "_leaf": false, + "_type": "object", "_data": { "main": { - "_leaf": false, + "_type": "object", "_data": { "floorIds": { @@ -125,7 +125,7 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = } }, "firstData": { - "_leaf": false, + "_type": "object", "_data": { "title": { @@ -154,7 +154,7 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_data": "初始楼层的ID" }, "hero": { - "_leaf": false, + "_type": "object", "_data": { "name": { @@ -214,7 +214,7 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_data": "初始装上的装备,此处建议请直接留空数组" }, "items": { - "_leaf": false, + "_type": "object", "_data": { "keys": { @@ -245,7 +245,7 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_data": "初始可飞的楼层;一般留空数组即可" }, "loc": { - "_leaf": false, + "_type": "object", "_data": { "direction": { @@ -316,7 +316,7 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = } }, "values": { - "_leaf": false, + "_type": "object", "_data": { "lavaDamage": { @@ -407,7 +407,7 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = } }, "flags": { - "_leaf": false, + "_type": "object", "_data": { "enableFloor": { diff --git a/_server/editor_file.js b/_server/editor_file.js index 0304d2f1..2fe185c5 100644 --- a/_server/editor_file.js +++ b/_server/editor_file.js @@ -82,7 +82,7 @@ editor_file = function (editor, callback) { callback('未选中文件或无数据'); } */ var filename = 'project/floors/' + editor.currentFloorId + '.js'; - var datastr = ['main.floors.', editor.currentFloorId, '=\n{']; + var datastr = ['main.floors.', editor.currentFloorId, '=\n']; if (editor.currentFloorData.map == 'new') { /* editor.currentFloorData.map = editor.map.map(function (v) { @@ -108,14 +108,18 @@ editor_file = function (editor, callback) { editor.currentFloorData[name]=mapArray; } } - for (var ii in editor.currentFloorData) - if (editor.currentFloorData.hasOwnProperty(ii)) { - if (['map','bgmap','fgmap'].indexOf(ii)!==-1) - datastr = datastr.concat(['\n"', ii, '": [\n', formatMap(editor.currentFloorData[ii],ii!='map'), '\n],']); - else - datastr = datastr.concat(['\n"', ii, '": ', JSON.stringify(editor.currentFloorData[ii], null, 4), ',']); - } - datastr = datastr.concat(['\n}']); + // format 更改实现方式以支持undefined删除 + var tempJsonObj=Object.assign({},editor.currentFloorData); + var tempMap=[['map',editor.guid()],['bgmap',editor.guid()],['fgmap',editor.guid()]]; + tempMap.forEach(function(v){ + v[2]=tempJsonObj[v[0]]; + tempJsonObj[v[0]]=v[1]; + }); + var tempJson=JSON.stringify(tempJsonObj, null, 4); + tempMap.forEach(function(v){ + tempJson=tempJson.replace('"'+v[1]+'"','[\n'+ formatMap(v[2],v[0]!='map')+ '\n]') + }); + datastr = datastr.concat([tempJson]); datastr = datastr.join(''); alertWhenCompress(); fs.writeFile(filename, encode(datastr), 'base64', function (err, data) { @@ -626,7 +630,7 @@ editor_file = function (editor, callback) { actionList.forEach(function (value) { value[1] = value[1] + "['" + x + "," + y + "']"; }); - saveSetting('floors', actionList, function (err) { + saveSetting('floorloc', actionList, function (err) { callback([ (function () { var locObj = {}; @@ -745,7 +749,7 @@ editor_file = function (editor, callback) { if (isset(editor.main[v])) locObj.main[v] = data_obj.main[v]; else - locObj[v] = null; + locObj.main[v] = null; }); return locObj; })(), @@ -761,7 +765,7 @@ editor_file = function (editor, callback) { if (isset(editor.main[v])) locObj.main[v] = data_obj.main[v]; else - locObj[v] = null; + locObj.main[v] = null; }); return locObj; })(), @@ -976,13 +980,18 @@ editor_file = function (editor, callback) { }); return; } - if (file == 'floors') { + if (file == 'floorloc') { actionList.forEach(function (value) { // 检测null/undefined - if (core.isset(value[2])) - eval("editor.currentFloorData" + value[1] + '=' + JSON.stringify(value[2])); - else - eval("delete editor.currentFloorData"+value[1]); + if (!core.isset(value[2]))value[2]=undefined; + eval("editor.currentFloorData" + value[1] + '=' + JSON.stringify(value[2])); + }); + editor_file.saveFloorFile(callback); + return; + } + if (file == 'floors') { + actionList.forEach(function (value) { + eval("editor.currentFloorData" + value[1] + '=' + JSON.stringify(value[2])); }); editor_file.saveFloorFile(callback); return; diff --git a/_server/editor_mode.js b/_server/editor_mode.js index 63cf5fce..45dd604f 100644 --- a/_server/editor_mode.js +++ b/_server/editor_mode.js @@ -18,6 +18,7 @@ editor_mode = function (editor) { this.mode = ''; this.info = {}; this.appendPic = {}; + this.doubleClickMode='change'; } editor_mode.prototype.init = function (callback) { @@ -91,9 +92,25 @@ editor_mode = function (editor) { * @param {Object} pcobj */ var recursionParse = function (pfield, pcfield, pvobj, pcobj) { + var keysForTableOrder={}; + var voidMark={}; // 1. 按照pcobj排序生成 + if (pcobj && pcobj['_data']){ + for (var ii in pcobj['_data']) keysForTableOrder[ii]=voidMark; + } // 2. 对每个pvobj且不在pcobj的,再添加到最后 - var generate = function (ii) { + keysForTableOrder=Object.assign(keysForTableOrder,pvobj) + for (var ii in keysForTableOrder) { + // 3. 对于pcobj有但是pvobj中没有的, 弹出提示, (正常情况下editor_file会补全成null) + // 事实上能执行到这一步工程没崩掉打不开,就继续吧.. + if(keysForTableOrder[ii]===voidMark){ + if(typeof id_815975ad_ee6f_4684_aac7_397b7e392702==="undefined"){ + alert('comment和data不匹配,请在群 HTML5造塔技术交流群 959329661 内反馈') + console.error('comment和data不匹配,请在群 HTML5造塔技术交流群 959329661 内反馈') + id_815975ad_ee6f_4684_aac7_397b7e392702=1; + } + pvobj[ii]=null; + } var field = pfield + "['" + ii + "']"; var cfield = pcfield + "['_data']['" + ii + "']"; var vobj = pvobj[ii]; @@ -113,7 +130,7 @@ editor_mode = function (editor) { if (cobj[key] instanceof Function) cobj[key] = cobj[key](args); } // 标记为_hide的属性不展示 - if (cobj._hide) return; + if (cobj._hide)continue; if (!cobj._leaf) { // 不是叶节点时, 插入展开的标记并继续遍历, 此处可以改成按钮用来添加新项或折叠等 outstr.push(["--------", field, "\n"].join('')); @@ -125,24 +142,18 @@ editor_mode = function (editor) { guids.push(leafnode[1]); } } - - var done = {}; - if (pcobj && pcobj['_data']) { - for (var ii in pcobj['_data']) { - generate(ii); - done[ii] = true; - } - } - for (var ii in pvobj) { - if (done[ii]) continue; - generate(ii); - } } // 开始遍历 recursionParse("", "", obj, commentObj); - var checkRange = function (evalstr, thiseval) { - if (evalstr) { - return eval(evalstr); + var checkRange = function (cobj, thiseval) { + if (cobj._range) { + return eval(cobj._range); + } + if (cobj._select) { + return cobj._select.values.indexOf(thiseval)!==-1; + } + if (cobj._bool) { + return [true,false].indexOf(thiseval)!==-1; } return true; } @@ -156,12 +167,12 @@ editor_mode = function (editor) { var input = thisTr.children[2].children[0].children[0]; var field = thisTr.children[0].getAttribute('title'); var cobj = JSON.parse(thisTr.children[1].getAttribute('cobj')); + var modeNode = thisTr.parentNode; + while (!editor_mode._ids.hasOwnProperty(modeNode.getAttribute('id'))) { + modeNode = modeNode.parentNode; + } input.onchange = function () { - var node = thisTr.parentNode; - while (!editor_mode._ids.hasOwnProperty(node.getAttribute('id'))) { - node = node.parentNode; - } - editor_mode.onmode(editor_mode._ids[node.getAttribute('id')]); + editor_mode.onmode(editor_mode._ids[modeNode.getAttribute('id')]); var thiseval = null; if (input.checked != null) input.value = input.checked; try { @@ -170,16 +181,31 @@ editor_mode = function (editor) { printe(field + ' : ' + ee); throw ee; } - if (checkRange(cobj._range, thiseval)) { + if (checkRange(cobj, thiseval)) { editor_mode.addAction(['change', field, thiseval]); - editor_mode.onmode('save');//自动保存 + editor_mode.onmode('save');//自动保存 删掉此行的话点保存按钮才会保存 } else { printe(field + ' : 输入的值不合要求,请鼠标放置在注释上查看说明'); } } + // 双击表格时 + // 正常编辑: 尝试用事件编辑器或多行文本编辑器打开 + // 添加: 在该项的同一级创建一个内容为null新的项, 刷新后生效并可以继续编辑 + // 删除: 删除该项, 刷新后生效 + // 在点击按钮 添加/删除 后,下一次双击将被视为 添加/删除 var dblclickfunc=function () { - if (cobj._type === 'event') editor_blockly.import(guid, {type: cobj._event}); - if (cobj._type === 'textarea') editor_multi.import(guid, {lint: cobj._lint, string: cobj._string}); + if(editor_mode.doubleClickMode==='change'){ + if (cobj._type === 'event') editor_blockly.import(guid, {type: cobj._event}); + if (cobj._type === 'textarea') editor_multi.import(guid, {lint: cobj._lint, string: cobj._string}); + } + if(editor_mode.doubleClickMode==='add'){ + editor_mode.doubleClickMode='change'; + addfunc() + } + if(editor_mode.doubleClickMode==='delete'){ + editor_mode.doubleClickMode='change'; + deletefunc() + } } input.ondblclick = dblclickfunc var doubleClickCheck=[0]; @@ -191,6 +217,46 @@ editor_mode = function (editor) { dblclickfunc() } } + var deletefunc=function(){ + editor_mode.onmode(editor_mode._ids[modeNode.getAttribute('id')]); + if (checkRange(cobj, null)) { + editor_mode.addAction(['delete', field, undefined]); + editor_mode.onmode('save');//自动保存 删掉此行的话点保存按钮才会保存 + } else { + printe(field + ' : 该值不允许为null,无法删除'); + } + } + var addfunc=function(){ + editor_mode.onmode(editor_mode._ids[modeNode.getAttribute('id')]); + // 1.输入id + var newid=prompt('请输入新项的id','newid'); + // 2.检查id是否符合规范或与已有id重复 + if (!/^[a-zA-Z0-9_]+$/.test(newid)){ + printe('id不符合规范, 请使用大小写字母数字下划线来构成'); + return; + } + var conflict=true; + var basefield=field.replace(/\[[^\[]*\]$/,''); + if (basefield==="['main']"){ + printe("全塔属性 ~ ['main'] 不允许添加新值"); + return; + } + try { + var baseobj=eval('obj'+basefield); + conflict=newid in baseobj; + } catch (ee) { + // 理论上这里不会发生错误 + printe(ee); + throw ee; + } + if (conflict){ + printe('id已存在, 请直接修改该项的值'); + return; + } + // 3.添加 + editor_mode.addAction(['add',basefield+"['"+newid+"']",null]); + editor_mode.onmode('save');//自动保存 删掉此行的话点保存按钮才会保存 + } }); } return {"HTML": outstr.join(''), "guids": guids, "listen": listen}; @@ -212,7 +278,7 @@ editor_mode = function (editor) { editor_mode.prototype.objToTr_ = function (obj, commentObj, field, cfield, vobj, cobj) { var guid = editor.guid(); var thiseval = vobj; - var comment = cobj._data; + var comment = String(cobj._data); var charlength = 10; // "['a']['b']" => "b" @@ -239,7 +305,6 @@ editor_mode = function (editor) { editor_mode.prototype.objToTd_ = function (obj, commentObj, field, cfield, vobj, cobj) { var thiseval = vobj; - if (thiseval === undefined) thiseval = null; if (cobj._select) { var values = cobj._select.values; var outstr = ['