diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..4beec2f --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,12 @@ +# Changelog + +## 📦 v0.1.0 (August 21, 2019) + +### Added + +* 💰 - Basic economy functionality and gameplay. + +### Changed + +### Fixed + diff --git a/README.md b/README.md index 2cacbc8..618f105 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

- Hermes logo + Hermes logo

@@ -46,4 +46,4 @@ A game about space and junk. [size-image]: https://img.shields.io/bundlephobia/minzip/hermes-game.svg [coverage-badge]: https://coveralls.io/repos/github/alexlee-dev/hermes/badge.svg?branch=master [coverage-link]: https://coveralls.io/github/alexlee-dev/hermes?branch=master -[travis]: https://travis-ci.org/alexlee-dev/hermes.svg?branch=master \ No newline at end of file +[travis]: https://travis-ci.org/alexlee-dev/hermes.svg?branch=master diff --git a/package.json b/package.json index 828853a..fb90fe4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hermes-game", - "version": "0.0.0", + "version": "0.1.0", "description": "A game about space and junk.", "repository": { "type": "git", diff --git a/src/App.js b/src/App.js index e6c3bed..396f70d 100644 --- a/src/App.js +++ b/src/App.js @@ -2,65 +2,49 @@ import React, { useEffect } from 'react' import PropTypes from 'prop-types' import { connect } from 'react-redux' import { generatePlanets } from './util' +import { setShipLocationValue, setShipLocationName } from './redux/actions/ship' import { setPlanets } from './redux/actions/world' -import ItemTimer from './components/ItemTimer' import View from './views/View' +import { Box } from 'grommet' +import CashDisplay from './components/CashDisplay' +import ItemTimer from './components/ItemTimer' +import Title from './components/Title' import ViewSelector from './components/ViewSelector' -import { setShipLocationValue, setShipLocationName } from './redux/actions/ship' -const App = ({ - handleInitializeShipLocation, - handleSetPlanets, - planets, - userCash -}) => { +const App = ({ handleInitializeApplication, planets }) => { useEffect(() => { - if (planets.length === 0) { - const planets = generatePlanets() - - handleSetPlanets(planets) - - const homePlanet = planets.find(planet => planet.isHomePlanet === true) - - const value = homePlanet.location - const name = homePlanet.name - - handleInitializeShipLocation(value, name) - } - + if (planets.length === 0) handleInitializeApplication() // eslint-disable-next-line }, []) return ( -
-

hermes

