feat: 战斗

This commit is contained in:
unanmed 2024-02-05 12:41:32 +08:00
parent 05fb8a8843
commit 637bf96d4e
15 changed files with 680 additions and 1720 deletions

View File

@ -1101,7 +1101,7 @@ editor_file = function (editor, callback) {
for (var id_ in plmap) {
plraw = plraw.replace('"' + id_ + '"', plmap[id_])
}
var datastr = 'var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = \n';
var datastr = '///<reference path="../../src/types/core.d.ts"/>\nvar plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = \n';
datastr += plraw;
fs.writeFile('project/plugins.js', encode(datastr), 'base64', function (err, data) {
callback(err);

View File

@ -3535,6 +3535,29 @@ control.prototype.hideStatusBar = function (showToolbox) {
// see src/plugin/game/ui.js
};
////// 更新状态栏的勇士图标 //////
control.prototype.updateHeroIcon = function (name) {
name = name || 'hero.png';
if (core.statusBar.icons.name == name) return;
core.statusBar.icons.name = name;
var image = core.material.images.hero;
// 全身图
var w = core.material.icons.hero.width || 32;
var h = core.material.icons.hero.height || 48;
var ratio = Math.min(w / h, 1),
width = 32 * ratio,
left = 16 - width / 2;
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
canvas.width = 32;
canvas.height = 32;
core.drawImage(ctx, image, 0, 0, w, h, left, 0, width, 32);
core.statusBar.image.name.src = canvas.toDataURL('image/png');
};
////// 改变工具栏为按钮1-8 //////
control.prototype.setToolbarButton = function (useButton) {
if (!core.domStyle.showStatusBar) {

View File

@ -19,7 +19,7 @@ main.floors.sample0=
[ 6, 6,125, 6, 6, 6, 0, 3, 0, 0, 0, 0, 0],
[208,227,212,216,278, 5, 0, 1, 1, 1,319, 1, 1],
[201,205,217,215,224, 5, 0, 1, 27, 28, 29, 30, 31],
[ 5, 5,125, 5, 5, 5, 0, 1, 21, 22, 23, 24, 26],
[ 5, 5,125, 5, 5, 5,342, 1, 21, 22, 23, 24, 26],
[ 0, 0,263, 0, 0, 0, 45, 1, 1, 1,121, 1, 1],
[ 4, 4,133, 4, 4, 4, 0, 0, 0, 0, 0, 85,124],
[ 87, 11, 12, 13, 14, 4, 4, 2, 2,122, 2, 2, 2],
@ -255,5 +255,11 @@ main.floors.sample0=
"height": 13,
"autoEvent": {},
"beforeBattle": {},
"cannotMoveIn": {}
"cannotMoveIn": {},
"bg2map": [
],
"fg2map": [
]
}

View File

@ -260,7 +260,19 @@ var icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1 =
"jumpShoes": 49,
"skill1": 30,
"wand": 10,
"pack": 46
"pack": 46,
"I331": 5,
"I332": 7,
"I333": 26,
"I334": 31,
"I335": 32,
"I336": 34,
"I337": 35,
"I338": 36,
"I339": 37,
"I340": 38,
"I341": 39,
"I342": 62
},
"autotile": {
"autotile": 0,

View File

@ -144,7 +144,7 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a =
"itemEffectTip": ",攻击+0"
},
"sword1": {
"cls": "items",
"cls": "equips",
"name": "铁剑",
"text": "一把很普通的铁剑",
"equip": {
@ -528,5 +528,67 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a =
"name": "钱袋",
"itemEffect": "core.status.hero.money += 500",
"itemEffectTip": ",金币+500"
},
"I331": {
"cls": "items",
"name": "新物品",
"canUseItemEffect": "true"
},
"I332": {
"cls": "items",
"name": "新物品",
"canUseItemEffect": "true"
},
"I333": {
"cls": "items",
"name": "新物品",
"canUseItemEffect": "true"
},
"I334": {
"cls": "items",
"name": "新物品",
"canUseItemEffect": "true"
},
"I335": {
"cls": "items",
"name": "新物品",
"canUseItemEffect": "true"
},
"I336": {
"cls": "items",
"name": "新物品",
"canUseItemEffect": "true"
},
"I337": {
"cls": "items",
"name": "新物品",
"canUseItemEffect": "true"
},
"I338": {
"cls": "items",
"name": "新物品",
"canUseItemEffect": "true"
},
"I339": {
"cls": "items",
"name": "新物品",
"canUseItemEffect": "true"
},
"I340": {
"cls": "items",
"name": "新物品",
"canUseItemEffect": "true"
},
"I341": {
"cls": "items",
"name": "新物品",
"canUseItemEffect": "true"
},
"I342": {
"cls": "constants",
"name": "系统设置",
"canUseItemEffect": "true",
"text": "系统设置,用于打开新样板的新设置界面",
"useItemEffect": "Mota.require('var', 'mainUi').open('settings');"
}
}

View File

@ -223,5 +223,17 @@ var maps_90f36752_8815_4be8_b32b_d7fad1d0542e =
"327": {"cls":"enemy48","id":"bearDown"},
"328": {"cls":"enemy48","id":"bearLeft"},
"329": {"cls":"enemy48","id":"bearRight"},
"330": {"cls":"enemy48","id":"bearUp"}
"330": {"cls":"enemy48","id":"bearUp"},
"331": {"cls":"items","id":"I331"},
"332": {"cls":"items","id":"I332"},
"333": {"cls":"items","id":"I333"},
"334": {"cls":"items","id":"I334"},
"335": {"cls":"items","id":"I335"},
"336": {"cls":"items","id":"I336"},
"337": {"cls":"items","id":"I337"},
"338": {"cls":"items","id":"I338"},
"339": {"cls":"items","id":"I339"},
"340": {"cls":"items","id":"I340"},
"341": {"cls":"items","id":"I341"},
"342": {"cls":"items","id":"I342"}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

@ -1,3 +1,4 @@
///<reference path="../../src/types/core.d.ts"/>
var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = {
fiveLayer: function () {
// 注册插件
@ -297,6 +298,211 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = {
});
}
},
special: function () {
// 这个插件负责定义怪物属性
const specials = Mota.require('var', 'enemySpecials');
// 怪物特殊属性包含四个信息
// code: 索引,必须与该属性在数组内的索引一致
// name: 特殊属性名称,可以是一个函数,接受 enemy 作为参数,返回字符串
// desc: 特殊属性说明,也可以是一个函数,接受 enemy 作为参数,返回字符串
// color: 特殊属性颜色,会在怪物手册中显示出来
specials.push(
{
code: 0,
name: '空',
desc: '空',
color: '#fff'
},
{
code: 1,
name: '致命一击',
desc: enemy =>
`怪物每5回合触发一次强力攻击造成${enemy.crit}%的伤害`,
color: '#fc3'
},
{
code: 2,
name: '恶毒',
desc: '怪物攻击无视勇士的防御',
color: '#bbb0ff'
},
{
code: 3,
name: '坚固',
desc: '怪物防御不小于勇士攻击-1',
color: '#c0b088'
},
{
code: 4,
name: '2连击',
desc: '怪物每回合攻击2次',
color: '#fe7'
},
{
code: 5,
name: '3连击',
desc: '怪物每回合攻击3次',
color: '#fe7'
},
{
code: 6,
name: enemy => `${enemy.n}连击`,
desc: enemy => `怪物每回合攻击${enemy.n}`,
color: '#fe7'
},
{
code: 7,
name: '饥渴',
desc: enemy =>
`战斗前,怪物降低勇士${enemy.hungry}%的攻击,并加在自己身上`,
color: '#b67'
},
{
code: 8,
name: '抱团',
desc: enemy =>
`怪物周围5×5范围内每有一个拥有该属性的怪物自身攻防就增加${enemy.together}%(线性叠加)`,
color: '#fa4'
},
{
code: 9,
name: '绝对防御',
desc: '怪物的奇特护甲可以让勇士的额外攻击失效,攻击变为基础攻击+额外攻击',
color: '#80eed6'
},
{
code: 10,
name: '勇气之刃',
desc: enemy => `怪物第一回合造成${enemy.courage}%的伤害`,
color: '#b0c0dd'
},
{
code: 11,
name: '勇气冲锋',
desc: enemy =>
`怪物首先攻击,造成${enemy.charge}%的伤害并眩晕勇士5回合`,
color: '#ff00d2'
},
{
code: 12,
name: '追猎',
desc: '当勇士移动到该怪物的水平或竖直方向上时,怪物向勇士移动一格',
color: '#9e8'
},
{
code: 13,
name: '魔攻',
desc: '怪物攻击无视勇士的防御',
color: '#bbb0ff'
},
{
code: 14,
name: '智慧之源',
desc: '困难难度下简单难度没有效果战斗后怪物会吸取勇士30%的智慧(勇士智慧向下取整至整十)加在本层的拥有该属性的怪物攻击上',
color: '#bbeef0'
},
{
code: 15,
name: '突刺',
desc: enemy =>
`勇士走到怪物怪物周围四格时,怪物对勇士造成${core.formatBigNumber(
Math.max((enemy.value || 0) - getHeroStatusOn('def'))
)}点伤害`,
color: '#c677dd'
},
{
code: 16,
name: '空',
desc: '空',
color: '#fff'
},
{
code: 17,
name: '先攻',
desc: '战斗时,怪物首先攻击',
color: '#b0b666'
},
{
code: 18,
name: '阻击',
desc: enemy =>
`经过怪物十字范围内时怪物后退一格,同时对勇士造成${enemy.value}点伤害`,
color: '#8888e6'
},
{
code: 19,
name: '电摇嘲讽',
desc:
'当勇士移动到怪物同行或同列时,勇士会直接冲向怪物,撞碎路上的所有地形和门,拾取路上的道具,与路上的怪物战斗' +
',最后与该怪物战斗',
color: '#ff6666'
},
{
code: 20,
name: '霜冻',
desc: enemy =>
`怪物寒冷的攻击使勇士动作变慢,勇士每回合对怪物造成的伤害减少${enemy.ice}%。装备杰克的衣服后可以免疫。`,
color: 'cyan'
},
{
code: 21,
name: '冰封光环',
desc: enemy =>
`寒气逼人使勇士对该怪物周围7*7范围内的怪物伤害减少${enemy.iceHalo}%(线性叠加)`,
color: 'cyan'
},
{
code: 22,
name: '永夜',
desc: enemy =>
`战斗后,减少勇士${enemy.night}点攻防,增加本层所有怪物${enemy.night}点攻防,仅在本层有效`,
color: '#d8a'
},
{
code: 23,
name: '极昼',
desc: enemy =>
`战斗后,减少本层所有怪物${enemy.day}点攻防,增加勇士${enemy.day}点攻防,仅在本层有效`,
color: '#ffd'
},
{
code: 24,
name: '射击',
desc: function () {
return '经过怪物同行或同列的可视范围内时受到一次普通攻击的伤害';
},
color: '#dda0dd'
},
{
code: 25,
name: '融化',
desc: enemy =>
`战斗后该怪物会融化在怪物位置产生一个3*3的范围光环光环内怪物的攻防增加${enemy.melt}%`,
color: '#e6e099'
},
{
code: 26,
name: '冰封之核',
desc: enemy =>
`怪物拥有逼人的寒气使周围5*5范围内的怪物防御增加${enemy.iceCore}%`,
color: '#70ffd1'
},
{
code: 27,
name: '火焰之核',
desc: enemy =>
`怪物拥有灼热的火焰使周围5*5范围内的怪物攻击增加${enemy.fireCore}%`,
color: '#ff6f0a'
},
{
code: 28,
name: '苍蓝刻',
desc: enemy =>
`怪物使用苍蓝之灵的力量,使自身受到的伤害减少${enemy.paleShield}%`,
color: '#ff6f0a'
}
);
},
battle: function () {
// 这个插件负责战斗相关内容
@ -364,6 +570,29 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = {
return damage;
});
// --------------- 秒杀伤害计算
// 用于计算一些特殊属性怪物在一回合内秒杀所需的攻击,依此计算临界的上界
// 函数没有参数返回一个数字表示临界上界Infinity表示没有上界不计算临界
// 不能返回数字型外的量
Mota.rewrite(
Mota.require('class', 'DamageEnemy').prototype,
'getSeckillAtk',
'full',
function () {
// 获取怪物的属性
const info = this.getRealInfo();
// 对于一般的怪物,应该是怪物防御加上怪物血量
const add = info.def + info.hp;
// 坚固,不可能通过攻击秒杀
if (info.special.includes(3)) {
return Infinity;
}
return add;
}
);
// --------------- 地图伤害
// 全量复写地图伤害的计算函数注意此处不能使用箭头函数因为这是在原型上的函数其this指向实例也即怪物(DamageEnemy实例)
// 函数接收两个参数damage和hero前者表示要将结果存入的对象后者是勇士真实属性
@ -442,5 +671,131 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = {
);
// --------------- 光环处理
// 光环分为两类,一类是会增强光环或者给怪物加光环的光环,另一类就是普通光环,这两种光环处理方式不同
// 对于前者,光环将会优先递归计算,同时每个光环将会确保只计算一次,直到没有光环需要计算
// 对于后者,不进行递归计算,只进行单次遍历计算。
// 光环使用 provideHalo 和 injectHalo 作为api表示提供光环和接受光环
// 光环属性列表是一个集合Set你可以在这里配置会被视为光环的属性
const haloSpecials = Mota.require('module', 'Damage').haloSpecials;
haloSpecials.add(8).add(11);
// ----- 计算第二类光环,即普通光环,这类光环更常见,因此放到前面了
Mota.rewrite(
Mota.require('class', 'DamageEnemy').prototype,
'provideHalo',
'full',
function () {
// 这部分用于判断当前是否应该计算光环,即计算光环的函数是否在不应该被调用的时刻调用了
// 一般不需要改动
if (this.progress !== 2) return;
this.progress = 3;
if (!this.floorId) return;
if (!has(this.x) || !has(this.y)) return;
const col = this.col ?? core.status.maps[this.floorId].enemy;
if (!col) return;
// 获取所有还没有计算的光环注意这里不能直接获取haloSpecial
const special = this.getHaloSpecials();
const square7 = [];
const square5 = [];
// e 是被加成怪的属性enemy 是施加光环的怪
for (const halo of special) {
switch (halo) {
case 8:
square5.push((e, enemy) => {
if (
e.special.includes(8) &&
(e.x !== this.x || this.y !== e.y)
) {
e.atkBuff += enemy.together ?? 0;
e.defBuff += enemy.together ?? 0;
}
});
this.providedHalo.add(8);
break;
case 21:
square7.push(e => {
// e.damageDecline += this.enemy.iceHalo ?? 0;
});
col.haloList.push({
type: 'square',
data: { x: this.x, y: this.y, d: 7 },
special: 21,
from: this
});
this.providedHalo.add(21);
break;
case 26:
square5.push(e => {
e.defBuff += this.enemy.iceCore ?? 0;
});
col.haloList.push({
type: 'square',
data: { x: this.x, y: this.y, d: 5 },
special: 26,
from: this
});
this.providedHalo.add(26);
break;
case 27:
square5.push(e => {
e.atkBuff += this.enemy.fireCore ?? 0;
});
col.haloList.push({
type: 'square',
data: { x: this.x, y: this.y, d: 5 },
special: 27,
from: this
});
this.providedHalo.add(27);
break;
}
}
col.applyHalo(
'square',
{ x: this.x, y: this.y, d: 7 },
square7
);
col.applyHalo(
'square',
{ x: this.x, y: this.y, d: 5 },
square5
);
}
);
// ----- 计算第一类光环
Mota.rewrite(
Mota.require('class', 'DamageEnemy').prototype,
'preProvideHalo',
'full',
function () {
if (this.progress !== 0) return;
this.progress = 1;
const special = this.getHaloSpecials();
for (const halo of special) {
switch (halo) {
default:
break;
}
}
}
);
// ----- 接受光环处理
Mota.rewrite(
Mota.require('class', 'DamageEnemy').prototype,
'injectHalo',
'full',
function (halo, enemy) {
// 这里的 halo 是光环函数enemy 是施加光环的怪物this.info 是当前怪物信息
halo(this.info, enemy);
}
);
}
};

