good release! (#117)
This commit is contained in:
commit
eb4173bfcb
18 changed files with 223 additions and 20 deletions
|
|
@ -46,6 +46,9 @@ const buildOptions = {
|
|||
// using \n breaks sourcemaps!
|
||||
js: banner.join(';'),
|
||||
},
|
||||
external: [
|
||||
'sharp'
|
||||
],
|
||||
alias: {
|
||||
events: 'events', // make explicit
|
||||
buffer: 'buffer',
|
||||
|
|
@ -56,7 +59,8 @@ const buildOptions = {
|
|||
stream: 'stream-browserify',
|
||||
net: 'net-browserify',
|
||||
assert: 'assert',
|
||||
dns: './src/dns.js'
|
||||
dns: './src/dns.js',
|
||||
// todo write advancedAliases plugin
|
||||
},
|
||||
inject: [
|
||||
'./src/shims.js'
|
||||
|
|
|
|||
15
experiments/ios-safe-area-bottom-bug.html
Normal file
15
experiments/ios-safe-area-bottom-bug.html
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<style>
|
||||
div {
|
||||
position: fixed;
|
||||
bottom: env(safe-area-inset-bottom);
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: #f00;
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
</style>
|
||||
<div>
|
||||
<span>bottom: env(safe-area-inset-bottom)</span>
|
||||
</div>
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
"lint": "eslint \"{src,cypress}/**/*.{ts,js,jsx,tsx}\"",
|
||||
"storybook": "storybook dev -p 6006",
|
||||
"build-storybook": "storybook build && node scripts/build.js moveStorybookFiles",
|
||||
"start-experiments": "vite --config experiments/vite.config.ts",
|
||||
"start-experiments": "vite --config experiments/vite.config.ts --host",
|
||||
"watch-other-workers": "echo NOT IMPLEMENTED",
|
||||
"watch-mesher": "node prismarine-viewer/buildMesherWorker.mjs -w",
|
||||
"run-playground": "run-p watch-mesher watch-other-workers playground-server watch-playground",
|
||||
|
|
@ -72,6 +72,7 @@
|
|||
"minecraft-assets": "^1.12.2",
|
||||
"minecraft-data": "3.65.0",
|
||||
"minecraft-protocol": "github:PrismarineJS/node-minecraft-protocol",
|
||||
"mineflayer-item-map-downloader": "github:zardoy/mineflayer-item-map-downloader",
|
||||
"mojangson": "^2.0.4",
|
||||
"net-browserify": "github:zardoy/prismarinejs-net-browserify",
|
||||
"node-gzip": "^1.1.2",
|
||||
|
|
|
|||
44
pnpm-lock.yaml
generated
44
pnpm-lock.yaml
generated
|
|
@ -130,6 +130,9 @@ importers:
|
|||
minecraft-protocol:
|
||||
specifier: github:PrismarineJS/node-minecraft-protocol
|
||||
version: https://codeload.github.com/PrismarineJS/node-minecraft-protocol/tar.gz/ccab9fb39681f3ebe0d264e2a3f833aa3c5a1ac7(patch_hash=2uxevyasyasdavsxuehfavgkjq)(encoding@0.1.13)
|
||||
mineflayer-item-map-downloader:
|
||||
specifier: github:zardoy/mineflayer-item-map-downloader
|
||||
version: https://codeload.github.com/zardoy/mineflayer-item-map-downloader/tar.gz/642fd4f7023a98a96da4caf8f993f8e19361a1e7(encoding@0.1.13)
|
||||
mojangson:
|
||||
specifier: ^2.0.4
|
||||
version: 2.0.4
|
||||
|
|
@ -6058,9 +6061,17 @@ packages:
|
|||
minecrafthawkeye@1.3.6:
|
||||
resolution: {integrity: sha512-SlRlorxQs6nNzMiiIQ5z47wzbAI27UaCdbRB82CE8jqj4C8m3Gqk5TlgN+PSThxx8EDPXySzd8Vk+/wNigAd5A==}
|
||||
|
||||
mineflayer-item-map-downloader@https://codeload.github.com/zardoy/mineflayer-item-map-downloader/tar.gz/642fd4f7023a98a96da4caf8f993f8e19361a1e7:
|
||||
resolution: {tarball: https://codeload.github.com/zardoy/mineflayer-item-map-downloader/tar.gz/642fd4f7023a98a96da4caf8f993f8e19361a1e7}
|
||||
version: 1.2.0
|
||||
|
||||
mineflayer-pathfinder@2.4.4:
|
||||
resolution: {integrity: sha512-HAXakZrJRb1UC+5dv8EaDrqjW3ZnBnBk3nkb6x/YWyhHCUKn/E7VU0FO+UN9whuqPlkSaVumEdXJdydE6lSYxQ==}
|
||||
|
||||
mineflayer@4.20.1:
|
||||
resolution: {integrity: sha512-QMMNPx4IyZE7ydAzjvGLQLCnQNUOfkk1qVZKxTTS9q3qPTAewz4GhsVUBtbQ8LSbHthe5RcQ1Sgxs4wlIma/Qw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
mineflayer@https://codeload.github.com/PrismarineJS/mineflayer/tar.gz/5a544cf2547a6e0f1f17786962d77a33c661c02f:
|
||||
resolution: {tarball: https://codeload.github.com/PrismarineJS/mineflayer/tar.gz/5a544cf2547a6e0f1f17786962d77a33c661c02f}
|
||||
version: 4.20.1
|
||||
|
|
@ -15753,6 +15764,14 @@ snapshots:
|
|||
detect-collisions: 7.0.5
|
||||
vec3: 0.1.8
|
||||
|
||||
mineflayer-item-map-downloader@https://codeload.github.com/zardoy/mineflayer-item-map-downloader/tar.gz/642fd4f7023a98a96da4caf8f993f8e19361a1e7(encoding@0.1.13):
|
||||
dependencies:
|
||||
mineflayer: 4.20.1(encoding@0.1.13)
|
||||
sharp: 0.30.7
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
- supports-color
|
||||
|
||||
mineflayer-pathfinder@2.4.4:
|
||||
dependencies:
|
||||
minecraft-data: 3.65.0
|
||||
|
|
@ -15763,6 +15782,29 @@ snapshots:
|
|||
prismarine-physics: 1.8.0
|
||||
vec3: 0.1.8
|
||||
|
||||
mineflayer@4.20.1(encoding@0.1.13):
|
||||
dependencies:
|
||||
minecraft-data: 3.65.0
|
||||
minecraft-protocol: https://codeload.github.com/PrismarineJS/node-minecraft-protocol/tar.gz/ccab9fb39681f3ebe0d264e2a3f833aa3c5a1ac7(patch_hash=2uxevyasyasdavsxuehfavgkjq)(encoding@0.1.13)
|
||||
prismarine-biome: 1.3.0(minecraft-data@3.65.0)(prismarine-registry@1.7.0)
|
||||
prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/ada4ec3fdfbbc1cc20ab01d0e23f0718a77cc1a0
|
||||
prismarine-chat: 1.10.1
|
||||
prismarine-chunk: https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/f32234a724a5c2482ffbaf85edc5e91c7ab9b38f(minecraft-data@3.65.0)
|
||||
prismarine-entity: 2.3.1
|
||||
prismarine-item: 1.14.0
|
||||
prismarine-nbt: 2.5.0
|
||||
prismarine-physics: 1.8.0
|
||||
prismarine-recipe: 1.3.1(prismarine-registry@1.7.0)
|
||||
prismarine-registry: 1.7.0
|
||||
prismarine-windows: 2.9.0
|
||||
prismarine-world: https://codeload.github.com/zardoy/prismarine-world/tar.gz/6ae6f009d38460de284f8c226c665f04cbad9465
|
||||
protodef: 1.15.0
|
||||
typed-emitter: 1.4.0
|
||||
vec3: 0.1.8
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
- supports-color
|
||||
|
||||
mineflayer@https://codeload.github.com/PrismarineJS/mineflayer/tar.gz/5a544cf2547a6e0f1f17786962d77a33c661c02f(encoding@0.1.13):
|
||||
dependencies:
|
||||
minecraft-data: 3.65.0
|
||||
|
|
@ -17408,7 +17450,7 @@ snapshots:
|
|||
detect-libc: 2.0.2
|
||||
node-addon-api: 5.1.0
|
||||
prebuild-install: 7.1.1
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
simple-get: 4.0.1
|
||||
tar-fs: 2.1.1
|
||||
tunnel-agent: 0.6.0
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ async function main () {
|
|||
viewer.entities.onSkinUpdate = () => {
|
||||
viewer.render()
|
||||
}
|
||||
viewer.world.mesherConfig.enableLighting = false
|
||||
|
||||
viewer.listen(worldView)
|
||||
// Load chunks
|
||||
|
|
|
|||
|
|
@ -38,8 +38,22 @@ export const setup = (version, initialBlocks: [number[], string][]) => {
|
|||
}
|
||||
reload()
|
||||
|
||||
const getLights = () => {
|
||||
return Object.fromEntries(getGeometry().faces.map(({ face, light }) => ([face, light * 15 - 2])))
|
||||
}
|
||||
|
||||
const setLight = (x: number, y: number, z: number, val = 0) => {
|
||||
// create columns first
|
||||
chunk1.setBlockLight(pos.offset(x, y, z), 15)
|
||||
chunk1.setSkyLight(pos.offset(x, y, z), 15)
|
||||
chunk1.setBlockLight(pos.offset(x, y, z), val)
|
||||
chunk1.setSkyLight(pos.offset(x, y, z), 0)
|
||||
}
|
||||
|
||||
return {
|
||||
mesherWorld,
|
||||
setLight,
|
||||
getLights,
|
||||
getGeometry,
|
||||
pos,
|
||||
mcData,
|
||||
|
|
|
|||
|
|
@ -23,3 +23,23 @@ Object.defineProperty(window, 'debugSceneChunks', {
|
|||
return (viewer.world as WorldRendererThree).getLoadedChunksRelative?.(bot.entity.position, true)
|
||||
},
|
||||
})
|
||||
|
||||
window.len = (obj) => Object.keys(obj).length
|
||||
|
||||
window.inspectPacket = (packetName, full = false) => {
|
||||
const listener = (...args) => console.log('packet', packetName, full ? args : args[0])
|
||||
const attach = () => {
|
||||
bot?.on(packetName, listener)
|
||||
}
|
||||
attach()
|
||||
customEvents.on('mineflayerBotCreated', attach)
|
||||
const returnobj = {}
|
||||
Object.defineProperty(returnobj, 'detach', {
|
||||
get () {
|
||||
bot?.removeListener(packetName, listener)
|
||||
customEvents.removeListener('mineflayerBotCreated', attach)
|
||||
return true
|
||||
},
|
||||
})
|
||||
return returnobj
|
||||
}
|
||||
|
|
|
|||
19
src/index.ts
19
src/index.ts
|
|
@ -128,6 +128,12 @@ if (isFirefox) {
|
|||
document.body.style.setProperty('--thin-if-firefox', 'thin')
|
||||
}
|
||||
|
||||
const isIphone = ua.getDevice().model === 'iPhone' // todo ipad?
|
||||
|
||||
if (isIphone) {
|
||||
document.documentElement.style.setProperty('--hud-bottom-max', '21px') // env-safe-aria-inset-bottom
|
||||
}
|
||||
|
||||
// Create viewer
|
||||
const viewer: import('prismarine-viewer/viewer/lib/viewer').Viewer = new Viewer(renderer)
|
||||
window.viewer = viewer
|
||||
|
|
@ -438,7 +444,9 @@ async function connect (connectOptions: ConnectOptions) {
|
|||
async versionSelectedHook (client) {
|
||||
await downloadMcData(client.version)
|
||||
setLoadingScreenStatus(initialLoadingText)
|
||||
}
|
||||
},
|
||||
'mapDownloader-saveToFile': false,
|
||||
// "mapDownloader-saveInternal": false, // do not save into memory, todo must be implemeneted as we do really care of ram
|
||||
}) as unknown as typeof __type_bot
|
||||
window.bot = bot
|
||||
earlySoundsMapCheck()
|
||||
|
|
@ -539,6 +547,15 @@ async function connect (connectOptions: ConnectOptions) {
|
|||
window.Vec3 = Vec3
|
||||
window.pathfinder = pathfinder
|
||||
|
||||
// patch mineflayer
|
||||
// todo move to mineflayer
|
||||
bot.inventory.on('updateSlot', (index) => {
|
||||
if ((index as unknown as number) === bot.quickBarSlot + bot.inventory.hotbarStart) {
|
||||
//@ts-expect-error
|
||||
bot.emit('heldItemChanged')
|
||||
}
|
||||
})
|
||||
|
||||
miscUiState.gameLoaded = true
|
||||
miscUiState.loadedServerIndex = connectOptions.serverIndex ?? ''
|
||||
customEvents.emit('gameLoaded')
|
||||
|
|
|
|||
55
src/react/HeldMapUi.tsx
Normal file
55
src/react/HeldMapUi.tsx
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import { useEffect, useState } from 'react'
|
||||
import { mapDownloader } from 'mineflayer-item-map-downloader/'
|
||||
import { setImageConverter } from 'mineflayer-item-map-downloader/lib/util'
|
||||
|
||||
export default () => {
|
||||
const [dataUrl, setDataUrl] = useState<string | null | true>(null) // true means loading
|
||||
|
||||
useEffect(() => {
|
||||
bot.loadPlugin(mapDownloader)
|
||||
|
||||
setImageConverter((buf: Uint8Array) => {
|
||||
const canvas = document.createElement('canvas')
|
||||
const ctx = canvas.getContext('2d')!
|
||||
canvas.width = 128
|
||||
canvas.height = 128
|
||||
const imageData = ctx.createImageData(canvas.width, canvas.height)
|
||||
imageData.data.set(buf)
|
||||
ctx.putImageData(imageData, 0, 0)
|
||||
// data url
|
||||
return canvas.toDataURL('image/png')
|
||||
})
|
||||
|
||||
// TODO delete maps!
|
||||
const updateHeldMap = () => {
|
||||
setDataUrl(null)
|
||||
if (!bot.heldItem || !['filled_map', 'map'].includes(bot.heldItem.name)) return
|
||||
// setDataUrl(true)
|
||||
const mapNumber = (bot.heldItem?.nbt?.value as any)?.map?.value
|
||||
// if (!mapNumber) return
|
||||
setDataUrl(bot.mapDownloader.maps?.[mapNumber] as unknown as string)
|
||||
}
|
||||
|
||||
bot.on('heldItemChanged' as any, () => {
|
||||
updateHeldMap()
|
||||
})
|
||||
|
||||
bot.on('new_map', () => {
|
||||
// total maps: Object.keys(bot.mapDownloader.maps).length
|
||||
updateHeldMap()
|
||||
})
|
||||
}, [])
|
||||
|
||||
return dataUrl && dataUrl !== true ? <div style={{
|
||||
position: 'fixed',
|
||||
bottom: 20,
|
||||
left: 8,
|
||||
pointerEvents: 'none',
|
||||
}}>
|
||||
<img src={dataUrl} style={{
|
||||
width: 92,
|
||||
height: 92,
|
||||
imageRendering: 'pixelated',
|
||||
}} />
|
||||
</div> : null
|
||||
}
|
||||
|
|
@ -211,7 +211,7 @@ export default () => {
|
|||
justifyContent: 'center',
|
||||
zIndex: hasModals ? 1 : 8,
|
||||
pointerEvents: 'none',
|
||||
bottom: 'env(safe-area-inset-bottom)'
|
||||
bottom: 'var(--hud-bottom-raw)'
|
||||
}} />
|
||||
</Portal>
|
||||
</SharedHudVars>
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ import './IndicatorEffects.css'
|
|||
function formatTime (seconds: number): string {
|
||||
if (seconds < 0) return ''
|
||||
const minutes = Math.floor(seconds / 60)
|
||||
const remainingSeconds = seconds % 60
|
||||
const remainingSeconds = Math.floor(seconds % 60)
|
||||
const formattedMinutes = String(minutes).padStart(2, '0')
|
||||
const formattedSeconds = String(remainingSeconds).padStart(2, '0')
|
||||
const formattedSeconds = String(remainingSeconds)
|
||||
return `${formattedMinutes}:${formattedSeconds}`
|
||||
}
|
||||
|
||||
|
|
@ -32,10 +32,10 @@ const EffectBox = ({ image, time, level }: Pick<EffectType, 'image' | 'time' | '
|
|||
// if time is negative then effect is shown without time.
|
||||
// Component should be removed manually with time = 0
|
||||
<div className='effect-box__time'>{formattedTime}</div>
|
||||
) : null }
|
||||
) : null}
|
||||
{level > 0 && level < 256 ? (
|
||||
<div className='effect-box__level'>{level + 1}</div>
|
||||
) : null }
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
|
@ -56,7 +56,7 @@ const indicatorIcons: Record<keyof typeof defaultIndicatorsState, string> = {
|
|||
readonlyFiles: 'file-off',
|
||||
}
|
||||
|
||||
export default ({ indicators, effects }: {indicators: typeof defaultIndicatorsState, effects: readonly EffectType[]}) => {
|
||||
export default ({ indicators, effects }: { indicators: typeof defaultIndicatorsState, effects: readonly EffectType[] }) => {
|
||||
const effectsRef = useRef(effects)
|
||||
useEffect(() => {
|
||||
effectsRef.current = effects
|
||||
|
|
|
|||
|
|
@ -60,14 +60,22 @@ export default ({ initialProxies, updateProxies: updateProxiesProp, joinServer,
|
|||
return <Singleplayer {...props}
|
||||
firstRowChildrenOverride={<form style={{ width: '100%', display: 'flex', justifyContent: 'center' }} onSubmit={(e) => {
|
||||
e.preventDefault()
|
||||
joinServer(serverIp, {
|
||||
let ip = serverIp
|
||||
let version
|
||||
const parts = ip.split(':')
|
||||
if (parts.length > 1 && parts.at(-1)!.includes('.')) {
|
||||
version = parts.at(-1)!
|
||||
ip = parts.slice(0, -1).join(':')
|
||||
}
|
||||
joinServer(ip, {
|
||||
shouldSave: save,
|
||||
versionOverride: version,
|
||||
})
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', gap: 5, alignItems: 'center' }}>
|
||||
{/* todo history */}
|
||||
<Input required placeholder='Quick Connect IP' value={serverIp} onChange={({ target: { value } }) => setServerIp(value)} />
|
||||
<Input required placeholder='Quick Connect IP (:version)' value={serverIp} onChange={({ target: { value } }) => setServerIp(value)} />
|
||||
<label style={{ fontSize: 10, display: 'flex', alignItems: 'center', gap: 5, height: '100%', marginTop: '-1px' }}>
|
||||
<input type='checkbox' checked={save}
|
||||
style={{ borderRadius: 0 }}
|
||||
|
|
|
|||
|
|
@ -114,6 +114,9 @@ export const updateLoadedServerData = (callback: (data: StoreServerItem) => Stor
|
|||
setNewServersList(servers)
|
||||
}
|
||||
|
||||
// todo move to base
|
||||
const normalizeIp = (ip: string) => ip.replace(/https?:\/\//, '').replace(/\/(:|$)/, '')
|
||||
|
||||
const Inner = () => {
|
||||
const [proxies, setProxies] = useState<readonly string[]>(localStorage['proxies'] ? JSON.parse(localStorage['proxies']) : getInitialProxies())
|
||||
const [selectedProxy, setSelectedProxy] = useState(localStorage.getItem('selectedProxy') ?? proxies?.[0] ?? '')
|
||||
|
|
@ -210,7 +213,7 @@ const Inner = () => {
|
|||
onQsConnect={(info) => {
|
||||
const connectOptions: ConnectOptions = {
|
||||
username: info.usernameOverride || defaultUsername,
|
||||
server: info.ip,
|
||||
server: normalizeIp(info.ip),
|
||||
proxy: info.proxyOverride || selectedProxy,
|
||||
botVersion: info.versionOverride,
|
||||
password: info.passwordOverride,
|
||||
|
|
@ -241,7 +244,7 @@ const Inner = () => {
|
|||
}
|
||||
const options = {
|
||||
username,
|
||||
server: ip,
|
||||
server: normalizeIp(ip),
|
||||
proxy: overrides.proxy || selectedProxy,
|
||||
botVersion: overrides.versionOverride ?? /* legacy */ overrides['version'],
|
||||
password: overrides.password,
|
||||
|
|
|
|||
|
|
@ -8,10 +8,12 @@ export default ({ children }): React.ReactElement => {
|
|||
// 1. Don't inline long data URLs for better DX in elements tab
|
||||
// 2. Easier application to globally override icons with custom image (eg from resourcepacks)
|
||||
const css = /* css */`
|
||||
:root {
|
||||
html {
|
||||
--widgets-gui-atlas: url(${widgets});
|
||||
--gui-icons: url(${icons}), url(${icons});
|
||||
--safe-area-inset-bottom: calc(env(safe-area-inset-bottom) / 2);
|
||||
--hud-bottom-max: 0px;
|
||||
--hud-bottom-raw: max(env(safe-area-inset-bottom), var(--hud-bottom-max));
|
||||
--safe-area-inset-bottom: calc(var(--hud-bottom-raw) / 2);
|
||||
}
|
||||
`
|
||||
const style = document.createElement('style')
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
.world_root {
|
||||
height: 40px;
|
||||
width: 300px;
|
||||
width: 308px;
|
||||
border: 1px solid transparent;
|
||||
display: flex;
|
||||
outline: none;
|
||||
|
|
@ -43,6 +43,7 @@
|
|||
flex-direction: column;
|
||||
font-size: 11px;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
}
|
||||
.world_info_formatted {
|
||||
font-size: 10px;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import Crosshair from './react/Crosshair'
|
|||
import ButtonAppProvider from './react/ButtonAppProvider'
|
||||
import ServersListProvider from './react/ServersListProvider'
|
||||
import GamepadUiCursor from './react/GamepadUiCursor'
|
||||
import HeldMapUi from './react/HeldMapUi'
|
||||
|
||||
const RobustPortal = ({ children, to }) => {
|
||||
return createPortal(<PerComponentErrorBoundary>{children}</PerComponentErrorBoundary>, to)
|
||||
|
|
@ -85,6 +86,12 @@ const GameHud = ({ children }) => {
|
|||
return gameLoaded ? children : null
|
||||
}
|
||||
|
||||
const InGameComponent = ({ children }) => {
|
||||
const { gameLoaded } = useSnapshot(miscUiState)
|
||||
if (!gameLoaded) return null
|
||||
return children
|
||||
}
|
||||
|
||||
const InGameUi = () => {
|
||||
const { gameLoaded } = useSnapshot(miscUiState)
|
||||
if (!gameLoaded) return
|
||||
|
|
@ -135,6 +142,14 @@ const WidgetDisplay = ({ name, Component }) => {
|
|||
const App = () => {
|
||||
return <div>
|
||||
<ButtonAppProvider>
|
||||
<RobustPortal to={document.body}>
|
||||
<div className='overlay-bottom-scaled'>
|
||||
<InGameComponent>
|
||||
<HeldMapUi />
|
||||
</InGameComponent>
|
||||
</div>
|
||||
<div></div>
|
||||
</RobustPortal>
|
||||
<EnterFullscreenButton />
|
||||
<InGameUi />
|
||||
<RobustPortal to={document.querySelector('#ui-root')}>
|
||||
|
|
@ -151,6 +166,7 @@ const App = () => {
|
|||
</GameHud> */}
|
||||
</RobustPortal>
|
||||
<RobustPortal to={document.body}>
|
||||
{/* todo correct mounting! */}
|
||||
<div className='overlay-top-scaled'>
|
||||
<GamepadUiCursor />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ body {
|
|||
-ms-interpolation-mode: nearest-neighbor;
|
||||
}
|
||||
|
||||
.overlay-top-scaled {
|
||||
.overlay-top-scaled, .overlay-bottom-scaled {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
transform-origin: top left;
|
||||
|
|
@ -146,6 +146,10 @@ body {
|
|||
pointer-events: none;
|
||||
}
|
||||
|
||||
.overlay-bottom-scaled {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#viewer-canvas {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ class WorldInteraction {
|
|||
'minecart', 'boat', 'tnt_minecart', 'chest_minecart', 'hopper_minecart',
|
||||
'command_block_minecart', 'armor_stand', 'lead', 'name_tag',
|
||||
//
|
||||
'writable_book', 'written_book', 'compass', 'clock', 'filled_map', 'empty_map',
|
||||
'writable_book', 'written_book', 'compass', 'clock', 'filled_map', 'empty_map', 'map',
|
||||
'shears', 'carrot_on_a_stick', 'warped_fungus_on_a_stick',
|
||||
'spawn_egg', 'trident', 'crossbow', 'elytra', 'shield', 'turtle_helmet',
|
||||
].includes(bot.heldItem.name)
|
||||
|
|
@ -219,10 +219,10 @@ class WorldInteraction {
|
|||
bot.lookAt = oldLookAt
|
||||
}).catch(console.warn)
|
||||
}
|
||||
this.lastBlockPlaced = 0
|
||||
} else {
|
||||
bot.activateItem() // todo offhand
|
||||
}
|
||||
this.lastBlockPlaced = 0
|
||||
}
|
||||
|
||||
// Stop break
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue