diff --git a/src/features/game/GridCell.module.css b/src/features/game/GridCell.module.css new file mode 100644 index 0000000..1bd6d28 --- /dev/null +++ b/src/features/game/GridCell.module.css @@ -0,0 +1,34 @@ +.cell { + position: relative; + transition: 'background-color 0.2s'; +} + +.link { + position:absolute; + width:10px; + height:10px; +} + +.left { + height:50px; + left:-10px; + top:0; +} + +.right { + height:50px; + right:-10px; + top:0; +} + +.up { + width:50px; + top:-10px; + left:0; +} + +.down { + width:50px; + bottom:-10px; + left:0; +} \ No newline at end of file diff --git a/src/features/game/GridCell.tsx b/src/features/game/GridCell.tsx index f4f6fda..0ee11ae 100644 --- a/src/features/game/GridCell.tsx +++ b/src/features/game/GridCell.tsx @@ -1,6 +1,7 @@ import { attack, move, select, type Phase, type GridInfo } from './gameSlice' import { useAppDispatch } from '../../app/hooks' import * as d3 from 'd3-color' +import styles from './GridCell.module.css' const SELECTED_COLOR = '#384bfa' const VALID_MOVE_POSITION_COLOR = 'rgb(201, 230, 253)' @@ -24,6 +25,7 @@ export const GridCell = ({ gridInfo, phase }: Props) => { unitType, unitSelected, unitHead, + unitLink, showMoveHighlight, showAttackHighlight, showImmediateMove, @@ -31,17 +33,11 @@ export const GridCell = ({ gridInfo, phase }: Props) => { let color: string let glowColor: string | undefined = undefined if (unit) { - const modifiableColor = unitHead - ? d3.cubehelix(unit.stats.headColor)! - : d3.cubehelix(unit.stats.color)! + const modifiableColor = d3.cubehelix(unit.stats.color) if (unitType === 'enemy') { - if (unitHead) { - modifiableColor.s *= 0.2 - modifiableColor.l *= 1.5 - } else { - modifiableColor.s *= 0.2 - } + modifiableColor.s *= 0.2 + modifiableColor.l *= 1.3 } color = modifiableColor.toString() if (unitSelected) { @@ -102,16 +98,30 @@ export const GridCell = ({ gridInfo, phase }: Props) => { cursorStyle = 'crosshair' } + const unitLinkClass = unitLink + ? { + left: styles.left, + right: styles.right, + up: styles.up, + down: styles.down, + }[unitLink] + : undefined + const style = { backgroundColor: color, boxShadow: glowColor ? '0px 0px 10px' + glowColor : undefined, - transition: 'background-color 0.2s', cursor: cursorStyle, } return ( -
+
{unitHead && unit && unit.stats.icon} {moveIcon} + {unitLink && ( +
+ )}
) } diff --git a/src/features/game/UnitInfo.tsx b/src/features/game/UnitInfo.tsx index cad408b..6ee6be6 100644 --- a/src/features/game/UnitInfo.tsx +++ b/src/features/game/UnitInfo.tsx @@ -3,7 +3,7 @@ import styles from './Game.module.css' const UnitInfo = ({ unit }: { unit: Unit }) => (
-

{unit.stats.name}

+

{unit.stats.name}

diff --git a/src/features/game/gameSlice.ts b/src/features/game/gameSlice.ts index d1642b5..c0495a9 100644 --- a/src/features/game/gameSlice.ts +++ b/src/features/game/gameSlice.ts @@ -13,10 +13,6 @@ const unitColor = (hue: number) => { return d3.cubehelix(hue, UNIT_SATURATION, UNIT_LIGHTNESS).toString() } -const unitHeadColor = (hue: number) => { - return d3.cubehelix(hue, UNIT_SATURATION + 0.2, UNIT_LIGHTNESS - 0.3).toString() -} - export type PlayerType = 'human' | 'ai' export type Player = { @@ -49,7 +45,6 @@ const defaultUnits: Unit[] = [ movement: 2, attack: 1, color: unitColor(0), - headColor: unitHeadColor(0), id: 'a', icon: '🐱', }, @@ -65,7 +60,6 @@ const defaultUnits: Unit[] = [ movement: 2, attack: 1, color: unitColor(30), - headColor: unitHeadColor(30), id: 'b', icon: '🐶', }, @@ -81,7 +75,6 @@ const defaultUnits: Unit[] = [ movement: 2, attack: 1, color: unitColor(60), - headColor: unitHeadColor(60), id: 'c', icon: '🐷', }, @@ -101,7 +94,6 @@ const defaultUnits: Unit[] = [ movement: 1, attack: 1, color: unitColor(500), - headColor: unitHeadColor(500), id: 'x', icon: '🥸', }, @@ -121,7 +113,6 @@ const defaultUnits: Unit[] = [ movement: 1, attack: 1, color: unitColor(530), - headColor: unitHeadColor(530), id: 'y', icon: '🤡', }, @@ -141,7 +132,6 @@ const defaultUnits: Unit[] = [ movement: 1, attack: 1, color: unitColor(560), - headColor: unitHeadColor(560), id: 'z', icon: '🤖', }, diff --git a/src/features/search/Brain.ts b/src/features/search/Brain.ts index 2bffd06..79b6301 100644 --- a/src/features/search/Brain.ts +++ b/src/features/search/Brain.ts @@ -7,6 +7,7 @@ import { overlapsAnything, type Phase, type Player, + type Direction, } from '../game/gameSlice' import { type Grid, inGrid } from '../game/Grid' @@ -75,6 +76,20 @@ const positionsWithinRange = (position: Position, distance: number) => { return toReturn } +const getDirection = (pos1: Position, pos2: Position): Direction | undefined => { + if (pos1.x > pos2.x) { + return 'right' + } else if (pos1.x < pos2.x) { + return 'left' + } else if (pos1.y > pos2.y) { + return 'down' + } else if (pos1.y < pos2.y) { + return 'up' + } else { + return undefined + } +} + const adjacent = (position: Position) => positionsWithinRange(position, 1) export const aiSubTurn = ( @@ -262,15 +277,15 @@ export const generateGridInfo = ( units.forEach((unit) => { const isActivePlayerUnit = activePlayer.unitIds.includes(unit.stats.id) - unit.positions.forEach((position) => { + unit.positions.forEach((position, i) => { + const previous = unit.positions[i - 1] gridInfo[posHash(position)] = { position, unit: unit, unitType: isActivePlayerUnit ? 'ally' : 'enemy', unitSelected: isSelected(position, selectedUnit), unitHead: posEquals(head(unit), position), - unitLink: undefined, // TODO - showImmediateMove: undefined, // TODO + unitLink: previous ? getDirection(previous, position) : undefined, } }) if (selectedUnit && phase === 'move') { @@ -289,15 +304,7 @@ export const generateGridInfo = ( grid ) immediateMoves.forEach((position) => { - if (position.x > unitHead.x) { - gridInfo[posHash(position)].showImmediateMove = 'right' - } else if (position.x < unitHead.x) { - gridInfo[posHash(position)].showImmediateMove = 'left' - } else if (position.y > unitHead.y) { - gridInfo[posHash(position)].showImmediateMove = 'down' - } else if (position.y < unitHead.y) { - gridInfo[posHash(position)].showImmediateMove = 'up' - } + gridInfo[posHash(position)].showImmediateMove = getDirection(position, unitHead) }) } if (selectedUnit && phase === 'attack' && !selectedUnit.attackUsed) { diff --git a/src/features/unit/Unit.ts b/src/features/unit/Unit.ts index 824b4ea..28952d4 100644 --- a/src/features/unit/Unit.ts +++ b/src/features/unit/Unit.ts @@ -8,7 +8,6 @@ export default interface Unit { readonly attack: number readonly name: string readonly color: string - readonly headColor: string readonly id: string readonly icon: string }