View File

@ -445,9 +445,6 @@ gameKey
.realize('skillTree', () => {
core.useItem('skill1', true);
})
.realize('desc', () => {
core.useItem('I560', true);
})
.realize('undo', () => {
core.doSL('autoSave', 'load');
})

View File

@ -21,7 +21,6 @@ interface EnemyInfo {
def: number;
hp: number;
special: number[];
damageDecline: number;
atkBuff: number;
defBuff: number;
hpBuff: number;
@ -64,9 +63,6 @@ interface CriticalDamageDelta extends Omit<DamageDelta, 'info'> {
type HaloFn = (info: EnemyInfo, enemy: Enemy) => void;
/** 光环属性 */
export const haloSpecials: number[] = [8, 21, 25, 26, 27];
export class EnemyCollection implements RangeCollection<DamageEnemy> {
floorId: FloorIds;
list: DamageEnemy[] = [];
@ -285,7 +281,7 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
info!: EnemyInfo;
/** 向其他怪提供过的光环 */
providedHalo: number[] = [];
providedHalo: Set<number> = new Set();
/**
* 0 -> -> 1 -> -> 2 -> provide inject
@ -316,7 +312,6 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
atk: enemy.atk,
def: enemy.def,
special: enemy.special.slice(),
damageDecline: 0,
atkBuff: 0,
defBuff: 0,
hpBuff: 0,
@ -326,7 +321,7 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
floorId: this.floorId
};
this.progress = 0;
this.providedHalo = [];
this.providedHalo = new Set();
}
/**
@ -387,7 +382,7 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
if (!has(this.x) || !has(this.y)) return [];
const special = this.info.special ?? this.enemy.special;
const filter = special.filter(v => {
return haloSpecials.includes(v) && !this.providedHalo.includes(v);
return Damage.haloSpecials.has(v) && !this.providedHalo.has(v);
});
if (filter.length === 0) return [];
const collection = this.col ?? core.status.maps[this.floorId].enemy;
@ -405,6 +400,14 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
preProvideHalo() {
if (this.progress !== 0) return;
this.progress = 1;
const special = this.getHaloSpecials();
for (const halo of special) {
switch (halo) {
default:
break;
}
}
}
/**
@ -424,60 +427,57 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
// e 是被加成怪的属性enemy 是施加光环的怪
// 抱团
if (special.includes(8)) {
square5.push((e, enemy) => {
if (
e.special.includes(8) &&
(e.x !== this.x || this.y !== e.y)
) {
e.atkBuff += enemy.together ?? 0;
e.defBuff += enemy.together ?? 0;
}
});
this.providedHalo.push(8);
}
// 冰封光环
if (special.includes(21)) {
square7.push(e => {
e.damageDecline += this.enemy.iceHalo ?? 0;
});
this.providedHalo.push(21);
col.haloList.push({
type: 'square',
data: { x: this.x, y: this.y, d: 7 },
special: 21,
from: this
});
}
// 冰封之核
if (special.includes(26)) {
square5.push(e => {
e.defBuff += this.enemy.iceCore ?? 0;
});
this.providedHalo.push(26);
col.haloList.push({
type: 'square',
data: { x: this.x, y: this.y, d: 5 },
special: 26,
from: this
});
}
// 火焰之核
if (special.includes(27)) {
square5.push(e => {
e.atkBuff += this.enemy.fireCore ?? 0;
});
this.providedHalo.push(27);
col.haloList.push({
type: 'square',
data: { x: this.x, y: this.y, d: 5 },
special: 27,
from: this
});
for (const halo of special) {
switch (halo) {
case 8:
square5.push((e, enemy) => {
if (
e.special.includes(8) &&
(e.x !== this.x || this.y !== e.y)
) {
e.atkBuff += enemy.together ?? 0;
e.defBuff += enemy.together ?? 0;
}
});
this.providedHalo.add(8);
break;
case 21:
square7.push(e => {
// e.damageDecline += this.enemy.iceHalo ?? 0;
});
col.haloList.push({
type: 'square',
data: { x: this.x, y: this.y, d: 7 },
special: 21,
from: this
});
this.providedHalo.add(21);
break;
case 26:
square5.push(e => {
e.defBuff += this.enemy.iceCore ?? 0;
});
col.haloList.push({
type: 'square',
data: { x: this.x, y: this.y, d: 5 },
special: 26,
from: this
});
this.providedHalo.add(26);
break;
case 27:
square5.push(e => {
e.atkBuff += this.enemy.fireCore ?? 0;
});
col.haloList.push({
type: 'square',
data: { x: this.x, y: this.y, d: 5 },
special: 27,
from: this
});
this.providedHalo.add(27);
break;
}
}
col.applyHalo('square', { x: this.x, y: this.y, d: 7 }, square7);
@ -538,32 +538,31 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
// 射击
if (this.info.special.includes(24)) {
const dirs: Dir[] = ['left', 'down', 'up', 'right'];
const dam = Math.max((enemy.atk ?? 0) - hero.def!, 0);
const objs = core.getMapBlocksObj(this.floorId);
for (const dir of dirs) {
let x = this.x;
let y = this.y;
const { x: dx, y: dy } = core.utils.scan[dir];
while (x >= 0 && y >= 0 && x < w && y < h) {
x += dx;
y += dy;
const loc = `${x},${y}` as LocString;
const block = objs[loc];
if (
block &&
block.event.noPass &&
block.event.cls !== 'enemys' &&
block.event.cls !== 'enemy48' &&
block.id !== 141 &&
block.id !== 151
) {
break;
}
this.setMapDamage(damage, loc, dam, '射击');
}
}
// const dirs: Dir[] = ['left', 'down', 'up', 'right'];
// const dam = Math.max((enemy.atk ?? 0) - hero.def!, 0);
// const objs = core.getMapBlocksObj(this.floorId);
// for (const dir of dirs) {
// let x = this.x;
// let y = this.y;
// const { x: dx, y: dy } = core.utils.scan[dir];
// while (x >= 0 && y >= 0 && x < w && y < h) {
// x += dx;
// y += dy;
// const loc = `${x},${y}` as LocString;
// const block = objs[loc];
// if (
// block &&
// block.event.noPass &&
// block.event.cls !== 'enemys' &&
// block.event.cls !== 'enemy48' &&
// block.id !== 141 &&
// block.id !== 151
// ) {
// break;
// }
// this.setMapDamage(damage, loc, dam, '射击');
// }
// }
}
return damage;
@ -583,27 +582,8 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
private calEnemyDamageOf(hero: Partial<HeroStatus>, enemy: EnemyInfo) {
const status = getHeroStatusOf(hero, Damage.realStatus, this.floorId);
let damage = Damage.calDamageWith(enemy, status) ?? Infinity;
let skill = -1;
// 自动切换技能
if (flags.autoSkill) {
for (let i = 0; i < skills.length; i++) {
const [unlock, condition] = skills[i];
if (!flags[unlock]) continue;
flags[condition] = true;
const status = getHeroStatusOf(hero, Damage.realStatus);
const d = Damage.calDamageWith(enemy, status) ?? Infinity;
if (d < damage) {
damage = d;
skill = i;
}
flags[condition] = false;
}
}
return { damage, skill };
return { damage };
}
/**
@ -687,7 +667,7 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
}
if (i++ >= 10000) {
console.warn(
`Unexpected endless loop in calculating critical.` +
`Unexpected long loop in calculating critical.` +
`Enemy Id: ${this.id}. Loc: ${this.x},${this.y}. Floor: ${this.floorId}`
);
break;
@ -742,51 +722,14 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
return Infinity;
}
// 列方程求解,拿笔算一下就知道了
// 饥渴,会偷取勇士攻击
if (info.special.includes(7)) {
if (info.damageDecline === 0) {
return add / (1 - this.enemy.hungry! / 100);
} else {
return (
(info.hp / (1 - info.damageDecline / 100) -
core.status.hero.mana +
info.def) /
(1 - this.enemy.hungry! / 100)
);
}
}
// 霜冻
if (info.special.includes(20) && !core.hasEquip('I589')) {
return (
info.def +
info.hp / (1 - this.enemy.ice! / 100) -
core.status.hero.mana
);
}
if (info.damageDecline !== 0) {
return (
info.def +
info.hp / (1 - info.damageDecline / 100) -
core.status.hero.mana
);
} else {
return add;
}
return add;
}
}
/**
*
*/
const skills: [unlock: string, condition: string][] = [
['bladeOn', 'blade'],
['shieldOn', 'shield']
];
export namespace Damage {
/** 光环属性 */
export const haloSpecials: Set<number> = new Set();
/**
* buff加成core.status.hero取
*/
@ -817,10 +760,7 @@ export namespace Damage {
let heroPerDamage: number;
// 绝对防御
if (special.includes(9)) {
heroPerDamage = atk + mana - monDef;
if (heroPerDamage <= 0) return null;
} else if (special.includes(3)) {
if (special.includes(3)) {
// 由于坚固的特性,只能放到这来计算了
if (atk > enemy.def) heroPerDamage = 1 + mana;
else return null;
@ -830,13 +770,6 @@ export namespace Damage {
else return null;
}
// 霜冻
if (special.includes(20) && !core.hasEquip('I589')) {
heroPerDamage *= 1 - enemy.ice! / 100;
}
heroPerDamage *= 1 - info.damageDecline / 100;
let enemyPerDamage: number;
// 魔攻
@ -857,39 +790,8 @@ export namespace Damage {
if (special.includes(5)) enemyPerDamage *= 3;
if (special.includes(6)) enemyPerDamage *= enemy.n!;
// 苍蓝刻
if (special.includes(28)) {
heroPerDamage *= 1 - enemy.paleShield! / 100;
}
let turn = Math.ceil(monHp / heroPerDamage);
// 致命一击
if (special.includes(1)) {
const times = Math.floor(turn / 5);
damage += ((times * (enemy.crit! - 100)) / 100) * enemyPerDamage;
}
// 勇气之刃
if (turn > 1 && special.includes(10)) {
damage += (enemy.courage! / 100 - 1) * enemyPerDamage;
}
// 勇气冲锋
if (special.includes(11)) {
damage += (enemy.charge! / 100) * enemyPerDamage;
turn += 5;
}
damage += (turn - 1) * enemyPerDamage;
// 无上之盾
if (flags.superSheild) {
damage -= mdef / 10;
}
// 生命回复
damage -= hpmax * turn;
if (flags.hard === 1) damage *= 0.9;
return damage;
}

View File

@ -105,7 +105,6 @@ interface VariableInterface {
settingStorage: GameStorage;
status: Ref<boolean>;
// 定义于游戏进程,渲染进程依然可用
haloSpecials: number[];
enemySpecials: typeof specials;
}
@ -519,14 +518,18 @@ function rewrite<O, K extends SelectKey<O, _Func>, T = O>(
);
}
if (type === 'full') {
function res(this: T, ...params: any[]) {
// @ts-ignore
return re.call(rebind ?? this, ...params);
}
// @ts-ignore
return (base[key] = re.bind(rebind ?? base));
return (base[key] = res);
} else if (type === 'add') {
const origin = base[key];
function res(this: T, ...params: [..._F<O[K]>[0], ...any[]]) {
const v = (origin as _Func).call(bind ?? base, ...params);
const v = (origin as _Func).call(bind ?? this, ...params);
// @ts-ignore
const ret = re.call(rebind ?? base, v, ...params);
const ret = re.call(rebind ?? this, v, ...params);
return ret;
}
// @ts-ignore
@ -535,8 +538,8 @@ function rewrite<O, K extends SelectKey<O, _Func>, T = O>(
const origin = base[key];
function res(this: T, ...params: [..._F<O[K]>[0], ...any[]]) {
// @ts-ignore
re.call(rebind ?? base, ...params);
const ret = (origin as _Func).call(bind ?? base, ...params);
re.call(rebind ?? this, ...params);
const ret = (origin as _Func).call(bind ?? this, ...params);
return ret;
}
// @ts-ignore

View File

@ -30,7 +30,7 @@ checkMobile();
function checkMobile() {
if (isMobile && !alerted) {
alert(
'手机端建议使用自带的浏览器进行游玩,并在进入游戏后开启游戏内的全屏设置游玩'
'手机端建议使用新版APP或者自带的浏览器进行游玩,并在进入游戏后开启游戏内的全屏设置游玩'
);
alerted = true;
}

485
src/source/cls.d.ts vendored
View File

@ -4,7 +4,7 @@ interface IdToCls {
blueWall: 'animates';
star: 'animates';
lava: 'animates';
ice: 'terrains';
ice: 'animates';
blueShopLeft: 'terrains';
blueShopRight: 'terrains';
pinkShopLeft: 'terrains';
@ -13,7 +13,7 @@ interface IdToCls {
poisonNet: 'animates';
weakNet: 'animates';
curseNet: 'animates';
blueWater: 'animates';
blueLava: 'animates';
water: 'animates';
autotile: 'autotile';
yellowKey: 'items';
@ -58,7 +58,7 @@ interface IdToCls {
curseWine: 'items';
superWine: 'items';
dagger: 'items';
silverCoin: 'items';
pack: 'items';
amulet: 'items';
hammer: 'items';
lifeWand: 'items';
@ -85,10 +85,6 @@ interface IdToCls {
crystalBottom: 'animates';
fire: 'animates';
switch: 'animates';
steelDoor2: 'animates';
steelDoor3: 'animates';
iceDoor: 'animates';
iceDoor2: 'animates';
magentaWall: 'animates';
man: 'npcs';
trader: 'npcs';
@ -108,16 +104,6 @@ interface IdToCls {
npc3: 'npc48';
greenMan: 'npcs';
blueTrader: 'npcs';
redMSNpc: 'npcs';
blackTrader: 'npcs';
autotile4: 'autotile';
autotile5: 'autotile';
autotile6: 'autotile';
autotile7: 'autotile';
autotile8: 'autotile';
autotile9: 'autotile';
autotile10: 'autotile';
autotile11: 'autotile';
autotile1: 'autotile';
autotile2: 'autotile';
autotile3: 'autotile';
@ -131,22 +117,6 @@ interface IdToCls {
flower: 'terrains';
box: 'terrains';
boxed: 'terrains';
octopusLeftTop: 'npcs';
octopusTop: 'npcs';
octopusRightTop: 'npcs';
octopusLeft: 'npcs';
octopusCenter: 'npcs';
octopusRight: 'npcs';
octopusLeftBottom: 'npcs';
octopusRightBottom: 'npcs';
dragonLeftTop: 'npcs';
dragonTop: 'npcs';
dragonRightTop: 'npcs';
dragonLeft: 'npcs';
dragonCenter: 'npcs';
dragonRight: 'npcs';
dragonLeftBottom: 'npcs';
dragonRightBottom: 'npcs';
greenSlime: 'enemys';
redSlime: 'enemys';
blackSlime: 'enemys';
@ -214,15 +184,10 @@ interface IdToCls {
silverSlimelord: 'enemys';
goldSlimelord: 'enemys';
grayRock: 'enemys';
blueRock: 'enemys';
skeletonLite: 'enemys';
greenKnight: 'enemys';
bowman: 'enemys';
liteBowman: 'enemys';
crimsonZombie: 'enemys';
frozenSkeleton: 'enemys';
purpleBowman: 'enemys';
watcherSlime: 'enemys';
mutantSlimeman: 'enemys';
frostBat: 'enemys';
devilKnight: 'enemys';
grayPriest: 'enemys';
@ -246,422 +211,28 @@ interface IdToCls {
sWallTLR: 'terrains';
sWallTBR: 'terrains';
sWallTBL: 'terrains';
I319: 'items';
I320: 'items';
I321: 'items';
I322: 'items';
I323: 'items';
I324: 'items';
I325: 'items';
I326: 'items';
I327: 'items';
I328: 'items';
I329: 'items';
I330: 'items';
T331: 'terrains';
T332: 'terrains';
T333: 'terrains';
T334: 'terrains';
T335: 'terrains';
T336: 'terrains';
T337: 'terrains';
T338: 'terrains';
T339: 'terrains';
T340: 'terrains';
T341: 'terrains';
T342: 'terrains';
T343: 'terrains';
T344: 'terrains';
T345: 'terrains';
T346: 'terrains';
T347: 'terrains';
T348: 'terrains';
T349: 'terrains';
T350: 'terrains';
T351: 'terrains';
T352: 'terrains';
T353: 'terrains';
T354: 'terrains';
T355: 'terrains';
T356: 'terrains';
T357: 'terrains';
T358: 'terrains';
T359: 'terrains';
T360: 'terrains';
T361: 'terrains';
T362: 'terrains';
T363: 'terrains';
T364: 'terrains';
T365: 'terrains';
T366: 'terrains';
N367: 'npc48';
E368: 'enemys';
E369: 'enemys';
E370: 'enemys';
E371: 'enemys';
E372: 'enemys';
E373: 'enemys';
E374: 'enemys';
E375: 'enemys';
I376: 'items';
I377: 'items';
I378: 'items';
I379: 'items';
I380: 'items';
I381: 'items';
I382: 'items';
I383: 'items';
I384: 'items';
I385: 'items';
I386: 'items';
I387: 'items';
I388: 'items';
I389: 'items';
I390: 'items';
I391: 'items';
I392: 'items';
I393: 'items';
I394: 'items';
I395: 'items';
I396: 'items';
I397: 'items';
I398: 'items';
I399: 'items';
I400: 'items';
I401: 'items';
I402: 'items';
I403: 'items';
I404: 'items';
I405: 'items';
I406: 'items';
I407: 'items';
I408: 'items';
I409: 'items';
I410: 'items';
I411: 'items';
I412: 'items';
I413: 'items';
I414: 'items';
I415: 'items';
I416: 'items';
I417: 'items';
I418: 'items';
I419: 'items';
I420: 'items';
I421: 'items';
I422: 'items';
I423: 'items';
I424: 'items';
I425: 'items';
I426: 'items';
I427: 'items';
I428: 'items';
I429: 'items';
I430: 'items';
I431: 'items';
I432: 'items';
I433: 'items';
I434: 'items';
I435: 'items';
I436: 'items';
I437: 'items';
I438: 'items';
I439: 'items';
I440: 'items';
I441: 'items';
I442: 'items';
I443: 'items';
I444: 'items';
I445: 'items';
I446: 'items';
I447: 'items';
I448: 'items';
I449: 'items';
I450: 'items';
I451: 'items';
I452: 'items';
I453: 'items';
I454: 'items';
I455: 'items';
I456: 'items';
I457: 'items';
I458: 'items';
I459: 'items';
I460: 'items';
I461: 'items';
I462: 'items';
I463: 'items';
I464: 'items';
I465: 'items';
I466: 'items';
I467: 'items';
I468: 'items';
I469: 'items';
I470: 'items';
I471: 'items';
I472: 'items';
I473: 'items';
I474: 'items';
I475: 'items';
I476: 'items';
I477: 'items';
I478: 'items';
I479: 'items';
I480: 'items';
I481: 'items';
I482: 'items';
I483: 'items';
I484: 'items';
I485: 'items';
I486: 'items';
I487: 'items';
I488: 'items';
I489: 'items';
I490: 'items';
I491: 'items';
A492: 'animates';
A493: 'animates';
A494: 'animates';
A495: 'animates';
A496: 'animates';
A497: 'animates';
E498: 'enemys';
E499: 'enemys';
E500: 'enemys';
E501: 'enemys';
E502: 'enemys';
E503: 'enemys';
E504: 'enemys';
E505: 'enemys';
A506: 'animates';
A507: 'animates';
A508: 'animates';
A509: 'animates';
A510: 'animates';
E511: 'enemys';
E512: 'enemys';
E513: 'enemys';
E514: 'enemys';
E515: 'enemys';
T516: 'terrains';
E517: 'enemys';
E518: 'enemys';
E519: 'enemys';
E520: 'enemys';
E521: 'enemys';
E522: 'enemys';
E523: 'enemys';
E524: 'enemys';
E525: 'enemys';
T526: 'terrains';
T527: 'terrains';
T528: 'terrains';
T529: 'terrains';
T530: 'terrains';
T531: 'terrains';
N532: 'npcs';
N533: 'npcs';
N534: 'npcs';
N535: 'npcs';
E536: 'enemys';
E537: 'enemys';
E538: 'enemys';
E539: 'enemys';
A540: 'animates';
A541: 'animates';
A542: 'animates';
A543: 'animates';
E544: 'enemys';
E545: 'enemys';
E546: 'enemys';
E547: 'enemys';
E548: 'enemys';
E549: 'enemys';
E550: 'enemys';
T551: 'terrains';
T552: 'terrains';
T553: 'terrains';
T554: 'terrains';
T555: 'terrains';
E556: 'enemys';
E557: 'enemys';
I558: 'items';
I559: 'items';
I560: 'items';
E561: 'enemys';
E562: 'enemys';
E563: 'enemys';
E564: 'enemys';
I565: 'items';
E566: 'enemys';
E567: 'enemys';
E568: 'enemys';
E569: 'enemys';
E570: 'enemys';
E571: 'enemys';
E572: 'enemys';
E573: 'enemys';
I574: 'items';
I575: 'items';
E576: 'enemys';
E577: 'enemys';
E578: 'enemys';
E579: 'enemys';
T580: 'terrains';
T581: 'terrains';
T582: 'terrains';
T583: 'terrains';
T584: 'terrains';
T585: 'terrains';
T586: 'terrains';
T587: 'terrains';
T588: 'terrains';
I589: 'items';
E590: 'enemys';
E591: 'enemys';
E592: 'enemys';
E593: 'enemys';
E594: 'enemys';
E595: 'enemys';
E596: 'enemys';
E597: 'enemys';
E598: 'enemys';
E599: 'enemys';
E600: 'enemys';
E601: 'enemys';
E602: 'enemys';
E603: 'enemys';
T604: 'terrains';
E605: 'enemys';
E606: 'enemys';
E607: 'enemys';
E608: 'enemys';
E609: 'enemys';
E610: 'enemys';
E611: 'enemys';
E612: 'enemys';
E613: 'enemys';
E614: 'enemys';
E615: 'enemys';
E616: 'enemys';
E617: 'enemys';
E618: 'enemys';
N619: 'npcs';
N620: 'npcs';
N621: 'npcs';
N622: 'npcs';
N623: 'npcs';
N624: 'npcs';
N625: 'npcs';
N626: 'npcs';
T627: 'terrains';
T628: 'terrains';
T629: 'terrains';
N630: 'npc48';
N631: 'npc48';
N632: 'npc48';
N633: 'npc48';
N634: 'npc48';
N635: 'npc48';
N636: 'npc48';
N637: 'npc48';
N638: 'npc48';
N639: 'npc48';
T640: 'terrains';
I641: 'items';
I642: 'items';
E643: 'enemys';
E644: 'enemys';
E645: 'enemys';
E646: 'enemys';
E647: 'enemys';
T648: 'terrains';
T649: 'terrains';
T650: 'terrains';
T651: 'terrains';
T652: 'terrains';
T653: 'terrains';
T654: 'terrains';
X20032: 'tileset';
X20033: 'tileset';
X20034: 'tileset';
X20037: 'tileset';
X20038: 'tileset';
X20039: 'tileset';
X20040: 'tileset';
X20041: 'tileset';
X20042: 'tileset';
X20045: 'tileset';
X20047: 'tileset';
X20048: 'tileset';
X20049: 'tileset';
X20050: 'tileset';
X20053: 'tileset';
X20054: 'tileset';
X20055: 'tileset';
X20056: 'tileset';
X20057: 'tileset';
X20058: 'tileset';
X20064: 'tileset';
X20065: 'tileset';
X20066: 'tileset';
X20074: 'tileset';
X20152: 'tileset';
X20153: 'tileset';
X30040: 'tileset';
X30041: 'tileset';
X30042: 'tileset';
X30048: 'tileset';
X30050: 'tileset';
X30056: 'tileset';
X30057: 'tileset';
X30058: 'tileset';
X30105: 'tileset';
X30112: 'tileset';
X30113: 'tileset';
X30121: 'tileset';
X30196: 'tileset';
X30204: 'tileset';
X70019: 'tileset';
X70048: 'tileset';
X70049: 'tileset';
X70050: 'tileset';
X70056: 'tileset';
X70058: 'tileset';
X70059: 'tileset';
X70060: 'tileset';
X70064: 'tileset';
X70065: 'tileset';
X70066: 'tileset';
X70072: 'tileset';
X70073: 'tileset';
X70074: 'tileset';
X70080: 'tileset';
X70081: 'tileset';
X70082: 'tileset';
X70083: 'tileset';
X70084: 'tileset';
X70090: 'tileset';
X70091: 'tileset';
X70098: 'tileset';
X70099: 'tileset';
X70112: 'tileset';
X70114: 'tileset';
X70116: 'tileset';
X70120: 'tileset';
X70122: 'tileset';
X70124: 'tileset';
X70128: 'tileset';
X70130: 'tileset';
X70131: 'tileset';
X70132: 'tileset';
X70184: 'tileset';
X70185: 'tileset';
X70186: 'tileset';
X70200: 'tileset';
X70201: 'tileset';
X70202: 'tileset';
X90153: 'tileset';
X90154: 'tileset';
X90155: 'tileset';
tallYellowDoor: 'npc48';
tallBlueDoor: 'npc48';
tallRedDoor: 'npc48';
tallGreenDoor: 'npc48';
tallSpecialDoor: 'npc48';
tallSteelDoor: 'npc48';
keiskeiFairy: 'enemys';
tulipFairy: 'enemys';
bearDown: 'enemy48';
bearLeft: 'enemy48';
bearRight: 'enemy48';
bearUp: 'enemy48';
I331: 'items';
I332: 'items';
I333: 'items';
I334: 'items';
I335: 'items';
I336: 'items';
I337: 'items';
I338: 'items';
I339: 'items';
I340: 'items';
I341: 'items';
I342: 'items';
}

161
src/source/items.d.ts vendored
View File

@ -12,18 +12,17 @@ interface ItemDeclaration {
greenPotion: 'items';
sword0: 'items';
sword1: 'equips';
sword2: 'equips';
sword2: 'items';
sword3: 'items';
sword4: 'items';
sword5: 'items';
shield0: 'items';
shield1: 'equips';
shield2: 'equips';
shield1: 'items';
shield2: 'items';
shield3: 'items';
shield4: 'items';
shield5: 'items';
superPotion: 'items';
silverCoin: 'items';
book: 'constants';
fly: 'constants';
coin: 'constants';
@ -37,7 +36,7 @@ interface ItemDeclaration {
pickaxe: 'tools';
icePickaxe: 'tools';
bomb: 'tools';
centerFly: 'constants';
centerFly: 'tools';
upFly: 'tools';
downFly: 'tools';
earthquake: 'tools';
@ -49,142 +48,18 @@ interface ItemDeclaration {
lifeWand: 'tools';
jumpShoes: 'tools';
skill1: 'constants';
wand: 'constants';
I319: 'items';
I320: 'items';
I321: 'items';
I322: 'constants';
I323: 'items';
I324: 'items';
I325: 'items';
I326: 'items';
I327: 'items';
I328: 'items';
I329: 'items';
I330: 'constants';
I376: 'items';
I377: 'items';
I378: 'items';
I379: 'items';
I380: 'items';
I381: 'items';
I382: 'items';
I383: 'items';
I384: 'items';
I385: 'items';
I386: 'items';
I387: 'items';
I388: 'items';
I389: 'items';
I390: 'items';
I391: 'items';
I392: 'items';
I393: 'items';
I394: 'items';
I395: 'items';
I396: 'items';
I397: 'items';
I398: 'items';
I399: 'items';
I400: 'items';
I401: 'items';
I402: 'items';
I403: 'items';
I404: 'items';
I405: 'items';
I406: 'items';
I407: 'items';
I408: 'items';
I409: 'items';
I410: 'items';
I411: 'items';
I412: 'items';
I413: 'items';
I414: 'items';
I415: 'items';
I416: 'items';
I417: 'items';
I418: 'items';
I419: 'items';
I420: 'items';
I421: 'items';
I422: 'items';
I423: 'items';
I424: 'items';
I425: 'items';
I426: 'items';
I427: 'items';
I428: 'items';
I429: 'items';
I430: 'items';
I431: 'items';
I432: 'items';
I433: 'items';
I434: 'items';
I435: 'items';
I436: 'items';
I437: 'items';
I438: 'items';
I439: 'items';
I440: 'items';
I441: 'items';
I442: 'items';
I443: 'items';
I444: 'items';
I445: 'items';
I446: 'items';
I447: 'items';
I448: 'items';
I449: 'items';
I450: 'items';
I451: 'items';
I452: 'items';
I453: 'items';
I454: 'items';
I455: 'items';
I456: 'items';
I457: 'items';
I458: 'items';
I459: 'items';
I460: 'items';
I461: 'items';
I462: 'items';
I463: 'items';
I464: 'items';
I465: 'items';
I466: 'items';
I467: 'items';
I468: 'items';
I469: 'items';
I470: 'items';
I471: 'items';
I472: 'items';
I473: 'items';
I474: 'items';
I475: 'items';
I476: 'items';
I477: 'items';
I478: 'items';
I479: 'items';
I480: 'items';
I481: 'items';
I482: 'items';
I483: 'items';
I484: 'items';
I485: 'items';
I486: 'items';
I487: 'items';
I488: 'items';
I489: 'items';
I490: 'items';
I491: 'items';
I558: 'constants';
I559: 'constants';
I560: 'constants';
I565: 'constants';
I574: 'items';
I575: 'equips';
I589: 'equips';
I641: 'equips';
I642: 'constants';
wand: 'items';
pack: 'items';
I331: 'items';
I332: 'items';
I333: 'items';
I334: 'items';
I335: 'items';
I336: 'items';
I337: 'items';
I338: 'items';
I339: 'items';
I340: 'items';
I341: 'items';
I342: 'constants';
}

966
src/source/maps.d.ts vendored

File diff suppressed because it is too large Load Diff