Map modal - need to implement rooms and add hallways to map UI
parent
a61237305e
commit
ced467289b
@ -0,0 +1,85 @@
|
||||
import React from 'react'
|
||||
import ReactMarkdown from 'react-markdown'
|
||||
import useGameState from '../../hooks/useGameState'
|
||||
|
||||
import map from './map.png'
|
||||
import {ReactComponent as PlayerIcon} from './mapPerson.svg'
|
||||
import styles from './Map.module.css'
|
||||
import useSharedState from '../../hooks/useSharedState'
|
||||
|
||||
export default function Map() {
|
||||
const gameState = useGameState()
|
||||
|
||||
const playerLocation = gameState?.player?.location
|
||||
const isOnLower = ['engine', 'docking', 'mainframe', 'stairlower'].includes(playerLocation)
|
||||
|
||||
const [currentFloor, setFloor] = useSharedState('mapFloor', isOnLower ? 'lower' : 'upper')
|
||||
const [roomName, setRoom] = useSharedState('mapRoom')
|
||||
|
||||
const currentRoom = (roomName && gameState.rooms.get(roomName)) || null
|
||||
|
||||
return (
|
||||
<div className={styles.map}>
|
||||
<img alt="" src={map}/>
|
||||
|
||||
<Floor name="upper" currentSelected={currentFloor} setCurrentFloor={setFloor}>
|
||||
<Room name="bridge" top={15} left={25} width={20} height={15} currentSelected={roomName} setSelected={setRoom}/>
|
||||
<Room name="commons" top={35} left={25} width={20} height={30} currentSelected={roomName} setSelected={setRoom}/>
|
||||
<Room name="cabin" top={35} left={50} width={10} height={20} currentSelected={roomName} setSelected={setRoom}/>
|
||||
<Room name="bathroom" top={60} left={50} width={10} height={10} currentSelected={roomName} setSelected={setRoom}/>
|
||||
<Room name="medbay" top={35} left={10} width={10} height={20} currentSelected={roomName} setSelected={setRoom}/>
|
||||
<Room name="stairupper" top={60} left={10} width={10} height={10} currentSelected={roomName} setSelected={setRoom}/>
|
||||
</Floor>
|
||||
|
||||
<Floor name="lower" currentSelected={currentFloor} setCurrentFloor={setFloor}>
|
||||
<Room name="engine" top={35} left={25} width={20} height={30} currentSelected={roomName} setSelected={setRoom}/>
|
||||
<Room name="docking" top={35} left={50} width={10} height={35} currentSelected={roomName} setSelected={setRoom}/>
|
||||
<Room name="mainframe" top={35} left={10} width={10} height={20} currentSelected={roomName} setSelected={setRoom}/>
|
||||
<Room name="stairlower" top={60} left={10} width={10} height={10} currentSelected={roomName} setSelected={setRoom}/>
|
||||
</Floor>
|
||||
|
||||
<div className={styles.floorSelector}>
|
||||
<button className={currentFloor === 'upper' && styles.selectedFloor} onClick={()=>setFloor('upper')}>Upper</button>
|
||||
<button className={currentFloor === 'lower' && styles.selectedFloor} onClick={()=>setFloor('lower')}>Lower</button>
|
||||
</div>
|
||||
|
||||
<div className={styles.description}>
|
||||
{currentRoom ? (
|
||||
<>
|
||||
<h3>{currentRoom.printableName}</h3>
|
||||
<ReactMarkdown>{currentRoom.description}</ReactMarkdown>
|
||||
</>
|
||||
) : (
|
||||
<h3 style={{marginTop: '45%', textAlign: 'center'}}>Select a Room</h3>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function Floor({name, currentSelected, children}) {
|
||||
// Do not render if not selected
|
||||
if(name !== currentSelected)
|
||||
return null;
|
||||
|
||||
return (
|
||||
<div className={styles.rooms}>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function Room({name, top, left, width, height, setSelected, currentSelected}) {
|
||||
const gameState = useGameState()
|
||||
const current = gameState?.player?.location === name
|
||||
|
||||
return (
|
||||
<div
|
||||
onClick={() => setSelected(name)}
|
||||
className={styles.room + (currentSelected === name ? ' ' + styles.selectedRoom : '')}
|
||||
style={{top, left, width, height}}
|
||||
>
|
||||
{current && <PlayerIcon/>}
|
||||
</div>
|
||||
)
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
.map {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.map img {
|
||||
position: absolute;
|
||||
top: 64px;
|
||||
left: 32px;
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
.rooms {
|
||||
position: absolute;
|
||||
top: 70px;
|
||||
left: 85px;
|
||||
width: 70px;
|
||||
height: 105px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.room {
|
||||
position: absolute;
|
||||
border: solid 1px white;
|
||||
background: rgba(0,0,0,.6);
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.room svg {
|
||||
display: block;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.selectedRoom {
|
||||
background: rgba(255,255,255,.2);
|
||||
}
|
||||
|
||||
.floorSelector {
|
||||
position: absolute;
|
||||
top: 200px;
|
||||
left: 58px
|
||||
}
|
||||
|
||||
.floorSelector button {
|
||||
display: inline-block;
|
||||
margin: 10px;
|
||||
background: transparent;
|
||||
color: white;
|
||||
border: solid 1px white;
|
||||
padding: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.floorSelector .selectedFloor {
|
||||
color: black;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-left: 240px;
|
||||
max-height: 100%;
|
||||
padding: 10px 0;
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 65 KiB |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="white" width="18px" height="18px"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></svg>
|
After Width: | Height: | Size: 264 B |
Loading…
Reference in New Issue