Skip to content

Commit e873766

Browse files
Fix save + add contour thresholds
1 parent fe89cf8 commit e873766

File tree

9 files changed

+80
-29
lines changed

9 files changed

+80
-29
lines changed

.eslintrc.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module.exports = {
88
"plugin:@typescript-eslint/recommended"
99
],
1010
rules: {
11-
"brace-style": ["error", "1tbs", { "allowSingleLine": true }]
11+
"brace-style": ["error", "1tbs", { "allowSingleLine": true }],
12+
"@typescript-eslint/ban-ts-comment": "off"
1213
}
1314
};

plugin-metadata.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,28 @@ params:
147147
text:
148148
default: Nearest
149149
pt: Mais próximo
150+
- name: advanced
151+
text:
152+
default: Advanced
153+
pt: Avançado
154+
description:
155+
default: Advanced parameters for the plugin
156+
pt: Parâmetros avançados do plugin
157+
children:
158+
- name: saveRectCoverThresholds
159+
text:
160+
default: Save rect cover thresholds
161+
pt: Limites da cobertura por retângulos no save
162+
description:
163+
default: |-
164+
List of threshold values for contour detection on save. More values imply bigger save files, but with finer
165+
detail. Zero is implicit.
166+
pt: |-
167+
Lista de valores limitantes para a detecção de contornos no save. Mais valores implicam em arquivos de save
168+
maiores, mas com maior precisão. O zero é implícito.
169+
type: array
170+
items: number
171+
default: ["0.25", "0.5", "0.75"]
150172

151173
commands:
152174
- name: setPlayerVisionRange

src/core/fog-of-war/renderer.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,7 @@ export class FogOfWarRenderer extends PIXI.ObjectRenderer {
1919
}
2020

