forked from external-repos/LifeTrinket
extra counters
This commit is contained in:
@@ -60,10 +60,10 @@ const initialPlayers: Player[] = [
|
||||
color: '#808080',
|
||||
settings: {
|
||||
useCommanderDamage: true,
|
||||
usePartner: true,
|
||||
useEnergy: true,
|
||||
useExperience: true,
|
||||
usePoison: true,
|
||||
usePartner: false,
|
||||
useEnergy: false,
|
||||
useExperience: false,
|
||||
usePoison: false,
|
||||
flipped: true,
|
||||
},
|
||||
},
|
||||
@@ -74,9 +74,9 @@ const initialPlayers: Player[] = [
|
||||
settings: {
|
||||
useCommanderDamage: true,
|
||||
usePartner: false,
|
||||
useEnergy: true,
|
||||
useExperience: true,
|
||||
usePoison: true,
|
||||
useEnergy: false,
|
||||
useExperience: false,
|
||||
usePoison: false,
|
||||
flipped: true,
|
||||
},
|
||||
},
|
||||
@@ -87,9 +87,9 @@ const initialPlayers: Player[] = [
|
||||
settings: {
|
||||
useCommanderDamage: true,
|
||||
usePartner: false,
|
||||
useEnergy: true,
|
||||
useExperience: true,
|
||||
usePoison: true,
|
||||
useEnergy: false,
|
||||
useExperience: false,
|
||||
usePoison: false,
|
||||
flipped: false,
|
||||
},
|
||||
},
|
||||
@@ -100,9 +100,9 @@ const initialPlayers: Player[] = [
|
||||
settings: {
|
||||
useCommanderDamage: true,
|
||||
usePartner: false,
|
||||
useEnergy: true,
|
||||
useExperience: true,
|
||||
usePoison: true,
|
||||
useEnergy: false,
|
||||
useExperience: false,
|
||||
usePoison: false,
|
||||
flipped: false,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useRef, useState } from 'react';
|
||||
import CommanderTaxIcon from '../../Icons/CommanderTaxIcon';
|
||||
import PoisonIcon from '../../Icons/PoisonIcon';
|
||||
import styled from 'styled-components';
|
||||
|
||||
export const StyledCommanderTaxButton = styled.button`
|
||||
|
||||
67
my-app/src/Components/Buttons/EnergyButton.tsx
Normal file
67
my-app/src/Components/Buttons/EnergyButton.tsx
Normal file
@@ -0,0 +1,67 @@
|
||||
import { useRef, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import EnergyIcon from '../../Icons/EnergyIcon';
|
||||
|
||||
export const StyledEnergyButton = styled.button`
|
||||
flex-grow: 1;
|
||||
border: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
user-select: none;
|
||||
`;
|
||||
|
||||
const EnergyButton = () => {
|
||||
const [energyCount, setEnergyCount] = useState(0);
|
||||
|
||||
const timeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
|
||||
const [timeoutFinished, setTimeoutFinished] = useState(false);
|
||||
const [hasPressedDown, setHasPressedDown] = useState(false);
|
||||
|
||||
const handleEnergyCountChange = (increment: number) => {
|
||||
setEnergyCount(energyCount + increment);
|
||||
};
|
||||
|
||||
const handleDownInput = () => {
|
||||
setTimeoutFinished(false);
|
||||
setHasPressedDown(true);
|
||||
timeoutRef.current = setTimeout(() => {
|
||||
setTimeoutFinished(true);
|
||||
handleEnergyCountChange(-1);
|
||||
}, 500);
|
||||
};
|
||||
|
||||
const handleUpInput = () => {
|
||||
if (!(hasPressedDown && !timeoutFinished)) {
|
||||
return;
|
||||
}
|
||||
clearTimeout(timeoutRef.current);
|
||||
handleEnergyCountChange(1);
|
||||
setHasPressedDown(false);
|
||||
};
|
||||
|
||||
const handleLeaveInput = () => {
|
||||
setTimeoutFinished(true);
|
||||
clearTimeout(timeoutRef.current);
|
||||
setHasPressedDown(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledEnergyButton
|
||||
onPointerDown={handleDownInput}
|
||||
onPointerUp={handleUpInput}
|
||||
onPointerLeave={handleLeaveInput}
|
||||
onContextMenu={(e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
||||
e.preventDefault();
|
||||
}}
|
||||
>
|
||||
<EnergyIcon
|
||||
size="8vh"
|
||||
text={energyCount ? energyCount : undefined}
|
||||
color=""
|
||||
/>
|
||||
</StyledEnergyButton>
|
||||
);
|
||||
};
|
||||
|
||||
export default EnergyButton;
|
||||
67
my-app/src/Components/Buttons/ExperienceButton.tsx
Normal file
67
my-app/src/Components/Buttons/ExperienceButton.tsx
Normal file
@@ -0,0 +1,67 @@
|
||||
import { useRef, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import ExperienceIcon from '../../Icons/ExperienceIcon';
|
||||
|
||||
export const StyledExperienceButton = styled.button`
|
||||
flex-grow: 1;
|
||||
border: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
user-select: none;
|
||||
`;
|
||||
|
||||
const ExperienceButton = () => {
|
||||
const [experienceCount, setExperienceCount] = useState(0);
|
||||
|
||||
const timeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
|
||||
const [timeoutFinished, setTimeoutFinished] = useState(false);
|
||||
const [hasPressedDown, setHasPressedDown] = useState(false);
|
||||
|
||||
const handleExperienceCountChange = (increment: number) => {
|
||||
setExperienceCount(experienceCount + increment);
|
||||
};
|
||||
|
||||
const handleDownInput = () => {
|
||||
setTimeoutFinished(false);
|
||||
setHasPressedDown(true);
|
||||
timeoutRef.current = setTimeout(() => {
|
||||
setTimeoutFinished(true);
|
||||
handleExperienceCountChange(-1);
|
||||
}, 500);
|
||||
};
|
||||
|
||||
const handleUpInput = () => {
|
||||
if (!(hasPressedDown && !timeoutFinished)) {
|
||||
return;
|
||||
}
|
||||
clearTimeout(timeoutRef.current);
|
||||
handleExperienceCountChange(1);
|
||||
setHasPressedDown(false);
|
||||
};
|
||||
|
||||
const handleLeaveInput = () => {
|
||||
setTimeoutFinished(true);
|
||||
clearTimeout(timeoutRef.current);
|
||||
setHasPressedDown(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledExperienceButton
|
||||
onPointerDown={handleDownInput}
|
||||
onPointerUp={handleUpInput}
|
||||
onPointerLeave={handleLeaveInput}
|
||||
onContextMenu={(e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
||||
e.preventDefault();
|
||||
}}
|
||||
>
|
||||
<ExperienceIcon
|
||||
size="8vh"
|
||||
text={experienceCount ? experienceCount : undefined}
|
||||
color=""
|
||||
/>
|
||||
</StyledExperienceButton>
|
||||
);
|
||||
};
|
||||
|
||||
export default ExperienceButton;
|
||||
68
my-app/src/Components/Buttons/PoisonButton.tsx
Normal file
68
my-app/src/Components/Buttons/PoisonButton.tsx
Normal file
@@ -0,0 +1,68 @@
|
||||
import { useRef, useState } from 'react';
|
||||
import CommanderTaxIcon from '../../Icons/CommanderTaxIcon';
|
||||
import PoisonIcon from '../../Icons/PoisonIcon';
|
||||
import styled from 'styled-components';
|
||||
|
||||
export const StyledPoisonButton = styled.button`
|
||||
flex-grow: 1;
|
||||
border: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
user-select: none;
|
||||
`;
|
||||
|
||||
const PoisonButton = () => {
|
||||
const [poisonCount, setPoisonCount] = useState(0);
|
||||
|
||||
const timeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
|
||||
const [timeoutFinished, setTimeoutFinished] = useState(false);
|
||||
const [hasPressedDown, setHasPressedDown] = useState(false);
|
||||
|
||||
const handlePoisonCountChange = (increment: number) => {
|
||||
setPoisonCount(poisonCount + increment);
|
||||
};
|
||||
|
||||
const handleDownInput = () => {
|
||||
setTimeoutFinished(false);
|
||||
setHasPressedDown(true);
|
||||
timeoutRef.current = setTimeout(() => {
|
||||
setTimeoutFinished(true);
|
||||
handlePoisonCountChange(-1);
|
||||
}, 500);
|
||||
};
|
||||
|
||||
const handleUpInput = () => {
|
||||
if (!(hasPressedDown && !timeoutFinished)) {
|
||||
return;
|
||||
}
|
||||
clearTimeout(timeoutRef.current);
|
||||
handlePoisonCountChange(1);
|
||||
setHasPressedDown(false);
|
||||
};
|
||||
|
||||
const handleLeaveInput = () => {
|
||||
setTimeoutFinished(true);
|
||||
clearTimeout(timeoutRef.current);
|
||||
setHasPressedDown(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledPoisonButton
|
||||
onPointerDown={handleDownInput}
|
||||
onPointerUp={handleUpInput}
|
||||
onPointerLeave={handleLeaveInput}
|
||||
onContextMenu={(e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
||||
e.preventDefault();
|
||||
}}
|
||||
>
|
||||
<PoisonIcon
|
||||
size="8vh"
|
||||
text={poisonCount ? poisonCount : undefined}
|
||||
color=""
|
||||
/>
|
||||
</StyledPoisonButton>
|
||||
);
|
||||
};
|
||||
|
||||
export default PoisonButton;
|
||||
@@ -8,6 +8,9 @@ import AddLifeButton from '../Buttons/AddLifeButton';
|
||||
import SubtractLifeButton from '../Buttons/SubtractLifeButton';
|
||||
import CommanderDamageBar from '../Buttons/CommanderDamageBar';
|
||||
import PlayerMenu from '../PlayerMenu/PlayerMenu';
|
||||
import PoisonButton from '../Buttons/PoisonButton';
|
||||
import EnergyButton from '../Buttons/EnergyButton';
|
||||
import ExperienceButton from '../Buttons/ExperienceButton';
|
||||
|
||||
type LifeCounterProps = {
|
||||
player: Player;
|
||||
@@ -60,6 +63,9 @@ const LifeCounter = ({
|
||||
{Boolean(
|
||||
player.settings.useCommanderDamage && player.settings.usePartner
|
||||
) && <PartnerCommanderTaxButton />}
|
||||
{player.settings.usePoison && <PoisonButton />}
|
||||
{player.settings.useEnergy && <EnergyButton />}
|
||||
{player.settings.useExperience && <ExperienceButton />}
|
||||
</S.ExtraCountersGrid>
|
||||
</S.LifeCounterContentContainer>
|
||||
|
||||
|
||||
@@ -49,6 +49,8 @@ const Settings = ({ player, onChange }: SettingsProps) => {
|
||||
checked={player.settings.useCommanderDamage}
|
||||
onChange={handleSettingsChange}
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
Use Partner Commander:
|
||||
<input
|
||||
type="checkbox"
|
||||
@@ -57,6 +59,42 @@ const Settings = ({ player, onChange }: SettingsProps) => {
|
||||
onChange={handleSettingsChange}
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
Show Poison Damage:
|
||||
<input
|
||||
type="checkbox"
|
||||
name="usePoison"
|
||||
checked={player.settings.usePoison}
|
||||
onChange={handleSettingsChange}
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
Show Energy:
|
||||
<input
|
||||
type="checkbox"
|
||||
name="useEnergy"
|
||||
checked={player.settings.useEnergy}
|
||||
onChange={handleSettingsChange}
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
Show Energy:
|
||||
<input
|
||||
type="checkbox"
|
||||
name="useEnergy"
|
||||
checked={player.settings.useEnergy}
|
||||
onChange={handleSettingsChange}
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
Show Experience:
|
||||
<input
|
||||
type="checkbox"
|
||||
name="useExperience"
|
||||
checked={player.settings.useExperience}
|
||||
onChange={handleSettingsChange}
|
||||
/>
|
||||
</label>
|
||||
<button
|
||||
onClick={() => {
|
||||
const updatedPlayer = {
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
type CommanderTaxIconProps = {
|
||||
size?: string;
|
||||
text?: number;
|
||||
};
|
||||
import { IconProps } from '../Types/Icon';
|
||||
|
||||
const CommanderTaxIcon = ({ size, text }: CommanderTaxIconProps) => {
|
||||
const CommanderTaxIcon = ({ size, text, color }: IconProps) => {
|
||||
return (
|
||||
<div style={{ position: 'relative', display: 'inline-block' }}>
|
||||
<svg
|
||||
@@ -12,9 +9,10 @@ const CommanderTaxIcon = ({ size, text }: CommanderTaxIconProps) => {
|
||||
viewBox="0 0 325 325"
|
||||
width={size || 'auto'}
|
||||
height={size || 'auto'}
|
||||
fill={color || 'black'}
|
||||
fillOpacity="0.5"
|
||||
>
|
||||
<title>CommanderTaxIcon</title>
|
||||
<style>{`.s0 { fill: #000000; fill-opacity: 0.5}`}</style>
|
||||
<path
|
||||
id="Lager 1"
|
||||
className="s0"
|
||||
|
||||
33
my-app/src/Icons/EnergyIcon.tsx
Normal file
33
my-app/src/Icons/EnergyIcon.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import { IconProps } from '../Types/Icon';
|
||||
|
||||
const EnergyIcon = ({ color, size, text }: IconProps) => {
|
||||
return (
|
||||
<div style={{ position: 'relative', display: 'inline-block' }}>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlSpace="preserve"
|
||||
viewBox="-30 0 500 500"
|
||||
width={size}
|
||||
height={size}
|
||||
fill={color || 'black'}
|
||||
fillOpacity="0.5"
|
||||
>
|
||||
<path d="M234.896 485.029c-2.669-2.858-3.364-8.205-5.593-11.658-2.645-4.099-5.889-7.763-8.697-11.742-3.68-5.217-7.881-10.06-11.601-15.262-6.362-8.897-13.587-16.63-21.201-24.468-18.683-19.234-38.196-37.019-60.371-52.199-34.356-23.52-70.771-44.106-109.819-58.761-2.709-1.017 0 0-17.614-8.609 3.325-5.34 23.831-34.407 28.638-42.12 8.028-12.881 13.8-26.964 19.782-40.866 7.616-17.7 14.438-35.819 19.899-54.296 6.976-23.604 12.835-47.549 17.354-71.747C86.931 86.566 94.42 29.508 98.888.314c39.192 11.299 25.749 7.891 34.636 10.185 24.621 6.357 50.451 7.612 75.722 9.557 14.404 1.109 28.678.999 43.104.777 21.448-.33 42.94-1.344 64.203-4.293 10.585-1.468 21.127-3.467 31.478-6.126 8.192-2.104 13.47-3.289 31.032-10.1 1.937 7.533 21.898 144.985 48.764 208.185 10.624 24.992 42.674 79.876 52.745 92.264-14.321 5.362-71.933 31.841-101.849 49.629-36.743 21.848-71.48 48.623-100.156 80.446-13.532 15.02-24.152 32.606-35.086 49.537-4.266 6.604-5.912 7.501-8.585 4.654zm11.489-54.904c7.625-39.942 29.623-90.766 63.953-147.75 11.581-19.223 33.603-52.214 46.967-70.363 8.287-11.254 10.945-15.403 10.945-17.086 0-1.254-.476-2.405-1.093-2.642-.602-.231-5.917.457-11.813 1.529-36.192 6.578-73.021 8.765-101.648 6.036-12.956-1.235-22.442-2.794-23.514-3.865-.759-.759 2.172-19.29 4.559-28.822 9.985-39.881 33.304-81.786 63.095-113.384 4.589-4.866 8.156-9.034 7.93-9.26-.228-.227-3.052.433-6.277 1.467-37.805 12.116-79.837 13.334-110.1 3.191-4.133-1.386-7.625-2.414-7.762-2.287-.136.128.165 4.227.669 9.11 4.746 45.95-17.074 106.187-62.849 173.502-6.884 10.124-20.352 28.227-28.176 37.875-3.156 3.891-4.503 6.084-3.834 6.239.567.132 6.354-1.116 12.86-2.772 18.57-4.727 34.105-7.629 55.329-10.332 16.237-2.068 56.226-1.88 70.125.33 9.04 1.437 21.549 4.209 22.277 4.938.15.15-.213 1.752-.806 3.561-3.145 9.582-7.186 28.637-9.049 42.662-3.581 26.956-3.578 70.348.006 102.375 1.409 12.596 3.907 28.753 4.624 29.913.611.986.929-.272 3.582-14.165z" />
|
||||
</svg>
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: 'translate(-50%, -50%)',
|
||||
fontSize: '8vh',
|
||||
fontWeight: 'bold',
|
||||
}}
|
||||
>
|
||||
{text}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default EnergyIcon;
|
||||
33
my-app/src/Icons/ExperienceIcon.tsx
Normal file
33
my-app/src/Icons/ExperienceIcon.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import { IconProps } from '../Types/Icon';
|
||||
|
||||
const ExperienceIcon = ({ color, size, text }: IconProps) => {
|
||||
return (
|
||||
<div style={{ position: 'relative', display: 'inline-block' }}>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlSpace="preserve"
|
||||
viewBox="0 0 980 980"
|
||||
width={size}
|
||||
height={size}
|
||||
fill={color || 'black'}
|
||||
fillOpacity="0.5"
|
||||
>
|
||||
<path d="M.775 171.102c96.217.111 192.488-.717 288.65.386 26.868 13.406 51.584 31.281 75.087 50.039-11.696 41.378-8.552 88.438 16.055 124.74 17.434 27.474 47.611 45.239 79.445 50.314l.055 497.248C351.107 834.08 244.959 767.49 151.445 685.175c-32.053-28.467-63.28-62.729-70.893-106.423-9.103-51.97 12.689-102.395 14.345-154.035.717-40.108-.111-81.541-16.331-118.946-15.227-40.494-46.783-71.224-70.065-106.865-6.014-8.054-7.503-17.985-7.724-27.805zm624.469 50.148c23.834-18.316 48.551-36.301 75.418-49.763 96.108-1.103 192.268-.275 288.43-.386-.719 8.219-.497 16.992-5.572 23.999-21.572 35.253-52.523 64.548-68.963 103.057-19.475 40.108-20.799 85.734-19.529 129.485 2.481 50.369 22.675 99.581 14.454 150.339-7.613 44.134-39.115 78.616-71.39 107.36-94.23 83.251-201.702 149.842-311.491 210.418-.055-166.337-.055-332.675-.055-499.012 35.75-4.359 69.403-25.378 86.837-57.156 20.965-35.418 22.731-79.334 11.861-118.34z" />
|
||||
</svg>
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: 'translate(-50%, -50%)',
|
||||
fontSize: '8vh',
|
||||
fontWeight: 'bold',
|
||||
}}
|
||||
>
|
||||
{text}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ExperienceIcon;
|
||||
33
my-app/src/Icons/PoisonIcon.tsx
Normal file
33
my-app/src/Icons/PoisonIcon.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import { IconProps } from '../Types/Icon';
|
||||
|
||||
const PhyrexianIcon = ({ color, size, text }: IconProps) => {
|
||||
return (
|
||||
<div style={{ position: 'relative', display: 'inline-block' }}>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlSpace="preserve"
|
||||
viewBox="0 0 152.667 223"
|
||||
width={size}
|
||||
height={size}
|
||||
fill={color || 'black'}
|
||||
fillOpacity="0.5"
|
||||
>
|
||||
<path d="M64.333 20.833V223l24-20.333V0M76.334 46.5C34.176 46.5 0 75.644 0 111.454c0 35.904 34.176 65.048 76.334 65.048 42.157 0 76.333-29.144 76.333-65.048 0-35.81-34.176-64.954-76.333-64.954zm.166 101.667c-23.748 0-43-16.146-43-36.083S52.752 76 76.5 76s43 16.147 43 36.083-19.252 36.084-43 36.084z" />
|
||||
</svg>
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: 'translate(-50%, -50%)',
|
||||
fontSize: '8vh',
|
||||
fontWeight: 'bold',
|
||||
}}
|
||||
>
|
||||
{text}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PhyrexianIcon;
|
||||
5
my-app/src/Types/Icon.ts
Normal file
5
my-app/src/Types/Icon.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export type IconProps = {
|
||||
size?: string;
|
||||
text?: number;
|
||||
color?: string; // Add color prop
|
||||
};
|
||||
Reference in New Issue
Block a user