diff --git a/API列表.txt b/API列表.txt
index b2013082..4ed96670 100644
--- a/API列表.txt
+++ b/API列表.txt
@@ -661,8 +661,9 @@ core.clearStatusBar()
清空状态栏的数据。
-core.updateStatusBar()
+core.updateStatusBar(doNotCheckAutoEvents)
更新状态栏,被转发到了脚本编辑中。此函数还会根据是否在回放来设置工具栏的图标。
+如果doNotCheckAutoEvents为true则此时不检查自动事件。
core.showStatusBar() / core.hideStatusBar(showToolbox)
diff --git a/README.md b/README.md
index 7ccf34ca..2345887d 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,7 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏!
``` bash
├── /_server/ # 为可视化地图编辑器提供一些支持的目录
├── /docs/ # 文档目录
+├── /extensions/ # 拓展工具目录,发布到网站后不会加载
├── /libs/ # 系统库目录
│ ├─ /thirdparty/ # 游戏所用到的第三方库文件
│ ├─ actions.js # 处理用户交互的文件
@@ -25,6 +26,7 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏!
│ ├─ data.js # 记录了一些初始化信息
│ ├─ enemys.js # 记录了怪物的信息,包括特殊属性、伤害计算公式、临界值计算等。
│ ├─ events.js # 处理事件的文件,所有自定义事件都会在此文件中进行处理
+│ ├─ extensions.js # 加载拓展工具的文件
│ ├─ icons.js # 图标信息,会被转发到project下
│ ├─ items.js # 道具信息,会被转发到project下
│ ├─ loader.js # 动态加载JS代码、图片、音效等
@@ -55,6 +57,23 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏!
## 更新说明
+### 2019.10.29 HTML5魔塔样板V2.6.4
+
+* [x] 自动事件,多事件页
+* [x] 增加开场logo动画
+* [x] 拓展:游戏时动态修改地图和怪物数据
+* [x] 插件:道具商店,支持买入和卖出道具
+* [x] 编辑器可以搜索变量出现位置
+* [x] 变量的中文替换
+* [x] 可以给图块绑定自定义脚本,碰触时触发
+* [x] 编辑器右键可以绑定机关门和出生点
+* [x] 支持多个drawTip同时出现
+* [x] 闪烁光标同时支持多个同时存在
+* [x] 插件:镜头平滑移动,默认禁用
+* [x] 素材的快速追加
+* [x] 批量导出动画
+* [x] 部分Bug修复,大量细节优化
+
### 2019.7.24 V2.6.3
* [x] 标题界面大幅美化,增加闪烁光标,支持键盘开始游戏
diff --git a/_docs/api.md b/_docs/api.md
index 6424dcf3..38916a10 100644
--- a/_docs/api.md
+++ b/_docs/api.md
@@ -654,9 +654,9 @@ core.clearStatusBar()
清空状态栏的数据。
-core.updateStatusBar()
+core.updateStatusBar(doNotCheckAutoEvents)
更新状态栏,被转发到了脚本编辑中。此函数还会根据是否在回放来设置工具栏的图标。
-
+如果doNotCheckAutoEvents为true则此时不检查自动事件。
core.showStatusBar() / core.hideStatusBar(showToolbox)
显示和隐藏状态栏。
@@ -973,6 +973,10 @@ core.getCommonEvent(name)
core.recoverEvents(data)
恢复事件现场。一般用于呼出怪物手册、呼出存读档页面等时,恢复事件执行流。
+core.checkAutoEvents()
+检测自动事件并执行。
+
+
// ------ 点击状态栏图标时执行的一些操作 ------ //
core.openBook(fromUserAction)
@@ -1220,6 +1224,10 @@ core.quickSaveEquip(index)
core.quickLoadEquip()
读取当前套装。index为读取的套装编号。
+
+
+core.getEquippedStatus(name)
+获得装备直接增加的属性数据。
```
## loader.js
@@ -1711,11 +1719,16 @@ core.clearUI()
重置UI窗口。此函数将清掉所有的UI帧动画和光标,清空UI画布,并将alpha设为1。
-core.drawTip(text, id)
+core.drawTip(text, id, clear)
在左上角以气泡的形式绘制一段提示。
text为文字内容,仅支持${}的表达式计算,不支持换行和变色。
id可选,为同时绘制的图标ID,如果不为null则会同时绘制该图标(仅对32x32的素材有效)。
也可以使用状态栏的图标ID,例如lv, hp, up, save, settings等。
+如果clear为true,则会清空当前所有正在显示的提示。
+
+
+core.clearTip()
+清空当前所有正在显示的提示。
core.drawText(content, callback)
@@ -1757,6 +1770,7 @@ config为绘制的配置项,目前可以包括如下几项:
- fontSize:字体大小,如果不设置则使用剧情文本设置中的正文字体大小。
- lineHeight:绘制的行距值,如果不设置则使用fontSize*1.3(即1.3倍行距)。
- time:打字机效果。若不为0,则会逐个字进行绘制,并设置core.status.event.interval定时器。
+ - interval:字符间的间距。值表示绘制每个字符之间间隔的距离,默认为0。
core.drawTextBox(content, showAll)
diff --git a/_docs/event.md b/_docs/event.md
index aaf97b4a..461b2c9c 100644
--- a/_docs/event.md
+++ b/_docs/event.md
@@ -413,6 +413,8 @@ textfont为可选项,表示正文字体大小(px为单位)。默认值:`
time为可选项,表示文字添加的速度。若此项设置为0将直接全部显示,若大于0则会设置为相邻字符依次显示的时间间隔。 默认值:`0`
+interval为可选项,表示文字之间的间距。单位为像素值。默认值:`0`
+
### tip:显示一段提示文字
`{"type": "tip"}`可以在左上角显示一段提示文字。
@@ -2193,14 +2195,14 @@ UI绘制事件。此事件可以绘制闪烁光标。
```js
[
- {"type": "drawSelector", "image": "winskin.png", "x": 0, "y": 0, "width": 100, "height": 100},
+ {"type": "drawSelector", "image": "winskin.png", "x": 0, "y": 0, "width": 100, "height": 100, "clear": true},
{"type": "drawSelector"} // 清除闪烁光标
]
```
image为要绘制的WindowSkin图片名;如果不填则视为“清除闪烁光标”。
-x, y, width, height分别为要绘制的起点坐标和长宽。
+x, y, width, height分别为要绘制的起点坐标和长宽。clear可选,如果为true则在绘制前清空已有光标。
请注意,同时只会有一个闪烁光标存在,如果创建多个则后者会替换前者。
@@ -2242,6 +2244,26 @@ core.insertAction([
!> 从V2.5.3开始,提供了一个"不自动执行下一个事件"的选项(`"async": true`)。如果设置了此项,那么在该部分代码执行完毕后,不会立刻执行下一个事件。你需要在脚本中手动调用`core.events.doAction()`来执行下一个事件。可以通过此项来实现一些异步的代码,即在异步函数的回调中再执行下一个事件。使用此选项请谨慎,最好向开发者寻求咨询。
+## 自动事件
+
+从V2.6.4开始,提供了自动事件。每个点都可以绑定若干个自动事件,其类似于RM的事件页。
+
+自动事件可以设置一个触发条件,当满足此条件时将自动执行。
+
+
+
+自动事件可以设置如下几项内容:
+
+- 条件:当满足此条件时将自动执行
+- 优先级:当多个自动事件的条件同时满足时,将按照优先级从大到小执行;相同优先级的按照楼层和坐标排序。
+- 仅在本层检测:是否仅在本层检测该条件。
+- 事件流中延迟执行:如果此项为true,则若满足条件时正在事件流的处理中,则将该自动事件延迟到事件流结束时执行。
+- 允许多次执行:如果此项为true,则该自动事件允许被多次触发;否则只会被触发一次。值得注意的是,即使允许多次触发,也不允许在正在执行本自动事件时再触发。(即在执行本自动事件时将暂时禁用自身,直到执行完毕为止)
+
+自动事件的检测时机为刷新状态栏,即每次刷新状态栏时都会进行检测。
+
+可以给自动事件加上【转变图块】,从而达到类似RM的多事件页并转变图块的效果
+
## 独立开关
从V2.5.3开始,针对每个事件都提供了独立开关。
diff --git a/_docs/img/autoEvent.png b/_docs/img/autoEvent.png
new file mode 100644
index 00000000..06dd923e
Binary files /dev/null and b/_docs/img/autoEvent.png differ
diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4
index 79b11511..49220756 100644
--- a/_server/MotaAction.g4
+++ b/_server/MotaAction.g4
@@ -26,12 +26,33 @@ return code;
*/;
+//自动事件 事件编辑器入口之一
+autoEvent_m
+ : '自动事件:' '触发条件' EvalString '优先级' Int BGNL? Newline '仅在本层检测' Bool '事件流中延迟执行' Bool '允许多次执行' Bool BGNL? Newline action+ BEND
+
+
+/* autoEvent_m
+tooltip : ?????
+helpUrl : https://h5mota.com/games/template/_docs/#/event
+default : ["flag:__door__==2",0,true,false,false,null]
+var code = {
+ "condition": EvalString_0, // 条件不可为null
+ "currentFloor": Bool_0, // 是否仅在本层检测
+ "priority": Int_0, // 优先级
+ "delayExecute": Bool_1, // 延迟执行
+ "multiExecute": Bool_2, // 是否允许多次执行
+ "data": 'autoEvent_asdfefw', // 事件列表
+};
+code=JSON.stringify(code,null,2).split('"autoEvent_asdfefw"').join('[\n'+action_0+']\n');
+return code;
+*/;
+
//升级 事件编辑器入口之一
level_m
: '等级提升' BGNL? Newline levelCase+ BEND
-/* level_m
+/* level_mexpression
tooltip : 升级事件
helpUrl : https://h5mota.com/games/template/_docs/#/event?id=%e7%bb%8f%e9%aa%8c%e5%8d%87%e7%ba%a7%ef%bc%88%e8%bf%9b%e9%98%b6%2f%e5%a2%83%e7%95%8c%e5%a1%94%ef%bc%89
var code = '[\n'+levelCase_0+']\n';
@@ -65,6 +86,7 @@ return code;
shoplist
: shopsub
+ | shopitem
| shopcommonevent
| emptyshop
;
@@ -79,7 +101,7 @@ return code;
*/;
shopcommonevent
- : '商店 id' IdString '快捷商店栏中名称' EvalString BGNL? '未开启状态则不显示在列表中' Bool BGNL? '执行的公共事件 id' EvalString '参数列表' EvalString?
+ : '公共事件版商店 id' IdString '快捷商店栏中名称' EvalString BGNL? '未开启状态则不显示在列表中' Bool BGNL? '执行的公共事件 id' EvalString '参数列表' EvalString?
/* shopcommonevent
tooltip : 全局商店, 执行一个公共事件
@@ -156,6 +178,45 @@ var code = idString_e_0+'+='+expression_0+';'
return code;
*/;
+shopitem
+ : '道具商店 id' IdString '快捷商店栏中名称' EvalString BGNL? '未开启状态则不显示在列表中' Bool BGNL? Newline shopItemChoices+ BEND
+
+
+/* shopitem
+tooltip : 道具商店
+helpUrl : https://h5mota.com/games/template/_docs/#/event?id=%e5%85%a8%e5%b1%80%e5%95%86%e5%ba%97
+default : ["itemShop","道具商店",false]
+var code = {
+ 'id': IdString_0,
+ 'item': true,
+ 'textInList': EvalString_0,
+ 'mustEnable': Bool_0,
+ 'choices': 'choices_aqwedsa'
+}
+code=JSON.stringify(code,null,2).split('"choices_aqwedsa"').join('[\n'+shopItemChoices_0+']\n')+',\n';
+return code;
+*/;
+
+shopItemChoices
+ : '道具名' IdString '存量' EvalString? '买入价格' EvalString? '卖出价格' EvalString? '出现条件' EvalString? BEND
+
+
+
+/* shopItemChoices
+tooltip : 道具商店选项,每一项是道具名;买入或卖出可以不填表示只能卖出或买入
+helpUrl : https://h5mota.com/games/template/_docs/#/event?id=%e5%85%a8%e5%b1%80%e5%95%86%e5%ba%97
+default : ["yellowKey","","10","",""]
+colour : this.subColor
+if (EvalString_0 && !/^\d+$/.test(EvalString_0)) throw "存量必须不填或非负整数";
+EvalString_0 = EvalString_0 ? (', "number": '+EvalString_0) : '';
+EvalString_1 = EvalString_1 ? (', "money": "'+EvalString_1+'"') : '';
+EvalString_2 = EvalString_2 ? (', "sell": "'+EvalString_2+'"') : '';
+if (!EvalString_1 && !EvalString_2) throw "买入金额和卖出金额至少需要填写一个";
+EvalString_3 = EvalString_3 ? (', "condition": "'+EvalString_3+'"') : '';
+var code = '{"id": "' + IdString_0 + '"' + EvalString_0 + EvalString_1 + EvalString_2 + EvalString_3 + '},\n';
+return code;
+*/;
+
//afterBattle 事件编辑器入口之一
afterBattle_m
: '战斗结束后' BGNL? Newline action+ BEND
@@ -458,13 +519,13 @@ return code;
*/;
setText_s
- : '设置剧情文本的属性' '位置' SetTextPosition_List '偏移像素' EvalString? '对齐' TextAlign_List? BGNL? '标题颜色' EvalString? Colour '正文颜色' EvalString? Colour '背景色' EvalString? Colour BGNL? '粗体' B_1_List '标题字体大小' EvalString? '正文字体大小' EvalString? '打字间隔' EvalString? Newline
+ : '设置剧情文本的属性' '位置' SetTextPosition_List '偏移像素' EvalString? '对齐' TextAlign_List? BGNL? '标题颜色' EvalString? Colour '正文颜色' EvalString? Colour '背景色' EvalString? Colour BGNL? '粗体' B_1_List '标题字体大小' EvalString? '正文字体大小' EvalString? '打字间隔' EvalString? '字符间距' EvalString? Newline
/* setText_s
-tooltip : setText:设置剧情文本的属性,颜色为RGB三元组或RGBA四元组,打字间隔为剧情文字添加的时间间隔,为整数或不填
+tooltip : setText:设置剧情文本的属性,颜色为RGB三元组或RGBA四元组,打字间隔为剧情文字添加的时间间隔,为整数或不填,字符间距为字符之间的距离,为整数或不填。
helpUrl : https://h5mota.com/games/template/_docs/#/event?id=settext%EF%BC%9A%E8%AE%BE%E7%BD%AE%E5%89%A7%E6%83%85%E6%96%87%E6%9C%AC%E7%9A%84%E5%B1%9E%E6%80%A7
-default : [null,"",null,"",'rgba(255,255,255,1)',"",'rgba(255,255,255,1)',"",'rgba(255,255,255,1)',null,"","",""]
+default : [null,"",null,"",'rgba(255,255,255,1)',"",'rgba(255,255,255,1)',"",'rgba(255,255,255,1)',null,"","","",""]
SetTextPosition_List_0 =SetTextPosition_List_0==='null'?'': ', "position": "'+SetTextPosition_List_0+'"';
TextAlign_List_0 = TextAlign_List_0==='null'?'': ', "align": "'+TextAlign_List_0+'"';
var colorRe = MotaActionFunctions.pattern.colorRe;
@@ -503,8 +564,12 @@ if (EvalString_6) {
if (!/^\d+$/.test(EvalString_6))throw new Error('打字时间间隔必须是整数或不填');
EvalString_6 = ', "time": '+EvalString_6;
}
+if (EvalString_7) {
+ if (!/^\d+$/.test(EvalString_7))throw new Error('字符间距必须是整数或不填');
+ EvalString_7 = ', "interval": '+EvalString_7;
+}
B_1_List_0 = B_1_List_0==='null'?'':', "bold": '+B_1_List_0;
-var code = '{"type": "setText"'+SetTextPosition_List_0+EvalString_0+TextAlign_List_0+EvalString_1+EvalString_2+B_1_List_0+EvalString_3+EvalString_4+EvalString_5+EvalString_6+'},\n';
+var code = '{"type": "setText"'+SetTextPosition_List_0+EvalString_0+TextAlign_List_0+EvalString_1+EvalString_2+B_1_List_0+EvalString_3+EvalString_4+EvalString_5+EvalString_6+EvalString_7+'},\n';
return code;
*/;
@@ -2367,27 +2432,28 @@ return code;
*/;
drawSelector_s
- : '绘制闪烁光标' EvalString '起点像素' 'x' PosString 'y' PosString '宽' PosString '高' PosString Newline
+ : '绘制闪烁光标' EvalString '编号' Int '起点像素' 'x' PosString 'y' PosString '宽' PosString '高' PosString Newline
/* drawSelector_s
tooltip : drawSelector:绘制闪烁光标
helpUrl : https://h5mota.com/games/template/_docs/#/event?id=drawSelector%ef%bc%9a%e7%bb%98%e5%88%b6%e9%97%aa%e7%83%81%e5%85%89%e6%a0%87
-default : ["winskin.png","0","0","100","100"]
+default : ["winskin.png","1","0","0","100","100"]
colour : this.subColor
-var code = '{"type": "drawSelector", "image": "'+EvalString_0+'", "x": '+PosString_0+', "y": '+PosString_1+', "width": '+PosString_2+', "height": '+PosString_3+'},\n';
+var code = '{"type": "drawSelector", "image": "'+EvalString_0+'", "code": '+Int_0+', "x": '+PosString_0+', "y": '+PosString_1+', "width": '+PosString_2+', "height": '+PosString_3+'},\n';
return code;
*/;
drawSelector_1_s
- : '清除闪烁光标' Newline
+ : '清除闪烁光标' '编号' Int Newline
/* drawSelector_1_s
tooltip : drawSelector:清除闪烁光标
helpUrl : https://h5mota.com/games/template/_docs/#/event?id=showImage%ef%bc%9a%e6%98%be%e7%a4%ba%e5%9b%be%e7%89%87
+default : ["1"]
colour : this.subColor
-var code = '{"type": "drawSelector"},\n';
+var code = '{"type": "drawSelector", "code": '+Int_0+'},\n';
return code;
*/;
@@ -2495,7 +2561,7 @@ idString_e
/* idString_e
colour : this.idstring_eColor
-default : ["status:hp"]
+default : ["变量:生命"]
var code = IdString_0;
return [code, Blockly.JavaScript.ORDER_ATOMIC];
*/;
@@ -2509,7 +2575,7 @@ idString_1_e
colour : this.idstring_eColor
default : [null,"自定义flag"]
//todo 将其output改成'idString_e'
-var code = Id_List_0+':'+IdText_0;
+var code = MotaActionFunctions.replaceFromName(MotaActionFunctions.replaceToName(Id_List_0+':'+IdText_0));
return [code, Blockly.JavaScript.ORDER_ATOMIC];
*/;
@@ -2755,6 +2821,12 @@ ActionParser.prototype.parse = function (obj,type) {
obj.trigger==='action',obj.enable,obj.noPass,obj.displayDamage,this.parseList(obj.data)
]);
+ case 'autoEvent':
+ if(!obj)obj={};
+ return MotaActionBlocks['autoEvent_m'].xmlText([
+ obj.condition,obj.priority,obj.currentFloor,obj.delayExecute,obj.multiExecute,this.parseList(obj.data)
+ ]);
+
case 'changeFloor':
if(!obj)obj={};
if(!this.isset(obj.loc)) {
@@ -2812,11 +2884,25 @@ ActionParser.prototype.parse = function (obj,type) {
obj.id,parser.EvalString(obj.textInList),obj.mustEnable,parser.EvalString(obj.commonEvent),obj.args,next
]);
}
+ var builditem = function (obj,parser,next){
+ var text_choices = null;
+ for(var ii=obj.choices.length-1,choice;choice=obj.choices[ii];ii--) {
+ text_choices = MotaActionBlocks['shopItemChoices'].xmlText([
+ choice.id, choice.number == null ? "" : (""+choice.number), choice.money == null ? "" : (""+choice.money),
+ choice.sell == null ? "" : (""+choice.sell), choice.condition || "", text_choices
+ ]);
+ }
+ return MotaActionBlocks['shopitem'].xmlText([
+ obj.id,obj.textInList,obj.mustEnable,text_choices,next
+ ]);
+ }
var next=null;
if(!obj)obj=[];
while(obj.length){
var shopobj=obj.pop()
- if(shopobj.choices)
+ if(shopobj.item)
+ next=builditem(shopobj,this,next);
+ else if(shopobj.choices)
next=buildsub(shopobj,this,next);
else if(shopobj.commonEvent)
next=buildcommentevent(shopobj,this,next);
@@ -2901,7 +2987,7 @@ ActionParser.prototype.parseAction = function() {
this.next = MotaActionBlocks['setText_s'].xmlText([
data.position,data.offset,data.align,data.title,'rgba('+data.title+')',
data.text,'rgba('+data.text+')',data.background,'rgba('+data.background+')',
- data.bold,data.titlefont,data.textfont,data.time,this.next]);
+ data.bold,data.titlefont,data.textfont,data.time,data.interval,this.next]);
break;
case "tip":
this.next = MotaActionBlocks['tip_s'].xmlText([
@@ -3513,11 +3599,11 @@ ActionParser.prototype.parseAction = function() {
case "drawSelector": // 绘制光标
if (data.image) {
this.next = MotaActionBlocks['drawSelector_s'].xmlText([
- data.image, data.x, data.y, data.width, data.height, this.next
+ data.image, data.code, data.x, data.y, data.width, data.height, this.next
]);
}
else {
- this.next = MotaActionBlocks['drawSelector_1_s'].xmlText([this.next]);
+ this.next = MotaActionBlocks['drawSelector_1_s'].xmlText([data.code, this.next]);
}
case "animateImage": // 兼容 animateImage
break;
@@ -3604,6 +3690,9 @@ MotaActionFunctions.actionParser = new ActionParser();
MotaActionFunctions.workspace = function(){return workspace}
MotaActionFunctions.parse = function(obj,type) {
+ try {
+ obj = JSON.parse(MotaActionFunctions.replaceToName(JSON.stringify(obj)));
+ } catch (e) {}
MotaActionFunctions.workspace().clear();
xml_text = MotaActionFunctions.actionParser.parse(obj,type||'event');
xml = Blockly.Xml.textToDom(''+xml_text+'');
@@ -3612,11 +3701,13 @@ MotaActionFunctions.parse = function(obj,type) {
MotaActionFunctions.EvalString_pre = function(EvalString){
if (EvalString.indexOf('__door__')!==-1) throw new Error('请修改开门变量__door__,如door1,door2,door3等依次向后。请勿存在两个门使用相同的开门变量。');
+ EvalString = MotaActionFunctions.replaceFromName(EvalString);
return EvalString.replace(/([^\\])"/g,'$1\\"').replace(/^"/g,'\\"').replace(/""/g,'"\\"');
}
MotaActionFunctions.IdString_pre = function(IdString){
if (IdString.indexOf('__door__')!==-1) throw new Error('请修改开门变量__door__,如door1,door2,door3等依次向后。请勿存在两个门使用相同的开门变量。');
+ IdString = MotaActionFunctions.replaceFromName(IdString);
if (IdString && !(MotaActionFunctions.pattern.id.test(IdString)) && !(MotaActionFunctions.pattern.idWithoutFlag.test(IdString)))
throw new Error('id: '+IdString+'中包含了0-9 a-z A-Z _ - :之外的字符');
return IdString;
@@ -3625,7 +3716,7 @@ MotaActionFunctions.IdString_pre = function(IdString){
MotaActionFunctions.PosString_pre = function(PosString){
if (!PosString || /^-?\d+$/.test(PosString)) return PosString;
//if (!(MotaActionFunctions.pattern.id.test(PosString)))throw new Error(PosString+'中包含了0-9 a-z A-Z _ 和中文之外的字符,或者是没有以flag: 开头');
- return '"'+PosString+'"';
+ return '"'+MotaActionFunctions.replaceFromName(PosString)+'"';
}
MotaActionFunctions.StepString_pre = function(StepString){
@@ -3674,4 +3765,113 @@ MotaActionFunctions.pattern.colorRe=/^(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-
MotaActionFunctions.pattern.fontRe=/^(italic )?(bold )?(\d+)px ([a-zA-Z0-9_\u4E00-\u9FCC]+)$/;
+MotaActionFunctions.pattern.replaceStatusList = [
+ // 保证顺序!
+ ["hpmax", "生命上限"],
+ ["hp", "生命"],
+ ["name", "名称"],
+ ["lv", "等级"],
+ ["atk", "攻击"],
+ ["def", "防御"],
+ ["mdef", "魔防"],
+ ["manamax", "魔力上限"],
+ ["mana", "魔力"],
+ ["money", "金币"],
+ ["experience", "经验"],
+ ["steps", "步数"]
+];
+
+MotaActionFunctions.pattern.replaceItemList = [
+ // 保证顺序!
+ ["yellowKey", "黄钥匙"],
+ ["blueKey", "蓝钥匙"],
+ ["redKey", "红钥匙"],
+ ["redJewel", "红宝石"],
+ ["blueJewel", "蓝宝石"],
+ ["greenJewel", "绿宝石"],
+ ["yellowJewel", "黄宝石"],
+ ["redPotion", "红血瓶"],
+ ["bluePotion", "蓝血瓶"],
+ ["yellowPotion", "黄血瓶"],
+ ["greenPotion", "绿血瓶"],
+ ["sword1", "铁剑"],
+ ["sword2", "银剑"],
+ ["sword3", "骑士剑"],
+ ["sword4", "圣剑"],
+ ["sword5", "神圣剑"],
+ ["shield1", "铁盾"],
+ ["shield2", "银盾"],
+ ["shield3", "骑士盾"],
+ ["shield4", "圣盾"],
+ ["shield5", "神圣盾"],
+ ["superPotion", "圣水"],
+ ["moneyPocket", "金钱袋"],
+ ["book", "怪物手册"],
+ ["fly", "楼层传送器"],
+ ["coin", "幸运金币"],
+ ["snow", "冰冻徽章"],
+ ["cross", "十字架"],
+ ["knife", "屠龙匕首"],
+ ["shoes", "绿鞋"],
+ ["bigKey", "大黄门钥匙"],
+ ["greenKey", "绿钥匙"],
+ ["steelKey", "铁门钥匙"],
+ ["pickaxe", "破墙镐"],
+ ["icePickaxe", "破冰镐"],
+ ["bomb", "炸弹"],
+ ["centerFly", "中心对称飞行器"],
+ ["upFly", "上楼器"],
+ ["downFly", "下楼器"],
+ ["earthquake", "地震卷轴"],
+ ["poisonWine", "解毒药水"],
+ ["weakWine", "解衰药水"],
+ ["curseWine", "解咒药水"],
+ ["superWine", "万能药水"],
+ ["hammer", "圣锤"],
+ ["lifeWand", "生命魔杖"],
+ ["jumpShoes", "跳跃靴"],
+];
+
+MotaActionFunctions.disableReplace = false;
+
+MotaActionFunctions.replaceToName = function (str) {
+ if (!str || MotaActionFunctions.disableReplace) return str;
+ var map = {}, list = [];
+ MotaActionFunctions.pattern.replaceStatusList.forEach(function (v) {
+ map[v[0]] = v[1]; list.push(v[0]);
+ });
+ str = str.replace(new RegExp("status:(" + list.join("|") + ")", "g"), function (a, b) {
+ return map[b] ? ("状态:" + map[b]) : b;
+ }).replace(/status:/g, "状态:");
+ map = {}; list = [];
+ MotaActionFunctions.pattern.replaceItemList.forEach(function (v) {
+ map[v[0]] = v[1]; list.push(v[0]);
+ });
+ str = str.replace(new RegExp("item:(" + list.join("|") + ")", "g"), function (a, b) {
+ return map[b] ? ("物品:" + map[b]) : b;
+ }).replace(/item:/g, "物品:");
+ str = str.replace(/flag:/g, "变量:").replace(/switch:/g, "独立开关:").replace(/global:/g, "全局存储:");
+ return str;
+}
+
+MotaActionFunctions.replaceFromName = function (str) {
+ if (!str || MotaActionFunctions.disableReplace) return str;
+ var map = {}, list = [];
+ MotaActionFunctions.pattern.replaceStatusList.forEach(function (v) {
+ map[v[1]] = v[0]; list.push(v[1]);
+ });
+ str = str.replace(new RegExp("状态[::](" + list.join("|") + ")", "g"), function (a, b) {
+ return map[b] ? ("status:" + map[b]) : b;
+ }).replace(/状态[::]/g, "status:");
+ map = {}; list = [];
+ MotaActionFunctions.pattern.replaceItemList.forEach(function (v) {
+ map[v[1]] = v[0]; list.push(v[1]);
+ });
+ str = str.replace(new RegExp("物品[::](" + list.join("|") + ")", "g"), function (a, b) {
+ return map[b] ? ("item:" + map[b]) : b;
+ }).replace(/物品[::]/g, "item:");
+ str = str.replace(/变量[::]/g, "flag:").replace(/独立开关[::]/g, "switch:").replace(/全局存储[::]/g, "global:");
+ return str;
+}
+
*/
\ No newline at end of file
diff --git a/_server/README.md b/_server/README.md
index e6a12c67..7bd750b1 100644
--- a/_server/README.md
+++ b/_server/README.md
@@ -1,140 +1,57 @@
# editor
-[重构](refactoring.md)
+直接使用游戏运行时(之后简称core)的代码来绘制游戏画面, 借助fs.js来实现浏览器编辑文件. 通过表格编辑数据, blockly图块编辑事件, code mirror编辑文本的可视化魔塔编辑器.
->! 以下均是v2.0时的说明, 未及时改动
+
-本目录下所有文件,以及`../editor.html`和`../启动服务.exe`([源码](http://github.com/ckcz123/mota-js-server/))是地图编辑器的所有组件.
+左侧数据区, 中间地图区, 右侧素材区
-`editor.js`,`editor_file.js`和`editor_mode.js`耦合较强,`editor_blockly.js`和`editor_multi.js`和`fs.js`基本可以独立使用.
+
-## 各组件功能
+事件编辑器
-### 总体上
+
-以`display:none`的形式引入了`index.html`的`dom`,修改了原来的`.gameCanvas #ui #data`等的名字以避免冲突
+脚本编辑器
-通过`main.init('editor')`加载数据
+> 此文件是editor的结构说明, 不是使用文档
-`editor`模式关闭了部分动画
+## 组成
-`core.drawMap`中`editor`模式下不再画图,而是生成画图的函数提供给`editor`
+本目录下所有文件,以及`../editor.html`,`../editor-mobile.html`和`../启动服务.exe`,`../server.py`是地图编辑器的所有组件.
-`editor`模式下`GlobalAnimate`可以独立的选择是否播放
+### 父目录
++ editor(-mobile).html
+ 编辑器的[入口页面](http://127.0.0.1:1055/editor.html)
+ 以`display:none`的形式引入了core的`index.html`的`dom`,修改了原来的`.gameCanvas #ui #data`等的名字以避免冲突
++ 启动服务.exe [源码](http://github.com/ckcz123/mota-js-server/)
+ 为fs.js提供后端支持, 同时集成了一些实用工具
++ server.py
+ 非windows平台中为fs.js提供后端支持
-`core.playBgm`和`core.playSound`中非`play`模式不再播放声音
+### core
-`core.show`和`core.hide`中非`play`模式不再进行动画而是立刻完成并执行回调
+游戏运行时中部分代码根据`main.mod=='editor'`进行了调整
-`editor`模式不执行`core.resize`
++ 通过`main.init('editor')`加载数据
-### editor.js
++ `editor`模式关闭了部分动画
-``` js
-editor.mapInit();//清空地图
-editor.changeFloor('MT2')//切换地图
-editor.util.guid()//产生一个可以作为id的长随机字符串
-```
++ `core.drawMap`中`editor`模式下不再画图,而是生成画图的函数提+ 供给`editor`
-`editor.updateMap`中画未定义快的报错
++ `editor`模式下`GlobalAnimate`可以独立的选择是否播放
-### editor_file.js
++ `core.playBgm`和`core.playSound`中非`play`模式不再播放声音
-提供了以下函数进行楼层`map`数组相关的操作
-```javascript
-editor.file.saveFloorFile
-editor.file.saveFloorFileAs
-```
++ `core.show`和`core.hide`中非`play`模式不再进行动画而是立刻+ 完成并执行回调
-编辑模式有关的查询
-```javascript
-editor.file.editItem('redJewel',[],function(a){console.log(a)});
-editor.file.editEnemy('redBat',[],function(a){console.log(a)});
-editor.file.editLoc(2,0,[],function(a){console.log(a)});
-editor.file.editFloor([],function(a){console.log(a)});
-editor.file.editTower([],function(a){console.log(a)});
-editor.file.editFunctions([],function(a){console.log(a)});
-```
++ `editor`模式不执行`core.resize`
-编辑模式有关的编辑
-```javascript
-editor.info={images: "terrains", y: 9};
-editor.file.changeIdAndIdnum('yellowWall2',16,editor.info,function(a){console.log(a)});
-editor.file.editItem('book',[["change","['items']['name']","怪物手册的新名字"]],function(a){console.log(a)});
-editor.file.editEnemy('redBat',[['change',"['atk']",20]],function(a){console.log(a)});
-editor.file.editLoc(2,6,[["change","['afterBattle']",null]],function(a){console.log(a)});
-editor.file.editFloor([["change","['title']",'样板 33 层']],function(a){console.log(a)});
-editor.file.editTower([["change","['values']['lavaDamage']",200]],function(a){console.log(a)});
-editor.file.editFunctions(["change","['events']['afterChangeLight']","function(x,y){console.log(x,y)}"],function(a){console.log(a)});
-```
-
-### editor_mode.js
-生成表格并绑定事件的函数
-```javascript
-editor.mode.loc();
-editor.mode.enemyitem();
-editor.mode.floor();
-editor.mode.tower();
-editor.mode.functions();
-```
-
-切换模式
-```javascript
-editor.mode.onmode('');//清空
-editor.mode.onmode('save');//保存
-editor.mode.onmode('nextChange');//下次onmode时前端进行切换
-
-editor.mode.onmode('loc');
-editor.mode.onmode('enemyitem');
-editor.mode.onmode('floor');
-editor.mode.onmode('tower');
-editor.mode.onmode('functions');
-editor.mode.onmode('map');
-editor.mode.onmode('appendpic');
-```
-在`onmode('save')`时,改动才会保存到文件,涉及到图片的改动需要刷新页面使得`editor`能看到
-
-表格的`onchange`的实现中,获得当前模式的方式.不注意的话,修改`index.html`中页面的结构,会被坑
-```javascript
-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.listen`中提供了追加素材的支持.
-
-
-### editor_blockly.js
-
-把选定`id_`的事件用blockly编辑
-``` js
-editor_blockly.import(id_,{type:'event'});
-```
-
-把文本区域的代码转换成图块
-``` js
-editor_blockly.parse();
-```
-
-### editor_multi.js
-
-用[CodeMirror](https://github.com/codemirror/CodeMirror) 实现有高亮的多行文本编辑
-
-编辑选定`id_`的文本域
-``` js
-editor_multi.import(id_,{lint:true})
-```
-
-编辑blockly方块的特定域
-``` js
-editor_multi.multiLineEdit(value,b,f,{lint:true},callback)
-```
### fs.js
-模仿node的fs模块提供如下api,与`启动服务.exe`配合为js提供文件读写功能
+依照[issue#31](https://github.com/ckcz123/mota-js/issues/13)的约定, 模仿node的fs模块提供如下api,与`启动服务.exe`,`server.py`配合为js提供文件读写功能, 是编辑器成立的前提
+
``` js
fs.readFile('file.in','utf-8',callback)
//读文本文件
@@ -162,3 +79,195 @@ fs.readdir(path, callback)
//所有参数不允许缺省
```
+### editor_multi.js
+
+用[CodeMirror](https://github.com/codemirror/CodeMirror) 实现有高亮的多行文本编辑
+
+编辑选定`id_`的文本域
+``` js
+editor_multi.import(id_,{lint:true})
+```
+
+编辑blockly方块的特定域
+``` js
+editor_multi.multiLineEdit(value,b,f,{lint:true},callback)
+```
+
+配置表格
+``` js
+editor_multi.editCommentJs(mod)
+```
+
+### MotaAction.g4
+
+通过[antlr-blockly](https://github.com/zhaouv/antlr-blockly)的语法定义core中各事件对应的方块.
+
+借助google的[blockly](https://github.com/google/blockly)来实现事件的可视化编辑.
+
+入口方块以`_m`结尾
+
+一般语句写在`action`中, 以`_s`结尾
+
+### editor_blockly.js
+
+把选定`id_`的事件用blockly编辑
+``` js
+editor_blockly.import(id_,{type:'event'});
+```
+
+把文本区域的代码转换成图块
+``` js
+editor_blockly.parse();
+```
+
+`initscript中`的`toolboxObj`定义了侧边栏中显示的图块
+
+自定义`Blockly.FieldColour.prototype.createWidget_`修改了颜色选择器的行为
+
+自定义`Blockly.FieldTextInput.prototype.showInlineEditor_`添加了自动补全
+
+
+### editor_mode.js
+
+用于切换数据区
+
+加载数据
+```javascript
+editor.mode.loc();
+editor.mode.enemyitem();
+editor.mode.floor();
+editor.mode.tower();
+editor.mode.functions();
+```
+
+切换模式
+```javascript
+editor.mode.onmode('');//清空
+editor.mode.onmode('save');//保存
+editor.mode.onmode('nextChange');//下次onmode时前端进行切换
+
+editor.mode.onmode('loc');
+editor.mode.onmode('enemyitem');
+editor.mode.onmode('floor');
+editor.mode.onmode('tower');
+editor.mode.onmode('functions');
+editor.mode.onmode('map');
+editor.mode.onmode('appendpic');
+```
+在`onmode('save')`时,改动才会保存到文件,涉及到图片的改动需要刷新页面使得`editor`能看到
+
+数据区一些通用的函数也定义在这里
+
+### editor_table.js
+
+处理表格的生成, 及其响应的事件
+
+其接受来自../project/\*.js的数据`obj`和来自table/\*.comment.js的注释`commentObj`
+
+commentObj的结构如示例
+``` js
+{
+ "_type": "object",
+ "_data": {
+ "events": {
+ "_type": "object",
+ "_data": {
+ "resetGame": {
+ "_leaf": true,
+ "_type": "textarea",
+ "_lint": true,
+ "_data": "重置整个游戏"
+ },
+ "setInitData": {
+ "_leaf": true,
+ "_type": "textarea",
+ "_lint": true,
+ "_data": "设置初始属性"
+ },
+```
+一层正常数据, 一层`_`开头的结构说明, 忽略`_`层的话与obj同结构
+
+通过
+``` js
+editor.table.objToTable(obj, commentObj)
+editor.table.objToTr
+editor.table.objToTd
+```
+遍历这两个对象来生成表格, 叶节点根据`_type`渲染成对应的dom
+
+表格的值变化`onchange`, 双击`dblclickfunc`, 删除`deletefunc`, 添加`addfunc`也定义在此文件
+
+### editor_mappanel.js
+
+与地图区相关的功能
++ 画地图 线/矩形/tileset
++ 通过地图选中事件或素材
++ 右键菜单
++ 切换楼层
++ 大地图移动可视窗口
+
+### editor_materialpanel.js
+
+与素材区相关的功能
++ 选中
++ 展开/折叠
+
+### editor_datapanel.js
+
+与数据区相关的功能 (且与表格无关的功能)
++ 地图编辑
+ - 创建新地图
+ - 批量创建
++ 地图选点
++ 图块属性
+ - 注册素材
+ - 修改id
++ 楼层属性
+ - 修改楼层id
++ 全塔属性
++ 脚本编辑
++ 追加素材
+ - 选择导入的区域
+ - 导入图片
+ - 改色相
+ - 选中图片中的格子
+ - 确认追加
++ 公共事件
++ 插件编写
+
+### editor_ui.js
+
+ui事件中没有具体到前三个区中的函数
++ 响应点击
++ 快捷键
++ 显示帮助
++ UI预览 & 地图选点相关
+
+### editor_util.js
+
+一些通用的函数
++ 生成id
++ HTML转义
++ 像素处理
++ base64的encode/decode
++ 检查值是否为空
+
+### editor_listen.js
+
+界面与功能的绑定
+
+### editor_file.js
+
+包装fs.js, 把数据读写到对应的文件
+
+### editor_game.js
+
+游戏数据的处理
+
+此部分的重构未完成, 实际上是由editor_file.js和editor_file_unsorted.js来做的
+
+### editor.js
+
+初始化加整合各模块
+
+现状是还放了一些游戏数据有关的函数未挪到editor_game, 以及部分和入口页面生成有关的函数
\ No newline at end of file
diff --git a/_server/css/editor.css b/_server/css/editor.css
index c12e3f07..92172a43 100644
--- a/_server/css/editor.css
+++ b/_server/css/editor.css
@@ -285,8 +285,10 @@ body {
#iconExpandBtn {
position: absolute;
- left: 10px;
+ left: 20px;
bottom: 30px;
+ font-size: 15px;
+ padding: 6px;
display: none;
}
diff --git a/_server/css/editor_mobile.css b/_server/css/editor_mobile.css
index c37142e1..40e28ff1 100644
--- a/_server/css/editor_mobile.css
+++ b/_server/css/editor_mobile.css
@@ -270,8 +270,10 @@ body {
#iconExpandBtn {
position: absolute;
- left: 10px;
+ left: 20px;
bottom: 30px;
+ font-size: 15px;
+ padding: 6px;
display: none;
}
diff --git a/_server/css/editor_mode.css b/_server/css/editor_mode.css
index a1859f65..d521a617 100644
--- a/_server/css/editor_mode.css
+++ b/_server/css/editor_mode.css
@@ -121,6 +121,7 @@
display: block;
width: 100%;
overflow: auto;
+ word-break: break-all;
}
.etable table th {
@@ -157,14 +158,19 @@
}
.etable tr > :nth-child(3) {
- width: 60%
+ width: 35%;
+}
+
+.etable tr > :nth-child(4) {
+ width: 25%;
+ padding: 0;
}
.etable table {
overflow: visible;
}
-.etable tr:not(:first-child) > :last-child:hover {
+.etable tr:not(:first-child) > :nth-child(3):hover {
border: 1px solid rgb(87, 198, 232);
box-shadow: 0px 0px 3px rgb(87, 198, 232);
}
@@ -175,14 +181,17 @@
box-shadow: 0px 0px 3px rgb(87, 232, 198);
}
-.etable tr:not(:first-child) > :last-child {
+.etable tr:not(:first-child) > :nth-child(3) {
margin: 0;
padding: 0;
height: 100%;
- width: 100%;
position: relative;
}
+.etable tr > :nth-child(4) {
+ text-align: center;
+}
+
div.etableInputDiv {
position: absolute;
padding: 5px 0 0 5px;
diff --git a/_server/css/editor_mode_mobile.css b/_server/css/editor_mode_mobile.css
index 3098df27..bb680213 100644
--- a/_server/css/editor_mode_mobile.css
+++ b/_server/css/editor_mode_mobile.css
@@ -135,6 +135,7 @@
display: block;
width: 100%;
overflow: auto;
+ word-break: break-all;
}
.etable table th {
@@ -171,14 +172,19 @@
}
.etable tr > :nth-child(3) {
- width: 60%
+ width: 30%;
+}
+
+.etable tr > :nth-child(4) {
+ width: 30%;
+ text-align: center;
}
.etable table {
overflow: visible;
}
-.etable tr:not(:first-child) > :last-child:hover {
+.etable tr:not(:first-child) > :nth-child(3):hover {
border: 1px solid rgb(87, 198, 232);
box-shadow: 0px 0px 3px rgb(87, 198, 232);
}
@@ -189,11 +195,10 @@
box-shadow: 0px 0px 3px rgb(87, 232, 198);
}
-.etable tr:not(:first-child) > :last-child {
+.etable tr:not(:first-child) > :nth-child(3) {
margin: 0;
padding: 0;
height: 100%;
- width: 100%;
position: relative;
}
diff --git a/_server/editor.js b/_server/editor.js
index cb7490a3..54b24e35 100644
--- a/_server/editor.js
+++ b/_server/editor.js
@@ -4,6 +4,88 @@ function editor() {
this.layerMod = "map";//["fgmap","map","bgmap"]
this.isMobile = false;
+ this.dom={
+ body:document.body,
+ eui:document.getElementById('eui'),
+ euiCtx:document.getElementById('eui').getContext('2d'),
+ mid:document.getElementById('mid'),
+ mapEdit:document.getElementById('mapEdit'),
+ selectFloor:document.getElementById('selectFloor'),
+ iconExpandBtn :document.getElementById('iconExpandBtn'),
+ dataSelection : document.getElementById('dataSelection'),
+ iconLib:document.getElementById('iconLib'),
+ midMenu:document.getElementById('midMenu'),
+ extraEvent: document.getElementById('extraEvent'),
+ chooseThis : document.getElementById('chooseThis'),
+ chooseInRight : document.getElementById('chooseInRight'),
+ copyLoc : document.getElementById('copyLoc'),
+ moveLoc : document.getElementById('moveLoc'),
+ clearEvent : document.getElementById('clearEvent'),
+ clearLoc : document.getElementById('clearLoc'),
+ brushMod:document.getElementById('brushMod'),
+ brushMod2:document.getElementById('brushMod2'),
+ brushMod3:document.getElementById('brushMod3'),
+ bgc : document.getElementById('bg'),
+ fgc : document.getElementById('fg'),
+ evc : document.getElementById('event'),
+ ev2c : document.getElementById('event2'),
+ layerMod:document.getElementById('layerMod'),
+ layerMod2:document.getElementById('layerMod2'),
+ layerMod3:document.getElementById('layerMod3'),
+ viewportButtons:document.getElementById('viewportButtons'),
+ appendPicCanvas : document.getElementById('appendPicCanvas'),
+ bg : document.getElementById('appendPicCanvas').children[0],
+ source : document.getElementById('appendPicCanvas').children[1],
+ picClick : document.getElementById('appendPicCanvas').children[2],
+ sprite : document.getElementById('appendPicCanvas').children[3],
+ sourceCtx:document.getElementById('appendPicCanvas').children[1].getContext('2d'),
+ spriteCtx:document.getElementById('appendPicCanvas').children[3].getContext('2d'),
+ appendPicSelection : document.getElementById('appendPicSelection'),
+ selectAppend : document.getElementById('selectAppend'),
+ selectFileBtn :document.getElementById('selectFileBtn'),
+ changeFloorId :document.getElementById('changeFloorId'),
+ left1 : document.getElementById('left1'),
+ editModeSelect :document.getElementById('editModeSelect'),
+ };
+
+ this.uivalues={
+ // 绘制区拖动有关
+ holdingPath : 0,
+ stepPostfix : null,//用于存放寻路检测的第一个点之后的后续移动
+ mouseOutCheck : 2,
+ startPos:null,
+ endPos:null,
+ // 撤销/恢复
+ currDrawData : {
+ pos: [],
+ info: {}
+ },
+ reDo : null,
+ preMapData : null,
+ //
+ shortcut:{},
+ copyedInfo : null,
+ // 折叠素材
+ scrollBarHeight :0,
+ folded:false,
+ foldPerCol: 50,
+ // 画图区菜单
+ lastRightButtonPos:[{x:0,y:0},{x:0,y:0}],
+ lastCopyedInfo : [null, null],
+ //
+ ratio : 1,
+ // blockly转义
+ disableBlocklyReplace: false,
+
+ // 绑定机关门事件相关
+ bindSpecialDoor: {
+ loc: null,
+ n: -1,
+ enemys: []
+ }
+
+ };
+
window.onerror = function (msg, url, lineNo, columnNo, error) {
var string = msg.toLowerCase();
var substring = "script error";
@@ -30,6 +112,8 @@ function editor() {
};
}
+editor.prototype.uifunctions={};
+
/*
editor.loc
editor.pos
@@ -52,7 +136,11 @@ editor.prototype.init = function (callback) {
editor_game_wrapper(editor, main, core);
editor_file_wrapper(editor);
editor_table_wrapper(editor);
- editor_unsorted_1_wrapper(editor);
+ editor_ui_wrapper(editor);
+ editor_mappanel_wrapper(editor);
+ editor_datapanel_wrapper(editor);
+ editor_materialpanel_wrapper(editor);
+ editor_listen_wrapper(editor);
editor.printe=printe;
afterMainInit();
});
@@ -65,7 +153,6 @@ editor.prototype.init = function (callback) {
editor_file = editor_file(editor, function () {
editor.file = editor_file;
editor_mode = editor_mode(editor);
- editor_unsorted_2_wrapper(editor_mode);
editor.mode = editor_mode;
core.resetGame(core.firstData.hero, null, core.firstData.floorId, core.clone(core.initStatus.maps));
core.changeFloor(core.status.floorId, null, core.firstData.hero.loc, null, function () {
@@ -103,6 +190,11 @@ editor.prototype.init = function (callback) {
for (var floorId in editor.main.floors) {
editor.addUsedFlags(JSON.stringify(editor.main.floors[floorId]));
}
+ if (events_c12a15a8_c380_4b28_8144_256cba95f760.commonEvent) {
+ for (var name in events_c12a15a8_c380_4b28_8144_256cba95f760.commonEvent) {
+ editor.addUsedFlags(JSON.stringify(events_c12a15a8_c380_4b28_8144_256cba95f760.commonEvent[name]));
+ }
+ }
if (editor.useCompress == null) editor.useCompress = useCompress;
if (Boolean(callback)) callback();
@@ -148,7 +240,8 @@ editor.prototype.changeFloor = function (floorId, callback) {
});
editor.currentFloorData[name]=mapArray;
}
- editor.preMapData = null;
+ editor.uivalues.preMapData = null;
+ editor.uifunctions._extraEvent_bindSpecialDoor_doAction(true);
core.changeFloor(floorId, null, {"x": 0, "y": 0, "direction": "up"}, null, function () {
editor.game.fetchMapFromCore();
editor.updateMap();
@@ -169,26 +262,48 @@ editor.prototype.drawEventBlock = function () {
var fg=document.getElementById('efg').getContext('2d');
fg.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__);
+ var firstData = editor.game.getFirstData();
for (var i=0;i= 0) {
+ fg.textAlign = 'right';
+ editor.game.doCoreFunc("fillBoldText", fg, index + 1,
+ 32 * i + 28, 32 * j + 15, '#FF7F00', '14px Verdana');
+ }
}
}
}
@@ -266,6 +381,7 @@ editor.prototype.updateMap = function () {
editor.prototype.setViewport=function (x, y) {
core.bigmap.offsetX = core.clamp(x, 0, 32*core.bigmap.width-core.__PIXELS__);
core.bigmap.offsetY = core.clamp(y, 0, 32*core.bigmap.height-core.__PIXELS__);
+ editor.viewportLoc = editor.viewportLoc || {};
editor.viewportLoc[editor.currentFloorId] = [core.bigmap.offsetX, core.bigmap.offsetY];
core.control.updateViewport();
editor.buildMark();
@@ -284,9 +400,9 @@ editor.prototype.drawInitData = function (icons) {
var maxHeight = 700;
var sumWidth = 0;
editor.widthsX = {};
- editor.folded = core.getLocalStorage('folded', false);
- // editor.folded = true;
- editor.foldPerCol = 50;
+ editor.uivalues.folded = core.getLocalStorage('folded', false);
+ // editor.uivalues.folded = true;
+ editor.uivalues.foldPerCol = 50;
// var imgNames = Object.keys(images); //还是固定顺序吧;
var imgNames = ["terrains", "animates", "enemys", "enemy48", "items", "npcs", "npc48", "autotile"];
@@ -297,17 +413,17 @@ editor.prototype.drawInitData = function (icons) {
for (var im in autotiles) {
tempy += autotiles[im].height;
}
- var tempx = editor.folded ? 32 : 3 * 32;
+ var tempx = editor.uivalues.folded ? 32 : 3 * 32;
editor.widthsX[img] = [img, sumWidth / 32, (sumWidth + tempx) / 32, tempy];
sumWidth += tempx;
maxHeight = Math.max(maxHeight, tempy);
continue;
}
var width = images[img].width, height = images[img].height, mh = height;
- if (editor.folded) {
+ if (editor.uivalues.folded) {
var per_height = (img == 'enemy48' || img == 'npc48' ? 48 : 32);
- width = Math.ceil(height / per_height / editor.foldPerCol) * 32;
- if (width > 32) mh = per_height * editor.foldPerCol;
+ width = Math.ceil(height / per_height / editor.uivalues.foldPerCol) * 32;
+ if (width > 32) mh = per_height * editor.uivalues.foldPerCol;
}
editor.widthsX[img] = [img, sumWidth / 32, (sumWidth + width) / 32, height];
sumWidth += width;
@@ -353,9 +469,9 @@ editor.prototype.drawInitData = function (icons) {
editor.updateMap();
}
})(editor.airwallImg,nowx);
- if (editor.folded) {
+ if (editor.uivalues.folded) {
// --- 单列 & 折行
- var subimgs = core.splitImage(images[img], 32, editor.foldPerCol * 32);
+ var subimgs = core.splitImage(images[img], 32, editor.uivalues.foldPerCol * 32);
var frames = images[img].width / 32;
for (var i = 0; i < subimgs.length; i+=frames) {
drawImage(subimgs[i], nowx, i==0?2*32:0);
@@ -370,7 +486,7 @@ editor.prototype.drawInitData = function (icons) {
}
if (img == 'autotile') {
var autotiles = images[img];
- var tempx = editor.folded ? 32 : 96;
+ var tempx = editor.uivalues.folded ? 32 : 96;
for (var im in autotiles) {
var subimgs = core.splitImage(autotiles[im], tempx, autotiles[im].height);
drawImage(subimgs[0], nowx, nowy);
@@ -379,10 +495,10 @@ editor.prototype.drawInitData = function (icons) {
nowx += tempx;
continue;
}
- if (editor.folded) {
+ if (editor.uivalues.folded) {
// --- 单列 & 折行
var per_height = img.endsWith('48') ? 48 : 32;
- var subimgs = core.splitImage(images[img], 32, editor.foldPerCol * per_height);
+ var subimgs = core.splitImage(images[img], 32, editor.uivalues.foldPerCol * per_height);
var frames = images[img].width / 32;
for (var i = 0; i < subimgs.length; i+=frames) {
drawImage(subimgs[i], nowx, 0);
@@ -471,16 +587,15 @@ editor.prototype.setSelectBoxFromInfo=function(thisevent){
pos.y=thisevent.y;
if(thisevent.x)pos.x+=thisevent.x;
ysize = thisevent.images.endsWith('48') ? 48 : 32;
- if (editor.folded && core.tilesets.indexOf(thisevent.images)==-1) {
- pos.x += Math.floor(pos.y / editor.foldPerCol);
- pos.y %= editor.foldPerCol;
+ if (editor.uivalues.folded && core.tilesets.indexOf(thisevent.images)==-1) {
+ pos.x += Math.floor(pos.y / editor.uivalues.foldPerCol);
+ pos.y %= editor.uivalues.foldPerCol;
}
if(pos.x == 0) pos.y+=2;
}
- var dataSelection = document.getElementById('dataSelection');
- dataSelection.style.left = pos.x * 32 + 'px';
- dataSelection.style.top = pos.y * ysize + 'px';
- dataSelection.style.height = ysize - 6 + 'px';
+ editor.dom.dataSelection.style.left = pos.x * 32 + 'px';
+ editor.dom.dataSelection.style.top = pos.y * ysize + 'px';
+ editor.dom.dataSelection.style.height = ysize - 6 + 'px';
setTimeout(function(){selectBox.isSelected(true);});
editor.info = JSON.parse(JSON.stringify(thisevent));
tip.infos(JSON.parse(JSON.stringify(thisevent)));
@@ -489,137 +604,21 @@ editor.prototype.setSelectBoxFromInfo=function(thisevent){
editor_mode.onmode('enemyitem');
}
-editor.prototype.listen = function () {
- // 移动至 editor_unsorted_1.js
-}//绑定事件
-
-editor.prototype.mobile_listen=function(){
- // 移动至 editor_unsorted_1.js
-}
-
-editor.prototype.copyFromPos = function (pos) {
- var fields = Object.keys(editor.file.comment._data.floors._data.loc._data);
- pos = pos || editor.pos;
- var map = core.clone(editor.map[pos.y][pos.x]);
- var events = {};
- fields.forEach(function(v){
- events[v] = core.clone(editor.currentFloorData[v][pos.x+','+pos.y]);
- })
- return {map: map, events: events};
-}
-
-editor.prototype.pasteToPos = function (info, pos) {
- if (info == null) return;
- var fields = Object.keys(editor.file.comment._data.floors._data.loc._data);
- pos = pos || editor.pos;
- editor.map[pos.y][pos.x] = core.clone(info.map);
- fields.forEach(function(v){
- if (info.events[v] == null) delete editor.currentFloorData[v][pos.x+","+pos.y];
- else editor.currentFloorData[v][pos.x+","+pos.y] = core.clone(info.events[v]);
- });
-}
-
-editor.prototype.movePos = function (startPos, endPos, callback) {
- if (!startPos || !endPos) return;
- if (startPos.x == endPos.x && startPos.y == endPos.y) return;
- var copyed = editor.copyFromPos(startPos);
- editor.pasteToPos({map:0, events: {}}, startPos);
- editor.pasteToPos(copyed, endPos);
- editor.updateMap();
- editor.file.saveFloorFile(function (err) {
- if (err) {
- printe(err);
- throw(err)
- }
- ;printf('移动事件成功');
- editor.drawPosSelection();
- if (callback) callback();
- });
-}
-
-editor.prototype.exchangePos = function (startPos, endPos, callback) {
- if (!startPos || !endPos) return;
- if (startPos.x == endPos.x && startPos.y == endPos.y) return;
- var startInfo = editor.copyFromPos(startPos);
- var endInfo = editor.copyFromPos(endPos);
- editor.pasteToPos(startInfo, endPos);
- editor.pasteToPos(endInfo, startPos);
- editor.updateMap();
- editor.file.saveFloorFile(function (err) {
- if (err) {
- printe(err);
- throw(err)
- }
- ;printf('交换事件成功');
- editor.drawPosSelection();
- if (callback) callback();
- });
-}
-
-editor.prototype.moveBgFg = function (startPos, endPos, name, callback) {
- if (!startPos || !endPos || ["bgmap","fgmap"].indexOf(name)<0) return;
- if (startPos.x == endPos.x && startPos.y == endPos.y) return;
- editor[name][endPos.y][endPos.x] = editor[name][startPos.y][startPos.x];
- editor[name][startPos.y][startPos.x] = 0;
- editor.updateMap();
- editor.file.saveFloorFile(function (err) {
- if (err) {
- printe(err);
- throw(err)
- }
- ;printf('移动图块成功');
- editor.drawPosSelection();
- if (callback) callback();
- });
-}
-
-editor.prototype.exchangeBgFg = function (startPos, endPos, name, callback) {
- if (!startPos || !endPos || ["bgmap","fgmap"].indexOf(name)<0) return;
- if (startPos.x == endPos.x && startPos.y == endPos.y) return;
- var value = editor[name][endPos.y][endPos.x];
- editor[name][endPos.y][endPos.x] = editor[name][startPos.y][startPos.x];
- editor[name][startPos.y][startPos.x] = value;
- editor.updateMap();
- editor.file.saveFloorFile(function (err) {
- if (err) {
- printe(err);
- throw(err)
- }
- ;printf('交换图块成功');
- editor.drawPosSelection();
- if (callback) callback();
- });
-
-}
-
-editor.prototype.clearPos = function (clearPos, pos, callback) {
- var fields = Object.keys(editor.file.comment._data.floors._data.loc._data);
- pos = pos || editor.pos;
- editor.hideMidMenu();
- editor.preMapData = null;
- editor.info = 0;
- editor_mode.onmode('');
- if (clearPos)
- editor.map[pos.y][pos.x]=editor.info;
- editor.updateMap();
- fields.forEach(function(v){
- delete editor.currentFloorData[v][pos.x+','+pos.y];
- })
- editor.file.saveFloorFile(function (err) {
- if (err) {
- printe(err);
- throw(err)
- }
- ;printf(clearPos?'清空该点和事件成功':'只清空该点事件成功');
- editor.drawPosSelection();
- if (callback) callback();
- });
-}
-
editor.prototype.addUsedFlags = function (s) {
s.replace(/flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)/g, function (s0, s1) {
editor.used_flags[s1] = true; return s0;
});
}
+editor.prototype.listen = function () {
+ // 移动至 editor_listen.js
+}//绑定事件
+
+editor.prototype.mobile_listen=function(){
+ // 移动至 editor_listen.js
+}
+
+
+
+
editor = new editor();
\ No newline at end of file
diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js
index 82d3b9f8..ef318e6a 100644
--- a/_server/editor_blockly.js
+++ b/_server/editor_blockly.js
@@ -26,6 +26,16 @@ editor_blockly = function () {
"本事件触发一次后会消失",
{"type": "hide", "time": 500},
],'event'),
+ MotaActionFunctions.actionParser.parse({
+ "condition": "flag:__door__==2",
+ "currentFloor": true,
+ "priority": 0,
+ "delayExecute": false,
+ "multiExecute": false,
+ "data": [
+ {"type": "openDoor", "loc": [10,5]}
+ ],
+ },'autoEvent'),
MotaActionBlocks['changeFloor_m'].xmlText(),
MotaActionFunctions.actionParser.parse([{
"id": "moneyShop1",
@@ -38,8 +48,13 @@ editor_blockly = function () {
"choices": [
{"text": "生命+800", "effect": "status:hp+=800"},
{"text": "攻击+4", "effect": "status:atk+=4"},
- {"text": "防御+4", "effect": "status:def+=4"},
- {"text": "魔防+10", "effect": "status:mdef+=10"}
+ ]
+ },{
+ "id": "itemShop",
+ "item": true,
+ "textInList": "道具商店",
+ "choices": [
+ {"id": "yellowKey", "number": 10, "money": 10}
]
},{
"id": "keyShop1",
@@ -84,11 +99,11 @@ editor_blockly = function () {
]),
],
'数据相关':[
- MotaActionBlocks['setValue_s'].xmlText([
- MotaActionBlocks['idString_1_e'].xmlText(['status','hp'])
- ]),
MotaActionBlocks['addValue_s'].xmlText([
- MotaActionBlocks['idString_1_e'].xmlText(['status','hp'])
+ MotaActionBlocks['idString_1_e'].xmlText(['status','生命'])
+ ]),
+ MotaActionBlocks['setValue_s'].xmlText([
+ MotaActionBlocks['idString_1_e'].xmlText(['status','生命'])
]),
MotaActionBlocks['setFloor_s'].xmlText(),
MotaActionBlocks['setGlobalAttribute_s'].xmlText(),
@@ -127,8 +142,8 @@ editor_blockly = function () {
MotaActionBlocks['hideFloorImg_s'].xmlText(),
],
'事件控制':[
- MotaActionBlocks['if_s'].xmlText(),
MotaActionBlocks['if_1_s'].xmlText(),
+ MotaActionBlocks['if_s'].xmlText(),
MotaActionFunctions.actionParser.parseList({"type": "switch", "condition": "判别值", "caseList": [
{"action": [{"type": "comment", "text": "当判别值是值的场合执行此事件"}]},
{"action": [], "nobreak": true},
@@ -201,11 +216,11 @@ editor_blockly = function () {
MotaActionBlocks['unknown_s'].xmlText(),
],
'值块':[
- MotaActionBlocks['setValue_s'].xmlText([
- MotaActionBlocks['idString_1_e'].xmlText(['status','hp'])
- ]),
MotaActionBlocks['addValue_s'].xmlText([
- MotaActionBlocks['idString_1_e'].xmlText(['status','hp'])
+ MotaActionBlocks['idString_1_e'].xmlText(['status','生命'])
+ ]),
+ MotaActionBlocks['setValue_s'].xmlText([
+ MotaActionBlocks['idString_1_e'].xmlText(['status','生命'])
]),
MotaActionBlocks['expression_arithmetic_0'].xmlText(),
MotaActionBlocks['evFlag_e'].xmlText(),
@@ -467,6 +482,17 @@ function omitedcheckUpdateFunction(event) {
`;
/////////////////initscript end /////////////////////////////
+ editor.uivalues.disableBlocklyReplace = core.getLocalStorage("disableBlocklyReplace", false);
+ var replaceCheckbox = document.getElementById('blocklyReplace');
+ replaceCheckbox.checked = !editor.uivalues.disableBlocklyReplace;
+
+ editor_blockly.triggerReplace = function () {
+ editor.uivalues.disableBlocklyReplace = !replaceCheckbox.checked;
+ core.setLocalStorage("disableBlocklyReplace", !replaceCheckbox.checked);
+ if (MotaActionFunctions) MotaActionFunctions.disableReplace = !replaceCheckbox.checked;
+ alert("已" + (replaceCheckbox.checked ? "开启" : "关闭") + "中文变量名替换!\n关闭并重开事件编辑器以生效。");
+ }
+
var input_ = '';
editor_blockly.runOne = function () {
//var printf = console.log;
@@ -496,6 +522,7 @@ function omitedcheckUpdateFunction(event) {
}
input_ = xhr.responseText;
editor_blockly.runOne();
+ MotaActionFunctions.disableReplace = editor.uivalues.disableBlocklyReplace;
}
xhr.open('GET', '_server/MotaAction.g4', true);
xhr.send(null);
@@ -612,9 +639,45 @@ function omitedcheckUpdateFunction(event) {
var code = Blockly.JavaScript.workspaceToCode(editor_blockly.workspace);
code = code.replace(/\\(i|c|d|e)/g, '\\\\$1');
eval('var obj=' + code);
+ if (this.checkAsync(obj) && confirm("警告!存在不等待执行完毕的事件但却没有用【等待所有异步事件处理完毕】来等待" +
+ "它们执行完毕,这样可能会导致录像检测系统出问题。\n你要返回修改么?")) return;
setvalue(JSON.stringify(obj));
}
+ // 检查"不等待处理完毕"
+ editor_blockly.checkAsync = function (obj) {
+ if (!(obj instanceof Array)) return false;
+ var hasAsync = false;
+ for (var i = 0; i < obj.length; ++i) {
+ var one = obj[i];
+ if (one.type == 'if' && (this.checkAsync(one['true']) || this.checkAsync(one['false'])))
+ return true;
+ if ((one.type == 'while' || one.type == 'dowhile') && this.checkAsync(one.data))
+ return true;
+ if (one.type == 'if' && (this.checkAsync(one.yes) || this.checkAsync(one.no)))
+ return true;
+ if (one.type == 'choices') {
+ var list = one.choices;
+ if (list instanceof Array) {
+ for (var j = 0; j < list.length; j++) {
+ if (this.checkAsync(list[j].action)) return true;
+ }
+ }
+ }
+ if (one.type == 'switch') {
+ var list = one.caseList;
+ if (list instanceof Array) {
+ for (var j = 0; j < list.length; j++) {
+ if (this.checkAsync(list[j].action)) return true;
+ }
+ }
+ }
+ if (one.async && one.type != 'animate') hasAsync = true;
+ if (one.type == 'waitAsync') hasAsync = false;
+ }
+ return hasAsync;
+ }
+
var previewBlock = function (b) {
var types = [
"previewUI_s", "clearMap_s", "clearMap_1_s", "setAttribute_s", "fillText_s",
@@ -629,8 +692,8 @@ function omitedcheckUpdateFunction(event) {
// console.log(obj);
if (obj.length > 0 && b.type.startsWith(obj[0].type)) {
if (b.type == 'previewUI_s')
- uievent.previewUI(obj[0].action);
- else uievent.previewUI([obj[0]]);
+ editor.uievent.previewUI(obj[0].action);
+ else editor.uievent.previewUI([obj[0]]);
}
} catch (e) {main.log(e);}
return true;
@@ -769,7 +832,7 @@ function omitedcheckUpdateFunction(event) {
"jump_s": ["PosString_2", "PosString_3"], // 跳跃暂时只考虑终点
"showBgFgMap_s": ["EvalString_0", "EvalString_1", "IdString_0"],
"hideBgFgMap_s": ["EvalString_0", "EvalString_1", "IdString_0"],
- "setBgFgBlock_s": ["PosString_0", "PosString_1", "IdString_0"],
+ "setBgFgBlock_s": ["EvalString_1", "EvalString_2", "IdString_0"],
"showFloorImg_s": ["EvalString_0", "EvalString_1", "IdString_0"],
"hideFloorImg_s": ["EvalString_0", "EvalString_1", "IdString_0"],
"trigger_s": ["PosString_0", "PosString_1"],
@@ -792,7 +855,7 @@ function omitedcheckUpdateFunction(event) {
if (!isNaN(yv)) y = yv;
if (arr[2] != null) floorId = block.getFieldValue(arr[2]) || floorId;
}
- uievent.selectPoint(floorId, x, y, arr && arr[2] == null, function (fv, xv, yv) {
+ editor.uievent.selectPoint(floorId, x, y, arr && arr[2] == null, function (fv, xv, yv) {
if (!arr) return;
if (arr[2] != null) {
if (fv != editor.currentFloorId) block.setFieldValue(fv, arr[2]);
@@ -815,22 +878,35 @@ function omitedcheckUpdateFunction(event) {
editor_blockly.getAutoCompletions = function (content) {
// --- content为当前框中输入内容;将返回一个列表,为后续所有可补全内容
- // 检查 flag:xxx,item:xxx和flag:xxx
- var index = content.lastIndexOf(":");
+ // 检查 status:xxx,item:xxx和flag:xxx
+ var index = Math.max(content.lastIndexOf(":"), content.lastIndexOf(":"));
if (index >= 0) {
+ var ch = content.charAt(index);
var before = content.substring(0, index), token = content.substring(index+1);
if (/^[a-zA-Z0-9_\u4E00-\u9FCC]*$/.test(token)) {
- if (before.endsWith("status")) {
- return Object.keys(core.status.hero).filter(function (one) {
+ if (before.endsWith("状态") || (ch == ':' && before.endsWith("status"))) {
+ var list = Object.keys(core.status.hero);
+ if (before.endsWith("状态") && MotaActionFunctions) {
+ list = MotaActionFunctions.pattern.replaceStatusList.map(function (v) {
+ return v[1];
+ }).concat(list);
+ }
+ return list.filter(function (one) {
return one != token && one.startsWith(token);
}).sort();
}
- else if (before.endsWith("item")) {
- return Object.keys(core.material.items).filter(function (one) {
+ else if (before.endsWith("物品") || (ch == ':' && before.endsWith("item"))) {
+ var list = Object.keys(core.material.items);
+ if (before.endsWith("物品") && MotaActionFunctions) {
+ list = MotaActionFunctions.pattern.replaceItemList.map(function (v) {
+ return v[1];
+ }).concat(list);
+ }
+ return list.filter(function (one) {
return one != token && one.startsWith(token);
}).sort();
}
- else if (before.endsWith("flag")) {
+ else if (before.endsWith("变量") || (ch == ':' && before.endsWith("flag"))) {
return Object.keys(editor.used_flags || {}).filter(function (one) {
return one != token && one.startsWith(token);
}).sort();
@@ -963,7 +1039,7 @@ Blockly.FieldTextInput.prototype.showInlineEditor_ = function(quietInput) {
// --- awesomplete
var awesomplete = new Awesomplete(htmlInput, {
- minChars: 4,
+ minChars: 2,
maxItems: 12,
autoFirst: true,
replace: function (text) {
diff --git a/_server/editor_unsorted_2.js b/_server/editor_datapanel.js
similarity index 51%
rename from _server/editor_unsorted_2.js
rename to _server/editor_datapanel.js
index 042b617b..5e1baa46 100644
--- a/_server/editor_unsorted_2.js
+++ b/_server/editor_datapanel.js
@@ -1,6 +1,158 @@
-editor_unsorted_2_wrapper=function(editor_mode){
+editor_datapanel_wrapper = function (editor) {
- editor_mode.constructor.prototype.listen=function (callback) {
+ // 此文件内的内容仅做了分类, 未仔细整理函数
+
+ ///////////////////////////////////////////////////////////////////////
+ //////////////////// 地图编辑 //////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+
+
+ editor.uifunctions.newMap_func = function () {
+
+ var newMap = document.getElementById('newMap');
+ var newFileName = document.getElementById('newFileName');
+ newMap.onclick = function () {
+ if (!newFileName.value) return;
+ if (core.floorIds.indexOf(newFileName.value) >= 0) {
+ printe("该楼层已存在!");
+ return;
+ }
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(newFileName.value)) {
+ printe("楼层名不合法!请使用字母、数字、下划线,且不能以数字开头!");
+ return;
+ }
+ var width = parseInt(document.getElementById('newMapWidth').value);
+ var height = parseInt(document.getElementById('newMapHeight').value);
+ if (!core.isset(width) || !core.isset(height) || width < core.__SIZE__ || height < core.__SIZE__ || width * height > 1000) {
+ printe("新建地图的宽高都不得小于" + core.__SIZE__ + ",且宽高之积不能超过1000");
+ return;
+ }
+
+ editor_mode.onmode('');
+ editor.file.saveNewFile(newFileName.value, function (err) {
+ if (err) {
+ printe(err);
+ throw (err)
+ }
+ core.floorIds.push(newFileName.value);
+ editor.file.editTower([['change', "['main']['floorIds']", core.floorIds]], function (objs_) {//console.log(objs_);
+ if (objs_.slice(-1)[0] != null) {
+ printe(objs_.slice(-1)[0]);
+ throw (objs_.slice(-1)[0])
+ }
+ ; printe('新建成功,请F5刷新编辑器生效');
+ });
+ });
+ }
+
+ }
+
+
+ editor.uifunctions.createNewMaps_func = function () {
+ var newMaps = document.getElementById('newMaps');
+ var newFloors = document.getElementById('newFloors');
+ newMaps.onclick = function () {
+ if (newFloors.style.display == 'none') newFloors.style.display = 'block';
+ else newFloors.style.display = 'none';
+ }
+
+ var createNewMaps = document.getElementById('createNewMaps');
+ createNewMaps.onclick = function () {
+ var floorIds = document.getElementById('newFloorIds').value;
+ if (!floorIds) return;
+ var from = parseInt(document.getElementById('newMapsFrom').value),
+ to = parseInt(document.getElementById('newMapsTo').value);
+ if (!core.isset(from) || !core.isset(to) || from > to || from < 0 || to < 0) {
+ printe("请输入有效的起始和终止楼层");
+ return;
+ }
+ if (to - from >= 100) {
+ printe("一次最多创建99个楼层");
+ return;
+ }
+ var floorIdList = [];
+ for (var i = from; i <= to; i++) {
+ var floorId = floorIds.replace(/\${(.*?)}/g, function (word, value) {
+ return eval(value);
+ });
+ if (core.floorIds.indexOf(floorId) >= 0) {
+ printe("要创建的楼层 " + floorId + " 已存在!");
+ return;
+ }
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(floorId)) {
+ printe("楼层名 " + floorId + " 不合法!请使用字母、数字、下划线,且不能以数字开头!");
+ return;
+ }
+ if (floorIdList.indexOf(floorId) >= 0) {
+ printe("尝试重复创建楼层 " + floorId + " !");
+ return;
+ }
+ floorIdList.push(floorId);
+ }
+
+ var width = parseInt(document.getElementById('newMapsWidth').value);
+ var height = parseInt(document.getElementById('newMapsHeight').value);
+ if (!core.isset(width) || !core.isset(height) || width < core.__SIZE__ || height < core.__SIZE__ || width * height > 1000) {
+ printe("新建地图的宽高都不得小于" + core.__SIZE__ + ",且宽高之积不能超过1000");
+ return;
+ }
+ editor_mode.onmode('');
+
+ editor.file.saveNewFiles(floorIdList, from, to, function (err) {
+ if (err) {
+ printe(err);
+ throw (err)
+ }
+ core.floorIds = core.floorIds.concat(floorIdList);
+ editor.file.editTower([['change', "['main']['floorIds']", core.floorIds]], function (objs_) {//console.log(objs_);
+ if (objs_.slice(-1)[0] != null) {
+ printe(objs_.slice(-1)[0]);
+ throw (objs_.slice(-1)[0])
+ }
+ ; printe('批量创建 ' + floorIdList[0] + '~' + floorIdList[floorIdList.length - 1] + ' 成功,请F5刷新编辑器生效');
+ });
+ });
+ }
+
+ }
+
+
+
+ ///////////////////////////////////////////////////////////////////////
+ //////////////////// 地图选点 //////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+
+
+ // 添加自动事件页,无需双击
+ editor.uifunctions.addAutoEvent = function () {
+ if (editor_mode.mode != 'loc') return false;
+ var newid = '2';
+ var ae = editor.currentFloorData.autoEvent[editor_mode.pos.x + ',' + editor_mode.pos.y];
+ if (ae != null) {
+ var testid;
+ for (testid = 2; Object.hasOwnProperty.call(ae, testid); testid++);
+ newid = testid + '';
+ }
+ editor_mode.addAction(['add', "['autoEvent']['" + newid + "']", null]);
+ editor_mode.onmode('save');
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+ ///////////////////////////////////////////////////////////////////////
+ //////////////////// 图块属性 //////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+
+ editor.uifunctions.newIdIdnum_func = function () {
var newIdIdnum = document.getElementById('newIdIdnum');
newIdIdnum.children[2].onclick = function () {
if (newIdIdnum.children[0].value && newIdIdnum.children[1].value) {
@@ -17,7 +169,7 @@ editor_unsorted_2_wrapper=function(editor_mode){
editor.file.changeIdAndIdnum(id, idnum, editor_mode.info, function (err) {
if (err) {
printe(err);
- throw(err)
+ throw (err)
}
printe('添加id和idnum成功,请F5刷新编辑器');
});
@@ -25,17 +177,18 @@ editor_unsorted_2_wrapper=function(editor_mode){
printe('请输入id和idnum');
}
}
-
newIdIdnum.children[4].onclick = function () {
editor.file.autoRegister(editor_mode.info, function (err) {
if (err) {
printe(err);
- throw(err)
+ throw (err)
}
printe('该列所有剩余项全部自动注册成功,请F5刷新编辑器');
})
}
+ }
+ editor.uifunctions.changeId_func = function () {
var changeId = document.getElementById('changeId');
changeId.children[1].onclick = function () {
var id = changeId.children[0].value;
@@ -47,7 +200,7 @@ editor_unsorted_2_wrapper=function(editor_mode){
editor.file.changeIdAndIdnum(id, null, editor_mode.info, function (err) {
if (err) {
printe(err);
- throw(err);
+ throw (err);
}
printe('修改id成功,请F5刷新编辑器');
});
@@ -55,146 +208,34 @@ editor_unsorted_2_wrapper=function(editor_mode){
printe('请输入要修改到的ID');
}
}
+ }
- var selectFloor = document.getElementById('selectFloor');
- editor.game.getFloorFileList(function (floors) {
- var outstr = [];
- floors[0].forEach(function (floor) {
- outstr.push(["\n'].join(''));
- });
- selectFloor.innerHTML = outstr.join('');
- selectFloor.value = core.status.floorId;
- selectFloor.onchange = function () {
- editor_mode.onmode('nextChange');
- editor_mode.onmode('floor');
- editor.changeFloor(selectFloor.value);
- }
- });
- var saveFloor = document.getElementById('saveFloor');
- editor_mode.saveFloor = function () {
- editor_mode.onmode('');
- editor.file.saveFloorFile(function (err) {
- if (err) {
- printe(err);
- throw(err)
- }
- ;printf('保存成功');
- });
- }
- saveFloor.onclick = editor_mode.saveFloor;
- var newMap = document.getElementById('newMap');
- var newFileName = document.getElementById('newFileName');
- newMap.onclick = function () {
- if (!newFileName.value) return;
- if (core.floorIds.indexOf(newFileName.value)>=0) {
- printe("该楼层已存在!");
- return;
- }
- if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(newFileName.value)) {
- printe("楼层名不合法!请使用字母、数字、下划线,且不能以数字开头!");
- return;
- }
- var width = parseInt(document.getElementById('newMapWidth').value);
- var height = parseInt(document.getElementById('newMapHeight').value);
- if (!core.isset(width) || !core.isset(height) || width1000) {
- printe("新建地图的宽高都不得小于"+core.__SIZE__+",且宽高之积不能超过1000");
- return;
- }
- editor_mode.onmode('');
- editor.file.saveNewFile(newFileName.value, function (err) {
- if (err) {
- printe(err);
- throw(err)
- }
- core.floorIds.push(newFileName.value);
- editor.file.editTower([['change', "['main']['floorIds']", core.floorIds]], function (objs_) {//console.log(objs_);
- if (objs_.slice(-1)[0] != null) {
- printe(objs_.slice(-1)[0]);
- throw(objs_.slice(-1)[0])
- }
- ;printe('新建成功,请F5刷新编辑器生效');
- });
- });
- }
- var newMaps = document.getElementById('newMaps');
- var newFloors = document.getElementById('newFloors');
- newMaps.onclick = function () {
- if (newFloors.style.display == 'none') newFloors.style.display = 'block';
- else newFloors.style.display = 'none';
- }
- var createNewMaps = document.getElementById('createNewMaps');
- createNewMaps.onclick = function () {
- var floorIds = document.getElementById('newFloorIds').value;
- if (!floorIds) return;
- var from = parseInt(document.getElementById('newMapsFrom').value),
- to = parseInt(document.getElementById('newMapsTo').value);
- if (!core.isset(from) || !core.isset(to) || from>to || from<0 || to<0) {
- printe("请输入有效的起始和终止楼层");
- return;
- }
- if (to-from >= 100) {
- printe("一次最多创建99个楼层");
- return;
- }
- var floorIdList = [];
- for (var i = from; i<=to; i++) {
- var floorId = floorIds.replace(/\${(.*?)}/g, function (word, value) {
- return eval(value);
- });
- if (core.floorIds.indexOf(floorId)>=0) {
- printe("要创建的楼层 "+floorId+" 已存在!");
- return;
- }
- if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(floorId)) {
- printe("楼层名 "+floorId+" 不合法!请使用字母、数字、下划线,且不能以数字开头!");
- return;
- }
- if (floorIdList.indexOf(floorId)>=0) {
- printe("尝试重复创建楼层 "+floorId+" !");
- return;
- }
- floorIdList.push(floorId);
- }
- var width = parseInt(document.getElementById('newMapsWidth').value);
- var height = parseInt(document.getElementById('newMapsHeight').value);
- if (!core.isset(width) || !core.isset(height) || width1000) {
- printe("新建地图的宽高都不得小于"+core.__SIZE__+",且宽高之积不能超过1000");
- return;
- }
- editor_mode.onmode('');
-
- editor.file.saveNewFiles(floorIdList, from, to, function (err) {
- if (err) {
- printe(err);
- throw(err)
- }
- core.floorIds = core.floorIds.concat(floorIdList);
- editor.file.editTower([['change', "['main']['floorIds']", core.floorIds]], function (objs_) {//console.log(objs_);
- if (objs_.slice(-1)[0] != null) {
- printe(objs_.slice(-1)[0]);
- throw(objs_.slice(-1)[0])
- }
- ;printe('批量创建 '+floorIdList[0]+'~'+floorIdList[floorIdList.length-1]+' 成功,请F5刷新编辑器生效');
- });
- });
- }
- var changeFloorId = document.getElementById('changeFloorId');
- changeFloorId.children[1].onclick = function () {
- var floorId = changeFloorId.children[0].value;
+
+
+ ///////////////////////////////////////////////////////////////////////
+ //////////////////// 楼层属性 //////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+
+
+
+ editor.uifunctions.changeFloorId_func = function () {
+
+ editor.dom.changeFloorId.children[1].onclick = function () {
+ var floorId = editor.dom.changeFloorId.children[0].value;
if (floorId) {
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(floorId)) {
- printe("楼层名 "+floorId+" 不合法!请使用字母、数字、下划线,且不能以数字开头!");
+ printe("楼层名 " + floorId + " 不合法!请使用字母、数字、下划线,且不能以数字开头!");
return;
}
- if (main.floorIds.indexOf(floorId)>=0) {
- printe("楼层名 "+floorId+" 已存在!");
+ if (main.floorIds.indexOf(floorId) >= 0) {
+ printe("楼层名 " + floorId + " 已存在!");
return;
}
var currentFloorId = editor.currentFloorId;
@@ -203,13 +244,13 @@ editor_unsorted_2_wrapper=function(editor_mode){
editor.file.saveFloorFile(function (err) {
if (err) {
printe(err);
- throw(err);
+ throw (err);
}
core.floorIds[core.floorIds.indexOf(currentFloorId)] = floorId;
editor.file.editTower([['change', "['main']['floorIds']", core.floorIds]], function (objs_) {//console.log(objs_);
if (objs_.slice(-1)[0] != null) {
printe(objs_.slice(-1)[0]);
- throw(objs_.slice(-1)[0])
+ throw (objs_.slice(-1)[0])
}
alert("修改floorId成功,需要刷新编辑器生效。\n请注意,原始的楼层文件没有删除,请根据需要手动删除。");
window.location.reload();
@@ -219,47 +260,89 @@ editor_unsorted_2_wrapper=function(editor_mode){
printe('请输入要修改到的floorId');
}
}
+ }
- var ratio = 1;
- var appendPicCanvas = document.getElementById('appendPicCanvas');
- var bg = appendPicCanvas.children[0];
- var source = appendPicCanvas.children[1];
- var source_ctx=source.getContext('2d');
- var picClick = appendPicCanvas.children[2];
- var sprite = appendPicCanvas.children[3];
- var sprite_ctx=sprite.getContext('2d');
- var appendPicSelection = document.getElementById('appendPicSelection');
-
- [source_ctx,sprite_ctx].forEach(function(ctx){
+
+
+
+
+
+
+
+
+ ///////////////////////////////////////////////////////////////////////
+ //////////////////// 全塔属性 //////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ///////////////////////////////////////////////////////////////////////
+ //////////////////// 脚本编辑 //////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ///////////////////////////////////////////////////////////////////////
+ //////////////////// 追加素材 //////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+
+
+
+
+
+ editor.uifunctions.fixCtx_func = function () {
+ [editor.dom.sourceCtx, editor.dom.spriteCtx].forEach(function (ctx) {
ctx.mozImageSmoothingEnabled = false;
ctx.webkitImageSmoothingEnabled = false;
ctx.msImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;
})
+ }
+
+ editor.uifunctions.selectAppend_func = function () {
- var selectAppend = document.getElementById('selectAppend');
var selectAppend_str = [];
["terrains", "animates", "enemys", "enemy48", "items", "npcs", "npc48", "autotile"].forEach(function (image) {
selectAppend_str.push(["\n'].join(''));
});
- selectAppend.innerHTML = selectAppend_str.join('');
- selectAppend.onchange = function () {
+ editor.dom.selectAppend.innerHTML = selectAppend_str.join('');
+ editor.dom.selectAppend.onchange = function () {
- var value = selectAppend.value;
+ var value = editor.dom.selectAppend.value;
if (value == 'autotile') {
editor_mode.appendPic.imageName = 'autotile';
- for (var jj=0;jj<4;jj++) appendPicSelection.children[jj].style = 'display:none';
+ for (var jj = 0; jj < 4; jj++) editor.dom.appendPicSelection.children[jj].style = 'display:none';
if (editor_mode.appendPic.img) {
- sprite.style.width = (sprite.width = editor_mode.appendPic.img.width) / ratio + 'px';
- sprite.style.height = (sprite.height = editor_mode.appendPic.img.height) / ratio + 'px';
- sprite_ctx.clearRect(0, 0, sprite.width, sprite.height);
- sprite_ctx.drawImage(editor_mode.appendPic.img, 0, 0);
+ editor.dom.sprite.style.width = (editor.dom.sprite.width = editor_mode.appendPic.img.width) / editor.uivalues.ratio + 'px';
+ editor.dom.sprite.style.height = (editor.dom.sprite.height = editor_mode.appendPic.img.height) / editor.uivalues.ratio + 'px';
+ editor.dom.spriteCtx.clearRect(0, 0, editor.dom.sprite.width, editor.dom.sprite.height);
+ editor.dom.spriteCtx.drawImage(editor_mode.appendPic.img, 0, 0);
}
return;
}
- var ysize = selectAppend.value.endsWith('48') ? 48 : 32;
+ var ysize = editor.dom.selectAppend.value.endsWith('48') ? 48 : 32;
editor_mode.appendPic.imageName = value;
var img = core.material.images[value];
editor_mode.appendPic.toImg = img;
@@ -268,21 +351,21 @@ editor_unsorted_2_wrapper=function(editor_mode){
editor_mode.appendPic.index = 0;
var selectStr = '';
for (var ii = 0; ii < num; ii++) {
- appendPicSelection.children[ii].style = 'left:0;top:0;height:' + (ysize - 6) + 'px';
+ editor.dom.appendPicSelection.children[ii].style = 'left:0;top:0;height:' + (ysize - 6) + 'px';
selectStr += '{"x":0,"y":0},'
}
editor_mode.appendPic.selectPos = eval('[' + selectStr + ']');
for (var jj = num; jj < 4; jj++) {
- appendPicSelection.children[jj].style = 'display:none';
+ editor.dom.appendPicSelection.children[jj].style = 'display:none';
}
- sprite.style.width = (sprite.width = img.width) / ratio + 'px';
- sprite.style.height = (sprite.height = img.height + ysize) / ratio + 'px';
- sprite_ctx.drawImage(img, 0, 0);
+ editor.dom.sprite.style.width = (editor.dom.sprite.width = img.width) / editor.uivalues.ratio + 'px';
+ editor.dom.sprite.style.height = (editor.dom.sprite.height = img.height + ysize) / editor.uivalues.ratio + 'px';
+ editor.dom.spriteCtx.drawImage(img, 0, 0);
}
- selectAppend.onchange();
+ editor.dom.selectAppend.onchange();
+ }
- var getPixel=editor.util.getPixel
- var setPixel=editor.util.setPixel
+ editor.uifunctions.selectFileBtn_func = function () {
var autoAdjust = function (image, callback) {
var changed = false;
@@ -297,21 +380,21 @@ editor_unsorted_2_wrapper=function(editor_mode){
tempCanvas.imageSmoothingEnabled = false;
tempCanvas.drawImage(image, 0, 0);
var imgData = tempCanvas.getImageData(0, 0, image.width, image.height);
- var trans = 0, white = 0, black=0;
- for (var i=0;iblack && white>trans*10 && confirm("看起来这张图片是以纯白为底色,是否自动调整为透明底色?")) {
- for (var i=0;i black && white > trans * 10 && confirm("看起来这张图片是以纯白为底色,是否自动调整为透明底色?")) {
+ for (var i = 0; i < image.width; i++) {
+ for (var j = 0; j < image.height; j++) {
+ var pixel = editor.util.getPixel(imgData, i, j);
+ if (pixel[0] == 255 && pixel[1] == 255 && pixel[2] == 255 && pixel[3] == 255) {
+ editor.util.setPixel(imgData, i, j, [0, 0, 0, 0]);
}
}
}
@@ -323,9 +406,9 @@ editor_unsorted_2_wrapper=function(editor_mode){
if (black>white && black>trans*10 && confirm("看起来这张图片是以纯黑为底色,是否自动调整为透明底色?")) {
for (var i=0;i= num) editor_mode.appendPic.index = ii + 1 - num;
else editor_mode.appendPic.index++;
editor_mode.appendPic.selectPos[ii] = pos;
- appendPicSelection.children[ii].style = [
+ editor.dom.appendPicSelection.children[ii].style = [
'left:', pos.x * 32, 'px;',
'top:', pos.y * pos.ysize, 'px;',
'height:', pos.ysize - 6, 'px;'
].join('');
}
+ }
+
+ editor.uifunctions.appendConfirm_func = function () {
var appendConfirm = document.getElementById('appendConfirm');
appendConfirm.onclick = function () {
var confirmAutotile = function () {
var image = editor_mode.appendPic.img;
- if (image.width % 96 !=0 || image.height != 128) {
+ if (image.width % 96 != 0 || image.height != 128) {
printe("不合法的Autotile图片!");
return;
}
- var imgData = source_ctx.getImageData(0,0,image.width,image.height);
- sprite_ctx.putImageData(imgData, 0, 0);
- var imgbase64 = sprite.toDataURL().split(',')[1];
+ var imgData = editor.dom.sourceCtx.getImageData(0, 0, image.width, image.height);
+ editor.dom.spriteCtx.putImageData(imgData, 0, 0);
+ var imgbase64 = editor.dom.sprite.toDataURL().split(',')[1];
// Step 1: List文件名
fs.readdir('./project/images', function (err, data) {
if (err) {
printe(err);
- throw(err);
+ throw (err);
}
// Step 2: 选择Autotile文件名
var filename;
- for (var i=1;;++i) {
- filename = 'autotile'+i;
- if (data.indexOf(filename+".png")==-1) break;
+ for (var i = 1; ; ++i) {
+ filename = 'autotile' + i;
+ if (data.indexOf(filename + ".png") == -1) break;
}
// Step 3: 写入文件
- fs.writeFile('./project/images/'+filename+".png", imgbase64, 'base64', function (err, data) {
+ fs.writeFile('./project/images/' + filename + ".png", imgbase64, 'base64', function (err, data) {
if (err) {
printe(err);
- throw(err);
+ throw (err);
}
// Step 4: 自动注册
editor.file.registerAutotile(filename, function (err) {
if (err) {
printe(err);
- throw(err);
+ throw (err);
}
- printe('自动元件'+filename+'注册成功,请F5刷新编辑器');
+ printe('自动元件' + filename + '注册成功,请F5刷新编辑器');
})
})
@@ -542,98 +634,96 @@ editor_unsorted_2_wrapper=function(editor_mode){
}
- if (selectAppend.value == 'autotile') {
+ if (editor.dom.selectAppend.value == 'autotile') {
confirmAutotile();
return;
}
- var ysize = selectAppend.value.endsWith('48') ? 48 : 32;
+ var ysize = editor.dom.selectAppend.value.endsWith('48') ? 48 : 32;
for (var ii = 0, v; v = editor_mode.appendPic.selectPos[ii]; ii++) {
- // var imgData = source_ctx.getImageData(v.x * 32, v.y * ysize, 32, ysize);
- // sprite_ctx.putImageData(imgData, ii * 32, sprite.height - ysize);
- // sprite_ctx.drawImage(editor_mode.appendPic.img, v.x * 32, v.y * ysize, 32, ysize, ii * 32, height, 32, ysize)
+ // var imgData = editor.dom.sourceCtx.getImageData(v.x * 32, v.y * ysize, 32, ysize);
+ // editor.dom.spriteCtx.putImageData(imgData, ii * 32, editor.dom.sprite.height - ysize);
+ // editor.dom.spriteCtx.drawImage(editor_mode.appendPic.img, v.x * 32, v.y * ysize, 32, ysize, ii * 32, height, 32, ysize)
- sprite_ctx.drawImage(source_ctx.canvas, v.x*32, v.y*ysize, 32, ysize, 32*ii, sprite.height - ysize, 32, ysize);
+ editor.dom.spriteCtx.drawImage(editor.dom.sourceCtx.canvas, v.x * 32, v.y * ysize, 32, ysize, 32 * ii, editor.dom.sprite.height - ysize, 32, ysize);
}
- var dt = sprite_ctx.getImageData(0, 0, sprite.width, sprite.height);
- var imgbase64 = sprite.toDataURL().split(',')[1];
+ var dt = editor.dom.spriteCtx.getImageData(0, 0, editor.dom.sprite.width, editor.dom.sprite.height);
+ var imgbase64 = editor.dom.sprite.toDataURL().split(',')[1];
fs.writeFile('./project/images/' + editor_mode.appendPic.imageName + '.png', imgbase64, 'base64', function (err, data) {
if (err) {
printe(err);
- throw(err)
+ throw (err)
}
- printe('追加素材成功,请F5刷新编辑器,或继续追加当前素材');
- sprite.style.height = (sprite.height = (sprite.height+ysize)) + "px";
- sprite_ctx.putImageData(dt, 0, 0);
+ printf('追加素材成功,你可以继续追加其他素材,最后再刷新以显示在素材区');
+ editor.dom.sprite.style.height = (editor.dom.sprite.height = (editor.dom.sprite.height + ysize)) + "px";
+ editor.dom.spriteCtx.putImageData(dt, 0, 0);
});
}
- editor_mode.change = function (value) {
- editor_mode.onmode('nextChange');
- editor_mode.onmode(value);
- if(editor.isMobile)editor.showdataarea(false);
- }
- var editModeSelect = document.getElementById('editModeSelect');
- editModeSelect.onchange = function () {
- editor_mode.change(editModeSelect.value);
- }
+ var quickAppendConfirm = document.getElementById('quickAppendConfirm');
+ quickAppendConfirm.onclick = function () {
+ var value = editor.dom.selectAppend.value;
+ if (value != 'enemys' && value != 'enemy48' && value != 'npcs' && value != 'npc48')
+ return printe("只有怪物或NPC才能快速导入!");
+ var ysize = value.endsWith('48') ? 48 : 32;
+ if (editor.dom.sourceCtx.canvas.width != 128 || editor.dom.sourceCtx.canvas.height != 4 * ysize)
+ return printe("只有 4*4 的素材图片才可以快速导入!");
- editor_mode.checkUnique = function (thiseval) {
- if (!(thiseval instanceof Array)) return false;
- var map = {};
- for (var i = 0; i,
+ * "plugins":
+ * }
+ * 的形式记录所有更改过的文件,save时写入
+ * 的内容暂时还没想好
+ */
+ this.fileMark = {}
}
// 这个函数之后挪到editor.table?
- editor_file_proto.prototype.loadCommentjs=function(callback){
+ editor_file_proto.prototype.loadCommentjs = function (callback) {
var commentjs = {
'comment': 'comment',
'data.comment': 'dataComment',
@@ -33,5 +42,107 @@ editor_file_wrapper = function (editor) {
}
}
+ editor_file_proto.prototype.alertWhenCompress = function () {
+ if (editor.useCompress === true) {
+ editor.useCompress = 'alerted';
+ setTimeout("alert('当前游戏使用的是压缩文件,修改完成后请使用启动服务.exe->Js代码压缩工具重新压缩,或者把main.js的useCompress改成false来使用原始文件')", 1000)
+ }
+ }
+
+ editor_file_proto.prototype.formatMap = function (mapArr, trySimplify) {
+ if (!mapArr || JSON.stringify(mapArr) == JSON.stringify([])) return '';
+ if (trySimplify) {
+ //检查是否是全0二维数组
+ var jsoncheck = JSON.stringify(mapArr).replace(/\D/g, '');
+ if (jsoncheck == Array(jsoncheck.length + 1).join('0')) return '';
+ }
+ //把二维数组格式化
+ var formatArrStr = '';
+ var arr = JSON.stringify(mapArr).replace(/\s+/g, '').split('],[');
+ var si = mapArr.length - 1, sk = mapArr[0].length - 1;
+ for (var i = 0; i <= si; i++) {
+ var a = [];
+ formatArrStr += ' [';
+ if (i == 0 || i == si) a = arr[i].split(/\D+/).join(' ').trim().split(' ');
+ else a = arr[i].split(/\D+/);
+ for (var k = 0; k <= sk; k++) {
+ var num = parseInt(a[k]);
+ formatArrStr += Array(Math.max(4 - String(num).length, 0)).join(' ') + num + (k == sk ? '' : ',');
+ }
+ formatArrStr += ']' + (i == si ? '' : ',\n');
+ }
+ return formatArrStr;
+ }
+
+ editor_file_proto.prototype.saveFloor = function (floorData, callback) {
+ //callback(err:String)
+ var floorId = floorData.floorId;
+ var filename = 'project/floors/' + floorId + '.js';
+ var datastr = ['main.floors.', floorId, '=\n'];
+
+ var tempJsonObj = Object.assign({}, floorData);
+ var tempMap = [['map', editor.util.guid()], ['bgmap', editor.util.guid()], ['fgmap', editor.util.guid()]];
+ tempMap.forEach(function (v) {
+ v[2] = tempJsonObj[v[0]];
+ tempJsonObj[v[0]] = v[1];
+ });
+ var tempJson = JSON.stringify(tempJsonObj, editor.game.replacerForSaving, 4);
+ tempMap.forEach(function (v) {
+ tempJson = tempJson.replace('"' + v[1] + '"', '[\n' + editor.file.formatMap(v[2], v[0] != 'map') + '\n]')
+ });
+ datastr = datastr.concat([tempJson]);
+ datastr = datastr.join('');
+ editor.file.alertWhenCompress();
+ editor.fs.writeFile(filename, editor.util.encode64(datastr), 'base64', function (err, data) {
+ editor.addUsedFlags(datastr);
+ callback(err);
+ });
+ }
+
+ editor_file_proto.prototype.saveScript = function (name, varName, dataObj, callback) {
+ // 此处格式化以及写入 project/xxx.js 形式的文件
+ editor.file.alertWhenCompress();
+
+ if (['maps', 'enemys'].indexOf(name) === -1) {
+ // 全部用\t展开
+ var content = JSON.stringify(dataObj, editor.game.replacerForSaving, '\t');
+ } else {
+ // 只用\t展开第一层
+ var emap = {};
+ var estr = JSON.stringify(dataObj, function (_k, v) {
+ if (v.id != null) {
+ var id_ = editor.util.guid();
+ emap[id_] = JSON.stringify(v, editor.game.replacerForSaving);
+ return id_;
+ } else return v
+ }, '\t');
+ for (var id_ in emap) {
+ estr = estr.replace('"' + id_ + '"', emap[id_]);
+ }
+ var content = estr;
+ }
+
+ var strToWrite = `var ${varName} = \n${content}`;
+ editor.fs.writeFile(`project/${name}.js`, editor.util.encode64(strToWrite), 'base64', function (err, data) {
+ callback(err);
+ });
+ }
+
+ editor_file_proto.prototype.saveCommentJs = function () {
+ // 无需格式化的写入, 把multi的那部分略微修改
+ }
+
+ editor_file_proto.prototype.saveImage = function () {
+ // 给追加素材使用
+ }
+
+ editor_file_proto.prototype.addMark = function (name) {
+ // 把name对应的文件在editor.file.fileMark添加标记
+ }
+
+ editor_file_proto.prototype.save = function (callback) {
+ // 根据 editor.file.fileMark 把游戏对象格式化写入文件
+ }
+
}
\ No newline at end of file
diff --git a/_server/editor_file_unsorted.js b/_server/editor_file_unsorted.js
index cbf79655..42509f14 100644
--- a/_server/editor_file_unsorted.js
+++ b/_server/editor_file_unsorted.js
@@ -5,9 +5,8 @@ editor_file = function (editor, callback) {
editor.file.loadCommentjs(callback);
- ///////////////////////////////////////////////////////////////////////////
-
editor.file.saveFloorFile = function (callback) {
+ //callback(err:String)
checkCallback(callback);
/* if (!isset(editor.currentFloorId) || !isset(editor.currentFloorData)) {
callback('未选中文件或无数据');
@@ -25,27 +24,11 @@ editor_file = function (editor, callback) {
editor.currentFloorData[name]=mapArray;
}
}
-
- // format 更改实现方式以支持undefined删除
- var tempJsonObj=Object.assign({},editor.currentFloorData);
- var tempMap=[['map',editor.util.guid()],['bgmap',editor.util.guid()],['fgmap',editor.util.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) {
- editor.addUsedFlags(datastr);
- callback(err);
- });
+ editor.file.saveFloor(editor.currentFloorData, callback)
}
- //callback(err:String)
+
+ ///////////////////////////////////////////////////////////////////////////
+
editor.file.saveNewFile = function (saveFilename, callback) {
//saveAsFilename不含'/'不含'.js'
checkCallback(callback);
@@ -135,7 +118,7 @@ editor_file = function (editor, callback) {
delete data[t];
else {
if (t=='map') {
- datastr = datastr.concat(['\n"', t, '": [\n', formatMap(data[t]), '\n],']);
+ datastr = datastr.concat(['\n"', t, '": [\n', editor.file.formatMap(data[t]), '\n],']);
}
else {
datastr = datastr.concat(['\n"', t, '": ', JSON.stringify(data[t], null, 4), ',']);
@@ -146,7 +129,7 @@ editor_file = function (editor, callback) {
datastr = datastr.join('');
datas.push(encode(datastr));
}
- alertWhenCompress();
+ editor.file.alertWhenCompress();
fs.writeMultiFiles(filenames, datas, function (err, data) {
callback(err);
});
@@ -469,7 +452,8 @@ editor_file = function (editor, callback) {
checkCallback(callback);
if (isset(actionList) && actionList.length > 0) {
actionList.forEach(function (value) {
- value[1] = value[1] + "['" + x + "," + y + "']";
+ if(/\['autoEvent'\]\['\d+'\]$/.test(value[1]))value[1]=value[1].replace(/\['\d+'\]$/,function(v){return "['" + x + "," + y + "']"+v})
+ else value[1] = value[1] + "['" + x + "," + y + "']";
});
saveSetting('floorloc', actionList, function (err) {
callback([err]);
@@ -700,32 +684,7 @@ editor_file = function (editor, callback) {
}
}
- var formatMap = function (mapArr,trySimplify) {
- if(!mapArr || JSON.stringify(mapArr)==JSON.stringify([]))return '';
- if(trySimplify){
- //检查是否是全0二维数组
- var jsoncheck=JSON.stringify(mapArr).replace(/\D/g,'');
- if(jsoncheck==Array(jsoncheck.length+1).join('0'))return '';
- }
- //把二维数组格式化
- var formatArrStr = '';
- var arr = JSON.stringify(mapArr).replace(/\s+/g, '').split('],[');
- var si=mapArr.length-1,sk=mapArr[0].length-1;
- for (var i = 0; i <= si; i++) {
- var a = [];
- formatArrStr += ' [';
- if (i == 0 || i == si) a = arr[i].split(/\D+/).join(' ').trim().split(' ');
- else a = arr[i].split(/\D+/);
- for (var k = 0; k <= sk; k++) {
- var num = parseInt(a[k]);
- formatArrStr += Array(Math.max(4 - String(num).length, 0)).join(' ') + num + (k == sk ? '' : ',');
- }
- formatArrStr += ']' + (i == si ? '' : ',\n');
- }
- return formatArrStr;
- }
-
- var encode = editor.util.encode64
+ var encode = editor.util.encode64;
var alertWhenCompress = function(){
if(editor.useCompress===true){
@@ -761,7 +720,7 @@ editor_file = function (editor, callback) {
var saveSetting = function (file, actionList, callback) {
//console.log(file);
//console.log(actionList);
- alertWhenCompress();
+ editor.file.alertWhenCompress();
if (file == 'icons') {
actionList.forEach(function (value) {
@@ -863,7 +822,13 @@ editor_file = function (editor, callback) {
if (file == 'floorloc') {
actionList.forEach(function (value) {
// 检测null/undefined
- if (value[2]==null)
+ if(/\['autoEvent'\]\['\d+,\d+'\]\['\d+'\]$/.test(value[1])){
+ var tempvalue=value[1].replace(/\['\d+'\]$/,'')
+ tempvalue="editor.currentFloorData" +tempvalue
+ tempvalue=tempvalue+'='+tempvalue+'||{}'
+ eval(tempvalue)
+ }
+ if (value[2]==null && value[0]!=='add')
eval("delete editor.currentFloorData" + value[1]);
else
eval("editor.currentFloorData" + value[1] + '=' + JSON.stringify(value[2]));
diff --git a/_server/editor_game.js b/_server/editor_game.js
index 278dd67e..27c51001 100644
--- a/_server/editor_game.js
+++ b/_server/editor_game.js
@@ -146,6 +146,9 @@ editor_game_wrapper = function (editor, main, core) {
});
editor.currentFloorId = core.status.floorId;
editor.currentFloorData = core.floors[core.status.floorId];
+ // 补出缺省的数据
+ editor.currentFloorData.autoEvent = editor.currentFloorData.autoEvent || {};
+ //
for (var ii = 0, name; name = ['bgmap', 'fgmap'][ii]; ii++) {
var mapArray = editor.currentFloorData[name];
if (!mapArray || JSON.stringify(mapArray) == JSON.stringify([])) {//未设置或空数组
@@ -175,6 +178,18 @@ editor_game_wrapper = function (editor, main, core) {
callback([editor.core.floorIds, null]);
}
+ editor_game.prototype.doCoreFunc = function (funcname) {
+ return core[funcname].apply(core, Array.prototype.slice.call(arguments, 1));
+ }
+
+ editor_game.prototype.getEnemy = function (id) {
+ return core.material.enemys[id];
+ }
+
+ editor_game.prototype.getFirstData = function () {
+ return core.firstData;
+ }
+
editor.constructor.prototype.game = new editor_game();
}
//editor_game_wrapper(editor);
\ No newline at end of file
diff --git a/_server/editor_unsorted_3.js b/_server/editor_legacy.js
similarity index 61%
rename from _server/editor_unsorted_3.js
rename to _server/editor_legacy.js
index 7f1d0edc..1313ebbc 100644
--- a/_server/editor_unsorted_3.js
+++ b/_server/editor_legacy.js
@@ -1,4 +1,6 @@
-
+// 由于历史遗留原因, 以下变量作为全局变量使用
+// exportMap mapEditArea pout mapEditArea copyMap clearMapButton deleteMap printf printe tip selectBox
+// 除对这些量的功能修改外, 误在此文件中增加新变量或函数
exportMap = document.getElementById('exportMap')
exportMap.isExport=false
exportMap.onclick=function(){
@@ -361,7 +363,6 @@ tip.whichShow=function(value){
return tip._whichShow
}
selectBox=document.getElementById('selectBox')
-dataSelection=document.getElementById('dataSelection')
selectBox._isSelected=false
selectBox.isSelected=function(value){
if(value!=null){
@@ -369,206 +370,9 @@ selectBox.isSelected=function(value){
tip.isSelectedBlock(value);
tip.whichShow(0);
clearTimeout(tip.timer);
- dataSelection.style.display=value?'':'none'
+ editor.dom.dataSelection.style.display=value?'':'none'
}
return selectBox._isSelected
}
-// ------ UI预览 & 地图选点相关 ------ //
-
-uievent = {
- elements: {},
- values: {},
- isOpen: false,
- mode: ""
-};
-
-uievent.elements.div = document.getElementById('uieventDiv');
-uievent.elements.title = document.getElementById('uieventTitle');
-uievent.elements.yes = document.getElementById('uieventYes');
-uievent.elements.no = document.getElementById('uieventNo');
-uievent.elements.selectBackground = document.getElementById('uieventBackground');
-uievent.elements.selectPoint = document.getElementById('selectPoint');
-uievent.elements.selectFloor = document.getElementById('selectPointFloor');
-uievent.elements.selectPointBox = document.getElementById('selectPointBox');
-uievent.elements.body = document.getElementById('uieventBody');
-uievent.elements.selectPointButtons = document.getElementById('selectPointButtons');
-
-uievent.confirm = function () {
- var callback = uievent.values.callback, floorId = uievent.values.floorId,
- x = uievent.values.x, y = uievent.values.y;
- uievent.close();
- if (callback) {
- callback(floorId, x, y);
- }
-}
-uievent.elements.yes.onclick = uievent.confirm;
-
-uievent.close = function () {
- uievent.isOpen = false;
- uievent.elements.div.style.display = 'none';
- uievent.values = {};
-}
-uievent.elements.no.onclick = uievent.close;
-
-uievent.elements.selectBackground.onchange = function () {
- uievent.drawPreviewUI();
-}
-
-uievent.drawPreviewUI = function () {
- core.setAlpha('uievent', 1);
- core.clearMap('uievent');
-
- // 绘制UI
- var background = uievent.elements.selectBackground.value;
- if (background == 'thumbnail') {
- core.drawThumbnail(editor.currentFloorId, null, {}, 'uievent');
- }
- else {
- core.fillRect('uievent', 0, 0, core.__PIXELS__, core.__PIXELS__, background);
- }
-
- if (uievent.values.list instanceof Array) {
- uievent.values.list.forEach(function (data) {
- var type = data.type;
- if (!type || !core.ui["_uievent_"+type]) return;
- core.ui["_uievent_"+type](data);
- })
- }
-}
-
-uievent.previewUI = function (list) {
- uievent.isOpen = true;
- uievent.elements.div.style.display = 'block';
- uievent.mode = 'previewUI';
- uievent.elements.selectPoint.style.display = 'none';
- uievent.elements.yes.style.display = 'none';
- uievent.elements.title.innerText = 'UI绘制预览';
- uievent.elements.selectBackground.style.display = 'inline';
- uievent.elements.selectBackground.value = 'thumbnail';
- uievent.elements.selectPointBox.style.display = 'none';
-
- uievent.values.list = list;
- uievent.drawPreviewUI();
-}
-
-uievent.selectPoint = function (floorId, x, y, hideFloor, callback) {
- uievent.values.hideFloor = hideFloor;
- uievent.values.callback = callback;
- uievent.values.size = editor.isMobile ? window.innerWidth / core.__SIZE__ : 32;
- uievent.elements.selectPointBox.style.width = (uievent.values.size - 6) + "px";
- uievent.elements.selectPointBox.style.height = (uievent.values.size - 6) + "px";
-
- uievent.isOpen = true;
- uievent.elements.div.style.display = 'block';
- uievent.mode = 'selectPoint';
- uievent.elements.selectPoint.style.display = 'block';
- uievent.elements.yes.style.display = 'inline';
- uievent.elements.selectBackground.style.display = 'none';
- uievent.elements.selectFloor.style.display = hideFloor ? 'none': 'inline';
- uievent.elements.selectPointBox.style.display = 'block';
-
- // Append children
- var floors = "";
- core.floorIds.forEach(function (f) {
- floors += "";
- })
- uievent.elements.selectFloor.innerHTML = floors;
-
- this.setPoint(floorId || editor.currentFloorId, core.calValue(x) || 0, core.calValue(y) || 0);
-}
-
-uievent.updateSelectPoint = function (redraw) {
- uievent.elements.title.innerText = '地图选点 ('+uievent.values.x+","+uievent.values.y+')';
- if (redraw) {
- core.setAlpha('uievent', 1);
- core.clearMap('uievent');
- core.drawThumbnail(uievent.values.floorId, null, null,
- {ctx: 'uievent', centerX: uievent.values.left + core.__HALF_SIZE__,
- centerY: uievent.values.top + core.__HALF_SIZE__});
- }
- uievent.elements.selectPointBox.style.left = uievent.values.size * (uievent.values.x - uievent.values.left) + "px";
- uievent.elements.selectPointBox.style.top = uievent.values.size * (uievent.values.y - uievent.values.top) + "px";
-}
-
-uievent.setPoint = function (floorId, x, y) {
- if (core.floorIds.indexOf(floorId) == -1) floorId = editor.currentFloorId;
- uievent.values.floorId = floorId;
- uievent.elements.selectFloor.value = floorId;
- uievent.values.x = x != null ? x : ( uievent.values.x || 0);
- uievent.values.y = y != null ? y : ( uievent.values.y || 0);
- uievent.values.width = core.floors[uievent.values.floorId].width || core.__SIZE__;
- uievent.values.height = core.floors[uievent.values.floorId].height || core.__SIZE__;
- uievent.values.left = core.clamp(uievent.values.x - core.__HALF_SIZE__, 0, uievent.values.width - core.__SIZE__);
- uievent.values.top = core.clamp(uievent.values.y - core.__HALF_SIZE__, 0, uievent.values.height - core.__SIZE__);
- uievent.updateSelectPoint(true);
-}
-
-uievent.elements.selectFloor.onchange = function () {
- uievent.setPoint(uievent.elements.selectFloor.value);
-}
-
-uievent.elements.selectPointBox.onclick = function (e) {
- e.stopPropagation();
-}
-
-uievent.elements.body.onclick = function (e) {
- if (uievent.mode != 'selectPoint') return;
- uievent.values.x = uievent.values.left + Math.floor(e.offsetX / uievent.values.size);
- uievent.values.y = uievent.values.top + Math.floor(e.offsetY / uievent.values.size);
- uievent.updateSelectPoint(false);
-}
-
-uievent.move = function (dx, dy) {
- if (uievent.mode != 'selectPoint') return;
- uievent.values.left = core.clamp(uievent.values.left + dx, 0, uievent.values.width - core.__SIZE__);
- uievent.values.top = core.clamp(uievent.values.top + dy, 0, uievent.values.height - core.__SIZE__);
- this.updateSelectPoint(true);
-};
-
-(function() {
-
- var viewportButtons = uievent.elements.selectPointButtons;
- var pressTimer = null;
- for(var ii=0,node;node=viewportButtons.children[ii];ii++){
- (function(x,y){
- var move = function () {
- uievent.move(x, y);
- }
- node.onmousedown = function () {
- clearTimeout(pressTimer);
- pressTimer = setTimeout(function () {
- pressTimer = -1;
- var f = function () {
- if (pressTimer != null) {
- move();
- setTimeout(f, 150);
- }
- }
- f();
- }, 500);
- };
- node.onmouseup = function () {
- if (pressTimer > 0) {
- clearTimeout(pressTimer);
- move();
- }
- pressTimer = null;
- }
- })([-1,0,0,1][ii],[0,-1,1,0][ii]);
- }
-})();
-
-uievent.elements.div.onmousewheel = function (e) {
- if (uievent.mode != 'selectPoint' || uievent.values.hideFloor) return;
- var index = core.floorIds.indexOf(uievent.values.floorId);
- try {
- if (e.wheelDelta)
- index+=Math.sign(e.wheelDelta);
- else if (e.detail)
- index+=Math.sign(e.detail);
- } catch (ee) { main.log(ee); }
- index = core.clamp(index, 0, core.floorIds.length - 1);
- uievent.setPoint(core.floorIds[index]);
-}
-
+// 修改此文件前先看文件开头的说明
\ No newline at end of file
diff --git a/_server/editor_listen.js b/_server/editor_listen.js
new file mode 100644
index 00000000..dec2bc2f
--- /dev/null
+++ b/_server/editor_listen.js
@@ -0,0 +1,159 @@
+editor_listen_wrapper = function (editor) {
+
+ editor.constructor.prototype.listen = function () {
+
+ editor.dom.body.onmousedown = editor.uifunctions.body_click;
+
+ editor.dom.eui.oncontextmenu = function (e) { e.preventDefault() } // 自定义了右键菜单, 阻止默认行为
+ editor.dom.midMenu.oncontextmenu = function (e) { e.preventDefault() }
+
+ editor.dom.eui.ondblclick = editor.uifunctions.map_doubleClick
+
+ editor.dom.eui.onmousedown = editor.uifunctions.map_ondown
+ editor.dom.eui.onmousemove = editor.uifunctions.map_onmove
+ editor.dom.eui.onmouseup = editor.uifunctions.map_onup
+
+ editor.dom.mid.onmousewheel = editor.uifunctions.map_mousewheel
+
+ editor.uivalues.shortcut = core.getLocalStorage('shortcut', { 48: 0, 49: 0, 50: 0, 51: 0, 52: 0, 53: 0, 54: 0, 55: 0, 56: 0, 57: 0 });
+ editor.dom.body.onkeydown = editor.uifunctions.body_shortcut
+
+ editor.uivalues.scrollBarHeight = editor.uifunctions.getScrollBarHeight();
+ editor.dom.iconExpandBtn.style.display = 'block';
+ editor.dom.iconExpandBtn.innerText = editor.uivalues.folded ? "展开素材区" : "折叠素材区";
+ editor.dom.iconExpandBtn.onclick = editor.uifunctions.fold_material_click
+
+ editor.dom.iconLib.onmousedown = editor.uifunctions.material_ondown
+
+ editor.dom.extraEvent.onmousedown = editor.uifunctions.extraEvent_click
+ editor.dom.chooseThis.onmousedown = editor.uifunctions.chooseThis_click
+ editor.dom.chooseInRight.onmousedown = editor.uifunctions.chooseInRight_click
+ editor.dom.copyLoc.onmousedown = editor.uifunctions.copyLoc_click
+ editor.dom.moveLoc.onmousedown = editor.uifunctions.moveLoc_click
+ editor.dom.clearEvent.onmousedown = editor.uifunctions.clearEvent_click
+ editor.dom.clearLoc.onmousedown = editor.uifunctions.clearLoc_click
+
+ editor.dom.brushMod.onchange = editor.uifunctions.brushMod_onchange
+ if (editor.dom.brushMod2) editor.dom.brushMod2.onchange = editor.uifunctions.brushMod2_onchange;
+ if (editor.dom.brushMod3) editor.dom.brushMod3.onchange = editor.uifunctions.brushMod3_onchange;
+
+ editor.dom.layerMod.onchange = editor.uifunctions.layerMod_onchange
+ if (editor.dom.layerMod2) editor.dom.layerMod2.onchange = editor.uifunctions.layerMod2_onchange;
+ if (editor.dom.layerMod3) editor.dom.layerMod3.onchange = editor.uifunctions.layerMod3_onchange;
+
+ editor.uifunctions.viewportButtons_func()
+ }
+
+ editor.constructor.prototype.mobile_listen = function () {
+ if (!editor.isMobile) return;
+
+ var mobileview = document.getElementById('mobileview');
+ var mid = document.getElementById('mid');
+ var right = document.getElementById('right');
+ // var mobileeditdata = document.getElementById('mobileeditdata');
+
+
+ editor.showdataarea = function (callShowMode) {
+ mid.style = 'z-index:-1;opacity: 0;';
+ right.style = 'z-index:-1;opacity: 0;';
+ // mobileeditdata.style = '';
+ if (callShowMode) editor.mode.showMode(editor.dom.editModeSelect.value);
+ editor.uifunctions.hideMidMenu();
+ }
+ mobileview.children[0].onclick = function () {
+ editor.showdataarea(true)
+ }
+ mobileview.children[1].onclick = function () {
+ mid.style = '';
+ right.style = 'z-index:-1;opacity: 0;';
+ // mobileeditdata.style = 'z-index:-1;opacity: 0;';
+ editor.lastClickId = '';
+ }
+ mobileview.children[3].onclick = function () {
+ mid.style = 'z-index:-1;opacity: 0;';
+ right.style = '';
+ // mobileeditdata.style = 'z-index:-1;opacity: 0;';
+ editor.lastClickId = '';
+ }
+
+ /*
+ var gettrbyid = function () {
+ if (!editor.lastClickId) return false;
+ thisTr = document.getElementById(editor.lastClickId);
+ input = thisTr.children[2].children[0].children[0];
+ field = thisTr.children[0].getAttribute('title');
+ cobj = JSON.parse(thisTr.children[1].getAttribute('cobj'));
+ return [thisTr, input, field, cobj];
+ }
+ mobileeditdata.children[0].onclick = function () {
+ var info = gettrbyid()
+ if (!info) return;
+ info[1].ondblclick()
+ }
+ mobileeditdata.children[1].onclick = function () {
+ var info = gettrbyid()
+ if (!info) return;
+ printf(info[2])
+ }
+ mobileeditdata.children[2].onclick = function () {
+ var info = gettrbyid()
+ if (!info) return;
+ printf(info[0].children[1].getAttribute('title'))
+ }
+ */
+
+ //=====
+
+ document.body.ontouchstart = document.body.onmousedown;
+ document.body.onmousedown = null;
+
+ editor.dom.eui.ontouchstart = editor.dom.eui.onmousedown
+ editor.dom.eui.onmousedown = null
+ editor.dom.eui.ontouchmove = editor.dom.eui.onmousemove
+ editor.dom.eui.onmousemove = null
+ editor.dom.eui.ontouchend = editor.dom.eui.onmouseup
+ editor.dom.eui.onmouseup = null
+
+
+ editor.dom.chooseThis.ontouchstart = editor.dom.chooseThis.onmousedown
+ editor.dom.chooseThis.onmousedown = null
+ editor.dom.chooseInRight.ontouchstart = editor.dom.chooseInRight.onmousedown
+ editor.dom.chooseInRight.onmousedown = null
+ editor.dom.copyLoc.ontouchstart = editor.dom.copyLoc.onmousedown
+ editor.dom.copyLoc.onmousedown = null
+ editor.dom.moveLoc.ontouchstart = editor.dom.moveLoc.onmousedown
+ editor.dom.moveLoc.onmousedown = null
+ editor.dom.clearLoc.ontouchstart = editor.dom.clearLoc.onmousedown
+ editor.dom.clearLoc.onmousedown = null
+ }
+
+ editor.constructor.prototype.mode_listen = function (callback) {
+
+ // 这里的函数还没有写jsdoc, 通过_func()的方式先完成分类
+
+ editor.uifunctions.newIdIdnum_func()
+ editor.uifunctions.changeId_func()
+
+ editor.uifunctions.selectFloor_func()
+ editor.uifunctions.saveFloor_func()
+
+ editor.uifunctions.newMap_func()
+
+ editor.uifunctions.createNewMaps_func()
+
+ editor.uifunctions.changeFloorId_func()
+
+ editor.uifunctions.fixCtx_func()
+
+ editor.uifunctions.selectAppend_func()
+ editor.uifunctions.selectFileBtn_func()
+ editor.uifunctions.changeColorInput_func()
+ editor.uifunctions.picClick_func()
+ editor.uifunctions.appendConfirm_func()
+
+ editor.dom.editModeSelect.onchange = editor.mode.editModeSelect_onchange
+
+ if (Boolean(callback)) callback();
+ }
+
+}
\ No newline at end of file
diff --git a/_server/editor_mappanel.js b/_server/editor_mappanel.js
new file mode 100644
index 00000000..9e50b957
--- /dev/null
+++ b/_server/editor_mappanel.js
@@ -0,0 +1,839 @@
+editor_mappanel_wrapper = function (editor) {
+
+ // 暂时先 注释+分类 内部函数未完成重构
+
+ /**
+ * 在绘图区格子内画一个随机色块
+ */
+ editor.uifunctions.fillPos = function (pos) {
+ editor.dom.euiCtx.fillStyle = '#' + ~~(Math.random() * 8) + ~~(Math.random() * 8) + ~~(Math.random() * 8);
+ editor.dom.euiCtx.fillRect(pos.x * 32 + 12 - core.bigmap.offsetX, pos.y * 32 + 12 - core.bigmap.offsetY, 8, 8);
+ }
+
+ /**
+ * 从鼠标点击返回可用的组件内坐标
+ */
+ editor.uifunctions.eToLoc = function (e) {
+ var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft
+ var scrollTop = document.documentElement.scrollTop || document.body.scrollTop
+ var xx = e.clientX, yy = e.clientY
+ if (editor.isMobile) { xx = e.touches[0].clientX, yy = e.touches[0].clientY }
+ editor.loc = {
+ 'x': scrollLeft + xx - editor.dom.mid.offsetLeft - editor.dom.mapEdit.offsetLeft,
+ 'y': scrollTop + yy - editor.dom.mid.offsetTop - editor.dom.mapEdit.offsetTop,
+ 'size': editor.isMobile ? (32 * innerWidth * 0.96 / core.__PIXELS__) : 32
+ };
+ return editor.loc;
+ }
+
+ /**
+ * 组件内坐标转地图位置
+ * @param {Boolean} addViewportOffset 是否加上大地图的偏置
+ */
+ editor.uifunctions.locToPos = function (loc, addViewportOffset) {
+ var offsetX = 0, offsetY = 0;
+ if (addViewportOffset) {
+ offsetX = core.bigmap.offsetX / 32;
+ offsetY = core.bigmap.offsetY / 32;
+ }
+ editor.pos = { 'x': ~~(loc.x / loc.size) + offsetX, 'y': ~~(loc.y / loc.size) + offsetY }
+ return editor.pos;
+ }
+
+ /**
+ * editor.dom.eui.ondblclick
+ * 双击地图可以选中素材
+ */
+ editor.uifunctions.map_doubleClick = function (e) {
+ if (editor.uivalues.bindSpecialDoor.loc != null) return;
+ var loc = editor.uifunctions.eToLoc(e);
+ var pos = editor.uifunctions.locToPos(loc, true);
+ editor.setSelectBoxFromInfo(editor[editor.layerMod][pos.y][pos.x]);
+ return;
+ }
+
+ /**
+ * 用于鼠标移出map后清除状态
+ */
+ editor.uifunctions.clearMapStepStatus = function () {
+ if (editor.uivalues.mouseOutCheck > 1) {
+ editor.uivalues.mouseOutCheck--;
+ setTimeout(editor.uifunctions.clearMapStepStatus, 1000);
+ return;
+ }
+ editor.uivalues.holdingPath = 0;
+ editor.uivalues.stepPostfix = [];
+ editor.dom.euiCtx.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__);
+ editor.uivalues.startPos = editor.uivalues.endPos = null;
+ }
+
+ /**
+ * editor.dom.eui.onmousedown
+ * + 绑定机关门事件的选择怪物
+ * + 右键进入菜单
+ * + 非绘图时选中
+ * + 绘图时画个矩形在那个位置
+ */
+ editor.uifunctions.map_ondown = function (e) {
+ var loc = editor.uifunctions.eToLoc(e);
+ var pos = editor.uifunctions.locToPos(loc, true);
+ if (editor.uivalues.bindSpecialDoor.loc != null) {
+ var x = editor.pos.x, y = editor.pos.y, id = (editor.map[y][x] || {}).id;
+ // 检测是否是怪物
+ if (id && editor.game.getEnemy(id)) {
+ var locstr = x + "," + y, index = editor.uivalues.bindSpecialDoor.enemys.indexOf(locstr);
+ if (index >= 0) editor.uivalues.bindSpecialDoor.enemys.splice(index, 1);
+ else editor.uivalues.bindSpecialDoor.enemys.push(locstr);
+ editor.drawEventBlock();
+ editor.uifunctions._extraEvent_bindSpecialDoor_doAction();
+ }
+ return false;
+ }
+ if (e.button == 2) {
+ editor.uifunctions.showMidMenu(e.clientX, e.clientY);
+ return false;
+ }
+ if (!selectBox.isSelected()) {
+ editor_mode.onmode('nextChange');
+ editor_mode.onmode('loc');
+ //editor_mode.loc();
+ //tip.whichShow(1);
+ tip.showHelp(6);
+ editor.uivalues.startPos = pos;
+ editor.dom.euiCtx.strokeStyle = '#FF0000';
+ editor.dom.euiCtx.lineWidth = 3;
+ if (editor.isMobile) editor.uifunctions.showMidMenu(e.clientX, e.clientY);
+ return false;
+ }
+
+ editor.uivalues.holdingPath = 1;
+ editor.uivalues.mouseOutCheck = 2;
+ setTimeout(editor.uifunctions.clearMapStepStatus);
+ editor.dom.euiCtx.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__);
+ editor.uivalues.stepPostfix = [];
+ editor.uivalues.stepPostfix.push(pos);
+ if (editor.brushMod == 'line') editor.uifunctions.fillPos(pos);
+ return false;
+ }
+
+ /**
+ * editor.dom.eui.onmousemove
+ * + 非绘图模式时维护起止位置并画箭头
+ * + 绘图模式时找到与队列尾相邻的鼠标方向的点画个矩形
+ */
+ editor.uifunctions.map_onmove = function (e) {
+ if (!selectBox.isSelected()) {
+ if (editor.uivalues.startPos == null) return;
+ //tip.whichShow(1);
+ var loc = editor.uifunctions.eToLoc(e);
+ var pos = editor.uifunctions.locToPos(loc, true);
+ if (editor.uivalues.endPos != null && editor.uivalues.endPos.x == pos.x && editor.uivalues.endPos.y == pos.y) return;
+ if (editor.uivalues.endPos != null) {
+ editor.dom.euiCtx.clearRect(Math.min(32 * editor.uivalues.startPos.x - core.bigmap.offsetX, 32 * editor.uivalues.endPos.x - core.bigmap.offsetX),
+ Math.min(32 * editor.uivalues.startPos.y - core.bigmap.offsetY, 32 * editor.uivalues.endPos.y - core.bigmap.offsetY),
+ (Math.abs(editor.uivalues.startPos.x - editor.uivalues.endPos.x) + 1) * 32, (Math.abs(editor.uivalues.startPos.y - editor.uivalues.endPos.y) + 1) * 32)
+ }
+ editor.uivalues.endPos = pos;
+ if (editor.uivalues.startPos != null) {
+ if (editor.uivalues.startPos.x != editor.uivalues.endPos.x || editor.uivalues.startPos.y != editor.uivalues.endPos.y) {
+ core.drawArrow('eui',
+ 32 * editor.uivalues.startPos.x + 16 - core.bigmap.offsetX, 32 * editor.uivalues.startPos.y + 16 - core.bigmap.offsetY,
+ 32 * editor.uivalues.endPos.x + 16 - core.bigmap.offsetX, 32 * editor.uivalues.endPos.y + 16 - core.bigmap.offsetY);
+ }
+ }
+ // editor_mode.onmode('nextChange');
+ // editor_mode.onmode('loc');
+ //editor_mode.loc();
+ //tip.whichShow(1);
+ // tip.showHelp(6);
+ return false;
+ }
+
+ if (editor.uivalues.holdingPath == 0) {
+ return false;
+ }
+ editor.uivalues.mouseOutCheck = 2;
+ var loc = editor.uifunctions.eToLoc(e);
+ var pos = editor.uifunctions.locToPos(loc, true);
+ var pos0 = editor.uivalues.stepPostfix[editor.uivalues.stepPostfix.length - 1]
+ var directionDistance = [pos.y - pos0.y, pos0.x - pos.x, pos0.y - pos.y, pos.x - pos0.x]
+ var max = 0, index = 4;
+ for (var i = 0; i < 4; i++) {
+ if (directionDistance[i] > max) {
+ index = i;
+ max = directionDistance[i];
+ }
+ }
+ var pos = [{ 'x': 0, 'y': 1 }, { 'x': -1, 'y': 0 }, { 'x': 0, 'y': -1 }, { 'x': 1, 'y': 0 }, false][index]
+ if (pos) {
+ pos.x += pos0.x;
+ pos.y += pos0.y;
+ if (editor.brushMod == 'line') editor.uifunctions.fillPos(pos);
+ else {
+ var x0 = editor.uivalues.stepPostfix[0].x;
+ var y0 = editor.uivalues.stepPostfix[0].y;
+ var x1 = pos.x;
+ var y1 = pos.y;
+ if (x0 > x1) { x0 ^= x1; x1 ^= x0; x0 ^= x1; }//swap
+ if (y0 > y1) { y0 ^= y1; y1 ^= y0; y0 ^= y1; }//swap
+ // draw rect
+ editor.dom.euiCtx.clearRect(0, 0, editor.dom.euiCtx.canvas.width, editor.dom.euiCtx.canvas.height);
+ editor.dom.euiCtx.fillStyle = 'rgba(0, 127, 255, 0.4)';
+ editor.dom.euiCtx.fillRect(32 * x0 - core.bigmap.offsetX, 32 * y0 - core.bigmap.offsetY,
+ 32 * (x1 - x0) + 32, 32 * (y1 - y0) + 32);
+ }
+ editor.uivalues.stepPostfix.push(pos);
+ }
+ return false;
+ }
+
+ /**
+ * editor.dom.eui.onmouseup
+ * + 非绘图模式时, 交换首末点的内容
+ * + 绘图模式时, 根据画线/画矩形/画tileset 做对应的绘制
+ */
+ editor.uifunctions.map_onup = function (e) {
+ if (!selectBox.isSelected()) {
+ //tip.whichShow(1);
+ // editor.movePos(editor.uivalues.startPos, editor.uivalues.endPos);
+ if (editor.layerMod == 'map')
+ editor.exchangePos(editor.uivalues.startPos, editor.uivalues.endPos);
+ else
+ editor.exchangeBgFg(editor.uivalues.startPos, editor.uivalues.endPos, editor.layerMod);
+ editor.uivalues.startPos = editor.uivalues.endPos = null;
+ editor.dom.euiCtx.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__);
+ return false;
+ }
+ editor.uivalues.holdingPath = 0;
+ if (editor.uivalues.stepPostfix && editor.uivalues.stepPostfix.length) {
+ editor.uivalues.preMapData = JSON.parse(JSON.stringify({ map: editor.map, fgmap: editor.fgmap, bgmap: editor.bgmap }));
+ if (editor.brushMod !== 'line') {
+ var x0 = editor.uivalues.stepPostfix[0].x;
+ var y0 = editor.uivalues.stepPostfix[0].y;
+ var x1 = editor.uivalues.stepPostfix[editor.uivalues.stepPostfix.length - 1].x;
+ var y1 = editor.uivalues.stepPostfix[editor.uivalues.stepPostfix.length - 1].y;
+ if (x0 > x1) { x0 ^= x1; x1 ^= x0; x0 ^= x1; }//swap
+ if (y0 > y1) { y0 ^= y1; y1 ^= y0; y0 ^= y1; }//swap
+ editor.uivalues.stepPostfix = [];
+ for (var jj = y0; jj <= y1; jj++) {
+ for (var ii = x0; ii <= x1; ii++) {
+ editor.uivalues.stepPostfix.push({ x: ii, y: jj })
+ }
+ }
+ }
+ editor.uivalues.currDrawData.pos = JSON.parse(JSON.stringify(editor.uivalues.stepPostfix));
+ editor.uivalues.currDrawData.info = JSON.parse(JSON.stringify(editor.info));
+ editor.uivalues.reDo = null;
+ // console.log(editor.uivalues.stepPostfix);
+ if (editor.brushMod === 'tileset' && core.tilesets.indexOf(editor.info.images) !== -1) {
+ var imgWidth = ~~(core.material.images.tilesets[editor.info.images].width / 32);
+ var x0 = editor.uivalues.stepPostfix[0].x;
+ var y0 = editor.uivalues.stepPostfix[0].y;
+ var idnum = editor.info.idnum;
+ for (var ii = 0; ii < editor.uivalues.stepPostfix.length; ii++) {
+ if (editor.uivalues.stepPostfix[ii].y != y0) {
+ y0++;
+ idnum += imgWidth;
+ }
+ editor[editor.layerMod][editor.uivalues.stepPostfix[ii].y][editor.uivalues.stepPostfix[ii].x] = editor.ids[editor.indexs[idnum + editor.uivalues.stepPostfix[ii].x - x0]];
+ }
+ } else {
+ for (var ii = 0; ii < editor.uivalues.stepPostfix.length; ii++)
+ editor[editor.layerMod][editor.uivalues.stepPostfix[ii].y][editor.uivalues.stepPostfix[ii].x] = editor.info;
+ }
+ // console.log(editor.map);
+ editor.updateMap();
+ editor.uivalues.holdingPath = 0;
+ editor.uivalues.stepPostfix = [];
+ editor.dom.euiCtx.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__);
+ }
+ return false;
+ }
+
+ /**
+ * editor.dom.mid.onmousewheel
+ * 在地图编辑区域滚轮切换楼层
+ */
+ editor.uifunctions.map_mousewheel = function (e) {
+ var wheel = function (direct) {
+ var index = editor.core.floorIds.indexOf(editor.currentFloorId);
+ var toId = editor.currentFloorId;
+
+ if (direct > 0 && index < editor.core.floorIds.length - 1)
+ toId = editor.core.floorIds[index + 1];
+ else if (direct < 0 && index > 0)
+ toId = editor.core.floorIds[index - 1];
+ else return;
+
+ editor_mode.onmode('nextChange');
+ editor_mode.onmode('floor');
+ editor.dom.selectFloor.value = toId;
+ editor.changeFloor(toId);
+ }
+
+ try {
+ if (e.wheelDelta)
+ wheel(Math.sign(e.wheelDelta))
+ else if (e.detail)
+ wheel(Math.sign(e.detail));
+ }
+ catch (ee) {
+ console.log(ee);
+ }
+ return false;
+ }
+
+ /**
+ * 显示右键菜单
+ */
+ editor.uifunctions.showMidMenu = function (x, y) {
+ editor.uivalues.lastRightButtonPos = JSON.parse(JSON.stringify(
+ [editor.pos, editor.uivalues.lastRightButtonPos[0]]
+ ));
+ // --- copy
+ editor.uivalues.lastCopyedInfo = [editor.copyFromPos(), editor.uivalues.lastCopyedInfo[0]];
+ var locStr = '(' + editor.uivalues.lastRightButtonPos[1].x + ',' + editor.uivalues.lastRightButtonPos[1].y + ')';
+ var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
+ var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
+
+ // 检测是否是上下楼
+ var thisevent = editor.map[editor.pos.y][editor.pos.x];
+ if (thisevent == 0) {
+ editor.dom.extraEvent.style.display = 'block';
+ editor.dom.extraEvent.children[0].innerHTML = '绑定出生点为此点';
+ }
+ else if (thisevent.id == 'upFloor') {
+ editor.dom.extraEvent.style.display = 'block';
+ editor.dom.extraEvent.children[0].innerHTML = '绑定上楼事件';
+ }
+ else if (thisevent.id == 'downFloor') {
+ editor.dom.extraEvent.style.display = 'block';
+ editor.dom.extraEvent.children[0].innerHTML = '绑定下楼事件';
+ }
+ else if (['leftPortal', 'rightPortal', 'downPortal', 'upPortal'].indexOf(thisevent.id) >= 0) {
+ editor.dom.extraEvent.style.display = 'block';
+ editor.dom.extraEvent.children[0].innerHTML = '绑定楼传事件';
+ }
+ else if (thisevent.id == 'specialDoor') {
+ editor.dom.extraEvent.style.display = 'block';
+ editor.dom.extraEvent.children[0].innerHTML = '绑定机关门事件';
+ }
+ else editor.dom.extraEvent.style.display = 'none';
+
+ editor.dom.chooseThis.children[0].innerHTML = '选中此点' + '(' + editor.pos.x + ',' + editor.pos.y + ')'
+ editor.dom.copyLoc.children[0].innerHTML = '复制事件' + locStr + '到此处';
+ editor.dom.moveLoc.children[0].innerHTML = '交换事件' + locStr + '与此事件的位置';
+ editor.dom.midMenu.style = 'top:' + (y + scrollTop) + 'px;left:' + (x + scrollLeft) + 'px;';
+ }
+
+ /**
+ * 隐藏右键菜单
+ */
+ editor.uifunctions.hideMidMenu = function () {
+ if (editor.isMobile) {
+ setTimeout(function () {
+ editor.dom.midMenu.style = 'display:none';
+ }, 200)
+ } else {
+ editor.dom.midMenu.style = 'display:none';
+ }
+ }
+
+ /**
+ * editor.dom.extraEvent.onmousedown
+ * 菜单 附加点操作
+ */
+ editor.uifunctions.extraEvent_click = function (e) {
+ editor.uifunctions.hideMidMenu();
+ e.stopPropagation();
+
+ var thisevent = editor.map[editor.pos.y][editor.pos.x];
+ return editor.uifunctions._extraEvent_bindStartPoint(thisevent)
+ || editor.uifunctions._extraEvent_bindStair(thisevent)
+ || editor.uifunctions._extraEvent_bindSpecialDoor(thisevent);
+ }
+
+ /**
+ * 绑定该空地点为起始点
+ */
+ editor.uifunctions._extraEvent_bindStartPoint = function (thisevent) {
+ if (thisevent != 0) return false;
+ editor.mode.onmode('tower');
+ editor.mode.addAction(["change", "['firstData']['floorId']", editor.currentFloorId]);
+ editor.mode.addAction(["change", "['firstData']['hero']['loc']['x']", editor.pos.x]);
+ editor.mode.addAction(["change", "['firstData']['hero']['loc']['y']", editor.pos.y]);
+ editor.mode.onmode('save', function () {
+ core.firstData.floorId = editor.currentFloorId;
+ core.firstData.hero.loc.x = editor.pos.x;
+ core.firstData.hero.loc.y = editor.pos.y;
+ editor.drawPosSelection();
+ editor.drawEventBlock();
+ editor.mode.tower();
+ printf('绑定初始点成功');
+ });
+ }
+
+ /**
+ * 绑定该楼梯的楼传事件
+ */
+ editor.uifunctions._extraEvent_bindStair = function (thisevent) {
+ if (['upFloor', 'downFloor', 'leftPortal', 'rightPortal', 'upPortal', 'downPortal'].indexOf(thisevent.id) < 0)
+ return false;
+ var loc = editor.pos.x + "," + editor.pos.y;
+ if (thisevent.id == 'upFloor') {
+ editor.currentFloorData.changeFloor[loc] = { "floorId": ":next", "stair": "downFloor" };
+ }
+ else if (thisevent.id == 'downFloor') {
+ editor.currentFloorData.changeFloor[loc] = { "floorId": ":before", "stair": "upFloor" };
+ }
+ else if (thisevent.id == 'leftPortal' || thisevent.id == 'rightPortal') {
+ editor.currentFloorData.changeFloor[loc] = { "floorId": ":next", "stair": ":symmetry_x" }
+ }
+ else if (thisevent.id == 'upPortal' || thisevent.id == 'downPortal') {
+ editor.currentFloorData.changeFloor[loc] = { "floorId": ":next", "stair": ":symmetry_y" }
+ }
+ editor.file.saveFloorFile(function (err) {
+ if (err) {
+ printe(err);
+ throw (err)
+ }
+ editor.drawPosSelection();
+ editor.drawEventBlock();
+ editor_mode.showMode('loc');
+ printf('添加楼梯事件成功');
+ });
+ return true;
+ }
+
+ /**
+ * 绑定该机关门的事件
+ */
+ editor.uifunctions._extraEvent_bindSpecialDoor = function (thisevent) {
+ if (thisevent.id != 'specialDoor') return false;
+ var number = parseInt(prompt("请输入该机关门的怪物数量", "0"))|| 0;
+ if (number <= 0) return true;
+ editor.uivalues.bindSpecialDoor.n = number;
+ editor.uivalues.bindSpecialDoor.loc = editor.pos.x + ',' + editor.pos.y;
+ editor.uivalues.bindSpecialDoor.enemys = [];
+ printf("请点击选择" + number + "个怪物;切换楼层或刷新页面取消操作。");
+ }
+
+ /**
+ * 确定绑定该机关门的事件
+ * cancel:是否取消此模式
+ */
+ editor.uifunctions._extraEvent_bindSpecialDoor_doAction = function (cancel) {
+ var bindSpecialDoor = editor.uivalues.bindSpecialDoor;
+ if (cancel) {
+ bindSpecialDoor.loc = null;
+ bindSpecialDoor.enemys = [];
+ bindSpecialDoor.n = 0;
+ editor.drawEventBlock();
+ printf("");
+ return;
+ }
+ if (bindSpecialDoor.loc == null || bindSpecialDoor.enemys.length != bindSpecialDoor.n) return;
+ // 添加机关门自动事件
+ var doorFlag = "flag:door_" + editor.currentFloorId + "_" + bindSpecialDoor.loc.replace(',', '_');
+ editor.currentFloorData.autoEvent[bindSpecialDoor.loc] = {
+ '0': {
+ "condition": doorFlag + "==" + bindSpecialDoor.n,
+ "currentFloor": true,
+ "priority": 0,
+ "delayExecute": false,
+ "multiExecute": false,
+ "data": [
+ {"type": "openDoor"}
+ ]
+ }
+ };
+ bindSpecialDoor.enemys.forEach(function (loc) {
+ editor.currentFloorData.afterBattle[loc] = [
+ {"type": "addValue", "name": doorFlag, "value": "1"}
+ ]
+ });
+ editor.file.saveFloorFile(function (err) {
+ if (err) {
+ printe(err);
+ throw (err)
+ }
+ editor.drawEventBlock();
+ editor.drawPosSelection();
+ editor_mode.showMode('loc');
+ printf('绑定机关门事件成功');
+ });
+ bindSpecialDoor.loc = null;
+ bindSpecialDoor.enemys = [];
+ bindSpecialDoor.n = 0;
+ }
+
+ /**
+ * editor.dom.chooseThis.onmousedown
+ * 菜单 选中此点
+ */
+ editor.uifunctions.chooseThis_click = function (e) {
+ editor.uifunctions.hideMidMenu();
+ e.stopPropagation();
+ selectBox.isSelected(false);
+
+ editor_mode.onmode('nextChange');
+ editor_mode.onmode('loc');
+ //editor_mode.loc();
+ //tip.whichShow(1);
+ if (editor.isMobile) editor.showdataarea(false);
+ }
+
+ /**
+ * editor.dom.chooseInRight.onmousedown
+ * 菜单 在素材区选中此图块
+ */
+ editor.uifunctions.chooseInRight_click = function (e) {
+ editor.uifunctions.hideMidMenu();
+ e.stopPropagation();
+ var thisevent = editor[editor.layerMod][editor.pos.y][editor.pos.x];
+ editor.setSelectBoxFromInfo(thisevent);
+ }
+
+ /**
+ * editor.dom.copyLoc.onmousedown
+ * 菜单 复制此事件
+ */
+ editor.uifunctions.copyLoc_click = function (e) {
+ editor.uifunctions.hideMidMenu();
+ e.stopPropagation();
+ editor.uivalues.preMapData = null;
+ editor.uivalues.reDo = null;
+ editor_mode.onmode('');
+ var now = editor.pos, last = editor.uivalues.lastRightButtonPos[1];
+ if (now.x == last.x && now.y == last.y) return;
+ editor.pasteToPos(editor.uivalues.lastCopyedInfo[1]);
+ editor.updateMap();
+ editor.file.saveFloorFile(function (err) {
+ if (err) {
+ printe(err);
+ throw (err)
+ }
+ ; printf('复制事件成功');
+ editor.drawPosSelection();
+ });
+ }
+
+ /**
+ * editor.dom.moveLoc.onmousedown
+ * 菜单 移动此事件
+ */
+ editor.uifunctions.moveLoc_click = function (e) {
+ editor.uifunctions.hideMidMenu();
+ e.stopPropagation();
+ editor.uivalues.preMapData = null;
+ editor.uivalues.reDo = null;
+ editor_mode.onmode('');
+ editor.exchangePos(editor.pos, editor.uivalues.lastRightButtonPos[1]);
+ }
+
+ /**
+ * editor.dom.clearEvent.onmousedown
+ * 菜单 仅清空此点事件
+ */
+ editor.uifunctions.clearEvent_click = function (e) {
+ e.stopPropagation();
+ editor.uivalues.reDo = null;
+ editor.clearPos(false);
+ }
+
+ /**
+ * editor.dom.clearLoc.onmousedown
+ * 菜单 清空此点及事件
+ */
+ editor.uifunctions.clearLoc_click = function (e) {
+ e.stopPropagation();
+ editor.uivalues.reDo = null;
+ editor.clearPos(true);
+ }
+
+ /**
+ * editor.dom.brushMod.onchange
+ * 切换画笔模式
+ */
+ editor.uifunctions.brushMod_onchange = function () {
+ editor.brushMod = editor.dom.brushMod.value;
+ }
+
+ /**
+ * editor.dom.brushMod2.onchange
+ * 切换画笔模式
+ */
+ editor.uifunctions.brushMod2_onchange = function () {
+ editor.brushMod = editor.dom.brushMod2.value;
+ }
+
+ /**
+ * editor.dom.brushMod3.onchange
+ * 切换画笔模式
+ */
+ editor.uifunctions.brushMod3_onchange = function () {
+ // tip.showHelp(5)
+ tip.isSelectedBlock(false)
+ tip.msgs[11] = String('tileset贴图模式下可以按选中tileset素材,并在地图上拖动来一次绘制一个区域');
+ tip.whichShow(12);
+ editor.brushMod = editor.dom.brushMod3.value;
+ }
+
+ /**
+ * editor.dom.layerMod.onchange
+ * 切换编辑的层
+ */
+ editor.uifunctions.layerMod_onchange = function () {
+ editor.layerMod = editor.dom.layerMod.value;
+ [editor.dom.bgc, editor.dom.fgc, editor.dom.evc, editor.dom.ev2c].forEach(function (x) {
+ x.style.opacity = 1;
+ });
+
+ // 手机端....
+ if (editor.isMobile) {
+ if (editor.dom.layerMod.value == 'bgmap') {
+ [editor.dom.fgc, editor.dom.evc, editor.dom.ev2c].forEach(function (x) {
+ x.style.opacity = 0.3;
+ });
+ }
+ if (editor.dom.layerMod.value == 'fgmap') {
+ [editor.dom.bgc, editor.dom.evc, editor.dom.ev2c].forEach(function (x) {
+ x.style.opacity = 0.3;
+ });
+ }
+ }
+ }
+
+ /**
+ * editor.dom.layerMod2.onchange
+ * 切换编辑的层
+ */
+ editor.uifunctions.layerMod2_onchange = function () {
+ editor.layerMod = editor.dom.layerMod2.value;
+ [editor.dom.fgc, editor.dom.evc, editor.dom.ev2c].forEach(function (x) {
+ x.style.opacity = 0.3;
+ });
+ editor.dom.bgc.style.opacity = 1;
+ }
+
+ /**
+ * editor.dom.layerMod3.onchange
+ * 切换编辑的层
+ */
+ editor.uifunctions.layerMod3_onchange = function () {
+ editor.layerMod = editor.dom.layerMod3.value;
+ [editor.dom.bgc, editor.dom.evc, editor.dom.ev2c].forEach(function (x) {
+ x.style.opacity = 0.3;
+ });
+ editor.dom.fgc.style.opacity = 1;
+ }
+
+ /**
+ * 移动大地图可视窗口的绑定
+ */
+ editor.uifunctions.viewportButtons_func = function () {
+ var pressTimer = null;
+ for (var ii = 0, node; node = editor.dom.viewportButtons.children[ii]; ii++) {
+ (function (x, y) {
+ var move = function () {
+ editor.moveViewport(x, y);
+ }
+ node.onmousedown = function () {
+ clearTimeout(pressTimer);
+ pressTimer = setTimeout(function () {
+ pressTimer = -1;
+ var f = function () {
+ if (pressTimer != null) {
+ move();
+ setTimeout(f, 150);
+ }
+ }
+ f();
+ }, 500);
+ };
+ node.onmouseup = function () {
+ if (pressTimer > 0) {
+ clearTimeout(pressTimer);
+ move();
+ }
+ pressTimer = null;
+ }
+ })([-1, 0, 0, 1][ii], [0, -1, 1, 0][ii]);
+ }
+ }
+
+ editor.uifunctions.selectFloor_func = function () {
+ var selectFloor = document.getElementById('selectFloor');
+ editor.game.getFloorFileList(function (floors) {
+ var outstr = [];
+ floors[0].forEach(function (floor) {
+ outstr.push(["\n'].join(''));
+ });
+ selectFloor.innerHTML = outstr.join('');
+ selectFloor.value = core.status.floorId;
+ selectFloor.onchange = function () {
+ editor_mode.onmode('nextChange');
+ editor_mode.onmode('floor');
+ editor.changeFloor(selectFloor.value);
+ }
+ });
+ }
+
+
+ editor.uifunctions.saveFloor_func = function () {
+ var saveFloor = document.getElementById('saveFloor');
+ editor_mode.saveFloor = function () {
+ editor_mode.onmode('');
+ editor.file.saveFloorFile(function (err) {
+ if (err) {
+ printe(err);
+ throw (err)
+ }
+ ; printf('保存成功');
+ });
+ }
+ saveFloor.onclick = editor_mode.saveFloor;
+ }
+
+
+
+ /////////////////////////////////////////////////////////////////////////////
+
+
+ editor.constructor.prototype.copyFromPos = function (pos) {
+ var fields = Object.keys(editor.file.comment._data.floors._data.loc._data);
+ pos = pos || editor.pos;
+ var map = core.clone(editor.map[pos.y][pos.x]);
+ var events = {};
+ fields.forEach(function(v){
+ events[v] = core.clone(editor.currentFloorData[v][pos.x+','+pos.y]);
+ })
+ return {map: map, events: events};
+ }
+
+ editor.constructor.prototype.pasteToPos = function (info, pos) {
+ if (info == null) return;
+ var fields = Object.keys(editor.file.comment._data.floors._data.loc._data);
+ pos = pos || editor.pos;
+ editor.map[pos.y][pos.x] = core.clone(info.map);
+ fields.forEach(function(v){
+ if (info.events[v] == null) delete editor.currentFloorData[v][pos.x+","+pos.y];
+ else editor.currentFloorData[v][pos.x+","+pos.y] = core.clone(info.events[v]);
+ });
+ }
+
+ editor.constructor.prototype.movePos = function (startPos, endPos, callback) {
+ if (!startPos || !endPos) return;
+ if (startPos.x == endPos.x && startPos.y == endPos.y) return;
+ var copyed = editor.copyFromPos(startPos);
+ editor.pasteToPos({map:0, events: {}}, startPos);
+ editor.pasteToPos(copyed, endPos);
+ editor.updateMap();
+ editor.file.saveFloorFile(function (err) {
+ if (err) {
+ printe(err);
+ throw(err)
+ }
+ ;printf('移动事件成功');
+ editor.drawPosSelection();
+ if (callback) callback();
+ });
+ }
+
+ editor.constructor.prototype.exchangePos = function (startPos, endPos, callback) {
+ if (!startPos || !endPos) return;
+ if (startPos.x == endPos.x && startPos.y == endPos.y) return;
+ var startInfo = editor.copyFromPos(startPos);
+ var endInfo = editor.copyFromPos(endPos);
+ editor.pasteToPos(startInfo, endPos);
+ editor.pasteToPos(endInfo, startPos);
+ editor.updateMap();
+ editor.file.saveFloorFile(function (err) {
+ if (err) {
+ printe(err);
+ throw(err)
+ }
+ ;printf('交换事件成功');
+ editor.drawPosSelection();
+ if (callback) callback();
+ });
+ }
+
+ editor.constructor.prototype.moveBgFg = function (startPos, endPos, name, callback) {
+ if (!startPos || !endPos || ["bgmap","fgmap"].indexOf(name)<0) return;
+ if (startPos.x == endPos.x && startPos.y == endPos.y) return;
+ editor[name][endPos.y][endPos.x] = editor[name][startPos.y][startPos.x];
+ editor[name][startPos.y][startPos.x] = 0;
+ editor.updateMap();
+ editor.file.saveFloorFile(function (err) {
+ if (err) {
+ printe(err);
+ throw(err)
+ }
+ ;printf('移动图块成功');
+ editor.drawPosSelection();
+ if (callback) callback();
+ });
+ }
+
+ editor.constructor.prototype.exchangeBgFg = function (startPos, endPos, name, callback) {
+ if (!startPos || !endPos || ["bgmap","fgmap"].indexOf(name)<0) return;
+ if (startPos.x == endPos.x && startPos.y == endPos.y) return;
+ var value = editor[name][endPos.y][endPos.x];
+ editor[name][endPos.y][endPos.x] = editor[name][startPos.y][startPos.x];
+ editor[name][startPos.y][startPos.x] = value;
+ editor.updateMap();
+ editor.file.saveFloorFile(function (err) {
+ if (err) {
+ printe(err);
+ throw(err)
+ }
+ ;printf('交换图块成功');
+ editor.drawPosSelection();
+ if (callback) callback();
+ });
+
+ }
+
+ editor.constructor.prototype.clearPos = function (clearPos, pos, callback) {
+ var fields = Object.keys(editor.file.comment._data.floors._data.loc._data);
+ pos = pos || editor.pos;
+ editor.uifunctions.hideMidMenu();
+ editor.uivalues.preMapData = null;
+ editor.info = 0;
+ editor_mode.onmode('');
+ if (clearPos)
+ editor.map[pos.y][pos.x]=editor.info;
+ editor.updateMap();
+ fields.forEach(function(v){
+ delete editor.currentFloorData[v][pos.x+','+pos.y];
+ })
+ editor.file.saveFloorFile(function (err) {
+ if (err) {
+ printe(err);
+ throw(err)
+ }
+ ;printf(clearPos?'清空该点和事件成功':'只清空该点事件成功');
+ editor.drawPosSelection();
+ if (callback) callback();
+ });
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
\ No newline at end of file
diff --git a/_server/editor_materialpanel.js b/_server/editor_materialpanel.js
new file mode 100644
index 00000000..2ba50d82
--- /dev/null
+++ b/_server/editor_materialpanel.js
@@ -0,0 +1,130 @@
+editor_materialpanel_wrapper = function (editor) {
+
+ editor.uifunctions.getScrollBarHeight = function () {
+ var outer = document.createElement("div");
+ outer.style.visibility = "hidden";
+ outer.style.width = "100px";
+ outer.style.msOverflowStyle = "scrollbar"; // needed for WinJS apps
+
+ document.body.appendChild(outer);
+
+ var widthNoScroll = outer.offsetWidth;
+ // force scrollbars
+ outer.style.overflow = "scroll";
+
+ // add innerdiv
+ var inner = document.createElement("div");
+ inner.style.width = "100%";
+ outer.appendChild(inner);
+
+ var widthWithScroll = inner.offsetWidth;
+
+ // remove divs
+ outer.parentNode.removeChild(outer);
+
+ return widthNoScroll - widthWithScroll;
+ }
+
+ /**
+ * editor.dom.iconExpandBtn.onclick
+ */
+ editor.uifunctions.fold_material_click = function () {
+ if (confirm(editor.uivalues.folded ? "你想要展开素材吗?\n展开模式下将显示全素材内容。"
+ : ("你想要折叠素材吗?\n折叠模式下每个素材将仅显示单列,并且每" + editor.uivalues.foldPerCol + "个自动换列。"))) {
+ core.setLocalStorage('folded', !editor.uivalues.folded);
+ window.location.reload();
+ }
+ }
+
+ /**
+ * editor.dom.iconLib.onmousedown
+ * 素材区的单击事件
+ */
+ editor.uifunctions.material_ondown = function (e) {
+ e.stopPropagation();
+ if (!editor.isMobile && e.clientY >= editor.dom.iconLib.offsetHeight - editor.uivalues.scrollBarHeight) return;
+ var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
+ var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
+ var loc = {
+ 'x': scrollLeft + e.clientX + editor.dom.iconLib.scrollLeft - right.offsetLeft - editor.dom.iconLib.offsetLeft,
+ 'y': scrollTop + e.clientY + editor.dom.iconLib.scrollTop - right.offsetTop - editor.dom.iconLib.offsetTop,
+ 'size': 32
+ };
+ editor.loc = loc;
+ var pos = editor.uifunctions.locToPos(loc);
+ for (var spriter in editor.widthsX) {
+ if (pos.x >= editor.widthsX[spriter][1] && pos.x < editor.widthsX[spriter][2]) {
+ var ysize = spriter.endsWith('48') ? 48 : 32;
+ loc.ysize = ysize;
+ pos.images = editor.widthsX[spriter][0];
+ pos.y = ~~(loc.y / loc.ysize);
+ if (!editor.uivalues.folded && core.tilesets.indexOf(pos.images) == -1) pos.x = editor.widthsX[spriter][1];
+ var autotiles = core.material.images['autotile'];
+ if (pos.images == 'autotile') {
+ var imNames = Object.keys(autotiles);
+ if ((pos.y + 1) * ysize > editor.widthsX[spriter][3])
+ pos.y = ~~(editor.widthsX[spriter][3] / ysize) - 4;
+ else {
+ for (var i = 0; i < imNames.length; i++) {
+ if (pos.y >= 4 * i && pos.y < 4 * (i + 1)) {
+ pos.images = imNames[i];
+ pos.y = 4 * i;
+ }
+ }
+ }
+ }
+ else {
+ var height = editor.widthsX[spriter][3], col = height / ysize;
+ if (editor.uivalues.folded && core.tilesets.indexOf(pos.images) == -1) {
+ col = (pos.x == editor.widthsX[spriter][2] - 1) ? ((col - 1) % editor.uivalues.foldPerCol + 1) : editor.uivalues.foldPerCol;
+ }
+ if (spriter == 'terrains' && pos.x == editor.widthsX[spriter][1]) col += 2;
+ pos.y = Math.min(pos.y, col - 1);
+ }
+
+ selectBox.isSelected(true);
+ // console.log(pos,core.material.images[pos.images].height)
+ editor.dom.dataSelection.style.left = pos.x * 32 + 'px';
+ editor.dom.dataSelection.style.top = pos.y * ysize + 'px';
+ editor.dom.dataSelection.style.height = ysize - 6 + 'px';
+
+ if (pos.x == 0 && pos.y == 0) {
+ // editor.info={idnum:0, id:'empty','images':'清除块', 'y':0};
+ editor.info = 0;
+ } else if (pos.x == 0 && pos.y == 1) {
+ editor.info = editor.ids[editor.indexs[17]];
+ } else {
+ if (autotiles[pos.images]) editor.info = { 'images': pos.images, 'y': 0 };
+ else if (core.tilesets.indexOf(pos.images) != -1) editor.info = { 'images': pos.images, 'y': pos.y, 'x': pos.x - editor.widthsX[spriter][1] };
+ else {
+ var y = pos.y;
+ if (editor.uivalues.folded) {
+ y += editor.uivalues.foldPerCol * (pos.x - editor.widthsX[spriter][1]);
+ }
+ if (pos.images == 'terrains' && pos.x == 0) y -= 2;
+ editor.info = { 'images': pos.images, 'y': y }
+ }
+
+ for (var ii = 0; ii < editor.ids.length; ii++) {
+ if ((core.tilesets.indexOf(pos.images) != -1 && editor.info.images == editor.ids[ii].images
+ && editor.info.y == editor.ids[ii].y && editor.info.x == editor.ids[ii].x)
+ || (Object.prototype.hasOwnProperty.call(autotiles, pos.images) && editor.info.images == editor.ids[ii].id
+ && editor.info.y == editor.ids[ii].y)
+ || (core.tilesets.indexOf(pos.images) == -1 && editor.info.images == editor.ids[ii].images
+ && editor.info.y == editor.ids[ii].y)
+ ) {
+
+ editor.info = editor.ids[ii];
+ break;
+ }
+ }
+ }
+ tip.infos(JSON.parse(JSON.stringify(editor.info)));
+ editor_mode.onmode('nextChange');
+ editor_mode.onmode('enemyitem');
+ //editor_mode.enemyitem();
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/_server/editor_mode.js b/_server/editor_mode.js
index aadbec9a..8e42b7e0 100644
--- a/_server/editor_mode.js
+++ b/_server/editor_mode.js
@@ -21,7 +21,7 @@ editor_mode = function (editor) {
this.mode = '';
this.info = {};
this.appendPic = {};
- this.doubleClickMode='change';
+ this.doubleClickMode = 'change';
}
editor_mode.prototype.init = function (callback) {
@@ -49,15 +49,16 @@ editor_mode = function (editor) {
editor_mode.actionList.push(action);
}
- editor_mode.prototype.doActionList = function (mode, actionList) {
+ editor_mode.prototype.doActionList = function (mode, actionList, callback) {
if (actionList.length == 0) return;
printf('修改中...');
- var cb=function(objs_){
+ var cb = function (objs_) {
if (objs_.slice(-1)[0] != null) {
printe(objs_.slice(-1)[0]);
- throw(objs_.slice(-1)[0])
+ throw (objs_.slice(-1)[0])
}
- ;printf('修改成功' + (data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.name == 'template' ? '\n\n请注意:全塔属性的name尚未修改,请及时予以设置' : ''));
+ ; printf('修改成功' + (data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.name == 'template' ? '\n\n请注意:全塔属性的name尚未修改,请及时予以设置' : ''));
+ if (callback) callback();
}
switch (mode) {
case 'loc':
@@ -95,9 +96,9 @@ editor_mode = function (editor) {
}
}
- editor_mode.prototype.onmode = function (mode) {
+ editor_mode.prototype.onmode = function (mode, callback) {
if (editor_mode.mode != mode) {
- if (mode === 'save') editor_mode.doActionList(editor_mode.mode, editor_mode.actionList);
+ if (mode === 'save') editor_mode.doActionList(editor_mode.mode, editor_mode.actionList, callback);
if (editor_mode.mode === 'nextChange' && mode) editor_mode.showMode(mode);
if (mode !== 'save') editor_mode.mode = mode;
editor_mode.actionList = [];
@@ -109,14 +110,78 @@ editor_mode = function (editor) {
editor_mode.dom[name].style = 'z-index:-1;opacity: 0;';
}
editor_mode.dom[mode].style = '';
- editor_mode.doubleClickMode='change';
+ editor_mode.doubleClickMode = 'change';
// clear
editor.drawEventBlock();
if (editor_mode[mode]) editor_mode[mode]();
- document.getElementById('editModeSelect').value = mode;
+ editor.dom.editModeSelect.value = mode;
if (!selectBox.isSelected()) tip.showHelp();
}
+ editor_mode.prototype.change = function (value) {
+ editor_mode.onmode('nextChange');
+ editor_mode.onmode(value);
+ if (editor.isMobile) editor.showdataarea(false);
+ }
+
+
+ editor_mode.prototype.checkUnique = function (thiseval) {
+ if (!(thiseval instanceof Array)) return false;
+ var map = {};
+ for (var i = 0; i < thiseval.length; ++i) {
+ if (map[thiseval[i]]) {
+ alert("警告:存在重复定义!");
+ return false;
+ }
+ map[thiseval[i]] = true;
+ }
+ return true;
+ }
+
+ editor_mode.prototype.checkFloorIds = function (thiseval) {
+ if (!editor_mode.checkUnique(thiseval)) return false;
+ var oldvalue = data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.main.floorIds;
+ fs.readdir('project/floors', function (err, data) {
+ if (err) {
+ printe(err);
+ throw Error(err);
+ }
+ var newfiles = thiseval.map(function (v) { return v + '.js' });
+ var notExist = '';
+ for (var name, ii = 0; name = newfiles[ii]; ii++) {
+ if (data.indexOf(name) === -1) notExist = name;
+ }
+ if (notExist) {
+ var discard = confirm('文件' + notExist + '不存在, 保存会导致工程无法打开, 是否放弃更改');
+ if (discard) {
+ editor.file.editTower([['change', "['main']['floorIds']", oldvalue]], function (objs_) {//console.log(objs_);
+ if (objs_.slice(-1)[0] != null) {
+ printe(objs_.slice(-1)[0]);
+ throw (objs_.slice(-1)[0])
+ }
+ ; printe('已放弃floorIds的修改,请F5进行刷新');
+ });
+ }
+ }
+ });
+ return true
+ }
+
+ editor_mode.prototype.changeDoubleClickModeByButton = function (mode) {
+ ({
+ delete: function () {
+ printf('下一次双击表格的项删除,切换下拉菜单可取消;编辑后需刷新浏览器生效。');
+ editor_mode.doubleClickMode = mode;
+ },
+ add: function () {
+ printf('下一次双击表格的项则在同级添加新项,切换下拉菜单可取消;编辑后需刷新浏览器生效。');
+ editor_mode.doubleClickMode = mode;
+ }
+ }[mode])();
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+
editor_mode.prototype.loc = function (callback) {
//editor.pos={x: 0, y: 0};
if (!core.isset(editor.pos)) return;
@@ -140,7 +205,7 @@ editor_mode = function (editor) {
//editor.info=editor.ids[editor.indexs[201]];
if (!core.isset(editor.info)) return;
- if (Object.keys(editor.info).length !== 0 && editor.info.idnum!=17) editor_mode.info = editor.info;//避免editor.info被清空导致无法获得是物品还是怪物
+ if (Object.keys(editor.info).length !== 0 && editor.info.idnum != 17) editor_mode.info = editor.info;//避免editor.info被清空导致无法获得是物品还是怪物
if (!core.isset(editor_mode.info.id)) {
// document.getElementById('table_a3f03d4c_55b8_4ef6_b362_b345783acd72').innerHTML = '';
@@ -232,7 +297,7 @@ editor_mode = function (editor) {
tableinfo.listen(tableinfo.guids);
if (Boolean(callback)) callback();
}
-
+
editor_mode.prototype.plugins = function (callback) {
var objs = [];
editor.file.editPlugins([], function (objs_) {
@@ -246,11 +311,17 @@ editor_mode = function (editor) {
if (Boolean(callback)) callback();
}
-/////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * editor.dom.editModeSelect.onchange
+ */
+ editor_mode.prototype.editModeSelect_onchange = function () {
+ editor_mode.change(editor.dom.editModeSelect.value);
+ }
editor_mode.prototype.listen = function (callback) {
-
- // 移动至 editor_unsorted_2.js
+ // 移动至 editor_listen.js -> editor.constructor.prototype.mode_listen
}
var editor_mode = new editor_mode();
diff --git a/_server/editor_multi.js b/_server/editor_multi.js
index ecfd6b7d..b694bf51 100644
--- a/_server/editor_multi.js
+++ b/_server/editor_multi.js
@@ -121,6 +121,7 @@ editor_multi = function () {
}
codeEditor.setValue(tstr || '');
}
+ document.getElementById('showPlugins').style.display = editor_mode.mode == 'plugins' ? 'block': 'none';
editor_multi.show();
return true;
}
@@ -186,6 +187,11 @@ editor_multi = function () {
setvalue(codeEditor.getValue() || '');
}
+ editor_multi.showPlugins = function () {
+ if (editor.isMobile && !confirm("你确定要跳转到云端插件列表吗?")) return;
+ window.open("https://h5mota.com/plugins/", "_blank");
+ }
+
var multiLineArgs = [null, null, null];
editor_multi.multiLineEdit = function (value, b, f, args, callback) {
editor_multi.id = 'callFromBlockly';
diff --git a/_server/editor_table.js b/_server/editor_table.js
index e141e5ff..b2e8cf3f 100644
--- a/_server/editor_table.js
+++ b/_server/editor_table.js
@@ -26,13 +26,19 @@ editor_table_wrapper = function (editor) {
editor_table.prototype.textarea = function (value, indent) {
return /* html */`\n`
}
+ editor_table.prototype.editGrid = function (showComment) {
+ var html = "";
+ if (showComment) html += "
";
+ html += "";
+ return html;
+ }
editor_table.prototype.title = function () {
- return /* html */`\n| 条目 | 注释 | 值 |
\n`
+ return /* html */`\n| 条目 | 注释 | 值 | 操作 |
\n`
}
editor_table.prototype.gap = function (field) {
- return /* html */`| ---- | ---- | ${field} |
\n`
+ return /* html */`| ---- | ---- | ${field} | ---- |
\n`
}
editor_table.prototype.tr = function (guid, field, shortField, commentHTMLescape, cobjstr, shortCommentHTMLescape, tdstr) {
@@ -40,6 +46,7 @@ editor_table_wrapper = function (editor) {
${shortField} |
${shortCommentHTMLescape} |
${tdstr} |
+ ${editor.table.editGrid(commentHTMLescape != shortCommentHTMLescape)} |
\n`
}
@@ -145,6 +152,7 @@ editor_table_wrapper = function (editor) {
if (key === '_data') continue;
if (cobj[key] instanceof Function) cobj[key] = cobj[key](args);
}
+ pvobj[ii] = vobj = args.vobj;
// 标记为_hide的属性不展示
if (cobj._hide) continue;
if (!cobj._leaf) {
@@ -193,7 +201,7 @@ editor_table_wrapper = function (editor) {
// "['a']['b']" => "b"
var shortField = field.split("']").slice(-2)[0].split("['").slice(-1)[0];
// 把长度超过 charlength 的字符改成 固定长度+...的形式
- shortField = (shortField.length < charlength ? shortField : shortField.slice(0, charlength) + '...');
+ // shortField = (shortField.length < charlength ? shortField : shortField.slice(0, charlength) + '...');
// 完整的内容转义后供悬停查看
var commentHTMLescape = editor.util.HTMLescape(comment);
@@ -298,6 +306,25 @@ editor_table_wrapper = function (editor) {
}
}
+ /**
+ * 当"显示完整注释"被按下时
+ */
+ editor_table.prototype.onCommentBtnClick = function (button) {
+ var tr = button.parentNode.parentNode;
+ printf(tr.children[1].getAttribute('title'));
+ }
+
+ /**
+ * 当"编辑表格内容"被按下时
+ */
+ editor_table.prototype.onEditBtnClick = function (button) {
+ var tr = button.parentNode.parentNode;
+ var guid = tr.getAttribute('id');
+ var cobj = JSON.parse(tr.children[1].getAttribute('cobj'));
+ 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 });
+ }
+
/**
* 双击表格时
* 正常编辑: 尝试用事件编辑器或多行文本编辑器打开
@@ -337,12 +364,22 @@ editor_table_wrapper = function (editor) {
editor_table.prototype.addfunc = function (guid, obj, commentObj, thisTr, input, field, cobj, modeNode) {
editor_mode.onmode(editor_mode._ids[modeNode.getAttribute('id')]);
- var mode = document.getElementById('editModeSelect').value;
+ var mode = editor.dom.editModeSelect.value;
// 1.输入id
- var newid = prompt('请输入新项的ID(仅公共事件支持中文ID)');
- if (newid == null || newid.length == 0) {
- return;
+ var newid = '2';
+ if (mode == 'loc') {
+ var ae = editor.currentFloorData.autoEvent[editor_mode.pos.x + ',' + editor_mode.pos.y];
+ if (ae != null) {
+ var testid;
+ for (testid = 2; Object.hasOwnProperty.call(ae, testid); testid++); // 从3开始是因为comment中设置了始终显示012
+ newid = testid + '';
+ }
+ } else {
+ newid = prompt('请输入新项的ID(仅公共事件支持中文ID)');
+ if (newid == null || newid.length == 0) {
+ return;
+ }
}
// 检查commentEvents
diff --git a/_server/editor_ui.js b/_server/editor_ui.js
new file mode 100644
index 00000000..589b19d0
--- /dev/null
+++ b/_server/editor_ui.js
@@ -0,0 +1,566 @@
+editor_ui_wrapper = function (editor) {
+
+
+ /**
+ * 根据鼠标点击, 得到从元素向上到body的所有id
+ */
+ editor.uifunctions.getClickpath = function (e) {
+ //console.log(e);
+ var clickpath = [];
+ var getpath = function (e) {
+ var path = [];
+ var currentElem = e.target;
+ while (currentElem) {
+ path.push(currentElem);
+ currentElem = currentElem.parentElement;
+ }
+ if (path.indexOf(window) === -1 && path.indexOf(document) === -1)
+ path.push(document);
+ if (path.indexOf(window) === -1)
+ path.push(window);
+ return path;
+ }
+ getpath(e).forEach(function (node) {
+ if (!node.getAttribute) return;
+ var id_ = node.getAttribute('id');
+ if (id_) {
+ if (['left', 'left1', 'left2', 'left3', 'left4', 'left5', 'left8', 'mobileview'].indexOf(id_) !== -1) clickpath.push('edit');
+ clickpath.push(id_);
+ }
+ });
+ return clickpath;
+ }
+
+ /**
+ * editor.dom.body.onmousedown
+ * 检测鼠标点击,
+ * + 如果选中了绘图区域之外, 就保存地图
+ * + 维护绘图区的菜单的隐藏
+ * + 记录最后一次点击的id(主要为了数据区服务)
+ */
+ editor.uifunctions.body_click = function (e) {
+ var clickpath = editor.uifunctions.getClickpath(e);
+
+ var unselect = true;
+ for (var ii = 0, thisId; thisId = ['edit', 'tip', 'brushMod', 'brushMod2', 'brushMod3', 'layerMod', 'layerMod2', 'layerMod3', 'viewportButtons'][ii]; ii++) {
+ if (clickpath.indexOf(thisId) !== -1) {
+ unselect = false;
+ break;
+ }
+ }
+ if (unselect) {
+ if (clickpath.indexOf('eui') === -1) {
+ if (selectBox.isSelected()) {
+ editor_mode.onmode('');
+ editor.file.saveFloorFile(function (err) {
+ if (err) {
+ printe(err);
+ throw (err)
+ }
+ ; printf('地图保存成功');
+ });
+ }
+ selectBox.isSelected(false);
+ editor.info = {};
+ }
+ }
+ //editor.mode.onmode('');
+ if (e.button != 2 && !editor.isMobile) {
+ editor.uifunctions.hideMidMenu();
+ }
+ if (clickpath.indexOf('down') !== -1 && editor.isMobile && clickpath.indexOf('midMenu') === -1) {
+ editor.uifunctions.hideMidMenu();
+ }
+ if (clickpath.length >= 2 && clickpath[0].indexOf('id_') === 0) { editor.lastClickId = clickpath[0] }
+ }
+
+ /**
+ * editor.dom.body.onkeydown
+ * 绑定快捷键
+ */
+ editor.uifunctions.body_shortcut = function (e) {
+
+ // UI预览 & 地图选点
+ if (uievent && uievent.isOpen) {
+ e.preventDefault();
+ if (e.keyCode == 27) uievent.close();
+ else if (e.keyCode == 13) uievent.confirm();
+ else if (e.keyCode == 87) uievent.move(0, -1)
+ else if (e.keyCode == 65) uievent.move(-1, 0)
+ else if (e.keyCode == 83) uievent.move(0, 1);
+ else if (e.keyCode == 68) uievent.move(1, 0);
+ return;
+ }
+
+ // 监听Ctrl+S保存
+ if (e.ctrlKey && e.keyCode == 83) {
+ e.preventDefault();
+ if (editor_multi.id != "") {
+ editor_multi.confirm(); // 保存脚本编辑器
+ }
+ else if (editor_blockly.id != "") {
+ editor_blockly.confirm(); // 保存事件编辑器
+ }
+ else {
+ editor_mode.saveFloor();
+ }
+ return;
+ }
+
+ // 如果是开启事件/脚本编辑器状态,则忽略
+ if (editor_multi.id != "" || editor_blockly.id != "")
+ return;
+
+ // 禁止快捷键的默认行为
+ if (e.ctrlKey && [89, 90, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57].indexOf(e.keyCode) !== -1)
+ e.preventDefault();
+ if (e.altKey && [48, 49, 50, 51, 52, 53, 54, 55, 56, 57].indexOf(e.keyCode) !== -1)
+ e.preventDefault();
+ //Ctrl+z 撤销上一步undo
+ if (e.keyCode == 90 && e.ctrlKey && editor.uivalues.preMapData && editor.uivalues.currDrawData.pos.length && selectBox.isSelected()) {
+ editor.map = JSON.parse(JSON.stringify(editor.uivalues.preMapData.map));
+ editor.fgmap = JSON.parse(JSON.stringify(editor.uivalues.preMapData.fgmap));
+ editor.bgmap = JSON.parse(JSON.stringify(editor.uivalues.preMapData.bgmap));
+ editor.updateMap();
+ editor.uivalues.reDo = JSON.parse(JSON.stringify(editor.uivalues.currDrawData));
+ editor.uivalues.currDrawData = { pos: [], info: {} };
+ editor.uivalues.preMapData = null;
+ return;
+ }
+ //Ctrl+y 重做一步redo
+ if (e.keyCode == 89 && e.ctrlKey && editor.uivalues.reDo && editor.uivalues.reDo.pos.length && selectBox.isSelected()) {
+ editor.uivalues.preMapData = JSON.parse(JSON.stringify({ map: editor.map, fgmap: editor.fgmap, bgmap: editor.bgmap }));
+ for (var j = 0; j < editor.uivalues.reDo.pos.length; j++)
+ editor.map[editor.uivalues.reDo.pos[j].y][editor.uivalues.reDo.pos[j].x] = JSON.parse(JSON.stringify(editor.uivalues.reDo.info));
+
+ editor.updateMap();
+ editor.uivalues.currDrawData = JSON.parse(JSON.stringify(editor.uivalues.reDo));
+ editor.uivalues.reDo = null;
+ return;
+ }
+
+ // PGUP和PGDOWN切换楼层
+ if (e.keyCode == 33 || e.keyCode == 34) {
+ e.preventDefault();
+ var index = editor.core.floorIds.indexOf(editor.currentFloorId);
+ var nextIndex = index + (e.keyCode == 33 ? 1 : -1);
+ if (nextIndex >= 0 && nextIndex < editor.core.floorIds.length) {
+ var toId = editor.core.floorIds[nextIndex];
+ editor_mode.onmode('nextChange');
+ editor_mode.onmode('floor');
+ document.getElementById('selectFloor').value = toId;
+ editor.changeFloor(toId);
+ }
+ return;
+ }
+ //ctrl + 0~9 切换到快捷图块
+ if (e.ctrlKey && [48, 49, 50, 51, 52, 53, 54, 55, 56, 57].indexOf(e.keyCode) !== -1) {
+ editor.setSelectBoxFromInfo(JSON.parse(JSON.stringify(editor.uivalues.shortcut[e.keyCode] || 0)));
+ return;
+ }
+ //alt + 0~9 改变快捷图块
+ if (e.altKey && [48, 49, 50, 51, 52, 53, 54, 55, 56, 57].indexOf(e.keyCode) !== -1) {
+ var infoToSave = JSON.stringify(editor.info || 0);
+ if (infoToSave == JSON.stringify({})) return;
+ editor.uivalues.shortcut[e.keyCode] = JSON.parse(infoToSave);
+ printf('已保存该快捷图块, ctrl + ' + (e.keyCode - 48) + ' 使用.')
+ core.setLocalStorage('shortcut', editor.uivalues.shortcut);
+ return;
+ }
+ var focusElement = document.activeElement;
+ if (!focusElement || focusElement.tagName.toLowerCase() == 'body') {
+ // Ctrl+C, Ctrl+X, Ctrl+V
+ if (e.ctrlKey && e.keyCode == 67 && !selectBox.isSelected()) {
+ e.preventDefault();
+ editor.uivalues.copyedInfo = editor.copyFromPos();
+ printf('该点事件已复制');
+ return;
+ }
+ if (e.ctrlKey && e.keyCode == 88 && !selectBox.isSelected()) {
+ e.preventDefault();
+ editor.uivalues.copyedInfo = editor.copyFromPos();
+ editor.clearPos(true, null, function () {
+ printf('该点事件已剪切');
+ })
+ return;
+ }
+ if (e.ctrlKey && e.keyCode == 86 && !selectBox.isSelected()) {
+ e.preventDefault();
+ if (!editor.uivalues.copyedInfo) {
+ printe("没有复制的事件");
+ return;
+ }
+ editor.pasteToPos(editor.uivalues.copyedInfo);
+ editor.updateMap();
+ editor.file.saveFloorFile(function (err) {
+ if (err) {
+ printe(err);
+ throw (err)
+ }
+ ; printf('粘贴事件成功');
+ editor.drawPosSelection();
+ });
+ return;
+ }
+ // DELETE
+ if (e.keyCode == 46 && !selectBox.isSelected()) {
+ editor.clearPos(true);
+ return;
+ }
+ // ESC
+ if (e.keyCode == 27) {
+ if (selectBox.isSelected()) {
+ editor_mode.onmode('');
+ editor.file.saveFloorFile(function (err) {
+ if (err) {
+ printe(err);
+ throw (err)
+ }
+ ; printf('地图保存成功');
+ });
+ }
+ selectBox.isSelected(false);
+ editor.info = {};
+ return;
+ }
+ switch (e.keyCode) {
+ // WASD
+ case 87: editor.moveViewport(0, -1); break;
+ case 65: editor.moveViewport(-1, 0); break;
+ case 83: editor.moveViewport(0, 1); break;
+ case 68: editor.moveViewport(1, 0); break;
+ // Z~.
+ case 90: editor_mode.change('map'); break; // Z
+ case 88: editor_mode.change('loc'); break; // X
+ case 67: editor_mode.change('enemyitem'); break; // C
+ case 86: editor_mode.change('floor'); break; // V
+ case 66: editor_mode.change('tower'); break; // B
+ case 78: editor_mode.change('functions'); break; // N
+ case 77: editor_mode.change('appendpic'); break; // M
+ case 188: editor_mode.change('commonevent'); break; // ,
+ case 190: editor_mode.change('plugins'); break; // .
+ // H
+ case 72: editor.uifunctions.showHelp(); break;
+ }
+ return;
+ }
+ }
+
+ editor.uifunctions.showHelp = function () {
+ alert(
+ "快捷操作帮助:\n" +
+ "ESC / 点击空白处:自动保存当前修改" +
+ "WASD / 长按箭头:平移大地图\n" +
+ "PgUp, PgDn / 鼠标滚轮:上下切换楼层\n" +
+ "Z~.(键盘的第三排):快捷切换标签\n" +
+ "双击地图:选中对应点的素材\n" +
+ "右键地图:弹出菜单栏\n" +
+ "Alt+0~9:保存当前使用的图块\n" +
+ "Ctrl+0~9:选中保存的图块\n" +
+ "Ctrl+Z / Ctrl+Y:撤销/重做上次绘制\n" +
+ "Ctrl+S:事件与脚本编辑器的保存并退出\n" +
+ "双击事件编辑器:长文本编辑/脚本编辑/地图选点/UI绘制预览"
+ );
+ }
+
+
+ // ------ UI预览 & 地图选点相关 ------ //
+
+ var uievent = {
+ elements: {},
+ values: {},
+ isOpen: false,
+ mode: ""
+ };
+
+ uievent.elements.div = document.getElementById('uieventDiv');
+ uievent.elements.title = document.getElementById('uieventTitle');
+ uievent.elements.yes = document.getElementById('uieventYes');
+ uievent.elements.no = document.getElementById('uieventNo');
+ uievent.elements.selectBackground = document.getElementById('uieventBackground');
+ uievent.elements.selectPoint = document.getElementById('selectPoint');
+ uievent.elements.selectFloor = document.getElementById('selectPointFloor');
+ uievent.elements.selectPointBox = document.getElementById('selectPointBox');
+ uievent.elements.body = document.getElementById('uieventBody');
+ uievent.elements.selectPointButtons = document.getElementById('selectPointButtons');
+ uievent.elements.canvas = document.getElementById('uievent');
+ uievent.elements.usedFlags = document.getElementById('uieventUsedFlags');
+ uievent.elements.usedFlagList = document.getElementById('uieventUsedFlagList');
+
+ uievent.confirm = function () {
+ var callback = uievent.values.callback, floorId = uievent.values.floorId,
+ x = uievent.values.x, y = uievent.values.y;
+ uievent.close();
+ if (callback) {
+ callback(floorId, x, y);
+ }
+ }
+ uievent.elements.yes.onclick = uievent.confirm;
+
+ uievent.close = function () {
+ uievent.isOpen = false;
+ uievent.elements.div.style.display = 'none';
+ uievent.values = {};
+ }
+ uievent.elements.no.onclick = uievent.close;
+
+ uievent.elements.selectBackground.onchange = function () {
+ uievent.drawPreviewUI();
+ }
+
+ uievent.drawPreviewUI = function () {
+ core.setAlpha('uievent', 1);
+ core.clearMap('uievent');
+
+ // 绘制UI
+ var background = uievent.elements.selectBackground.value;
+ if (background == 'thumbnail') {
+ core.drawThumbnail(editor.currentFloorId, null, {}, 'uievent');
+ }
+ else {
+ core.fillRect('uievent', 0, 0, core.__PIXELS__, core.__PIXELS__, background);
+ }
+
+ if (uievent.values.list instanceof Array) {
+ uievent.values.list.forEach(function (data) {
+ var type = data.type;
+ if (!type || !core.ui["_uievent_" + type]) return;
+ core.ui["_uievent_" + type](data);
+ })
+ }
+ }
+
+ uievent.previewUI = function (list) {
+ uievent.isOpen = true;
+ uievent.elements.div.style.display = 'block';
+ uievent.mode = 'previewUI';
+ uievent.elements.selectPoint.style.display = 'none';
+ uievent.elements.yes.style.display = 'none';
+ uievent.elements.title.innerText = 'UI绘制预览';
+ uievent.elements.selectBackground.style.display = 'inline';
+ uievent.elements.selectBackground.value = 'thumbnail';
+ uievent.elements.selectFloor.style.display = 'none';
+ uievent.elements.selectPointBox.style.display = 'none';
+ uievent.elements.canvas.style.display = 'block';
+ uievent.elements.usedFlags.style.display = 'none';
+ uievent.elements.usedFlagList.style.display = 'none';
+ uievent.elements.body.style.overflow = "hidden";
+
+ uievent.values.list = list;
+ uievent.drawPreviewUI();
+ }
+
+ uievent.selectPoint = function (floorId, x, y, hideFloor, callback) {
+ uievent.values.hideFloor = hideFloor;
+ uievent.values.callback = callback;
+ uievent.values.size = editor.isMobile ? window.innerWidth / core.__SIZE__ : 32;
+ uievent.elements.selectPointBox.style.width = (uievent.values.size - 6) + "px";
+ uievent.elements.selectPointBox.style.height = (uievent.values.size - 6) + "px";
+
+ uievent.isOpen = true;
+ uievent.elements.div.style.display = 'block';
+ uievent.mode = 'selectPoint';
+ uievent.elements.selectPoint.style.display = 'block';
+ uievent.elements.yes.style.display = 'inline';
+ uievent.elements.selectBackground.style.display = 'none';
+ uievent.elements.selectFloor.style.display = hideFloor ? 'none' : 'inline';
+ uievent.elements.selectPointBox.style.display = 'block';
+ uievent.elements.canvas.style.display = 'block';
+ uievent.elements.usedFlags.style.display = 'none';
+ uievent.elements.usedFlagList.style.display = 'none';
+ uievent.elements.body.style.overflow = "hidden";
+
+ // Append children
+ var floors = "";
+ core.floorIds.forEach(function (f) {
+ floors += "";
+ })
+ uievent.elements.selectFloor.innerHTML = floors;
+
+ this.setPoint(floorId || editor.currentFloorId, core.calValue(x) || 0, core.calValue(y) || 0);
+ }
+
+ uievent.updateSelectPoint = function (redraw) {
+ uievent.elements.title.innerText = '地图选点 (' + uievent.values.x + "," + uievent.values.y + ')';
+ if (redraw) {
+ core.setAlpha('uievent', 1);
+ core.clearMap('uievent');
+ core.drawThumbnail(uievent.values.floorId, null, null,
+ {
+ ctx: 'uievent', centerX: uievent.values.left + core.__HALF_SIZE__,
+ centerY: uievent.values.top + core.__HALF_SIZE__
+ });
+ }
+ uievent.elements.selectPointBox.style.left = uievent.values.size * (uievent.values.x - uievent.values.left) + "px";
+ uievent.elements.selectPointBox.style.top = uievent.values.size * (uievent.values.y - uievent.values.top) + "px";
+ }
+
+ uievent.setPoint = function (floorId, x, y) {
+ if (core.floorIds.indexOf(floorId) == -1) floorId = editor.currentFloorId;
+ uievent.values.floorId = floorId;
+ uievent.elements.selectFloor.value = floorId;
+ uievent.values.x = x != null ? x : (uievent.values.x || 0);
+ uievent.values.y = y != null ? y : (uievent.values.y || 0);
+ uievent.values.width = core.floors[uievent.values.floorId].width || core.__SIZE__;
+ uievent.values.height = core.floors[uievent.values.floorId].height || core.__SIZE__;
+ uievent.values.left = core.clamp(uievent.values.x - core.__HALF_SIZE__, 0, uievent.values.width - core.__SIZE__);
+ uievent.values.top = core.clamp(uievent.values.y - core.__HALF_SIZE__, 0, uievent.values.height - core.__SIZE__);
+ uievent.updateSelectPoint(true);
+ }
+
+ uievent.elements.selectFloor.onchange = function () {
+ uievent.setPoint(uievent.elements.selectFloor.value);
+ }
+
+ uievent.elements.selectPointBox.onclick = function (e) {
+ e.stopPropagation();
+ }
+
+ uievent.elements.body.onclick = function (e) {
+ if (uievent.mode != 'selectPoint') return;
+ uievent.values.x = uievent.values.left + Math.floor(e.offsetX / uievent.values.size);
+ uievent.values.y = uievent.values.top + Math.floor(e.offsetY / uievent.values.size);
+ uievent.updateSelectPoint(false);
+ }
+
+ uievent.move = function (dx, dy) {
+ if (uievent.mode != 'selectPoint') return;
+ uievent.values.left = core.clamp(uievent.values.left + dx, 0, uievent.values.width - core.__SIZE__);
+ uievent.values.top = core.clamp(uievent.values.top + dy, 0, uievent.values.height - core.__SIZE__);
+ this.updateSelectPoint(true);
+ };
+
+ (function () {
+
+ var viewportButtons = uievent.elements.selectPointButtons;
+ var pressTimer = null;
+ for (var ii = 0, node; node = viewportButtons.children[ii]; ii++) {
+ (function (x, y) {
+ var move = function () {
+ uievent.move(x, y);
+ }
+ node.onmousedown = function () {
+ clearTimeout(pressTimer);
+ pressTimer = setTimeout(function () {
+ pressTimer = -1;
+ var f = function () {
+ if (pressTimer != null) {
+ move();
+ setTimeout(f, 150);
+ }
+ }
+ f();
+ }, 500);
+ };
+ node.onmouseup = function () {
+ if (pressTimer > 0) {
+ clearTimeout(pressTimer);
+ move();
+ }
+ pressTimer = null;
+ }
+ })([-1, 0, 0, 1][ii], [0, -1, 1, 0][ii]);
+ }
+ })();
+
+ uievent.elements.div.onmousewheel = function (e) {
+ if (uievent.mode != 'selectPoint' || uievent.values.hideFloor) return;
+ var index = core.floorIds.indexOf(uievent.values.floorId);
+ try {
+ if (e.wheelDelta)
+ index += Math.sign(e.wheelDelta);
+ else if (e.detail)
+ index += Math.sign(e.detail);
+ } catch (ee) { main.log(ee); }
+ index = core.clamp(index, 0, core.floorIds.length - 1);
+ uievent.setPoint(core.floorIds[index]);
+ }
+
+ // ------ 搜索变量出现的位置,也放在uievent好了 ------ //
+
+ uievent.searchUsedFlags = function () {
+ uievent.isOpen = true;
+ uievent.elements.div.style.display = 'block';
+ uievent.mode = 'searchUsedFlags';
+ uievent.elements.selectPoint.style.display = 'none';
+ uievent.elements.yes.style.display = 'none';
+ uievent.elements.title.innerText = '搜索变量';
+ uievent.elements.selectBackground.style.display = 'none';
+ uievent.elements.selectFloor.style.display = 'none';
+ uievent.elements.selectPointBox.style.display = 'none';
+ uievent.elements.canvas.style.display = 'none';
+ uievent.elements.usedFlags.style.display = 'inline';
+ uievent.elements.usedFlagList.style.display = 'block';
+ uievent.elements.body.style.overflow = "auto";
+
+ // build flags
+ var html = "";
+ Object.keys(editor.used_flags).sort().forEach(function (v) {
+ v = "flag:" + v;
+ html += "";
+ });
+ uievent.elements.usedFlags.innerHTML = html;
+
+ uievent.doSearchUsedFlags();
+ }
+
+ uievent.doSearchUsedFlags = function () {
+ var flag = uievent.elements.usedFlags.value;
+
+ var html = "该变量出现的所有位置如下:
";
+ var list = uievent._searchUsedFlags(flag);
+ list.forEach(function (v) {
+ var x = "- ";
+ if (v[0] != null) x += v[0] + "层 ";
+ else x += "公共事件 ";
+ x += v[1];
+ if (v[2] != null) x += " 的 (" + v[2] + ") 点";
+ x += "
";
+ html += x;
+ });
+ html += "
";
+ uievent.elements.usedFlagList.innerHTML = html;
+ }
+
+ var hasUsedFlags = function (obj, flag) {
+ if (obj == null) return false;
+ if (typeof obj != 'string') return hasUsedFlags(JSON.stringify(obj), flag);
+
+ var index = -1, length = flag.length;
+ while (true) {
+ index = obj.indexOf(flag, index + 1);
+ if (index < 0) return false;
+ if (!/^[a-zA-Z0-9_\u4E00-\u9FCC]$/.test(obj.charAt(index + length))) return true;
+ }
+ }
+
+ uievent._searchUsedFlags = function (flag) {
+ var list = [];
+ var events = ["events", "autoEvent", "changeFloor", "afterBattle", "afterGetItem", "afterOpenDoor"]
+ for (var floorId in core.floors) {
+ var floor = core.floors[floorId];
+ if (hasUsedFlags(floor.firstArrive, flag)) list.push([floorId, "firstArrive"]);
+ if (hasUsedFlags(floor.eachArrive, flag)) list.push([floorId, "eachArrive"]);
+ events.forEach(function (e) {
+ if (floor[e]) {
+ for (var loc in floor[e]) {
+ if (hasUsedFlags(floor[e][loc], flag)) {
+ list.push([floorId, e, loc]);
+ }
+ }
+ }
+ });
+ }
+ // 公共事件
+ if (core.events.commonEvent) {
+ for (var name in core.events.commonEvent) {
+ if (hasUsedFlags(core.events.commonEvent[name], flag))
+ list.push([null, name]);
+ }
+ }
+ return list;
+ }
+
+ editor.constructor.prototype.uievent=uievent;
+
+}
\ No newline at end of file
diff --git a/_server/editor_unsorted_1.js b/_server/editor_unsorted_1.js
deleted file mode 100644
index 2ff64a08..00000000
--- a/_server/editor_unsorted_1.js
+++ /dev/null
@@ -1,957 +0,0 @@
-editor_unsorted_1_wrapper=function(editor){
-
-editor.constructor.prototype.listen=function () {
- document.body.onmousedown = function (e) {
- //console.log(e);
- var clickpath = [];
- var getpath=function(e) {
- var path = [];
- var currentElem = e.target;
- while (currentElem) {
- path.push(currentElem);
- currentElem = currentElem.parentElement;
- }
- if (path.indexOf(window) === -1 && path.indexOf(document) === -1)
- path.push(document);
- if (path.indexOf(window) === -1)
- path.push(window);
- return path;
- }
- getpath(e).forEach(function (node) {
- if (!node.getAttribute) return;
- var id_ = node.getAttribute('id');
- if (id_) {
- if (['left', 'left1', 'left2', 'left3', 'left4', 'left5', 'left8', 'mobileview'].indexOf(id_) !== -1) clickpath.push('edit');
- clickpath.push(id_);
- }
- });
-
- var unselect=true;
- for(var ii=0,thisId;thisId=['edit','tip','brushMod','brushMod2','brushMod3','layerMod','layerMod2','layerMod3','viewportButtons'][ii];ii++){
- if (clickpath.indexOf(thisId) !== -1){
- unselect=false;
- break;
- }
- }
- if (unselect) {
- if (clickpath.indexOf('eui') === -1) {
- if (selectBox.isSelected()) {
- editor_mode.onmode('');
- editor.file.saveFloorFile(function (err) {
- if (err) {
- printe(err);
- throw(err)
- }
- ;printf('地图保存成功');
- });
- }
- selectBox.isSelected(false);
- editor.info = {};
- }
- }
- //editor.mode.onmode('');
- if (e.button!=2 && !editor.isMobile){
- editor.hideMidMenu();
- }
- if (clickpath.indexOf('down') !== -1 && editor.isMobile && clickpath.indexOf('midMenu') === -1){
- editor.hideMidMenu();
- }
- if(clickpath.length>=2 && clickpath[0].indexOf('id_')===0){editor.lastClickId=clickpath[0]}
- }
-
- var eui=document.getElementById('eui');
- var uc = eui.getContext('2d');
-
- function fillPos(pos) {
- uc.fillStyle = '#' + ~~(Math.random() * 8) + ~~(Math.random() * 8) + ~~(Math.random() * 8);
- uc.fillRect(pos.x * 32 + 12 - core.bigmap.offsetX, pos.y * 32 + 12 - core.bigmap.offsetY, 8, 8);
- }//在格子内画一个随机色块
-
- function eToLoc(e) {
- var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft
- var scrollTop = document.documentElement.scrollTop || document.body.scrollTop
- var xx=e.clientX,yy=e.clientY
- if(editor.isMobile){xx=e.touches[0].clientX,yy=e.touches[0].clientY}
- editor.loc = {
- 'x': scrollLeft + xx - mid.offsetLeft - mapEdit.offsetLeft,
- 'y': scrollTop + yy - mid.offsetTop - mapEdit.offsetTop,
- 'size': editor.isMobile?(32*innerWidth*0.96/core.__PIXELS__):32
- };
- return editor.loc;
- }//返回可用的组件内坐标
-
- function locToPos(loc, addViewportOffset) {
- var offsetX=0, offsetY=0;
- if (addViewportOffset){
- offsetX=core.bigmap.offsetX/32;
- offsetY=core.bigmap.offsetY/32;
- }
- editor.pos = {'x': ~~(loc.x / loc.size)+offsetX, 'y': ~~(loc.y / loc.size)+offsetY}
- return editor.pos;
- }
-
- var holdingPath = 0;
- var stepPostfix = null;//用于存放寻路检测的第一个点之后的后续移动
-
- var mouseOutCheck = 2;
-
- function clear1() {
- if (mouseOutCheck > 1) {
- mouseOutCheck--;
- setTimeout(clear1, 1000);
- return;
- }
- holdingPath = 0;
- stepPostfix = [];
- uc.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__);
- startPos = endPos = null;
- }//用于鼠标移出canvas时的自动清除状态
-
- eui.oncontextmenu=function(e){e.preventDefault()}
-
- eui.ondblclick = function(e) {
- // 双击地图可以选中素材
- var loc = eToLoc(e);
- var pos = locToPos(loc,true);
- editor.setSelectBoxFromInfo(editor[editor.layerMod][pos.y][pos.x]);
- return;
- }
-
- var startPos=null, endPos=null;
- eui.onmousedown = function (e) {
- if (e.button==2){
- var loc = eToLoc(e);
- var pos = locToPos(loc,true);
- editor.showMidMenu(e.clientX,e.clientY);
- return false;
- }
- if (!selectBox.isSelected()) {
- var loc = eToLoc(e);
- var pos = locToPos(loc,true);
- editor_mode.onmode('nextChange');
- editor_mode.onmode('loc');
- //editor_mode.loc();
- //tip.whichShow(1);
- tip.showHelp(6);
- startPos = pos;
- uc.strokeStyle = '#FF0000';
- uc.lineWidth = 3;
- if(editor.isMobile)editor.showMidMenu(e.clientX,e.clientY);
- return false;
- }
-
- holdingPath = 1;
- mouseOutCheck = 2;
- setTimeout(clear1);
- uc.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__);
- var loc = eToLoc(e);
- var pos = locToPos(loc,true);
- stepPostfix = [];
- stepPostfix.push(pos);
- fillPos(pos);
- return false;
- }
-
- eui.onmousemove = function (e) {
- if (!selectBox.isSelected()) {
- if (startPos == null) return;
- //tip.whichShow(1);
- var loc = eToLoc(e);
- var pos = locToPos(loc,true);
- if (endPos != null && endPos.x == pos.x && endPos.y == pos.y) return;
- if (endPos != null) {
- uc.clearRect(Math.min(32 * startPos.x - core.bigmap.offsetX, 32 * endPos.x - core.bigmap.offsetX),
- Math.min(32 * startPos.y - core.bigmap.offsetY, 32 * endPos.y - core.bigmap.offsetY),
- (Math.abs(startPos.x - endPos.x) + 1) * 32, (Math.abs(startPos.y - endPos.y) + 1) * 32)
- }
- endPos = pos;
- if (startPos != null) {
- if (startPos.x != endPos.x || startPos.y != endPos.y) {
- core.drawArrow('eui',
- 32 * startPos.x + 16 - core.bigmap.offsetX, 32 * startPos.y + 16 - core.bigmap.offsetY,
- 32 * endPos.x + 16 - core.bigmap.offsetX, 32 * endPos.y + 16 - core.bigmap.offsetY);
- }
- }
- // editor_mode.onmode('nextChange');
- // editor_mode.onmode('loc');
- //editor_mode.loc();
- //tip.whichShow(1);
- // tip.showHelp(6);
- return false;
- }
-
- if (holdingPath == 0) {
- return false;
- }
- mouseOutCheck = 2;
- var loc = eToLoc(e);
- var pos = locToPos(loc,true);
- var pos0 = stepPostfix[stepPostfix.length - 1]
- var directionDistance = [pos.y - pos0.y, pos0.x - pos.x, pos0.y - pos.y, pos.x - pos0.x]
- var max = 0, index = 4;
- for (var i = 0; i < 4; i++) {
- if (directionDistance[i] > max) {
- index = i;
- max = directionDistance[i];
- }
- }
- var pos = [{'x': 0, 'y': 1}, {'x': -1, 'y': 0}, {'x': 0, 'y': -1}, {'x': 1, 'y': 0}, false][index]
- if (pos) {
- pos.x += pos0.x;
- pos.y += pos0.y;
- stepPostfix.push(pos);
- fillPos(pos);
- }
- return false;
- }
-
- eui.onmouseup = function (e) {
- if (!selectBox.isSelected()) {
- //tip.whichShow(1);
- // editor.movePos(startPos, endPos);
- if (editor.layerMod == 'map')
- editor.exchangePos(startPos, endPos);
- else
- editor.exchangeBgFg(startPos, endPos, editor.layerMod);
- startPos = endPos = null;
- uc.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__);
- return false;
- }
- holdingPath = 0;
- if (stepPostfix && stepPostfix.length) {
- editor.preMapData = JSON.parse(JSON.stringify({map:editor.map,fgmap:editor.fgmap,bgmap:editor.bgmap}));
- if(editor.brushMod!=='line'){
- var x0=stepPostfix[0].x;
- var y0=stepPostfix[0].y;
- var x1=stepPostfix[stepPostfix.length-1].x;
- var y1=stepPostfix[stepPostfix.length-1].y;
- if(x0>x1){x0^=x1;x1^=x0;x0^=x1;}//swap
- if(y0>y1){y0^=y1;y1^=y0;y0^=y1;}//swap
- stepPostfix=[];
- for(var jj=y0;jj<=y1;jj++){
- for(var ii=x0;ii<=x1;ii++){
- stepPostfix.push({x:ii,y:jj})
- }
- }
- }
- currDrawData.pos = JSON.parse(JSON.stringify(stepPostfix));
- currDrawData.info = JSON.parse(JSON.stringify(editor.info));
- reDo = null;
- // console.log(stepPostfix);
- if(editor.brushMod==='tileset' && core.tilesets.indexOf(editor.info.images)!==-1){
- var imgWidth=~~(core.material.images.tilesets[editor.info.images].width/32);
- var x0=stepPostfix[0].x;
- var y0=stepPostfix[0].y;
- var idnum=editor.info.idnum;
- for (var ii = 0; ii < stepPostfix.length; ii++){
- if(stepPostfix[ii].y!=y0){
- y0++;
- idnum+=imgWidth;
- }
- editor[editor.layerMod][stepPostfix[ii].y][stepPostfix[ii].x] = editor.ids[editor.indexs[idnum+stepPostfix[ii].x-x0]];
- }
- } else {
- for (var ii = 0; ii < stepPostfix.length; ii++)
- editor[editor.layerMod][stepPostfix[ii].y][stepPostfix[ii].x] = editor.info;
- }
- // console.log(editor.map);
- editor.updateMap();
- holdingPath = 0;
- stepPostfix = [];
- uc.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__);
- }
- return false;
- }
-
- /*
- document.getElementById('mid').onkeydown = function (e) {
- console.log(e);
- if (e.keyCode==37) {
- editor.moveViewport(-1, 0);
- }
- if (e.keyCode==38) {
- editor.moveViewport(0, -1);
- }
- if (e.keyCode==39) {
- editor.moveViewport(1, 0);
- }
- if (e.keyCode==40) {
- editor.moveViewport(0, 1);
- }
- }
- */
-
- document.getElementById('mid').onmousewheel = function (e) {
- var wheel = function (direct) {
- var index=editor.core.floorIds.indexOf(editor.currentFloorId);
- var toId = editor.currentFloorId;
-
- if (direct>0 && index0)
- toId = editor.core.floorIds[index-1];
- else return;
-
- editor_mode.onmode('nextChange');
- editor_mode.onmode('floor');
- document.getElementById('selectFloor').value = toId;
- editor.changeFloor(toId);
- }
-
- try {
- if (e.wheelDelta)
- wheel(Math.sign(e.wheelDelta))
- else if (e.detail)
- wheel(Math.sign(e.detail));
- }
- catch (ee) {
- console.log(ee);
- }
- return false;
- }
-
- editor.preMapData = null;
- var currDrawData = {
- pos: [],
- info: {}
- };
- var reDo = null;
- var shortcut = core.getLocalStorage('shortcut',{48: 0, 49: 0, 50: 0, 51: 0, 52: 0, 53: 0, 54: 0, 55: 0, 56: 0, 57: 0});
- var copyedInfo = null;
- document.body.onkeydown = function (e) {
-
- // UI预览 & 地图选点
- if (uievent && uievent.isOpen) {
- e.preventDefault();
- if (e.keyCode == 27) uievent.close();
- else if (e.keyCode == 13) uievent.confirm();
- else if (e.keyCode==87) uievent.move(0,-1)
- else if (e.keyCode==65) uievent.move(-1,0)
- else if (e.keyCode==83) uievent.move(0,1);
- else if (e.keyCode==68) uievent.move(1,0);
- return;
- }
-
- // 监听Ctrl+S保存
- if (e.ctrlKey && e.keyCode == 83) {
- e.preventDefault();
- if (editor_multi.id != "") {
- editor_multi.confirm(); // 保存脚本编辑器
- }
- else if (editor_blockly.id != "") {
- editor_blockly.confirm(); // 保存事件编辑器
- }
- else {
- editor_mode.saveFloor();
- }
- return;
- }
-
- // 如果是开启事件/脚本编辑器状态,则忽略
- if (editor_multi.id!="" || editor_blockly.id!="")
- return;
-
- // 禁止快捷键的默认行为
- if (e.ctrlKey && [89, 90, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57].indexOf(e.keyCode) !== -1)
- e.preventDefault();
- if (e.altKey && [48, 49, 50, 51, 52, 53, 54, 55, 56, 57].indexOf(e.keyCode) !== -1)
- e.preventDefault();
- //Ctrl+z 撤销上一步undo
- if (e.keyCode == 90 && e.ctrlKey && editor.preMapData && currDrawData.pos.length && selectBox.isSelected()) {
- editor.map = JSON.parse(JSON.stringify(editor.preMapData.map));
- editor.fgmap = JSON.parse(JSON.stringify(editor.preMapData.fgmap));
- editor.bgmap = JSON.parse(JSON.stringify(editor.preMapData.bgmap));
- editor.updateMap();
- reDo = JSON.parse(JSON.stringify(currDrawData));
- currDrawData = {pos: [], info: {}};
- editor.preMapData = null;
- return;
- }
- //Ctrl+y 重做一步redo
- if (e.keyCode == 89 && e.ctrlKey && reDo && reDo.pos.length && selectBox.isSelected()) {
- editor.preMapData = JSON.parse(JSON.stringify({map:editor.map,fgmap:editor.fgmap,bgmap:editor.bgmap}));
- for (var j = 0; j < reDo.pos.length; j++)
- editor.map[reDo.pos[j].y][reDo.pos[j].x] = JSON.parse(JSON.stringify(reDo.info));
-
- editor.updateMap();
- currDrawData = JSON.parse(JSON.stringify(reDo));
- reDo = null;
- return;
- }
-
- // PGUP和PGDOWN切换楼层
- if (e.keyCode==33 || e.keyCode==34) {
- e.preventDefault();
- var index=editor.core.floorIds.indexOf(editor.currentFloorId);
- var nextIndex = index + (e.keyCode==33?1:-1);
- if (nextIndex>=0 && nextIndex=iconLib.offsetHeight - scrollBarHeight) return;
- var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
- var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
- var loc = {
- 'x': scrollLeft + e.clientX + iconLib.scrollLeft - right.offsetLeft - iconLib.offsetLeft,
- 'y': scrollTop + e.clientY + iconLib.scrollTop - right.offsetTop - iconLib.offsetTop,
- 'size': 32
- };
- editor.loc = loc;
- var pos = locToPos(loc);
- for (var spriter in editor.widthsX) {
- if (pos.x >= editor.widthsX[spriter][1] && pos.x < editor.widthsX[spriter][2]) {
- var ysize = spriter.endsWith('48') ? 48 : 32;
- loc.ysize = ysize;
- pos.images = editor.widthsX[spriter][0];
- pos.y = ~~(loc.y / loc.ysize);
- if(!editor.folded && core.tilesets.indexOf(pos.images)==-1) pos.x = editor.widthsX[spriter][1];
- var autotiles = core.material.images['autotile'];
- if (pos.images == 'autotile') {
- var imNames = Object.keys(autotiles);
- if ((pos.y + 1) * ysize > editor.widthsX[spriter][3])
- pos.y = ~~(editor.widthsX[spriter][3] / ysize) - 4;
- else {
- for (var i = 0; i < imNames.length; i++) {
- if (pos.y >= 4 * i && pos.y < 4 * (i + 1)) {
- pos.images = imNames[i];
- pos.y = 4 * i;
- }
- }
- }
- }
- else {
- var height = editor.widthsX[spriter][3], col = height / ysize;
- if (editor.folded && core.tilesets.indexOf(pos.images)==-1) {
- col = (pos.x == editor.widthsX[spriter][2] - 1) ? ((col - 1) % editor.foldPerCol + 1) : editor.foldPerCol;
- }
- if (spriter == 'terrains' && pos.x == editor.widthsX[spriter][1]) col += 2;
- pos.y = Math.min(pos.y, col - 1);
- }
-
- selectBox.isSelected(true);
- // console.log(pos,core.material.images[pos.images].height)
- dataSelection.style.left = pos.x * 32 + 'px';
- dataSelection.style.top = pos.y * ysize + 'px';
- dataSelection.style.height = ysize - 6 + 'px';
-
- if (pos.x == 0 && pos.y == 0) {
- // editor.info={idnum:0, id:'empty','images':'清除块', 'y':0};
- editor.info = 0;
- } else if(pos.x == 0 && pos.y == 1){
- editor.info = editor.ids[editor.indexs[17]];
- } else {
- if (autotiles[pos.images]) editor.info = {'images': pos.images, 'y': 0};
- else if (core.tilesets.indexOf(pos.images)!=-1) editor.info = {'images': pos.images, 'y': pos.y, 'x': pos.x-editor.widthsX[spriter][1]};
- else {
- var y = pos.y;
- if (editor.folded) {
- y += editor.foldPerCol * (pos.x-editor.widthsX[spriter][1]);
- }
- if (pos.images == 'terrains' && pos.x == 0) y -= 2;
- editor.info = {'images': pos.images, 'y': y}
- }
-
- for (var ii = 0; ii < editor.ids.length; ii++) {
- if ((core.tilesets.indexOf(pos.images)!=-1 && editor.info.images == editor.ids[ii].images
- && editor.info.y == editor.ids[ii].y && editor.info.x == editor.ids[ii].x)
- || (Object.prototype.hasOwnProperty.call(autotiles, pos.images) && editor.info.images == editor.ids[ii].id
- && editor.info.y == editor.ids[ii].y)
- || (core.tilesets.indexOf(pos.images)==-1 && editor.info.images == editor.ids[ii].images
- && editor.info.y == editor.ids[ii].y )
- ) {
-
- editor.info = editor.ids[ii];
- break;
- }
- }
- }
- tip.infos(JSON.parse(JSON.stringify(editor.info)));
- editor_mode.onmode('nextChange');
- editor_mode.onmode('enemyitem');
- //editor_mode.enemyitem();
- }
- }
- }
-
- var midMenu=document.getElementById('midMenu');
- midMenu.oncontextmenu=function(e){e.preventDefault()}
- editor.lastRightButtonPos=[{x:0,y:0},{x:0,y:0}];
- editor.lastCopyedInfo = [null, null];
- editor.showMidMenu=function(x,y){
- editor.lastRightButtonPos=JSON.parse(JSON.stringify(
- [editor.pos,editor.lastRightButtonPos[0]]
- ));
- // --- copy
- editor.lastCopyedInfo = [editor.copyFromPos(), editor.lastCopyedInfo[0]];
- var locStr='('+editor.lastRightButtonPos[1].x+','+editor.lastRightButtonPos[1].y+')';
- var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
- var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
-
- // 检测是否是上下楼
- var thisevent = editor.map[editor.pos.y][editor.pos.x];
- if (thisevent.id=='upFloor') {
- addFloorEvent.style.display='block';
- addFloorEvent.children[0].innerHTML='绑定上楼事件';
- }
- else if (thisevent.id=='downFloor') {
- addFloorEvent.style.display='block';
- addFloorEvent.children[0].innerHTML='绑定下楼事件';
- }
- else if (['leftPortal','rightPortal','downPortal','upPortal'].indexOf(thisevent.id)>=0) {
- addFloorEvent.style.display='block';
- addFloorEvent.children[0].innerHTML='绑定楼传事件';
- }
- else addFloorEvent.style.display='none';
-
- chooseThis.children[0].innerHTML='选中此点'+'('+editor.pos.x+','+editor.pos.y+')'
- copyLoc.children[0].innerHTML='复制事件'+locStr+'到此处';
- moveLoc.children[0].innerHTML='交换事件'+locStr+'与此事件的位置';
- midMenu.style='top:'+(y+scrollTop)+'px;left:'+(x+scrollLeft)+'px;';
- }
- editor.hideMidMenu=function(){
- if(editor.isMobile){
- setTimeout(function(){
- midMenu.style='display:none';
- },200)
- } else {
- midMenu.style='display:none';
- }
- }
-
- var addFloorEvent = document.getElementById('addFloorEvent');
- addFloorEvent.onmousedown = function(e) {
- editor.hideMidMenu();
- e.stopPropagation();
- var thisevent = editor.map[editor.pos.y][editor.pos.x];
- var loc = editor.pos.x+","+editor.pos.y;
- if (thisevent.id=='upFloor') {
- editor.currentFloorData.changeFloor[loc] = {"floorId": ":next", "stair": "downFloor"};
- }
- else if (thisevent.id=='downFloor') {
- editor.currentFloorData.changeFloor[loc] = {"floorId": ":before", "stair": "upFloor"};
- }
- else if (thisevent.id=='leftPortal' || thisevent.id=='rightPortal') {
- editor.currentFloorData.changeFloor[loc] = {"floorId": ":next", "stair": ":symmetry_x"}
- }
- else if (thisevent.id=='upPortal' || thisevent.id=='downPortal') {
- editor.currentFloorData.changeFloor[loc] = {"floorId": ":next", "stair": ":symmetry_y"}
- }
- editor.file.saveFloorFile(function (err) {
- if (err) {
- printe(err);
- throw(err)
- }
- editor.drawPosSelection();
- editor_mode.showMode('loc');
- printf('添加楼梯事件成功');
- });
- }
-
- var chooseThis = document.getElementById('chooseThis');
- chooseThis.onmousedown = function(e){
- editor.hideMidMenu();
- e.stopPropagation();
- selectBox.isSelected(false);
-
- editor_mode.onmode('nextChange');
- editor_mode.onmode('loc');
- //editor_mode.loc();
- //tip.whichShow(1);
- if(editor.isMobile)editor.showdataarea(false);
- }
-
- var chooseInRight = document.getElementById('chooseInRight');
- chooseInRight.onmousedown = function(e){
- editor.hideMidMenu();
- e.stopPropagation();
- var thisevent = editor[editor.layerMod][editor.pos.y][editor.pos.x];
- editor.setSelectBoxFromInfo(thisevent);
- }
-
- var copyLoc = document.getElementById('copyLoc');
- copyLoc.onmousedown = function(e){
- editor.hideMidMenu();
- e.stopPropagation();
- editor.preMapData = null;
- reDo = null;
- editor_mode.onmode('');
- var now = editor.pos, last = editor.lastRightButtonPos[1];
- if (now.x == last.x && now.y == last.y) return;
- editor.pasteToPos(editor.lastCopyedInfo[1]);
- editor.updateMap();
- editor.file.saveFloorFile(function (err) {
- if (err) {
- printe(err);
- throw(err)
- }
- ;printf('复制事件成功');
- editor.drawPosSelection();
- });
- }
-
- var moveLoc = document.getElementById('moveLoc');
- moveLoc.onmousedown = function(e){
- editor.hideMidMenu();
- e.stopPropagation();
- editor.preMapData = null;
- reDo = null;
- editor_mode.onmode('');
- editor.exchangePos(editor.pos, editor.lastRightButtonPos[1]);
- }
-
- var clearEvent = document.getElementById('clearEvent');
- clearEvent.onmousedown = function (e) {
- e.stopPropagation();
- reDo = null;
- editor.clearPos(false);
- }
-
- var clearLoc = document.getElementById('clearLoc');
- clearLoc.onmousedown = function(e){
- e.stopPropagation();
- reDo = null;
- editor.clearPos(true);
- }
-
- var brushMod=document.getElementById('brushMod');
- brushMod.onchange=function(){
- editor.brushMod=brushMod.value;
- }
-
- var brushMod2=document.getElementById('brushMod2');
- if(brushMod2)brushMod2.onchange=function(){
- editor.brushMod=brushMod2.value;
- }
-
- var brushMod3=document.getElementById('brushMod3');
- if(brushMod3) {
- brushMod3.onchange=function(){
- // tip.showHelp(5)
- tip.isSelectedBlock(false)
- tip.msgs[11] = String('tileset贴图模式下可以按选中tileset素材,并在地图上拖动来一次绘制一个区域');
- tip.whichShow(12);
- editor.brushMod=brushMod3.value;
- }
- }
-
- var bgc = document.getElementById('bg'), fgc = document.getElementById('fg'),
- evc = document.getElementById('event'), ev2c = document.getElementById('event2');
-
- var layerMod=document.getElementById('layerMod');
- layerMod.onchange=function(){
- editor.layerMod=layerMod.value;
- [bgc,fgc,evc,ev2c].forEach(function (x) {
- x.style.opacity = 1;
- });
-
- // 手机端....
- if (editor.isMobile) {
- if (layerMod.value == 'bgmap') {
- [fgc,evc,ev2c].forEach(function (x) {
- x.style.opacity = 0.3;
- });
- }
- if (layerMod.value == 'fgmap') {
- [bgc,evc,ev2c].forEach(function (x) {
- x.style.opacity = 0.3;
- });
- }
- }
- }
-
- var layerMod2=document.getElementById('layerMod2');
- if(layerMod2)layerMod2.onchange=function(){
- editor.layerMod=layerMod2.value;
- [fgc,evc,ev2c].forEach(function (x) {
- x.style.opacity = 0.3;
- });
- bgc.style.opacity = 1;
- }
-
- var layerMod3=document.getElementById('layerMod3');
- if(layerMod3)layerMod3.onchange=function(){
- editor.layerMod=layerMod3.value;
- [bgc,evc,ev2c].forEach(function (x) {
- x.style.opacity = 0.3;
- });
- fgc.style.opacity = 1;
- }
-
- var viewportButtons=document.getElementById('viewportButtons');
- var pressTimer = null;
- for(var ii=0,node;node=viewportButtons.children[ii];ii++){
- (function(x,y){
- var move = function () {
- editor.moveViewport(x, y);
- }
- node.onmousedown = function () {
- clearTimeout(pressTimer);
- pressTimer = setTimeout(function () {
- pressTimer = -1;
- var f = function () {
- if (pressTimer != null) {
- move();
- setTimeout(f, 150);
- }
- }
- f();
- }, 500);
- };
- node.onmouseup = function () {
- if (pressTimer > 0) {
- clearTimeout(pressTimer);
- move();
- }
- pressTimer = null;
- }
- })([-1,0,0,1][ii],[0,-1,1,0][ii]);
- }
-}
-
-editor.constructor.prototype.mobile_listen=function () {
- if(!editor.isMobile)return;
-
- var mobileview=document.getElementById('mobileview');
- var editModeSelect=document.getElementById('editModeSelect');
- var mid=document.getElementById('mid');
- var right=document.getElementById('right');
- var mobileeditdata=document.getElementById('mobileeditdata');
-
-
- editor.showdataarea=function(callShowMode){
- mid.style='z-index:-1;opacity: 0;';
- right.style='z-index:-1;opacity: 0;';
- mobileeditdata.style='';
- if(callShowMode)editor.mode.showMode(editModeSelect.value);
- editor.hideMidMenu();
- }
- mobileview.children[0].onclick=function(){
- editor.showdataarea(true)
- }
- mobileview.children[1].onclick=function(){
- mid.style='';
- right.style='z-index:-1;opacity: 0;';
- mobileeditdata.style='z-index:-1;opacity: 0;';
- editor.lastClickId='';
- }
- mobileview.children[3].onclick=function(){
- mid.style='z-index:-1;opacity: 0;';
- right.style='';
- mobileeditdata.style='z-index:-1;opacity: 0;';
- editor.lastClickId='';
- }
-
-
- var gettrbyid=function(){
- if(!editor.lastClickId)return false;
- thisTr = document.getElementById(editor.lastClickId);
- input = thisTr.children[2].children[0].children[0];
- field = thisTr.children[0].getAttribute('title');
- cobj = JSON.parse(thisTr.children[1].getAttribute('cobj'));
- return [thisTr,input,field,cobj];
- }
- mobileeditdata.children[0].onclick=function(){
- var info = gettrbyid()
- if(!info)return;
- info[1].ondblclick()
- }
- mobileeditdata.children[1].onclick=function(){
- var info = gettrbyid()
- if(!info)return;
- printf(info[2])
- }
- mobileeditdata.children[2].onclick=function(){
- var info = gettrbyid()
- if(!info)return;
- printf(info[0].children[1].getAttribute('title'))
- }
-
- //=====
-
- document.body.ontouchstart=document.body.onmousedown;
- document.body.onmousedown=null;
-
-
- var eui=document.getElementById('eui');
- eui.ontouchstart=eui.onmousedown
- eui.onmousedown=null
- eui.ontouchmove=eui.onmousemove
- eui.onmousemove=null
- eui.ontouchend=eui.onmouseup
- eui.onmouseup=null
-
-
- var chooseThis = document.getElementById('chooseThis');
- chooseThis.ontouchstart=chooseThis.onmousedown
- chooseThis.onmousedown=null
- var chooseInRight = document.getElementById('chooseInRight');
- chooseInRight.ontouchstart=chooseInRight.onmousedown
- chooseInRight.onmousedown=null
- var copyLoc = document.getElementById('copyLoc');
- copyLoc.ontouchstart=copyLoc.onmousedown
- copyLoc.onmousedown=null
- var moveLoc = document.getElementById('moveLoc');
- moveLoc.ontouchstart=moveLoc.onmousedown
- moveLoc.onmousedown=null
- var clearLoc = document.getElementById('clearLoc');
- clearLoc.ontouchstart=clearLoc.onmousedown
- clearLoc.onmousedown=null
-}
-
-}
\ No newline at end of file
diff --git a/_server/editor_util.js b/_server/editor_util.js
index 6f81a8c1..beb437db 100644
--- a/_server/editor_util.js
+++ b/_server/editor_util.js
@@ -161,10 +161,10 @@ editor_util_wrapper = function (editor) {
return val != null && !(typeof val == 'number' && isNaN(val));
}
- editor_util.prototype.checkCallback=function(callback){
+ editor_util.prototype.checkCallback = function (callback) {
if (!editor.util.isset(callback)) {
editor.printe('未设置callback');
- throw('未设置callback')
+ throw ('未设置callback')
}
}
diff --git a/_server/fs.js b/_server/fs.js
index dddfbbec..7a74d647 100644
--- a/_server/fs.js
+++ b/_server/fs.js
@@ -132,7 +132,13 @@
var data = '';
data += 'name=' + path;
postsomething(data, '/listFile', function (err, data) {
- callback(err, JSON.parse(data))
+ try {
+ data = JSON.parse(data);
+ } catch (e) {
+ err = "Invalid /listFile";
+ data = null;
+ }
+ callback(err, data);
});
return;
}
diff --git a/_server/img_md/view1.png b/_server/img_md/view1.png
new file mode 100644
index 00000000..9cf0135c
Binary files /dev/null and b/_server/img_md/view1.png differ
diff --git a/_server/img_md/view2.png b/_server/img_md/view2.png
new file mode 100644
index 00000000..8243840b
Binary files /dev/null and b/_server/img_md/view2.png differ
diff --git a/_server/img_md/view3.png b/_server/img_md/view3.png
new file mode 100644
index 00000000..34daceac
Binary files /dev/null and b/_server/img_md/view3.png differ
diff --git a/_server/refactoring.md b/_server/refactoring.md
index 8ea8c365..fbd0fff0 100644
--- a/_server/refactoring.md
+++ b/_server/refactoring.md
@@ -1,5 +1,7 @@
# 重构
+> 目前状态: 按功能分类已基本完成, 未完成file/game的重写
+
总体思路
+ 按功能拆分文件
+ 左侧页面模块化, 方便添加
@@ -12,16 +14,21 @@
editor_file之后是更改editor.map的储存方式, 现有的存对象的模式要在对象和数字间来回转换, 非常繁琐和奇怪
-再之后是把editor_unsorted_*.js整理清晰
-
## 文件结构
+(全部小写,必要时用下划线分割)
+
+ [ ] editor_blockly 图块化事件编辑器
+ [ ] editor_multi 多行文本编辑器
+ [x] editor_table 处理表格的生成, 及其响应的事件, 从原editor\_mode中分离
+ [ ] editor_file 调用fs.js编辑文件, 把原editor\_file模块化, 并且只负责文件写入
+ [ ] editor_game 处理游戏数据, 导入为editor的数据, 编辑数据, 从原editor和editor_file中抽离. **只有此文件允许`\s(main|core)`形式的调用**(以及其初始化`editor_game_wrapper(editor, main, core);`)
+ [x] editor_util 生成guid/处理颜色 等函数, 从editor分离
++ [ ] editor_listen 处理界面上的按钮/下拉框点击等用户的操作与功能函数的绑定, 维护editor.dom, unsorted_1/2中的绑定挪到此处, 其中的函数内容, 分类放在其他文件
++ [ ] editor_mappanel 与地图区相关的功能, <-unsorted_1/2/3
++ [ ] editor_datapanel 与数据区相关的功能, <-unsorted_1/2/3
++ [ ] editor_materialpanel 与素材区相关的功能, <-unsorted_1/2/3
++ [ ] editor_ui 维护printe/printf/tip, 以及之后可能的窗口化, ui事件中没有具体到前三个区中的函数 <-unsorted_1/2/3
+ [ ] editor 执行初始化流程加组合各组件
+ [ ] 原editor_mode 移除
+ [x] 原vm 移除
@@ -72,9 +79,11 @@ editor: {
+ editor.widthX特别不直观
++ ? 编辑器使用可拖拽和调大小的窗口做容器
+
## 功能改进
-+ [ ] 大地图
++ [x] 大地图
在切换时, 每次都回到最左上->每个楼层记录一个位置
四个箭头支持长按
? 滚动条
@@ -87,12 +96,12 @@ editor: {
+ [ ] ? 简洁的事件方块注册
`editor.registerEvent('log',[['test','Int','测试',0],['floorId','Idstring','楼层','MT0']])`
-+ [ ] 一个显示所有快捷键的文本
++ [x] 一个显示所有快捷键的文本
-+ [ ] 更多快捷键
++ [x] 更多快捷键
【全塔属性】、【楼层属性】等常用的编辑栏切换
-+ [ ] ? 地图编辑优化
++ [x] ? 地图编辑优化
常用的地图编辑快捷键/命令:复制ctrl+c、粘贴ctrl+v、(复制可绑定为现在的“选中xx位置事件” 粘贴为复制xx事件到此处),撤回ctrl+z、取消撤回ctrl+y
可以按住拖动图块与事件。
@@ -103,18 +112,20 @@ editor: {
+ [x] 修改系统的触发器(下拉菜单增加新项)
在编辑器修改`comment.js`:现场发readFile请求读文件,然后开脚本编辑器进行编辑
-+ [ ] ? 删除注册项/修改图块ID
++ [x] ? 删除注册项/修改图块ID
+ [ ] ? 怪物和道具也能像其他类型那样查看“图块信息”(而不只是具体的怪物属性)
-+ [ ] 素材区自动换列
++ [x] 素材区自动换列
怪物或道具太多时, 按照每100个进行拆分新开列来显示
-+ [ ] 多帧素材只显示第一帧
++ [x] 多帧素材只显示第一帧
-+ [ ] `显示文章`以及`选项`等方块, 把`标题`和`图像`从字符串提取出填回相应的空
++ [x] `显示文章`以及`选项`等方块, 把`标题`和`图像`从字符串提取出填回相应的空
-+ [ ] blockly中某些需要选点的填空, 增加按钮, 点击后从缩略图中点击位置
++ [x] blockly中某些需要选点的填空, 增加按钮, 点击后从缩略图中点击位置
+
++ [ ] 插件编写增加判定,如果保存时框内不是以 "function\s*()" 开头(也就是用户直接写的脚本),则自动添加一个 function() { } 将代码包装起来。
## 左侧页面模式
diff --git a/_server/table/comment.js b/_server/table/comment.js
index abbf3b7d..6e549b88 100644
--- a/_server/table/comment.js
+++ b/_server/table/comment.js
@@ -258,11 +258,12 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
},
"_data": "该图块是否不可通行;true代表不可通行,false代表可通行,null代表使用系统缺省值"
},
- "canBreak": {
+ "script": {
"_leaf": true,
- "_type": "checkbox",
- "_bool": "bool",
- "_data": "该图块是否可被破墙或地震"
+ "_type": "textarea",
+ "_string": true,
+ "_lint": true,
+ "_data": "触碰到该图块时自动执行的脚本内容;此脚本会在该点的触发器执行前执行"
},
"cannotOut": {
"_leaf": true,
@@ -276,6 +277,12 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
"_range": "thiseval==null||(thiseval instanceof Array)",
"_data": "该图块的不可入方向\n可以在这里定义不能朝哪个方向进入该图块,可以达到悬崖之类的效果\n例如 [\"down\"] 代表不能从该图块的上方点朝向下进入此图块\n此值对背景层、事件层、前景层上的图块均有效"
},
+ "canBreak": {
+ "_leaf": true,
+ "_type": "checkbox",
+ "_bool": "bool",
+ "_data": "该图块是否可被破墙或地震"
+ },
"animate": {
"_leaf": true,
"_type": "textarea",
@@ -435,6 +442,24 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
"_event": "event",
"_data": "该点的可能事件列表,可以双击进入事件编辑器。"
},
+ "autoEvent": {
+ "_type": "object",
+ "_leaf": false,
+ "_action": function (args) {
+ args.vobj=args.vobj||{};
+ for(var ii=0;ii<2;ii++){
+ args.vobj[ii]=args.vobj[ii]||null;
+ }
+ },
+ "_data": function (key) {
+ return {
+ "_leaf": true,
+ "_type": "event",
+ "_event": "autoEvent",
+ "_data": "自动事件页"
+ }
+ }
+ },
"changeFloor": {
"_leaf": true,
"_type": "event",
@@ -464,7 +489,7 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
"_type": "textarea",
"_range": "thiseval==null||(thiseval instanceof Array)",
"_data": "该点不可通行的方向 \n 可以在这里定义该点不能前往哪个方向,可以达到悬崖之类的效果\n例如 [\"up\", \"left\"] 代表该点不能往上和左走"
- }
+ },
}
}
}
@@ -496,6 +521,7 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
"afterBattle": {},
"afterGetItem": {},
"afterOpenDoor": {},
+ "autoEvent": {},
"cannotMove": {}
}
}
diff --git a/_server/table/functions.comment.js b/_server/table/functions.comment.js
index 44396901..55dc8d1c 100644
--- a/_server/table/functions.comment.js
+++ b/_server/table/functions.comment.js
@@ -94,6 +94,12 @@ var functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
"_lint": true,
"_data": "炸弹事件"
},
+ "afterPassNet": {
+ "_leaf": true,
+ "_type": "textarea",
+ "_lint": true,
+ "_data": "经过特殊地形后的事件"
+ },
"canUseQuickShop": {
"_leaf": true,
"_type": "textarea",
diff --git a/_server/table/plugins.comment.js b/_server/table/plugins.comment.js
index fc4f5144..3d436a06 100644
--- a/_server/table/plugins.comment.js
+++ b/_server/table/plugins.comment.js
@@ -20,6 +20,18 @@ var plugins_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
"_range": "typeof(thiseval)=='string' || thiseval==null",
"_data": "绘制灯光效果"
},
+ "drawItemShop": {
+ "_leaf": true,
+ "_type": "textarea",
+ "_range": "typeof(thiseval)=='string' || thiseval==null",
+ "_data": "道具商店插件"
+ },
+ "smoothCamera": {
+ "_leaf": true,
+ "_type": "textarea",
+ "_range": "typeof(thiseval)=='string' || thiseval==null",
+ "_data": "平滑移动镜头效果"
+ },
}
if (obj[key]) return obj[key];
return {
diff --git a/editor-mobile.html b/editor-mobile.html
index b8d2e0eb..fe371abd 100644
--- a/editor-mobile.html
+++ b/editor-mobile.html
@@ -76,6 +76,7 @@
+
色相:
@@ -101,7 +102,7 @@
-
@@ -236,6 +241,7 @@
语法检查
+