Add war display
This commit is contained in:
parent
e8cf27d65d
commit
132995c051
@ -10,12 +10,15 @@
|
||||
"@types/node": "^16.11.4",
|
||||
"@types/react": "^17.0.5",
|
||||
"@types/react-dom": "^17.0.5",
|
||||
"@types/roman-numerals": "^0.3.0",
|
||||
"classnames": "^2.3.1",
|
||||
"eslint-config-react-app": "^6.0.0",
|
||||
"formik": "^2.2.6",
|
||||
"ketchup-react": "^0.1.1",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-scripts": "^4.0.3",
|
||||
"roman-numerals": "^0.3.2",
|
||||
"typescript": "^4.1.2",
|
||||
"web-vitals": "^2.1.2",
|
||||
"wonders-common": "^0.1.1"
|
||||
|
||||
@ -11,4 +11,5 @@
|
||||
|
||||
.wonder-game-wrapper {
|
||||
overflow: auto;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
.wonder-civ {
|
||||
border: black solid;
|
||||
margin: 1em;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ import { useMemo } from 'react'
|
||||
import { Player, playerStats, Resource, Science, Structure, StructureType, wonders } from 'wonders-common'
|
||||
import fill from 'lodash/fill'
|
||||
import './Civ.css'
|
||||
import classNames from 'classnames'
|
||||
|
||||
type DisplayStyle = 'player' | 'neighbor' | 'distant'
|
||||
|
||||
@ -72,7 +73,7 @@ export default function Civ({ player, displayStyle }: { player: Player, displayS
|
||||
{col.filter(type => pStats.structObjs.some(s => s.type === type)).map(type =>
|
||||
<ol key={type} className='wonder-civ-struct-group'>
|
||||
{pStats.structObjs.filter(o => o.type === type).map((s, i) =>
|
||||
<li key={i} className={`wonder-civ-struct wonder-civ-struct-type-${type.replaceAll(' ', '-')}`}>
|
||||
<li key={i} className={classNames({ 'wonder-civ-struct': true, [`wonder-civ-struct-type-${type.replaceAll(' ', '-')}`]: true })}>
|
||||
{s.name} {structurePeek(s)}
|
||||
</li>
|
||||
)}
|
||||
|
||||
@ -2,21 +2,29 @@
|
||||
background-image: url(world.webp);
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.wonder-lobby {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.wonder-distant {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.wonder-neighbors {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.wonder-neighbor {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.wonder-center {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
@ -4,6 +4,9 @@ import Civ from '../Civ/Civ'
|
||||
import Card from '../Card/Card'
|
||||
import './Game.css'
|
||||
import WonderSelector from '../WonderSelector/WonderSelector'
|
||||
import War from '../War/War'
|
||||
import first from 'lodash/first'
|
||||
import last from 'lodash/last'
|
||||
|
||||
function getDistant<T>(arr: T[], idx: number) {
|
||||
switch (idx) {
|
||||
@ -45,19 +48,32 @@ export default function Game({ state, playerName, dispatch }: { state: State, pl
|
||||
</>
|
||||
}
|
||||
} else {
|
||||
console.log(player.name, player.leftBattles)
|
||||
console.log(started.right.name, started.right.rightBattles)
|
||||
gameElem = <>
|
||||
<div className='wonder-distant'>
|
||||
{started.distant.map(p =>
|
||||
<Civ key={p.name} player={p} displayStyle='distant' />
|
||||
<War vertical players={[started.left, first(started.distant)!]} state={state} alignBottom />
|
||||
{started.distant.map((p, i) =>
|
||||
<>
|
||||
<Civ key={p.name} player={p} displayStyle='distant' />
|
||||
{i + 1 < started.distant.length && <War vertical players={started.distant.slice(i, i + 2)} state={state} />}
|
||||
</>
|
||||
)}
|
||||
<War vertical players={[last(started.distant)!, started.right]} state={state} alignBottom />
|
||||
</div>
|
||||
<div className='wonder-neighbors'>
|
||||
<Civ player={started.left} displayStyle='neighbor' />
|
||||
<div className='wonder-neighbor'>
|
||||
<Civ player={started.left} displayStyle='neighbor' />
|
||||
<War players={[started.left, player]} state={state} />
|
||||
</div>
|
||||
<div className='wonder-center'>
|
||||
<div>{state.age === undefined ? '' : `Age ${state.age + 1} ${state.age % 2 === 0 ? '🔃' : '🔄'}`}</div>
|
||||
<div><button>Discards</button></div>
|
||||
</div>
|
||||
<Civ player={started.right} displayStyle='neighbor' />
|
||||
<div className='wonder-neighbor'>
|
||||
<Civ player={started.right} displayStyle='neighbor' />
|
||||
<War players={[started.right, player]} state={state} />
|
||||
</div>
|
||||
</div>
|
||||
<Civ player={player} displayStyle='player' />
|
||||
<div>{player.hand?.map(s => structures.get(s)!)?.map((s, i) =>
|
||||
|
||||
46
packages/wonders-client/src/components/War/War.css
Normal file
46
packages/wonders-client/src/components/War/War.css
Normal file
@ -0,0 +1,46 @@
|
||||
.wonder-war {
|
||||
display: flex;
|
||||
background-color: lightcoral;
|
||||
align-self: center;
|
||||
justify-content: center;
|
||||
font-family: serif;
|
||||
text-align: center;
|
||||
}
|
||||
.wonder-war-vertical {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.wonder-war-crossed-swords {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.wonder-war-align-bottom {
|
||||
align-self: flex-end;
|
||||
}
|
||||
|
||||
.wonder-war-battle {
|
||||
border: 1pt solid red;
|
||||
margin: 0.1em;
|
||||
padding: 0.1em;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.wonder-war-vertical .wonder-war-battle {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.wonder-war-battle-results {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.wonder-war-horizontal .wonder-war-battle-results {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.wonder-war-battle-result {
|
||||
background-color: red;
|
||||
color: white;
|
||||
margin: 0.2em;
|
||||
min-width: 1.5em;
|
||||
font-weight: bold;
|
||||
}
|
||||
30
packages/wonders-client/src/components/War/War.tsx
Normal file
30
packages/wonders-client/src/components/War/War.tsx
Normal file
@ -0,0 +1,30 @@
|
||||
import classNames from "classnames";
|
||||
import { numAges, Player, State } from 'wonders-common'
|
||||
import zip from 'lodash/zip'
|
||||
import range from 'lodash/range'
|
||||
import './War.css'
|
||||
import { toRoman } from 'roman-numerals'
|
||||
|
||||
function Battle({ age, future, battle }: { age: number, future: boolean, battle: [number | undefined, number | undefined] }) {
|
||||
function resultText(result?: number) {
|
||||
return future ? '…' : result ?? '🕊️'
|
||||
}
|
||||
|
||||
return <div className='wonder-war-battle'>
|
||||
<div>{toRoman(age + 1)}</div>
|
||||
<div className='wonder-war-battle-results'>
|
||||
{range(2).map(i => <div className='wonder-war-battle-result' key={i}>{resultText(battle[i])}</div>)}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
export default function War({ state, players, vertical, alignBottom }: { state: State, players: Player[], vertical?: boolean, alignBottom?: boolean }) {
|
||||
let battles = zip(players[0].rightBattles, players[1].leftBattles)
|
||||
|
||||
console.log(players, vertical, battles)
|
||||
|
||||
return <div className={classNames({ 'wonder-war': true, 'wonder-war-vertical': vertical, 'wonder-war-horizontal': !vertical, 'wonder-war-align-bottom': alignBottom })}>
|
||||
<div className='wonder-war-crossed-swords'>⚔️</div>
|
||||
{range(numAges).map(age => <Battle age={age} battle={battles[age] ?? []} future={age >= state.age!} key={age} />)}
|
||||
</div>
|
||||
}
|
||||
15
yarn.lock
15
yarn.lock
@ -2967,6 +2967,11 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/roman-numerals@^0.3.0":
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/roman-numerals/-/roman-numerals-0.3.0.tgz#6e8ad8e7c0dc6e2d4f4d6aca9df6677f3b8e2282"
|
||||
integrity sha512-sfO4vwDEH5hpm9GHQMkcJaRUWgcrlgJn9YLQv+6l9JBQk+Xe4nx9zfbHgS+3x1sMwZUnFc0sgTY0eAHr9Foqhw==
|
||||
|
||||
"@types/scheduler@*":
|
||||
version "0.16.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39"
|
||||
@ -4668,6 +4673,11 @@ class-utils@^0.3.5:
|
||||
isobject "^3.0.0"
|
||||
static-extend "^0.1.1"
|
||||
|
||||
classnames@^2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e"
|
||||
integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==
|
||||
|
||||
clean-css@^4.2.3:
|
||||
version "4.2.4"
|
||||
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.4.tgz#733bf46eba4e607c6891ea57c24a989356831178"
|
||||
@ -12781,6 +12791,11 @@ rollup@^1.31.1:
|
||||
"@types/node" "*"
|
||||
acorn "^7.1.0"
|
||||
|
||||
roman-numerals@^0.3.2:
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/roman-numerals/-/roman-numerals-0.3.2.tgz#907ddf90c64e1b5dce8ed5e8fb0718318f2f26e6"
|
||||
integrity sha1-kH3fkMZOG13OjtXo+wcYMY8vJuY=
|
||||
|
||||
rsvp@^4.8.4:
|
||||
version "4.8.5"
|
||||
resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user