光环绘制

This commit is contained in:
unanmed 2023-07-14 11:22:36 +08:00
parent faf5a5c0c3
commit f72d2161e5
10 changed files with 87 additions and 180 deletions

View File

@ -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);
});
}; };
// ------ 录像相关 ------ // // ------ 录像相关 ------ //

View File

@ -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 = {};

View File

@ -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);
} }
}; };

View File

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

View File

@ -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);

View File

@ -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
View 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();
}

View File

@ -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);
}; };
// 获取宝石信息 并绘制 // 获取宝石信息 并绘制

View File

@ -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');

View File

@ -490,7 +490,7 @@ interface Control {
* *
* @param ctx * @param ctx
*/ */
drawDamage(ctx?: CtxRefer): void; drawDamage(ctx?: CtxRefer, floorId: FloorIds): void;
/** /**
* *