|
1 | 1 | import React from 'react' |
| 2 | +import { SectionHeader } from '../../section-header' |
| 3 | +import { BATTLECODE_YEAR } from '../../../constants' |
| 4 | + |
| 5 | +enum TabType { |
| 6 | + NONE = '', |
| 7 | + OVERVIEW = 'Overview', |
| 8 | + GAME = 'Game Tab', |
| 9 | + RUNNER = 'Runner Tab', |
| 10 | + HOTKEYS = 'Hotkeys' |
| 11 | +} |
2 | 12 |
|
3 | 13 | interface Props { |
4 | 14 | open: boolean |
5 | 15 | } |
6 | 16 |
|
7 | 17 | export const HelpPage: React.FC<Props> = (props) => { |
| 18 | + const [openTabType, setOpenTabType] = React.useState(TabType.OVERVIEW) |
| 19 | + |
| 20 | + const toggleTab = (newType: TabType) => { |
| 21 | + setOpenTabType(newType == openTabType ? TabType.NONE : newType) |
| 22 | + } |
| 23 | + |
8 | 24 | const hotkeyElement = (key: string, description: string) => { |
9 | 25 | return ( |
10 | | - <div className="font-light"> |
11 | | - <b>{key}</b> - {description} |
| 26 | + <div> |
| 27 | + <div className="font-bold">{key}</div> |
| 28 | + <div>{description}</div> |
12 | 29 | </div> |
13 | 30 | ) |
14 | 31 | } |
15 | 32 |
|
16 | 33 | if (!props.open) return null |
17 | 34 |
|
| 35 | + const sections: Record<TabType, JSX.Element> = { |
| 36 | + [TabType.NONE]: <></>, |
| 37 | + [TabType.OVERVIEW]: ( |
| 38 | + <> |
| 39 | + <div> |
| 40 | + {`Welcome to the Battlecode ${BATTLECODE_YEAR} client! `} |
| 41 | + {`We've completely overhauled the client this year, and we hope it is a better experience overall. `} |
| 42 | + {`As such, there may be issues, so please let us know if you come across anything at all. `} |
| 43 | + {`On this page, you will find some basic information about some of the more complex features of the client. `} |
| 44 | + {`If anything is confusing or you have other questions, feel free to ask. `} |
| 45 | + <b>{`NOTE: If you are experiencing performance issues on Mac or a laptop, turn off low power mode. `}</b> |
| 46 | + </div> |
| 47 | + </> |
| 48 | + ), |
| 49 | + [TabType.GAME]: ( |
| 50 | + <> |
| 51 | + <div> |
| 52 | + {`The game page is where you will visualize the stats for a game. `} |
| 53 | + {`Each statistic is specific to a match, and a game may contain multiple matches. `} |
| 54 | + {`The crown that appears above one team indicates who has won the majority of matches within a game. `} |
| 55 | + {`Each duck indicates how many ducks currently exist of that type for each team. The first duck is `} |
| 56 | + {`the standard duck, and the next three are the ducks that have specialized to level four and above. `} |
| 57 | + {`Red is attack, purple is build, and yellow is heal. The final caged duck represents how many ducks `} |
| 58 | + {`are in jail. `} |
| 59 | + {`Finally, the flags represent how many flags each team has that have not been captured. If a flag is `} |
| 60 | + {`outlined red, it means the flag is currently being carried. `} |
| 61 | + </div> |
| 62 | + </> |
| 63 | + ), |
| 64 | + [TabType.RUNNER]: ( |
| 65 | + <> |
| 66 | + <div> |
| 67 | + {`The runner is an easy way to run games from within the client. `} |
| 68 | + {`To get started, make sure you are running the desktop version of the client. `} |
| 69 | + {`Then, select the root folder of the scaffold (battlecode${BATTLECODE_YEAR}-scaffold). `} |
| 70 | + {`Once you do that, you should see all of your maps and robots loaded in automatically. `} |
| 71 | + {`Before you run a game, ensure that your JDK installation has been correctly set up. `} |
| 72 | + {`The runner will attempt to detect the correct version of the JDK and display it in the `} |
| 73 | + {`dropdown. However, if no versions are listed and the 'Auto' setting does not work, you will `} |
| 74 | + {`have to manually customize the path to your JDK installation. `} |
| 75 | + {`Once everything is working, you'll be able to run games from within the client, and the `} |
| 76 | + {`client will automatically load the game to be visualized once it is complete. `} |
| 77 | + </div> |
| 78 | + </> |
| 79 | + ), |
| 80 | + [TabType.HOTKEYS]: ( |
| 81 | + <div className="flex flex-col gap-[10px]"> |
| 82 | + {hotkeyElement(`Space`, 'Pauses / Unpauses game')} |
| 83 | + {hotkeyElement( |
| 84 | + `LeftArrow and RightArrow`, |
| 85 | + 'Controls speed if game is unpaused, or moves the current round if paused' |
| 86 | + )} |
| 87 | + {hotkeyElement(`\` and 1`, 'Scroll through Game, Runner, and Queue')} |
| 88 | + {/* |
| 89 | + {hotkeyElement( |
| 90 | + `Shift`, |
| 91 | + 'Switches to Queue tab. If you are already on it, prompts you to select a replay file' |
| 92 | + )} |
| 93 | + */} |
| 94 | + {hotkeyElement(`Shift`, 'If you are on the queue tab, prompts you to select a replay file')} |
| 95 | + {hotkeyElement(`C`, 'Hides and Unhides Game control bar')} |
| 96 | + {hotkeyElement(`.`, 'Skip to the very last turn of the current game')} |
| 97 | + {hotkeyElement(`,`, 'Skip to the first turn of the current game')} |
| 98 | + </div> |
| 99 | + ) |
| 100 | + } |
| 101 | + |
18 | 102 | return ( |
19 | | - <div> |
20 | | - Shortcuts: <br /> |
21 | | - <br /> |
22 | | - {hotkeyElement(`Space`, 'Pauses / Unpauses game')} |
23 | | - <br /> |
24 | | - {hotkeyElement( |
25 | | - `LeftArrow and RightArrow`, |
26 | | - 'Controls speed if game is unpaused, or moves the current round if paused' |
27 | | - )} |
28 | | - <br /> |
29 | | - {hotkeyElement(`~ and 1`, 'Scroll through Game, Runner, and Queue')} |
30 | | - <br /> |
31 | | - {/* |
32 | | - {hotkeyElement( |
33 | | - `Shift`, |
34 | | - 'Switches to Queue tab. If you are already on it, prompts you to select a replay file' |
35 | | - )} |
36 | | - <br /> |
37 | | - */} |
38 | | - {hotkeyElement(`Shift`, 'If you are on the queue tab, prompts you to select a replay file')} |
39 | | - <br /> |
40 | | - {hotkeyElement(`C`, 'Hides and Unhides Game control bar')} |
41 | | - <br /> |
42 | | - {hotkeyElement(`.`, 'Skip to the very last turn of the current game')} |
43 | | - <br /> |
44 | | - {hotkeyElement(`,`, 'Skip to the first turn of the current game')} |
| 103 | + <div className="pb-5"> |
| 104 | + {Object.getOwnPropertyNames(sections).map((tabType) => { |
| 105 | + if (tabType == TabType.NONE) return null |
| 106 | + return ( |
| 107 | + <SectionHeader |
| 108 | + key={tabType} |
| 109 | + title={tabType} |
| 110 | + open={tabType == openTabType} |
| 111 | + onClick={() => toggleTab(tabType as TabType)} |
| 112 | + titleClassName="py-2" |
| 113 | + > |
| 114 | + <div className="pl-3 text-xs">{sections[tabType as TabType]}</div> |
| 115 | + </SectionHeader> |
| 116 | + ) |
| 117 | + })} |
45 | 118 | </div> |
46 | 119 | ) |
47 | 120 | } |
0 commit comments