支援 & 捕捉

This commit is contained in:
oc 2019-03-05 01:59:00 +08:00
parent 42e04f58be
commit 84213fd528
4 changed files with 265 additions and 135 deletions

View File

@ -683,6 +683,9 @@ control.prototype.automaticRoute = function (destX, destY) {
if (nextBlock.block.event.trigger == 'changeFloor') deepAdd+=10; if (nextBlock.block.event.trigger == 'changeFloor') deepAdd+=10;
} }
deepAdd+=core.status.checkBlock.damage[nid]*10; deepAdd+=core.status.checkBlock.damage[nid]*10;
// 绕过捕捉
if (core.status.checkBlock.ambush[nid])
deepAdd += 10000;
if (nx == destX && ny == destY) { if (nx == destX && ny == destY) {
route[nid] = direction; route[nid] = direction;
@ -1284,6 +1287,21 @@ control.prototype.checkBlock = function () {
if (snipe.length>0) if (snipe.length>0)
core.snipe(snipe); core.snipe(snipe);
} }
// 检查捕捉
var ambush = core.status.checkBlock.ambush[x+core.bigmap.width*y];
if (core.isset(ambush)) {
// 捕捉效果
var actions = [];
ambush.forEach(function (t) {
actions.push({"type": "move", "loc": [t[0],t[1]], "steps": [t[3]], "time": 500, "keep": false, "async":true});
});
actions.push({"type": "waitAsync"});
// 强制战斗
ambush.forEach(function (t) {
actions.push({"type": "battle", "id": t[2]});
})
core.insertAction(actions);
}
} }
////// 阻击事件(动画效果) ////// ////// 阻击事件(动画效果) //////
@ -1493,10 +1511,15 @@ control.prototype.updateDamage = function (floorId, canvas) {
for (var x=0;x<core.bigmap.width;x++) { for (var x=0;x<core.bigmap.width;x++) {
for (var y=0;y<core.bigmap.height;y++) { for (var y=0;y<core.bigmap.height;y++) {
var damage = core.status.checkBlock.damage[x+core.bigmap.width*y]; var damage = core.status.checkBlock.damage[x+core.bigmap.width*y];
if (damage>0) { if (damage>0) { // 该点伤害
damage = core.formatBigNumber(damage, true); damage = core.formatBigNumber(damage, true);
core.fillBoldText(canvas, damage, 32*x+16, 32*(y+1)-14, '#FF7F00'); core.fillBoldText(canvas, damage, 32*x+16, 32*(y+1)-14, '#FF7F00');
} }
else { // 检查捕捉
if ((core.status.checkBlock.ambush||[])[x+core.bigmap.width*y]) {
core.fillBoldText(canvas, '!', 32*x+16, 32*(y+1)-14, '#FF7F00');
}
}
} }
} }

View File

@ -1505,6 +1505,26 @@ events.prototype.battle = function (id, x, y, force, callback) {
if (!core.isset(core.status.event.id)) // 自动存档 if (!core.isset(core.status.event.id)) // 自动存档
core.autosave(true); core.autosave(true);
// ------ 支援技能 ------//
if (core.isset(x) && core.isset(y)) {
var index = x + "," + y, buff = (core.status.checkBlock.buff || {})[index] || {},
guards = buff.guards || [];
if (guards.length>0) {
core.setFlag("__guards__"+x+"_"+y, guards);
var actions = [];
guards.forEach(function (g) {
core.push(actions, {"type": "jump", "from": [g[0],g[1]], "to": [x, y],
"time": 300, "keep": false, "async": true});
})
core.push(actions, [
{"type": "waitAsync"},
{"type": "trigger", "loc": [x,y]}
]);
core.insertAction(actions);
return;
}
}
if (core.flags.battleAnimate&&!core.isReplaying()) { if (core.flags.battleAnimate&&!core.isReplaying()) {
core.waitHeroToStop(function() { core.waitHeroToStop(function() {
core.ui.drawBattleAnimate(id, function() { core.ui.drawBattleAnimate(id, function() {

View File

@ -426,7 +426,8 @@ maps.prototype.canMoveDirectly = function (destX,destY) {
for (var dir in directions) { for (var dir in directions) {
if (!core.canMoveHero(nowX, nowY, dir)) continue; if (!core.canMoveHero(nowX, nowY, dir)) continue;
var nx=nowX+directions[dir][0], ny=nowY+directions[dir][1]; var nx=nowX+directions[dir][0], ny=nowY+directions[dir][1];
if (nx<0||nx>=core.bigmap.width||ny<0||ny>=core.bigmap.height||visited[nx+core.bigmap.width*ny]||core.getBlock(nx,ny)!=null||core.status.checkBlock.damage[nx+core.bigmap.width*ny]>0) continue; if (nx<0||nx>=core.bigmap.width||ny<0||ny>=core.bigmap.height||visited[nx+core.bigmap.width*ny]||core.getBlock(nx,ny)!=null
||core.status.checkBlock.damage[nx+core.bigmap.width*ny]>0||core.status.checkBlock.ambush[nx+core.bigmap.width*ny]) continue;
visited[nx+core.bigmap.width*ny]=visited[nowX+core.bigmap.width*nowY]+1; visited[nx+core.bigmap.width*ny]=visited[nowX+core.bigmap.width*nowY]+1;
if (nx==destX&&ny==destY) return visited[nx+core.bigmap.width*ny]; if (nx==destX&&ny==destY) return visited[nx+core.bigmap.width*ny];
queue.push(nx+core.bigmap.width*ny); queue.push(nx+core.bigmap.width*ny);

View File

@ -178,7 +178,8 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
var enemy = core.material.enemys[enemyId]; var enemy = core.material.enemys[enemyId];
// 播放战斗音效和动画 // 播放战斗音效和动画
var equipAnimate = 'hand', equipId = (core.status.hero.equipment||[])[0]; var equipAnimate = 'hand',
equipId = (core.status.hero.equipment || [])[0];
if (core.isset(equipId) && core.isset((core.material.items[equipId].equip || {}).animate)) if (core.isset(equipId) && core.isset((core.material.items[equipId].equip || {}).animate))
equipAnimate = core.material.items[equipId].equip.animate; equipAnimate = core.material.items[equipId].equip.animate;
// 检查equipAnimate是否存在SE如果不存在则使用默认音效 // 检查equipAnimate是否存在SE如果不存在则使用默认音效
@ -202,13 +203,28 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
core.events.lose('战斗失败'); core.events.lose('战斗失败');
return; return;
} }
// 删除该块
var guards = []; // 支援
if (core.isset(x) && core.isset(y)) {
core.removeBlock(x, y);
guards = core.getFlag("__guards__" + x + "_" + y, []);
core.removeFlag("__guards__" + x + "_" + y);
}
// 获得金币和经验 // 获得金币和经验
var money = enemy.money; var money = enemy.money;
guards.forEach(function (g) {
money += core.material.enemys[g[2]].money;
});
if (core.hasItem('coin')) money *= 2; if (core.hasItem('coin')) money *= 2;
if (core.hasFlag('curse')) money = 0; if (core.hasFlag('curse')) money = 0;
core.status.hero.money += money; core.status.hero.money += money;
core.status.hero.statistics.money += money; core.status.hero.statistics.money += money;
var experience = enemy.experience; var experience = enemy.experience;
guards.forEach(function (g) {
experience += core.material.enemys[g[2]].experience;
})
if (core.hasFlag('curse')) experience = 0; if (core.hasFlag('curse')) experience = 0;
core.status.hero.experience += experience; core.status.hero.experience += experience;
core.status.hero.statistics.experience += experience; core.status.hero.statistics.experience += experience;
@ -219,11 +235,6 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
hint += ",经验+" + experience; hint += ",经验+" + experience;
core.drawTip(hint); core.drawTip(hint);
// 删除该块
if (core.isset(x) && core.isset(y)) {
core.removeBlock(x, y);
}
// 事件的处理 // 事件的处理
var todo = []; var todo = [];
@ -303,8 +314,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
// 如果已有事件正在处理中 // 如果已有事件正在处理中
if (core.status.event.id == null) { if (core.status.event.id == null) {
core.continueAutomaticRoute(); core.continueAutomaticRoute();
} } else {
else {
core.clearContinueAutomaticRoute(); core.clearContinueAutomaticRoute();
} }
if (core.isset(callback)) callback(); if (core.isset(callback)) callback();
@ -446,7 +456,9 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
[22, "固伤", function (enemy) { return "战斗前,怪物对勇士造成" + (enemy.damage || 0) + "点固定伤害,无视勇士魔防。"; }], [22, "固伤", function (enemy) { return "战斗前,怪物对勇士造成" + (enemy.damage || 0) + "点固定伤害,无视勇士魔防。"; }],
[23, "重生", "怪物被击败后,角色转换楼层则怪物将再次出现"], [23, "重生", "怪物被击败后,角色转换楼层则怪物将再次出现"],
[24, "激光", function (enemy) { return "经过怪物同行或同列时自动减生命" + (enemy.value || 0) + "点"; }], [24, "激光", function (enemy) { return "经过怪物同行或同列时自动减生命" + (enemy.value || 0) + "点"; }],
[25, "光环", function (enemy) {return "同楼层所有怪物生命提升"+(enemy.value||0)+"%,攻击提升"+(enemy.atkValue||0)+"%,防御提升"+(enemy.defValue||0)+"%"+(enemy.add?"可叠加":"不可叠加");}] [25, "光环", function (enemy) { return "同楼层所有怪物生命提升" + (enemy.value || 0) + "%,攻击提升" + (enemy.atkValue || 0) + "%,防御提升" + (enemy.defValue || 0) + "%" + (enemy.add ? "可叠加" : "不可叠加"); }],
[26, "支援", "当周围一圈的怪物受到攻击时将上前支援,并组成小队战斗。"],
[27, "捕捉", "当走到怪物周围十字时会强制进行战斗。"]
]; ];
}, },
"getEnemyInfo": function (enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId) { "getEnemyInfo": function (enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId) {
@ -460,8 +472,13 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
// floorId该怪物所在的楼层 // floorId该怪物所在的楼层
// 后面三个参数主要是可以在光环等效果上可以适用(也可以按需制作部分范围光环效果) // 后面三个参数主要是可以在光环等效果上可以适用(也可以按需制作部分范围光环效果)
floorId = floorId || core.status.floorId; floorId = floorId || core.status.floorId;
var mon_hp = enemy.hp, mon_atk = enemy.atk, mon_def = enemy.def, mon_special = enemy.special; var mon_hp = enemy.hp,
var mon_money = enemy.money, mon_experience = enemy.experience, mon_point = enemy.point; mon_atk = enemy.atk,
mon_def = enemy.def,
mon_special = enemy.special;
var mon_money = enemy.money,
mon_experience = enemy.experience,
mon_point = enemy.point;
// 模仿 // 模仿
if (core.hasSpecial(mon_special, 10)) { if (core.hasSpecial(mon_special, 10)) {
mon_atk = hero_atk; mon_atk = hero_atk;
@ -475,7 +492,12 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
// 光环检查 // 光环检查
// 从V2.5.4开始,对光环效果增加缓存,以解决多次重复计算的问题,从而大幅提升运行效率。 // 从V2.5.4开始,对光环效果增加缓存,以解决多次重复计算的问题,从而大幅提升运行效率。
// 检查当前楼层所有光环怪物数字25 // 检查当前楼层所有光环怪物数字25
var hp_buff = 0, atk_buff = 0, def_buff = 0, cnt = 0; var hp_buff = 0,
atk_buff = 0,
def_buff = 0,
cnt = 0;
// ------ 支援 ------
var guards = [];
// 检查光环缓存 // 检查光环缓存
if (!core.isset(core.status.checkBlock.buff)) core.status.checkBlock.buff = {}; if (!core.isset(core.status.checkBlock.buff)) core.status.checkBlock.buff = {};
var index = core.isset(x) && core.isset(y) ? (x + "," + y) : "floor"; var index = core.isset(x) && core.isset(y) ? (x + "," + y) : "floor";
@ -485,7 +507,8 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
core.status.maps[floorId].blocks.forEach(function (block) { core.status.maps[floorId].blocks.forEach(function (block) {
if (core.isset(block.event) && !block.disable) { if (core.isset(block.event) && !block.disable) {
// 获得该图块的ID // 获得该图块的ID
var id = block.event.id, enemy = core.material.enemys[id]; var id = block.event.id,
enemy = core.material.enemys[id];
// 检查是不是怪物,且是否拥有该特殊属性 // 检查是不是怪物,且是否拥有该特殊属性
if (core.isset(enemy) && core.hasSpecial(enemy.special, 25)) { if (core.isset(enemy) && core.hasSpecial(enemy.special, 25)) {
// 检查是否可叠加 // 检查是否可叠加
@ -496,19 +519,27 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
cnt++; cnt++;
} }
} }
// 检查【支援】技能
if (core.isset(enemy) && core.hasSpecial(enemy.special, 26) &&
// 检查支援条件坐标存在距离为1且不能是自己
// 其他类型的支援怪,比如十字之类的话.... 看着做是一样的
core.isset(x) && core.isset(y) && Math.abs(block.x - x) <= 1 && Math.abs(block.y - y) <= 1 && !(x == block.x && y == block.y)) {
// 记录怪物的x,yID
guards.push([block.x, block.y, id]);
}
// TODO如果有其他类型光环怪物在这里仿照添加检查
} }
}); });
// TODO如果有其他类型光环怪物在这里仿照添加检查hp_buff, atk_buff和def_buff即可。
// 放入缓存中 // 放入缓存中
core.status.checkBlock.buff[index] = {"hp_buff": hp_buff, "atk_buff": atk_buff, "def_buff": def_buff}; core.status.checkBlock.buff[index] = { "hp_buff": hp_buff, "atk_buff": atk_buff, "def_buff": def_buff, "guards": guards };
} } else {
else {
// 直接使用缓存数据 // 直接使用缓存数据
hp_buff = cache.hp_buff; hp_buff = cache.hp_buff;
atk_buff = cache.atk_buff; atk_buff = cache.atk_buff;
def_buff = cache.def_buff; def_buff = cache.def_buff;
guards = cache.guards;
} }
// 增加比例;如果要增加数值可以直接在这里修改 // 增加比例;如果要增加数值可以直接在这里修改
@ -531,7 +562,8 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
"money": Math.floor(mon_money), "money": Math.floor(mon_money),
"experience": Math.floor(mon_experience), "experience": Math.floor(mon_experience),
"point": Math.floor(mon_point), "point": Math.floor(mon_point),
"special": mon_special "special": mon_special,
"guards": guards, // 返回支援情况
}; };
}, },
"getDamageInfo": function (enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId) { "getDamageInfo": function (enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId) {
@ -545,6 +577,10 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
// 后面三个参数主要是可以在光环等效果上可以适用 // 后面三个参数主要是可以在光环等效果上可以适用
floorId = floorId || core.status.floorId; floorId = floorId || core.status.floorId;
var origin_hero_hp = hero_hp,
origin_hero_atk = hero_atk,
origin_hero_def = hero_def;
// 勇士的负属性都按0计算 // 勇士的负属性都按0计算
hero_hp = Math.max(0, hero_hp); hero_hp = Math.max(0, hero_hp);
hero_atk = Math.max(0, hero_atk); hero_atk = Math.max(0, hero_atk);
@ -559,7 +595,10 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
// 怪物的各项数据 // 怪物的各项数据
// 对坚固模仿等处理扔到了脚本编辑-getEnemyInfo之中 // 对坚固模仿等处理扔到了脚本编辑-getEnemyInfo之中
var enemyInfo = core.enemys.getEnemyInfo(enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId); var enemyInfo = core.enemys.getEnemyInfo(enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId);
var mon_hp = enemyInfo.hp, mon_atk = enemyInfo.atk, mon_def = enemyInfo.def, mon_special = enemyInfo.special; var mon_hp = enemyInfo.hp,
mon_atk = enemyInfo.atk,
mon_def = enemyInfo.def,
mon_special = enemyInfo.special;
// 技能的处理 // 技能的处理
if (core.getFlag('skill', 0) == 1) { // 开启了技能1二倍斩 if (core.getFlag('skill', 0) == 1) { // 开启了技能1二倍斩
@ -624,6 +663,38 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
// 勇士的攻击回合数;为怪物生命除以每回合伤害向上取整 // 勇士的攻击回合数;为怪物生命除以每回合伤害向上取整
var turn = Math.ceil(mon_hp / hero_per_damage); var turn = Math.ceil(mon_hp / hero_per_damage);
// ------ 支援 ----- //
// 这个递归最好想明白为什么flag:extra_turn是怎么用的
var guards = core.getFlag("__guards__" + x + "_" + y, enemyInfo.guards);
var guard_before_current_enemy = false; // ------ 支援怪是先打(true)还是后打(false)
turn += core.getFlag("__extraTurn__", 0);
if (guards.length > 0) {
if (!guard_before_current_enemy) { // --- 先打当前怪物,记录当前回合数
core.setFlag("__extraTurn__", turn);
}
// 获得那些怪物组成小队战斗
for (var i = 0; i < guards.length; i++) {
var gx = guards[i][0],
gy = guards[i][1],
gid = guards[i][2];
// 递归计算支援怪伤害信息这里不传x,y保证不会重复调用
// 这里的mdef传0因为护盾应该只会被计算一次
var info = core.enemys.getDamageInfo(core.material.enemys[gid], origin_hero_hp, origin_hero_atk, origin_hero_def, 0);
if (info == null) { // 小队中任何一个怪物不可战斗直接返回null
return null;
}
// 已经进行的回合数
core.setFlag("__extraTurn__", info.turn);
init_damage += info.damage;
}
if (guard_before_current_enemy) { // --- 先打支援怪物,增加当前回合数
turn += core.getFlag("__extraTurn__", 0);
}
}
core.removeFlag("__extraTurn__");
// ------ 支援END ------ //
// 最终伤害:初始伤害 + 怪物对勇士造成的伤害 + 反击伤害 // 最终伤害:初始伤害 + 怪物对勇士造成的伤害 + 反击伤害
var damage = init_damage + (turn - 1) * per_damage + turn * counterDamage; var damage = init_damage + (turn - 1) * per_damage + turn * counterDamage;
// 再扣去魔防 // 再扣去魔防
@ -951,7 +1022,8 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
for (var n = 0; n < blocks.length; n++) { for (var n = 0; n < blocks.length; n++) {
var block = blocks[n]; var block = blocks[n];
if (core.isset(block.event) && !block.disable && block.event.cls.indexOf('enemy') == 0) { if (core.isset(block.event) && !block.disable && block.event.cls.indexOf('enemy') == 0) {
var id = block.event.id, enemy = core.material.enemys[id]; var id = block.event.id,
enemy = core.material.enemys[id];
if (core.isset(enemy)) { if (core.isset(enemy)) {
core.status.checkBlock.map[block.x + core.bigmap.width * block.y] = id; core.status.checkBlock.map[block.x + core.bigmap.width * block.y] = id;
} }
@ -966,6 +1038,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
// Step2: 更新领域、阻击伤害 // Step2: 更新领域、阻击伤害
core.status.checkBlock.damage = []; // 记录(x,y)点的伤害;(x,y)对应的值是 x+core.bigmap.width*y core.status.checkBlock.damage = []; // 记录(x,y)点的伤害;(x,y)对应的值是 x+core.bigmap.width*y
for (var x = 0; x < core.bigmap.width * core.bigmap.height; x++) core.status.checkBlock.damage[x] = 0; for (var x = 0; x < core.bigmap.width * core.bigmap.height; x++) core.status.checkBlock.damage[x] = 0;
core.status.checkBlock.ambush = [];
for (var x = 0; x < core.bigmap.width; x++) { for (var x = 0; x < core.bigmap.width; x++) {
for (var y = 0; y < core.bigmap.height; y++) { for (var y = 0; y < core.bigmap.height; y++) {
@ -991,7 +1064,8 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
for (var dx = -range; dx <= range; dx++) { for (var dx = -range; dx <= range; dx++) {
for (var dy = -range; dy <= range; dy++) { for (var dy = -range; dy <= range; dy++) {
if (dx == 0 && dy == 0) continue; if (dx == 0 && dy == 0) continue;
var nx=x+dx, ny=y+dy; var nx = x + dx,
ny = y + dy;
if (nx < 0 || nx >= core.bigmap.width || ny < 0 || ny >= core.bigmap.height) continue; if (nx < 0 || nx >= core.bigmap.width || ny < 0 || ny >= core.bigmap.height) continue;
// 如果是十字领域,则还需要满足 |dx|+|dy|<=range // 如果是十字领域,则还需要满足 |dx|+|dy|<=range
if (!zoneSquare && Math.abs(dx) + Math.abs(dy) > range) continue; if (!zoneSquare && Math.abs(dx) + Math.abs(dy) > range) continue;
@ -1016,12 +1090,24 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
for (var dx = -1; dx <= 1; dx++) { for (var dx = -1; dx <= 1; dx++) {
for (var dy = -1; dy <= 1; dy++) { for (var dy = -1; dy <= 1; dy++) {
if (dx == 0 && dy == 0) continue; if (dx == 0 && dy == 0) continue;
var nx=x+dx, ny=y+dy; var nx = x + dx,
ny = y + dy;
if (nx < 0 || nx >= core.bigmap.width || ny < 0 || ny >= core.bigmap.height || Math.abs(dx) + Math.abs(dy) > 1) continue; if (nx < 0 || nx >= core.bigmap.width || ny < 0 || ny >= core.bigmap.height || Math.abs(dx) + Math.abs(dy) > 1) continue;
core.status.checkBlock.damage[nx + ny * core.bigmap.width] += enemy.value || 0; core.status.checkBlock.damage[nx + ny * core.bigmap.width] += enemy.value || 0;
} }
} }
} }
// 存在捕捉
if (core.enemys.hasSpecial(enemy.special, 27)) {
// 给周围格子加上【捕捉】记号
for (var dir in core.utils.scan) {
var nx = x + core.utils.scan[dir].x,
ny = y + core.utils.scan[dir].y;
if (!core.isset(core.status.checkBlock.ambush[nx + ny * core.bigmap.width]))
core.status.checkBlock.ambush[nx + ny * core.bigmap.width] = [];
core.status.checkBlock.ambush[nx + ny * core.bigmap.width].push([x, y, id, dir]);
}
}
} }
} }
} }