Skip to content

Commit

Permalink
Main Menu + New Run
Browse files Browse the repository at this point in the history
  • Loading branch information
imisaacwu committed Aug 27, 2024
1 parent aa1d265 commit 996e0ce
Show file tree
Hide file tree
Showing 36 changed files with 467 additions and 120 deletions.
162 changes: 80 additions & 82 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,16 @@ import { InfoPanel } from './components/InfoPanel'
import { Joker } from './components/Joker'
import { Round } from './components/Round'
import { Shop } from './components/Shop'
import { Blinds, Consumables, DeckType } from './Constants'
import { Blinds } from './Constants'
import { gameReducer, GameStateContext, initialGameState } from './GameState'
import { cardSnap } from './Utilities'
import { MainMenu } from './components/MainMenu'

export default function App() {
const [ game, dispatch ] = useReducer(gameReducer, initialGameState)
const gameRef = useRef(game)
gameRef.current = game

useEffect(() => {
dispatch({type: 'init', payload: {deck: DeckType.Red }})
dispatch({type: 'addCard', payload: {cardLocation: 'consumables', card: Consumables[41]}})
}, [])

useEffect(() => {
document.addEventListener('keydown', handleKeys)

Expand Down Expand Up @@ -53,91 +49,93 @@ export default function App() {

return (
<GameStateContext.Provider value={{ state: game, dispatch }}>
<div className='container'>
<div id='sidebar'>
<div id='top-sidebar'>
{game.state === 'blind-select' && <div>Choose your<br />next Blind</div>}
{game.state === 'scoring' && <Blind type='sidebar' blind={currBlindType} />}
{game.state === 'shop' && <img id='shop-logo' src={shopIcon} />}
</div>
<Round />
<Calculator />
<InfoPanel />
</div>
<div id='main'>
<div id='top'>
<div id='jokers' className='card-container'>
<div id='joker-area' className='card-area'>
<label id='joker-bkg'>JOKERS</label>
{game.jokers.map(j =>
<Joker key={j.id} {...j}/>
)}
</div>
<div id='joker-label' className='counter'>{`${game.jokers.length}/${game.stats.jokerSize}`}</div>
</div>
<div id='consumables' className='card-container'>
<div id='consumables-area' className='card-area'>
<label id='consumable-bkg'>CONSUMABLES</label>
{game.cards.consumables.map(c => (
<Consumable key={c.id} {...c} />
))}
</div>
<div id='consumables-label' className='counter'>{`${game.cards.consumables.length}/${game.stats.consumableSize}`}</div>
{game.state === 'main-menu' ? <MainMenu /> :
<div className='container'>
<div id='sidebar'>
<div id='top-sidebar'>
{game.state === 'blind-select' && <div>Choose your<br />next Blind</div>}
{game.state === 'scoring' && <Blind type='sidebar' blind={currBlindType} />}
{game.state === 'shop' && <img id='shop-logo' src={shopIcon} />}
</div>
<Round />
<Calculator />
<InfoPanel />
</div>
<div id='lower'>
<div id='content'>
{game.state === 'blind-select' && <>
<div id='blinds-container'>
<Blind type='select' blind={Blinds[0]} />
<Blind type='select' blind={Blinds[1]} />
<Blind type='select' blind={game.blind.boss} />
</div>
</>}
{game.state === 'scoring' && <>
<div id='mid'>
{game.cards.submitted.map(c => <Card key={c.id} {...c} />)}
<div id='main'>
<div id='top'>
<div id='jokers' className='card-container'>
<div id='joker-area' className='card-area'>
<label id='joker-bkg'>JOKERS</label>
{game.jokers.map(j =>
<Joker key={j.id} {...j}/>
)}
</div>
<div id='bot'>
<Hand />
<div id='joker-label' className='counter'>{`${game.jokers.length}/${game.stats.jokerSize}`}</div>
</div>
<div id='consumables' className='card-container'>
<div id='consumables-area' className='card-area'>
<label id='consumable-bkg'>CONSUMABLES</label>
{game.cards.consumables.map(c => (
<Consumable key={c.id} {...c} />
))}
</div>
</>}
{game.state === 'post-scoring' && <>
<div id='post-outer'>
<div id='post-container'>
<div id='post-inner'>
<div id='cash-out' onClick={() => {
dispatch({type: 'state', payload: {
state: 'shop',
amount: reward,
}})
}}>{`Cash Out: $${reward}`}</div>
<Blind type='post' blind={currBlindType} />
<div id='post-dots'>{'. '.repeat(49)}</div>
{game.stats.hands > 0 &&
<div id='remaining-hands' className='extra-reward'>
<div className='num-extra'>{game.stats.hands}</div>
<div className='extra-reward-text'>{'Remaining Hands \[$1 each\]'}</div>
<div className='reward'>{'$'.repeat(game.stats.hands)}</div>
</div>
}
{game.stats.money > 4 &&
<div id='interest' className='extra-reward'>
<div className='num-extra'>{Math.min(Math.floor(game.stats.money / 5), 5)}</div>
<div className='extra-reward-text'>{'1 interest per $5 \[5 max\]'}</div>
<div className='reward'>{'$'.repeat(Math.min(Math.floor(game.stats.money / 5), 5))}</div>
</div>
}
<div id='consumables-label' className='counter'>{`${game.cards.consumables.length}/${game.stats.consumableSize}`}</div>
</div>
</div>
<div id='lower'>
<div id='content'>
{game.state === 'blind-select' && <>
<div id='blinds-container'>
<Blind type='select' blind={Blinds[0]} />
<Blind type='select' blind={Blinds[1]} />
<Blind type='select' blind={game.blind.boss} />
</div>
</>}
{game.state === 'scoring' && <>
<div id='mid'>
{game.cards.submitted.map(c => <Card key={c.id} {...c} />)}
</div>
<div id='bot'>
<Hand />
</div>
</>}
{game.state === 'post-scoring' && <>
<div id='post-outer'>
<div id='post-container'>
<div id='post-inner'>
<div id='cash-out' onClick={() => {
dispatch({type: 'state', payload: {
state: 'shop',
amount: reward,
}})
}}>{`Cash Out: $${reward}`}</div>
<Blind type='post' blind={currBlindType} />
<div id='post-dots'>{'. '.repeat(49)}</div>
{game.stats.hands > 0 &&
<div id='remaining-hands' className='extra-reward'>
<div className='num-extra'>{game.stats.hands}</div>
<div className='extra-reward-text'>{'Remaining Hands \[$1 each\]'}</div>
<div className='reward'>{'$'.repeat(game.stats.hands)}</div>
</div>
}
{game.stats.money > 4 &&
<div id='interest' className='extra-reward'>
<div className='num-extra'>{Math.min(Math.floor(game.stats.money / 5), 5)}</div>
<div className='extra-reward-text'>{'1 interest per $5 \[5 max\]'}</div>
<div className='reward'>{'$'.repeat(Math.min(Math.floor(game.stats.money / 5), 5))}</div>
</div>
}
</div>
</div>
</div>
</div>
</>}
{game.state === 'shop' && <Shop />}
</>}
{game.state === 'shop' && <Shop />}
</div>
<Deck />
</div>
<Deck />
</div>
</div>
</div>
}
</GameStateContext.Provider>
)
}
45 changes: 32 additions & 13 deletions src/Constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
export enum DeckType { Abandoned, Anaglyph, Black, Blue, Challenge, Checkered, Erratic, Ghost, Green, Magic, Nebula, Painted, Plasma, Red, Yellow, Zodiac }

export const deckInfo: {[D in keyof typeof DeckType]: string} = {
Abandoned: 'Start run with\n no/ {orange}Face Cards\n in your deck',
Anaglyph: '',
Black: '{orange}+1/ Joker slot\n {blue}-1/ hand\n every round',
Blue: '{blue}+1/ hand\n every round',
Challenge: '',
Checkered: 'Start run with\n {orange}26/ {dark-purple}Spades/ and\n {orange}26/ {red}Hearts/ in deck',
Erratic: 'All Ranks and\n Suits in deck\n are randomized',
Ghost: '{indigo}Spectral/ cards may\n appear in the shop,\n start with a/ {indigo}Hex/ card',
Green: 'At end of each Round:\n {yellow}$2/ {small black}per remaining/ {blue}Hand\n {yellow}$1/ {small black}per remaining/ {red}Discard\n Earn no/ {orange}Interest',
Magic: 'Start run with the\n {purple}Crystal Ball/ voucher\n and/ {orange}2/ copies\n of/ {purple}The Fool',
Nebula: 'Start run with the\n {aqua}Telescope/ voucher\n {red}-1/ consumable slot',
Painted: '{orange}+2/ Hand Size,\n {orange}-1/ Joker Slot',
Plasma: '',
Red: '{red}+1/ discard\n every round',
Yellow: 'Start with\n extra/ {yellow}$10',
Zodiac: 'Start run with\n {purple}Tarot Merchant/,\n {aqua}Planet Merchant/,\n and {orange}Overstock'
}

export enum Suit { Spades, Hearts, Clubs, Diamonds }
export enum Rank { Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King, Ace }
export enum Edition { Foil, Holographic, Negative, Polychrome }
Expand All @@ -15,22 +34,22 @@ export const editionInfo: {[E in keyof typeof Edition]: string} = {
}

export const enhancementInfo: {[E in keyof typeof Enhancement]: string} = {
Base: "",
Bonus: "{blue}+30/ extra chips",
Glass: "{red-invert}X2/ Mult\n{green}1 in 4/ chance\nto destroy card",
Gold: "{yellow}+$3/ if this\ncard is held in hand\nat end of round",
Lucky: "{green}1 in 5/ chance\nfor /{red}+20/ Mult\n{green}1 in 15/ chance\nto win /{yellow}$20",
Mult: "{red}+4/ Mult",
Steel: "{red-invert}X1.5/ Mult\nwhile this card\nstays in hand",
Stone: "{blue}+50/ Chips\nno rank or suit",
Wild: "Can be used\nas any suit"
Base: '',
Bonus: '{blue}+30/ extra chips',
Glass: '{red-invert}X2/ Mult\n{green}1 in 4/ chance\nto destroy card',
Gold: '{yellow}+$3/ if this\ncard is held in hand\nat end of round',
Lucky: '{green}1 in 5/ chance\nfor /{red}+20/ Mult\n{green}1 in 15/ chance\nto win /{yellow}$20',
Mult: '{red}+4/ Mult',
Steel: '{red-invert}X1.5/ Mult\nwhile this card\nstays in hand',
Stone: '{blue}+50/ Chips\nno rank or suit',
Wild: 'Can be used\nas any suit'
}

export const sealInfo: {[S in keyof typeof Seal]: string} = {
Blue: "Creates the/{aqua}Planet/card\nfor final played/{orange}poker hand\nof round if/{orange}held/in hand\n{grey}(Must have room)",
Gold: "Earn/{yellow}$3/when this\ncard is played\nand scores",
Purple: "Creates a/{purple}Tarot/card\nwhen/{orange}discarded\n{grey}(Must have room)",
Red: "Retrigger this\ncard/{orange}1/time"
Blue: 'Creates the/{aqua}Planet/card\nfor final played/{orange}poker hand\nof round if/{orange}held/in hand\n{grey}(Must have room)',
Gold: 'Earn/{yellow}$3/when this\ncard is played\nand scores',
Purple: 'Creates a/{purple}Tarot/card\nwhen/{orange}discarded\n{grey}(Must have room)',
Red: 'Retrigger this\ncard/{orange}1/time'
}

export const rankChips: {[R in keyof typeof Rank]: number} = {
Expand Down
27 changes: 16 additions & 11 deletions src/GameState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,20 @@ import { CardInfo } from "./components/CardInfo"
import { Activation, JokerInstance, JokerType } from "./components/JokerInfo"
import Rand from "rand-seed"

export const seed = (Math.random() + 1).toString(36).toUpperCase().slice(2)
export const Random = new Rand(seed)
export let Random: Rand = new Rand()

export const levelHand = ({ hand, n = 1 }: {hand: keyof typeof handLevels, n?: number}) => {
handLevels[hand].level += n
handLevels[hand].chips += handUpgrade[hand].chips * n
handLevels[hand].mult += handUpgrade[hand].mult * n
}

type GameStates = 'blind-select' | 'scoring' | 'post-scoring' | 'shop'
type GameStates = 'main-menu' | 'blind-select' | 'scoring' | 'post-scoring' | 'shop'

export type GameState = {
state: GameStates
seed: string
seeded: boolean

stats: {
handSize: number
Expand Down Expand Up @@ -96,7 +97,8 @@ export type GameAction = {
'setLastUsedConsumable' | 'updateJokers' | 'addJoker' | 'removeJoker' |
'shop-select' | 'shop-remove' | 'reroll'
payload?: {
deck?: DeckType,
deck?: DeckType
seed?: string

state?: GameStates

Expand All @@ -113,7 +115,9 @@ export type GameAction = {
}

export const initialGameState: GameState = {
state: 'shop' as GameStates,
state: 'main-menu' as GameStates,
seed: '',
seeded: false,

stats: {
handSize: 8,
Expand All @@ -134,8 +138,8 @@ export const initialGameState: GameState = {
offers: [],
weights: {
Joker: 20,
Tarot: 0,
Planet: 1,
Tarot: 4,
Planet: 4,
Card: 0,
Spectral: 0
}
Expand Down Expand Up @@ -192,16 +196,13 @@ export const gameReducer = (state: GameState, action: GameAction): GameState =>
case DeckType.Erratic:
next.stats.deck = DeckType.Erratic
for(let i = 1; i <= 52; i++) {
let rank = Rank[ranks[Math.floor(Random.next()*ranks.length)*0+4]]
let rank = Rank[ranks[Math.floor(Random.next()*ranks.length)]]
arr.push(
{
id: i,
suit: Suit[suits[Math.floor(Random.next()*suits.length)]],
rank: rank,
chips: rankChips[rank],
edition: Edition.Polychrome,
enhancement: (Random.next() < .9 ? Enhancement.Steel : Enhancement.Glass),
seal: Seal.Red,
deck: DeckType.Erratic
}
)
Expand All @@ -220,7 +221,10 @@ export const gameReducer = (state: GameState, action: GameAction): GameState =>
)
})})
}
next = initialGameState
next = {...next,
seed: action.payload?.seed ?? (Math.random() + 1).toString(36).toUpperCase().slice(2),
seeded: action.payload?.seed !== undefined,
blind: {...state.blind,
boss: boss_roll(state.stats.ante),
base: ante_base(state.stats.ante)
Expand All @@ -230,6 +234,7 @@ export const gameReducer = (state: GameState, action: GameAction): GameState =>
deck: arr
}
}
Random = new Rand(next.seed)
break
case 'state':
next = {...next,
Expand Down
Binary file added src/assets/decks/Abandoned.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/decks/Anaglyph.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/decks/Black.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/decks/Blue.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/decks/Checkered.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/assets/decks/Erratic.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/decks/Ghost.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/decks/Green.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/decks/Magic.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/decks/Nebula.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/decks/Painted.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/decks/Plasma.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/assets/decks/Red.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/decks/Yellow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/decks/Zodiac.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/components/Blind.css
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@

#blind-select.true:hover {
cursor: pointer;
filter: brightness(.75);
}

#blind-select.false {
Expand Down
5 changes: 4 additions & 1 deletion src/components/Card.css
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@
}

.card:hover { scale: 1.1; }
.card.standard:hover { cursor: pointer; }
.card.standard:hover {
cursor: pointer;
filter: brightness(.75);
}

.card:active { z-index: 1; }

Expand Down
1 change: 1 addition & 0 deletions src/components/Consumable.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ div[id^='consumable_'].shopping {

div[id^='consumable_']:hover {
cursor: pointer;
filter: brightness(.75);
scale: 1.1;
}

Expand Down
1 change: 1 addition & 0 deletions src/components/Deck.css
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#face-down:hover {
cursor: pointer;
filter: brightness(.75);
}

#deck-label {
Expand Down
Loading

0 comments on commit 996e0ce

Please sign in to comment.