diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx deleted file mode 100644 index cfbc1e2..0000000 --- a/app/(tabs)/_layout.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { Tabs } from 'expo-router'; -import React from 'react'; -import { Platform } from 'react-native'; - -import { HapticTab } from '@/components/HapticTab'; -import { IconSymbol } from '@/components/ui/IconSymbol'; -import TabBarBackground from '@/components/ui/TabBarBackground'; -import { Colors } from '@/constants/Colors'; -import { useColorScheme } from '@/hooks/useColorScheme'; - -export default function TabLayout() { - const colorScheme = useColorScheme(); - - return ( - - , - }} - /> - , - }} - /> - - ); -} diff --git a/app/(tabs)/explore.tsx b/app/(tabs)/explore.tsx deleted file mode 100644 index d4fbcaa..0000000 --- a/app/(tabs)/explore.tsx +++ /dev/null @@ -1,110 +0,0 @@ -import { Image } from 'expo-image'; -import { Platform, StyleSheet } from 'react-native'; - -import { Collapsible } from '@/components/Collapsible'; -import { ExternalLink } from '@/components/ExternalLink'; -import ParallaxScrollView from '@/components/ParallaxScrollView'; -import { ThemedText } from '@/components/ThemedText'; -import { ThemedView } from '@/components/ThemedView'; -import { IconSymbol } from '@/components/ui/IconSymbol'; - -export default function TabTwoScreen() { - return ( - - }> - - Explore - - This app includes example code to help you get started. - - - This app has two screens:{' '} - app/(tabs)/index.tsx and{' '} - app/(tabs)/explore.tsx - - - The layout file in app/(tabs)/_layout.tsx{' '} - sets up the tab navigator. - - - Learn more - - - - - You can open this project on Android, iOS, and the web. To open the web version, press{' '} - w in the terminal running this project. - - - - - For static images, you can use the @2x and{' '} - @3x suffixes to provide files for - different screen densities - - - - Learn more - - - - - Open app/_layout.tsx to see how to load{' '} - - custom fonts such as this one. - - - - Learn more - - - - - This template has light and dark mode support. The{' '} - useColorScheme() hook lets you inspect - what the user's current color scheme is, and so you can adjust UI colors accordingly. - - - Learn more - - - - - This template includes an example of an animated component. The{' '} - components/HelloWave.tsx component uses - the powerful react-native-reanimated{' '} - library to create a waving hand animation. - - {Platform.select({ - ios: ( - - The components/ParallaxScrollView.tsx{' '} - component provides a parallax effect for the header image. - - ), - })} - - - ); -} - -const styles = StyleSheet.create({ - headerImage: { - color: '#808080', - bottom: -90, - left: -35, - position: 'absolute', - }, - titleContainer: { - flexDirection: 'row', - gap: 8, - }, -}); diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx deleted file mode 100644 index 462e8cd..0000000 --- a/app/(tabs)/index.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import { Image } from 'expo-image'; -import { Platform, StyleSheet } from 'react-native'; - -import { HelloWave } from '@/components/HelloWave'; -import ParallaxScrollView from '@/components/ParallaxScrollView'; -import { ThemedText } from '@/components/ThemedText'; -import { ThemedView } from '@/components/ThemedView'; - -export default function HomeScreen() { - return ( - - }> - - Welcome! - - - - Step 1: Try it - - Edit app/(tabs)/index.tsx to see changes. - Press{' '} - - {Platform.select({ - ios: 'cmd + d', - android: 'cmd + m', - web: 'F12', - })} - {' '} - to open developer tools. - - - - Step 2: Explore - - {`Tap the Explore tab to learn more about what's included in this starter app.`} - - - - Step 3: Get a fresh start - - {`When you're ready, run `} - npm run reset-project to get a fresh{' '} - app directory. This will move the current{' '} - app to{' '} - app-example. - - - - ); -} - -const styles = StyleSheet.create({ - titleContainer: { - flexDirection: 'row', - alignItems: 'center', - gap: 8, - }, - stepContainer: { - gap: 8, - marginBottom: 8, - }, - reactLogo: { - height: 178, - width: 290, - bottom: 0, - left: 0, - position: 'absolute', - }, -}); diff --git a/app/+not-found.tsx b/app/+not-found.tsx deleted file mode 100644 index 215b0ed..0000000 --- a/app/+not-found.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { Link, Stack } from 'expo-router'; -import { StyleSheet } from 'react-native'; - -import { ThemedText } from '@/components/ThemedText'; -import { ThemedView } from '@/components/ThemedView'; - -export default function NotFoundScreen() { - return ( - <> - - - This screen does not exist. - - Go to home screen! - - - - ); -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - alignItems: 'center', - justifyContent: 'center', - padding: 20, - }, - link: { - marginTop: 15, - paddingVertical: 15, - }, -}); diff --git a/app/_layout.tsx b/app/_layout.tsx index 8d506f7..889f341 100644 --- a/app/_layout.tsx +++ b/app/_layout.tsx @@ -1,29 +1,5 @@ -import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native'; -import { useFonts } from 'expo-font'; -import { Stack } from 'expo-router'; -import { StatusBar } from 'expo-status-bar'; -import 'react-native-reanimated'; - -import { useColorScheme } from '@/hooks/useColorScheme'; +import { Stack } from "expo-router"; export default function RootLayout() { - const colorScheme = useColorScheme(); - const [loaded] = useFonts({ - SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'), - }); - - if (!loaded) { - // Async font loading only occurs in development. - return null; - } - - return ( - - - - - - - - ); + return ; } diff --git a/app/index.tsx b/app/index.tsx new file mode 100644 index 0000000..bb03ed8 --- /dev/null +++ b/app/index.tsx @@ -0,0 +1,1277 @@ +import { Asset } from 'expo-asset'; +import { GLView } from 'expo-gl'; +import { Renderer } from 'expo-three'; +import React, { useEffect, useRef, useState } from 'react'; +import { Dimensions, PanResponder, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; +import * as THREE from 'three'; +import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; + +import background1 from '@/assets/images/background-1.jpg'; + +const { width, height } = Dimensions.get('window'); + +interface HexagonTile { + position: THREE.Vector3; + mesh?: THREE.Mesh | null; + stroke?: THREE.Mesh | null; + occupied: boolean; + unit?: THREE.Mesh; + biome: 'desert' | 'grass' | 'water' | 'forest' | 'rock'; + modelPath?: string; +} + +interface Unit { + id: string; + name: string; + color: number; + cost: number; + level: number; +} + +export default function TFTGameScene() { + const sceneRef = useRef(null); + const cameraRef = useRef(null); + const rendererRef = useRef(null); + const tilesRef = useRef([]); + const animationFrameRef = useRef(null); + const [selectedUnit, setSelectedUnit] = useState(null); + const [gold, setGold] = useState(10); + const [isDragging, setIsDragging] = useState(false); + const [dragStartPosition, setDragStartPosition] = useState({ x: 0, y: 0 }); + const [draggedTile, setDraggedTile] = useState<{ row: number; col: number } | null>(null); + const [dragPosition, setDragPosition] = useState({ x: 0, y: 0 }); + const [draggedUnitMesh, setDraggedUnitMesh] = useState(null); + const [availableUnits, setAvailableUnits] = useState([ + { id: '1', name: 'Warrior', color: 0xff6b6b, cost: 3, level: 1 }, + { id: '2', name: 'Mage', color: 0x4ecdc4, cost: 4, level: 1 }, + { id: '3', name: 'Archer', color: 0x45b7d1, cost: 2, level: 1 }, + { id: '4', name: 'Tank', color: 0x96ceb4, cost: 5, level: 1 }, + { id: '5', name: 'Assassin', color: 0xfeca57, cost: 3, level: 1 }, + { id: '6', name: 'Knight', color: 0x9b59b6, cost: 4, level: 1 }, + { id: '7', name: 'Priest', color: 0xe74c3c, cost: 2, level: 1 }, + { id: '8', name: 'Wizard', color: 0x3498db, cost: 3, level: 1 }, + { id: '9', name: 'Ranger', color: 0x2ecc71, cost: 2, level: 1 }, + { id: '10', name: 'Guardian', color: 0xf39c12, cost: 4, level: 1 }, + { id: '11', name: 'Berserker', color: 0xe67e22, cost: 3, level: 1 }, + { id: '12', name: 'Sorcerer', color: 0x8e44ad, cost: 5, level: 1 }, + { id: '13', name: 'Scout', color: 0x16a085, cost: 2, level: 1 }, + { id: '14', name: 'Paladin', color: 0xc0392b, cost: 4, level: 1 }, + { id: '15', name: 'Necromancer', color: 0x7f8c8d, cost: 3, level: 1 }, + { id: '16', name: 'Dragon', color: 0xe74c3c, cost: 5, level: 1 }, + ]); + + // GLB model loader + const gltfLoader = new GLTFLoader(); + + // Load GLB model with proper asset handling + const loadGLBModel = async (modelPath: string): Promise => { + try { + // Use static require for GLB models + let asset; + switch (modelPath) { + case 'hex_sand_detail.gltf.glb': + asset = Asset.fromModule(require('../assets/arena/hex_sand_detail.gltf.glb')); + break; + case 'hex_forest.gltf.glb': + asset = Asset.fromModule(require('../assets/arena/hex_forest.gltf.glb')); + break; + case 'hex_water_detail.gltf.glb': + asset = Asset.fromModule(require('../assets/arena/hex_water_detail.gltf.glb')); + break; + case 'hex_rock_detail.gltf.glb': + asset = Asset.fromModule(require('../assets/arena/hex_rock_detail.gltf.glb')); + break; + case 'hex_sand_roadA.gltf.glb': + asset = Asset.fromModule(require('../assets/arena/hex_sand_roadA.gltf.glb')); + break; + default: + console.log('Model not found:', modelPath); + return null; + } + + await asset.downloadAsync(); + + return new Promise((resolve, reject) => { + gltfLoader.load( + asset.uri, + (gltf) => { + const model = gltf.scene; + // Scale to fit within hexagon (radius = 0.5) + model.scale.set(0.4, 0.4, 0.4); + // Rotate model to align with our hexagons (vertical) + model.rotation.y = Math.PI / 6; // 30 degrees to align with our hexagons + // Position underneath hexagon with minimal gap + model.position.y = -0.01; // Minimal gap + resolve(model); + }, + undefined, + (error) => { + console.error('Error loading GLB model:', error); + reject(error); + } + ); + }); + } catch (error) { + console.error('Error loading GLB model:', error); + return null; + } + }; + + // Create enhanced geometry for different biomes + const createEnhancedGeometry = (biome: string, radius: number = 0.5) => { + switch (biome) { + case 'desert': + // Create sand-like geometry with bumps + const sandGeometry = new THREE.CylinderGeometry(radius, radius, 0.1, 6); + const sandMaterial = new THREE.MeshLambertMaterial({ + color: 0xd2b48c, + transparent: true, + opacity: 0.9 + }); + return new THREE.Mesh(sandGeometry, sandMaterial); + + case 'water': + // Create water-like geometry with waves + const waterGeometry = new THREE.CylinderGeometry(radius, radius, 0.08, 6); + const waterMaterial = new THREE.MeshLambertMaterial({ + color: 0x87CEEB, + transparent: true, + opacity: 0.7 + }); + return new THREE.Mesh(waterGeometry, waterMaterial); + + case 'forest': + // Create forest-like geometry with texture + const forestGeometry = new THREE.CylinderGeometry(radius, radius, 0.12, 6); + const forestMaterial = new THREE.MeshLambertMaterial({ + color: 0x228B22, + transparent: true, + opacity: 0.9 + }); + return new THREE.Mesh(forestGeometry, forestMaterial); + + case 'rock': + // Create rock-like geometry with roughness + const rockGeometry = new THREE.CylinderGeometry(radius, radius, 0.15, 6); + const rockMaterial = new THREE.MeshLambertMaterial({ + color: 0x696969, + transparent: true, + opacity: 0.9 + }); + return new THREE.Mesh(rockGeometry, rockMaterial); + + default: + // Default grass geometry + const grassGeometry = new THREE.CylinderGeometry(radius, radius, 0.1, 6); + const grassMaterial = new THREE.MeshLambertMaterial({ + color: 0x90EE90, + transparent: true, + opacity: 0.9 + }); + return new THREE.Mesh(grassGeometry, grassMaterial); + } + }; + + // Hexagon geometry helper + const createHexagonGeometry = (radius: number, height: number) => { + const geometry = new THREE.CylinderGeometry(radius, radius, height, 6); + return geometry; + }; + + // Create a single hexagon tile with GLB models + const createHexagonTile = async (x: number, z: number, radius: number = 0.5, biome: 'desert' | 'grass' | 'water' | 'forest' | 'rock' = 'grass') => { + // Biome-based model paths + let modelPath: string | undefined; + + switch (biome) { + case 'desert': + modelPath = 'hex_sand_detail.gltf.glb'; + break; + case 'grass': + modelPath = 'hex_forest.gltf.glb'; + break; + case 'water': + modelPath = 'hex_water_detail.gltf.glb'; + break; + case 'forest': + modelPath = 'hex_forest.gltf.glb'; + break; + case 'rock': + modelPath = 'hex_rock_detail.gltf.glb'; + break; + default: + modelPath = 'hex_forest.gltf.glb'; + } + + return { + position: new THREE.Vector3(x, 0, z), + mesh: null, // We don't need our custom mesh anymore + stroke: null, // We don't need our custom stroke anymore + occupied: false, + biome, + modelPath + }; + }; + + // Create a unit cube with proper level scaling + const createUnitCube = (color: number = 0xff6b6b, level: number = 1) => { + const geometry = new THREE.BoxGeometry(0.3, 0.3, 0.3); + const material = new THREE.MeshLambertMaterial({ color }); + const mesh = new THREE.Mesh(geometry, material); + mesh.position.y = 0.5; // Position above GLB models + + // TFT style scaling: Level 1 = normal, Level 2 = 1.2x, Level 3 = 1.4x, Level 4 = 1.6x + const scaleMultiplier = 1 + (level - 1) * 0.2; + mesh.scale.set(scaleMultiplier, scaleMultiplier, scaleMultiplier); + + return mesh; + }; + + // Create the beautiful 6x6 hexagonal arena with GLB models + const createArena = async () => { + const tiles: HexagonTile[][] = []; + const hexRadius = 0.5; + const hexWidth = hexRadius * 2; + const hexHeight = hexRadius * Math.sqrt(3); + + // Calculate arena center offset to center it on screen + const arenaWidth = 5 * hexWidth * 0.75; // 6 columns + const arenaHeight = 5 * hexHeight; // 6 rows + const centerX = -arenaWidth / 2; + const centerZ = -arenaHeight / 2; + + // Define biome layout based on the image with roads + const biomeLayout = [ + ['desert', 'desert', 'desert', 'grass', 'grass', 'grass'], + ['desert', 'desert', 'grass', 'grass', 'grass', 'grass'], + ['desert', 'grass', 'grass', 'grass', 'grass', 'water'], + ['grass', 'grass', 'grass', 'forest', 'water', 'water'], + ['grass', 'grass', 'forest', 'water', 'water', 'water'], + ['grass', 'forest', 'water', 'water', 'water', 'water'] + ]; + + // Define road layout (connecting different biomes) + const roadLayout = [ + [false, false, false, false, false, false], + [false, false, true, false, false, false], + [false, true, false, true, false, false], + [false, false, true, false, true, false], + [false, false, false, true, false, true], + [false, false, false, false, true, false] + ]; + + for (let row = 0; row < 6; row++) { + tiles[row] = []; + for (let col = 0; col < 6; col++) { + // Calculate position with offset for hexagonal grid, centered + const x = centerX + col * hexWidth * 0.75; + const z = centerZ + row * hexHeight + (col % 2) * (hexHeight / 2); + + // Get biome from layout + const biome = biomeLayout[row][col] as 'desert' | 'grass' | 'water' | 'forest' | 'rock'; + const hasRoad = roadLayout[row][col]; + + const tile = await createHexagonTile(x, z, hexRadius, biome); + tiles[row][col] = tile; + + if (sceneRef.current) { + // Only add GLB model - no custom hexagons + if (tile.modelPath) { + try { + const model = await loadGLBModel(tile.modelPath); + if (model) { + // Center the model with the hexagon position + model.position.copy(tile.position); + model.position.y = 0.0; // At ground level + + // Add color tint based on area (player vs enemy) + const isPlayerArea = row >= 3; // Bottom 3 rows are player area + if (isPlayerArea) { + // Player area - normal colors + model.children.forEach(child => { + if (child instanceof THREE.Mesh && child.material) { + if (Array.isArray(child.material)) { + child.material.forEach(mat => { + if (mat instanceof THREE.MeshLambertMaterial) { + mat.emissive = new THREE.Color(0x00ff00); + mat.emissiveIntensity = 0.1; + } + }); + } else if (child.material instanceof THREE.MeshLambertMaterial) { + child.material.emissive = new THREE.Color(0x00ff00); + child.material.emissiveIntensity = 0.1; + } + } + }); + } else { + // Enemy area - red tint + model.children.forEach(child => { + if (child instanceof THREE.Mesh && child.material) { + if (Array.isArray(child.material)) { + child.material.forEach(mat => { + if (mat instanceof THREE.MeshLambertMaterial) { + mat.emissive = new THREE.Color(0xff0000); + mat.emissiveIntensity = 0.2; + } + }); + } else if (child.material instanceof THREE.MeshLambertMaterial) { + child.material.emissive = new THREE.Color(0xff0000); + child.material.emissiveIntensity = 0.2; + } + } + }); + } + + sceneRef.current.add(model); + } + } catch (error) { + console.log('Using fallback geometry for tile'); + } + } + } + } + } + + tilesRef.current = tiles; + + // Add bases to arena corners (outside the arena) - REMOVED + // if (sceneRef.current) { + // // Player base (bottom right corner) - Castle style + // const playerBaseGeometry = new THREE.CylinderGeometry(1.5, 1.5, 0.4, 8); + // const playerBaseMaterial = new THREE.MeshLambertMaterial({ + // color: 0x4a90e2, + // transparent: true, + // opacity: 0.9 + // }); + // const playerBase = new THREE.Mesh(playerBaseGeometry, playerBaseMaterial); + // playerBase.position.set(centerX + 6 * hexWidth * 0.75, 0.2, centerZ + 6 * hexHeight); + // sceneRef.current.add(playerBase); + // + // // Enemy base (top left corner) - Tower style + // const enemyBaseGeometry = new THREE.CylinderGeometry(1.2, 1.2, 0.6, 8); + // const enemyBaseMaterial = new THREE.MeshLambertMaterial({ + // color: 0x666666, + // transparent: true, + // opacity: 0.9 + // }); + // const enemyBase = new THREE.Mesh(enemyBaseGeometry, enemyBaseMaterial); + // enemyBase.position.set(centerX - hexWidth * 0.75, 0.3, centerZ - hexHeight); + // sceneRef.current.add(enemyBase); + // + // // Add some decorative structures + // addDecorations(centerX, centerZ, hexWidth, hexHeight); + // } + }; + + // Add decorative structures to the arena + const addDecorations = async (centerX: number, centerZ: number, hexWidth: number, hexHeight: number) => { + if (!sceneRef.current) return; + + // Add a castle in the center grass area + const castleGeometry = new THREE.BoxGeometry(1.2, 1.5, 1.2); + const castleMaterial = new THREE.MeshLambertMaterial({ color: 0x8B4513 }); + const castle = new THREE.Mesh(castleGeometry, castleMaterial); + castle.position.set(centerX + 2 * hexWidth * 0.75, 0.75, centerZ + 2 * hexHeight); + sceneRef.current.add(castle); + + // Add castle towers + for (let i = 0; i < 4; i++) { + const towerGeometry = new THREE.CylinderGeometry(0.2, 0.2, 0.8, 8); + const towerMaterial = new THREE.MeshLambertMaterial({ color: 0x8B4513 }); + const tower = new THREE.Mesh(towerGeometry, towerMaterial); + const angle = (i * Math.PI) / 2; + tower.position.set( + centerX + 2 * hexWidth * 0.75 + Math.cos(angle) * 0.8, + 0.4, + centerZ + 2 * hexHeight + Math.sin(angle) * 0.8 + ); + sceneRef.current.add(tower); + } + + // Add a windmill in the water area + const windmillGeometry = new THREE.CylinderGeometry(0.3, 0.3, 1.0, 8); + const windmillMaterial = new THREE.MeshLambertMaterial({ color: 0xDEB887 }); + const windmill = new THREE.Mesh(windmillGeometry, windmillMaterial); + windmill.position.set(centerX + 4 * hexWidth * 0.75, 0.5, centerZ + 4 * hexHeight); + sceneRef.current.add(windmill); + + // Add windmill blades + const bladeGeometry = new THREE.BoxGeometry(0.1, 0.8, 0.05); + const bladeMaterial = new THREE.MeshLambertMaterial({ color: 0x8B4513 }); + for (let i = 0; i < 4; i++) { + const blade = new THREE.Mesh(bladeGeometry, bladeMaterial); + const angle = (i * Math.PI) / 2; + blade.position.set( + centerX + 4 * hexWidth * 0.75 + Math.cos(angle) * 0.4, + 1.0, + centerZ + 4 * hexHeight + Math.sin(angle) * 0.4 + ); + blade.rotation.y = angle; + sceneRef.current.add(blade); + } + + // Add some trees in the forest area using GLB models + for (let i = 0; i < 3; i++) { + try { + const treeModel = await loadGLBModel('hex_forest.gltf.glb'); + if (treeModel) { + treeModel.position.set( + centerX + (3 + i) * hexWidth * 0.75, + 0.4, + centerZ + (4 + i % 2) * hexHeight + ); + treeModel.scale.set(0.3, 0.3, 0.3); + sceneRef.current.add(treeModel); + } else { + // Fallback to geometry + const treeGeometry = new THREE.ConeGeometry(0.3, 0.8, 8); + const treeMaterial = new THREE.MeshLambertMaterial({ color: 0x228B22 }); + const tree = new THREE.Mesh(treeGeometry, treeMaterial); + tree.position.set( + centerX + (3 + i) * hexWidth * 0.75, + 0.4, + centerZ + (4 + i % 2) * hexHeight + ); + sceneRef.current.add(tree); + } + } catch (error) { + console.log('Tree model not loaded, using fallback'); + const treeGeometry = new THREE.ConeGeometry(0.3, 0.8, 8); + const treeMaterial = new THREE.MeshLambertMaterial({ color: 0x228B22 }); + const tree = new THREE.Mesh(treeGeometry, treeMaterial); + tree.position.set( + centerX + (3 + i) * hexWidth * 0.75, + 0.4, + centerZ + (4 + i % 2) * hexHeight + ); + sceneRef.current.add(tree); + } + } + + // Add rocks in the desert area using GLB models + for (let i = 0; i < 2; i++) { + try { + const rockModel = await loadGLBModel('hex_rock_detail.gltf.glb'); + if (rockModel) { + rockModel.position.set( + centerX + i * hexWidth * 0.75, + 0.1, + centerZ + i * hexHeight + ); + rockModel.scale.set(0.2, 0.2, 0.2); + sceneRef.current.add(rockModel); + } else { + // Fallback to geometry + const rockGeometry = new THREE.DodecahedronGeometry(0.2); + const rockMaterial = new THREE.MeshLambertMaterial({ color: 0x696969 }); + const rock = new THREE.Mesh(rockGeometry, rockMaterial); + rock.position.set( + centerX + i * hexWidth * 0.75, + 0.1, + centerZ + i * hexHeight + ); + sceneRef.current.add(rock); + } + } catch (error) { + console.log('Rock model not loaded, using fallback'); + const rockGeometry = new THREE.DodecahedronGeometry(0.2); + const rockMaterial = new THREE.MeshLambertMaterial({ color: 0x696969 }); + const rock = new THREE.Mesh(rockGeometry, rockMaterial); + rock.position.set( + centerX + i * hexWidth * 0.75, + 0.1, + centerZ + i * hexHeight + ); + sceneRef.current.add(rock); + } + } + + // Add a bridge over water + const bridgeGeometry = new THREE.BoxGeometry(1.0, 0.1, 0.3); + const bridgeMaterial = new THREE.MeshLambertMaterial({ color: 0x8B4513 }); + const bridge = new THREE.Mesh(bridgeGeometry, bridgeMaterial); + bridge.position.set(centerX + 3 * hexWidth * 0.75, 0.15, centerZ + 4 * hexHeight); + sceneRef.current.add(bridge); + + // Add some houses in the grass area + for (let i = 0; i < 2; i++) { + const houseGeometry = new THREE.BoxGeometry(0.6, 0.4, 0.6); + const houseMaterial = new THREE.MeshLambertMaterial({ color: 0xDEB887 }); + const house = new THREE.Mesh(houseGeometry, houseMaterial); + house.position.set( + centerX + (1 + i) * hexWidth * 0.75, + 0.2, + centerZ + (3 + i) * hexHeight + ); + sceneRef.current.add(house); + + // Add roof + const roofGeometry = new THREE.ConeGeometry(0.4, 0.3, 4); + const roofMaterial = new THREE.MeshLambertMaterial({ color: 0x8B4513 }); + const roof = new THREE.Mesh(roofGeometry, roofMaterial); + roof.position.set( + centerX + (1 + i) * hexWidth * 0.75, + 0.55, + centerZ + (3 + i) * hexHeight + ); + roof.rotation.y = Math.PI / 4; + sceneRef.current.add(roof); + } + }; + + // Handle unit purchase + const handleUnitPurchase = (unit: Unit) => { + if (gold >= unit.cost) { + setGold(gold - unit.cost); + setSelectedUnit(unit); + console.log('Unit selected:', unit.name); // Debug log + } + }; + + // Handle tile placement with proper merge logic + const handleTilePlacement = (row: number, col: number) => { + if (selectedUnit && tilesRef.current[row] && tilesRef.current[row][col]) { + const tile = tilesRef.current[row][col]; + if (!tile.occupied) { + // Check for merge first + const wasMerged = checkForMerge(selectedUnit); + + if (!wasMerged) { + // Place new unit normally - add to scene directly since we don't have tile.mesh + const unit = createUnitCube(selectedUnit.color, selectedUnit.level); + unit.position.copy(tile.position); + unit.position.y = 0.5; // Position above GLB model + if (sceneRef.current) { + sceneRef.current.add(unit); + } + tile.occupied = true; + tile.unit = unit; + } + + setSelectedUnit(null); + } + } + }; + + // Add some sample units to the arena (only in user area) + const addSampleUnits = () => { + const sampleUnits = [ + { row: 4, col: 2, unit: availableUnits[0] }, // Warrior + { row: 5, col: 3, unit: availableUnits[1] }, // Mage + { row: 4, col: 4, unit: availableUnits[2] }, // Archer + ]; + + sampleUnits.forEach(({ row, col, unit }) => { + if (tilesRef.current[row] && tilesRef.current[row][col]) { + const tile = tilesRef.current[row][col]; + const mesh = createUnitCube(unit.color, unit.level); + mesh.position.copy(tile.position); + mesh.position.y = 0.5; // Position above GLB model + if (sceneRef.current) { + sceneRef.current.add(mesh); + } + tile.occupied = true; + tile.unit = mesh; + } + }); + }; + + // Get tile at screen position + const getTileAtPosition = (x: number, y: number) => { + if (!cameraRef.current) return null; + + const mouse = new THREE.Vector2(); + mouse.x = (x / width) * 2 - 1; + mouse.y = -(y / height) * 2 + 1; + + const raycaster = new THREE.Raycaster(); + raycaster.setFromCamera(mouse, cameraRef.current); + + // Get all GLB models from the scene + const modelMeshes: THREE.Mesh[] = []; + if (sceneRef.current) { + sceneRef.current.children.forEach(child => { + if (child.type === 'Group') { + child.children.forEach(groupChild => { + if (groupChild.type === 'Mesh') { + modelMeshes.push(groupChild as THREE.Mesh); + } + }); + } + }); + } + + const intersects = raycaster.intersectObjects(modelMeshes); + + if (intersects.length > 0) { + const intersectedMesh = intersects[0].object; + + // Find the tile based on the intersected mesh position + for (let row = 0; row < 6; row++) { + for (let col = 0; col < 6; col++) { + const tile = tilesRef.current[row][col]; + // Check if the intersected mesh belongs to this tile's position + if (tile.position.distanceTo(intersectedMesh.position) < 0.5) { + return { row, col, tile }; + } + } + } + } + return null; + }; + + // PanResponder for drag and drop + const panResponder = PanResponder.create({ + onStartShouldSetPanResponder: () => true, + onMoveShouldSetPanResponder: () => true, + onPanResponderGrant: (event) => { + const touch = event.nativeEvent; + console.log('Drag started at:', touch.locationX, touch.locationY); // Debug log + setDragStartPosition({ x: touch.locationX, y: touch.locationY }); + setDragPosition({ x: touch.locationX, y: touch.locationY }); + setIsDragging(true); + + // Check if we're dragging an existing unit + const tileInfo = getTileAtPosition(touch.locationX, touch.locationY); + console.log('Tile info:', tileInfo); // Debug log + + if (tileInfo && tileInfo.tile.occupied && tileInfo.row >= 3) { + console.log('Dragging existing unit'); // Debug log + // Dragging an existing unit from user area + setDraggedTile({ row: tileInfo.row, col: tileInfo.col }); + setSelectedUnit(null); // Clear selected unit since we're moving existing one + + // Create a copy of the unit for dragging + if (tileInfo.tile.unit) { + const unitGeometry = new THREE.BoxGeometry(0.3, 0.3, 0.3); + const unitMaterial = new THREE.MeshLambertMaterial({ + color: tileInfo.tile.unit.material instanceof THREE.MeshLambertMaterial + ? tileInfo.tile.unit.material.color + : 0xff6b6b, + transparent: true, + opacity: 0.8 + }); + const dragMesh = new THREE.Mesh(unitGeometry, unitMaterial); + dragMesh.position.y = 0.5; + dragMesh.scale.copy(tileInfo.tile.unit.scale); // Copy the scale (level) + setDraggedUnitMesh(dragMesh); + + // Add to scene immediately + if (sceneRef.current) { + sceneRef.current.add(dragMesh); + } + + // Hide the original unit temporarily + tileInfo.tile.unit.visible = false; + } + } else if (selectedUnit) { + console.log('Dragging new unit:', selectedUnit.name); // Debug log + // Dragging a new unit from bottom panel + setDraggedTile(null); + + // Create a new unit mesh for dragging + const unitGeometry = new THREE.BoxGeometry(0.3, 0.3, 0.3); + const unitMaterial = new THREE.MeshLambertMaterial({ + color: selectedUnit.color, + transparent: true, + opacity: 0.8 + }); + const dragMesh = new THREE.Mesh(unitGeometry, unitMaterial); + dragMesh.position.y = 0.5; + + // Apply proper level scaling + const scaleMultiplier = 1 + (selectedUnit.level - 1) * 0.2; + dragMesh.scale.set(scaleMultiplier, scaleMultiplier, scaleMultiplier); + + setDraggedUnitMesh(dragMesh); + + // Add to scene immediately + if (sceneRef.current) { + sceneRef.current.add(dragMesh); + } + } + }, + onPanResponderMove: (event) => { + if (!isDragging) return; + + const touch = event.nativeEvent; + setDragPosition({ x: touch.locationX, y: touch.locationY }); + const tileInfo = getTileAtPosition(touch.locationX, touch.locationY); + + // Update dragged unit position to follow touch + if (draggedUnitMesh && cameraRef.current) { + const mouse = new THREE.Vector2(); + mouse.x = (touch.locationX / width) * 2 - 1; + mouse.y = -(touch.locationY / height) * 2 + 1; + + const raycaster = new THREE.Raycaster(); + raycaster.setFromCamera(mouse, cameraRef.current); + + // Get intersection with a plane at y=0 + const plane = new THREE.Plane(new THREE.Vector3(0, 1, 0), 0); + const intersection = new THREE.Vector3(); + raycaster.ray.intersectPlane(plane, intersection); + + draggedUnitMesh.position.set(intersection.x, 0.5, intersection.z); + } + }, + onPanResponderRelease: (event) => { + if (!isDragging) return; + + const touch = event.nativeEvent; + console.log('Drag ended at:', touch.locationX, touch.locationY); // Debug log + const tileInfo = getTileAtPosition(touch.locationX, touch.locationY); + console.log('Final tile info:', tileInfo); // Debug log + + if (draggedTile) { + console.log('Moving existing unit'); // Debug log + // Moving an existing unit + if (tileInfo && !tileInfo.tile.occupied && tileInfo.row >= 3) { + console.log('Moving unit to new position'); // Debug log + // Move unit to new position + const sourceTile = tilesRef.current[draggedTile.row][draggedTile.col]; + const targetTile = tilesRef.current[tileInfo.row][tileInfo.col]; + + if (sourceTile.unit) { + // Show the original unit again + sourceTile.unit.visible = true; + + // Remove unit from scene + if (sceneRef.current) { + sceneRef.current.remove(sourceTile.unit); + } + sourceTile.occupied = false; + + // Add unit to new position + sourceTile.unit.position.copy(targetTile.position); + sourceTile.unit.position.y = 0.5; + if (sceneRef.current) { + sceneRef.current.add(sourceTile.unit); + } + targetTile.occupied = true; + targetTile.unit = sourceTile.unit; + + // Clear source tile unit reference + sourceTile.unit = undefined; + } + } else { + console.log('Reset dragged unit'); // Debug log + // Reset the dragged unit if placement failed + const sourceTile = tilesRef.current[draggedTile.row][draggedTile.col]; + if (sourceTile.unit) { + sourceTile.unit.visible = true; + } + } + setDraggedTile(null); + } else if (selectedUnit) { + console.log('Placing new unit:', selectedUnit.name); // Debug log + // Placing a new unit + if (tileInfo && !tileInfo.tile.occupied && tileInfo.row >= 3) { + console.log('Placing unit at:', tileInfo.row, tileInfo.col); // Debug log + // Place new unit normally - add to scene directly since we don't have tile.mesh + const unit = createUnitCube(selectedUnit.color, selectedUnit.level); + unit.position.copy(tileInfo.tile.position); + unit.position.y = 0.5; // Position above GLB model + if (sceneRef.current) { + sceneRef.current.add(unit); + } + tileInfo.tile.occupied = true; + tileInfo.tile.unit = unit; + setSelectedUnit(null); + } + } + + // Remove dragged unit mesh from scene + if (draggedUnitMesh && sceneRef.current) { + sceneRef.current.remove(draggedUnitMesh); + } + setDraggedUnitMesh(null); + + setIsDragging(false); + }, + onPanResponderTerminate: (event) => { + if (!isDragging) return; + + const touch = event.nativeEvent; + const tileInfo = getTileAtPosition(touch.locationX, touch.locationY); + + if (draggedTile) { + // Moving an existing unit + if (tileInfo && !tileInfo.tile.occupied && tileInfo.row >= 3) { + // Move unit to new position + const sourceTile = tilesRef.current[draggedTile.row][draggedTile.col]; + const targetTile = tilesRef.current[tileInfo.row][tileInfo.col]; + + if (sourceTile.unit) { + // Show the original unit again + sourceTile.unit.visible = true; + + // Remove unit from scene + if (sceneRef.current) { + sceneRef.current.remove(sourceTile.unit); + } + sourceTile.occupied = false; + + // Add unit to new position + sourceTile.unit.position.copy(targetTile.position); + sourceTile.unit.position.y = 0.5; + if (sceneRef.current) { + sceneRef.current.add(sourceTile.unit); + } + targetTile.occupied = true; + targetTile.unit = sourceTile.unit; + + // Clear source tile unit reference + sourceTile.unit = undefined; + } + } else { + // Reset the dragged unit if placement failed + const sourceTile = tilesRef.current[draggedTile.row][draggedTile.col]; + if (sourceTile.unit) { + sourceTile.unit.visible = true; + } + } + setDraggedTile(null); + } else if (selectedUnit) { + // Placing a new unit + if (tileInfo && !tileInfo.tile.occupied && tileInfo.row >= 3) { + // Place new unit normally - add to scene directly since we don't have tile.mesh + const unit = createUnitCube(selectedUnit.color, selectedUnit.level); + unit.position.copy(tileInfo.tile.position); + unit.position.y = 0.5; // Position above GLB model + if (sceneRef.current) { + sceneRef.current.add(unit); + } + tileInfo.tile.occupied = true; + tileInfo.tile.unit = unit; + setSelectedUnit(null); + } + } + + // Remove dragged unit mesh from scene + if (draggedUnitMesh && sceneRef.current) { + sceneRef.current.remove(draggedUnitMesh); + } + setDraggedUnitMesh(null); + + setIsDragging(false); + }, + }); + + // Setup scene + const setupScene = async (gl: any) => { + // Create renderer + const renderer = new Renderer({ gl }); + rendererRef.current = renderer; + + // Create scene with beautiful background + const scene = new THREE.Scene(); + scene.background = new THREE.Color(0x1a1a2e); // Beautiful dark blue for TFT theme + sceneRef.current = scene; + + // Load and set background image + try { + const bgAsset = Asset.fromModule(background1); + await bgAsset.downloadAsync(); + + console.log('Asset URI:', bgAsset.uri); + + // Create a new texture loader with more aggressive settings + const textureLoader = new THREE.TextureLoader(); + + // Try multiple approaches to load the texture + const loadTexture = () => { + textureLoader.load( + bgAsset.uri, + (texture) => { + console.log('Background texture loaded successfully'); + if (sceneRef.current) { + sceneRef.current.background = texture; + } + }, + (progress) => { + console.log('Loading progress:', progress); + }, + (error) => { + console.log('Error loading background texture:', error); + // Try again with a different approach + setTimeout(() => { + console.log('Retrying texture load...'); + textureLoader.load( + bgAsset.uri, + (texture) => { + console.log('Background texture loaded on retry'); + if (sceneRef.current) { + sceneRef.current.background = texture; + } + }, + undefined, + (retryError) => { + console.log('Retry failed:', retryError); + } + ); + }, 1000); + } + ); + }; + + // Start loading + loadTexture(); + + } catch (error) { + console.log('Failed to load background image:', error); + // Keep the default color + } + + // Create fixed camera - positioned to show arena and bases + const camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 1000); + camera.position.set(0, 12, 12); // Closer to arena + camera.lookAt(0, 0, 0); + cameraRef.current = camera; + + // Add lighting + const ambientLight = new THREE.AmbientLight(0xffffff, 0.7); + scene.add(ambientLight); + + const directionalLight = new THREE.DirectionalLight(0xffffff, 0.9); + directionalLight.position.set(5, 15, 10); + scene.add(directionalLight); + + // Create arena with GLB models + await createArena(); + addSampleUnits(); + + // Animation loop - no camera movement + const animate = () => { + animationFrameRef.current = requestAnimationFrame(animate); + renderer.render(scene, camera); + gl.endFrameEXP(); + }; + + animate(); + }; + + // Cleanup on unmount + useEffect(() => { + return () => { + if (animationFrameRef.current) { + cancelAnimationFrame(animationFrameRef.current); + } + }; + }, []); + + // Get units on arena with proper level detection + const getUnitsOnArena = (): Unit[] => { + const units: Unit[] = []; + tilesRef.current.forEach(row => { + row.forEach(tile => { + if (tile.occupied && tile.unit) { + const unitColor = (tile.unit.material as any)?.color?.getHexString(); + const unitData = availableUnits.find(u => u.color.toString(16) === unitColor); + if (unitData) { + // Calculate level based on scale + const scale = tile.unit.scale.x; + const level = Math.round((scale - 1) / 0.2) + 1; + units.push({ ...unitData, level: Math.max(1, Math.min(4, level)) }); + } + } + }); + }); + return units; + }; + + // Check for merging opportunities + const checkForMerge = (newUnit: Unit) => { + const arenaUnits = getUnitsOnArena(); + const sameTypeUnits = arenaUnits.filter(u => u.name === newUnit.name); + + // TFT style: need 3 units of same type to merge + if (sameTypeUnits.length >= 2) { + // Calculate new level based on TFT rules + const totalUnits = sameTypeUnits.length + 1; // +1 for the new unit + const newLevel = Math.min(4, Math.floor(totalUnits / 3) + 1); + + // Create merged unit + const mergedUnit: Unit = { + ...newUnit, + level: newLevel + }; + + // Remove old units from arena + let removedCount = 0; + tilesRef.current.forEach(row => { + row.forEach(tile => { + if (tile.occupied && tile.unit && removedCount < 3) { + const unitColor = (tile.unit.material as any)?.color?.getHexString(); + const unitData = availableUnits.find(u => u.color.toString(16) === unitColor && u.name === newUnit.name); + if (unitData) { + // Remove unit from scene + if (sceneRef.current) { + sceneRef.current.remove(tile.unit); + } + tile.occupied = false; + tile.unit = undefined; + removedCount++; + } + } + }); + }); + + // Add merged unit to first empty tile + for (let row = 3; row < 6; row++) { + for (let col = 0; col < 6; col++) { + const tile = tilesRef.current[row][col]; + if (!tile.occupied) { + const mergedMesh = createUnitCube(mergedUnit.color, mergedUnit.level); + mergedMesh.position.copy(tile.position); // Position the merged unit + mergedMesh.position.y = 0.5; // Position above GLB model + if (sceneRef.current) { + sceneRef.current.add(mergedMesh); + } + tile.occupied = true; + tile.unit = mergedMesh; + return true; // Merged successfully + } + } + } + } + + return false; // No merge + }; + + return ( + + + + + + {/* Gold Display - Top Right */} + + šŸ’° + {gold} + + + {/* Horizontal Card Slider */} + + + {/* Main Cards (4 visible) */} + + {availableUnits.slice(0, 4).map((unit, index) => { + const isSelected = selectedUnit?.id === unit.id; + + return ( + handleUnitPurchase(unit)} + disabled={gold < unit.cost} + > + {/* Card Back Pattern */} + + + + + + + + + + {/* Unit Info Overlay */} + + {unit.name} + + ā˜… {unit.level} + + {unit.cost} + + + ); + })} + + + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: '#1a1a2e', + }, + glView: { + flex: 1, + }, + glContainer: { + flex: 1, + }, + goldDisplay: { + position: 'absolute', + top: 50, + right: 20, + backgroundColor: 'rgba(0, 0, 0, 0.8)', + paddingHorizontal: 15, + paddingVertical: 10, + borderRadius: 25, + flexDirection: 'row', + alignItems: 'center', + shadowColor: '#feca57', + shadowOffset: { + width: 0, + height: 0, + }, + shadowOpacity: 0.5, + shadowRadius: 10, + elevation: 10, + }, + goldIcon: { + fontSize: 20, + marginRight: 8, + }, + goldText: { + color: '#feca57', + fontSize: 18, + fontWeight: 'bold', + }, + cardSlider: { + position: 'absolute', + bottom: 30, + left: 0, + right: 0, + alignItems: 'center', + }, + sliderContainer: { + flexDirection: 'row', + justifyContent: 'space-around', + alignItems: 'center', + width: '100%', + height: 100, + }, + mainCardsContainer: { + flexDirection: 'row', + justifyContent: 'space-around', + alignItems: 'center', + width: '100%', + height: 100, + }, + unitCard: { + padding: 12, + borderRadius: 15, + alignItems: 'center', + minWidth: 70, + height: 100, + shadowColor: '#000', + shadowOffset: { + width: 0, + height: 4, + }, + shadowOpacity: 0.3, + shadowRadius: 8, + elevation: 8, + borderWidth: 2, + borderColor: 'rgba(255, 255, 255, 0.2)', + backgroundColor: 'rgba(0, 0, 0, 0.8)', + position: 'relative', + marginHorizontal: 5, + }, + selectedUnitCard: { + borderWidth: 3, + borderColor: '#ffffff', + shadowColor: '#ffffff', + shadowOffset: { + width: 0, + height: 0, + }, + shadowOpacity: 0.8, + shadowRadius: 15, + elevation: 15, + backgroundColor: 'rgba(255, 255, 255, 0.1)', + }, + unitName: { + color: '#ffffff', + fontSize: 12, + fontWeight: 'bold', + textAlign: 'center', + }, + unitLevel: { + color: '#feca57', + fontSize: 12, + fontWeight: 'bold', + marginTop: 2, + }, + unitCost: { + color: '#feca57', + fontSize: 16, + fontWeight: 'bold', + marginTop: 4, + }, + cardBack: { + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + borderRadius: 20, + backgroundColor: 'rgba(0, 0, 0, 0.5)', + justifyContent: 'center', + alignItems: 'center', + zIndex: 1, + }, + cardPattern: { + width: '100%', + height: '100%', + borderRadius: 20, + backgroundColor: 'rgba(255, 255, 255, 0.1)', + justifyContent: 'center', + alignItems: 'center', + }, + eyePattern: { + width: '80%', + height: '80%', + borderRadius: 40, + backgroundColor: 'rgba(255, 255, 255, 0.2)', + justifyContent: 'center', + alignItems: 'center', + }, + eyeCenter: { + width: '60%', + height: '60%', + borderRadius: 30, + backgroundColor: 'rgba(255, 255, 255, 0.3)', + }, + eyeTriangle: { + position: 'absolute', + top: '50%', + left: '50%', + width: 0, + height: 0, + borderLeftWidth: 10, + borderRightWidth: 10, + borderBottomWidth: 20, + borderStyle: 'solid', + borderLeftColor: 'transparent', + borderRightColor: 'transparent', + borderBottomColor: 'transparent', + transform: [{ rotate: '90deg' }], + }, + cardInfo: { + position: 'absolute', + bottom: 10, + left: 0, + right: 0, + alignItems: 'center', + zIndex: 2, + }, + levelContainer: { + flexDirection: 'row', + alignItems: 'center', + marginTop: 2, + }, +}); diff --git a/assets/arena/hex_forest.gltf.glb b/assets/arena/hex_forest.gltf.glb new file mode 100644 index 0000000..133ba2d Binary files /dev/null and b/assets/arena/hex_forest.gltf.glb differ diff --git a/assets/arena/hex_forest_detail.gltf.glb b/assets/arena/hex_forest_detail.gltf.glb new file mode 100644 index 0000000..c9458f9 Binary files /dev/null and b/assets/arena/hex_forest_detail.gltf.glb differ diff --git a/assets/arena/hex_forest_roadA.gltf.glb b/assets/arena/hex_forest_roadA.gltf.glb new file mode 100644 index 0000000..6cb121c Binary files /dev/null and b/assets/arena/hex_forest_roadA.gltf.glb differ diff --git a/assets/arena/hex_forest_roadA_detail.gltf.glb b/assets/arena/hex_forest_roadA_detail.gltf.glb new file mode 100644 index 0000000..cec68db Binary files /dev/null and b/assets/arena/hex_forest_roadA_detail.gltf.glb differ diff --git a/assets/arena/hex_forest_roadB.gltf.glb b/assets/arena/hex_forest_roadB.gltf.glb new file mode 100644 index 0000000..0762226 Binary files /dev/null and b/assets/arena/hex_forest_roadB.gltf.glb differ diff --git a/assets/arena/hex_forest_roadB_detail.gltf.glb b/assets/arena/hex_forest_roadB_detail.gltf.glb new file mode 100644 index 0000000..9c82dd4 Binary files /dev/null and b/assets/arena/hex_forest_roadB_detail.gltf.glb differ diff --git a/assets/arena/hex_forest_roadC.gltf.glb b/assets/arena/hex_forest_roadC.gltf.glb new file mode 100644 index 0000000..d6ba108 Binary files /dev/null and b/assets/arena/hex_forest_roadC.gltf.glb differ diff --git a/assets/arena/hex_forest_roadC_detail.gltf.glb b/assets/arena/hex_forest_roadC_detail.gltf.glb new file mode 100644 index 0000000..1e5e5ba Binary files /dev/null and b/assets/arena/hex_forest_roadC_detail.gltf.glb differ diff --git a/assets/arena/hex_forest_roadD.gltf.glb b/assets/arena/hex_forest_roadD.gltf.glb new file mode 100644 index 0000000..76a20af Binary files /dev/null and b/assets/arena/hex_forest_roadD.gltf.glb differ diff --git a/assets/arena/hex_forest_roadD_detail.gltf.glb b/assets/arena/hex_forest_roadD_detail.gltf.glb new file mode 100644 index 0000000..efcb545 Binary files /dev/null and b/assets/arena/hex_forest_roadD_detail.gltf.glb differ diff --git a/assets/arena/hex_forest_roadE.gltf.glb b/assets/arena/hex_forest_roadE.gltf.glb new file mode 100644 index 0000000..dda8ef2 Binary files /dev/null and b/assets/arena/hex_forest_roadE.gltf.glb differ diff --git a/assets/arena/hex_forest_roadE_detail.gltf.glb b/assets/arena/hex_forest_roadE_detail.gltf.glb new file mode 100644 index 0000000..7662976 Binary files /dev/null and b/assets/arena/hex_forest_roadE_detail.gltf.glb differ diff --git a/assets/arena/hex_forest_roadF.gltf.glb b/assets/arena/hex_forest_roadF.gltf.glb new file mode 100644 index 0000000..021de5e Binary files /dev/null and b/assets/arena/hex_forest_roadF.gltf.glb differ diff --git a/assets/arena/hex_forest_roadF_detail.gltf.glb b/assets/arena/hex_forest_roadF_detail.gltf.glb new file mode 100644 index 0000000..6805565 Binary files /dev/null and b/assets/arena/hex_forest_roadF_detail.gltf.glb differ diff --git a/assets/arena/hex_forest_roadG.gltf.glb b/assets/arena/hex_forest_roadG.gltf.glb new file mode 100644 index 0000000..f2f59ff Binary files /dev/null and b/assets/arena/hex_forest_roadG.gltf.glb differ diff --git a/assets/arena/hex_forest_roadG_detail.gltf.glb b/assets/arena/hex_forest_roadG_detail.gltf.glb new file mode 100644 index 0000000..565065d Binary files /dev/null and b/assets/arena/hex_forest_roadG_detail.gltf.glb differ diff --git a/assets/arena/hex_forest_roadH.gltf.glb b/assets/arena/hex_forest_roadH.gltf.glb new file mode 100644 index 0000000..362c342 Binary files /dev/null and b/assets/arena/hex_forest_roadH.gltf.glb differ diff --git a/assets/arena/hex_forest_roadH_detail.gltf.glb b/assets/arena/hex_forest_roadH_detail.gltf.glb new file mode 100644 index 0000000..f57a562 Binary files /dev/null and b/assets/arena/hex_forest_roadH_detail.gltf.glb differ diff --git a/assets/arena/hex_forest_roadI.gltf.glb b/assets/arena/hex_forest_roadI.gltf.glb new file mode 100644 index 0000000..b984ed5 Binary files /dev/null and b/assets/arena/hex_forest_roadI.gltf.glb differ diff --git a/assets/arena/hex_forest_roadI_detail.gltf.glb b/assets/arena/hex_forest_roadI_detail.gltf.glb new file mode 100644 index 0000000..963a7a8 Binary files /dev/null and b/assets/arena/hex_forest_roadI_detail.gltf.glb differ diff --git a/assets/arena/hex_forest_roadJ.gltf.glb b/assets/arena/hex_forest_roadJ.gltf.glb new file mode 100644 index 0000000..dfc995f Binary files /dev/null and b/assets/arena/hex_forest_roadJ.gltf.glb differ diff --git a/assets/arena/hex_forest_roadJ_detail.gltf.glb b/assets/arena/hex_forest_roadJ_detail.gltf.glb new file mode 100644 index 0000000..a729811 Binary files /dev/null and b/assets/arena/hex_forest_roadJ_detail.gltf.glb differ diff --git a/assets/arena/hex_forest_roadK.gltf.glb b/assets/arena/hex_forest_roadK.gltf.glb new file mode 100644 index 0000000..9066744 Binary files /dev/null and b/assets/arena/hex_forest_roadK.gltf.glb differ diff --git a/assets/arena/hex_forest_roadK_detail.gltf.glb b/assets/arena/hex_forest_roadK_detail.gltf.glb new file mode 100644 index 0000000..8890565 Binary files /dev/null and b/assets/arena/hex_forest_roadK_detail.gltf.glb differ diff --git a/assets/arena/hex_forest_roadL.gltf.glb b/assets/arena/hex_forest_roadL.gltf.glb new file mode 100644 index 0000000..0ea9f95 Binary files /dev/null and b/assets/arena/hex_forest_roadL.gltf.glb differ diff --git a/assets/arena/hex_forest_roadL_detail.gltf.glb b/assets/arena/hex_forest_roadL_detail.gltf.glb new file mode 100644 index 0000000..8cef810 Binary files /dev/null and b/assets/arena/hex_forest_roadL_detail.gltf.glb differ diff --git a/assets/arena/hex_forest_roadM.gltf.glb b/assets/arena/hex_forest_roadM.gltf.glb new file mode 100644 index 0000000..1d11fe4 Binary files /dev/null and b/assets/arena/hex_forest_roadM.gltf.glb differ diff --git a/assets/arena/hex_forest_roadM_detail.gltf.glb b/assets/arena/hex_forest_roadM_detail.gltf.glb new file mode 100644 index 0000000..7f2cc04 Binary files /dev/null and b/assets/arena/hex_forest_roadM_detail.gltf.glb differ diff --git a/assets/arena/hex_forest_transitionA.gltf.glb b/assets/arena/hex_forest_transitionA.gltf.glb new file mode 100644 index 0000000..01891ad Binary files /dev/null and b/assets/arena/hex_forest_transitionA.gltf.glb differ diff --git a/assets/arena/hex_forest_transitionB.gltf.glb b/assets/arena/hex_forest_transitionB.gltf.glb new file mode 100644 index 0000000..cd474b7 Binary files /dev/null and b/assets/arena/hex_forest_transitionB.gltf.glb differ diff --git a/assets/arena/hex_forest_waterA.gltf.glb b/assets/arena/hex_forest_waterA.gltf.glb new file mode 100644 index 0000000..6512d4b Binary files /dev/null and b/assets/arena/hex_forest_waterA.gltf.glb differ diff --git a/assets/arena/hex_forest_waterA_detail.gltf.glb b/assets/arena/hex_forest_waterA_detail.gltf.glb new file mode 100644 index 0000000..500b22b Binary files /dev/null and b/assets/arena/hex_forest_waterA_detail.gltf.glb differ diff --git a/assets/arena/hex_forest_waterA_empty.gltf.glb b/assets/arena/hex_forest_waterA_empty.gltf.glb new file mode 100644 index 0000000..40614d9 Binary files /dev/null and b/assets/arena/hex_forest_waterA_empty.gltf.glb differ diff --git a/assets/arena/hex_forest_waterB.gltf.glb b/assets/arena/hex_forest_waterB.gltf.glb new file mode 100644 index 0000000..d7a9800 Binary files /dev/null and b/assets/arena/hex_forest_waterB.gltf.glb differ diff --git a/assets/arena/hex_forest_waterB_detail.gltf.glb b/assets/arena/hex_forest_waterB_detail.gltf.glb new file mode 100644 index 0000000..2436c01 Binary files /dev/null and b/assets/arena/hex_forest_waterB_detail.gltf.glb differ diff --git a/assets/arena/hex_forest_waterB_empty.gltf.glb b/assets/arena/hex_forest_waterB_empty.gltf.glb new file mode 100644 index 0000000..196c06d Binary files /dev/null and b/assets/arena/hex_forest_waterB_empty.gltf.glb differ diff --git a/assets/arena/hex_forest_waterC.gltf.glb b/assets/arena/hex_forest_waterC.gltf.glb new file mode 100644 index 0000000..7277baf Binary files /dev/null and b/assets/arena/hex_forest_waterC.gltf.glb differ diff --git a/assets/arena/hex_forest_waterC_detail.gltf.glb b/assets/arena/hex_forest_waterC_detail.gltf.glb new file mode 100644 index 0000000..7e854fa Binary files /dev/null and b/assets/arena/hex_forest_waterC_detail.gltf.glb differ diff --git a/assets/arena/hex_forest_waterC_empty.gltf.glb b/assets/arena/hex_forest_waterC_empty.gltf.glb new file mode 100644 index 0000000..eb17e6a Binary files /dev/null and b/assets/arena/hex_forest_waterC_empty.gltf.glb differ diff --git a/assets/arena/hex_forest_waterD.gltf.glb b/assets/arena/hex_forest_waterD.gltf.glb new file mode 100644 index 0000000..ab60f8e Binary files /dev/null and b/assets/arena/hex_forest_waterD.gltf.glb differ diff --git a/assets/arena/hex_forest_waterD_detail.gltf.glb b/assets/arena/hex_forest_waterD_detail.gltf.glb new file mode 100644 index 0000000..ad3c3bb Binary files /dev/null and b/assets/arena/hex_forest_waterD_detail.gltf.glb differ diff --git a/assets/arena/hex_forest_waterD_empty.gltf.glb b/assets/arena/hex_forest_waterD_empty.gltf.glb new file mode 100644 index 0000000..d299200 Binary files /dev/null and b/assets/arena/hex_forest_waterD_empty.gltf.glb differ diff --git a/assets/arena/hex_rock.gltf.glb b/assets/arena/hex_rock.gltf.glb new file mode 100644 index 0000000..4c6af9e Binary files /dev/null and b/assets/arena/hex_rock.gltf.glb differ diff --git a/assets/arena/hex_rock_detail.gltf.glb b/assets/arena/hex_rock_detail.gltf.glb new file mode 100644 index 0000000..1e13ce7 Binary files /dev/null and b/assets/arena/hex_rock_detail.gltf.glb differ diff --git a/assets/arena/hex_rock_roadA.gltf.glb b/assets/arena/hex_rock_roadA.gltf.glb new file mode 100644 index 0000000..8ded8f0 Binary files /dev/null and b/assets/arena/hex_rock_roadA.gltf.glb differ diff --git a/assets/arena/hex_rock_roadA_detail.gltf.glb b/assets/arena/hex_rock_roadA_detail.gltf.glb new file mode 100644 index 0000000..cb535e0 Binary files /dev/null and b/assets/arena/hex_rock_roadA_detail.gltf.glb differ diff --git a/assets/arena/hex_rock_roadB.gltf.glb b/assets/arena/hex_rock_roadB.gltf.glb new file mode 100644 index 0000000..3446702 Binary files /dev/null and b/assets/arena/hex_rock_roadB.gltf.glb differ diff --git a/assets/arena/hex_rock_roadB_detail.gltf.glb b/assets/arena/hex_rock_roadB_detail.gltf.glb new file mode 100644 index 0000000..0f500ad Binary files /dev/null and b/assets/arena/hex_rock_roadB_detail.gltf.glb differ diff --git a/assets/arena/hex_rock_roadC.gltf.glb b/assets/arena/hex_rock_roadC.gltf.glb new file mode 100644 index 0000000..9017133 Binary files /dev/null and b/assets/arena/hex_rock_roadC.gltf.glb differ diff --git a/assets/arena/hex_rock_roadC_detail.gltf.glb b/assets/arena/hex_rock_roadC_detail.gltf.glb new file mode 100644 index 0000000..e29da55 Binary files /dev/null and b/assets/arena/hex_rock_roadC_detail.gltf.glb differ diff --git a/assets/arena/hex_rock_roadD.gltf.glb b/assets/arena/hex_rock_roadD.gltf.glb new file mode 100644 index 0000000..e80531d Binary files /dev/null and b/assets/arena/hex_rock_roadD.gltf.glb differ diff --git a/assets/arena/hex_rock_roadD_detail.gltf.glb b/assets/arena/hex_rock_roadD_detail.gltf.glb new file mode 100644 index 0000000..a54117d Binary files /dev/null and b/assets/arena/hex_rock_roadD_detail.gltf.glb differ diff --git a/assets/arena/hex_rock_roadE.gltf.glb b/assets/arena/hex_rock_roadE.gltf.glb new file mode 100644 index 0000000..e5e9c6b Binary files /dev/null and b/assets/arena/hex_rock_roadE.gltf.glb differ diff --git a/assets/arena/hex_rock_roadE_detail.gltf.glb b/assets/arena/hex_rock_roadE_detail.gltf.glb new file mode 100644 index 0000000..e9741a0 Binary files /dev/null and b/assets/arena/hex_rock_roadE_detail.gltf.glb differ diff --git a/assets/arena/hex_rock_roadF.gltf.glb b/assets/arena/hex_rock_roadF.gltf.glb new file mode 100644 index 0000000..e46ac18 Binary files /dev/null and b/assets/arena/hex_rock_roadF.gltf.glb differ diff --git a/assets/arena/hex_rock_roadF_detail.gltf.glb b/assets/arena/hex_rock_roadF_detail.gltf.glb new file mode 100644 index 0000000..8522ff0 Binary files /dev/null and b/assets/arena/hex_rock_roadF_detail.gltf.glb differ diff --git a/assets/arena/hex_rock_roadG.gltf.glb b/assets/arena/hex_rock_roadG.gltf.glb new file mode 100644 index 0000000..0b754e4 Binary files /dev/null and b/assets/arena/hex_rock_roadG.gltf.glb differ diff --git a/assets/arena/hex_rock_roadG_detail.gltf.glb b/assets/arena/hex_rock_roadG_detail.gltf.glb new file mode 100644 index 0000000..1e5048a Binary files /dev/null and b/assets/arena/hex_rock_roadG_detail.gltf.glb differ diff --git a/assets/arena/hex_rock_roadH.gltf.glb b/assets/arena/hex_rock_roadH.gltf.glb new file mode 100644 index 0000000..24a489c Binary files /dev/null and b/assets/arena/hex_rock_roadH.gltf.glb differ diff --git a/assets/arena/hex_rock_roadH_detail.gltf.glb b/assets/arena/hex_rock_roadH_detail.gltf.glb new file mode 100644 index 0000000..43007b3 Binary files /dev/null and b/assets/arena/hex_rock_roadH_detail.gltf.glb differ diff --git a/assets/arena/hex_rock_roadI.gltf.glb b/assets/arena/hex_rock_roadI.gltf.glb new file mode 100644 index 0000000..60cae61 Binary files /dev/null and b/assets/arena/hex_rock_roadI.gltf.glb differ diff --git a/assets/arena/hex_rock_roadI_detail.gltf.glb b/assets/arena/hex_rock_roadI_detail.gltf.glb new file mode 100644 index 0000000..a86b791 Binary files /dev/null and b/assets/arena/hex_rock_roadI_detail.gltf.glb differ diff --git a/assets/arena/hex_rock_roadJ.gltf.glb b/assets/arena/hex_rock_roadJ.gltf.glb new file mode 100644 index 0000000..dc85527 Binary files /dev/null and b/assets/arena/hex_rock_roadJ.gltf.glb differ diff --git a/assets/arena/hex_rock_roadJ_detail.gltf.glb b/assets/arena/hex_rock_roadJ_detail.gltf.glb new file mode 100644 index 0000000..17abbbc Binary files /dev/null and b/assets/arena/hex_rock_roadJ_detail.gltf.glb differ diff --git a/assets/arena/hex_rock_roadK.gltf.glb b/assets/arena/hex_rock_roadK.gltf.glb new file mode 100644 index 0000000..a07bd62 Binary files /dev/null and b/assets/arena/hex_rock_roadK.gltf.glb differ diff --git a/assets/arena/hex_rock_roadK_detail.gltf.glb b/assets/arena/hex_rock_roadK_detail.gltf.glb new file mode 100644 index 0000000..e25dae9 Binary files /dev/null and b/assets/arena/hex_rock_roadK_detail.gltf.glb differ diff --git a/assets/arena/hex_rock_roadL.gltf.glb b/assets/arena/hex_rock_roadL.gltf.glb new file mode 100644 index 0000000..2469f38 Binary files /dev/null and b/assets/arena/hex_rock_roadL.gltf.glb differ diff --git a/assets/arena/hex_rock_roadL_detail.gltf.glb b/assets/arena/hex_rock_roadL_detail.gltf.glb new file mode 100644 index 0000000..e7343f0 Binary files /dev/null and b/assets/arena/hex_rock_roadL_detail.gltf.glb differ diff --git a/assets/arena/hex_rock_roadM.gltf.glb b/assets/arena/hex_rock_roadM.gltf.glb new file mode 100644 index 0000000..a51c637 Binary files /dev/null and b/assets/arena/hex_rock_roadM.gltf.glb differ diff --git a/assets/arena/hex_rock_roadM_detail.gltf.glb b/assets/arena/hex_rock_roadM_detail.gltf.glb new file mode 100644 index 0000000..66ce90a Binary files /dev/null and b/assets/arena/hex_rock_roadM_detail.gltf.glb differ diff --git a/assets/arena/hex_rock_transitionA.gltf.glb b/assets/arena/hex_rock_transitionA.gltf.glb new file mode 100644 index 0000000..6b0cd0a Binary files /dev/null and b/assets/arena/hex_rock_transitionA.gltf.glb differ diff --git a/assets/arena/hex_rock_transitionB.gltf.glb b/assets/arena/hex_rock_transitionB.gltf.glb new file mode 100644 index 0000000..ab8972a Binary files /dev/null and b/assets/arena/hex_rock_transitionB.gltf.glb differ diff --git a/assets/arena/hex_rock_waterA.gltf.glb b/assets/arena/hex_rock_waterA.gltf.glb new file mode 100644 index 0000000..762dd15 Binary files /dev/null and b/assets/arena/hex_rock_waterA.gltf.glb differ diff --git a/assets/arena/hex_rock_waterA_detail.gltf.glb b/assets/arena/hex_rock_waterA_detail.gltf.glb new file mode 100644 index 0000000..b5f57e7 Binary files /dev/null and b/assets/arena/hex_rock_waterA_detail.gltf.glb differ diff --git a/assets/arena/hex_rock_waterA_empty.gltf.glb b/assets/arena/hex_rock_waterA_empty.gltf.glb new file mode 100644 index 0000000..49e478c Binary files /dev/null and b/assets/arena/hex_rock_waterA_empty.gltf.glb differ diff --git a/assets/arena/hex_rock_waterB.gltf.glb b/assets/arena/hex_rock_waterB.gltf.glb new file mode 100644 index 0000000..7d36af3 Binary files /dev/null and b/assets/arena/hex_rock_waterB.gltf.glb differ diff --git a/assets/arena/hex_rock_waterB_detail.gltf.glb b/assets/arena/hex_rock_waterB_detail.gltf.glb new file mode 100644 index 0000000..b66877c Binary files /dev/null and b/assets/arena/hex_rock_waterB_detail.gltf.glb differ diff --git a/assets/arena/hex_rock_waterB_empty.gltf.glb b/assets/arena/hex_rock_waterB_empty.gltf.glb new file mode 100644 index 0000000..30a0fc0 Binary files /dev/null and b/assets/arena/hex_rock_waterB_empty.gltf.glb differ diff --git a/assets/arena/hex_rock_waterC.gltf.glb b/assets/arena/hex_rock_waterC.gltf.glb new file mode 100644 index 0000000..5d04991 Binary files /dev/null and b/assets/arena/hex_rock_waterC.gltf.glb differ diff --git a/assets/arena/hex_rock_waterC_detail.gltf.glb b/assets/arena/hex_rock_waterC_detail.gltf.glb new file mode 100644 index 0000000..cb9791a Binary files /dev/null and b/assets/arena/hex_rock_waterC_detail.gltf.glb differ diff --git a/assets/arena/hex_rock_waterC_empty.gltf.glb b/assets/arena/hex_rock_waterC_empty.gltf.glb new file mode 100644 index 0000000..2c9a1bd Binary files /dev/null and b/assets/arena/hex_rock_waterC_empty.gltf.glb differ diff --git a/assets/arena/hex_rock_waterD.gltf.glb b/assets/arena/hex_rock_waterD.gltf.glb new file mode 100644 index 0000000..f43656f Binary files /dev/null and b/assets/arena/hex_rock_waterD.gltf.glb differ diff --git a/assets/arena/hex_rock_waterD_detail.gltf.glb b/assets/arena/hex_rock_waterD_detail.gltf.glb new file mode 100644 index 0000000..9684a26 Binary files /dev/null and b/assets/arena/hex_rock_waterD_detail.gltf.glb differ diff --git a/assets/arena/hex_rock_waterD_empty.gltf.glb b/assets/arena/hex_rock_waterD_empty.gltf.glb new file mode 100644 index 0000000..395f5e4 Binary files /dev/null and b/assets/arena/hex_rock_waterD_empty.gltf.glb differ diff --git a/assets/arena/hex_sand.gltf.glb b/assets/arena/hex_sand.gltf.glb new file mode 100644 index 0000000..a07f142 Binary files /dev/null and b/assets/arena/hex_sand.gltf.glb differ diff --git a/assets/arena/hex_sand_detail.gltf.glb b/assets/arena/hex_sand_detail.gltf.glb new file mode 100644 index 0000000..5a6ece0 Binary files /dev/null and b/assets/arena/hex_sand_detail.gltf.glb differ diff --git a/assets/arena/hex_sand_roadA.gltf.glb b/assets/arena/hex_sand_roadA.gltf.glb new file mode 100644 index 0000000..afd2c77 Binary files /dev/null and b/assets/arena/hex_sand_roadA.gltf.glb differ diff --git a/assets/arena/hex_sand_roadA_detail.gltf.glb b/assets/arena/hex_sand_roadA_detail.gltf.glb new file mode 100644 index 0000000..4da2335 Binary files /dev/null and b/assets/arena/hex_sand_roadA_detail.gltf.glb differ diff --git a/assets/arena/hex_sand_roadB.gltf.glb b/assets/arena/hex_sand_roadB.gltf.glb new file mode 100644 index 0000000..3ecbd54 Binary files /dev/null and b/assets/arena/hex_sand_roadB.gltf.glb differ diff --git a/assets/arena/hex_sand_roadB_detail.gltf.glb b/assets/arena/hex_sand_roadB_detail.gltf.glb new file mode 100644 index 0000000..ced06df Binary files /dev/null and b/assets/arena/hex_sand_roadB_detail.gltf.glb differ diff --git a/assets/arena/hex_sand_roadC.gltf.glb b/assets/arena/hex_sand_roadC.gltf.glb new file mode 100644 index 0000000..400366e Binary files /dev/null and b/assets/arena/hex_sand_roadC.gltf.glb differ diff --git a/assets/arena/hex_sand_roadC_detail.gltf.glb b/assets/arena/hex_sand_roadC_detail.gltf.glb new file mode 100644 index 0000000..2bddc33 Binary files /dev/null and b/assets/arena/hex_sand_roadC_detail.gltf.glb differ diff --git a/assets/arena/hex_sand_roadD.gltf.glb b/assets/arena/hex_sand_roadD.gltf.glb new file mode 100644 index 0000000..34e0e93 Binary files /dev/null and b/assets/arena/hex_sand_roadD.gltf.glb differ diff --git a/assets/arena/hex_sand_roadD_detail.gltf.glb b/assets/arena/hex_sand_roadD_detail.gltf.glb new file mode 100644 index 0000000..42eea3a Binary files /dev/null and b/assets/arena/hex_sand_roadD_detail.gltf.glb differ diff --git a/assets/arena/hex_sand_roadE.gltf.glb b/assets/arena/hex_sand_roadE.gltf.glb new file mode 100644 index 0000000..8c0a832 Binary files /dev/null and b/assets/arena/hex_sand_roadE.gltf.glb differ diff --git a/assets/arena/hex_sand_roadE_detail.gltf.glb b/assets/arena/hex_sand_roadE_detail.gltf.glb new file mode 100644 index 0000000..3e64461 Binary files /dev/null and b/assets/arena/hex_sand_roadE_detail.gltf.glb differ diff --git a/assets/arena/hex_sand_roadF.gltf.glb b/assets/arena/hex_sand_roadF.gltf.glb new file mode 100644 index 0000000..86b288a Binary files /dev/null and b/assets/arena/hex_sand_roadF.gltf.glb differ diff --git a/assets/arena/hex_sand_roadF_detail.gltf.glb b/assets/arena/hex_sand_roadF_detail.gltf.glb new file mode 100644 index 0000000..2200410 Binary files /dev/null and b/assets/arena/hex_sand_roadF_detail.gltf.glb differ diff --git a/assets/arena/hex_sand_roadG.gltf.glb b/assets/arena/hex_sand_roadG.gltf.glb new file mode 100644 index 0000000..7be5c7c Binary files /dev/null and b/assets/arena/hex_sand_roadG.gltf.glb differ diff --git a/assets/arena/hex_sand_roadG_detail.gltf.glb b/assets/arena/hex_sand_roadG_detail.gltf.glb new file mode 100644 index 0000000..210cff0 Binary files /dev/null and b/assets/arena/hex_sand_roadG_detail.gltf.glb differ diff --git a/assets/arena/hex_sand_roadH.gltf.glb b/assets/arena/hex_sand_roadH.gltf.glb new file mode 100644 index 0000000..988391f Binary files /dev/null and b/assets/arena/hex_sand_roadH.gltf.glb differ diff --git a/assets/arena/hex_sand_roadH_detail.gltf.glb b/assets/arena/hex_sand_roadH_detail.gltf.glb new file mode 100644 index 0000000..9035841 Binary files /dev/null and b/assets/arena/hex_sand_roadH_detail.gltf.glb differ diff --git a/assets/arena/hex_sand_roadI.gltf.glb b/assets/arena/hex_sand_roadI.gltf.glb new file mode 100644 index 0000000..015d4b2 Binary files /dev/null and b/assets/arena/hex_sand_roadI.gltf.glb differ diff --git a/assets/arena/hex_sand_roadI_detail.gltf.glb b/assets/arena/hex_sand_roadI_detail.gltf.glb new file mode 100644 index 0000000..38d68ab Binary files /dev/null and b/assets/arena/hex_sand_roadI_detail.gltf.glb differ diff --git a/assets/arena/hex_sand_roadJ.gltf.glb b/assets/arena/hex_sand_roadJ.gltf.glb new file mode 100644 index 0000000..7efd274 Binary files /dev/null and b/assets/arena/hex_sand_roadJ.gltf.glb differ diff --git a/assets/arena/hex_sand_roadJ_detail.gltf.glb b/assets/arena/hex_sand_roadJ_detail.gltf.glb new file mode 100644 index 0000000..03b88fd Binary files /dev/null and b/assets/arena/hex_sand_roadJ_detail.gltf.glb differ diff --git a/assets/arena/hex_sand_roadK.gltf.glb b/assets/arena/hex_sand_roadK.gltf.glb new file mode 100644 index 0000000..39f8c22 Binary files /dev/null and b/assets/arena/hex_sand_roadK.gltf.glb differ diff --git a/assets/arena/hex_sand_roadK_detail.gltf.glb b/assets/arena/hex_sand_roadK_detail.gltf.glb new file mode 100644 index 0000000..834861a Binary files /dev/null and b/assets/arena/hex_sand_roadK_detail.gltf.glb differ diff --git a/assets/arena/hex_sand_roadL.gltf.glb b/assets/arena/hex_sand_roadL.gltf.glb new file mode 100644 index 0000000..832b7ec Binary files /dev/null and b/assets/arena/hex_sand_roadL.gltf.glb differ diff --git a/assets/arena/hex_sand_roadL_detail.gltf.glb b/assets/arena/hex_sand_roadL_detail.gltf.glb new file mode 100644 index 0000000..0ca1090 Binary files /dev/null and b/assets/arena/hex_sand_roadL_detail.gltf.glb differ diff --git a/assets/arena/hex_sand_roadM.gltf.glb b/assets/arena/hex_sand_roadM.gltf.glb new file mode 100644 index 0000000..6cfb232 Binary files /dev/null and b/assets/arena/hex_sand_roadM.gltf.glb differ diff --git a/assets/arena/hex_sand_roadM_detail.gltf.glb b/assets/arena/hex_sand_roadM_detail.gltf.glb new file mode 100644 index 0000000..9b7e627 Binary files /dev/null and b/assets/arena/hex_sand_roadM_detail.gltf.glb differ diff --git a/assets/arena/hex_sand_transitionA.gltf.glb b/assets/arena/hex_sand_transitionA.gltf.glb new file mode 100644 index 0000000..b060fc5 Binary files /dev/null and b/assets/arena/hex_sand_transitionA.gltf.glb differ diff --git a/assets/arena/hex_sand_transitionB.gltf.glb b/assets/arena/hex_sand_transitionB.gltf.glb new file mode 100644 index 0000000..c3b9227 Binary files /dev/null and b/assets/arena/hex_sand_transitionB.gltf.glb differ diff --git a/assets/arena/hex_sand_waterA.gltf.glb b/assets/arena/hex_sand_waterA.gltf.glb new file mode 100644 index 0000000..2466552 Binary files /dev/null and b/assets/arena/hex_sand_waterA.gltf.glb differ diff --git a/assets/arena/hex_sand_waterA_detail.gltf.glb b/assets/arena/hex_sand_waterA_detail.gltf.glb new file mode 100644 index 0000000..620dcdb Binary files /dev/null and b/assets/arena/hex_sand_waterA_detail.gltf.glb differ diff --git a/assets/arena/hex_sand_waterA_empty.gltf.glb b/assets/arena/hex_sand_waterA_empty.gltf.glb new file mode 100644 index 0000000..0421f0d Binary files /dev/null and b/assets/arena/hex_sand_waterA_empty.gltf.glb differ diff --git a/assets/arena/hex_sand_waterB.gltf.glb b/assets/arena/hex_sand_waterB.gltf.glb new file mode 100644 index 0000000..fe72b05 Binary files /dev/null and b/assets/arena/hex_sand_waterB.gltf.glb differ diff --git a/assets/arena/hex_sand_waterB_detail.gltf.glb b/assets/arena/hex_sand_waterB_detail.gltf.glb new file mode 100644 index 0000000..da4855a Binary files /dev/null and b/assets/arena/hex_sand_waterB_detail.gltf.glb differ diff --git a/assets/arena/hex_sand_waterB_empty.gltf.glb b/assets/arena/hex_sand_waterB_empty.gltf.glb new file mode 100644 index 0000000..e0b5ce2 Binary files /dev/null and b/assets/arena/hex_sand_waterB_empty.gltf.glb differ diff --git a/assets/arena/hex_sand_waterC.gltf.glb b/assets/arena/hex_sand_waterC.gltf.glb new file mode 100644 index 0000000..d639c95 Binary files /dev/null and b/assets/arena/hex_sand_waterC.gltf.glb differ diff --git a/assets/arena/hex_sand_waterC_detail.gltf.glb b/assets/arena/hex_sand_waterC_detail.gltf.glb new file mode 100644 index 0000000..c5243cb Binary files /dev/null and b/assets/arena/hex_sand_waterC_detail.gltf.glb differ diff --git a/assets/arena/hex_sand_waterC_empty.gltf.glb b/assets/arena/hex_sand_waterC_empty.gltf.glb new file mode 100644 index 0000000..19ccefb Binary files /dev/null and b/assets/arena/hex_sand_waterC_empty.gltf.glb differ diff --git a/assets/arena/hex_sand_waterD.gltf.glb b/assets/arena/hex_sand_waterD.gltf.glb new file mode 100644 index 0000000..7097113 Binary files /dev/null and b/assets/arena/hex_sand_waterD.gltf.glb differ diff --git a/assets/arena/hex_sand_waterD_detail.gltf.glb b/assets/arena/hex_sand_waterD_detail.gltf.glb new file mode 100644 index 0000000..9e44717 Binary files /dev/null and b/assets/arena/hex_sand_waterD_detail.gltf.glb differ diff --git a/assets/arena/hex_sand_waterD_empty.gltf.glb b/assets/arena/hex_sand_waterD_empty.gltf.glb new file mode 100644 index 0000000..33f06b1 Binary files /dev/null and b/assets/arena/hex_sand_waterD_empty.gltf.glb differ diff --git a/assets/arena/hex_water.gltf.glb b/assets/arena/hex_water.gltf.glb new file mode 100644 index 0000000..36acea2 Binary files /dev/null and b/assets/arena/hex_water.gltf.glb differ diff --git a/assets/arena/hex_water_detail.gltf.glb b/assets/arena/hex_water_detail.gltf.glb new file mode 100644 index 0000000..be30de9 Binary files /dev/null and b/assets/arena/hex_water_detail.gltf.glb differ diff --git a/assets/images/background-1.jpg b/assets/images/background-1.jpg new file mode 100644 index 0000000..a0b1526 Binary files /dev/null and b/assets/images/background-1.jpg differ diff --git a/components/Collapsible.tsx b/components/Collapsible.tsx deleted file mode 100644 index 55bff2f..0000000 --- a/components/Collapsible.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { PropsWithChildren, useState } from 'react'; -import { StyleSheet, TouchableOpacity } from 'react-native'; - -import { ThemedText } from '@/components/ThemedText'; -import { ThemedView } from '@/components/ThemedView'; -import { IconSymbol } from '@/components/ui/IconSymbol'; -import { Colors } from '@/constants/Colors'; -import { useColorScheme } from '@/hooks/useColorScheme'; - -export function Collapsible({ children, title }: PropsWithChildren & { title: string }) { - const [isOpen, setIsOpen] = useState(false); - const theme = useColorScheme() ?? 'light'; - - return ( - - setIsOpen((value) => !value)} - activeOpacity={0.8}> - - - {title} - - {isOpen && {children}} - - ); -} - -const styles = StyleSheet.create({ - heading: { - flexDirection: 'row', - alignItems: 'center', - gap: 6, - }, - content: { - marginTop: 6, - marginLeft: 24, - }, -}); diff --git a/components/ExternalLink.tsx b/components/ExternalLink.tsx deleted file mode 100644 index dfbd23e..0000000 --- a/components/ExternalLink.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { Href, Link } from 'expo-router'; -import { openBrowserAsync } from 'expo-web-browser'; -import { type ComponentProps } from 'react'; -import { Platform } from 'react-native'; - -type Props = Omit, 'href'> & { href: Href & string }; - -export function ExternalLink({ href, ...rest }: Props) { - return ( - { - if (Platform.OS !== 'web') { - // Prevent the default behavior of linking to the default browser on native. - event.preventDefault(); - // Open the link in an in-app browser. - await openBrowserAsync(href); - } - }} - /> - ); -} diff --git a/components/HapticTab.tsx b/components/HapticTab.tsx deleted file mode 100644 index 7f3981c..0000000 --- a/components/HapticTab.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { BottomTabBarButtonProps } from '@react-navigation/bottom-tabs'; -import { PlatformPressable } from '@react-navigation/elements'; -import * as Haptics from 'expo-haptics'; - -export function HapticTab(props: BottomTabBarButtonProps) { - return ( - { - if (process.env.EXPO_OS === 'ios') { - // Add a soft haptic feedback when pressing down on the tabs. - Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); - } - props.onPressIn?.(ev); - }} - /> - ); -} diff --git a/components/HelloWave.tsx b/components/HelloWave.tsx deleted file mode 100644 index eb6ea61..0000000 --- a/components/HelloWave.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { useEffect } from 'react'; -import { StyleSheet } from 'react-native'; -import Animated, { - useAnimatedStyle, - useSharedValue, - withRepeat, - withSequence, - withTiming, -} from 'react-native-reanimated'; - -import { ThemedText } from '@/components/ThemedText'; - -export function HelloWave() { - const rotationAnimation = useSharedValue(0); - - useEffect(() => { - rotationAnimation.value = withRepeat( - withSequence(withTiming(25, { duration: 150 }), withTiming(0, { duration: 150 })), - 4 // Run the animation 4 times - ); - }, [rotationAnimation]); - - const animatedStyle = useAnimatedStyle(() => ({ - transform: [{ rotate: `${rotationAnimation.value}deg` }], - })); - - return ( - - šŸ‘‹ - - ); -} - -const styles = StyleSheet.create({ - text: { - fontSize: 28, - lineHeight: 32, - marginTop: -6, - }, -}); diff --git a/components/ParallaxScrollView.tsx b/components/ParallaxScrollView.tsx deleted file mode 100644 index 5df1d75..0000000 --- a/components/ParallaxScrollView.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import type { PropsWithChildren, ReactElement } from 'react'; -import { StyleSheet } from 'react-native'; -import Animated, { - interpolate, - useAnimatedRef, - useAnimatedStyle, - useScrollViewOffset, -} from 'react-native-reanimated'; - -import { ThemedView } from '@/components/ThemedView'; -import { useBottomTabOverflow } from '@/components/ui/TabBarBackground'; -import { useColorScheme } from '@/hooks/useColorScheme'; - -const HEADER_HEIGHT = 250; - -type Props = PropsWithChildren<{ - headerImage: ReactElement; - headerBackgroundColor: { dark: string; light: string }; -}>; - -export default function ParallaxScrollView({ - children, - headerImage, - headerBackgroundColor, -}: Props) { - const colorScheme = useColorScheme() ?? 'light'; - const scrollRef = useAnimatedRef(); - const scrollOffset = useScrollViewOffset(scrollRef); - const bottom = useBottomTabOverflow(); - const headerAnimatedStyle = useAnimatedStyle(() => { - return { - transform: [ - { - translateY: interpolate( - scrollOffset.value, - [-HEADER_HEIGHT, 0, HEADER_HEIGHT], - [-HEADER_HEIGHT / 2, 0, HEADER_HEIGHT * 0.75] - ), - }, - { - scale: interpolate(scrollOffset.value, [-HEADER_HEIGHT, 0, HEADER_HEIGHT], [2, 1, 1]), - }, - ], - }; - }); - - return ( - - - - {headerImage} - - {children} - - - ); -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - }, - header: { - height: HEADER_HEIGHT, - overflow: 'hidden', - }, - content: { - flex: 1, - padding: 32, - gap: 16, - overflow: 'hidden', - }, -}); diff --git a/components/ThemedText.tsx b/components/ThemedText.tsx deleted file mode 100644 index 9d214a2..0000000 --- a/components/ThemedText.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import { StyleSheet, Text, type TextProps } from 'react-native'; - -import { useThemeColor } from '@/hooks/useThemeColor'; - -export type ThemedTextProps = TextProps & { - lightColor?: string; - darkColor?: string; - type?: 'default' | 'title' | 'defaultSemiBold' | 'subtitle' | 'link'; -}; - -export function ThemedText({ - style, - lightColor, - darkColor, - type = 'default', - ...rest -}: ThemedTextProps) { - const color = useThemeColor({ light: lightColor, dark: darkColor }, 'text'); - - return ( - - ); -} - -const styles = StyleSheet.create({ - default: { - fontSize: 16, - lineHeight: 24, - }, - defaultSemiBold: { - fontSize: 16, - lineHeight: 24, - fontWeight: '600', - }, - title: { - fontSize: 32, - fontWeight: 'bold', - lineHeight: 32, - }, - subtitle: { - fontSize: 20, - fontWeight: 'bold', - }, - link: { - lineHeight: 30, - fontSize: 16, - color: '#0a7ea4', - }, -}); diff --git a/components/ThemedView.tsx b/components/ThemedView.tsx deleted file mode 100644 index 4d2cb09..0000000 --- a/components/ThemedView.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { View, type ViewProps } from 'react-native'; - -import { useThemeColor } from '@/hooks/useThemeColor'; - -export type ThemedViewProps = ViewProps & { - lightColor?: string; - darkColor?: string; -}; - -export function ThemedView({ style, lightColor, darkColor, ...otherProps }: ThemedViewProps) { - const backgroundColor = useThemeColor({ light: lightColor, dark: darkColor }, 'background'); - - return ; -} diff --git a/components/ui/IconSymbol.ios.tsx b/components/ui/IconSymbol.ios.tsx deleted file mode 100644 index 9177f4d..0000000 --- a/components/ui/IconSymbol.ios.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { SymbolView, SymbolViewProps, SymbolWeight } from 'expo-symbols'; -import { StyleProp, ViewStyle } from 'react-native'; - -export function IconSymbol({ - name, - size = 24, - color, - style, - weight = 'regular', -}: { - name: SymbolViewProps['name']; - size?: number; - color: string; - style?: StyleProp; - weight?: SymbolWeight; -}) { - return ( - - ); -} diff --git a/components/ui/IconSymbol.tsx b/components/ui/IconSymbol.tsx deleted file mode 100644 index b7ece6b..0000000 --- a/components/ui/IconSymbol.tsx +++ /dev/null @@ -1,41 +0,0 @@ -// Fallback for using MaterialIcons on Android and web. - -import MaterialIcons from '@expo/vector-icons/MaterialIcons'; -import { SymbolWeight, SymbolViewProps } from 'expo-symbols'; -import { ComponentProps } from 'react'; -import { OpaqueColorValue, type StyleProp, type TextStyle } from 'react-native'; - -type IconMapping = Record['name']>; -type IconSymbolName = keyof typeof MAPPING; - -/** - * Add your SF Symbols to Material Icons mappings here. - * - see Material Icons in the [Icons Directory](https://icons.expo.fyi). - * - see SF Symbols in the [SF Symbols](https://developer.apple.com/sf-symbols/) app. - */ -const MAPPING = { - 'house.fill': 'home', - 'paperplane.fill': 'send', - 'chevron.left.forwardslash.chevron.right': 'code', - 'chevron.right': 'chevron-right', -} as IconMapping; - -/** - * An icon component that uses native SF Symbols on iOS, and Material Icons on Android and web. - * This ensures a consistent look across platforms, and optimal resource usage. - * Icon `name`s are based on SF Symbols and require manual mapping to Material Icons. - */ -export function IconSymbol({ - name, - size = 24, - color, - style, -}: { - name: IconSymbolName; - size?: number; - color: string | OpaqueColorValue; - style?: StyleProp; - weight?: SymbolWeight; -}) { - return ; -} diff --git a/components/ui/TabBarBackground.ios.tsx b/components/ui/TabBarBackground.ios.tsx deleted file mode 100644 index 495b2d4..0000000 --- a/components/ui/TabBarBackground.ios.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs'; -import { BlurView } from 'expo-blur'; -import { StyleSheet } from 'react-native'; - -export default function BlurTabBarBackground() { - return ( - - ); -} - -export function useBottomTabOverflow() { - return useBottomTabBarHeight(); -} diff --git a/components/ui/TabBarBackground.tsx b/components/ui/TabBarBackground.tsx deleted file mode 100644 index 70d1c3c..0000000 --- a/components/ui/TabBarBackground.tsx +++ /dev/null @@ -1,6 +0,0 @@ -// This is a shim for web and Android where the tab bar is generally opaque. -export default undefined; - -export function useBottomTabOverflow() { - return 0; -} diff --git a/constants/Colors.ts b/constants/Colors.ts deleted file mode 100644 index 14e6784..0000000 --- a/constants/Colors.ts +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Below are the colors that are used in the app. The colors are defined in the light and dark mode. - * There are many other ways to style your app. For example, [Nativewind](https://www.nativewind.dev/), [Tamagui](https://tamagui.dev/), [unistyles](https://reactnativeunistyles.vercel.app), etc. - */ - -const tintColorLight = '#0a7ea4'; -const tintColorDark = '#fff'; - -export const Colors = { - light: { - text: '#11181C', - background: '#fff', - tint: tintColorLight, - icon: '#687076', - tabIconDefault: '#687076', - tabIconSelected: tintColorLight, - }, - dark: { - text: '#ECEDEE', - background: '#151718', - tint: tintColorDark, - icon: '#9BA1A6', - tabIconDefault: '#9BA1A6', - tabIconSelected: tintColorDark, - }, -}; diff --git a/hooks/useColorScheme.ts b/hooks/useColorScheme.ts deleted file mode 100644 index 17e3c63..0000000 --- a/hooks/useColorScheme.ts +++ /dev/null @@ -1 +0,0 @@ -export { useColorScheme } from 'react-native'; diff --git a/hooks/useColorScheme.web.ts b/hooks/useColorScheme.web.ts deleted file mode 100644 index 7eb1c1b..0000000 --- a/hooks/useColorScheme.web.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { useEffect, useState } from 'react'; -import { useColorScheme as useRNColorScheme } from 'react-native'; - -/** - * To support static rendering, this value needs to be re-calculated on the client side for web - */ -export function useColorScheme() { - const [hasHydrated, setHasHydrated] = useState(false); - - useEffect(() => { - setHasHydrated(true); - }, []); - - const colorScheme = useRNColorScheme(); - - if (hasHydrated) { - return colorScheme; - } - - return 'light'; -} diff --git a/hooks/useThemeColor.ts b/hooks/useThemeColor.ts deleted file mode 100644 index 0608e73..0000000 --- a/hooks/useThemeColor.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Learn more about light and dark modes: - * https://docs.expo.dev/guides/color-schemes/ - */ - -import { Colors } from '@/constants/Colors'; -import { useColorScheme } from '@/hooks/useColorScheme'; - -export function useThemeColor( - props: { light?: string; dark?: string }, - colorName: keyof typeof Colors.light & keyof typeof Colors.dark -) { - const theme = useColorScheme() ?? 'light'; - const colorFromProps = props[theme]; - - if (colorFromProps) { - return colorFromProps; - } else { - return Colors[theme][colorName]; - } -} diff --git a/metro.config.js b/metro.config.js new file mode 100644 index 0000000..9a11768 --- /dev/null +++ b/metro.config.js @@ -0,0 +1,17 @@ +const { getDefaultConfig } = require('expo/metro-config'); + +const config = getDefaultConfig(__dirname); + +// Add GLB file support +config.resolver.assetExts.push('glb', 'gltf', 'jpg'); + +// Serve static files from public directory +config.server = { + ...config.server, + static: { + directory: 'public', + publicPath: '/' + } +}; + +module.exports = config; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 81d2916..a2de195 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,9 +13,12 @@ "@react-navigation/elements": "^2.3.8", "@react-navigation/native": "^7.1.6", "expo": "~53.0.20", + "expo-asset": "^11.1.7", "expo-blur": "~14.1.5", "expo-constants": "~17.1.7", + "expo-file-system": "^18.1.11", "expo-font": "~13.3.2", + "expo-gl": "~15.1.7", "expo-haptics": "~14.1.4", "expo-image": "~2.4.0", "expo-linking": "~7.1.7", @@ -24,6 +27,7 @@ "expo-status-bar": "~2.2.3", "expo-symbols": "~0.4.5", "expo-system-ui": "~5.0.10", + "expo-three": "^8.0.0", "expo-web-browser": "~14.2.0", "react": "19.0.0", "react-dom": "19.0.0", @@ -33,11 +37,13 @@ "react-native-safe-area-context": "5.4.0", "react-native-screens": "~4.11.1", "react-native-web": "~0.20.0", - "react-native-webview": "13.13.5" + "react-native-webview": "13.13.5", + "three": "^0.166.1" }, "devDependencies": { "@babel/core": "^7.25.2", "@types/react": "~19.0.10", + "@types/three": "^0.178.1", "eslint": "^9.25.0", "eslint-config-expo": "~9.2.0", "typescript": "~5.8.3" @@ -1429,6 +1435,12 @@ "node": ">=6.9.0" } }, + "node_modules/@dimforge/rapier3d-compat": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@dimforge/rapier3d-compat/-/rapier3d-compat-0.12.0.tgz", + "integrity": "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==", + "dev": true + }, "node_modules/@egjs/hammerjs": { "version": "2.0.17", "resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz", @@ -2910,6 +2922,12 @@ "@sinonjs/commons": "^3.0.0" } }, + "node_modules/@tweenjs/tween.js": { + "version": "23.1.3", + "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz", + "integrity": "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==", + "dev": true + }, "node_modules/@tybys/wasm-util": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.0.tgz", @@ -3030,6 +3048,33 @@ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==" }, + "node_modules/@types/stats.js": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.4.tgz", + "integrity": "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==", + "dev": true + }, + "node_modules/@types/three": { + "version": "0.178.1", + "resolved": "https://registry.npmjs.org/@types/three/-/three-0.178.1.tgz", + "integrity": "sha512-WSabew1mgWgRx2RfLfKY+9h4wyg6U94JfLbZEGU245j/WY2kXqU0MUfghS+3AYMV5ET1VlILAgpy77cB6a3Itw==", + "dev": true, + "dependencies": { + "@dimforge/rapier3d-compat": "~0.12.0", + "@tweenjs/tween.js": "~23.1.3", + "@types/stats.js": "*", + "@types/webxr": "*", + "@webgpu/types": "*", + "fflate": "~0.8.2", + "meshoptimizer": "~0.18.1" + } + }, + "node_modules/@types/webxr": { + "version": "0.5.22", + "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.22.tgz", + "integrity": "sha512-Vr6Stjv5jPRqH690f5I5GLjVk8GSsoQSYJ2FVd/3jJF7KaqfwPi3ehfBS96mlQ2kPCwZaX6U0rG2+NGHBKkA/A==", + "dev": true + }, "node_modules/@types/yargs": { "version": "17.0.33", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", @@ -3571,6 +3616,12 @@ "@urql/core": "^5.0.0" } }, + "node_modules/@webgpu/types": { + "version": "0.1.64", + "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.64.tgz", + "integrity": "sha512-84kRIAGV46LJTlJZWxShiOrNL30A+9KokD7RB3dRCIqODFjodS5tCD5yyiZ8kIReGVZSDfA3XkkwyyOIF6K62A==", + "dev": true + }, "node_modules/@xmldom/xmldom": { "version": "0.8.10", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", @@ -3622,6 +3673,16 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/adaptive-bezier-curve": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/adaptive-bezier-curve/-/adaptive-bezier-curve-1.0.3.tgz", + "integrity": "sha512-mDcwN284LlNAdunqnVmS0PAoDNHKze/PY8zvpCdxzyXD+ZZFeMWQ3FKNBw0VMOd9IfnhIyzAWJDXzRcWnXtoSg==" + }, + "node_modules/adaptive-quadratic-curve": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/adaptive-quadratic-curve/-/adaptive-quadratic-curve-1.0.2.tgz", + "integrity": "sha512-D6NxIKnelgRDqQijGR6FQzdWPgs4bC7H54LyukFKxTkoZW4+zNemU2JevF4BuMraoxYogvAIMRc2LD5oSCL34g==" + }, "node_modules/agent-base": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", @@ -4701,6 +4762,12 @@ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" }, + "node_modules/core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha512-ZiPp9pZlgxpWRu0M+YWbm6+aQ84XEfH1JRXvfOc/fILWI0VKhLC2LX13X1NYq4fULzLMq7Hfh43CSo2/aIaUPA==", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js." + }, "node_modules/core-js-compat": { "version": "3.44.0", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.44.0.tgz", @@ -4796,6 +4863,11 @@ "node": ">=8" } }, + "node_modules/css-font-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/css-font-parser/-/css-font-parser-0.2.3.tgz", + "integrity": "sha512-QhdfNV+RjQLVg24d/ls4I8UrA/5WCeEfUmi1je8ISPr7RGZJXwWU2AwZpCiUmWuLZW7dKaB3ER0Bq1W9UhEUag==" + }, "node_modules/css-in-js-utils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz", @@ -5000,6 +5072,20 @@ "node": ">=0.10.0" } }, + "node_modules/domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "deprecated": "Use your platform's native DOMException instead", + "dependencies": { + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/domexception/node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, "node_modules/dotenv": { "version": "16.4.7", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", @@ -5039,6 +5125,11 @@ "node": ">= 0.4" } }, + "node_modules/earcut": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.1.1.tgz", + "integrity": "sha512-+BGT9Mffq3Oxf2nDOtzaJDd9P8g/z3WNYGO84Q23hDBot5VU8DNGY73Vc94eVDvHjMyhonnuEg+DNwEQ6iZn3w==" + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -5067,6 +5158,14 @@ "node": ">= 0.8" } }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, "node_modules/env-editor": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/env-editor/-/env-editor-0.4.2.tgz", @@ -5742,6 +5841,39 @@ } } }, + "node_modules/expo-2d-context": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/expo-2d-context/-/expo-2d-context-0.0.3.tgz", + "integrity": "sha512-loO/cIj5owNXv0GJxEQ7Sm1vlGOYoJwHCaf2uiPKG3BZm+gQw6GnDgxN+2WDisNZKLTjnMLUGP1HhBsNnElt6g==", + "dependencies": { + "adaptive-bezier-curve": "1.0.3", + "adaptive-quadratic-curve": "1.0.2", + "color-convert": "^1.9.3", + "css-font-parser": "0.2.3", + "domexception": "1.0.1", + "earcut": "2.1.1", + "gl-matrix": "^2.4.0", + "parse-bmfont-ascii": "1.0.6", + "string-format": "0.5.0", + "tess2": "^1.0.0" + }, + "peerDependencies": { + "expo-asset": "*" + } + }, + "node_modules/expo-2d-context/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/expo-2d-context/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, "node_modules/expo-asset": { "version": "11.1.7", "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-11.1.7.tgz", @@ -5756,6 +5888,18 @@ "react-native": "*" } }, + "node_modules/expo-asset-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/expo-asset-utils/-/expo-asset-utils-3.0.0.tgz", + "integrity": "sha512-CgIbNvTqKqQi1lrlptmwoaCMu4ZVOZf8tghmytlor23CjIOuorw6cfuOqiqWkJLz23arTt91maYEU9XLMPB23A==", + "peerDependencies": { + "expo-asset": "*", + "expo-file-system": "*", + "expo-font": "*", + "expo-modules-core": "*", + "react-native": "*" + } + }, "node_modules/expo-blur": { "version": "14.1.5", "resolved": "https://registry.npmjs.org/expo-blur/-/expo-blur-14.1.5.tgz", @@ -5800,6 +5944,25 @@ "react": "*" } }, + "node_modules/expo-gl": { + "version": "15.1.7", + "resolved": "https://registry.npmjs.org/expo-gl/-/expo-gl-15.1.7.tgz", + "integrity": "sha512-ozvaQn3Ev1oZ3lraOpp6PJpSCbb5DRxu29K/prtfUdygrNJbCFhhxG7zgpEcPaFZXj4b1Yc7jzn1UzOylfUdaw==", + "dependencies": { + "invariant": "^2.2.4" + }, + "peerDependencies": { + "expo": "*", + "react": "*", + "react-native": "*", + "react-native-web": "*" + }, + "peerDependenciesMeta": { + "react-native-web": { + "optional": true + } + } + }, "node_modules/expo-haptics": { "version": "14.1.4", "resolved": "https://registry.npmjs.org/expo-haptics/-/expo-haptics-14.1.4.tgz", @@ -5978,6 +6141,61 @@ } } }, + "node_modules/expo-three": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/expo-three/-/expo-three-8.0.0.tgz", + "integrity": "sha512-aGSxS7UEA0DtkdY9UdAHWW4JsJh4Q2vtOQNb3oocIP5bBazb6qTm0PtsXUF0YYo5s9TCJfm4t2ED+0LUz7QwaQ==", + "dependencies": { + "@expo/browser-polyfill": "^1.0.1", + "expo-asset-utils": "~3.0.0" + }, + "peerDependencies": { + "expo": "*", + "expo-asset": "*", + "expo-file-system": "*", + "expo-gl": "*", + "react-native": "*", + "three": "^0.166.0" + } + }, + "node_modules/expo-three/node_modules/@expo/browser-polyfill": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@expo/browser-polyfill/-/browser-polyfill-1.0.1.tgz", + "integrity": "sha512-0K6USycVKDj/k9Gr2UYa+7MiCjb0f2NznsE4LX11H85vQMJma5JS3a2oe6lxCfleY9hDcQ/9zKCYS8O6crsv3A==", + "dependencies": { + "expo-2d-context": "^0.0.3", + "fbemitter": "^2.1.1", + "text-encoding": "^0.7.0", + "uuid": "^8.3.2", + "xmldom-qsa": "^1.0.3" + }, + "peerDependencies": { + "expo-file-system": "^13.2.0", + "react": "^17.0.1", + "react-native": "^0.64.3" + } + }, + "node_modules/expo-three/node_modules/react": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz", + "integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expo-three/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/expo-web-browser": { "version": "14.2.0", "resolved": "https://registry.npmjs.org/expo-web-browser/-/expo-web-browser-14.2.0.tgz", @@ -6068,6 +6286,61 @@ "bser": "2.1.1" } }, + "node_modules/fbemitter": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fbemitter/-/fbemitter-2.1.1.tgz", + "integrity": "sha512-hd8PgD+Q6RQtlcGrkM9oY3MFIjq6CA6wurCK1TKn2eaA76Ww4VAOihmq98NyjRhjJi/axgznZnh9lF8+TcTsNQ==", + "dependencies": { + "fbjs": "^0.8.4" + } + }, + "node_modules/fbemitter/node_modules/fbjs": { + "version": "0.8.18", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.18.tgz", + "integrity": "sha512-EQaWFK+fEPSoibjNy8IxUtaFOMXcWsY0JaVrQoZR9zC8N2Ygf9iDITPWjUTVIax95b6I742JFLqASHfsag/vKA==", + "dependencies": { + "core-js": "^1.0.0", + "isomorphic-fetch": "^2.1.1", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^0.7.30" + } + }, + "node_modules/fbemitter/node_modules/promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dependencies": { + "asap": "~2.0.3" + } + }, + "node_modules/fbemitter/node_modules/ua-parser-js": { + "version": "0.7.40", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.40.tgz", + "integrity": "sha512-us1E3K+3jJppDBa3Tl0L3MOJiGhe1C6P0+nIvQAFYbxlMAx0h81eOwLmU57xgqToduDDPx3y5QsdjPfDu+FgOQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "bin": { + "ua-parser-js": "script/cli.js" + }, + "engines": { + "node": "*" + } + }, "node_modules/fbjs": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.5.tgz", @@ -6109,6 +6382,12 @@ } } }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "dev": true + }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -6413,6 +6692,11 @@ "node": ">=6" } }, + "node_modules/gl-matrix": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-2.8.1.tgz", + "integrity": "sha512-0YCjVpE3pS5XWlN3J4X7AiAx65+nqAI54LndtVFnQZB6G/FVLkZH8y8V6R3cIoOQR4pUdfwQGd1iwyoXHJ4Qfw==" + }, "node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", @@ -6684,6 +6968,17 @@ "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz", "integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==" }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -7137,6 +7432,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-string": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", @@ -7250,6 +7553,24 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, + "node_modules/isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha512-9c4TNAKYXM5PRyVcwUZrF3W09nQ+sO7+jydgs4ZGW9dhsLG2VOlISJABombdQqQRXCwuYG3sYV/puGf5rp0qmA==", + "dependencies": { + "node-fetch": "^1.0.1", + "whatwg-fetch": ">=0.10.0" + } + }, + "node_modules/isomorphic-fetch/node_modules/node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "dependencies": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", @@ -8015,6 +8336,12 @@ "node": ">= 8" } }, + "node_modules/meshoptimizer": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-0.18.1.tgz", + "integrity": "sha512-ZhoIoL7TNV4s5B6+rx5mC//fw8/POGyNxS/DZyCJeiZ12ScLfVwRE/GfsxwiTkMYYD5DmK2/JXnEVXqL4rF+Sw==", + "dev": true + }, "node_modules/metro": { "version": "0.82.5", "resolved": "https://registry.npmjs.org/metro/-/metro-0.82.5.tgz", @@ -8944,6 +9271,11 @@ "node": ">=6" } }, + "node_modules/parse-bmfont-ascii": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz", + "integrity": "sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA==" + }, "node_modules/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -9985,6 +10317,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, "node_modules/sax": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", @@ -10574,6 +10911,11 @@ "node": ">=4" } }, + "node_modules/string-format": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/string-format/-/string-format-0.5.0.tgz", + "integrity": "sha512-c/CiKQMy7uuEzi+Tsvnn63/PQw/F7IOSLHNuQ44Eypd0x5VvFnDXMd2T9H0ntphv8nrHAKoZcINPb/yitOAB/g==" + }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -10927,6 +11269,11 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, + "node_modules/tess2": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tess2/-/tess2-1.0.0.tgz", + "integrity": "sha512-iSWBSOUoPn3cCT26L5Wi6mvVgL11RV4kReSnVIIPdMN7qNpkL5SLKen5BJcWj+ZTN7kK6JrHBdqTV7vvL8g+9w==" + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -10960,6 +11307,12 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/text-encoding": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.7.0.tgz", + "integrity": "sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA==", + "deprecated": "no longer maintained" + }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -10979,6 +11332,11 @@ "node": ">=0.8" } }, + "node_modules/three": { + "version": "0.166.1", + "resolved": "https://registry.npmjs.org/three/-/three-0.166.1.tgz", + "integrity": "sha512-LtuafkKHHzm61AQA1be2MAYIw1IjmhOUxhBa0prrLpEMWbV7ijvxCRHjSgHPGp2493wLBzwKV46tA9nivLEgKg==" + }, "node_modules/throat": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", @@ -11787,6 +12145,14 @@ "node": ">=8.0" } }, + "node_modules/xmldom-qsa": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/xmldom-qsa/-/xmldom-qsa-1.1.3.tgz", + "integrity": "sha512-IJBOczBpAYrIBJFFsmCBwfBhwe4zdMR3Xz0ZBX0OFtgO49rLy/BWbhkegOwsthdBWb1gUtFK6ZZnGdT8ZqPRBA==", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index f79c1f4..a8fb339 100644 --- a/package.json +++ b/package.json @@ -16,9 +16,12 @@ "@react-navigation/elements": "^2.3.8", "@react-navigation/native": "^7.1.6", "expo": "~53.0.20", + "expo-asset": "^11.1.7", "expo-blur": "~14.1.5", "expo-constants": "~17.1.7", + "expo-file-system": "^18.1.11", "expo-font": "~13.3.2", + "expo-gl": "~15.1.7", "expo-haptics": "~14.1.4", "expo-image": "~2.4.0", "expo-linking": "~7.1.7", @@ -27,6 +30,7 @@ "expo-status-bar": "~2.2.3", "expo-symbols": "~0.4.5", "expo-system-ui": "~5.0.10", + "expo-three": "^8.0.0", "expo-web-browser": "~14.2.0", "react": "19.0.0", "react-dom": "19.0.0", @@ -36,14 +40,16 @@ "react-native-safe-area-context": "5.4.0", "react-native-screens": "~4.11.1", "react-native-web": "~0.20.0", - "react-native-webview": "13.13.5" + "react-native-webview": "13.13.5", + "three": "^0.166.1" }, "devDependencies": { "@babel/core": "^7.25.2", "@types/react": "~19.0.10", - "typescript": "~5.8.3", + "@types/three": "^0.178.1", "eslint": "^9.25.0", - "eslint-config-expo": "~9.2.0" + "eslint-config-expo": "~9.2.0", + "typescript": "~5.8.3" }, "private": true } diff --git a/public/assets/arena/hex_forest.gltf.glb b/public/assets/arena/hex_forest.gltf.glb new file mode 100644 index 0000000..133ba2d Binary files /dev/null and b/public/assets/arena/hex_forest.gltf.glb differ diff --git a/public/assets/arena/hex_forest_detail.gltf.glb b/public/assets/arena/hex_forest_detail.gltf.glb new file mode 100644 index 0000000..c9458f9 Binary files /dev/null and b/public/assets/arena/hex_forest_detail.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadA.gltf.glb b/public/assets/arena/hex_forest_roadA.gltf.glb new file mode 100644 index 0000000..6cb121c Binary files /dev/null and b/public/assets/arena/hex_forest_roadA.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadA_detail.gltf.glb b/public/assets/arena/hex_forest_roadA_detail.gltf.glb new file mode 100644 index 0000000..cec68db Binary files /dev/null and b/public/assets/arena/hex_forest_roadA_detail.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadB.gltf.glb b/public/assets/arena/hex_forest_roadB.gltf.glb new file mode 100644 index 0000000..0762226 Binary files /dev/null and b/public/assets/arena/hex_forest_roadB.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadB_detail.gltf.glb b/public/assets/arena/hex_forest_roadB_detail.gltf.glb new file mode 100644 index 0000000..9c82dd4 Binary files /dev/null and b/public/assets/arena/hex_forest_roadB_detail.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadC.gltf.glb b/public/assets/arena/hex_forest_roadC.gltf.glb new file mode 100644 index 0000000..d6ba108 Binary files /dev/null and b/public/assets/arena/hex_forest_roadC.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadC_detail.gltf.glb b/public/assets/arena/hex_forest_roadC_detail.gltf.glb new file mode 100644 index 0000000..1e5e5ba Binary files /dev/null and b/public/assets/arena/hex_forest_roadC_detail.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadD.gltf.glb b/public/assets/arena/hex_forest_roadD.gltf.glb new file mode 100644 index 0000000..76a20af Binary files /dev/null and b/public/assets/arena/hex_forest_roadD.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadD_detail.gltf.glb b/public/assets/arena/hex_forest_roadD_detail.gltf.glb new file mode 100644 index 0000000..efcb545 Binary files /dev/null and b/public/assets/arena/hex_forest_roadD_detail.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadE.gltf.glb b/public/assets/arena/hex_forest_roadE.gltf.glb new file mode 100644 index 0000000..dda8ef2 Binary files /dev/null and b/public/assets/arena/hex_forest_roadE.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadE_detail.gltf.glb b/public/assets/arena/hex_forest_roadE_detail.gltf.glb new file mode 100644 index 0000000..7662976 Binary files /dev/null and b/public/assets/arena/hex_forest_roadE_detail.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadF.gltf.glb b/public/assets/arena/hex_forest_roadF.gltf.glb new file mode 100644 index 0000000..021de5e Binary files /dev/null and b/public/assets/arena/hex_forest_roadF.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadF_detail.gltf.glb b/public/assets/arena/hex_forest_roadF_detail.gltf.glb new file mode 100644 index 0000000..6805565 Binary files /dev/null and b/public/assets/arena/hex_forest_roadF_detail.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadG.gltf.glb b/public/assets/arena/hex_forest_roadG.gltf.glb new file mode 100644 index 0000000..f2f59ff Binary files /dev/null and b/public/assets/arena/hex_forest_roadG.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadG_detail.gltf.glb b/public/assets/arena/hex_forest_roadG_detail.gltf.glb new file mode 100644 index 0000000..565065d Binary files /dev/null and b/public/assets/arena/hex_forest_roadG_detail.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadH.gltf.glb b/public/assets/arena/hex_forest_roadH.gltf.glb new file mode 100644 index 0000000..362c342 Binary files /dev/null and b/public/assets/arena/hex_forest_roadH.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadH_detail.gltf.glb b/public/assets/arena/hex_forest_roadH_detail.gltf.glb new file mode 100644 index 0000000..f57a562 Binary files /dev/null and b/public/assets/arena/hex_forest_roadH_detail.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadI.gltf.glb b/public/assets/arena/hex_forest_roadI.gltf.glb new file mode 100644 index 0000000..b984ed5 Binary files /dev/null and b/public/assets/arena/hex_forest_roadI.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadI_detail.gltf.glb b/public/assets/arena/hex_forest_roadI_detail.gltf.glb new file mode 100644 index 0000000..963a7a8 Binary files /dev/null and b/public/assets/arena/hex_forest_roadI_detail.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadJ.gltf.glb b/public/assets/arena/hex_forest_roadJ.gltf.glb new file mode 100644 index 0000000..dfc995f Binary files /dev/null and b/public/assets/arena/hex_forest_roadJ.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadJ_detail.gltf.glb b/public/assets/arena/hex_forest_roadJ_detail.gltf.glb new file mode 100644 index 0000000..a729811 Binary files /dev/null and b/public/assets/arena/hex_forest_roadJ_detail.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadK.gltf.glb b/public/assets/arena/hex_forest_roadK.gltf.glb new file mode 100644 index 0000000..9066744 Binary files /dev/null and b/public/assets/arena/hex_forest_roadK.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadK_detail.gltf.glb b/public/assets/arena/hex_forest_roadK_detail.gltf.glb new file mode 100644 index 0000000..8890565 Binary files /dev/null and b/public/assets/arena/hex_forest_roadK_detail.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadL.gltf.glb b/public/assets/arena/hex_forest_roadL.gltf.glb new file mode 100644 index 0000000..0ea9f95 Binary files /dev/null and b/public/assets/arena/hex_forest_roadL.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadL_detail.gltf.glb b/public/assets/arena/hex_forest_roadL_detail.gltf.glb new file mode 100644 index 0000000..8cef810 Binary files /dev/null and b/public/assets/arena/hex_forest_roadL_detail.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadM.gltf.glb b/public/assets/arena/hex_forest_roadM.gltf.glb new file mode 100644 index 0000000..1d11fe4 Binary files /dev/null and b/public/assets/arena/hex_forest_roadM.gltf.glb differ diff --git a/public/assets/arena/hex_forest_roadM_detail.gltf.glb b/public/assets/arena/hex_forest_roadM_detail.gltf.glb new file mode 100644 index 0000000..7f2cc04 Binary files /dev/null and b/public/assets/arena/hex_forest_roadM_detail.gltf.glb differ diff --git a/public/assets/arena/hex_forest_transitionA.gltf.glb b/public/assets/arena/hex_forest_transitionA.gltf.glb new file mode 100644 index 0000000..01891ad Binary files /dev/null and b/public/assets/arena/hex_forest_transitionA.gltf.glb differ diff --git a/public/assets/arena/hex_forest_transitionB.gltf.glb b/public/assets/arena/hex_forest_transitionB.gltf.glb new file mode 100644 index 0000000..cd474b7 Binary files /dev/null and b/public/assets/arena/hex_forest_transitionB.gltf.glb differ diff --git a/public/assets/arena/hex_forest_waterA.gltf.glb b/public/assets/arena/hex_forest_waterA.gltf.glb new file mode 100644 index 0000000..6512d4b Binary files /dev/null and b/public/assets/arena/hex_forest_waterA.gltf.glb differ diff --git a/public/assets/arena/hex_forest_waterA_detail.gltf.glb b/public/assets/arena/hex_forest_waterA_detail.gltf.glb new file mode 100644 index 0000000..500b22b Binary files /dev/null and b/public/assets/arena/hex_forest_waterA_detail.gltf.glb differ diff --git a/public/assets/arena/hex_forest_waterA_empty.gltf.glb b/public/assets/arena/hex_forest_waterA_empty.gltf.glb new file mode 100644 index 0000000..40614d9 Binary files /dev/null and b/public/assets/arena/hex_forest_waterA_empty.gltf.glb differ diff --git a/public/assets/arena/hex_forest_waterB.gltf.glb b/public/assets/arena/hex_forest_waterB.gltf.glb new file mode 100644 index 0000000..d7a9800 Binary files /dev/null and b/public/assets/arena/hex_forest_waterB.gltf.glb differ diff --git a/public/assets/arena/hex_forest_waterB_detail.gltf.glb b/public/assets/arena/hex_forest_waterB_detail.gltf.glb new file mode 100644 index 0000000..2436c01 Binary files /dev/null and b/public/assets/arena/hex_forest_waterB_detail.gltf.glb differ diff --git a/public/assets/arena/hex_forest_waterB_empty.gltf.glb b/public/assets/arena/hex_forest_waterB_empty.gltf.glb new file mode 100644 index 0000000..196c06d Binary files /dev/null and b/public/assets/arena/hex_forest_waterB_empty.gltf.glb differ diff --git a/public/assets/arena/hex_forest_waterC.gltf.glb b/public/assets/arena/hex_forest_waterC.gltf.glb new file mode 100644 index 0000000..7277baf Binary files /dev/null and b/public/assets/arena/hex_forest_waterC.gltf.glb differ diff --git a/public/assets/arena/hex_forest_waterC_detail.gltf.glb b/public/assets/arena/hex_forest_waterC_detail.gltf.glb new file mode 100644 index 0000000..7e854fa Binary files /dev/null and b/public/assets/arena/hex_forest_waterC_detail.gltf.glb differ diff --git a/public/assets/arena/hex_forest_waterC_empty.gltf.glb b/public/assets/arena/hex_forest_waterC_empty.gltf.glb new file mode 100644 index 0000000..eb17e6a Binary files /dev/null and b/public/assets/arena/hex_forest_waterC_empty.gltf.glb differ diff --git a/public/assets/arena/hex_forest_waterD.gltf.glb b/public/assets/arena/hex_forest_waterD.gltf.glb new file mode 100644 index 0000000..ab60f8e Binary files /dev/null and b/public/assets/arena/hex_forest_waterD.gltf.glb differ diff --git a/public/assets/arena/hex_forest_waterD_detail.gltf.glb b/public/assets/arena/hex_forest_waterD_detail.gltf.glb new file mode 100644 index 0000000..ad3c3bb Binary files /dev/null and b/public/assets/arena/hex_forest_waterD_detail.gltf.glb differ diff --git a/public/assets/arena/hex_forest_waterD_empty.gltf.glb b/public/assets/arena/hex_forest_waterD_empty.gltf.glb new file mode 100644 index 0000000..d299200 Binary files /dev/null and b/public/assets/arena/hex_forest_waterD_empty.gltf.glb differ diff --git a/public/assets/arena/hex_rock.gltf.glb b/public/assets/arena/hex_rock.gltf.glb new file mode 100644 index 0000000..4c6af9e Binary files /dev/null and b/public/assets/arena/hex_rock.gltf.glb differ diff --git a/public/assets/arena/hex_rock_detail.gltf.glb b/public/assets/arena/hex_rock_detail.gltf.glb new file mode 100644 index 0000000..1e13ce7 Binary files /dev/null and b/public/assets/arena/hex_rock_detail.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadA.gltf.glb b/public/assets/arena/hex_rock_roadA.gltf.glb new file mode 100644 index 0000000..8ded8f0 Binary files /dev/null and b/public/assets/arena/hex_rock_roadA.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadA_detail.gltf.glb b/public/assets/arena/hex_rock_roadA_detail.gltf.glb new file mode 100644 index 0000000..cb535e0 Binary files /dev/null and b/public/assets/arena/hex_rock_roadA_detail.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadB.gltf.glb b/public/assets/arena/hex_rock_roadB.gltf.glb new file mode 100644 index 0000000..3446702 Binary files /dev/null and b/public/assets/arena/hex_rock_roadB.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadB_detail.gltf.glb b/public/assets/arena/hex_rock_roadB_detail.gltf.glb new file mode 100644 index 0000000..0f500ad Binary files /dev/null and b/public/assets/arena/hex_rock_roadB_detail.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadC.gltf.glb b/public/assets/arena/hex_rock_roadC.gltf.glb new file mode 100644 index 0000000..9017133 Binary files /dev/null and b/public/assets/arena/hex_rock_roadC.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadC_detail.gltf.glb b/public/assets/arena/hex_rock_roadC_detail.gltf.glb new file mode 100644 index 0000000..e29da55 Binary files /dev/null and b/public/assets/arena/hex_rock_roadC_detail.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadD.gltf.glb b/public/assets/arena/hex_rock_roadD.gltf.glb new file mode 100644 index 0000000..e80531d Binary files /dev/null and b/public/assets/arena/hex_rock_roadD.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadD_detail.gltf.glb b/public/assets/arena/hex_rock_roadD_detail.gltf.glb new file mode 100644 index 0000000..a54117d Binary files /dev/null and b/public/assets/arena/hex_rock_roadD_detail.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadE.gltf.glb b/public/assets/arena/hex_rock_roadE.gltf.glb new file mode 100644 index 0000000..e5e9c6b Binary files /dev/null and b/public/assets/arena/hex_rock_roadE.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadE_detail.gltf.glb b/public/assets/arena/hex_rock_roadE_detail.gltf.glb new file mode 100644 index 0000000..e9741a0 Binary files /dev/null and b/public/assets/arena/hex_rock_roadE_detail.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadF.gltf.glb b/public/assets/arena/hex_rock_roadF.gltf.glb new file mode 100644 index 0000000..e46ac18 Binary files /dev/null and b/public/assets/arena/hex_rock_roadF.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadF_detail.gltf.glb b/public/assets/arena/hex_rock_roadF_detail.gltf.glb new file mode 100644 index 0000000..8522ff0 Binary files /dev/null and b/public/assets/arena/hex_rock_roadF_detail.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadG.gltf.glb b/public/assets/arena/hex_rock_roadG.gltf.glb new file mode 100644 index 0000000..0b754e4 Binary files /dev/null and b/public/assets/arena/hex_rock_roadG.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadG_detail.gltf.glb b/public/assets/arena/hex_rock_roadG_detail.gltf.glb new file mode 100644 index 0000000..1e5048a Binary files /dev/null and b/public/assets/arena/hex_rock_roadG_detail.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadH.gltf.glb b/public/assets/arena/hex_rock_roadH.gltf.glb new file mode 100644 index 0000000..24a489c Binary files /dev/null and b/public/assets/arena/hex_rock_roadH.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadH_detail.gltf.glb b/public/assets/arena/hex_rock_roadH_detail.gltf.glb new file mode 100644 index 0000000..43007b3 Binary files /dev/null and b/public/assets/arena/hex_rock_roadH_detail.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadI.gltf.glb b/public/assets/arena/hex_rock_roadI.gltf.glb new file mode 100644 index 0000000..60cae61 Binary files /dev/null and b/public/assets/arena/hex_rock_roadI.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadI_detail.gltf.glb b/public/assets/arena/hex_rock_roadI_detail.gltf.glb new file mode 100644 index 0000000..a86b791 Binary files /dev/null and b/public/assets/arena/hex_rock_roadI_detail.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadJ.gltf.glb b/public/assets/arena/hex_rock_roadJ.gltf.glb new file mode 100644 index 0000000..dc85527 Binary files /dev/null and b/public/assets/arena/hex_rock_roadJ.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadJ_detail.gltf.glb b/public/assets/arena/hex_rock_roadJ_detail.gltf.glb new file mode 100644 index 0000000..17abbbc Binary files /dev/null and b/public/assets/arena/hex_rock_roadJ_detail.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadK.gltf.glb b/public/assets/arena/hex_rock_roadK.gltf.glb new file mode 100644 index 0000000..a07bd62 Binary files /dev/null and b/public/assets/arena/hex_rock_roadK.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadK_detail.gltf.glb b/public/assets/arena/hex_rock_roadK_detail.gltf.glb new file mode 100644 index 0000000..e25dae9 Binary files /dev/null and b/public/assets/arena/hex_rock_roadK_detail.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadL.gltf.glb b/public/assets/arena/hex_rock_roadL.gltf.glb new file mode 100644 index 0000000..2469f38 Binary files /dev/null and b/public/assets/arena/hex_rock_roadL.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadL_detail.gltf.glb b/public/assets/arena/hex_rock_roadL_detail.gltf.glb new file mode 100644 index 0000000..e7343f0 Binary files /dev/null and b/public/assets/arena/hex_rock_roadL_detail.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadM.gltf.glb b/public/assets/arena/hex_rock_roadM.gltf.glb new file mode 100644 index 0000000..a51c637 Binary files /dev/null and b/public/assets/arena/hex_rock_roadM.gltf.glb differ diff --git a/public/assets/arena/hex_rock_roadM_detail.gltf.glb b/public/assets/arena/hex_rock_roadM_detail.gltf.glb new file mode 100644 index 0000000..66ce90a Binary files /dev/null and b/public/assets/arena/hex_rock_roadM_detail.gltf.glb differ diff --git a/public/assets/arena/hex_rock_transitionA.gltf.glb b/public/assets/arena/hex_rock_transitionA.gltf.glb new file mode 100644 index 0000000..6b0cd0a Binary files /dev/null and b/public/assets/arena/hex_rock_transitionA.gltf.glb differ diff --git a/public/assets/arena/hex_rock_transitionB.gltf.glb b/public/assets/arena/hex_rock_transitionB.gltf.glb new file mode 100644 index 0000000..ab8972a Binary files /dev/null and b/public/assets/arena/hex_rock_transitionB.gltf.glb differ diff --git a/public/assets/arena/hex_rock_waterA.gltf.glb b/public/assets/arena/hex_rock_waterA.gltf.glb new file mode 100644 index 0000000..762dd15 Binary files /dev/null and b/public/assets/arena/hex_rock_waterA.gltf.glb differ diff --git a/public/assets/arena/hex_rock_waterA_detail.gltf.glb b/public/assets/arena/hex_rock_waterA_detail.gltf.glb new file mode 100644 index 0000000..b5f57e7 Binary files /dev/null and b/public/assets/arena/hex_rock_waterA_detail.gltf.glb differ diff --git a/public/assets/arena/hex_rock_waterA_empty.gltf.glb b/public/assets/arena/hex_rock_waterA_empty.gltf.glb new file mode 100644 index 0000000..49e478c Binary files /dev/null and b/public/assets/arena/hex_rock_waterA_empty.gltf.glb differ diff --git a/public/assets/arena/hex_rock_waterB.gltf.glb b/public/assets/arena/hex_rock_waterB.gltf.glb new file mode 100644 index 0000000..7d36af3 Binary files /dev/null and b/public/assets/arena/hex_rock_waterB.gltf.glb differ diff --git a/public/assets/arena/hex_rock_waterB_detail.gltf.glb b/public/assets/arena/hex_rock_waterB_detail.gltf.glb new file mode 100644 index 0000000..b66877c Binary files /dev/null and b/public/assets/arena/hex_rock_waterB_detail.gltf.glb differ diff --git a/public/assets/arena/hex_rock_waterB_empty.gltf.glb b/public/assets/arena/hex_rock_waterB_empty.gltf.glb new file mode 100644 index 0000000..30a0fc0 Binary files /dev/null and b/public/assets/arena/hex_rock_waterB_empty.gltf.glb differ diff --git a/public/assets/arena/hex_rock_waterC.gltf.glb b/public/assets/arena/hex_rock_waterC.gltf.glb new file mode 100644 index 0000000..5d04991 Binary files /dev/null and b/public/assets/arena/hex_rock_waterC.gltf.glb differ diff --git a/public/assets/arena/hex_rock_waterC_detail.gltf.glb b/public/assets/arena/hex_rock_waterC_detail.gltf.glb new file mode 100644 index 0000000..cb9791a Binary files /dev/null and b/public/assets/arena/hex_rock_waterC_detail.gltf.glb differ diff --git a/public/assets/arena/hex_rock_waterC_empty.gltf.glb b/public/assets/arena/hex_rock_waterC_empty.gltf.glb new file mode 100644 index 0000000..2c9a1bd Binary files /dev/null and b/public/assets/arena/hex_rock_waterC_empty.gltf.glb differ diff --git a/public/assets/arena/hex_rock_waterD.gltf.glb b/public/assets/arena/hex_rock_waterD.gltf.glb new file mode 100644 index 0000000..f43656f Binary files /dev/null and b/public/assets/arena/hex_rock_waterD.gltf.glb differ diff --git a/public/assets/arena/hex_rock_waterD_detail.gltf.glb b/public/assets/arena/hex_rock_waterD_detail.gltf.glb new file mode 100644 index 0000000..9684a26 Binary files /dev/null and b/public/assets/arena/hex_rock_waterD_detail.gltf.glb differ diff --git a/public/assets/arena/hex_rock_waterD_empty.gltf.glb b/public/assets/arena/hex_rock_waterD_empty.gltf.glb new file mode 100644 index 0000000..395f5e4 Binary files /dev/null and b/public/assets/arena/hex_rock_waterD_empty.gltf.glb differ diff --git a/public/assets/arena/hex_sand.gltf.glb b/public/assets/arena/hex_sand.gltf.glb new file mode 100644 index 0000000..a07f142 Binary files /dev/null and b/public/assets/arena/hex_sand.gltf.glb differ diff --git a/public/assets/arena/hex_sand_detail.gltf.glb b/public/assets/arena/hex_sand_detail.gltf.glb new file mode 100644 index 0000000..5a6ece0 Binary files /dev/null and b/public/assets/arena/hex_sand_detail.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadA.gltf.glb b/public/assets/arena/hex_sand_roadA.gltf.glb new file mode 100644 index 0000000..afd2c77 Binary files /dev/null and b/public/assets/arena/hex_sand_roadA.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadA_detail.gltf.glb b/public/assets/arena/hex_sand_roadA_detail.gltf.glb new file mode 100644 index 0000000..4da2335 Binary files /dev/null and b/public/assets/arena/hex_sand_roadA_detail.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadB.gltf.glb b/public/assets/arena/hex_sand_roadB.gltf.glb new file mode 100644 index 0000000..3ecbd54 Binary files /dev/null and b/public/assets/arena/hex_sand_roadB.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadB_detail.gltf.glb b/public/assets/arena/hex_sand_roadB_detail.gltf.glb new file mode 100644 index 0000000..ced06df Binary files /dev/null and b/public/assets/arena/hex_sand_roadB_detail.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadC.gltf.glb b/public/assets/arena/hex_sand_roadC.gltf.glb new file mode 100644 index 0000000..400366e Binary files /dev/null and b/public/assets/arena/hex_sand_roadC.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadC_detail.gltf.glb b/public/assets/arena/hex_sand_roadC_detail.gltf.glb new file mode 100644 index 0000000..2bddc33 Binary files /dev/null and b/public/assets/arena/hex_sand_roadC_detail.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadD.gltf.glb b/public/assets/arena/hex_sand_roadD.gltf.glb new file mode 100644 index 0000000..34e0e93 Binary files /dev/null and b/public/assets/arena/hex_sand_roadD.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadD_detail.gltf.glb b/public/assets/arena/hex_sand_roadD_detail.gltf.glb new file mode 100644 index 0000000..42eea3a Binary files /dev/null and b/public/assets/arena/hex_sand_roadD_detail.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadE.gltf.glb b/public/assets/arena/hex_sand_roadE.gltf.glb new file mode 100644 index 0000000..8c0a832 Binary files /dev/null and b/public/assets/arena/hex_sand_roadE.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadE_detail.gltf.glb b/public/assets/arena/hex_sand_roadE_detail.gltf.glb new file mode 100644 index 0000000..3e64461 Binary files /dev/null and b/public/assets/arena/hex_sand_roadE_detail.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadF.gltf.glb b/public/assets/arena/hex_sand_roadF.gltf.glb new file mode 100644 index 0000000..86b288a Binary files /dev/null and b/public/assets/arena/hex_sand_roadF.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadF_detail.gltf.glb b/public/assets/arena/hex_sand_roadF_detail.gltf.glb new file mode 100644 index 0000000..2200410 Binary files /dev/null and b/public/assets/arena/hex_sand_roadF_detail.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadG.gltf.glb b/public/assets/arena/hex_sand_roadG.gltf.glb new file mode 100644 index 0000000..7be5c7c Binary files /dev/null and b/public/assets/arena/hex_sand_roadG.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadG_detail.gltf.glb b/public/assets/arena/hex_sand_roadG_detail.gltf.glb new file mode 100644 index 0000000..210cff0 Binary files /dev/null and b/public/assets/arena/hex_sand_roadG_detail.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadH.gltf.glb b/public/assets/arena/hex_sand_roadH.gltf.glb new file mode 100644 index 0000000..988391f Binary files /dev/null and b/public/assets/arena/hex_sand_roadH.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadH_detail.gltf.glb b/public/assets/arena/hex_sand_roadH_detail.gltf.glb new file mode 100644 index 0000000..9035841 Binary files /dev/null and b/public/assets/arena/hex_sand_roadH_detail.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadI.gltf.glb b/public/assets/arena/hex_sand_roadI.gltf.glb new file mode 100644 index 0000000..015d4b2 Binary files /dev/null and b/public/assets/arena/hex_sand_roadI.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadI_detail.gltf.glb b/public/assets/arena/hex_sand_roadI_detail.gltf.glb new file mode 100644 index 0000000..38d68ab Binary files /dev/null and b/public/assets/arena/hex_sand_roadI_detail.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadJ.gltf.glb b/public/assets/arena/hex_sand_roadJ.gltf.glb new file mode 100644 index 0000000..7efd274 Binary files /dev/null and b/public/assets/arena/hex_sand_roadJ.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadJ_detail.gltf.glb b/public/assets/arena/hex_sand_roadJ_detail.gltf.glb new file mode 100644 index 0000000..03b88fd Binary files /dev/null and b/public/assets/arena/hex_sand_roadJ_detail.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadK.gltf.glb b/public/assets/arena/hex_sand_roadK.gltf.glb new file mode 100644 index 0000000..39f8c22 Binary files /dev/null and b/public/assets/arena/hex_sand_roadK.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadK_detail.gltf.glb b/public/assets/arena/hex_sand_roadK_detail.gltf.glb new file mode 100644 index 0000000..834861a Binary files /dev/null and b/public/assets/arena/hex_sand_roadK_detail.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadL.gltf.glb b/public/assets/arena/hex_sand_roadL.gltf.glb new file mode 100644 index 0000000..832b7ec Binary files /dev/null and b/public/assets/arena/hex_sand_roadL.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadL_detail.gltf.glb b/public/assets/arena/hex_sand_roadL_detail.gltf.glb new file mode 100644 index 0000000..0ca1090 Binary files /dev/null and b/public/assets/arena/hex_sand_roadL_detail.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadM.gltf.glb b/public/assets/arena/hex_sand_roadM.gltf.glb new file mode 100644 index 0000000..6cfb232 Binary files /dev/null and b/public/assets/arena/hex_sand_roadM.gltf.glb differ diff --git a/public/assets/arena/hex_sand_roadM_detail.gltf.glb b/public/assets/arena/hex_sand_roadM_detail.gltf.glb new file mode 100644 index 0000000..9b7e627 Binary files /dev/null and b/public/assets/arena/hex_sand_roadM_detail.gltf.glb differ diff --git a/public/assets/arena/hex_sand_transitionA.gltf.glb b/public/assets/arena/hex_sand_transitionA.gltf.glb new file mode 100644 index 0000000..b060fc5 Binary files /dev/null and b/public/assets/arena/hex_sand_transitionA.gltf.glb differ diff --git a/public/assets/arena/hex_sand_transitionB.gltf.glb b/public/assets/arena/hex_sand_transitionB.gltf.glb new file mode 100644 index 0000000..c3b9227 Binary files /dev/null and b/public/assets/arena/hex_sand_transitionB.gltf.glb differ diff --git a/public/assets/arena/hex_sand_waterA.gltf.glb b/public/assets/arena/hex_sand_waterA.gltf.glb new file mode 100644 index 0000000..2466552 Binary files /dev/null and b/public/assets/arena/hex_sand_waterA.gltf.glb differ diff --git a/public/assets/arena/hex_sand_waterA_detail.gltf.glb b/public/assets/arena/hex_sand_waterA_detail.gltf.glb new file mode 100644 index 0000000..620dcdb Binary files /dev/null and b/public/assets/arena/hex_sand_waterA_detail.gltf.glb differ diff --git a/public/assets/arena/hex_sand_waterA_empty.gltf.glb b/public/assets/arena/hex_sand_waterA_empty.gltf.glb new file mode 100644 index 0000000..0421f0d Binary files /dev/null and b/public/assets/arena/hex_sand_waterA_empty.gltf.glb differ diff --git a/public/assets/arena/hex_sand_waterB.gltf.glb b/public/assets/arena/hex_sand_waterB.gltf.glb new file mode 100644 index 0000000..fe72b05 Binary files /dev/null and b/public/assets/arena/hex_sand_waterB.gltf.glb differ diff --git a/public/assets/arena/hex_sand_waterB_detail.gltf.glb b/public/assets/arena/hex_sand_waterB_detail.gltf.glb new file mode 100644 index 0000000..da4855a Binary files /dev/null and b/public/assets/arena/hex_sand_waterB_detail.gltf.glb differ diff --git a/public/assets/arena/hex_sand_waterB_empty.gltf.glb b/public/assets/arena/hex_sand_waterB_empty.gltf.glb new file mode 100644 index 0000000..e0b5ce2 Binary files /dev/null and b/public/assets/arena/hex_sand_waterB_empty.gltf.glb differ diff --git a/public/assets/arena/hex_sand_waterC.gltf.glb b/public/assets/arena/hex_sand_waterC.gltf.glb new file mode 100644 index 0000000..d639c95 Binary files /dev/null and b/public/assets/arena/hex_sand_waterC.gltf.glb differ diff --git a/public/assets/arena/hex_sand_waterC_detail.gltf.glb b/public/assets/arena/hex_sand_waterC_detail.gltf.glb new file mode 100644 index 0000000..c5243cb Binary files /dev/null and b/public/assets/arena/hex_sand_waterC_detail.gltf.glb differ diff --git a/public/assets/arena/hex_sand_waterC_empty.gltf.glb b/public/assets/arena/hex_sand_waterC_empty.gltf.glb new file mode 100644 index 0000000..19ccefb Binary files /dev/null and b/public/assets/arena/hex_sand_waterC_empty.gltf.glb differ diff --git a/public/assets/arena/hex_sand_waterD.gltf.glb b/public/assets/arena/hex_sand_waterD.gltf.glb new file mode 100644 index 0000000..7097113 Binary files /dev/null and b/public/assets/arena/hex_sand_waterD.gltf.glb differ diff --git a/public/assets/arena/hex_sand_waterD_detail.gltf.glb b/public/assets/arena/hex_sand_waterD_detail.gltf.glb new file mode 100644 index 0000000..9e44717 Binary files /dev/null and b/public/assets/arena/hex_sand_waterD_detail.gltf.glb differ diff --git a/public/assets/arena/hex_sand_waterD_empty.gltf.glb b/public/assets/arena/hex_sand_waterD_empty.gltf.glb new file mode 100644 index 0000000..33f06b1 Binary files /dev/null and b/public/assets/arena/hex_sand_waterD_empty.gltf.glb differ diff --git a/public/assets/arena/hex_water.gltf.glb b/public/assets/arena/hex_water.gltf.glb new file mode 100644 index 0000000..36acea2 Binary files /dev/null and b/public/assets/arena/hex_water.gltf.glb differ diff --git a/public/assets/arena/hex_water_detail.gltf.glb b/public/assets/arena/hex_water_detail.gltf.glb new file mode 100644 index 0000000..be30de9 Binary files /dev/null and b/public/assets/arena/hex_water_detail.gltf.glb differ diff --git a/public/assets/images/background-1.jpg b/public/assets/images/background-1.jpg new file mode 100644 index 0000000..fe682ce Binary files /dev/null and b/public/assets/images/background-1.jpg differ diff --git a/scripts/reset-project.js b/scripts/reset-project.js deleted file mode 100755 index 51dff15..0000000 --- a/scripts/reset-project.js +++ /dev/null @@ -1,112 +0,0 @@ -#!/usr/bin/env node - -/** - * This script is used to reset the project to a blank state. - * It deletes or moves the /app, /components, /hooks, /scripts, and /constants directories to /app-example based on user input and creates a new /app directory with an index.tsx and _layout.tsx file. - * You can remove the `reset-project` script from package.json and safely delete this file after running it. - */ - -const fs = require("fs"); -const path = require("path"); -const readline = require("readline"); - -const root = process.cwd(); -const oldDirs = ["app", "components", "hooks", "constants", "scripts"]; -const exampleDir = "app-example"; -const newAppDir = "app"; -const exampleDirPath = path.join(root, exampleDir); - -const indexContent = `import { Text, View } from "react-native"; - -export default function Index() { - return ( - - Edit app/index.tsx to edit this screen. - - ); -} -`; - -const layoutContent = `import { Stack } from "expo-router"; - -export default function RootLayout() { - return ; -} -`; - -const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout, -}); - -const moveDirectories = async (userInput) => { - try { - if (userInput === "y") { - // Create the app-example directory - await fs.promises.mkdir(exampleDirPath, { recursive: true }); - console.log(`šŸ“ /${exampleDir} directory created.`); - } - - // Move old directories to new app-example directory or delete them - for (const dir of oldDirs) { - const oldDirPath = path.join(root, dir); - if (fs.existsSync(oldDirPath)) { - if (userInput === "y") { - const newDirPath = path.join(root, exampleDir, dir); - await fs.promises.rename(oldDirPath, newDirPath); - console.log(`āž”ļø /${dir} moved to /${exampleDir}/${dir}.`); - } else { - await fs.promises.rm(oldDirPath, { recursive: true, force: true }); - console.log(`āŒ /${dir} deleted.`); - } - } else { - console.log(`āž”ļø /${dir} does not exist, skipping.`); - } - } - - // Create new /app directory - const newAppDirPath = path.join(root, newAppDir); - await fs.promises.mkdir(newAppDirPath, { recursive: true }); - console.log("\nšŸ“ New /app directory created."); - - // Create index.tsx - const indexPath = path.join(newAppDirPath, "index.tsx"); - await fs.promises.writeFile(indexPath, indexContent); - console.log("šŸ“„ app/index.tsx created."); - - // Create _layout.tsx - const layoutPath = path.join(newAppDirPath, "_layout.tsx"); - await fs.promises.writeFile(layoutPath, layoutContent); - console.log("šŸ“„ app/_layout.tsx created."); - - console.log("\nāœ… Project reset complete. Next steps:"); - console.log( - `1. Run \`npx expo start\` to start a development server.\n2. Edit app/index.tsx to edit the main screen.${ - userInput === "y" - ? `\n3. Delete the /${exampleDir} directory when you're done referencing it.` - : "" - }` - ); - } catch (error) { - console.error(`āŒ Error during script execution: ${error.message}`); - } -}; - -rl.question( - "Do you want to move existing files to /app-example instead of deleting them? (Y/n): ", - (answer) => { - const userInput = answer.trim().toLowerCase() || "y"; - if (userInput === "y" || userInput === "n") { - moveDirectories(userInput).finally(() => rl.close()); - } else { - console.log("āŒ Invalid input. Please enter 'Y' or 'N'."); - rl.close(); - } - } -);