diff --git a/ui/src/actions.js b/ui/src/actions.js index 57b31389..35af0b00 100644 --- a/ui/src/actions.js +++ b/ui/src/actions.js @@ -5,6 +5,7 @@ const ACTIONS = Object.freeze({ SET_IS_BUILDING_ROAD: "SET_IS_BUILDING_ROAD", SET_IS_BUILDING_SETTLEMENT: "SET_IS_BUILDING_SETTLEMENT", SET_IS_BUILDING_CITY: "SET_IS_BUILDING_CITY", + SET_IS_ROAD_BUILDING: "SET_IS_ROAD_BUILDING", }); export default ACTIONS; diff --git a/ui/src/components/Prompt.js b/ui/src/components/Prompt.js index 6ee09b02..a1fab98f 100644 --- a/ui/src/components/Prompt.js +++ b/ui/src/components/Prompt.js @@ -56,6 +56,9 @@ export function humanizeAction(gameState, action) { case "PLAY_KNIGHT_CARD": { return `${player} PLAYED KNIGHT CARD`; } + case "PLAY_ROAD_BUILDING": { + return `${player} PLAYED ROAD BUILDING` + } case "PLAY_YEAR_OF_PLENTY": { return `${player} YEAR OF PLENTY ${action[2]}`; } diff --git a/ui/src/pages/ActionsToolbar.js b/ui/src/pages/ActionsToolbar.js index 50a38599..65fc3fef 100644 --- a/ui/src/pages/ActionsToolbar.js +++ b/ui/src/pages/ActionsToolbar.js @@ -57,6 +57,14 @@ function PlayButtons() { .filter((action) => action[1].startsWith("PLAY")) .map((action) => action[1]) ); + const humanColor = getHumanColor(state.gameState); + const setIsRoadBuilding = useCallback(async () => { + const action = [humanColor, "PLAY_ROAD_BUILDING", null]; + const gameState = await postAction(gameId, action); + dispatch({ type: ACTIONS.SET_IS_ROAD_BUILDING }); + dispatch({ type: ACTIONS.SET_GAME_STATE, data: gameState }); + dispatchSnackbar(enqueueSnackbar, closeSnackbar, gameState); + }, [gameId, dispatch, enqueueSnackbar, closeSnackbar, humanColor]); const useItems = [ { label: "Monopoly", @@ -69,6 +77,7 @@ function PlayButtons() { { label: "Road Building", disabled: !playableDevCardTypes.has("PLAY_ROAD_BUILDING"), + onClick: setIsRoadBuilding, }, { label: "Knight", @@ -86,7 +95,6 @@ function PlayButtons() { ) .map((a) => a[1]) ); - const humanColor = getHumanColor(state.gameState); const buyDevCard = useCallback(async () => { const action = [humanColor, "BUY_DEVELOPMENT_CARD", null]; const gameState = await postAction(gameId, action); diff --git a/ui/src/pages/ZoomableBoard.js b/ui/src/pages/ZoomableBoard.js index c79e3b11..96feef83 100644 --- a/ui/src/pages/ZoomableBoard.js +++ b/ui/src/pages/ZoomableBoard.js @@ -65,7 +65,7 @@ function buildEdgeActions(state) { buildInitialRoadActions.forEach((action) => { edgeActions[action[2]] = action; }); - } else if (state.isBuildingRoad) { + } else if (state.isBuildingRoad || state.isRoadBuilding) { state.gameState.current_playable_actions .filter((action) => action[1] === "BUILD_ROAD") .forEach((action) => { diff --git a/ui/src/store.js b/ui/src/store.js index 5c58d740..aefbe3b0 100644 --- a/ui/src/store.js +++ b/ui/src/store.js @@ -8,6 +8,8 @@ const initialState = { isBuildingSettlement: false, isBuildingCity: false, isLeftDrawerOpen: false, + isRoadBuilding: false, + freeRoadsAvailable: 0, }; const store = createContext(initialState); const { Provider } = store; @@ -25,6 +27,8 @@ const StateProvider = ({ children }) => { isBuildingRoad: false, isBuildingSettlement: false, isBuildingCity: false, + isRoadBuilding: state.isRoadBuilding && state.freeRoadsAvailable > 0, + freeRoadsAvailable: state.isRoadBuilding ? state.freeRoadsAvailable - 1 : 0, }; case ACTIONS.SET_IS_BUILDING_ROAD: return { ...state, isBuildingRoad: true }; @@ -32,6 +36,12 @@ const StateProvider = ({ children }) => { return { ...state, isBuildingSettlement: true }; case ACTIONS.SET_IS_BUILDING_CITY: return { ...state, isBuildingCity: true }; + case ACTIONS.SET_IS_ROAD_BUILDING: + return { + ...state, + isRoadBuilding: true, + freeRoadsAvailable: 2 + }; default: throw new Error("Unknown Reducer Action: " + action.type); }