diff --git a/_server/blockly/MotaAction.g4 b/_server/blockly/MotaAction.g4 index b96e4290..5650453f 100644 --- a/_server/blockly/MotaAction.g4 +++ b/_server/blockly/MotaAction.g4 @@ -257,6 +257,7 @@ action | changeFloor_s | changePos_0_s | changePos_1_s + | useItem_s | openShop_s | disableShop_s | follow_s @@ -951,6 +952,19 @@ var code = '{"type": "changePos", "direction": "'+Direction_List_0+'"},\n'; return code; */; +useItem_s + : '使用道具' IdString Newline + + +/* useItem_s +tooltip : useItem: 使用道具 +helpUrl : https://h5mota.com/games/template/docs/#/event?id=useItem%ef%bc%9a%e4%bd%bf%e7%94%a8%e9%81%93%e5%85%b7 +colour : this.dataColor +default : ["pickaxe"] +var code = '{"type": "useItem", "id": "'+IdString_0+'"},\n'; +return code; +*/; + openShop_s : '打开全局商店' IdString Newline @@ -1794,8 +1808,8 @@ Floor_Meta_List /*Floor_Meta_List ['title','name','canFlyTo', 'canUseQuickShop', 'cannotViewMap', 'cannotMoveDirectly', 'defaultGround', 'images', 'item_ratio', 'upFloor', 'downFloor', 'bgm', 'color', 'weather', 'underGround']*/; Global_Attribute_List - : '全局字体'|'横屏左侧状态栏背景'|'竖屏上方状态栏背景'|'竖屏下方道具栏背景'|'边框颜色'|'状态栏文字色'|'难度显示文字色'|'楼层转换背景'|'楼层转换文字色' - /*Global_Attribute_List ['font','statusLeftBackground','statusTopBackground', 'toolsBackground', 'borderColor', 'statusBarColor', 'hardLabelColor', 'floorChangingBackground', 'floorChangingTextColor']*/; + : '全局字体'|'横屏左侧状态栏背景'|'竖屏上方状态栏背景'|'竖屏下方道具栏背景'|'边框颜色'|'状态栏文字色'|'难度显示文字色'|'楼层转换背景'|'楼层转换文字色'|'装备列表' + /*Global_Attribute_List ['font','statusLeftBackground','statusTopBackground', 'toolsBackground', 'borderColor', 'statusBarColor', 'hardLabelColor', 'floorChangingBackground', 'floorChangingTextColor', 'equipName']*/; Global_Value_List : '血网伤害'|'中毒伤害'|'衰弱效果'|'红宝石效果'|'蓝宝石效果'|'绿宝石效果'|'红血瓶效果'|'蓝血瓶效果'|'黄血瓶效果'|'绿血瓶效果'|'破甲比例'|'反击比例'|'净化比例'|'仇恨增加值'|'行走速度'|'动画时间'|'楼层切换时间' @@ -2205,7 +2219,7 @@ ActionParser.prototype.parseAction = function() { case "showImage": // 显示图片 data.loc=data.loc||['',''] this.next = MotaActionBlocks['showImage_s'].xmlText([ - data.code,data.image,data.loc[0],data.loc[1],data.dw,data.dh,data.opacity,data.time||0,data.async||false,this.next]); + data.code,data.image||data.name,data.loc[0],data.loc[1],data.dw,data.dh,data.opacity,data.time||0,data.async||false,this.next]); break; case "hideImage": // 清除图片 this.next = MotaActionBlocks['hideImage_s'].xmlText([ @@ -2252,6 +2266,10 @@ ActionParser.prototype.parseAction = function() { this.next = MotaActionBlocks['openDoor_s'].xmlText([ data.loc[0],data.loc[1],data.floorId||'',this.next]); break; + case "useItem": // 使用道具 + this.next = MotaActionBlocks['useItem_s'].xmlText([ + data.id,this.next]); + break; case "openShop": // 打开一个全局商店 this.next = MotaActionBlocks['openShop_s'].xmlText([ data.id,this.next]); @@ -2436,6 +2454,8 @@ ActionParser.prototype.parseAction = function() { this.next = MotaActionBlocks['exit_s'].xmlText([ this.next]); break; + case "animateImage": // 兼容 animateImage + break; default: throw new Error("[警告]出错啦!\n"+data.type+" 事件不被支持..."); } diff --git a/_server/colorPicker/jsColor.js b/_server/colorPicker/jsColor.js index e846a04f..177bc566 100644 --- a/_server/colorPicker/jsColor.js +++ b/_server/colorPicker/jsColor.js @@ -330,7 +330,7 @@ Blockly.FieldColour.prototype.createWidget_ = function() { self.setValue(newValue) var c=new Colors(); c.setColor(newValue) - var rgbatext=`${c.colors.webSmart.r},${c.colors.webSmart.g},${c.colors.webSmart.b},${c.colors.alpha}` // 转成r,g,b,a文本 + var rgbatext = [c.colors.webSmart.r,c.colors.webSmart.g,c.colors.webSmart.b,c.colors.alpha].join(","); pb.setFieldValue(rgbatext, targetf) // 放在颜色块左边的域中 } diff --git a/_server/comment.js b/_server/comment.js index b44cc428..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": { @@ -386,7 +386,10 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = }, "bgm": { "_leaf": true, - "_type": "textarea", + "_type": "select", + "_select": { + "values": [null].concat(Object.keys(editor.core.material.bgms)) + }, "_data": "到达该层后默认播放的BGM。本项可忽略,或者为一个定义过的背景音乐如\"bgm.mp3\"。" }, "item_ratio": { @@ -404,7 +407,7 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = } }, "loc": { - "_leaf": false, + "_type": "object", "_data": { "events": { diff --git a/_server/css/editor.css b/_server/css/editor.css index ffd78e80..8126b33c 100644 --- a/_server/css/editor.css +++ b/_server/css/editor.css @@ -254,6 +254,15 @@ body { overflow: auto; } +#iconImages { + z-index: 0; + overflow: hidden; +} + +#iconImages img { + position: absolute; +} + .egameCanvas { position: absolute; } diff --git a/_server/css/editor_mobile.css b/_server/css/editor_mobile.css index 9f3f81ff..7bdf8953 100644 --- a/_server/css/editor_mobile.css +++ b/_server/css/editor_mobile.css @@ -238,6 +238,15 @@ body { overflow: auto; } +#iconImages { + z-index: 0; + overflow: hidden; +} + +#iconImages img { + position: absolute; +} + .egameCanvas { position: absolute; } diff --git a/_server/css/editor_mode.css b/_server/css/editor_mode.css index 2cb2e95a..a1859f65 100644 --- a/_server/css/editor_mode.css +++ b/_server/css/editor_mode.css @@ -32,6 +32,7 @@ position: fixed; top: 15px; left: 15px; + z-index: 20; } .leftTab .leftTabContent { 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.js b/_server/editor.js index 48338d0c..42523528 100644 --- a/_server/editor.js +++ b/_server/editor.js @@ -62,7 +62,7 @@ editor.prototype.init = function (callback) { editor.mode.floor(); editor.mode.tower(); editor.mode.functions(); - editor.mode.showMode('floor'); + editor.mode.showMode('tower'); editor_multi = editor_multi(); editor_blockly = editor_blockly(); @@ -415,9 +415,50 @@ editor.prototype.drawInitData = function (icons) { var fullWidth = ~~(sumWidth * ratio); var fullHeight = ~~(maxHeight * ratio); + /* if (fullWidth > edata.width) edata.style.width = (edata.width = fullWidth) / ratio + 'px'; edata.style.height = (edata.height = fullHeight) / ratio + 'px'; - var dc = edata.getContext('2d'); + */ + iconImages.style.width = (iconImages.width = fullWidth) / ratio + 'px'; + iconImages.style.height = (iconImages.height = fullHeight) / ratio + 'px'; + var dc = {drawImage:function(){ + var image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight; + var a=Array.prototype.slice.call(arguments) + if(arguments.length==3){ + // [image, dx, dy]=arguments + // [sx, sy, sWidth, sHeight, dWidth, dHeight]=[0,0,image.width,image.height,image.width,image.height] + image=a[0] + a=[a[0],0,0,image.width,image.height,a[1],a[2],image.width,image.height] + } + if(arguments.length==5){ + // [image, dx, dy, dWidth, dHeight]=arguments + // [sx, sy, sWidth, sHeight]=[0,0,image.width,image.height] + image=a[0] + a=[a[0],0,0,image.width,image.height,a[1],a[2],a[3],a[4]] + } + if(arguments.length==9){ + // [image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight]=arguments + } + image=a[0]; + sx=a[1]; + sy=a[2]; + sWidth=a[3]; + sHeight=a[4]; + dx=a[5]; + dy=a[6]; + dWidth=a[7]; + dHeight=a[8]; + //放弃对 dWidth, dHeight 的支持, 始终画一样大的 + var dimg=new Image() + dimg.src = image.src; + dimg.style.clip=['rect(',sy,'px,',sx+sWidth,'px,',sy+sHeight,'px,',sx,'px)'].join('') + dimg.style.top=dy-sy+'px' + dimg.style.left=dx-sx+'px' + dimg.width=image.width/ratio + dimg.height=image.height/ratio + iconImages.appendChild(dimg) + }} + // var dc = edata.getContext('2d'); var nowx = 0; var nowy = 0; for (var ii = 0; ii < imgNames.length; ii++) { @@ -605,6 +646,7 @@ editor.prototype.listen = function () { var iconLib=document.getElementById('iconLib'); iconLib.onmousedown = function (e) { + console.log("iconLib: ("+e.clientX+","+e.clientY+")"); e.stopPropagation(); } @@ -661,8 +703,7 @@ editor.prototype.listen = function () { // 双击地图可以选中素材 var loc = eToLoc(e); var pos = locToPos(loc,true); - var thisevent = editor.map[pos.y][pos.x]; - editor.setSelectBoxFromInfo(thisevent); + editor.setSelectBoxFromInfo(editor[editor.layerMod][pos.y][pos.x]); return; } @@ -918,7 +959,7 @@ editor.prototype.listen = function () { } var dataSelection = document.getElementById('dataSelection'); - edata.onmousedown = function (e) { + iconLib.onmousedown = function (e) { e.stopPropagation(); var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft; var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; @@ -1068,7 +1109,7 @@ editor.prototype.listen = function () { chooseInRight.onmousedown = function(e){ editor.hideMidMenu(); e.stopPropagation(); - var thisevent = editor.map[editor.pos.y][editor.pos.x]; + var thisevent = editor[editor.layerMod][editor.pos.y][editor.pos.x]; editor.setSelectBoxFromInfo(thisevent); } diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index db34e4f8..202f142f 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -100,6 +100,7 @@ editor_blockly = function () { MotaActionBlocks['changePos_1_s'].xmlText(), MotaActionBlocks['battle_s'].xmlText(), MotaActionBlocks['openDoor_s'].xmlText(), + MotaActionBlocks['useItem_s'].xmlText(), MotaActionBlocks['openShop_s'].xmlText(), MotaActionBlocks['setBlock_s'].xmlText(), MotaActionBlocks['setHeroIcon_s'].xmlText(), @@ -144,7 +145,7 @@ editor_blockly = function () { MotaActionBlocks['screenFlash_s'].xmlText(), MotaActionBlocks['setWeather_s'].xmlText(), MotaActionBlocks['playBgm_s'].xmlText(), - // MotaActionBlocks['pauseBgm_s'].xmlText(), + MotaActionBlocks['pauseBgm_s'].xmlText(), // MotaActionBlocks['resumeBgm_s'].xmlText(), MotaActionBlocks['loadBgm_s'].xmlText(), MotaActionBlocks['freeBgm_s'].xmlText(), 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 cb223751..1ed9a7ae 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,7 +92,25 @@ editor_mode = function (editor) { * @param {Object} pcobj */ var recursionParse = function (pfield, pcfield, pvobj, pcobj) { - for (var ii in pvobj) { + var keysForTableOrder={}; + var voidMark={}; + // 1. 按照pcobj排序生成 + if (pcobj && pcobj['_data']){ + for (var ii in pcobj['_data']) keysForTableOrder[ii]=voidMark; + } + // 2. 对每个pvobj且不在pcobj的,再添加到最后 + 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]; @@ -122,13 +141,19 @@ editor_mode = function (editor) { outstr.push(leafnode[0]); guids.push(leafnode[1]); } - } + } } // 开始遍历 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; } @@ -142,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 { @@ -156,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]; @@ -177,6 +217,49 @@ 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'); + if (newid == null || newid.length==0) { + return; + } + // 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}; @@ -198,7 +281,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" @@ -347,6 +430,7 @@ editor_mode = function (editor) { editor_mode.dom[name].style = 'z-index:-1;opacity: 0;'; } editor_mode.dom[mode].style = ''; + editor_mode.doubleClickMode='change'; // clear editor.drawEventBlock(); if (editor_mode[mode]) editor_mode[mode](); @@ -1121,6 +1205,19 @@ editor_mode = function (editor) { return true } + editor_mode.changeDoubleClickModeByButton=function(mode){ + ({ + delete:function(){ + printf('下一次双击表格的项删除, 编辑后刷新浏览器生效 (正常模式下双击是用事件或文本编辑器编辑);切换下拉菜单可取消。'); + editor_mode.doubleClickMode=mode; + }, + add:function(){ + printf('下一次双击表格的项, 在同级添加新项, 编辑后刷新浏览器生效 (正常模式下双击是用事件或文本编辑器编辑);切换下拉菜单可取消。'); + editor_mode.doubleClickMode=mode; + } + }[mode])(); + } + if (Boolean(callback)) callback(); } diff --git a/_server/fs.js b/_server/fs.js index 52aacfcb..dddfbbec 100644 --- a/_server/fs.js +++ b/_server/fs.js @@ -56,7 +56,7 @@ callback(null, data); } }, function (e) { - console.log(e); + main.log(e); callback(e+":请检查启动服务是否处于正常运行状态。"); }, "text/plain; charset=x-user-defined"); } diff --git a/_server/functions.comment.js b/_server/functions.comment.js index fc21ae17..89181b22 100644 --- a/_server/functions.comment.js +++ b/_server/functions.comment.js @@ -1,10 +1,10 @@ var functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = { - "_leaf": false, + "_type": "object", "_data": { "events": { - "_leaf": false, + "_type": "object", "_data": { "initGame": { @@ -106,7 +106,7 @@ var functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = } }, "enemys": { - "_leaf": false, + "_type": "object", "_data": { "getSpecials": { @@ -136,7 +136,7 @@ var functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = } }, "actions": { - "_leaf": false, + "_type": "object", "_data": { "onKeyUp": { @@ -148,7 +148,7 @@ var functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = } }, "control": { - "_leaf": false, + "_type": "object", "_data": { "flyTo": { @@ -178,7 +178,7 @@ var functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = } }, "ui": { - "_leaf": false, + "_type": "object", "_data": { "drawStatusBar": { @@ -202,7 +202,7 @@ var functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = } }, "plugins": { - "_leaf": false, + "_type": "object", "_data": { "parallelDo": { diff --git a/docs/api.md b/docs/api.md index 4668597f..283e0720 100644 --- a/docs/api.md +++ b/docs/api.md @@ -252,8 +252,9 @@ core.setBlock(number, x, y, floorId) 改变图块。number为要改变到的图块数字,x和y为坐标,floorId为楼层ID,可忽略表示当前楼层。 -core.useItem(itemId, callback) -尝试使用某个道具。itemId为道具ID,callback为成功或失败后的回调。 +core.useItem(itemId, noRoute, callback) +尝试使用某个道具。itemId为道具ID,noRoute如果为真则该道具的使用不计入录像。 +callback为成功或失败后的回调。 core.canUseItem(itemId) diff --git a/docs/element.md b/docs/element.md index 532ddc25..51c9e7ee 100644 --- a/docs/element.md +++ b/docs/element.md @@ -85,6 +85,30 @@ percentage为该装备是否按比例增加属性。 更多相关API详见[附录:API列表](api)。 +### 多重装备 + +从V2.5.4开始,允许支持多重装备,即有若干的装备可共用若干的格子(例如永不复还那样)。 + +要实现这一点,上面的写法有所改变。 + +在全塔属性中的`equipName`项写法不变,不过可以写重复的装备孔名称。(但仍然最多只能写6个) + +``` js +"equipName": ["武器", "武器", "武器", "防具", "防具", "首饰"] +``` + +然后对于某个装备,将其`type`(装备类型)写对应的装备孔名称即可。 + +``` js +{"type": "武器", "atk": 20, "def": 0, ...} +``` + +这样写的话,则所有该名称的装备孔均可装上此装备。 + +当尝试装上此装备时,会取最小的一个空的装备孔进行装备。如果没有空闲的装备孔,则会提示“请先卸下装备”。 + +装备动画仍然会取第一个(装备类型为0)的装备的`animate`项,即使装备了多个有动画的武器。 + ## 门 本塔支持6种门,黄蓝红绿铁花。前五种门需要有对应的钥匙打开,花门只能通过调用`openDoor`事件进行打开。 diff --git a/docs/event.md b/docs/event.md index 951b00e3..4259f2c5 100644 --- a/docs/event.md +++ b/docs/event.md @@ -882,6 +882,24 @@ time为可选的,指定的话将作为楼层切换动画的时间。 ] ``` +### useItem:使用道具 + +调用`{"type": "useItem"}`可以使用一个道具。 + +``` js +"x,y": [ // 实际执行的事件列表 + {"type": "changePos", "id": "pickaxe"}, // 尝试使用破 + {"type": "changePos", "id": "bomb"}, // 尝试使用炸 + {"type": "changePos", "id": "centerFly"} // 尝试使用飞 +] +``` + +使用道具事件会消耗对应的道具。 + +如果当前不可使用该道具(如没有,或者达不到使用条件),则会进行提示并跳过本事件。 + +不可使用“怪物手册”(请使用【呼出怪物手册】事件)或楼层传送器(如果[覆盖楼传事件](personalization#覆盖楼传事件)则可忽视本项)。 + ### openShop:打开一个全局商店 使用openShop可以打开一个全局商店。有关全局商店的说明可参见[全局商店](#全局商店)。 @@ -1255,15 +1273,13 @@ async可选,如果为true则会异步执行(即不等待当前事件执行 ### pauseBgm:暂停背景音乐 使用`{"type": "pauseBgm"}`可以暂停背景音乐的播放。 - -**从V2.5.4开始不再支持此事件,请通过设置音量来达到此效果。** - + ### loadBgm:预加载一个背景音乐 使用loadBgm可以预加载一个背景音乐。 @@ -1851,7 +1867,7 @@ core.insertAction([ try { eval(core.floors[core.status.floorId].parallelDo); } catch (e) { - console.log(e); + main.log(e); } } diff --git a/docs/personalization.md b/docs/personalization.md index 2eec42dc..7a4859df 100644 --- a/docs/personalization.md +++ b/docs/personalization.md @@ -416,14 +416,7 @@ control.prototype.useFly = function (need) { else core.drawTip("当前无法使用"+core.material.items.fly.name); } ``` -2. 让录像记下楼传的使用。在items.js的useItem函数中找到记录路线的那几行,修改为: -``` js - // 记录路线 - if (itemId!='book') { // 把 `&& itemId!='fly'` 给删除 - core.status.route.push("item:"+itemId); - } -``` -3. 修改楼传的使用事件。和其他永久道具一样,在地图编辑器的图块属性中修改楼传的useItemEffect和canUseItemEffect两个内容。例如: +2. 修改楼传的使用事件。和其他永久道具一样,在地图编辑器的图块属性中修改楼传的useItemEffect和canUseItemEffect两个内容。例如: ``` js "useItemEffect": "core.insertAction([...])" // 执行某段自定义事件,或者其他脚本 "canUseItemEffect": "true" // 任何时候可用 diff --git a/editor-mobile.html b/editor-mobile.html index 2c71fd1d..3a05e8e2 100644 --- a/editor-mobile.html +++ b/editor-mobile.html @@ -116,7 +116,7 @@
-

图块属性   +

图块属性      

@@ -142,7 +142,7 @@
-

楼层属性   +

楼层属性      

@@ -159,7 +159,7 @@
-

全塔属性   +

全塔属性    

@@ -257,7 +257,7 @@
-

图块属性   +

图块属性      

@@ -138,7 +138,7 @@
-

楼层属性   +

楼层属性      

@@ -155,7 +155,7 @@
-

全塔属性   +

全塔属性    

@@ -304,7 +304,7 @@