mota-js/extensions/dynamicMapEditor.js
2019-10-21 10:27:48 +08:00

407 lines
12 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 运行时可编辑地图的扩展By fux2黄鸡
*/
"use strict";
function dynamicMapEditor() {
// 所有显示的ID
this.displayIds = [
'none', 'yellowWall', 'blueWall', 'whiteWall', 'yellowDoor', 'blueDoor', 'redDoor', 'star', 'lava', 'lavaNet',
'yellowKey', 'blueKey', 'redKey', 'redJewel', 'blueJewel', 'greenJewel', 'yellowJewel',
'redPotion', 'bluePotion', 'yellowPotion', 'greenPotion', 'pickaxe', 'bomb', 'centerFly',
'cls:autotile', 'cls:enemys', 'cls:enemy48'
];
this.userParams = {
hotKeys: {
openToolBox: 219,
save: 221,
undo: 220
}
};
this.infos = [];
this.userChanged = [];
this.key2Function = {};
this.dom = null;
this.canvas = null;
this.database = [];
this.mapRecord = {};
this.enemy2id = {};
this.pageId = 0;
this.pageMaxItems = 21;
this.pageMax = 0;
this.selectedIndex = 0;
this.selectedItem = null;
this._init();
}
dynamicMapEditor.prototype._init = function () {
var hotkeys = this.userParams.hotKeys;
this.key2Function[hotkeys.openToolBox] = this.openToolBox;
this.key2Function[hotkeys.save] = this.applyCurrentChange;
this.key2Function[hotkeys.undo] = this.undo;
this.dom = document.createElement("canvas");
this.dom.id = 'dynamicMapEditor';
this.dom.style.display = 'none';
this.dom.style.position = 'absolute';
this.dom.style.left = '3px';
this.dom.style.top = '3px';
this.dom.style.zIndex = 99999;
this.canvas = this.dom.getContext("2d");
core.dom.gameGroup.appendChild(this.dom);
this.initInfos();
for(var k in core.material.enemys) {
var index = core.material.icons.enemys[k];
if(index !== undefined) {
this.database[index] = k;
}
}
this.database = this.database.filter(function(item){ return !!item; });
for(var k in core.maps.blocksInfo) {
var block = core.maps.blocksInfo[k];
if(block.cls == 'enemys') {
this.enemy2id[block.id] = k;
}
}
this.pageMax = Math.ceil(this.database.length / this.pageMaxItems);
core.actions.registerAction('onkeyUp', 'plugin_dme_keydown', this.onKeyDown.bind(this), 200);
core.actions.registerAction('onclick', 'plugin_dme_click', this.onMapClick.bind(this), 200);
this.dom.addEventListener("click",this.onBoxClick.bind(this));
}
dynamicMapEditor.prototype.initInfos = function () {
this.infos = [];
this.displayIds.forEach(function (v) {
if (v.startsWith("cls:")) {
var cls = v.substr(4);
for (var id in core.maps.blocksInfo) {
var u = core.maps.blocksInfo[id];
if (u && u.cls == cls) {
this.infos.push(core.getBlockInfo(u.id));
}
}
} else {
this.infos.push(core.getBlockInfo(v));
}
}, this);
}
dynamicMapEditor.prototype.openToolBox = function() {
this.isUsingTool = !this.isUsingTool;
this.selectedItem = null;
this.selectedIndex = -1;
this.refreshToolBox();
}
dynamicMapEditor.prototype.undo = function() {
var operation = this.userChanged.pop();
if(!operation) {
core.drawTip('没有动作可以撤销');
return;
}
var type = operation.type;
if(type == 'put') {
var blockId = operation.originId;
var x = operation.x;
var y = operation.y;
var floorId = operation.floorId;
var originData = core.floors[floorId];
core.floors[floorId].map[y][x] = blockId;
this.mapRecord[floorId] = true;
core.removeBlock(x,y,floorId);
core.drawTip('已撤销'+floorId+'在('+x+','+y+')的图块操作');
}else{
var enemyId = operation.enemyId;
var hp = operation.originHp;
var atk = operation.originAtk;
var def = operation.originDef;
var special = operation.originSpecial;
var enemy = core.material.enemys[enemyId];
enemy.hp = hp;
enemy.atk = atk;
enemy.def = def;
enemy.special = special;
core.drawTip('已撤销对'+enemy.name+'的属性修改');
}
}
dynamicMapEditor.prototype.onKeyDown = function(e) {
if(core.status.lockControl) return false;
var func = this.key2Function[e.keyCode];
func && func.call(this);
return false;
}
dynamicMapEditor.prototype.addOperation = function() {
var operation = {};
var type = arguments[0];
operation.type = type;
if(type == 'put') {
operation.applyId = arguments[1];
operation.x = arguments[2];
operation.y = arguments[3];
operation.floorId = arguments[4];
operation.originId = core.floors[operation.floorId].map[operation.y][operation.x];
core.floors[operation.floorId].map[operation.y][operation.x] = operation.applyId;
this.mapRecord[operation.floorId] = true;
}else if(type == 'modify') {
operation.enemyId = arguments[1];
operation.hp = arguments[2];
operation.atk = arguments[3];
operation.def = arguments[4];
operation.special = arguments[5];
var enemy = core.material.enemys[operation.enemyId];
operation.originHp = enemy.hp;
operation.originAtk = enemy.atk;
operation.originDef = enemy.def;
operation.originSpecial = enemy.special;
enemy.hp = operation.hp;
enemy.atk = operation.atk;
enemy.def = operation.def;
enemy.special = operation.special;
}
this.userChanged.push(operation);
}
dynamicMapEditor.prototype.onMapClick = function(x,y) {
if(core.status.lockControl) return false;
if(!this.isUsingTool) return false;
if(!this.selectedItem) return false;
var blockId = Number(this.enemy2id[this.selectedItem.id]);
this.addOperation('put',blockId,x,y,core.status.floorId);
core.setBlock(blockId, x, y, core.status.floorId);
return true;
}
dynamicMapEditor.prototype.onItemClick = function(index) {
var startIndex = this.pageId * this.pageMaxItems;
var item = this.database[startIndex + index];
if(!item) return;
if(index == this.selectedIndex) {
var enemy = core.material.enemys[item];
var nowData = [enemy.hp,enemy.atk,enemy.def,enemy.special].join(',');
var result = prompt("输入血,攻,防,能力",nowData);
if(result) {
var finalData = result.split(/,/);
var hp = Number(finalData[0]);
var atk = Number(finalData[1]);
var def = Number(finalData[2]);
var special = eval(finalData[3]);
this.addOperation('modify',item,hp,atk,def,special);
core.drawTip('已更新'+enemy.name+'的数据');
this.refreshToolBox();
}else{
core.drawTip('无效的输入数据');
}
}else{
this.selectedIndex = index;
this.selectedItem = core.material.enemys[item];
this.refreshToolBox();
}
}
dynamicMapEditor.prototype.onPageUp = function() {
if(this.pageId>0) {
this.pageId--;
this.selectedItem = null;
this.refreshToolBox();
}
}
dynamicMapEditor.prototype.onPageDown = function() {
if(this.pageId<this.pageMax-1) {
this.pageId++;
this.selectedItem = null;
this.refreshToolBox();
}
}
dynamicMapEditor.prototype.onBoxClick = function(e) {
if(!this.isUsingTool) return;
var x = e.layerX;
var y = e.layerY;
for(var i=0;i<this.pageMaxItems;i++) {
var rect = this.itemRect(i);
if(x>=rect.x && x<=rect.x+rect.w && y>=rect.y && y<=rect.y+rect.h) {
this.onItemClick(i);
return;
}
}
if(y>=350) {
if(x>=this.offsetX && x<=this.offsetX+60){
this.onPageUp();
}else{
this.onPageDown();
}
}
}
dynamicMapEditor.prototype.resetCanvas = function() {
this.canvas.font = "12px 宋体";
this.canvas.textBaseline = 'alphabetic';
this.canvas.mozImageSmoothingEnabled = false;
this.canvas.webkitImageSmoothingEnabled = false;
this.canvas.msImageSmoothingEnabled = false;
this.canvas.imageSmoothingEnabled = false;
}
dynamicMapEditor.prototype.itemRect = function(index) {
return {
'x' : this.offsetX+(index%3)*40,
'y' : Math.floor(index/3)*50,
'w' : 40,
'h' : 50
};
}
dynamicMapEditor.prototype.fillTextWithOutline = function(text,x,y,style) {
this.canvas.fillStyle = '#000000';
this.canvas.fillText(text, x-1, y-1);
this.canvas.fillText(text, x-1, y+1);
this.canvas.fillText(text, x+1, y-1);
this.canvas.fillText(text, x+1, y+1);
this.canvas.fillStyle = style;
this.canvas.fillText(text, x, y);
}
dynamicMapEditor.prototype.refreshToolBox = function() {
this.dom.style.width = core.dom.statusCanvas.style.width;
this.dom.width = core.dom.statusCanvas.width;
this.dom.style.height = core.dom.statusCanvas.style.height;
this.dom.height = core.dom.statusCanvas.height;
this.offsetX = this.dom.width / 2 - 60;;
if(this.isUsingTool) {
this.canvas.fillStyle = '#000000';
this.canvas.fillRect(0,0,this.dom.width,this.dom.height);
if(!core.domStyle.isVertical) {
this.resetCanvas();
var source = core.material.images.enemys;
var enemyCount = this.database.length;
var startIndex = this.pageId * this.pageMaxItems;
for(var i=0;i<this.pageMaxItems;i++) {
var item = this.database[startIndex + i];
if(!item) break;
var name = core.material.enemys[item].name;
var si = core.material.icons.enemys[item]*32;
var rect = this.itemRect(i);
this.canvas.drawImage(source,0,si,32,32,rect.x+4,rect.y,32,32);
this.canvas.textAlign = 'center';
this.canvas.fillText(name,rect.x+20,rect.y+44);
var damageString = core.enemys.getDamageString(item, 0, 0, core.status.floorId);
var damage = damageString.damage
this.fillTextWithOutline(damage,rect.x+20,rect.y+32,damageString.color);
this.canvas.textAlign = 'left';
var critical = core.enemys.nextCriticals(item, 1, 0, 0, core.status.floorId);
critical = core.formatBigNumber((critical[0]||[])[0], true);
if (critical == '???') critical = '?';
this.fillTextWithOutline(critical,rect.x+2,rect.y+12,'#FFFFFF');
}
this.canvas.textAlign = 'center';
if(this.pageId>0) this.canvas.fillText('上一页',this.offsetX + 30,380);
if(this.pageId<this.pageMax-1) this.canvas.fillText('下一页',this.offsetX + 90,380);
if(this.selectedItem) {
this.canvas.strokeStyle = '#FFFFFF';
var rect = this.itemRect(this.selectedIndex);
this.canvas.strokeRect(rect.x,rect.y,rect.w,rect.h);
}
}
}
this.dom.style.display = this.isUsingTool ? 'block' : 'none';
}
// ------ save
dynamicMapEditor.prototype.applyCurrentChange = function() {
this.saveEnemys();
this.saveFloors();
this.mapRecord = {};
core.drawTip('已将所有改动应用到文件,刷新后生效');
}
dynamicMapEditor.prototype.saveEnemys = function () {
core.enemys.enemys = core.clone(core.material.enemys);
var datastr = 'var enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80 = \n';
var emap = {};
var estr = JSON.stringify(core.enemys.enemys, function (k, v) {
if (v.hp != null) {
var id_ = ":" + k + ":";
emap[id_] = JSON.stringify(v);
return id_;
} else return v
}, '\t');
for (var id_ in emap) {
estr = estr.replace('"' + id_ + '"', emap[id_])
}
datastr += estr;
fs.writeFile('project/enemys.js', core.encodeBase64(datastr), 'base64', function (e, d) {});
}
dynamicMapEditor.prototype.saveFloors = function () {
core.initStatus.maps = core.maps._initMaps();
for (var floorId in this.mapRecord) {
if (this.mapRecord[floorId]) {
this.saveFloor(floorId);
}
}
}
dynamicMapEditor.prototype.saveFloor = function (floorId) {
var floorData = core.floors[floorId];
var filename = 'project/floors/' + floorId + '.js';
var datastr = ['main.floors.', floorId, '=\n'];
var tempJsonObj = core.clone(floorData);
var tempMap = [['map', ':map:'], ['bgmap', ':bgmap:'], ['fgmap', ':fgmap:']];
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' + dynamicMapEditor.formatMap(v[2], v[0] != 'map') + '\n]')
});
datastr = datastr.concat([tempJson]);
datastr = datastr.join('');
fs.writeFile(filename, core.encodeBase64(datastr), 'base64', function (e, d) {});
}
dynamicMapEditor.prototype.formapMap = 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, '').sdatastr
var si = mapArr.length - 1, sk = mapArr[0].length - 1;datastr
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;
}
// ------ rewrite
dynamicMapEditor._resize_statusBar = core.control._resize_statusBar;
core.control._resize_statusBar = function (obj) {
dynamicMapEditor._resize_statusBar.call(this,obj);
dynamicMapEditor.refreshToolBox();
}
var dynamicMapEditor = new dynamicMapEditor();