Skip to content

Commit

Permalink
Merge pull request #84 from signed/fetch-item-cards-from-worldhaven
Browse files Browse the repository at this point in the history
Fetch item cards from worldhaven
  • Loading branch information
kosta authored Jan 16, 2023
2 parents 07779f9 + 5f832e5 commit f5eb816
Show file tree
Hide file tree
Showing 23 changed files with 729 additions and 13,578 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Sorry for the extremely horrible look! If you're good at CSS, send a Pull Reques

[Gloomhaven TTS](/~https://github.com/saizai/gloomhaven_tts/)
[Assets](https://drive.google.com/drive/folders/1SiXb3u2mJbN-Dg2j3Rb-y5amnRJSXIDc)
[Scans](/~https://github.com/any2cards/gloomhaven)
[Scans](/~https://github.com/any2cards/worldhaven)
[Some](https://boardgamegeek.com/thread/1733586/files-creation) [font](https://www.reddit.com/r/Gloomhaven/comments/8abglc/which_font_is_used_for_what/) related links.

# Developer Documentation
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
"@types/jest": "29.2.5",
"@types/react-dom": "18.0.10",
"css-loader": "6.7.3",
"file-loader": "6.2.0",
"html-webpack-plugin": "5.5.0",
"jest": "29.3.1",
"jest-environment-jsdom": "29.3.1",
Expand All @@ -21,6 +20,7 @@
"style-loader": "3.3.1",
"ts-jest": "29.0.4",
"ts-loader": "9.4.2",
"ts-node": "10.9.1",
"typescript": "4.9.4",
"webpack": "5.75.0",
"webpack-cli": "5.0.1",
Expand All @@ -35,7 +35,8 @@
"start": "webpack-dev-server --open --mode development",
"test": "jest",
"deploy": "webpack --mode production",
"typecheck": "tsc --noEmit"
"typecheck": "tsc --noEmit",
"update-item-data": "ts-node scripts/update-item-data.ts"
},
"prettier": "@signed/prettier-config",
"jest": {
Expand Down
44 changes: 44 additions & 0 deletions scripts/update-item-data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { writeFileSync } from 'fs'

type Expansion = 'Gloomhaven' | 'Forgotten Circles' | 'Crimson Scales' | 'Trail of Ashes'
type ItemData = {
name: string
points: number
expansion: Expansion
image: string
xws: string
}
type Refined = {
cardId: number
path: string
}

function itemDataFile(strings: any, items: string) {
return `// file is auto generated by running yarn update-item-data
//prettier-ignore
const itemData = ${items} as const;
export const gloomhavenItems = itemData.reduce((acc, cur) => acc.set(cur.cardId, cur.path), new Map<number, string>())
`
}

;(async function () {
const response = await fetch('https://raw.githubusercontent.com/any2cards/worldhaven/master/data/items.js')
if (response.status !== 200) {
throw new Error('could not fetch data')
}
const itemData: ItemData[] = await response.json()
const refinedData = itemData
.filter((item) => item.expansion === 'Gloomhaven' && !item.image.endsWith('-back.png'))
.map((item) => {
const fileName = item.image.substring(item.image.lastIndexOf('/'))
const cardId = Number.parseInt(fileName.substring(4, 7), 10)
const path = item.image
return {
cardId,
path,
}
})
.reduce((acc, cur) => acc.set(cur.cardId, cur), new Map<number, Refined>())
const items = JSON.stringify(Array.from(refinedData.values()), null, 2)
writeFileSync('src/cards/items-data.ts', itemDataFile`${items}`)
})()
74 changes: 38 additions & 36 deletions src/Gallery.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { BattleGoalCard } from 'battlegoals/BattleGoalCard'
import { BattleGoal, battleGoalImages, officialBattleGoals, satireGamingBattleGoals } from 'battlegoals/battleGoals'
import { css } from 'lang/react'
import * as React from 'react'
import * as ReactDOM from 'react-dom'
import { NoProps, NoState } from 'lang/react'
import { BattleGoal, officialBattleGoals, satireGamingBattleGoals } from 'battlegoals/battleGoals'
import BattleGoalCard from 'battlegoals/BattleGoalCard'
import { CSSProperties } from 'react'
import { createRoot } from 'react-dom/client'
import './style.css'

interface ScanFilenameLookupTable {
Expand All @@ -16,7 +15,7 @@ const scanFilenameLookupTable: ScanFilenameLookupTable = {
260: 'workhorse',
261: 'zealot',
262: 'masochist',
263: 'fasthealer',
263: 'fast-healer',
264: 'neutralizer',
265: 'plunderer',
266: 'protector',
Expand Down Expand Up @@ -44,35 +43,38 @@ function urlToScanFor(it: BattleGoal) {
return 'empty'
}

class Gallery extends React.Component<NoProps, NoState> {
render(): React.ReactNode {
const allBattleGoals = officialBattleGoals.concat(satireGamingBattleGoals)
const style = {
display: 'flex',
flexDirection: 'row',
flexWrap: 'wrap',
} as CSSProperties
const imageStyle = {
width: 200,
height: 300,
}
const cards = allBattleGoals.map((it) => {
const imgUrl = `https://raw.githubusercontent.com/any2cards/gloomhaven/master/images/battle-goals/gloomhaven/${urlToScanFor(
it,
)}.png`
const style = {
display: 'flex',
flexDirection: 'row',
} as CSSProperties
return (
<div style={style} key={it.globalCardId.asString()}>
<BattleGoalCard battleGoal={it} cardShadow={false} blurCard={false} />
<img style={imageStyle} src={imgUrl} alt="empty" />
</div>
)
})
return <div style={style}>{cards}</div>
}
const galleryStyle = css({
display: 'flex',
flexDirection: 'row',
flexWrap: 'wrap',
})
const imageStyle = css({
width: 200,
height: 300,
})
const battleGoalContainerStyles = css({
display: 'flex',
flexDirection: 'row',
})

const Gallery = () => {
const allBattleGoals = officialBattleGoals.concat(satireGamingBattleGoals)
const cards = allBattleGoals.map((it) => {
const nameInRepository = urlToScanFor(it)
const battleCardGoalurl = `https://raw.githubusercontent.com/any2cards/worldhaven/master/images/battle-goals/gloomhaven/gh-${nameInRepository}.png`
const imgUrl = nameInRepository === 'empty' ? battleGoalImages.background : battleCardGoalurl
return (
<div style={battleGoalContainerStyles} key={it.globalCardId.asString()}>
<BattleGoalCard battleGoal={it} cardShadow={false} blurCard={false} />
<img style={imageStyle} src={imgUrl} alt="empty" />
</div>
)
})
return <div style={galleryStyle}>{cards}</div>
}

ReactDOM.render(<Gallery />, document.getElementById('root'))
const container = document.getElementById('root')
if (container === null) {
throw new Error('root element not found')
}
createRoot(container).render(<Gallery />)
11 changes: 7 additions & 4 deletions src/StagingRoom.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import * as React from 'react'
import * as ReactDOM from 'react-dom'
import { PartyBattleGoals } from 'battlegoals/PartyBattleGoals'
import * as React from 'react'
import { createRoot } from 'react-dom/client'
import './style.css'

let app = <PartyBattleGoals />
ReactDOM.render(app, document.getElementById('root'))
const container = document.getElementById('root')
if (container === null) {
throw new Error('root element not found')
}
createRoot(container).render(<PartyBattleGoals />)
4 changes: 2 additions & 2 deletions src/app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ export class App extends React.Component<AppProps, AppState> {
}

setDialog(dialog: JSX.Element) {
// first remove, then add so that the component doesnt get recycled
// first remove, then add so that the component doesn't get recycled
this.setState(
{
dialog: null,
Expand All @@ -217,7 +217,7 @@ export class App extends React.Component<AppProps, AppState> {
}

render() {
let prosperity = this.state.stacks.prosperity
const prosperity = this.state.stacks.prosperity
return (
<React.Fragment>
<div key="button-frame" className="frame">
Expand Down
39 changes: 16 additions & 23 deletions src/app/Shop.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,28 @@
import * as React from 'react'
import { noop, NoState } from 'lang/react'
import { rangeFromTo } from 'lang/ranges'
import { itemToDiv } from 'cards/cards'
import { itemIdsByProsperityLevel } from 'app/Propsperity'
import { itemToDiv } from 'cards/cards'
import { rangeFromTo } from 'lang/ranges'
import { noop } from 'lang/react'
import * as React from 'react'

interface ProsperityInputProps {
onIncreaseProsperity: () => void
prosperity: number
}

export class ProsperityInput extends React.Component<ProsperityInputProps, NoState> {
constructor(props: ProsperityInputProps) {
super(props)
this.increaseProsperity = this.increaseProsperity.bind(this)
}

increaseProsperity() {
this.props.onIncreaseProsperity()
export const ProsperityInput = (props: ProsperityInputProps) => {
const increaseProsperity = () => {
props.onIncreaseProsperity()
}

render() {
const prosperity = this.props.prosperity
return (
<h2 key="h2">
Prosperity {prosperity}
<button disabled={prosperity >= 9} type="button" onClick={this.increaseProsperity}>
+
</button>
</h2>
)
}
const prosperity = props.prosperity
return (
<h2 key="h2">
Prosperity {prosperity}
<button disabled={prosperity >= 9} type="button" onClick={increaseProsperity}>
+
</button>
</h2>
)
}

interface ShopProps {
Expand Down
Loading

0 comments on commit f5eb816

Please sign in to comment.