Added initial selection of player who chooses a BoardEntry in BE

This commit is contained in:
EisiBaer 2023-07-11 17:22:05 +02:00
parent a4b0db9118
commit 70d9786ef2
9 changed files with 93 additions and 6 deletions

View File

@ -63,6 +63,26 @@ exports.setAllPlayersAcceptAnswers = ( playerIds, acceptAnswersValue ) => {
}); });
} }
/**
* Sets one player as isChoosing and other players as isChoosing false
* @param {String} choosingPlayerId
* @param {Array} notChoosingPlayerIds
* @returns A promise which resolves with the choosing player
*/
exports.setAllPlayersAcceptAnswers = ( choosingPlayerId, notChoosingPlayerIds ) => {
return new Promise((resolve, reject) => {
let promiseSetChoosing = PlayerModel.updateOne( { _id: choosingPlayerId }, { isChoosing: true } );
let promiseSetNotChoosing = PlayerModel.updateMany( { _id: { $in : notChoosingPlayerIds } }, { isChoosing: false } );
Promise.all( [ promiseSetChoosing, promiseSetNotChoosing ] )
.then( ( resArr ) => {
resolve( resArr[0] );
})
.catch( ( err ) => {
reject( err );
})
});
}
/** /**
* Checks if a player is allowed to currently answer a question * Checks if a player is allowed to currently answer a question
* @param {String} playerId * @param {String} playerId
@ -86,6 +106,29 @@ exports.checkPlayerAcceptAnswers = ( playerId ) => {
}); });
} }
/**
* Checks if a player is allowed to choose a BoardEntry
* @param {String} playerId
* @returns A promise which resolves with wheter the player is allowed to choose a BoardEntry or not. Rejects if an error occurs.
*/
exports.checkPlayerCanChoose = ( playerId ) => {
return new Promise((resolve, reject) => {
PlayerModel.findById( playerId )
.then( ( player ) => {
if( player ){
resolve( player.isChoosing );
} else {
let playerNotFoundError = new Error(`No player found with id "${playerId}"`);
playerNotFoundError.name = "NotFoundError";
reject(playerNotFoundError);
}
})
.catch( ( err ) => {
reject( err );
})
});
}
/** /**
* Checks if a player is allowed to currently answer a question and sets it to the specified value * Checks if a player is allowed to currently answer a question and sets it to the specified value
* @param {String} playerId * @param {String} playerId

View File

@ -5,7 +5,8 @@ const Schema = mongoose.Schema;
const PlayerSchema = new Schema({ const PlayerSchema = new Schema({
name: { type: String, required: true, maxLength: 100 }, name: { type: String, required: true, maxLength: 100 },
points: { type: Number }, points: { type: Number },
acceptAnswers: { type: Boolean, default: false } acceptAnswers: { type: Boolean, default: false },
isChoosing: { type: Boolean, default: false },
}); });
// Export model // Export model

View File

@ -126,10 +126,18 @@ exports.handleMessage = ( gameSocketList, socket, dataRaw ) => {
break; break;
case "startGame": case "startGame":
if( socket.locals.isHost ){ if( socket.locals.isHost ){
let gameOuter;
gameController.findGameByIdAndSetStateAndPopulateBoard( socket.locals.game, "IN_PROGRESS" ) gameController.findGameByIdAndSetStateAndPopulateBoard( socket.locals.game, "IN_PROGRESS" )
.then( ( game ) => { .then( ( game ) => {
gameOuter = game;
let randomPlayerIndex = crypto.randomInt(0, game.players.length );
let randomPlayer = game.players[randomPlayerIndex];
let otherPlayers = game.players.splice(randomPlayerIndex, 1);
return playerController.setPlayerIsChoosingAndOthersNotChoosing( randomPlayer, otherPlayers );
})
.then( ( choosingPlayer ) => {
let message = "Game is starting"; let message = "Game is starting";
let sendingData = { gameId: game._id, board: game.board }; let sendingData = { gameId: gameOuter._id, board: gameOuter.board, choosingPlayer: choosingPlayer._id };
sendAllPlayers( socket, gameSocketList, "gameStarted", message, sendingData); sendAllPlayers( socket, gameSocketList, "gameStarted", message, sendingData);
resolve(); resolve();
}) })
@ -150,6 +158,20 @@ exports.handleMessage = ( gameSocketList, socket, dataRaw ) => {
reject( new Error("Message not sent by host") ); reject( new Error("Message not sent by host") );
} }
break; break;
case "playerChooseBoardEntry":
playerController.checkPlayerCanChoose()
.then( ( canChoose ) => {
if( canChoose ){
let message = `BoardEntry ${payload.boardEntryIndex} selected`;
let sendingData = { categoryIndex: payload.categoryIndex, boardEntryIndex: payload.boardEntryIndex };
sendAllPlayers( socket, gameSocketList, "boardEntrySelected", message, sendingData );
resolve();
} else {
resolve();
}
})
.catch();
break;
case "selectBoard": case "selectBoard":
if( socket.locals.isHost ){ if( socket.locals.isHost ){
let message = "Board selected"; let message = "Board selected";

View File

@ -12,6 +12,10 @@ const props = defineProps({
type: Boolean, type: Boolean,
default: true, default: true,
}, },
isPlayerChoosing: {
type: Boolean,
default: false,
},
}); });
const emit = defineEmits(["boardEntryCardClicked", "boardEntryAnsweredClicked", "boardEntryAnsweredRevertClicked" ]); const emit = defineEmits(["boardEntryCardClicked", "boardEntryAnsweredClicked", "boardEntryAnsweredRevertClicked" ]);
@ -42,7 +46,7 @@ function boardEntryAnsweredRevertClicked(){
{ 'border-pink-accent-primary-disabled' : props.boardEntry.isAnswered }, { 'border-pink-accent-primary-disabled' : props.boardEntry.isAnswered },
{ 'border-pink-accent-primary' : !props.boardEntry.isAnswered }, { 'border-pink-accent-primary' : !props.boardEntry.isAnswered },
{ 'bg-dark-primary': props.boardEntry.isAnswered }, { 'bg-dark-primary': props.boardEntry.isAnswered },
{ 'pointer': !props.boardEntry.isAnswered && props.isHost }, { 'pointer': !props.boardEntry.isAnswered && ( props.isHost || props.isPlayerChoosing ) },
]" ]"
@click="questionCardClicked" @click="questionCardClicked"
> >

View File

@ -226,6 +226,8 @@ function showBoard(){
function boardEntryClicked( cIndex, entryIndex ){ function boardEntryClicked( cIndex, entryIndex ){
if( gameStore.isHost ){ if( gameStore.isHost ){
gameStore.sendEvent( "selectBoardEntry", { categoryIndex: cIndex, boardEntryIndex: entryIndex } ); gameStore.sendEvent( "selectBoardEntry", { categoryIndex: cIndex, boardEntryIndex: entryIndex } );
} else if( gameStore.isPlayerChoosing ){
gameStore.sendEvent( "playerChooseBoardEntry", { categoryIndex: cIndex, boardEntryIndex: entryIndex } );
} }
} }
@ -390,6 +392,7 @@ onBeforeRouteLeave((to, from) => {
:bEIndex="boardEntryIndex" :bEIndex="boardEntryIndex"
:showingBottomView="true" :showingBottomView="true"
:isHost="gameStore.isHost" :isHost="gameStore.isHost"
:isPlayerChoosing="gameStore.isPlayerChoosing"
:anyPlayerIsAnswering="anyPlayerIsAnswering" :anyPlayerIsAnswering="anyPlayerIsAnswering"
:isBeingPlayed="isBeingPlayed" :isBeingPlayed="isBeingPlayed"
@showBoard="showBoard" @showBoard="showBoard"

View File

@ -29,6 +29,9 @@ function boardSelected( id ){
onMounted( () => { onMounted( () => {
gameStore.addSocketListener("gameStarted", ( data ) => { gameStore.addSocketListener("gameStarted", ( data ) => {
if( !gameStore.isHost ){
gameStore.isPlayerChoosing = data.payload.choosingPlayer === gameStore.playerId;
}
router.push( { name: "gameWithGameId", params: { gameId: route.params.gameId } } ); router.push( { name: "gameWithGameId", params: { gameId: route.params.gameId } } );
}); });

View File

@ -12,12 +12,16 @@ const props = defineProps({
type: Boolean, type: Boolean,
default: true, default: true,
}, },
isPlayerChoosing: {
type: Boolean,
default: false,
},
}); });
const emit = defineEmits(["boardEntryClicked", "questionAnswered", "questionAnsweredRevert" ]) const emit = defineEmits(["boardEntryClicked", "questionAnswered", "questionAnsweredRevert" ])
function boardEntryCardClicked( categoryIndex, boardEntryIndex ){ function boardEntryCardClicked( categoryIndex, boardEntryIndex ){
if( props.isHost ){ if( props.isHost || props.isPlayerChoosing ){
emit("boardEntryClicked", categoryIndex, boardEntryIndex); emit("boardEntryClicked", categoryIndex, boardEntryIndex);
} }
} }
@ -41,7 +45,8 @@ function boardEntryCardClicked( categoryIndex, boardEntryIndex ){
/> />
<template v-for="( boardEntry, boardEntryIndex ) of category.boardEntries" :key="boardEntryIndex"> <template v-for="( boardEntry, boardEntryIndex ) of category.boardEntries" :key="boardEntryIndex">
<BoardEntryCard <BoardEntryCard
:isHost="isHost" :isHost="props.isHost"
:isPlayerChoosing="props.isPlayerChoosing"
:isBeingPlayed="props.isBeingPlayed" :isBeingPlayed="props.isBeingPlayed"
:boardEntry="boardEntry" :boardEntry="boardEntry"
@boardEntryCardClicked="boardEntryCardClicked( categoryIndex, boardEntryIndex )" @boardEntryCardClicked="boardEntryCardClicked( categoryIndex, boardEntryIndex )"

View File

@ -29,7 +29,11 @@ const props = defineProps({
isBeingPlayed: { isBeingPlayed: {
type: Boolean, type: Boolean,
default: true, default: true,
} },
isPlayerChoosing: {
type: Boolean,
default: false,
},
}); });
const emit = defineEmits(["boardEntryClicked", "specificQuestionLayerSelected", "showBoard", "playerBuzzered", "playAudio", "stopAudio", const emit = defineEmits(["boardEntryClicked", "specificQuestionLayerSelected", "showBoard", "playerBuzzered", "playAudio", "stopAudio",
@ -119,6 +123,7 @@ watch(
:board="props.board" :board="props.board"
:isHost="props.isHost" :isHost="props.isHost"
:isBeingPlayed="props.isBeingPlayed" :isBeingPlayed="props.isBeingPlayed"
:isPlayerChoosing="props.isPlayerChoosing"
@boardEntryClicked="boardEntryClicked" @boardEntryClicked="boardEntryClicked"
@questionAnswered="questionAnswered" @questionAnswered="questionAnswered"
@questionAnsweredRevert="questionAnsweredRevert" @questionAnsweredRevert="questionAnsweredRevert"

View File

@ -23,6 +23,7 @@ export const useGameStore = defineStore('game', {
currentQuestion: {}, currentQuestion: {},
board: new Board( undefined, "New Board", []), board: new Board( undefined, "New Board", []),
acceptAnswers: false, acceptAnswers: false,
isPlayerChoosing: false,
} }
}, },
actions: { actions: {