2121
private _createShader(): PIXI.Shader {
22-
const fragmentSrc = {
23-
bicubic: bicubicFragmentSrc,
24-
bilinear: bilinearFragmentSrc,
25-
nearest: nearestFragmentSrc
26-
}[pluginParams.fogFilter];
27-
22+
const fragmentSrc = this.getFragmentSrc(pluginParams.fogFilter);
2823
return PIXI.Shader.from(vertexSrc, fragmentSrc, {
2924
uProjectionMatrix: new PIXI.Matrix(),
3025
uTint: new Float32Array([0, 0, 0]),
@@ -34,6 +29,15 @@ export class FogOfWarRenderer extends PIXI.ObjectRenderer {
3429
});
3530
}
3631

32+
getFragmentSrc(name: string): string {
33+
switch (name) {
34+
case "bicubic": return bicubicFragmentSrc
35+
case "bilinear": return bilinearFragmentSrc
36+
case "nearest": return nearestFragmentSrc
37+
default: throw `unknown shader ${name}`;
38+
}
39+
}
40+
3741
get shader(): PIXI.Shader {
3842
return this._shader;
3943
}

src/game/fog-of-war.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,25 @@ export class Game_FogOfWar {
1818
this._invalidated = false;
1919
}
2020

21-
static from(width: number, height: number, rects: Rect[]): Game_FogOfWar {
21+
static from(width: number, height: number, contourRects: Rect[][], contourValues: number[]): Game_FogOfWar {
2222
const fog = new Game_FogOfWar();
2323
fog.reset(width, height);
24-
for (const [left, top, right, bottom] of rects) {
25-
for (let j = top; j <= bottom; j++) {
26-
for (let i = left; i <= right; i++) {
27-
fog._data[i + j * width] = Game_FogOfWar.FOW_MAX_DARKNESS;
24+
fog._data.fill(Game_FogOfWar.FOW_MAX_DARKNESS);
25+
26+
const contours = contourValues
27+
.map((value, i) => [value, contourRects[i]] as [number, Rect[]])
28+
.sort(([a,], [b,]) => b - a);
29+
30+
for (const [value, rects] of contours) {
31+
for (const [left, top, right, bottom] of rects) {
32+
for (let j = top; j <= bottom; j++) {
33+
for (let i = left; i <= right; i++) {
34+
fog._data[i + j * width] = value * Game_FogOfWar.FOW_MAX_DARKNESS;
35+
}
2836
}
2937
}
3038
}
39+
3140
return fog;
3241
}
3342

src/main.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export * from "./game";
22
export * from "./core";
3+
export * from "./utils";
34
import "./patch";
45
import "./commands";

src/parameters.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,8 @@ export default {
1414
blue: Number(tint.blue)
1515
},
1616
fogDispersionTime: Number(parameters['fogDispersionTime']),
17-
fogFilter: parameters['fogFilter']
17+
fogFilter: parameters['fogFilter'],
18+
advanced: {
19+
saveRectCoverThresholds: [0, ...JSON.parse(parameters['saveRectCoverThresholds']).map(Number)]
20+
}
1821
};

src/patch/core/json-ex.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,16 @@
88
import { Game_FogOfWar } from "game";
99
import { RectCover } from "utils";
1010

11+
import pluginParams from "parameters";
12+
1113
declare class JsonEx {
1214
static _encode(value: unknown, depth: number): string
1315
static _decode(value: unknown): unknown
1416
}
1517

1618
const _JsonEx_encode = JsonEx._encode;
1719
JsonEx._encode = function(value, depth): string {
18-
if (typeof value === "object" && value != null) {
20+
if (typeof value === "object" && !(value instanceof Array) && value != null) {
1921
const constructor = value.constructor;
2022
value = Object.assign({}, value);
2123
Object.setPrototypeOf(value, constructor.prototype);
@@ -24,9 +26,11 @@ JsonEx._encode = function(value, depth): string {
2426
if (value instanceof Game_FogOfWar) {
2527
const width = value.width;
2628
const height = value.height;
27-
const cover = new RectCover(value);
28-
const rects = cover.minimize();
29-
return _JsonEx_encode.call(this, { '@': 'Game_FogOfWar', width, height, rects }, depth + 1);
29+
const contours = pluginParams.advanced.saveRectCoverThresholds.map(threshold => {
30+
const cover = new RectCover(value as Game_FogOfWar, threshold);
31+
return cover.minimize();
32+
});
33+
return _JsonEx_encode.call(this, { '@': 'Game_FogOfWar', width, height, contours }, depth + 1);
3034
}
3135

3236
return _JsonEx_encode.call(this, value, depth);
@@ -36,7 +40,11 @@ const _JsonEx_decode = JsonEx._decode;
3640
JsonEx._decode = function(value): unknown {
3741
if (typeof value === "object" && value != null) {
3842
if (value["@"] === 'Game_FogOfWar') {
39-
return Game_FogOfWar.from(value['width'], value['height'], value['rects']);
43+
return Game_FogOfWar.from(
44+
value['width'],
45+
value['height'],
46+
value['contours'],
47+
pluginParams.advanced.saveRectCoverThresholds);
4048
}
4149
}
4250
return _JsonEx_decode.call(this, value);

src/utils/rect-cover.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ export type Grid = {
1010
type Strip = { x: number, top: number, bottom: number };
1111

1212
export class RectCover {
13-
private _grid: Grid
13+
private readonly _grid: Grid
14+
private readonly _threshold: number;
1415

15-
constructor(grid: Grid) {
16+
constructor(grid: Grid, threshold: number) {
1617
this._grid = grid;
18+
this._threshold = threshold;
1719
}
1820

1921
private _slice(): Strip[] {
@@ -23,8 +25,7 @@ export class RectCover {
2325
for (let y = 0; y < this._grid.height; y++) {
2426
const sy = y;
2527

26-
while (this._grid.at(x, y))
27-
y++;
28+
while (this._grid.at(x, y) <= this._threshold) y++;
2829

2930
if (sy != y) {
3031
strips.push({
@@ -43,21 +44,22 @@ export class RectCover {
4344
const strips = this._slice();
4445
const rectangles = new RectTrie();
4546
for (const { x: sx, top, bottom } of strips) {
46-
const rect: Rect = [top, bottom, 0, 0];
47+
const rect: Rect = [sx, top, sx, bottom];
4748

4849
let x = sx;
4950
right: while (x < this._grid.width) {
50-
for (let y = top; y <= bottom; y++)
51-
if (!this._grid.at(x, y)) break right;
52-
51+
for (let y = top; y <= bottom; y++) {
52+
if (this._grid.at(x, y) > this._threshold) break right;
53+
}
5354
x++;
5455
}
5556
rect[2] = x - 1;
5657

5758
x = sx;
5859
left: while (x >= 0) {
59-
for (let y = top; y <= bottom; y++)
60-
if (!this._grid.at(x, y)) break left;
60+
for (let y = top; y <= bottom; y++) {
61+
if (this._grid.at(x, y) > this._threshold) break left;
62+
}
6163
x--;
6264
}
6365
rect[0] = x + 1;

src/utils/rect-trie.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ class RectTrieNode {
4848
}
4949

5050
*[Symbol.iterator](): Iterator<[number, RectTrieNode]> {
51-
for (const [value, child] of Object.entries(this._children))
51+
for (const [value, child] of Object.entries(this._children)) {
5252
yield [Number(value), child];
53+
}
5354
}
5455
}

0 commit comments

Comments
 (0)