4869 lines
176 KiB
JavaScript
4869 lines
176 KiB
JavaScript
var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
|
||
{
|
||
"init": function () {
|
||
this._afterLoadResources = function () {
|
||
// 本函数将在所有资源加载完毕后,游戏开启前被执行
|
||
}
|
||
if (!core.platform.isPC) {
|
||
try {
|
||
window.screen.orientation.lock("landscape-primary");
|
||
} catch (e) {}
|
||
}
|
||
|
||
core.dom.playGame.setAttribute('selected', true); ////游戏第一次打开进入到标题界面时要将光标设置为到playGame
|
||
|
||
core.control.hideStatusBar();
|
||
core.control.resize = function () {
|
||
if (main.mode == 'editor') return;
|
||
var clientWidth = main.dom.body.clientWidth,
|
||
clientHeight = main.dom.body.clientHeight;
|
||
var BORDER = 0;
|
||
var extendToolbar = core.flags.extendToolbar;
|
||
var BAR_WIDTH = extendToolbar ? 0 : Math.round(core._PY_ / 3);
|
||
|
||
var horizontalMaxRatio = (clientHeight - 2 * BORDER - (extendToolbar ? BORDER : 0)) / (core._PY_ + (extendToolbar ? 38 : 0));
|
||
|
||
//////强制横屏插件
|
||
|
||
|
||
////////
|
||
// 横屏
|
||
|
||
|
||
core.domStyle.availableScale = [];
|
||
[1, 1.25, 1.5, 1.75, 2, 2.25, 2.5].forEach(function (v) {
|
||
if (clientWidth - 3 * BORDER >= v * (core._PX_ + BAR_WIDTH) && horizontalMaxRatio >= v) {
|
||
core.domStyle.availableScale.push(v);
|
||
}
|
||
});
|
||
if (core.domStyle.availableScale.indexOf(core.domStyle.scale) < 0) {
|
||
core.domStyle.scale = Math.min(1, horizontalMaxRatio);
|
||
}
|
||
if (clientWidth - 3 * BORDER >= core._PX_ + BAR_WIDTH || (clientWidth > clientHeight && horizontalMaxRatio < 1)) {
|
||
core.domStyle.isVertical = false;
|
||
core.clearMap('Vertical');
|
||
} else if (core.status.played) {
|
||
// 竖屏
|
||
core.domStyle.isVertical = true;
|
||
core.createCanvas('Vertical', 0, 0, 480, 480, 200);
|
||
core.drawWindowSkin('winskin.png', 'Vertical', 30, 150, 400, 100);
|
||
core.drawTextContent('Vertical', '\r[#ff8080]强烈建议建议使用最新版浏览器\n开启手机自动旋转功能进行横屏游戏', {
|
||
left: 50,
|
||
top: 180,
|
||
maxWidth: 400,
|
||
fontSize: 20,
|
||
lineHeight: 20,
|
||
bold: true,
|
||
});
|
||
// core.domStyle.scale = Math.min((clientWidth - 2 * BORDER) / core._PX_);
|
||
// core.domStyle.availableScale = [];
|
||
// extendToolbar = false;
|
||
// BAR_WIDTH = Math.round(core._PX_ * 0.3);
|
||
}
|
||
|
||
var statusDisplayArr = this._shouldDisplayStatus(),
|
||
count = statusDisplayArr.length;
|
||
var statusCanvas = core.flags.statusCanvas,
|
||
statusCanvasRows = core.values.statusCanvasRowsOnMobile || 3;
|
||
var col = statusCanvas ? statusCanvasRows : Math.ceil(count / 3);
|
||
if (col > 5) {
|
||
if (statusCanvas) alert("自绘状态栏的在竖屏下的行数应不超过5!");
|
||
else alert("当前状态栏数目(" + count + ")大于15,请调整到不超过15以避免手机端出现显示问题。");
|
||
}
|
||
var globalAttribute = core.status.globalAttribute || core.initStatus.globalAttribute;
|
||
|
||
var obj = {
|
||
clientWidth: clientWidth,
|
||
clientHeight: clientHeight,
|
||
BORDER: BORDER,
|
||
BAR_WIDTH: BAR_WIDTH,
|
||
TOOLBAR_HEIGHT: 38,
|
||
outerWidth: core._PX_ * core.domStyle.scale + 2 * BORDER,
|
||
outerHeight: core._PY_ * core.domStyle.scale + 2 * BORDER,
|
||
globalAttribute: globalAttribute,
|
||
border: '0px ' + core.arrayToRGBA(globalAttribute.borderColor) + ' solid',
|
||
statusDisplayArr: statusDisplayArr,
|
||
count: count,
|
||
col: col,
|
||
statusBarHeightInVertical: core.domStyle.isVertical ? (32 * col + 6) * core.domStyle.scale + 2 * BORDER : 0,
|
||
toolbarHeightInVertical: core.domStyle.isVertical ? 38 * core.domStyle.scale + 2 * BORDER : 0,
|
||
extendToolbar: extendToolbar,
|
||
is15x15: false
|
||
};
|
||
|
||
this._doResize(obj);
|
||
this.setToolbarButton();
|
||
core.updateStatusBar();
|
||
}
|
||
|
||
core.control._resize_statusBar = function (obj) {
|
||
// statusBar
|
||
var statusBar = core.dom.statusBar;
|
||
if (core.domStyle.isVertical) {
|
||
statusBar.style.width = obj.outerWidth + "px";
|
||
statusBar.style.height = obj.statusBarHeightInVertical + "px";
|
||
statusBar.style.background = obj.globalAttribute.statusTopBackground;
|
||
statusBar.style.fontSize = 16 * core.domStyle.scale + "px";
|
||
} else {
|
||
statusBar.style.width = (obj.BAR_WIDTH * core.domStyle.scale + obj.BORDER) + "px";
|
||
statusBar.style.height = obj.outerHeight + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER : 0) + "px";
|
||
statusBar.style.background = obj.globalAttribute.statusLeftBackground;
|
||
// --- 计算文字大小
|
||
if (obj.extendToolbar) {
|
||
statusBar.style.fontSize = 16 * core.domStyle.scale + "px";
|
||
} else {
|
||
statusBar.style.fontSize = 16 * Math.min(1, (core._HEIGHT_ - 4) / obj.count) * core.domStyle.scale + "px";
|
||
}
|
||
}
|
||
statusBar.style.display = obj.extendToolbar ? 'none' : 'block';
|
||
statusBar.style.borderTop = statusBar.style.borderLeft = obj.border;
|
||
statusBar.style.borderRight = core.domStyle.isVertical ? obj.border : '';
|
||
statusBar.style.borderBottom = core.domStyle.isVertical ? '' : obj.border;
|
||
// 自绘状态栏
|
||
if (core.domStyle.isVertical) {
|
||
core.dom.statusCanvas.style.width = core._PX_ * core.domStyle.scale + "px";
|
||
core.dom.statusCanvas.style.height = obj.statusBarHeightInVertical - 3 + "px";
|
||
core.maps._setHDCanvasSize(core.dom.statusCanvasCtx, core._PX_, obj.col * 32 + 9);
|
||
} else {
|
||
core.dom.statusCanvas.style.width = obj.BAR_WIDTH * core.domStyle.scale + "px";
|
||
core.dom.statusCanvas.style.height = obj.outerHeight - 2 * obj.BORDER + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER : 0) + "px";
|
||
core.maps._setHDCanvasSize(core.dom.statusCanvasCtx, obj.BAR_WIDTH, core._PY_ + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT + obj.BORDER : 0));
|
||
}
|
||
if (core.domStyle.isVertical) {
|
||
core.dom.caidan1.style.width = core._PX_ * core.domStyle.scale + "px";
|
||
core.dom.caidan1.style.height = obj.statusBarHeightInVertical - 3 + "px";
|
||
core.maps._setHDCanvasSize(core.dom.caidan1Ctx, core._PX_, obj.col * 32 + 9);
|
||
} else {
|
||
core.dom.caidan1.style.width = obj.BAR_WIDTH * core.domStyle.scale + "px";
|
||
core.dom.caidan1.style.height = obj.outerHeight - 2 * obj.BORDER + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER : 0) + "px";
|
||
core.maps._setHDCanvasSize(core.dom.caidan1Ctx, obj.BAR_WIDTH, core._PY_ + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT + obj.BORDER : 0));
|
||
}
|
||
core.dom.statusCanvas.style.display = core.flags.statusCanvas && !obj.extendToolbar ? "block" : "none";
|
||
}
|
||
core.registerResize("statusBar", core.control._resize_statusBar);
|
||
core.control._resize_gameGroup = function (obj) {
|
||
var startBackground = core.domStyle.isVertical ? (main.styles.startVerticalBackground || main.styles.startBackground) : main.styles.startBackground;
|
||
if (main.dom.startBackground.getAttribute('__src__') != startBackground) {
|
||
main.dom.startBackground.setAttribute('__src__', startBackground);
|
||
main.dom.startBackground.src = startBackground;
|
||
}
|
||
|
||
var gameGroup = core.dom.gameGroup;
|
||
var totalWidth, totalHeight;
|
||
if (core.domStyle.isVertical) {
|
||
totalWidth = obj.outerWidth;
|
||
totalHeight = obj.outerHeight + obj.statusBarHeightInVertical + obj.toolbarHeightInVertical
|
||
} else {
|
||
totalWidth = obj.outerWidth + obj.BAR_WIDTH * core.domStyle.scale + (obj.extendToolbar ? 0 : obj.BORDER);
|
||
totalHeight = obj.outerHeight + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER : 0);
|
||
}
|
||
gameGroup.style.width = totalWidth + "px";
|
||
gameGroup.style.height = totalHeight + "px";
|
||
gameGroup.style.left = (obj.clientWidth - totalWidth) / 2 + "px";
|
||
gameGroup.style.top = (obj.clientHeight - totalHeight) / 2 + "px";
|
||
gameGroup.style.overflow = "hidden";
|
||
var whole = core.dom.whole;
|
||
whole.style.width = totalWidth + "px";
|
||
whole.style.height = totalHeight + "px";
|
||
// floorMsgGroup
|
||
var floorMsgGroup = core.dom.floorMsgGroup;
|
||
floorMsgGroup.style = obj.globalAttribute.floorChangingStyle;
|
||
floorMsgGroup.style.width = obj.outerWidth - 2 * obj.BORDER + "px";
|
||
floorMsgGroup.style.height = totalHeight - 2 * obj.BORDER + "px";
|
||
floorMsgGroup.style.fontSize = 16 * core.domStyle.scale + "px";
|
||
// startPanel
|
||
core.dom.startPanel.style.fontSize = 16 * core.domStyle.scale + "px";
|
||
// musicBtn
|
||
if (core.domStyle.isVertical || core.domStyle.scale < 1) {
|
||
core.dom.musicBtn.style.right = core.dom.musicBtn.style.bottom = "3px";
|
||
} else {
|
||
core.dom.musicBtn.style.right = (obj.clientWidth - totalWidth) / 2 + "px";
|
||
core.dom.musicBtn.style.bottom = (obj.clientHeight - totalHeight) / 2 - 27 + "px";
|
||
}
|
||
}
|
||
core.registerResize("gameGroup", core.control._resize_gameGroup);
|
||
core.maps._drawThumbnail_realDrawTempCanvas = function (floorId, blocks, options) {
|
||
// 缩略图:背景
|
||
this.drawBg(floorId, options);
|
||
// 缩略图:事件
|
||
this.drawEvents(floorId, blocks, options);
|
||
// 缩略图:勇士
|
||
if (options.heroLoc) {
|
||
options.heroIcon = options.heroIcon || core.status.hero.image || 'hero.png';
|
||
options.heroIcon = core.getMappedName(options.heroIcon);
|
||
var icon = core.material.icons.hero[options.heroLoc.direction];
|
||
var height = core.material.images.images[options.heroIcon].height / 4;
|
||
var width = (core.material.images.images[options.heroIcon].width || 128) / 4;
|
||
core.drawImage(options.ctx, core.material.images.images[options.heroIcon], icon.stop * width, icon.loc * height, width, height,
|
||
32 * options.heroLoc.x + 32 - width, 32 * options.heroLoc.y + 32 - height, width, height);
|
||
}
|
||
// 缩略图:卷轴
|
||
if (floorId != 'nandu') core.drawImage(options.ctx, 'caidan.png', -161, 0);
|
||
// 缩略图:前景
|
||
this.drawFg(floorId, options);
|
||
// 缩略图:显伤
|
||
if (options.damage && core.hasItem('book')) {
|
||
core.updateCheckBlock(floorId);
|
||
core.control.updateDamage(floorId, options.ctx);
|
||
}
|
||
}
|
||
core.maps._drawMap_drawAll = function (floorId, config) {
|
||
floorId = floorId || core.status.floorId;
|
||
this.drawBg(floorId, config);
|
||
this.drawEvents(floorId);
|
||
this.drawFg(floorId, config);
|
||
if (floorId == "nandu") {
|
||
core.maps._drawFloorImages(floorId, core.dom.wholeCtx, 'whole', null, null, (config || {}).onMap);
|
||
} else core.dom.wholeCtx.clearRect(0, 0, core.dom.whole.width, core.dom.whole.height);
|
||
}
|
||
core.control._animationFrame_globalAnimate = function (timestamp) {
|
||
if (timestamp - core.animateFrame.globalTime <= core.values.animateSpeed) return;
|
||
core.status.globalAnimateStatus++;
|
||
if (core.status.floorId) {
|
||
// Global Animate
|
||
core.status.globalAnimateObjs.forEach(function (block) {
|
||
core.drawBlock(block, core.status.globalAnimateStatus);
|
||
});
|
||
|
||
// Global floor images
|
||
core.maps._drawFloorImages(core.status.floorId, core.canvas.bg, 'bg', core.status.floorAnimateObjs || [], core.status.globalAnimateStatus);
|
||
core.maps._drawFloorImages(core.status.floorId, core.canvas.fg, 'fg', core.status.floorAnimateObjs || [], core.status.globalAnimateStatus);
|
||
core.maps._drawFloorImages(core.status.floorId, core.dom.wholeCtx, 'whole', core.status.floorAnimateObjs || [], core.status.globalAnimateStatus);
|
||
|
||
// Global Autotile Animate
|
||
core.status.autotileAnimateObjs.forEach(function (block) {
|
||
core.maps._drawAutotileAnimate(block, core.status.globalAnimateStatus);
|
||
});
|
||
|
||
// Global hero animate
|
||
if ((core.status.hero || {}).animate && core.status.heroMoving == 0 && main.mode == 'play' && !core.status.preview.enabled) {
|
||
core.drawHero('stop', null, core.status.globalAnimateStatus);
|
||
}
|
||
}
|
||
// Box animate
|
||
core.drawBoxAnimate();
|
||
core.animateFrame.globalTime = timestamp;
|
||
}
|
||
core.control.registerAnimationFrame("globalAnimate", true, core.control._animationFrame_globalAnimate);
|
||
core.ui.createCanvas2 = function (name, x, y, width, height, z) {
|
||
// 如果画布已存在则直接调用
|
||
if (core.dymCanvas[name]) {
|
||
core.deleteCanvas(name);
|
||
}
|
||
var newCanvas = document.createElement("canvas");
|
||
newCanvas.id = name;
|
||
newCanvas.style.display = 'block';
|
||
newCanvas.setAttribute("_left", x);
|
||
newCanvas.setAttribute("_top", y);
|
||
newCanvas.style.width = width * core.domStyle.scale + 'px';
|
||
newCanvas.style.height = height * core.domStyle.scale + 'px';
|
||
newCanvas.style.left = x * core.domStyle.scale + 'px';
|
||
newCanvas.style.top = y * core.domStyle.scale + 'px';
|
||
newCanvas.style.zIndex = z;
|
||
newCanvas.style.position = 'absolute';
|
||
newCanvas.style.pointerEvents = 'none';
|
||
core.dymCanvas[name] = newCanvas.getContext('2d');
|
||
core.maps._setHDCanvasSize(core.dymCanvas[name], width, height);
|
||
core.dom.gameGroup.appendChild(newCanvas);
|
||
return core.dymCanvas[name];
|
||
}
|
||
core.ui.deleteCanvas = function (name) {
|
||
if (name instanceof Function) {
|
||
Object.keys(core.dymCanvas).forEach(function (one) {
|
||
if (name(one)) core.deleteCanvas(one);
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (!core.dymCanvas[name]) return null;
|
||
var temp = core.dymCanvas[name].canvas.parentElement.id;
|
||
if (temp == "gameDraw") core.dom.gameDraw.removeChild(core.dymCanvas[name].canvas);
|
||
if (temp == "gameGroup") core.dom.gameGroup.removeChild(core.dymCanvas[name].canvas);
|
||
delete core.dymCanvas[name];
|
||
}
|
||
core.events.showImage2 = function (code, image, sloc, loc, opacityVal, time, callback) {
|
||
var imageName = null;
|
||
if (typeof image == 'string') {
|
||
imageName = image;
|
||
if (image.endsWith(':x') || image.endsWith(':y') || image.endsWith(':o')) {
|
||
image = image.substring(0, image.length - 2);
|
||
}
|
||
image = core.getMappedName(image);
|
||
image = core.material.images.images[image];
|
||
}
|
||
if (!image) {
|
||
if (callback) callback();
|
||
return;
|
||
}
|
||
sloc = sloc || [];
|
||
var sx = core.calValue(sloc[0]) || 0,
|
||
sy = core.calValue(sloc[1]) || 0;
|
||
var sw = core.calValue(sloc[2]),
|
||
sh = core.calValue(sloc[3]);
|
||
if (sw == null) sw = image.width;
|
||
if (sh == null) sh = image.height;
|
||
loc = loc || [];
|
||
var x = core.calValue(loc[0]) || 0,
|
||
y = core.calValue(loc[1]) || 0;
|
||
var w = core.calValue(loc[2]),
|
||
h = core.calValue(loc[3]);
|
||
if (w == null) w = sw;
|
||
if (h == null) h = sh;
|
||
var zIndex = code + 100;
|
||
time = time || 0;
|
||
var name = "image" + zIndex;
|
||
var ctx = core.ui.createCanvas2(name, x, y, w, h, zIndex);
|
||
core.drawImage(ctx, imageName == null ? image : imageName, sx, sy, sw, sh, 0, 0, w, h);
|
||
if (time == 0) {
|
||
core.setOpacity(name, opacityVal);
|
||
if (callback) callback();
|
||
return;
|
||
}
|
||
core.setOpacity(name, 0);
|
||
this.moveImage(code, null, opacityVal, null, time, callback);
|
||
}
|
||
core.events._action_showImage2 = function (data, x, y, prefix) {
|
||
if (core.isReplaying()) data.time = 0;
|
||
this.__action_doAsyncFunc(data.async || data.time == 0, core.events.showImage2,
|
||
data.code, data.image + (data.reverse || ''), data.sloc, data.loc, data.opacity, data.time);
|
||
}
|
||
core.ui._drawCenterFly = function () {
|
||
core.lockControl();
|
||
core.status.event.id = 'centerFly';
|
||
var fillstyle = 'rgba(255,0,0,0.5)';
|
||
if (core.canUseItem('centerFly')) fillstyle = 'rgba(0,255,0,0.5)';
|
||
var toX = core.bigmap.width - 1 - core.getHeroLoc('x'),
|
||
toY = core.bigmap.height - 3 - core.getHeroLoc('y');
|
||
this.clearUI();
|
||
core.fillRect('ui', 0, 0, core._PX_, core._PY_, '#000000');
|
||
core.drawThumbnail(null, null, { heroLoc: core.status.hero.loc, heroIcon: core.status.hero.image, ctx: 'ui', centerX: toX, centerY: toY });
|
||
var offsetX = core.clamp(toX - core._HALF_WIDTH_, 0, core.bigmap.width - core._WIDTH_),
|
||
offsetY = core.clamp(toY - core._HALF_HEIGHT_, 0, core.bigmap.height - core._HEIGHT_);
|
||
core.fillRect('ui', (toX - offsetX) * 32, (toY - offsetY) * 32, 32, 32, fillstyle);
|
||
core.status.event.data = { "x": toX, "y": toY, "posX": toX - offsetX, "posY": toY - offsetY };
|
||
core.playSound('打开界面');
|
||
core.drawTip("请确认当前" + core.material.items['centerFly'].name + "的位置", 'centerFly');
|
||
return;
|
||
}
|
||
core.control.setAutomaticRoute = function (destX, destY, stepPostfix) {
|
||
if (!core.status.played || core.status.lockControl) return;
|
||
if (this._setAutomaticRoute_isMoving(destX, destY)) return;
|
||
if (this._setAutomaticRoute_isTurning(destX, destY, stepPostfix)) return;
|
||
if (this._setAutomaticRoute_clickMoveDirectly(destX, destY, stepPostfix)) return;
|
||
// 找寻自动寻路路线
|
||
if (destY == 13 || destY == 14) {
|
||
if (destX == 2 || destX == 3) {
|
||
destY == 13 ? core.openBook(true) : core.ui._drawHelp();
|
||
}
|
||
if (destX == 4 || destX == 5) {
|
||
destY == 13 ? core.useFly(true) : core.turnHero();
|
||
}
|
||
if (destX == 6 || destX == 7 || destX == 8) {
|
||
destY == 13 ? core.openToolbox(true) : core.openQuickShop(true);
|
||
}
|
||
if (destX == 9 || destX == 10) {
|
||
destY == 13 ? core.save(true) : core.openSettings(true);
|
||
}
|
||
if (destX == 11 || destX == 12) {
|
||
destY == 13 ? core.load(true) : core.openSettings(true);
|
||
}
|
||
return;
|
||
}
|
||
var moveStep = core.automaticRoute(destX, destY);
|
||
if (moveStep.length == 0 && (destX != core.status.hero.loc.x || destY != core.status.hero.loc.y || stepPostfix.length == 0))
|
||
return;
|
||
moveStep = moveStep.concat(stepPostfix);
|
||
core.status.automaticRoute.destX = destX;
|
||
core.status.automaticRoute.destY = destY;
|
||
this._setAutomaticRoute_drawRoute(moveStep);
|
||
this._setAutomaticRoute_setAutoSteps(moveStep);
|
||
// 立刻移动
|
||
core.setAutoHeroMove();
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
core.ui._drawSettings = function () {
|
||
core.status.event.id = 'settings';
|
||
this.drawChoices(null, [
|
||
"系统设置", "虚拟键盘", "浏览地图", "存档笔记", "同步存档", "游戏信息", "返回标题", "返回游戏", "爽塔相关", "RM相关"
|
||
]);
|
||
}
|
||
core.actions._clickSettings = function (x, y) {
|
||
if (this._out(x)) return;
|
||
var choices = core.status.event.ui.choices;
|
||
var topIndex = this._getChoicesTopIndex(choices.length);
|
||
if (y >= topIndex && y < topIndex + choices.length) {
|
||
var selection = y - topIndex;
|
||
core.status.event.selection = selection;
|
||
switch (selection) {
|
||
case 0:
|
||
core.status.event.selection = 0;
|
||
core.playSound('确定');
|
||
core.ui._drawSwitchs();
|
||
break;
|
||
case 1:
|
||
// core.playSound('确定');
|
||
core.ui._drawKeyBoard();
|
||
break;
|
||
case 2:
|
||
// core.playSound('确定');
|
||
core.clearUI();
|
||
core.ui._drawViewMaps();
|
||
break;
|
||
case 3:
|
||
core.status.event.selection = 0;
|
||
core.playSound('确定');
|
||
core.ui._drawNotes();
|
||
break;
|
||
case 4:
|
||
core.status.event.selection = 0;
|
||
core.playSound('确定');
|
||
core.ui._drawSyncSave();
|
||
break;
|
||
case 5:
|
||
core.status.event.selection = 0;
|
||
core.playSound('确定');
|
||
core.ui._drawGameInfo();
|
||
break;
|
||
case 6:
|
||
return core.confirmRestart();
|
||
case 7:
|
||
core.playSound('取消');
|
||
core.ui.closePanel();
|
||
break;
|
||
case 8:
|
||
core.status.event.selection = 0;
|
||
core.playSound('确定');
|
||
core.ui._drawShuangta();
|
||
/*core.playSound('确定');
|
||
core.setFlag("itemDetail", !core.getFlag("itemDetail"));
|
||
core.getItemDetail();
|
||
core.ui.closePanel();*/
|
||
break;
|
||
case 9:
|
||
core.status.event.selection = 0;
|
||
core.playSound('确定');
|
||
core.ui._drawRM();
|
||
/*core.playSound('确定');
|
||
core.setFlag("isRmFly", !core.getFlag("isRmFly"));
|
||
core.ui.closePanel();*/
|
||
break;
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
core.ui._drawShuangta = function () {
|
||
core.status.event.id = 'shuangta';
|
||
this.drawChoices(null, [
|
||
"数值显示: " + (core.getFlag("itemDetail") ? "[ON]" : "[OFF]"),
|
||
"自动拾取: " + (core.getFlag("__autoGetItem__") ? "[ON]" : "[OFF]"),
|
||
"自动清怪: " + (core.getFlag("__autoBattle__") ? "[ON]" : "[OFF]"), "返回主菜单"
|
||
]);
|
||
}
|
||
core.ui._drawRM = function () {
|
||
core.status.event.id = 'rm';
|
||
this.drawChoices(null, [
|
||
"RM楼传: " + (core.getFlag("isRmFly") ? "[ON]" : "[OFF]"),
|
||
"显伤靠右: " + (core.getFlag("isDamageRight") ? "[ON]" : "[OFF]"),
|
||
"零伤白色: " + (core.getFlag("isZeroWhite") ? "[ON]" : "[OFF]"),
|
||
"道具打怪不提示: " + (core.getFlag("isNoTip") ? "[ON]" : "[OFF]"),
|
||
"手册显示普通: " + (core.getFlag("isCommon") ? "[ON]" : "[OFF]"),
|
||
"返回主菜单"
|
||
]);
|
||
}
|
||
////// 获得某个物品 //////
|
||
core.events.getItem = function (id, num, x, y, isGentleClick, callback) {
|
||
if (num == null) num = 1;
|
||
var itemCls = core.material.items[id].cls;
|
||
core.removeBlock(x, y);
|
||
core.items.getItemEffect(id, num);
|
||
var text = '获得 ' + core.material.items[id].name;
|
||
if (num > 1) text += "x" + num;
|
||
if (itemCls === 'items' && num == 1) text += core.items.getItemEffectTip(id);
|
||
if (!core.getFlag("isNoTip")) core.drawTip(text, id);
|
||
|
||
// --- 首次获得道具的提示
|
||
if (!core.hasFlag("__itemHint__")) core.setFlag("__itemHint__", []);
|
||
var itemHint = core.getFlag("__itemHint__");
|
||
if (core.flags.itemFirstText && itemHint.indexOf(id) < 0 && itemCls != 'items') {
|
||
var hint = core.material.items[id].text || "该道具暂无描述";
|
||
try {
|
||
hint = core.replaceText(hint);
|
||
} catch (e) {}
|
||
if (!core.status.event.id || core.status.event.id == 'action') {
|
||
//core.insertAction("\t[" + core.material.items[id].name + "," + id + "]\b[center]" + hint + "\n"
|
||
//+
|
||
// (id.endsWith('Key') ? "(钥匙类道具,遇到对应的门时自动打开)" :
|
||
// itemCls == 'tools' ? "(消耗类道具,请按T在道具栏使用)" :
|
||
// itemCls == 'constants' ? "(永久类道具,请按T在道具栏使用)" :
|
||
// itemCls == 'equips' ? "(装备类道具,请按Q在装备栏进行装备)" : ""));
|
||
core.insertAction("\b[center]\\c[32]\\i[" + id + "]\\c[22]" + core.material.items[id].name + '\n\n' + hint + "\n");
|
||
|
||
}
|
||
itemHint.push(id);
|
||
}
|
||
|
||
this.afterGetItem(id, x, y, isGentleClick);
|
||
if (callback) callback();
|
||
}
|
||
core.enemys.getDamageString = function (enemy, x, y, floorId) {
|
||
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
|
||
var damage = this.getDamage(enemy, x, y, floorId);
|
||
|
||
var color = '#000000';
|
||
|
||
if (damage == null) {
|
||
damage = "???";
|
||
color = '#FF2222';
|
||
} else {
|
||
if (damage < 0) color = '#11FF11';
|
||
else if (damage == 0) color = '#FFFFFF';
|
||
else if (damage < core.status.hero.hp / 3) color = '#FFFF00';
|
||
else if (damage < core.status.hero.hp * 2 / 3) color = '#FF9933';
|
||
else if (damage < core.status.hero.hp) color = '#FF9933';
|
||
else color = '#FF2222';
|
||
if (!core.getFlag('isZeroWhite')) {
|
||
if (damage <= 0) color = '#11FF11';
|
||
else if (damage < core.status.hero.hp / 3) color = '#FFFFFF';
|
||
else if (damage < core.status.hero.hp * 2 / 3) color = '#FFFF00';
|
||
else if (damage < core.status.hero.hp) color = '#FF9933';
|
||
else color = '#FF2222';
|
||
}
|
||
damage = core.formatBigNumber(damage, true);
|
||
if (core.enemys.hasSpecial(enemy, 19))
|
||
damage += "+";
|
||
if (core.enemys.hasSpecial(enemy, 21))
|
||
damage += "-";
|
||
if (core.enemys.hasSpecial(enemy, 11))
|
||
damage += "^";
|
||
}
|
||
|
||
return {
|
||
"damage": damage,
|
||
"color": color
|
||
};
|
||
}
|
||
core.ui._drawBook_drawBackground = function () {
|
||
core.setAlpha('ui', 1);
|
||
//core.setFillStyle('ui', '#000000');
|
||
//core.fillRect('ui', 0, 0, core._PX_, core._PY_);删除绘制的黑底
|
||
core.createCanvas('bookBg', 0, 0, 480, 480, 138); ///创建一个动态画布用于绘制手册bg
|
||
core.drawWindowSkin('winskin.png', 'bookBg', 0, 0, core._PX_, core._PY_);
|
||
}
|
||
core.actions._sys_keyDown_lockControl = function (keyCode) {
|
||
if (!core.status.lockControl) return false;
|
||
// Ctrl跳过对话
|
||
if (keyCode == 17) {
|
||
this.keyDownCtrl();
|
||
return true;
|
||
}
|
||
switch (core.status.event.id) {
|
||
case 'action':
|
||
this._keyDownAction(keyCode);
|
||
break;
|
||
case 'book':
|
||
this._keyDownBook(keyCode);
|
||
break;
|
||
case 'fly':
|
||
this._keyDownFly(keyCode);
|
||
break;
|
||
case 'viewMaps':
|
||
this._keyDownViewMaps(keyCode);
|
||
break;
|
||
case 'equipbox':
|
||
this._keyDownEquipbox(keyCode);
|
||
break;
|
||
case 'toolbox':
|
||
this._keyDownToolbox(keyCode);
|
||
break;
|
||
case 'save':
|
||
case 'load':
|
||
case 'replayLoad':
|
||
case 'replayRemain':
|
||
case 'replaySince':
|
||
this._keyDownSL(keyCode);
|
||
break;
|
||
case 'selectShop':
|
||
case 'switchs':
|
||
case 'switchs-sounds':
|
||
case 'switchs-display':
|
||
case 'switchs-action':
|
||
case 'notes':
|
||
case 'settings':
|
||
case 'syncSave':
|
||
case 'syncSelect':
|
||
case 'localSaveSelect':
|
||
case 'storageRemove':
|
||
case 'replay':
|
||
case 'gameInfo':
|
||
case 'shuangta':
|
||
case 'rm':
|
||
this._keyDownChoices(keyCode);
|
||
break;
|
||
case 'cursor':
|
||
this._keyDownCursor(keyCode);
|
||
break;
|
||
}
|
||
return true;
|
||
}
|
||
core.actions._sys_keyUp_lockControl = function (keyCode, altKey) {
|
||
if (!core.status.lockControl) return false;
|
||
|
||
var ok = function () {
|
||
return keyCode == 27 || keyCode == 88 || keyCode == 13 || keyCode == 32 || keyCode == 67;
|
||
}
|
||
|
||
core.status.holdingKeys = [];
|
||
switch (core.status.event.id) {
|
||
case 'text':
|
||
ok() && core.drawText();
|
||
break;
|
||
case 'confirmBox':
|
||
this._keyUpConfirmBox(keyCode);
|
||
break;
|
||
case 'action':
|
||
this._keyUpAction(keyCode);
|
||
break;
|
||
case 'about':
|
||
ok() && core.closePanel();
|
||
break;
|
||
case 'help':
|
||
ok() && core.closePanel();
|
||
break;
|
||
case 'book':
|
||
this._keyUpBook(keyCode);
|
||
break;
|
||
case 'book-detail':
|
||
ok() && this._clickBookDetail();
|
||
break;
|
||
case 'fly':
|
||
this._keyUpFly(keyCode);
|
||
break;
|
||
case 'viewMaps':
|
||
this._keyUpViewMaps(keyCode);
|
||
break;
|
||
case 'selectShop':
|
||
this._keyUpQuickShop(keyCode);
|
||
break;
|
||
case 'toolbox':
|
||
this._keyUpToolbox(keyCode);
|
||
break;
|
||
case 'equipbox':
|
||
this._keyUpEquipbox(keyCode, altKey);
|
||
break;
|
||
case 'save':
|
||
case 'load':
|
||
case 'replayLoad':
|
||
case 'replayRemain':
|
||
case 'replaySince':
|
||
this._keyUpSL(keyCode);
|
||
break;
|
||
case 'keyBoard':
|
||
ok() && core.closePanel();
|
||
break;
|
||
case 'switchs':
|
||
this._keyUpSwitchs(keyCode);
|
||
break;
|
||
case 'switchs-sounds':
|
||
this._keyUpSwitchs_sounds(keyCode);
|
||
break;
|
||
case 'switchs-display':
|
||
this._keyUpSwitchs_display(keyCode);
|
||
break;
|
||
case 'switchs-action':
|
||
this._keyUpSwitchs_action(keyCode);
|
||
break;
|
||
case 'settings':
|
||
this._keyUpSettings(keyCode);
|
||
break;
|
||
case 'notes':
|
||
this._keyUpNotes(keyCode);
|
||
break;
|
||
case 'syncSave':
|
||
this._keyUpSyncSave(keyCode);
|
||
break;
|
||
case 'syncSelect':
|
||
this._keyUpSyncSelect(keyCode);
|
||
break;
|
||
case 'localSaveSelect':
|
||
this._keyUpLocalSaveSelect(keyCode);
|
||
break;
|
||
case 'storageRemove':
|
||
this._keyUpStorageRemove(keyCode);
|
||
break;
|
||
case 'cursor':
|
||
this._keyUpCursor(keyCode);
|
||
break;
|
||
case 'replay':
|
||
this._keyUpReplay(keyCode);
|
||
break;
|
||
case 'gameInfo':
|
||
this._keyUpGameInfo(keyCode);
|
||
break;
|
||
case 'shuangta':
|
||
this._keyUpShuangta(keyCode);
|
||
break;
|
||
case 'rm':
|
||
this._keyUpRM(keyCode);
|
||
break;
|
||
case 'centerFly':
|
||
this._keyUpCenterFly(keyCode);
|
||
break;
|
||
}
|
||
return true;
|
||
}
|
||
core.actions._sys_ondown_lockControl = function (x, y, px, py) {
|
||
if (core.status.played && !core.status.lockControl) return false;
|
||
|
||
switch (core.status.event.id) {
|
||
case 'centerFly':
|
||
this._clickCenterFly(x, y, px, py);
|
||
break;
|
||
case 'book':
|
||
this._clickBook(x, y, px, py);
|
||
break;
|
||
case 'book-detail':
|
||
this._clickBookDetail(x, y, px, py);
|
||
break;
|
||
case 'fly':
|
||
this._clickFly(x, y, px, py);
|
||
break;
|
||
case 'viewMaps':
|
||
this._clickViewMaps(x, y, px, py);
|
||
break;
|
||
case 'switchs':
|
||
this._clickSwitchs(x, y, px, py);
|
||
break;
|
||
case 'switchs-sounds':
|
||
this._clickSwitchs_sounds(x, y, px, py);
|
||
break;
|
||
case 'switchs-display':
|
||
this._clickSwitchs_display(x, y, px, py);
|
||
break;
|
||
case 'switchs-action':
|
||
this._clickSwitchs_action(x, y, px, py);
|
||
break;
|
||
case 'settings':
|
||
this._clickSettings(x, y, px, py);
|
||
break;
|
||
case 'selectShop':
|
||
this._clickQuickShop(x, y, px, py);
|
||
break;
|
||
case 'equipbox':
|
||
this._clickEquipbox(x, y, px, py);
|
||
break;
|
||
case 'toolbox':
|
||
this._clickToolbox(x, y, px, py);
|
||
break;
|
||
case 'save':
|
||
case 'load':
|
||
case 'replayLoad':
|
||
case 'replayRemain':
|
||
case 'replaySince':
|
||
this._clickSL(x, y, px, py);
|
||
break;
|
||
case 'confirmBox':
|
||
this._clickConfirmBox(x, y, px, py);
|
||
break;
|
||
case 'keyBoard':
|
||
this._clickKeyBoard(x, y, px, py);
|
||
break;
|
||
case 'action':
|
||
this._clickAction(x, y, px, py);
|
||
break;
|
||
case 'text':
|
||
core.drawText();
|
||
break;
|
||
case 'notes':
|
||
this._clickNotes(x, y, px, py);
|
||
break;
|
||
case 'syncSave':
|
||
this._clickSyncSave(x, y, px, py);
|
||
break;
|
||
case 'syncSelect':
|
||
this._clickSyncSelect(x, y, px, py);
|
||
break;
|
||
case 'localSaveSelect':
|
||
this._clickLocalSaveSelect(x, y, px, py);
|
||
break;
|
||
case 'storageRemove':
|
||
this._clickStorageRemove(x, y, px, py);
|
||
break;
|
||
case 'cursor':
|
||
this._clickCursor(x, y, px, py);
|
||
break;
|
||
case 'replay':
|
||
this._clickReplay(x, y, px, py);
|
||
break;
|
||
case 'gameInfo':
|
||
this._clickGameInfo(x, y, px, py);
|
||
break;
|
||
case 'shuangta':
|
||
this._clickShuangta(x, y, px, py);
|
||
break;
|
||
case 'rm':
|
||
this._clickRM(x, y, px, py);
|
||
break;
|
||
case 'about':
|
||
case 'help':
|
||
core.ui.closePanel();
|
||
break;
|
||
}
|
||
|
||
// --- 长按判定
|
||
if (core.timeout.onDownTimeout == null) {
|
||
core.timeout.onDownTimeout = setTimeout(function () {
|
||
if (core.interval.onDownInterval == null) {
|
||
core.interval.onDownInterval = setInterval(function () {
|
||
if (!core.actions.longClick(x, y, px, py)) {
|
||
clearInterval(core.interval.onDownInterval);
|
||
core.interval.onDownInterval = null;
|
||
}
|
||
}, 40)
|
||
}
|
||
}, 500);
|
||
}
|
||
return true;
|
||
}
|
||
core.actions._sys_onmove_choices = function (x, y, px, py) {
|
||
if (!core.status.lockControl) return false;
|
||
|
||
switch (core.status.event.id) {
|
||
case 'action':
|
||
if (core.status.event.data.type == 'choices') {
|
||
this._onMoveChoices(x, y);
|
||
return true;
|
||
}
|
||
if (core.status.event.data.type == 'confirm') {
|
||
this._onMoveConfirmBox(x, y, px, py);
|
||
return true;
|
||
}
|
||
break;
|
||
case 'selectShop':
|
||
case 'switchs':
|
||
case 'switchs-sounds':
|
||
case 'switchs-display':
|
||
case 'switchs-action':
|
||
case 'notes':
|
||
case 'settings':
|
||
case 'syncSave':
|
||
case 'syncSelect':
|
||
case 'localSaveSelect':
|
||
case 'storageRemove':
|
||
case 'replay':
|
||
case 'gameInfo':
|
||
case 'shuangta':
|
||
case 'rm':
|
||
this._onMoveChoices(x, y);
|
||
return true;
|
||
case 'confirmBox':
|
||
this._onMoveConfirmBox(x, y, px, py);
|
||
return true;
|
||
default:
|
||
break;
|
||
}
|
||
return false;
|
||
}
|
||
core.actions._keyUpShuangta = function (keycode) {
|
||
if (keycode == 27 || keycode == 88) {
|
||
core.status.event.selection = 8;
|
||
core.playSound('取消');
|
||
return core.ui._drawSettings();
|
||
}
|
||
this._selectChoices(core.status.event.ui.choices.length, keycode, this._clickShuangta);
|
||
}
|
||
core.actions._clickShuangta = function (x, y) {
|
||
if (this._out(x)) return;
|
||
var choices = core.status.event.ui.choices;
|
||
|
||
var topIndex = this._getChoicesTopIndex(choices.length);
|
||
|
||
if (y >= topIndex && y < topIndex + choices.length) {
|
||
var selection = y - topIndex;
|
||
core.status.event.selection = selection;
|
||
switch (selection) {
|
||
case 0:
|
||
core.setFlag("itemDetail", !core.getFlag("itemDetail"));
|
||
core.ui._drawShuangta();
|
||
break;
|
||
case 1:
|
||
core.setFlag("__autoGetItem__", !core.getFlag("__autoGetItem__"));
|
||
core.ui._drawShuangta();
|
||
break;
|
||
case 2:
|
||
core.setFlag("__autoBattle__", !core.getFlag("__autoBattle__"));
|
||
core.ui._drawShuangta();
|
||
break;
|
||
case 3:
|
||
core.status.event.selection = 8;
|
||
core.playSound('取消');
|
||
core.ui._drawSettings();
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
core.actions._keyUpRM = function (keycode) {
|
||
if (keycode == 27 || keycode == 88) {
|
||
core.status.event.selection = 9;
|
||
core.playSound('取消');
|
||
return core.ui._drawSettings();
|
||
}
|
||
this._selectChoices(core.status.event.ui.choices.length, keycode, this._clickRM);
|
||
}
|
||
core.actions._clickRM = function (x, y) {
|
||
if (this._out(x)) return;
|
||
var choices = core.status.event.ui.choices;
|
||
|
||
var topIndex = this._getChoicesTopIndex(choices.length);
|
||
|
||
if (y >= topIndex && y < topIndex + choices.length) {
|
||
var selection = y - topIndex;
|
||
core.status.event.selection = selection;
|
||
switch (selection) {
|
||
case 0:
|
||
core.setFlag("isRmFly", !core.getFlag("isRmFly"));
|
||
core.ui._drawRM();
|
||
break;
|
||
case 1:
|
||
core.setFlag("isDamageRight", !core.getFlag("isDamageRight"));
|
||
core.updateStatusBar();
|
||
core.ui._drawRM();
|
||
break;
|
||
case 2:
|
||
core.setFlag("isZeroWhite", !core.getFlag("isZeroWhite"));
|
||
core.updateStatusBar();
|
||
core.ui._drawRM();
|
||
break;
|
||
case 3:
|
||
core.setFlag("isNoTip", !core.getFlag("isNoTip"));
|
||
core.ui._drawRM();
|
||
break;
|
||
case 4:
|
||
core.setFlag("isCommon", !core.getFlag("isCommon"));
|
||
core.ui._drawRM();
|
||
break;
|
||
case 5:
|
||
core.status.event.selection = 9;
|
||
core.playSound('取消');
|
||
core.ui._drawSettings();
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
core.actions.registerAction('keyDown', '_sys_keyDown_lockControl', core.actions._sys_keyDown_lockControl, 50);
|
||
core.actions.registerAction('keyUp', '_sys_keyUp_lockControl', core.actions._sys_keyUp_lockControl, 50);
|
||
core.actions.registerAction('ondown', '_sys_ondown_lockControl', core.actions._sys_ondown_lockControl, 30);
|
||
core.actions.registerAction('onmove', '_sys_onmove_choices', core.actions._sys_onmove_choices, 30);
|
||
main.dom.statusCanvas.onmousedown = main.dom.statusCanvas.onclick;
|
||
main.dom.statusCanvas.onclick = null;
|
||
main.dom.statusCanvas.onmousemove = function (e) {
|
||
try {
|
||
e.stopPropagation();
|
||
if (e == null) return;
|
||
var t = main.core.actions._getClickLoc(e.clientX, e.clientY);
|
||
px = Math.floor(t.x / core.domStyle.scale);
|
||
py = Math.floor(t.y / core.domStyle.scale);
|
||
if (core.status.floorId == "nandu") {
|
||
var h = -1;
|
||
if (py >= 46 && py <= 430) h = Math.floor((py - 46) / 77) + 1;
|
||
if (h > 0 && h != core.getFlag("hard") && px < 160) {
|
||
core.actions._clickAction(0, Math.floor(py / 16), 1, py);
|
||
}
|
||
}
|
||
} catch (ee) { console.error(ee) }
|
||
}
|
||
core.actions._sys_onmove = function (x, y, px, py) {
|
||
if (core.status.floorId == "nandu") {
|
||
var h = -1;
|
||
if (py >= 46 && py <= 430) h = Math.floor((py - 46) / 77) + 1;
|
||
if (h > 0 && h != core.getFlag("hard") && px < 160) {
|
||
core.actions._clickAction(0, Math.floor(py / 16), 1, py);
|
||
}
|
||
}
|
||
if (core.status.lockControl) return false;
|
||
|
||
if (core.status.preview.dragging) {
|
||
core.setViewport(core.bigmap.offsetX - px + core.status.preview.px, core.bigmap.offsetY - py + core.status.preview.py);
|
||
core.status.preview.px = px;
|
||
core.status.preview.py = py;
|
||
return true;
|
||
}
|
||
if (core.status.preview.prepareDragging) {
|
||
if (Math.abs(px - core.status.preview.px) <= 20 && Math.abs(py - core.status.preview.py) <= 20)
|
||
return true;
|
||
else core.status.preview.prepareDragging = false;
|
||
}
|
||
|
||
clearTimeout(core.timeout.onDownTimeout);
|
||
core.timeout.onDownTimeout = null;
|
||
|
||
if ((core.status.stepPostfix || []).length > 0) {
|
||
var pos = { 'x': parseInt((px + core.bigmap.offsetX) / 32), 'y': parseInt((py + core.bigmap.offsetY) / 32) };
|
||
var pos0 = core.status.stepPostfix[core.status.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 ii = 0; ii < 4; ii++) {
|
||
if (directionDistance[ii] > max) {
|
||
index = ii;
|
||
max = directionDistance[ii];
|
||
}
|
||
}
|
||
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;
|
||
core.status.stepPostfix.push(pos);
|
||
core.fillRect('ui', pos.x * 32 + 12 - core.bigmap.offsetX, pos.y * 32 + 12 - core.bigmap.offsetY, 8, 8, '#bfbfbf');
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
core.actions.registerAction('onmove', '_sys_onmove', core.actions._sys_onmove, 0);
|
||
|
||
|
||
|
||
|
||
ui.prototype._drawBook_drawOne = function (floorId, index, enemy, pageinfo, selected) {
|
||
var top = pageinfo.per_height * index + pageinfo.padding_top; // 最上面margin默认是12px
|
||
enemy.floorId = floorId;
|
||
// 横向规划:
|
||
// 22 + 42 = 64 是头像框
|
||
this._drawBook_drawBox(index, enemy, top, pageinfo);
|
||
var left = 64,
|
||
total_width = core._PX_ - left;
|
||
var name_width = total_width * 10 / 35;
|
||
this._drawBook_drawName(index, enemy, top, left, name_width);
|
||
this._drawBook_drawContent(index, enemy, top, left + name_width);
|
||
if (selected)
|
||
core.drawUIEventSelector(1, 'winskin.png', 10, top + 1, core._PX_ - 10 * 2, pageinfo.per_height, 139); ////绘制光标
|
||
//core.strokeRoundRect('ui', 10, top + 1, core._PX_ - 10 * 2, pageinfo.per_height, 10, core.status.globalAttribute.selectColor);取消原本的黄色框框
|
||
}
|
||
|
||
ui.prototype._drawBook_drawBox = function (index, enemy, top, pageinfo) {
|
||
// 横向:22+42;纵向:10 + 42 + 10(正好居中);内部图像 32x32
|
||
var border_top = top + (pageinfo.per_height - 42) / 2,
|
||
border_left = 22;
|
||
var img_top = border_top + 5,
|
||
img_left = border_left + 5;
|
||
//core.strokeRect('ui', 22, border_top, 42, 42, '#DDDDDD', 2); //删除怪物边框
|
||
var blockInfo = core.getBlockInfo(enemy.id);
|
||
core.drawIcon('ui', enemy.id, 22 + 5, border_top + 5, 32, 32) ///取消用动画的绘制,改用图标绘制
|
||
|
||
}
|
||
|
||
ui.prototype._drawBook_drawName = function (index, enemy, top, left, width) {
|
||
// 绘制第零列(名称和特殊属性)
|
||
// 如果需要添加自己的比如怪物的称号等,也可以在这里绘制
|
||
core.setTextAlign('ui', 'center');
|
||
if (enemy.specialText.length == 0) {
|
||
core.fillText('ui', enemy.name, left + width / 2,
|
||
top + 35, '#ffffff', this._buildFont(enemy.name.length >= 5 ? 18 : 20, false), width); /////修改怪物名字的颜色,取消加粗
|
||
} else {
|
||
core.fillText('ui', enemy.name, left + width / 2,
|
||
top + 28, '#ffffff', this._buildFont(enemy.name.length >= 5 ? 18 : 20, false), width); /////修改怪物名字颜色,取消加粗
|
||
switch (enemy.specialText.length) {
|
||
case 1:
|
||
core.fillText('ui', ((!core.getFlag('isCommon') || (2 != enemy.specialText[0].length)) ?
|
||
enemy.specialText[0] : enemy.specialText[0][0] + ' ' + enemy.specialText[0][1]),
|
||
left + width / 2, ////单属性两个字中间空一格
|
||
top + 50, core.arrayToRGBA((enemy.specialColor || [])[0] || '#FF6A6A'),
|
||
this._buildFont(20, false), width); ////调大怪物字号,取消加粗
|
||
break;
|
||
case 2:
|
||
// Step 1: 计算字体
|
||
var text = enemy.specialText[0] + "" + enemy.specialText[1]; ///减少空格
|
||
core.setFontForMaxWidth('ui', text, width, this._buildFont(20, false)); ////调大怪物属性的字号,取消加粗
|
||
// Step 2: 计算总宽度
|
||
var totalWidth = core.calWidth('ui', text);
|
||
var leftWidth = core.calWidth('ui', enemy.specialText[0]);
|
||
var rightWidth = core.calWidth('ui', enemy.specialText[1]);
|
||
// Step 3: 绘制
|
||
core.fillText('ui', enemy.specialText[0], left + (width + leftWidth - totalWidth) / 2,
|
||
top + 50, core.arrayToRGBA((enemy.specialColor || [])[0] || '#FF6A6A'));
|
||
core.fillText('ui', enemy.specialText[1], left + (width + totalWidth - rightWidth) / 2,
|
||
top + 50, core.arrayToRGBA((enemy.specialColor || [])[1] || '#FF6A6A'));
|
||
break;
|
||
default:
|
||
core.fillText('ui', '多属性...', left + width / 2,
|
||
top + 50, '#FF6A6A', this._buildFont(15, true), width);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
ui.prototype._drawBook_drawRow1 = function (index, enemy, top, left, width, position) {
|
||
// 绘制第一行
|
||
core.setTextAlign('ui', 'left');
|
||
var b13 = this._buildFont(13, true),
|
||
f13 = this._buildFont(13, false);
|
||
var col1 = left,
|
||
col2 = left + width * 9 / 25,
|
||
col3 = left + width * 17 / 25;
|
||
var colour = '#80ffff'; ////单数行颜色
|
||
if (index % 2 === 0)
|
||
colour = '#80ff80'; ////双数行颜色
|
||
core.fillText('ui', core.getStatusLabel('hp'), col1, position, colour, f13);
|
||
core.fillText('ui', core.formatBigNumber(enemy.hp || 0), col1 + 30, position, null, b13);
|
||
core.fillText('ui', core.getStatusLabel('atk'), col2, position, colour, f13);
|
||
core.fillText('ui', core.formatBigNumber(enemy.atk || 0), col2 + 30, position, null, b13);
|
||
core.fillText('ui', core.getStatusLabel('def'), col3, position, colour, f13);
|
||
core.fillText('ui', core.formatBigNumber(enemy.def || 0), col3 + 30, position, null, b13);
|
||
}
|
||
|
||
ui.prototype._drawBook_drawRow2 = function (index, enemy, top, left, width, position) {
|
||
// 绘制第二行
|
||
core.setTextAlign('ui', 'left');
|
||
var b13 = this._buildFont(13, true),
|
||
f13 = this._buildFont(13, false);
|
||
var col1 = left,
|
||
col2 = left + width * 9 / 25,
|
||
col3 = left + width * 17 / 25;
|
||
var colour = '#80ffff'; ////单数行颜色
|
||
if (index % 2 === 0)
|
||
colour = '#80ff80'; ////双数行颜色
|
||
// 获得第二行绘制的内容
|
||
var second_line = [];
|
||
if (core.flags.statusBarItems.indexOf('enableMoney') >= 0) second_line.push([core.getStatusLabel('money'), core.formatBigNumber(enemy.money || 0)]);
|
||
if (core.flags.enableAddPoint) second_line.push([core.getStatusLabel('point'), core.formatBigNumber(enemy.point || 0)]);
|
||
if (core.flags.statusBarItems.indexOf('enableExp') >= 0) second_line.push([core.getStatusLabel('exp'), core.formatBigNumber(enemy.exp || 0)]);
|
||
|
||
var damage_offset = col1 + (core._PX_ - col1) / 2 - 12;
|
||
// 第一列
|
||
if (second_line.length > 0) {
|
||
var one = second_line.shift();
|
||
core.fillText('ui', one[0], col1, position, colour, f13);
|
||
core.fillText('ui', one[1], col1 + 30, position, colour, b13);
|
||
damage_offset = col2 + (core._PX_ - col2) / 2 - 12;
|
||
}
|
||
// 第二列
|
||
if (second_line.length > 0) {
|
||
var one = second_line.shift();
|
||
core.fillText('ui', one[0], col2, position, colour, f13);
|
||
core.fillText('ui', one[1], col2 + 30, position, colour, b13);
|
||
damage_offset = col3 + (core._PX_ - col3) / 2 - 12;
|
||
}
|
||
// 忽略第三列,直接绘制伤害
|
||
core.fillText('ui', '伤害', col3, position, colour, f13); ////增加绘制伤害两字
|
||
this._drawBook_drawDamage(index, enemy, damage_offset, position);
|
||
|
||
}
|
||
|
||
ui.prototype._drawBook_drawRow3 = function (index, enemy, top, left, width, position) {
|
||
// 绘制第三行
|
||
core.setTextAlign('ui', 'left');
|
||
var b13 = this._buildFont(13, true),
|
||
f13 = this._buildFont(13, false);
|
||
var col1 = left,
|
||
col2 = left + width * 9 / 25,
|
||
col3 = left + width * 17 / 25;
|
||
var colour = '#80ffff'; ////单数行颜色
|
||
if (index % 2 === 0)
|
||
colour = '#80ff80'; ////双数行颜色
|
||
core.fillText('ui', '临界', col1, position, colour, f13);
|
||
core.fillText('ui', core.formatBigNumber(enemy.critical || 0), col1 + 30, position, colour, b13);
|
||
core.fillText('ui', '减伤', col2, position, colour, f13);
|
||
core.fillText('ui', core.formatBigNumber(enemy.criticalDamage || 0), col2 + 30, position, colour, b13);
|
||
core.fillText('ui', '加防', col3, position, colour, f13);
|
||
core.fillText('ui', core.formatBigNumber(enemy.defDamage || 0), col3 + 30, position, colour, b13);
|
||
}
|
||
|
||
ui.prototype._drawBook_drawDamage = function (index, enemy, offset, position) { //////修改了颜色
|
||
offset -= 5; //往左移5像素
|
||
//core.setTextAlign('ui', 'center');取消居中对齐
|
||
var damage = enemy.damage,
|
||
color = '#e6de0d';
|
||
if (damage == null) {
|
||
damage = '????'; ////////无法战斗怪物手册中改为????显示
|
||
color = '#ff8080';
|
||
} else {
|
||
if (damage >= core.status.hero.hp) color = '#ff8080';
|
||
else if (damage >= core.status.hero.hp * 2 / 3) color = '#ffc080';
|
||
else if (damage <= 0) color = '#ffffff';
|
||
damage = core.formatBigNumber(damage);
|
||
if (core.enemys.hasSpecial(enemy, 19)) damage += "+";
|
||
if (core.enemys.hasSpecial(enemy, 21)) damage += "-";
|
||
if (core.enemys.hasSpecial(enemy, 11)) damage += "^";
|
||
}
|
||
if (enemy.notBomb) damage += "[b]";
|
||
core.fillText('ui', damage, offset, position, color, this._buildFont(13, true));
|
||
}
|
||
|
||
////// 绘制怪物属性的详细信息 //////
|
||
ui.prototype._drawBookDetail = function (index) {
|
||
var info = this._drawBookDetail_getInfo(index),
|
||
enemy = info[0];
|
||
if (!enemy) return;
|
||
var content = info[1].join("\n");
|
||
core.status.event.id = 'book-detail';
|
||
core.animateFrame.tip = null;
|
||
core.clearMap('data');
|
||
|
||
var left = 10,
|
||
width = core._PX_ - 2 * left,
|
||
right = left + width;
|
||
var content_left = left + 25,
|
||
validWidth = right - content_left - 13;
|
||
var height = Math.max(this.getTextContentHeight(content, { fontSize: 16, lineHeight: 24, maxWidth: validWidth }) + 58, 80),
|
||
top = (core._PY_ - height) / 2,
|
||
bottom = top + height;
|
||
|
||
core.drawWindowSkin('winskin.png', 'data', left, top, width, height); ////用winskin绘制一个对话框
|
||
/// core.setAlpha('data', 0.9);///注销原本的黑底边框
|
||
///core.fillRect('data', left, top, width, height, '#000000');
|
||
// core.setAlpha('data', 1);
|
||
// core.strokeRect('data', left - 1, top - 1, width + 1, height + 1,
|
||
// core.arrayToRGBA(core.status.globalAttribute.borderColor), 2);
|
||
core.playSound('确定');
|
||
this._drawBookDetail_drawContent(enemy, content, { top: top, content_left: content_left, bottom: bottom, validWidth: validWidth });
|
||
}
|
||
|
||
|
||
////// 结束一切事件和绘制,关闭UI窗口,返回游戏进程 //////
|
||
ui.prototype.closePanel = function () {
|
||
|
||
core.clearMap('bookBg'); ////清空手册Bg
|
||
core.clearMap('itemBg'); ////清空道具栏Bg
|
||
core.clearMap('flyText'); ////清空fly对话框
|
||
core.clearUIEventSelector(1); ////清除绘制的光标
|
||
core.clearUIEventSelector(2);
|
||
if (core.status.hero && core.status.hero.flags) {
|
||
// 清除全部临时变量
|
||
Object.keys(core.status.hero.flags).forEach(function (name) {
|
||
if (name.startsWith("@temp@") || /^arg\d+$/.test(name)) {
|
||
delete core.status.hero.flags[name];
|
||
}
|
||
});
|
||
}
|
||
this.clearUI();
|
||
core.maps.generateGroundPattern();
|
||
core.updateStatusBar(true);
|
||
core.unlockControl();
|
||
core.status.event.data = null;
|
||
core.status.event.id = null;
|
||
core.status.event.selection = null;
|
||
core.status.event.ui = null;
|
||
core.status.event.interval = null;
|
||
// 清除onDownInterval
|
||
clearInterval(core.interval.onDownInterval);
|
||
core.interval.onDownInterval = 'tmp';
|
||
}
|
||
|
||
ui.prototype._drawToolbox_drawBackground = function () {
|
||
// 绘制
|
||
core.clearMap('ui');
|
||
/// core.setAlpha('ui', 0.85);
|
||
/// core.fillRect('ui', 0, 0, core._PX_, core._PY_, '#000000');
|
||
core.createCanvas('itemBg', 0, 0, 480, 480, 138); ///创建一个动态画布用于绘制道具栏bg
|
||
core.drawWindowSkin('winskin.png', 'itemBg', 0, 0, core._PX_, core._PY_ - 306); ///道具栏背景用winskin绘制
|
||
core.drawWindowSkin('winskin.png', 'itemBg', 0, core._PY_ - 306 - 20, core._PX_, core._PY_ - 306);
|
||
core.drawWindowSkin('winskin.png', 'itemBg', 0, core._PY_ - 146 - 30, core._PX_, core._PY_ - 306);
|
||
}
|
||
|
||
////// 绘制道具栏 //////
|
||
ui.prototype._drawToolbox = function (index) {
|
||
var info = this._drawToolbox_getInfo(index);
|
||
this._drawToolbox_drawBackground();
|
||
|
||
// 绘制线
|
||
core.setAlpha('ui', 1);
|
||
core.setStrokeStyle('ui', '#DDDDDD');
|
||
core.canvas.ui.lineWidth = 2;
|
||
core.canvas.ui.strokeWidth = 2;
|
||
core.setTextAlign('ui', 'right');
|
||
var line1 = core._PY_ - 306;
|
||
// this._drawToolbox_drawLine(line1, "消耗道具");
|
||
var line2 = core._PY_ - 146;
|
||
// this._drawToolbox_drawLine(line2, "永久道具");
|
||
|
||
this._drawToolbox_drawDescription(info, line1);
|
||
|
||
this._drawToolbox_drawContent(info, line1, info.tools, info.toolsPage, true);
|
||
this.drawPagination(info.toolsPage, info.toolsTotalPage, core._HEIGHT_ - 6);
|
||
this._drawToolbox_drawContent(info, line2, info.constants, info.constantsPage);
|
||
this.drawPagination(info.constantsPage, info.constantsTotalPage);
|
||
|
||
core.setTextAlign('ui', 'center');
|
||
//core.fillText('ui', '[装备栏]', core._PX_ - 46, 25, '#DDDDDD', this._buildFont(15, true));
|
||
core.fillText('ui', '返回游戏', core._PX_ - 46, core._PY_ - 13);
|
||
}
|
||
|
||
ui.prototype._drawToolbox_drawDescription = function (info, max_height) {
|
||
core.setTextAlign('ui', 'left');
|
||
if (!info.selectId) return;
|
||
var item = core.material.items[info.selectId];
|
||
var name = item.name || "未知道具";
|
||
try { name = core.replaceText(name); } catch (e) {}
|
||
core.fillText('ui', name, 10 + 10, 32 + 10, "#ffffff", this._buildFont(20, true));
|
||
core.drawUIEventSelector(2, 'winskin.png', 15, 32 - 10, 25 * name.length || 0, 30, 139);
|
||
var text = item.text || "该道具暂无描述。";
|
||
try { text = core.replaceText(text); } catch (e) {}
|
||
|
||
var height = null;
|
||
for (var fontSize = 20; fontSize >= 9; fontSize -= 2) {
|
||
var config = { left: 10 + 10, top: 46 + 20, fontSize: fontSize, maxWidth: core._PX_ - 15, bold: true, color: "white" };
|
||
height = 42 + core.getTextContentHeight(text, config);
|
||
if (height < max_height || fontSize == 9) {
|
||
core.drawTextContent('ui', text, config);
|
||
break;
|
||
}
|
||
}
|
||
if (height < max_height - 33) {
|
||
core.fillText('ui', '<继续点击该道具即可进行使用>', 10 + 10, max_height - 15 - 10, '#CCCCCC', this._buildFont(14, false));
|
||
}
|
||
}
|
||
|
||
////// 点击工具栏时的打开操作 //////
|
||
events.prototype.openToolbox = function (fromUserAction) {
|
||
if (core.isReplaying()) return;
|
||
if (!this._checkStatus('toolbox', fromUserAction)) return;
|
||
core.playSound('打开界面');
|
||
core.updateStatusBar(); ///更新状态栏以绘制工具栏时的状态栏背景
|
||
core.ui._drawToolbox();
|
||
}
|
||
|
||
ui.prototype._drawToolbox_drawContent = function (info, line, items, page, drawCount) {
|
||
var n = core._HALF_WIDTH_;
|
||
core.setTextAlign('ui', 'right');
|
||
for (var i = 0; i < core._WIDTH_ - 1; i++) {
|
||
var item = items[(core._WIDTH_ - 1) * (page - 1) + i];
|
||
if (!item) continue;
|
||
var yoffset = line + 54 * Math.floor(i / n) + 19;
|
||
var icon = core.material.icons.items[item],
|
||
image = core.material.images.items;
|
||
core.drawImage('ui', image, 0, 32 * icon, 32, 32, 64 * (i % n) + 21, yoffset, 32, 32);
|
||
if (drawCount)
|
||
core.fillText('ui', core.itemCount(item), 64 * (i % n) + 56, yoffset + 33, '#FFFFFF', this._buildFont(14, true));
|
||
if (info.selectId == item)
|
||
core.drawUIEventSelector(1, 'winskin.png', 64 * (i % n) + 17, yoffset - 4, 40, 40, 139); ////绘制光标
|
||
//core.strokeRoundRect('ui', 64 * (i % n) + 17, yoffset - 4, 40, 40, 6, core.status.globalAttribute.selectColor);删除原本绘制的黄色边框
|
||
}
|
||
}
|
||
|
||
////// 战斗 //////
|
||
events.prototype.battle = function (id, x, y, force, callback) {
|
||
core.saveAndStopAutomaticRoute();
|
||
id = id || core.getBlockId(x, y);
|
||
if (!id) return core.clearContinueAutomaticRoute(callback);
|
||
// 非强制战斗
|
||
if (!core.enemys.canBattle(id, x, y) && !force && !core.status.event.id) {
|
||
core.stopSound();
|
||
core.playSound('操作失败');
|
||
//core.drawTip("你打不过此怪物!", id);
|
||
core.drawAnimate('jingu', x, y);
|
||
core.drawText('你的能力不足以战胜这个对手。\n\n\n');
|
||
return core.clearContinueAutomaticRoute(callback);
|
||
}
|
||
// 自动存档
|
||
if (!core.status.event.id) core.autosave(true);
|
||
// 战前事件
|
||
if (!this.beforeBattle(id, x, y))
|
||
return core.clearContinueAutomaticRoute(callback);
|
||
// 战后事件
|
||
this.afterBattle(id, x, y);
|
||
if (callback) callback();
|
||
}
|
||
|
||
////// “即捡即用类”道具的使用效果 //////
|
||
items.prototype.getItemEffect = function (itemId, itemNum) {
|
||
var itemCls = core.material.items[itemId].cls;
|
||
// 消耗品
|
||
if (itemCls === 'items' || itemCls === "equips") {
|
||
var curr_hp = core.status.hero.hp;
|
||
var itemEffect = core.material.items[itemId].itemEffect;
|
||
if (itemEffect) {
|
||
try {
|
||
for (var i = 0; i < itemNum; ++i)
|
||
eval(itemEffect);
|
||
} catch (e) {
|
||
console.error(e);
|
||
}
|
||
}
|
||
core.status.hero.statistics.hp += core.status.hero.hp - curr_hp;
|
||
|
||
var useItemEvent = core.material.items[itemId].useItemEvent;
|
||
if (useItemEvent) {
|
||
try {
|
||
core.insertAction(useItemEvent);
|
||
} catch (e) {
|
||
console.error(e);
|
||
}
|
||
}
|
||
core.updateStatusBar(false, true);
|
||
} else {
|
||
core.addItem(itemId, itemNum);
|
||
}
|
||
}
|
||
|
||
/////屏蔽装备栏
|
||
////// 点击装备栏时的打开操作 //////
|
||
events.prototype.openEquipbox = function (fromUserAction) {
|
||
if (core.isReplaying() || true) return; ////直接返回
|
||
if (!this._checkStatus('equipbox', fromUserAction)) return;
|
||
core.playSound('打开界面');
|
||
core.ui._drawEquipbox();
|
||
}
|
||
////// 工具栏界面时的点击操作 //////
|
||
actions.prototype._clickToolbox = function (x, y) {
|
||
var tools = core.getToolboxItems('tools'),
|
||
constants = core.getToolboxItems('constants');
|
||
|
||
// 装备栏
|
||
// if (x >= this.LAST - 2 && y == 0) {
|
||
// core.ui.closePanel();
|
||
// if (core.isReplaying())
|
||
// core.control._replay_equipbox();
|
||
// else
|
||
// core.openEquipbox();
|
||
// return;
|
||
// }
|
||
if (x >= this.LAST - 2 && y === core._HEIGHT_ - 1) {
|
||
core.playSound('取消');
|
||
core.ui.closePanel();
|
||
var last = core.status.route[core.status.route.length - 1] || '';
|
||
if (last.startsWith('equip:') || last.startsWith('unEquip:')) {
|
||
core.status.route.push('no');
|
||
}
|
||
core.checkAutoEvents();
|
||
return;
|
||
}
|
||
|
||
var toolsPage = core.status.event.data.toolsPage;
|
||
var constantsPage = core.status.event.data.constantsPage;
|
||
// 上一页
|
||
if (x == this._HX_ - 2 || x == this._HX_ - 3) {
|
||
if (y === core._HEIGHT_ - 1 - 5 && toolsPage > 1) {
|
||
core.status.event.data.toolsPage--;
|
||
core.playSound('光标移动');
|
||
core.ui._drawToolbox(core.status.event.selection);
|
||
}
|
||
if (y === core._HEIGHT_ - 1 && constantsPage > 1) {
|
||
core.status.event.data.constantsPage--;
|
||
core.playSound('光标移动');
|
||
core.ui._drawToolbox(core.status.event.selection);
|
||
}
|
||
}
|
||
// 下一页
|
||
if (x == this._HX_ + 2 || x == this._HX_ + 3) {
|
||
if (y === core._HEIGHT_ - 1 - 5 && toolsPage < Math.ceil(tools.length / this.LAST)) {
|
||
core.status.event.data.toolsPage++;
|
||
core.playSound('光标移动');
|
||
core.ui._drawToolbox(core.status.event.selection);
|
||
}
|
||
if (y === core._HEIGHT_ - 1 && constantsPage < Math.ceil(constants.length / this.LAST)) {
|
||
core.status.event.data.constantsPage++;
|
||
core.playSound('光标移动');
|
||
core.ui._drawToolbox(core.status.event.selection);
|
||
}
|
||
}
|
||
|
||
var index = parseInt(x / 2);
|
||
if (y === core._HEIGHT_ - 1 - 8) index += 0;
|
||
else if (y === core._HEIGHT_ - 1 - 6) index += this._HX_;
|
||
else if (y === core._HEIGHT_ - 1 - 3) index += this.LAST;
|
||
else if (y === core._HEIGHT_ - 1 - 1) index += this.LAST + this._HX_;
|
||
else index = -1;
|
||
if (index >= 0)
|
||
this._clickToolboxIndex(index);
|
||
}
|
||
////// 工具栏界面时,放开某个键的操作 //////
|
||
actions.prototype._keyUpToolbox = function (keycode) {
|
||
// if (keycode == 81) {
|
||
// core.playSound('确定');
|
||
// core.ui.closePanel();
|
||
// if (core.isReplaying())
|
||
// core.control._replay_equipbox();
|
||
// else
|
||
// core.openEquipbox();
|
||
// return;
|
||
//}
|
||
if (keycode == 84 || keycode == 27 || keycode == 88) {
|
||
core.playSound('取消');
|
||
core.ui.closePanel();
|
||
var last = core.status.route[core.status.route.length - 1] || '';
|
||
if (last.startsWith('equip:') || last.startsWith('unEquip:')) {
|
||
core.status.route.push('no');
|
||
}
|
||
core.checkAutoEvents();
|
||
return;
|
||
}
|
||
if (core.status.event.data == null) return;
|
||
|
||
if (keycode == 13 || keycode == 32 || keycode == 67) {
|
||
this._clickToolboxIndex(core.status.event.selection);
|
||
return;
|
||
}
|
||
}
|
||
|
||
|
||
},
|
||
"drawLight": function () {
|
||
|
||
// 绘制灯光/漆黑层效果。调用方式 core.plugin.drawLight(...)
|
||
// 【参数说明】
|
||
// name:必填,要绘制到的画布名;可以是一个系统画布,或者是个自定义画布;如果不存在则创建
|
||
// color:可选,只能是一个0~1之间的数,为不透明度的值。不填则默认为0.9。
|
||
// lights:可选,一个数组,定义了每个独立的灯光。
|
||
// 其中每一项是三元组 [x,y,r] x和y分别为该灯光的横纵坐标,r为该灯光的半径。
|
||
// lightDec:可选,0到1之间,光从多少百分比才开始衰减(在此范围内保持全亮),不设置默认为0。
|
||
// 比如lightDec为0.5代表,每个灯光部分内圈50%的范围全亮,50%以后才开始快速衰减。
|
||
// 【调用样例】
|
||
// core.plugin.drawLight('curtain'); // 在curtain层绘制全图不透明度0.9,等价于更改画面色调为[0,0,0,0.9]。
|
||
// core.plugin.drawLight('ui', 0.95, [[25,11,46]]); // 在ui层绘制全图不透明度0.95,其中在(25,11)点存在一个半径为46的灯光效果。
|
||
// core.plugin.drawLight('test', 0.2, [[25,11,46,0.1]]); // 创建一个test图层,不透明度0.2,其中在(25,11)点存在一个半径为46的灯光效果,灯光中心不透明度0.1。
|
||
// core.plugin.drawLight('test2', 0.9, [[25,11,46],[105,121,88],[301,221,106]]); // 创建test2图层,且存在三个灯光效果,分别是中心(25,11)半径46,中心(105,121)半径88,中心(301,221)半径106。
|
||
// core.plugin.drawLight('xxx', 0.3, [[25,11,46],[105,121,88,0.2]], 0.4); // 存在两个灯光效果,它们在内圈40%范围内保持全亮,40%后才开始衰减。
|
||
this.drawLight = function (name, color, lights, lightDec) {
|
||
|
||
// 清空色调层;也可以修改成其它层比如animate/weather层,或者用自己创建的canvas
|
||
var ctx = core.getContextByName(name);
|
||
if (ctx == null) {
|
||
if (typeof name == 'string')
|
||
ctx = core.createCanvas(name, 0, 0, core._PX_ || core.__PIXELS__, core._PY_ || core.__PIXELS__, 98);
|
||
else return;
|
||
}
|
||
|
||
ctx.mozImageSmoothingEnabled = false;
|
||
ctx.webkitImageSmoothingEnabled = false;
|
||
ctx.msImageSmoothingEnabled = false;
|
||
ctx.imageSmoothingEnabled = false;
|
||
|
||
core.clearMap(name);
|
||
// 绘制色调层,默认不透明度
|
||
if (color == null) color = 0.9;
|
||
ctx.fillStyle = "rgba(0,0,0," + color + ")";
|
||
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
|
||
|
||
lightDec = core.clamp(lightDec, 0, 1);
|
||
|
||
// 绘制每个灯光效果
|
||
ctx.globalCompositeOperation = 'destination-out';
|
||
lights.forEach(function (light) {
|
||
// 坐标,半径,中心不透明度
|
||
var x = light[0],
|
||
y = light[1],
|
||
r = light[2];
|
||
// 计算衰减距离
|
||
var decDistance = parseInt(r * lightDec);
|
||
// 正方形区域的直径和左上角坐标
|
||
var grd = ctx.createRadialGradient(x, y, decDistance, x, y, r);
|
||
grd.addColorStop(0, "rgba(0,0,0,1)");
|
||
grd.addColorStop(1, "rgba(0,0,0,0)");
|
||
ctx.beginPath();
|
||
ctx.fillStyle = grd;
|
||
ctx.arc(x, y, r, 0, 2 * Math.PI);
|
||
ctx.fill();
|
||
});
|
||
ctx.globalCompositeOperation = 'source-over';
|
||
// 可以在任何地方(如afterXXX或自定义脚本事件)调用函数,方法为 core.plugin.xxx();
|
||
}
|
||
},
|
||
"shop": function () {
|
||
// 【全局商店】相关的功能
|
||
//
|
||
// 打开一个全局商店
|
||
// shopId:要打开的商店id;noRoute:是否不计入录像
|
||
this.openShop = function (shopId, noRoute) {
|
||
var shop = core.status.shops[shopId];
|
||
// Step 1: 检查能否打开此商店
|
||
if (!this.canOpenShop(shopId)) {
|
||
core.drawTip("该商店尚未开启");
|
||
return false;
|
||
}
|
||
|
||
// Step 2: (如有必要)记录打开商店的脚本事件
|
||
if (!noRoute) {
|
||
core.status.route.push("shop:" + shopId);
|
||
}
|
||
|
||
// Step 3: 检查道具商店 or 公共事件
|
||
if (shop.item) {
|
||
if (core.openItemShop) {
|
||
core.openItemShop(shopId);
|
||
} else {
|
||
core.playSound('操作失败');
|
||
core.insertAction("道具商店插件不存在!请检查是否存在该插件!");
|
||
}
|
||
return;
|
||
}
|
||
if (shop.commonEvent) {
|
||
core.insertCommonEvent(shop.commonEvent, shop.args);
|
||
return;
|
||
}
|
||
|
||
_shouldProcessKeyUp = true;
|
||
|
||
// Step 4: 执行标准公共商店
|
||
core.insertAction(this._convertShop(shop));
|
||
return true;
|
||
}
|
||
|
||
////// 将一个全局商店转变成可预览的公共事件 //////
|
||
this._convertShop = function (shop) {
|
||
return [
|
||
{ "type": "function", "function": "function() {core.addFlag('@temp@shop', 1);}" },
|
||
{
|
||
"type": "while",
|
||
"condition": "true",
|
||
"data": [
|
||
// 检测能否访问该商店
|
||
{
|
||
"type": "if",
|
||
"condition": "core.isShopVisited('" + shop.id + "')",
|
||
"true": [
|
||
// 可以访问,直接插入执行效果
|
||
{ "type": "function", "function": "function() { core.plugin._convertShop_replaceChoices('" + shop.id + "', false) }" },
|
||
],
|
||
"false": [
|
||
// 不能访问的情况下:检测能否预览
|
||
{
|
||
"type": "if",
|
||
"condition": shop.disablePreview,
|
||
"true": [
|
||
// 不可预览,提示并退出
|
||
{ "type": "playSound", "name": "操作失败" },
|
||
"当前无法访问该商店!",
|
||
{ "type": "break" },
|
||
],
|
||
"false": [
|
||
// 可以预览:将商店全部内容进行替换
|
||
{ "type": "tip", "text": "当前处于预览模式,不可购买" },
|
||
{ "type": "function", "function": "function() { core.plugin._convertShop_replaceChoices('" + shop.id + "', true) }" },
|
||
]
|
||
}
|
||
]
|
||
}
|
||
]
|
||
},
|
||
{ "type": "function", "function": "function() {core.addFlag('@temp@shop', -1);}" }
|
||
];
|
||
}
|
||
|
||
this._convertShop_replaceChoices = function (shopId, previewMode) {
|
||
var shop = core.status.shops[shopId];
|
||
var choices = (shop.choices || []).filter(function (choice) {
|
||
if (choice.condition == null || choice.condition == '') return true;
|
||
try { return core.calValue(choice.condition); } catch (e) { return true; }
|
||
}).map(function (choice) {
|
||
var ableToBuy = core.calValue(choice.need);
|
||
return {
|
||
"text": choice.text,
|
||
"icon": choice.icon,
|
||
"color": ableToBuy && !previewMode ? choice.color : [153, 153, 153, 1],
|
||
"action": ableToBuy && !previewMode ? [{ "type": "playSound", "name": "商店" }].concat(choice.action) : [
|
||
{ "type": "playSound", "name": "操作失败" },
|
||
{ "type": "tip", "text": previewMode ? "预览模式下不可购买" : "购买条件不足" }
|
||
]
|
||
};
|
||
}).concat({ "text": "离开", "action": [{ "type": "playSound", "name": "取消" }, { "type": "break" }] });
|
||
core.insertAction({ "type": "choices", "text": shop.text, "choices": choices });
|
||
}
|
||
|
||
/// 是否访问过某个快捷商店
|
||
this.isShopVisited = function (id) {
|
||
if (!core.hasFlag("__shops__")) core.setFlag("__shops__", {});
|
||
var shops = core.getFlag("__shops__");
|
||
if (!shops[id]) shops[id] = {};
|
||
return shops[id].visited;
|
||
}
|
||
|
||
/// 当前应当显示的快捷商店列表
|
||
this.listShopIds = function () {
|
||
return Object.keys(core.status.shops).filter(function (id) {
|
||
return core.isShopVisited(id) || !core.status.shops[id].mustEnable;
|
||
});
|
||
}
|
||
|
||
/// 是否能够打开某个商店
|
||
this.canOpenShop = function (id) {
|
||
if (this.isShopVisited(id)) return true;
|
||
var shop = core.status.shops[id];
|
||
if (shop.item || shop.commonEvent || shop.mustEnable) return false;
|
||
return true;
|
||
}
|
||
|
||
/// 启用或禁用某个快捷商店
|
||
this.setShopVisited = function (id, visited) {
|
||
if (!core.hasFlag("__shops__")) core.setFlag("__shops__", {});
|
||
var shops = core.getFlag("__shops__");
|
||
if (!shops[id]) shops[id] = {};
|
||
if (visited) shops[id].visited = true;
|
||
else delete shops[id].visited;
|
||
}
|
||
|
||
/// 能否使用快捷商店
|
||
this.canUseQuickShop = function (id) {
|
||
// 如果返回一个字符串,表示不能,字符串为不能使用的提示
|
||
// 返回null代表可以使用
|
||
|
||
// 检查当前楼层的canUseQuickShop选项是否为false
|
||
if (core.status.thisMap.canUseQuickShop === false)
|
||
return '当前楼层不能使用快捷商店。';
|
||
return null;
|
||
}
|
||
|
||
var _shouldProcessKeyUp = true;
|
||
|
||
/// 允许商店X键退出
|
||
core.registerAction('keyUp', 'shops', function (keycode) {
|
||
if (!core.status.lockControl || core.status.event.id != 'action') return false;
|
||
if ((keycode == 13 || keycode == 32) && !_shouldProcessKeyUp) {
|
||
_shouldProcessKeyUp = true;
|
||
return true;
|
||
}
|
||
|
||
if (!core.hasFlag("@temp@shop") || core.status.event.data.type != 'choices') return false;
|
||
var data = core.status.event.data.current;
|
||
var choices = data.choices;
|
||
var topIndex = core.actions._getChoicesTopIndex(choices.length);
|
||
if (keycode == 88 || keycode == 27) { // X, ESC
|
||
core.actions._clickAction(core._HALF_WIDTH_ || core.__HALF_SIZE__, topIndex + choices.length - 1);
|
||
return true;
|
||
}
|
||
return false;
|
||
}, 60);
|
||
|
||
/// 允许长按空格或回车连续执行操作
|
||
core.registerAction('keyDown', 'shops', function (keycode) {
|
||
if (!core.status.lockControl || !core.hasFlag("@temp@shop") || core.status.event.id != 'action') return false;
|
||
if (core.status.event.data.type != 'choices') return false;
|
||
core.status.onShopLongDown = true;
|
||
var data = core.status.event.data.current;
|
||
var choices = data.choices;
|
||
var topIndex = core.actions._getChoicesTopIndex(choices.length);
|
||
if (keycode == 13 || keycode == 32) { // Space, Enter
|
||
core.actions._clickAction(core._HALF_WIDTH_ || core.__HALF_SIZE__, topIndex + core.status.event.selection);
|
||
_shouldProcessKeyUp = false;
|
||
return true;
|
||
}
|
||
return false;
|
||
}, 60);
|
||
|
||
// 允许长按屏幕连续执行操作
|
||
core.registerAction('longClick', 'shops', function (x, y, px, py) {
|
||
if (!core.status.lockControl || !core.hasFlag("@temp@shop") || core.status.event.id != 'action') return false;
|
||
if (core.status.event.data.type != 'choices') return false;
|
||
var data = core.status.event.data.current;
|
||
var choices = data.choices;
|
||
var topIndex = core.actions._getChoicesTopIndex(choices.length);
|
||
if (Math.abs(x - (core._HALF_WIDTH_ || core.__HALF_SIZE__)) <= 2 && y >= topIndex && y < topIndex + choices.length) {
|
||
core.actions._clickAction(x, y);
|
||
return true;
|
||
}
|
||
return false;
|
||
}, 60);
|
||
},
|
||
"removeMap": function () {
|
||
// 高层塔砍层插件,删除后不会存入存档,不可浏览地图也不可飞到。
|
||
// 推荐用法:
|
||
// 对于超高层或分区域塔,当在1区时将2区以后的地图删除;1区结束时恢复2区,进二区时删除1区地图,以此类推
|
||
// 这样可以大幅减少存档空间,以及加快存读档速度
|
||
|
||
// 删除楼层
|
||
// core.removeMaps("MT1", "MT300") 删除MT1~MT300之间的全部层
|
||
// core.removeMaps("MT10") 只删除MT10层
|
||
this.removeMaps = function (fromId, toId) {
|
||
toId = toId || fromId;
|
||
var fromIndex = core.floorIds.indexOf(fromId),
|
||
toIndex = core.floorIds.indexOf(toId);
|
||
if (toIndex < 0) toIndex = core.floorIds.length - 1;
|
||
flags.__visited__ = flags.__visited__ || {};
|
||
flags.__removed__ = flags.__removed__ || [];
|
||
flags.__disabled__ = flags.__disabled__ || {};
|
||
flags.__leaveLoc__ = flags.__leaveLoc__ || {};
|
||
for (var i = fromIndex; i <= toIndex; ++i) {
|
||
var floorId = core.floorIds[i];
|
||
if (core.status.maps[floorId].deleted) continue;
|
||
delete flags.__visited__[floorId];
|
||
flags.__removed__.push(floorId);
|
||
delete flags.__disabled__[floorId];
|
||
delete flags.__leaveLoc__[floorId];
|
||
(core.status.autoEvents || []).forEach(function (event) {
|
||
if (event.floorId == floorId && event.currentFloor) {
|
||
core.autoEventExecuting(event.symbol, false);
|
||
core.autoEventExecuted(event.symbol, false);
|
||
}
|
||
});
|
||
core.status.maps[floorId].deleted = true;
|
||
core.status.maps[floorId].canFlyTo = false;
|
||
core.status.maps[floorId].canFlyFrom = false;
|
||
core.status.maps[floorId].cannotViewMap = true;
|
||
}
|
||
}
|
||
|
||
// 恢复楼层
|
||
// core.resumeMaps("MT1", "MT300") 恢复MT1~MT300之间的全部层
|
||
// core.resumeMaps("MT10") 只恢复MT10层
|
||
this.resumeMaps = function (fromId, toId) {
|
||
toId = toId || fromId;
|
||
var fromIndex = core.floorIds.indexOf(fromId),
|
||
toIndex = core.floorIds.indexOf(toId);
|
||
if (toIndex < 0) toIndex = core.floorIds.length - 1;
|
||
flags.__removed__ = flags.__removed__ || [];
|
||
for (var i = fromIndex; i <= toIndex; ++i) {
|
||
var floorId = core.floorIds[i];
|
||
if (!core.status.maps[floorId].deleted) continue;
|
||
flags.__removed__ = flags.__removed__.filter(function (f) { return f != floorId; });
|
||
core.status.maps[floorId] = core.loadFloor(floorId);
|
||
}
|
||
}
|
||
|
||
// 分区砍层相关
|
||
var inAnyPartition = function (floorId) {
|
||
var inPartition = false;
|
||
(core.floorPartitions || []).forEach(function (floor) {
|
||
var fromIndex = core.floorIds.indexOf(floor[0]);
|
||
var toIndex = core.floorIds.indexOf(floor[1]);
|
||
var index = core.floorIds.indexOf(floorId);
|
||
if (fromIndex < 0 || index < 0) return;
|
||
if (toIndex < 0) toIndex = core.floorIds.length - 1;
|
||
if (index >= fromIndex && index <= toIndex) inPartition = true;
|
||
});
|
||
return inPartition;
|
||
}
|
||
|
||
// 分区砍层
|
||
this.autoRemoveMaps = function (floorId) {
|
||
if (main.mode != 'play' || !inAnyPartition(floorId)) return;
|
||
// 根据分区信息自动砍层与恢复
|
||
(core.floorPartitions || []).forEach(function (floor) {
|
||
var fromIndex = core.floorIds.indexOf(floor[0]);
|
||
var toIndex = core.floorIds.indexOf(floor[1]);
|
||
var index = core.floorIds.indexOf(floorId);
|
||
if (fromIndex < 0 || index < 0) return;
|
||
if (toIndex < 0) toIndex = core.floorIds.length - 1;
|
||
if (index >= fromIndex && index <= toIndex) {
|
||
core.resumeMaps(core.floorIds[fromIndex], core.floorIds[toIndex]);
|
||
} else {
|
||
core.removeMaps(core.floorIds[fromIndex], core.floorIds[toIndex]);
|
||
}
|
||
});
|
||
}
|
||
},
|
||
"fiveLayers": function () {
|
||
// 是否启用五图层(增加背景2层和前景2层) 将__enable置为true即会启用;启用后请保存后刷新编辑器
|
||
// 背景层2将会覆盖背景层 被事件层覆盖 前景层2将会覆盖前景层
|
||
// 另外 请注意加入两个新图层 会让大地图的性能降低一些
|
||
// 插件作者:ad
|
||
var __enable = false;
|
||
if (!__enable) return;
|
||
|
||
// 创建新图层
|
||
function createCanvas (name, zIndex) {
|
||
if (!name) return;
|
||
var canvas = document.createElement('canvas');
|
||
canvas.id = name;
|
||
canvas.className = 'gameCanvas anti-aliasing';
|
||
// 编辑器模式下设置zIndex会导致加入的图层覆盖优先级过高
|
||
if (main.mode != "editor") canvas.style.zIndex = zIndex || 0;
|
||
// 将图层插入进游戏内容
|
||
document.getElementById('gameDraw').appendChild(canvas);
|
||
var ctx = canvas.getContext('2d');
|
||
core.canvas[name] = ctx;
|
||
canvas.width = core._PX_ || core.__PIXELS__;
|
||
canvas.height = core._PY_ || core.__PIXELS__;
|
||
return canvas;
|
||
}
|
||
|
||
var bg2Canvas = createCanvas('bg2', 20);
|
||
var fg2Canvas = createCanvas('fg2', 63);
|
||
// 大地图适配
|
||
core.bigmap.canvas = ["bg2", "fg2", "bg", "event", "event2", "fg", "damage"];
|
||
core.initStatus.bg2maps = {};
|
||
core.initStatus.fg2maps = {};
|
||
|
||
if (main.mode == 'editor') {
|
||
/*插入编辑器的图层 不做此步新增图层无法在编辑器显示*/
|
||
// 编辑器图层覆盖优先级 eui > efg > fg(前景层) > event2(48*32图块的事件层) > event(事件层) > bg(背景层)
|
||
// 背景层2(bg2) 插入事件层(event)之前(即bg与event之间)
|
||
document.getElementById('mapEdit').insertBefore(bg2Canvas, document.getElementById('event'));
|
||
// 前景层2(fg2) 插入编辑器前景(efg)之前(即fg之后)
|
||
document.getElementById('mapEdit').insertBefore(fg2Canvas, document.getElementById('ebm'));
|
||
// 原本有三个图层 从4开始添加
|
||
var num = 4;
|
||
// 新增图层存入editor.dom中
|
||
editor.dom.bg2c = core.canvas.bg2.canvas;
|
||
editor.dom.bg2Ctx = core.canvas.bg2;
|
||
editor.dom.fg2c = core.canvas.fg2.canvas;
|
||
editor.dom.fg2Ctx = core.canvas.fg2;
|
||
editor.dom.maps.push('bg2map', 'fg2map');
|
||
editor.dom.canvas.push('bg2', 'fg2');
|
||
|
||
// 创建编辑器上的按钮
|
||
var createCanvasBtn = function (name) {
|
||
// 电脑端创建按钮
|
||
var input = document.createElement('input');
|
||
// layerMod4/layerMod5
|
||
var id = 'layerMod' + num++;
|
||
// bg2map/fg2map
|
||
var value = name + 'map';
|
||
input.type = 'radio';
|
||
input.name = 'layerMod';
|
||
input.id = id;
|
||
input.value = value;
|
||
editor.dom[id] = input;
|
||
input.onchange = function () {
|
||
editor.uifunctions.setLayerMod(value);
|
||
}
|
||
return input;
|
||
};
|
||
|
||
var createCanvasBtn_mobile = function (name) {
|
||
// 手机端往选择列表中添加子选项
|
||
var input = document.createElement('option');
|
||
var id = 'layerMod' + num++;
|
||
var value = name + 'map';
|
||
input.name = 'layerMod';
|
||
input.value = value;
|
||
editor.dom[id] = input;
|
||
return input;
|
||
};
|
||
if (!editor.isMobile) {
|
||
var input = createCanvasBtn('bg2');
|
||
var input2 = createCanvasBtn('fg2');
|
||
// 获取事件层及其父节点
|
||
var child = document.getElementById('layerMod'),
|
||
parent = child.parentNode;
|
||
// 背景层2插入事件层前
|
||
parent.insertBefore(input, child);
|
||
// 不能直接更改背景层2的innerText 所以创建文本节点
|
||
var txt = document.createTextNode('bg2');
|
||
// 插入事件层前(即新插入的背景层2前)
|
||
parent.insertBefore(txt, child);
|
||
// 向最后插入前景层2(即插入前景层后)
|
||
parent.appendChild(input2);
|
||
var txt2 = document.createTextNode('fg2');
|
||
parent.appendChild(txt2);
|
||
parent.childNodes[2].replaceWith("bg");
|
||
parent.childNodes[6].replaceWith("事件");
|
||
parent.childNodes[8].replaceWith("fg");
|
||
} else {
|
||
var input = createCanvasBtn_mobile('bg2');
|
||
var input2 = createCanvasBtn_mobile('fg2');
|
||
// 手机端因为是选项 所以可以直接改innerText
|
||
input.innerText = '背景层2';
|
||
input2.innerText = '前景层2';
|
||
var parent = document.getElementById('layerMod');
|
||
parent.insertBefore(input, parent.children[1]);
|
||
parent.appendChild(input2);
|
||
}
|
||
}
|
||
|
||
var _loadFloor_doNotCopy = core.maps._loadFloor_doNotCopy;
|
||
core.maps._loadFloor_doNotCopy = function () {
|
||
return ["bg2map", "fg2map"].concat(_loadFloor_doNotCopy());
|
||
}
|
||
////// 绘制背景和前景层 //////
|
||
core.maps._drawBg_draw = function (floorId, toDrawCtx, cacheCtx, config) {
|
||
config.ctx = cacheCtx;
|
||
core.maps._drawBg_drawBackground(floorId, config);
|
||
// ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制背景图块;后绘制的覆盖先绘制的。
|
||
core.maps._drawFloorImages(floorId, config.ctx, 'bg', null, null, config.onMap);
|
||
core.maps._drawBgFgMap(floorId, 'bg', config);
|
||
if (config.onMap) {
|
||
core.drawImage(toDrawCtx, cacheCtx.canvas, core.bigmap.v2 ? -32 : 0, core.bigmap.v2 ? -32 : 0);
|
||
core.clearMap('bg2');
|
||
core.clearMap(cacheCtx);
|
||
}
|
||
core.maps._drawBgFgMap(floorId, 'bg2', config);
|
||
if (config.onMap) core.drawImage('bg2', cacheCtx.canvas, core.bigmap.v2 ? -32 : 0, core.bigmap.v2 ? -32 : 0);
|
||
config.ctx = toDrawCtx;
|
||
}
|
||
core.maps._drawFg_draw = function (floorId, toDrawCtx, cacheCtx, config) {
|
||
config.ctx = cacheCtx;
|
||
// ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制前景图块;后绘制的覆盖先绘制的。
|
||
core.maps._drawFloorImages(floorId, config.ctx, 'fg', null, null, config.onMap);
|
||
core.maps._drawBgFgMap(floorId, 'fg', config);
|
||
if (config.onMap) {
|
||
core.drawImage(toDrawCtx, cacheCtx.canvas, core.bigmap.v2 ? -32 : 0, core.bigmap.v2 ? -32 : 0);
|
||
core.clearMap('fg2');
|
||
core.clearMap(cacheCtx);
|
||
}
|
||
core.maps._drawBgFgMap(floorId, 'fg2', config);
|
||
if (config.onMap) core.drawImage('fg2', cacheCtx.canvas, core.bigmap.v2 ? -32 : 0, core.bigmap.v2 ? -32 : 0);
|
||
config.ctx = toDrawCtx;
|
||
}
|
||
////// 移动判定 //////
|
||
core.maps._generateMovableArray_arrays = function (floorId) {
|
||
return {
|
||
bgArray: this.getBgMapArray(floorId),
|
||
fgArray: this.getFgMapArray(floorId),
|
||
eventArray: this.getMapArray(floorId),
|
||
bg2Array: this._getBgFgMapArray('bg2', floorId),
|
||
fg2Array: this._getBgFgMapArray('fg2', floorId)
|
||
};
|
||
}
|
||
},
|
||
"itemShop": function () {
|
||
// 道具商店相关的插件
|
||
// 可在全塔属性-全局商店中使用「道具商店」事件块进行编辑(如果找不到可以在入口方块中找)
|
||
|
||
var shopId = null; // 当前商店ID
|
||
var type = 0; // 当前正在选中的类型,0买入1卖出
|
||
var selectItem = 0; // 当前正在选中的道具
|
||
var selectCount = 0; // 当前已经选中的数量
|
||
var page = 0;
|
||
var totalPage = 0;
|
||
var totalMoney = 0;
|
||
var list = [];
|
||
var shopInfo = null; // 商店信息
|
||
var choices = []; // 商店选项
|
||
var use = 'money';
|
||
var useText = '金币';
|
||
|
||
var bigFont = core.ui._buildFont(20, false),
|
||
middleFont = core.ui._buildFont(18, false);
|
||
|
||
this._drawItemShop = function () {
|
||
// 绘制道具商店
|
||
|
||
// Step 1: 背景和固定的几个文字
|
||
core.ui._createUIEvent();
|
||
core.clearMap('uievent');
|
||
core.ui.clearUIEventSelector();
|
||
core.setTextAlign('uievent', 'left');
|
||
core.setTextBaseline('uievent', 'top');
|
||
core.fillRect('uievent', 0, 0, 480, 480, 'black');
|
||
core.drawWindowSkin('winskin.png', 'uievent', 0, 0, 480, 64);
|
||
core.drawWindowSkin('winskin.png', 'uievent', 0, 64, 360, 64);
|
||
core.drawWindowSkin('winskin.png', 'uievent', 0, 128, 360, 352);
|
||
core.drawWindowSkin('winskin.png', 'uievent', 360, 64, 120, 64);
|
||
core.drawWindowSkin('winskin.png', 'uievent', 360, 128, 120, 352);
|
||
core.setFillStyle('uievent', 'white');
|
||
core.setStrokeStyle('uievent', 'white');
|
||
core.fillText("uievent", "购买", 32, 84, 'white', bigFont);
|
||
core.fillText("uievent", "卖出", 152, 84);
|
||
core.fillText("uievent", "离开", 272, 84);
|
||
core.fillText("uievent", "当前" + useText, 374, 75, null, middleFont);
|
||
core.setTextAlign("uievent", "right");
|
||
core.fillText("uievent", core.formatBigNumber(core.status.hero.money), 466, 100);
|
||
core.setTextAlign("uievent", "left");
|
||
core.ui.drawUIEventSelector(1, "winskin.png", 22 + 120 * type, 76, 60, 33);
|
||
if (selectItem != null) {
|
||
core.setTextAlign('uievent', 'center');
|
||
core.fillText("uievent", type == 0 ? "买入个数" : "卖出个数", 420, 360, null, bigFont);
|
||
core.fillText("uievent", "< " + selectCount + " >", 420, 390);
|
||
core.fillText("uievent", "确定", 420, 420);
|
||
}
|
||
|
||
// Step 2:获得列表并展示
|
||
list = choices.filter(function (one) {
|
||
if (one.condition != null && one.condition != '') {
|
||
try { if (!core.calValue(one.condition)) return false; } catch (e) {}
|
||
}
|
||
return (type == 0 && one.money != null) || (type == 1 && one.sell != null);
|
||
});
|
||
var per_page = 7;
|
||
totalPage = Math.ceil(list.length / per_page);
|
||
page = Math.floor((selectItem || 0) / per_page) + 1;
|
||
|
||
// 绘制分页
|
||
if (totalPage > 1) {
|
||
var half = 180;
|
||
core.setTextAlign('uievent', 'center');
|
||
core.fillText('uievent', page + " / " + totalPage, half, 450, null, middleFont);
|
||
if (page > 1) core.fillText('uievent', '上一页', half - 80, 450);
|
||
if (page < totalPage) core.fillText('uievent', '下一页', half + 80, 450);
|
||
}
|
||
core.setTextAlign('uievent', 'left');
|
||
|
||
// 绘制每一项
|
||
var start = (page - 1) * per_page;
|
||
for (var i = 0; i < per_page; ++i) {
|
||
var curr = start + i;
|
||
if (curr >= list.length) break;
|
||
var item = list[curr];
|
||
core.drawIcon('uievent', item.id, 10, 141 + i * 40);
|
||
core.setTextAlign('uievent', 'left');
|
||
core.fillText('uievent', core.material.items[item.id].name, 50, 148 + i * 40, null, bigFont);
|
||
core.setTextAlign('uievent', 'right');
|
||
core.fillText('uievent', (type == 0 ? core.calValue(item.money) : core.calValue(item.sell)) + useText + "/个", 340, 149 + i * 40, null, middleFont);
|
||
core.setTextAlign("uievent", "left");
|
||
if (curr == selectItem) {
|
||
// 绘制描述,文字自动放缩
|
||
var text = core.material.items[item.id].text || "该道具暂无描述";
|
||
try { text = core.replaceText(text); } catch (e) {}
|
||
for (var fontSize = 20; fontSize >= 8; fontSize -= 2) {
|
||
var config = { left: 10, fontSize: fontSize, maxWidth: 467 };
|
||
var height = core.getTextContentHeight(text, config);
|
||
if (height <= 60) {
|
||
config.top = (64 - height) / 2;
|
||
core.drawTextContent("uievent", text, config);
|
||
break;
|
||
}
|
||
}
|
||
core.ui.drawUIEventSelector(2, "winskin.png", 8, 137 + i * 40, 343, 40);
|
||
if (type == 0 && item.number != null) {
|
||
core.fillText("uievent", "存货", 370, 152, null, bigFont);
|
||
core.setTextAlign("uievent", "right");
|
||
core.fillText("uievent", item.number, 470, 152, null, null, 60);
|
||
} else if (type == 1) {
|
||
core.fillText("uievent", "数量", 370, 152, null, bigFont);
|
||
core.setTextAlign("uievent", "right");
|
||
core.fillText("uievent", core.itemCount(item.id), 470, 152, null, null, 40);
|
||
}
|
||
core.setTextAlign("uievent", "left");
|
||
core.fillText("uievent", "预计" + useText, 370, 280);
|
||
core.setTextAlign("uievent", "right");
|
||
totalMoney = selectCount * (type == 0 ? core.calValue(item.money) : core.calValue(item.sell));
|
||
core.fillText("uievent", core.formatBigNumber(totalMoney), 470, 310);
|
||
|
||
core.setTextAlign("uievent", "left");
|
||
core.fillText("uievent", type == 0 ? "已购次数" : "已卖次数", 370, 190);
|
||
core.setTextAlign("uievent", "right");
|
||
core.fillText("uievent", (type == 0 ? item.money_count : item.sell_count) || 0, 470, 220);
|
||
}
|
||
}
|
||
|
||
core.setTextAlign('uievent', 'left');
|
||
core.setTextBaseline('uievent', 'alphabetic');
|
||
}
|
||
|
||
var _add = function (item, delta) {
|
||
if (item == null) return;
|
||
selectCount = core.clamp(
|
||
selectCount + delta, 0,
|
||
Math.min(type == 0 ? Math.floor(core.status.hero[use] / core.calValue(item.money)) : core.itemCount(item.id),
|
||
type == 0 && item.number != null ? item.number : Number.MAX_SAFE_INTEGER)
|
||
);
|
||
}
|
||
|
||
var _confirm = function (item) {
|
||
if (item == null || selectCount == 0) return;
|
||
if (type == 0) {
|
||
core.status.hero[use] -= totalMoney;
|
||
core.getItem(item.id, selectCount);
|
||
core.stopSound();
|
||
core.playSound('确定');
|
||
if (item.number != null) item.number -= selectCount;
|
||
item.money_count = (item.money_count || 0) + selectCount;
|
||
} else {
|
||
core.status.hero[use] += totalMoney;
|
||
core.removeItem(item.id, selectCount);
|
||
core.playSound('确定');
|
||
core.drawTip("成功卖出" + selectCount + "个" + core.material.items[item.id].name, item.id);
|
||
if (item.number != null) item.number += selectCount;
|
||
item.sell_count = (item.sell_count || 0) + selectCount;
|
||
}
|
||
selectCount = 0;
|
||
}
|
||
|
||
this._performItemShopKeyBoard = function (keycode) {
|
||
var item = list[selectItem] || null;
|
||
// 键盘操作
|
||
switch (keycode) {
|
||
case 38: // up
|
||
if (selectItem == null) break;
|
||
if (selectItem == 0) selectItem = null;
|
||
else selectItem--;
|
||
selectCount = 0;
|
||
break;
|
||
case 37: // left
|
||
if (selectItem == null) {
|
||
if (type > 0) type--;
|
||
break;
|
||
}
|
||
_add(item, -1);
|
||
break;
|
||
case 39: // right
|
||
if (selectItem == null) {
|
||
if (type < 2) type++;
|
||
break;
|
||
}
|
||
_add(item, 1);
|
||
break;
|
||
case 40: // down
|
||
if (selectItem == null) {
|
||
if (list.length > 0) selectItem = 0;
|
||
break;
|
||
}
|
||
if (list.length == 0) break;
|
||
selectItem = Math.min(selectItem + 1, list.length - 1);
|
||
selectCount = 0;
|
||
break;
|
||
case 13:
|
||
case 32: // Enter/Space
|
||
if (selectItem == null) {
|
||
if (type == 2)
|
||
core.insertAction({ "type": "break" });
|
||
else if (list.length > 0)
|
||
selectItem = 0;
|
||
break;
|
||
}
|
||
_confirm(item);
|
||
break;
|
||
case 27: // ESC
|
||
if (selectItem == null) {
|
||
core.insertAction({ "type": "break" });
|
||
break;
|
||
}
|
||
selectItem = null;
|
||
break;
|
||
}
|
||
}
|
||
|
||
this._performItemShopClick = function (px, py) {
|
||
var item = list[selectItem] || null;
|
||
// 鼠标操作
|
||
if (px >= 22 && px <= 82 && py >= 81 && py <= 112) {
|
||
// 买
|
||
if (type != 0) {
|
||
type = 0;
|
||
selectItem = null;
|
||
selectCount = 0;
|
||
}
|
||
return;
|
||
}
|
||
if (px >= 142 && px <= 202 && py >= 81 && py <= 112) {
|
||
// 卖
|
||
if (type != 1) {
|
||
type = 1;
|
||
selectItem = null;
|
||
selectCount = 0;
|
||
}
|
||
return;
|
||
}
|
||
if (px >= 262 && px <= 322 && py >= 81 && py <= 112) // 离开
|
||
return core.insertAction({ "type": "break" });
|
||
// <,>
|
||
if (px >= 370 && px <= 395 && py >= 392 && py <= 415)
|
||
return _add(item, -1);
|
||
if (px >= 445 && px <= 470 && py >= 302 && py <= 415)
|
||
return _add(item, 1);
|
||
// 确定
|
||
if (px >= 392 && px <= 443 && py >= 421 && py <= 446)
|
||
return _confirm(item);
|
||
|
||
// 上一页/下一页
|
||
if (px >= 70 && px <= 130 && py >= 450) {
|
||
if (page > 1) {
|
||
selectItem -= 7;
|
||
selectCount = 0;
|
||
}
|
||
return;
|
||
}
|
||
if (px >= 230 && px <= 290 && py >= 450) {
|
||
if (page < totalPage) {
|
||
selectItem = Math.min(selectItem + 7, list.length - 1);
|
||
selectCount = 0;
|
||
}
|
||
return;
|
||
}
|
||
|
||
// 实际区域
|
||
if (px >= 9 && px <= 351 && py >= 142 && py < 422) {
|
||
if (list.length == 0) return;
|
||
var index = parseInt((py - 142) / 40);
|
||
var newItem = 7 * (page - 1) + index;
|
||
if (newItem >= list.length) newItem = list.length - 1;
|
||
if (newItem != selectItem) {
|
||
selectItem = newItem;
|
||
selectCount = 0;
|
||
}
|
||
return;
|
||
}
|
||
}
|
||
|
||
this._performItemShopAction = function () {
|
||
if (flags.type == 0) return this._performItemShopKeyBoard(flags.keycode);
|
||
else return this._performItemShopClick(flags.px, flags.py);
|
||
}
|
||
|
||
this.openItemShop = function (itemShopId) {
|
||
shopId = itemShopId;
|
||
type = 0;
|
||
page = 0;
|
||
selectItem = null;
|
||
selectCount = 0;
|
||
core.isShopVisited(itemShopId);
|
||
shopInfo = flags.__shops__[shopId];
|
||
if (shopInfo.choices == null) shopInfo.choices = core.clone(core.status.shops[shopId].choices);
|
||
choices = shopInfo.choices;
|
||
use = core.status.shops[shopId].use;
|
||
if (use != 'exp') use = 'money';
|
||
useText = use == 'money' ? '金币' : '经验';
|
||
|
||
core.insertAction([{
|
||
"type": "while",
|
||
"condition": "true",
|
||
"data": [
|
||
{ "type": "function", "function": "function () { core.plugin._drawItemShop(); }" },
|
||
{ "type": "wait" },
|
||
{ "type": "function", "function": "function() { core.plugin._performItemShopAction(); }" }
|
||
]
|
||
},
|
||
{
|
||
"type": "function",
|
||
"function": "function () { core.deleteCanvas('uievent'); core.ui.clearUIEventSelector(); }"
|
||
}
|
||
]);
|
||
}
|
||
|
||
},
|
||
"enemyLevel": function () {
|
||
// 此插件将提供怪物手册中的怪物境界显示
|
||
// 使用此插件需要先给每个怪物定义境界,方法如下:
|
||
// 点击怪物的【配置表格】,找到“【怪物】相关的表格配置”,然后在【名称】仿照增加境界定义:
|
||
/*
|
||
"level": {
|
||
"_leaf": true,
|
||
"_type": "textarea",
|
||
"_string": true,
|
||
"_data": "境界"
|
||
},
|
||
*/
|
||
// 然后保存刷新,可以看到怪物的属性定义中出现了【境界】。再开启本插件即可。
|
||
|
||
// 是否开启本插件,默认禁用;将此改成 true 将启用本插件。
|
||
var __enable = false;
|
||
if (!__enable) return;
|
||
|
||
// 这里定义每个境界的显示颜色;可以写'red', '#RRGGBB' 或者[r,g,b,a]四元数组
|
||
var levelToColors = {
|
||
"萌新一阶": "red",
|
||
"萌新二阶": "#FF0000",
|
||
"萌新三阶": [255, 0, 0, 1],
|
||
};
|
||
|
||
// 复写 _drawBook_drawName
|
||
var originDrawBook = core.ui._drawBook_drawName;
|
||
core.ui._drawBook_drawName = function (index, enemy, top, left, width) {
|
||
// 如果没有境界,则直接调用原始代码绘制
|
||
if (!enemy.level) return originDrawBook.call(core.ui, index, enemy, top, left, width);
|
||
// 存在境界,则额外进行绘制
|
||
core.setTextAlign('ui', 'center');
|
||
if (enemy.specialText.length == 0) {
|
||
core.fillText('ui', enemy.name, left + width / 2,
|
||
top + 27, '#DDDDDD', this._buildFont(17, true));
|
||
core.fillText('ui', enemy.level, left + width / 2,
|
||
top + 51, core.arrayToRGBA(levelToColors[enemy.level] || '#DDDDDD'), this._buildFont(14, true));
|
||
} else {
|
||
core.fillText('ui', enemy.name, left + width / 2,
|
||
top + 20, '#DDDDDD', this._buildFont(17, true), width);
|
||
switch (enemy.specialText.length) {
|
||
case 1:
|
||
core.fillText('ui', enemy.specialText[0], left + width / 2,
|
||
top + 38, core.arrayToRGBA((enemy.specialColor || [])[0] || '#FF6A6A'),
|
||
this._buildFont(14, true), width);
|
||
break;
|
||
case 2:
|
||
// Step 1: 计算字体
|
||
var text = enemy.specialText[0] + " " + enemy.specialText[1];
|
||
core.setFontForMaxWidth('ui', text, width, this._buildFont(14, true));
|
||
// Step 2: 计算总宽度
|
||
var totalWidth = core.calWidth('ui', text);
|
||
var leftWidth = core.calWidth('ui', enemy.specialText[0]);
|
||
var rightWidth = core.calWidth('ui', enemy.specialText[1]);
|
||
// Step 3: 绘制
|
||
core.fillText('ui', enemy.specialText[0], left + (width + leftWidth - totalWidth) / 2,
|
||
top + 38, core.arrayToRGBA((enemy.specialColor || [])[0] || '#FF6A6A'));
|
||
core.fillText('ui', enemy.specialText[1], left + (width + totalWidth - rightWidth) / 2,
|
||
top + 38, core.arrayToRGBA((enemy.specialColor || [])[1] || '#FF6A6A'));
|
||
break;
|
||
default:
|
||
core.fillText('ui', '多属性...', left + width / 2,
|
||
top + 38, '#FF6A6A', this._buildFont(14, true), width);
|
||
}
|
||
core.fillText('ui', enemy.level, left + width / 2,
|
||
top + 56, core.arrayToRGBA(levelToColors[enemy.level] || '#DDDDDD'), this._buildFont(14, true));
|
||
}
|
||
}
|
||
|
||
// 也可以复写其他的属性颜色如怪物攻防等,具体参见下面的例子的注释部分
|
||
core.ui._drawBook_drawRow1 = function (index, enemy, top, left, width, position) {
|
||
// 绘制第一行
|
||
core.setTextAlign('ui', 'left');
|
||
var b13 = this._buildFont(13, true),
|
||
f13 = this._buildFont(13, false);
|
||
var col1 = left,
|
||
col2 = left + width * 9 / 25,
|
||
col3 = left + width * 17 / 25;
|
||
core.fillText('ui', '生命', col1, position, '#DDDDDD', f13);
|
||
core.fillText('ui', core.formatBigNumber(enemy.hp || 0), col1 + 30, position, /*'red' */ null, b13);
|
||
core.fillText('ui', '攻击', col2, position, null, f13);
|
||
core.fillText('ui', core.formatBigNumber(enemy.atk || 0), col2 + 30, position, /* '#FF0000' */ null, b13);
|
||
core.fillText('ui', '防御', col3, position, null, f13);
|
||
core.fillText('ui', core.formatBigNumber(enemy.def || 0), col3 + 30, position, /* [255, 0, 0, 1] */ null, b13);
|
||
}
|
||
},
|
||
"multiHeros": function () {
|
||
// 多角色插件
|
||
// Step 1: 启用本插件
|
||
// Step 2: 定义每个新的角色各项初始数据(参见下方注释)
|
||
// Step 3: 在游戏中的任何地方都可以调用 `core.changeHero()` 进行切换;也可以 `core.changeHero(1)` 来切换到某个具体的角色上
|
||
|
||
// 是否开启本插件,默认禁用;将此改成 true 将启用本插件。
|
||
var __enable = false;
|
||
if (!__enable) return;
|
||
|
||
// 在这里定义全部的新角色属性
|
||
// 请注意,在这里定义的内容不会多角色共用,在切换时会进行恢复。
|
||
// 你也可以自行新增或删除,比如不共用金币则可以加上"money"的初始化,不共用道具则可以加上"items"的初始化,
|
||
// 多角色共用hp的话则删除hp,等等。总之,不共用的属性都在这里进行定义就好。
|
||
var hero1 = {
|
||
"floorId": "MT0", // 该角色初始楼层ID;如果共用楼层可以注释此项
|
||
"image": "brave.png", // 角色的行走图名称;此项必填不然会报错
|
||
"name": "1号角色",
|
||
"lv": 1,
|
||
"hp": 10000, // 如果HP共用可注释此项
|
||
"atk": 1000,
|
||
"def": 1000,
|
||
"mdef": 0,
|
||
// "money": 0, // 如果要不共用金币则取消此项注释
|
||
// "exp": 0, // 如果要不共用经验则取消此项注释
|
||
"loc": { "x": 0, "y": 0, "direction": "up" }, // 该角色初始位置;如果共用位置可注释此项
|
||
"items": {
|
||
"tools": {}, // 如果共用消耗道具(含钥匙)则可注释此项
|
||
// "constants": {}, // 如果不共用永久道具(如手册)可取消注释此项
|
||
"equips": {}, // 如果共用在背包的装备可注释此项
|
||
},
|
||
"equipment": [], // 如果共用装备可注释此项;此项和上面的「共用在背包的装备」需要拥有相同状态,不然可能出现问题
|
||
};
|
||
// 也可以类似新增其他角色
|
||
// 新增的角色,各项属性共用与不共用的选择必须和上面完全相同,否则可能出现问题。
|
||
// var hero2 = { ...
|
||
|
||
var heroCount = 2; // 包含默认角色在内总共多少个角色,该值需手动修改。
|
||
|
||
this.initHeros = function () {
|
||
core.setFlag("hero1", core.clone(hero1)); // 将属性值存到变量中
|
||
// core.setFlag("hero2", core.clone(hero2)); // 更多的角色也存入变量中;每个定义的角色都需要新增一行
|
||
|
||
// 检测是否存在装备
|
||
if (hero1.equipment) {
|
||
if (!hero1.items || !hero1.items.equips) {
|
||
alert('多角色插件的equipment和道具中的equips必须拥有相同状态!');
|
||
}
|
||
// 存99号套装为全空
|
||
var saveEquips = core.getFlag("saveEquips", []);
|
||
saveEquips[99] = [];
|
||
core.setFlag("saveEquips", saveEquips);
|
||
} else {
|
||
if (hero1.items && hero1.items.equips) {
|
||
alert('多角色插件的equipment和道具中的equips必须拥有相同状态!');
|
||
}
|
||
}
|
||
}
|
||
|
||
// 在游戏开始注入initHeros
|
||
var _startGame_setHard = core.events._startGame_setHard;
|
||
core.events._startGame_setHard = function () {
|
||
_startGame_setHard.call(core.events);
|
||
core.initHeros();
|
||
}
|
||
|
||
// 切换角色
|
||
// 可以使用 core.changeHero() 来切换到下一个角色
|
||
// 也可以 core.changeHero(1) 来切换到某个角色(默认角色为0)
|
||
this.changeHero = function (toHeroId) {
|
||
var currHeroId = core.getFlag("heroId", 0); // 获得当前角色ID
|
||
if (toHeroId == null) {
|
||
toHeroId = (currHeroId + 1) % heroCount;
|
||
}
|
||
if (currHeroId == toHeroId) return;
|
||
|
||
var saveList = Object.keys(hero1);
|
||
|
||
// 保存当前内容
|
||
var toSave = {};
|
||
// 暂时干掉 drawTip 和 音效,避免切装时的提示
|
||
var _drawTip = core.ui.drawTip;
|
||
core.ui.drawTip = function () { };
|
||
var _playSound = core.control.playSound;
|
||
core.control.playSound = function () { }
|
||
// 记录当前录像,因为可能存在换装问题
|
||
core.clearRouteFolding();
|
||
var routeLength = core.status.route.length;
|
||
// 优先判定装备
|
||
if (hero1.equipment) {
|
||
core.items.quickSaveEquip(100 + currHeroId);
|
||
core.items.quickLoadEquip(99);
|
||
}
|
||
|
||
saveList.forEach(function (name) {
|
||
if (name == 'floorId') toSave[name] = core.status.floorId; // 楼层单独设置
|
||
else if (name == 'items') {
|
||
toSave.items = core.clone(core.status.hero.items);
|
||
Object.keys(toSave.items).forEach(function (one) {
|
||
if (!hero1.items[one]) delete toSave.items[one];
|
||
});
|
||
} else toSave[name] = core.clone(core.status.hero[name]); // 使用core.clone()来创建新对象
|
||
});
|
||
|
||
core.setFlag("hero" + currHeroId, toSave); // 将当前角色信息进行保存
|
||
var data = core.getFlag("hero" + toHeroId); // 获得要切换的角色保存内容
|
||
|
||
// 设置角色的属性值
|
||
saveList.forEach(function (name) {
|
||
if (name == "floorId");
|
||
else if (name == "items") {
|
||
Object.keys(core.status.hero.items).forEach(function (one) {
|
||
if (data.items[one]) core.status.hero.items[one] = core.clone(data.items[one]);
|
||
});
|
||
} else {
|
||
core.status.hero[name] = core.clone(data[name]);
|
||
}
|
||
});
|
||
// 最后装上装备
|
||
if (hero1.equipment) {
|
||
core.items.quickLoadEquip(100 + toHeroId);
|
||
}
|
||
|
||
core.ui.drawTip = _drawTip;
|
||
core.control.playSound = _playSound;
|
||
core.status.route = core.status.route.slice(0, routeLength);
|
||
core.control._bindRoutePush();
|
||
|
||
// 插入事件:改变角色行走图并进行楼层切换
|
||
var toFloorId = data.floorId || core.status.floorId;
|
||
var toLoc = data.loc || core.status.hero.loc;
|
||
core.insertAction([
|
||
{ "type": "setHeroIcon", "name": data.image || "hero.png" }, // 改变行走图
|
||
// 同层则用changePos,不同层则用changeFloor;这是为了避免共用楼层造成触发eachArrive
|
||
toFloorId != core.status.floorId ? {
|
||
"type": "changeFloor",
|
||
"floorId": toFloorId,
|
||
"loc": [toLoc.x, toLoc.y],
|
||
"direction": toLoc.direction,
|
||
"time": 0 // 可以在这里设置切换时间
|
||
} : { "type": "changePos", "loc": [toLoc.x, toLoc.y], "direction": toLoc.direction }
|
||
// 你还可以在这里执行其他事件,比如增加或取消跟随效果
|
||
]);
|
||
core.setFlag("heroId", toHeroId); // 保存切换到的角色ID
|
||
}
|
||
},
|
||
"heroFourFrames": function () {
|
||
// 样板的勇士/跟随者移动时只使用2、4两帧,观感较差。本插件可以将四帧全用上。
|
||
|
||
// 是否启用本插件
|
||
var __enable = true;
|
||
if (!__enable) return;
|
||
|
||
["up", "down", "left", "right"].forEach(function (one) {
|
||
// 指定中间帧动画
|
||
core.material.icons.hero[one].midFoot = 2;
|
||
});
|
||
|
||
var heroMoving = function (timestamp) {
|
||
if (core.status.heroMoving <= 0) return;
|
||
if (timestamp - core.animateFrame.moveTime > core.values.moveSpeed) {
|
||
core.animateFrame.leftLeg++;
|
||
core.animateFrame.moveTime = timestamp;
|
||
}
|
||
core.drawHero(['stop', 'leftFoot', 'midFoot', 'rightFoot'][core.animateFrame.leftLeg % 4], 4 * core.status.heroMoving);
|
||
}
|
||
core.registerAnimationFrame('heroMoving', true, heroMoving);
|
||
|
||
core.events._eventMoveHero_moving = function (step, moveSteps) {
|
||
var curr = moveSteps[0];
|
||
var direction = curr[0], x = core.getHeroLoc('x'), y = core.getHeroLoc('y');
|
||
// ------ 前进/后退
|
||
var o = direction == 'backward' ? -1 : 1;
|
||
if (direction == 'forward' || direction == 'backward') direction = core.getHeroLoc('direction');
|
||
var faceDirection = direction;
|
||
if (direction == 'leftup' || direction == 'leftdown') faceDirection = 'left';
|
||
if (direction == 'rightup' || direction == 'rightdown') faceDirection = 'right';
|
||
core.setHeroLoc('direction', direction);
|
||
if (curr[1] <= 0) {
|
||
core.setHeroLoc('direction', faceDirection);
|
||
moveSteps.shift();
|
||
return true;
|
||
}
|
||
if (step <= 4) core.drawHero('stop', 4 * o * step);
|
||
else if (step <= 8) core.drawHero('leftFoot', 4 * o * step);
|
||
else if (step <= 12) core.drawHero('midFoot', 4 * o * (step - 8));
|
||
else if (step <= 16) core.drawHero('rightFoot', 4 * o * (step - 8)); // if (step == 8) {
|
||
if (step == 8 || step == 16) {
|
||
core.setHeroLoc('x', x + o * core.utils.scan2[direction].x, true);
|
||
core.setHeroLoc('y', y + o * core.utils.scan2[direction].y, true);
|
||
core.updateFollowers();
|
||
curr[1]--;
|
||
if (curr[1] <= 0) moveSteps.shift();
|
||
core.setHeroLoc('direction', faceDirection);
|
||
return step == 16;
|
||
}
|
||
return false;
|
||
}
|
||
},
|
||
"routeFixing": function () {
|
||
// 是否开启本插件,true 表示启用,false 表示禁用。
|
||
var __enable = true;
|
||
if (!__enable) return;
|
||
/*
|
||
使用说明:启用本插件后,录像回放时您可以用数字键1或6分别切换到原速或24倍速,
|
||
暂停播放时按数字键7(电脑按N)可以单步播放。(手机端可以点击难度单词切换出数字键)
|
||
数字键2-5可以进行录像自助精修,具体描述见下(实际弹窗请求您输入时不要带有任何空格):
|
||
|
||
up down left right 勇士向某个方向「行走一步或撞击」
|
||
item:ID 使用某件道具,如 item:bomb 表示使用炸弹
|
||
unEquip:n 卸掉身上第(n+1)件装备(n从0开始),如 unEquip:1 默认表示卸掉盾牌
|
||
equip:ID 穿上某件装备,如 equip:sword1 表示装上铁剑
|
||
saveEquip:n 将身上的当前套装保存到第n套快捷套装(n从0开始)
|
||
loadEquip:n 快捷换上之前保存好的第n套套装
|
||
fly:ID 使用楼传飞到某一层,如 fly:MT10 表示飞到主塔10层
|
||
choices:none 确认框/选择项「超时」(作者未设置超时时间则此项视为缺失)
|
||
choices:n 确认框/选择项选择第(n+1)项(选择项n从0开始,确认框n为0表示「确定」,1表示「取消」)
|
||
选择项n为负数时表示选择倒数第 -n 项,如 -1 表示最后一项(V2.8.2起标准全局商店的「离开」项)
|
||
此项缺失的话,确认框将选择作者指定的默认项(初始光标位置),选择项将弹窗请求补选(后台录像验证中选最后一项,可以复写函数来修改)
|
||
shop:ID 打开某个全局商店,如 shop:itemShop 表示打开道具商店。因此连载塔千万不要中途修改商店ID!
|
||
turn 单击勇士(Z键)转身,core.turnHero() 会产生此项,因此通过事件等方式强制让勇士转向应该用 core.setHeroLoc()
|
||
turn:dir 勇士转向某个方向,dir 可以为 up down left right(此项一般是读取自动存档产生的,属于样板的不良特性,请勿滥用)
|
||
getNext 轻按获得身边道具,优先获得面前的(面前没有则按上下左右顺序依次获得),身边如果没有道具则此项会被跳过
|
||
input:none “等待用户操作事件”中超时(作者未设置超时时间则此项会导致报错)
|
||
input:xxx 可能表示“等待用户操作事件”的一个操作(如按键操作将直接记录 input:keycode ),
|
||
也可能表示一个“接受用户输入数字”的输入,后者的情况下 xxx 为输入的整数。此项缺失的话前者将直接报错,后者将用0代替(后者现在支持负数了)
|
||
input2:xxx 可能表示“读取全局存储(core.getGlobal)”读取到的值,也可能表示一个“接受用户输入文本”的输入,
|
||
两种情况下 xxx 都为 base64 编码。此项缺失的话前者将重新现场读取,后者将用空字符串代替
|
||
no 走到可穿透的楼梯上不触发楼层切换事件,通过本插件可以让勇士停在旁边没有障碍物的楼梯上哦~
|
||
move:x:y 尝试瞬移到 [x,y] 点(不改变朝向),该点甚至可以和勇士相邻或者位于视野外
|
||
key:n 松开键值为n的键,如 key:49 表示松开大键盘数字键1,默认会触发使用破墙镐
|
||
click:n:px:py 点击自绘状态栏,n为0表示横屏1表示竖屏,[px,py] 为点击的像素坐标
|
||
random:n 生成了随机数n,即 core.rand2(num) 的返回结果,n必须在 [0,num-1] 范围,num必须为正整数。此项缺失将导致现场重新随机生成数值,可能导致回放结果不一致!
|
||
作者自定义的新项(一般为js对象,可以先JSON.stringify()再core.encodeBase64()得到纯英文数字的内容)需要用(半角圆括弧)括起来。
|
||
|
||
当您使用数字键5将一些项追加到即将播放内容的开头时,请注意要逆序逐项追加,或者每追加一项就按下数字键7或字母键N单步播放一步。
|
||
但是【input input2 random choices】是被动读取的,单步播放如果触发了相应的事件就会连续读取,这时候只能提前逐项追加好。
|
||
电脑端熟练以后推荐直接在控制台操作 core.status.route 和 core.status.replay.toReplay(后者录像回放时才有),配合 core.push() 和 core.unshift() 更加灵活自由哦!
|
||
*/
|
||
core.actions.registerAction('onkeyUp', '_sys_onkeyUp_replay', function (e) {
|
||
if (this._checkReplaying()) {
|
||
if (e.keyCode == 27) // ESCAPE
|
||
core.stopReplay();
|
||
else if (e.keyCode == 90) // Z
|
||
core.speedDownReplay();
|
||
else if (e.keyCode == 67) // C
|
||
core.speedUpReplay();
|
||
else if (e.keyCode == 32) // SPACE
|
||
core.triggerReplay();
|
||
else if (e.keyCode == 65) // A
|
||
core.rewindReplay();
|
||
else if (e.keyCode == 83) // S
|
||
core.control._replay_SL();
|
||
else if (e.keyCode == 88) // X
|
||
core.control._replay_book();
|
||
else if (e.keyCode == 33 || e.keyCode == 34) // PgUp/PgDn
|
||
core.control._replay_viewMap();
|
||
else if (e.keyCode == 78) // N
|
||
core.stepReplay();
|
||
else if (e.keyCode == 84) // T
|
||
core.control._replay_toolbox();
|
||
else if (e.keyCode == 81) // Q
|
||
core.control._replay_equipbox();
|
||
else if (e.keyCode == 66) // B
|
||
core.ui._drawStatistics();
|
||
else if (e.keyCode == 49 || e.keyCode == 54) // 1/6,原速/24倍速播放
|
||
core.setReplaySpeed(e.keyCode == 49 ? 1 : 24);
|
||
else if (e.keyCode > 49 && e.keyCode < 54) { // 2-5,录像精修
|
||
switch (e.keyCode - 48) {
|
||
case 2: // pop
|
||
alert("您已移除已录制内容的最后一项:" + core.status.route.pop());
|
||
break;
|
||
case 3: // push
|
||
core.utils.myprompt("请输入您要追加到已录制内容末尾的项:", "", function (value) {
|
||
if (value != null) core.status.route.push(value);
|
||
});
|
||
break;
|
||
case 4: // shift
|
||
alert("您已移除即将播放内容的第一项:" + core.status.replay.toReplay.shift());
|
||
break;
|
||
case 5: // unshift
|
||
core.utils.myprompt("请输入您要追加到即将播放内容开头的项:", "", function (value) {
|
||
if (value != null) core.status.replay.toReplay.unshift(value);
|
||
});
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
}, 100);
|
||
},
|
||
"numpad": function () {
|
||
// 样板自带的整数输入事件为白屏弹窗且可以误输入任意非法内容但不支持负整数,观感较差。本插件可以将其美化成仿RM样式,使其支持负整数同时带有音效
|
||
// 另一方面,4399等第三方平台不允许使用包括 core.myprompt() 和 core.myconfirm() 在内的弹窗,因此也需要此插件来替代,不然类似生命魔杖的道具就不好实现了
|
||
// 关于负整数输入,V2.8.2原生支持其录像的压缩和解压,只是默认的 core.events._action_input() 函数将负数取了绝对值,可以只复写下面的 core.isReplaying() 部分来取消
|
||
|
||
// 是否启用本插件,false表示禁用,true表示启用
|
||
var __enable = true;
|
||
if (!__enable) return;
|
||
|
||
core.events._action_input = function (data, x, y, prefix) { // 复写整数输入事件
|
||
if (core.isReplaying()) { // 录像回放时,处理方式不变,但增加负整数支持
|
||
core.events.__action_getInput(core.replaceText(data.text, prefix), false, function (value) {
|
||
value = parseInt(value) || 0; // 去掉了取绝对值的步骤
|
||
core.status.route.push("input:" + value);
|
||
core.setFlag("input", value);
|
||
core.doAction();
|
||
});
|
||
} else {
|
||
// 正常游戏中,采用暂停录制的方式然后用事件流循环“绘制-等待-变量操作”三板斧实现(按照13*13适配的)。
|
||
// 您可以自行修改循环内的内容来适配15*15或其他需求,或干脆作为公共事件编辑。
|
||
core.insertAction([
|
||
// 记录当前录像长度,下面的循环结束后裁剪。达到“暂停录制”的效果
|
||
{ "type": "function", "function": "function(){flags['@temp@length']=core.status.route.length}" },
|
||
{ "type": "setValue", "name": "flag:input", "value": "0" },
|
||
{
|
||
"type": "while",
|
||
"condition": "true",
|
||
"data": [
|
||
{ "type": "drawBackground", "background": "winskin.png", "x": 16, "y": 16, "width": 384, "height": 384 },
|
||
{ "type": "drawIcon", "id": "X10181", "x": 32, "y": 288 },
|
||
{ "type": "drawIcon", "id": "X10185", "x": 64, "y": 288 },
|
||
{ "type": "drawIcon", "id": "X10186", "x": 96, "y": 288 },
|
||
{ "type": "drawIcon", "id": "X10187", "x": 128, "y": 288 },
|
||
{ "type": "drawIcon", "id": "X10188", "x": 160, "y": 288 },
|
||
{ "type": "drawIcon", "id": "X10189", "x": 192, "y": 288 },
|
||
{ "type": "drawIcon", "id": "X10193", "x": 224, "y": 288 },
|
||
{ "type": "drawIcon", "id": "X10194", "x": 256, "y": 288 },
|
||
{ "type": "drawIcon", "id": "X10195", "x": 288, "y": 288 },
|
||
{ "type": "drawIcon", "id": "X10196", "x": 320, "y": 288 },
|
||
{ "type": "drawIcon", "id": "X10197", "x": 352, "y": 288 },
|
||
{ "type": "drawIcon", "id": "X10286", "x": 32, "y": 352 },
|
||
{ "type": "drawIcon", "id": "X10169", "x": 96, "y": 352 },
|
||
{ "type": "drawIcon", "id": "X10232", "x": 128, "y": 352 },
|
||
{ "type": "drawIcon", "id": "X10185", "x": 320, "y": 352 },
|
||
{ "type": "drawIcon", "id": "X10242", "x": 352, "y": 352 },
|
||
{ "type": "fillBoldText", "x": 48, "y": 256, "style": [255, 255, 255, 1], "font": "bold 32px Consolas", "text": "${flag:input}" },
|
||
{ "type": "fillBoldText", "x": 32, "y": 48, "style": [255, 255, 255, 1], "font": "16px Consolas", "text": core.replaceText(data.text, prefix) },
|
||
{
|
||
"type": "wait",
|
||
"forceChild": true,
|
||
"data": [{
|
||
"case": "keyboard",
|
||
"keycode": "48,49,50,51,52,53,54,55,56,57",
|
||
"action": [
|
||
// 按下数字键,追加到已输入内容的末尾,但禁止越界。变量:keycode-48就是末位数字
|
||
{ "type": "playSound", "name": "光标移动" },
|
||
{
|
||
"type": "if",
|
||
"condition": "(flag:input<0)",
|
||
"true": [
|
||
{ "type": "setValue", "name": "flag:input", "value": "10*flag:input-(flag:keycode-48)" },
|
||
],
|
||
"false": [
|
||
{ "type": "setValue", "name": "flag:input", "value": "10*flag:input+(flag:keycode-48)" },
|
||
]
|
||
},
|
||
{ "type": "setValue", "name": "flag:input", "value": "core.clamp(flag:input,-9e15,9e15)" },
|
||
]
|
||
},
|
||
{
|
||
"case": "keyboard",
|
||
"keycode": "189",
|
||
"action": [
|
||
// 按下减号键,变更已输入内容的符号
|
||
{ "type": "playSound", "name": "跳跃" },
|
||
{ "type": "setValue", "name": "flag:input", "value": "-flag:input" },
|
||
]
|
||
},
|
||
{
|
||
"case": "keyboard",
|
||
"keycode": "8",
|
||
"action": [
|
||
// 按下退格键,从已输入内容的末尾删除一位
|
||
{ "type": "playSound", "name": "取消" },
|
||
{ "type": "setValue", "name": "flag:input", "operator": "//=", "value": "10" },
|
||
]
|
||
},
|
||
{
|
||
"case": "keyboard",
|
||
"keycode": "27",
|
||
"action": [
|
||
// 按下ESC键,清空已输入内容
|
||
{ "type": "playSound", "name": "读档" },
|
||
{ "type": "setValue", "name": "flag:input", "value": "0" },
|
||
]
|
||
},
|
||
{
|
||
"case": "keyboard",
|
||
"keycode": "13",
|
||
"action": [
|
||
// 按下回车键,确定
|
||
{ "type": "break", "n": 1 },
|
||
]
|
||
},
|
||
{
|
||
"case": "mouse",
|
||
"px": [32, 63],
|
||
"py": [288, 320],
|
||
"action": [
|
||
// 点击减号,变号。右边界写63防止和下面重叠
|
||
{ "type": "playSound", "name": "跳跃" },
|
||
{ "type": "setValue", "name": "flag:input", "value": "-flag:input" },
|
||
]
|
||
},
|
||
{
|
||
"case": "mouse",
|
||
"px": [64, 384],
|
||
"py": [288, 320],
|
||
"action": [
|
||
// 点击数字,追加到已输入内容的末尾,但禁止越界。变量:x-2就是末位数字
|
||
{ "type": "playSound", "name": "光标移动" },
|
||
{
|
||
"type": "if",
|
||
"condition": "(flag:input<0)",
|
||
"true": [
|
||
{ "type": "setValue", "name": "flag:input", "value": "10*flag:input-(flag:x-2)" },
|
||
],
|
||
"false": [
|
||
{ "type": "setValue", "name": "flag:input", "value": "10*flag:input+(flag:x-2)" },
|
||
]
|
||
},
|
||
{ "type": "setValue", "name": "flag:input", "value": "core.clamp(flag:input,-9e15,9e15)" },
|
||
]
|
||
},
|
||
{
|
||
"case": "mouse",
|
||
"px": [32, 64],
|
||
"py": [352, 384],
|
||
"action": [
|
||
// 点击左箭头,退格
|
||
{ "type": "playSound", "name": "取消" },
|
||
{ "type": "setValue", "name": "flag:input", "operator": "//=", "value": "10" },
|
||
]
|
||
},
|
||
{
|
||
"case": "mouse",
|
||
"px": [96, 160],
|
||
"py": [352, 384],
|
||
"action": [
|
||
// 点击CE,清空
|
||
{ "type": "playSound", "name": "读档" },
|
||
{ "type": "setValue", "name": "flag:input", "value": "0" },
|
||
]
|
||
},
|
||
{
|
||
"case": "mouse",
|
||
"px": [320, 384],
|
||
"py": [352, 384],
|
||
"action": [
|
||
// 点击OK,确定
|
||
{ "type": "break", "n": 1 },
|
||
]
|
||
}
|
||
]
|
||
}
|
||
]
|
||
},
|
||
{ "type": "clearMap" },
|
||
// 裁剪录像,只保留'input:n',然后继续录制
|
||
{ "type": "function", "function": "function(){core.status.route.splice(flags['@temp@length']);core.status.route.push('input:'+core.getFlag('input',0))}" }
|
||
], x, y);
|
||
core.events.doAction();
|
||
}
|
||
}
|
||
},
|
||
"sprites": function () {
|
||
// 基于canvas的sprite化,摘编整理自万宁魔塔
|
||
//
|
||
// ---------------------------------------- 第一部分 js代码 (必装) --------------------------------------- //
|
||
|
||
/* ---------------- 用法说明 ---------------- *
|
||
* 1. 创建sprite: var sprite = new Sprite(x, y, w, h, z, reference, name);
|
||
* 其中x y w h为画布的横纵坐标及长宽,reference为参考系,只能填game(相对于游戏画面)和window(相对于窗口)
|
||
* 且当为相对游戏画面时,长宽与坐标将会乘以放缩比例(相当于用createCanvas创建)
|
||
* z为纵深,表示不同元素之间的覆盖关系,大的覆盖小的
|
||
* name为自定义名称,可以不填
|
||
* 2. 删除: sprite.destroy();
|
||
* 3. 设置css特效: sprite.setCss(css);
|
||
* 其中css直接填 box-shadow: 0px 0px 10px black;的形式即可,与style标签与css文件内写法相同
|
||
* 对于已设置的特效,如果之后不需要再次设置,可以不填
|
||
* 4. 添加事件监听器: sprite.addEventListener(); 用法与html元素的addEventListener完全一致
|
||
* 5. 移除事件监听器: sprite.removeEventListener(); 用法与html元素的removeEventListener完全一致
|
||
* 6. 属性列表
|
||
* (1) sprite.x | sprite.y | sprite.width | sprite.height | sprite.zIndex | sprite.reference 顾名思义
|
||
* (2) sprite.canvas 该sprite的画布
|
||
* (3) sprite.context 该画布的CanvasRenderingContext2d对象,即样板中常见的ctx
|
||
* (4) sprite.count 不要改这个玩意
|
||
* 7. 使用样板api进行绘制
|
||
* 示例:
|
||
* var ctx = sprite.context;
|
||
* core.fillText(ctx, 'xxx', 100, 100);
|
||
* core.fillRect(ctx, 0, 0, 50, 50);
|
||
* 当然也可以使用原生js
|
||
* ctx.moveTo(0, 0);
|
||
* ctx.bezierCurveTo(50, 50, 100, 0, 100, 50);
|
||
* ctx.stroke();
|
||
* ---------------- 用法说明 ---------------- */
|
||
|
||
var count = 0;
|
||
|
||
/** 创建一个sprite画布
|
||
* @param {number} x
|
||
* @param {number} y
|
||
* @param {number} w
|
||
* @param {number} h
|
||
* @param {number} z
|
||
* @param {'game' | 'window'} reference 参考系,游戏画面或者窗口
|
||
* @param {string} name 可选,sprite的名称,方便通过core.dymCanvas获取
|
||
*/
|
||
function Sprite (x, y, w, h, z, reference, name) {
|
||
this.x = x;
|
||
this.y = y;
|
||
this.width = w;
|
||
this.height = h;
|
||
this.zIndex = z;
|
||
this.reference = reference;
|
||
this.canvas = null;
|
||
this.context = null;
|
||
this.count = 0;
|
||
this.name = name || '_sprite_' + count;
|
||
this.style = null;
|
||
/** 初始化 */
|
||
this.init = function () {
|
||
if (reference === 'window') {
|
||
var canvas = document.createElement('canvas');
|
||
this.canvas = canvas;
|
||
this.context = canvas.getContext('2d');
|
||
canvas.width = w;
|
||
canvas.height = h;
|
||
canvas.style.width = w + 'px';
|
||
canvas.style.height = h + 'px';
|
||
canvas.style.position = 'absolute';
|
||
canvas.style.top = y + 'px';
|
||
canvas.style.left = x + 'px';
|
||
canvas.style.zIndex = z.toString();
|
||
document.body.appendChild(canvas);
|
||
this.style = canvas.style;
|
||
} else {
|
||
this.context = core.createCanvas(this.name || '_sprite_' + count, x, y, w, h, z);
|
||
this.canvas = this.context.canvas;
|
||
this.canvas.style.pointerEvents = 'auto';
|
||
this.style = this.canvas.style;
|
||
}
|
||
this.count = count;
|
||
count++;
|
||
}
|
||
this.init();
|
||
|
||
/** 设置css特效
|
||
* @param {string} css
|
||
*/
|
||
this.setCss = function (css) {
|
||
css = css.replace('\n', ';').replace(';;', ';');
|
||
var effects = css.split(';');
|
||
var self = this;
|
||
effects.forEach(function (v) {
|
||
var content = v.split(':');
|
||
var name = content[0];
|
||
var value = content[1];
|
||
name = name.trim().split('-').reduce(function (pre, curr, i, a) {
|
||
if (i === 0 && curr !== '') return curr;
|
||
if (a[0] === '' && i === 1) return curr;
|
||
return pre + curr.toUpperCase()[0] + curr.slice(1);
|
||
}, '');
|
||
var canvas = self.canvas;
|
||
if (name in canvas.style) canvas.style[name] = value;
|
||
});
|
||
return this;
|
||
}
|
||
|
||
/**
|
||
* 移动sprite
|
||
* @param {boolean} isDelta 是否是相对位置,如果是,那么sprite会相对于原先的位置进行移动
|
||
*/
|
||
this.move = function (x, y, isDelta) {
|
||
if (x !== undefined && x !== null) this.x = x;
|
||
if (y !== undefined && y !== null) this.y = y;
|
||
if (this.reference === 'window') {
|
||
var ele = this.canvas;
|
||
ele.style.left = x + (isDelta ? parseFloat(ele.style.left) : 0) + 'px';
|
||
ele.style.top = y + (isDelta ? parseFloat(ele.style.top) : 0) + 'px';
|
||
} else core.relocateCanvas(this.context, x, y, isDelta);
|
||
return this;
|
||
}
|
||
|
||
/**
|
||
* 重新设置sprite的大小
|
||
* @param {boolean} styleOnly 是否只修改css效果,如果是,那么将会不高清,如果不是,那么会清空画布
|
||
*/
|
||
this.resize = function (w, h, styleOnly) {
|
||
if (w !== undefined && w !== null) this.w = w;
|
||
if (h !== undefined && h !== null) this.h = h;
|
||
if (reference === 'window') {
|
||
var ele = this.canvas;
|
||
ele.style.width = w + 'px';
|
||
ele.style.height = h + 'px';
|
||
if (!styleOnly) {
|
||
ele.width = w;
|
||
ele.height = h;
|
||
}
|
||
} else core.resizeCanvas(this.context, w, h, styleOnly);
|
||
return this;
|
||
}
|
||
|
||
/**
|
||
* 旋转画布
|
||
*/
|
||
this.rotate = function (angle, cx, cy) {
|
||
if (this.reference === 'window') {
|
||
var left = this.x;
|
||
var top = this.y;
|
||
this.canvas.style.transformOrigin = (cx - left) + 'px ' + (cy - top) + 'px';
|
||
if (angle === 0) {
|
||
canvas.style.transform = '';
|
||
} else {
|
||
canvas.style.transform = 'rotate(' + angle + 'deg)';
|
||
}
|
||
} else {
|
||
core.rotateCanvas(this.context, angle, cx, cy);
|
||
}
|
||
return this;
|
||
}
|
||
|
||
/**
|
||
* 清除sprite
|
||
*/
|
||
this.clear = function (x, y, w, h) {
|
||
if (this.reference === 'window') {
|
||
this.context.clearRect(x, y, w, h);
|
||
} else {
|
||
core.clearMap(this.context, x, y, w, h);
|
||
}
|
||
return this;
|
||
}
|
||
|
||
/** 删除 */
|
||
this.destroy = function () {
|
||
if (this.reference === 'window') {
|
||
if (this.canvas) document.body.removeChild(this.canvas);
|
||
} else {
|
||
core.deleteCanvas(this.name || '_sprite_' + this.count);
|
||
}
|
||
}
|
||
|
||
/** 添加事件监听器 */
|
||
this.addEventListener = function () {
|
||
this.canvas.addEventListener.apply(this.canvas, arguments);
|
||
}
|
||
|
||
/** 移除事件监听器 */
|
||
this.removeEventListener = function () {
|
||
this.canvas.removeEventListener.apply(this.canvas, arguments);
|
||
}
|
||
}
|
||
|
||
window.Sprite = Sprite;
|
||
},
|
||
"跳字": function () {
|
||
// 在此增加新插件
|
||
this.tiaozi1 = function (neirong, yanse) { //跳字一
|
||
if (core.status.replay.replaying) {} else {
|
||
core.createCanvas('tiaozi', 0, 0, 416, 416, 77);
|
||
core.setFlag("tiaozizhong", core.getFlag("tiaozizhong", 0) + 1);
|
||
var tiaozihao = core.getFlag("tiaozizhong");
|
||
var shangsheng = 1;
|
||
var gaodu = 0;
|
||
var herox = core.status.hero.loc.x,
|
||
heroy = core.status.hero.loc.y;
|
||
var fade = setInterval(function () {
|
||
core.clearMap('tiaozi', 0, 0, 416, 416);
|
||
if (gaodu >= -6 && shangsheng == 1) {
|
||
gaodu = gaodu - 1;
|
||
if (gaodu == -6) { shangsheng = 0 }
|
||
} else if (gaodu <= 12) {
|
||
gaodu = gaodu + 1;
|
||
if (gaodu == 12) { var tiaozizhong = 1 }
|
||
};
|
||
core.fillText('tiaozi', neirong, herox * 32 - 13, heroy * 32 + gaodu, yanse, "bold 17px Verdana");
|
||
if (tiaozizhong == 1 || core.getFlag("tiaozizhong") > tiaozihao) {
|
||
core.setFlag("tiaozizhong", core.getFlag("tiaozizhong", 0) - 1);
|
||
core.clearMap('tiaozi', 0, 0, 416, 416);
|
||
clearInterval(fade);
|
||
}
|
||
}, 16);
|
||
}
|
||
}
|
||
|
||
this.tiaozi2 = function (neirong1, neirong2, yanse1, yanse2) { //二段跳字
|
||
if (core.status.replay.replaying) {} else {
|
||
core.createCanvas('tiaozi', 0, 0, 416, 416, 77);
|
||
core.setFlag("tiaozizhong", core.getFlag("tiaozizhong", 0) + 1);
|
||
var tiaozihao = core.getFlag("tiaozizhong");
|
||
var shangsheng = 1;
|
||
var gaodu = 0;
|
||
var huanzi = 0;
|
||
var herox = core.status.hero.loc.x,
|
||
heroy = core.status.hero.loc.y;
|
||
var fade = setInterval(function () {
|
||
core.clearMap('tiaozi', 0, 0, 416, 416);
|
||
if (gaodu >= -6 && shangsheng == 1) {
|
||
gaodu = gaodu - 1;
|
||
if (gaodu == -6) { shangsheng = 0 }
|
||
} else if (gaodu <= 12) {
|
||
gaodu = gaodu + 1;
|
||
if (gaodu == 12) {
|
||
if (huanzi == 1) { var tiaozizhong = 1 } else {
|
||
huanzi = 1;
|
||
gaodu = 0;
|
||
shangsheng = 1;
|
||
}
|
||
}
|
||
};
|
||
if (huanzi == 0) core.fillText('tiaozi', neirong1, herox * 32 - 13, heroy * 32 + gaodu, yanse1, "bold 17px Verdana");
|
||
else core.fillText('tiaozi', neirong2, herox * 32 - 13, heroy * 32 + gaodu, yanse2, "bold 17px Verdana");
|
||
if (tiaozizhong == 1 || core.getFlag("tiaozizhong") > tiaozihao) {
|
||
core.setFlag("tiaozizhong", core.getFlag("tiaozizhong", 0) - 1);
|
||
core.clearMap('tiaozi', 0, 0, 416, 416);
|
||
clearInterval(fade);
|
||
}
|
||
}, 16);
|
||
}
|
||
}
|
||
|
||
this.tiaozi3 = function (neirong1, neirong2, neirong3, yanse1, yanse2, yanse3) { //三段跳字
|
||
if (core.status.replay.replaying) {} else {
|
||
core.createCanvas('tiaozi', 0, 0, 416, 416, 77);
|
||
core.setFlag("tiaozizhong", core.getFlag("tiaozizhong", 0) + 1);
|
||
var tiaozihao = core.getFlag("tiaozizhong");
|
||
var shangsheng = 1;
|
||
var gaodu = 0;
|
||
var huanzi = 0;
|
||
var herox = core.status.hero.loc.x,
|
||
heroy = core.status.hero.loc.y;
|
||
var fade = setInterval(function () {
|
||
core.clearMap('tiaozi', 0, 0, 416, 416);
|
||
if (gaodu >= -6 && shangsheng == 1) {
|
||
gaodu = gaodu - 1;
|
||
if (gaodu == -6) { shangsheng = 0 }
|
||
} else if (gaodu <= 12) {
|
||
gaodu = gaodu + 1;
|
||
if (gaodu == 12) {
|
||
switch (huanzi) {
|
||
case 0:
|
||
{
|
||
huanzi = 1;
|
||
gaodu = 0;
|
||
shangsheng = 1;
|
||
};
|
||
break;
|
||
case 1:
|
||
{
|
||
huanzi = 2;
|
||
gaodu = 0;
|
||
shangsheng = 1;
|
||
};
|
||
break;
|
||
case 2:
|
||
var tiaozizhong = 1;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
switch (huanzi) {
|
||
case 0:
|
||
core.fillText('tiaozi', neirong1, herox * 32 - 13, heroy * 32 + gaodu, yanse1, "bold 17px Verdana");
|
||
break;
|
||
case 1:
|
||
core.fillText('tiaozi', neirong2, herox * 32 - 13, heroy * 32 + gaodu, yanse2, "bold 17px Verdana");
|
||
break;
|
||
case 2:
|
||
core.fillText('tiaozi', neirong3, herox * 32 - 13, heroy * 32 + gaodu, yanse3, "bold 17px Verdana");
|
||
break;
|
||
}
|
||
if (tiaozizhong == 1 || core.getFlag("tiaozizhong") > tiaozihao) {
|
||
core.setFlag("tiaozizhong", core.getFlag("tiaozizhong", 0) - 1);
|
||
core.clearMap('tiaozi', 0, 0, 416, 416);
|
||
clearInterval(fade);
|
||
}
|
||
}, 16);
|
||
}
|
||
}
|
||
this.donghuas = function () {
|
||
core.plugin.donghua();
|
||
for (var i = 1; i <= 20; i++)
|
||
if (core.plugin['donghua' + i]) core.plugin['donghua' + i]();
|
||
}
|
||
this.donghua = function () {
|
||
if (core.status.floorId == "MT0") {
|
||
if (core.isReplaying()) {setTimeout(core.plugin.donghua, 100); return;}
|
||
core.setFlag("linshi", core.drawAnimate("jingu", 10, 10, false, function () {
|
||
|
||
core.plugin.donghua();
|
||
}));
|
||
} else core.stopAnimate(core.getFlag("linshi", 0), false);
|
||
|
||
}
|
||
this.donghua1 = function () {
|
||
if (core.status.floorId == "MT14") {
|
||
core.setFlag("linshi1", core.drawAnimate("dianji", 4, 5, false, function () {
|
||
|
||
core.plugin.donghua1();
|
||
}));
|
||
} else core.stopAnimate(core.getFlag("linshi1", 0), false);
|
||
}
|
||
this.donghua2 = function () {
|
||
if (core.status.floorId == "MT14") {
|
||
core.setFlag("linshi2", core.drawAnimate("dianji", 10, 5, false, function () {
|
||
|
||
core.plugin.donghua2();
|
||
}));
|
||
} else core.stopAnimate(core.getFlag("linshi2", 0), false);
|
||
}
|
||
this.donghua3 = function () {
|
||
if (core.getFlag("poison")) {
|
||
core.setFlag("linshi3", core.drawHeroAnimate("dufa",
|
||
function () {
|
||
core.plugin.donghua3();
|
||
}));
|
||
} else core.stopAnimate(core.getFlag("linshi3", 0), false);
|
||
|
||
}
|
||
this.donghua4 = function () {
|
||
if (core.getFlag("bofang", 0) == 1) {
|
||
core.setFlag("linshi4", core.drawHeroAnimate("STruoli",
|
||
function () {
|
||
core.plugin.donghua4();
|
||
}));
|
||
} else core.stopAnimate(core.getFlag("linshi4", 0), false);
|
||
|
||
}
|
||
this.donghua5 = function () {
|
||
if (core.getFlag("bofang", 0) == 1) {
|
||
core.setFlag("linshi5", core.drawHeroAnimate("lansebaofa",
|
||
function () {
|
||
core.plugin.donghua5();
|
||
}));
|
||
} else core.stopAnimate(core.getFlag("linshi5", 0), false);
|
||
|
||
}
|
||
this.donghua6 = function () {
|
||
if (core.getFlag("bofang", 0) == 1) {
|
||
if (core.status.floorId == "MT81") {
|
||
core.setFlag("linshi6", core.drawAnimate("shenlanbaofa", 7, 5, false, function () {
|
||
|
||
core.plugin.donghua6();
|
||
}));
|
||
} else core.stopAnimate(core.getFlag("linshi6", 0), false);
|
||
}
|
||
}
|
||
this.donghua7 = function () {
|
||
if (core.status.floorId == "MT64") {
|
||
if (core.getPlayingAnimates().includes(core.getFlag("linshi7", 0))) return;
|
||
core.setFlag("linshi7", core.drawAnimate("jingu", 7, 1, false, function () {
|
||
|
||
core.plugin.donghua7();
|
||
}));
|
||
} else core.stopAnimate(core.getFlag("linshi7", 0), false);
|
||
|
||
|
||
}
|
||
this.donghua8 = function () {
|
||
if (core.getFlag("bofang8", 0) == 1) {
|
||
if (core.status.floorId == "jiange") {
|
||
core.setFlag("linshi8", core.drawAnimate("lvbaofa", 9, 8, false, function () {
|
||
|
||
core.plugin.donghua8();
|
||
}));
|
||
} else core.stopAnimate(core.getFlag("linshi8", 0), false);
|
||
}
|
||
}
|
||
this.donghua9 = function () {
|
||
if (core.getFlag("bofang9", 0) == 1) {
|
||
core.setFlag("linshi9", core.drawHeroAnimate("lansebaofa",
|
||
function () {
|
||
core.plugin.donghua9();
|
||
}));
|
||
} else core.stopAnimate(core.getFlag("linshi9", 0), false);
|
||
|
||
}
|
||
},
|
||
"楼层切换": function () {
|
||
// 在此增加新插件
|
||
////// 楼层切换 //////
|
||
core.events.changeFloor = function (floorId, stair, heroLoc, time, callback) {
|
||
var info = this._changeFloor_getInfo(floorId, stair, heroLoc, time);
|
||
var tempCanvas = {};
|
||
core.createCanvas("first", 0, 0, core.__PIXELS__, core.__PIXELS__, 61);
|
||
if (!core.isReplaying()) {
|
||
tempCanvas = core.createCanvas("_save_", 0, 0, core.__PIXELS__, core.__PIXELS__);
|
||
core.clearMap("_save_");
|
||
core.drawImage(tempCanvas, core.dom.gameCanvas.bg, 0, 0, core.__PIXELS__, core.__PIXELS__);
|
||
core.drawImage(tempCanvas, core.dom.gameCanvas.event, 0, 0, core.__PIXELS__, core.__PIXELS__);
|
||
core.drawImage(tempCanvas, core.dom.gameCanvas.event2, 0, 0, core.__PIXELS__, core.__PIXELS__);
|
||
core.drawImage(tempCanvas, core.dom.gameCanvas.fg, 0, 0, core.__PIXELS__, core.__PIXELS__);
|
||
}
|
||
|
||
info.tempCanvas = tempCanvas.canvas;
|
||
if (info == null) {
|
||
if (callback) callback();
|
||
return;
|
||
}
|
||
floorId = info.floorId;
|
||
info.locked = core.status.lockControl;
|
||
|
||
core.dom.floorNameLabel.innerText = core.status.maps[floorId].title;
|
||
core.lockControl();
|
||
core.stopAutomaticRoute();
|
||
core.clearContinueAutomaticRoute();
|
||
core.status.replay.animate = true;
|
||
clearInterval(core.interval.onDownInterval);
|
||
core.interval.onDownInterval = 'tmp';
|
||
|
||
this._changeFloor_beforeChange(info, callback);
|
||
}
|
||
|
||
core.events._changeFloor_beforeChange = function (info, callback) {
|
||
this._changeFloor_playSound();
|
||
// 需要 setTimeout 执行,不然会出错
|
||
window.setTimeout(function () {
|
||
core.events._changeFloor_changing(info, callback);
|
||
/*if (info.time == 0)
|
||
core.events._changeFloor_changing(info, callback);
|
||
else
|
||
core.showWithAnimate(core.dom.floorMsgGroup, info.time / 2, function () {
|
||
core.events._changeFloor_changing(info, callback);
|
||
});*/
|
||
}, 25)
|
||
}
|
||
|
||
core.events._changeFloor_changing = function (info, callback) {
|
||
this.changingFloor(info.floorId, info.heroLoc);
|
||
// 回归视角
|
||
var __lockViewport__ = flags.__lockViewport__;
|
||
core.setFlag('__lockViewport__', null);
|
||
core.drawHero();
|
||
core.setFlag('__lockViewport__', __lockViewport__);
|
||
var obj = core.getContextByName("first").canvas;
|
||
var end = function () {
|
||
clearInterval(core.__floor);
|
||
core.clearMap("first");
|
||
obj.style.opacity = 1;
|
||
obj.style.display = "block";
|
||
core.__floor = null;
|
||
}
|
||
var deleteCanvas = function () {
|
||
core.deleteCanvas("_save_");
|
||
info.tempCanvas = null;
|
||
}
|
||
|
||
if (info.time == 0 || main.mode != 'play') {
|
||
end();
|
||
deleteCanvas();
|
||
} else {
|
||
if (core.__floor) end();
|
||
core.drawImage("first", info.tempCanvas, 0, 0, core.__PIXELS__, core.__PIXELS__);
|
||
obj.style.opacity = 1;
|
||
var opacityVal = 1;
|
||
core.__floor = window.setInterval(function () {
|
||
opacityVal -= 0.03;
|
||
obj.style.opacity = opacityVal;
|
||
if (opacityVal < 0) {
|
||
end();
|
||
deleteCanvas();
|
||
}
|
||
}, info.time / 1.7);
|
||
}
|
||
core.events._changeFloor_afterChange(info, callback);
|
||
/*core.hideWithAnimate(core.dom.floorMsgGroup, info.time / 4, function () {
|
||
core.events._changeFloor_afterChange(info, callback);
|
||
});*/
|
||
}
|
||
},
|
||
"标题动画": function () {
|
||
|
||
|
||
var start = document.getElementById('startPanel');
|
||
var list = [];
|
||
var id = 0;
|
||
/*
|
||
// 标题
|
||
var title = document.getElementById('startTitle');
|
||
core.registerResize('startTitle', function () {
|
||
title.style.width = 300 * core.domStyle.scale + 'px';
|
||
title.style.height = 187 * core.domStyle.scale + 'px';
|
||
});
|
||
*/
|
||
|
||
// 星星动画,使用sprite化方法
|
||
function draw() {
|
||
if (start.style.display === 'none') return;
|
||
// 每帧有10%的概率出
|
||
if (Math.random() < 0.1) {
|
||
var config = {
|
||
x: Math.random() * 450 * core.domStyle.scale,
|
||
y: -187 * core.domStyle.scale,
|
||
id: id++
|
||
};
|
||
if (id > 100) id -= 100;
|
||
list.push(config);
|
||
// 追加新的ele
|
||
var img = document.createElement('img');
|
||
img.src = './project/images/Title_starlong.png';
|
||
img.style.position = 'absolute';
|
||
img.style.zIndex = '280';
|
||
img.style.left = config.x + 'px';
|
||
img.style.top = '0px';
|
||
img.style.transform = 'scale(' + core.domStyle.scale * 100 + '%)'
|
||
img.id = id + '_star';
|
||
list[list.length - 1].ele = img;
|
||
start.appendChild(img);
|
||
}
|
||
update();
|
||
}
|
||
|
||
// 每帧更新动画
|
||
function update() {
|
||
for (var i = 0; i < list.length; i++) {
|
||
// 一定要匀速运动
|
||
var one = list[i];
|
||
if (one.x < -154 * core.domStyle.scale) {
|
||
list.splice(i, 1);
|
||
i--;
|
||
one.ele.remove();
|
||
continue;
|
||
}
|
||
one.x -= 3 * core.domStyle.scale;
|
||
one.y += 3 * core.domStyle.scale;
|
||
one.ele.style.top = one.y + 'px';
|
||
one.ele.style.left = one.x + 'px';
|
||
}
|
||
}
|
||
core.registerAnimationFrame('startAnimation', false, draw);
|
||
},
|
||
"showValue": function () {
|
||
/* 宝石血瓶左下角显示数值
|
||
* 需要将 变量:itemDetail改为true才可正常运行
|
||
* 请尽量减少勇士的属性数量,否则可能会出现严重卡顿
|
||
* 注意:这里的属性必须是core.status.hero里面的,flag无法显示
|
||
* 如果不想显示,可以core.setFlag("itemDetail", false);
|
||
* 然后再core.getItemDetail();
|
||
* 如有bug在大群或造塔群@古祠
|
||
*/
|
||
|
||
// 谁tm在即捡即用效果里面调用带有含刷新状态栏的函数
|
||
var origin = core.control.updateStatusBar;
|
||
core.updateStatusBar = core.control.updateStatusBar = function () {
|
||
if (core.getFlag('__statistics__')) return;
|
||
else return origin.apply(core.control, arguments);
|
||
}
|
||
|
||
core.bigmap.threshold = 256;
|
||
|
||
core.control.updateDamage = function (floorId, ctx) {
|
||
floorId = floorId || core.status.floorId;
|
||
if (!floorId || core.status.gameOver || main.mode != 'play') return;
|
||
var onMap = ctx == null;
|
||
|
||
// 没有怪物手册
|
||
if (!core.hasItem('book')) return;
|
||
core.status.damage.posX = core.bigmap.posX;
|
||
core.status.damage.posY = core.bigmap.posY;
|
||
if (!onMap) {
|
||
var width = core.floors[floorId].width,
|
||
height = core.floors[floorId].height;
|
||
// 地图过大的缩略图不绘制显伤
|
||
if (width * height > core.bigmap.threshold) return;
|
||
}
|
||
this._updateDamage_damage(floorId, onMap);
|
||
this._updateDamage_extraDamage(floorId, onMap);
|
||
core.getItemDetail(floorId); // 宝石血瓶详细信息
|
||
this.drawDamage(ctx);
|
||
};
|
||
// 绘制地图显示
|
||
control.prototype._drawDamage_draw = function (ctx, onMap) {
|
||
if (!core.hasItem('book')) return;
|
||
// *** 下一句话可以更改你想要的显示字体
|
||
core.setFont(ctx, "bold 11px Arial");
|
||
// ***
|
||
core.setTextAlign(ctx, core.getFlag("isDamageRight") ? "right" : "left");
|
||
core.status.damage.data.forEach(function (one) {
|
||
var px = one.px,
|
||
py = one.py;
|
||
if (onMap && core.bigmap.v2) {
|
||
px -= core.bigmap.posX * 32;
|
||
py -= core.bigmap.posY * 32;
|
||
if (px < -32 * 2 || px > core.__PX__ + 32 || py < -32 || py > core.__PY__ + 32)
|
||
return;
|
||
}
|
||
core.fillBoldText(ctx, one.text, px + (core.getFlag("isDamageRight") ? 32 : 0), py, one.color);
|
||
});
|
||
core.setTextAlign(ctx, 'center');
|
||
core.status.damage.extraData.forEach(function (one) {
|
||
var px = one.px,
|
||
py = one.py;
|
||
if (onMap && core.bigmap.v2) {
|
||
px -= core.bigmap.posX * 32;
|
||
py -= core.bigmap.posY * 32;
|
||
if (px < -32 || px > core.__PX__ + 32 || py < -32 || py > core.__PY__ + 32)
|
||
return;
|
||
}
|
||
core.fillBoldText(ctx, one.text, px, py, one.color);
|
||
});
|
||
};
|
||
// 获取宝石信息 并绘制
|
||
this.getItemDetail = function (floorId) {
|
||
if (!core.getFlag("itemDetail")) return;
|
||
floorId = floorId || core.status.thisMap.floorId;
|
||
core.status.maps[floorId].blocks.forEach(function (block) {
|
||
if (block.event.cls !== 'items' || block.event.id === 'superPotion') return;
|
||
var x = block.x,
|
||
y = block.y;
|
||
// v2优化,只绘制范围内的部分
|
||
if (core.bigmap.v2) {
|
||
if (x < core.bigmap.posX - core.bigmap.extend || x > core.bigmap.posX + core.__SIZE__ + core.bigmap.extend ||
|
||
y < core.bigmap.posY - core.bigmap.extend || y > core.bigmap.posY + core.__SIZE__ + core.bigmap.extend) {
|
||
return;
|
||
}
|
||
}
|
||
var id = block.event.id;
|
||
var item = core.material.items[id];
|
||
if (item.cls === 'equips') {
|
||
// 装备也显示
|
||
var diff = core.clone(item.equip.value || {});
|
||
var per = item.equip.percentage;
|
||
for (var name in per) {
|
||
diff[name + 'per'] = per[name].toString() + '%';
|
||
}
|
||
drawItemDetail(diff, x, y);
|
||
return;
|
||
}
|
||
var before = core.clone(core.status.hero);
|
||
// 跟数据统计原理一样 执行效果 前后比较
|
||
core.setFlag("__statistics__", true);
|
||
try {
|
||
eval(item.itemEffect);
|
||
} catch (error) {}
|
||
var diff = compareObject(before, core.status.hero);
|
||
core.status.hero = hero = before;
|
||
flags = core.status.hero.flags;
|
||
drawItemDetail(diff, x, y);
|
||
});
|
||
};
|
||
// 比较两个对象之间每一项的数值差异(弱等于) 返回数值差异
|
||
function compareObject(a, b) {
|
||
a = a || {};
|
||
b = b || {};
|
||
var diff = {}; // 差异
|
||
for (var name in a) {
|
||
diff[name] = b[name] - (a[name] || 0);
|
||
if (!diff[name]) diff[name] = void 0;
|
||
}
|
||
return diff;
|
||
};
|
||
// 绘制
|
||
function drawItemDetail(diff, x, y) {
|
||
var px = 32 * x + 2,
|
||
py = 32 * y + 30;
|
||
var content = "";
|
||
// 获得数据和颜色
|
||
var i = 0;
|
||
for (var name in diff) {
|
||
if (!diff[name]) continue;
|
||
var color = "#ffffff";
|
||
if (typeof diff[name] === 'number')
|
||
diff[name] = core.formatBigNumber(diff[name], true);
|
||
switch (name) {
|
||
case 'atk':
|
||
case 'atkper':
|
||
color = "#FF7A7A";
|
||
break;
|
||
case 'def':
|
||
case 'defper':
|
||
color = "#00E6F1";
|
||
break;
|
||
case 'mdef':
|
||
case 'mdefper':
|
||
color = "#6EFF83";
|
||
break;
|
||
case 'hp':
|
||
color = "#A4FF00";
|
||
break;
|
||
case 'hpmax':
|
||
case 'hpmaxper':
|
||
color = "#F9FF00";
|
||
break;
|
||
case 'mana':
|
||
color = "#cc6666";
|
||
break;
|
||
}
|
||
content = diff[name];
|
||
// 绘制
|
||
core.status.damage.data.push({ text: content, px: px, py: py - 10 * i, color: color });
|
||
i++;
|
||
}
|
||
}
|
||
},
|
||
"autoBattle": function () {
|
||
/**
|
||
* --------------- 安装说明 ---------------
|
||
*
|
||
* 复制到插件编写里面即可
|
||
*
|
||
* --------------- 使用说明 ---------------
|
||
*
|
||
* 把变量 __autoBattle__ 设置成true开启,设置成false关闭,然后在想要清的时刻,比如战后,每步后等加上core.autoBattle()即可
|
||
*
|
||
* --------------- 自定义说明 ---------------
|
||
*
|
||
* 可以更改canBattle函数自定义某个怪物是否应该被清
|
||
*/
|
||
|
||
/**
|
||
* 是否清这个怪,可以修改这里来实现对不同怪的不同操作
|
||
* @param {string} enemy
|
||
* @param {number} x
|
||
* @param {number} y
|
||
*/
|
||
function canBattle(enemy, x, y) {
|
||
const loc = `${x},${y}`;
|
||
const floor = core.floors[core.status.floorId];
|
||
const e = core.material.enemys[enemy];
|
||
const hasEvent =
|
||
has(floor.afterBattle[loc]) ||
|
||
has(floor.beforeBattle[loc]) ||
|
||
has(e.beforeBattle) ||
|
||
has(e.afterBattle) ||
|
||
has(floor.events[loc]);
|
||
// 有事件,不清
|
||
if (hasEvent) return false;
|
||
const damage = core.getDamageInfo(enemy, void 0, x, y);
|
||
// 0伤或负伤,清
|
||
if (has(damage) && has(damage.damage) && damage.damage <= 0) return true;
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* @template T
|
||
* @param {T} v
|
||
* @returns {v is NonNullable<T>}
|
||
*/
|
||
function has(v) {
|
||
return v !== null && v !== undefined;
|
||
}
|
||
|
||
/**
|
||
* 广搜,搜索可以到达的需要清的怪
|
||
* @param {string} floorId
|
||
*/
|
||
function bfs(floorId, deep = Infinity) {
|
||
core.extractBlocks(floorId);
|
||
const objs = core.getMapBlocksObj(floorId);
|
||
const { x, y } = core.status.hero.loc;
|
||
/** @type {[direction, number, number][]} */
|
||
const dir = Object.entries(core.utils.scan).map(v => [
|
||
v[0],
|
||
v[1].x,
|
||
v[1].y
|
||
]);
|
||
|
||
/** @type {[number, number][]} */
|
||
const queue = [
|
||
[x, y]
|
||
];
|
||
const mapped = {
|
||
[`${x},${y}`]: true
|
||
};
|
||
while (queue.length > 0 && deep > 0) {
|
||
const [nx, ny] = queue.shift();
|
||
dir.forEach(v => {
|
||
const [tx, ty] = [nx + v[1], ny + v[2]];
|
||
const loc = `${tx},${ty}`;
|
||
if (mapped[loc]) return;
|
||
const block = objs[loc];
|
||
mapped[loc] = true;
|
||
const isEnemy =
|
||
has(block) && block.event.cls.startsWith('enemy');
|
||
const changeFloor = core.floors[floorId].changeFloor[loc];
|
||
if (
|
||
(!core.canMoveHero(nx, ny, v[0]) && !isEnemy) ||
|
||
(has(block) && block.event.cls === 'items') ||
|
||
(core.noPass(tx, ty) && !isEnemy) ||
|
||
has(core.floors[floorId].events[loc]) ||
|
||
(has(changeFloor) &&
|
||
changeFloor.ignoreChangeFloor === false)
|
||
)
|
||
return;
|
||
|
||
if (isEnemy) {
|
||
if (canBattle(block.event.id, tx, ty) && !block.disable) {
|
||
console.log(block.event.id, tx, ty);
|
||
// 能打且没有事件就直接干他丫的
|
||
core.battle(block.event.id, tx, ty);
|
||
} else return;
|
||
}
|
||
// 然后判断目标点是否有地图伤害等,没有就直接添加到队列
|
||
const damage = core.status.checkBlock.damage[loc];
|
||
const ambush = core.status.checkBlock.ambush[loc];
|
||
const repulse = core.status.checkBlock.repulse[loc];
|
||
if (
|
||
(!has(damage) || (has(damage) && damage <= 0)) &&
|
||
!has(ambush) &&
|
||
!has(repulse)
|
||
)
|
||
queue.push([tx, ty]);
|
||
});
|
||
deep--;
|
||
}
|
||
}
|
||
|
||
this.autoBattle = function () {
|
||
if (!flags.__autoBattle__ || flags.poison) return;
|
||
// 如果勇士当前点有地图伤害,只清周围
|
||
const { x, y } = core.status.hero.loc;
|
||
const floor = core.floors[core.status.floorId];
|
||
const hasEvent = has(floor.events[`${x},${y}`]);
|
||
if (hasEvent) return;
|
||
const damage = core.status.checkBlock.damage[`${x},${y}`];
|
||
let deep = Infinity;
|
||
if (has(damage) && damage > 0) {
|
||
deep = 1;
|
||
}
|
||
bfs(core.status.floorId, deep);
|
||
};
|
||
},
|
||
"autoGet": function () {
|
||
var enable = true;
|
||
if (!enable) return;
|
||
//
|
||
// var noUpdate = false;
|
||
////// 更新状态栏 ////// 不建议状态栏刷新后触发 容易导致录像不一致的问题
|
||
//control.prototype.updateStatusBar = function (doNotCheckAutoEvents) {
|
||
// if (!core.isPlaying()) return;
|
||
// if (noUpdate) return;
|
||
// noUpdate = true;
|
||
// core.autoGetItem();
|
||
// noUpdate = false;
|
||
// this.controldata.updateStatusBar();
|
||
// if (!doNotCheckAutoEvents) core.checkAutoEvents();
|
||
// this._updateStatusBar_setToolboxIcon();
|
||
// core.clearRouteFolding();
|
||
//}
|
||
|
||
////// 每移动一格后执行的事件 //////
|
||
control.prototype.moveOneStep = function (callback) {
|
||
core.autoGetItem();
|
||
core.autoBattle();
|
||
return this.controldata.moveOneStep(callback);
|
||
}
|
||
|
||
function bfsFlood(sx, sy, blockfn) {
|
||
var canMoveArray = core.generateMovableArray();
|
||
var blocksObj = core.getMapBlocksObj();
|
||
var bgMap = core.getBgMapArray();
|
||
|
||
var visited = [],
|
||
queue = [];
|
||
visited[sx + "," + sy] = 0;
|
||
queue.push(sx + "," + sy);
|
||
|
||
while (queue.length > 0) {
|
||
var now = queue.shift().split(","),
|
||
x = ~~now[0],
|
||
y = ~~now[1];
|
||
for (var direction in core.utils.scan) {
|
||
if (!core.inArray(canMoveArray[x][y], direction)) continue;
|
||
var nx = x + core.utils.scan[direction].x,
|
||
ny = y + core.utils.scan[direction].y,
|
||
nindex = nx + "," + ny;
|
||
if (visited[nindex]) continue;
|
||
if (core.onSki(bgMap[ny][nx])) continue;
|
||
if (blockfn && !blockfn(blocksObj, nx, ny)) continue;
|
||
visited[nindex] = visited[now] + 1;
|
||
queue.push(nindex);
|
||
}
|
||
}
|
||
}
|
||
|
||
function attractAnimate() {
|
||
var name = 'attractAnimate';
|
||
var isPlaying = false;
|
||
this.nodes = [];
|
||
|
||
this.add = function (id, x, y, callback) {
|
||
this.nodes.push({ id: id, x: x, y: y, callback: callback });
|
||
}
|
||
this.start = function () {
|
||
if (isPlaying) return;
|
||
isPlaying = true;
|
||
core.registerAnimationFrame(name, true, this.update);
|
||
this.ctx = core.createCanvas(name, 0, 0, core.__PIXELS__, core.__PIXELS__, 120);
|
||
}
|
||
this.remove = function () {
|
||
core.unregisterAnimationFrame(name);
|
||
core.deleteCanvas(name);
|
||
isPlaying = false;
|
||
}
|
||
this.clear = function () {
|
||
this.nodes = [];
|
||
this.remove();
|
||
}
|
||
var lastTime = -1;
|
||
var self = this;
|
||
this.update = function (timeStamp) {
|
||
if (lastTime < 0) lastTime = timeStamp;
|
||
if (timeStamp - lastTime < 20) return;
|
||
lastTime = timeStamp;
|
||
core.clearMap(name);
|
||
var cx = core.status.heroCenter.px - 16,
|
||
cy = core.status.heroCenter.py - 16;
|
||
var thr = 5; //缓动比例倒数 越大移动越慢
|
||
self.nodes.forEach(function (n) {
|
||
var dx = cx - n.x,
|
||
dy = cy - n.y;
|
||
if (Math.abs(dx) <= thr && Math.abs(dy) <= thr) {
|
||
n.dead = true;
|
||
} else {
|
||
n.x += ~~(dx / thr);
|
||
n.y += ~~(dy / thr);
|
||
}
|
||
core.drawIcon(name, n.id, n.x, n.y, 32, 32);
|
||
});
|
||
self.nodes = self.nodes.filter(function (n) {
|
||
if (n.dead && n.callback) {
|
||
n.callback();
|
||
}
|
||
return !n.dead;
|
||
});
|
||
if (self.nodes.length == 0)
|
||
self.remove();
|
||
}
|
||
}
|
||
|
||
|
||
var animateHwnd = new attractAnimate();
|
||
|
||
this.stopAttractAnimate = function () {
|
||
animateHwnd.clear();
|
||
}
|
||
|
||
this.autoGetItem = function () {
|
||
if (!flags.__autoGetItem__ || flags.poison) return;
|
||
var canGetItems = {};
|
||
if (!core.status.floorId || !core.status.checkBlock.damage || core.status.event.id == 'action' || core.status.lockControl) return;
|
||
|
||
bfsFlood(core.getHeroLoc('x'), core.getHeroLoc('y'), function (blockMap, x, y) {
|
||
var idx = x + ',' + y;
|
||
if (idx in canGetItems) return false;
|
||
var blk = blockMap[idx];
|
||
if (blk && !blk.disable && blk.event.cls == 'items' && !core.isMapBlockDisabled(core.status.floorId, blk.x, blk.y) && blk.event.trigger == 'getItem') {
|
||
canGetItems[idx] = { x: x, y: y, id: blk.event.id };
|
||
return !core.status.checkBlock.damage[idx] && !core.status.checkBlock.ambush[idx];
|
||
}
|
||
return core.maps._canMoveDirectly_checkNextPoint(blockMap, x, y);
|
||
});
|
||
for (var k in canGetItems) {
|
||
var x = canGetItems[k].x,
|
||
y = canGetItems[k].y,
|
||
id = canGetItems[k].id;
|
||
core.trigger(x, y);
|
||
animateHwnd.add(id, x * 32, y * 32);
|
||
}
|
||
animateHwnd.start();
|
||
}
|
||
},
|
||
"怪物手册和显伤": function () {
|
||
// 在此增加新插件
|
||
////// 获得所有特殊属性的名称 /////
|
||
core.enemys.getSpecialText = function (enemy) {
|
||
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
|
||
if (!enemy) return [];
|
||
var special = enemy.special;
|
||
var text = [];
|
||
|
||
var specials = this.getSpecials();
|
||
if (specials) {
|
||
for (var i = 0; i < specials.length; i++) {
|
||
if (this.hasSpecial(special, specials[i][0]))
|
||
text.push(this._calSpecialContent(enemy, specials[i][1]));
|
||
}
|
||
}
|
||
if (special === 0) {
|
||
if (core.getFlag('isCommon')) text.push('普通'); ///////无特殊属性时增加“普通”属性显示
|
||
}
|
||
return text;
|
||
}
|
||
|
||
////// 获得所有特殊属性的颜色 //////
|
||
core.enemys.getSpecialColor = function (enemy) {
|
||
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
|
||
if (!enemy) return [];
|
||
var special = enemy.special;
|
||
var colors = [];
|
||
|
||
var specials = this.getSpecials();
|
||
if (specials) {
|
||
for (var i = 0; i < specials.length; i++) {
|
||
if (this.hasSpecial(special, specials[i][0]))
|
||
colors.push(specials[i][3] || null);
|
||
}
|
||
}
|
||
if (special === 0) {
|
||
colors.push("#ffffff"); ////“普通”属性显示为白色
|
||
}
|
||
return colors;
|
||
|
||
}
|
||
|
||
},
|
||
"仿RM渐变效果": function () {
|
||
// 在此增加新插件
|
||
// 准备渐变
|
||
this.maskPrepare = function () {
|
||
// 执行后画面将凝固
|
||
var mask = core.ui.createCanvas2("mask", 0, 0, core.__PIXELS__ + 161, core.__PIXELS__, 200);
|
||
core.drawThumbnail(core.status.floorId, null, { ctx: mask, x: 161, y: 0, size: 1, damage: false, all: true });
|
||
core.drawImage('mask', 'caidan.png', 0, 0);
|
||
// for (var m in core.canvas) {
|
||
// core.dymCanvas.mask.drawImage(core.canvas[m].canvas, 0, 0);
|
||
// };
|
||
}
|
||
|
||
// 执行渐变
|
||
this.maskFliter = function (time, sample) { // sample为渐变图名称,渐变图需要在全塔属性注册
|
||
var tempCanvas = core.ui.createCanvas2("mask2", 0, 0, core.__PIXELS__ + 161, core.__PIXELS__, 200);
|
||
var tempWidth = tempCanvas.canvas.width,
|
||
tempHeight = tempCanvas.canvas.height;
|
||
//tempCanvas.canvas.width = tempWidth;
|
||
//tempCanvas.canvas.height = tempHeight;
|
||
tempCanvas.clearRect(0, 0, tempWidth, tempHeight);
|
||
tempCanvas.drawImage(core.material.images.images[sample], 0, 0, tempWidth, tempHeight);
|
||
// 读取渐变图开始处理
|
||
var sampleData = tempCanvas.getImageData(0, 0, tempWidth, tempHeight);
|
||
var processData = core.dymCanvas.mask.getImageData(0, 0, tempWidth, tempHeight);
|
||
tempCanvas.clearRect(0, 0, tempWidth, tempHeight);
|
||
var timer = 0;
|
||
var animate = setInterval(function () {
|
||
timer++;
|
||
for (var i = 0; i < sampleData.data.length; i += 4) {
|
||
if (sampleData.data[i] < timer) {
|
||
processData.data[i] = 0;
|
||
processData.data[i + 1] = 0;
|
||
processData.data[i + 2] = 0;
|
||
processData.data[i + 3] = 0;
|
||
}
|
||
}
|
||
core.dymCanvas.mask.putImageData(processData, 0, 0);
|
||
if (timer == 255) {
|
||
delete core.animateFrame.asyncId[animate];
|
||
clearInterval(animate);
|
||
core.deleteCanvas("mask");
|
||
}
|
||
}, time / 256);
|
||
core.animateFrame.asyncId[animate] = true;
|
||
}
|
||
},
|
||
"标题界面监听按钮": function () {
|
||
// 在此增加新插件
|
||
//////用于监听标题界面的键盘操作和鼠标移动操作,然后高亮显示当前选择的光标
|
||
|
||
if (main.replayChecking) return; ////录像过程中
|
||
if (core.status.played) return; ////游戏开始后
|
||
|
||
var i = 1;
|
||
if (core.dom.playGame.getAttribute('selected'))
|
||
i = 1; ////第一项,开始游戏
|
||
else if (core.dom.loadGame.getAttribute('selected'))
|
||
i = 2; ////第二项,继续游戏
|
||
else if (core.dom.replayGame.getAttribute('selected'))
|
||
i = 3; /////第三项,录像回放
|
||
|
||
////当鼠标离开某个选项
|
||
document.getElementById("playGame").addEventListener("mouseleave", function () {
|
||
core.dom.playGame.setAttribute('selected', true);
|
||
core.dom.loadGame.setAttribute('selected', false);
|
||
core.dom.replayGame.setAttribute('selected', false);
|
||
i = 1;
|
||
});
|
||
document.getElementById("loadGame").addEventListener("mouseleave", function () {
|
||
core.dom.loadGame.setAttribute('selected', true);
|
||
core.dom.playGame.setAttribute('selected', false);
|
||
core.dom.replayGame.setAttribute('selected', false);
|
||
i = 2;
|
||
});
|
||
document.getElementById("replayGame").addEventListener("mouseleave", function () {
|
||
core.dom.replayGame.setAttribute('selected', true);
|
||
core.dom.playGame.setAttribute('selected', false);
|
||
core.dom.loadGame.setAttribute('selected', false);
|
||
i = 3;
|
||
});
|
||
|
||
////当鼠标移动到某个选项
|
||
document.getElementById("playGame").addEventListener("mouseenter", function () {
|
||
core.dom.playGame.setAttribute('selected', true);
|
||
core.dom.loadGame.setAttribute('selected', false);
|
||
core.dom.replayGame.setAttribute('selected', false);
|
||
i = 1;
|
||
});
|
||
document.getElementById("loadGame").addEventListener("mouseenter", function () {
|
||
core.dom.loadGame.setAttribute('selected', true);
|
||
core.dom.playGame.setAttribute('selected', false);
|
||
core.dom.replayGame.setAttribute('selected', false);
|
||
i = 2;
|
||
});
|
||
document.getElementById("loadGame").addEventListener("click", function () {
|
||
core.dom.playGame.setAttribute('selected', true);
|
||
core.dom.loadGame.setAttribute('selected', false);
|
||
core.dom.replayGame.setAttribute('selected', false);
|
||
i = 1;
|
||
});
|
||
document.getElementById("replayGame").addEventListener("mouseenter", function () {
|
||
core.dom.replayGame.setAttribute('selected', true);
|
||
core.dom.playGame.setAttribute('selected', false);
|
||
core.dom.loadGame.setAttribute('selected', false);
|
||
i = 3;
|
||
});
|
||
/////按键操作
|
||
document.body.addEventListener('keyup', e => {
|
||
if (e.keyCode === 38) {
|
||
i = (i - 1) || 3; // 上。。。
|
||
} else if (e.keyCode === 40) {
|
||
i = (i + 1) % 4 || 1; // 下。。。
|
||
} else if (i !== 3 && (e.keyCode === 32 || e.keyCode === 13 || e.keyCode === 67)) {
|
||
i = 1; /////确认键,且不是录像回放
|
||
}
|
||
core.dom.playGame.setAttribute('selected', false);
|
||
core.dom.loadGame.setAttribute('selected', false);
|
||
core.dom.replayGame.setAttribute('selected', false);
|
||
if (i === 1)
|
||
core.dom.playGame.setAttribute('selected', true);
|
||
else if (i === 2)
|
||
core.dom.loadGame.setAttribute('selected', true);
|
||
else if (i === 3)
|
||
core.dom.replayGame.setAttribute('selected', true);
|
||
})
|
||
|
||
|
||
},
|
||
"仿RM楼传": function () {
|
||
// 在此增加新插件
|
||
|
||
core.ui.drawFly = function (page) {
|
||
if (!core.getFlag("isRmFly")) {
|
||
///////H5版楼传
|
||
core.status.event.data = page;
|
||
var floorId = core.floorIds[page];
|
||
var title = core.status.maps[floorId].title;
|
||
core.clearMap('ui');
|
||
core.setAlpha('ui', 0.85);
|
||
core.fillRect('ui', 0, 0, core._PX_, core._PY_, '#000000');
|
||
core.setAlpha('ui', 1);
|
||
core.setTextAlign('ui', 'center');
|
||
core.fillText('ui', '楼层跳跃', core._PX_ / 2, 48, '#FFFFFF', this._buildFont(28, true));
|
||
core.fillText('ui', '返回游戏', core._PX_ / 2, core._PY_ - 13, null, this._buildFont(15, true))
|
||
core.setTextAlign('ui', 'right');
|
||
core.fillText('ui', '浏览地图时也', core._PX_ - 10, core._PY_ - 23, '#aaaaaa', this._buildFont(10, false));
|
||
core.fillText('ui', '可楼层跳跃!', core._PX_ - 10, core._PY_ - 11, null, this._buildFont(10, false));
|
||
core.setTextAlign('ui', 'center');
|
||
|
||
var middle = core._PY_ / 2 + 39;
|
||
|
||
// 换行
|
||
var lines = core.splitLines('ui', title, 120, this._buildFont(19, true));
|
||
var start_y = middle - (lines.length - 1) * 11;
|
||
for (var i in lines) {
|
||
core.fillText('ui', lines[i], core._PX_ - 53, start_y, '#FFFFFF', this._buildFont(17, true));
|
||
start_y += 22;
|
||
}
|
||
if (core.actions._getNextFlyFloor(1) != page) {
|
||
core.fillText('ui', '▲', core._PX_ - 60, middle - 64, null, this._buildFont(17, false));
|
||
core.fillText('ui', '▲', core._PX_ - 60, middle - 96);
|
||
core.fillText('ui', '▲', core._PX_ - 60, middle - 96 - 7);
|
||
}
|
||
if (core.actions._getNextFlyFloor(-1) != page) {
|
||
core.fillText('ui', '▼', core._PX_ - 60, middle + 64, null, this._buildFont(17, false));
|
||
core.fillText('ui', '▼', core._PX_ - 60, middle + 96);
|
||
core.fillText('ui', '▼', core._PX_ - 60, middle + 96 + 7);
|
||
}
|
||
var size = 0.75;
|
||
core.strokeRect('ui', 16, 64, size * core._PX_, size * core._PY_, '#FFFFFF', 2);
|
||
core.drawThumbnail(floorId, null, { ctx: 'ui', x: 16, y: 64, size: size, damage: true, all: true });
|
||
} else {
|
||
//////RM版楼传
|
||
core.status.event.data = page;
|
||
var floorId = core.floorIds[page];
|
||
var title = core.status.maps[floorId].title;
|
||
var maxFloorId = 81;
|
||
var minFloorId = 49;
|
||
if (core.status.played) {
|
||
if (!core.status.thisMap.underGround)
|
||
while (core.hasVisitedFloor('MT' + maxFloorId) === false && maxFloorId >= 0) {
|
||
maxFloorId--
|
||
}
|
||
else
|
||
while (core.hasVisitedFloor('UT' + minFloorId) === false && minFloorId >= 1) {
|
||
minFloorId--
|
||
}
|
||
}
|
||
core.clearMap('ui');
|
||
core.createCanvas('flyText', 0, 0, 480, 480, 141);
|
||
core.setOpacity("flyText", 0.7);
|
||
core.drawThumbnail(floorId, null, { ctx: 'ui', x: 0, y: 0, size: 1, damage: true, all: true });
|
||
core.drawWindowSkin('winskin2.png', 'flyText', 0, 304, core._PX_ - 10, 160);
|
||
core.setTextAlign('flyText', 'left');
|
||
if (!core.status.thisMap.underGround)
|
||
core.fillText('flyText', '请输入您要去的楼层(0~' + maxFloorId + '):', 20, 304 + 40, '#FFFFFF', this._buildFont(22, false));
|
||
else {
|
||
core.fillText('flyText', '请输入您要去的', 20, 304 + 40, '#FFFFFF', this._buildFont(22, false));
|
||
core.fillText('flyText', '地下楼层', 20 + 154, 304 + 40, '#aaaaaa', this._buildFont(22, false));
|
||
core.fillText('flyText', '(1~' + minFloorId + '):', 20 + 242, 304 + 40, '#FFFFFF', this._buildFont(22, false));
|
||
}
|
||
core.fillText('flyText', title, 20, 304 + 72, '#FFFFFF', this._buildFont(22, false));
|
||
core.setTextAlign('ui', 'right');
|
||
core.fillText('ui', '浏览地图时也', core._PX_ - 10, core._PY_ - 23, '#aaaaaa', this._buildFont(10, false));
|
||
core.fillText('ui', '可楼层跳跃!', core._PX_ - 10, core._PY_ - 11, null, this._buildFont(10, false));
|
||
core.setTextAlign('flyText', 'center');
|
||
var middle = core._PY_ / 2 + 39;
|
||
if (core.actions._getNextFlyFloor(1) != page) {
|
||
core.fillText('flyText', '▲', core._PX_ - 112, middle + 64, null, this._buildFont(24, false));
|
||
core.fillText('flyText', '◀', core._PX_ - 144, middle + 96);
|
||
|
||
}
|
||
if (core.actions._getNextFlyFloor(-1) != page) {
|
||
core.fillText('flyText', '▼', core._PX_ - 112, middle + 128, null, this._buildFont(24, false));
|
||
core.fillText('flyText', '▶', core._PX_ - 80, middle + 96);
|
||
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
////// 楼层传送器界面时的点击操作 //////
|
||
|
||
actions.prototype._clickFly = function (x, y) {
|
||
if (!core.getFlag("isRmFly")) { ///H5版
|
||
if ((x == core._WIDTH_ - 2 || x == core._WIDTH_ - 3) && y == this._HY_ + 3) {
|
||
core.playSound('光标移动');
|
||
core.ui.drawFly(this._getNextFlyFloor(-1));
|
||
}
|
||
if ((x == core._WIDTH_ - 2 || x == core._WIDTH_ - 3) && y == this._HY_ - 1) {
|
||
core.playSound('光标移动');
|
||
core.ui.drawFly(this._getNextFlyFloor(1));
|
||
}
|
||
if ((x == core._WIDTH_ - 2 || x == core._WIDTH_ - 3) && y == this._HY_ + 4) {
|
||
core.playSound('光标移动');
|
||
core.ui.drawFly(this._getNextFlyFloor(-10));
|
||
}
|
||
if ((x == core._WIDTH_ - 2 || x == core._WIDTH_ - 3) && y == this._HY_ - 2) {
|
||
core.playSound('光标移动');
|
||
core.ui.drawFly(this._getNextFlyFloor(10));
|
||
}
|
||
if (x >= this._HX_ - 1 && x <= this._HX_ + 1 && y === core._HEIGHT_ - 1) {
|
||
core.playSound('取消');
|
||
core.ui.closePanel();
|
||
}
|
||
if (x >= 0 && x <= this._HX_ + 3 && y >= 3 && y <= core._HEIGHT_ - 1 - 1)
|
||
core.flyTo(core.floorIds[core.status.event.data]);
|
||
return;
|
||
} else { ////RM版
|
||
if ((x == core._WIDTH_ - 4) && y == this._HY_ + 5) {
|
||
core.playSound('光标移动');
|
||
core.ui.drawFly(this._getNextFlyFloor(-1));
|
||
} else if ((x == core._WIDTH_ - 4) && y == this._HY_ + 3) {
|
||
core.playSound('光标移动');
|
||
core.ui.drawFly(this._getNextFlyFloor(1));
|
||
} else if ((x == core._WIDTH_ - 5) && y == this._HY_ + 4) {
|
||
core.playSound('光标移动');
|
||
core.ui.drawFly(this._getNextFlyFloor(-10));
|
||
} else if ((x == core._WIDTH_ - 3) && y == this._HY_ + 4) {
|
||
core.playSound('光标移动');
|
||
core.ui.drawFly(this._getNextFlyFloor(10));
|
||
} else if (x >= this._HX_ - 1 && x <= this._HX_ + 1 && y === core._HEIGHT_ - 1) {
|
||
core.playSound('取消');
|
||
core.ui.closePanel();
|
||
} else if (x >= 0 && x <= this._HX_ + 3 && y >= 3 && y <= core._HEIGHT_ - 1 - 1)
|
||
core.flyTo(core.floorIds[core.status.event.data]);
|
||
return;
|
||
}
|
||
}
|
||
},
|
||
"按S跳过剧情": function () {
|
||
// 在此增加新插件
|
||
|
||
if (core.status.played) return; ////游戏开始后
|
||
|
||
core.registerAction('keyDown', "useS_PASS", function (keycode) { /////按下某个键
|
||
|
||
if (!core.getFlag('useS_PASS')) return false;
|
||
|
||
|
||
}, 100);
|
||
|
||
var _my_useS_PASS = function (keycode) { ////放开某个键
|
||
if (!core.getFlag('useS_PASS')) return false;
|
||
if (keycode == 83) { ////按下S时
|
||
if (core.hasAsync())
|
||
core.drawTip('请等待事件结束');
|
||
else
|
||
core.Confirmskip();
|
||
}
|
||
};
|
||
core.registerAction('keyUp', 'useS_PASS', _my_useS_PASS, 100);
|
||
|
||
core.registerAction('ondown', 'useS_PASS', function (x, y, px, py) {
|
||
if (!core.getFlag('useS_PASS')) return false;
|
||
|
||
if (x >= 7 && y <= 2) {
|
||
if (core.hasAsync())
|
||
core.drawTip('请等待事件结束');
|
||
else
|
||
core.Confirmskip();
|
||
}
|
||
|
||
}, 100);
|
||
|
||
|
||
core.Confirmskip = function () { ////跳过剧情确认框
|
||
core.status.hero.flags.useS_PASS = false; ////禁用按S跳过
|
||
core.status.hero.flags.Confirmskip = true;
|
||
core.status.hero.flags.ConfirmskipChoose = 0;
|
||
core.createCanvas('Confirmskip', 0, 0, 480, 480, 200);
|
||
core.createCanvas('Confirmskip_text', 0, 0, 480, 480, 202);
|
||
core.drawWindowSkin('winskin.png', 'Confirmskip', 48, 182, 176, 96);
|
||
core.fillText('Confirmskip_text', '不跳过剧情', 70, 222, "#ffffff", ui.prototype._buildFont(22, false))
|
||
core.fillText('Confirmskip_text', '跳过剧情', 70, 248, "#ffffff", ui.prototype._buildFont(22, false))
|
||
core.drawUIEventSelector(1, 'winskin.png', 70, 202, 120, 24, 201); ////绘制光标
|
||
|
||
}
|
||
|
||
core.registerAction('keyDown', "Confirmskip", function (keycode) { /////按下某个键
|
||
|
||
if (!core.getFlag('Confirmskip')) return false;
|
||
|
||
return true; ///全部拦截
|
||
}, 100);
|
||
|
||
var _my_Confirmskip = function (keycode) { ////放开某个键
|
||
if (!core.getFlag('Confirmskip')) return false;
|
||
if ((keycode == 13 || keycode == 32 || keycode == 67)) { ////按下空格\回车\C时
|
||
if (core.status.hero.flags.ConfirmskipChoose === 1) { ///选择为跳过剧情
|
||
core.ConfirmskipOK();
|
||
} else { ///选择为不跳过剧情
|
||
core.status.hero.flags.useS_PASS = true; ////允许按S的开关
|
||
core.status.hero.flags.Confirmskip = false;
|
||
core.clearMap('Confirmskip') /////清除画布
|
||
core.clearMap('Confirmskip_text')
|
||
core.clearUIEventSelector(1); ////清除光标
|
||
}
|
||
|
||
} else if (keycode == 38 || keycode == 40) ///上下切换
|
||
{
|
||
core.setFlag('ConfirmskipChoose', 1 ^ (core.getFlag('ConfirmskipChoose') || 0));
|
||
if (core.status.hero.flags.ConfirmskipChoose === 0)
|
||
core.drawUIEventSelector(1, 'winskin.png', 70, 202, 120, 24, 201); ////绘制光标
|
||
else
|
||
core.drawUIEventSelector(1, 'winskin.png', 70, 229, 120, 24, 201); ////绘制光标
|
||
}
|
||
return true; ///全部拦截
|
||
};
|
||
core.registerAction('keyUp', 'Confirmskip', _my_Confirmskip, 100);
|
||
|
||
core.registerAction('ondown', 'Confirmskip', function (x, y, px, py) {
|
||
if (!core.getFlag('Confirmskip')) return false;
|
||
|
||
if (x >= 3 && x <= 6 && y === 6) {
|
||
if (core.status.hero.flags.ConfirmskipChoose === 0) {
|
||
///选择为不跳过剧情
|
||
core.status.hero.flags.useS_PASS = true; ////允许按S的开关
|
||
core.status.hero.flags.Confirmskip = false;
|
||
core.clearMap('Confirmskip') /////清除画布
|
||
core.clearMap('Confirmskip_text')
|
||
core.clearUIEventSelector(1); ////清除光标
|
||
} else
|
||
|
||
{
|
||
core.status.hero.flags.ConfirmskipChoose = 0;
|
||
core.drawUIEventSelector(1, 'winskin.png', 70, 202, 120, 24, 201); ////绘制光标
|
||
}
|
||
} else if (x >= 3 && x <= 6 && y === 7) {
|
||
if (core.status.hero.flags.ConfirmskipChoose === 1) {
|
||
core.ConfirmskipOK();
|
||
|
||
} else {
|
||
core.status.hero.flags.ConfirmskipChoose = 1;
|
||
core.drawUIEventSelector(1, 'winskin.png', 70, 229, 120, 24, 201); ////绘制光标
|
||
}
|
||
}
|
||
return true; ///全部拦截
|
||
}, 100);
|
||
|
||
core.ConfirmskipOK = function () { ////决定跳过剧情
|
||
core.status.hero.flags.Confirmskip = false;
|
||
core.clearMap('Confirmskip') /////清除画布
|
||
core.clearMap('Confirmskip_text')
|
||
core.clearUIEventSelector(1); ////清除光标
|
||
core.deleteAllCanvas(); ///清空画布
|
||
core.status.hero.flags.SkipThePlot = true; ////跳过事件开关开启
|
||
core.insertAction({ "type": "exit" });
|
||
if (core.hasAsync())
|
||
core.insertAction({ "type": "stopAsync" }); ///结束异步
|
||
core.insertAction({ "type": "insert" }); ///重新触发当前事件
|
||
core.doAction(); ///执行下一个事件
|
||
core.status.hero.flags.tiaojuqing_black = 0; ///闪烁开关归0
|
||
}
|
||
|
||
core.Confirmskip_On = function () {
|
||
core.status.hero.flags.useS_PASS = true;
|
||
core.insertCommonEvent('跳过事件图片');
|
||
core.createCanvas('tiaojuqing_black', 0, 0, 480, 480, 151); ///
|
||
core.setFilter('tiaojuqing_black', 'brightness(0%)');
|
||
core.setOpacity('tiaojuqing_black', 0);
|
||
core.drawImage('tiaojuqing_black', 'tiaojuqing.png', 0, 0, 324, 95, 240, 0, 243, 71);
|
||
core.status.hero.flags.tiaojuqing_black = 100; ///闪烁开关,此数值也影响闪烁的明暗,为100时刚刚开始闪烁
|
||
|
||
}
|
||
|
||
core.Confirmskip_Off = function () {
|
||
core.status.hero.flags.useS_PASS = false;
|
||
core.insertCommonEvent('跳过事件图片');
|
||
core.status.hero.flags.tiaojuqing_black = 0; ///闪烁开关归0
|
||
core.clearMap('tiaojuqing_black') /////清除特效画布
|
||
|
||
}
|
||
|
||
},
|
||
"移动怪物渐变消失": function () {
|
||
///AD NB(小声bb)
|
||
// 在此增加新插件
|
||
this.moveHidingBlock = function (x, y, steps, time, keep, callback) {
|
||
flags._moveHide = 1;
|
||
core.moveBlock(x, y, steps, time, keep, callback);
|
||
delete flags._moveHide;
|
||
}
|
||
|
||
core.maps.moveBlock = function (x, y, steps, time, keep, callback) {
|
||
if (core.status.replay.speed == 24) time = 1;
|
||
time = time || 500;
|
||
var blockArr = this._getAndRemoveBlock(x, y);
|
||
if (blockArr == null) {
|
||
if (callback) callback();
|
||
return;
|
||
}
|
||
var block = blockArr[0],
|
||
blockInfo = blockArr[1];
|
||
var moveSteps = (steps || []).map(function (t) {
|
||
return [t.split(':')[0], parseInt(t.split(':')[1] || "1")];
|
||
}).filter(function (t) {
|
||
return ['up', 'down', 'left', 'right', 'forward', 'backward', 'leftup', 'leftdown', 'rightup', 'rightdown', 'speed'].indexOf(t[0]) >= 0 &&
|
||
!(t[0] == 'speed' && t[1] < 16)
|
||
});
|
||
var canvases = this._initDetachedBlock(blockInfo, x, y, block.event.animate !== false);
|
||
this._moveDetachedBlock(blockInfo, 32 * x, 32 * y, 1, canvases);
|
||
|
||
const calStep = (step) => {
|
||
if (["up", "down", "left", "right", "forward", "backward"].includes(step[0])) {
|
||
return step[1];
|
||
}
|
||
return 0;
|
||
}
|
||
let stepSum = 0;
|
||
moveSteps.forEach((s) => stepSum += calStep(s));
|
||
var moveInfo = {
|
||
sx: x,
|
||
sy: y,
|
||
x: x,
|
||
y: y,
|
||
px: 32 * x,
|
||
py: 32 * y,
|
||
opacity: 1,
|
||
keep: keep,
|
||
lastDirection: null,
|
||
offset: 1,
|
||
moveSteps: moveSteps,
|
||
stepSum: stepSum * 16,
|
||
movedStep: 0,
|
||
withHiding: flags._moveHide,
|
||
step: 0,
|
||
per_time: time / 16 / core.status.replay.speed
|
||
}
|
||
this._moveBlock_doMove(blockInfo, canvases, moveInfo, callback);
|
||
}
|
||
|
||
core.maps._moveBlock_moving = function (blockInfo, canvases, moveInfo) {
|
||
if (moveInfo.step == 0) {
|
||
if (!this._moveBlock_updateDirection(blockInfo, moveInfo)) return;
|
||
}
|
||
var curr = moveInfo.moveSteps[0];
|
||
moveInfo.step++;
|
||
moveInfo.movedStep++;
|
||
moveInfo.px += core.utils.scan2[curr[0]].x * 2 * moveInfo.offset;
|
||
moveInfo.py += core.utils.scan2[curr[0]].y * 2 * moveInfo.offset;
|
||
if (moveInfo.withHiding) {
|
||
let o = moveInfo.movedStep / moveInfo.stepSum;
|
||
let op = 1 - o * o;
|
||
moveInfo.opacity = op;
|
||
}
|
||
this._moveDetachedBlock(blockInfo, moveInfo.px, moveInfo.py, moveInfo.opacity, canvases);
|
||
if (moveInfo.step == 16) {
|
||
moveInfo.step = 0;
|
||
moveInfo.moveSteps[0][1]--;
|
||
if (moveInfo.moveSteps[0][1] <= 0) {
|
||
moveInfo.moveSteps.shift();
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"对话框偏移": function () {
|
||
// 在此增加新插件
|
||
core.dom.gameDraw.style.overflow = "visible";
|
||
////// 绘制一个对话框 //////
|
||
core.ui.drawTextBox = function (content, config) {
|
||
config = config || {};
|
||
|
||
this.clearUI();
|
||
content = core.replaceText(content);
|
||
|
||
let ctx = core.getContextByName(config.ctx || 'ui');
|
||
if (ctx && main.mode == 'play') {
|
||
core.createCanvas(ctx, 0, 0, core._PX_, core._PY_, 141);
|
||
ctx = core.getContextByName(ctx);
|
||
}
|
||
|
||
let off = flags.textOffset || 0;
|
||
|
||
if (!config.ctx || config.ctx == 'ui') {
|
||
core.relocateCanvas("ui", off, 0);
|
||
}
|
||
|
||
// Step 1: 获得标题信息和位置信息
|
||
var textAttribute = core.status.textAttribute;
|
||
var titleInfo = this._getTitleAndIcon(content);
|
||
var posInfo = this._getPosition(titleInfo.content);
|
||
if (posInfo.position != 'up' && posInfo.position != 'down') posInfo.px = posInfo.py = null;
|
||
if (!posInfo.position) posInfo.position = textAttribute.position;
|
||
content = this._drawTextBox_drawImages(posInfo.content, config.ctx);
|
||
if (config.pos) {
|
||
delete posInfo.px;
|
||
delete posInfo.py;
|
||
posInfo.pos = config.pos;
|
||
}
|
||
posInfo.ctx = ctx;
|
||
|
||
// Step 2: 计算对话框的矩形位置
|
||
var hPos = this._drawTextBox_getHorizontalPosition(content, titleInfo, posInfo);
|
||
var vPos = this._drawTextBox_getVerticalPosition(content, titleInfo, posInfo, hPos.validWidth);
|
||
posInfo.xoffset = hPos.xoffset;
|
||
posInfo.yoffset = vPos.yoffset - 4;
|
||
|
||
if (ctx && main.mode == 'play') {
|
||
ctx.canvas.setAttribute('_text_left', hPos.left);
|
||
ctx.canvas.setAttribute('_text_top', vPos.top);
|
||
}
|
||
|
||
// Step 3: 绘制背景图
|
||
var isWindowSkin = this.drawBackground(hPos.left, vPos.top, hPos.right, vPos.bottom, posInfo);
|
||
|
||
if (titleInfo.title) {
|
||
let titlefont = core.status.textAttribute.titlefont,
|
||
titleStyle = core.arrayToRGBA(core.status.textAttribute.title);
|
||
let tf = this._buildFont(titlefont, false), ///取消加粗
|
||
width = this.calWidth(ctx, titleInfo.title, tf);
|
||
this.drawBackground(hPos.left, vPos.top - titlefont - 12 - 10, hPos.left + width + 30, vPos.top, posInfo);
|
||
ctx.save();
|
||
ctx.textAlign = 'center';
|
||
ctx.textBaseline = 'middle';
|
||
core.fillText(ctx, titleInfo.title, hPos.left + (width + 30) / 2 - 5, vPos.top - (titlefont + 12) / 2 - 5, titleStyle, tf);
|
||
ctx.restore();
|
||
}
|
||
titleInfo.title = null;
|
||
|
||
var alpha = isWindowSkin ? this._drawWindowSkin_getOpacity() : textAttribute.background[3];
|
||
|
||
// Step 4: 绘制标题、头像、动画
|
||
var content_top = this._drawTextBox_drawTitleAndIcon(titleInfo, hPos, vPos, alpha, config.ctx);
|
||
|
||
// Step 5: 绘制正文
|
||
var config = this.drawTextContent(config.ctx || 'ui', content, {
|
||
left: hPos.content_left,
|
||
top: content_top,
|
||
maxWidth: hPos.validWidth,
|
||
lineHeight: vPos.lineHeight,
|
||
time: (config.showAll || config.async || textAttribute.time <= 0 || core.status.event.id != 'action') ? 0 : textAttribute.time
|
||
});
|
||
|
||
// Step 6: 绘制光标
|
||
if (main.mode == 'play') {
|
||
main.dom.next.style.display = 'block';
|
||
main.dom.next.style.borderRightColor = main.dom.next.style.borderBottomColor = core.arrayToRGB(textAttribute.text);
|
||
main.dom.next.style.top = (vPos.bottom - 20) * core.domStyle.scale + "px";
|
||
var left = (hPos.left + hPos.right) / 2;
|
||
left += off;
|
||
if (posInfo.position == 'up' && !posInfo.noPeak && posInfo.px != null && Math.abs(posInfo.px * 32 + 16 - left) < 50)
|
||
left = hPos.right - 64;
|
||
main.dom.next.style.left = left * core.domStyle.scale + "px";
|
||
}
|
||
return config;
|
||
}
|
||
|
||
const _doa = core.events.doAction;
|
||
core.events.doAction = function () {
|
||
core.relocateCanvas('ui', 0, 0);
|
||
_doa.call(core.events);
|
||
}
|
||
},
|
||
"怪物受击发亮": function () {
|
||
// 在此增加新插件
|
||
// 在此增加新插件
|
||
|
||
|
||
function pop() {
|
||
var ctx = core.getContextByName('pop');
|
||
if (!ctx) ctx = core.createCanvas('pop', 0, 0, core.__PIXELS__, core.__PIXELS__, 90);
|
||
core.clearMap(ctx);
|
||
|
||
if (core.status.replay.speed <= 3) {
|
||
var list = core.status.pop || [];
|
||
var count = 0;
|
||
list.forEach(function (one) {
|
||
|
||
one.frame++;
|
||
// 绘制
|
||
|
||
core.setFilter(ctx, 'brightness(' + (220 - 6 * one.frame) + '%)');
|
||
|
||
|
||
core.drawIcon(ctx, one.value, one.px, one.py, 32, 32);
|
||
|
||
if (one.frame >= 20) count++;
|
||
});
|
||
if (count > 0) list.splice(0, count);
|
||
}
|
||
}
|
||
|
||
if (!main.replayChecking) {
|
||
core.registerAnimationFrame('pop', true, pop);
|
||
}
|
||
/** 添加弹出内容 */
|
||
this.addPop = function (px, py, value, frame) {
|
||
var data = { px: px, py: py, value: value, frame: frame || 0 };
|
||
if (core.status.replay.speed <= 3) {
|
||
if (!core.status.pop) core.status.pop = [data];
|
||
else core.status.pop.push(data);
|
||
}
|
||
}
|
||
|
||
},
|
||
"仿RM样式商店": function () {
|
||
////// 绘制一个选项界面 //////
|
||
ui.prototype.drawChoices = function (content, choices, width, ctx) {
|
||
choices = core.clone(choices || []);
|
||
|
||
core.status.event.ui = { "text": content, "choices": choices, "width": width };
|
||
this.clearUI();
|
||
|
||
content = core.replaceText(content || "");
|
||
var titleInfo = this._getTitleAndIcon(content);
|
||
titleInfo.content = this._drawTextBox_drawImages(titleInfo.content, ctx);
|
||
var hPos = this._drawChoices_getHorizontalPosition(titleInfo, choices, width, ctx);
|
||
var vPos = this._drawChoices_getVerticalPosition(titleInfo, choices, hPos);
|
||
core.status.event.ui.offset = vPos.offset;
|
||
|
||
var isWindowSkin = this.drawBackground(hPos.left, vPos.top, hPos.right, vPos.bottom, { ctx: ctx });
|
||
//var isWindowSkin = this.drawBackground(hPos.left, vPos.top - titlefont - 12 - 10, hPos.left + width + 30, vPos.top, posInfo);
|
||
this._drawChoices_drawTitle(titleInfo, hPos, vPos, ctx);
|
||
this._drawChoices_drawChoices(choices, isWindowSkin, hPos, vPos, ctx);
|
||
}
|
||
|
||
ui.prototype._drawChoices_getHorizontalPosition = function (titleInfo, choices, width, ctx) {
|
||
ctx = ctx || 'ui';
|
||
// 宽度计算:考虑提示文字和选项的长度
|
||
core.setFont(ctx, this._buildFont(22, false));
|
||
var width = this._calTextBoxWidth(ctx, titleInfo.content || "", width || 246, core._PX_ - 20);
|
||
for (var i = 0; i < choices.length; i++) {
|
||
if (typeof choices[i] === 'string')
|
||
choices[i] = { "text": choices[i] };
|
||
choices[i].text = core.replaceText(choices[i].text);
|
||
choices[i].width = core.calWidth(ctx, core.replaceText(choices[i].text));
|
||
if (choices[i].icon != null) choices[i].width += 28;
|
||
width = Math.max(width, choices[i].width + 30);
|
||
}
|
||
var left = (core._PX_ - width) / 2,
|
||
right = left + width;
|
||
if (flags.isRMshop) {
|
||
left = 7 + 3 * (core._HALF_WIDTH_ - 6);
|
||
right = core._PX_ - left;
|
||
}
|
||
var content_left = left + (titleInfo.icon == null ? 15 : 60),
|
||
validWidth = right - content_left - 10;
|
||
|
||
return { left: left, right: right, width: width, content_left: content_left, validWidth: validWidth };
|
||
}
|
||
|
||
ui.prototype._drawChoices_getVerticalPosition = function (titleInfo, choices, hPos) {
|
||
var length = choices.length;
|
||
var height = 32 * (length + 2),
|
||
bottom = core._PY_ / 2 + height / 2;
|
||
if (flags.isRMshop)
|
||
bottom += 160;
|
||
if (length % 2 == 0) bottom += 16;
|
||
var offset = 0;
|
||
var choice_top = bottom - height + 56;
|
||
if (titleInfo.content) {
|
||
var headHeight = 0;
|
||
if (titleInfo.title) headHeight += 25;
|
||
headHeight += this.getTextContentHeight(titleInfo.content, {
|
||
lineHeight: 20,
|
||
maxWidth: hPos.validWidth,
|
||
fontSize: 15,
|
||
bold: true
|
||
});
|
||
height += headHeight;
|
||
if (bottom - height <= 32) {
|
||
offset = Math.floor(headHeight / 64);
|
||
bottom += 32 * offset;
|
||
choice_top += 32 * offset;
|
||
}
|
||
}
|
||
return { top: bottom - height, height: height, bottom: bottom, choice_top: choice_top, offset: offset };
|
||
}
|
||
|
||
ui.prototype._drawChoices_drawTitle = function (titleInfo, hPos, vPos, ctx) {
|
||
if (!titleInfo.content) return;
|
||
ctx = ctx || 'ui';
|
||
var content_top = vPos.top + 21;
|
||
if (titleInfo.title != null) {
|
||
core.setTextAlign(ctx, 'center');
|
||
|
||
content_top = vPos.top + 41;
|
||
var title_offset = hPos.left + hPos.width / 2;
|
||
// 动画
|
||
|
||
if (titleInfo.icon != null) {
|
||
title_offset += 12;
|
||
core.strokeRect(ctx, hPos.left + 15 - 1, vPos.top + 30 - 1, 34, titleInfo.height + 2, '#DDDDDD', 2);
|
||
core.status.boxAnimateObjs = [];
|
||
if (titleInfo.bigImage) {
|
||
core.status.boxAnimateObjs.push({
|
||
bigImage: titleInfo.bigImage,
|
||
face: titleInfo.face,
|
||
centerX: hPos.left + 15 + 16,
|
||
centerY: vPos.top + 30 + titleInfo.height / 2,
|
||
max_width: 50,
|
||
ctx: ctx
|
||
});
|
||
} else {
|
||
core.status.boxAnimateObjs.push({
|
||
'bgx': hPos.left + 15,
|
||
'bgy': vPos.top + 30,
|
||
'bgWidth': 32,
|
||
'bgHeight': titleInfo.height,
|
||
'x': hPos.left + 15,
|
||
'y': vPos.top + 30,
|
||
'height': titleInfo.height,
|
||
'animate': titleInfo.animate,
|
||
'image': titleInfo.image,
|
||
'pos': titleInfo.icon * titleInfo.height,
|
||
ctx: ctx
|
||
});
|
||
}
|
||
core.drawBoxAnimate();
|
||
};
|
||
|
||
core.fillText(ctx, titleInfo.title, title_offset, vPos.top + 27,
|
||
core.arrayToRGBA(core.status.textAttribute.title), this._buildFont(22, false));
|
||
}
|
||
|
||
core.setTextAlign(ctx, 'left');
|
||
this.drawTextContent(ctx, titleInfo.content, {
|
||
left: hPos.content_left,
|
||
top: content_top,
|
||
maxWidth: hPos.validWidth,
|
||
fontSize: 22,
|
||
lineHeight: 20,
|
||
bold: false
|
||
});
|
||
}
|
||
|
||
ui.prototype._drawChoices_drawChoices = function (choices, isWindowSkin, hPos, vPos, ctx) {
|
||
var hasCtx = ctx != null;
|
||
ctx = ctx || 'ui';
|
||
// 选项
|
||
core.setTextAlign(ctx, 'center');
|
||
core.setFont(ctx, this._buildFont(17, true));
|
||
for (var i = 0; i < choices.length; i++) {
|
||
var color = core.arrayToRGBA(choices[i].color || core.status.textAttribute.text);
|
||
if (main.mode == 'play' && choices[i].need != null && choices[i].need != '' && !core.calValue(choices[i].need)) color = '#999999';
|
||
core.setFillStyle(ctx, color);
|
||
var offset = core._PX_ / 2;
|
||
if (choices[i].icon) {
|
||
var iconInfo = this._getDrawableIconInfo(choices[i].icon),
|
||
image = iconInfo[0],
|
||
icon = iconInfo[1];
|
||
if (image != null) {
|
||
core.drawImage(ctx, image, 0, 32 * icon, 32, 32,
|
||
core._PX_ / 2 - choices[i].width / 2, vPos.choice_top + 32 * i - 17, 22, 22);
|
||
offset += 14;
|
||
}
|
||
}
|
||
core.fillText(ctx, choices[i].text, core.status.event.id != 'action' ? offset : offset - 55, vPos.choice_top + 32 * i, color, ui.prototype._buildFont(22, false));
|
||
}
|
||
|
||
if (choices.length > 0 && core.status.event.selection != 'none') {
|
||
core.status.event.selection = core.status.event.selection || 0;
|
||
while (core.status.event.selection < 0) core.status.event.selection += choices.length;
|
||
while (core.status.event.selection >= choices.length) core.status.event.selection -= choices.length;
|
||
var len = choices[core.status.event.selection].width;
|
||
if (isWindowSkin) {
|
||
if (hasCtx) {
|
||
this._drawSelector(ctx, core.status.textAttribute.background,
|
||
len + 10, 28, core._PX_ / 2 - len / 2 - 5, vPos.choice_top + 32 * core.status.event.selection - 20);
|
||
} else {
|
||
this._drawWindowSelector(core.status.textAttribute.background,
|
||
core.status.event.id != 'action' ? (core._PX_ / 2 - len / 2 - 5 - 20) : (core._PX_ / 2 - len / 2 - 5 - 60), vPos.choice_top + 32 * core.status.event.selection - 20, core.status.event.id != 'action' ? (len + 10 + 30) : (len + 10 + 30), 28);
|
||
}
|
||
} else
|
||
core.strokeRoundRect(ctx, core._PX_ / 2 - len / 2 - 5, vPos.choice_top + 32 * core.status.event.selection - 20,
|
||
len + 10, 28, 6, core.status.globalAttribute.selectColor, 2);
|
||
}
|
||
}
|
||
|
||
ui.prototype._drawChoices_drawChoices = function (choices, isWindowSkin, hPos, vPos, ctx) {
|
||
var hasCtx = ctx != null;
|
||
ctx = ctx || 'ui';
|
||
// 选项
|
||
core.setTextAlign(ctx, 'center');
|
||
core.setFont(ctx, this._buildFont(17, true));
|
||
if (flags.isRMshop || flags.isRMTitle) {
|
||
core.setTextAlign(ctx, 'left');
|
||
core.setFont(ctx, this._buildFont(22, false));
|
||
}
|
||
for (var i = 0; i < choices.length; i++) {
|
||
var color = core.arrayToRGBA(choices[i].color || core.status.textAttribute.text);
|
||
if (main.mode == 'play' && choices[i].need != null && choices[i].need != '' && !core.calValue(choices[i].need)) color = '#999999';
|
||
core.setFillStyle(ctx, color);
|
||
var offset = core._PX_ / 2;
|
||
if (flags.isRMshop)
|
||
offset = 30;
|
||
if (flags.isRMTitle)
|
||
offset = 130;
|
||
if (choices[i].icon) {
|
||
var iconInfo = this._getDrawableIconInfo(choices[i].icon),
|
||
image = iconInfo[0],
|
||
icon = iconInfo[1];
|
||
if (image != null) {
|
||
core.drawImage(ctx, image, 0, 32 * icon, 32, 32,
|
||
core._PX_ / 2 - choices[i].width / 2, vPos.choice_top + 32 * i - 17, 22, 22);
|
||
offset += 14;
|
||
}
|
||
}
|
||
core.fillText(ctx, choices[i].text, offset, vPos.choice_top + 32 * i, color);
|
||
}
|
||
|
||
if (choices.length > 0 && core.status.event.selection != 'none') {
|
||
core.status.event.selection = core.status.event.selection || 0;
|
||
while (core.status.event.selection < 0) core.status.event.selection += choices.length;
|
||
while (core.status.event.selection >= choices.length) core.status.event.selection -= choices.length;
|
||
var len = choices[core.status.event.selection].width;
|
||
var rightX = core._PX_ / 2 - len / 2 - 5;
|
||
if (flags.isRMshop)
|
||
rightX = 30;
|
||
if (flags.isRMTitle)
|
||
rightX = 130;
|
||
if (isWindowSkin) {
|
||
if (hasCtx) {
|
||
this._drawSelector(ctx, core.status.textAttribute.background,
|
||
len + 10, 28, core._PX_ / 2 - len / 2 - 5, vPos.choice_top + 32 * core.status.event.selection - 20);
|
||
} else {
|
||
this._drawWindowSelector(core.status.textAttribute.background,
|
||
rightX, vPos.choice_top + 32 * core.status.event.selection - 20, len + 10, 28);
|
||
}
|
||
} else
|
||
core.strokeRoundRect(ctx, core._PX_ / 2 - len / 2 - 5, vPos.choice_top + 32 * core.status.event.selection - 20,
|
||
len + 10, 28, 6, core.status.globalAttribute.selectColor, 2);
|
||
}
|
||
}
|
||
actions.prototype._getChoicesTopIndex = function (length) {
|
||
if (flags.isRMshop)
|
||
return this._HY_ - parseInt((length - 1) / 2) + (core.status.event.ui.offset || 0) + 5;
|
||
else
|
||
return this._HY_ - parseInt((length - 1) / 2) + (core.status.event.ui.offset || 0);
|
||
}
|
||
// 移动光标
|
||
actions.prototype._onMoveChoices = function (x, y) {
|
||
if (flags.isRMshop || flags.isRMTitle);
|
||
else if (this._out(x)) return;
|
||
var choices = core.status.event.ui.choices;
|
||
var topIndex = this._getChoicesTopIndex(choices.length);
|
||
if (y >= topIndex && y < topIndex + choices.length) {
|
||
var selection = y - topIndex;
|
||
if (selection == core.status.event.selection) return;
|
||
core.status.event.selection = selection;
|
||
core.playSound('光标移动');
|
||
core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices, core.status.event.ui.width);
|
||
}
|
||
}
|
||
////// 自定义事件时的点击操作 //////
|
||
actions.prototype._clickAction = function (x, y, px, py) {
|
||
if (core.status.event.data.type == 'text') {
|
||
return this._clickAction_text();
|
||
}
|
||
|
||
if (core.status.event.data.type == 'wait') {
|
||
var timeout = Math.max(0, core.status.event.timeout - new Date().getTime()) || 0;
|
||
core.setFlag('type', 1);
|
||
core.setFlag('x', x);
|
||
core.setFlag('y', y);
|
||
core.setFlag('px', px);
|
||
core.setFlag('py', py);
|
||
core.setFlag('timeout', timeout);
|
||
var executed = core.events.__action_wait_afterGet(core.status.event.data.current);
|
||
if (executed || !core.status.event.data.current.forceChild) {
|
||
core.status.route.push("input:" + (1e8 * timeout + 1000000 + 1000 * px + py));
|
||
clearTimeout(core.status.event.interval);
|
||
delete core.status.event.timeout;
|
||
core.doAction();
|
||
}
|
||
return;
|
||
}
|
||
|
||
if (core.status.event.data.type == 'choices') {
|
||
// 选项
|
||
var data = core.status.event.data.current;
|
||
var choices = data.choices;
|
||
if (choices.length == 0) return;
|
||
if (flags.isRMshop || flags.isRMTitle);
|
||
else if (this._out(x)) return;
|
||
var topIndex = this._getChoicesTopIndex(choices.length);
|
||
if (y >= topIndex && y < topIndex + choices.length) {
|
||
var choice = choices[y - topIndex];
|
||
if (choice.need != null && choice.need != '' && !core.calValue(choice.need)) {
|
||
core.playSound('操作失败');
|
||
core.drawTip("无法选择此项");
|
||
return;
|
||
}
|
||
clearTimeout(core.status.event.interval);
|
||
var timeout = Math.max(0, core.status.event.timeout - new Date().getTime()) || 0;
|
||
delete core.status.event.timeout;
|
||
core.setFlag('timeout', timeout);
|
||
// 对全局商店特殊处理
|
||
var index = y - topIndex;
|
||
if (index == choices.length - 1 && core.hasFlag('@temp@shop')) {
|
||
index = -1;
|
||
}
|
||
core.status.route.push("choices:" + (100 * timeout + index));
|
||
core.insertAction(choice.action);
|
||
core.doAction();
|
||
}
|
||
return;
|
||
}
|
||
|
||
if (core.status.event.data.type == 'confirm') {
|
||
if ((x == this._HX_ - 2 || x == this._HX_ - 1) && y == this._HY_ + 1) {
|
||
clearTimeout(core.status.event.interval);
|
||
var timeout = Math.max(0, core.status.event.timeout - new Date().getTime()) || 0;
|
||
delete core.status.event.timeout;
|
||
core.setFlag('timeout', timeout);
|
||
core.status.route.push("choices:" + 100 * timeout);
|
||
core.insertAction(core.status.event.ui.yes);
|
||
core.doAction();
|
||
} else if ((x == this._HX_ + 2 || x == this._HX_ + 1) && y == this._HY_ + 1) {
|
||
clearTimeout(core.status.event.interval);
|
||
var timeout = Math.max(0, core.status.event.timeout - new Date().getTime()) || 0;
|
||
delete core.status.event.timeout;
|
||
core.setFlag('timeout', timeout);
|
||
core.status.route.push("choices:" + (100 * timeout + 1));
|
||
core.insertAction(core.status.event.ui.no);
|
||
core.doAction();
|
||
}
|
||
return;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
}
|
||
} |