forked from external-repos/LifeTrinket
Compare commits
8 Commits
two-headed
...
tailwind-w
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6e222995b6 | ||
|
|
808c55109d | ||
|
|
183fd9c079 | ||
|
|
ea2114e048 | ||
|
|
47251b6f7b | ||
|
|
77e8a79a35 | ||
|
|
bdbea848d3 | ||
|
|
3e2deca2f0 |
@@ -27,17 +27,22 @@
|
||||
"devDependencies": {
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@savvywombat/tailwindcss-grid-areas": "^3.1.0",
|
||||
"@svgr/cli": "^8.1.0",
|
||||
"@types/react": "^18.2.15",
|
||||
"@types/react-dom": "^18.2.7",
|
||||
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
||||
"@typescript-eslint/parser": "^6.0.0",
|
||||
"@vitejs/plugin-react-swc": "^3.3.2",
|
||||
"autoprefixer": "^10.4.16",
|
||||
"eslint": "^8.45.0",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.3",
|
||||
"firebase-tools": "^12.5.2",
|
||||
"install": "^0.13.0",
|
||||
"postcss": "^8.4.32",
|
||||
"prettier": "2.8.8",
|
||||
"tailwindcss": "^3.4.0",
|
||||
"typescript": "^5.0.2",
|
||||
"vite": "^4.4.5"
|
||||
}
|
||||
|
||||
6
postcss.config.js
Normal file
6
postcss.config.js
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
@@ -14,6 +14,9 @@ const ExtraCounterContainer = styled.div`
|
||||
`;
|
||||
|
||||
export const StyledExtraCounterButton = styled.button`
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
flex-grow: 1;
|
||||
border: none;
|
||||
|
||||
@@ -49,7 +49,6 @@ export const ExtraCountersGrid = styled.div<{ $rotation: Rotation }>`
|
||||
height: 100%;
|
||||
width: auto;
|
||||
bottom: auto;
|
||||
right: -6px;
|
||||
`;
|
||||
}
|
||||
}}
|
||||
|
||||
@@ -79,7 +79,7 @@ const fadeOut = keyframes`
|
||||
}
|
||||
`;
|
||||
|
||||
export const RecentDifference = styled.span`
|
||||
export const RecentDifference = styled.span<{ $rotation: Rotation }>`
|
||||
position: absolute;
|
||||
top: 40%;
|
||||
left: 50%;
|
||||
@@ -95,6 +95,20 @@ export const RecentDifference = styled.span`
|
||||
font-size: 8vmin;
|
||||
color: #333333;
|
||||
animation: ${fadeOut} 3s 1s ease-out forwards;
|
||||
|
||||
${(props) => {
|
||||
if (
|
||||
props.$rotation === Rotation.SideFlipped ||
|
||||
props.$rotation === Rotation.Side
|
||||
) {
|
||||
return css`
|
||||
top: 27%;
|
||||
left: 30%;
|
||||
transform: translate(-50%, -50%);
|
||||
rotate: 270deg;
|
||||
`;
|
||||
}
|
||||
}}
|
||||
`;
|
||||
|
||||
type HealthProps = {
|
||||
@@ -137,6 +151,7 @@ const Health = ({
|
||||
const textContainer = textContainerRef.current;
|
||||
const resizeObserver = new ResizeObserver(() => {
|
||||
const calcFontSize = calculateFontSize(textContainer);
|
||||
console.log(calcFontSize);
|
||||
setFontSize(calcFontSize);
|
||||
});
|
||||
|
||||
@@ -166,9 +181,9 @@ const Health = ({
|
||||
|
||||
const minRatio = Math.min(widthRatio, heightRatio);
|
||||
|
||||
const heightIsLarger = heightRatio > widthRatio;
|
||||
const heightIs40PercentSmaller = heightRatio > widthRatio * 0.6;
|
||||
|
||||
const scaleFactor = heightIsLarger ? 0.8 : 1;
|
||||
const scaleFactor = heightIs40PercentSmaller ? 0.8 : 1;
|
||||
|
||||
return minRatio * scaleFactor * 1;
|
||||
};
|
||||
@@ -195,7 +210,10 @@ const Health = ({
|
||||
{player.lifeTotal}
|
||||
</OutlinedText>
|
||||
{recentDifference !== 0 && (
|
||||
<RecentDifference key={differenceKey}>
|
||||
<RecentDifference
|
||||
key={differenceKey}
|
||||
$rotation={player.settings.rotation}
|
||||
>
|
||||
{recentDifference > 0 ? '+' : ''}
|
||||
{recentDifference}
|
||||
</RecentDifference>
|
||||
|
||||
@@ -6,7 +6,7 @@ import { LoseGameButton } from '../Buttons/LoseButton';
|
||||
import SettingsButton from '../Buttons/SettingsButton';
|
||||
import CommanderDamageBar from '../Counters/CommanderDamageBar';
|
||||
import ExtraCountersBar from '../Counters/ExtraCountersBar';
|
||||
import PlayerMenu from '../PlayerMenu/PlayerMenu';
|
||||
import PlayerMenu from '../Player/PlayerMenu';
|
||||
import Health from './Health';
|
||||
import { usePlayers } from '../../Hooks/usePlayers';
|
||||
import { useGlobalSettings } from '../../Hooks/useGlobalSettings';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import styled from 'styled-components';
|
||||
import Play from './Views/Play';
|
||||
import StartMenu from './Views/StartMenu/StartMenu';
|
||||
import { useGlobalSettings } from '../Hooks/useGlobalSettings';
|
||||
import StartMenu from './Views/StartMenu/StartMenu';
|
||||
import { Play } from './Views/Play';
|
||||
|
||||
const StartWrapper = styled.div`
|
||||
max-width: fit-content;
|
||||
@@ -35,7 +35,7 @@ export const LifeTrinket = () => {
|
||||
<>
|
||||
{showPlay && initialGameSettings ? (
|
||||
<PlayWrapper>
|
||||
<Play gridAreas={initialGameSettings?.gridAreas} />
|
||||
<Play />
|
||||
<EmergencyResetButton onClick={goToStart}>
|
||||
<p>If you can see this, something is wrong.</p>
|
||||
<p>Press screen to go to start.</p>
|
||||
|
||||
47
src/Components/Player/Player.tsx
Normal file
47
src/Components/Player/Player.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import LifeCounter from '../LifeCounter/LifeCounter';
|
||||
import { Player as PlayerType } from '../../Types/Player';
|
||||
|
||||
const getGridArea = (player: PlayerType) => {
|
||||
switch (player.index) {
|
||||
case 0:
|
||||
return 'grid-in-player0';
|
||||
case 1:
|
||||
return 'grid-in-player1';
|
||||
case 2:
|
||||
return 'grid-in-player2';
|
||||
case 3:
|
||||
return 'grid-in-player3';
|
||||
case 4:
|
||||
return 'grid-in-player4';
|
||||
case 5:
|
||||
return 'grid-in-player5';
|
||||
default:
|
||||
throw new Error('Invalid player index');
|
||||
}
|
||||
};
|
||||
|
||||
export const Player = (players: PlayerType[], gridClasses: string) => {
|
||||
return (
|
||||
<div className="w-full h-full bg-black">
|
||||
<div className={`grid w-full h-full gap-1 box-border ${gridClasses} `}>
|
||||
{players.map((player) => {
|
||||
const gridArea = getGridArea(player);
|
||||
|
||||
return (
|
||||
<div
|
||||
key={player.index}
|
||||
className={`flex justify-center items-center align-middle ${gridArea}`}
|
||||
>
|
||||
<LifeCounter
|
||||
player={player}
|
||||
opponents={players.filter(
|
||||
(opponent) => opponent.index !== player.index
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,5 +1,8 @@
|
||||
import styled from 'styled-components';
|
||||
import Counters from '../Counters/Counters';
|
||||
import { useGlobalSettings } from '../../Hooks/useGlobalSettings';
|
||||
import { usePlayers } from '../../Hooks/usePlayers';
|
||||
import { Orientation } from '../../Types/Settings';
|
||||
import { Player } from '../Player/Player';
|
||||
|
||||
const MainWrapper = styled.div`
|
||||
width: 100vmax;
|
||||
@@ -9,16 +12,62 @@ const MainWrapper = styled.div`
|
||||
overflow: hidden;
|
||||
`;
|
||||
|
||||
type PlayProps = {
|
||||
gridAreas: string;
|
||||
};
|
||||
export const Play = () => {
|
||||
const { players } = usePlayers();
|
||||
const { initialGameSettings } = useGlobalSettings();
|
||||
|
||||
const Play = ({ gridAreas }: PlayProps) => {
|
||||
return (
|
||||
<MainWrapper>
|
||||
<Counters gridAreas={gridAreas} />
|
||||
</MainWrapper>
|
||||
);
|
||||
};
|
||||
let Layout: JSX.Element;
|
||||
switch (players.length) {
|
||||
case 1:
|
||||
if (initialGameSettings?.orientation === Orientation.Portrait) {
|
||||
Layout = Player(players, 'grid-areas-onePlayerPortrait');
|
||||
}
|
||||
Layout = Player(players, 'grid-areas-onePlayerLandscape');
|
||||
break;
|
||||
case 2:
|
||||
switch (initialGameSettings?.orientation) {
|
||||
case Orientation.Portrait:
|
||||
Layout = Player(players, 'grid-areas-twoPlayersOppositePortrait');
|
||||
break;
|
||||
default:
|
||||
case Orientation.Landscape:
|
||||
Layout = Player(players, 'grid-areas-twoPlayersSameSideLandscape');
|
||||
break;
|
||||
case Orientation.OppositeLandscape:
|
||||
Layout = Player(players, 'grid-areas-twoPlayersOppositeLandscape');
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (initialGameSettings?.orientation === Orientation.Portrait) {
|
||||
Layout = Player(players, 'grid-areas-threePlayersSide');
|
||||
break;
|
||||
}
|
||||
Layout = Player(players, 'grid-areas-threePlayers');
|
||||
break;
|
||||
default:
|
||||
case 4:
|
||||
if (initialGameSettings?.orientation === Orientation.Portrait) {
|
||||
Layout = Player(players, 'grid-areas-fourPlayerPortrait');
|
||||
break;
|
||||
}
|
||||
Layout = Player(players, 'grid-areas-fourPlayer');
|
||||
break;
|
||||
case 5:
|
||||
if (initialGameSettings?.orientation === Orientation.Portrait) {
|
||||
Layout = Player(players, 'grid-areas-fivePlayersSide');
|
||||
break;
|
||||
}
|
||||
Layout = Player(players, 'grid-areas-fivePlayers');
|
||||
break;
|
||||
case 6:
|
||||
if (initialGameSettings?.orientation === Orientation.Portrait) {
|
||||
Layout = Player(players, 'grid-areas-sixPlayersSide');
|
||||
break;
|
||||
}
|
||||
Layout = Player(players, 'grid-areas-sixPlayers');
|
||||
break;
|
||||
}
|
||||
|
||||
export default Play;
|
||||
return <MainWrapper>{Layout}</MainWrapper>;
|
||||
};
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
import { FormControlLabel, Radio, RadioGroup } from '@mui/material';
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { GridTemplateAreas } from '../../../Data/GridTemplateAreas';
|
||||
import { FormControlLabel, Radio, RadioGroup } from '@mui/material';
|
||||
import { theme } from '../../../Data/theme';
|
||||
import {
|
||||
OnePlayerPortrait,
|
||||
TwoPlayersOppositeLandscape,
|
||||
TwoPlayersOppositePortrait,
|
||||
ThreePlayers,
|
||||
ThreePlayersSide,
|
||||
FivePlayers,
|
||||
FourPlayers,
|
||||
FourPlayersSide,
|
||||
FivePlayers,
|
||||
OnePlayerPortrait,
|
||||
SixPlayers,
|
||||
ThreePlayers,
|
||||
ThreePlayersSide,
|
||||
TwoPlayersOppositeLandscape,
|
||||
TwoPlayersOppositePortrait,
|
||||
TwoPlayersSameSide,
|
||||
} from '../../../Icons/generated/Layouts';
|
||||
|
||||
import OnePlayerLandscape from '../../../Icons/generated/Layouts/OnePlayerLandscape';
|
||||
import { Orientation } from '../../../Types/Settings';
|
||||
|
||||
const LayoutWrapper = styled.div`
|
||||
flex-direction: row;
|
||||
@@ -25,13 +26,13 @@ const LayoutWrapper = styled.div`
|
||||
|
||||
type LayoutOptionsProps = {
|
||||
numberOfPlayers: number;
|
||||
gridAreas: GridTemplateAreas;
|
||||
onChange: (gridAreas: GridTemplateAreas) => void;
|
||||
selectedOrientation: Orientation;
|
||||
onChange: (orientation: Orientation) => void;
|
||||
};
|
||||
|
||||
const LayoutOptions: React.FC<LayoutOptionsProps> = ({
|
||||
export const LayoutOptions: React.FC<LayoutOptionsProps> = ({
|
||||
numberOfPlayers,
|
||||
gridAreas,
|
||||
selectedOrientation,
|
||||
onChange,
|
||||
}) => {
|
||||
const iconHeight = '30vmin';
|
||||
@@ -43,7 +44,7 @@ const LayoutOptions: React.FC<LayoutOptionsProps> = ({
|
||||
return (
|
||||
<>
|
||||
<FormControlLabel
|
||||
value={GridTemplateAreas.OnePlayerLandscape}
|
||||
value={Orientation.Landscape}
|
||||
control={
|
||||
<Radio
|
||||
icon={
|
||||
@@ -66,7 +67,7 @@ const LayoutOptions: React.FC<LayoutOptionsProps> = ({
|
||||
label=""
|
||||
/>
|
||||
<FormControlLabel
|
||||
value={GridTemplateAreas.OnePlayerPortrait}
|
||||
value={Orientation.Portrait}
|
||||
control={
|
||||
<Radio
|
||||
icon={
|
||||
@@ -94,7 +95,7 @@ const LayoutOptions: React.FC<LayoutOptionsProps> = ({
|
||||
return (
|
||||
<>
|
||||
<FormControlLabel
|
||||
value={GridTemplateAreas.TwoPlayersSameSide}
|
||||
value={Orientation.Landscape}
|
||||
control={
|
||||
<Radio
|
||||
icon={
|
||||
@@ -117,7 +118,7 @@ const LayoutOptions: React.FC<LayoutOptionsProps> = ({
|
||||
label=""
|
||||
/>
|
||||
<FormControlLabel
|
||||
value={GridTemplateAreas.TwoPlayersOppositePortrait}
|
||||
value={Orientation.Portrait}
|
||||
control={
|
||||
<Radio
|
||||
icon={
|
||||
@@ -140,7 +141,7 @@ const LayoutOptions: React.FC<LayoutOptionsProps> = ({
|
||||
label=""
|
||||
/>
|
||||
<FormControlLabel
|
||||
value={GridTemplateAreas.TwoPlayersOppositeLandscape}
|
||||
value={Orientation.OppositeLandscape}
|
||||
control={
|
||||
<Radio
|
||||
icon={
|
||||
@@ -168,7 +169,7 @@ const LayoutOptions: React.FC<LayoutOptionsProps> = ({
|
||||
return (
|
||||
<>
|
||||
<FormControlLabel
|
||||
value={GridTemplateAreas.ThreePlayers}
|
||||
value={Orientation.Landscape}
|
||||
control={
|
||||
<Radio
|
||||
icon={
|
||||
@@ -191,7 +192,7 @@ const LayoutOptions: React.FC<LayoutOptionsProps> = ({
|
||||
label=""
|
||||
/>
|
||||
<FormControlLabel
|
||||
value={GridTemplateAreas.ThreePlayersSide}
|
||||
value={Orientation.Portrait}
|
||||
control={
|
||||
<Radio
|
||||
icon={
|
||||
@@ -220,7 +221,7 @@ const LayoutOptions: React.FC<LayoutOptionsProps> = ({
|
||||
return (
|
||||
<>
|
||||
<FormControlLabel
|
||||
value={GridTemplateAreas.FourPlayers}
|
||||
value={Orientation.Landscape}
|
||||
control={
|
||||
<Radio
|
||||
icon={
|
||||
@@ -243,7 +244,7 @@ const LayoutOptions: React.FC<LayoutOptionsProps> = ({
|
||||
label=""
|
||||
/>
|
||||
<FormControlLabel
|
||||
value={GridTemplateAreas.FourPlayersSide}
|
||||
value={Orientation.Portrait}
|
||||
control={
|
||||
<Radio
|
||||
icon={
|
||||
@@ -272,7 +273,7 @@ const LayoutOptions: React.FC<LayoutOptionsProps> = ({
|
||||
return (
|
||||
<>
|
||||
<FormControlLabel
|
||||
value={GridTemplateAreas.FivePlayers}
|
||||
value={Orientation.Landscape}
|
||||
control={
|
||||
<Radio
|
||||
icon={
|
||||
@@ -324,7 +325,7 @@ const LayoutOptions: React.FC<LayoutOptionsProps> = ({
|
||||
return (
|
||||
<>
|
||||
<FormControlLabel
|
||||
value={GridTemplateAreas.SixPlayers}
|
||||
value={Orientation.Landscape}
|
||||
control={
|
||||
<Radio
|
||||
icon={
|
||||
@@ -382,9 +383,9 @@ const LayoutOptions: React.FC<LayoutOptionsProps> = ({
|
||||
<RadioGroup
|
||||
row
|
||||
onChange={(_e, value) => {
|
||||
onChange(value as GridTemplateAreas);
|
||||
onChange(value as Orientation);
|
||||
}}
|
||||
value={gridAreas}
|
||||
value={selectedOrientation}
|
||||
style={{ justifyContent: 'center' }}
|
||||
>
|
||||
{renderLayoutOptions()}
|
||||
@@ -392,5 +393,3 @@ const LayoutOptions: React.FC<LayoutOptionsProps> = ({
|
||||
</LayoutWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default LayoutOptions;
|
||||
|
||||
@@ -2,20 +2,19 @@ import { Button, FormControl, FormLabel, Switch } from '@mui/material';
|
||||
import Slider from '@mui/material/Slider';
|
||||
import { useEffect, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { GridTemplateAreas } from '../../../Data/GridTemplateAreas';
|
||||
import { createInitialPlayers } from '../../../Data/getInitialPlayers';
|
||||
import { theme } from '../../../Data/theme';
|
||||
import { useAnalytics } from '../../../Hooks/useAnalytics';
|
||||
import { useGlobalSettings } from '../../../Hooks/useGlobalSettings';
|
||||
import { usePlayers } from '../../../Hooks/usePlayers';
|
||||
import { Cog, Info } from '../../../Icons/generated';
|
||||
import { InitialGameSettings, Orientation } from '../../../Types/Settings';
|
||||
import { InfoModal } from '../../Misc/InfoModal';
|
||||
import { SettingsModal } from '../../Misc/SettingsModal';
|
||||
import { Spacer } from '../../Misc/Spacer';
|
||||
import { SupportMe } from '../../Misc/SupportMe';
|
||||
import { H1, Paragraph } from '../../Misc/TextComponents';
|
||||
import LayoutOptions from './LayoutOptions';
|
||||
import { Spacer } from '../../Misc/Spacer';
|
||||
import { usePlayers } from '../../../Hooks/usePlayers';
|
||||
import { useGlobalSettings } from '../../../Hooks/useGlobalSettings';
|
||||
import { InitialGameSettings } from '../../../Types/Settings';
|
||||
import { SettingsModal } from '../../Misc/SettingsModal';
|
||||
import { LayoutOptions } from './LayoutOptions';
|
||||
|
||||
const MainWrapper = styled.div`
|
||||
width: 100dvw;
|
||||
@@ -118,7 +117,8 @@ const Start = () => {
|
||||
numberOfPlayers: 4,
|
||||
startingLifeTotal: 40,
|
||||
useCommanderDamage: true,
|
||||
gridAreas: GridTemplateAreas.FourPlayers,
|
||||
orientation: Orientation.Portrait,
|
||||
gameFormat: 'commander',
|
||||
}
|
||||
);
|
||||
|
||||
@@ -156,31 +156,9 @@ const Start = () => {
|
||||
return `${value}`;
|
||||
};
|
||||
|
||||
const getDefaultLayout = (numberOfPlayers: number) => {
|
||||
switch (numberOfPlayers) {
|
||||
case 1:
|
||||
return GridTemplateAreas.OnePlayerLandscape;
|
||||
case 2:
|
||||
return GridTemplateAreas.TwoPlayersSameSide;
|
||||
case 3:
|
||||
return GridTemplateAreas.ThreePlayers;
|
||||
case 4:
|
||||
return GridTemplateAreas.FourPlayers;
|
||||
case 5:
|
||||
return GridTemplateAreas.FivePlayers;
|
||||
case 6:
|
||||
return GridTemplateAreas.SixPlayers;
|
||||
default:
|
||||
return GridTemplateAreas.FourPlayers;
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const defaultLayout = getDefaultLayout(playerOptions.numberOfPlayers);
|
||||
|
||||
setPlayerOptions({
|
||||
...playerOptions,
|
||||
gridAreas: defaultLayout,
|
||||
});
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [playerOptions.numberOfPlayers]);
|
||||
@@ -228,6 +206,7 @@ const Start = () => {
|
||||
setPlayerOptions({
|
||||
...playerOptions,
|
||||
numberOfPlayers: value as number,
|
||||
orientation: Orientation.Landscape,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
@@ -246,6 +225,7 @@ const Start = () => {
|
||||
setPlayerOptions({
|
||||
...playerOptions,
|
||||
startingLifeTotal: value as number,
|
||||
orientation: Orientation.Landscape,
|
||||
})
|
||||
}
|
||||
/>
|
||||
@@ -267,6 +247,7 @@ const Start = () => {
|
||||
useCommanderDamage: value,
|
||||
numberOfPlayers: 4,
|
||||
startingLifeTotal: 40,
|
||||
orientation: Orientation.Landscape,
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -275,6 +256,7 @@ const Start = () => {
|
||||
useCommanderDamage: value,
|
||||
numberOfPlayers: 2,
|
||||
startingLifeTotal: 20,
|
||||
orientation: Orientation.Landscape,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
@@ -291,12 +273,28 @@ const Start = () => {
|
||||
</ToggleButtonsWrapper>
|
||||
|
||||
<FormLabel>Layout</FormLabel>
|
||||
<LayoutOptions
|
||||
{/* <LayoutOptions
|
||||
numberOfPlayers={playerOptions.numberOfPlayers}
|
||||
gridAreas={playerOptions.gridAreas}
|
||||
onChange={(gridAreas) =>
|
||||
setPlayerOptions({ ...playerOptions, gridAreas })
|
||||
setPlayerOptions({
|
||||
...playerOptions,
|
||||
gridAreas,
|
||||
//TODO fix the layout selection
|
||||
orientation: Orientation.Portrait,
|
||||
})
|
||||
}
|
||||
/> */}
|
||||
<LayoutOptions
|
||||
numberOfPlayers={playerOptions.numberOfPlayers}
|
||||
selectedOrientation={playerOptions.orientation}
|
||||
onChange={(orientation) => {
|
||||
console.log('orientation', { orientation });
|
||||
setPlayerOptions({
|
||||
...playerOptions,
|
||||
orientation,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
export enum GridTemplateAreas {
|
||||
OnePlayerLandscape = '"player0 player0"',
|
||||
OnePlayerPortrait = '"player0" "player0"',
|
||||
TwoPlayersOppositeLandscape = '"player0" "player1"',
|
||||
TwoPlayersOppositePortrait = '"player0 player1" "player0 player1"',
|
||||
TwoPlayersSameSide = '"player0 player1"',
|
||||
ThreePlayers = '"player0 player0" "player1 player2"',
|
||||
ThreePlayersSide = '"player0 player0 player0 player2" "player1 player1 player1 player2"',
|
||||
FourPlayers = '"player0 player1" "player2 player3"',
|
||||
FourPlayersSide = '"player0 player1 player1 player1 player3" "player0 player2 player2 player2 player3"',
|
||||
FivePlayers = '"player0 player0 player0 player1 player1 player1" "player2 player2 player3 player3 player4 player4"',
|
||||
FivePlayersSide = '"player0 player0 player0 player0 player0 player1 player1 player1 player1 player1 player2" "player3 player3 player3 player3 player3 player4 player4 player4 player4 player4 player2"',
|
||||
SixPlayers = '"player0 player1 player2" "player3 player4 player5"',
|
||||
SixPlayersSide = '"player0 player1 player1 player1 player1 player2 player2 player2 player2 player3" "player0 player4 player4 player4 player4 player5 player5 player5 player5 player3"',
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Player, Rotation } from '../Types/Player';
|
||||
import { InitialGameSettings } from '../Types/Settings';
|
||||
import { GridTemplateAreas } from './GridTemplateAreas';
|
||||
import { InitialGameSettings, Orientation } from '../Types/Settings';
|
||||
|
||||
const presetColors = [
|
||||
'#F06292', // Light Pink
|
||||
@@ -13,184 +12,182 @@ const presetColors = [
|
||||
'#FF8A80', // Coral
|
||||
];
|
||||
|
||||
const getRotation = (index: number, gridAreas: GridTemplateAreas): Rotation => {
|
||||
if (gridAreas === GridTemplateAreas.OnePlayerLandscape && index === 0) {
|
||||
return Rotation.Normal;
|
||||
const getOrientationRotations = (
|
||||
index: number,
|
||||
numberOfPlayers: number,
|
||||
orientation: Orientation
|
||||
): Rotation => {
|
||||
switch (numberOfPlayers) {
|
||||
case 1:
|
||||
switch (orientation) {
|
||||
default:
|
||||
case Orientation.Landscape:
|
||||
return Rotation.Normal;
|
||||
case Orientation.Portrait:
|
||||
return Rotation.Side;
|
||||
}
|
||||
case 2:
|
||||
switch (orientation) {
|
||||
default:
|
||||
case Orientation.Landscape:
|
||||
return Rotation.Normal;
|
||||
case Orientation.Portrait:
|
||||
switch (index) {
|
||||
case 0:
|
||||
return Rotation.SideFlipped;
|
||||
case 1:
|
||||
return Rotation.Side;
|
||||
default:
|
||||
return Rotation.Normal;
|
||||
}
|
||||
case Orientation.OppositeLandscape:
|
||||
switch (index) {
|
||||
case 0:
|
||||
return Rotation.Flipped;
|
||||
case 1:
|
||||
return Rotation.Normal;
|
||||
default:
|
||||
return Rotation.Normal;
|
||||
}
|
||||
}
|
||||
case 3:
|
||||
switch (orientation) {
|
||||
default:
|
||||
case Orientation.Landscape:
|
||||
switch (index) {
|
||||
case 0:
|
||||
return Rotation.Flipped;
|
||||
case 1:
|
||||
return Rotation.Normal;
|
||||
case 2:
|
||||
return Rotation.Normal;
|
||||
default:
|
||||
return Rotation.Normal;
|
||||
}
|
||||
case Orientation.Portrait:
|
||||
switch (index) {
|
||||
case 0:
|
||||
return Rotation.Flipped;
|
||||
case 1:
|
||||
return Rotation.Normal;
|
||||
case 2:
|
||||
return Rotation.Side;
|
||||
default:
|
||||
return Rotation.Normal;
|
||||
}
|
||||
}
|
||||
case 4:
|
||||
switch (orientation) {
|
||||
default:
|
||||
case Orientation.Landscape:
|
||||
switch (index) {
|
||||
case 0:
|
||||
return Rotation.Flipped;
|
||||
case 1:
|
||||
return Rotation.Flipped;
|
||||
case 2:
|
||||
return Rotation.Normal;
|
||||
case 3:
|
||||
return Rotation.Normal;
|
||||
default:
|
||||
return Rotation.Normal;
|
||||
}
|
||||
case Orientation.Portrait:
|
||||
switch (index) {
|
||||
case 0:
|
||||
return Rotation.SideFlipped;
|
||||
case 1:
|
||||
return Rotation.Flipped;
|
||||
case 2:
|
||||
return Rotation.Normal;
|
||||
case 3:
|
||||
return Rotation.Side;
|
||||
default:
|
||||
return Rotation.Normal;
|
||||
}
|
||||
}
|
||||
case 5:
|
||||
switch (orientation) {
|
||||
default:
|
||||
case Orientation.Landscape:
|
||||
switch (index) {
|
||||
case 0:
|
||||
return Rotation.Flipped;
|
||||
case 1:
|
||||
return Rotation.Flipped;
|
||||
case 2:
|
||||
return Rotation.Normal;
|
||||
case 3:
|
||||
return Rotation.Normal;
|
||||
case 4:
|
||||
return Rotation.Normal;
|
||||
default:
|
||||
return Rotation.Normal;
|
||||
}
|
||||
case Orientation.Portrait:
|
||||
switch (index) {
|
||||
case 0:
|
||||
return Rotation.Side;
|
||||
case 1:
|
||||
return Rotation.Side;
|
||||
case 2:
|
||||
return Rotation.SideFlipped;
|
||||
case 3:
|
||||
return Rotation.SideFlipped;
|
||||
case 4:
|
||||
return Rotation.SideFlipped;
|
||||
default:
|
||||
return Rotation.Normal;
|
||||
}
|
||||
}
|
||||
case 6:
|
||||
switch (orientation) {
|
||||
default:
|
||||
case Orientation.Landscape:
|
||||
switch (index) {
|
||||
case 0:
|
||||
return Rotation.Flipped;
|
||||
case 1:
|
||||
return Rotation.Flipped;
|
||||
case 2:
|
||||
return Rotation.Flipped;
|
||||
case 3:
|
||||
return Rotation.Normal;
|
||||
case 4:
|
||||
return Rotation.Normal;
|
||||
case 5:
|
||||
return Rotation.Normal;
|
||||
default:
|
||||
return Rotation.Normal;
|
||||
}
|
||||
case Orientation.Portrait:
|
||||
switch (index) {
|
||||
case 0:
|
||||
return Rotation.Side;
|
||||
case 1:
|
||||
return Rotation.Side;
|
||||
case 2:
|
||||
return Rotation.Side;
|
||||
case 3:
|
||||
return Rotation.SideFlipped;
|
||||
case 4:
|
||||
return Rotation.SideFlipped;
|
||||
case 5:
|
||||
return Rotation.SideFlipped;
|
||||
default:
|
||||
return Rotation.Normal;
|
||||
}
|
||||
}
|
||||
default:
|
||||
return Rotation.Normal;
|
||||
}
|
||||
|
||||
if (gridAreas === GridTemplateAreas.OnePlayerPortrait && index === 0) {
|
||||
return Rotation.Side;
|
||||
}
|
||||
|
||||
if (gridAreas === GridTemplateAreas.TwoPlayersOppositePortrait) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return Rotation.SideFlipped;
|
||||
case 1:
|
||||
return Rotation.Side;
|
||||
default:
|
||||
return Rotation.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
if (gridAreas === GridTemplateAreas.TwoPlayersOppositeLandscape) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return Rotation.Flipped;
|
||||
case 1:
|
||||
return Rotation.Normal;
|
||||
default:
|
||||
return Rotation.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
if (gridAreas === GridTemplateAreas.TwoPlayersSameSide) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return Rotation.Normal;
|
||||
case 1:
|
||||
return Rotation.Normal;
|
||||
default:
|
||||
return Rotation.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
if (gridAreas === GridTemplateAreas.ThreePlayers) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return Rotation.Flipped;
|
||||
case 1:
|
||||
return Rotation.Normal;
|
||||
case 2:
|
||||
return Rotation.Normal;
|
||||
default:
|
||||
return Rotation.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
if (gridAreas === GridTemplateAreas.ThreePlayersSide) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return Rotation.Flipped;
|
||||
case 1:
|
||||
return Rotation.Normal;
|
||||
case 2:
|
||||
return Rotation.Side;
|
||||
default:
|
||||
return Rotation.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
if (gridAreas === GridTemplateAreas.FourPlayers) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return Rotation.Flipped;
|
||||
case 1:
|
||||
return Rotation.Flipped;
|
||||
case 2:
|
||||
return Rotation.Normal;
|
||||
case 3:
|
||||
return Rotation.Normal;
|
||||
default:
|
||||
return Rotation.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
if (gridAreas === GridTemplateAreas.FourPlayersSide) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return Rotation.SideFlipped;
|
||||
case 1:
|
||||
return Rotation.Flipped;
|
||||
case 2:
|
||||
return Rotation.Normal;
|
||||
case 3:
|
||||
return Rotation.Side;
|
||||
default:
|
||||
return Rotation.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
if (gridAreas === GridTemplateAreas.FivePlayers) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return Rotation.Flipped;
|
||||
case 1:
|
||||
return Rotation.Flipped;
|
||||
case 2:
|
||||
return Rotation.Normal;
|
||||
case 3:
|
||||
return Rotation.Normal;
|
||||
case 4:
|
||||
return Rotation.Normal;
|
||||
default:
|
||||
return Rotation.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
if (gridAreas === GridTemplateAreas.FivePlayersSide) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return Rotation.Flipped;
|
||||
case 1:
|
||||
return Rotation.Flipped;
|
||||
case 2:
|
||||
return Rotation.Side;
|
||||
case 3:
|
||||
return Rotation.Normal;
|
||||
case 4:
|
||||
return Rotation.Normal;
|
||||
default:
|
||||
return Rotation.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
if (gridAreas === GridTemplateAreas.SixPlayers) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return Rotation.Flipped;
|
||||
case 1:
|
||||
return Rotation.Flipped;
|
||||
case 2:
|
||||
return Rotation.Flipped;
|
||||
case 3:
|
||||
return Rotation.Normal;
|
||||
case 4:
|
||||
return Rotation.Normal;
|
||||
case 5:
|
||||
return Rotation.Normal;
|
||||
default:
|
||||
return Rotation.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
if (gridAreas === GridTemplateAreas.SixPlayersSide) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return Rotation.SideFlipped;
|
||||
case 1:
|
||||
return Rotation.Flipped;
|
||||
case 2:
|
||||
return Rotation.Flipped;
|
||||
case 3:
|
||||
return Rotation.Side;
|
||||
case 4:
|
||||
return Rotation.Normal;
|
||||
case 5:
|
||||
return Rotation.Normal;
|
||||
default:
|
||||
return Rotation.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
return Rotation.Normal;
|
||||
};
|
||||
|
||||
export const createInitialPlayers = ({
|
||||
numberOfPlayers,
|
||||
startingLifeTotal,
|
||||
useCommanderDamage,
|
||||
gridAreas,
|
||||
orientation,
|
||||
}: InitialGameSettings): Player[] => {
|
||||
const players: Player[] = [];
|
||||
const availableColors = [...presetColors]; // Create a copy of the colors array
|
||||
@@ -213,7 +210,7 @@ export const createInitialPlayers = ({
|
||||
});
|
||||
}
|
||||
|
||||
const rotation = getRotation(i, gridAreas);
|
||||
const rotation = getOrientationRotations(i, numberOfPlayers, orientation);
|
||||
|
||||
const player: Player = {
|
||||
lifeTotal: startingLifeTotal,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { ReactNode, useEffect, useMemo, useState } from 'react';
|
||||
import { useWakeLock } from 'react-screen-wake-lock';
|
||||
import {
|
||||
GlobalSettingsContext,
|
||||
GlobalSettingsContextType,
|
||||
} from '../Contexts/GlobalSettingsContext';
|
||||
import { useWakeLock } from 'react-screen-wake-lock';
|
||||
import { useAnalytics } from '../Hooks/useAnalytics';
|
||||
import { InitialGameSettings, Settings } from '../Types/Settings';
|
||||
import { InitialGameSettings, Orientation, Settings } from '../Types/Settings';
|
||||
|
||||
export const GlobalSettingsProvider = ({
|
||||
children,
|
||||
@@ -22,11 +22,22 @@ export const GlobalSettingsProvider = ({
|
||||
savedShowPlay ? savedShowPlay === 'true' : false
|
||||
);
|
||||
|
||||
const [initialGameSettings, setInitialGameSettings] =
|
||||
const [initialGameSettings, setInitialSettings] =
|
||||
useState<InitialGameSettings | null>(
|
||||
savedGameSettings ? JSON.parse(savedGameSettings) : null
|
||||
);
|
||||
|
||||
const setInitialGameSettings = (initialGameSettings: InitialGameSettings) => {
|
||||
const defaultSettings: InitialGameSettings = {
|
||||
numberOfPlayers: 4,
|
||||
startingLifeTotal: 40,
|
||||
useCommanderDamage: true,
|
||||
orientation: Orientation.Landscape,
|
||||
gameFormat: 'commander',
|
||||
};
|
||||
setInitialSettings({ ...defaultSettings, ...initialGameSettings });
|
||||
};
|
||||
|
||||
const [settings, setSettings] = useState<Settings>(
|
||||
savedSettings
|
||||
? JSON.parse(savedSettings)
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { GridTemplateAreas } from '../Data/GridTemplateAreas';
|
||||
export enum Orientation {
|
||||
OppositeLandscape = 'opposite-landscape',
|
||||
Landscape = 'landscape',
|
||||
Portrait = 'portrait',
|
||||
}
|
||||
|
||||
export type Settings = {
|
||||
keepAwake: boolean;
|
||||
@@ -9,9 +13,9 @@ export type Settings = {
|
||||
export type InitialGameSettings = {
|
||||
startingLifeTotal: number;
|
||||
useCommanderDamage: boolean;
|
||||
gameFormat: GameFormat;
|
||||
gameFormat?: GameFormat;
|
||||
numberOfPlayers: number;
|
||||
gridAreas: GridTemplateAreas;
|
||||
orientation: Orientation;
|
||||
};
|
||||
|
||||
type GameFormat = 'commander' | 'standard' | 'two-headed-giant';
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
|
||||
41
tailwind.config.js
Normal file
41
tailwind.config.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import tailwindcssGridAreas from '@savvywombat/tailwindcss-grid-areas';
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
|
||||
theme: {
|
||||
extend: {
|
||||
gridTemplateAreas: {
|
||||
onePlayerLandscape: ['player0 player0'],
|
||||
onePlayerPortrait: ['player0', 'player0'],
|
||||
twoPlayersOppositeLandscape: ['player0', 'player1'],
|
||||
twoPlayersOppositePortrait: ['player0 player1', 'player0 player1'],
|
||||
twoPlayersSameSideLandscape: ['player0 player1'],
|
||||
threePlayers: ['player0 player0', 'player1 player2'],
|
||||
threePlayersSide: [
|
||||
'player0 player0 player0 player2',
|
||||
'player1 player1 player1 player2',
|
||||
],
|
||||
fourPlayerPortrait: [
|
||||
'player0 player1 player1 player1 player1 player3',
|
||||
'player0 player2 player2 player2 player2 player3',
|
||||
],
|
||||
fourPlayer: ['player0 player1', 'player2 player3'],
|
||||
fivePlayers: [
|
||||
'player0 player0 player0 player1 player1 player1',
|
||||
'player2 player2 player3 player3 player4 player4',
|
||||
],
|
||||
fivePlayersSide: [
|
||||
'player0 player0 player0 player0 player0 player1 player1 player1 player1 player1 player2',
|
||||
'player3 player3 player3 player3 player3 player4 player4 player4 player4 player4 player2',
|
||||
],
|
||||
sixPlayers: ['player0 player1 player2', 'player3 player4 player5'],
|
||||
sixPlayersSide: [
|
||||
'player0 player1 player1 player1 player1 player2 player2 player2 player2 player3',
|
||||
'player0 player4 player4 player4 player4 player5 player5 player5 player5 player3',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [tailwindcssGridAreas],
|
||||
};
|
||||
Reference in New Issue
Block a user