+ + <ItemTimer /> - <h2>Cash:</h2> - <span>{userCash}</span> - <br /> - <br /> + <CashDisplay /> <ViewSelector /> - <div> - <View /> - </div> - </div> + <View /> + </Box> ) } App.propTypes = { - handleInitializeShipLocation: PropTypes.func.isRequired, - handleSetPlanets: PropTypes.func.isRequired, + handleInitializeApplication: PropTypes.func.isRequired, planets: PropTypes.array.isRequired } -const mapStateToProps = ({ user, world }) => ({ - planets: world.planets, - userCash: user.cash +const mapStateToProps = ({ world }) => ({ + planets: world.planets }) const mapDispatchToProps = dispatch => ({ - handleSetPlanets: planets => dispatch(setPlanets(planets)), - handleInitializeShipLocation: (value, name) => { + handleInitializeApplication: () => { + const planets = generatePlanets() + const homePlanet = planets.find(planet => planet.isHomePlanet === true) + const value = homePlanet.location + const name = homePlanet.name + + dispatch(setPlanets(planets)) dispatch(setShipLocationValue(value)) dispatch(setShipLocationName(name)) } diff --git a/src/components/CashDisplay.js b/src/components/CashDisplay.js new file mode 100644 index 0000000..7f586ab --- /dev/null +++ b/src/components/CashDisplay.js @@ -0,0 +1,23 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { Heading, Text, Box } from 'grommet' +import { connect } from 'react-redux' + +const CashDisplay = ({ cash }) => { + return ( + <Box margin={{ bottom: 'small' }}> + <Heading level="2" margin={{ bottom: 'xsmall' }}> + Cash: + </Heading> + <Text>{cash}</Text> + </Box> + ) +} + +CashDisplay.propTypes = { + cash: PropTypes.number.isRequired +} + +const mapStateToProps = ({ user }) => ({ cash: user.cash }) + +export default connect(mapStateToProps)(CashDisplay) diff --git a/src/components/Title.js b/src/components/Title.js new file mode 100644 index 0000000..77c43c3 --- /dev/null +++ b/src/components/Title.js @@ -0,0 +1,8 @@ +import React from 'react' +import { Heading } from 'grommet' + +const Title = () => { + return <Heading level="1">Hermes</Heading> +} + +export default Title diff --git a/src/components/ViewSelector.js b/src/components/ViewSelector.js index 6c41ade..f9d74dc 100644 --- a/src/components/ViewSelector.js +++ b/src/components/ViewSelector.js @@ -3,21 +3,24 @@ import PropTypes from 'prop-types' import { connect } from 'react-redux' import { views } from '../constants' import { setView } from '../redux/actions/ui' +import { Box } from 'grommet' const ViewSelector = ({ handleSetView, view }) => { const handleChange = e => handleSetView(e.target.value) return ( - <select onChange={handleChange}> - <option>{view}</option> - {Object.keys(views).map((viewName, i) => { - if (viewName !== view) { - return <option key={i}>{viewName}</option> - } else { - return null - } - })} - </select> + <Box width="small"> + <select onChange={handleChange}> + <option>{view}</option> + {Object.keys(views).map((viewName, i) => { + if (viewName !== view) { + return <option key={i}>{viewName}</option> + } else { + return null + } + })} + </select> + </Box> ) } diff --git a/src/redux/actions/ship.js b/src/redux/actions/ship.js index c2b208a..af6c7dd 100644 --- a/src/redux/actions/ship.js +++ b/src/redux/actions/ship.js @@ -1,17 +1,10 @@ // * ACTION TYPES -const STORE_CARGO = 'STORE_CARGO' const REMOVE_CARGO = 'REMOVE_CARGO' -const SET_SHIP_LOCATION_VALUE = 'SET_SHIP_LOCATION_VALUE' const SET_SHIP_LOCATION_NAME = 'SET_SHIP_LOCATION_NAME' +const SET_SHIP_LOCATION_VALUE = 'SET_SHIP_LOCATION_VALUE' +const STORE_CARGO = 'STORE_CARGO' // * ACTION GENERATORS -export const storeCargo = item => ({ - type: STORE_CARGO, - payload: { - item - } -}) - export const removeCargo = item => ({ type: REMOVE_CARGO, payload: { @@ -19,14 +12,21 @@ export const removeCargo = item => ({ } }) +export const setShipLocationName = name => ({ + type: SET_SHIP_LOCATION_NAME, + payload: { name } +}) + export const setShipLocationValue = value => ({ type: SET_SHIP_LOCATION_VALUE, payload: { value } }) -export const setShipLocationName = name => ({ - type: SET_SHIP_LOCATION_NAME, - payload: { name } +export const storeCargo = item => ({ + type: STORE_CARGO, + payload: { + item + } }) // * PROMISES diff --git a/src/redux/actions/world.js b/src/redux/actions/world.js index 15ae018..dfbaab4 100644 --- a/src/redux/actions/world.js +++ b/src/redux/actions/world.js @@ -1,20 +1,14 @@ // * ACTION TYPES -const SET_TIMER_RUNNING = 'SET_TIMER_RUNNING' -const REMOVE_ITEM = 'REMOVE_ITEM' -const SET_PLANETS = 'SET_PLANETS' const CLEAR_ITEMS = 'CLEAR_ITEMS' const REFRESH_ITEMS = 'REFRESH_ITEMS' +const REMOVE_ITEM = 'REMOVE_ITEM' +const SET_PLANETS = 'SET_PLANETS' +const SET_TIMER_RUNNING = 'SET_TIMER_RUNNING' // * ACTION GENERATORS -export const setPlanets = planets => ({ - type: SET_PLANETS, - payload: { planets } -}) +export const clearItems = () => ({ type: CLEAR_ITEMS }) -export const setTimerRunning = isTimerRunning => ({ - type: SET_TIMER_RUNNING, - payload: { isTimerRunning } -}) +export const refreshItems = () => ({ type: REFRESH_ITEMS }) export const removeItem = item => ({ type: REMOVE_ITEM, @@ -23,9 +17,15 @@ export const removeItem = item => ({ } }) -export const clearItems = () => ({ type: CLEAR_ITEMS }) +export const setPlanets = planets => ({ + type: SET_PLANETS, + payload: { planets } +}) -export const refreshItems = () => ({ type: REFRESH_ITEMS }) +export const setTimerRunning = isTimerRunning => ({ + type: SET_TIMER_RUNNING, + payload: { isTimerRunning } +}) // * PROMISES diff --git a/src/redux/reducers/ship.js b/src/redux/reducers/ship.js index 05b67dd..423af2d 100644 --- a/src/redux/reducers/ship.js +++ b/src/redux/reducers/ship.js @@ -8,27 +8,23 @@ const shipDefaultState = { export default (state = shipDefaultState, action) => { switch (action.type) { - case 'SET_SHIP_LOCATION_VALUE': + case 'REMOVE_CARGO': return { ...state, - location: { ...state.location, value: action.payload.value } + cargo: state.cargo.filter(item => item.id !== action.payload.item.id) } case 'SET_SHIP_LOCATION_NAME': return { ...state, location: { ...state.location, name: action.payload.name } } + case 'SET_SHIP_LOCATION_VALUE': + return { + ...state, + location: { ...state.location, value: action.payload.value } + } case 'STORE_CARGO': return { ...state, cargo: [...state.cargo, action.payload.item] } - case 'REMOVE_CARGO': - const itemIndex = state.cargo.findIndex( - item => item.id === action.payload.item.id - ) - - const newCargo = Array.from(state.cargo) - newCargo.splice(itemIndex, 1) - - return { ...state, cargo: newCargo } default: return state } diff --git a/src/redux/reducers/ui.js b/src/redux/reducers/ui.js index 9ff3790..37416f8 100644 --- a/src/redux/reducers/ui.js +++ b/src/redux/reducers/ui.js @@ -5,8 +5,7 @@ const uiDefaultState = { export default (state = uiDefaultState, action) => { switch (action.type) { case 'SET_VIEW': - const { view } = action.payload - return { ...state, view } + return { ...state, view: action.payload.view } default: return state } diff --git a/src/redux/reducers/world.js b/src/redux/reducers/world.js index a53fb2f..baf8179 100644 --- a/src/redux/reducers/world.js +++ b/src/redux/reducers/world.js @@ -8,55 +8,41 @@ const worldDefaultState = { export default (state = worldDefaultState, action) => { switch (action.type) { case 'CLEAR_ITEMS': - const newPlanets = [...state.planets] - - newPlanets.forEach(planet => { - planet.items = [] - }) - - return { ...state, planets: newPlanets } + return { + ...state, + planets: state.planets.map(planet => ({ ...planet, items: [] })) + } case 'REFRESH_ITEMS': - const additionalPlanets = [...state.planets] - - additionalPlanets.forEach(planet => { - planet.items = generateItems() - }) - - return { ...state, planets: additionalPlanets } - case 'SET_PLANETS': - const { planets } = action.payload - - return { ...state, planets } - case 'SET_TIMER_RUNNING': - const { isTimerRunning } = action.payload - - return { ...state, isTimerRunning } + return { + ...state, + planets: state.planets.map(planet => ({ + ...planet, + items: generateItems(state.planets) + })) + } case 'REMOVE_ITEM': const { item } = action.payload - const updatedPlanets = [] - - state.planets.forEach(planet => { + const updatedPlanets = state.planets.map(planet => { const { isHomePlanet, items, location, name } = planet - const planetContainsItem = items.includes(item) - if (planetContainsItem) { - const itemIndex = items.findIndex(currentItem => item === currentItem) - const newItems = Array.from(items) - newItems.splice(itemIndex, 1) - const newPlanetObj = { + if (planet.items.includes(item)) { + return { isHomePlanet, - items: newItems, + items: items.filter(currentItem => item !== currentItem), location, name } - updatedPlanets.push(newPlanetObj) } else { - updatedPlanets.push(planet) + return planet } }) return { ...state, planets: updatedPlanets } + case 'SET_PLANETS': + return { ...state, planets: action.payload.planets } + case 'SET_TIMER_RUNNING': + return { ...state, isTimerRunning: action.payload.isTimerRunning } default: return state } diff --git a/src/util.js b/src/util.js index bc251eb..03d4776 100644 --- a/src/util.js +++ b/src/util.js @@ -42,11 +42,10 @@ export const generatePlanets = () => { planets.push({ isHomePlanet, location, name }) } - planets.forEach((planet, i) => { - const otherPlanets = [...planets] - otherPlanets.splice(i, 1) - - planet.items = generateItems(otherPlanets) + planets.forEach(planet => { + planet.items = generateItems( + planets.filter(currentPlanet => currentPlanet !== planet) + ) }) return planets diff --git a/src/views/planets.js b/src/views/planets.js index 6653596..2da42d4 100644 --- a/src/views/planets.js +++ b/src/views/planets.js @@ -116,12 +116,10 @@ const mapDispatchToProps = dispatch => ({ dispatch(removeItem(item)) }, handleShipTravel: (destination, shipCargo) => { - const sellableItems = [] - shipCargo.forEach(item => { - if (item.destination.value === destination.value) { - sellableItems.push(item) - } - }) + const sellableItems = shipCargo.filter( + item => item.destination.value === destination.value + ) + sellableItems.forEach(item => { // * Add the value of this item to the user's cash dispatch(addCash(item.value))