战斗动画及伤害计算函数达成

This commit is contained in:
草莓 2025-03-06 18:35:37 +08:00
parent 11c2174bcd
commit 0a9e8383f6
4 changed files with 447 additions and 279 deletions

View File

@ -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},

View File

@ -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": [
]
}

View File

@ -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();
// 文字属性,全局属性

View File

@ -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为主手武器IDvalue为帧动画名)
"sword1": "sword"
}
this.enemyanimate = { //怪物对应的动画(key为怪物IDvalue为帧动画名)
"bat": "sword"
}
this.equipanimate = { //勇士周期性装备对应的动画(key为装备Idvalue为帧动画名)
"shield0": "sword"
}
}
}