diff --git a/client/src/components/user-interface/common/Checkbox.tsx b/client/src/components/user-interface/common/Checkbox.tsx
new file mode 100644
index 0000000..318cc68
--- /dev/null
+++ b/client/src/components/user-interface/common/Checkbox.tsx
@@ -0,0 +1,22 @@
+import colours from '../../../utils/colours';
+
+type CheckboxProps = {
+ title: string;
+ value: boolean;
+ onChange: (value: boolean) => void;
+};
+
+const Checkbox = ({ title, value, onChange }: CheckboxProps) => (
+
+
{title}
+
+);
+
+export default Checkbox;
diff --git a/client/src/components/world/boards/Board.tsx b/client/src/components/world/boards/Board.tsx
index c4f377d..ef6700d 100644
--- a/client/src/components/world/boards/Board.tsx
+++ b/client/src/components/world/boards/Board.tsx
@@ -13,13 +13,11 @@ import colours from '../../../utils/colours';
type BoardProps = {
board: BoardData;
- isActive: boolean;
winner: Nation | null;
};
-const Board = ({ board, isActive, winner }: BoardProps) => {
+const Board = ({ board, winner }: BoardProps) => {
const { phase } = board;
- const showWinner = isActive && winner;
const width = phase === Phase.Winter ? minorBoardWidth : majorBoardWidth;
@@ -41,12 +39,12 @@ const Board = ({ board, isActive, winner }: BoardProps) => {
minHeight: width,
height: width,
borderWidth: boardBorderWidth,
- borderColor: showWinner ? getNationColour(winner) : colours.boardBorder,
- boxShadow: showWinner ? `0px 0px 100px 50px ${getNationColour(winner)}` : '',
+ borderColor: winner ? getNationColour(winner) : colours.boardBorder,
+ boxShadow: winner ? `0px 0px 100px 50px ${getNationColour(winner)}` : '',
}}
>
{getBoardName(board)}
-
+
{phase === Phase.Winter && }
diff --git a/client/src/components/world/boards/BoardGhost.tsx b/client/src/components/world/boards/BoardGhost.tsx
index 00aa18c..669ae21 100644
--- a/client/src/components/world/boards/BoardGhost.tsx
+++ b/client/src/components/world/boards/BoardGhost.tsx
@@ -7,12 +7,15 @@ import Map from './Map';
import TextInput from '../../user-interface/common/TextInput';
import Select from '../../user-interface/common/Select';
import { isInteger } from '../../../utils/numberUtils';
+import Checkbox from '../../user-interface/common/Checkbox';
type LocationInputProps = {
board: Board;
onTimelineEntered: (value: string) => void;
onYearEntered: (value: string) => void;
onPhaseEntered: (value: Phase) => void;
+ isShowingCoasts: boolean;
+ onCoastsToggled: (value: boolean) => void;
};
const LocationInput = ({
@@ -20,8 +23,10 @@ const LocationInput = ({
onTimelineEntered,
onYearEntered,
onPhaseEntered,
+ isShowingCoasts,
+ onCoastsToggled,
}: LocationInputProps) => (
-
+
+
);
@@ -51,6 +57,7 @@ const BoardGhost = ({ initialTimeline, initialYear, initialPhase }: BoardGhostPr
const [timeline, setTimeline] = useState(initialTimeline);
const [year, setYear] = useState(initialYear);
const [phase, setPhase] = useState(initialPhase);
+ const [isShowingCoasts, setIsShowingCoasts] = useState(false);
const board = {
timeline,
@@ -95,6 +102,8 @@ const BoardGhost = ({ initialTimeline, initialYear, initialPhase }: BoardGhostPr
onTimelineEntered={onTimelineEntered}
onYearEntered={onYearEntered}
onPhaseEntered={setPhase}
+ isShowingCoasts={isShowingCoasts}
+ onCoastsToggled={setIsShowingCoasts}
/>
{getBoardName(board)}
-
+
);
diff --git a/client/src/components/world/boards/BoardLayer.tsx b/client/src/components/world/boards/BoardLayer.tsx
index 35e8718..f529600 100644
--- a/client/src/components/world/boards/BoardLayer.tsx
+++ b/client/src/components/world/boards/BoardLayer.tsx
@@ -1,5 +1,5 @@
import { useContext } from 'react';
-import { getNextMajorPhase, getNextPhase } from '../../../types/enums/phase';
+import { getNextMajorPhase } from '../../../types/enums/phase';
import { filterUnique } from '../../../utils/listUtils';
import Board from './Board';
import BoardSkip from './BoardSkip';
@@ -17,9 +17,6 @@ const BoardLayer = () => {
const boards = filterUnique(world.boards.map(({ year, phase }) => ({ year, phase })));
const { winner } = world;
- const hasRetreats = world.boards.some((board) =>
- Object.values(board.units).some((unit) => unit.mustRetreat),
- );
const selectedLocation = currentOrder?.location;
const showGhostBoard =
@@ -46,21 +43,9 @@ const BoardLayer = () => {
);
const key = `${board.year}-${board.phase}`;
- const nextBoard = getNextPhase(year, phase);
- const hasNextBoard = world.boards.find(
- (otherBoard) =>
- otherBoard.timeline === timeline &&
- otherBoard.year === nextBoard.year &&
- otherBoard.phase === nextBoard.phase,
- );
return possibleBoard ? (
-
+
) : (
);
diff --git a/client/src/components/world/boards/Map.tsx b/client/src/components/world/boards/Map.tsx
index 24e55ad..c570d66 100644
--- a/client/src/components/world/boards/Map.tsx
+++ b/client/src/components/world/boards/Map.tsx
@@ -5,13 +5,18 @@ import regions from '../../../data/regions';
import OrderEntryContext from '../../context/OrderEntryContext';
import UnitType from '../../../types/enums/unitType';
import InputMode from '../../../types/enums/inputMode';
+import { OrderType } from '../../../types/order';
+import WorldContext from '../../context/WorldContext';
+import { findUnit } from '../../../types/world';
+import Phase from '../../../types/enums/phase';
type MapProps = {
board: Board;
- isActive: boolean;
+ isShowingCoasts?: boolean;
};
-const Map = ({ board, isActive }: MapProps) => {
+const Map = ({ board, isShowingCoasts }: MapProps) => {
+ const { world } = useContext(WorldContext);
const { currentMode, currentOrder } = useContext(OrderEntryContext);
return (
@@ -30,17 +35,25 @@ const Map = ({ board, isActive }: MapProps) => {
phase={board.phase}
owner={board.centres[region]}
unit={board.units[region]}
- isActive={isActive}
/>
);
}
- // TODO fix for fleet supporting army on space with coasts and army supporting fleet to coast
- const showCoast =
- currentOrder?.unit?.type !== UnitType.Army &&
- ((currentOrder?.unit?.type === UnitType.Fleet && currentMode !== InputMode.Convoy) ||
- board.units[region] !== undefined ||
- currentMode === InputMode.Build);
+ const hasFleet = board.units[region]?.type === UnitType.Fleet;
+
+ const showCoast = {
+ [InputMode.None]: hasFleet || board.phase === Phase.Winter,
+ [InputMode.Hold]: hasFleet,
+ [InputMode.Move]: currentOrder?.unit?.type === UnitType.Fleet,
+ [InputMode.Support]:
+ currentOrder?.$type === OrderType.Support &&
+ ((!currentOrder.supportLocation && hasFleet) ||
+ (currentOrder.supportLocation !== null &&
+ findUnit(world, currentOrder.supportLocation)?.type === UnitType.Fleet)),
+ [InputMode.Convoy]: hasFleet,
+ [InputMode.Build]: true,
+ [InputMode.Disband]: hasFleet,
+ }[currentMode];
return (
{
phase={board.phase}
owner={board.centres[baseRegion]}
unit={board.units[region]}
- isActive={isActive}
- isVisible={showCoast}
+ isVisible={showCoast || isShowingCoasts}
/>
);
})}
diff --git a/client/src/components/world/boards/Region.tsx b/client/src/components/world/boards/Region.tsx
index 5c48071..93a5227 100644
--- a/client/src/components/world/boards/Region.tsx
+++ b/client/src/components/world/boards/Region.tsx
@@ -1,4 +1,4 @@
-import { useContext, useState } from 'react';
+import { useContext, useEffect, useState } from 'react';
import Nation, { getNationColour } from '../../../types/enums/nation';
import OrderEntryContext from '../../context/OrderEntryContext';
import { OrderEntryActionType } from '../../../types/context/orderEntryAction';
@@ -11,9 +11,9 @@ import UnitIcon from './UnitIcon';
import { compareLocations, getLocationKey } from '../../../types/location';
import { OrderType } from '../../../types/order';
import BuildOptions from '../../user-interface/BuildOption';
-import InputMode from '../../../types/enums/inputMode';
import colours from '../../../utils/colours';
import RegionType from '../../../types/enums/regionType';
+import useSelectLocation from '../../../hooks/useSelectLocation';
const getRegionColour = (
isHovering: boolean,
@@ -33,42 +33,17 @@ type RegionProps = {
phase: Phase;
owner?: Nation;
unit?: Unit;
- isActive: boolean;
isVisible?: boolean;
};
-const Region = ({
- id,
- timeline,
- year,
- phase,
- owner,
- unit,
- isActive,
- isVisible = true,
-}: RegionProps) => {
- const { dispatch, currentOrder, currentMode } = useContext(OrderEntryContext);
+const Region = ({ id, timeline, year, phase, owner, unit, isVisible = true }: RegionProps) => {
+ const { dispatch, currentOrder } = useContext(OrderEntryContext);
const location = { timeline, year, phase, region: id };
const Svg = useRegionSvg(id)!;
- const { x, y, type, homeNation } = regions[id];
+ const { x, y, type } = regions[id];
- const canRetreat = unit?.mustRetreat;
- const canMove = isActive && phase !== Phase.Winter && unit !== undefined;
- const canBuild =
- isActive &&
- phase === Phase.Winter &&
- currentMode !== InputMode.Disband &&
- unit === undefined &&
- homeNation !== undefined &&
- owner === homeNation;
- const canDisband = isActive && phase === Phase.Winter && unit !== undefined;
-
- const canCreateOrder = canRetreat || canMove || canBuild || canDisband;
-
- const hasUnfinishedOrder =
- currentOrder?.location !== undefined && currentOrder.$type !== OrderType.Build;
- const canSelect = canCreateOrder || hasUnfinishedOrder;
+ const canSelect = useSelectLocation(location, owner, unit);
const scaleFactor =
phase === Phase.Winter
@@ -77,12 +52,16 @@ const Region = ({
const [isHovering, setIsHovering] = useState(false);
- let isSelected = compareLocations(currentOrder?.location, location);
- if (currentOrder?.$type === OrderType.Support) {
- isSelected ||= compareLocations(currentOrder.supportLocation, location);
- } else if (currentOrder?.$type === OrderType.Convoy) {
- isSelected ||= compareLocations(currentOrder.convoyLocation, location);
- }
+ useEffect(() => {
+ if (!isVisible) setIsHovering(false);
+ }, [isVisible]);
+
+ const isSelected =
+ compareLocations(currentOrder?.location, location) ||
+ (currentOrder?.$type === OrderType.Support &&
+ compareLocations(currentOrder.supportLocation, location)) ||
+ (currentOrder?.$type === OrderType.Convoy &&
+ compareLocations(currentOrder.convoyLocation, location));
const colour = getRegionColour(isHovering, isSelected, owner, type === RegionType.Sea);
diff --git a/client/src/components/world/orders/Disband.tsx b/client/src/components/world/orders/Disband.tsx
index 1b715f2..1c62d3d 100644
--- a/client/src/components/world/orders/Disband.tsx
+++ b/client/src/components/world/orders/Disband.tsx
@@ -12,7 +12,7 @@ const Disband = ({ location, status, isHighlighted }: DisbandProps) => {
const radius = 10;
return (
-