mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-04-19 08:56:08 +08:00
光环绘制
This commit is contained in:
parent
faf5a5c0c3
commit
f72d2161e5
@ -1492,65 +1492,7 @@ control.prototype.updateDamage = function (floorId, ctx) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
control.prototype._updateDamage_damage = function (floorId, onMap) {
|
control.prototype._updateDamage_damage = function (floorId, onMap) {
|
||||||
core.status.damage.data = [];
|
// Deprecated. See src/plugin/game/damage.ts EnemyCollection.render.
|
||||||
if (!core.flags.displayEnemyDamage && !core.flags.displayExtraDamage)
|
|
||||||
return;
|
|
||||||
|
|
||||||
core.extractBlocks(floorId);
|
|
||||||
core.status.maps[floorId].blocks.forEach(function (block) {
|
|
||||||
var x = block.x,
|
|
||||||
y = block.y;
|
|
||||||
|
|
||||||
// v2优化,只绘制范围内的部分
|
|
||||||
if (onMap && core.bigmap.v2) {
|
|
||||||
if (
|
|
||||||
x < core.bigmap.posX - core.bigmap.extend ||
|
|
||||||
x > core.bigmap.posX + core._WIDTH_ + core.bigmap.extend ||
|
|
||||||
y < core.bigmap.posY - core.bigmap.extend ||
|
|
||||||
y > core.bigmap.posY + core._HEIGHT_ + core.bigmap.extend
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
!block.disable &&
|
|
||||||
block.event.cls.indexOf('enemy') == 0 &&
|
|
||||||
block.event.displayDamage !== false
|
|
||||||
) {
|
|
||||||
if (core.flags.displayEnemyDamage) {
|
|
||||||
var damageString = core.enemys.getDamageString(
|
|
||||||
block.event.id,
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
floorId
|
|
||||||
);
|
|
||||||
core.status.damage.data.push({
|
|
||||||
text: damageString.damage,
|
|
||||||
px: 32 * x + 1,
|
|
||||||
py: 32 * (y + 1) - 1,
|
|
||||||
color: damageString.color
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (core.flags.displayCritical) {
|
|
||||||
var critical = core.enemys.nextCriticals(
|
|
||||||
block.event.id,
|
|
||||||
1,
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
floorId
|
|
||||||
);
|
|
||||||
critical = core.formatBigNumber((critical[0] || [])[0], true);
|
|
||||||
if (critical == '???') critical = '?';
|
|
||||||
core.status.damage.data.push({
|
|
||||||
text: critical,
|
|
||||||
px: 32 * x + 1,
|
|
||||||
py: 32 * (y + 1) - 11,
|
|
||||||
color: '#FFFFFF'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
control.prototype._updateDamage_extraDamage = function (floorId, onMap) {
|
control.prototype._updateDamage_extraDamage = function (floorId, onMap) {
|
||||||
@ -1558,7 +1500,7 @@ control.prototype._updateDamage_extraDamage = function (floorId, onMap) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
////// 重绘地图显伤 //////
|
////// 重绘地图显伤 //////
|
||||||
control.prototype.drawDamage = function (ctx) {
|
control.prototype.drawDamage = function (ctx, floorId = core.status.floorId) {
|
||||||
if (core.status.gameOver || !core.status.damage || main.mode != 'play')
|
if (core.status.gameOver || !core.status.damage || main.mode != 'play')
|
||||||
return;
|
return;
|
||||||
var onMap = false;
|
var onMap = false;
|
||||||
@ -1579,53 +1521,11 @@ control.prototype.drawDamage = function (ctx) {
|
|||||||
return this.updateDamage();
|
return this.updateDamage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this._drawDamage_draw(ctx, onMap);
|
return this._drawDamage_draw(ctx, onMap, floorId);
|
||||||
};
|
};
|
||||||
|
|
||||||
control.prototype._drawDamage_draw = function (ctx, onMap) {
|
control.prototype._drawDamage_draw = function (ctx, onMap) {
|
||||||
if (!core.hasItem('book')) return;
|
// Deprecated. See src/plugin/game/popup.js
|
||||||
core.plugin.halo.drawHalo(ctx, onMap);
|
|
||||||
|
|
||||||
core.setFont(ctx, "14px 'normal'");
|
|
||||||
core.setTextAlign(ctx, 'center');
|
|
||||||
core.setTextBaseline(ctx, 'middle');
|
|
||||||
core.status.damage.extraData.forEach(function (one) {
|
|
||||||
var px = one.px,
|
|
||||||
py = one.py;
|
|
||||||
if (onMap && core.bigmap.v2) {
|
|
||||||
px -= core.bigmap.posX * 32;
|
|
||||||
py -= core.bigmap.posY * 32;
|
|
||||||
if (
|
|
||||||
px < -32 ||
|
|
||||||
px > core._PX_ + 32 ||
|
|
||||||
py < -32 ||
|
|
||||||
py > core._PY_ + 32
|
|
||||||
)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var alpha = core.setAlpha(ctx, one.alpha);
|
|
||||||
core.fillBoldText(ctx, one.text, px, py, one.color);
|
|
||||||
core.setAlpha(ctx, alpha);
|
|
||||||
});
|
|
||||||
|
|
||||||
core.setTextAlign(ctx, 'left');
|
|
||||||
core.setTextBaseline(ctx, 'alphabetic');
|
|
||||||
core.status.damage.data.forEach(function (one) {
|
|
||||||
var px = one.px,
|
|
||||||
py = one.py;
|
|
||||||
if (onMap && core.bigmap.v2) {
|
|
||||||
px -= core.bigmap.posX * 32;
|
|
||||||
py -= core.bigmap.posY * 32;
|
|
||||||
if (
|
|
||||||
px < -32 * 2 ||
|
|
||||||
px > core._PX_ + 32 ||
|
|
||||||
py < -32 ||
|
|
||||||
py > core._PY_ + 32
|
|
||||||
)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
core.fillBoldText(ctx, one.text, px, py, one.color);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------ 录像相关 ------ //
|
// ------ 录像相关 ------ //
|
||||||
|
@ -448,7 +448,7 @@ enemys.prototype._getDamage = function (enemy, hero, x, y, floorId) {
|
|||||||
|
|
||||||
////// 获得当前楼层的怪物列表 //////
|
////// 获得当前楼层的怪物列表 //////
|
||||||
enemys.prototype.getCurrentEnemys = function (floorId) {
|
enemys.prototype.getCurrentEnemys = function (floorId) {
|
||||||
// todo: 删除getEnemyInfo - _getCurrentEnemys_addEnemy
|
// todo: 删除 getEnemyInfo - _getCurrentEnemys_addEnemy
|
||||||
floorId = floorId || core.status.floorId;
|
floorId = floorId || core.status.floorId;
|
||||||
var enemys = [],
|
var enemys = [],
|
||||||
used = {};
|
used = {};
|
||||||
|
@ -939,8 +939,7 @@ maps.prototype._canMoveDirectly_checkGlobal = function () {
|
|||||||
};
|
};
|
||||||
|
|
||||||
maps.prototype._canMoveDirectly_checkStartPoint = function (sx, sy) {
|
maps.prototype._canMoveDirectly_checkStartPoint = function (sx, sy) {
|
||||||
// todo: 不使用 core.status.checkBlock
|
if (core.status.thisMap.enemy.mapDamage[`${sx},${sy}`]) return false;
|
||||||
if (core.status.checkBlock.damage[sx + ',' + sy]) return false;
|
|
||||||
var block = core.getBlock(sx, sy);
|
var block = core.getBlock(sx, sy);
|
||||||
if (block != null) {
|
if (block != null) {
|
||||||
// 只有起点是传送点才是能无视
|
// 只有起点是传送点才是能无视
|
||||||
@ -2589,8 +2588,6 @@ maps.prototype._drawThumbnail_realDrawTempCanvas = function (
|
|||||||
options.ctx.imageSmoothingEnabled = true;
|
options.ctx.imageSmoothingEnabled = true;
|
||||||
// 缩略图:显伤
|
// 缩略图:显伤
|
||||||
if (options.damage && core.hasItem('book')) {
|
if (options.damage && core.hasItem('book')) {
|
||||||
// todo: 删除 updateCheckBlock
|
|
||||||
core.updateCheckBlock(floorId);
|
|
||||||
core.control.updateDamage(floorId, options.ctx);
|
core.control.updateDamage(floorId, options.ctx);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -3302,7 +3302,6 @@ ui.prototype._drawViewMaps = function (index, x, y) {
|
|||||||
if (index == null) return this._drawViewMaps_drawHint();
|
if (index == null) return this._drawViewMaps_drawHint();
|
||||||
core.animateFrame.tip = null;
|
core.animateFrame.tip = null;
|
||||||
// todo: 不使用 core.status.checkBlock
|
// todo: 不使用 core.status.checkBlock
|
||||||
core.status.checkBlock.cache = {};
|
|
||||||
var data = this._drawViewMaps_buildData(index, x, y);
|
var data = this._drawViewMaps_buildData(index, x, y);
|
||||||
core.fillRect('ui', 0, 0, core._PX_, core._PY_, '#000000');
|
core.fillRect('ui', 0, 0, core._PX_, core._PY_, '#000000');
|
||||||
core.drawThumbnail(data.floorId, null, {
|
core.drawThumbnail(data.floorId, null, {
|
||||||
|
@ -54,6 +54,7 @@ interface HaloData<T extends keyof HaloType = keyof HaloType> {
|
|||||||
type: T;
|
type: T;
|
||||||
data: HaloType[T];
|
data: HaloType[T];
|
||||||
from: DamageEnemy;
|
from: DamageEnemy;
|
||||||
|
special: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DamageDelta {
|
interface DamageDelta {
|
||||||
@ -107,8 +108,8 @@ export class EnemyCollection implements RangeCollection<DamageEnemy> {
|
|||||||
* 计算怪物真实属性
|
* 计算怪物真实属性
|
||||||
* @param noCache 是否不使用缓存
|
* @param noCache 是否不使用缓存
|
||||||
*/
|
*/
|
||||||
calRealAttribute(noCache: boolean = false) {
|
calRealAttribute() {
|
||||||
if (!noCache) return;
|
this.haloList = [];
|
||||||
this.list.forEach(v => {
|
this.list.forEach(v => {
|
||||||
v.reset();
|
v.reset();
|
||||||
v.preProvideHalo();
|
v.preProvideHalo();
|
||||||
@ -127,7 +128,7 @@ export class EnemyCollection implements RangeCollection<DamageEnemy> {
|
|||||||
* @param noCache 是否不使用缓存
|
* @param noCache 是否不使用缓存
|
||||||
*/
|
*/
|
||||||
calDamage(noCache: boolean = false, onMap: boolean = false) {
|
calDamage(noCache: boolean = false, onMap: boolean = false) {
|
||||||
if (noCache) this.calRealAttribute(noCache);
|
if (noCache) this.calRealAttribute();
|
||||||
this.list.forEach(v => {
|
this.list.forEach(v => {
|
||||||
v.calDamage(void 0, onMap);
|
v.calDamage(void 0, onMap);
|
||||||
});
|
});
|
||||||
@ -137,9 +138,8 @@ export class EnemyCollection implements RangeCollection<DamageEnemy> {
|
|||||||
* 计算地图伤害
|
* 计算地图伤害
|
||||||
* @param noCache 是否不使用缓存
|
* @param noCache 是否不使用缓存
|
||||||
*/
|
*/
|
||||||
calMapDamage(noCache: boolean = false) {
|
calMapDamage() {
|
||||||
if (!noCache) return;
|
this.mapDamage = {};
|
||||||
if (noCache) this.mapDamage = {};
|
|
||||||
const hero = getHeroStatusOn(
|
const hero = getHeroStatusOn(
|
||||||
realStatus,
|
realStatus,
|
||||||
core.status.hero.loc.x,
|
core.status.hero.loc.x,
|
||||||
@ -200,7 +200,7 @@ export class EnemyCollection implements RangeCollection<DamageEnemy> {
|
|||||||
) {
|
) {
|
||||||
if (cal) {
|
if (cal) {
|
||||||
this.calDamage(noCache, true);
|
this.calDamage(noCache, true);
|
||||||
this.calMapDamage(noCache);
|
this.calMapDamage();
|
||||||
}
|
}
|
||||||
core.status.damage.data = [];
|
core.status.damage.data = [];
|
||||||
core.status.damage.extraData = [];
|
core.status.damage.extraData = [];
|
||||||
@ -527,6 +527,12 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
|
|||||||
e.damageDecline += this.enemy.iceHalo ?? 0;
|
e.damageDecline += this.enemy.iceHalo ?? 0;
|
||||||
});
|
});
|
||||||
this.providedHalo.push(21);
|
this.providedHalo.push(21);
|
||||||
|
col.haloList.push({
|
||||||
|
type: 'square',
|
||||||
|
data: { x: this.x, y: this.y, d: 7 },
|
||||||
|
special: 21,
|
||||||
|
from: this
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 冰封之核
|
// 冰封之核
|
||||||
@ -535,6 +541,12 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
|
|||||||
e.defBuff += this.enemy.iceCore ?? 0;
|
e.defBuff += this.enemy.iceCore ?? 0;
|
||||||
});
|
});
|
||||||
this.providedHalo.push(26);
|
this.providedHalo.push(26);
|
||||||
|
col.haloList.push({
|
||||||
|
type: 'square',
|
||||||
|
data: { x: this.x, y: this.y, d: 5 },
|
||||||
|
special: 26,
|
||||||
|
from: this
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 火焰之核
|
// 火焰之核
|
||||||
@ -543,6 +555,12 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
|
|||||||
e.atkBuff += this.enemy.fireCore ?? 0;
|
e.atkBuff += this.enemy.fireCore ?? 0;
|
||||||
});
|
});
|
||||||
this.providedHalo.push(27);
|
this.providedHalo.push(27);
|
||||||
|
col.haloList.push({
|
||||||
|
type: 'square',
|
||||||
|
data: { x: this.x, y: this.y, d: 5 },
|
||||||
|
special: 27,
|
||||||
|
from: this
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
col.applyHalo('square', { x: this.x, y: this.y, d: 7 }, square7);
|
col.applyHalo('square', { x: this.x, y: this.y, d: 7 }, square7);
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
///<reference path="../../../src/types/core.d.ts" />
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 绘制光环范围
|
|
||||||
* @param {CanvasRenderingContext2D} ctx
|
|
||||||
* @param {boolean} onMap
|
|
||||||
*/
|
|
||||||
export function drawHalo(ctx, onMap) {
|
|
||||||
if (main.replayChecking) return;
|
|
||||||
if (!core.getLocalStorage('showHalo', true)) return;
|
|
||||||
// todo: 不使用 core.status.checkBlock
|
|
||||||
const halo = core.status.checkBlock.halo;
|
|
||||||
ctx.save();
|
|
||||||
for (const [loc, range] of Object.entries(halo)) {
|
|
||||||
const [x, y] = loc.split(',').map(v => parseInt(v));
|
|
||||||
for (const r of range) {
|
|
||||||
const [type, value, color, border] = r.split(':');
|
|
||||||
if (type === 'square') {
|
|
||||||
// 正方形光环
|
|
||||||
const n = parseInt(value);
|
|
||||||
const r = Math.floor(n / 2);
|
|
||||||
let left = x - r,
|
|
||||||
right = x + r,
|
|
||||||
top = y - r,
|
|
||||||
bottom = y + r;
|
|
||||||
if (onMap && core.bigmap.v2) {
|
|
||||||
left -= core.bigmap.posX;
|
|
||||||
top -= core.bigmap.posY;
|
|
||||||
right -= core.bigmap.posX;
|
|
||||||
bottom -= core.bigmap.posY;
|
|
||||||
if (
|
|
||||||
right < -1 ||
|
|
||||||
left > core._PX_ / 32 + 1 ||
|
|
||||||
top < -1 ||
|
|
||||||
bottom > core._PY_ / 32 + 1
|
|
||||||
) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ctx.fillStyle = color;
|
|
||||||
ctx.strokeStyle = border ?? color;
|
|
||||||
ctx.lineWidth = 1;
|
|
||||||
ctx.globalAlpha = 0.1;
|
|
||||||
ctx.fillRect(left * 32, top * 32, n * 32, n * 32);
|
|
||||||
ctx.globalAlpha = 0.6;
|
|
||||||
ctx.strokeRect(left * 32, top * 32, n * 32, n * 32);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ctx.restore();
|
|
||||||
}
|
|
||||||
|
|
||||||
core.plugin.halo = {
|
|
||||||
drawHalo
|
|
||||||
};
|
|
50
src/plugin/game/halo.ts
Normal file
50
src/plugin/game/halo.ts
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
const haloColor: Record<number, string[]> = {
|
||||||
|
21: ['cyan'],
|
||||||
|
26: ['blue'],
|
||||||
|
27: ['red']
|
||||||
|
};
|
||||||
|
|
||||||
|
export function drawHalo(
|
||||||
|
ctx: CanvasRenderingContext2D,
|
||||||
|
onMap: boolean,
|
||||||
|
floorId: FloorIds
|
||||||
|
) {
|
||||||
|
if (main.replayChecking) return;
|
||||||
|
if (!core.getLocalStorage('showHalo', true)) return;
|
||||||
|
const list = core.status.maps[floorId].enemy.haloList;
|
||||||
|
ctx.save();
|
||||||
|
for (const halo of list) {
|
||||||
|
if (halo.type === 'square') {
|
||||||
|
const { x, y, d } = halo.data;
|
||||||
|
const [color, border] = haloColor[halo.special];
|
||||||
|
const r = Math.floor(d / 2);
|
||||||
|
let left = x - r,
|
||||||
|
right = x + r,
|
||||||
|
top = y - r,
|
||||||
|
bottom = y + r;
|
||||||
|
if (onMap && core.bigmap.v2) {
|
||||||
|
left -= core.bigmap.posX;
|
||||||
|
top -= core.bigmap.posY;
|
||||||
|
right -= core.bigmap.posX;
|
||||||
|
bottom -= core.bigmap.posY;
|
||||||
|
if (
|
||||||
|
right < -1 ||
|
||||||
|
left > core._PX_ / 32 + 1 ||
|
||||||
|
top < -1 ||
|
||||||
|
bottom > core._PY_ / 32 + 1
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.fillStyle = color;
|
||||||
|
ctx.strokeStyle = border ?? color;
|
||||||
|
ctx.lineWidth = 1;
|
||||||
|
ctx.globalAlpha = 0.1;
|
||||||
|
ctx.fillRect(left * 32, top * 32, d * 32, d * 32);
|
||||||
|
ctx.globalAlpha = 0.6;
|
||||||
|
ctx.strokeRect(left * 32, top * 32, d * 32, d * 32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.restore();
|
||||||
|
}
|
@ -19,15 +19,13 @@ core.control.updateDamage = function (floorId = core.status.floorId, ctx) {
|
|||||||
core.plugin.damage.ensureFloorDamage(floorId);
|
core.plugin.damage.ensureFloorDamage(floorId);
|
||||||
|
|
||||||
floor.enemy.calDamage(true, onMap);
|
floor.enemy.calDamage(true, onMap);
|
||||||
floor.enemy.calMapDamage(true);
|
floor.enemy.calMapDamage();
|
||||||
core.status.damage.data = [];
|
core.status.damage.data = [];
|
||||||
|
|
||||||
floor.enemy.render();
|
floor.enemy.render();
|
||||||
|
|
||||||
// this._updateDamage_damage(floorId, onMap);
|
|
||||||
// this._updateDamage_extraDamage(floorId, onMap);
|
|
||||||
getItemDetail(floorId, onMap); // 宝石血瓶详细信息
|
getItemDetail(floorId, onMap); // 宝石血瓶详细信息
|
||||||
this.drawDamage(ctx);
|
this.drawDamage(ctx, floorId);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 获取宝石信息 并绘制
|
// 获取宝石信息 并绘制
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
///<reference path="../../../src/types/core.d.ts" />
|
///<reference path="../../../src/types/core.d.ts" />
|
||||||
export {};
|
import { drawHalo } from './halo';
|
||||||
|
|
||||||
// 伤害弹出
|
// 伤害弹出
|
||||||
// 复写阻激夹域检测
|
// 复写阻激夹域检测
|
||||||
@ -40,9 +40,9 @@ control.prototype.checkBlock = function (forceMockery) {
|
|||||||
/**
|
/**
|
||||||
* @param {CanvasRenderingContext2D} ctx
|
* @param {CanvasRenderingContext2D} ctx
|
||||||
*/
|
*/
|
||||||
control.prototype._drawDamage_draw = function (ctx, onMap) {
|
control.prototype._drawDamage_draw = function (ctx, onMap, floorId) {
|
||||||
if (!core.hasItem('book')) return;
|
if (!core.hasItem('book')) return;
|
||||||
core.plugin.halo.drawHalo(ctx, onMap);
|
drawHalo(ctx, onMap, floorId);
|
||||||
|
|
||||||
core.setFont(ctx, "14px 'normal'");
|
core.setFont(ctx, "14px 'normal'");
|
||||||
core.setTextAlign(ctx, 'center');
|
core.setTextAlign(ctx, 'center');
|
||||||
|
2
src/types/control.d.ts
vendored
2
src/types/control.d.ts
vendored
@ -490,7 +490,7 @@ interface Control {
|
|||||||
* 重绘地图显伤
|
* 重绘地图显伤
|
||||||
* @param ctx 绘制到的画布
|
* @param ctx 绘制到的画布
|
||||||
*/
|
*/
|
||||||
drawDamage(ctx?: CtxRefer): void;
|
drawDamage(ctx?: CtxRefer, floorId: FloorIds): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 选择录像文件
|
* 选择录像文件
|
||||||
|
Loading…
Reference in New Issue
Block a user