diff --git a/project/enemys.js b/project/enemys.js index 8e6612a..5e591b8 100644 --- a/project/enemys.js +++ b/project/enemys.js @@ -18,7 +18,7 @@ var enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80 = "brownWizard": {"name":"初级巫师","hp":100,"atk":120,"def":0,"money":16,"exp":0,"point":0,"special":15,"value":100,"range":2,"mdef":0,"spell":0,"speed":1}, "redWizard": {"name":"高级巫师","hp":1000,"atk":1200,"def":0,"money":160,"exp":0,"point":0,"special":15,"value":200,"zoneSquare":true,"mdef":0,"spell":0,"speed":1}, "swordsman": {"name":"双手剑士","hp":100,"atk":120,"def":0,"money":6,"exp":3,"point":0,"special":4,"mdef":0,"spell":0,"speed":1}, - "soldier": {"name":"冥战士","hp":120,"atk":50,"def":8,"money":10,"exp":7,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "soldier": {"name":"冥战士","hp":120,"atk":50,"def":8,"money":10,"exp":7,"point":0,"special":0,"mdef":0,"spell":0,"speed":8}, "yellowKnight": {"name":"金骑士","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, "redKnight": {"name":"红骑士","hp":500,"atk":200,"def":50,"money":0,"exp":0,"point":0,"special":[7],"mdef":0,"spell":0,"speed":1}, "darkKnight": {"name":"黑骑士","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, diff --git a/project/floors/yiqu7.js b/project/floors/yiqu7.js index d47401f..e2e082b 100644 --- a/project/floors/yiqu7.js +++ b/project/floors/yiqu7.js @@ -1,29 +1,29 @@ main.floors.yiqu7= { -"floorId": "yiqu7", -"title": "主塔 7 层", -"name": "7", -"width": 13, -"height": 13, -"canFlyTo": true, -"canFlyFrom": true, -"canUseQuickShop": true, -"images": [], -"ratio": 1, -"defaultGround": "grass2", -"firstArrive": [], -"eachArrive": [], -"parallelDo": "", -"events": {}, -"changeFloor": {}, -"beforeBattle": {}, -"afterBattle": {}, -"afterGetItem": {}, -"afterOpenDoor": {}, -"autoEvent": {}, -"cannotMove": {}, -"cannotMoveIn": {}, -"map": [ + "floorId": "yiqu7", + "title": "主塔 7 层", + "name": "7", + "width": 13, + "height": 13, + "canFlyTo": true, + "canFlyFrom": true, + "canUseQuickShop": true, + "images": [], + "ratio": 1, + "defaultGround": "grass2", + "firstArrive": [], + "eachArrive": [], + "parallelDo": "", + "events": {}, + "changeFloor": {}, + "beforeBattle": {}, + "afterBattle": {}, + "afterGetItem": {}, + "afterOpenDoor": {}, + "autoEvent": {}, + "cannotMove": {}, + "cannotMoveIn": {}, + "map": [ [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], @@ -38,4 +38,16 @@ main.floors.yiqu7= [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ], + "bgmap": [ + +], + "fgmap": [ + +], + "bg2map": [ + +], + "fg2map": [ + +] } \ No newline at end of file diff --git a/project/functions.js b/project/functions.js index bfa1127..32d9a29 100644 --- a/project/functions.js +++ b/project/functions.js @@ -308,7 +308,19 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // 获得战斗伤害信息 var damageInfo = core.getDamageInfo(enemyId, null, x, y) || {}; - console.log(damageInfo) + + if (!core.getFlag("noAnimate")) core.attackAnimate( + enemyId, + damageInfo.start[0], + damageInfo.start[1], + damageInfo.start[2], + damageInfo.start[3], + damageInfo.start[4], + damageInfo.heroDiffList, + damageInfo.enemyDiffList, + damageInfo.heroanimateList, + damageInfo.enemyanimateList + ) // 战斗伤害 var damage = damageInfo.damage; // 当前战斗回合数,可用于战后所需的判定 @@ -928,7 +940,8 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = mon_special = enemyInfo.special, mon_absorb_damage = enemyInfo.absorb, mon_barrier = enemyInfo.barrier; - + const { lcm, gcd } = core.plugin.utils + const equip0 = core.getEquip(0) //---第一部分:静态属性修正--- //此处写入静态影响勇士属性的勇士或怪物技能(静态影响怪物属性的技能于getEnemyInfo中写入) // 技能的处理 @@ -977,10 +990,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = } //——第二部分:变量定义和初始赋值—— - // 每回合怪物对勇士造成的战斗伤害 - let per_damage = Math.max(mon_atk - hero_def, 0), - per_mdamage = Math.floor(mon_spell * (100 - hero_mdef) / 100); - // + let hero_per_damage = Math.max(hero_atk - mon_def, 0), hero_per_mdamage = Math.floor((hero_spell * hero_matk / 100) * (100 - mon_mdef) / 100); @@ -988,152 +998,290 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = let damage = 0, hero_turn = 0, mon_turn = 0; + let equipInfo = [] //回合生效的装备列表 + + for (let i = 0; i < 5; i++) { + const a = core.plugin.equip[core.getEquip(i)] + if (a) equipInfo.push(a) + } + + //处理回合条长度 + let oneTurn = [hero_speed, mon_speed]; + if (equipInfo.length > 0) { + for (let i = 0; i < equipInfo.length; i++) { + equipInfo[i].now = 0; + equipInfo[i].isAttack = false; + oneTurn.push(equipInfo[i].speed); + } + } + //需要变更 + + const onegcd = gcd(...oneTurn) //最大公约数 + oneTurn = lcm(...oneTurn) / onegcd //单次回合长度 + //在这里处理equip的初始位置now + equipInfo.forEach(v => { + switch (v.id) { + case "sword1": + default: + v.now = 0 + break + } + v.onAttack = false + if (v.now === oneTurn) v.onAttack = true //增加正在攻击的标志 + }) + const heroinfo = { hp: hero_hp, atk: hero_atk, def: hero_def, mdef: hero_mdef, spell: hero_spell, mhp: Math.floor(hero_spell * hero_mhp / 100), matk: Math.floor(hero_spell * hero_matk / 100), speed: hero_speed, now: 0, isAttack: false } //勇士属性 + const enemyinfo = { hp: mon_hp, atk: mon_atk, def: mon_def, mdef: mon_mdef, spell: mon_spell, speed: mon_speed, special: mon_special, now: 0, onAttack: false, isAttack: false } //怪物属性 + //先攻,先攻为怪物和勇士勇士行动前怪物出第一刀 + if (core.hasSpecial(mon_special, 1)) { + enemyinfo.now = oneTurn + enemyinfo.onAttack = true + } + const start = [core.clone(heroinfo), core.clone(enemyinfo), core.clone(equipInfo), oneTurn, onegcd] //记录开始战斗时的属性并转发 //---第三部分:递归开始--- - let length = hero_speed * mon_speed; - let heroDiffPerTurn = [], - enemyDiffPerTurn = []; + const heroDiffList = [], + enemyDiffList = [], + heroanimateList = [], + enemyanimateList = []; - let now_mon_hp = mon_hp, - last_mon_hp = mon_hp, - mon_length = length, - hero_length = 0, - mon_time = 0, - hero_time = 0; - //先攻,先攻为怪物和勇士同时出第一刀 - if (core.hasSpecial(mon_special, 1)) mon_length = 0; + let beforehp = enemyinfo.hp while ( - now_mon_hp > 0 - + enemyinfo.hp > 0 ) { - //勇士和怪物的长度 - mon_time = mon_length / mon_speed; - hero_time = hero_length / hero_speed; + let onattack = false + const hero_diff = {}, + enemy_diff = {}, + hero_animate = [], + enemy_animate = []; + + if (enemyinfo.onAttack) { //怪物先攻的场合 + //这里计算怪物攻击时发生的各种变化,同时计入enemy_diff + let mon_damage = 0 + let hero_damage = 0 + //伤害计算 + let per_damage = Math.max(enemyinfo.atk - heroinfo.def, 0), + per_mdamage = Math.floor(enemyinfo.spell * (100 - heroinfo.mdef) / 100); + + //这里记录伤害触发后的属性变化和动画,同时计入diff、damage + if (core.hasSpecial(mon_special, 6)) { + hero_damage += per_damage * enemy.n + per_mdamage * enemy.n + } else { + hero_damage += per_damage + per_mdamage + } + let animate = core.plugin.enemyanimate[enemy.id] ?? "sword" + //这里可通过if更改默认的怪物攻击特效 + hero_animate.push(animate) //勇士身上绘制sword动画 + if (heroinfo.mhp - hero_damage >= 0) { + heroinfo.mhp = heroinfo.mhp - hero_damage + hero_damage = 0 + } else { + hero_damage -= heroinfo.mhp + heroinfo.hp -= hero_damage + hero_diff.hp = (hero_diff.hp ?? 0) - hero_damage + } + + damage += hero_damage + enemyinfo.onAttack = false + enemyinfo.now = 0 + onattack = true + } + equipInfo.forEach(v => { + if (v.onAttack) { + let mon_damage = 0 + let hero_damage = 0 + //这里写生效装备的技能效果,同时对双方属性的修改计入diff + let animate = core.plugin.equipanimate[v.id] ?? "sword" + //这里可通过if更改默认的道具特效 + enemy_animate.push(animate) //勇士身上绘制动画 + + v.now = 0 + v.onAttack = false + onattack = true + } + }) + if (onattack) { //先手处理完毕后的数据处理 + heroDiffList.push(hero_diff) + enemyDiffList.push(enemy_diff) + heroanimateList.push(hero_animate) + enemyanimateList.push(enemy_animate) + continue //进入下一循环 + } + heroinfo.now += heroinfo.speed + enemyinfo.now += enemyinfo.speed + equipInfo.forEach(v => { + v.now += v.speed + }) if ( - mon_time == Math.min(mon_time, hero_time) + heroinfo.now >= oneTurn ) { - //怪物攻击的回合 - //这里计算怪物攻击时发生的各种变化 - - //伤害与回合增加 - - //N连击,待定,想做成“以x%、y%……攻击力各攻击一次”的形式 - if (core.hasSpecial(mon_special, 6)) { - damage += per_damage * enemy.n; - mon_turn += enemy.n; - } else { - damage += per_damage; - mon_turn += 1; - } - damage += per_mdamage; - //重新为长度赋值 - mon_length = length; - hero_length = hero_length - mon_time * hero_speed; - } else if (hero_time == Math.min(mon_time, hero_time)) { //勇士攻击的回合 - // 这里计算勇士攻击时发生的各种变化 + let mon_damage = 0 + let hero_damage = 0 + //这里计算勇士攻击时发生的各种变化 - // 伤害与回合数增加 - now_mon_hp -= hero_per_damage + hero_per_mdamage; - hero_turn += 1; //勇士回合+1,如果有勇士每回合多次攻击的情况,在这里写判断 - // 无法战斗计算 - if (hero_turn % 50 == 0) { - if (now_mon_hp >= last_mon_hp) return null; - last_mon_hp = now_mon_hp; - } - //重新为长度赋值 - hero_length = length; - mon_length = mon_length - hero_time * mon_speed; + //伤害计算 + let per_damage = Math.max(heroinfo.atk - enemyinfo.def, 0) + let per_mdamage = Math.max(Math.floor(heroinfo.matk * (100 - enemyinfo.mdef) / 100), 0) + mon_damage = per_damage + per_mdamage + //这里记录伤害触发后的属性变化和动画,同时计入diff + let animate = core.plugin.heroanimate[equip0] ?? "sword" + //这里可通过if更改默认的武器攻击特效 + enemy_animate.push(animate) + + enemyinfo.hp -= mon_damage + enemy_diff.hp = (enemy_diff.hp ?? 0) - mon_damage + heroinfo.now -= oneTurn + hero_turn++ + onattack = true } - let hero_diff = {}, - mon_diff = {}; - //这里插入汇总勇士和怪物在此回合结束时的情况变化(hp, atk, def, speed, spell, damage, etc),用以跑条动画读取 - heroDiffPerTurn.push(hero_diff); - enemyDiffPerTurn.push(mon_diff); //将勇士和怪物此回合结束时的属性变动保存到heroPerInfo和enemyPerInfo中,用以跑条动画读取 + + if (enemyinfo.now >= oneTurn) { + //怪物攻击的回合 + let mon_damage = 0 + let hero_damage = 0 + //伤害计算 + let per_damage = Math.max(enemyinfo.atk - heroinfo.def, 0), + per_mdamage = Math.floor(enemyinfo.spell * (100 - heroinfo.mdef) / 100); + + //这里记录伤害触发后的属性变化和动画,同时计入diff、damage + if (core.hasSpecial(mon_special, 6)) { + hero_damage += per_damage * enemy.n + per_mdamage * enemy.n + } else { + hero_damage += per_damage + per_mdamage + } + let animate = core.plugin.enemyanimate[enemy.id] ?? "sword" + //这里可通过if更改默认的怪物攻击特效 + hero_animate.push(animate) //勇士身上绘制sword动画 + if (heroinfo.mhp - hero_damage >= 0) { + heroinfo.mhp = heroinfo.mhp - hero_damage + hero_damage = 0 + } else { + hero_damage -= heroinfo.mhp + heroinfo.hp -= hero_damage + hero_diff.hp = (hero_diff.hp ?? 0) - hero_damage + } + + damage += hero_damage + enemyinfo.now -= oneTurn + mon_turn++ + onattack = true + } + equipInfo.forEach(v => { + if (v.now >= oneTurn) { + let mon_damage = 0 + let hero_damage = 0 + //这里写生效装备的技能效果,同时对双方属性的修改计入diff + let animate = core.plugin.equipanimate[v.id] ?? "sword" + //这里可通过if更改默认的道具特效 + enemy_animate.push(animate) //怪物身上绘制动画 + + v.now -= oneTurn + onattack = true + } + + }) + + if (onattack) { //处理完毕后的数据处理 + heroDiffList.push(hero_diff) + enemyDiffList.push(enemy_diff) + heroanimateList.push(hero_animate) + enemyanimateList.push(enemy_animate) + let a = hero_turn % 50 //出手50回合怪物生命未降低直接判负,避免死循环 + if (a === 0) { + if (enemyinfo.hp >= beforehp) { + return null + } else { + beforehp = enemyinfo.hp + } + } + } } - //下面这些还没修改 - - // 每回合的反击伤害;反击是按照勇士的攻击次数来计算回合 - let counterDamage = 0; - if (core.hasSpecial(mon_special, 8)) - counterDamage += Math.floor( - (enemy.counterAttack || core.values.counterAttack) * hero_atk - ); + //下面这些还没修改,原有技能除先攻、连击外暂时全部移除,所有技能需要在上方的模拟循环中做修正 + /* + // 每回合的反击伤害;反击是按照勇士的攻击次数来计算回合 + let counterDamage = 0; + if (core.hasSpecial(mon_special, 8)) + counterDamage += Math.floor( + (enemy.counterAttack || core.values.counterAttack) * hero_atk + ); - // 净化 - if (core.hasSpecial(mon_special, 9)) - init_damage += Math.floor( - (enemy.purify || core.values.purify) * hero_mdef - ); - //上面这些还没修改 - //勇士护盾计算 - let barrier = Math.floor(hero_spell * hero_mhp / 100); + // 净化 + if (core.hasSpecial(mon_special, 9)) + init_damage += Math.floor( + (enemy.purify || core.values.purify) * hero_mdef + ); + //上面这些还没修改 + //勇士护盾计算 + let barrier = Math.floor(hero_spell * hero_mhp / 100); - // ------ 支援 ----- // - // 这个递归最好想明白为什么,flag:__extraTurn__是怎么用的 - /*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], { hp: origin_hero_hp, atk: origin_hero_atk, def: origin_hero_def, mdef: 0 }); - if (info == null) { // 小队中任何一个怪物不可战斗,直接返回null - core.removeFlag("__extraTurn__"); - return null; + // ------ 支援 ----- // + // 这个递归最好想明白为什么,flag:__extraTurn__是怎么用的 + /*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], { hp: origin_hero_hp, atk: origin_hero_atk, def: origin_hero_def, mdef: 0 }); + if (info == null) { // 小队中任何一个怪物不可战斗,直接返回null + core.removeFlag("__extraTurn__"); + return null; + } + // 已经进行的回合数 + core.setFlag("__extraTurn__", info.turn); + init_damage += info.damage; + } + if (guard_before_current_enemy) { // --- 先打支援怪物,增加当前回合数 + turn += core.getFlag("__extraTurn__", 0); } - // 已经进行的回合数 - core.setFlag("__extraTurn__", info.turn); - init_damage += info.damage; } - if (guard_before_current_enemy) { // --- 先打支援怪物,增加当前回合数 - turn += core.getFlag("__extraTurn__", 0); - } - } - core.removeFlag("__extraTurn__");*/ + core.removeFlag("__extraTurn__");*/ // ------ 支援END ------ // + /* + // 最终伤害:初始伤害 + 怪物对勇士造成的伤害 + 反击伤害 + damage += init_damage + hero_turn * counterDamage; + // 再扣去护盾 + damage -= barrier; - // 最终伤害:初始伤害 + 怪物对勇士造成的伤害 + 反击伤害 - damage += init_damage + hero_turn * counterDamage; - // 再扣去护盾 - damage -= barrier; - - // 检查是否允许负伤 - if (!core.flags.enableNegativeDamage) damage = Math.max(0, damage); - - // 最后处理仇恨和固伤(因为这两个不能被护盾减伤) - if (core.hasSpecial(mon_special, 17)) { - // 仇恨 - damage += core.getFlag("hatred", 0); - } - if (core.hasSpecial(mon_special, 22)) { - // 固伤 - damage += enemy.damage2 || 0; - } + // 检查是否允许负伤 + if (!core.flags.enableNegativeDamage) damage = Math.max(0, damage); + // 最后处理仇恨和固伤(因为这两个不能被护盾减伤) + if (core.hasSpecial(mon_special, 17)) { + // 仇恨 + damage += core.getFlag("hatred", 0); + } + if (core.hasSpecial(mon_special, 22)) { + // 固伤 + damage += enemy.damage2 || 0; + } + */ return { + start: start, mon_hp: Math.floor(mon_hp), mon_atk: Math.floor(mon_atk), mon_def: Math.floor(mon_def), mon_mdef: Math.floor(mon_mdef), - init_damage: Math.floor(init_damage), - per_damage: Math.floor(per_damage), - hero_per_damage: Math.floor(hero_per_damage), - turn: Math.floor(hero_turn), + mon_speed: Math.floor(mon_speed), + heroDiffList: heroDiffList, + enemyDiffList: enemyDiffList, + heroanimateList: heroanimateList, + enemyanimateList: enemyanimateList, + hero_turn: Math.floor(hero_turn), mon_turn: Math.floor(mon_turn), damage: Math.floor(damage) }; @@ -1401,6 +1549,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = version: core.firstData.version, guid: core.getGuid(), time: new Date().getTime(), + 'material': core.clone(core.material.enemys) }; return data; }, @@ -1415,6 +1564,8 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = core.maps.loadMap(data.maps, null, data.hero.flags), data.values ); + //如果作者造塔想随时修改怪物属性平衡数值,请注释下面这行。该行作用为保存怪物当前属性,用以储存临时修改的怪物属性。 + core.material.enemys = data.material ?? core.material.enemys; core.status.route = core.decodeRoute(data.route); core.control._bindRoutePush(); // 文字属性,全局属性 diff --git a/project/plugins.js b/project/plugins.js index 1b620a5..40962b4 100644 --- a/project/plugins.js +++ b/project/plugins.js @@ -4791,7 +4791,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = // 在此增加新插件 /////// 用户设置 /////// // 将__enable置为false将关闭插件 - var __enable = false; + var __enable = true; // 魔防攻速之类的属性可以在这里加 ['atk', 'def', 'mdef'] var heroStatus = ["atk", "def", "mdef", "hp"]; // saveHero为true 将会把每次造塔测试时的角色数据存下来 否则会读取初始属性 @@ -20360,14 +20360,14 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = }); }, "intro&loop": function () { - // 在此增加新插件 - this.introAndLoop = function (intro, time, loop) { - core.playBgm(intro); - setTimeout(() => { - core.playBgm(loop); - }, time * 1000); - }; - }, + // 在此增加新插件 + this.introAndLoop = function (intro, time, loop) { + core.playBgm(intro); + setTimeout(() => { + core.playBgm(loop); + }, time * 1000); + }; +}, "开局选项悬停": function () { // 在此增加新插件 @@ -20877,8 +20877,8 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = const pos = [px, py]; const easybox = makeBox([90, 212], [80, 22]), easyclosebox = makeBox([290, 212], [40, 22]), - uneasybox = makeBox([250, 300], [80, 22]), - uneasyclosebox = makeBox([290, 325], [40, 22]); + uneasybox = makeBox([265, 310], [65, 20]), + uneasyclosebox = makeBox([290, 330], [40, 20]); if (inRect(pos, easybox) && easy) { easy = false } else if (inRect(pos, uneasybox) && !easy) { @@ -20891,7 +20891,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = } } - + let turn = 0 main.dom.gameDraw.appendChild(animateAttack); const { lcm, gcd } = core.plugin.utils this.drawAttackAnimate = async function ( @@ -20900,8 +20900,12 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = enemyInfo, equipInfo, farme, - damageInfo, - onegcd + onegcd, + heroDiffList, + enemyDiffList, + heroanimateList, + enemyanimateList, + ) { core.lockControl() core.status.event.id = 'battle' @@ -20912,6 +20916,12 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = equipInfo.forEach(function (v) { if (v.isAttack) attack = true; }); + let onattack = false; + if (heroInfo.onAttack) onattack = true; + if (enemyInfo.onAttack) onattack = true; + equipInfo.forEach(function (v) { + if (v.onAttack) onattack = true; + }); core.clearMap(ctx); let animate = Math.floor(farme / 30); if (easy) { @@ -20951,7 +20961,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.strokeRect(ctx, 112, 139, 32, 48, "rgba(255,255,255,1)", 1); - let img = heroInfo.inAttack ? imagelighter(core.material.images.images["hero.webp"]) : core.material.images.images["hero.webp"] + let img = attack && (heroDiffList[turn].hp < 0) ? imagelighter(core.material.images.images["hero.webp"]) : attack && (heroDiffList[turn].hp > 0) ? imagelighter(core.material.images.images["hero.webp"], 'rgba(0, 255, 0, 0.5)') : core.material.images.images["hero.webp"] core.drawImage( ctx, img, @@ -20979,7 +20989,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.setTextAlign(ctx, "right"); if (enemyInfo.cls === "enemys") { core.strokeRect(ctx, 272, 155, 32, 32, "rgba(255,255,255,1)", 1); - let img = enemyInfo.inAttack ? imagelighter(core.getBlockInfo(enemyInfo.id).image) : core.getBlockInfo(enemyInfo.id).image + let img = attack && (enemyDiffList[turn].hp < 0) ? imagelighter(core.getBlockInfo(enemyInfo.id).image) : attack && (enemyDiffList[turn].hp > 0) ? imagelighter(core.getBlockInfo(enemyInfo.id).image, 'rgba(0, 255, 0, 0.5)') : core.getBlockInfo(enemyInfo.id).image core.drawImage( ctx, img, @@ -20994,7 +21004,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = ); } else { core.strokeRect(ctx, 272, 139, 32, 48, "rgba(255,255,255,1)", 1); - let img = enemyInfo.inAttack ? imagelighter(core.getBlockInfo(enemyInfo.id).image) : core.getBlockInfo(enemyInfo.id).image + let img = attack && (enemyDiffList[turn].hp < 0) ? imagelighter(core.getBlockInfo(enemyInfo.id).image) : attack && (enemyDiffList[turn].hp > 0) ? imagelighter(core.getBlockInfo(enemyInfo.id).image, 'rgba(0, 255, 0, 0.5)') : core.getBlockInfo(enemyInfo.id).image core.drawImage( ctx, img, @@ -21048,7 +21058,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = "bold 36px pala" ); - if (!attack) enemyInfo.now += enemyInfo.speed / onegcd; + if (!attack && !onattack) enemyInfo.now += enemyInfo.speed / onegcd; let enemynow = Math.min(100 + enemyInfo.now / oneTurn * 215, 315); ctx.fillStyle = "#FFFFFF"; ctx.beginPath(); @@ -21087,7 +21097,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = } core.drawLine(ctx, 100, 105, 315, 105, "#FFFFFF", 5); equipInfo.forEach(function (v) { - if (!attack) v.now += v.speed / onegcd; + if (!attack && !onattack) v.now += v.speed / onegcd; let vnow = Math.min(100 + v.now / oneTurn * 215, 315); ctx.beginPath(); ctx.moveTo(vnow, 100); @@ -21099,7 +21109,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.drawIcon(ctx, v.id, vnow - 16, 64, 32, 32); }); - if (!attack) heroInfo.now += hero.speed / onegcd; + if (!attack && !onattack) heroInfo.now += hero.speed / onegcd; let heronow = Math.min(100 + heroInfo.now / oneTurn * 215, 315); ctx.beginPath(); ctx.moveTo(heronow, 100); @@ -21171,10 +21181,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.fillBoldText( ctx, "法攻 " + - core.formatBigNumber((heroInfo.matk / 100) * heroInfo.spell) + - "(" + - heroInfo.matk + - "%)", + core.formatBigNumber(heroInfo.matk), 90, 285, "#FFFFFF", @@ -21184,10 +21191,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.fillBoldText( ctx, "护盾 " + - core.formatBigNumber((heroInfo.mhp / 100) * heroInfo.spell) + - "(" + - heroInfo.mhp + - "%)", + core.formatBigNumber(heroInfo.mhp), 90, 305, "#FFFFFF", @@ -21214,7 +21218,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = ); core.strokeRect(ctx, 112, 139, 32, 48, "rgba(255,255,255,1)", 1); - let img = heroInfo.inAttack ? imagelighter(core.material.images.images["hero.webp"]) : core.material.images.images["hero.webp"] + let img = attack && (heroDiffList[turn].hp < 0) ? imagelighter(core.material.images.images["hero.webp"]) : attack && (heroDiffList[turn].hp > 0) ? imagelighter(core.material.images.images["hero.webp"], 'rgba(0, 255, 0, 0.5)') : core.material.images.images["hero.webp"] core.drawImage( ctx, img, @@ -21242,7 +21246,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.setTextAlign(ctx, "right"); if (enemyInfo.cls === "enemys") { core.strokeRect(ctx, 272, 155, 32, 32, "rgba(255,255,255,1)", 1); - let img = enemyInfo.inAttack ? imagelighter(core.getBlockInfo(enemyInfo.id).image) : core.getBlockInfo(enemyInfo.id).image + let img = attack && (enemyDiffList[turn].hp < 0) ? imagelighter(core.getBlockInfo(enemyInfo.id).image) : attack && (enemyDiffList[turn].hp > 0) ? imagelighter(core.getBlockInfo(enemyInfo.id).image, 'rgba(0, 255, 0, 0.5)') : core.getBlockInfo(enemyInfo.id).image core.drawImage( ctx, img, @@ -21257,7 +21261,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = ); } else { core.strokeRect(ctx, 272, 139, 32, 48, "rgba(255,255,255,1)", 1); - let img = enemyInfo.inAttack ? imagelighter(core.getBlockInfo(enemyInfo.id).image) : core.getBlockInfo(enemyInfo.id).image + let img = attack && (enemyDiffList[turn].hp < 0) ? imagelighter(core.getBlockInfo(enemyInfo.id).image) : attack && (enemyDiffList[turn].hp > 0) ? imagelighter(core.getBlockInfo(enemyInfo.id).image, 'rgba(0, 255, 0, 0.5)') : core.getBlockInfo(enemyInfo.id).image core.drawImage( ctx, img, @@ -21274,8 +21278,9 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.drawIcon(ctx, "hp", 330, 190, 16, 16); core.drawIcon(ctx, "atk", 330, 210, 16, 16); core.drawIcon(ctx, "def", 330, 230, 16, 16); - core.drawIcon(ctx, "amulet", 330, 250, 16, 16); - core.drawIcon(ctx, "jumpShoes", 330, 270, 16, 16); + core.drawIcon(ctx, "I374", 330, 250, 16, 16); + core.drawIcon(ctx, "amulet", 330, 270, 16, 16); + core.drawIcon(ctx, "jumpShoes", 330, 290, 16, 16); core.fillBoldText( ctx, core.formatBigNumber(enemyInfo.hp, true) + " 生命", @@ -21303,10 +21308,9 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = "#000000", "bold 14px Arial" ); - core.fillBoldText( ctx, - (enemyInfo.mdef ?? 0) * 100 + "% 法抗", + (enemyInfo.spell ?? 0) + " 法qi强", 330, 265, "#FFFFFF", @@ -21315,30 +21319,39 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = ); core.fillBoldText( ctx, - core.formatBigNumber(enemyInfo.speed) + " 速度", + (enemyInfo.mdef ?? 0) * 100 + "% 法抗", 330, 285, "#FFFFFF", "#000000", "bold 14px Arial" ); + core.fillBoldText( + ctx, + core.formatBigNumber(enemyInfo.speed) + " 速度", + 330, + 305, + "#FFFFFF", + "#000000", + "bold 14px Arial" + ); core.fillBoldText( ctx, "简易模式", 330, - 315, + 325, "#FFFF60", "#000000", - "bold 18px Verdana" + "bold 16px Verdana" ); core.fillBoldText( ctx, "跳过", 330, - 340, + 345, "#FFFF60", "#000000", - "bold 18px Verdana" + "bold 16px Verdana" ); core.fillBoldText( @@ -21360,7 +21373,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = "bold 36px pala" ); - if (!attack) enemyInfo.now += enemyInfo.speed / onegcd; + if (!attack && !onattack) enemyInfo.now += enemyInfo.speed / onegcd; let enemynow = Math.min(100 + enemyInfo.now / oneTurn * 215, 315); ctx.fillStyle = "#FFFFFF"; ctx.beginPath(); @@ -21399,7 +21412,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = } core.drawLine(ctx, 100, 105, 315, 105, "#FFFFFF", 5); equipInfo.forEach(function (v) { - if (!attack) v.now += v.speed / onegcd; + if (!attack && !onattack) v.now += v.speed / onegcd; let vnow = Math.min(100 + v.now / oneTurn * 215, 315); ctx.beginPath(); ctx.moveTo(vnow, 100); @@ -21411,7 +21424,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.drawIcon(ctx, v.id, vnow - 16, 64, 32, 32); }); - if (!attack) heroInfo.now += hero.speed / onegcd; + if (!attack && !onattack) heroInfo.now += hero.speed / onegcd; let heronow = Math.min(100 + heroInfo.now / oneTurn * 215, 315); ctx.beginPath(); ctx.moveTo(heronow, 100); @@ -21424,13 +21437,13 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = } let nowattacking = false if (heroInfo.now >= oneTurn && !heroInfo.isAttack) { - + heroInfo.onattack = false heroInfo.isAttack = true; nowattacking = true } if (enemyInfo.now >= oneTurn && !enemyInfo.isAttack) { - + enemyInfo.onattack = false enemyInfo.isAttack = true; nowattacking = true @@ -21439,6 +21452,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = equipInfo.forEach(v => { if (v.now >= oneTurn && !v.isAttack) { v.isAttack = true; + v.onattack = false nowattacking = true equipanimate.push(v) @@ -21446,58 +21460,54 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = }); if (!attack && nowattacking) { - if (heroInfo.isAttack) { - enemyInfo.inAttack = true - const herodamage = -Math.max(heroInfo.atk - enemyInfo.def, 0) - Dove.MorePerform.ShowDamagePop.PopDamage( - ctx, // 默认画布名称 - 270, // 英雄位置 x - 140, // 英雄位置 y - herodamage, // 伤害值 - 18, // 默认字体大小 - "Arial", //默认字体 - null, // 默认颜色 - null, // 默认描边颜色 - 0, // 默认水平速度 - -1, // 默认垂直速度 - 0, // 默认重力 - 90 // 默认显示时长(帧数) - ); - enemyInfo.hp += herodamage - if (enemyInfo.hp < 0) enemyInfo.hp = 0 - animateOnAttack('sword', true) + let herodamage = enemyDiffList[turn].hp + let text = herodamage === 0 ? "抵抗" : herodamage + if (enemyDiffList[turn].attack) Dove.MorePerform.ShowDamagePop.PopDamage( + ctx, // 默认画布名称 + 270, // 英雄位置 x + 140, // 英雄位置 y + text, // 伤害值 + 18, // 默认字体大小 + "Arial", //默认字体 + null, // 默认颜色 + null, // 默认描边颜色 + 0, // 默认水平速度 + -1, // 默认垂直速度 + 0, // 默认重力 + 90 // 默认显示时长(帧数) + ); + for (const v in enemyDiffList[turn]) { + enemyInfo[v] += enemyDiffList[turn][v] } - if (enemyInfo.isAttack) { - heroInfo.inAttack = true - const enemydamage = -Math.max(enemyInfo.atk - heroInfo.def, 0) - Dove.MorePerform.ShowDamagePop.PopDamage( - ctx, // 默认画布名称 - 110, // 英雄位置 x - 140, // 英雄位置 y - enemydamage, // 伤害值 - 18, // 默认字体大小 - "Arial", //默认字体 - null, // 默认颜色 - null, // 默认描边颜色 - 0, // 默认水平速度 - -1, // 默认垂直速度 - 0, // 默认重力 - 90 // 默认显示时长(帧数) - ); - heroInfo.hp += enemydamage - if (heroInfo.hp < 0) heroInfo.hp = 0 - animateOnAttack('sword', false) - } - if (equipanimate.length > 0) { - equipanimate.forEach(v => { - animateOnAttack('sword', true) - }) + enemyanimateList[turn].forEach(v => animateOnAttack(v, true)) + const enemydamage = heroDiffList[turn].hp + text = enemydamage === 0 ? "抵抗" : enemydamage + if (heroDiffList[turn].attack) Dove.MorePerform.ShowDamagePop.PopDamage( + ctx, // 默认画布名称 + 110, // 英雄位置 x + 140, // 英雄位置 y + text, // 伤害值 + 18, // 默认字体大小 + "Arial", //默认字体 + null, // 默认颜色 + null, // 默认描边颜色 + 0, // 默认水平速度 + -1, // 默认垂直速度 + 0, // 默认重力 + 90 // 默认显示时长(帧数) + ); + for (const v in heroDiffList[turn]) { + heroInfo[v] += heroDiffList[turn][v] } + heroanimateList[turn].forEach(v => animateOnAttack(v, false)) + if (enemyDiffList[turn] < 0) enemyInfo.inAttack = true + if (heroDiffList[turn] < 0) heroInfo.inAttack = true + if (heroInfo.hp < 0) heroInfo.hp = 0 + if (enemyInfo.hp < 0) enemyInfo.hp = 0 await Promise.all([await playinganimate(), new Promise(resolve => { if (heroInfo.isAttack) { - enemyInfo.inAttack = false heroInfo.now = 0; heroInfo.isAttack = false; } @@ -21505,7 +21515,6 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = }), new Promise(resolve => { if (enemyInfo.isAttack) { - heroInfo.inAttack = false enemyInfo.now = 0; enemyInfo.isAttack = false; } @@ -21519,6 +21528,10 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = }) } resolve() + }), + new Promise(resolve => { + turn++ + resolve() }) ]) @@ -21546,53 +21559,26 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = this.attackAnimate = function ( enemyId, + heroInfo, enemyInfo, - damageInfo, - equipInfo = [] + equipInfo, + oneTurn, + onegcd, + heroDiffList, + enemyDiffList, + heroanimateList, + enemyanimateList ) { //参数分别为怪物id、真实属性,战斗信息,特殊装备(如火焰风衣)属性特殊装备属性为以元组{equipId,oneDamage,speed,now:0}构成的数组(列出每个需要计算的特殊装备,没有则为空数组或不填) core.lockControl(); core.clearMap(ctx); core.status.event.id = "attackAnimate"; - let hero_hp = core.getRealStatusOrDefault(hero, "hp"), - hero_atk = core.getRealStatusOrDefault(hero, "atk"), - hero_def = core.getRealStatusOrDefault(hero, "def"), - hero_spell = core.getRealStatusOrDefault(hero, "spell"), - hero_matk = core.getRealStatusOrDefault(hero, "matk"), - hero_mdef = core.getRealStatusOrDefault(hero, "mdef"), - hero_speed = core.getRealStatusOrDefault(hero, "speed"), - hero_hpmax = core.getRealStatusOrDefault(hero, "hpmax"), - hero_mhp = core.getRealStatusOrDefault(hero, "mhp"); - const heroInfo = { - hp: hero_hp, - hpmax: hero_hpmax, - atk: hero_atk, - def: hero_def, - spell: hero_spell, - mhp: hero_mhp, - matk: hero_matk, - mdef: hero_mdef, - speed: hero_speed, - now: 0, - isAttack: false, - }; + turn = 0 enemyInfo.id = enemyId; enemyInfo.cls = core.getClsFromId(enemyId); enemyInfo.name = core.material.enemys[enemyId].name; - enemyInfo.now = 0; - enemyInfo.isAttack = false; - let oneTurn = [heroInfo.speed, enemyInfo.speed]; - if (equipInfo.length > 0) { - for (let i; i < equipInfo.length - 1; i++) { - equipInfo[i].now = 0; - equipInfo[i].isAttack = false; - oneTurn.push(equipInfo[i].speed); - } - } - const onegcd = gcd(...oneTurn) - oneTurn = lcm(...oneTurn) / onegcd - if (oneTurn < 60) oneTurn *= Math.round(60 / oneTurn) + if (oneTurn < 120) oneTurn *= Math.round(120 / oneTurn) let time = 0, farme = 0; @@ -21605,8 +21591,11 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = enemyInfo, equipInfo, farme, - damageInfo, - onegcd + onegcd, + heroDiffList, + enemyDiffList, + heroanimateList, + enemyanimateList ); @@ -22514,5 +22503,21 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = ]; +}, + "动画及周期装备映射": function () { + // 在此增加新插件 + this.equip = { //所有回合中的装备及速度 + "sword1": { id: 'sword1', speed: 10 } + } + this.heroanimate = { //勇士武器对应的动画(key为主手武器ID,value为帧动画名) + "sword1": "sword" + } + this.enemyanimate = { //怪物对应的动画(key为怪物ID,value为帧动画名) + "bat": "sword" + } + this.equipanimate = { //勇士周期性装备对应的动画(key为装备Id,value为帧动画名) + "shield0": "sword" + } + } } \ No newline at end of file