HumanBreak/回合制.js

1484 lines
58 KiB
JavaScript
Raw Normal View History

2023-11-14 18:21:38 +08:00
///<reference path="./src/types/core.d.ts"/>
////////// 回合制总览 ///////////////
function screenFlash(color, time, times, moveMode) {
return new Promise(res => {
core.screenFlash(color, time, times, moveMode, res);
});
} // 闪烁事件转解析脚本
function sleep(time) {
return new Promise(res => {
setTimeout(res, time);
});
} // 等待事件转解析脚本
function setCurtain(color, time, moveMode) {
return new Promise(res => {
core.setCurtain(color, time, moveMode, res);
});
} // 改变画面色调事件转解析脚本
function showImage(code, image, sloc, loc, opacityVal, time) {
return new Promise(res => {
core.showImage(code, image, sloc, loc, opacityVal, time, res);
});
} //图片移动事件转解析脚本
function hideImage(code, time) {
return new Promise(res => {
core.hideImage(code, time, res);
});
} // 隐藏图片事件转解析脚本
function choices_libs(content, choices, width, ctx) {
return new Promise(res => {
core.drawChoices(content, choices, width, ctx, res);
});
} // 选项框事件转解析脚本
// 固定回合制内容获取 step 1
this._turnBattle = function (enemyId, mon_mdef, insertAction) {
// 获得楼层应需图片
var BgImage = null;
let floorId = core.status.floorId;
switch (floorId) {
case 'AT1':
BgImage = 'turnBg1.jpg';
break;
}
// 获得主角基础图片
var heroBg = [];
// 获得主角形象
let heroId = core.getFlag('heroId');
if (heroId == 0) heroBg.push('heroTurnImage_lx.png');
if (heroId == 1) heroBg.push('heroTurnImage_peixi.png');
let name = heroBg[0].replace('.png', '');
if (core.material.images.images[name + 1 + '.png'])
heroBg.push(name + 1 + '.png'); // 如果存在主角战损图片,则加入新图片
if (core.material.images.images[name + 2 + '.png'])
heroBg.push(name + 2 + '.png');
if (core.material.images.images[name + 3 + '.png'])
heroBg.push(name + 3 + '.png');
// 怪物合集
// 获得怪物基础图片和音乐
let monName = null; // 怪物名称
let monHpCaseNum = 1; // 怪物血条倍率
let monImage = null; // 怪物图像
let bgm = null; // 背景音乐
switch (enemyId) {
case 'E418':
monName = '森林黄莱姆';
monHpCaseNum = 2;
monImage = 'slime1.png';
bgm = 'turnBgm1.mp3';
break;
}
// 如果怪物图像存在分歧
var monBgList = [monImage];
let name2 = monImage.replace('.png', '');
if (core.material.images.images[name2 + 1 + '.png'])
monBgList.push(name2 + 1 + '.png'); // 如果存在怪物战损图片,则加入新图片
if (core.material.images.images[name2 + 2 + '.png'])
monBgList.push(name2 + 2 + '.png');
if (core.material.images.images[name2 + 3 + '.png'])
monBgList.push(name2 + 3 + '.png');
// 获得主角基础属性
// 基础属性
let heroHp =
core.getFlag('turnHeroHp') ||
Math.min(
core.status.hero.hp,
Math.max(core.status.hero.mdef * 10, core.status.hero.lv * 100)
); // 回合制中若没有特殊情况主角所持有的最高生命值不超过魔防的10倍,如果魔防太低,那么将会取魔防 + 自身等级 * 100 作为自己的生命值
const enemyInfo = core.enemys.getEnemyInfo('greenSlime');
let heroHpMax =
core.getFlag('turnHeroHpMax') ||
Math.min(
core.status.hero.hp,
Math.max(core.status.hero.mdef * 10, core.status.hero.lv * 100)
);
let heroAtk = core.getFlag('turnHeroAtk') || core.status.hero.atk;
let heroDef = core.getFlag('turnHeroDef') || core.status.hero.def;
let heroMdef = core.getFlag('turnHeroMdef') || core.status.hero.mdef;
let heroGodAtk = enemyInfo.god_per_damage || 0; // 神圣攻击
let physics_resist = enemyInfo.physics_resist || 0; // 物伤抵抗
let pray_drink = enemyInfo.pray_drink || 0; // 神圣祷吸
// 获得怪物基础属性
// 如果属性不是初始值*在回合战中出现过变动,那么将使用变动量)
let Nx = core.nextX();
let Ny = core.nextY();
let thisMonHp =
core.getFlag('turnMonHp') || core.getEnemyInfo(enemyId).hp || 0;
let thisMonAtk =
core.getFlag('turnMonAtk') || core.getEnemyInfo(enemyId).atk || 0;
let thisMonDef =
core.getFlag('turnMonDef') || core.getEnemyInfo(enemyId).def || 0;
let thisMonHpMax =
core.getFlag('turnMonHpMax') || core.getEnemyInfo(enemyId).hp;
let thisMonMdef = mon_mdef || 0;
// 获得主角特技文本和效果
// name 名称 text 文本 flag 变量开关名称 freezeTurn 冷却时间(可受增益影响,若不填则可随意使用) sp 耗费蓝量可不填action行为 value:行为的数值特殊情况下不填。effect 对敌人造成的特殊影响,若填此项,则 time 也需要填animate 技能动画,order,动画次数
let heroSpecailList = [];
// 所有特技
let moreList = [];
moreList.push(
{
name: '普通攻击',
text: '一次普通的攻击',
flag: 'attack_skill',
action: 'atk',
value: heroAtk - thisMonDef || 0,
animate: 'hand',
pray_drink: pray_drink > 0 ? thisMonAtk * pray_drink * 2 : null // 类似于普通攻击或者多连击可以触发神圣祷吸
},
{
name:
'二连击' +
(core.getFlag('doubleAttack_skill_freeze') > 0
? '(冷却 ' +
core.getFlag('doubleAttack_skill_freeze') +
' 回合)'
: ''),
text: '对敌人进行连续两次普通攻击。冷却时间3回合',
flag: 'doubleAttack_skill',
freezeTurn:
3 - core.getFlag('doubleAttack_skill_reduceFreeze') || 3,
action: 'atk',
value: (heroAtk - thisMonDef) * 2 || 0,
animate: 'hand',
order: 2,
pray_drink: pray_drink > 0 ? thisMonAtk * pray_drink * 2 : null // 类似于普通攻击或者多连击可以触发神圣祷吸
},
{
name:
'闪烁' +
(core.getFlag('flicker_skill_freeze') > 0
? '(冷却 ' +
core.getFlag('flicker_skill_freeze') +
' 回合)'
: ''),
text: '发出耀光对敌人造成1000%神圣伤害并使怪物此回合和下回合眩晕。冷却时间4回合',
flag: 'flicker_skill',
freezeTurn: 4 - core.getFlag('flicker_skill_reduceFreeze') || 4,
action: 'atk',
value: heroGodAtk * 10 || 0,
effect: 'swim',
time: 2,
animate: 'light1'
}
);
// 获得主角已持有的特级,没学习的不算在内(需区分不同的角色)
for (let i = 0; i < moreList.length; i++) {
if (core.getFlag('heroId') == core.getFlag(moreList[i].flag)) {
heroSpecailList.push(moreList[i]);
}
}
// 获得怪物特技文本和效果
let monSpecailList = [];
// 1.怪物id 2.特技种类(可以有多个,按顺序使用并循环 例如atk:直接伤害类) name:技能名称action:行为value:行为的数值特殊情况下不填animate行为动画
// 3.turnEnd 回合后状态变动(turnEndOccur:变动效果例如cutDef为降低它自己的防御力turnEndValue变动数值,effect变动回合时长若填max则持续无限)
// 4.rival 对手(主角)受到的影响特效,feedback 反馈效果 se音效
monSpecailList.push({
enemyId: 'E418', // 森林黄莱姆 剧情战斗1层
special: [
{
name: '普通攻击',
action: 'atk',
value: thisMonAtk,
animate: 'hand'
}, // 普通攻击
{
name: '重击',
action: 'atk',
value: thisMonAtk * 1.5,
animate: 'hand'
}, // 重击1.5倍攻击伤害
{
name: '蓄力',
action: 'addAtk',
value: thisMonAtk,
animate: 'hand'
}, // 蓄力使攻击提升至2倍
{
name: '粘液重创',
action: 'Matk',
value: thisMonAtk,
animate: 'hand'
}, // 无视防御的粘液重创,之后防御力降低100%,持续两回合
{ name: '发呆', action: 'sleep' }, // 发呆,什么也不做
{ name: '发呆', action: 'sleep' } // 发呆,什么也不做
],
turnEnd: [
null,
null,
null,
{
name: '怪物的防御力降低50%!',
turnEndOccur: 'monDefReduce',
value: 0.5,
effect: 2
},
null,
null
],
rival: [
{ feedback: 'hit' },
{ feedback: 'hit' },
null,
{ feedback: 'bigHit' },
null,
null
]
});
////////// 回合制开始后的开场舞台 //////////////
if (insertAction) {
// 检查是否为执行内容而非调用内容,如果是调用内容,跳过该步骤
/*let cc = async function firstBattle() {
const toWait_1 = [ // 需要不等待执行完毕的内容第一组
screenFlash([255, 255, 255, 1], 300, 1),
sleep(50),
setCurtain([0, 0, 0, 1], 800, "easeIn"),
core.drawWarning(Nx, Ny, '')
]
core.lockControl();
core.pauseBgm();
core.playBgm("turnBgm1.mp3");
core.playSound("Battle1.ogg");
await Promise.all(toWait_1);
await showImage(31, monImage, [0, 0, null, null], [240, 0, null, null], 1, 0);
await showImage(32, heroBg[0], [0, 0, null, null], [-25, 155, 180, 268], 1, 0);
await showImage(30, BgImage, [0, 0, null, null], [0, 0, null, null], 1, 0);
await showImage(100, "hei.png", [0, 0], null, 1, 0);
await sleep(500);
await setCurtain(null, 1);
core.drawUIEventSelector(10, "winskin.png", 0, 152, 155, 268);
await hideImage(100, 700);
let UI = "turnBattleUI";
core.createCanvas(UI, 0, 0, 416, 416, 151);
core.fillBoldText(UI, "HP", 170, 378, [255, 99, 99, 1], [36, 31, 5, 1], "bold 18px gameFont");
core.fillBoldText(UI, "MP", 172, 390, [140, 176, 255, 1], [36, 31, 5, 1], "bold 14px gameFont");
core.fillBoldText(UI, "Atk", 160, 408, [255, 255, 255, 1], null, "bold 16px gameFont");
core.fillBoldText(UI, "Def", 240, 408, [255, 255, 255, 1], null, "bold 16px gameFont");
core.fillBoldText(UI, "Shd", 320, 408, [255, 255, 255, 1], null, "bold 16px gameFont");
core.fillBoldText(UI, "Atk", 5, 70, [255, 255, 255, 1], null, "bold 16px gameFont");
core.fillBoldText(UI, "Def", 85, 70, [255, 255, 255, 1], null, "bold 16px gameFont");
core.fillBoldText(UI, "Shd", 165, 70, [255, 255, 255, 1], null, "bold 16px gameFont");
core.strokeRect(UI, 200, 360, 200, 30, [123, 176, 193, 1], 2);
core.drawLine(UI, 200, 380, 400, 380, [123, 176, 193, 1], 2);
core.drawLine(UI, 200, 390, 400, 390, [94, 143, 159, 1], 2);
core.drawLine(UI, 200, 360, 400, 360, [94, 143, 159, 1], 2);
core.strokeRect(UI, 10, 30, 240, 20, [123, 176, 193, 1], 2);
core.drawLine(UI, 10, 50, 250, 50, [94, 143, 159, 1], 2);
core.drawLine(UI, 10, 30, 250, 30, [193, 226, 236, 1], 2);
core.plugin._turnBattleDrawNum(enemyId);*/
core.insertAction([
{ type: 'pauseBgm' },
{ type: 'playBgm', name: 'turnBgm1.mp3' },
{ type: 'playSound', name: 'Battle1.ogg' },
{
type: 'screenFlash',
color: [255, 255, 255, 1],
time: 300,
times: 1,
async: true
},
{ type: 'sleep', time: 50 },
{
type: 'setCurtain',
color: [0, 0, 0, 1],
time: 800,
moveMode: 'easeIn',
keep: true,
async: true
},
{
type: 'function',
function:
'function(){\ncore.drawWarning(' +
Nx +
',' +
Ny +
", '');\n}"
},
{ type: 'waitAsync' },
{
type: 'showImage',
code: 26,
image: monImage,
sloc: [0, 0, ,],
loc: [240, 30, ,],
opacity: 1,
time: 0
},
{
type: 'showImage',
code: 27,
image: heroBg[0],
sloc: [0, 0, ,],
loc: [-25, 155, 180, 268],
opacity: 1,
time: 0
},
{
type: 'showImage',
code: 25,
image: BgImage,
sloc: [0, 0, ,],
loc: [0, 0, ,],
opacity: 1,
time: 0
},
{
type: 'showImage',
code: 100,
image: 'hei.png',
loc: [0, 0],
opacity: 1,
time: 0
},
{ type: 'sleep', time: 500 },
{ type: 'setCurtain', time: 1 },
{
type: 'drawSelector',
image: 'winskin.png',
code: 31,
x: 0,
y: 152,
width: 155,
height: 268
},
{ type: 'hideImage', code: 100, time: 700 },
{
type: 'previewUI',
action: [
{ type: 'setAttribute', alpha: 1, z: 130 },
{
type: 'fillBoldText',
x: 170,
y: 378,
style: [255, 99, 99, 1],
strokeStyle: [36, 31, 5, 1],
font: 'bold 18px gameFont',
text: 'HP'
},
{
type: 'fillBoldText',
x: 172,
y: 390,
style: [140, 176, 255, 1],
strokeStyle: [36, 31, 5, 1],
font: 'bold 14px gameFont',
text: 'MP'
},
{
type: 'fillBoldText',
x: 160,
y: 408,
style: [255, 255, 255, 1],
font: 'bold 16px gameFont',
text: 'Atk:'
},
{
type: 'fillBoldText',
x: 240,
y: 408,
style: [255, 255, 255, 1],
font: 'bold 16px gameFont',
text: 'Def:'
},
{
type: 'fillBoldText',
x: 320,
y: 408,
style: [255, 255, 255, 1],
font: 'bold 16px gameFont',
text: 'Shd:'
},
{
type: 'fillBoldText',
x: 5,
y: 70,
style: [255, 255, 255, 1],
font: 'bold 16px gameFont',
text: 'Atk:'
},
{
type: 'fillBoldText',
x: 85,
y: 70,
style: [255, 255, 255, 1],
font: 'bold 16px gameFont',
text: 'Def:'
},
{
type: 'fillBoldText',
x: 165,
y: 70,
style: [255, 255, 255, 1],
font: 'bold 16px gameFont',
text: 'Shd:'
},
{
type: 'strokeRect',
x: 200,
y: 360,
width: 200,
height: 30,
style: [123, 176, 193, 1],
lineWidth: 2
},
{
type: 'drawLine',
x1: 200,
y1: 380,
x2: 400,
y2: 380,
style: [123, 176, 193, 1],
lineWidth: 2
},
{
type: 'drawLine',
x1: 200,
y1: 390,
x2: 400,
y2: 390,
style: [94, 143, 159, 1],
lineWidth: 2
},
{
type: 'drawLine',
x1: 200,
y1: 360,
x2: 400,
y2: 360,
style: [193, 226, 236, 1],
lineWidth: 2
},
{
type: 'strokeRect',
x: 10,
y: 30,
width: 240,
height: 20,
style: [123, 176, 193, 1],
lineWidth: 2
},
{
type: 'drawLine',
x1: 10,
y1: 50,
x2: 250,
y2: 50,
style: [94, 143, 159, 1]
},
{
type: 'drawLine',
x1: 10,
y1: 30,
x2: 250,
y2: 30,
style: [193, 226, 236, 1],
lineWidth: 2
}
]
},
{
type: 'function',
function:
"function(){\ncore.plugin._turnBattleDrawNum('" +
enemyId +
"');\n}"
}
]);
}
return {
BgImage: BgImage,
heroId: heroId,
heroBg: heroBg,
monName: monName,
monImage: monImage,
monBgList: monBgList,
monHpCaseNum: monHpCaseNum,
heroHp: heroHp,
heroheroHpMax: heroHpMax,
heroAtk: heroAtk,
heroDef: heroDef,
heroMdef: heroMdef,
thisMonHp: thisMonHp,
thisMonHpMax: thisMonHpMax,
thisMonAtk: thisMonAtk,
thisMonDef: thisMonDef,
thisMonMdef: thisMonMdef,
heroSpecailList: heroSpecailList,
monSpecailList: monSpecailList
};
};
/////// 循环绘制内容预备(需要不断变动的绘制内容) /////////
// 绘制变动数据(如果为战斗刚刚开始,则跳过执行双方变动数据,绘制固定数据)
this._turnBattleDrawNum = function (enemyId) {
// 回合数据
let turnInfo = core.plugin._turnBattle(enemyId, null, null);
let BgImage = turnInfo.BgImage; // 场景图像
let monName = turnInfo.monName; // 怪物名称
let monImage = turnInfo.monImage; // 怪物图像
let monBgList = turnInfo.monBgList; // 怪物图像合集如果存在多张将替代monImage
if (monBgList > 1) {
}
let heroImageList = turnInfo.heroBg; // 主角图像合集
// 主角血条量(战斗初始为满条,在下面条件分歧中进行改变)
let heroHpCase = 1;
// 主角蓝条量(战斗初始为满条,在下面条件分歧中进行改变)
let heroSpCase = 1;
// 怪物血条量(战斗初始为满条,在下面条件分歧中进行改变)
let monHpCase = 1;
// 属性获取
let heroHp = core.getFlag('turnHeroHp') || turnInfo.heroHp || 0,
heroHpMax = core.getFlag('turnHeroHpmax') || heroHp || 0,
heroAtk = core.getFlag('turnHeroAtk') || turnInfo.heroAtk || 0,
heroDef = core.getFlag('turnHeroDef') || turnInfo.heroDef || 0,
heroMdef = core.getFlag('turnHeroMdef') || turnInfo.heroMdef || 0;
let heroSp = turnInfo.sp || 0;
let heroSpMax = turnInfo.spmax || 0;
let monHp = core.getFlag('turnMonHp') || turnInfo.thisMonHp || 0,
monHpMax = core.getFlag('turnMonHpmax') || turnInfo.thisMonHpMax || 0,
monAtk = core.getFlag('turnMonAtk') || turnInfo.thisMonAtk || 0,
monDef = core.getFlag('turnMondef') || turnInfo.thisMonDef || 0,
monMdef = core.getFlag('turnMonMdef') || turnInfo.thisMonMdef || 0;
// 如果不是初始回合则需要调用flag的数据
let turn = core.getFlag('thisTurn') || 1;
if (core.getFlag('thisTurn') > 1) {
if (core.getFlag('turnHeroHp'))
heroHpCase = core.getFlag('turnHeroHp') / turnInfo.heroHp; // 如果主角血条发生过变化,则变动百分比
if (core.getFlag('turnHeroSp'))
heroSpCase = core.getFlag('turnMonSp') / turnInfo.heroSp;
if (core.getFlag('turnMonHp'))
monHpCase = core.getFlag('turnMonHp') / turnInfo.thisMonHp; // 如果怪物血条发生过变化,则变动百分比
} else {
// 如果只是初始回合,则直接搬运首发函数的回调
heroHp = turnInfo.heroHp;
heroHpMax = heroHp;
heroAtk = turnInfo.heroAtk;
heroDef = turnInfo.heroDef;
heroMdef = turnInfo.heroMdef;
heroSp = turnInfo.sp || 0;
heroSpMax = turnInfo.spmax || 0;
monHp = turnInfo.thisMonHp;
monHpMax = turnInfo.thisMonHpMax;
monAtk = turnInfo.thisMonAtk;
monDef = turnInfo.thisMonDef;
monMdef = turnInfo.thisMonMdef;
core.insertAction([
{
type: 'fillBoldText',
x: 10,
y: 20,
style: [255, 255, 255, 1],
font: 'bold 20px gameFont',
text: monName
},
{
type: 'fillBoldText',
x: 40,
y: 70,
style: [255, 255, 255, 1],
strokeStyle: [255, 2, 2, 1],
font: 'bold 12px gameFont',
text: monAtk
},
{
type: 'fillBoldText',
x: 120,
y: 70,
style: [255, 255, 255, 1],
strokeStyle: [38, 48, 255, 1],
font: 'bold 12px gameFont',
text: monDef
},
{
type: 'fillBoldText',
x: 200,
y: 70,
style: [255, 255, 255, 1],
strokeStyle: [30, 255, 24, 1],
font: 'bold 12px gameFont',
text: monMdef
},
{
type: 'fillBoldText',
x: 195,
y: 408,
style: [255, 255, 255, 1],
strokeStyle: [255, 2, 2, 1],
font: 'bold 12px gameFont',
text: heroAtk
},
{
type: 'fillBoldText',
x: 275,
y: 408,
style: [255, 255, 255, 1],
strokeStyle: [38, 48, 255, 1],
font: 'bold 12px gameFont',
text: heroDef
},
{
type: 'fillBoldText',
x: 355,
y: 408,
style: [255, 255, 255, 1],
strokeStyle: [30, 255, 24, 1],
font: 'bold 12px gameFont',
text: heroMdef || 0
},
{
type: 'fillRect',
x: 12,
y: 32,
width: 236 * monHpCase,
height: 16,
radius: 4,
style: [255, 70, 70, 1]
},
{
type: 'fillRect',
x: 12,
y: 32,
width: 234 * monHpCase,
height: 2,
radius: 4,
style: [255, 147, 147, 1]
},
{
type: 'fillRect',
x: 202,
y: 362,
width: 196 * heroHpCase,
height: 16,
radius: 4,
style: [255, 70, 70, 1]
},
{
type: 'fillRect',
x: 202,
y: 362,
width: 194 * heroHpCase,
height: 2,
radius: 4,
style: [255, 147, 147, 1]
},
{
type: 'if',
condition: "'" + heroSp > 0 + "'",
true: [
{
type: 'fillRect',
x: 202,
y: 382,
width: 196 * heroSpCase,
height: 6,
style: [175, 182, 255, 1]
}
]
},
{
type: 'fillBoldText',
x: 14,
y: 45,
style: [255, 255, 255, 1],
strokeStyle: [0, 0, 0, 1],
font: 'bold 14px gameFont',
text: monHp + ' / ' + monHpMax
},
{
type: 'fillBoldText',
x: 204,
y: 375,
style: [255, 255, 255, 1],
strokeStyle: [0, 0, 0, 1],
font: 'bold 14px gameFont',
text: heroHp + ' / ' + heroHpMax
},
{
type: 'fillBoldText',
x: 204,
y: 390,
style: [255, 255, 255, 1],
strokeStyle: [0, 0, 0, 1],
font: 'bold 12px gameFont',
text: heroSp || 0 + ' / ' + heroSpMax || 0
},
{
type: 'function',
function: 'function(){\ncore.displayChapter()\n}'
},
{ type: 'sleep', time: 2800 },
{
type: 'function',
function: 'function(){\ncore.displayChapter_1(1)\n}'
},
{ type: 'sleep', time: 2800 },
{
type: 'function',
function:
"function(){\ncore.plugin._turnBattleNowAction('" +
enemyId +
"')\n}"
}
]);
}
};
// 当前回合循序渐进执行事件流导入函数
this._turnBattleNowAction = function (enemyId) {
// 检查回合数,如果没检查到回合数,则默认第一回合,并跳过第二步骤
if (core.getFlag('thisTurn') > 1) {
// 执行步骤二
core.plugin._turnBattleHeroInfo(enemyId);
} else core.plugin._turnBattleManage(enemyId); // 直接进入主角行动选择阶段
// 执行一次回合预览后,立即输出
};
// 下一回合数
this._turnBattlePrepareInfo = function () {
let turn = core.getFlag('thisTurn') || 1;
core.setFlag('thisTurn', turn++);
return turn++;
};
// step 2 检测当前回合末主角属性是否受到影响,会替换下一回合主角的属性
this._turnBattleHeroInfo = function (enemyId, click) {
// 怪物id主角
// 当前回合
let turn = core.getFlag('thisTurn') || 1;
// 回合数据
let turnInfo = core.plugin._turnBattle(enemyId, null, null);
// 设置各属性变化变量(百分比)
let HpReg = 1,
HpMaxReg = 1,
AtkReg = 1,
DefReg = 1,
MdefReg = 1;
//////// 检测该回合是否有影响主角属性的各类效果
//// 检测当前怪物特技的回合末影响 step 2-1
let TEspe = null; // 对应回合数的技能
let TEend = null; // 对应技能的影响效果
let TEeff = null; // 对应技能的影响回合时长
let TEvalue = null; // 对应技能影响效果的数值
// 逻辑怪物会根据技能列表的释放顺序依次使用技能当技能列表项目全部使用完毕后将会重新开始循环使用该函数只涉及回合末buff影响
for (let i = 0; i < turnInfo.monSpecailList.length; i++) {
if (turnInfo.monSpecailList[i].enemyId == enemyId) {
// 检测哪个是战斗怪物的数据
// 根据怪物特技数组元素求余,找到相对应的使用技能
let length1 = turnInfo.monSpecailList[i].turnEnd.length; // 判断有多少个技能需要释放
let realTurn = (turn % length1) - 1; // 应当释放的技能 -1代表数组需要额外-1
TEspe = turnInfo.monSpecailList[i].turnEnd[realTurn];
TEend = TEspe.turnEndOccur;
TEeff = TEspe.effect;
TEvalue = TEspe.value;
}
}
// 如果是新触发的怪物影响主角buff且技能如果存在效果一些buff效果则新建一个flag, 值为持续效果THeff就算原先存在buff也会直接覆盖不论这个效果高低低的也会覆盖高的
if (TEeff) {
core.setFlag(TEend + '_time', TEeff + 1);
}
// 怪物导致主角属性变化
switch (TEend) {
case 'heroAtkReduce': // 主角攻击减弱
if (core.getFlag(TEend + '_time') > 0) {
AtkReg -= TEend.value;
core.addFlag(TEend + '_time', -1); // 减少回合持续效果1点
}
break;
case 'heroDefReduce': // 主角防御减弱
if (core.getFlag(TEend + '_time') > 0) {
DefReg -= TEend.value;
core.addFlag(TEend + '_time', -1); // 减少回合持续效果1点
}
break;
case 'heroHpMaxReduce': // 主角生命值上限降低
if (core.getFlag(TEend + '_time') > 0) {
HpMaxReg -= TEend.value;
core.addFlag(TEend + '_time', -1); // 减少回合持续效果1点
}
break;
}
//// 检测当前主角自身特技给自己带来的回合末影响 step 2-2
let THend = null; // 回合末效果
let THeff = null; // 效果持续时间
let THflag = null; // 技能启用条件
// 检查使用的是哪一个技能(玩家点击技能类选项框的选择项)
for (var i = 0; i < turnInfo.heroSpecailList.length; i++) {
if (
turnInfo.heroSpecailList[i].flag &&
click == turnInfo.heroSpecailList[i].name
) {
// 如果技能开启过且玩家点击特技的名称是库里的名称,则导入
THend = turnInfo.heroSpecailList[i].effect || null;
THeff = turnInfo.heroSpecailList[i].time;
THflag = turnInfo.heroSpecailList[i].flag;
}
}
// 如果是新触发的主角自身buff且技能如果存在效果一些buff效果则新建一个flag, 值为持续效果THeff就算原先存在buff也会直接覆盖不论这个效果高低低的也会覆盖高的
if (THflag && THeff) {
core.setFlag(THend + '_time', THeff + 1);
}
// 主角导致自己属性变化
switch (THend) {
case 'heroAtkAdd': // 主角攻击增强
if (core.getFlag('heroAtkAdd' + '_time') > 0) {
AtkReg += THend.value;
core.addFlag('heroAtkAdd' + '_time', -1); // 减少回合持续效果1点
}
break;
case 'heroDefAdd': // 主角防御增强
if (core.getFlag('heroDefAdd' + '_time') > 0) {
DefReg += THend.value;
core.addFlag('heroDefAdd' + '_time', -1); // 减少回合持续效果1点
}
break;
case 'heroHpMaxAdd': // 主角生命值上限增加
if (core.getFlag('heroHpMaxAdd' + '_time') > 0) {
HpMaxReg += THend.value;
core.addFlag('heroHpMaxAdd' + '_time', -1); // 减少回合持续效果1点
}
break;
}
// 设置全局属性的变化比例
core.setFlag('hero_atkReg', AtkReg); // 攻击比例
core.setFlag('hero_defReg', DefReg); // 防御比例
core.setFlag('hero_hpMaxReg', HpMaxReg); // 防御比例
};
// step 3 获得主角当前属性
this._turnBattleHeroThisPower = function () {
// 变动属性 (如果被影响过数据内容)
let newHeroHpMax = core.getFlag('turnHeroHpMax') || null;
let newHeroAtk = core.getFlag('turnHeroAtk') || null;
let newHeroDef = core.getFlag('turnHeroDef') || null;
let newHeroMdef = core.getFlag('turnHeroMdef') || null;
// 获得主角基础属性
let heroHp = Math.min(
core.status.hero.hp,
Math.max(core.status.hero.mdef * 3, core.status.hero.lv * 100)
); // 回合制中若没有特殊情况主角所持有的最高生命值不超过魔防的3倍,如果魔防太低,那么将会取魔防 + 自身等级 * 100 作为自己的生命值
const enemyInfo = core.enemys.getEnemyInfo('greenSlime');
let heroHpMax = core.getFlag('turnHeroHpMax') || heroHp;
let heroAtk = core.status.hero.atk;
let heroDef = core.status.hero.def;
let heroMdef = core.status.hero.Mdef;
let heroGodAtk = enemyInfo.god_per_damage || 0; // 神圣攻击
// 获得主角携带buff的影响效果
let HpReg = core.getFlag('hero_hpReg') || 1,
HpMaxReg = core.getFlag('hero_hpMaxReg') || 1,
AtkReg = core.getFlag('hero_atkReg') || 1,
DefReg = core.getFlag('hero_defReg') || 1,
MdefReg = core.getFlag('hero_mdefReg') || 1;
// 如果属性不是初始值(在回合战中出现过变动,那么将使用变动量)
heroHpMax *= HpReg;
heroAtk *= AtkReg;
heroDef *= DefReg;
heroMdef *= MdefReg;
// 记录所有属性
core.setFlag('turnHeroHpmax', heroHpMax); // 实际最大生命
core.setFlag('turnHeroAtk', heroAtk); // 实际攻击
core.setFlag('turnHeroDef', heroDef); // 实际防御
core.setFlag('turnHeroMdef', heroMdef); // 实际护盾
};
// choices事件流处理flag
this.turnHeroSpecialFlag = function (enemyId, value) {
// 被选中的特技
let special = core.plugin._turnBattle(enemyId, null, null).heroSpecailList[
value
];
core.setFlag('heroSpecialClick', special);
// 如果特技存在冷却时间且冷却时间已结束需要额外创建一个flag代表冷却时间以便后面回合不显示该项目
let freeze = '' + special.flag + '_freeze';
if (special.freezeTurn) {
if (core.getFlag(freeze, 0) < 1)
core.setFlag(freeze, special.freezeTurn);
}
console.log(special.flag, special.freezeTurn);
};
// step 4 执行主角当前操作
this._turnBattleManage = function (enemyId) {
// 获取技能列表
// 当前回合
let turn = core.getFlag('thisTurn') || 1;
// 回合数据
let turnInfo = core.plugin._turnBattle(enemyId, null, null);
// 主角技能列表
let heroSpecial = turnInfo.heroSpecailList;
let heroSpecialNum = heroSpecial.length; // 技能数
// 设置主角全局特技存储
core.setFlag('heroSpecialNum', heroSpecialNum);
// 所选择的技能
let n = null;
// 技能文本说明
let SpText = function () {
let spe = [];
for (let i = 0; i < heroSpecialNum; i++) {
spe.push(heroSpecial[i].name + ': ' + heroSpecial[i].text + '\n\n');
}
return spe;
};
// 开始执行
core.insertAction([
{ type: 'setText', background: 'winskin2.png' },
{
type: 'choices',
text: '选择行动',
choices: [
{
text: '发动技能',
color: [255, 162, 162, 1],
action: [
{
type: 'while',
condition: '1',
data: [
{
type: 'choices',
text: '选择技能',
choices: [
{
text:
'' + heroSpecial[0]?.name + '',
condition:
'core.getFlag("heroSpecialNum")>=1',
need:
"!core.getFlag('" +
heroSpecial[0]?.flag +
"_freeze') || core.getFlag('" +
heroSpecial[0]?.flag +
"_freeze') < 1 ",
action: [
{
type: 'function',
function:
"function(){\ncore.plugin.turnHeroSpecialFlag('" +
enemyId +
'\', 0)\nlet f = core.getFlag("heroSpecialClick")\ncore.plugin.turnBattleHeroAct(\'' +
enemyId +
"', f);}"
},
{ type: 'break', n: 1 }
]
},
{
text:
'' + heroSpecial[1]?.name + '',
need:
"!core.getFlag('" +
heroSpecial[1]?.flag +
"_freeze') || core.getFlag('" +
heroSpecial[1]?.flag +
"_freeze') < 1 ",
condition:
'core.getFlag("heroSpecialNum")>=2',
action: [
{
type: 'function',
function:
"function(){\ncore.plugin.turnHeroSpecialFlag('" +
enemyId +
'\', 1)\nlet f = core.getFlag("heroSpecialClick")\ncore.plugin.turnBattleHeroAct(\'' +
enemyId +
"', f);}"
},
{ type: 'break', n: 1 }
]
},
{
text:
'' + heroSpecial[2]?.name + '',
condition:
'core.getFlag("heroSpecialNum")>=3',
action: [
{
type: 'function',
function:
"function(){\ncore.plugin.turnHeroSpecialFlag('" +
enemyId +
'\', 2)\nlet f = core.getFlag("heroSpecialClick")\ncore.plugin.turnBattleHeroAct(\'' +
enemyId +
"', f);}"
},
{ type: 'break', n: 1 }
]
},
{
text:
'' + heroSpecial[3]?.name + '',
condition:
'core.getFlag("heroSpecialNum")>=4',
action: [
{
type: 'function',
function:
"function(){\ncore.plugin.turnHeroSpecialFlag('" +
enemyId +
'\', 3)\nlet f = core.getFlag("heroSpecialClick")\ncore.plugin.turnBattleHeroAct(\'' +
enemyId +
"', f);}"
},
{ type: 'break', n: 1 }
]
},
{
text:
'' + heroSpecial[4]?.name + '',
condition:
'core.getFlag("heroSpecialNum")>=5',
action: [
{
type: 'function',
function:
"function(){\ncore.plugin.turnHeroSpecialFlag('" +
enemyId +
'\', 4)\nlet f = core.getFlag("heroSpecialClick")\ncore.plugin.turnBattleHeroAct(\'' +
enemyId +
"', f);}"
},
{ type: 'break', n: 1 }
]
},
{
text:
'' + heroSpecial[5]?.name + '',
condition:
'core.getFlag("heroSpecialNum")>=6',
action: [
{
type: 'function',
function:
"function(){\ncore.plugin.turnHeroSpecialFlag('" +
enemyId +
'\', 5)\nlet f = core.getFlag("heroSpecialClick")\ncore.plugin.turnBattleHeroAct(\'' +
enemyId +
"', f);}"
},
{ type: 'break', n: 1 }
]
},
{
text:
"'" + heroSpecial[6]?.name + '',
condition:
'core.getFlag("heroSpecialNum")>=7',
action: [
{
type: 'function',
function:
"function(){\ncore.plugin.turnHeroSpecialFlag('" +
enemyId +
'\', 6)\nlet f = core.getFlag("heroSpecialClick")\ncore.plugin.turnBattleHeroAct(\'' +
enemyId +
"', f);}"
},
{ type: 'break', n: 1 }
]
},
{
text:
'' + heroSpecial[7]?.name + '',
condition:
'core.getFlag("heroSpecialNum")>=8',
action: [
{
type: 'function',
function:
"function(){\ncore.plugin.turnHeroSpecialFlag('" +
enemyId +
'\', 7)\nlet f = core.getFlag("heroSpecialClick")\ncore.plugin.turnBattleHeroAct(\'' +
enemyId +
"', f);}"
},
{ type: 'break', n: 1 }
]
},
{
text: '当前持有技能效果一览',
color: [255, 255, 0, 1],
action: ['' + SpText() + '']
}
]
}
]
}
]
},
{
text: '进行防御',
action: [
{
type: 'choices',
text: '选择行动',
choices: [
{
text: '防御(该回合遭受的伤害降低50%)',
action: [
{
type: 'setValue',
name: 'flag:hero_defend_skill',
value: '1'
}
]
},
{
text: '发呆(摆烂)',
action: []
}
]
}
]
},
{
text: '使用道具',
action: []
}
]
}
]);
};
// 检测玩家使用主角项目后,对怪物数据进行处理,并绘制跳字内容
this.turnBattleHeroToMon = function (enemyId, special) {
// 设置需要插入的主事件
let slotAction = [];
// 设置需要插入的多重打击事件
let slotAction1 = [];
// 获取怪物属性
let turnInfo = core.plugin._turnBattle(enemyId, null, null);
// 处理特殊属性导致的伤害变动(暂无)
// ....
// 获得扣除后的生命值
let realMonHp = turnInfo.thisMonHp - special.value;
// 获得血条长度比例
let monHpCase = realMonHp / turnInfo.thisMonHpMax;
// 存在多重打击下,需要将打击伤害分成多份插入
if (special.order && special.order > 1) {
for (let i = 1; i <= special.order; i++) {
slotAction1.push([
{
type: 'showTextImage',
code: 34 + i,
text: '- ' + special.value / special.order,
loc: [240, 120],
lineHeight: 1.4,
opacity: 1,
time: 0
},
{ type: 'sleep', time: 30 },
{
type: 'moveImage',
code: 34 + i,
to: [265, 0],
moveMode: 'easeOut',
opacity: 0,
time: 2500,
async: true
}
]);
if (special.order - i > 0)
slotAction1.at(-1).push({ type: 'sleep', time: 50 });
}
} else {
slotAction1.push([
{
type: 'showTextImage',
code: 34,
text: '- ' + special.value,
loc: [240, 120],
lineHeight: 1.4,
opacity: 1,
time: 0
},
{ type: 'sleep', time: 30 },
{
type: 'moveImage',
code: 34,
to: [265, 0],
moveMode: 'easeOut',
opacity: 0,
time: 2500,
async: true
}
]);
}
// 重绘怪物血条部分
slotAction.push([
{ type: 'clearMap', x: 12, y: 32, width: 236, height: 16 }, //擦除血条部分
{
type: 'fillRect',
x: 12,
y: 32,
width: 236 * monHpCase,
height: 16,
radius: 4,
style: [255, 70, 70, 1]
},
{
type: 'fillRect',
x: 12,
y: 32,
width: 234 * monHpCase,
height: 2,
radius: 4,
style: [255, 147, 147, 1]
}
]);
// 插入伤害弹出事件
// slotAction.push(...slotAction1);
// 设置全局当前怪物血量
core.setFlag('turnMonHp', realMonHp);
console.log(slotAction, slotAction1);
return {
slotAction: slotAction,
slotAction1: slotAction1.length > 0 ? slotAction1 : null
};
};
// step 5 开始主角行动的舞台演出以及属性计算
this.turnBattleHeroAct = function (enemyId, special) {
// 获取动画
let animate = '' + special.animate;
// 临时调整动画层高度
core.canvas.animate.canvas.style.zIndex = 139;
// 获取固定数据
let turnInfo = core.plugin._turnBattle(enemyId, null, null);
// 检查回合伤害类型
let damageCode = special.action;
// 主角名称
let heroName = core.status.hero.name;
// 主行动
let pushOrder = [];
// 如果存在多重动画次行动
let pushOrder1 = [];
if (damageCode == 'atk') {
// 攻击类型
// 处理buff情况或特殊属性情况
let pray_drink_action = []; // 神圣祷吸
if (special.pray_drink) {
core.setFlag('battleTurn_pray_drink', special.pray_drink);
pray_drink_action = [
{ type: 'sleep', time: 200 },
{
type: 'animate',
name: 'praydrink',
loc: [2, 7],
alignWindow: true
}
];
}
// 记录伤害量
pushOrder = [
{
type: 'function',
function:
"function(){\ncore.plugin.turnBattleHeroToMon('" +
enemyId +
"', " +
JSON.stringify(special) +
').slotAction \n}'
},
{
type: 'animate',
name: animate,
loc: [10, 2],
alignWindow: true,
async: true
},
{
type: 'moveImage',
code: 26,
to: [265, 30],
moveMode: 'easeIn',
time: 50,
async: true
},
{
type: 'rotateImage',
code: 26,
angle: 8,
moveMode: 'easeIn',
time: 50
},
{ type: 'waitAsync' },
{ type: 'sleep', time: 50 },
{
type: 'moveImage',
code: 26,
to: [240, 30],
moveMode: 'easeOut',
time: 50,
async: true
},
{
type: 'rotateImage',
code: 26,
angle: -8,
moveMode: 'easeIn',
time: 50
},
{ type: 'waitAsync' }
];
pushOrder1 = [
{
type: 'animate',
name: animate,
loc: [10, 2],
alignWindow: true,
async: true
},
{
type: 'moveImage',
code: 26,
to: [265, 30],
moveMode: 'easeOut',
time: 50,
async: true
},
{
type: 'rotateImage',
code: 26,
angle: 8,
moveMode: 'easeIn',
time: 50
},
{ type: 'waitAsync' },
{ type: 'sleep', time: 50 },
{
type: 'moveImage',
code: 26,
to: [240, 30],
moveMode: 'easeOut',
time: 50,
async: true
},
{
type: 'rotateImage',
code: 26,
angle: -8,
moveMode: 'easeIn',
time: 50
},
{ type: 'waitAsync' }
];
if (special.order && special.order > 1) {
// 是否拥有多重打击,如果有,则叠加打击事件
for (let i = 1; i < special.order; i++) {
pushOrder.push({
type: 'function',
function:
"function(){\ncore.plugin.turnBattleHeroToMon('" +
enemyId +
"', " +
JSON.stringify(special) +
').slotAction1' +
[i - 1] +
' \n}'
});
pushOrder.push(...pushOrder1);
}
}
if (special.pray_drink) pushOrder.push(...pray_drink_action);
}
core.insertAction([
{ type: 'tip', text: heroName + ' 使用了 ' + special.name + '!' },
...pushOrder
]);
core.insertAction([
{ type: ' hideImage', code: 35, time: 0 },
{ type: ' hideImage', code: 36, time: 0 },
{ type: ' hideImage', code: 37, time: 0 }
]);
};
// 检测当前回合怪物的属性
this._turnBattleMonInfo = function (enemyId) {
// 当前回合
let turn = core.getFlag('thisTurn') || 1;
// 回合数据
let turnInfo = core.plugin._turnBattle(enemyId, null, null);
// 怪物属性
let MonHp = turnInfo.thisMonHp;
let MonHpMax = turnInfo.heroHpMax;
let MonAtk = turnInfo.heroAtk;
let MonDef = turnInfo.heroDef;
let MonMdef = turnInfo.heroMdef;
//////// 检测该回合是否有影响怪物属性的各类效果
//// 检测当前怪物特技的回合末影响
let TEend = null;
for (let i = 0; i < turnInfo.monSpecailList.length; i++) {
if (turnInfo.monSpecailList[i].enemyId == enemyId) {
TEend = turnInfo.monSpecailList[i].turnEnd.turnEndOccur || null;
}
}
//// 检测当前主角自身特技给自己带来的回合末影响、
let THend = null;
for (let i = 0; i < turnInfo.heroSpecailList.length; i++) {
if (turnInfo.heroSpecailList[i].flag) {
THend = turnInfo.heroSpecailList[i].turnEnd.turnEndOccur || null;
}
}
// 设置各属性变化变量(百分比)
let HpReg = 1,
HpMaxReg = 1,
AtkReg = 1,
DefReg = 1,
MdefReg = 1;
switch (TEend) {
case 'monAtkReduce': // 怪物攻击减弱
AtkReg -= TEend.value;
break;
case 'monDefReduce': // 怪物防御减弱
DefReg -= TEend.value;
break;
case 'monHpMaxReduce': // 怪物生命值上限降低
HpMaxReg -= TEend.value;
break;
}
switch (THend) {
case 'monAtkAdd': // 怪物攻击增强
AtkReg += THend.value;
break;
case 'monDefAdd': // 怪物防御增强
DefReg += THend.value;
break;
case 'monHpMaxAdd': // 怪物生命值上限增加
HpMaxReg += THend.value;
break;
}
MonHp = Math.round(MonHp * HpReg);
MonHpMax = Math.round(MonHpMax * HpMaxReg);
MonAtk = Math.round(MonAtk * AtkReg);
MonDef = Math.round(MonDef * DefReg);
MonMdef = Math.round(MonMdef * MdefReg);
};