From e84dc5924eb60279918875f202694825818d793c Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 13 Jun 2024 21:29:02 +0400 Subject: [PATCH 001/285] minimap storybook --- src/react/Minimap.stories.tsx | 17 +++++++++++++ src/react/Minimap.tsx | 47 +++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 src/react/Minimap.stories.tsx create mode 100644 src/react/Minimap.tsx diff --git a/src/react/Minimap.stories.tsx b/src/react/Minimap.stories.tsx new file mode 100644 index 000000000..854b27fbe --- /dev/null +++ b/src/react/Minimap.stories.tsx @@ -0,0 +1,17 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import Minimap from './Minimap' + +const meta: Meta = { + component: Minimap, + args: { + }, +} + +export default meta +type Story = StoryObj; + +export const Primary: Story = { + args: { + }, +} diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx new file mode 100644 index 000000000..9f3337799 --- /dev/null +++ b/src/react/Minimap.tsx @@ -0,0 +1,47 @@ +import { useRef, useEffect } from 'react' + +export default () => { + const canvasRef = useRef(null) + + const drawMap = () => { + const canvas = canvasRef.current! + const ctx = canvas.getContext('2d')! + ctx.clearRect(0, 0, canvas.width, canvas.height) + + const centerX = canvas.width / 2 + const centerY = canvas.height / 2 + const radius = 25 + + ctx.beginPath() + + ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false) + + ctx.fillStyle = 'white' + ctx.fill() + + ctx.strokeStyle = '#000000' + ctx.lineWidth = 1 + ctx.stroke() + } + + useEffect(() => { + if (canvasRef.current) { + drawMap() + } + }, [canvasRef.current]) + + + return
+ + +
+} From d8aabaf99d8680688fb65c2ecd01cb27bb64f02f Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 13 Jun 2024 22:10:06 +0400 Subject: [PATCH 002/285] simple class for map drawing --- src/react/Minimap.tsx | 20 +++--------------- src/react/MinimapDrawer.ts | 43 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 17 deletions(-) create mode 100644 src/react/MinimapDrawer.ts diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 9f3337799..3ee177b6c 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,27 +1,13 @@ import { useRef, useEffect } from 'react' +import { MinimapDrawer } from './MinimapDrawer' export default () => { const canvasRef = useRef(null) const drawMap = () => { const canvas = canvasRef.current! - const ctx = canvas.getContext('2d')! - ctx.clearRect(0, 0, canvas.width, canvas.height) - - const centerX = canvas.width / 2 - const centerY = canvas.height / 2 - const radius = 25 - - ctx.beginPath() - - ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false) - - ctx.fillStyle = 'white' - ctx.fill() - - ctx.strokeStyle = '#000000' - ctx.lineWidth = 1 - ctx.stroke() + const minimapDrawer = new MinimapDrawer(canvas) + minimapDrawer.draw() } useEffect(() => { diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts new file mode 100644 index 000000000..8bb29f976 --- /dev/null +++ b/src/react/MinimapDrawer.ts @@ -0,0 +1,43 @@ + +export class MinimapDrawer { + centerX: number + centerY: number + radius: number + canvas: HTMLCanvasElement + ctx: CanvasRenderingContext2D + + constructor ( + canvas: HTMLCanvasElement, + centerX?: number, + centerY?: number, + radius?: number, + ) { + this.canvas = canvas + this.ctx = this.canvas.getContext('2d')! + this.centerX = centerX ?? this.canvas.width / 2 + this.centerY = centerY ?? this.canvas.height / 2 + this.radius = radius ?? 25 + } + + draw() { + this.ctx.clearRect( + this.centerX - this.radius, + this.centerY - this.radius, + this.canvas.width, + this.canvas.height + ) + this.ctx.strokeStyle = 'black' + + this.ctx.beginPath() + + this.ctx.arc(this.centerX, this.centerY, this.radius, 0, 2 * Math.PI, false) + + this.ctx.fillStyle = 'white' + this.ctx.fill() + + this.ctx.strokeStyle = '#000000' + this.ctx.lineWidth = 1 + this.ctx.stroke() + + } +} From 2696a1e345d6355dae137f6de3b6a420c59e1148 Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 13 Jun 2024 23:13:26 +0400 Subject: [PATCH 003/285] drawing map by pixel ex --- src/react/Minimap.stories.tsx | 14 ++++++++++-- src/react/Minimap.tsx | 4 ++-- src/react/MinimapDrawer.ts | 43 +++++++++++++++++++++++++++-------- 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/react/Minimap.stories.tsx b/src/react/Minimap.stories.tsx index 854b27fbe..5df1b26af 100644 --- a/src/react/Minimap.stories.tsx +++ b/src/react/Minimap.stories.tsx @@ -4,14 +4,24 @@ import Minimap from './Minimap' const meta: Meta = { component: Minimap, - args: { - }, } export default meta type Story = StoryObj; +let worldColors: string[][] = [] + +const mapSize = 50 +for (let i=0; i { +export default ({ worldColors }: { worldColors: string[][] }) => { const canvasRef = useRef(null) const drawMap = () => { const canvas = canvasRef.current! const minimapDrawer = new MinimapDrawer(canvas) - minimapDrawer.draw() + minimapDrawer.draw(worldColors) } useEffect(() => { diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 8bb29f976..71f24a18c 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -1,10 +1,10 @@ - export class MinimapDrawer { centerX: number centerY: number radius: number canvas: HTMLCanvasElement ctx: CanvasRenderingContext2D + worldColors: string[] constructor ( canvas: HTMLCanvasElement, @@ -19,25 +19,48 @@ export class MinimapDrawer { this.radius = radius ?? 25 } - draw() { + draw(worldColors?: string[][]) { this.ctx.clearRect( this.centerX - this.radius, this.centerY - this.radius, this.canvas.width, this.canvas.height ) - this.ctx.strokeStyle = 'black' - this.ctx.beginPath() + if (worldColors) { + this.updateWorldColors(worldColors) + } else { + this.ctx.strokeStyle = 'black' + this.ctx.beginPath() - this.ctx.arc(this.centerX, this.centerY, this.radius, 0, 2 * Math.PI, false) + this.ctx.arc(this.centerX, this.centerY, this.radius, 0, 2 * Math.PI, false) - this.ctx.fillStyle = 'white' - this.ctx.fill() + this.ctx.fillStyle = 'white' + this.ctx.fill() - this.ctx.strokeStyle = '#000000' - this.ctx.lineWidth = 1 - this.ctx.stroke() + this.ctx.strokeStyle = '#000000' + this.ctx.lineWidth = 1 + this.ctx.stroke() + } } + + updateWorldColors(worldColors: string[][]) { + const left = this.centerX - this.radius + const top = this.centerY - this.radius + + this.ctx.save() + + this.ctx.beginPath() + this.ctx.arc(this.centerX, this.centerY, this.radius, 0, Math.PI*2, true) + this.ctx.clip() + + for (let row=0; row Date: Thu, 13 Jun 2024 23:21:41 +0400 Subject: [PATCH 004/285] better scaling --- src/react/Minimap.stories.tsx | 2 +- src/react/MinimapDrawer.ts | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/react/Minimap.stories.tsx b/src/react/Minimap.stories.tsx index 5df1b26af..8b63d3910 100644 --- a/src/react/Minimap.stories.tsx +++ b/src/react/Minimap.stories.tsx @@ -11,7 +11,7 @@ type Story = StoryObj; let worldColors: string[][] = [] -const mapSize = 50 +const mapSize = 10 for (let i=0; i Date: Fri, 14 Jun 2024 12:45:37 +0400 Subject: [PATCH 005/285] fixed eslint in MinimapDrawer --- src/react/Minimap.stories.tsx | 6 +++--- src/react/MinimapDrawer.ts | 20 ++++++++------------ src/react/MinimapProvider.tsx | 17 +++++++++++++++++ 3 files changed, 28 insertions(+), 15 deletions(-) create mode 100644 src/react/MinimapProvider.tsx diff --git a/src/react/Minimap.stories.tsx b/src/react/Minimap.stories.tsx index 8b63d3910..25ea6507a 100644 --- a/src/react/Minimap.stories.tsx +++ b/src/react/Minimap.stories.tsx @@ -9,12 +9,12 @@ const meta: Meta = { export default meta type Story = StoryObj; -let worldColors: string[][] = [] +const worldColors: string[][] = [] const mapSize = 10 -for (let i=0; i { + const [worldColors, setWorldColors] = useState([]) + + useEffect(() => { + const newColors = [] as string[][] + + + }, []) + + return
+ +
+} From 0f78c74146b4e11da99037350068b731fcc44974 Mon Sep 17 00:00:00 2001 From: gguio Date: Sat, 15 Jun 2024 13:37:35 +0400 Subject: [PATCH 006/285] map draws and updates. Not optimized --- src/react/Minimap.tsx | 2 +- src/react/MinimapProvider.tsx | 35 ++++++++++++++++++++++++++++++++++- src/reactUi.tsx | 2 ++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 0e6aee42d..7590862a6 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -14,7 +14,7 @@ export default ({ worldColors }: { worldColors: string[][] }) => { if (canvasRef.current) { drawMap() } - }, [canvasRef.current]) + }, [canvasRef.current, worldColors]) return
{ const [worldColors, setWorldColors] = useState([]) - useEffect(() => { + const getHighestBlock = (x: number, z: number) => { + let block = null as import('prismarine-block').Block | null + let height = (bot.game as any).height + const airBlocks = ['air', 'cave_air', 'void_air'] + do { + block = bot.world.getBlock(new Vec3(x, height, z)) + height -= 1 + } while (airBlocks.includes(block?.name ?? '')) + return height + } + + const drawMap = () => { + const { colors } = BlockData const newColors = [] as string[][] + const mapSize = 24 + for (let i = 0; i < mapSize; i += 1) { + newColors[i] = [] as string[] + for (let j = 0; j < mapSize; j += 1) { + const x = bot.entity.position.x - mapSize / 2 + i + const z = bot.entity.position.z - mapSize / 2 + j + const y = getHighestBlock(x, z) + const blockName = bot.world.getBlock(new Vec3(x, y, z))?.name + newColors[i][j] = blockName ? colors[blockName] ?? 'white' : 'white' + } + } + setWorldColors([...newColors]) + } + + useEffect(() => { + bot.on('move', drawMap) + return () => { + bot.off('move', drawMap) + } }, []) return
diff --git a/src/reactUi.tsx b/src/reactUi.tsx index 8a9cc32ce..7a80d55ea 100644 --- a/src/reactUi.tsx +++ b/src/reactUi.tsx @@ -19,6 +19,7 @@ import ScoreboardProvider from './react/ScoreboardProvider' import SignEditorProvider from './react/SignEditorProvider' import IndicatorEffectsProvider from './react/IndicatorEffectsProvider' import PlayerListOverlayProvider from './react/PlayerListOverlayProvider' +import MinimapProvider from './react/MinimapProvider' import HudBarsProvider from './react/HudBarsProvider' import XPBarProvider from './react/XPBarProvider' import DebugOverlay from './react/DebugOverlay' @@ -114,6 +115,7 @@ const InGameUi = () => { +
From 362d87c320293807d95a596f61f7e0c5d1a9a0a0 Mon Sep 17 00:00:00 2001 From: gguio Date: Mon, 17 Jun 2024 12:20:43 +0400 Subject: [PATCH 007/285] stable --- src/react/MinimapProvider.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index c0193e213..237122dd6 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -15,25 +15,24 @@ export default () => { block = bot.world.getBlock(new Vec3(x, height, z)) height -= 1 } while (airBlocks.includes(block?.name ?? '')) - return height + return block.name } const drawMap = () => { const { colors } = BlockData const newColors = [] as string[][] - const mapSize = 24 + const mapSize = 50 for (let i = 0; i < mapSize; i += 1) { newColors[i] = [] as string[] for (let j = 0; j < mapSize; j += 1) { const x = bot.entity.position.x - mapSize / 2 + i const z = bot.entity.position.z - mapSize / 2 + j - const y = getHighestBlock(x, z) - const blockName = bot.world.getBlock(new Vec3(x, y, z))?.name + const blockName = getHighestBlock(x, z) newColors[i][j] = blockName ? colors[blockName] ?? 'white' : 'white' } } - setWorldColors([...newColors]) + setWorldColors(newColors) } useEffect(() => { From 73cf00b1b4c399999cc7fe720d2064b75f4152dd Mon Sep 17 00:00:00 2001 From: gguio Date: Mon, 17 Jun 2024 13:37:27 +0400 Subject: [PATCH 008/285] a little faster drawing. Still lags --- src/react/Minimap.tsx | 25 ++++++++++----- src/react/MinimapDrawer.ts | 57 +++++++++++++++++++++++++++-------- src/react/MinimapProvider.tsx | 39 +----------------------- 3 files changed, 63 insertions(+), 58 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 7590862a6..1ddcef0e3 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,20 +1,31 @@ import { useRef, useEffect } from 'react' import { MinimapDrawer } from './MinimapDrawer' -export default ({ worldColors }: { worldColors: string[][] }) => { +export default () => { + const canvasTick = useRef(0) const canvasRef = useRef(null) + const drawerRef = useRef(null) - const drawMap = () => { - const canvas = canvasRef.current! - const minimapDrawer = new MinimapDrawer(canvas) - minimapDrawer.draw(worldColors) + function updateMap () { + if (drawerRef.current && canvasTick.current % 10 === 0) { + drawerRef.current.draw(bot) + } + canvasTick.current += 1 } useEffect(() => { if (canvasRef.current) { - drawMap() + drawerRef.current = new MinimapDrawer(canvasRef.current) + } + }, [canvasRef.current]) + + useEffect(() => { + bot.on('move', updateMap) + + return () => { + bot.off('move', updateMap) } - }, [canvasRef.current, worldColors]) + }, []) return
& { + world: Omit & { + getBlock: (pos: import('vec3').Vec3) => import('prismarine-block').Block | null + } + _client: Omit & { + write: typeof import('../generatedClientPackets').clientWrite + on: typeof import('../generatedServerPackets').clientOn + } +} + export class MinimapDrawer { centerX: number centerY: number + mapSize: number radius: number ctx: CanvasRenderingContext2D @@ -9,15 +24,17 @@ export class MinimapDrawer { centerX?: number, centerY?: number, radius?: number, + mapSize?: number ) { this.canvas = canvas this.ctx = this.canvas.getContext('2d')! this.centerX = centerX ?? this.canvas.width / 2 this.centerY = centerY ?? this.canvas.height / 2 this.radius = radius ?? 25 + this.mapSize = mapSize ?? this.radius * 2 } - draw (worldColors?: string[][]) { + draw (bot: BotType | undefined) { this.ctx.clearRect( this.centerX - this.radius, this.centerY - this.radius, @@ -25,8 +42,8 @@ export class MinimapDrawer { this.radius * 2 ) - if (worldColors) { - this.updateWorldColors(worldColors) + if (bot) { + this.updateWorldColors(bot) } else { this.ctx.strokeStyle = 'black' this.ctx.beginPath() @@ -42,9 +59,10 @@ export class MinimapDrawer { } } - updateWorldColors (worldColors: string[][]) { + updateWorldColors (bot: BotType) { const left = this.centerX - this.radius const top = this.centerY - this.radius + const mapPixel = Math.floor(this.radius * 2 / this.mapSize) this.ctx.save() @@ -52,18 +70,31 @@ export class MinimapDrawer { this.ctx.arc(this.centerX, this.centerY, this.radius, 0, Math.PI * 2, true) this.ctx.clip() - for (let row = 0; row < worldColors.length; row += 1) { - for (let col = 0; col < worldColors[row].length; col += 1) { - this.ctx.fillStyle = worldColors[row][col] - const rectWidth = Math.floor(this.radius * 2 / worldColors[row].length) - const rectHeight = Math.floor(this.radius * 2 / worldColors.length) + for (let row = 0; row < this.mapSize; row += 1) { + for (let col = 0; col < this.mapSize; col += 1) { + this.ctx.fillStyle = this.getHighestBlockColor( + bot, + bot.entity.position.x - this.mapSize / 2 + row, + bot.entity.position.z - this.mapSize / 2 + col + ) this.ctx.fillRect( - left + rectWidth * col, - top + rectHeight * row, - rectWidth, - rectHeight + left + mapPixel * col, + top + mapPixel * row, + mapPixel, + mapPixel ) } } } + + getHighestBlockColor (bot: BotType, x: number, z: number) { + let block = null as import('prismarine-block').Block | null + let { height } = (bot.game as any) + const airBlocks = new Set(['air', 'cave_air', 'void_air']) + do { + block = bot.world.getBlock(new Vec3(x, height, z)) + height -= 1 + } while (airBlocks.has(block?.name ?? '')) + return BlockData.colors[block?.name ?? ''] ?? 'white' + } } diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 237122dd6..d189337ac 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -5,45 +5,8 @@ import Minimap from './Minimap' export default () => { - const [worldColors, setWorldColors] = useState([]) - - const getHighestBlock = (x: number, z: number) => { - let block = null as import('prismarine-block').Block | null - let height = (bot.game as any).height - const airBlocks = ['air', 'cave_air', 'void_air'] - do { - block = bot.world.getBlock(new Vec3(x, height, z)) - height -= 1 - } while (airBlocks.includes(block?.name ?? '')) - return block.name - } - - const drawMap = () => { - const { colors } = BlockData - const newColors = [] as string[][] - - const mapSize = 50 - for (let i = 0; i < mapSize; i += 1) { - newColors[i] = [] as string[] - for (let j = 0; j < mapSize; j += 1) { - const x = bot.entity.position.x - mapSize / 2 + i - const z = bot.entity.position.z - mapSize / 2 + j - const blockName = getHighestBlock(x, z) - newColors[i][j] = blockName ? colors[blockName] ?? 'white' : 'white' - } - } - setWorldColors(newColors) - } - - useEffect(() => { - bot.on('move', drawMap) - - return () => { - bot.off('move', drawMap) - } - }, []) return
- +
} From 55ce44585f6f65af1eb4d4938dff925dd6f6026b Mon Sep 17 00:00:00 2001 From: gguio Date: Mon, 17 Jun 2024 19:59:40 +0400 Subject: [PATCH 009/285] cacha added. Didnt change anything, refactoring required --- src/react/Minimap.tsx | 3 ++ src/react/MinimapDrawer.ts | 63 ++++++++++++++++++++++++++------------ 2 files changed, 46 insertions(+), 20 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 1ddcef0e3..7f46c349d 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -9,6 +9,9 @@ export default () => { function updateMap () { if (drawerRef.current && canvasTick.current % 10 === 0) { drawerRef.current.draw(bot) + if (canvasTick.current % 300 === 0) { + drawerRef.current.clearCache(bot.entity.position.x, bot.entity.position.z) + } } canvasTick.current += 1 } diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 013421c6e..a5f12a608 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -1,15 +1,17 @@ import { Vec3 } from 'vec3' +import { Position } from 'source-map-js' +import { underive } from 'valtio/utils' import BlockData from '../../prismarine-viewer/viewer/lib/moreBlockDataGenerated.json' type BotType = Omit & { - world: Omit & { - getBlock: (pos: import('vec3').Vec3) => import('prismarine-block').Block | null - } - _client: Omit & { - write: typeof import('../generatedClientPackets').clientWrite - on: typeof import('../generatedServerPackets').clientOn - } + world: Omit & { + getBlock: (pos: import('vec3').Vec3) => import('prismarine-block').Block | null + } + _client: Omit & { + write: typeof import('../generatedClientPackets').clientWrite + on: typeof import('../generatedServerPackets').clientOn + } } export class MinimapDrawer { @@ -17,7 +19,8 @@ export class MinimapDrawer { centerY: number mapSize: number radius: number - ctx: CanvasRenderingContext2D + ctx: CanvasRenderingContext2D + worldColors: { [key: string]: string } constructor ( private readonly canvas: HTMLCanvasElement, @@ -28,6 +31,7 @@ export class MinimapDrawer { ) { this.canvas = canvas this.ctx = this.canvas.getContext('2d')! + this.ctx.imageSmoothingEnabled = false this.centerX = centerX ?? this.canvas.width / 2 this.centerY = centerY ?? this.canvas.height / 2 this.radius = radius ?? 25 @@ -36,9 +40,9 @@ export class MinimapDrawer { draw (bot: BotType | undefined) { this.ctx.clearRect( - this.centerX - this.radius, - this.centerY - this.radius, - this.radius * 2, + this.centerX - this.radius, + this.centerY - this.radius, + this.radius * 2, this.radius * 2 ) @@ -67,20 +71,20 @@ export class MinimapDrawer { this.ctx.save() this.ctx.beginPath() - this.ctx.arc(this.centerX, this.centerY, this.radius, 0, Math.PI * 2, true) + this.ctx.arc(this.centerX, this.centerY, this.radius, 0, Math.PI * 2, true) this.ctx.clip() for (let row = 0; row < this.mapSize; row += 1) { for (let col = 0; col < this.mapSize; col += 1) { this.ctx.fillStyle = this.getHighestBlockColor( - bot, - bot.entity.position.x - this.mapSize / 2 + row, + bot, + bot.entity.position.x - this.mapSize / 2 + row, bot.entity.position.z - this.mapSize / 2 + col ) this.ctx.fillRect( - left + mapPixel * col, - top + mapPixel * row, - mapPixel, + left + mapPixel * col, + top + mapPixel * row, + mapPixel, mapPixel ) } @@ -88,13 +92,32 @@ export class MinimapDrawer { } getHighestBlockColor (bot: BotType, x: number, z: number) { - let block = null as import('prismarine-block').Block | null + const key = `${x},${z}` + if (Object.keys(this.worldColors).includes(key)) { + return this.worldColors[key] + } + let block = null as import('prismarine-block').Block | null let { height } = (bot.game as any) const airBlocks = new Set(['air', 'cave_air', 'void_air']) do { block = bot.world.getBlock(new Vec3(x, height, z)) height -= 1 } while (airBlocks.has(block?.name ?? '')) - return BlockData.colors[block?.name ?? ''] ?? 'white' - } + const color = BlockData.colors[block?.name ?? ''] ?? 'white' + this.worldColors[key] = color + return color + } + + getDistance (x1: number, z1: number, x2: number, z2: number): number { + return Math.hypot((x2 - x1), (z2 - z1)) + } + + clearCache (currX: number, currZ: number) { + for (const key of Object.keys(this.worldColors)) { + const [x, z] = key.split(',').map(Number) + if (this.getDistance(x, z, currX, currZ) > this.radius * 5) { + delete this.worldColors[`${x},${z}`] + } + } + } } From dfd1cb00283bc0028cb458be80f2dffbd5f6db97 Mon Sep 17 00:00:00 2001 From: gguio Date: Tue, 18 Jun 2024 13:33:23 +0400 Subject: [PATCH 010/285] build doesnt work right --- src/react/Minimap.tsx | 4 ++++ src/react/MinimapDrawer.ts | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 7f46c349d..291fdc4aa 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -7,7 +7,9 @@ export default () => { const drawerRef = useRef(null) function updateMap () { + console.log('test') if (drawerRef.current && canvasTick.current % 10 === 0) { + console.log(drawerRef.current.worldColors) drawerRef.current.draw(bot) if (canvasTick.current % 300 === 0) { drawerRef.current.clearCache(bot.entity.position.x, bot.entity.position.z) @@ -23,9 +25,11 @@ export default () => { }, [canvasRef.current]) useEffect(() => { + console.log('set update') bot.on('move', updateMap) return () => { + console.log('delete update') bot.off('move', updateMap) } }, []) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index a5f12a608..e96d177da 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -48,6 +48,7 @@ export class MinimapDrawer { if (bot) { this.updateWorldColors(bot) + console.log(this.worldColors) } else { this.ctx.strokeStyle = 'black' this.ctx.beginPath() @@ -93,7 +94,8 @@ export class MinimapDrawer { getHighestBlockColor (bot: BotType, x: number, z: number) { const key = `${x},${z}` - if (Object.keys(this.worldColors).includes(key)) { + if (this.worldColors[key]) { + console.log('using cashed value') return this.worldColors[key] } let block = null as import('prismarine-block').Block | null @@ -113,7 +115,7 @@ export class MinimapDrawer { } clearCache (currX: number, currZ: number) { - for (const key of Object.keys(this.worldColors)) { + for (const key in this.worldColors) { const [x, z] = key.split(',').map(Number) if (this.getDistance(x, z, currX, currZ) > this.radius * 5) { delete this.worldColors[`${x},${z}`] From f6194e462826348893cc282c79b6336f022bf322 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Tue, 18 Jun 2024 15:22:00 +0300 Subject: [PATCH 011/285] fix and cleanup code --- src/react/MinimapDrawer.ts | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index e96d177da..32c231df1 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -1,9 +1,9 @@ import { Vec3 } from 'vec3' import { Position } from 'source-map-js' -import { underive } from 'valtio/utils' +import { TypedEventEmitter } from 'contro-max/build/typedEventEmitter' +import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' import BlockData from '../../prismarine-viewer/viewer/lib/moreBlockDataGenerated.json' - type BotType = Omit & { world: Omit & { getBlock: (pos: import('vec3').Vec3) => import('prismarine-block').Block | null @@ -14,15 +14,26 @@ type BotType = Omit & { } } +interface DrawerAdapter extends TypedEventEmitter<{ + updateBlockColor: (pos: Position) => void + updatePlayerPosition: () => void + updateWarps: () => void +}> { + getHighestBlockColor: (x: number, z: number) => string + playerPosition: Position + warps: WorldWarp + setWarp: (name: string, pos: Position, rotation: Position, color: string, disabled: boolean) => void +} + export class MinimapDrawer { centerX: number centerY: number mapSize: number radius: number ctx: CanvasRenderingContext2D - worldColors: { [key: string]: string } + worldColors: { [key: string]: string } = {} - constructor ( + constructor( private readonly canvas: HTMLCanvasElement, centerX?: number, centerY?: number, @@ -48,7 +59,6 @@ export class MinimapDrawer { if (bot) { this.updateWorldColors(bot) - console.log(this.worldColors) } else { this.ctx.strokeStyle = 'black' this.ctx.beginPath() @@ -95,7 +105,6 @@ export class MinimapDrawer { getHighestBlockColor (bot: BotType, x: number, z: number) { const key = `${x},${z}` if (this.worldColors[key]) { - console.log('using cashed value') return this.worldColors[key] } let block = null as import('prismarine-block').Block | null From ce951fe6ddcb2d1dd273af96c4a44e411da671d0 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Tue, 18 Jun 2024 19:55:58 +0300 Subject: [PATCH 012/285] update squid, fix lint --- package.json | 2 +- pnpm-lock.yaml | 11 ++++++----- src/react/Minimap.tsx | 6 +++--- src/react/MinimapDrawer.ts | 9 +++++---- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 56e3cfdd3..3369e91c7 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "esbuild-plugin-polyfill-node": "^0.3.0", "express": "^4.18.2", "filesize": "^10.0.12", - "flying-squid": "npm:@zardoy/flying-squid@^0.0.29", + "flying-squid": "npm:@zardoy/flying-squid@^0.0.30", "fs-extra": "^11.1.1", "google-drive-browserfs": "github:zardoy/browserfs#google-drive", "iconify-icon": "^1.0.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3e1ab099a..fa8ba5e4a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -104,8 +104,8 @@ importers: specifier: ^10.0.12 version: 10.0.12 flying-squid: - specifier: npm:@zardoy/flying-squid@^0.0.29 - version: '@zardoy/flying-squid@0.0.29(encoding@0.1.13)' + specifier: npm:@zardoy/flying-squid@^0.0.30 + version: '@zardoy/flying-squid@0.0.30(encoding@0.1.13)' fs-extra: specifier: ^11.1.1 version: 11.1.1 @@ -3075,8 +3075,8 @@ packages: resolution: {integrity: sha512-6xm38yGVIa6mKm/DUCF2zFFJhERh/QWp1ufm4cNUvxsONBmfPg8uZ9pZBdOmF6qFGr/HlT6ABBkCSx/dlEtvWg==} engines: {node: '>=12 <14 || 14.2 - 14.9 || >14.10.0'} - '@zardoy/flying-squid@0.0.29': - resolution: {integrity: sha512-E5Nk1gMeH+fAHM5aJY8kIxjBS/zuPtPD6QPeZg+laPV5H58Jx3Et17clF1zC9MT2wyFQ5wi5uTnfdGBTpSEqHw==} + '@zardoy/flying-squid@0.0.30': + resolution: {integrity: sha512-jQ9GQUKR0nRmUxERLB1sOIkQRc1PdSxqHVPe+BB80ELx2P7R1sVcG8sGMQ2BBdH2vRYBg+HD3r1vKudqYSd1Ww==} engines: {node: '>=8'} hasBin: true @@ -11971,7 +11971,7 @@ snapshots: '@types/emscripten': 1.39.8 tslib: 1.14.1 - '@zardoy/flying-squid@0.0.29(encoding@0.1.13)': + '@zardoy/flying-squid@0.0.30(encoding@0.1.13)': dependencies: '@tootallnate/once': 2.0.0 change-case: 4.1.2 @@ -11997,6 +11997,7 @@ snapshots: random-seed: 0.3.0 range: 0.0.3 readline: 1.3.0 + sanitize-filename: 1.6.3 typed-emitter: 1.4.0 uuid-1345: 1.0.2 vec3: 0.1.8 diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 291fdc4aa..a017936c7 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -3,7 +3,7 @@ import { MinimapDrawer } from './MinimapDrawer' export default () => { const canvasTick = useRef(0) - const canvasRef = useRef(null) + const canvasRef = useRef(null) const drawerRef = useRef(null) function updateMap () { @@ -12,7 +12,7 @@ export default () => { console.log(drawerRef.current.worldColors) drawerRef.current.draw(bot) if (canvasTick.current % 300 === 0) { - drawerRef.current.clearCache(bot.entity.position.x, bot.entity.position.z) + drawerRef.current.deleteOldWorldColors(bot.entity.position.x, bot.entity.position.z) } } canvasTick.current += 1 @@ -35,7 +35,7 @@ export default () => { }, []) - return
string playerPosition: Position warps: WorldWarp - setWarp: (name: string, pos: Position, rotation: Position, color: string, disabled: boolean) => void + setWarp: (name: string, pos: Position, rotation: Position, dimension: string, color: string, disabled: boolean) => void } export class MinimapDrawer { @@ -33,7 +33,7 @@ export class MinimapDrawer { ctx: CanvasRenderingContext2D worldColors: { [key: string]: string } = {} - constructor( + constructor ( private readonly canvas: HTMLCanvasElement, centerX?: number, centerY?: number, @@ -123,10 +123,11 @@ export class MinimapDrawer { return Math.hypot((x2 - x1), (z2 - z1)) } - clearCache (currX: number, currZ: number) { - for (const key in this.worldColors) { + deleteOldWorldColors (currX: number, currZ: number) { + for (const key of Object.keys(this.worldColors)) { const [x, z] = key.split(',').map(Number) if (this.getDistance(x, z, currX, currZ) > this.radius * 5) { + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete this.worldColors[`${x},${z}`] } } From 326ef49c7e791b3f531d8c622f9428bd68a1ce2e Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 20 Jun 2024 17:48:36 +0400 Subject: [PATCH 013/285] fix cache --- src/react/Minimap.tsx | 2 +- src/react/MinimapDrawer.ts | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index a017936c7..610befa94 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -7,12 +7,12 @@ export default () => { const drawerRef = useRef(null) function updateMap () { - console.log('test') if (drawerRef.current && canvasTick.current % 10 === 0) { console.log(drawerRef.current.worldColors) drawerRef.current.draw(bot) if (canvasTick.current % 300 === 0) { drawerRef.current.deleteOldWorldColors(bot.entity.position.x, bot.entity.position.z) + console.log(drawerRef.current.worldColors) } } canvasTick.current += 1 diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 49f0241ae..bba5e107e 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -103,7 +103,9 @@ export class MinimapDrawer { } getHighestBlockColor (bot: BotType, x: number, z: number) { - const key = `${x},${z}` + const roundX = Math.floor(x) + const roundZ = Math.floor(z) + const key = `${roundX},${roundZ}` if (this.worldColors[key]) { return this.worldColors[key] } From 6ebe049ad1d85183a64aa69f42b199a69f11eff7 Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 20 Jun 2024 18:24:12 +0400 Subject: [PATCH 014/285] full map container --- src/react/Minimap.tsx | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 610befa94..67d133039 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,41 +1,52 @@ -import { useRef, useEffect } from 'react' +import { useRef, useEffect, useState } from 'react' import { MinimapDrawer } from './MinimapDrawer' export default () => { + const [fullMapOpened, setFullMapOpened] = useState(false) const canvasTick = useRef(0) const canvasRef = useRef(null) const drawerRef = useRef(null) function updateMap () { - if (drawerRef.current && canvasTick.current % 10 === 0) { - console.log(drawerRef.current.worldColors) + if (drawerRef.current && canvasTick.current % 2 === 0) { drawerRef.current.draw(bot) if (canvasTick.current % 300 === 0) { drawerRef.current.deleteOldWorldColors(bot.entity.position.x, bot.entity.position.z) - console.log(drawerRef.current.worldColors) } } canvasTick.current += 1 } + const openFullMap = () => { + setFullMapOpened(true) + } + useEffect(() => { - if (canvasRef.current) { + if (canvasRef.current && !drawerRef.current) { drawerRef.current = new MinimapDrawer(canvasRef.current) } }, [canvasRef.current]) useEffect(() => { - console.log('set update') bot.on('move', updateMap) return () => { - console.log('delete update') bot.off('move', updateMap) } }, []) + return fullMapOpened ?
+ - return
:
Date: Thu, 20 Jun 2024 19:16:56 +0400 Subject: [PATCH 015/285] fix for weired bug with undo button in Keybindings screen --- src/react/KeybindingsScreen.module.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/react/KeybindingsScreen.module.css b/src/react/KeybindingsScreen.module.css index e8a9f69b3..102974ce4 100644 --- a/src/react/KeybindingsScreen.module.css +++ b/src/react/KeybindingsScreen.module.css @@ -49,6 +49,7 @@ .undo-keyboard, .undo-gamepad { aspect-ratio: 1; + min-width: 20px; } .button { From 3b91a17f90c87926c231d609148e8909704ac58e Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 21 Jun 2024 12:09:52 +0400 Subject: [PATCH 016/285] toggle command --- src/controls.ts | 17 +++++++++-------- src/react/Minimap.tsx | 10 ++++++++-- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/controls.ts b/src/controls.ts index a3a220295..0469a0b01 100644 --- a/src/controls.ts +++ b/src/controls.ts @@ -51,6 +51,7 @@ export const contro = new ControMax({ }, ui: { back: [null/* 'Escape' */, 'B'], + toggleMap: ['KeyM'], leftClick: [null, 'A'], rightClick: [null, 'Y'], speedupCursor: [null, 'Left Stick'], @@ -75,12 +76,12 @@ export const contro = new ControMax({ }, { defaultControlOptions: controlOptions, target: document, - captureEvents () { + captureEvents() { return true }, storeProvider: { load: () => customKeymaps, - save () { }, + save() { }, }, gamepadPollingInterval: 10 }) @@ -153,10 +154,10 @@ let lastCommandTrigger = null as { command: string, time: number } | null const secondActionActivationTimeout = 300 const secondActionCommands = { - 'general.jump' () { + 'general.jump'() { toggleFly() }, - 'general.forward' () { + 'general.forward'() { setSprinting(true) } } @@ -292,7 +293,7 @@ const alwaysPressedHandledCommand = (command: Command) => { } } -function cycleHotbarSlot (dir: 1 | -1) { +function cycleHotbarSlot(dir: 1 | -1) { const newHotbarSlot = (bot.quickBarSlot + dir + 9) % 9 bot.setQuickBarSlot(newHotbarSlot) } @@ -418,7 +419,7 @@ contro.on('release', ({ command }) => { export const f3Keybinds = [ { key: 'KeyA', - action () { + action() { //@ts-expect-error const loadedChunks = Object.entries(worldView.loadedChunks).filter(([, v]) => v).map(([key]) => key.split(',').map(Number)) for (const [x, z] of loadedChunks) { @@ -440,7 +441,7 @@ export const f3Keybinds = [ }, { key: 'KeyG', - action () { + action() { options.showChunkBorders = !options.showChunkBorders viewer.world.updateShowChunksBorder(options.showChunkBorders) }, @@ -448,7 +449,7 @@ export const f3Keybinds = [ }, { key: 'KeyT', - async action () { + async action() { // waypoints const widgetNames = widgets.map(widget => widget.name) const widget = await showOptionsModal('Open Widget', widgetNames) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 67d133039..c1740a601 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,5 +1,6 @@ import { useRef, useEffect, useState } from 'react' import { MinimapDrawer } from './MinimapDrawer' +import { contro } from '../controls' export default () => { const [fullMapOpened, setFullMapOpened] = useState(false) @@ -17,10 +18,11 @@ export default () => { canvasTick.current += 1 } - const openFullMap = () => { - setFullMapOpened(true) + const toggleFullMap = ({ command }) => { + if (command === 'ui.toggleMap') setFullMapOpened(prev => !prev) } + useEffect(() => { if (canvasRef.current && !drawerRef.current) { drawerRef.current = new MinimapDrawer(canvasRef.current) @@ -30,8 +32,11 @@ export default () => { useEffect(() => { bot.on('move', updateMap) + contro.on('trigger', toggleFullMap) + return () => { bot.off('move', updateMap) + contro.off('', toggleFullMap) } }, []) @@ -41,6 +46,7 @@ export default () => { inset: '0px', display: 'flex', justifyContent: 'center', + alignItems: 'center', border: '2px solid red' }} > From 33302c06aa9a8a1ec11c254435f6c3ccca457f42 Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 21 Jun 2024 13:48:27 +0400 Subject: [PATCH 017/285] toggle full map --- src/controls.ts | 16 ++++++++-------- src/react/Minimap.tsx | 22 +++++++++++++++++----- src/react/MinimapDrawer.ts | 22 +++++++++++++++------- 3 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/controls.ts b/src/controls.ts index 0469a0b01..8df3f2093 100644 --- a/src/controls.ts +++ b/src/controls.ts @@ -76,12 +76,12 @@ export const contro = new ControMax({ }, { defaultControlOptions: controlOptions, target: document, - captureEvents() { + captureEvents () { return true }, storeProvider: { load: () => customKeymaps, - save() { }, + save () { }, }, gamepadPollingInterval: 10 }) @@ -154,10 +154,10 @@ let lastCommandTrigger = null as { command: string, time: number } | null const secondActionActivationTimeout = 300 const secondActionCommands = { - 'general.jump'() { + 'general.jump' () { toggleFly() }, - 'general.forward'() { + 'general.forward' () { setSprinting(true) } } @@ -293,7 +293,7 @@ const alwaysPressedHandledCommand = (command: Command) => { } } -function cycleHotbarSlot(dir: 1 | -1) { +function cycleHotbarSlot (dir: 1 | -1) { const newHotbarSlot = (bot.quickBarSlot + dir + 9) % 9 bot.setQuickBarSlot(newHotbarSlot) } @@ -419,7 +419,7 @@ contro.on('release', ({ command }) => { export const f3Keybinds = [ { key: 'KeyA', - action() { + action () { //@ts-expect-error const loadedChunks = Object.entries(worldView.loadedChunks).filter(([, v]) => v).map(([key]) => key.split(',').map(Number)) for (const [x, z] of loadedChunks) { @@ -441,7 +441,7 @@ export const f3Keybinds = [ }, { key: 'KeyG', - action() { + action () { options.showChunkBorders = !options.showChunkBorders viewer.world.updateShowChunksBorder(options.showChunkBorders) }, @@ -449,7 +449,7 @@ export const f3Keybinds = [ }, { key: 'KeyT', - async action() { + async action () { // waypoints const widgetNames = widgets.map(widget => widget.name) const widget = await showOptionsModal('Open Widget', widgetNames) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index c1740a601..39577ffc9 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,6 +1,6 @@ import { useRef, useEffect, useState } from 'react' -import { MinimapDrawer } from './MinimapDrawer' import { contro } from '../controls' +import { MinimapDrawer } from './MinimapDrawer' export default () => { const [fullMapOpened, setFullMapOpened] = useState(false) @@ -25,9 +25,13 @@ export default () => { useEffect(() => { if (canvasRef.current && !drawerRef.current) { + console.log('creating canvas') drawerRef.current = new MinimapDrawer(canvasRef.current) + } else if (canvasRef.current && drawerRef.current) { + console.log('updating canvas') + drawerRef.current.canvas = canvasRef.current } - }, [canvasRef.current]) + }, [canvasRef.current, fullMapOpened]) useEffect(() => { bot.on('move', updateMap) @@ -36,7 +40,7 @@ export default () => { return () => { bot.off('move', updateMap) - contro.off('', toggleFullMap) + contro.off('trigger', toggleFullMap) } }, []) @@ -47,10 +51,18 @@ export default () => { display: 'flex', justifyContent: 'center', alignItems: 'center', - border: '2px solid red' + border: '2px solid red', + backgroundColor: 'rgba(0, 0, 0, 0.4)' }} > - +
:
Date: Fri, 21 Jun 2024 13:49:41 +0400 Subject: [PATCH 018/285] small clean up --- src/react/Minimap.tsx | 2 -- src/react/MinimapDrawer.ts | 3 --- 2 files changed, 5 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 39577ffc9..9a22d3ef1 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -25,10 +25,8 @@ export default () => { useEffect(() => { if (canvasRef.current && !drawerRef.current) { - console.log('creating canvas') drawerRef.current = new MinimapDrawer(canvasRef.current) } else if (canvasRef.current && drawerRef.current) { - console.log('updating canvas') drawerRef.current.canvas = canvasRef.current } }, [canvasRef.current, fullMapOpened]) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 924a38105..7b2ba2967 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -36,9 +36,6 @@ export class MinimapDrawer { constructor ( canvas: HTMLCanvasElement, - centerX?: number, - centerY?: number, - mapSize?: number ) { this.canvas = canvas } From 7901a3a041cb7499ae0a047ccb8e0eb72f957707 Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 21 Jun 2024 15:10:36 +0400 Subject: [PATCH 019/285] adapter implementation --- src/react/Minimap.stories.tsx | 34 ++++++++-------- src/react/Minimap.tsx | 27 +++++++----- src/react/MinimapDrawer.ts | 77 +++++++++++++++++++---------------- src/react/MinimapProvider.tsx | 72 +++++++++++++++++++++++++++++++- 4 files changed, 144 insertions(+), 66 deletions(-) diff --git a/src/react/Minimap.stories.tsx b/src/react/Minimap.stories.tsx index 25ea6507a..8fd94c1c0 100644 --- a/src/react/Minimap.stories.tsx +++ b/src/react/Minimap.stories.tsx @@ -7,21 +7,21 @@ const meta: Meta = { } export default meta -type Story = StoryObj; +// type Story = StoryObj; -const worldColors: string[][] = [] - -const mapSize = 10 -for (let i = 0; i < mapSize; i += 1) { - worldColors[i] = [] as string[] - for (let j = 0; j < mapSize; j += 1) { - const randColor = Math.floor(Math.random() * 255) - worldColors[i][j] = `rgb(${randColor}, ${randColor}, ${randColor})` - } -} - -export const Primary: Story = { - args: { - worldColors - }, -} +// const worldColors: string[][] = [] +// +// const mapSize = 10 +// for (let i = 0; i < mapSize; i += 1) { +// worldColors[i] = [] as string[] +// for (let j = 0; j < mapSize; j += 1) { +// const randColor = Math.floor(Math.random() * 255) +// worldColors[i][j] = `rgb(${randColor}, ${randColor}, ${randColor})` +// } +// } +// +// export const Primary: Story = { +// args: { +// worldColors +// }, +// } diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 9a22d3ef1..361b65697 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,25 +1,27 @@ import { useRef, useEffect, useState } from 'react' import { contro } from '../controls' import { MinimapDrawer } from './MinimapDrawer' +import { DrawerAdapter } from './MinimapDrawer' -export default () => { +export default ({ adapter }: { adapter: DrawerAdapter | null }) => { const [fullMapOpened, setFullMapOpened] = useState(false) const canvasTick = useRef(0) const canvasRef = useRef(null) const drawerRef = useRef(null) function updateMap () { + if (!adapter) return if (drawerRef.current && canvasTick.current % 2 === 0) { - drawerRef.current.draw(bot) + drawerRef.current.draw(adapter.getHighestBlockColor, adapter.playerPosition.x, adapter.playerPosition.z) if (canvasTick.current % 300 === 0) { - drawerRef.current.deleteOldWorldColors(bot.entity.position.x, bot.entity.position.z) + drawerRef.current.deleteOldWorldColors(adapter.playerPosition.x, adapter.playerPosition.z) } } canvasTick.current += 1 } - const toggleFullMap = ({ command }) => { - if (command === 'ui.toggleMap') setFullMapOpened(prev => !prev) + const toggleFullMap = () => { + setFullMapOpened(prev => !prev) } @@ -32,15 +34,18 @@ export default () => { }, [canvasRef.current, fullMapOpened]) useEffect(() => { - bot.on('move', updateMap) - - contro.on('trigger', toggleFullMap) + if (adapter) { + adapter.on('updateMap', updateMap) + adapter.on('toggleFullMap', toggleFullMap) + } return () => { - bot.off('move', updateMap) - contro.off('trigger', toggleFullMap) + if (adapter) { + adapter.off('updateMap', updateMap) + adapter.off('toggleFullMap', toggleFullMap) + } } - }, []) + }, [adapter]) return fullMapOpened ?
& { } } -interface DrawerAdapter extends TypedEventEmitter<{ - updateBlockColor: (pos: Position) => void +export interface DrawerAdapter extends TypedEventEmitter<{ + updateBlockColor: (pos: Vec3) => void updatePlayerPosition: () => void updateWarps: () => void }> { getHighestBlockColor: (x: number, z: number) => string - playerPosition: Position - warps: WorldWarp - setWarp: (name: string, pos: Position, rotation: Position, dimension: string, color: string, disabled: boolean) => void + playerPosition: Vec3 + warps: WorldWarp[] + setWarp: (name: string, pos: Vec3, dimension: string, color: string, disabled: boolean) => void } export class MinimapDrawer { @@ -54,7 +54,11 @@ export class MinimapDrawer { this._canvas = canvas } - draw (bot: BotType | undefined) { + draw ( + getHighestBlockColor: DrawerAdapter['getHighestBlockColor'], + x: number, + z: number + ) { this.ctx.clearRect( this.centerX - this.radius, this.centerY - this.radius, @@ -62,24 +66,28 @@ export class MinimapDrawer { this.radius * 2 ) - if (bot) { - this.updateWorldColors(bot) - } else { - this.ctx.strokeStyle = 'black' - this.ctx.beginPath() - - this.ctx.arc(this.centerX, this.centerY, this.radius, 0, 2 * Math.PI, false) - - this.ctx.fillStyle = 'white' - this.ctx.fill() - - this.ctx.strokeStyle = '#000000' - this.ctx.lineWidth = 1 - this.ctx.stroke() - } + // if (bot) { + this.updateWorldColors(getHighestBlockColor, x, z) + // } else { + // this.ctx.strokeStyle = 'black' + // this.ctx.beginPath() + // + // this.ctx.arc(this.centerX, this.centerY, this.radius, 0, 2 * Math.PI, false) + // + // this.ctx.fillStyle = 'white' + // this.ctx.fill() + // + // this.ctx.strokeStyle = '#000000' + // this.ctx.lineWidth = 1 + // this.ctx.stroke() + // } } - updateWorldColors (bot: BotType) { + updateWorldColors ( + getHighestBlockColor: DrawerAdapter['getHighestBlockColor'], + x: number, + z: number + ) { const left = this.centerX - this.radius const top = this.centerY - this.radius const mapPixel = Math.floor(this.radius * 2 / this.mapSize) @@ -92,10 +100,10 @@ export class MinimapDrawer { for (let row = 0; row < this.mapSize; row += 1) { for (let col = 0; col < this.mapSize; col += 1) { - this.ctx.fillStyle = this.getHighestBlockColor( - bot, - bot.entity.position.x - this.mapSize / 2 + row, - bot.entity.position.z - this.mapSize / 2 + col + this.ctx.fillStyle = this.getHighestBlockColorCached( + getHighestBlockColor, + x - this.mapSize / 2 + row, + z - this.mapSize / 2 + col ) this.ctx.fillRect( left + mapPixel * col, @@ -107,22 +115,19 @@ export class MinimapDrawer { } } - getHighestBlockColor (bot: BotType, x: number, z: number) { + getHighestBlockColorCached ( + getHighestBlockColor: DrawerAdapter['getHighestBlockColor'], + x: number, + z: number + ) { const roundX = Math.floor(x) const roundZ = Math.floor(z) const key = `${roundX},${roundZ}` if (this.worldColors[key]) { return this.worldColors[key] } - let block = null as import('prismarine-block').Block | null - let { height } = (bot.game as any) - const airBlocks = new Set(['air', 'cave_air', 'void_air']) - do { - block = bot.world.getBlock(new Vec3(x, height, z)) - height -= 1 - } while (airBlocks.has(block?.name ?? '')) - const color = BlockData.colors[block?.name ?? ''] ?? 'white' - this.worldColors[key] = color + const color = getHighestBlockColor(x, z) + if (color !== 'white') this.worldColors[key] = color return color } diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index d189337ac..1a306070e 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -1,12 +1,80 @@ -import { useEffect, useState } from 'react' +import { useEffect, useRef } from 'react' import { Vec3 } from 'vec3' import BlockData from '../../prismarine-viewer/viewer/lib/moreBlockDataGenerated.json' import Minimap from './Minimap' +import { DrawerAdapter } from './MinimapDrawer' +import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' +import { TypedEventEmitter } from 'contro-max/build/typedEventEmitter' +import { contro } from '../controls' +class DrawerAdapterImpl extends TypedEventEmitter<{ + updateBlockColor: (pos: Vec3) => void + updatePlayerPosition: () => void + updateWarps: () => void +}> implements DrawerAdapter { + playerPosition: Vec3 + warps: WorldWarp[] + + constructor(pos?: Vec3, warps?: WorldWarp[]) { + super() + this.playerPosition = pos ?? new Vec3(0, 0, 0) + this.warps = warps ?? [] as WorldWarp[] + } + + getHighestBlockColor (x: number, z:number) { + let block = null as import('prismarine-block').Block | null + let { height } = (bot.game as any) + const airBlocks = new Set(['air', 'cave_air', 'void_air']) + do { + block = bot.world.getBlock(new Vec3(x, height, z)) + height -= 1 + } while (airBlocks.has(block?.name ?? '')) + const color = BlockData.colors[block?.name ?? ''] ?? 'white' + return color + } + + setWarp(name: string, pos: Vec3, world: string, color: string, disabled: boolean): void { + const warp: WorldWarp = { name, x: pos.x, y: pos.y, z: pos.z, world, color, disabled } + const index = this.warps.findIndex(w => w.name === name) + if (index !== -1) { + this.warps[index] = warp + } else { + this.warps.push(warp) + } + this.emit('updateWarps') + } +} export default () => { + const adapter = useRef(null) + + const updateMap = () => { + if (!adapter.current) return + adapter.current.playerPosition = bot.entity.position + adapter.current.emit('updateMap') + } + + const toggleFullMap = ({ command }) => { + if (!adapter.current) return + if (command === 'ui.toggleMap') adapter.current.emit('toggleFullMap') + } + + useEffect(() => { + adapter.current = new DrawerAdapterImpl(bot.entity.position) + }, []) + + useEffect(() => { + bot.on('move', updateMap) + + contro.on('trigger', toggleFullMap) + + return () => { + bot.off('move', updateMap) + contro.off('trigger', toggleFullMap) + } + }, []) return
- +
} From fb84af6105ffdb9c809eb7f7649aa2f3acc5cc9c Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 21 Jun 2024 15:17:54 +0400 Subject: [PATCH 020/285] clean up --- src/react/Minimap.tsx | 4 ++-- src/react/MinimapDrawer.ts | 16 +--------------- src/react/MinimapProvider.tsx | 16 ++++++++-------- 3 files changed, 11 insertions(+), 25 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 361b65697..29b29d9ca 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,7 +1,7 @@ import { useRef, useEffect, useState } from 'react' import { contro } from '../controls' -import { MinimapDrawer } from './MinimapDrawer' -import { DrawerAdapter } from './MinimapDrawer' +import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' + export default ({ adapter }: { adapter: DrawerAdapter | null }) => { const [fullMapOpened, setFullMapOpened] = useState(false) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 68149a41c..f2088fc7c 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -66,21 +66,7 @@ export class MinimapDrawer { this.radius * 2 ) - // if (bot) { - this.updateWorldColors(getHighestBlockColor, x, z) - // } else { - // this.ctx.strokeStyle = 'black' - // this.ctx.beginPath() - // - // this.ctx.arc(this.centerX, this.centerY, this.radius, 0, 2 * Math.PI, false) - // - // this.ctx.fillStyle = 'white' - // this.ctx.fill() - // - // this.ctx.strokeStyle = '#000000' - // this.ctx.lineWidth = 1 - // this.ctx.stroke() - // } + this.updateWorldColors(getHighestBlockColor, x, z) } updateWorldColors ( diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 1a306070e..4656c0f6f 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -1,11 +1,11 @@ import { useEffect, useRef } from 'react' import { Vec3 } from 'vec3' -import BlockData from '../../prismarine-viewer/viewer/lib/moreBlockDataGenerated.json' -import Minimap from './Minimap' -import { DrawerAdapter } from './MinimapDrawer' import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' import { TypedEventEmitter } from 'contro-max/build/typedEventEmitter' +import BlockData from '../../prismarine-viewer/viewer/lib/moreBlockDataGenerated.json' import { contro } from '../controls' +import Minimap from './Minimap' +import { DrawerAdapter } from './MinimapDrawer' class DrawerAdapterImpl extends TypedEventEmitter<{ updateBlockColor: (pos: Vec3) => void @@ -15,7 +15,7 @@ class DrawerAdapterImpl extends TypedEventEmitter<{ playerPosition: Vec3 warps: WorldWarp[] - constructor(pos?: Vec3, warps?: WorldWarp[]) { + constructor (pos?: Vec3, warps?: WorldWarp[]) { super() this.playerPosition = pos ?? new Vec3(0, 0, 0) this.warps = warps ?? [] as WorldWarp[] @@ -33,13 +33,13 @@ class DrawerAdapterImpl extends TypedEventEmitter<{ return color } - setWarp(name: string, pos: Vec3, world: string, color: string, disabled: boolean): void { + setWarp (name: string, pos: Vec3, world: string, color: string, disabled: boolean): void { const warp: WorldWarp = { name, x: pos.x, y: pos.y, z: pos.z, world, color, disabled } const index = this.warps.findIndex(w => w.name === name) - if (index !== -1) { - this.warps[index] = warp - } else { + if (index === -1) { this.warps.push(warp) + } else { + this.warps[index] = warp } this.emit('updateWarps') } From 0dfff262f477623b6fc091d23d4dda2e57fb6d4c Mon Sep 17 00:00:00 2001 From: gguio Date: Sat, 22 Jun 2024 17:00:55 +0400 Subject: [PATCH 021/285] useState used for adapter --- src/react/MinimapDrawer.ts | 8 ++++---- src/react/MinimapProvider.tsx | 28 ++++++++++------------------ 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index f2088fc7c..d9094ae7f 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -1,8 +1,6 @@ import { Vec3 } from 'vec3' -import { Position } from 'source-map-js' import { TypedEventEmitter } from 'contro-max/build/typedEventEmitter' import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' -import BlockData from '../../prismarine-viewer/viewer/lib/moreBlockDataGenerated.json' type BotType = Omit & { world: Omit & { @@ -14,11 +12,13 @@ type BotType = Omit & { } } -export interface DrawerAdapter extends TypedEventEmitter<{ +export type MapUpdates = { updateBlockColor: (pos: Vec3) => void updatePlayerPosition: () => void updateWarps: () => void -}> { +} + +export interface DrawerAdapter extends TypedEventEmitter { getHighestBlockColor: (x: number, z: number) => string playerPosition: Vec3 warps: WorldWarp[] diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 4656c0f6f..7eab51eb1 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -1,17 +1,13 @@ -import { useEffect, useRef } from 'react' +import { useEffect, useRef, useState } from 'react' import { Vec3 } from 'vec3' import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' import { TypedEventEmitter } from 'contro-max/build/typedEventEmitter' import BlockData from '../../prismarine-viewer/viewer/lib/moreBlockDataGenerated.json' import { contro } from '../controls' import Minimap from './Minimap' -import { DrawerAdapter } from './MinimapDrawer' +import { DrawerAdapter, MapUpdates } from './MinimapDrawer' -class DrawerAdapterImpl extends TypedEventEmitter<{ - updateBlockColor: (pos: Vec3) => void - updatePlayerPosition: () => void - updateWarps: () => void -}> implements DrawerAdapter { +class DrawerAdapterImpl extends TypedEventEmitter implements DrawerAdapter { playerPosition: Vec3 warps: WorldWarp[] @@ -46,23 +42,19 @@ class DrawerAdapterImpl extends TypedEventEmitter<{ } export default () => { - const adapter = useRef(null) + const [adapter] = useState(() => new DrawerAdapterImpl(bot.entity.position)) const updateMap = () => { - if (!adapter.current) return - adapter.current.playerPosition = bot.entity.position - adapter.current.emit('updateMap') + if (!adapter) return + adapter.playerPosition = bot.entity.position + adapter.emit('updateMap') } const toggleFullMap = ({ command }) => { - if (!adapter.current) return - if (command === 'ui.toggleMap') adapter.current.emit('toggleFullMap') + if (!adapter) return + if (command === 'ui.toggleMap') adapter.emit('toggleFullMap') } - useEffect(() => { - adapter.current = new DrawerAdapterImpl(bot.entity.position) - }, []) - useEffect(() => { bot.on('move', updateMap) @@ -75,6 +67,6 @@ export default () => { }, []) return
- +
} From 03d8e3100fe9501f2bde4fad2fadc2edbb9f0e95 Mon Sep 17 00:00:00 2001 From: gguio Date: Sat, 22 Jun 2024 17:46:39 +0400 Subject: [PATCH 022/285] pointer lock --- src/react/Minimap.tsx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 29b29d9ca..353807081 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,10 +1,11 @@ -import { useRef, useEffect, useState } from 'react' -import { contro } from '../controls' +import { useRef, useEffect } from 'react' +import { showModal, hideModal } from '../globalState' +import { useIsModalActive } from './utilsApp' import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' export default ({ adapter }: { adapter: DrawerAdapter | null }) => { - const [fullMapOpened, setFullMapOpened] = useState(false) + const fullMapOpened = useIsModalActive('full-map') const canvasTick = useRef(0) const canvasRef = useRef(null) const drawerRef = useRef(null) @@ -21,7 +22,11 @@ export default ({ adapter }: { adapter: DrawerAdapter | null }) => { } const toggleFullMap = () => { - setFullMapOpened(prev => !prev) + if (fullMapOpened) { + hideModal({ reactType: 'full-map' }) + } else { + showModal({ reactType: 'full-map' }) + } } From 4ef31616c2ab458d309e98b9cab1e832b5ccd748 Mon Sep 17 00:00:00 2001 From: gguio Date: Tue, 25 Jun 2024 15:52:30 +0400 Subject: [PATCH 023/285] mouse click in world coords doesnt count correctly --- src/react/Minimap.tsx | 21 +++++++++++++++++++++ src/react/MinimapDrawer.ts | 7 +++++++ src/react/MinimapProvider.tsx | 2 +- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 353807081..9a60364e1 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -29,6 +29,14 @@ export default ({ adapter }: { adapter: DrawerAdapter | null }) => { } } + const setWarp = (e: MouseEvent) => { + if (!e.target) return + const rect = (e.target as HTMLCanvasElement).getBoundingClientRect() + const x = e.pageX - rect.left + const y = e.pageY - rect.top + const coords = drawerRef.current?.mouseToWorldPos(x, y, bot.entity.position) + console.log('coords:', x, y, '| In game coords:', coords) + } useEffect(() => { if (canvasRef.current && !drawerRef.current) { @@ -38,6 +46,19 @@ export default ({ adapter }: { adapter: DrawerAdapter | null }) => { } }, [canvasRef.current, fullMapOpened]) + useEffect(() => { + console.log('full map toggled') + if (fullMapOpened && canvasRef.current) { + console.log('in if') + canvasRef.current.addEventListener('click', setWarp) + } + + return () => { + console.log('memory clear') + canvasRef.current?.removeEventListener('click', setWarp) + } + }, [fullMapOpened]) + useEffect(() => { if (adapter) { adapter.on('updateMap', updateMap) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index d9094ae7f..bc9a79a78 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -130,4 +130,11 @@ export class MinimapDrawer { } } } + + mouseToWorldPos(x: number, z: number, botPos: Vec3) { + const worldX = x - this.radius + const worldZ = z - this.radius + + return [botPos.x - worldX, botPos.z - worldZ] + } } diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 7eab51eb1..14afc6575 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -1,4 +1,4 @@ -import { useEffect, useRef, useState } from 'react' +import { useEffect, useState } from 'react' import { Vec3 } from 'vec3' import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' import { TypedEventEmitter } from 'contro-max/build/typedEventEmitter' From e8864447d239d9c1cbbfe76975d8cc37d5d49ed5 Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 26 Jun 2024 12:46:17 +0400 Subject: [PATCH 024/285] click to map pos fix --- src/react/Minimap.tsx | 4 ++-- src/react/MinimapDrawer.ts | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 9a60364e1..4c11aa272 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -32,8 +32,8 @@ export default ({ adapter }: { adapter: DrawerAdapter | null }) => { const setWarp = (e: MouseEvent) => { if (!e.target) return const rect = (e.target as HTMLCanvasElement).getBoundingClientRect() - const x = e.pageX - rect.left - const y = e.pageY - rect.top + const x = (e.pageX - rect.left) * canvasRef.current!.width / rect.width + const y = (e.pageY - rect.top) * canvasRef.current!.height / rect.height const coords = drawerRef.current?.mouseToWorldPos(x, y, bot.entity.position) console.log('coords:', x, y, '| In game coords:', coords) } diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index bc9a79a78..5d583a6fe 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -131,10 +131,10 @@ export class MinimapDrawer { } } - mouseToWorldPos(x: number, z: number, botPos: Vec3) { - const worldX = x - this.radius - const worldZ = z - this.radius + mouseToWorldPos (x: number, z: number, botPos: Vec3) { + const worldX = x - this.mapSize / 2 + const worldZ = z - this.mapSize / 2 - return [botPos.x - worldX, botPos.z - worldZ] + return [(botPos.x + worldX).toFixed(1), (botPos.z + worldZ).toFixed(1)] } } From a6880be14cc58480633c3da78ece72b50b23750d Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 26 Jun 2024 13:18:14 +0400 Subject: [PATCH 025/285] x and y should be otherwise --- src/react/Minimap.tsx | 11 ++++------- src/react/MinimapDrawer.ts | 27 ++++++++++++++++++++------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 4c11aa272..df1831e41 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -4,7 +4,7 @@ import { useIsModalActive } from './utilsApp' import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' -export default ({ adapter }: { adapter: DrawerAdapter | null }) => { +export default ({ adapter }: { adapter: DrawerAdapter }) => { const fullMapOpened = useIsModalActive('full-map') const canvasTick = useRef(0) const canvasRef = useRef(null) @@ -13,7 +13,7 @@ export default ({ adapter }: { adapter: DrawerAdapter | null }) => { function updateMap () { if (!adapter) return if (drawerRef.current && canvasTick.current % 2 === 0) { - drawerRef.current.draw(adapter.getHighestBlockColor, adapter.playerPosition.x, adapter.playerPosition.z) + drawerRef.current.draw(bot.entity.position) if (canvasTick.current % 300 === 0) { drawerRef.current.deleteOldWorldColors(adapter.playerPosition.x, adapter.playerPosition.z) } @@ -34,27 +34,24 @@ export default ({ adapter }: { adapter: DrawerAdapter | null }) => { const rect = (e.target as HTMLCanvasElement).getBoundingClientRect() const x = (e.pageX - rect.left) * canvasRef.current!.width / rect.width const y = (e.pageY - rect.top) * canvasRef.current!.height / rect.height - const coords = drawerRef.current?.mouseToWorldPos(x, y, bot.entity.position) + const coords = drawerRef.current?.mouseToWorldPos(y, x, bot.entity.position) console.log('coords:', x, y, '| In game coords:', coords) } useEffect(() => { if (canvasRef.current && !drawerRef.current) { - drawerRef.current = new MinimapDrawer(canvasRef.current) + drawerRef.current = new MinimapDrawer(canvasRef.current, adapter.getHighestBlockColor) } else if (canvasRef.current && drawerRef.current) { drawerRef.current.canvas = canvasRef.current } }, [canvasRef.current, fullMapOpened]) useEffect(() => { - console.log('full map toggled') if (fullMapOpened && canvasRef.current) { - console.log('in if') canvasRef.current.addEventListener('click', setWarp) } return () => { - console.log('memory clear') canvasRef.current?.removeEventListener('click', setWarp) } }, [fullMapOpened]) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 5d583a6fe..87e56962e 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -28,16 +28,20 @@ export interface DrawerAdapter extends TypedEventEmitter { export class MinimapDrawer { centerX: number centerY: number - mapSize: number + _mapSize: number radius: number ctx: CanvasRenderingContext2D _canvas: HTMLCanvasElement worldColors: { [key: string]: string } = {} + getHighestBlockColor: DrawerAdapter['getHighestBlockColor'] + lastBotPos: Vec3 constructor ( canvas: HTMLCanvasElement, + getHighestBlockColor: DrawerAdapter['getHighestBlockColor'] ) { this.canvas = canvas + this.getHighestBlockColor = getHighestBlockColor } get canvas () { @@ -48,16 +52,24 @@ export class MinimapDrawer { this.ctx = canvas.getContext('2d')! this.ctx.imageSmoothingEnabled = false this.radius = Math.min(canvas.width, canvas.height) / 2 - this.mapSize = this.radius * 2 + this._mapSize = this.radius * 2 this.centerX = canvas.width / 2 this.centerY = canvas.height / 2 this._canvas = canvas } + get mapSize() { + return this._mapSize + } + + set mapSize(mapSize: number) { + this._mapSize = mapSize + this.draw(this.lastBotPos) + } + draw ( - getHighestBlockColor: DrawerAdapter['getHighestBlockColor'], - x: number, - z: number + botPos: Vec3, + getHighestBlockColor?: DrawerAdapter['getHighestBlockColor'], ) { this.ctx.clearRect( this.centerX - this.radius, @@ -66,7 +78,8 @@ export class MinimapDrawer { this.radius * 2 ) - this.updateWorldColors(getHighestBlockColor, x, z) + this.lastBotPos = botPos + this.updateWorldColors(getHighestBlockColor ?? this.getHighestBlockColor, botPos.x, botPos.z) } updateWorldColors ( @@ -135,6 +148,6 @@ export class MinimapDrawer { const worldX = x - this.mapSize / 2 const worldZ = z - this.mapSize / 2 - return [(botPos.x + worldX).toFixed(1), (botPos.z + worldZ).toFixed(1)] + return [(botPos.x + worldX).toFixed(0), (botPos.z + worldZ).toFixed(0)] } } From 3c63c0b24006bc40a86e64efffe5e88d52d626c6 Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 26 Jun 2024 13:39:54 +0400 Subject: [PATCH 026/285] add new warp logic in MinimapDrawer --- src/react/Minimap.tsx | 27 +++++++++------------------ src/react/MinimapDrawer.ts | 19 +++++++++++-------- 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index df1831e41..9e0c8c273 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -29,18 +29,13 @@ export default ({ adapter }: { adapter: DrawerAdapter }) => { } } - const setWarp = (e: MouseEvent) => { - if (!e.target) return - const rect = (e.target as HTMLCanvasElement).getBoundingClientRect() - const x = (e.pageX - rect.left) * canvasRef.current!.width / rect.width - const y = (e.pageY - rect.top) * canvasRef.current!.height / rect.height - const coords = drawerRef.current?.mouseToWorldPos(y, x, bot.entity.position) - console.log('coords:', x, y, '| In game coords:', coords) + const handleClickOnMap = (e: MouseEvent) => { + drawerRef.current?.addWarpOnClick(e, bot.entity.position) } useEffect(() => { if (canvasRef.current && !drawerRef.current) { - drawerRef.current = new MinimapDrawer(canvasRef.current, adapter.getHighestBlockColor) + drawerRef.current = new MinimapDrawer(canvasRef.current, adapter) } else if (canvasRef.current && drawerRef.current) { drawerRef.current.canvas = canvasRef.current } @@ -48,25 +43,21 @@ export default ({ adapter }: { adapter: DrawerAdapter }) => { useEffect(() => { if (fullMapOpened && canvasRef.current) { - canvasRef.current.addEventListener('click', setWarp) + canvasRef.current.addEventListener('click', handleClickOnMap) } return () => { - canvasRef.current?.removeEventListener('click', setWarp) + canvasRef.current?.removeEventListener('click', handleClickOnMap) } }, [fullMapOpened]) useEffect(() => { - if (adapter) { - adapter.on('updateMap', updateMap) - adapter.on('toggleFullMap', toggleFullMap) - } + adapter.on('updateMap', updateMap) + adapter.on('toggleFullMap', toggleFullMap) return () => { - if (adapter) { - adapter.off('updateMap', updateMap) - adapter.off('toggleFullMap', toggleFullMap) - } + adapter.off('updateMap', updateMap) + adapter.off('toggleFullMap', toggleFullMap) } }, [adapter]) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 87e56962e..a24c21741 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -33,15 +33,14 @@ export class MinimapDrawer { ctx: CanvasRenderingContext2D _canvas: HTMLCanvasElement worldColors: { [key: string]: string } = {} - getHighestBlockColor: DrawerAdapter['getHighestBlockColor'] lastBotPos: Vec3 constructor ( canvas: HTMLCanvasElement, - getHighestBlockColor: DrawerAdapter['getHighestBlockColor'] + public adapter: DrawerAdapter ) { this.canvas = canvas - this.getHighestBlockColor = getHighestBlockColor + this.adapter = adapter } get canvas () { @@ -58,11 +57,11 @@ export class MinimapDrawer { this._canvas = canvas } - get mapSize() { + get mapSize () { return this._mapSize } - set mapSize(mapSize: number) { + set mapSize (mapSize: number) { this._mapSize = mapSize this.draw(this.lastBotPos) } @@ -79,7 +78,7 @@ export class MinimapDrawer { ) this.lastBotPos = botPos - this.updateWorldColors(getHighestBlockColor ?? this.getHighestBlockColor, botPos.x, botPos.z) + this.updateWorldColors(getHighestBlockColor ?? this.adapter.getHighestBlockColor, botPos.x, botPos.z) } updateWorldColors ( @@ -144,10 +143,14 @@ export class MinimapDrawer { } } - mouseToWorldPos (x: number, z: number, botPos: Vec3) { + addWarpOnClick (e: MouseEvent, botPos: Vec3) { + if (!e.target) return + const rect = (e.target as HTMLCanvasElement).getBoundingClientRect() + const z = (e.pageX - rect.left) * this.canvas.width / rect.width + const x = (e.pageY - rect.top) * this.canvas.height / rect.height const worldX = x - this.mapSize / 2 const worldZ = z - this.mapSize / 2 - return [(botPos.x + worldX).toFixed(0), (botPos.z + worldZ).toFixed(0)] + console.log([(botPos.x + worldX).toFixed(0), (botPos.z + worldZ).toFixed(0)]) } } From d61adb0a5a2a1288b2df034368bf21d346236251 Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 26 Jun 2024 14:35:32 +0400 Subject: [PATCH 027/285] screen to set up warp --- src/react/Minimap.tsx | 44 ++++++++++++++++++++++++++++++++++++-- src/react/MinimapDrawer.ts | 2 +- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 9e0c8c273..b17770f88 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,11 +1,13 @@ -import { useRef, useEffect } from 'react' +import { useRef, useEffect, useState } from 'react' import { showModal, hideModal } from '../globalState' import { useIsModalActive } from './utilsApp' import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' +import Input from './Input' export default ({ adapter }: { adapter: DrawerAdapter }) => { const fullMapOpened = useIsModalActive('full-map') + const [isWarpInfoOpened, setIsWarpInfoOpened] = useState(false) const canvasTick = useRef(0) const canvasRef = useRef(null) const drawerRef = useRef(null) @@ -13,7 +15,7 @@ export default ({ adapter }: { adapter: DrawerAdapter }) => { function updateMap () { if (!adapter) return if (drawerRef.current && canvasTick.current % 2 === 0) { - drawerRef.current.draw(bot.entity.position) + drawerRef.current.draw(adapter.playerPosition) if (canvasTick.current % 300 === 0) { drawerRef.current.deleteOldWorldColors(adapter.playerPosition.x, adapter.playerPosition.z) } @@ -31,6 +33,11 @@ export default ({ adapter }: { adapter: DrawerAdapter }) => { const handleClickOnMap = (e: MouseEvent) => { drawerRef.current?.addWarpOnClick(e, bot.entity.position) + setIsWarpInfoOpened(true) + } + + const updateWarps = () => { + } useEffect(() => { @@ -44,6 +51,8 @@ export default ({ adapter }: { adapter: DrawerAdapter }) => { useEffect(() => { if (fullMapOpened && canvasRef.current) { canvasRef.current.addEventListener('click', handleClickOnMap) + } else if (!fullMapOpened) { + setIsWarpInfoOpened(false) } return () => { @@ -54,10 +63,12 @@ export default ({ adapter }: { adapter: DrawerAdapter }) => { useEffect(() => { adapter.on('updateMap', updateMap) adapter.on('toggleFullMap', toggleFullMap) + adapter.on('updateWaprs', updateWarps) return () => { adapter.off('updateMap', updateMap) adapter.off('toggleFullMap', toggleFullMap) + adapter.off('updateWaprs', updateWarps) } }, [adapter]) @@ -80,6 +91,7 @@ export default ({ adapter }: { adapter: DrawerAdapter }) => { height={150} ref={canvasRef} > + {isWarpInfoOpened && }
:
{
} + +const WarpInfo = ({ adapter }: { adapter: DrawerAdapter }) => { + + return
+
+ Name: +
+
+
X:
+
Y:
+
Z:
+
+ +
+} diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index a24c21741..ff6457dca 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -22,7 +22,7 @@ export interface DrawerAdapter extends TypedEventEmitter { getHighestBlockColor: (x: number, z: number) => string playerPosition: Vec3 warps: WorldWarp[] - setWarp: (name: string, pos: Vec3, dimension: string, color: string, disabled: boolean) => void + setWarp: (name: string, pos: Vec3, world: string, color: string, disabled: boolean) => void } export class MinimapDrawer { From 9e7299c2b0021b1f97afc929d8cd0ecda67c679a Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 26 Jun 2024 14:45:51 +0400 Subject: [PATCH 028/285] storybook doesnt worl --- src/react/Minimap.stories.tsx | 20 ++++++++++++++------ src/react/Minimap.tsx | 2 +- src/react/MinimapProvider.tsx | 2 +- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/react/Minimap.stories.tsx b/src/react/Minimap.stories.tsx index 8fd94c1c0..458139e37 100644 --- a/src/react/Minimap.stories.tsx +++ b/src/react/Minimap.stories.tsx @@ -1,4 +1,6 @@ +import { Vec3 } from 'vec3' import type { Meta, StoryObj } from '@storybook/react' +import { DrawerAdapterImpl } from './MinimapProvider' import Minimap from './Minimap' @@ -7,7 +9,13 @@ const meta: Meta = { } export default meta -// type Story = StoryObj; +type Story = StoryObj; + +const adapter = new DrawerAdapterImpl(new Vec3(0, 0, 0)) + +adapter.getHighestBlockColor = (x: number, z: number) => { + return 'green' +} // const worldColors: string[][] = [] // @@ -20,8 +28,8 @@ export default meta // } // } // -// export const Primary: Story = { -// args: { -// worldColors -// }, -// } +export const Primary: Story = { + args: { + adapter + }, +} diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index b17770f88..f2d8d1e24 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -32,7 +32,7 @@ export default ({ adapter }: { adapter: DrawerAdapter }) => { } const handleClickOnMap = (e: MouseEvent) => { - drawerRef.current?.addWarpOnClick(e, bot.entity.position) + drawerRef.current?.addWarpOnClick(e, adapter.playerPosition) setIsWarpInfoOpened(true) } diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 14afc6575..27520c49f 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -7,7 +7,7 @@ import { contro } from '../controls' import Minimap from './Minimap' import { DrawerAdapter, MapUpdates } from './MinimapDrawer' -class DrawerAdapterImpl extends TypedEventEmitter implements DrawerAdapter { +export class DrawerAdapterImpl extends TypedEventEmitter implements DrawerAdapter { playerPosition: Vec3 warps: WorldWarp[] From d960d9a55af3b326d8c7299a555df9c9756034c3 Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 26 Jun 2024 16:16:46 +0400 Subject: [PATCH 029/285] storybook for minimap. Toggle full map doesnt work yet --- src/react/Minimap.stories.tsx | 65 ++++++++++++++++++++++++++--------- src/react/Minimap.tsx | 10 +++++- 2 files changed, 58 insertions(+), 17 deletions(-) diff --git a/src/react/Minimap.stories.tsx b/src/react/Minimap.stories.tsx index 458139e37..1c73ff223 100644 --- a/src/react/Minimap.stories.tsx +++ b/src/react/Minimap.stories.tsx @@ -1,35 +1,68 @@ import { Vec3 } from 'vec3' import type { Meta, StoryObj } from '@storybook/react' -import { DrawerAdapterImpl } from './MinimapProvider' +import { DrawerAdapter, MapUpdates } from './MinimapDrawer' +import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' +import { TypedEventEmitter } from 'contro-max/build/typedEventEmitter' +import { useEffect } from 'react' import Minimap from './Minimap' const meta: Meta = { component: Minimap, + decorators: [ + (Story, context) => { + + useEffect(() => { + adapter.emit('toggleFullMap') + setTimeout(updateMap, 2000) + }, [context.args['fullMap']]) + + return
+ } + ] } export default meta type Story = StoryObj; -const adapter = new DrawerAdapterImpl(new Vec3(0, 0, 0)) -adapter.getHighestBlockColor = (x: number, z: number) => { - return 'green' +class DrawerAdapterImpl extends TypedEventEmitter implements DrawerAdapter { + playerPosition: Vec3 + warps: WorldWarp[] + + constructor (pos?: Vec3, warps?: WorldWarp[]) { + super() + this.playerPosition = pos ?? new Vec3(0, 0, 0) + this.warps = warps ?? [] as WorldWarp[] + } + + getHighestBlockColor (x: number, z:number) { + console.log('got color') + return 'green' + } + + setWarp (name: string, pos: Vec3, world: string, color: string, disabled: boolean): void { + const warp: WorldWarp = { name, x: pos.x, y: pos.y, z: pos.z, world, color, disabled } + const index = this.warps.findIndex(w => w.name === name) + if (index === -1) { + this.warps.push(warp) + } else { + this.warps[index] = warp + } + this.emit('updateWarps') + } +} + +const adapter = new DrawerAdapterImpl() +const updateMap = () => { + console.log('map updated') + adapter.emit('updateMap') } +setTimeout(updateMap, 2000) -// const worldColors: string[][] = [] -// -// const mapSize = 10 -// for (let i = 0; i < mapSize; i += 1) { -// worldColors[i] = [] as string[] -// for (let j = 0; j < mapSize; j += 1) { -// const randColor = Math.floor(Math.random() * 255) -// worldColors[i][j] = `rgb(${randColor}, ${randColor}, ${randColor})` -// } -// } -// export const Primary: Story = { args: { - adapter + adapter, + fullMap: false }, } diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index f2d8d1e24..ebf8a6bc5 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -5,7 +5,7 @@ import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' import Input from './Input' -export default ({ adapter }: { adapter: DrawerAdapter }) => { +export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolean }) => { const fullMapOpened = useIsModalActive('full-map') const [isWarpInfoOpened, setIsWarpInfoOpened] = useState(false) const canvasTick = useRef(0) @@ -48,6 +48,14 @@ export default ({ adapter }: { adapter: DrawerAdapter }) => { } }, [canvasRef.current, fullMapOpened]) + // useEffect(() => { + // if (fullMap) { + // showModal({ reactType: 'full-map' }) + // } else { + // hideModal({ reactType: 'full-map' }) + // } + // }, [fullMap]) + useEffect(() => { if (fullMapOpened && canvasRef.current) { canvasRef.current.addEventListener('click', handleClickOnMap) From c4282c9ab7659dc6a4ceb4167cb2578ae9255281 Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 26 Jun 2024 20:36:35 +0400 Subject: [PATCH 030/285] storybook for map + fields to set warp. Styles are not done --- src/react/Minimap.stories.tsx | 13 +++---- src/react/Minimap.tsx | 67 +++++++++++++++++++++++------------ src/react/MinimapDrawer.ts | 1 + 3 files changed, 51 insertions(+), 30 deletions(-) diff --git a/src/react/Minimap.stories.tsx b/src/react/Minimap.stories.tsx index 1c73ff223..75c0b45d8 100644 --- a/src/react/Minimap.stories.tsx +++ b/src/react/Minimap.stories.tsx @@ -1,11 +1,12 @@ import { Vec3 } from 'vec3' import type { Meta, StoryObj } from '@storybook/react' -import { DrawerAdapter, MapUpdates } from './MinimapDrawer' import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' import { TypedEventEmitter } from 'contro-max/build/typedEventEmitter' import { useEffect } from 'react' +import { cleanData } from 'cypress/types/jquery' import Minimap from './Minimap' +import { DrawerAdapter, MapUpdates } from './MinimapDrawer' const meta: Meta = { component: Minimap, @@ -13,8 +14,9 @@ const meta: Meta = { (Story, context) => { useEffect(() => { - adapter.emit('toggleFullMap') - setTimeout(updateMap, 2000) + console.log('map updated') + adapter.emit('updateMap') + }, [context.args['fullMap']]) return
@@ -54,11 +56,6 @@ class DrawerAdapterImpl extends TypedEventEmitter implements DrawerA } const adapter = new DrawerAdapterImpl() -const updateMap = () => { - console.log('map updated') - adapter.emit('updateMap') -} -setTimeout(updateMap, 2000) export const Primary: Story = { args: { diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index ebf8a6bc5..4f4458133 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,4 +1,4 @@ -import { useRef, useEffect, useState } from 'react' +import { useRef, useEffect, useState, CSSProperties } from 'react' import { showModal, hideModal } from '../globalState' import { useIsModalActive } from './utilsApp' import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' @@ -13,7 +13,6 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea const drawerRef = useRef(null) function updateMap () { - if (!adapter) return if (drawerRef.current && canvasTick.current % 2 === 0) { drawerRef.current.draw(adapter.playerPosition) if (canvasTick.current % 300 === 0) { @@ -46,27 +45,19 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea } else if (canvasRef.current && drawerRef.current) { drawerRef.current.canvas = canvasRef.current } - }, [canvasRef.current, fullMapOpened]) - - // useEffect(() => { - // if (fullMap) { - // showModal({ reactType: 'full-map' }) - // } else { - // hideModal({ reactType: 'full-map' }) - // } - // }, [fullMap]) + }, [canvasRef.current, fullMapOpened, fullMap]) useEffect(() => { - if (fullMapOpened && canvasRef.current) { + if ((fullMapOpened || fullMap) && canvasRef.current) { canvasRef.current.addEventListener('click', handleClickOnMap) - } else if (!fullMapOpened) { + } else if (!fullMapOpened || !fullMap) { setIsWarpInfoOpened(false) } return () => { canvasRef.current?.removeEventListener('click', handleClickOnMap) } - }, [fullMapOpened]) + }, [fullMapOpened, fullMap]) useEffect(() => { adapter.on('updateMap', updateMap) @@ -80,7 +71,7 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea } }, [adapter]) - return fullMapOpened ?
- {isWarpInfoOpened && } + {isWarpInfoOpened && }
:
} -const WarpInfo = ({ adapter }: { adapter: DrawerAdapter }) => { +const WarpInfo = ({ adapter, drawer }: { adapter: DrawerAdapter, drawer: MinimapDrawer | null }) => { + const posInputStyle: CSSProperties = { + width: '100%', + } + const posInputContStyle: CSSProperties = { + flexGrow: '1', + display: 'flex', + } return
{ display: 'flex', justifyContent: 'center', alignItems: 'center', + gap: '10px', flexDirection: 'column', backgroundColor: 'rgba(0, 0, 0, 0.5)', - maxWidth: '70%' }} >
Name:
-
X:
-
Y:
-
Z:
+
X: +
+
+ Y: +
+
+ Z: +
+
+
+ Color: +
+
+ Disabled:
diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index ff6457dca..3f0e03e39 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -152,5 +152,6 @@ export class MinimapDrawer { const worldZ = z - this.mapSize / 2 console.log([(botPos.x + worldX).toFixed(0), (botPos.z + worldZ).toFixed(0)]) + this.lastBotPos = new Vec3(Math.floor(botPos.x + worldX), botPos.y, Math.floor(botPos.z + worldZ)) } } From f49c5294423225fd641975d278598c180b10e78d Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 27 Jun 2024 13:04:31 +0400 Subject: [PATCH 031/285] ui for set warp --- src/react/Minimap.tsx | 100 +++++++++++++++++++++------------- src/react/MinimapProvider.tsx | 1 + 2 files changed, 63 insertions(+), 38 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 4f4458133..617dcbd55 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,8 +1,9 @@ -import { useRef, useEffect, useState, CSSProperties } from 'react' +import { useRef, useEffect, useState, CSSProperties, Dispatch, SetStateAction } from 'react' import { showModal, hideModal } from '../globalState' import { useIsModalActive } from './utilsApp' import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' import Input from './Input' +import Button from './Button' export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolean }) => { @@ -90,8 +91,7 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea height={150} ref={canvasRef} > - {isWarpInfoOpened && } - + {isWarpInfoOpened && }
:
-
} -const WarpInfo = ({ adapter, drawer }: { adapter: DrawerAdapter, drawer: MinimapDrawer | null }) => { +const WarpInfo = ( + { adapter, drawer, setIsWarpInfoOpened } + : + { adapter: DrawerAdapter, drawer: MinimapDrawer | null, setIsWarpInfoOpened: Dispatch> } +) => { const posInputStyle: CSSProperties = { - width: '100%', - } - const posInputContStyle: CSSProperties = { flexGrow: '1', + } + const fieldCont: CSSProperties = { display: 'flex', + alignItems: 'center', + gap: '5px' } return
-
- Name: -
-
-
X: +
+
+ Name: +
+ +
+
+
+ X: +
+ -
-
- Y: + Y: +
+ -
-
- Z: + Z: +
+ -
+
+
+
Color:
+ +
+
+
Disabled:
+ +
+
+ + +
-
- Color: -
-
- Disabled: -
-
} diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 27520c49f..b40ddefa0 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -37,6 +37,7 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } else { this.warps[index] = warp } + if (localServer) void localServer.setWarp(warp) this.emit('updateWarps') } } From 58cb23d2d83d8c60f999da5a74dbd74a6039b5af Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 27 Jun 2024 14:41:07 +0400 Subject: [PATCH 032/285] saving warps in local server --- src/react/Minimap.stories.tsx | 2 +- src/react/Minimap.tsx | 98 +++++++++++++++++++++++++++-------- src/react/MinimapDrawer.ts | 10 ++-- src/react/MinimapProvider.tsx | 8 ++- 4 files changed, 90 insertions(+), 28 deletions(-) diff --git a/src/react/Minimap.stories.tsx b/src/react/Minimap.stories.tsx index 75c0b45d8..d55f809a7 100644 --- a/src/react/Minimap.stories.tsx +++ b/src/react/Minimap.stories.tsx @@ -43,7 +43,7 @@ class DrawerAdapterImpl extends TypedEventEmitter implements DrawerA return 'green' } - setWarp (name: string, pos: Vec3, world: string, color: string, disabled: boolean): void { + setWarp (name: string, pos: Vec3, color: string, disabled: boolean, world?: string): void { const warp: WorldWarp = { name, x: pos.x, y: pos.y, z: pos.z, world, color, disabled } const index = this.warps.findIndex(w => w.name === name) if (index === -1) { diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 617dcbd55..9c37cd36b 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,10 +1,12 @@ import { useRef, useEffect, useState, CSSProperties, Dispatch, SetStateAction } from 'react' +import { Vec3 } from 'vec3' +import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' import { showModal, hideModal } from '../globalState' import { useIsModalActive } from './utilsApp' import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' import Input from './Input' import Button from './Button' - + export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolean }) => { const fullMapOpened = useIsModalActive('full-map') @@ -32,7 +34,7 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea } const handleClickOnMap = (e: MouseEvent) => { - drawerRef.current?.addWarpOnClick(e, adapter.playerPosition) + drawerRef.current?.setWarpPosOnClick(e, adapter.playerPosition) setIsWarpInfoOpened(true) } @@ -72,7 +74,7 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea } }, [adapter]) - return fullMapOpened || fullMap ?
- {isWarpInfoOpened && } @@ -108,9 +110,19 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea const WarpInfo = ( { adapter, drawer, setIsWarpInfoOpened } - : - { adapter: DrawerAdapter, drawer: MinimapDrawer | null, setIsWarpInfoOpened: Dispatch> } + : + { adapter: DrawerAdapter, drawer: MinimapDrawer | null, setIsWarpInfoOpened: Dispatch> } ) => { + const [warp, setWarp] = useState({ + name: '', + x: drawer?.lastWarpPos.x ?? 100, + y: drawer?.lastWarpPos.y ?? 100, + z: drawer?.lastWarpPos.z ?? 100, + color: '#d3d3d3', + disabled: false, + world: adapter.world + }) + const posInputStyle: CSSProperties = { flexGrow: '1', } @@ -149,38 +161,82 @@ const WarpInfo = (
Name:
- + { + if (!e.target) return + setWarp(prev => { return { ...prev, name: e.target.value } }) + }} + />
X:
- + { + if (!e.target) return + setWarp(prev => { return { ...prev, x: Number(e.target.value) } }) + }} + />
Y:
- + { + if (!e.target) return + setWarp(prev => { return { ...prev, y: Number(e.target.value) } }) + }} + />
Z:
- + { + if (!e.target) return + setWarp(prev => { return { ...prev, z: Number(e.target.value) } }) + }} + />
Color:
- + { + if (!e.target) return + setWarp(prev => { return { ...prev, color: e.target.value } }) + }} + />
Disabled:
- + { + if (!e.target) return + setWarp(prev => { return { ...prev, disabled: e.target.checked } }) + }} + />
- + diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 1be02898f..d097c3027 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -37,7 +37,7 @@ export class MinimapDrawer { lastBotPos: Vec3 lastWarpPos: Vec3 - constructor ( + constructor( canvas: HTMLCanvasElement, public adapter: DrawerAdapter ) { @@ -45,11 +45,11 @@ export class MinimapDrawer { this.adapter = adapter } - get canvas () { + get canvas() { return this._canvas } - set canvas (canvas: HTMLCanvasElement) { + set canvas(canvas: HTMLCanvasElement) { this.ctx = canvas.getContext('2d')! this.ctx.imageSmoothingEnabled = false this.radius = Math.min(canvas.width, canvas.height) / 2 @@ -59,16 +59,16 @@ export class MinimapDrawer { this._canvas = canvas } - get mapSize () { + get mapSize() { return this._mapSize } - set mapSize (mapSize: number) { + set mapSize(mapSize: number) { this._mapSize = mapSize this.draw(this.lastBotPos) } - draw ( + draw( botPos: Vec3, getHighestBlockColor?: DrawerAdapter['getHighestBlockColor'], ) { @@ -83,7 +83,7 @@ export class MinimapDrawer { this.updateWorldColors(getHighestBlockColor ?? this.adapter.getHighestBlockColor, botPos.x, botPos.z) } - updateWorldColors ( + updateWorldColors( getHighestBlockColor: DrawerAdapter['getHighestBlockColor'], x: number, z: number @@ -115,9 +115,9 @@ export class MinimapDrawer { } } - getHighestBlockColorCached ( - getHighestBlockColor: DrawerAdapter['getHighestBlockColor'], - x: number, + getHighestBlockColorCached( + getHighestBlockColor: DrawerAdapter['getHighestBlockColor'], + x: number, z: number ) { const roundX = Math.floor(x) @@ -131,11 +131,11 @@ export class MinimapDrawer { return color } - getDistance (x1: number, z1: number, x2: number, z2: number): number { + getDistance(x1: number, z1: number, x2: number, z2: number): number { return Math.hypot((x2 - x1), (z2 - z1)) } - deleteOldWorldColors (currX: number, currZ: number) { + deleteOldWorldColors(currX: number, currZ: number) { for (const key of Object.keys(this.worldColors)) { const [x, z] = key.split(',').map(Number) if (this.getDistance(x, z, currX, currZ) > this.radius * 5) { @@ -145,15 +145,34 @@ export class MinimapDrawer { } } - setWarpPosOnClick (e: MouseEvent, botPos: Vec3) { + setWarpPosOnClick(e: MouseEvent, botPos: Vec3) { if (!e.target) return const rect = (e.target as HTMLCanvasElement).getBoundingClientRect() - const z = (e.pageX - rect.left) * this.canvas.width / rect.width - const x = (e.pageY - rect.top) * this.canvas.height / rect.height + const z = (e.pageX - rect.left) * this.canvas.width / rect.width + const x = (e.pageY - rect.top) * this.canvas.height / rect.height const worldX = x - this.mapSize / 2 const worldZ = z - this.mapSize / 2 // console.log([(botPos.x + worldX).toFixed(0), (botPos.z + worldZ).toFixed(0)]) this.lastWarpPos = new Vec3(Math.floor(botPos.x + worldX), botPos.y, Math.floor(botPos.z + worldZ)) } + + drawWarps() { + for (const warp of this.adapter.warps) { + const distance = this.getDistance( + this.adapter.playerPosition.x, + this.adapter.playerPosition.z, + warp.x, + warp.z + ) + if (distance > this.mapSize * 2/3) continue + const z = Math.floor((this.mapSize / 2 - this.adapter.playerPosition.z + warp.z)) + const x = Math.floor((this.mapSize / 2 - this.adapter.playerPosition.x + warp.x)) + this.ctx.beginPath() + this.ctx.arc(z, x, 2, 0, Math.PI * 2, false) + this.ctx.fillStyle = warp.disabled ? 'rgba(255, 255, 255, 0.4)' : warp.color ?? 'd3d3d3' + this.ctx.fill() + this.ctx.closePath() + } + } } From 2fc14ec420763ae1c49b4c4257397a3a218b5bb2 Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 28 Jun 2024 14:03:22 +0400 Subject: [PATCH 034/285] delay for warp on border --- src/react/MinimapDrawer.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index d097c3027..c5e560359 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -168,8 +168,15 @@ export class MinimapDrawer { if (distance > this.mapSize * 2/3) continue const z = Math.floor((this.mapSize / 2 - this.adapter.playerPosition.z + warp.z)) const x = Math.floor((this.mapSize / 2 - this.adapter.playerPosition.x + warp.x)) + const dz = z - this.centerX + const dx = x - this.centerY + const circleDist = Math.sqrt(dx * dx + dz * dz) + + const angle = Math.atan2(dx, dz) + const worldZ = circleDist > this.mapSize / 2 ? this.centerX + this.mapSize / 2 * Math.cos(angle) : z + const worldX = circleDist > this.mapSize / 2 ? this.centerY + this.mapSize / 2 * Math.cos(angle) : x this.ctx.beginPath() - this.ctx.arc(z, x, 2, 0, Math.PI * 2, false) + this.ctx.arc(worldZ, worldX, 2, 0, Math.PI * 2, false) this.ctx.fillStyle = warp.disabled ? 'rgba(255, 255, 255, 0.4)' : warp.color ?? 'd3d3d3' this.ctx.fill() this.ctx.closePath() From 32a0f4c2204bb68db8dd687eadc9f082a716fafc Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 28 Jun 2024 14:20:51 +0400 Subject: [PATCH 035/285] fix delay for warp on border --- src/react/MinimapDrawer.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index c5e560359..7fb08363d 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -165,18 +165,18 @@ export class MinimapDrawer { warp.x, warp.z ) - if (distance > this.mapSize * 2/3) continue + if (distance > this.mapSize) continue const z = Math.floor((this.mapSize / 2 - this.adapter.playerPosition.z + warp.z)) const x = Math.floor((this.mapSize / 2 - this.adapter.playerPosition.x + warp.x)) const dz = z - this.centerX const dx = x - this.centerY const circleDist = Math.sqrt(dx * dx + dz * dz) - const angle = Math.atan2(dx, dz) - const worldZ = circleDist > this.mapSize / 2 ? this.centerX + this.mapSize / 2 * Math.cos(angle) : z - const worldX = circleDist > this.mapSize / 2 ? this.centerY + this.mapSize / 2 * Math.cos(angle) : x + const angle = Math.atan2(dz, dx) + const circleZ = circleDist > this.mapSize / 2 ? this.centerX + this.mapSize / 2 * Math.sin(angle) : z + const circleX = circleDist > this.mapSize / 2 ? this.centerY + this.mapSize / 2 * Math.cos(angle) : x this.ctx.beginPath() - this.ctx.arc(worldZ, worldX, 2, 0, Math.PI * 2, false) + this.ctx.arc(circleZ, circleX, circleDist > this.mapSize / 2 ? 1.5 : 2, 0, Math.PI * 2, false) this.ctx.fillStyle = warp.disabled ? 'rgba(255, 255, 255, 0.4)' : warp.color ?? 'd3d3d3' this.ctx.fill() this.ctx.closePath() From a61fc535e2dded3267ba27515a112d329905583a Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 28 Jun 2024 14:27:19 +0400 Subject: [PATCH 036/285] localServer warps are in provider --- src/react/MinimapProvider.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 5e3b6726c..89cee961f 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -39,15 +39,13 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } else { this.warps[index] = warp } - if (localServer) void localServer.setWarp(warp) + // if (localServer) void localServer.setWarp(warp) this.emit('updateWarps') - // console.log('local server warps:', localServer?.warps) - // console.log('adapter warps:', this.warps) } } export default () => { - const [adapter] = useState(() => new DrawerAdapterImpl(bot.entity.position)) + const [adapter] = useState(() => new DrawerAdapterImpl(bot.entity.position, localServer?.warps)) const updateMap = () => { if (!adapter) return From 65eae1583e244568e1d4eee82cf7133b8119b68c Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 28 Jun 2024 14:38:12 +0400 Subject: [PATCH 037/285] open map on click --- src/react/Minimap.tsx | 17 ++++++++++++++++- src/react/MinimapDrawer.ts | 30 +++++++++++++++--------------- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index d8ed7a7d6..5b5238d08 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -78,6 +78,7 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea return fullMapOpened || fullMap ?
+
{ + toggleFullMap() + }} + >
+ { + toggleFullMap() + }} >
@@ -227,7 +243,6 @@ const WarpInfo = (
} diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index cfa3b4cbd..0037b6452 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -53,8 +53,9 @@ export class MinimapDrawer { set canvas (canvas: HTMLCanvasElement) { this.ctx = canvas.getContext('2d', { willReadFrequently: true })! this.ctx.imageSmoothingEnabled = false - this.radius = Math.min(canvas.width, canvas.height) / 2 + this.radius = Math.floor(Math.min(canvas.width, canvas.height) / 2.2) this._mapSize = this.radius * 2 + this.mapPixel = Math.floor(this.radius * 2 / this.mapSize) this.centerX = canvas.width / 2 this.centerY = canvas.height / 2 this._canvas = canvas @@ -84,6 +85,7 @@ export class MinimapDrawer { this.lastBotPos = botPos this.updateWorldColors(getHighestBlockColor ?? this.adapter.getHighestBlockColor, botPos.x, botPos.z) this.drawWarps() + this.drawPartsOfWorld() } updateWorldColors ( @@ -190,20 +192,33 @@ export class MinimapDrawer { this.ctx.strokeStyle = 'black' this.ctx.lineWidth = 1 this.ctx.stroke() - this.ctx.fillStyle = warp.disabled ? 'rgba(255, 255, 255, 0.4)' : warp.color ?? 'd3d3d3' + this.ctx.fillStyle = warp.disabled ? 'rgba(255, 255, 255, 0.4)' : warp.color ?? '#d3d3d3' this.ctx.fill() this.ctx.closePath() } } drawPartsOfWorld () { - this.ctx.font = '12px serif' + this.ctx.fillStyle = 'white' + this.ctx.shadowOffsetX = 1 + this.ctx.shadowOffsetY = 1 + this.ctx.shadowColor = 'black' + this.ctx.font = `${this.radius / 4}px serif` this.ctx.textAlign = 'center' this.ctx.textBaseline = 'middle' - - this.ctx.fillText('N', this.centerX, 5) - this.ctx.fillText('S', this.centerX, this.centerY - 5) - this.ctx.fillText('W', 5, this.centerY) - this.ctx.fillText('E', this.centerX - 5, this.centerY) + this.ctx.strokeStyle = 'black' + this.ctx.lineWidth = 1 + + this.ctx.strokeText('W', this.centerX, this.centerY - this.radius) + this.ctx.strokeText('E', this.centerX, this.centerY + this.radius) + this.ctx.strokeText('N', this.centerX - this.radius, this.centerY) + this.ctx.strokeText('S', this.centerX + this.radius, this.centerY) + this.ctx.fillText('W', this.centerX, this.centerY - this.radius) + this.ctx.fillText('E', this.centerX, this.centerY + this.radius) + this.ctx.fillText('N', this.centerX - this.radius, this.centerY) + this.ctx.fillText('S', this.centerX + this.radius, this.centerY) + + this.ctx.shadowOffsetX = 0 + this.ctx.shadowOffsetY = 0 } } From b357ea2e6ee8c7c8b5726ec0d77f6a31d42a6d83 Mon Sep 17 00:00:00 2001 From: gguio Date: Tue, 2 Jul 2024 22:10:01 +0400 Subject: [PATCH 042/285] mirror x axis --- src/react/MinimapDrawer.ts | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 0037b6452..8deb742de 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -106,7 +106,7 @@ export class MinimapDrawer { for (let col = 0; col < this.mapSize; col += 1) { this.ctx.fillStyle = this.getHighestBlockColorCached( getHighestBlockColor, - x - this.mapSize / 2 + row, + x - this.mapSize / 2 + this.mapSize - row, z - this.mapSize / 2 + col ) this.ctx.fillRect( @@ -119,11 +119,8 @@ export class MinimapDrawer { } const clippedImage = this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height) - this.ctx.restore() - this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height) - this.ctx.putImageData(clippedImage, 0, 0) } @@ -162,7 +159,7 @@ export class MinimapDrawer { const rect = (e.target as HTMLCanvasElement).getBoundingClientRect() const z = (e.pageX - rect.left) * this.canvas.width / rect.width const x = (e.pageY - rect.top) * this.canvas.height / rect.height - const worldX = x - this.mapSize / 2 + const worldX = -1 * x + this.mapSize / 2 const worldZ = z - this.mapSize / 2 // console.log([(botPos.x + worldX).toFixed(0), (botPos.z + worldZ).toFixed(0)]) @@ -179,7 +176,7 @@ export class MinimapDrawer { ) if (distance > this.mapSize) continue const z = Math.floor((this.mapSize / 2 - this.adapter.playerPosition.z + warp.z)) - const x = Math.floor((this.mapSize / 2 - this.adapter.playerPosition.x + warp.x)) + const x = Math.floor((this.mapSize / 2 + this.adapter.playerPosition.x - warp.x)) const dz = z - this.centerX const dx = x - this.centerY const circleDist = Math.hypot(dx, dz) @@ -209,12 +206,12 @@ export class MinimapDrawer { this.ctx.strokeStyle = 'black' this.ctx.lineWidth = 1 - this.ctx.strokeText('W', this.centerX, this.centerY - this.radius) - this.ctx.strokeText('E', this.centerX, this.centerY + this.radius) + this.ctx.strokeText('E', this.centerX, this.centerY - this.radius) + this.ctx.strokeText('W', this.centerX, this.centerY + this.radius) this.ctx.strokeText('N', this.centerX - this.radius, this.centerY) this.ctx.strokeText('S', this.centerX + this.radius, this.centerY) - this.ctx.fillText('W', this.centerX, this.centerY - this.radius) - this.ctx.fillText('E', this.centerX, this.centerY + this.radius) + this.ctx.fillText('E', this.centerX, this.centerY - this.radius) + this.ctx.fillText('W', this.centerX, this.centerY + this.radius) this.ctx.fillText('N', this.centerX - this.radius, this.centerY) this.ctx.fillText('S', this.centerX + this.radius, this.centerY) From d35db9a9a565be9272a4e59a19df679b367f7353 Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 3 Jul 2024 13:12:18 +0400 Subject: [PATCH 043/285] fixed drawing direction --- src/react/MinimapDrawer.ts | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 8deb742de..c33b8bb05 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -84,8 +84,8 @@ export class MinimapDrawer { this.lastBotPos = botPos this.updateWorldColors(getHighestBlockColor ?? this.adapter.getHighestBlockColor, botPos.x, botPos.z) - this.drawWarps() this.drawPartsOfWorld() + this.drawWarps() } updateWorldColors ( @@ -106,8 +106,8 @@ export class MinimapDrawer { for (let col = 0; col < this.mapSize; col += 1) { this.ctx.fillStyle = this.getHighestBlockColorCached( getHighestBlockColor, - x - this.mapSize / 2 + this.mapSize - row, - z - this.mapSize / 2 + col + x - this.mapSize / 2 + col, + z - this.mapSize / 2 + row ) this.ctx.fillRect( left + this.mapPixel * col, @@ -157,9 +157,9 @@ export class MinimapDrawer { setWarpPosOnClick (e: MouseEvent, botPos: Vec3) { if (!e.target) return const rect = (e.target as HTMLCanvasElement).getBoundingClientRect() - const z = (e.pageX - rect.left) * this.canvas.width / rect.width - const x = (e.pageY - rect.top) * this.canvas.height / rect.height - const worldX = -1 * x + this.mapSize / 2 + const z = (e.pageY - rect.top) * this.canvas.width / rect.width + const x = (e.pageX - rect.left) * this.canvas.height / rect.height + const worldX = x - this.mapSize / 2 const worldZ = z - this.mapSize / 2 // console.log([(botPos.x + worldX).toFixed(0), (botPos.z + worldZ).toFixed(0)]) @@ -176,7 +176,7 @@ export class MinimapDrawer { ) if (distance > this.mapSize) continue const z = Math.floor((this.mapSize / 2 - this.adapter.playerPosition.z + warp.z)) - const x = Math.floor((this.mapSize / 2 + this.adapter.playerPosition.x - warp.x)) + const x = Math.floor((this.mapSize / 2 - this.adapter.playerPosition.x + warp.x)) const dz = z - this.centerX const dx = x - this.centerY const circleDist = Math.hypot(dx, dz) @@ -185,7 +185,7 @@ export class MinimapDrawer { const circleZ = circleDist > this.mapSize / 2 ? this.centerX + this.mapSize / 2 * Math.sin(angle) : z const circleX = circleDist > this.mapSize / 2 ? this.centerY + this.mapSize / 2 * Math.cos(angle) : x this.ctx.beginPath() - this.ctx.arc(circleZ, circleX, circleDist > this.mapSize / 2 ? 1.5 : 2, 0, Math.PI * 2, false) + this.ctx.arc(circleX, circleZ, circleDist > this.mapSize / 2 ? 1.5 : 2, 0, Math.PI * 2, false) this.ctx.strokeStyle = 'black' this.ctx.lineWidth = 1 this.ctx.stroke() @@ -206,14 +206,14 @@ export class MinimapDrawer { this.ctx.strokeStyle = 'black' this.ctx.lineWidth = 1 - this.ctx.strokeText('E', this.centerX, this.centerY - this.radius) - this.ctx.strokeText('W', this.centerX, this.centerY + this.radius) - this.ctx.strokeText('N', this.centerX - this.radius, this.centerY) - this.ctx.strokeText('S', this.centerX + this.radius, this.centerY) - this.ctx.fillText('E', this.centerX, this.centerY - this.radius) - this.ctx.fillText('W', this.centerX, this.centerY + this.radius) - this.ctx.fillText('N', this.centerX - this.radius, this.centerY) - this.ctx.fillText('S', this.centerX + this.radius, this.centerY) + this.ctx.strokeText('N', this.centerX, this.centerY - this.radius) + this.ctx.strokeText('S', this.centerX, this.centerY + this.radius) + this.ctx.strokeText('W', this.centerX - this.radius, this.centerY) + this.ctx.strokeText('E', this.centerX + this.radius, this.centerY) + this.ctx.fillText('N', this.centerX, this.centerY - this.radius) + this.ctx.fillText('S', this.centerX, this.centerY + this.radius) + this.ctx.fillText('W', this.centerX - this.radius, this.centerY) + this.ctx.fillText('E', this.centerX + this.radius, this.centerY) this.ctx.shadowOffsetX = 0 this.ctx.shadowOffsetY = 0 From 5f4a57234711ba94b9694fcabe86cf6f8c032134 Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 4 Jul 2024 00:23:02 +0400 Subject: [PATCH 044/285] map rotation --- src/react/Minimap.stories.tsx | 1 + src/react/MinimapDrawer.ts | 10 ++++++++++ src/react/MinimapProvider.tsx | 2 ++ 3 files changed, 13 insertions(+) diff --git a/src/react/Minimap.stories.tsx b/src/react/Minimap.stories.tsx index d55f809a7..3ecdf9b5a 100644 --- a/src/react/Minimap.stories.tsx +++ b/src/react/Minimap.stories.tsx @@ -30,6 +30,7 @@ type Story = StoryObj; class DrawerAdapterImpl extends TypedEventEmitter implements DrawerAdapter { playerPosition: Vec3 + yaw: number warps: WorldWarp[] constructor (pos?: Vec3, warps?: WorldWarp[]) { diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index c33b8bb05..887722581 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -23,6 +23,7 @@ export interface DrawerAdapter extends TypedEventEmitter { playerPosition: Vec3 warps: WorldWarp[] world?: string + yaw: number setWarp: (name: string, pos: Vec3, color: string, disabled: boolean, world?: string) => void } @@ -86,6 +87,7 @@ export class MinimapDrawer { this.updateWorldColors(getHighestBlockColor ?? this.adapter.getHighestBlockColor, botPos.x, botPos.z) this.drawPartsOfWorld() this.drawWarps() + this.rotateMap() } updateWorldColors ( @@ -218,4 +220,12 @@ export class MinimapDrawer { this.ctx.shadowOffsetX = 0 this.ctx.shadowOffsetY = 0 } + + rotateMap () { + this.ctx.setTransform(1, 0, 0, 1, 0, 0) + const angle = this.adapter.yaw % Math.PI + this.ctx.translate(this.centerX, this.centerY) + this.ctx.rotate(angle) + this.ctx.translate(-this.centerX, -this.centerY) + } } diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 89cee961f..5e56e5853 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -9,6 +9,7 @@ import { DrawerAdapter, MapUpdates } from './MinimapDrawer' export class DrawerAdapterImpl extends TypedEventEmitter implements DrawerAdapter { playerPosition: Vec3 + yaw: number warps: WorldWarp[] world: string @@ -50,6 +51,7 @@ export default () => { const updateMap = () => { if (!adapter) return adapter.playerPosition = bot.entity.position + adapter.yaw = bot.entity.yaw adapter.emit('updateMap') } From 1bd85346505bf94c2e3d3023eb0159f894ca2283 Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 4 Jul 2024 00:52:05 +0400 Subject: [PATCH 045/285] map rotation. Fixes required: drawing has flaws + parts of world --- src/react/MinimapDrawer.ts | 55 +++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 887722581..eddc338e3 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -85,9 +85,9 @@ export class MinimapDrawer { this.lastBotPos = botPos this.updateWorldColors(getHighestBlockColor ?? this.adapter.getHighestBlockColor, botPos.x, botPos.z) - this.drawPartsOfWorld() this.drawWarps() this.rotateMap() + this.drawPartsOfWorld() } updateWorldColors ( @@ -208,14 +208,51 @@ export class MinimapDrawer { this.ctx.strokeStyle = 'black' this.ctx.lineWidth = 1 - this.ctx.strokeText('N', this.centerX, this.centerY - this.radius) - this.ctx.strokeText('S', this.centerX, this.centerY + this.radius) - this.ctx.strokeText('W', this.centerX - this.radius, this.centerY) - this.ctx.strokeText('E', this.centerX + this.radius, this.centerY) - this.ctx.fillText('N', this.centerX, this.centerY - this.radius) - this.ctx.fillText('S', this.centerX, this.centerY + this.radius) - this.ctx.fillText('W', this.centerX - this.radius, this.centerY) - this.ctx.fillText('E', this.centerX + this.radius, this.centerY) + const angle = this.adapter.yaw % Math.PI + const angleS = angle + Math.PI + const angleW = angle + Math.PI * 3 / 2 + const angleE = angle + Math.PI / 2 + + this.ctx.strokeText( + 'N', + this.centerX + this.radius * Math.cos(angle), + this.centerY + this.radius * Math.sin(angle) + ) + this.ctx.strokeText( + 'S', + this.centerX + this.radius * Math.cos(angleS), + this.centerY + this.radius * Math.sin(angleS) + ) + this.ctx.strokeText( + 'W', + this.centerX + this.radius * Math.cos(angleW), + this.centerY + this.radius * Math.sin(angleW) + ) + this.ctx.strokeText( + 'E', + this.centerX + this.radius * Math.cos(angleE), + this.centerY + this.radius * Math.sin(angleE) + ) + this.ctx.fillText( + 'N', + this.centerX + this.radius * Math.cos(angle), + this.centerY + this.radius * Math.sin(angle) + ) + this.ctx.fillText( + 'S', + this.centerX + this.radius * Math.cos(angleS), + this.centerY + this.radius * Math.sin(angleS) + ) + this.ctx.fillText( + 'W', + this.centerX + this.radius * Math.cos(angleW), + this.centerY + this.radius * Math.sin(angleW) + ) + this.ctx.fillText( + 'E', + this.centerX + this.radius * Math.cos(angleE), + this.centerY + this.radius * Math.sin(angleE) + ) this.ctx.shadowOffsetX = 0 this.ctx.shadowOffsetY = 0 From e600c65076e6472508f144ea50aa3dfa507afe80 Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 4 Jul 2024 01:13:21 +0400 Subject: [PATCH 046/285] map rotation fixed but parts of the world rotate too fast --- src/react/MinimapDrawer.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index eddc338e3..5458b6846 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -208,7 +208,7 @@ export class MinimapDrawer { this.ctx.strokeStyle = 'black' this.ctx.lineWidth = 1 - const angle = this.adapter.yaw % Math.PI + const angle = this.adapter.yaw % (Math.PI * 2) const angleS = angle + Math.PI const angleW = angle + Math.PI * 3 / 2 const angleE = angle + Math.PI / 2 @@ -260,7 +260,7 @@ export class MinimapDrawer { rotateMap () { this.ctx.setTransform(1, 0, 0, 1, 0, 0) - const angle = this.adapter.yaw % Math.PI + const angle = this.adapter.yaw % (Math.PI * 2) this.ctx.translate(this.centerX, this.centerY) this.ctx.rotate(angle) this.ctx.translate(-this.centerX, -this.centerY) From 0f6776c292b7e80f2fda4c6bcf326efbc1dc9236 Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 5 Jul 2024 12:06:44 +0400 Subject: [PATCH 047/285] better map rotation --- src/react/Minimap.tsx | 13 +++++++++---- src/react/MinimapDrawer.ts | 20 ++++++++++++-------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index b33b1cc02..1c1b83866 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,7 +1,7 @@ import { useRef, useEffect, useState, CSSProperties, Dispatch, SetStateAction } from 'react' import { Vec3 } from 'vec3' import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' -import { showModal, hideModal } from '../globalState' +import { showModal, hideModal, activeModalStack } from '../globalState' import { useIsModalActive } from './utilsApp' import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' import Input from './Input' @@ -16,8 +16,9 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea const drawerRef = useRef(null) function updateMap () { - if (drawerRef.current && canvasTick.current % 2 === 0) { - drawerRef.current.draw(adapter.playerPosition) + if (drawerRef.current) { + drawerRef.current.draw(adapter.playerPosition, undefined, fullMapOpened) + rotateMap() if (canvasTick.current % 300 === 0) { drawerRef.current.deleteOldWorldColors(adapter.playerPosition.x, adapter.playerPosition.z) } @@ -38,8 +39,12 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea setIsWarpInfoOpened(true) } - const updateWarps = () => { + const updateWarps = () => { } + const rotateMap = () => { + if (!drawerRef.current) return + const angle = adapter.yaw % (Math.PI * 2) + drawerRef.current.canvas.style.transform = `rotate(${angle}rad)` } useEffect(() => { diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 5458b6846..1870e225d 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -75,6 +75,7 @@ export class MinimapDrawer { draw ( botPos: Vec3, getHighestBlockColor?: DrawerAdapter['getHighestBlockColor'], + full?: boolean ) { this.ctx.clearRect( this.centerX - this.radius, @@ -84,16 +85,16 @@ export class MinimapDrawer { ) this.lastBotPos = botPos - this.updateWorldColors(getHighestBlockColor ?? this.adapter.getHighestBlockColor, botPos.x, botPos.z) - this.drawWarps() - this.rotateMap() + this.updateWorldColors(getHighestBlockColor ?? this.adapter.getHighestBlockColor, botPos.x, botPos.z, full) this.drawPartsOfWorld() + this.drawWarps() } updateWorldColors ( getHighestBlockColor: DrawerAdapter['getHighestBlockColor'], x: number, - z: number + z: number, + full?: boolean ) { const left = this.centerX - this.radius const top = this.centerY - this.radius @@ -101,7 +102,11 @@ export class MinimapDrawer { this.ctx.save() this.ctx.beginPath() - this.ctx.arc(this.centerX, this.centerY, this.radius, 0, Math.PI * 2, true) + if (full) { + this.ctx.rect(this.centerX - this.radius, this.centerY - this.radius, this.radius * 2, this.radius * 2) + } else { + this.ctx.arc(this.centerX, this.centerY, this.radius, 0, Math.PI * 2, true) + } this.ctx.clip() for (let row = 0; row < this.mapSize; row += 1) { @@ -208,7 +213,7 @@ export class MinimapDrawer { this.ctx.strokeStyle = 'black' this.ctx.lineWidth = 1 - const angle = this.adapter.yaw % (Math.PI * 2) + const angle = - Math.PI / 2 const angleS = angle + Math.PI const angleW = angle + Math.PI * 3 / 2 const angleE = angle + Math.PI / 2 @@ -258,9 +263,8 @@ export class MinimapDrawer { this.ctx.shadowOffsetY = 0 } - rotateMap () { + rotateMap (angle: number) { this.ctx.setTransform(1, 0, 0, 1, 0, 0) - const angle = this.adapter.yaw % (Math.PI * 2) this.ctx.translate(this.centerX, this.centerY) this.ctx.rotate(angle) this.ctx.translate(-this.centerX, -this.centerY) From 13a5c7c2fd6d994ca623b8f1469061e06953bdf2 Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 5 Jul 2024 12:46:41 +0400 Subject: [PATCH 048/285] full map is square --- src/react/Minimap.tsx | 11 ++++++++--- src/react/MinimapDrawer.ts | 1 + 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 1c1b83866..05184f122 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -10,15 +10,18 @@ import Button from './Button' export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolean }) => { const fullMapOpened = useIsModalActive('full-map') + const full = useRef(false) const [isWarpInfoOpened, setIsWarpInfoOpened] = useState(false) const canvasTick = useRef(0) const canvasRef = useRef(null) const drawerRef = useRef(null) - function updateMap () { + const updateMap = () => { if (drawerRef.current) { - drawerRef.current.draw(adapter.playerPosition, undefined, fullMapOpened) - rotateMap() + drawerRef.current.draw(adapter.playerPosition, undefined, full.current) + if (!full.current) { + rotateMap() + } if (canvasTick.current % 300 === 0) { drawerRef.current.deleteOldWorldColors(adapter.playerPosition.x, adapter.playerPosition.z) } @@ -29,8 +32,10 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea const toggleFullMap = () => { if (fullMapOpened) { hideModal({ reactType: 'full-map' }) + full.current = false } else { showModal({ reactType: 'full-map' }) + full.current = true } } diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 1870e225d..062473964 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -99,6 +99,7 @@ export class MinimapDrawer { const left = this.centerX - this.radius const top = this.centerY - this.radius + this.ctx.reset() this.ctx.save() this.ctx.beginPath() From 81b064a5727c4f0250692f74b08a2966879cc93a Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 5 Jul 2024 13:12:51 +0400 Subject: [PATCH 049/285] map zoom --- package.json | 1 + pnpm-lock.yaml | 15 +++++++++++++++ src/react/Minimap.tsx | 24 ++++++++++++++---------- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 5bf32a69d..3ab1d349e 100644 --- a/package.json +++ b/package.json @@ -88,6 +88,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-transition-group": "^4.4.5", + "react-zoom-pan-pinch": "^3.6.1", "remark": "^15.0.1", "sanitize-filename": "^1.6.3", "skinview3d": "^3.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cf890476e..59a9b19d4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -181,6 +181,9 @@ importers: react-transition-group: specifier: ^4.4.5 version: 4.4.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + react-zoom-pan-pinch: + specifier: ^3.6.1 + version: 3.6.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) remark: specifier: ^15.0.1 version: 15.0.1 @@ -7121,6 +7124,13 @@ packages: react: ^18.2.0 react-dom: ^16.8.0 || ^17.0.0 + react-zoom-pan-pinch@3.6.1: + resolution: {integrity: sha512-SdPqdk7QDSV7u/WulkFOi+cnza8rEZ0XX4ZpeH7vx3UZEg7DoyuAy3MCmm+BWv/idPQL2Oe73VoC0EhfCN+sZQ==} + engines: {node: '>=8', npm: '>=5'} + peerDependencies: + react: ^18.2.0 + react-dom: '*' + react@18.2.0: resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} engines: {node: '>=0.10.0'} @@ -17057,6 +17067,11 @@ snapshots: ts-easing: 0.2.0 tslib: 2.6.2 + react-zoom-pan-pinch@3.6.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + dependencies: + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react@18.2.0: dependencies: loose-envify: 1.4.0 diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 05184f122..dd69908c9 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,7 +1,8 @@ import { useRef, useEffect, useState, CSSProperties, Dispatch, SetStateAction } from 'react' import { Vec3 } from 'vec3' import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' -import { showModal, hideModal, activeModalStack } from '../globalState' +import { showModal, hideModal } from '../globalState' +import { TransformWrapper, TransformComponent } from "react-zoom-pan-pinch" import { useIsModalActive } from './utilsApp' import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' import Input from './Input' @@ -108,14 +109,17 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea }} >
- + + + + + {isWarpInfoOpened && }
:
- +
} From 27b5a2a5c43d742453730b1cf335ab444af6a6f7 Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 5 Jul 2024 13:49:06 +0400 Subject: [PATCH 050/285] zoom added. Two fixes required: handle drag and click properly + recount world position --- src/react/Minimap.tsx | 29 ++++++++++++++++++++++++++--- src/react/MinimapDrawer.ts | 10 +++++++--- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index dd69908c9..9216c6078 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -10,6 +10,7 @@ import Button from './Button' export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolean }) => { + const isDragging = useRef(false) const fullMapOpened = useIsModalActive('full-map') const full = useRef(false) const [isWarpInfoOpened, setIsWarpInfoOpened] = useState(false) @@ -40,7 +41,20 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea } } - const handleClickOnMap = (e: MouseEvent) => { + const eventControl = (event: MouseEvent | TouchEvent) => { + if (event.type === 'mousemove' || event.type === 'touchmove') { + isDragging.current = true + } + + if (event.type === 'mouseup' || event.type === 'touchend') { + if (!isDragging.current) { + handleClickOnMap(event) + } + isDragging.current = false + } + } + + const handleClickOnMap = (e: MouseEvent | TouchEvent) => { drawerRef.current?.setWarpPosOnClick(e, adapter.playerPosition) setIsWarpInfoOpened(true) } @@ -63,13 +77,19 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea useEffect(() => { if ((fullMapOpened || fullMap) && canvasRef.current) { - canvasRef.current.addEventListener('click', handleClickOnMap) + canvasRef.current.addEventListener('mousemove', eventControl) + canvasRef.current.addEventListener('touchmove', eventControl) + canvasRef.current.addEventListener('mouseup', eventControl) + canvasRef.current.addEventListener('touchend', eventControl) } else if (!fullMapOpened || !fullMap) { setIsWarpInfoOpened(false) } return () => { - canvasRef.current?.removeEventListener('click', handleClickOnMap) + canvasRef.current?.removeEventListener('mousemove', eventControl) + canvasRef.current?.removeEventListener('touchmove', eventControl) + canvasRef.current?.removeEventListener('mouseup', eventControl) + canvasRef.current?.removeEventListener('touchend', eventControl) } }, [fullMapOpened, fullMap]) @@ -111,6 +131,9 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea Date: Tue, 9 Jul 2024 14:14:09 +0400 Subject: [PATCH 051/285] set warp on click works fine --- src/packetsPatcher.ts | 16 ++++++++-------- src/react/Minimap.tsx | 14 +++++++++++--- src/react/MinimapDrawer.ts | 10 +++++----- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/packetsPatcher.ts b/src/packetsPatcher.ts index f877d6eda..587c41c98 100644 --- a/src/packetsPatcher.ts +++ b/src/packetsPatcher.ts @@ -2,13 +2,13 @@ // todo these fixes should be ported to mineflayer export default () => { - customEvents.on('mineflayerBotCreated', () => { - bot._client.on('packet', (data, meta) => { - if (meta.name === 'map_chunk') { - if (data.groundUp && data.bitMap === 1 && data.chunkData.every(x => x === 0)) { - data.chunkData = Buffer.from(Array.from({ length: 12_544 }).fill(0) as any) - } - } - }) + customEvents.on('mineflayerBotCreated', () => { + bot._client.on('packet', (data, meta) => { + if (meta.name === 'map_chunk') { + if (data.groundUp && data.bitMap === 1 && data.chunkData.every(x => x === 0)) { + data.chunkData = Buffer.from(Array.from({ length: 12_544 }).fill(0) as any) + } + } }) + }) } diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 9216c6078..9c820cd5c 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,8 +1,8 @@ import { useRef, useEffect, useState, CSSProperties, Dispatch, SetStateAction } from 'react' import { Vec3 } from 'vec3' import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' +import { TransformWrapper, TransformComponent } from 'react-zoom-pan-pinch' import { showModal, hideModal } from '../globalState' -import { TransformWrapper, TransformComponent } from "react-zoom-pan-pinch" import { useIsModalActive } from './utilsApp' import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' import Input from './Input' @@ -11,6 +11,7 @@ import Button from './Button' export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolean }) => { const isDragging = useRef(false) + const zoomRef = useRef(null) const fullMapOpened = useIsModalActive('full-map') const full = useRef(false) const [isWarpInfoOpened, setIsWarpInfoOpened] = useState(false) @@ -131,11 +132,18 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea - + - +
} diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 00b7ce6aa..ac13c9141 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -165,12 +165,12 @@ export class MinimapDrawer { setWarpPosOnClick (e: MouseEvent | TouchEvent, botPos: Vec3) { if (!e.target) return const rect = (e.target as HTMLCanvasElement).getBoundingClientRect() - const z = (e.type === 'touchend' + const z = ((e.type === 'touchend' ? (e as TouchEvent).changedTouches[-1].pageY - : (e as MouseEvent).pageY - rect.top) * this.canvas.width / rect.width - const x = (e.type === 'touchend' - ? (e as TouchEvent).changedTouches[-1].pageY - : (e as MouseEvent).pageY - rect.left) * this.canvas.height / rect.height + : (e as MouseEvent).pageY) - rect.top) * this.canvas.height / rect.height + const x = ((e.type === 'touchend' + ? (e as TouchEvent).changedTouches[-1].pageX + : (e as MouseEvent).pageX) - rect.left) * this.canvas.width / rect.width const worldX = x - this.mapSize / 2 const worldZ = z - this.mapSize / 2 From 39d6405b9b95ae390e5620f72d9aabff2aae14e8 Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 10 Jul 2024 11:59:55 +0400 Subject: [PATCH 052/285] fullmap in a separate component --- src/react/Fullmap.tsx | 206 ++++++++++++++++++++++++++++++++++++++++++ src/react/Minimap.tsx | 69 ++++---------- 2 files changed, 222 insertions(+), 53 deletions(-) create mode 100644 src/react/Fullmap.tsx diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx new file mode 100644 index 000000000..ac9bc4378 --- /dev/null +++ b/src/react/Fullmap.tsx @@ -0,0 +1,206 @@ +import { Vec3 } from 'vec3' +import { useRef, useState, CSSProperties, Dispatch, SetStateAction } from 'react' +import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' +import { TransformWrapper, TransformComponent } from 'react-zoom-pan-pinch' +import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' +import Button from './Button' +import Input from './Input' + + +type FullmapProps = { + onClick: () => void, + adapter: any, + drawer: MinimapDrawer | null, + canvasRef: any +} + +export default ({ onClick, adapter, drawer, canvasRef }: FullmapProps) => { + const zoomRef = useRef(null) + const [isWarpInfoOpened, setIsWarpInfoOpened] = useState(false) + + return
+
+ + + + + + + {isWarpInfoOpened && } +
+} + + +const WarpInfo = ( + { adapter, drawer, setIsWarpInfoOpened } + : + { adapter: DrawerAdapter, drawer: MinimapDrawer | null, setIsWarpInfoOpened: Dispatch> } +) => { + const [warp, setWarp] = useState({ + name: '', + x: drawer?.lastWarpPos.x ?? 100, + y: drawer?.lastWarpPos.y ?? 100, + z: drawer?.lastWarpPos.z ?? 100, + color: '#d3d3d3', + disabled: false, + world: adapter.world + }) + + const posInputStyle: CSSProperties = { + flexGrow: '1', + } + const fieldCont: CSSProperties = { + display: 'flex', + alignItems: 'center', + gap: '5px' + } + + return
+
+
+
+ Name: +
+ { + if (!e.target) return + setWarp(prev => { return { ...prev, name: e.target.value } }) + }} + /> +
+
+
+ X: +
+ { + if (!e.target) return + setWarp(prev => { return { ...prev, x: Number(e.target.value) } }) + }} + /> +
+ Y: +
+ { + if (!e.target) return + setWarp(prev => { return { ...prev, y: Number(e.target.value) } }) + }} + /> +
+ Z: +
+ { + if (!e.target) return + setWarp(prev => { return { ...prev, z: Number(e.target.value) } }) + }} + /> +
+
+
Color:
+ { + if (!e.target) return + setWarp(prev => { return { ...prev, color: e.target.value } }) + }} + /> +
+
+
Disabled:
+ { + if (!e.target) return + setWarp(prev => { return { ...prev, disabled: e.target.checked } }) + }} + /> +
+
+ + +
+
+
+} diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 9c820cd5c..7e30e5a25 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -7,6 +7,7 @@ import { useIsModalActive } from './utilsApp' import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' import Input from './Input' import Button from './Button' +import Fullmap from './Fullmap' export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolean }) => { @@ -106,67 +107,29 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea } }, [adapter]) - return fullMapOpened || fullMap ?
{ + toggleFullMap() }} - > -
+ :
{ toggleFullMap() }} - >
- - - - - - - {isWarpInfoOpened && } -
:
{ - toggleFullMap() - }} - > - -
+ +
} const WarpInfo = ( From 326170f59cb571f3423bcc68a00363f621237984 Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 10 Jul 2024 12:13:28 +0400 Subject: [PATCH 053/285] clean up --- src/react/Fullmap.tsx | 38 ++++++++- src/react/Minimap.tsx | 182 ------------------------------------------ 2 files changed, 37 insertions(+), 183 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index ac9bc4378..7f0b416cd 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -1,5 +1,5 @@ import { Vec3 } from 'vec3' -import { useRef, useState, CSSProperties, Dispatch, SetStateAction } from 'react' +import { useRef, useEffect, useState, CSSProperties, Dispatch, SetStateAction } from 'react' import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' import { TransformWrapper, TransformComponent } from 'react-zoom-pan-pinch' import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' @@ -16,8 +16,44 @@ type FullmapProps = { export default ({ onClick, adapter, drawer, canvasRef }: FullmapProps) => { const zoomRef = useRef(null) + const isDragging = useRef(false) const [isWarpInfoOpened, setIsWarpInfoOpened] = useState(false) + const handleClickOnMap = (e: MouseEvent | TouchEvent) => { + drawer?.setWarpPosOnClick(e, adapter.playerPosition) + setIsWarpInfoOpened(true) + } + + const eventControl = (event: MouseEvent | TouchEvent) => { + if (event.type === 'mousemove' || event.type === 'touchmove') { + isDragging.current = true + } + + if (event.type === 'mouseup' || event.type === 'touchend') { + if (!isDragging.current) { + handleClickOnMap(event) + } + isDragging.current = false + } + } + + useEffect(() => { + if (canvasRef.current) { + canvasRef.current.addEventListener('mousemove', eventControl) + canvasRef.current.addEventListener('touchmove', eventControl) + canvasRef.current.addEventListener('mouseup', eventControl) + canvasRef.current.addEventListener('touchend', eventControl) + } + + return () => { + canvasRef.current?.removeEventListener('mousemove', eventControl) + canvasRef.current?.removeEventListener('touchmove', eventControl) + canvasRef.current?.removeEventListener('mouseup', eventControl) + canvasRef.current?.removeEventListener('touchend', eventControl) + setIsWarpInfoOpened(false) + } + }, []) + return
{ - const isDragging = useRef(false) - const zoomRef = useRef(null) const fullMapOpened = useIsModalActive('full-map') const full = useRef(false) - const [isWarpInfoOpened, setIsWarpInfoOpened] = useState(false) const canvasTick = useRef(0) const canvasRef = useRef(null) const drawerRef = useRef(null) @@ -43,24 +35,6 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea } } - const eventControl = (event: MouseEvent | TouchEvent) => { - if (event.type === 'mousemove' || event.type === 'touchmove') { - isDragging.current = true - } - - if (event.type === 'mouseup' || event.type === 'touchend') { - if (!isDragging.current) { - handleClickOnMap(event) - } - isDragging.current = false - } - } - - const handleClickOnMap = (e: MouseEvent | TouchEvent) => { - drawerRef.current?.setWarpPosOnClick(e, adapter.playerPosition) - setIsWarpInfoOpened(true) - } - const updateWarps = () => { } const rotateMap = () => { @@ -77,24 +51,6 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea } }, [canvasRef.current, fullMapOpened, fullMap]) - useEffect(() => { - if ((fullMapOpened || fullMap) && canvasRef.current) { - canvasRef.current.addEventListener('mousemove', eventControl) - canvasRef.current.addEventListener('touchmove', eventControl) - canvasRef.current.addEventListener('mouseup', eventControl) - canvasRef.current.addEventListener('touchend', eventControl) - } else if (!fullMapOpened || !fullMap) { - setIsWarpInfoOpened(false) - } - - return () => { - canvasRef.current?.removeEventListener('mousemove', eventControl) - canvasRef.current?.removeEventListener('touchmove', eventControl) - canvasRef.current?.removeEventListener('mouseup', eventControl) - canvasRef.current?.removeEventListener('touchend', eventControl) - } - }, [fullMapOpened, fullMap]) - useEffect(() => { adapter.on('updateMap', updateMap) adapter.on('toggleFullMap', toggleFullMap) @@ -132,141 +88,3 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea
} -const WarpInfo = ( - { adapter, drawer, setIsWarpInfoOpened } - : - { adapter: DrawerAdapter, drawer: MinimapDrawer | null, setIsWarpInfoOpened: Dispatch> } -) => { - const [warp, setWarp] = useState({ - name: '', - x: drawer?.lastWarpPos.x ?? 100, - y: drawer?.lastWarpPos.y ?? 100, - z: drawer?.lastWarpPos.z ?? 100, - color: '#d3d3d3', - disabled: false, - world: adapter.world - }) - - const posInputStyle: CSSProperties = { - flexGrow: '1', - } - const fieldCont: CSSProperties = { - display: 'flex', - alignItems: 'center', - gap: '5px' - } - - return
-
-
-
- Name: -
- { - if (!e.target) return - setWarp(prev => { return { ...prev, name: e.target.value } }) - }} - /> -
-
-
- X: -
- { - if (!e.target) return - setWarp(prev => { return { ...prev, x: Number(e.target.value) } }) - }} - /> -
- Y: -
- { - if (!e.target) return - setWarp(prev => { return { ...prev, y: Number(e.target.value) } }) - }} - /> -
- Z: -
- { - if (!e.target) return - setWarp(prev => { return { ...prev, z: Number(e.target.value) } }) - }} - /> -
-
-
Color:
- { - if (!e.target) return - setWarp(prev => { return { ...prev, color: e.target.value } }) - }} - /> -
-
-
Disabled:
- { - if (!e.target) return - setWarp(prev => { return { ...prev, disabled: e.target.checked } }) - }} - /> -
-
- - -
-
-
-} From c5a485f6a5babf33412d3eeef60b56f52d786725 Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 10 Jul 2024 12:25:13 +0400 Subject: [PATCH 054/285] state --- src/react/Fullmap.tsx | 7 +++++++ src/react/Minimap.tsx | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index 7f0b416cd..c689c4353 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -17,6 +17,7 @@ type FullmapProps = { export default ({ onClick, adapter, drawer, canvasRef }: FullmapProps) => { const zoomRef = useRef(null) const isDragging = useRef(false) + const stateRef = useRef({ scale: 1, positionX: 0, positionY: 0 }) const [isWarpInfoOpened, setIsWarpInfoOpened] = useState(false) const handleClickOnMap = (e: MouseEvent | TouchEvent) => { @@ -83,6 +84,12 @@ export default ({ onClick, adapter, drawer, canvasRef }: FullmapProps) => { doubleClick={{ disabled: true }} + onTransformed={(ref, state)=>{ + stateRef.current = { ...state } + }} + onPanningStop={()=>{ + console.log(stateRef.current) + }} > Date: Wed, 10 Jul 2024 13:14:07 +0400 Subject: [PATCH 055/285] canvases container --- src/react/Fullmap.tsx | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index c689c4353..1120e373e 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -17,6 +17,7 @@ type FullmapProps = { export default ({ onClick, adapter, drawer, canvasRef }: FullmapProps) => { const zoomRef = useRef(null) const isDragging = useRef(false) + const canvasesCont = useRef(null) const stateRef = useRef({ scale: 1, positionX: 0, positionY: 0 }) const [isWarpInfoOpened, setIsWarpInfoOpened] = useState(false) @@ -38,6 +39,14 @@ export default ({ onClick, adapter, drawer, canvasRef }: FullmapProps) => { } } + const drawNewPartOfMap = () => { + const newCanvas = document.createElement('canvas') + newCanvas.width = 200 / stateRef.current.scale + newCanvas.height = 200 / stateRef.current.scale + canvasRef.current = newCanvas + + } + useEffect(() => { if (canvasRef.current) { canvasRef.current.addEventListener('mousemove', eventControl) @@ -97,11 +106,19 @@ export default ({ onClick, adapter, drawer, canvasRef }: FullmapProps) => { willChange: 'transform', }} > - +
+ +
{isWarpInfoOpened && } From 738ed8cd4bb9d6b8f3e7a24b1430b430bf1b3bf3 Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 10 Jul 2024 13:36:45 +0400 Subject: [PATCH 056/285] drawing new canvas after map move --- src/react/Fullmap.tsx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index 1120e373e..f4cbb11a5 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -17,7 +17,7 @@ type FullmapProps = { export default ({ onClick, adapter, drawer, canvasRef }: FullmapProps) => { const zoomRef = useRef(null) const isDragging = useRef(false) - const canvasesCont = useRef(null) + const canvasesCont = useRef(null) const stateRef = useRef({ scale: 1, positionX: 0, positionY: 0 }) const [isWarpInfoOpened, setIsWarpInfoOpened] = useState(false) @@ -43,8 +43,14 @@ export default ({ onClick, adapter, drawer, canvasRef }: FullmapProps) => { const newCanvas = document.createElement('canvas') newCanvas.width = 200 / stateRef.current.scale newCanvas.height = 200 / stateRef.current.scale + newCanvas.style.position = 'absolute' + newCanvas.style.top = `${-stateRef.current.positionY * 1 / stateRef.current.scale}px` + newCanvas.style.left = `${-stateRef.current.positionX * 1 / stateRef.current.scale}px` + newCanvas.style.border = '2px solid red' canvasRef.current = newCanvas - + if (canvasesCont.current) { + canvasesCont.current.appendChild(newCanvas) + } } useEffect(() => { @@ -97,7 +103,7 @@ export default ({ onClick, adapter, drawer, canvasRef }: FullmapProps) => { stateRef.current = { ...state } }} onPanningStop={()=>{ - console.log(stateRef.current) + drawNewPartOfMap() }} > Date: Wed, 10 Jul 2024 14:13:06 +0400 Subject: [PATCH 057/285] drawing new canvas on move --- src/react/Fullmap.tsx | 18 ++++++++++++++++-- src/react/Minimap.tsx | 2 +- src/react/MinimapDrawer.ts | 6 +++--- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index f4cbb11a5..d70e7f579 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -9,7 +9,7 @@ import Input from './Input' type FullmapProps = { onClick: () => void, - adapter: any, + adapter: DrawerAdapter, drawer: MinimapDrawer | null, canvasRef: any } @@ -48,11 +48,25 @@ export default ({ onClick, adapter, drawer, canvasRef }: FullmapProps) => { newCanvas.style.left = `${-stateRef.current.positionX * 1 / stateRef.current.scale}px` newCanvas.style.border = '2px solid red' canvasRef.current = newCanvas - if (canvasesCont.current) { + if (canvasesCont.current && drawer) { canvasesCont.current.appendChild(newCanvas) + drawer.canvas = newCanvas + drawer.draw( + new Vec3( + adapter.playerPosition.x - stateRef.current.positionX * 1 / stateRef.current.scale, + adapter.playerPosition.y, + adapter.playerPosition.z - stateRef.current.positionY * 1 / stateRef.current.scale, + ), + undefined, + true + ) } } + useEffect(()=>{ + drawer?.draw(adapter.playerPosition, undefined, true) + }, [drawer]) + useEffect(() => { if (canvasRef.current) { canvasRef.current.addEventListener('mousemove', eventControl) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 9af28c6d6..c87992b2d 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -14,9 +14,9 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea const updateMap = () => { if (drawerRef.current) { - drawerRef.current.draw(adapter.playerPosition, undefined, full.current) if (!full.current) { rotateMap() + drawerRef.current.draw(adapter.playerPosition, undefined, full.current) } if (canvasTick.current % 300 === 0) { drawerRef.current.deleteOldWorldColors(adapter.playerPosition.x, adapter.playerPosition.z) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index ac13c9141..f62b56925 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -86,8 +86,8 @@ export class MinimapDrawer { this.lastBotPos = botPos this.updateWorldColors(getHighestBlockColor ?? this.adapter.getHighestBlockColor, botPos.x, botPos.z, full) - this.drawPartsOfWorld() - this.drawWarps() + if (!full) this.drawPartsOfWorld() + this.drawWarps(botPos) } updateWorldColors ( @@ -178,7 +178,7 @@ export class MinimapDrawer { this.lastWarpPos = new Vec3(Math.floor(botPos.x + worldX), botPos.y, Math.floor(botPos.z + worldZ)) } - drawWarps () { + drawWarps (centerPos: Vec3) { for (const warp of this.adapter.warps) { const distance = this.getDistance( this.adapter.playerPosition.x, From 58599799e56b0e29576264d069c6e1f339984a9f Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 10 Jul 2024 22:06:29 +0400 Subject: [PATCH 058/285] map is drawing on mouse move. Not finished: scaling ruins the position of the map, right formula required --- src/react/Fullmap.tsx | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index d70e7f579..c798ee2ab 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -19,6 +19,7 @@ export default ({ onClick, adapter, drawer, canvasRef }: FullmapProps) => { const isDragging = useRef(false) const canvasesCont = useRef(null) const stateRef = useRef({ scale: 1, positionX: 0, positionY: 0 }) + const box = useRef({ left: 0, top: 0 }) const [isWarpInfoOpened, setIsWarpInfoOpened] = useState(false) const handleClickOnMap = (e: MouseEvent | TouchEvent) => { @@ -41,21 +42,23 @@ export default ({ onClick, adapter, drawer, canvasRef }: FullmapProps) => { const drawNewPartOfMap = () => { const newCanvas = document.createElement('canvas') - newCanvas.width = 200 / stateRef.current.scale - newCanvas.height = 200 / stateRef.current.scale + newCanvas.width = Math.floor(200 / stateRef.current.scale) + if (newCanvas.width % 2) newCanvas.width += 1 + newCanvas.height = Math.floor(200 / stateRef.current.scale) + if (newCanvas.height % 2) newCanvas.height += 1 newCanvas.style.position = 'absolute' - newCanvas.style.top = `${-stateRef.current.positionY * 1 / stateRef.current.scale}px` - newCanvas.style.left = `${-stateRef.current.positionX * 1 / stateRef.current.scale}px` - newCanvas.style.border = '2px solid red' + newCanvas.style.top = `${-stateRef.current.positionY / stateRef.current.scale}px` + newCanvas.style.left = `${-stateRef.current.positionX / stateRef.current.scale}px` + // newCanvas.style.border = '2px solid red' canvasRef.current = newCanvas if (canvasesCont.current && drawer) { canvasesCont.current.appendChild(newCanvas) drawer.canvas = newCanvas drawer.draw( new Vec3( - adapter.playerPosition.x - stateRef.current.positionX * 1 / stateRef.current.scale, + adapter.playerPosition.x - (stateRef.current.positionX + (1 - stateRef.current.scale) * newCanvas.width / 2) / stateRef.current.scale, adapter.playerPosition.y, - adapter.playerPosition.z - stateRef.current.positionY * 1 / stateRef.current.scale, + adapter.playerPosition.z - (stateRef.current.positionY + (1 - stateRef.current.scale) * newCanvas.height / 2) / stateRef.current.scale, ), undefined, true @@ -115,9 +118,19 @@ export default ({ onClick, adapter, drawer, canvasRef }: FullmapProps) => { }} onTransformed={(ref, state)=>{ stateRef.current = { ...state } + if ( + Math.abs(state.positionX - box.current.left) > 20 || Math.abs(state.positionY - box.current.top) > 20 + ) { + drawNewPartOfMap() + box.current.top = state.positionY + box.current.left = state.positionX + } }} onPanningStop={()=>{ - drawNewPartOfMap() + console.log(stateRef.current) + }} + onZoomStop={()=>{ + console.log(stateRef.current) }} > Date: Thu, 11 Jul 2024 09:53:44 +0400 Subject: [PATCH 059/285] full map with overlapping canvases --- src/react/Fullmap.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index c798ee2ab..d5d1306b6 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -49,16 +49,15 @@ export default ({ onClick, adapter, drawer, canvasRef }: FullmapProps) => { newCanvas.style.position = 'absolute' newCanvas.style.top = `${-stateRef.current.positionY / stateRef.current.scale}px` newCanvas.style.left = `${-stateRef.current.positionX / stateRef.current.scale}px` - // newCanvas.style.border = '2px solid red' canvasRef.current = newCanvas if (canvasesCont.current && drawer) { canvasesCont.current.appendChild(newCanvas) drawer.canvas = newCanvas drawer.draw( new Vec3( - adapter.playerPosition.x - (stateRef.current.positionX + (1 - stateRef.current.scale) * newCanvas.width / 2) / stateRef.current.scale, + adapter.playerPosition.x - (stateRef.current.positionX + (1 - stateRef.current.scale) * newCanvas.width ), adapter.playerPosition.y, - adapter.playerPosition.z - (stateRef.current.positionY + (1 - stateRef.current.scale) * newCanvas.height / 2) / stateRef.current.scale, + adapter.playerPosition.z - (stateRef.current.positionY + (1 - stateRef.current.scale) * newCanvas.height), ), undefined, true @@ -158,7 +157,6 @@ export default ({ onClick, adapter, drawer, canvasRef }: FullmapProps) => {
} - const WarpInfo = ( { adapter, drawer, setIsWarpInfoOpened } : From 52f1f79ce0881ce36dab7116c7b28eb3d8aff2b0 Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 11 Jul 2024 09:57:55 +0400 Subject: [PATCH 060/285] new factor --- src/react/Fullmap.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index d5d1306b6..c7871f8aa 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -55,9 +55,9 @@ export default ({ onClick, adapter, drawer, canvasRef }: FullmapProps) => { drawer.canvas = newCanvas drawer.draw( new Vec3( - adapter.playerPosition.x - (stateRef.current.positionX + (1 - stateRef.current.scale) * newCanvas.width ), + adapter.playerPosition.x - (stateRef.current.positionX + (1 - stateRef.current.scale) * newCanvas.width / 2), adapter.playerPosition.y, - adapter.playerPosition.z - (stateRef.current.positionY + (1 - stateRef.current.scale) * newCanvas.height), + adapter.playerPosition.z - (stateRef.current.positionY + (1 - stateRef.current.scale) * newCanvas.height / 2), ), undefined, true From 35439b7576f330b6cf2b56c98314238689883887 Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 11 Jul 2024 10:04:10 +0400 Subject: [PATCH 061/285] observer component --- src/react/Fullmap.tsx | 51 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index d5d1306b6..6f56f8afd 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -138,6 +138,7 @@ export default ({ onClick, adapter, drawer, canvasRef }: FullmapProps) => { willChange: 'transform', }} > +
{
} + +const Observer = () => { + const ref = useRef(null) + + useEffect(() => { + const intersectionObserver = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + console.log('visible') + } else { + console.log('not visible') + } + }) + }) + intersectionObserver.observe(ref.current!) + + return () => { + intersectionObserver.disconnect() + } + }, []); + + return ( + + +
+ {/* canvas for chunk: 16x16 blocks */} +
+
+
+
+ ) +} + const WarpInfo = ( { adapter, drawer, setIsWarpInfoOpened } : From 0635a94ffdf49ffb50c3424da4d29426bc97ba90 Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 11 Jul 2024 10:29:41 +0400 Subject: [PATCH 062/285] fixed map offset when scaled --- src/react/Fullmap.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index c7871f8aa..ca94750e7 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -55,9 +55,9 @@ export default ({ onClick, adapter, drawer, canvasRef }: FullmapProps) => { drawer.canvas = newCanvas drawer.draw( new Vec3( - adapter.playerPosition.x - (stateRef.current.positionX + (1 - stateRef.current.scale) * newCanvas.width / 2), + adapter.playerPosition.x - (stateRef.current.positionX / stateRef.current.scale - (1 - stateRef.current.scale) * newCanvas.width / 2), adapter.playerPosition.y, - adapter.playerPosition.z - (stateRef.current.positionY + (1 - stateRef.current.scale) * newCanvas.height / 2), + adapter.playerPosition.z - (stateRef.current.positionY / stateRef.current.scale - (1 - stateRef.current.scale) * newCanvas.height / 2), ), undefined, true From 4553d0323797b38fdb1fd6731b7ab9a79d581c1d Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 11 Jul 2024 10:39:56 +0400 Subject: [PATCH 063/285] warp is drawing on right place in fullmap --- src/react/Fullmap.tsx | 6 +++--- src/react/Minimap.tsx | 2 +- src/react/MinimapDrawer.ts | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index ca94750e7..7abc99b17 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -8,13 +8,13 @@ import Input from './Input' type FullmapProps = { - onClick: () => void, + toggleFullMap: () => void, adapter: DrawerAdapter, drawer: MinimapDrawer | null, canvasRef: any } -export default ({ onClick, adapter, drawer, canvasRef }: FullmapProps) => { +export default ({ toggleFullMap, adapter, drawer, canvasRef }: FullmapProps) => { const zoomRef = useRef(null) const isDragging = useRef(false) const canvasesCont = useRef(null) @@ -105,7 +105,7 @@ export default ({ onClick, adapter, drawer, canvasRef }: FullmapProps) => { height: '100%', zIndex: '-1' }} - onClick={onClick} + onClick={toggleFullMap} >
{ + toggleFullMap={()=>{ toggleFullMap() }} adapter={adapter} diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index f62b56925..89a7fa719 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -178,17 +178,17 @@ export class MinimapDrawer { this.lastWarpPos = new Vec3(Math.floor(botPos.x + worldX), botPos.y, Math.floor(botPos.z + worldZ)) } - drawWarps (centerPos: Vec3) { + drawWarps (centerPos?: Vec3) { for (const warp of this.adapter.warps) { const distance = this.getDistance( - this.adapter.playerPosition.x, - this.adapter.playerPosition.z, + centerPos?.x ?? this.adapter.playerPosition.x, + centerPos?.z ?? this.adapter.playerPosition.z, warp.x, warp.z ) if (distance > this.mapSize) continue - const z = Math.floor((this.mapSize / 2 - this.adapter.playerPosition.z + warp.z)) - const x = Math.floor((this.mapSize / 2 - this.adapter.playerPosition.x + warp.x)) + const z = Math.floor((this.mapSize / 2 - (centerPos?.z ?? this.adapter.playerPosition.z) + warp.z)) + const x = Math.floor((this.mapSize / 2 - (centerPos?.x ?? this.adapter.playerPosition.x) + warp.x)) const dz = z - this.centerX const dx = x - this.centerY const circleDist = Math.hypot(dx, dz) From 629f6b2662b09e1aec56f4559cf52f4e18643248 Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 11 Jul 2024 10:46:49 +0400 Subject: [PATCH 064/285] warps are not cut in fullmap --- src/react/MinimapDrawer.ts | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 89a7fa719..070150805 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -87,7 +87,7 @@ export class MinimapDrawer { this.lastBotPos = botPos this.updateWorldColors(getHighestBlockColor ?? this.adapter.getHighestBlockColor, botPos.x, botPos.z, full) if (!full) this.drawPartsOfWorld() - this.drawWarps(botPos) + this.drawWarps(botPos, full) } updateWorldColors ( @@ -178,15 +178,17 @@ export class MinimapDrawer { this.lastWarpPos = new Vec3(Math.floor(botPos.x + worldX), botPos.y, Math.floor(botPos.z + worldZ)) } - drawWarps (centerPos?: Vec3) { + drawWarps (centerPos?: Vec3, full?: boolean) { for (const warp of this.adapter.warps) { - const distance = this.getDistance( - centerPos?.x ?? this.adapter.playerPosition.x, - centerPos?.z ?? this.adapter.playerPosition.z, - warp.x, - warp.z - ) - if (distance > this.mapSize) continue + if (!full) { + const distance = this.getDistance( + centerPos?.x ?? this.adapter.playerPosition.x, + centerPos?.z ?? this.adapter.playerPosition.z, + warp.x, + warp.z + ) + if (distance > this.mapSize) continue + } const z = Math.floor((this.mapSize / 2 - (centerPos?.z ?? this.adapter.playerPosition.z) + warp.z)) const x = Math.floor((this.mapSize / 2 - (centerPos?.x ?? this.adapter.playerPosition.x) + warp.x)) const dz = z - this.centerX @@ -194,10 +196,14 @@ export class MinimapDrawer { const circleDist = Math.hypot(dx, dz) const angle = Math.atan2(dz, dx) - const circleZ = circleDist > this.mapSize / 2 ? this.centerX + this.mapSize / 2 * Math.sin(angle) : z - const circleX = circleDist > this.mapSize / 2 ? this.centerY + this.mapSize / 2 * Math.cos(angle) : x + const circleZ = circleDist > this.mapSize / 2 && !full ? + this.centerX + this.mapSize / 2 * Math.sin(angle) + : z + const circleX = circleDist > this.mapSize / 2 && !full ? + this.centerY + this.mapSize / 2 * Math.cos(angle) + : x this.ctx.beginPath() - this.ctx.arc(circleX, circleZ, circleDist > this.mapSize / 2 ? 1.5 : 2, 0, Math.PI * 2, false) + this.ctx.arc(circleX, circleZ, circleDist > this.mapSize / 2 && !full ? 1.5 : 2, 0, Math.PI * 2, false) this.ctx.strokeStyle = 'black' this.ctx.lineWidth = 1 this.ctx.stroke() From 8ebcdfd33f38eca40e514bb881bc4311b1f9d854 Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 11 Jul 2024 11:05:52 +0400 Subject: [PATCH 065/285] canvases clean up --- src/react/Fullmap.tsx | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index 7abc99b17..bea9ed28b 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -8,8 +8,8 @@ import Input from './Input' type FullmapProps = { - toggleFullMap: () => void, - adapter: DrawerAdapter, + toggleFullMap: () => void, + adapter: DrawerAdapter, drawer: MinimapDrawer | null, canvasRef: any } @@ -17,6 +17,7 @@ type FullmapProps = { export default ({ toggleFullMap, adapter, drawer, canvasRef }: FullmapProps) => { const zoomRef = useRef(null) const isDragging = useRef(false) + const oldCanvases = useRef([]) const canvasesCont = useRef(null) const stateRef = useRef({ scale: 1, positionX: 0, positionY: 0 }) const box = useRef({ left: 0, top: 0 }) @@ -49,6 +50,7 @@ export default ({ toggleFullMap, adapter, drawer, canvasRef }: FullmapProps) => newCanvas.style.position = 'absolute' newCanvas.style.top = `${-stateRef.current.positionY / stateRef.current.scale}px` newCanvas.style.left = `${-stateRef.current.positionX / stateRef.current.scale}px` + oldCanvases.current.push(newCanvas) canvasRef.current = newCanvas if (canvasesCont.current && drawer) { canvasesCont.current.appendChild(newCanvas) @@ -65,7 +67,16 @@ export default ({ toggleFullMap, adapter, drawer, canvasRef }: FullmapProps) => } } - useEffect(()=>{ + const deleteOldCanvases = () => { + if (oldCanvases.current.length < 30) return + for (const [index, canvas] of oldCanvases.current.entries()) { + if (index >= 20) break + canvas.remove() + } + oldCanvases.current.splice(0, 20) + } + + useEffect(() => { drawer?.draw(adapter.playerPosition, undefined, true) }, [drawer]) @@ -75,7 +86,7 @@ export default ({ toggleFullMap, adapter, drawer, canvasRef }: FullmapProps) => canvasRef.current.addEventListener('touchmove', eventControl) canvasRef.current.addEventListener('mouseup', eventControl) canvasRef.current.addEventListener('touchend', eventControl) - } + } return () => { canvasRef.current?.removeEventListener('mousemove', eventControl) @@ -111,11 +122,11 @@ export default ({ toggleFullMap, adapter, drawer, canvasRef }: FullmapProps) => { + onTransformed={(ref, state) => { stateRef.current = { ...state } if ( Math.abs(state.positionX - box.current.left) > 20 || Math.abs(state.positionY - box.current.top) > 20 @@ -125,10 +136,10 @@ export default ({ toggleFullMap, adapter, drawer, canvasRef }: FullmapProps) => box.current.left = state.positionX } }} - onPanningStop={()=>{ - console.log(stateRef.current) + onPanningStop={() => { + deleteOldCanvases() }} - onZoomStop={()=>{ + onZoomStop={() => { console.log(stateRef.current) }} > @@ -276,10 +287,10 @@ const WarpInfo = ( + @@ -163,3 +159,45 @@ export default ({ connectToServerAction, mapsProvider, singleplayerAction, optio ) } + +const DoubleButton = () => { + const [isOpen, setIsOpen] = useState(false) + const { refs, floatingStyles } = useFloating({ + open: isOpen, + onOpenChange: setIsOpen + }) + + const styles: CSSProperties = { + ...floatingStyles, + background: 'rgba(0, 0, 0, 0.3)', + fontSize: 8, + userSelect: 'text', + padding: '2px 4px', + opacity: 1, + transition: 'opacity 0.3s ease-in-out', + textShadow: '1px 1px 2px BLACK', + display: 'flex', + flexDirection: 'column', + zIndex: 11 + } + + return <> + + { + isOpen && + } + +} From a9fa8a7799b971ac8a7f004cf504582599de825c Mon Sep 17 00:00:00 2001 From: gguio Date: Tue, 23 Jul 2024 01:56:08 +0400 Subject: [PATCH 104/285] dropdown discord button in main menu and pause screen --- src/react/MainMenu.tsx | 42 +++++++++++++++++++++++++++++---------- src/react/PauseScreen.tsx | 14 ++++++++++++- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/react/MainMenu.tsx b/src/react/MainMenu.tsx index 68d3c18fd..cfccb1ce1 100644 --- a/src/react/MainMenu.tsx +++ b/src/react/MainMenu.tsx @@ -6,7 +6,7 @@ import { activeModalStack } from '../globalState' import styles from './mainMenu.module.css' import Button from './Button' import ButtonWithTooltip from './ButtonWithTooltip' -import { pixelartIcons } from './PixelartIcon' +import PixelartIcon, { pixelartIcons } from './PixelartIcon' type Action = (e: React.MouseEvent) => void @@ -65,6 +65,16 @@ export default ({ connectToServerAction, mapsProvider, singleplayerAction, optio } }, []) + const links: DropdownButtonItem[] = [ + { + text: 'link 1', + clickHandler: () => openURL('https://discord.com/') + }, + { + text: 'link 2', + clickHandler: () => openURL('https://discord.com/') + } + ] return (
@@ -125,7 +135,7 @@ export default ({ connectToServerAction, mapsProvider, singleplayerAction, optio > GitHub - +
@@ -160,7 +170,13 @@ export default ({ connectToServerAction, mapsProvider, singleplayerAction, optio ) } -const DoubleButton = () => { + +export type DropdownButtonItem = { + text: string, + clickHandler: () => void +} + +export const DropdownButton = ({ text, links }: { text: string, links: DropdownButtonItem[] }) => { const [isOpen, setIsOpen] = useState(false) const { refs, floatingStyles } = useFloating({ open: isOpen, @@ -183,20 +199,24 @@ const DoubleButton = () => { return <> + >{text} + { isOpen &&
- - link 1 - - - link 2 - + {links.map(el => { + return + })}
} diff --git a/src/react/PauseScreen.tsx b/src/react/PauseScreen.tsx index c6da297ba..7bea32446 100644 --- a/src/react/PauseScreen.tsx +++ b/src/react/PauseScreen.tsx @@ -20,6 +20,7 @@ import { showOptionsModal } from './SelectOption' import Button from './Button' import Screen from './Screen' import styles from './PauseScreen.module.css' +import { DropdownButton, DropdownButtonItem } from './MainMenu' export const saveToBrowserMemory = async () => { setLoadingScreenStatus('Saving world') @@ -103,6 +104,17 @@ export default () => { } } + const links: DropdownButtonItem[] = [ + { + text: 'link 1', + clickHandler: () => openURL('https://discord.gg/4Ucm684Fq3') + }, + { + text: 'link 2', + clickHandler: () => openURL('https://discord.com/') + } + ] + if (!isModalActive) return null return
- +
{singleplayer ? ( From 3959bb201ba27d6222da84610e600725dfd05101 Mon Sep 17 00:00:00 2001 From: gguio Date: Tue, 23 Jul 2024 18:37:33 +0400 Subject: [PATCH 105/285] no context reset --- src/react/MinimapDrawer.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index e57642ed6..ad1f25c9a 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -111,7 +111,6 @@ export class MinimapDrawer { const left = this.centerX - this.radius const top = this.centerY - this.radius - this.ctx.reset() this.ctx.save() this.ctx.beginPath() From da094bd34f372626a2c5fa3a2ab0b3d797f91b9a Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 24 Jul 2024 14:36:23 +0400 Subject: [PATCH 106/285] 100% map for small screens --- src/react/Fullmap.css | 13 +++++++++++++ src/react/Fullmap.tsx | 16 ++-------------- 2 files changed, 15 insertions(+), 14 deletions(-) create mode 100644 src/react/Fullmap.css diff --git a/src/react/Fullmap.css b/src/react/Fullmap.css new file mode 100644 index 000000000..5b4b37ce8 --- /dev/null +++ b/src/react/Fullmap.css @@ -0,0 +1,13 @@ + +.map { + width: 70% !important; + height: 80% !important; + border: 1px solid black; +} + +@media (max-width: 500px) { + .map { + width: 100% !important; + height: 100% !important; + } +} diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index c65590cd9..de9242d4a 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -5,6 +5,7 @@ import { TransformWrapper, TransformComponent, ReactZoomPanPinchRef } from 'reac import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' import Button from './Button' import Input from './Input' +import './Fullmap.css' type FullmapProps = { @@ -48,16 +49,6 @@ export default ({ toggleFullMap, adapter, drawer, canvasRef }: FullmapProps) => updateGrid() }, []) - // useEffect(() => { - // const wrapper = zoomRef.current?.instance.wrapperComponent - // if (!wrapper) return - // wrapper.style.width = `${Math.min(window.innerHeight, window.innerWidth) / 3}px` - // wrapper.style.aspectRatio = '1' - // - // - // updateGrid() - // }, [zoomRef.current]) - return
display: 'flex', justifyContent: 'center', alignItems: 'center', - border: '2px solid red', backgroundColor: 'rgba(0, 0, 0, 0.4)' }} > @@ -103,11 +93,9 @@ export default ({ toggleFullMap, adapter, drawer, canvasRef }: FullmapProps) => }} > {[...grid].map((cellCoords) => { From 54f96cda9926853b8a79d836c2ebf8d37d3dd99d Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 24 Jul 2024 15:12:33 +0400 Subject: [PATCH 107/285] close button for small screen --- src/react/Fullmap.tsx | 13 +++++++++++-- src/react/MinimapDrawer.ts | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index de9242d4a..df8dd19bc 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -60,7 +60,7 @@ export default ({ toggleFullMap, adapter, drawer, canvasRef }: FullmapProps) => backgroundColor: 'rgba(0, 0, 0, 0.4)' }} > -
500 ?
}} onClick={toggleFullMap} >
- + :
: null } - diff --git a/src/reactUi.tsx b/src/reactUi.tsx index 2e3d2313b..216cfbcaa 100644 --- a/src/reactUi.tsx +++ b/src/reactUi.tsx @@ -118,7 +118,6 @@ const InGameUi = () => { - @@ -135,6 +134,7 @@ const InGameUi = () => { + {/* because of z-index */} {showUI && } From dc4b989fb7eec265327fde357fd9a577e70784b7 Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 24 Jul 2024 22:26:56 +0400 Subject: [PATCH 110/285] fix crash on loading --- src/react/MinimapProvider.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index eef96d3ff..db5a033bf 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -32,6 +32,7 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements if (!viewer.world.finishedChunks[`${chunkX},${chunkZ}`]) return 'rgb(200, 200, 200)' const block = viewer.world.highestBlocks[`${x},${z}`] const color = block ? BlockData.colors[block.name] ?? 'rgb(211, 211, 211)' : 'rgb(200, 200, 200)' + if (!block) return color // shadows const upKey = `${x},${z - 1}` From 9e6733e6ceca6e66cd07f47ede3ca8b32b10e38e Mon Sep 17 00:00:00 2001 From: gguio Date: Mon, 29 Jul 2024 12:22:40 +0400 Subject: [PATCH 111/285] chunk coords --- src/react/MinimapProvider.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index db5a033bf..ce701652f 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -7,6 +7,7 @@ import BlockData from '../../prismarine-viewer/viewer/lib/moreBlockDataGenerated import { contro } from '../controls' import { showModal, hideModal, miscUiState } from '../globalState' import { options } from '../optionsStorage' +import { longArrayToNumber } from '../loadSave' import Minimap from './Minimap' import { DrawerAdapter, MapUpdates } from './MinimapDrawer' import { useIsModalActive } from './utilsApp' @@ -134,6 +135,11 @@ export default () => { useEffect(() => { bot.on('move', updateMap) + bot._client.on('map_chunk', (data) => { + console.log('x:', data.x, 'z:', data.z) + console.log(data) + console.log(longArrayToNumber((data as any).heightmaps.value.WORLD_SURFACE.value[0])) + }) // viewer.world.renderUpdateEmitter.on('update', updateMap) contro.on('trigger', toggleFullMap) From aa49f7c201876960ad757eb4c73ac81598d2fb07 Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 2 Aug 2024 16:11:12 +0400 Subject: [PATCH 112/285] minimap with scale and fullmap without scale --- src/reactUi.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/reactUi.tsx b/src/reactUi.tsx index 216cfbcaa..13200909e 100644 --- a/src/reactUi.tsx +++ b/src/reactUi.tsx @@ -28,7 +28,7 @@ import PauseScreen from './react/PauseScreen' import SoundMuffler from './react/SoundMuffler' import TouchControls from './react/TouchControls' import widgets from './react/widgets' -import { useIsWidgetActive } from './react/utilsApp' +import { useIsModalActive, useIsWidgetActive } from './react/utilsApp' import GlobalSearchInput from './GlobalSearchInput' import TouchAreasControlsProvider from './react/TouchAreasControlsProvider' import NotificationProvider, { showNotification } from './react/NotificationProvider' @@ -101,6 +101,7 @@ const InGameComponent = ({ children }) => { const InGameUi = () => { const { gameLoaded, showUI: showUIRaw } = useSnapshot(miscUiState) const hasModals = useSnapshot(activeModalStack).length > 0 + const isFullmap = useIsModalActive('full-map') const showUI = showUIRaw || hasModals if (!gameLoaded || !bot) return @@ -115,6 +116,7 @@ const InGameUi = () => { + {!isFullmap && } @@ -134,7 +136,7 @@ const InGameUi = () => { - + {isFullmap && } {/* because of z-index */} {showUI && } From bf042798ea32ddf205a8464689f53bb8744be90f Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 2 Aug 2024 23:19:14 +0400 Subject: [PATCH 113/285] fullmap adjustements --- src/react/Fullmap.tsx | 43 ++++++++++++++++------------------- src/react/Minimap.tsx | 10 ++++---- src/react/MinimapDrawer.ts | 2 +- src/react/MinimapProvider.tsx | 16 ++++++------- src/reactUi.tsx | 5 ++-- 5 files changed, 37 insertions(+), 39 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index df8dd19bc..a7eba835e 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -27,13 +27,13 @@ export default ({ toggleFullMap, adapter, drawer, canvasRef }: FullmapProps) => const updateGrid = () => { const wrapperRect = zoomRef.current?.instance.wrapperComponent?.getBoundingClientRect() if (!wrapperRect) return - const cellSize = 32 + const cellSize = 64 const columns = Math.ceil(wrapperRect.width / (cellSize * stateRef.current.scale)) const rows = Math.ceil(wrapperRect.height / (cellSize * stateRef.current.scale)) cells.current.rows = rows cells.current.columns = columns - const leftBorder = - Math.floor(stateRef.current.positionX / (stateRef.current.scale * cellSize)) * cellSize - Math.floor(columns / 4) * cellSize - const topBorder = - Math.floor(stateRef.current.positionY / (stateRef.current.scale * cellSize)) * cellSize - Math.floor(rows / 4) * cellSize + const leftBorder = - Math.floor(stateRef.current.positionX / (stateRef.current.scale * cellSize)) * cellSize + const topBorder = - Math.floor(stateRef.current.positionY / (stateRef.current.scale * cellSize)) * cellSize const newGrid = new Set() for (let row = 0; row < rows; row += 1) { for (let col = 0; col < columns; col += 1) { @@ -57,7 +57,8 @@ export default ({ toggleFullMap, adapter, drawer, canvasRef }: FullmapProps) => display: 'flex', justifyContent: 'center', alignItems: 'center', - backgroundColor: 'rgba(0, 0, 0, 0.4)' + backgroundColor: 'rgba(0, 0, 0, 0.4)', + zIndex: 100 }} > { window.screen.width > 500 ?
ref={zoomRef} minScale={0.1} doubleClick={{ - disabled: true + disabled: false }} panning={{ - allowLeftClickPan: false, - allowRightClickPan: true, - allowMiddleClickPan: true + allowLeftClickPan: true, + allowRightClickPan: false }} onTransformed={(ref, state) => { stateRef.current = { ...state } @@ -112,8 +112,8 @@ export default ({ toggleFullMap, adapter, drawer, canvasRef }: FullmapProps) => const playerChunkLeft = Math.floor(adapter.playerPosition.x / 16) * 16 const playerChunkTop = Math.floor(adapter.playerPosition.z / 16) * 16 const wrapperRect = zoomRef.current?.instance.wrapperComponent?.getBoundingClientRect() - const offsetX = Math.floor((wrapperRect?.width ?? 0) / (12 * 16)) * 16 - const offsetY = Math.floor((wrapperRect?.height ?? 0) / (12 * 16)) * 16 + const offsetX = Math.floor((wrapperRect?.width ?? 0) / (8 * 16)) * 16 + const offsetY = Math.floor((wrapperRect?.height ?? 0) / (8 * 16)) * 16 return y={y} scale={stateRef.current.scale} adapter={adapter} - worldX={playerChunkLeft + x / 2 - offsetX} - worldZ={playerChunkTop + y / 2 - offsetY} + worldX={playerChunkLeft + x / 4 - offsetX } + worldZ={playerChunkTop + y / 4 - offsetY } setIsWarpInfoOpened={setIsWarpInfoOpened} setLastWarpPos={setLastWarpPos} redraw={redrawCell.current} @@ -165,7 +165,8 @@ const MapChunk = ( const [isCanvas, setIsCanvas] = useState(false) const handleClick = (e: MouseEvent) => { - if ('buttons' in e && e.buttons !== 0) return + console.log('click:', e) + if ('buttons' in e && e.button !== 2) return const rect = canvasRef.current!.getBoundingClientRect() const dpr = window.devicePixelRatio const x = (e.clientX - rect.left) / (scale * dpr) @@ -185,14 +186,10 @@ const MapChunk = ( }, [canvasRef.current, isCanvas]) useEffect(() => { - console.log('new scale:', scale) - }, [scale]) - - useEffect(() => { - canvasRef.current?.addEventListener('click', handleClick) + canvasRef.current?.addEventListener('contextmenu', handleClick) return () => { - canvasRef.current?.removeEventListener('click', handleClick) + canvasRef.current?.removeEventListener('contextmenu', handleClick) } }, [canvasRef.current, scale]) @@ -221,20 +218,20 @@ const MapChunk = ( ref={containerRef} style={{ position: 'absolute', - width: '32px', - height: '32px', + width: '64px', + height: '64px', top: `${y}px`, left: `${x}px`, }} > {isCanvas && }
} diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 5d30960c8..1cfad70dc 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -3,8 +3,10 @@ import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' import Fullmap from './Fullmap' +export type DisplayMode = 'fullmapOnly' | 'minimapOnly' + export default ( - { adapter, showMinimap, showFullmap, singleplayer, fullMap, toggleFullMap } + { adapter, showMinimap, showFullmap, singleplayer, fullMap, toggleFullMap, displayMode } : { adapter: DrawerAdapter, @@ -13,6 +15,7 @@ export default ( singleplayer: boolean, fullMap?: boolean, toggleFullMap?: ({ command }: { command: string }) => void + displayMode?: DisplayMode } ) => { const full = useRef(false) @@ -81,7 +84,7 @@ export default ( } }, [adapter]) - return fullMap && (showFullmap === 'singleplayer' && singleplayer || showFullmap === 'always') + return fullMap && displayMode !== 'minimapOnly' && (showFullmap === 'singleplayer' && singleplayer || showFullmap === 'always') ? { toggleFullMap?.({ command: 'ui.toggleMap' }) @@ -90,7 +93,7 @@ export default ( drawer={drawerRef.current} canvasRef={canvasRef} /> - : showMinimap === 'singleplayer' && singleplayer || showMinimap === 'always' + : displayMode !== 'fullmapOnly' && (showMinimap === 'singleplayer' && singleplayer || showMinimap === 'always') ?
{ toggleFullMap?.({ command: 'ui.toggleMap' }) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 4d9e407cd..1b581f88f 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -70,7 +70,7 @@ export class MinimapDrawer { ) { if (full) { this.radius = Math.floor(Math.min(this.canvas.width, this.canvas.height) / 2) - this._mapSize = this.radius * 2 + this._mapSize = 16 this.mapPixel = Math.floor(this.radius * 2 / this.mapSize) } this.ctx.clearRect( diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index ce701652f..21677de81 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -7,8 +7,7 @@ import BlockData from '../../prismarine-viewer/viewer/lib/moreBlockDataGenerated import { contro } from '../controls' import { showModal, hideModal, miscUiState } from '../globalState' import { options } from '../optionsStorage' -import { longArrayToNumber } from '../loadSave' -import Minimap from './Minimap' +import Minimap, { DisplayMode } from './Minimap' import { DrawerAdapter, MapUpdates } from './MinimapDrawer' import { useIsModalActive } from './utilsApp' @@ -111,7 +110,7 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } } -export default () => { +export default ({ displayMode }: { displayMode?: DisplayMode }) => { const [adapter] = useState(() => new DrawerAdapterImpl(bot.entity.position, localServer?.warps)) const fullMapOpened = useIsModalActive('full-map') @@ -135,11 +134,11 @@ export default () => { useEffect(() => { bot.on('move', updateMap) - bot._client.on('map_chunk', (data) => { - console.log('x:', data.x, 'z:', data.z) - console.log(data) - console.log(longArrayToNumber((data as any).heightmaps.value.WORLD_SURFACE.value[0])) - }) + // bot._client.on('map_chunk', (data) => { + // console.log('x:', data.x, 'z:', data.z) + // console.log(data) + // console.log(longArrayToNumber((data as any).heightmaps.value.WORLD_SURFACE.value[0])) + // }) // viewer.world.renderUpdateEmitter.on('update', updateMap) contro.on('trigger', toggleFullMap) @@ -160,6 +159,7 @@ export default () => { singleplayer={miscUiState.singleplayer} fullMap={fullMapOpened} toggleFullMap={toggleFullMap} + displayMode={displayMode} />
} diff --git a/src/reactUi.tsx b/src/reactUi.tsx index 13200909e..20de2cfc2 100644 --- a/src/reactUi.tsx +++ b/src/reactUi.tsx @@ -101,7 +101,6 @@ const InGameComponent = ({ children }) => { const InGameUi = () => { const { gameLoaded, showUI: showUIRaw } = useSnapshot(miscUiState) const hasModals = useSnapshot(activeModalStack).length > 0 - const isFullmap = useIsModalActive('full-map') const showUI = showUIRaw || hasModals if (!gameLoaded || !bot) return @@ -116,7 +115,7 @@ const InGameUi = () => { - {!isFullmap && } + @@ -136,7 +135,7 @@ const InGameUi = () => { - {isFullmap && } + {/* because of z-index */} {showUI && } From 5651670e0f5f982e9b505a2d2694372a4fff7c62 Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 2 Aug 2024 23:30:04 +0400 Subject: [PATCH 114/285] set warp scale --- src/react/Fullmap.tsx | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index a7eba835e..a42f4b00a 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -274,7 +274,8 @@ const WarpInfo = ( alignItems: 'center', flexDirection: 'column', backgroundColor: 'rgba(0, 0, 0, 0.5)', - fontSize: '0.8em' + fontSize: '0.8em', + transform: 'scale(3)' }} >
{ return { ...prev, x: Number(e.target.value) } }) }} /> -
- Y: -
- { - if (!e.target) return - setWarp(prev => { return { ...prev, y: Number(e.target.value) } }) - }} - />
Z:
From e794274caa184a34e14df5cfedf2e0f920330b9d Mon Sep 17 00:00:00 2001 From: gguio Date: Mon, 5 Aug 2024 16:37:51 +0400 Subject: [PATCH 115/285] fix set warp on full map --- src/react/Fullmap.tsx | 5 +++-- src/react/MinimapDrawer.ts | 21 +++++++++++++++++---- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index a42f4b00a..7169f0858 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -171,7 +171,7 @@ const MapChunk = ( const dpr = window.devicePixelRatio const x = (e.clientX - rect.left) / (scale * dpr) const y = (e.clientY - rect.top) / (scale * dpr) - drawerRef.current?.setWarpPosOnClick(new Vec3(Math.floor(x / 6), 0, Math.floor(y / 6)), new Vec3(worldX, 0, worldZ)) + drawerRef.current?.setWarpPosOnClick(new Vec3(Math.floor(x / 3), 0, Math.floor(y / 3)), new Vec3(worldX, 0, worldZ)) setLastWarpPos(drawerRef.current!.lastWarpPos) setIsWarpInfoOpened(true) } @@ -228,7 +228,8 @@ const MapChunk = ( ref={canvasRef} style={{ width: '100%', - height: '100%' + height: '100%', + imageRendering: 'pixelated' }} width={64} height={64} diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 1b581f88f..be4bd556b 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -202,8 +202,12 @@ export class MinimapDrawer { if (distance > this.mapSize) continue } const offset = full ? 0 : this.radius * 0.2 - const z = Math.floor((this.mapSize / 2 - (centerPos?.z ?? this.adapter.playerPosition.z) + warp.z)) + offset - const x = Math.floor((this.mapSize / 2 - (centerPos?.x ?? this.adapter.playerPosition.x) + warp.x)) + offset + const z = Math.floor( + (this.mapSize / 2 - (centerPos?.z ?? this.adapter.playerPosition.z) + warp.z) * this.mapPixel + ) + offset + const x = Math.floor( + (this.mapSize / 2 - (centerPos?.x ?? this.adapter.playerPosition.x) + warp.x) * this.mapPixel + ) + offset const dz = z - this.centerX const dx = x - this.centerY const circleDist = Math.hypot(dx, dz) @@ -216,9 +220,18 @@ export class MinimapDrawer { this.centerY + this.mapSize / 2 * Math.cos(angle) : x this.ctx.beginPath() - this.ctx.arc(circleX, circleZ, circleDist > this.mapSize / 2 && !full ? 1.5 : 2, 0, Math.PI * 2, false) + this.ctx.arc( + circleX, + circleZ, + circleDist > this.mapSize / 2 && !full + ? this.mapPixel * 1.5 + : full ? this.mapPixel : this.mapPixel * 2, + 0, + Math.PI * 2, + false + ) this.ctx.strokeStyle = 'black' - this.ctx.lineWidth = 1 + this.ctx.lineWidth = this.mapPixel this.ctx.stroke() this.ctx.fillStyle = warp.disabled ? 'rgba(255, 255, 255, 0.4)' : warp.color ?? '#d3d3d3' this.ctx.fill() From fd4cbc5de6e7d31666dcdbbca74f130b7f096b84 Mon Sep 17 00:00:00 2001 From: gguio Date: Tue, 6 Aug 2024 16:04:37 +0400 Subject: [PATCH 116/285] complete fix for set warp on click --- src/react/Fullmap.tsx | 17 +++++++++++------ src/react/MinimapDrawer.ts | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index 7169f0858..cdc0ca415 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -121,8 +121,8 @@ export default ({ toggleFullMap, adapter, drawer, canvasRef }: FullmapProps) => y={y} scale={stateRef.current.scale} adapter={adapter} - worldX={playerChunkLeft + x / 4 - offsetX } - worldZ={playerChunkTop + y / 4 - offsetY } + worldX={playerChunkLeft + x / 4 - offsetX} + worldZ={playerChunkTop + y / 4 - offsetY} setIsWarpInfoOpened={setIsWarpInfoOpened} setLastWarpPos={setLastWarpPos} redraw={redrawCell.current} @@ -169,9 +169,10 @@ const MapChunk = ( if ('buttons' in e && e.button !== 2) return const rect = canvasRef.current!.getBoundingClientRect() const dpr = window.devicePixelRatio - const x = (e.clientX - rect.left) / (scale * dpr) - const y = (e.clientY - rect.top) / (scale * dpr) - drawerRef.current?.setWarpPosOnClick(new Vec3(Math.floor(x / 3), 0, Math.floor(y / 3)), new Vec3(worldX, 0, worldZ)) + const factor = scale * (drawerRef.current?.mapPixel ?? 1) + const x = (e.clientX - rect.left) / factor + const y = (e.clientY - rect.top) / factor + drawerRef.current?.setWarpPosOnClick(new Vec3(Math.floor(x), 0, Math.floor(y)), new Vec3(worldX, 0, worldZ)) setLastWarpPos(drawerRef.current!.lastWarpPos) setIsWarpInfoOpened(true) } @@ -195,7 +196,11 @@ const MapChunk = ( useEffect(() => { if (drawerRef.current) { - drawerRef.current.draw(new Vec3(worldX + 8, 0, worldZ + 8), undefined, true) + drawerRef.current.draw( + new Vec3(worldX + 8, 0, worldZ + 8), + undefined, + true + ) } }, [drawerRef.current, redraw]) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index be4bd556b..9e420f137 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -187,7 +187,7 @@ export class MinimapDrawer { // const worldZ = z // console.log([(botPos.x + worldX).toFixed(0), (botPos.z + worldZ).toFixed(0)]) - this.lastWarpPos = new Vec3(Math.floor(botPos.x + mousePos.x), botPos.y, Math.floor(botPos.z + mousePos.z)) + this.lastWarpPos = new Vec3(Math.floor(botPos.x + mousePos.x), 0, Math.floor(botPos.z + mousePos.z)) } drawWarps (centerPos?: Vec3, full?: boolean) { From 6f2e18870c6552ea5021ee964a8d120559fe37af Mon Sep 17 00:00:00 2001 From: gguio Date: Tue, 6 Aug 2024 16:24:22 +0400 Subject: [PATCH 117/285] known issue: warps dont draw on minimap on server --- src/react/Minimap.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 1cfad70dc..5deb33cae 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -35,7 +35,10 @@ export default ( drawerRef.current.updateWorldColors(adapter.getHighestBlockColor, adapter.playerPosition.x, adapter.playerPosition.z, false) } if (canvasTick.current % 300 === 0) { - drawerRef.current.deleteOldWorldColors(adapter.playerPosition.x, adapter.playerPosition.z) + requestIdleCallback(() => { + drawerRef.current!.deleteOldWorldColors(adapter.playerPosition.x, adapter.playerPosition.z) + }) + canvasTick.current = 0 } } if (warpsDrawerRef.current) { From f7cede30e9546a96aa7fc62ec5f4b94116df9a0b Mon Sep 17 00:00:00 2001 From: gguio Date: Tue, 6 Aug 2024 21:29:59 +0400 Subject: [PATCH 118/285] persist warps --- src/react/MinimapProvider.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 21677de81..e9c16286a 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -22,7 +22,7 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements constructor (pos?: Vec3, warps?: WorldWarp[]) { super() this.playerPosition = pos ?? new Vec3(0, 0, 0) - this.warps = warps ?? [] as WorldWarp[] + this.warps = warps ?? localServer?.warps ?? [] as WorldWarp[] } async getHighestBlockColor (x: number, z: number) { @@ -97,7 +97,7 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } else { this.warps[index] = warp } - // if (localServer) void localServer.setWarp(warp) + if (localServer) void localServer.setWarp(warp) this.emit('updateWarps') } From bed71db3ac232b6434722bbb4ee5a5565cc4800b Mon Sep 17 00:00:00 2001 From: gguio Date: Tue, 6 Aug 2024 22:21:09 +0400 Subject: [PATCH 119/285] fix warp info width --- src/react/Fullmap.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index cdc0ca415..8b4f15f19 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -289,9 +289,9 @@ const WarpInfo = ( display: 'flex', flexDirection: 'column', gap: '10px', - width: '40%', + width: '100%', minWidth: '100px', - maxWidth: '150px', + maxWidth: '300px', padding: '20px', backgroundColor: 'rgba(0, 0, 0, 0.5)', border: '2px solid black' From 82bed0ba7a02dcd1112d8978c13c555b65bc04fc Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 7 Aug 2024 01:15:27 +0400 Subject: [PATCH 120/285] sync warps for fullmap and minimap on server --- src/globalState.ts | 3 +++ src/react/MinimapProvider.tsx | 12 ++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/globalState.ts b/src/globalState.ts index a332258bd..7d40b6f63 100644 --- a/src/globalState.ts +++ b/src/globalState.ts @@ -1,6 +1,7 @@ //@ts-check import { proxy, ref, subscribe } from 'valtio' +import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' import { pointerLock } from './utils' import type { OptionsGroupType } from './optionsGuiScheme' @@ -14,6 +15,8 @@ type ContextMenuItem = { callback; label } export const activeModalStack: Modal[] = proxy([]) +export const warps: WorldWarp[] = proxy([]) + export const insertActiveModalStack = (name: string, newModalStack = activeModalStacks[name]) => { hideModal(undefined, undefined, { restorePrevious: false, force: true }) activeModalStack.splice(0, activeModalStack.length, ...newModalStack) diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index e9c16286a..24fee4c71 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -5,7 +5,7 @@ import { TypedEventEmitter } from 'contro-max/build/typedEventEmitter' import { PCChunk } from 'prismarine-chunk' import BlockData from '../../prismarine-viewer/viewer/lib/moreBlockDataGenerated.json' import { contro } from '../controls' -import { showModal, hideModal, miscUiState } from '../globalState' +import { warps, showModal, hideModal, miscUiState } from '../globalState' import { options } from '../optionsStorage' import Minimap, { DisplayMode } from './Minimap' import { DrawerAdapter, MapUpdates } from './MinimapDrawer' @@ -19,10 +19,10 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements currChunk: PCChunk | undefined currChunkPos: { x: number, z: number } = { x: 0, z: 0 } - constructor (pos?: Vec3, warps?: WorldWarp[]) { + constructor (pos?: Vec3, initialWarps?: WorldWarp[]) { super() this.playerPosition = pos ?? new Vec3(0, 0, 0) - this.warps = warps ?? localServer?.warps ?? [] as WorldWarp[] + this.warps = initialWarps ?? localServer?.warps ?? warps } async getHighestBlockColor (x: number, z: number) { @@ -97,7 +97,11 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } else { this.warps[index] = warp } - if (localServer) void localServer.setWarp(warp) + if (localServer) { + void localServer.setWarp(warp) + } else if (!warps.some(w => w.name === warp.name)) { + warps.push(warp) + } this.emit('updateWarps') } From d3bac9f4fb07b75b2d74e877882a329a30311229 Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 7 Aug 2024 12:57:21 +0400 Subject: [PATCH 121/285] reset warp on click --- src/react/Fullmap.tsx | 79 ++++++++++++++++++++++++++----------------- 1 file changed, 48 insertions(+), 31 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index 8b4f15f19..506321e70 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -23,6 +23,7 @@ export default ({ toggleFullMap, adapter, drawer, canvasRef }: FullmapProps) => const stateRef = useRef({ scale: 1, positionX: 0, positionY: 0 }) const cells = useRef({ columns: 0, rows: 0 }) const [isWarpInfoOpened, setIsWarpInfoOpened] = useState(false) + const [initWarp, setInitWarp] = useState(undefined) const updateGrid = () => { const wrapperRect = zoomRef.current?.instance.wrapperComponent?.getBoundingClientRect() @@ -126,6 +127,7 @@ export default ({ toggleFullMap, adapter, drawer, canvasRef }: FullmapProps) => setIsWarpInfoOpened={setIsWarpInfoOpened} setLastWarpPos={setLastWarpPos} redraw={redrawCell.current} + setInitWarp={setInitWarp} /> })} @@ -133,11 +135,12 @@ export default ({ toggleFullMap, adapter, drawer, canvasRef }: FullmapProps) => { isWarpInfoOpened && { redrawCell.current = !redrawCell.current }} + initWarp={initWarp} /> }
@@ -145,19 +148,20 @@ export default ({ toggleFullMap, adapter, drawer, canvasRef }: FullmapProps) => const MapChunk = ( - { x, y, scale, adapter, worldX, worldZ, setIsWarpInfoOpened, setLastWarpPos, redraw } - : - { - x: number, - y: number, - scale: number, - adapter: DrawerAdapter, - worldX: number, - worldZ: number, - setIsWarpInfoOpened: (x: boolean) => void, - setLastWarpPos: (obj: { x: number, y: number, z: number }) => void, - redraw?: boolean - } + { x, y, scale, adapter, worldX, worldZ, setIsWarpInfoOpened, setLastWarpPos, redraw, setInitWarp } + : + { + x: number, + y: number, + scale: number, + adapter: DrawerAdapter, + worldX: number, + worldZ: number, + setIsWarpInfoOpened: (x: boolean) => void, + setLastWarpPos: (obj: { x: number, y: number, z: number }) => void, + redraw?: boolean + setInitWarp?: (warp: WorldWarp) => void + } ) => { const containerRef = useRef(null) const drawerRef = useRef(null) @@ -168,12 +172,17 @@ const MapChunk = ( console.log('click:', e) if ('buttons' in e && e.button !== 2) return const rect = canvasRef.current!.getBoundingClientRect() - const dpr = window.devicePixelRatio const factor = scale * (drawerRef.current?.mapPixel ?? 1) const x = (e.clientX - rect.left) / factor const y = (e.clientY - rect.top) / factor - drawerRef.current?.setWarpPosOnClick(new Vec3(Math.floor(x), 0, Math.floor(y)), new Vec3(worldX, 0, worldZ)) - setLastWarpPos(drawerRef.current!.lastWarpPos) + if (!drawerRef.current) return + drawerRef.current.setWarpPosOnClick(new Vec3(Math.floor(x), 0, Math.floor(y)), new Vec3(worldX, 0, worldZ)) + setLastWarpPos(drawerRef.current.lastWarpPos) + const { lastWarpPos } = drawerRef.current + if (adapter.warps.some(warp => Math.hypot(lastWarpPos.x - warp.x, lastWarpPos.z - warp.z) < 5)) { + const initWarp = adapter.warps.find(warp => Math.hypot(lastWarpPos.x - warp.x, lastWarpPos.z - warp.z) < 5) + if (initWarp) setInitWarp?.(initWarp) + } setIsWarpInfoOpened(true) } @@ -243,20 +252,21 @@ const MapChunk = ( } const WarpInfo = ( - { adapter, drawer, setIsWarpInfoOpened, afterWarpIsSet } - : - { - adapter: DrawerAdapter, - drawer: { x: number, y: number, z: number }, - setIsWarpInfoOpened: Dispatch>, - afterWarpIsSet?: () => void - } + { adapter, warpPos, setIsWarpInfoOpened, afterWarpIsSet, initWarp } + : + { + adapter: DrawerAdapter, + warpPos: { x: number, y: number, z: number }, + setIsWarpInfoOpened: Dispatch>, + afterWarpIsSet?: () => void + initWarp?: WorldWarp + } ) => { - const [warp, setWarp] = useState({ + const [warp, setWarp] = useState(initWarp ?? { name: '', - x: drawer?.x ?? 100, - y: drawer?.y ?? 100, - z: drawer?.z ?? 100, + x: warpPos?.x ?? 100, + y: warpPos?.y ?? 100, + z: warpPos?.z ?? 100, color: '#d3d3d3', disabled: false, world: adapter.world @@ -302,6 +312,7 @@ const WarpInfo = ( Name: { if (!e.target) return setWarp(prev => { return { ...prev, name: e.target.value } }) @@ -314,7 +325,7 @@ const WarpInfo = ( { if (!e.target) return setWarp(prev => { return { ...prev, x: Number(e.target.value) } }) @@ -325,7 +336,7 @@ const WarpInfo = ( { if (!e.target) return setWarp(prev => { return { ...prev, z: Number(e.target.value) } }) @@ -336,6 +347,7 @@ const WarpInfo = (
Color:
{ if (!e.target) return setWarp(prev => { return { ...prev, color: e.target.value } }) @@ -346,6 +358,7 @@ const WarpInfo = (
Disabled:
{ if (!e.target) return setWarp(prev => { return { ...prev, disabled: e.target.checked } }) @@ -355,6 +368,10 @@ const WarpInfo = (
{ if (!e.target) return setWarp(prev => { return { ...prev, z: Number(e.target.value) } }) @@ -384,6 +382,13 @@ const WarpInfo = ( afterWarpIsSet?.() }} >Add + - + >Delete } } diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index a877e5fbd..8f146db1c 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -100,7 +100,7 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements const index = this.warps.findIndex(w => w.name === name) if (index === -1) { this.warps.push(warp) - } else if (remove) { + } else if (remove && index !== -1) { this.warps.splice(index, 1) } else { this.warps[index] = warp From 1fb69f89c880087ba2dfad1924f8e8017630ffb8 Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 8 Aug 2024 22:23:36 +0400 Subject: [PATCH 131/285] set warp on long touch for mobile --- src/react/Fullmap.tsx | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index b81b9c2cc..4de7aa7b1 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -166,17 +166,37 @@ const MapChunk = ( ) => { const containerRef = useRef(null) const drawerRef = useRef(null) + const touchTimer = useRef | null>(null) const canvasRef = useRef(null) const [isCanvas, setIsCanvas] = useState(false) - const handleClick = (e: MouseEvent) => { + const longPress = (e) => { + touchTimer.current = setTimeout(() => { + touchTimer.current = null + handleClick(e) + }, 500) + } + + const cancel = () => { + if (touchTimer.current) clearTimeout(touchTimer.current) + } + + const handleClick = (e: MouseEvent | TouchEvent) => { console.log('click:', e) if (!drawerRef.current) return - if ('buttons' in e && e.button !== 2) return + let clientX: number + let clientY: number + if ('buttons' in e && e.button !== 2) { + clientX = e.clientX + clientY = e.clientY + } else { + clientX = (e as TouchEvent).changedTouches[0].clientX + clientY = (e as TouchEvent).changedTouches[0].clientY + } const rect = canvasRef.current!.getBoundingClientRect() const factor = scale * (drawerRef.current?.mapPixel ?? 1) - const x = (e.clientX - rect.left) / factor - const y = (e.clientY - rect.top) / factor + const x = (clientX - rect.left) / factor + const y = (clientY - rect.top) / factor drawerRef.current.setWarpPosOnClick(new Vec3(Math.floor(x), 0, Math.floor(y)), new Vec3(worldX, 0, worldZ)) setLastWarpPos(drawerRef.current.lastWarpPos) const { lastWarpPos } = drawerRef.current @@ -196,9 +216,15 @@ const MapChunk = ( useEffect(() => { canvasRef.current?.addEventListener('contextmenu', handleClick) + canvasRef.current?.addEventListener('touchstart', longPress) + canvasRef.current?.addEventListener('touchend', cancel) + canvasRef.current?.addEventListener('touchmove', cancel) return () => { canvasRef.current?.removeEventListener('contextmenu', handleClick) + canvasRef.current?.removeEventListener('touchstart', longPress) + canvasRef.current?.removeEventListener('touchend', cancel) + canvasRef.current?.removeEventListener('touchmove', cancel) } }, [canvasRef.current, scale]) @@ -380,7 +406,7 @@ const WarpInfo = ( afterWarpIsSet?.() }} >Add - { initWarp && } + >Delete} diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 8d5808998..7b55843c8 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -89,7 +89,6 @@ export class MinimapDrawer { this.lastBotPos = botPos void this.updateWorldColors(getHighestBlockColor ?? this.adapter.getHighestBlockColor, botPos.x, botPos.z, full) if (!full) this.drawPartsOfWorld() - this.drawWarps(botPos, full) } clearRect (full?: boolean) { @@ -147,6 +146,7 @@ export class MinimapDrawer { ) this.updatingPixels.delete(pixelKey) if (this.full) this.drawPlayerPos(x, z) + this.drawWarps(new Vec3(x, 0, z), this.full) } async getHighestBlockColorCached ( From 338ec03d60304011b8ec41a76e6035d7d30dfae4 Mon Sep 17 00:00:00 2001 From: gguio Date: Mon, 2 Sep 2024 15:39:57 +0400 Subject: [PATCH 177/285] delete updates fullmap. Fixes required: drawing warps causes lagging + after one warp is set then coords on fullmap are broken --- src/react/Fullmap.tsx | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index 20ff09e41..ec26ed329 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -354,6 +354,17 @@ const WarpInfo = ( gap: '5px' } + const updateRegion = () => { + for (let i = -1; i < 2; i += 1) { + for (let j = -1; j < 2; j += 1) { + adapter.emit( + 'cellReady', + `${(Math.floor(warp.x / 16) + j) * 16},${(Math.floor(warp.z / 16) + i) * 16}` + ) + } + } + } + return
Add @@ -461,6 +465,7 @@ const WarpInfo = ( if (index !== -1) { adapter.setWarp({ name: warp.name, x: 0, y: 0, z: 0, color: '', disabled: false, world: '' }, true) setIsWarpInfoOpened(false) + updateRegion() afterWarpIsSet?.() } }} From 79ca8183470ef9c215bbc50c65a57d3b850904e1 Mon Sep 17 00:00:00 2001 From: gguio Date: Tue, 3 Sep 2024 09:59:11 +0400 Subject: [PATCH 178/285] small fixes --- src/react/MinimapDrawer.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 7b55843c8..228e8d676 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -111,6 +111,7 @@ export class MinimapDrawer { z: number, full?: boolean ) { + if (this.adapter.chunksStore[`${Math.floor(x / 16) * 16},${Math.floor(z / 16) * 16}`] === null) return this.full = full for (let row = 0; row < this.mapSize; row += 1) { @@ -145,8 +146,11 @@ export class MinimapDrawer { this.mapPixel ) this.updatingPixels.delete(pixelKey) - if (this.full) this.drawPlayerPos(x, z) - this.drawWarps(new Vec3(x, 0, z), this.full) + if (this.full) { + this.drawPlayerPos(x, z) + const lastPixel = this.mapSize - 1 + if (col === lastPixel && row === lastPixel) this.drawWarps(new Vec3(x, 0, z), this.full) + } } async getHighestBlockColorCached ( From 65a8868927d2a5ac69d29174d3eda8b6b1b3f006 Mon Sep 17 00:00:00 2001 From: gguio Date: Tue, 3 Sep 2024 10:01:41 +0400 Subject: [PATCH 179/285] clean up --- src/react/Minimap.tsx | 19 ------------------- src/react/MinimapDrawer.ts | 11 ----------- 2 files changed, 30 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 1c7f65371..f7339f440 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -23,7 +23,6 @@ export default ( const warpsAndPartsCanvasRef = useRef(null) const warpsDrawerRef = useRef(null) const drawerRef = useRef(null) - const playerPosCanvas = useRef(null) const [position, setPosition] = useState({ x: 0, z: 0 }) const updateMap = () => { @@ -83,24 +82,6 @@ export default ( } }, [warpsAndPartsCanvasRef.current]) - // useEffect(() => { - // if (playerPosCanvas.current) { - // const ctx = playerPosCanvas.current.getContext('2d') - // if (ctx) { - // const path = new Path2D() - // const width = (canvasRef.current?.width ?? 80) / 2 - // const height = (canvasRef.current?.height ?? 80) / 2 - // path.moveTo(width, height * 0.9) - // path.lineTo(width * 0.9, height * 1.1) - // path.lineTo(width * 1.1, height * 1.1) - // - // ctx.fillStyle = '#FFFFFF' - // ctx.strokeStyle = '#000000' - // ctx.fill(path) - // } - // } - // }, [playerPosCanvas.current]) - useEffect(() => { adapter.on('updateMap', updateMap) adapter.on('updateWaprs', updateWarps) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 228e8d676..a0eee2386 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -153,17 +153,6 @@ export class MinimapDrawer { } } - async getHighestBlockColorCached ( - getHighestBlockColor: DrawerAdapter['getHighestBlockColor'], - x: number, - z: number - ) { - return new Promise((resolve) => { - const color = getHighestBlockColor(x, z) - resolve(color) - }) - } - getDistance (x1: number, z1: number, x2: number, z2: number): number { return Math.hypot((x2 - x1), (z2 - z1)) } From 15bcf3d8b27674dfe493ee854f8f0da77df0376d Mon Sep 17 00:00:00 2001 From: gguio Date: Tue, 3 Sep 2024 10:29:42 +0400 Subject: [PATCH 180/285] fix coords on fullmap are broken --- src/react/Fullmap.tsx | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index ec26ed329..05d5e8ee9 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -237,6 +237,7 @@ const MapChunk = ( setWarpPreview?.( warp ? { name: warp.name, x: warp.x, z: warp.z, clientX: e.clientX, clientY: e.clientY } : undefined ) + console.log('pos:', x, z) } const handleRedraw = (key?: string) => { @@ -253,13 +254,18 @@ const MapChunk = ( } useEffect(() => { - if (canvasRef.current && isCanvas && !drawerRef.current) { + if (canvasRef.current && !drawerRef.current) { drawerRef.current = new MinimapDrawer(canvasRef.current, adapter) drawerRef.current.draw(new Vec3(worldX + 8, 0, worldZ + 8), undefined, true) - } else if (canvasRef.current && isCanvas && drawerRef.current) { + } else if (canvasRef.current && drawerRef.current) { drawerRef.current.canvas = canvasRef.current + drawerRef.current.draw( + new Vec3(worldX + 8, 0, worldZ + 8), + undefined, + true + ) } - }, [canvasRef.current, isCanvas]) + }, [canvasRef.current]) useEffect(() => { canvasRef.current?.addEventListener('contextmenu', handleClick) @@ -311,7 +317,7 @@ const MapChunk = ( left: `${x}px`, }} > - {isCanvas && } + />
} From 41f0a83f59dceca81d24087bc3651b957ce7a7b3 Mon Sep 17 00:00:00 2001 From: gguio Date: Tue, 3 Sep 2024 10:59:49 +0400 Subject: [PATCH 181/285] interface fixes on set warp window --- src/react/Fullmap.tsx | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index 05d5e8ee9..495ca5438 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -384,7 +384,7 @@ const WarpInfo = ( transform: 'scale(2)' }} > -
+

Point on the map

Name: @@ -407,6 +408,7 @@ const WarpInfo = ( if (!e.target) return setWarp(prev => { return { ...prev, name: e.target.value } }) }} + autoFocus />
@@ -436,8 +438,8 @@ const WarpInfo = (
Color:
{ if (!e.target) return setWarp(prev => { return { ...prev, color: e.target.value } }) @@ -445,8 +447,9 @@ const WarpInfo = ( />
-
Disabled:
+ { @@ -456,6 +459,11 @@ const WarpInfo = ( />
+ + type='submit' + >Add Warp {initWarp && } -
-
+
} From 4bb87ddda4cb1b94dd3e5845f7c6a4d89a7786bd Mon Sep 17 00:00:00 2001 From: gguio Date: Tue, 3 Sep 2024 11:21:27 +0400 Subject: [PATCH 182/285] quick tp --- src/react/Fullmap.tsx | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index 495ca5438..8343cc3bf 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -160,6 +160,7 @@ export default ({ toggleFullMap, adapter }: FullmapProps) => { }} initWarp={initWarp} setInitWarp={setInitWarp} + toggleFullMap={toggleFullMap} /> }
@@ -331,14 +332,15 @@ const MapChunk = ( } const WarpInfo = ( - { adapter, warpPos, setIsWarpInfoOpened, afterWarpIsSet, initWarp }: + { adapter, warpPos, setIsWarpInfoOpened, afterWarpIsSet, initWarp, toggleFullMap }: { adapter: DrawerAdapter, warpPos: { x: number, y: number, z: number }, setIsWarpInfoOpened: Dispatch>, afterWarpIsSet?: () => void initWarp?: WorldWarp, - setInitWarp?: React.Dispatch> + setInitWarp?: React.Dispatch>, + toggleFullMap?: ({ command }: { command: string }) => void } ) => { const [warp, setWarp] = useState(initWarp ?? { @@ -371,6 +373,12 @@ const WarpInfo = ( } } + const quickTp = () => { + const y = adapter.getHighestBlockY(warp.x, warp.z) + toggleFullMap?.({ command: 'ui.toggleMap' }) + bot.chat(`/tp ${warp.x} ${y + 10} ${warp.z}`) + } + return
+
- { - isOpen &&
- {links.map(el => { - return - })} -
- } - -} From fda6db79a10fa36b64583c84579e35226e543d88 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Thu, 12 Sep 2024 02:49:09 +0300 Subject: [PATCH 195/285] Fix Setting, [perf] do not update minimap twice and do not update at all if not enabled or opened, fix logging --- src/optionsGuiScheme.tsx | 10 +---- src/optionsStorage.ts | 1 - src/react/MinimapProvider.tsx | 69 ++++++++++++++++++++++------------- 3 files changed, 44 insertions(+), 36 deletions(-) diff --git a/src/optionsGuiScheme.tsx b/src/optionsGuiScheme.tsx index 8f5a334b7..46c5d3f8c 100644 --- a/src/optionsGuiScheme.tsx +++ b/src/optionsGuiScheme.tsx @@ -237,15 +237,7 @@ export const guiOptionsScheme: { return Map }, showMinimap: { - text: 'Show minimap', - values: [ - 'always', - 'singleplayer', - 'never' - ], - }, - showFullmap: { - text: 'Show fullmap', + text: 'Enable Minimap', values: [ 'always', 'singleplayer', diff --git a/src/optionsStorage.ts b/src/optionsStorage.ts index b214731a8..03f690182 100644 --- a/src/optionsStorage.ts +++ b/src/optionsStorage.ts @@ -83,7 +83,6 @@ const defaultOptions = { autoSignEditor: true, wysiwygSignEditor: 'auto' as 'auto' | 'always' | 'never', showMinimap: 'always' as 'always' | 'singleplayer' | 'never', - showFullmap: 'always' as 'always' | 'singleplayer' | 'never', displayBossBars: false, // boss bar overlay was removed for some reason, enable safely disabledUiParts: [] as string[], neighborChunkUpdates: true diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 3f27cc136..f8aaff3c6 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -7,10 +7,11 @@ import { PCChunk } from 'prismarine-chunk' import { Chunk } from 'prismarine-world/types/world' import { INVISIBLE_BLOCKS } from 'prismarine-viewer/viewer/lib/mesher/worldConstants' import { getRenamedData } from 'flying-squid/dist/blockRenames' +import { useSnapshot } from 'valtio' import BlockData from '../../prismarine-viewer/viewer/lib/moreBlockDataGenerated.json' import preflatMap from '../preflatMap.json' import { contro } from '../controls' -import { gameAdditionalState, showModal, hideModal, miscUiState, loadedGameState } from '../globalState' +import { gameAdditionalState, showModal, hideModal, miscUiState, loadedGameState, activeModalStack } from '../globalState' import { options } from '../optionsStorage' import Minimap, { DisplayMode } from './Minimap' import { DrawerAdapter, MapUpdates } from './MinimapDrawer' @@ -51,14 +52,12 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements this.overwriteWarps(JSON.parse(storageWarps ?? '[]')) } this.isOldVersion = versionToNumber(bot.version) < versionToNumber('1.13') - console.log('version is old:', this.isOldVersion) this.blockData = {} for (const blockKey of Object.keys(BlockData.colors)) { const renamedKey = getRenamedData('blocks', blockKey, '1.20.2', bot.version) this.blockData[renamedKey as string] = BlockData.colors[blockKey] } - console.log('block data:', this.blockData) } overwriteWarps (newWarps: WorldWarp[]) { @@ -81,7 +80,7 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } this.chunksStore[`${chunkX},${chunkZ}`] = null this.loadingChunksCount += 1 - console.log('loading:', chunkX, chunkZ) + console.log('[minimap] loading:', chunkX, chunkZ) this.loadChunk(chunkX, chunkZ) return emptyColor } @@ -251,9 +250,9 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements this.chunksStore[`${chunkX},${chunkZ}`] = res this.emit(`cellReady`, `${chunkX},${chunkZ}`) this.loadingChunksCount -= 1 - console.log('loaded:', chunkX, chunkZ, res) + console.log('[minimap] loaded:', chunkX, chunkZ, res) } - ).catch((err) => { console.warn('failed to get chunk:', chunkX, chunkZ) }) + ).catch((err) => { console.warn('[minimap] failed to get chunk:', chunkX, chunkZ) }) } clearChunksStore (x: number, z: number) { @@ -281,9 +280,8 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } } -export default ({ displayMode }: { displayMode?: DisplayMode }) => { +const Inner = ({ displayMode }: { displayMode?: DisplayMode }) => { const [adapter] = useState(() => new DrawerAdapterImpl(bot.entity.position)) - const fullMapOpened = useIsModalActive('full-map') const updateWarps = (newWarps: WorldWarp[] | Error) => { if (newWarps instanceof Error) { @@ -301,40 +299,59 @@ export default ({ displayMode }: { displayMode?: DisplayMode }) => { adapter.emit('updateMap') } - const toggleFullMap = ({ command }: { command?: string }) => { - if (!adapter) return - if (command === 'ui.toggleMap') { - if (fullMapOpened) { - hideModal({ reactType: 'full-map' }) - } else { - showModal({ reactType: 'full-map' }) - } - } - } - useEffect(() => { bot.on('move', updateMap) - contro.on('trigger', toggleFullMap) localServer?.on('warpsUpdated' as keyof ServerEvents, updateWarps) return () => { bot?.off('move', updateMap) - contro?.off('trigger', toggleFullMap) localServer?.off('warpsUpdated' as keyof ServerEvents, updateWarps) } }, []) - if (options.showMinimap === 'never' && options.showFullmap === 'never') return null - return
{ + hideModal() + }} displayMode={displayMode} />
} + +export default ({ displayMode }: { displayMode?: DisplayMode }) => { + const { showMinimap } = useSnapshot(options) + const fullMapOpened = useIsModalActive('full-map') + + useEffect(() => { + if (displayMode !== 'fullmapOnly') return + const toggleFullMap = ({ command }: { command?: string }) => { + if (command === 'ui.toggleMap') { + if (activeModalStack.at(-1)?.reactType === 'full-map') { + hideModal({ reactType: 'full-map' }) + } else { + showModal({ reactType: 'full-map' }) + } + } + } + contro?.on('trigger', toggleFullMap) + return () => { + contro?.off('trigger', toggleFullMap) + } + }, []) + + if ( + displayMode === 'minimapOnly' + ? showMinimap === 'never' || (showMinimap === 'singleplayer' && !miscUiState.singleplayer) + : !fullMapOpened + ) { + return null + } + + return +} From 77b011a937941fc3c9a11da0da7a3a785618cf36 Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 13 Sep 2024 02:17:38 +0400 Subject: [PATCH 196/285] using heightmaps when possible --- src/react/MinimapProvider.tsx | 72 ++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index f8aaff3c6..1ee076171 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -1,4 +1,8 @@ +import fs from 'fs' import { useEffect, useState } from 'react' +import { versions } from 'minecraft-data' +import { simplify } from 'prismarine-nbt' +import RegionFile from 'prismarine-provider-anvil/src/region' import { Vec3 } from 'vec3' import { versionToNumber } from 'prismarine-viewer/viewer/prepare/utils' import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' @@ -34,6 +38,8 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements isOldVersion: boolean blockData: any heightMap: Record = {} + regions: Record = {} + chunksHeightmaps: Record = {} constructor (pos?: Vec3) { super() @@ -204,6 +210,23 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements return color } + async getChunkHeightMapFromRegion (chunkX: number, chunkZ: number, cb?: (hm: number[]) => void) { + const regionX = Math.floor(chunkX / 32) + const regionZ = Math.floor(chunkZ / 32) + const { worldFolder } = localServer!.options + const path = `${worldFolder}/region/r.${regionX}.${regionZ}.mca` + if (!this.regions[`${regionX},${regionZ}`]) { + const region = new RegionFile(path) + await region.initialize() + this.regions[`${regionX},${regionZ}`] = region + } + const rawChunk = await this.regions[`${regionX},${regionZ}`].read(chunkX - regionX * 32, chunkZ - regionZ * 32) + const chunk = simplify(rawChunk as any) + console.log(`heightmaps ${chunkX}, ${chunkZ}:`, chunk.HeightMap) + this.chunksHeightmaps[`${chunkX / 16},${chunkZ / 16}`] = chunk.HeightMap + cb?.(chunk.HeigtMap) + } + setWarp (warp: WorldWarp, remove?: boolean): void { this.world = bot.game.dimension const index = this.warps.findIndex(w => w.name === warp.name) @@ -226,9 +249,15 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } getHighestBlockY (x: number, z: number, chunk?: Chunk) { + const chunkX = Math.floor(x / 16) * 16 + const chunkZ = Math.floor(z / 16) * 16 + if (this.chunksHeightmaps[`${chunkX},${chunkZ}`]) { + return this.chunksHeightmaps[`${chunkX},${chunkZ}`][x + z - chunkX - chunkZ] + } + const source = chunk ?? bot.world const { height, minY } = (bot.game as any) for (let i = height; i > 0; i -= 1) { - const block = chunk ? chunk.getBlock(new Vec3(x & 15, minY + i, z & 15)) : bot.world.getBlock(new Vec3(x, minY + i, z)) + const block = source.getBlock(new Vec3(x & 15, minY + i, z & 15)) if (block && !INVISIBLE_BLOCKS.has(block.name)) { return minY + i } @@ -245,6 +274,7 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } loadChunk (chunkX: number, chunkZ: number) { + void this.getChunkHeightMapFromRegion(chunkX / 16, chunkZ / 16) this.getChunkSingleplayer(chunkX, chunkZ).then( (res) => { this.chunksStore[`${chunkX},${chunkZ}`] = res @@ -328,6 +358,46 @@ export default ({ displayMode }: { displayMode?: DisplayMode }) => { const { showMinimap } = useSnapshot(options) const fullMapOpened = useIsModalActive('full-map') + const readChunksHeightMaps = async () => { + const { worldFolder } = localServer!.options + const path = `${worldFolder}/region/r.0.0.mca` + const region = new RegionFile(path) + await region.initialize() + const chunks: Record = {} + console.log('Reading chunks...') + console.log(chunks) + let versionDetected = false + for (const [i, _] of Array.from({ length: 32 }).entries()) { + for (const [k, _] of Array.from({ length: 32 }).entries()) { + // todo, may use faster reading, but features is not commonly used + // eslint-disable-next-line no-await-in-loop + const nbt = await region.read(i, k) + chunks[`${i},${k}`] = nbt + if (nbt && !versionDetected) { + const simplified = simplify(nbt) + const version = versions.pc.find(x => x['dataVersion'] === simplified.DataVersion)?.minecraftVersion + console.log('Detected version', version ?? 'unknown') + versionDetected = true + } + } + } + Object.defineProperty(chunks, 'simplified', { + get () { + const mapped = {} + for (const [i, _] of Array.from({ length: 32 }).entries()) { + for (const [k, _] of Array.from({ length: 32 }).entries()) { + const key = `${i},${k}` + const chunk = chunks[key] + if (!chunk) continue + mapped[key] = simplify(chunk) + } + } + return mapped + }, + }) + console.log('Done!', chunks) + } + useEffect(() => { if (displayMode !== 'fullmapOnly') return const toggleFullMap = ({ command }: { command?: string }) => { From c4493917e96529b48f2d9694a4659cdddd476098 Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 13 Sep 2024 02:23:15 +0400 Subject: [PATCH 197/285] clean up for heightmap --- src/react/MinimapProvider.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 1ee076171..176c19a1f 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -223,7 +223,7 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements const rawChunk = await this.regions[`${regionX},${regionZ}`].read(chunkX - regionX * 32, chunkZ - regionZ * 32) const chunk = simplify(rawChunk as any) console.log(`heightmaps ${chunkX}, ${chunkZ}:`, chunk.HeightMap) - this.chunksHeightmaps[`${chunkX / 16},${chunkZ / 16}`] = chunk.HeightMap + this.chunksHeightmaps[`${chunkX * 16},${chunkZ * 16}`] = chunk.HeightMap cb?.(chunk.HeigtMap) } @@ -290,6 +290,7 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements const [chunkX, chunkZ] = key.split(',').map(Number) if (Math.hypot((chunkX - x), (chunkZ - z)) > 300) { delete this.chunksStore[key] + delete this.chunksHeightmaps[key] for (let i = 0; i < 16; i += 1) { for (let j = 0; j < 16; j += 1) { delete this.heightMap[`${chunkX + i},${chunkZ + j}`] From 2cb3a158e4490b8915adddfa4d4b1f644a7c3acc Mon Sep 17 00:00:00 2001 From: gguio Date: Mon, 16 Sep 2024 09:41:21 +0400 Subject: [PATCH 198/285] fixed heightmap name --- src/react/MinimapProvider.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 176c19a1f..0d3924798 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -222,9 +222,10 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } const rawChunk = await this.regions[`${regionX},${regionZ}`].read(chunkX - regionX * 32, chunkZ - regionZ * 32) const chunk = simplify(rawChunk as any) - console.log(`heightmaps ${chunkX}, ${chunkZ}:`, chunk.HeightMap) - this.chunksHeightmaps[`${chunkX * 16},${chunkZ * 16}`] = chunk.HeightMap - cb?.(chunk.HeigtMap) + console.log(`chunk ${chunkX}, ${chunkZ}:`, chunk) + console.log(`heightmap ${chunkX}, ${chunkZ}:`, chunk.Heightmaps) + this.chunksHeightmaps[`${chunkX * 16},${chunkZ * 16}`] = chunk.Heightmaps + cb?.(chunk.Heightmaps) } setWarp (warp: WorldWarp, remove?: boolean): void { From 6415adaca45271f4046de3b0d71333cf08afec82 Mon Sep 17 00:00:00 2001 From: gguio Date: Mon, 16 Sep 2024 10:00:29 +0400 Subject: [PATCH 199/285] heightmap is better found --- src/react/MinimapProvider.tsx | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 0d3924798..a415cc3f3 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -25,6 +25,22 @@ const getBlockKey = (x: number, z: number) => { return `${x},${z}` } +const findHeightMap = (obj: any): any => { + function search (obj: any): any | undefined { + for (const key in obj) { + if (typeof obj[key] === 'object' && obj[key] !== null) { + const result = search(obj[key]) + if (result !== undefined) { + return result + } + } else if (['heightmap', 'heightmaps'].includes(key.toLowerCase())) { + return obj[key] + } + } + } + return search(obj) +} + export class DrawerAdapterImpl extends TypedEventEmitter implements DrawerAdapter { playerPosition: Vec3 yaw: number @@ -223,9 +239,10 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements const rawChunk = await this.regions[`${regionX},${regionZ}`].read(chunkX - regionX * 32, chunkZ - regionZ * 32) const chunk = simplify(rawChunk as any) console.log(`chunk ${chunkX}, ${chunkZ}:`, chunk) - console.log(`heightmap ${chunkX}, ${chunkZ}:`, chunk.Heightmaps) - this.chunksHeightmaps[`${chunkX * 16},${chunkZ * 16}`] = chunk.Heightmaps - cb?.(chunk.Heightmaps) + const heightmap = findHeightMap(chunk) + console.log(`heightmap ${chunkX}, ${chunkZ}:`, heightmap) + this.chunksHeightmaps[`${chunkX * 16},${chunkZ * 16}`] = heightmap + cb?.(heightmap) } setWarp (warp: WorldWarp, remove?: boolean): void { From a7ad5c761553ee0d8b53aa78eebef40c027fa4f1 Mon Sep 17 00:00:00 2001 From: gguio Date: Mon, 16 Sep 2024 12:14:28 +0400 Subject: [PATCH 200/285] fix heightmap search --- src/react/MinimapProvider.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index a415cc3f3..e7861fb84 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -28,13 +28,13 @@ const getBlockKey = (x: number, z: number) => { const findHeightMap = (obj: any): any => { function search (obj: any): any | undefined { for (const key in obj) { - if (typeof obj[key] === 'object' && obj[key] !== null) { + if (['heightmap', 'heightmaps'].includes(key.toLowerCase())) { + return obj[key] + } else if (typeof obj[key] === 'object' && obj[key] !== null) { const result = search(obj[key]) if (result !== undefined) { return result } - } else if (['heightmap', 'heightmaps'].includes(key.toLowerCase())) { - return obj[key] } } } From 9b499ccdb216e94dfb019e1dc6dd1e78a33282b6 Mon Sep 17 00:00:00 2001 From: gguio Date: Mon, 16 Sep 2024 12:32:59 +0400 Subject: [PATCH 201/285] fix chunks coords in heightmap --- src/react/MinimapProvider.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index e7861fb84..82779bbdd 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -270,7 +270,7 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements const chunkX = Math.floor(x / 16) * 16 const chunkZ = Math.floor(z / 16) * 16 if (this.chunksHeightmaps[`${chunkX},${chunkZ}`]) { - return this.chunksHeightmaps[`${chunkX},${chunkZ}`][x + z - chunkX - chunkZ] + return this.chunksHeightmaps[`${chunkX},${chunkZ}`][x - chunkX + (z - chunkZ) * 16] } const source = chunk ?? bot.world const { height, minY } = (bot.game as any) From e107583549dda90a5c96bfa15199f6cf0c60c2f7 Mon Sep 17 00:00:00 2001 From: gguio Date: Mon, 16 Sep 2024 12:49:58 +0400 Subject: [PATCH 202/285] heightmap y fix --- src/react/MinimapProvider.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 82779bbdd..b4af4b6fb 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -270,7 +270,7 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements const chunkX = Math.floor(x / 16) * 16 const chunkZ = Math.floor(z / 16) * 16 if (this.chunksHeightmaps[`${chunkX},${chunkZ}`]) { - return this.chunksHeightmaps[`${chunkX},${chunkZ}`][x - chunkX + (z - chunkZ) * 16] + return this.chunksHeightmaps[`${chunkX},${chunkZ}`][x - chunkX + (z - chunkZ) * 16] - 1 } const source = chunk ?? bot.world const { height, minY } = (bot.game as any) From a7aac8bcb59f9bfda3c543c21350b0a0bf2664a8 Mon Sep 17 00:00:00 2001 From: gguio Date: Mon, 16 Sep 2024 14:24:19 +0400 Subject: [PATCH 203/285] fix open fullmap on mobile --- src/react/MinimapProvider.tsx | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index b4af4b6fb..bfe4cc0f3 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -329,7 +329,13 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } } -const Inner = ({ displayMode }: { displayMode?: DisplayMode }) => { +const Inner = ( + { displayMode, toggleFullMap }: + { + displayMode?: DisplayMode, + toggleFullMap?: ({ command }: { command?: string }) => void + } +) => { const [adapter] = useState(() => new DrawerAdapterImpl(bot.entity.position)) const updateWarps = (newWarps: WorldWarp[] | Error) => { @@ -365,9 +371,7 @@ const Inner = ({ displayMode }: { displayMode?: DisplayMode }) => { showFullmap='always' singleplayer={miscUiState.singleplayer} fullMap={displayMode === 'fullmapOnly'} - toggleFullMap={() => { - hideModal() - }} + toggleFullMap={toggleFullMap} displayMode={displayMode} />
@@ -417,17 +421,18 @@ export default ({ displayMode }: { displayMode?: DisplayMode }) => { console.log('Done!', chunks) } - useEffect(() => { - if (displayMode !== 'fullmapOnly') return - const toggleFullMap = ({ command }: { command?: string }) => { - if (command === 'ui.toggleMap') { - if (activeModalStack.at(-1)?.reactType === 'full-map') { - hideModal({ reactType: 'full-map' }) - } else { - showModal({ reactType: 'full-map' }) - } + const toggleFullMap = ({ command }: { command?: string }) => { + if (command === 'ui.toggleMap') { + if (activeModalStack.at(-1)?.reactType === 'full-map') { + hideModal({ reactType: 'full-map' }) + } else { + showModal({ reactType: 'full-map' }) } } + } + + useEffect(() => { + if (displayMode !== 'fullmapOnly') return contro?.on('trigger', toggleFullMap) return () => { contro?.off('trigger', toggleFullMap) @@ -442,5 +447,5 @@ export default ({ displayMode }: { displayMode?: DisplayMode }) => { return null } - return + return } From a6d6818f044cc58e18886f9a6d778028d64dbc20 Mon Sep 17 00:00:00 2001 From: gguio Date: Mon, 16 Sep 2024 14:41:33 +0400 Subject: [PATCH 204/285] Y in position --- src/react/Minimap.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index f7339f440..6ac6792f8 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -23,10 +23,10 @@ export default ( const warpsAndPartsCanvasRef = useRef(null) const warpsDrawerRef = useRef(null) const drawerRef = useRef(null) - const [position, setPosition] = useState({ x: 0, z: 0 }) + const [position, setPosition] = useState({ x: 0, y: 0, z: 0 }) const updateMap = () => { - setPosition({ x: adapter.playerPosition.x, z: adapter.playerPosition.z }) + setPosition({ x: adapter.playerPosition.x, y: adapter.playerPosition.y, z: adapter.playerPosition.z }) if (drawerRef.current) { if (!full.current && canvasTick.current % 3 === 0) { rotateMap() @@ -142,7 +142,7 @@ export default ( textShadow: '0.1em 0 black, 0 0.1em black, -0.1em 0 black, 0 -0.1em black, -0.1em -0.1em black, -0.1em 0.1em black, 0.1em -0.1em black, 0.1em 0.1em black' }} > - {position.x.toFixed(2)} {position.z.toFixed(2)} + {position.x.toFixed(2)} {position.y.toFixed(2)} {position.z.toFixed(2)} : null } From a4ea91441aff2ae0f02924b231da7976a1dc87dd Mon Sep 17 00:00:00 2001 From: gguio Date: Mon, 23 Sep 2024 12:45:14 +0400 Subject: [PATCH 205/285] player position on minimap is stable --- src/react/Minimap.tsx | 26 +++++++++++++++++++++++++- src/react/MinimapDrawer.ts | 4 ++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 6ac6792f8..a0a851f3b 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -21,8 +21,10 @@ export default ( const canvasTick = useRef(0) const canvasRef = useRef(null) const warpsAndPartsCanvasRef = useRef(null) + const playerPosCanvasRef = useRef(null) const warpsDrawerRef = useRef(null) const drawerRef = useRef(null) + const playerPosDrawerRef = useRef(null) const [position, setPosition] = useState({ x: 0, y: 0, z: 0 }) const updateMap = () => { @@ -51,9 +53,11 @@ export default ( warpsDrawerRef.current.clearRect() warpsDrawerRef.current.drawPartsOfWorld() warpsDrawerRef.current.drawWarps() - warpsDrawerRef.current.drawPlayerPos() } } + if (playerPosDrawerRef.current && !full.current) { + playerPosDrawerRef.current.drawPlayerPos(null as any, null as any, true) + } canvasTick.current += 1 } @@ -82,6 +86,15 @@ export default ( } }, [warpsAndPartsCanvasRef.current]) + useEffect(() => { + if (playerPosCanvasRef.current && !playerPosDrawerRef.current) { + playerPosDrawerRef.current = new MinimapDrawer(playerPosCanvasRef.current, adapter) + } else if (playerPosCanvasRef.current && playerPosDrawerRef.current) { + playerPosDrawerRef.current.canvas = playerPosCanvasRef.current + } + + }, [playerPosCanvasRef.current]) + useEffect(() => { adapter.on('updateMap', updateMap) adapter.on('updateWaprs', updateWarps) @@ -136,6 +149,17 @@ export default ( height={80} ref={warpsAndPartsCanvasRef} /> +
Date: Mon, 23 Sep 2024 12:54:57 +0400 Subject: [PATCH 206/285] fix color picker for ios --- src/react/Fullmap.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index 3c883fec1..a73fde53c 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -455,6 +455,9 @@ const WarpInfo = ( if (!e.target) return setWarp(prev => { return { ...prev, color: e.target.value } }) }} + rootStyles={{ + width: /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream ? '20px' : '200px', + }} />
From 5e32e381d43bdefc679a9d3ee7fb37f49efca2ba Mon Sep 17 00:00:00 2001 From: gguio Date: Mon, 23 Sep 2024 13:10:29 +0400 Subject: [PATCH 207/285] small color picker --- src/react/Fullmap.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index a73fde53c..832943e88 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -455,9 +455,7 @@ const WarpInfo = ( if (!e.target) return setWarp(prev => { return { ...prev, color: e.target.value } }) }} - rootStyles={{ - width: /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream ? '20px' : '200px', - }} + rootStyles={{ width: '20px', }} />
From 6132d9f3feb99505bb727d1eeedaf26d4d34d455 Mon Sep 17 00:00:00 2001 From: gguio Date: Mon, 23 Sep 2024 13:25:34 +0400 Subject: [PATCH 208/285] better alignment for color picker --- src/react/Fullmap.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index 832943e88..663489d6c 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -455,7 +455,8 @@ const WarpInfo = ( if (!e.target) return setWarp(prev => { return { ...prev, color: e.target.value } }) }} - rootStyles={{ width: '20px', }} + rootStyles={{ width: '30px', }} + style={{ left: '0px' }} />
From 27a297620d895fb61c402d18e59a02e928ae0250 Mon Sep 17 00:00:00 2001 From: gguio Date: Mon, 23 Sep 2024 15:03:40 +0400 Subject: [PATCH 209/285] faster map redraw --- src/react/Minimap.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index a0a851f3b..5f710e9db 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -30,7 +30,7 @@ export default ( const updateMap = () => { setPosition({ x: adapter.playerPosition.x, y: adapter.playerPosition.y, z: adapter.playerPosition.z }) if (drawerRef.current) { - if (!full.current && canvasTick.current % 3 === 0) { + if (!full.current) { rotateMap() drawerRef.current.clearRect() void drawerRef.current.updateWorldColors(adapter.getHighestBlockColor, adapter.playerPosition.x, adapter.playerPosition.z, false) @@ -48,7 +48,7 @@ export default ( } } if (warpsDrawerRef.current) { - if (!full.current && canvasTick.current % 3 === 0) { + if (!full.current) { rotateMap() warpsDrawerRef.current.clearRect() warpsDrawerRef.current.drawPartsOfWorld() @@ -56,6 +56,7 @@ export default ( } } if (playerPosDrawerRef.current && !full.current) { + playerPosDrawerRef.current.clearRect() playerPosDrawerRef.current.drawPlayerPos(null as any, null as any, true) } canvasTick.current += 1 @@ -92,7 +93,6 @@ export default ( } else if (playerPosCanvasRef.current && playerPosDrawerRef.current) { playerPosDrawerRef.current.canvas = playerPosCanvasRef.current } - }, [playerPosCanvasRef.current]) useEffect(() => { From e28c114527b98466dcbb6493bb29681f7214ad97 Mon Sep 17 00:00:00 2001 From: gguio Date: Mon, 30 Sep 2024 12:37:46 +0400 Subject: [PATCH 210/285] massive refactor of minimapDrawer --- .../viewer/lib/worldrendererCommon.ts | 2 + src/react/MinimapDrawer.ts | 179 +++++++++++------- src/react/MinimapProvider.tsx | 25 ++- 3 files changed, 134 insertions(+), 72 deletions(-) diff --git a/prismarine-viewer/viewer/lib/worldrendererCommon.ts b/prismarine-viewer/viewer/lib/worldrendererCommon.ts index 92fc96819..cedf4f366 100644 --- a/prismarine-viewer/viewer/lib/worldrendererCommon.ts +++ b/prismarine-viewer/viewer/lib/worldrendererCommon.ts @@ -59,6 +59,7 @@ export abstract class WorldRendererCommon dirty (pos: Vec3, value: boolean): void update (/* pos: Vec3, value: boolean */): void textureDownloaded (): void + chunkFinished (chunkX: number, chunkZ: number) }> customTexturesDataUrl = undefined as string | undefined @worldCleanup() @@ -145,6 +146,7 @@ export abstract class WorldRendererCommon return x === chunkCoords[0] && z === chunkCoords[2] })) { this.finishedChunks[`${chunkCoords[0]},${chunkCoords[2]}`] = true + this.renderUpdateEmitter.emit('chunkFinished', chunkCoords[0] / 16, chunkCoords[2] / 16) } } if (this.sectionsOutstanding.size === 0) { diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index f0c8e3bf0..27e009dac 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -20,22 +20,29 @@ export interface DrawerAdapter extends TypedEventEmitter { yaw: number setWarp: (warp: WorldWarp, remove?: boolean) => void quickTp?: (x: number, z: number) => void - loadChunk?: (chunkX: number, chunkZ: number) => void + loadChunk: (chunkX: number, chunkZ: number) => Promise +} + +type ChunkInfo = { + heightmap: Uint8Array, + colors: string[], } export class MinimapDrawer { - centerX: number - centerY: number + canvasWidthCenterX: number + canvasWidthCenterY: number _mapSize: number radius: number ctx: CanvasRenderingContext2D _canvas: HTMLCanvasElement worldColors: { [key: string]: string } = {} + chunksStore: { [key: string]: undefined | null | 'requested' | ChunkInfo } + chunksInView: Set lastBotPos: Vec3 lastWarpPos: Vec3 mapPixel: number updatingPixels: Set - full: boolean | undefined + _full: boolean = false constructor ( canvas: HTMLCanvasElement, @@ -46,6 +53,17 @@ export class MinimapDrawer { this.updatingPixels = new Set([] as string[]) } + get full () { + return this._full + } + + set full (full: boolean) { + this._full = full + this.radius = Math.floor(Math.min(this.canvas.width, this.canvas.height) / 2) + this._mapSize = 16 + this.mapPixel = Math.floor(this.radius * 2 / this.mapSize) + } + get canvas () { return this._canvas } @@ -56,8 +74,8 @@ export class MinimapDrawer { this.radius = Math.floor(Math.min(canvas.width, canvas.height) / 2.2) this._mapSize = this.radius * 2 this.mapPixel = Math.floor(this.radius * 2 / this.mapSize) - this.centerX = canvas.width / 2 - this.centerY = canvas.height / 2 + this.canvasWidthCenterX = canvas.width / 2 + this.canvasWidthCenterY = canvas.height / 2 this._canvas = canvas } @@ -73,24 +91,63 @@ export class MinimapDrawer { draw ( botPos: Vec3, - getHighestBlockColor?: DrawerAdapter['getHighestBlockColor'], - full?: boolean ) { - if (full) { - this.radius = Math.floor(Math.min(this.canvas.width, this.canvas.height) / 2) - this._mapSize = 16 - this.mapPixel = Math.floor(this.radius * 2 / this.mapSize) - } - this.ctx.clearRect( - this.centerX - this.canvas.width, - this.centerY - this.canvas.height, - this.canvas.width, - this.canvas.height - ) + // this.ctx.clearRect( + // this.canvasWidthCenterX - this.canvas.width, + // this.canvasWidthCenterY - this.canvas.height, + // this.canvas.width, + // this.canvas.height + // ) this.lastBotPos = botPos - void this.updateWorldColors(getHighestBlockColor ?? this.adapter.getHighestBlockColor, botPos.x, botPos.z, full) - if (!full) this.drawPartsOfWorld() + this.updateChunksInView() + for (const key of this.chunksInView) { + const [chunkX, chunkZ] = key.split(',').map(x => Number(x)) + if (this.chunksStore[key] === undefined) { + this.adapter.loadChunk(chunkX, chunkZ) + this.chunksStore[key] = 'requested' + } + this.drawChunk(key) + } + if (!this.full) this.drawPartsOfWorld() + } + + updateChunksInView (viewX?: number, viewZ?: number) { + const worldCenterX = viewX ?? this.lastBotPos.x + const worldCenterZ = viewZ ?? this.lastBotPos.z + + const leftViewBorder = Math.floor((worldCenterX - this.mapSize) / 16) + const rightViewBorder = Math.floor((worldCenterX + this.mapSize) / 16) + const topViewBorder = Math.floor((worldCenterZ - this.mapSize) / 16) + const bottomViewBorder = Math.floor((worldCenterZ + this.mapSize) / 16) + + this.chunksInView.clear() + for (let i=topViewBorder; i <= bottomViewBorder; i+=1) { + for (let j=leftViewBorder; j<=rightViewBorder; j+=1) { + this.chunksInView.add(`${i},${j}`) + } + } + } + + drawChunk (key: string) { + const [chunkX, chunkZ] = key.split(',').map(x => Number(x)) + const chunkCanvasX = (chunkX - this.lastBotPos.x) * this.mapPixel + this.canvasWidthCenterX + const chunkCanvasY = (chunkZ - this.lastBotPos.z) * this.mapPixel + this.canvasWidthCenterY + if (typeof this.chunksStore[key] !== 'object') { + const chunkSize = this.mapPixel * 16 + this.ctx.fillStyle = this.chunksStore[key] === 'requested' ? 'rgb(200, 200, 200)' : 'rgba(0, 0, 0, 0.5)' + this.ctx.fillRect(chunkCanvasX, chunkCanvasY, chunkSize, chunkSize) + return + } + for (let row = 0; row < 16; row += 1) { + for (let col = 0; col < 16; col += 1) { + const index = row * 16 + col + const color = `rgb(${this.chunksStore[key]!.colors[index]}, ${this.chunksStore[key]!.colors[index + 1]}, ${this.chunksStore[key]!.colors[index + 2]})` + const pixelX = chunkCanvasX + this.mapPixel * col + const pixelY = chunkCanvasY + this.mapPixel * row + this.drawPixel(pixelX, pixelY, color) + } + } } clearRect (full?: boolean) { @@ -100,8 +157,8 @@ export class MinimapDrawer { this.mapPixel = Math.floor(this.radius * 2 / this.mapSize) } this.ctx.clearRect( - this.centerX - this.canvas.width, - this.centerY - this.canvas.height, + this.canvasWidthCenterX - this.canvas.width, + this.canvasWidthCenterY - this.canvas.height, this.canvas.width * 2, this.canvas.height * 2 ) @@ -114,44 +171,30 @@ export class MinimapDrawer { full?: boolean ) { if (this.adapter.chunksStore[`${Math.floor(x / 16) * 16},${Math.floor(z / 16) * 16}`] === null) return - this.full = full for (let row = 0; row < this.mapSize; row += 1) { for (let col = 0; col < this.mapSize; col += 1) { - void this.drawPixel(x, z, col, row) + // void this.drawPixel(x, z, col, row) } } } - async drawPixel (x: number, z: number, col: number, row: number) { - const left = this.centerX - this.radius - const top = this.centerY - this.radius - const pixelX = left + this.mapPixel * col - const pixelY = top + this.mapPixel * row - const pixelKey = `${pixelX},${pixelY}` - if (this.updatingPixels.has(pixelKey)) return - this.updatingPixels.add(pixelKey) - if (!this.full && Math.hypot(pixelX - this.centerX, pixelY - this.centerY) > this.radius) { + drawPixel (pixelX: number, pixelY: number, color: string) { + if (!this.full && Math.hypot(pixelX - this.canvasWidthCenterX, pixelY - this.canvasWidthCenterY) > this.radius) { this.ctx.clearRect(pixelX, pixelY, this.mapPixel, this.mapPixel) return } - const roundX = Math.floor(x - this.mapSize / 2 + col) - const roundZ = Math.floor(z - this.mapSize / 2 + row) - const key = `${roundX},${roundZ}` - const fillColor = this.worldColors[key] ?? await this.adapter.getHighestBlockColor(roundX, roundZ, this.full) - if (fillColor !== 'rgb(200, 200, 200)' && !this.worldColors[key]) this.worldColors[key] = fillColor - this.ctx.fillStyle = fillColor + this.ctx.fillStyle = color this.ctx.fillRect( pixelX, pixelY, this.mapPixel, this.mapPixel ) - this.updatingPixels.delete(pixelKey) if (this.full) { - this.drawPlayerPos(x, z) - const lastPixel = this.mapSize - 1 - if (col === lastPixel && row === lastPixel) this.drawWarps(new Vec3(x, 0, z), this.full) + // this.drawPlayerPos(x, z) + // const lastPixel = this.mapSize - 1 + // if (col === lastPixel && row === lastPixel) this.drawWarps(new Vec3(x, 0, z), this.full) } } @@ -191,16 +234,16 @@ export class MinimapDrawer { const x = Math.floor( (this.mapSize / 2 - (centerPos?.x ?? this.adapter.playerPosition.x) + warp.x) * this.mapPixel ) + offset - const dz = z - this.centerX - const dx = x - this.centerY + const dz = z - this.canvasWidthCenterX + const dx = x - this.canvasWidthCenterY const circleDist = Math.hypot(dx, dz) const angle = Math.atan2(dz, dx) const circleZ = circleDist > this.mapSize / 2 && !full ? - this.centerX + this.mapSize / 2 * Math.sin(angle) + this.canvasWidthCenterX + this.mapSize / 2 * Math.sin(angle) : z const circleX = circleDist > this.mapSize / 2 && !full ? - this.centerY + this.mapSize / 2 * Math.cos(angle) + this.canvasWidthCenterY + this.mapSize / 2 * Math.cos(angle) : x this.ctx.beginPath() this.ctx.arc( @@ -240,53 +283,53 @@ export class MinimapDrawer { this.ctx.strokeText( 'N', - this.centerX + this.radius * Math.cos(angle), - this.centerY + this.radius * Math.sin(angle) + this.canvasWidthCenterX + this.radius * Math.cos(angle), + this.canvasWidthCenterY + this.radius * Math.sin(angle) ) this.ctx.strokeText( 'S', - this.centerX + this.radius * Math.cos(angleS), - this.centerY + this.radius * Math.sin(angleS) + this.canvasWidthCenterX + this.radius * Math.cos(angleS), + this.canvasWidthCenterY + this.radius * Math.sin(angleS) ) this.ctx.strokeText( 'W', - this.centerX + this.radius * Math.cos(angleW), - this.centerY + this.radius * Math.sin(angleW) + this.canvasWidthCenterX + this.radius * Math.cos(angleW), + this.canvasWidthCenterY + this.radius * Math.sin(angleW) ) this.ctx.strokeText( 'E', - this.centerX + this.radius * Math.cos(angleE), - this.centerY + this.radius * Math.sin(angleE) + this.canvasWidthCenterX + this.radius * Math.cos(angleE), + this.canvasWidthCenterY + this.radius * Math.sin(angleE) ) this.ctx.fillText( 'N', - this.centerX + this.radius * Math.cos(angle), - this.centerY + this.radius * Math.sin(angle) + this.canvasWidthCenterX + this.radius * Math.cos(angle), + this.canvasWidthCenterY + this.radius * Math.sin(angle) ) this.ctx.fillText( 'S', - this.centerX + this.radius * Math.cos(angleS), - this.centerY + this.radius * Math.sin(angleS) + this.canvasWidthCenterX + this.radius * Math.cos(angleS), + this.canvasWidthCenterY + this.radius * Math.sin(angleS) ) this.ctx.fillText( 'W', - this.centerX + this.radius * Math.cos(angleW), - this.centerY + this.radius * Math.sin(angleW) + this.canvasWidthCenterX + this.radius * Math.cos(angleW), + this.canvasWidthCenterY + this.radius * Math.sin(angleW) ) this.ctx.fillText( 'E', - this.centerX + this.radius * Math.cos(angleE), - this.centerY + this.radius * Math.sin(angleE) + this.canvasWidthCenterX + this.radius * Math.cos(angleE), + this.canvasWidthCenterY + this.radius * Math.sin(angleE) ) this.ctx.shadowOffsetX = 0 this.ctx.shadowOffsetY = 0 } - drawPlayerPos (centerX?: number, centerZ?: number, disableTurn?: boolean) { + drawPlayerPos (canvasWidthCenterX?: number, centerZ?: number, disableTurn?: boolean) { this.ctx.setTransform(1, 0, 0, 1, 0, 0) - const x = (this.adapter.playerPosition.x - (centerX ?? this.adapter.playerPosition.x)) * this.mapPixel + const x = (this.adapter.playerPosition.x - (canvasWidthCenterX ?? this.adapter.playerPosition.x)) * this.mapPixel const z = (this.adapter.playerPosition.z - (centerZ ?? this.adapter.playerPosition.z)) * this.mapPixel const center = this.mapSize / 2 * this.mapPixel + (this.full ? 0 : this.radius * 0.1) this.ctx.translate(center + x, center + z) @@ -315,8 +358,8 @@ export class MinimapDrawer { rotateMap (angle: number) { this.ctx.setTransform(1, 0, 0, 1, 0, 0) - this.ctx.translate(this.centerX, this.centerY) + this.ctx.translate(this.canvasWidthCenterX, this.canvasWidthCenterY) this.ctx.rotate(angle) - this.ctx.translate(-this.centerX, -this.centerY) + this.ctx.translate(-this.canvasWidthCenterX, -this.canvasWidthCenterY) } } diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index bfe4cc0f3..f9afb646c 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -1,4 +1,3 @@ -import fs from 'fs' import { useEffect, useState } from 'react' import { versions } from 'minecraft-data' import { simplify } from 'prismarine-nbt' @@ -78,7 +77,6 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements for (const blockKey of Object.keys(BlockData.colors)) { const renamedKey = getRenamedData('blocks', blockKey, '1.20.2', bot.version) this.blockData[renamedKey as string] = BlockData.colors[blockKey] - } } @@ -291,8 +289,27 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements return chunk } - loadChunk (chunkX: number, chunkZ: number) { - void this.getChunkHeightMapFromRegion(chunkX / 16, chunkZ / 16) + async loadChunk (chunkX: number, chunkZ: number) { + // void this.getChunkHeightMapFromRegion(chunkX / 16, chunkZ / 16) + const chunkWorldX = chunkX * 16 + const chunkWorldZ = chunkZ * 16 + if (localServer) { + if (viewer.world.finishedChunks[`${chunkWorldX},${chunkWorldZ}`]) { + const heightmap = new Uint8Array(256) + const colors = [] as string[] + for (let z=0; z<16; z+=1) { + for (let x=0; x<16 ; x+=1) { + const block = viewer.world.highestBlocks[`${chunkWorldX + x},${chunkWorldZ + z}`] + const index = z * 16 + x + heightmap[index] = block.y + const color = this.isOldVersion ? BlockData.colors[preflatMap.blocks[`${block.type}:${block.metadata}`]?.replaceAll(/\[.*?]/g, '')] ?? 'rgb(0, 255, 0)' : this.blockData[block.name]) ?? 'rgb(0, 255, 0)' + colors.push(color) + } + + } + const chunk = { } + } + } this.getChunkSingleplayer(chunkX, chunkZ).then( (res) => { this.chunksStore[`${chunkX},${chunkZ}`] = res From 974a3dc92ae23466aeb1eb6f16fd3d38d6718ed7 Mon Sep 17 00:00:00 2001 From: gguio Date: Mon, 30 Sep 2024 13:02:02 +0400 Subject: [PATCH 211/285] viewer changes --- prismarine-viewer/viewer/lib/mesher/models.ts | 25 ++++++++----------- prismarine-viewer/viewer/lib/mesher/shared.ts | 4 ++- .../viewer/lib/worldrendererCommon.ts | 5 ++-- src/react/MinimapProvider.tsx | 5 ++-- 4 files changed, 19 insertions(+), 20 deletions(-) diff --git a/prismarine-viewer/viewer/lib/mesher/models.ts b/prismarine-viewer/viewer/lib/mesher/models.ts index 6333eab4c..9e8146b63 100644 --- a/prismarine-viewer/viewer/lib/mesher/models.ts +++ b/prismarine-viewer/viewer/lib/mesher/models.ts @@ -27,7 +27,7 @@ type Tiles = { [blockPos: string]: BlockType } -function prepareTints (tints) { +function prepareTints(tints) { const map = new Map() const defaultValue = tintToGl(tints.default) for (let { keys, color } of tints.data) { @@ -37,18 +37,18 @@ function prepareTints (tints) { } } return new Proxy(map, { - get (target, key) { + get(target, key) { return target.has(key) ? target.get(key) : defaultValue } }) } -function mod (x: number, n: number) { +function mod(x: number, n: number) { return ((x % n) + n) % n } const calculatedBlocksEntries = Object.entries(legacyJson.clientCalculatedBlocks) -export function preflatBlockCalculation (block: Block, world: World, position: Vec3) { +export function preflatBlockCalculation(block: Block, world: World, position: Vec3) { const type = calculatedBlocksEntries.find(([name, blocks]) => blocks.includes(block.name))?.[0] if (!type) return switch (type) { @@ -100,14 +100,14 @@ export function preflatBlockCalculation (block: Block, world: World, position: V } } -function tintToGl (tint) { +function tintToGl(tint) { const r = (tint >> 16) & 0xff const g = (tint >> 8) & 0xff const b = tint & 0xff return [r / 255, g / 255, b / 255] } -function getLiquidRenderHeight (world, block, type, pos) { +function getLiquidRenderHeight(world, block, type, pos) { if (!block || block.type !== type) return 1 / 9 if (block.metadata === 0) { // source block const blockAbove = world.getBlock(pos.offset(0, 1, 0)) @@ -128,7 +128,7 @@ const isCube = (block: Block) => { })) } -function renderLiquid (world: World, cursor: Vec3, texture: any | undefined, type: number, biome: string, water: boolean, attr: Record) { +function renderLiquid(world: World, cursor: Vec3, texture: any | undefined, type: number, biome: string, water: boolean, attr: Record) { const heights: number[] = [] for (let z = -1; z <= 1; z++) { for (let x = -1; x <= 1; x++) { @@ -200,7 +200,7 @@ function renderLiquid (world: World, cursor: Vec3, texture: any | undefined, typ let needRecompute = false -function renderElement (world: World, cursor: Vec3, element: BlockElement, doAO: boolean, attr: MesherGeometryOutput, globalMatrix: any, globalShift: any, block: Block, biome: string) { +function renderElement(world: World, cursor: Vec3, element: BlockElement, doAO: boolean, attr: MesherGeometryOutput, globalMatrix: any, globalShift: any, block: Block, biome: string) { const position = cursor // const key = `${position.x},${position.y},${position.z}` // if (!globalThis.allowedBlocks.includes(key)) return @@ -392,7 +392,7 @@ const isBlockWaterlogged = (block: Block) => block.getProperties().waterlogged = let unknownBlockModel: BlockModelPartsResolved let erroredBlockModel: BlockModelPartsResolved -export function getSectionGeometry (sx, sy, sz, world: World) { +export function getSectionGeometry(sx, sy, sz, world: World) { let delayedRender = [] as Array<() => void> const attr: MesherGeometryOutput = { @@ -423,11 +423,8 @@ export function getSectionGeometry (sx, sy, sz, world: World) { const block = world.getBlock(cursor)! if (!INVISIBLE_BLOCKS.has(block.name)) { const highest = attr.highestBlocks[`${cursor.x},${cursor.z}`] - if (!highest || highest.y < cursor.y) { - attr.highestBlocks[`${cursor.x},${cursor.z}`] = { - y: cursor.y, - name: block.name - } + if (!highest || highest.pos.y < cursor.y) { + attr.highestBlocks[`${cursor.x},${cursor.z}`] = { pos: cursor.clone(), ...block } } } if (INVISIBLE_BLOCKS.has(block.name)) continue diff --git a/prismarine-viewer/viewer/lib/mesher/shared.ts b/prismarine-viewer/viewer/lib/mesher/shared.ts index 30b62c45d..0d471c54c 100644 --- a/prismarine-viewer/viewer/lib/mesher/shared.ts +++ b/prismarine-viewer/viewer/lib/mesher/shared.ts @@ -1,4 +1,6 @@ import { BlockType } from '../../../examples/shared' +import { World, WorldBlock } from './world' +import { Vec3 } from 'vec3' export const defaultMesherConfig = { version: '', @@ -30,6 +32,6 @@ export type MesherGeometryOutput = { tiles: Record, signs: Record, // isFull: boolean - highestBlocks: Record + highestBlocks: Record hadErrors: boolean } diff --git a/prismarine-viewer/viewer/lib/worldrendererCommon.ts b/prismarine-viewer/viewer/lib/worldrendererCommon.ts index cedf4f366..028e4cc44 100644 --- a/prismarine-viewer/viewer/lib/worldrendererCommon.ts +++ b/prismarine-viewer/viewer/lib/worldrendererCommon.ts @@ -17,6 +17,7 @@ import { buildCleanupDecorator } from './cleanupDecorator' import { MesherGeometryOutput, defaultMesherConfig } from './mesher/shared' import { chunkPos } from './simpleUtils' import { HandItemBlock } from './holdingBlock' +import { WorldBlock } from './mesher/world' function mod (x, n) { return ((x % n) + n) % n @@ -79,7 +80,7 @@ export abstract class WorldRendererCommon handleResize = () => { } mesherConfig = defaultMesherConfig camera: THREE.PerspectiveCamera - highestBlocks: Record = {} + highestBlocks: Record = {} blockstatesModels: any customBlockStates: Record | undefined customModels: Record | undefined @@ -128,7 +129,7 @@ export abstract class WorldRendererCommon const geometry = data.geometry as MesherGeometryOutput for (const key in geometry.highestBlocks) { const highest = geometry.highestBlocks[key] - if (!this.highestBlocks[key] || this.highestBlocks[key].y < highest.y) { + if (!this.highestBlocks[key] || this.highestBlocks[key].pos.y < highest.pos.y) { this.highestBlocks[key] = highest } } diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index f9afb646c..bbaae51f4 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -301,11 +301,10 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements for (let x=0; x<16 ; x+=1) { const block = viewer.world.highestBlocks[`${chunkWorldX + x},${chunkWorldZ + z}`] const index = z * 16 + x - heightmap[index] = block.y - const color = this.isOldVersion ? BlockData.colors[preflatMap.blocks[`${block.type}:${block.metadata}`]?.replaceAll(/\[.*?]/g, '')] ?? 'rgb(0, 255, 0)' : this.blockData[block.name]) ?? 'rgb(0, 255, 0)' + heightmap[index] = block.pos.y + const color = this.isOldVersion ? BlockData.colors[preflatMap.blocks[`${block.type}:${block.metadata}`]?.replaceAll(/\[.*?]/g, '')] ?? 'rgb(0, 255, 0)' : this.blockData[block.name] ?? 'rgb(0, 255, 0)' colors.push(color) } - } const chunk = { } } From 8acf7ab4e1b5348b06630dec6f07494929474259 Mon Sep 17 00:00:00 2001 From: gguio Date: Mon, 30 Sep 2024 16:50:58 +0400 Subject: [PATCH 212/285] works but map is transparent --- prismarine-viewer/viewer/lib/mesher/models.ts | 6 +- prismarine-viewer/viewer/lib/mesher/shared.ts | 4 +- prismarine-viewer/viewer/lib/mesher/world.ts | 10 +- .../viewer/lib/worldrendererCommon.ts | 7 +- src/react/Minimap.tsx | 18 +- src/react/MinimapDrawer.ts | 35 ++- src/react/MinimapProvider.tsx | 226 ++++++++++-------- 7 files changed, 165 insertions(+), 141 deletions(-) diff --git a/prismarine-viewer/viewer/lib/mesher/models.ts b/prismarine-viewer/viewer/lib/mesher/models.ts index 9e8146b63..d0069c06a 100644 --- a/prismarine-viewer/viewer/lib/mesher/models.ts +++ b/prismarine-viewer/viewer/lib/mesher/models.ts @@ -412,7 +412,7 @@ export function getSectionGeometry(sx, sy, sz, world: World) { // todo this can be removed here signs: {}, // isFull: true, - highestBlocks: {}, // todo migrate to map for 2% boost perf + highestBlocks: new Map([]), hadErrors: false } @@ -422,9 +422,9 @@ export function getSectionGeometry(sx, sy, sz, world: World) { for (cursor.x = sx; cursor.x < sx + 16; cursor.x++) { const block = world.getBlock(cursor)! if (!INVISIBLE_BLOCKS.has(block.name)) { - const highest = attr.highestBlocks[`${cursor.x},${cursor.z}`] + const highest = attr.highestBlocks.get(`${cursor.x},${cursor.z}`) if (!highest || highest.pos.y < cursor.y) { - attr.highestBlocks[`${cursor.x},${cursor.z}`] = { pos: cursor.clone(), ...block } + attr.highestBlocks.set(`${cursor.x},${cursor.z}`, { pos: cursor.clone(), ...block }) } } if (INVISIBLE_BLOCKS.has(block.name)) continue diff --git a/prismarine-viewer/viewer/lib/mesher/shared.ts b/prismarine-viewer/viewer/lib/mesher/shared.ts index 0d471c54c..19eb0b4a5 100644 --- a/prismarine-viewer/viewer/lib/mesher/shared.ts +++ b/prismarine-viewer/viewer/lib/mesher/shared.ts @@ -1,5 +1,5 @@ import { BlockType } from '../../../examples/shared' -import { World, WorldBlock } from './world' +import { WorldBlock } from './world' import { Vec3 } from 'vec3' export const defaultMesherConfig = { @@ -32,6 +32,6 @@ export type MesherGeometryOutput = { tiles: Record, signs: Record, // isFull: boolean - highestBlocks: Record + highestBlocks: Map hadErrors: boolean } diff --git a/prismarine-viewer/viewer/lib/mesher/world.ts b/prismarine-viewer/viewer/lib/mesher/world.ts index ae65118c9..73867b5be 100644 --- a/prismarine-viewer/viewer/lib/mesher/world.ts +++ b/prismarine-viewer/viewer/lib/mesher/world.ts @@ -126,11 +126,11 @@ export class World { //@ts-expect-error b.isCube = isCube(b.shapes) this.blockCache[stateId] = b - Object.defineProperty(b, 'position', { - get () { - throw new Error('position is not reliable, use pos parameter instead of block.position') - } - }) + // Object.defineProperty(b, 'position', { + // get () { + // throw new Error('position is not reliable, use pos parameter instead of block.position') + // } + // }) if (this.preflat) { //@ts-expect-error b._properties = {} diff --git a/prismarine-viewer/viewer/lib/worldrendererCommon.ts b/prismarine-viewer/viewer/lib/worldrendererCommon.ts index 028e4cc44..dca769dd4 100644 --- a/prismarine-viewer/viewer/lib/worldrendererCommon.ts +++ b/prismarine-viewer/viewer/lib/worldrendererCommon.ts @@ -60,7 +60,7 @@ export abstract class WorldRendererCommon dirty (pos: Vec3, value: boolean): void update (/* pos: Vec3, value: boolean */): void textureDownloaded (): void - chunkFinished (chunkX: number, chunkZ: number) + chunkFinished (key: string): void }> customTexturesDataUrl = undefined as string | undefined @worldCleanup() @@ -127,8 +127,7 @@ export abstract class WorldRendererCommon this.handleWorkerMessage(data) if (data.type === 'geometry') { const geometry = data.geometry as MesherGeometryOutput - for (const key in geometry.highestBlocks) { - const highest = geometry.highestBlocks[key] + for (const [key, highest] of geometry.highestBlocks.entries()) { if (!this.highestBlocks[key] || this.highestBlocks[key].pos.y < highest.pos.y) { this.highestBlocks[key] = highest } @@ -147,7 +146,7 @@ export abstract class WorldRendererCommon return x === chunkCoords[0] && z === chunkCoords[2] })) { this.finishedChunks[`${chunkCoords[0]},${chunkCoords[2]}`] = true - this.renderUpdateEmitter.emit('chunkFinished', chunkCoords[0] / 16, chunkCoords[2] / 16) + this.renderUpdateEmitter.emit(`chunkFinished`, `${chunkCoords[0] / 16},${chunkCoords[2] / 16}`) } } if (this.sectionsOutstanding.size === 0) { diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 5f710e9db..bd48d95df 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,5 +1,5 @@ import { useRef, useEffect, useState } from 'react' -import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' +import { MinimapDrawer, DrawerAdapter, ChunkInfo } from './MinimapDrawer' import Fullmap from './Fullmap' @@ -32,8 +32,7 @@ export default ( if (drawerRef.current) { if (!full.current) { rotateMap() - drawerRef.current.clearRect() - void drawerRef.current.updateWorldColors(adapter.getHighestBlockColor, adapter.playerPosition.x, adapter.playerPosition.z, false) + drawerRef.current.draw(adapter.playerPosition) } if (canvasTick.current % 300 === 0) { if ('requestIdleCallback' in window) { @@ -71,12 +70,19 @@ export default ( warpsDrawerRef.current.canvas.style.transform = `rotate(${adapter.yaw}rad)` } + const updateChunkOnMap = (key: string, chunk: ChunkInfo) => { + console.log('updateChunkOnMap', key, chunk) + drawerRef.current!.chunksStore[key] = chunk + } + useEffect(() => { if (canvasRef.current && !drawerRef.current) { drawerRef.current = new MinimapDrawer(canvasRef.current, adapter) + drawerRef.current.adapter.on('chunkReady', updateChunkOnMap) } else if (canvasRef.current && drawerRef.current) { drawerRef.current.canvas = canvasRef.current } + }, [canvasRef.current]) useEffect(() => { @@ -105,6 +111,12 @@ export default ( } }, [adapter]) + useEffect(() => { + return () => { + if (drawerRef.current) drawerRef.current.adapter.off('chunkReady', updateChunkOnMap) + } + }, []) + return fullMap && displayMode !== 'minimapOnly' && (showFullmap === 'singleplayer' && singleplayer || showFullmap === 'always') ? { diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 27e009dac..4726c66e5 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -23,7 +23,7 @@ export interface DrawerAdapter extends TypedEventEmitter { loadChunk: (chunkX: number, chunkZ: number) => Promise } -type ChunkInfo = { +export type ChunkInfo = { heightmap: Uint8Array, colors: string[], } @@ -36,13 +36,13 @@ export class MinimapDrawer { ctx: CanvasRenderingContext2D _canvas: HTMLCanvasElement worldColors: { [key: string]: string } = {} - chunksStore: { [key: string]: undefined | null | 'requested' | ChunkInfo } - chunksInView: Set + chunksStore: { [key: string]: undefined | null | 'requested' | ChunkInfo } = {} + chunksInView: Set = new Set() lastBotPos: Vec3 lastWarpPos: Vec3 mapPixel: number updatingPixels: Set - _full: boolean = false + _full = false constructor ( canvas: HTMLCanvasElement, @@ -89,20 +89,13 @@ export class MinimapDrawer { this.draw(this.lastBotPos) } - draw ( - botPos: Vec3, - ) { - // this.ctx.clearRect( - // this.canvasWidthCenterX - this.canvas.width, - // this.canvasWidthCenterY - this.canvas.height, - // this.canvas.width, - // this.canvas.height - // ) + draw ( botPos: Vec3,) { + this.ctx.clearRect( 0, 0, this.canvas.width, this.canvas.height) this.lastBotPos = botPos this.updateChunksInView() for (const key of this.chunksInView) { - const [chunkX, chunkZ] = key.split(',').map(x => Number(x)) + const [chunkX, chunkZ] = key.split(',').map(Number) if (this.chunksStore[key] === undefined) { this.adapter.loadChunk(chunkX, chunkZ) this.chunksStore[key] = 'requested' @@ -122,17 +115,19 @@ export class MinimapDrawer { const bottomViewBorder = Math.floor((worldCenterZ + this.mapSize) / 16) this.chunksInView.clear() - for (let i=topViewBorder; i <= bottomViewBorder; i+=1) { - for (let j=leftViewBorder; j<=rightViewBorder; j+=1) { + for (let i = topViewBorder; i <= bottomViewBorder; i += 1) { + for (let j = leftViewBorder; j <= rightViewBorder; j += 1) { this.chunksInView.add(`${i},${j}`) } } } drawChunk (key: string) { - const [chunkX, chunkZ] = key.split(',').map(x => Number(x)) - const chunkCanvasX = (chunkX - this.lastBotPos.x) * this.mapPixel + this.canvasWidthCenterX - const chunkCanvasY = (chunkZ - this.lastBotPos.z) * this.mapPixel + this.canvasWidthCenterY + const [chunkX, chunkZ] = key.split(',').map(Number) + const chunkWorldX = chunkX * 16 + const chunkWorldZ = chunkZ * 16 + const chunkCanvasX = (chunkWorldX - this.lastBotPos.x) * this.mapPixel + this.canvasWidthCenterX + const chunkCanvasY = (chunkWorldZ - this.lastBotPos.z) * this.mapPixel + this.canvasWidthCenterY if (typeof this.chunksStore[key] !== 'object') { const chunkSize = this.mapPixel * 16 this.ctx.fillStyle = this.chunksStore[key] === 'requested' ? 'rgb(200, 200, 200)' : 'rgba(0, 0, 0, 0.5)' @@ -142,7 +137,7 @@ export class MinimapDrawer { for (let row = 0; row < 16; row += 1) { for (let col = 0; col < 16; col += 1) { const index = row * 16 + col - const color = `rgb(${this.chunksStore[key]!.colors[index]}, ${this.chunksStore[key]!.colors[index + 1]}, ${this.chunksStore[key]!.colors[index + 2]})` + const color = this.chunksStore[key]?.colors[index] ?? 'rgb(255, 0, 0)' const pixelX = chunkCanvasX + this.mapPixel * col const pixelY = chunkCanvasY + this.mapPixel * row this.drawPixel(pixelX, pixelY, color) diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index bbaae51f4..2d33698f3 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -60,24 +60,33 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements super() this.playerPosition = pos ?? new Vec3(0, 0, 0) this.warps = gameAdditionalState.warps - if (localServer) { - this.overwriteWarps(localServer.warps) - this.on('cellReady', (key: string) => { - if (this.loadingChunksQueue.size === 0) return - const [x, z] = this.loadingChunksQueue.values().next().value.split(',').map(Number) - this.loadChunk(x, z) - this.loadingChunksQueue.delete(`${x},${z}`) - }) - } else { - const storageWarps = localStorage.getItem(`warps: ${loadedGameState.username} ${loadedGameState.serverIp ?? ''}`) - this.overwriteWarps(JSON.parse(storageWarps ?? '[]')) - } + // if (localServer) { + // this.overwriteWarps(localServer.warps) + // this.on('cellReady', (key: string) => { + // if (this.loadingChunksQueue.size === 0) return + // const [x, z] = this.loadingChunksQueue.values().next().value.split(',').map(Number) + // this.loadChunk(x, z) + // this.loadingChunksQueue.delete(`${x},${z}`) + // }) + // } else { + // const storageWarps = localStorage.getItem(`warps: ${loadedGameState.username} ${loadedGameState.serverIp ?? ''}`) + // this.overwriteWarps(JSON.parse(storageWarps ?? '[]')) + // } this.isOldVersion = versionToNumber(bot.version) < versionToNumber('1.13') this.blockData = {} for (const blockKey of Object.keys(BlockData.colors)) { const renamedKey = getRenamedData('blocks', blockKey, '1.20.2', bot.version) this.blockData[renamedKey as string] = BlockData.colors[blockKey] } + + viewer.world?.renderUpdateEmitter.on('chunkFinished', (key) => { + console.log('[chunkFinished] finished', key) + if (!this.loadingChunksQueue.has(key)) return + const [chunkX, chunkZ] = key.split(',').map(Number) + void this.loadChunk(chunkX, chunkZ) + console.log('[chunkFinished] loading chunk', key) + this.loadingChunksQueue.delete(key) + }) } overwriteWarps (newWarps: WorldWarp[]) { @@ -88,82 +97,83 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } async getHighestBlockColor (x: number, z: number, full?: boolean) { - const chunkX = Math.floor(x / 16) * 16 - const chunkZ = Math.floor(z / 16) * 16 - const emptyColor = 'rgb(200, 200, 200)' - if (localServer && full) { - const chunk = this.chunksStore[`${chunkX},${chunkZ}`] - if (chunk === undefined) { - if (this.loadingChunksCount > 19) { - this.loadingChunksQueue.add(`${chunkX},${chunkZ}`) - return emptyColor - } - this.chunksStore[`${chunkX},${chunkZ}`] = null - this.loadingChunksCount += 1 - console.log('[minimap] loading:', chunkX, chunkZ) - this.loadChunk(chunkX, chunkZ) - return emptyColor - } - return this.getHighestBlockColorLocalServer(x, z) - } - if (!viewer.world.finishedChunks[`${chunkX},${chunkZ}`]) return emptyColor - const block = viewer.world.highestBlocks[`${x},${z}`] - const blockData = bot.world.getBlock(new Vec3(x, block?.y ?? 0, z)) - const color = block && blockData ? (this.isOldVersion ? BlockData.colors[preflatMap.blocks[`${blockData.type}:${blockData.metadata}`]?.replaceAll(/\[.*?]/g, '')] : this.blockData[block.name]) ?? 'rgb(211, 211, 211)' : emptyColor - if (!block) return color - - // shadows - const upKey = `${x},${z - 1}` - const blockUp = viewer.world.highestBlocks[upKey] && viewer.world.highestBlocks[upKey].y > block.y - ? viewer.world.highestBlocks[upKey] - : null - const rightKey = `${x + 1},${z}` - const blockRight = viewer.world.highestBlocks[rightKey] && viewer.world.highestBlocks[rightKey].y > block.y - ? viewer.world.highestBlocks[rightKey] - : null - const rightUpKey = `${x + 1},${z - 1}` - const blockRightUp = viewer.world.highestBlocks[rightUpKey] && viewer.world.highestBlocks[rightUpKey].y > block.y - ? viewer.world.highestBlocks[rightUpKey] - : null - if ((blockUp && !INVISIBLE_BLOCKS.has(blockUp.name)) - || (blockRight && !INVISIBLE_BLOCKS.has(blockRight.name)) - || (blockRightUp && !INVISIBLE_BLOCKS.has(blockRightUp.name)) - ) { - let rgbArray = color.match(/\d+/g).map(Number) - if (rgbArray.length !== 3) return color - rgbArray = rgbArray.map(element => { - let newColor = element - 20 - if (newColor < 0) newColor = 0 - return newColor - }) - return `rgb(${rgbArray.join(',')})` - } - const downKey = `${x},${z + 1}` - const blockDown = viewer.world.highestBlocks[downKey] && viewer.world.highestBlocks[downKey].y > block.y - ? viewer.world.highestBlocks[downKey] - : null - const leftKey = `${x - 1},${z}` - const blockLeft = viewer.world.highestBlocks[leftKey] && viewer.world.highestBlocks[leftKey].y > block.y - ? viewer.world.highestBlocks[leftKey] - : null - const leftDownKey = `${x - 1},${z + 1}` - const blockLeftDown = viewer.world.highestBlocks[leftDownKey] && viewer.world.highestBlocks[leftDownKey].y > block.y - ? viewer.world.highestBlocks[leftDownKey] - : null - if ((blockDown && !INVISIBLE_BLOCKS.has(blockDown.name)) - || (blockLeft && !INVISIBLE_BLOCKS.has(blockLeft.name)) - || (blockLeftDown && !INVISIBLE_BLOCKS.has(blockLeftDown.name)) - ) { - let rgbArray = color.match(/\d+/g).map(Number) - if (rgbArray.length !== 3) return color - rgbArray = rgbArray.map(element => { - let newColor = element + 20 - if (newColor > 255) newColor = 255 - return newColor - }) - return `rgb(${rgbArray.join(',')})` - } - return color + // const chunkX = Math.floor(x / 16) * 16 + // const chunkZ = Math.floor(z / 16) * 16 + // const emptyColor = 'rgb(200, 200, 200)' + // if (localServer && full) { + // const chunk = this.chunksStore[`${chunkX},${chunkZ}`] + // if (chunk === undefined) { + // if (this.loadingChunksCount > 19) { + // this.loadingChunksQueue.add(`${chunkX},${chunkZ}`) + // return emptyColor + // } + // this.chunksStore[`${chunkX},${chunkZ}`] = null + // this.loadingChunksCount += 1 + // console.log('[minimap] loading:', chunkX, chunkZ) + // this.loadChunk(chunkX, chunkZ) + // return emptyColor + // } + // return this.getHighestBlockColorLocalServer(x, z) + // } + // if (!viewer.world.finishedChunks[`${chunkX},${chunkZ}`]) return emptyColor + // const block = viewer.world.highestBlocks[`${x},${z}`] + // const blockData = bot.world.getBlock(new Vec3(x, block?.y ?? 0, z)) + // const color = block && blockData ? (this.isOldVersion ? BlockData.colors[preflatMap.blocks[`${blockData.type}:${blockData.metadata}`]?.replaceAll(/\[.*?]/g, '')] : this.blockData[block.name]) ?? 'rgb(211, 211, 211)' : emptyColor + // if (!block) return color + // + // // shadows + // const upKey = `${x},${z - 1}` + // const blockUp = viewer.world.highestBlocks[upKey] && viewer.world.highestBlocks[upKey].y > block.y + // ? viewer.world.highestBlocks[upKey] + // : null + // const rightKey = `${x + 1},${z}` + // const blockRight = viewer.world.highestBlocks[rightKey] && viewer.world.highestBlocks[rightKey].y > block.y + // ? viewer.world.highestBlocks[rightKey] + // : null + // const rightUpKey = `${x + 1},${z - 1}` + // const blockRightUp = viewer.world.highestBlocks[rightUpKey] && viewer.world.highestBlocks[rightUpKey].y > block.y + // ? viewer.world.highestBlocks[rightUpKey] + // : null + // if ((blockUp && !INVISIBLE_BLOCKS.has(blockUp.name)) + // || (blockRight && !INVISIBLE_BLOCKS.has(blockRight.name)) + // || (blockRightUp && !INVISIBLE_BLOCKS.has(blockRightUp.name)) + // ) { + // let rgbArray = color.match(/\d+/g).map(Number) + // if (rgbArray.length !== 3) return color + // rgbArray = rgbArray.map(element => { + // let newColor = element - 20 + // if (newColor < 0) newColor = 0 + // return newColor + // }) + // return `rgb(${rgbArray.join(',')})` + // } + // const downKey = `${x},${z + 1}` + // const blockDown = viewer.world.highestBlocks[downKey] && viewer.world.highestBlocks[downKey].y > block.y + // ? viewer.world.highestBlocks[downKey] + // : null + // const leftKey = `${x - 1},${z}` + // const blockLeft = viewer.world.highestBlocks[leftKey] && viewer.world.highestBlocks[leftKey].y > block.y + // ? viewer.world.highestBlocks[leftKey] + // : null + // const leftDownKey = `${x - 1},${z + 1}` + // const blockLeftDown = viewer.world.highestBlocks[leftDownKey] && viewer.world.highestBlocks[leftDownKey].y > block.y + // ? viewer.world.highestBlocks[leftDownKey] + // : null + // if ((blockDown && !INVISIBLE_BLOCKS.has(blockDown.name)) + // || (blockLeft && !INVISIBLE_BLOCKS.has(blockLeft.name)) + // || (blockLeftDown && !INVISIBLE_BLOCKS.has(blockLeftDown.name)) + // ) { + // let rgbArray = color.match(/\d+/g).map(Number) + // if (rgbArray.length !== 3) return color + // rgbArray = rgbArray.map(element => { + // let newColor = element + 20 + // if (newColor > 255) newColor = 255 + // return newColor + // }) + // return `rgb(${rgbArray.join(',')})` + // } + // return color + return '' } async getHighestBlockColorLocalServer (x: number, z: number) { @@ -289,34 +299,42 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements return chunk } - async loadChunk (chunkX: number, chunkZ: number) { + async loadChunk (chunkX: number, chunkZ: number, full?: boolean) { // void this.getChunkHeightMapFromRegion(chunkX / 16, chunkZ / 16) const chunkWorldX = chunkX * 16 const chunkWorldZ = chunkZ * 16 - if (localServer) { + if (!full) { if (viewer.world.finishedChunks[`${chunkWorldX},${chunkWorldZ}`]) { const heightmap = new Uint8Array(256) - const colors = [] as string[] - for (let z=0; z<16; z+=1) { - for (let x=0; x<16 ; x+=1) { + const colors = Array.from({ length: 256 }).fill('') as string[] + for (let z = 0; z < 16; z += 1) { + for (let x = 0; x < 16; x += 1) { const block = viewer.world.highestBlocks[`${chunkWorldX + x},${chunkWorldZ + z}`] + if (!block) { + console.warn(`[loadChunk] ${chunkX}, ${chunkZ}, ${chunkWorldX + x}, ${chunkWorldZ + z}`) + return + } const index = z * 16 + x heightmap[index] = block.pos.y - const color = this.isOldVersion ? BlockData.colors[preflatMap.blocks[`${block.type}:${block.metadata}`]?.replaceAll(/\[.*?]/g, '')] ?? 'rgb(0, 255, 0)' : this.blockData[block.name] ?? 'rgb(0, 255, 0)' - colors.push(color) + const color = this.isOldVersion ? BlockData.colors[preflatMap.blocks[`${block.type}:${block.metadata}`]?.replaceAll(/\[.*?]/g, '')] ?? 'rgb(0, 0, 255)' : this.blockData[block.name] ?? 'rgb(0, 255, 0)' + colors[index] = color } } - const chunk = { } + const chunk = { heightmap, colors } + this.emit(`chunkReady`, `${chunkX},${chunkZ}`, chunk) + } else { + console.log('[loadChunk] chunk qeued', chunkX, chunkZ) + this.loadingChunksQueue.add(`${chunkX},${chunkZ}`) } } - this.getChunkSingleplayer(chunkX, chunkZ).then( - (res) => { - this.chunksStore[`${chunkX},${chunkZ}`] = res - this.emit(`cellReady`, `${chunkX},${chunkZ}`) - this.loadingChunksCount -= 1 - console.log('[minimap] loaded:', chunkX, chunkZ, res) - } - ).catch((err) => { console.warn('[minimap] failed to get chunk:', chunkX, chunkZ) }) + // this.getChunkSingleplayer(chunkX, chunkZ).then( + // (res) => { + // this.chunksStore[`${chunkX},${chunkZ}`] = res + // this.emit(`cellReady`, `${chunkX},${chunkZ}`) + // this.loadingChunksCount -= 1 + // console.log('[minimap] loaded:', chunkX, chunkZ, res) + // } + // ).catch((err) => { console.warn('[minimap] failed to get chunk:', chunkX, chunkZ) }) } clearChunksStore (x: number, z: number) { From f731f87986c71d532db19a9b432e7266699574b6 Mon Sep 17 00:00:00 2001 From: gguio Date: Tue, 1 Oct 2024 17:36:01 +0400 Subject: [PATCH 213/285] fix wrong chunks in view --- src/react/MinimapDrawer.ts | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 4726c66e5..bf319de70 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -37,7 +37,7 @@ export class MinimapDrawer { _canvas: HTMLCanvasElement worldColors: { [key: string]: string } = {} chunksStore: { [key: string]: undefined | null | 'requested' | ChunkInfo } = {} - chunksInView: Set = new Set() + chunksInView = new Set() lastBotPos: Vec3 lastWarpPos: Vec3 mapPixel: number @@ -89,15 +89,15 @@ export class MinimapDrawer { this.draw(this.lastBotPos) } - draw ( botPos: Vec3,) { - this.ctx.clearRect( 0, 0, this.canvas.width, this.canvas.height) + draw (botPos: Vec3,) { + this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height) this.lastBotPos = botPos this.updateChunksInView() for (const key of this.chunksInView) { - const [chunkX, chunkZ] = key.split(',').map(Number) if (this.chunksStore[key] === undefined) { - this.adapter.loadChunk(chunkX, chunkZ) + const [chunkX, chunkZ] = key.split(',').map(Number) + void this.adapter.loadChunk(chunkX, chunkZ) this.chunksStore[key] = 'requested' } this.drawChunk(key) @@ -109,15 +109,16 @@ export class MinimapDrawer { const worldCenterX = viewX ?? this.lastBotPos.x const worldCenterZ = viewZ ?? this.lastBotPos.z - const leftViewBorder = Math.floor((worldCenterX - this.mapSize) / 16) - const rightViewBorder = Math.floor((worldCenterX + this.mapSize) / 16) - const topViewBorder = Math.floor((worldCenterZ - this.mapSize) / 16) - const bottomViewBorder = Math.floor((worldCenterZ + this.mapSize) / 16) + const radius = this.mapSize / 2 + const leftViewBorder = Math.floor((worldCenterX - radius) / 16) + const rightViewBorder = Math.ceil((worldCenterX + radius) / 16) + const topViewBorder = Math.floor((worldCenterZ - radius) / 16) + const bottomViewBorder = Math.ceil((worldCenterZ + radius) / 16) this.chunksInView.clear() for (let i = topViewBorder; i <= bottomViewBorder; i += 1) { for (let j = leftViewBorder; j <= rightViewBorder; j += 1) { - this.chunksInView.add(`${i},${j}`) + this.chunksInView.add(`${j},${i}`) } } } @@ -126,8 +127,8 @@ export class MinimapDrawer { const [chunkX, chunkZ] = key.split(',').map(Number) const chunkWorldX = chunkX * 16 const chunkWorldZ = chunkZ * 16 - const chunkCanvasX = (chunkWorldX - this.lastBotPos.x) * this.mapPixel + this.canvasWidthCenterX - const chunkCanvasY = (chunkWorldZ - this.lastBotPos.z) * this.mapPixel + this.canvasWidthCenterY + const chunkCanvasX = Math.floor((chunkWorldX - this.lastBotPos.x) * this.mapPixel + this.canvasWidthCenterX) + const chunkCanvasY = Math.floor((chunkWorldZ - this.lastBotPos.z) * this.mapPixel + this.canvasWidthCenterY) if (typeof this.chunksStore[key] !== 'object') { const chunkSize = this.mapPixel * 16 this.ctx.fillStyle = this.chunksStore[key] === 'requested' ? 'rgb(200, 200, 200)' : 'rgba(0, 0, 0, 0.5)' @@ -175,10 +176,10 @@ export class MinimapDrawer { } drawPixel (pixelX: number, pixelY: number, color: string) { - if (!this.full && Math.hypot(pixelX - this.canvasWidthCenterX, pixelY - this.canvasWidthCenterY) > this.radius) { - this.ctx.clearRect(pixelX, pixelY, this.mapPixel, this.mapPixel) - return - } + // if (!this.full && Math.hypot(pixelX - this.canvasWidthCenterX, pixelY - this.canvasWidthCenterY) > this.radius) { + // this.ctx.clearRect(pixelX, pixelY, this.mapPixel, this.mapPixel) + // return + // } this.ctx.fillStyle = color this.ctx.fillRect( pixelX, From 8d011179356874fa335b45b39969e4f0a70e1500 Mon Sep 17 00:00:00 2001 From: gguio Date: Tue, 1 Oct 2024 18:50:55 +0400 Subject: [PATCH 214/285] chunkStore to map --- src/react/Minimap.tsx | 16 +++------------- src/react/MinimapDrawer.ts | 17 +++++++++-------- 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index bd48d95df..39f22095f 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -33,6 +33,8 @@ export default ( if (!full.current) { rotateMap() drawerRef.current.draw(adapter.playerPosition) + drawerRef.current.drawPlayerPos(null as any, null as any, true) + drawerRef.current.drawWarps() } if (canvasTick.current % 300 === 0) { if ('requestIdleCallback' in window) { @@ -46,18 +48,6 @@ export default ( canvasTick.current = 0 } } - if (warpsDrawerRef.current) { - if (!full.current) { - rotateMap() - warpsDrawerRef.current.clearRect() - warpsDrawerRef.current.drawPartsOfWorld() - warpsDrawerRef.current.drawWarps() - } - } - if (playerPosDrawerRef.current && !full.current) { - playerPosDrawerRef.current.clearRect() - playerPosDrawerRef.current.drawPlayerPos(null as any, null as any, true) - } canvasTick.current += 1 } @@ -72,7 +62,7 @@ export default ( const updateChunkOnMap = (key: string, chunk: ChunkInfo) => { console.log('updateChunkOnMap', key, chunk) - drawerRef.current!.chunksStore[key] = chunk + drawerRef.current!.chunksStore.set(key, chunk) } useEffect(() => { diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index bf319de70..d2b4b12fc 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -36,7 +36,7 @@ export class MinimapDrawer { ctx: CanvasRenderingContext2D _canvas: HTMLCanvasElement worldColors: { [key: string]: string } = {} - chunksStore: { [key: string]: undefined | null | 'requested' | ChunkInfo } = {} + chunksStore = new Map() chunksInView = new Set() lastBotPos: Vec3 lastWarpPos: Vec3 @@ -95,10 +95,10 @@ export class MinimapDrawer { this.lastBotPos = botPos this.updateChunksInView() for (const key of this.chunksInView) { - if (this.chunksStore[key] === undefined) { + if (!this.chunksStore.has(key)) { const [chunkX, chunkZ] = key.split(',').map(Number) void this.adapter.loadChunk(chunkX, chunkZ) - this.chunksStore[key] = 'requested' + this.chunksStore.set(key, 'requested') } this.drawChunk(key) } @@ -110,9 +110,9 @@ export class MinimapDrawer { const worldCenterZ = viewZ ?? this.lastBotPos.z const radius = this.mapSize / 2 - const leftViewBorder = Math.floor((worldCenterX - radius) / 16) + const leftViewBorder = Math.floor((worldCenterX - radius) / 16) - 1 const rightViewBorder = Math.ceil((worldCenterX + radius) / 16) - const topViewBorder = Math.floor((worldCenterZ - radius) / 16) + const topViewBorder = Math.floor((worldCenterZ - radius) / 16) - 1 const bottomViewBorder = Math.ceil((worldCenterZ + radius) / 16) this.chunksInView.clear() @@ -129,16 +129,17 @@ export class MinimapDrawer { const chunkWorldZ = chunkZ * 16 const chunkCanvasX = Math.floor((chunkWorldX - this.lastBotPos.x) * this.mapPixel + this.canvasWidthCenterX) const chunkCanvasY = Math.floor((chunkWorldZ - this.lastBotPos.z) * this.mapPixel + this.canvasWidthCenterY) - if (typeof this.chunksStore[key] !== 'object') { + const chunk = this.chunksStore.get(key) + if (typeof chunk !== 'object') { const chunkSize = this.mapPixel * 16 - this.ctx.fillStyle = this.chunksStore[key] === 'requested' ? 'rgb(200, 200, 200)' : 'rgba(0, 0, 0, 0.5)' + this.ctx.fillStyle = chunk === 'requested' ? 'rgb(200, 200, 200)' : 'rgba(0, 0, 0, 0.5)' this.ctx.fillRect(chunkCanvasX, chunkCanvasY, chunkSize, chunkSize) return } for (let row = 0; row < 16; row += 1) { for (let col = 0; col < 16; col += 1) { const index = row * 16 + col - const color = this.chunksStore[key]?.colors[index] ?? 'rgb(255, 0, 0)' + const color = chunk?.colors[index] ?? 'rgb(255, 0, 0)' const pixelX = chunkCanvasX + this.mapPixel * col const pixelY = chunkCanvasY + this.mapPixel * row this.drawPixel(pixelX, pixelY, color) From 3e444853a3bb2ffb0d4d4e738c5ae84f63f30e4e Mon Sep 17 00:00:00 2001 From: gguio Date: Tue, 1 Oct 2024 23:44:52 +0400 Subject: [PATCH 215/285] chunks store clear --- src/react/Minimap.tsx | 7 +++---- src/react/MinimapDrawer.ts | 9 +++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 39f22095f..702989995 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -33,17 +33,16 @@ export default ( if (!full.current) { rotateMap() drawerRef.current.draw(adapter.playerPosition) - drawerRef.current.drawPlayerPos(null as any, null as any, true) + drawerRef.current.drawPlayerPos() drawerRef.current.drawWarps() } if (canvasTick.current % 300 === 0) { if ('requestIdleCallback' in window) { requestIdleCallback(() => { - drawerRef.current?.deleteOldWorldColors(adapter.playerPosition.x, adapter.playerPosition.z) - adapter.clearChunksStore(position.x, position.z) + drawerRef.current?.clearChunksStore() }) } else { - drawerRef.current.deleteOldWorldColors(adapter.playerPosition.x, adapter.playerPosition.z) + drawerRef.current.clearChunksStore() } canvasTick.current = 0 } diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index d2b4b12fc..3597fd829 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -209,6 +209,15 @@ export class MinimapDrawer { } } + clearChunksStore () { + for (const key of this.chunksStore.keys()) { + const [x, z] = key.split(',').map(x => Number(x) * 16) + if (Math.hypot((this.lastBotPos.x - x), (this.lastBotPos.z - z)) > this.radius * 5) { + this.chunksStore.delete(key) + } + } + } + setWarpPosOnClick (mousePos: Vec3) { this.lastWarpPos = new Vec3(mousePos.x, mousePos.y, mousePos.z) } From 8430a17a61363a96e0b4cd8ee73909affc289943 Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 2 Oct 2024 00:45:52 +0400 Subject: [PATCH 216/285] shadows --- src/react/MinimapProvider.tsx | 82 ++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 2d33698f3..cce8fc200 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -17,7 +17,7 @@ import { contro } from '../controls' import { gameAdditionalState, showModal, hideModal, miscUiState, loadedGameState, activeModalStack } from '../globalState' import { options } from '../optionsStorage' import Minimap, { DisplayMode } from './Minimap' -import { DrawerAdapter, MapUpdates } from './MinimapDrawer' +import { ChunkInfo, DrawerAdapter, MapUpdates } from './MinimapDrawer' import { useIsModalActive } from './utilsApp' const getBlockKey = (x: number, z: number) => { @@ -321,6 +321,7 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } } const chunk = { heightmap, colors } + this.applyShadows(chunk) this.emit(`chunkReady`, `${chunkX},${chunkZ}`, chunk) } else { console.log('[loadChunk] chunk qeued', chunkX, chunkZ) @@ -337,6 +338,85 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements // ).catch((err) => { console.warn('[minimap] failed to get chunk:', chunkX, chunkZ) }) } + applyShadows (chunk: ChunkInfo) { + for (let j = 0; j < 16; j += 1) { + for (let i = 0; i < 16; i += 1) { + const index = j * 16 + i + const color = chunk.colors[index] + // if (i === 0 || j === 0 || i === 15 || j === 16) { + // const r = Math.floor(Math.random() * 2) + // chunk.colors[index] = r===0 ? this.makeDarker(color) : this.makeLighter(color) + // continue + // } + + const h = chunk.heightmap[index] + let isLighterOrDarker = 0 + + const r = chunk.heightmap[index + 1] ?? 0 + const u = chunk.heightmap[index - 16] ?? 0 + const ur = chunk.heightmap[index - 15] ?? 0 + if (r > h || u > h || ur > h) { + chunk.colors[index] = this.makeDarker(color) + isLighterOrDarker -= 1 + } + + const l = chunk.heightmap[index - 1] ?? 0 + const d = chunk.heightmap[index + 16] ?? 0 + const dl = chunk.heightmap[index + 15] ?? 0 + if (l > h || d > h || dl > h) { + chunk.colors[index] = this.makeLighter(color) + isLighterOrDarker += 1 + } + + let linkedIndex: number | undefined + if (i === 1) { + linkedIndex = index - 1 + } else if (i === 14) { + linkedIndex = index + 1 + } else if (j === 1) { + linkedIndex = index - 16 + } else if (j === 14) { + linkedIndex = index + 16 + } + if (linkedIndex !== undefined) { + const linkedColor = chunk.colors[linkedIndex] + switch (isLighterOrDarker) { + case 1: + chunk.colors[linkedIndex] = this.makeLighter(linkedColor) + break + case -1: + chunk.colors[linkedIndex] = this.makeDarker(linkedColor) + break + default: + break + } + } + } + } + } + + makeDarker (color: string) { + let rgbArray = color.match(/\d+/g)?.map(Number) ?? [] + if (rgbArray.length !== 3) return color + rgbArray = rgbArray.map(element => { + let newColor = element - 20 + if (newColor < 0) newColor = 0 + return newColor + }) + return `rgb(${rgbArray.join(',')})` + } + + makeLighter (color: string) { + let rgbArray = color.match(/\d+/g)?.map(Number) ?? [] + if (rgbArray.length !== 3) return color + rgbArray = rgbArray.map(element => { + let newColor = element + 20 + if (newColor > 255) newColor = 255 + return newColor + }) + return `rgb(${rgbArray.join(',')})` + } + clearChunksStore (x: number, z: number) { for (const key of Object.keys(this.chunksStore)) { const [chunkX, chunkZ] = key.split(',').map(Number) From 2349e237f357f91dcf6c9c0d29117eb925569090 Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 4 Oct 2024 13:01:04 +0400 Subject: [PATCH 217/285] fullmap support --- src/react/Fullmap.tsx | 48 +++++++++++++---------------- src/react/Minimap.stories.tsx | 2 ++ src/react/Minimap.tsx | 1 - src/react/MinimapDrawer.ts | 58 ++++++++++++++++++----------------- src/react/MinimapProvider.tsx | 3 -- 5 files changed, 53 insertions(+), 59 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index 663489d6c..9e47f4d76 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -2,7 +2,7 @@ import { Vec3 } from 'vec3' import { useRef, useEffect, useState, CSSProperties, Dispatch, SetStateAction } from 'react' import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' import { TransformWrapper, TransformComponent, ReactZoomPanPinchRef } from 'react-zoom-pan-pinch' -import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' +import { MinimapDrawer, DrawerAdapter, ChunkInfo } from './MinimapDrawer' import Button from './Button' import Input from './Input' import './Fullmap.css' @@ -47,7 +47,6 @@ export default ({ toggleFullMap, adapter }: FullmapProps) => { setGrid(newGrid) } - useEffect(() => { updateGrid() }, []) @@ -201,7 +200,7 @@ const MapChunk = ( } const handleClick = (e: MouseEvent | TouchEvent) => { - console.log('click:', e) + // console.log('click:', e) if (!drawerRef.current) return let clientX: number let clientY: number @@ -238,18 +237,19 @@ const MapChunk = ( setWarpPreview?.( warp ? { name: warp.name, x: warp.x, z: warp.z, clientX: e.clientX, clientY: e.clientY } : undefined ) - console.log('pos:', x, z) } - const handleRedraw = (key?: string) => { - if (key !== `${worldX},${worldZ}`) return + const handleRedraw = (key?: string, chunk?: ChunkInfo) => { + if (key !== `${worldX / 16},${worldZ / 16}`) return console.log('handle redraw:', key) + if (chunk) { + drawerRef.current?.chunksStore.set(key, chunk) + } const timeout = setTimeout(() => { - drawerRef.current?.draw( - new Vec3(worldX + 8, 0, worldZ + 8), - undefined, - true - ) + const center = new Vec3(worldX + 8, 0, worldZ + 8) + drawerRef.current?.draw(center) + drawerRef.current?.drawWarps(center) + drawerRef.current?.drawPlayerPos(center.x, center.z) clearTimeout(timeout) }, 100) } @@ -257,15 +257,11 @@ const MapChunk = ( useEffect(() => { if (canvasRef.current && !drawerRef.current) { drawerRef.current = new MinimapDrawer(canvasRef.current, adapter) - drawerRef.current.draw(new Vec3(worldX + 8, 0, worldZ + 8), undefined, true) + drawerRef.current.full = true } else if (canvasRef.current && drawerRef.current) { drawerRef.current.canvas = canvasRef.current - drawerRef.current.draw( - new Vec3(worldX + 8, 0, worldZ + 8), - undefined, - true - ) } + handleRedraw(`${worldX / 16},${worldZ / 16}`) }, [canvasRef.current]) useEffect(() => { @@ -293,18 +289,16 @@ const MapChunk = ( for (const entry of entries) { if (entry.isIntersecting) { setIsCanvas(true) - } else { - delete adapter.chunksStore[`${worldX},${worldZ}`] } } }) intersectionObserver.observe(containerRef.current!) - adapter.on('cellReady', handleRedraw) + adapter.on('chunkReady', handleRedraw) return () => { intersectionObserver.disconnect() - adapter.off('cellReady', handleRedraw) + adapter.off('chunkReady', handleRedraw) } }, []) @@ -362,19 +356,19 @@ const WarpInfo = ( gap: '5px' } - const updateRegion = () => { + const updateChunk = () => { for (let i = -1; i < 2; i += 1) { for (let j = -1; j < 2; j += 1) { adapter.emit( - 'cellReady', - `${(Math.floor(warp.x / 16) + j) * 16},${(Math.floor(warp.z / 16) + i) * 16}` + 'chunkReady', + `${Math.floor(warp.x / 16) + j},${Math.floor(warp.z / 16) + i}` ) } } } const tpNow = () => { - adapter.off('cellReady', tpNow) + adapter.off('updateChunk', tpNow) } const quickTp = () => { @@ -488,7 +482,7 @@ const WarpInfo = ( adapter.setWarp({ ...warp }) console.log(adapter.warps) setIsWarpInfoOpened(false) - updateRegion() + updateChunk() afterWarpIsSet?.() }} type='submit' @@ -499,7 +493,7 @@ const WarpInfo = ( if (index !== -1) { adapter.setWarp({ name: warp.name, x: 0, y: 0, z: 0, color: '', disabled: false, world: '' }, true) setIsWarpInfoOpened(false) - updateRegion() + updateChunk() afterWarpIsSet?.() } }} diff --git a/src/react/Minimap.stories.tsx b/src/react/Minimap.stories.tsx index c9a8870a6..7579f03b1 100644 --- a/src/react/Minimap.stories.tsx +++ b/src/react/Minimap.stories.tsx @@ -59,6 +59,8 @@ class DrawerAdapterImpl extends TypedEventEmitter implements DrawerA } clearChunksStore (x: number, z: number) { } + + async loadChunk (chunkX: number, chunkZ: number) {} } const adapter = new DrawerAdapterImpl() diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 702989995..50e8a4167 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -60,7 +60,6 @@ export default ( } const updateChunkOnMap = (key: string, chunk: ChunkInfo) => { - console.log('updateChunkOnMap', key, chunk) drawerRef.current!.chunksStore.set(key, chunk) } diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 3597fd829..c24f1216b 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -53,15 +53,24 @@ export class MinimapDrawer { this.updatingPixels = new Set([] as string[]) } + setMapPixel () { + if (this.full) { + this.radius = Math.floor(Math.min(this.canvas.width, this.canvas.height) / 2) + this._mapSize = 16 + } else { + this.radius = Math.floor(Math.min(this.canvas.width, this.canvas.height) / 2.2) + this._mapSize = this.radius * 2 + } + this.mapPixel = Math.floor(this.radius * 2 / this.mapSize) + } + get full () { return this._full } set full (full: boolean) { this._full = full - this.radius = Math.floor(Math.min(this.canvas.width, this.canvas.height) / 2) - this._mapSize = 16 - this.mapPixel = Math.floor(this.radius * 2 / this.mapSize) + this.setMapPixel() } get canvas () { @@ -71,12 +80,10 @@ export class MinimapDrawer { set canvas (canvas: HTMLCanvasElement) { this.ctx = canvas.getContext('2d', { willReadFrequently: true })! this.ctx.imageSmoothingEnabled = false - this.radius = Math.floor(Math.min(canvas.width, canvas.height) / 2.2) - this._mapSize = this.radius * 2 - this.mapPixel = Math.floor(this.radius * 2 / this.mapSize) this.canvasWidthCenterX = canvas.width / 2 this.canvasWidthCenterY = canvas.height / 2 this._canvas = canvas + this.setMapPixel() } get mapSize () { @@ -188,11 +195,6 @@ export class MinimapDrawer { this.mapPixel, this.mapPixel ) - if (this.full) { - // this.drawPlayerPos(x, z) - // const lastPixel = this.mapSize - 1 - // if (col === lastPixel && row === lastPixel) this.drawWarps(new Vec3(x, 0, z), this.full) - } } getDistance (x1: number, z1: number, x2: number, z2: number): number { @@ -224,16 +226,16 @@ export class MinimapDrawer { drawWarps (centerPos?: Vec3, full?: boolean) { for (const warp of this.adapter.warps) { - if (!full) { - const distance = this.getDistance( - centerPos?.x ?? this.adapter.playerPosition.x, - centerPos?.z ?? this.adapter.playerPosition.z, - warp.x, - warp.z - ) - if (distance > this.mapSize) continue - } - const offset = full ? 0 : this.radius * 0.2 + // if (!full) { + // const distance = this.getDistance( + // centerPos?.x ?? this.adapter.playerPosition.x, + // centerPos?.z ?? this.adapter.playerPosition.z, + // warp.x, + // warp.z + // ) + // if (distance > this.mapSize) continue + // } + const offset = this.full ? 0 : this.radius * 0.1 const z = Math.floor( (this.mapSize / 2 - (centerPos?.z ?? this.adapter.playerPosition.z) + warp.z) * this.mapPixel ) + offset @@ -245,19 +247,19 @@ export class MinimapDrawer { const circleDist = Math.hypot(dx, dz) const angle = Math.atan2(dz, dx) - const circleZ = circleDist > this.mapSize / 2 && !full ? + const circleZ = circleDist > this.mapSize / 2 && !this.full ? this.canvasWidthCenterX + this.mapSize / 2 * Math.sin(angle) : z - const circleX = circleDist > this.mapSize / 2 && !full ? + const circleX = circleDist > this.mapSize / 2 && !this.full ? this.canvasWidthCenterY + this.mapSize / 2 * Math.cos(angle) : x this.ctx.beginPath() this.ctx.arc( circleX, circleZ, - circleDist > this.mapSize / 2 && !full + circleDist > this.mapSize / 2 && !this.full ? this.mapPixel * 1.5 - : full ? this.mapPixel : this.mapPixel * 2, + : this.full ? this.mapPixel : this.mapPixel * 2, 0, Math.PI * 2, false @@ -332,11 +334,11 @@ export class MinimapDrawer { this.ctx.shadowOffsetY = 0 } - drawPlayerPos (canvasWidthCenterX?: number, centerZ?: number, disableTurn?: boolean) { + drawPlayerPos (canvasWorldCenterX?: number, canvasWorldCenterZ?: number, disableTurn?: boolean) { this.ctx.setTransform(1, 0, 0, 1, 0, 0) - const x = (this.adapter.playerPosition.x - (canvasWidthCenterX ?? this.adapter.playerPosition.x)) * this.mapPixel - const z = (this.adapter.playerPosition.z - (centerZ ?? this.adapter.playerPosition.z)) * this.mapPixel + const x = (this.adapter.playerPosition.x - (canvasWorldCenterX ?? this.adapter.playerPosition.x)) * this.mapPixel + const z = (this.adapter.playerPosition.z - (canvasWorldCenterZ ?? this.adapter.playerPosition.z)) * this.mapPixel const center = this.mapSize / 2 * this.mapPixel + (this.full ? 0 : this.radius * 0.1) this.ctx.translate(center + x, center + z) if (!disableTurn) this.ctx.rotate(-this.adapter.yaw) diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index cce8fc200..2a9faf7eb 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -80,11 +80,9 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } viewer.world?.renderUpdateEmitter.on('chunkFinished', (key) => { - console.log('[chunkFinished] finished', key) if (!this.loadingChunksQueue.has(key)) return const [chunkX, chunkZ] = key.split(',').map(Number) void this.loadChunk(chunkX, chunkZ) - console.log('[chunkFinished] loading chunk', key) this.loadingChunksQueue.delete(key) }) } @@ -324,7 +322,6 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements this.applyShadows(chunk) this.emit(`chunkReady`, `${chunkX},${chunkZ}`, chunk) } else { - console.log('[loadChunk] chunk qeued', chunkX, chunkZ) this.loadingChunksQueue.add(`${chunkX},${chunkZ}`) } } From 9c195879145bd32602c7632d7fba28c519e9c34f Mon Sep 17 00:00:00 2001 From: gguio Date: Mon, 7 Oct 2024 10:53:53 +0400 Subject: [PATCH 218/285] different load chunk funcs for fullmap and minimap --- src/react/Fullmap.tsx | 4 ++- src/react/Minimap.stories.tsx | 1 + src/react/MinimapDrawer.ts | 1 + src/react/MinimapProvider.tsx | 61 +++++++++++++++++++++++------------ 4 files changed, 45 insertions(+), 22 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index 9e47f4d76..9f5bfebb1 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -48,6 +48,8 @@ export default ({ toggleFullMap, adapter }: FullmapProps) => { } useEffect(() => { + adapter.full = true + console.log('[fullmap] set full property to true') updateGrid() }, []) @@ -241,7 +243,7 @@ const MapChunk = ( const handleRedraw = (key?: string, chunk?: ChunkInfo) => { if (key !== `${worldX / 16},${worldZ / 16}`) return - console.log('handle redraw:', key) + // console.log('handle redraw:', key) if (chunk) { drawerRef.current?.chunksStore.set(key, chunk) } diff --git a/src/react/Minimap.stories.tsx b/src/react/Minimap.stories.tsx index 7579f03b1..b2e633a9c 100644 --- a/src/react/Minimap.stories.tsx +++ b/src/react/Minimap.stories.tsx @@ -32,6 +32,7 @@ class DrawerAdapterImpl extends TypedEventEmitter implements DrawerA yaw: number warps: WorldWarp[] chunksStore: any = {} + full: boolean constructor (pos?: Vec3, warps?: WorldWarp[]) { super() diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index c24f1216b..000efad14 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -18,6 +18,7 @@ export interface DrawerAdapter extends TypedEventEmitter { warps: WorldWarp[] world?: string yaw: number + full: boolean setWarp: (warp: WorldWarp, remove?: boolean) => void quickTp?: (x: number, z: number) => void loadChunk: (chunkX: number, chunkZ: number) => Promise diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 2a9faf7eb..cb43003da 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -55,9 +55,12 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements heightMap: Record = {} regions: Record = {} chunksHeightmaps: Record = {} + loadChunk: (chunkX: number, chunkZ: number) => Promise + _full: boolean constructor (pos?: Vec3) { super() + this.full = false this.playerPosition = pos ?? new Vec3(0, 0, 0) this.warps = gameAdditionalState.warps // if (localServer) { @@ -87,6 +90,20 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements }) } + get full () { + return this._full + } + + set full (full: boolean) { + if (full) { + this.loadChunk = this.loadChunkFullmap + } else { + console.log('this is minimap') + this.loadChunk = this.loadChunkMinimap + } + this._full = full + } + overwriteWarps (newWarps: WorldWarp[]) { this.warps.splice(0, this.warps.length) for (const warp of newWarps) { @@ -297,33 +314,31 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements return chunk } - async loadChunk (chunkX: number, chunkZ: number, full?: boolean) { + async loadChunkMinimap (chunkX: number, chunkZ: number) { // void this.getChunkHeightMapFromRegion(chunkX / 16, chunkZ / 16) const chunkWorldX = chunkX * 16 const chunkWorldZ = chunkZ * 16 - if (!full) { - if (viewer.world.finishedChunks[`${chunkWorldX},${chunkWorldZ}`]) { - const heightmap = new Uint8Array(256) - const colors = Array.from({ length: 256 }).fill('') as string[] - for (let z = 0; z < 16; z += 1) { - for (let x = 0; x < 16; x += 1) { - const block = viewer.world.highestBlocks[`${chunkWorldX + x},${chunkWorldZ + z}`] - if (!block) { - console.warn(`[loadChunk] ${chunkX}, ${chunkZ}, ${chunkWorldX + x}, ${chunkWorldZ + z}`) - return - } - const index = z * 16 + x - heightmap[index] = block.pos.y - const color = this.isOldVersion ? BlockData.colors[preflatMap.blocks[`${block.type}:${block.metadata}`]?.replaceAll(/\[.*?]/g, '')] ?? 'rgb(0, 0, 255)' : this.blockData[block.name] ?? 'rgb(0, 255, 0)' - colors[index] = color + if (viewer.world.finishedChunks[`${chunkWorldX},${chunkWorldZ}`]) { + const heightmap = new Uint8Array(256) + const colors = Array.from({ length: 256 }).fill('') as string[] + for (let z = 0; z < 16; z += 1) { + for (let x = 0; x < 16; x += 1) { + const block = viewer.world.highestBlocks[`${chunkWorldX + x},${chunkWorldZ + z}`] + if (!block) { + console.warn(`[loadChunk] ${chunkX}, ${chunkZ}, ${chunkWorldX + x}, ${chunkWorldZ + z}`) + return } + const index = z * 16 + x + heightmap[index] = block.pos.y + const color = this.isOldVersion ? BlockData.colors[preflatMap.blocks[`${block.type}:${block.metadata}`]?.replaceAll(/\[.*?]/g, '')] ?? 'rgb(0, 0, 255)' : this.blockData[block.name] ?? 'rgb(0, 255, 0)' + colors[index] = color } - const chunk = { heightmap, colors } - this.applyShadows(chunk) - this.emit(`chunkReady`, `${chunkX},${chunkZ}`, chunk) - } else { - this.loadingChunksQueue.add(`${chunkX},${chunkZ}`) } + const chunk = { heightmap, colors } + this.applyShadows(chunk) + this.emit(`chunkReady`, `${chunkX},${chunkZ}`, chunk) + } else { + this.loadingChunksQueue.add(`${chunkX},${chunkZ}`) } // this.getChunkSingleplayer(chunkX, chunkZ).then( // (res) => { @@ -335,6 +350,10 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements // ).catch((err) => { console.warn('[minimap] failed to get chunk:', chunkX, chunkZ) }) } + async loadChunkFullmap (chunkX: number, chunkZ: number) { + console.log('this is fullmap') + } + applyShadows (chunk: ChunkInfo) { for (let j = 0; j < 16; j += 1) { for (let i = 0; i < 16; i += 1) { From 3711b90c10be58a2c232b05e81cd7e5d48e0fc59 Mon Sep 17 00:00:00 2001 From: gguio Date: Tue, 8 Oct 2024 11:59:37 +0400 Subject: [PATCH 219/285] fullmap loads in singlplayer --- src/react/Fullmap.tsx | 11 +++++-- src/react/Minimap.tsx | 8 ++--- src/react/MinimapDrawer.ts | 18 +++++----- src/react/MinimapProvider.tsx | 62 +++++++++++++++++++++++++---------- 4 files changed, 64 insertions(+), 35 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index 9f5bfebb1..df59ee794 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -244,12 +244,17 @@ const MapChunk = ( const handleRedraw = (key?: string, chunk?: ChunkInfo) => { if (key !== `${worldX / 16},${worldZ / 16}`) return // console.log('handle redraw:', key) - if (chunk) { - drawerRef.current?.chunksStore.set(key, chunk) + // if (chunk) { + // drawerRef.current?.chunksStore.set(key, chunk) + // } + if (!adapter.chunksStore.has(key)) { + adapter.loadChunk(key) + return } const timeout = setTimeout(() => { const center = new Vec3(worldX + 8, 0, worldZ + 8) - drawerRef.current?.draw(center) + drawerRef.current!.lastBotPos = center + drawerRef.current?.drawChunk(key) drawerRef.current?.drawWarps(center) drawerRef.current?.drawPlayerPos(center.x, center.z) clearTimeout(timeout) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 50e8a4167..962e55863 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -36,7 +36,7 @@ export default ( drawerRef.current.drawPlayerPos() drawerRef.current.drawWarps() } - if (canvasTick.current % 300 === 0) { + if (canvasTick.current % 300 === 0 && !fullMap) { if ('requestIdleCallback' in window) { requestIdleCallback(() => { drawerRef.current?.clearChunksStore() @@ -60,13 +60,13 @@ export default ( } const updateChunkOnMap = (key: string, chunk: ChunkInfo) => { - drawerRef.current!.chunksStore.set(key, chunk) + drawerRef.current!.adapter.chunksStore.set(key, chunk) } useEffect(() => { if (canvasRef.current && !drawerRef.current) { drawerRef.current = new MinimapDrawer(canvasRef.current, adapter) - drawerRef.current.adapter.on('chunkReady', updateChunkOnMap) + // drawerRef.current.adapter.on('chunkReady', updateChunkOnMap) } else if (canvasRef.current && drawerRef.current) { drawerRef.current.canvas = canvasRef.current } @@ -101,7 +101,7 @@ export default ( useEffect(() => { return () => { - if (drawerRef.current) drawerRef.current.adapter.off('chunkReady', updateChunkOnMap) + // if (drawerRef.current) drawerRef.current.adapter.off('chunkReady', updateChunkOnMap) } }, []) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 000efad14..66e21509a 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -13,15 +13,16 @@ export interface DrawerAdapter extends TypedEventEmitter { getHighestBlockColor: (x: number, z: number, full?: boolean) => Promise getHighestBlockY: (x: number, z: number, chunk?: Chunk) => number clearChunksStore: (x: number, z: number) => void - chunksStore: Record + chunksStore: Map playerPosition: Vec3 warps: WorldWarp[] + loadingChunksQueue: Set world?: string yaw: number full: boolean setWarp: (warp: WorldWarp, remove?: boolean) => void quickTp?: (x: number, z: number) => void - loadChunk: (chunkX: number, chunkZ: number) => Promise + loadChunk: (key: string) => Promise } export type ChunkInfo = { @@ -37,7 +38,6 @@ export class MinimapDrawer { ctx: CanvasRenderingContext2D _canvas: HTMLCanvasElement worldColors: { [key: string]: string } = {} - chunksStore = new Map() chunksInView = new Set() lastBotPos: Vec3 lastWarpPos: Vec3 @@ -103,10 +103,8 @@ export class MinimapDrawer { this.lastBotPos = botPos this.updateChunksInView() for (const key of this.chunksInView) { - if (!this.chunksStore.has(key)) { - const [chunkX, chunkZ] = key.split(',').map(Number) - void this.adapter.loadChunk(chunkX, chunkZ) - this.chunksStore.set(key, 'requested') + if (!this.adapter.chunksStore.has(key) && !this.adapter.loadingChunksQueue.has(key)) { + void this.adapter.loadChunk(key) } this.drawChunk(key) } @@ -137,7 +135,7 @@ export class MinimapDrawer { const chunkWorldZ = chunkZ * 16 const chunkCanvasX = Math.floor((chunkWorldX - this.lastBotPos.x) * this.mapPixel + this.canvasWidthCenterX) const chunkCanvasY = Math.floor((chunkWorldZ - this.lastBotPos.z) * this.mapPixel + this.canvasWidthCenterY) - const chunk = this.chunksStore.get(key) + const chunk = this.adapter.chunksStore.get(key) if (typeof chunk !== 'object') { const chunkSize = this.mapPixel * 16 this.ctx.fillStyle = chunk === 'requested' ? 'rgb(200, 200, 200)' : 'rgba(0, 0, 0, 0.5)' @@ -213,10 +211,10 @@ export class MinimapDrawer { } clearChunksStore () { - for (const key of this.chunksStore.keys()) { + for (const key of this.adapter.chunksStore.keys()) { const [x, z] = key.split(',').map(x => Number(x) * 16) if (Math.hypot((this.lastBotPos.x - x), (this.lastBotPos.z - z)) > this.radius * 5) { - this.chunksStore.delete(key) + this.adapter.chunksStore.delete(key) } } } diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index cb43003da..a8a137fc5 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -45,7 +45,7 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements yaw: number warps: WorldWarp[] world: string - chunksStore: Record = {} + chunksStore = new Map() loadingChunksCount = 0 loadingChunksQueue = new Set() currChunk: PCChunk | undefined @@ -55,7 +55,7 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements heightMap: Record = {} regions: Record = {} chunksHeightmaps: Record = {} - loadChunk: (chunkX: number, chunkZ: number) => Promise + loadChunk: (key: string) => Promise _full: boolean constructor (pos?: Vec3) { @@ -84,8 +84,7 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements viewer.world?.renderUpdateEmitter.on('chunkFinished', (key) => { if (!this.loadingChunksQueue.has(key)) return - const [chunkX, chunkZ] = key.split(',').map(Number) - void this.loadChunk(chunkX, chunkZ) + void this.loadChunk(key) this.loadingChunksQueue.delete(key) }) } @@ -308,14 +307,15 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements async getChunkSingleplayer (chunkX: number, chunkZ: number) { // absolute coords - const region = (localServer!.overworld.storageProvider as any).getRegion(chunkX, chunkZ) + const region = (localServer!.overworld.storageProvider as any).getRegion(chunkX * 16, chunkZ * 16) if (!region) return 'unavailable' - const chunk = await localServer!.players[0]!.world.getColumn(chunkX / 16, chunkZ / 16) + const chunk = await localServer!.players[0]!.world.getColumn(chunkX, chunkZ) return chunk } - async loadChunkMinimap (chunkX: number, chunkZ: number) { + async loadChunkMinimap (key: string) { // void this.getChunkHeightMapFromRegion(chunkX / 16, chunkZ / 16) + const [chunkX, chunkZ] = key.split(',').map(Number) const chunkWorldX = chunkX * 16 const chunkWorldZ = chunkZ * 16 if (viewer.world.finishedChunks[`${chunkWorldX},${chunkWorldZ}`]) { @@ -336,22 +336,48 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } const chunk = { heightmap, colors } this.applyShadows(chunk) - this.emit(`chunkReady`, `${chunkX},${chunkZ}`, chunk) + this.chunksStore.set(key, chunk) + this.emit(`chunkReady`, `${chunkX},${chunkZ}`) } else { this.loadingChunksQueue.add(`${chunkX},${chunkZ}`) + this.chunksStore.set(key, 'requested') } - // this.getChunkSingleplayer(chunkX, chunkZ).then( - // (res) => { - // this.chunksStore[`${chunkX},${chunkZ}`] = res - // this.emit(`cellReady`, `${chunkX},${chunkZ}`) - // this.loadingChunksCount -= 1 - // console.log('[minimap] loaded:', chunkX, chunkZ, res) - // } - // ).catch((err) => { console.warn('[minimap] failed to get chunk:', chunkX, chunkZ) }) } - async loadChunkFullmap (chunkX: number, chunkZ: number) { - console.log('this is fullmap') + async loadChunkFullmap (key: string) { + // this.loadingChunksQueue.add(`${chunkX},${chunkZ}`) + this.chunksStore.set(key, 'requested') + const [chunkX, chunkZ] = key.split(',').map(Number) + const chunkWorldX = chunkX * 16 + const chunkWorldZ = chunkZ * 16 + const chunkInfo = await this.getChunkSingleplayer(chunkX, chunkZ) + if (chunkInfo === 'unavailable') { + this.chunksStore.set(key, null) + this.emit(`chunkReady`, key) + return + } + const heightmap = new Uint8Array(256) + const colors = Array.from({ length: 256 }).fill('') as string[] + for (let z = 0; z < 16; z += 1) { + for (let x = 0; x < 16; x += 1) { + const blockX = chunkWorldX + x + const blockZ = chunkWorldZ + z + const blockY = this.getHighestBlockY(blockX, blockZ, chunkInfo) + const block = chunkInfo.getBlock(new Vec3(blockX & 15, blockY, blockZ & 15)) + if (!block) { + console.warn(`[loadChunk] ${chunkX}, ${chunkZ}, ${chunkWorldX + x}, ${chunkWorldZ + z}`) + return + } + const index = z * 16 + x + heightmap[index] = blockY + const color = this.isOldVersion ? BlockData.colors[preflatMap.blocks[`${block.type}:${block.metadata}`]?.replaceAll(/\[.*?]/g, '')] ?? 'rgb(0, 0, 255)' : this.blockData[block.name] ?? 'rgb(0, 255, 0)' + colors[index] = color + } + } + const chunk = { heightmap, colors } + this.applyShadows(chunk) + this.chunksStore.set(key, chunk) + this.emit(`chunkReady`, key) } applyShadows (chunk: ChunkInfo) { From 9d3da449f3461e3bbfa64672331d08d72b52ae3c Mon Sep 17 00:00:00 2001 From: gguio Date: Tue, 8 Oct 2024 12:10:13 +0400 Subject: [PATCH 220/285] small clean up --- src/react/Fullmap.tsx | 2 +- src/react/MinimapDrawer.ts | 51 +----------- src/react/MinimapProvider.tsx | 141 +--------------------------------- 3 files changed, 4 insertions(+), 190 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index df59ee794..2f52573b7 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -248,7 +248,7 @@ const MapChunk = ( // drawerRef.current?.chunksStore.set(key, chunk) // } if (!adapter.chunksStore.has(key)) { - adapter.loadChunk(key) + void adapter.loadChunk(key) return } const timeout = setTimeout(() => { diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 66e21509a..45f97821e 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -10,16 +10,15 @@ export type MapUpdates = { } export interface DrawerAdapter extends TypedEventEmitter { - getHighestBlockColor: (x: number, z: number, full?: boolean) => Promise getHighestBlockY: (x: number, z: number, chunk?: Chunk) => number clearChunksStore: (x: number, z: number) => void chunksStore: Map playerPosition: Vec3 warps: WorldWarp[] loadingChunksQueue: Set - world?: string yaw: number full: boolean + world: string setWarp: (warp: WorldWarp, remove?: boolean) => void quickTp?: (x: number, z: number) => void loadChunk: (key: string) => Promise @@ -37,12 +36,10 @@ export class MinimapDrawer { radius: number ctx: CanvasRenderingContext2D _canvas: HTMLCanvasElement - worldColors: { [key: string]: string } = {} chunksInView = new Set() lastBotPos: Vec3 lastWarpPos: Vec3 mapPixel: number - updatingPixels: Set _full = false constructor ( @@ -51,7 +48,6 @@ export class MinimapDrawer { ) { this.canvas = canvas this.adapter = adapter - this.updatingPixels = new Set([] as string[]) } setMapPixel () { @@ -153,35 +149,6 @@ export class MinimapDrawer { } } - clearRect (full?: boolean) { - if (full) { - this.radius = Math.floor(Math.min(this.canvas.width, this.canvas.height) / 2) - this._mapSize = this.radius * 2 - this.mapPixel = Math.floor(this.radius * 2 / this.mapSize) - } - this.ctx.clearRect( - this.canvasWidthCenterX - this.canvas.width, - this.canvasWidthCenterY - this.canvas.height, - this.canvas.width * 2, - this.canvas.height * 2 - ) - } - - async updateWorldColors ( - getHighestBlockColor: DrawerAdapter['getHighestBlockColor'], - x: number, - z: number, - full?: boolean - ) { - if (this.adapter.chunksStore[`${Math.floor(x / 16) * 16},${Math.floor(z / 16) * 16}`] === null) return - - for (let row = 0; row < this.mapSize; row += 1) { - for (let col = 0; col < this.mapSize; col += 1) { - // void this.drawPixel(x, z, col, row) - } - } - } - drawPixel (pixelX: number, pixelY: number, color: string) { // if (!this.full && Math.hypot(pixelX - this.canvasWidthCenterX, pixelY - this.canvasWidthCenterY) > this.radius) { // this.ctx.clearRect(pixelX, pixelY, this.mapPixel, this.mapPixel) @@ -196,20 +163,6 @@ export class MinimapDrawer { ) } - getDistance (x1: number, z1: number, x2: number, z2: number): number { - return Math.hypot((x2 - x1), (z2 - z1)) - } - - deleteOldWorldColors (currX: number, currZ: number) { - for (const key of Object.keys(this.worldColors)) { - const [x, z] = key.split(',').map(Number) - if (this.getDistance(x, z, currX, currZ) > this.radius * 5) { - - delete this.worldColors[`${x},${z}`] - } - } - } - clearChunksStore () { for (const key of this.adapter.chunksStore.keys()) { const [x, z] = key.split(',').map(x => Number(x) * 16) @@ -223,7 +176,7 @@ export class MinimapDrawer { this.lastWarpPos = new Vec3(mousePos.x, mousePos.y, mousePos.z) } - drawWarps (centerPos?: Vec3, full?: boolean) { + drawWarps (centerPos?: Vec3) { for (const warp of this.adapter.warps) { // if (!full) { // const distance = this.getDistance( diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index a8a137fc5..dd37ce002 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -45,8 +45,7 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements yaw: number warps: WorldWarp[] world: string - chunksStore = new Map() - loadingChunksCount = 0 + chunksStore = new Map() loadingChunksQueue = new Set() currChunk: PCChunk | undefined currChunkPos: { x: number, z: number } = { x: 0, z: 0 } @@ -110,144 +109,6 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } } - async getHighestBlockColor (x: number, z: number, full?: boolean) { - // const chunkX = Math.floor(x / 16) * 16 - // const chunkZ = Math.floor(z / 16) * 16 - // const emptyColor = 'rgb(200, 200, 200)' - // if (localServer && full) { - // const chunk = this.chunksStore[`${chunkX},${chunkZ}`] - // if (chunk === undefined) { - // if (this.loadingChunksCount > 19) { - // this.loadingChunksQueue.add(`${chunkX},${chunkZ}`) - // return emptyColor - // } - // this.chunksStore[`${chunkX},${chunkZ}`] = null - // this.loadingChunksCount += 1 - // console.log('[minimap] loading:', chunkX, chunkZ) - // this.loadChunk(chunkX, chunkZ) - // return emptyColor - // } - // return this.getHighestBlockColorLocalServer(x, z) - // } - // if (!viewer.world.finishedChunks[`${chunkX},${chunkZ}`]) return emptyColor - // const block = viewer.world.highestBlocks[`${x},${z}`] - // const blockData = bot.world.getBlock(new Vec3(x, block?.y ?? 0, z)) - // const color = block && blockData ? (this.isOldVersion ? BlockData.colors[preflatMap.blocks[`${blockData.type}:${blockData.metadata}`]?.replaceAll(/\[.*?]/g, '')] : this.blockData[block.name]) ?? 'rgb(211, 211, 211)' : emptyColor - // if (!block) return color - // - // // shadows - // const upKey = `${x},${z - 1}` - // const blockUp = viewer.world.highestBlocks[upKey] && viewer.world.highestBlocks[upKey].y > block.y - // ? viewer.world.highestBlocks[upKey] - // : null - // const rightKey = `${x + 1},${z}` - // const blockRight = viewer.world.highestBlocks[rightKey] && viewer.world.highestBlocks[rightKey].y > block.y - // ? viewer.world.highestBlocks[rightKey] - // : null - // const rightUpKey = `${x + 1},${z - 1}` - // const blockRightUp = viewer.world.highestBlocks[rightUpKey] && viewer.world.highestBlocks[rightUpKey].y > block.y - // ? viewer.world.highestBlocks[rightUpKey] - // : null - // if ((blockUp && !INVISIBLE_BLOCKS.has(blockUp.name)) - // || (blockRight && !INVISIBLE_BLOCKS.has(blockRight.name)) - // || (blockRightUp && !INVISIBLE_BLOCKS.has(blockRightUp.name)) - // ) { - // let rgbArray = color.match(/\d+/g).map(Number) - // if (rgbArray.length !== 3) return color - // rgbArray = rgbArray.map(element => { - // let newColor = element - 20 - // if (newColor < 0) newColor = 0 - // return newColor - // }) - // return `rgb(${rgbArray.join(',')})` - // } - // const downKey = `${x},${z + 1}` - // const blockDown = viewer.world.highestBlocks[downKey] && viewer.world.highestBlocks[downKey].y > block.y - // ? viewer.world.highestBlocks[downKey] - // : null - // const leftKey = `${x - 1},${z}` - // const blockLeft = viewer.world.highestBlocks[leftKey] && viewer.world.highestBlocks[leftKey].y > block.y - // ? viewer.world.highestBlocks[leftKey] - // : null - // const leftDownKey = `${x - 1},${z + 1}` - // const blockLeftDown = viewer.world.highestBlocks[leftDownKey] && viewer.world.highestBlocks[leftDownKey].y > block.y - // ? viewer.world.highestBlocks[leftDownKey] - // : null - // if ((blockDown && !INVISIBLE_BLOCKS.has(blockDown.name)) - // || (blockLeft && !INVISIBLE_BLOCKS.has(blockLeft.name)) - // || (blockLeftDown && !INVISIBLE_BLOCKS.has(blockLeftDown.name)) - // ) { - // let rgbArray = color.match(/\d+/g).map(Number) - // if (rgbArray.length !== 3) return color - // rgbArray = rgbArray.map(element => { - // let newColor = element + 20 - // if (newColor > 255) newColor = 255 - // return newColor - // }) - // return `rgb(${rgbArray.join(',')})` - // } - // return color - return '' - } - - async getHighestBlockColorLocalServer (x: number, z: number) { - const emptyColor = 'rgb(200, 200, 200)' - const chunkX = Math.floor(x / 16) - const chunkZ = Math.floor(z / 16) - const chunk = this.chunksStore[`${chunkX * 16},${chunkZ * 16}`] - switch (chunk) { - case undefined: - return emptyColor - case null: - return emptyColor - case 'unavailable': - return 'rgba(0, 0, 0, 0)' - default: - break - } - const y = this.getHighestBlockY(x, z, chunk) - this.heightMap[getBlockKey(x, z)] = y - const block = chunk.getBlock(new Vec3(x & 15, y, z & 15)) - const color = block ? (this.isOldVersion ? BlockData.colors[preflatMap.blocks[`${block.type}:${block.metadata}`]?.replaceAll(/\[.*?]/g, '')] : this.blockData[block.name]) ?? 'rgb(211, 211, 211)' : emptyColor - if (!block) return color - - // shadows - const blockUp = this.heightMap[getBlockKey(x, z - 1)] - const blockRight = this.heightMap[getBlockKey(x + 1, z)] - const blockRightUp = this.heightMap[getBlockKey(x + 1, z - 1)] - if ((blockUp > y) - || (blockRight > y) - || (blockRightUp > y) - ) { - let rgbArray = color.match(/\d+/g).map(Number) - if (rgbArray.length !== 3) return color - rgbArray = rgbArray.map(element => { - let newColor = element - 20 - if (newColor < 0) newColor = 0 - return newColor - }) - return `rgb(${rgbArray.join(',')})` - } - const blockDown = this.heightMap[getBlockKey(x, z + 1)] - const blockLeft = this.heightMap[getBlockKey(x - 1, z)] - const blockLeftDown = this.heightMap[getBlockKey(x - 1, z + 1)] - if ((blockDown > y) - || (blockLeft > y) - || (blockLeftDown > y) - ) { - let rgbArray = color.match(/\d+/g).map(Number) - if (rgbArray.length !== 3) return color - rgbArray = rgbArray.map(element => { - let newColor = element + 20 - if (newColor > 255) newColor = 255 - return newColor - }) - return `rgb(${rgbArray.join(',')})` - } - - return color - } - async getChunkHeightMapFromRegion (chunkX: number, chunkZ: number, cb?: (hm: number[]) => void) { const regionX = Math.floor(chunkX / 32) const regionZ = Math.floor(chunkZ / 32) From 0a3ed566e5139c9a952553bfb145087fefead45b Mon Sep 17 00:00:00 2001 From: gguio Date: Tue, 8 Oct 2024 12:45:33 +0400 Subject: [PATCH 221/285] mapDrawer moved in addapter --- src/react/Fullmap.tsx | 2 +- src/react/Minimap.tsx | 33 ++++++++++++++++---------------- src/react/MinimapDrawer.ts | 36 +++++++++++++++++------------------ src/react/MinimapProvider.tsx | 8 +++++++- 4 files changed, 42 insertions(+), 37 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index 2f52573b7..c37c53c25 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -263,7 +263,7 @@ const MapChunk = ( useEffect(() => { if (canvasRef.current && !drawerRef.current) { - drawerRef.current = new MinimapDrawer(canvasRef.current, adapter) + drawerRef.current = adapter.mapDrawer drawerRef.current.full = true } else if (canvasRef.current && drawerRef.current) { drawerRef.current.canvas = canvasRef.current diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 962e55863..8c2fe4c9a 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -60,12 +60,13 @@ export default ( } const updateChunkOnMap = (key: string, chunk: ChunkInfo) => { - drawerRef.current!.adapter.chunksStore.set(key, chunk) + adapter.chunksStore.set(key, chunk) } useEffect(() => { if (canvasRef.current && !drawerRef.current) { - drawerRef.current = new MinimapDrawer(canvasRef.current, adapter) + drawerRef.current = adapter.mapDrawer + drawerRef.current.canvas = canvasRef.current // drawerRef.current.adapter.on('chunkReady', updateChunkOnMap) } else if (canvasRef.current && drawerRef.current) { drawerRef.current.canvas = canvasRef.current @@ -73,21 +74,21 @@ export default ( }, [canvasRef.current]) - useEffect(() => { - if (warpsAndPartsCanvasRef.current && !warpsDrawerRef.current) { - warpsDrawerRef.current = new MinimapDrawer(warpsAndPartsCanvasRef.current, adapter) - } else if (warpsAndPartsCanvasRef.current && warpsDrawerRef.current) { - warpsDrawerRef.current.canvas = warpsAndPartsCanvasRef.current - } - }, [warpsAndPartsCanvasRef.current]) + // useEffect(() => { + // if (warpsAndPartsCanvasRef.current && !warpsDrawerRef.current) { + // warpsDrawerRef.current = new MinimapDrawer(warpsAndPartsCanvasRef.current, adapter) + // } else if (warpsAndPartsCanvasRef.current && warpsDrawerRef.current) { + // warpsDrawerRef.current.canvas = warpsAndPartsCanvasRef.current + // } + // }, [warpsAndPartsCanvasRef.current]) - useEffect(() => { - if (playerPosCanvasRef.current && !playerPosDrawerRef.current) { - playerPosDrawerRef.current = new MinimapDrawer(playerPosCanvasRef.current, adapter) - } else if (playerPosCanvasRef.current && playerPosDrawerRef.current) { - playerPosDrawerRef.current.canvas = playerPosCanvasRef.current - } - }, [playerPosCanvasRef.current]) + // useEffect(() => { + // if (playerPosCanvasRef.current && !playerPosDrawerRef.current) { + // playerPosDrawerRef.current = new MinimapDrawer(playerPosCanvasRef.current, adapter) + // } else if (playerPosCanvasRef.current && playerPosDrawerRef.current) { + // playerPosDrawerRef.current.canvas = playerPosCanvasRef.current + // } + // }, [playerPosCanvasRef.current]) useEffect(() => { adapter.on('updateMap', updateMap) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 45f97821e..2b38cf04b 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -16,6 +16,7 @@ export interface DrawerAdapter extends TypedEventEmitter { playerPosition: Vec3 warps: WorldWarp[] loadingChunksQueue: Set + mapDrawer: MinimapDrawer yaw: number full: boolean world: string @@ -40,16 +41,13 @@ export class MinimapDrawer { lastBotPos: Vec3 lastWarpPos: Vec3 mapPixel: number + yaw: number + chunksStore = new Map() + loadingChunksQueue: undefined | Set + warps: WorldWarp[] + loadChunk: undefined | ((key: string) => Promise) _full = false - constructor ( - canvas: HTMLCanvasElement, - public adapter: DrawerAdapter - ) { - this.canvas = canvas - this.adapter = adapter - } - setMapPixel () { if (this.full) { this.radius = Math.floor(Math.min(this.canvas.width, this.canvas.height) / 2) @@ -99,8 +97,8 @@ export class MinimapDrawer { this.lastBotPos = botPos this.updateChunksInView() for (const key of this.chunksInView) { - if (!this.adapter.chunksStore.has(key) && !this.adapter.loadingChunksQueue.has(key)) { - void this.adapter.loadChunk(key) + if (!this.chunksStore.has(key) && !this.loadingChunksQueue?.has(key)) { + void this.loadChunk?.(key) } this.drawChunk(key) } @@ -131,7 +129,7 @@ export class MinimapDrawer { const chunkWorldZ = chunkZ * 16 const chunkCanvasX = Math.floor((chunkWorldX - this.lastBotPos.x) * this.mapPixel + this.canvasWidthCenterX) const chunkCanvasY = Math.floor((chunkWorldZ - this.lastBotPos.z) * this.mapPixel + this.canvasWidthCenterY) - const chunk = this.adapter.chunksStore.get(key) + const chunk = this.chunksStore.get(key) if (typeof chunk !== 'object') { const chunkSize = this.mapPixel * 16 this.ctx.fillStyle = chunk === 'requested' ? 'rgb(200, 200, 200)' : 'rgba(0, 0, 0, 0.5)' @@ -164,10 +162,10 @@ export class MinimapDrawer { } clearChunksStore () { - for (const key of this.adapter.chunksStore.keys()) { + for (const key of this.chunksStore.keys()) { const [x, z] = key.split(',').map(x => Number(x) * 16) if (Math.hypot((this.lastBotPos.x - x), (this.lastBotPos.z - z)) > this.radius * 5) { - this.adapter.chunksStore.delete(key) + this.chunksStore.delete(key) } } } @@ -177,7 +175,7 @@ export class MinimapDrawer { } drawWarps (centerPos?: Vec3) { - for (const warp of this.adapter.warps) { + for (const warp of this.warps) { // if (!full) { // const distance = this.getDistance( // centerPos?.x ?? this.adapter.playerPosition.x, @@ -189,10 +187,10 @@ export class MinimapDrawer { // } const offset = this.full ? 0 : this.radius * 0.1 const z = Math.floor( - (this.mapSize / 2 - (centerPos?.z ?? this.adapter.playerPosition.z) + warp.z) * this.mapPixel + (this.mapSize / 2 - (centerPos?.z ?? this.lastBotPos.z) + warp.z) * this.mapPixel ) + offset const x = Math.floor( - (this.mapSize / 2 - (centerPos?.x ?? this.adapter.playerPosition.x) + warp.x) * this.mapPixel + (this.mapSize / 2 - (centerPos?.x ?? this.lastBotPos.x) + warp.x) * this.mapPixel ) + offset const dz = z - this.canvasWidthCenterX const dx = x - this.canvasWidthCenterY @@ -289,11 +287,11 @@ export class MinimapDrawer { drawPlayerPos (canvasWorldCenterX?: number, canvasWorldCenterZ?: number, disableTurn?: boolean) { this.ctx.setTransform(1, 0, 0, 1, 0, 0) - const x = (this.adapter.playerPosition.x - (canvasWorldCenterX ?? this.adapter.playerPosition.x)) * this.mapPixel - const z = (this.adapter.playerPosition.z - (canvasWorldCenterZ ?? this.adapter.playerPosition.z)) * this.mapPixel + const x = (this.lastBotPos.x - (canvasWorldCenterX ?? this.lastBotPos.x)) * this.mapPixel + const z = (this.lastBotPos.z - (canvasWorldCenterZ ?? this.lastBotPos.z)) * this.mapPixel const center = this.mapSize / 2 * this.mapPixel + (this.full ? 0 : this.radius * 0.1) this.ctx.translate(center + x, center + z) - if (!disableTurn) this.ctx.rotate(-this.adapter.yaw) + if (!disableTurn) this.ctx.rotate(-this.yaw) const size = 3 const factor = this.full ? 2 : 1 diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index dd37ce002..6495fdcfc 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -17,7 +17,7 @@ import { contro } from '../controls' import { gameAdditionalState, showModal, hideModal, miscUiState, loadedGameState, activeModalStack } from '../globalState' import { options } from '../optionsStorage' import Minimap, { DisplayMode } from './Minimap' -import { ChunkInfo, DrawerAdapter, MapUpdates } from './MinimapDrawer' +import { ChunkInfo, DrawerAdapter, MapUpdates, MinimapDrawer } from './MinimapDrawer' import { useIsModalActive } from './utilsApp' const getBlockKey = (x: number, z: number) => { @@ -43,6 +43,7 @@ const findHeightMap = (obj: any): any => { export class DrawerAdapterImpl extends TypedEventEmitter implements DrawerAdapter { playerPosition: Vec3 yaw: number + mapDrawer = new MinimapDrawer() warps: WorldWarp[] world: string chunksStore = new Map() @@ -62,6 +63,10 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements this.full = false this.playerPosition = pos ?? new Vec3(0, 0, 0) this.warps = gameAdditionalState.warps + this.mapDrawer.warps = this.warps + this.mapDrawer.loadChunk = this.loadChunk + this.mapDrawer.loadingChunksQueue = this.loadingChunksQueue + this.mapDrawer.chunksStore = this.chunksStore // if (localServer) { // this.overwriteWarps(localServer.warps) // this.on('cellReady', (key: string) => { @@ -99,6 +104,7 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements console.log('this is minimap') this.loadChunk = this.loadChunkMinimap } + this.mapDrawer.loadChunk = this.loadChunk this._full = full } From 01fdde05f4609dbeec3d6a44fca5bc5a997dfd0c Mon Sep 17 00:00:00 2001 From: gguio Date: Tue, 8 Oct 2024 13:42:35 +0400 Subject: [PATCH 222/285] fullmap loading in singleplayer --- src/react/Fullmap.tsx | 25 +++++++++++++------------ src/react/MinimapDrawer.ts | 5 +++-- src/react/MinimapProvider.tsx | 23 ++++++++++++++--------- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/react/Fullmap.tsx b/src/react/Fullmap.tsx index c37c53c25..69a2c5148 100644 --- a/src/react/Fullmap.tsx +++ b/src/react/Fullmap.tsx @@ -243,11 +243,14 @@ const MapChunk = ( const handleRedraw = (key?: string, chunk?: ChunkInfo) => { if (key !== `${worldX / 16},${worldZ / 16}`) return + adapter.mapDrawer.canvas = canvasRef.current! + adapter.mapDrawer.full = true // console.log('handle redraw:', key) // if (chunk) { // drawerRef.current?.chunksStore.set(key, chunk) // } if (!adapter.chunksStore.has(key)) { + adapter.chunksStore.set(key, 'requested') void adapter.loadChunk(key) return } @@ -255,20 +258,18 @@ const MapChunk = ( const center = new Vec3(worldX + 8, 0, worldZ + 8) drawerRef.current!.lastBotPos = center drawerRef.current?.drawChunk(key) - drawerRef.current?.drawWarps(center) - drawerRef.current?.drawPlayerPos(center.x, center.z) + // drawerRef.current?.drawWarps(center) + // drawerRef.current?.drawPlayerPos(center.x, center.z) clearTimeout(timeout) }, 100) } useEffect(() => { - if (canvasRef.current && !drawerRef.current) { - drawerRef.current = adapter.mapDrawer - drawerRef.current.full = true - } else if (canvasRef.current && drawerRef.current) { - drawerRef.current.canvas = canvasRef.current - } - handleRedraw(`${worldX / 16},${worldZ / 16}`) + // if (canvasRef.current && !drawerRef.current) { + // drawerRef.current = adapter.mapDrawer + // } else if (canvasRef.current && drawerRef.current) { + // } + if (canvasRef.current) void adapter.drawChunkOnCanvas(`${worldX / 16},${worldZ / 16}`, canvasRef.current) }, [canvasRef.current]) useEffect(() => { @@ -288,7 +289,7 @@ const MapChunk = ( }, [canvasRef.current, scale]) useEffect(() => { - handleRedraw() + // handleRedraw() }, [drawerRef.current, redraw]) useEffect(() => { @@ -301,11 +302,11 @@ const MapChunk = ( }) intersectionObserver.observe(containerRef.current!) - adapter.on('chunkReady', handleRedraw) + // adapter.on('chunkReady', handleRedraw) return () => { intersectionObserver.disconnect() - adapter.off('chunkReady', handleRedraw) + // adapter.off('chunkReady', handleRedraw) } }, []) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 2b38cf04b..5f9a701ae 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -23,6 +23,7 @@ export interface DrawerAdapter extends TypedEventEmitter { setWarp: (warp: WorldWarp, remove?: boolean) => void quickTp?: (x: number, z: number) => void loadChunk: (key: string) => Promise + drawChunkOnCanvas: (key: string, canvas: HTMLCanvasElement) => Promise } export type ChunkInfo = { @@ -123,13 +124,13 @@ export class MinimapDrawer { } } - drawChunk (key: string) { + drawChunk (key: string, chunkInfo?: ChunkInfo) { const [chunkX, chunkZ] = key.split(',').map(Number) const chunkWorldX = chunkX * 16 const chunkWorldZ = chunkZ * 16 const chunkCanvasX = Math.floor((chunkWorldX - this.lastBotPos.x) * this.mapPixel + this.canvasWidthCenterX) const chunkCanvasY = Math.floor((chunkWorldZ - this.lastBotPos.z) * this.mapPixel + this.canvasWidthCenterY) - const chunk = this.chunksStore.get(key) + const chunk = chunkInfo ?? this.chunksStore.get(key) if (typeof chunk !== 'object') { const chunkSize = this.mapPixel * 16 this.ctx.fillStyle = chunk === 'requested' ? 'rgb(200, 200, 200)' : 'rgba(0, 0, 0, 0.5)' diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 6495fdcfc..305e22d87 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -98,12 +98,8 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } set full (full: boolean) { - if (full) { - this.loadChunk = this.loadChunkFullmap - } else { - console.log('this is minimap') - this.loadChunk = this.loadChunkMinimap - } + console.log('this is minimap') + this.loadChunk = this.loadChunkMinimap this.mapDrawer.loadChunk = this.loadChunk this._full = full } @@ -213,7 +209,6 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements async loadChunkFullmap (key: string) { // this.loadingChunksQueue.add(`${chunkX},${chunkZ}`) - this.chunksStore.set(key, 'requested') const [chunkX, chunkZ] = key.split(',').map(Number) const chunkWorldX = chunkX * 16 const chunkWorldZ = chunkZ * 16 @@ -243,8 +238,7 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } const chunk = { heightmap, colors } this.applyShadows(chunk) - this.chunksStore.set(key, chunk) - this.emit(`chunkReady`, key) + return chunk } applyShadows (chunk: ChunkInfo) { @@ -350,6 +344,17 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements clearTimeout(timeout) }, 500) } + + async drawChunkOnCanvas (key: string, canvas: HTMLCanvasElement) { + console.log('chunk', key, 'on canvas') + const chunk = await this.loadChunkFullmap(key) + const [worldX, worldZ] = key.split(',').map(x => Number(x) * 16) + const center = new Vec3(worldX + 8, 0, worldZ + 8) + this.mapDrawer.lastBotPos = center + this.mapDrawer.canvas = canvas + this.mapDrawer.full = true + this.mapDrawer.drawChunk(key, chunk) + } } const Inner = ( From b5e9490a7ac440f1a9cbce0de4f24bafb743eade Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 10 Oct 2024 11:51:36 +0400 Subject: [PATCH 223/285] loading heightmap from region if possible --- src/react/MinimapProvider.tsx | 73 ++++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 18 deletions(-) diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 305e22d87..621ed830b 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -24,16 +24,14 @@ const getBlockKey = (x: number, z: number) => { return `${x},${z}` } -const findHeightMap = (obj: any): any => { +const findHeightMap = (obj: PCChunk): number[] | undefined => { function search (obj: any): any | undefined { for (const key in obj) { if (['heightmap', 'heightmaps'].includes(key.toLowerCase())) { return obj[key] } else if (typeof obj[key] === 'object' && obj[key] !== null) { const result = search(obj[key]) - if (result !== undefined) { - return result - } + return result } } } @@ -53,10 +51,12 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements isOldVersion: boolean blockData: any heightMap: Record = {} - regions: Record = {} + regions = new Map() chunksHeightmaps: Record = {} loadChunk: (key: string) => Promise + loadChunkFullmap: (key: string) => Promise _full: boolean + isBuiltinHeightmapAvailable = false constructor (pos?: Vec3) { super() @@ -67,6 +67,33 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements this.mapDrawer.loadChunk = this.loadChunk this.mapDrawer.loadingChunksQueue = this.loadingChunksQueue this.mapDrawer.chunksStore = this.chunksStore + + // check if should use heightmap + if (localServer) { + const chunkX = Math.floor(this.playerPosition.x / 16) + const chunkZ = Math.floor(this.playerPosition.z / 16) + const regionX = Math.floor(chunkX / 32) + const regionZ = Math.floor(chunkZ / 32) + const regionKey = `${regionX},${regionZ}` + const { worldFolder } = localServer.options + const path = `${worldFolder}/region/r.${regionX}.${regionZ}.mca` + const region = new RegionFile(path) + void region.initialize() + this.regions.set(regionKey, region) + const readX = chunkX + (regionX > 0 ? 1 : -1) * regionX * 32 + const readZ = chunkZ + (regionZ > 0 ? 1 : -1) * regionZ * 32 + void this.regions.get(regionKey)!.read(readX, readZ).then((rawChunk) => { + const chunk = simplify(rawChunk as any) + const heightmap = findHeightMap(chunk) + if (heightmap) { + this.isBuiltinHeightmapAvailable = true + this.loadChunkFullmap = this.loadChunkFromRegion + } else { + this.isBuiltinHeightmapAvailable = false + this.loadChunkFullmap = this.loadChunkNoRegion + } + }) + } // if (localServer) { // this.overwriteWarps(localServer.warps) // this.on('cellReady', (key: string) => { @@ -114,20 +141,24 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements async getChunkHeightMapFromRegion (chunkX: number, chunkZ: number, cb?: (hm: number[]) => void) { const regionX = Math.floor(chunkX / 32) const regionZ = Math.floor(chunkZ / 32) - const { worldFolder } = localServer!.options - const path = `${worldFolder}/region/r.${regionX}.${regionZ}.mca` - if (!this.regions[`${regionX},${regionZ}`]) { + const regionKey = `${regionX},${regionZ}` + if (!this.regions.has(regionKey)) { + const { worldFolder } = localServer!.options + const path = `${worldFolder}/region/r.${regionX}.${regionZ}.mca` const region = new RegionFile(path) await region.initialize() - this.regions[`${regionX},${regionZ}`] = region + this.regions.set(regionKey, region) } - const rawChunk = await this.regions[`${regionX},${regionZ}`].read(chunkX - regionX * 32, chunkZ - regionZ * 32) + const rawChunk = await this.regions.get(regionKey)! .read( + chunkX - (regionX > 0 ? 1 : -1) * regionX * 32, chunkZ - (regionZ > 0 ? 1 : -1) * regionZ * 32 + ) const chunk = simplify(rawChunk as any) console.log(`chunk ${chunkX}, ${chunkZ}:`, chunk) const heightmap = findHeightMap(chunk) console.log(`heightmap ${chunkX}, ${chunkZ}:`, heightmap) - this.chunksHeightmaps[`${chunkX * 16},${chunkZ * 16}`] = heightmap - cb?.(heightmap) + cb?.(heightmap!) + return heightmap + // this.chunksHeightmaps[`${chunkX},${chunkZ}`] = heightmap } setWarp (warp: WorldWarp, remove?: boolean): void { @@ -207,8 +238,7 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } } - async loadChunkFullmap (key: string) { - // this.loadingChunksQueue.add(`${chunkX},${chunkZ}`) + async loadChunkNoRegion (key: string) { const [chunkX, chunkZ] = key.split(',').map(Number) const chunkWorldX = chunkX * 16 const chunkWorldZ = chunkZ * 16 @@ -236,11 +266,16 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements colors[index] = color } } - const chunk = { heightmap, colors } + const chunk: ChunkInfo = { heightmap, colors } this.applyShadows(chunk) return chunk } + async loadChunkFromRegion (key: string): Promise { + + return undefined + } + applyShadows (chunk: ChunkInfo) { for (let j = 0; j < 16; j += 1) { for (let i = 0; i < 16; i += 1) { @@ -358,13 +393,13 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } const Inner = ( - { displayMode, toggleFullMap }: + { adapter, displayMode, toggleFullMap }: { + adapter: DrawerAdapterImpl displayMode?: DisplayMode, toggleFullMap?: ({ command }: { command?: string }) => void } ) => { - const [adapter] = useState(() => new DrawerAdapterImpl(bot.entity.position)) const updateWarps = (newWarps: WorldWarp[] | Error) => { if (newWarps instanceof Error) { @@ -406,6 +441,8 @@ const Inner = ( } export default ({ displayMode }: { displayMode?: DisplayMode }) => { + const [adapter] = useState(() => new DrawerAdapterImpl(bot.entity.position)) + const { showMinimap } = useSnapshot(options) const fullMapOpened = useIsModalActive('full-map') @@ -475,5 +512,5 @@ export default ({ displayMode }: { displayMode?: DisplayMode }) => { return null } - return + return } From d3520385d66d88bef38f63d4be7c348feb260de2 Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 10 Oct 2024 12:21:56 +0400 Subject: [PATCH 224/285] fix minimap on server --- src/react/MinimapProvider.tsx | 37 ++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 621ed830b..13e83d48c 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -208,7 +208,6 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } async loadChunkMinimap (key: string) { - // void this.getChunkHeightMapFromRegion(chunkX / 16, chunkZ / 16) const [chunkX, chunkZ] = key.split(',').map(Number) const chunkWorldX = chunkX * 16 const chunkWorldZ = chunkZ * 16 @@ -218,11 +217,13 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements for (let z = 0; z < 16; z += 1) { for (let x = 0; x < 16; x += 1) { const block = viewer.world.highestBlocks[`${chunkWorldX + x},${chunkWorldZ + z}`] + const index = z * 16 + x if (!block) { console.warn(`[loadChunk] ${chunkX}, ${chunkZ}, ${chunkWorldX + x}, ${chunkWorldZ + z}`) - return + heightmap[index] = 0 + colors[index] = 'rgba(0, 0, 0, 0.5)' + continue } - const index = z * 16 + x heightmap[index] = block.pos.y const color = this.isOldVersion ? BlockData.colors[preflatMap.blocks[`${block.type}:${block.metadata}`]?.replaceAll(/\[.*?]/g, '')] ?? 'rgb(0, 0, 255)' : this.blockData[block.name] ?? 'rgb(0, 255, 0)' colors[index] = color @@ -276,6 +277,36 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements return undefined } + async loadChunkFromViewer (key: string) { + const [chunkX, chunkZ] = key.split(',').map(Number) + const chunkWorldX = chunkX * 16 + const chunkWorldZ = chunkZ * 16 + if (viewer.world.finishedChunks[`${chunkWorldX},${chunkWorldZ}`]) { + const heightmap = new Uint8Array(256) + const colors = Array.from({ length: 256 }).fill('') as string[] + for (let z = 0; z < 16; z += 1) { + for (let x = 0; x < 16; x += 1) { + const block = viewer.world.highestBlocks[`${chunkWorldX + x},${chunkWorldZ + z}`] + if (!block) { + console.warn(`[loadChunk] ${chunkX}, ${chunkZ}, ${chunkWorldX + x}, ${chunkWorldZ + z}`) + return + } + const index = z * 16 + x + heightmap[index] = block.pos.y + const color = this.isOldVersion ? BlockData.colors[preflatMap.blocks[`${block.type}:${block.metadata}`]?.replaceAll(/\[.*?]/g, '')] ?? 'rgb(0, 0, 255)' : this.blockData[block.name] ?? 'rgb(0, 255, 0)' + colors[index] = color + } + } + const chunk = { heightmap, colors } + this.applyShadows(chunk) + this.chunksStore.set(key, chunk) + return chunk + } else { + this.loadingChunksQueue.add(`${chunkX},${chunkZ}`) + this.chunksStore.set(key, 'requested') + } + } + applyShadows (chunk: ChunkInfo) { for (let j = 0; j < 16; j += 1) { for (let i = 0; i < 16; i += 1) { From b1e7c67b5351af0d436cca01b845197665206512 Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 10 Oct 2024 12:41:11 +0400 Subject: [PATCH 225/285] fix fullmap on server --- src/react/MinimapDrawer.ts | 2 +- src/react/MinimapProvider.tsx | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 5f9a701ae..935bdd4bb 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -124,7 +124,7 @@ export class MinimapDrawer { } } - drawChunk (key: string, chunkInfo?: ChunkInfo) { + drawChunk (key: string, chunkInfo?: ChunkInfo | null) { const [chunkX, chunkZ] = key.split(',').map(Number) const chunkWorldX = chunkX * 16 const chunkWorldZ = chunkZ * 16 diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 13e83d48c..a0c827c8f 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -54,7 +54,7 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements regions = new Map() chunksHeightmaps: Record = {} loadChunk: (key: string) => Promise - loadChunkFullmap: (key: string) => Promise + loadChunkFullmap: (key: string) => Promise _full: boolean isBuiltinHeightmapAvailable = false @@ -93,6 +93,9 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements this.loadChunkFullmap = this.loadChunkNoRegion } }) + } else { + this.isBuiltinHeightmapAvailable = false + this.loadChunkFullmap = this.loadChunkFromViewer } // if (localServer) { // this.overwriteWarps(localServer.warps) @@ -287,11 +290,13 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements for (let z = 0; z < 16; z += 1) { for (let x = 0; x < 16; x += 1) { const block = viewer.world.highestBlocks[`${chunkWorldX + x},${chunkWorldZ + z}`] + const index = z * 16 + x if (!block) { console.warn(`[loadChunk] ${chunkX}, ${chunkZ}, ${chunkWorldX + x}, ${chunkWorldZ + z}`) - return + heightmap[index] = 0 + colors[index] = 'rgba(0, 0, 0, 0.5)' + continue } - const index = z * 16 + x heightmap[index] = block.pos.y const color = this.isOldVersion ? BlockData.colors[preflatMap.blocks[`${block.type}:${block.metadata}`]?.replaceAll(/\[.*?]/g, '')] ?? 'rgb(0, 0, 255)' : this.blockData[block.name] ?? 'rgb(0, 255, 0)' colors[index] = color @@ -299,11 +304,9 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } const chunk = { heightmap, colors } this.applyShadows(chunk) - this.chunksStore.set(key, chunk) return chunk } else { - this.loadingChunksQueue.add(`${chunkX},${chunkZ}`) - this.chunksStore.set(key, 'requested') + return null } } From 9d11a1754c89b062cfa1a0b0c2b027947b64fc98 Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 10 Oct 2024 12:53:25 +0400 Subject: [PATCH 226/285] regular heightmap for fullmap --- src/react/MinimapProvider.tsx | 80 ++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 29 deletions(-) diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index a0c827c8f..9fa7253a7 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -141,28 +141,6 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } } - async getChunkHeightMapFromRegion (chunkX: number, chunkZ: number, cb?: (hm: number[]) => void) { - const regionX = Math.floor(chunkX / 32) - const regionZ = Math.floor(chunkZ / 32) - const regionKey = `${regionX},${regionZ}` - if (!this.regions.has(regionKey)) { - const { worldFolder } = localServer!.options - const path = `${worldFolder}/region/r.${regionX}.${regionZ}.mca` - const region = new RegionFile(path) - await region.initialize() - this.regions.set(regionKey, region) - } - const rawChunk = await this.regions.get(regionKey)! .read( - chunkX - (regionX > 0 ? 1 : -1) * regionX * 32, chunkZ - (regionZ > 0 ? 1 : -1) * regionZ * 32 - ) - const chunk = simplify(rawChunk as any) - console.log(`chunk ${chunkX}, ${chunkZ}:`, chunk) - const heightmap = findHeightMap(chunk) - console.log(`heightmap ${chunkX}, ${chunkZ}:`, heightmap) - cb?.(heightmap!) - return heightmap - // this.chunksHeightmaps[`${chunkX},${chunkZ}`] = heightmap - } setWarp (warp: WorldWarp, remove?: boolean): void { this.world = bot.game.dimension @@ -247,11 +225,7 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements const chunkWorldX = chunkX * 16 const chunkWorldZ = chunkZ * 16 const chunkInfo = await this.getChunkSingleplayer(chunkX, chunkZ) - if (chunkInfo === 'unavailable') { - this.chunksStore.set(key, null) - this.emit(`chunkReady`, key) - return - } + if (chunkInfo === 'unavailable') return null const heightmap = new Uint8Array(256) const colors = Array.from({ length: 256 }).fill('') as string[] for (let z = 0; z < 16; z += 1) { @@ -275,9 +249,57 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements return chunk } - async loadChunkFromRegion (key: string): Promise { + async loadChunkFromRegion (key: string): Promise { + const [chunkX, chunkZ] = key.split(',').map(Number) + const chunkWorldX = chunkX * 16 + const chunkWorldZ = chunkZ * 16 + const heightmap = await this.getChunkHeightMapFromRegion(chunkX, chunkZ) as unknown as Uint8Array + if (!heightmap) return null + const chunkInfo = await this.getChunkSingleplayer(chunkX, chunkZ) + if (chunkInfo === 'unavailable') return null + const colors = Array.from({ length: 256 }).fill('') as string[] + for (let z = 0; z < 16; z += 1) { + for (let x = 0; x < 16; x += 1) { + const blockX = chunkWorldX + x + const blockZ = chunkWorldZ + z + const index = z * 16 + x + const blockY = heightmap[index] + const block = chunkInfo.getBlock(new Vec3(blockX & 15, blockY, blockZ & 15)) + if (!block) { + console.warn(`[loadChunk] ${chunkX}, ${chunkZ}, ${chunkWorldX + x}, ${chunkWorldZ + z}`) + return + } + heightmap[index] = blockY + const color = this.isOldVersion ? BlockData.colors[preflatMap.blocks[`${block.type}:${block.metadata}`]?.replaceAll(/\[.*?]/g, '')] ?? 'rgb(0, 0, 255)' : this.blockData[block.name] ?? 'rgb(0, 255, 0)' + colors[index] = color + } + } + const chunk: ChunkInfo = { heightmap, colors } + this.applyShadows(chunk) + return chunk + } - return undefined + async getChunkHeightMapFromRegion (chunkX: number, chunkZ: number, cb?: (hm: number[]) => void) { + const regionX = Math.floor(chunkX / 32) + const regionZ = Math.floor(chunkZ / 32) + const regionKey = `${regionX},${regionZ}` + if (!this.regions.has(regionKey)) { + const { worldFolder } = localServer!.options + const path = `${worldFolder}/region/r.${regionX}.${regionZ}.mca` + const region = new RegionFile(path) + await region.initialize() + this.regions.set(regionKey, region) + } + const rawChunk = await this.regions.get(regionKey)! .read( + chunkX - (regionX > 0 ? 1 : -1) * regionX * 32, chunkZ - (regionZ > 0 ? 1 : -1) * regionZ * 32 + ) + const chunk = simplify(rawChunk as any) + console.log(`chunk ${chunkX}, ${chunkZ}:`, chunk) + const heightmap = findHeightMap(chunk) + console.log(`heightmap ${chunkX}, ${chunkZ}:`, heightmap) + cb?.(heightmap!) + return heightmap + // this.chunksHeightmaps[`${chunkX},${chunkZ}`] = heightmap } async loadChunkFromViewer (key: string) { From 6e36847ae0894a7c5681f469ab80887416287935 Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 10 Oct 2024 12:55:28 +0400 Subject: [PATCH 227/285] fix build --- src/react/Minimap.stories.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/react/Minimap.stories.tsx b/src/react/Minimap.stories.tsx index b2e633a9c..5b28a5b99 100644 --- a/src/react/Minimap.stories.tsx +++ b/src/react/Minimap.stories.tsx @@ -27,7 +27,7 @@ export default meta type Story = StoryObj -class DrawerAdapterImpl extends TypedEventEmitter implements DrawerAdapter { +class DrawerAdapterImpl extends TypedEventEmitter { playerPosition: Vec3 yaw: number warps: WorldWarp[] @@ -61,10 +61,10 @@ class DrawerAdapterImpl extends TypedEventEmitter implements DrawerA clearChunksStore (x: number, z: number) { } - async loadChunk (chunkX: number, chunkZ: number) {} + async loadChunk (key: string) {} } -const adapter = new DrawerAdapterImpl() +const adapter = new DrawerAdapterImpl() as any export const Primary: Story = { args: { From 55207788b02e2009aaf1163b4b55577f0d43b7c8 Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 11 Oct 2024 00:24:48 +0400 Subject: [PATCH 228/285] fix viewer --- prismarine-viewer/viewer/lib/mesher/models.ts | 8 +++---- prismarine-viewer/viewer/lib/mesher/shared.ts | 6 ++--- .../viewer/lib/worldrendererCommon.ts | 13 ++++++----- src/react/MinimapProvider.tsx | 23 +++++++++++++------ 4 files changed, 30 insertions(+), 20 deletions(-) diff --git a/prismarine-viewer/viewer/lib/mesher/models.ts b/prismarine-viewer/viewer/lib/mesher/models.ts index d0069c06a..e1a17c66c 100644 --- a/prismarine-viewer/viewer/lib/mesher/models.ts +++ b/prismarine-viewer/viewer/lib/mesher/models.ts @@ -5,7 +5,7 @@ import { BlockType } from '../../../examples/shared' import { World, BlockModelPartsResolved, WorldBlock as Block } from './world' import { BlockElement, buildRotationMatrix, elemFaces, matmul3, matmulmat3, vecadd3, vecsub3 } from './modelsGeometryCommon' import { INVISIBLE_BLOCKS } from './worldConstants' -import { MesherGeometryOutput } from './shared' +import { MesherGeometryOutput, HighestBlockInfo } from './shared' let blockProvider: WorldBlockProvider @@ -412,7 +412,7 @@ export function getSectionGeometry(sx, sy, sz, world: World) { // todo this can be removed here signs: {}, // isFull: true, - highestBlocks: new Map([]), + highestBlocks: new Map([]), hadErrors: false } @@ -423,8 +423,8 @@ export function getSectionGeometry(sx, sy, sz, world: World) { const block = world.getBlock(cursor)! if (!INVISIBLE_BLOCKS.has(block.name)) { const highest = attr.highestBlocks.get(`${cursor.x},${cursor.z}`) - if (!highest || highest.pos.y < cursor.y) { - attr.highestBlocks.set(`${cursor.x},${cursor.z}`, { pos: cursor.clone(), ...block }) + if (!highest || highest.y < cursor.y) { + attr.highestBlocks.set(`${cursor.x},${cursor.z}`, { y: cursor.y, stateId: block.stateId, biomeId: block.biome.id }) } } if (INVISIBLE_BLOCKS.has(block.name)) continue diff --git a/prismarine-viewer/viewer/lib/mesher/shared.ts b/prismarine-viewer/viewer/lib/mesher/shared.ts index 19eb0b4a5..fd015c0cc 100644 --- a/prismarine-viewer/viewer/lib/mesher/shared.ts +++ b/prismarine-viewer/viewer/lib/mesher/shared.ts @@ -1,6 +1,4 @@ import { BlockType } from '../../../examples/shared' -import { WorldBlock } from './world' -import { Vec3 } from 'vec3' export const defaultMesherConfig = { version: '', @@ -32,6 +30,8 @@ export type MesherGeometryOutput = { tiles: Record, signs: Record, // isFull: boolean - highestBlocks: Map + highestBlocks: Map hadErrors: boolean } + +export type HighestBlockInfo = { y: number, stateId: number | undefined, biomeId: number | undefined } diff --git a/prismarine-viewer/viewer/lib/worldrendererCommon.ts b/prismarine-viewer/viewer/lib/worldrendererCommon.ts index dca769dd4..e3473b47d 100644 --- a/prismarine-viewer/viewer/lib/worldrendererCommon.ts +++ b/prismarine-viewer/viewer/lib/worldrendererCommon.ts @@ -14,10 +14,10 @@ import TypedEmitter from 'typed-emitter' import { dynamicMcDataFiles } from '../../buildMesherConfig.mjs' import { toMajorVersion } from '../../../src/utils' import { buildCleanupDecorator } from './cleanupDecorator' -import { MesherGeometryOutput, defaultMesherConfig } from './mesher/shared' +import { defaultMesherConfig } from './mesher/shared' import { chunkPos } from './simpleUtils' import { HandItemBlock } from './holdingBlock' -import { WorldBlock } from './mesher/world' +import { HighestBlockInfo, MesherGeometryOutput} from './mesher/shared' function mod (x, n) { return ((x % n) + n) % n @@ -80,7 +80,7 @@ export abstract class WorldRendererCommon handleResize = () => { } mesherConfig = defaultMesherConfig camera: THREE.PerspectiveCamera - highestBlocks: Record = {} + highestBlocks = new Map() blockstatesModels: any customBlockStates: Record | undefined customModels: Record | undefined @@ -128,8 +128,9 @@ export abstract class WorldRendererCommon if (data.type === 'geometry') { const geometry = data.geometry as MesherGeometryOutput for (const [key, highest] of geometry.highestBlocks.entries()) { - if (!this.highestBlocks[key] || this.highestBlocks[key].pos.y < highest.pos.y) { - this.highestBlocks[key] = highest + const currHighest = this.highestBlocks.get(key) + if (!currHighest || currHighest.y < highest.y) { + this.highestBlocks.set(key, highest) } } } @@ -350,7 +351,7 @@ export abstract class WorldRendererCommon const endZ = Math.ceil((z + 1) / 16) * 16 for (let x = startX; x < endX; x += 16) { for (let z = startZ; z < endZ; z += 16) { - delete this.highestBlocks[`${x},${z}`] + this.highestBlocks.delete(`${x},${z}`) } } } diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 9fa7253a7..aacf60cb2 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -8,6 +8,7 @@ import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' import { TypedEventEmitter } from 'contro-max/build/typedEventEmitter' import { PCChunk } from 'prismarine-chunk' import { Chunk } from 'prismarine-world/types/world' +import { Block } from 'prismarine-block' import { INVISIBLE_BLOCKS } from 'prismarine-viewer/viewer/lib/mesher/worldConstants' import { getRenamedData } from 'flying-squid/dist/blockRenames' import { useSnapshot } from 'valtio' @@ -141,7 +142,6 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } } - setWarp (warp: WorldWarp, remove?: boolean): void { this.world = bot.game.dimension const index = this.warps.findIndex(w => w.name === warp.name) @@ -197,15 +197,19 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements const colors = Array.from({ length: 256 }).fill('') as string[] for (let z = 0; z < 16; z += 1) { for (let x = 0; x < 16; x += 1) { - const block = viewer.world.highestBlocks[`${chunkWorldX + x},${chunkWorldZ + z}`] + const blockX = chunkWorldX + x + const blockZ = chunkWorldZ + z + const hBlock = viewer.world.highestBlocks.get(`${blockX},${blockZ}`) + const block = bot.world.getBlock(new Vec3(blockX, hBlock?.y ?? 0, blockZ)) + // const block = Block.fromStateId(hBlock?.stateId ?? -1, hBlock?.biomeId ?? -1) const index = z * 16 + x - if (!block) { + if (!block || !hBlock) { console.warn(`[loadChunk] ${chunkX}, ${chunkZ}, ${chunkWorldX + x}, ${chunkWorldZ + z}`) heightmap[index] = 0 colors[index] = 'rgba(0, 0, 0, 0.5)' continue } - heightmap[index] = block.pos.y + heightmap[index] = hBlock.y const color = this.isOldVersion ? BlockData.colors[preflatMap.blocks[`${block.type}:${block.metadata}`]?.replaceAll(/\[.*?]/g, '')] ?? 'rgb(0, 0, 255)' : this.blockData[block.name] ?? 'rgb(0, 255, 0)' colors[index] = color } @@ -311,15 +315,19 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements const colors = Array.from({ length: 256 }).fill('') as string[] for (let z = 0; z < 16; z += 1) { for (let x = 0; x < 16; x += 1) { - const block = viewer.world.highestBlocks[`${chunkWorldX + x},${chunkWorldZ + z}`] + const blockX = chunkWorldX + x + const blockZ = chunkWorldZ + z + const hBlock = viewer.world.highestBlocks.get(`${blockX},${blockZ}`) + const block = bot.world.getBlock(new Vec3(blockX, hBlock?.y ?? 0, blockZ)) + // const block = Block.fromStateId(hBlock?.stateId ?? -1, hBlock?.biomeId ?? -1) const index = z * 16 + x - if (!block) { + if (!block || !hBlock) { console.warn(`[loadChunk] ${chunkX}, ${chunkZ}, ${chunkWorldX + x}, ${chunkWorldZ + z}`) heightmap[index] = 0 colors[index] = 'rgba(0, 0, 0, 0.5)' continue } - heightmap[index] = block.pos.y + heightmap[index] = hBlock.y const color = this.isOldVersion ? BlockData.colors[preflatMap.blocks[`${block.type}:${block.metadata}`]?.replaceAll(/\[.*?]/g, '')] ?? 'rgb(0, 0, 255)' : this.blockData[block.name] ?? 'rgb(0, 255, 0)' colors[index] = color } @@ -502,6 +510,7 @@ export default ({ displayMode }: { displayMode?: DisplayMode }) => { const { showMinimap } = useSnapshot(options) const fullMapOpened = useIsModalActive('full-map') + const readChunksHeightMaps = async () => { const { worldFolder } = localServer!.options const path = `${worldFolder}/region/r.0.0.mca` From 223c7cca17c3378ff804d87c274c67317dc1e63f Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 11 Oct 2024 00:39:36 +0400 Subject: [PATCH 229/285] fix chunk coords in region --- src/react/MinimapProvider.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index aacf60cb2..8454e3f93 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -295,7 +295,7 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements this.regions.set(regionKey, region) } const rawChunk = await this.regions.get(regionKey)! .read( - chunkX - (regionX > 0 ? 1 : -1) * regionX * 32, chunkZ - (regionZ > 0 ? 1 : -1) * regionZ * 32 + chunkX + (regionX > 0 ? 1 : -1) * regionX * 32, chunkZ + (regionZ > 0 ? 1 : -1) * regionZ * 32 ) const chunk = simplify(rawChunk as any) console.log(`chunk ${chunkX}, ${chunkZ}:`, chunk) From 4be98a8cc750bf0201241e0216775d39482c2804 Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 17 Oct 2024 14:38:21 +0400 Subject: [PATCH 230/285] chunk is loading from heightmap in greenfield --- src/react/MinimapProvider.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 8454e3f93..a2d945c98 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -267,13 +267,14 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements const blockX = chunkWorldX + x const blockZ = chunkWorldZ + z const index = z * 16 + x + heightmap[index] -= 1 + if (heightmap[index] < 0) heightmap[index] = 0 const blockY = heightmap[index] const block = chunkInfo.getBlock(new Vec3(blockX & 15, blockY, blockZ & 15)) if (!block) { console.warn(`[loadChunk] ${chunkX}, ${chunkZ}, ${chunkWorldX + x}, ${chunkWorldZ + z}`) return } - heightmap[index] = blockY const color = this.isOldVersion ? BlockData.colors[preflatMap.blocks[`${block.type}:${block.metadata}`]?.replaceAll(/\[.*?]/g, '')] ?? 'rgb(0, 0, 255)' : this.blockData[block.name] ?? 'rgb(0, 255, 0)' colors[index] = color } From 7a5ef7f1afd44753dfd1a0058ec69c3f0bd43000 Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 18 Oct 2024 12:14:59 +0400 Subject: [PATCH 231/285] fix region --- src/react/MinimapProvider.tsx | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index a2d945c98..e0c320293 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -81,17 +81,19 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements const region = new RegionFile(path) void region.initialize() this.regions.set(regionKey, region) - const readX = chunkX + (regionX > 0 ? 1 : -1) * regionX * 32 - const readZ = chunkZ + (regionZ > 0 ? 1 : -1) * regionZ * 32 + const readX = chunkX % 32 + const readZ = chunkZ % 32 void this.regions.get(regionKey)!.read(readX, readZ).then((rawChunk) => { const chunk = simplify(rawChunk as any) const heightmap = findHeightMap(chunk) if (heightmap) { this.isBuiltinHeightmapAvailable = true this.loadChunkFullmap = this.loadChunkFromRegion + console.log('using heightmap') } else { this.isBuiltinHeightmapAvailable = false this.loadChunkFullmap = this.loadChunkNoRegion + console.log('dont use heightmap') } }) } else { @@ -210,7 +212,13 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements continue } heightmap[index] = hBlock.y - const color = this.isOldVersion ? BlockData.colors[preflatMap.blocks[`${block.type}:${block.metadata}`]?.replaceAll(/\[.*?]/g, '')] ?? 'rgb(0, 0, 255)' : this.blockData[block.name] ?? 'rgb(0, 255, 0)' + let color: string + if (this.isOldVersion) { + color = BlockData.colors[preflatMap.blocks[`${block.type}:${block.metadata}`]?.replaceAll(/\[.*?]/g, '')] + ?? 'rgb(0, 0, 255)' + } else { + color = this.blockData[block.name] ?? 'rgb(0, 255, 0)' + } colors[index] = color } } @@ -239,8 +247,8 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements const blockY = this.getHighestBlockY(blockX, blockZ, chunkInfo) const block = chunkInfo.getBlock(new Vec3(blockX & 15, blockY, blockZ & 15)) if (!block) { - console.warn(`[loadChunk] ${chunkX}, ${chunkZ}, ${chunkWorldX + x}, ${chunkWorldZ + z}`) - return + console.warn(`[cannot get the block] ${chunkX}, ${chunkZ}, ${chunkWorldX + x}, ${chunkWorldZ + z}`) + return null } const index = z * 16 + x heightmap[index] = blockY @@ -272,8 +280,8 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements const blockY = heightmap[index] const block = chunkInfo.getBlock(new Vec3(blockX & 15, blockY, blockZ & 15)) if (!block) { - console.warn(`[loadChunk] ${chunkX}, ${chunkZ}, ${chunkWorldX + x}, ${chunkWorldZ + z}`) - return + console.warn(`[cannot get the block] ${chunkX}, ${chunkZ}, ${chunkWorldX + x}, ${chunkWorldZ + z}`) + return null } const color = this.isOldVersion ? BlockData.colors[preflatMap.blocks[`${block.type}:${block.metadata}`]?.replaceAll(/\[.*?]/g, '')] ?? 'rgb(0, 0, 255)' : this.blockData[block.name] ?? 'rgb(0, 255, 0)' colors[index] = color @@ -295,9 +303,7 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements await region.initialize() this.regions.set(regionKey, region) } - const rawChunk = await this.regions.get(regionKey)! .read( - chunkX + (regionX > 0 ? 1 : -1) * regionX * 32, chunkZ + (regionZ > 0 ? 1 : -1) * regionZ * 32 - ) + const rawChunk = await this.regions.get(regionKey)!.read(chunkX % 32, chunkZ % 32) const chunk = simplify(rawChunk as any) console.log(`chunk ${chunkX}, ${chunkZ}:`, chunk) const heightmap = findHeightMap(chunk) From 1976eb95c220a1ad97313665d3550eefbdca7d64 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Sun, 20 Oct 2024 20:27:03 +0300 Subject: [PATCH 232/285] feat: add a setting to either completely hide perf stats or enable more advanced display can be used for demos like: `?setting=renderDebug:"none"` --- prismarine-viewer/examples/baseScene.ts | 1 + .../viewer/lib/mesher/test/tests.test.ts | 1 - prismarine-viewer/viewer/lib/ui/newStats.ts | 3 +++ .../viewer/lib/worldrendererCommon.ts | 2 ++ .../viewer/lib/worldrendererThree.ts | 5 ++++- src/optionsGuiScheme.tsx | 7 +++++++ src/optionsStorage.ts | 2 ++ src/react/PauseScreen.tsx | 2 ++ src/topRightStats.ts | 16 +++++++++++++--- src/watchOptions.ts | 15 +++++++++++++++ 10 files changed, 49 insertions(+), 5 deletions(-) diff --git a/prismarine-viewer/examples/baseScene.ts b/prismarine-viewer/examples/baseScene.ts index 53e106c4d..652e605ba 100644 --- a/prismarine-viewer/examples/baseScene.ts +++ b/prismarine-viewer/examples/baseScene.ts @@ -154,6 +154,7 @@ export class BasePlaygroundScene { // Create viewer const viewer = new Viewer(renderer, { numWorkers: 1, showChunkBorders: false, }) window.viewer = viewer + viewer.world.isPlayground = true viewer.addChunksBatchWaitTime = 0 viewer.world.blockstatesModels = blockstatesModels viewer.entities.setDebugMode('basic') diff --git a/prismarine-viewer/viewer/lib/mesher/test/tests.test.ts b/prismarine-viewer/viewer/lib/mesher/test/tests.test.ts index 955d796e9..7c58a047c 100644 --- a/prismarine-viewer/viewer/lib/mesher/test/tests.test.ts +++ b/prismarine-viewer/viewer/lib/mesher/test/tests.test.ts @@ -51,7 +51,6 @@ test('Known blocks are not rendered', () => { "end_gateway": true, "end_portal": true, "structure_void": true, - "trial_spawner": true, } `) expect(erroredBlocks).toMatchInlineSnapshot('{}') diff --git a/prismarine-viewer/viewer/lib/ui/newStats.ts b/prismarine-viewer/viewer/lib/ui/newStats.ts index 5c11d7c73..4f4b5cee7 100644 --- a/prismarine-viewer/viewer/lib/ui/newStats.ts +++ b/prismarine-viewer/viewer/lib/ui/newStats.ts @@ -28,6 +28,9 @@ export const addNewStat = (id: string, width = 80, x = rightOffset, y = lastY) = return { updateText (text: string) { pane.innerText = text + }, + setVisibility (visible: boolean) { + pane.style.display = visible ? 'block' : 'none' } } } diff --git a/prismarine-viewer/viewer/lib/worldrendererCommon.ts b/prismarine-viewer/viewer/lib/worldrendererCommon.ts index 3527e0e7b..1edf2645d 100644 --- a/prismarine-viewer/viewer/lib/worldrendererCommon.ts +++ b/prismarine-viewer/viewer/lib/worldrendererCommon.ts @@ -39,6 +39,8 @@ type CustomTexturesData = { } export abstract class WorldRendererCommon { + isPlayground = false + displayStats = true worldConfig = { minY: 0, worldHeight: 256 } // todo need to cleanup material = new THREE.MeshLambertMaterial({ vertexColors: true, transparent: true, alphaTest: 0.1 }) diff --git a/prismarine-viewer/viewer/lib/worldrendererThree.ts b/prismarine-viewer/viewer/lib/worldrendererThree.ts index b9a9427e4..e8769c888 100644 --- a/prismarine-viewer/viewer/lib/worldrendererThree.ts +++ b/prismarine-viewer/viewer/lib/worldrendererThree.ts @@ -79,7 +79,10 @@ export class WorldRendererThree extends WorldRendererCommon { this.debugOverlayAdded = true const pane = addNewStat('debug-overlay') setInterval(() => { - pane.updateText(`C: ${this.renderer.info.render.calls} TR: ${this.renderer.info.render.triangles} TE: ${this.renderer.info.memory.textures} F: ${this.tilesRendered} B: ${this.blocksRendered}`) + pane.setVisibility(this.displayStats) + if (this.displayStats) { + pane.updateText(`C: ${this.renderer.info.render.calls} TR: ${this.renderer.info.render.triangles} TE: ${this.renderer.info.memory.textures} F: ${this.tilesRendered} B: ${this.blocksRendered}`) + } }, 100) } diff --git a/src/optionsGuiScheme.tsx b/src/optionsGuiScheme.tsx index 2add01e21..fdb1134a8 100644 --- a/src/optionsGuiScheme.tsx +++ b/src/optionsGuiScheme.tsx @@ -90,6 +90,13 @@ export const guiOptionsScheme: { }, handDisplay: {}, neighborChunkUpdates: {}, + renderDebug: { + values: [ + 'advanced', + 'basic', + 'none' + ], + }, }, ], main: [ diff --git a/src/optionsStorage.ts b/src/optionsStorage.ts index 4893b04d7..b6832ba00 100644 --- a/src/optionsStorage.ts +++ b/src/optionsStorage.ts @@ -5,6 +5,7 @@ import { proxy, subscribe } from 'valtio/vanilla' import { subscribeKey } from 'valtio/utils' import { omitObj } from '@zardoy/utils' +const isDev = process.env.NODE_ENV === 'development' const defaultOptions = { renderDistance: 3, keepChunksDistance: 1, @@ -75,6 +76,7 @@ const defaultOptions = { autoJump: 'auto' as 'auto' | 'always' | 'never', autoParkour: false, vrSupport: true, // doesn't directly affect the VR mode, should only disable the button which is annoying to android users + renderDebug: (isDev ? 'basic' : 'advanced') as 'none' | 'advanced' | 'basic', // advanced bot options autoRespawn: false, diff --git a/src/react/PauseScreen.tsx b/src/react/PauseScreen.tsx index 19f1385cb..75b94872b 100644 --- a/src/react/PauseScreen.tsx +++ b/src/react/PauseScreen.tsx @@ -237,6 +237,7 @@ export default () => { {(navigator.share as typeof navigator.share | undefined) ? (