You're right, in the network tab, there's no AJAX call and therefore it's in my js file.
I looked at it a lot and I can't figure out why tho
I thought it may be cause by the default content in onUpdateActionButtons with the condtion on this.isCurrentPlayerActive() but commenting lines didn't solve the issue. The other parts of the file look fine. Maybe I don't see something?
I hate dumping code but here, as I don't really know which part is concerned, I think it's better to entirely link it:
Code: Select all
/**
*------
* BGA framework: Gregory Isabelli & Emmanuel Colin & BoardGameArena
* TimebombBGA implementation : © <Your name here> <Your email address here>
*
* This code has been produced on the BGA studio platform for use on http://boardgamearena.com.
* See http://en.boardgamearena.com/#!doc/Studio for more information.
* -----
*
* timebombbga.js
*
* TimebombBGA user interface script
*
* In this file, you are describing the logic of your user interface, in Javascript language.
*
*/
define([
"dojo","dojo/_base/declare",
"ebg/core/gamegui",
"ebg/counter"
],
function (dojo, declare) {
return declare("bgagame.timebombbga", ebg.core.gamegui, {
constructor: function(){
console.log('timebombbga constructor');
// Here, you can init the global variables of your user interface
// Example:
// this.myGlobalValue = 0;
},
/*
setup:
This method must set up the game user interface according to current game situation specified
in parameters.
The method is called each time the game interface is displayed to a player, ie:
_ when the game starts
_ when a player refreshes the game page (F5)
"gamedatas" argument contains all datas retrieved by your "getAllDatas" PHP method.
*/
setup: function( gamedatas )
{
console.log( "Starting game setup" );
this.updateBoard(gamedatas);
// Setup game notifications to handle (see "setupNotifications" method below)
this.setupNotifications();
console.log( "Ending game setup" );
},
///////////////////////////////////////////////////
//// Game & client states
// onEnteringState: this method is called each time we are entering into a new game state.
// You can use this method to perform some user interface changes at this moment.
//
onEnteringState: function( stateName, args )
{
console.log( 'Entering state: '+stateName );
switch( stateName )
{
case 'playerTurn':
console.log("onEnteringState", stateName, args);
// Remove all event listeners and classes
let cards = document.querySelectorAll('.card-clickable');
cards.forEach(card => {
card.classList.remove('card-clickable');
});
// Add class to cards of everyone else for the current player to play
if (this.isCurrentPlayerActive()) {
let boards = document.getElementsByClassName('board');
// For each board of boards
for (let i = 0; i < boards.length; i++) {
let board = boards[i];
if (board.getAttribute('data-player-id') === args.active_player) {
continue;
}
let cardsDiv = board.querySelectorAll('.card');
cardsDiv.forEach(card => {
if (card.classList.contains('card-state-hidden')) card.classList.add('card-clickable');
});
}
}
break;
}
},
// onLeavingState: this method is called each time we are leaving a game state.
// You can use this method to perform some user interface changes at this moment.
//
onLeavingState: function( stateName )
{
console.log( 'Leaving state: '+stateName );
switch( stateName )
{
case 'dummmy':
break;
}
},
updateBoard: function(gamedatas) {
console.log("updateBoard", gamedatas);
// Empty boards div
let boardsDiv = document.getElementById('boards');
boardsDiv.innerHTML = '';
let activePlayerId = gamedatas.active_player;
let orderedAnnounces = [];
for (let i = 0; i < gamedatas.announces.length; i++) {
let announce = gamedatas.announces[i];
orderedAnnounces[announce['player_id']+'_'+announce['type']] = announce['qty'];
}
// Setting up player boards
for( var player_id in gamedatas.players )
{
let player = gamedatas.players[player_id];
let ucRole = this.ucfirst(player.role);
let playerBoardDiv = $('player_board_'+player_id);
dojo.place(this.format_block('jstpl_player_board', player), playerBoardDiv);
let roleDiv = playerBoardDiv.getElementsByClassName('role_'+player_id)[0];
let wiresDiv = playerBoardDiv.getElementsByClassName('wires_'+player_id)[0];
let bombDiv = playerBoardDiv.getElementsByClassName('bomb_'+player_id)[0];
roleDiv.classList.add('role-'+player.role);
let announceWires = orderedAnnounces[player_id+'_wire'];
if (announceWires !== undefined) {
wiresDiv.innerHTML = announceWires;
}
let announceBomb = orderedAnnounces[player_id+'_bomb'];
if (announceBomb !== undefined) {
bombDiv.innerHTML = announceBomb;
}
let cardsForPlayer = gamedatas.cards.filter(card => card.owner === player_id);
// Div for player's board
let boardDiv = document.createElement('div');
boardDiv.classList.add('board', 'flex', 'flex-col', 'items-center', 'gap-2', 'p-2', 'whiteblock');
boardDiv.setAttribute('data-player-id', player_id);
if (player_id === activePlayerId) {
boardDiv.classList.add('active-player');
}
boardsDiv.appendChild(boardDiv);
// Div for player's name
let playerNameDiv = document.createElement('h3');
playerNameDiv.classList.add('text-center');
playerNameDiv.textContent = player.name;
boardDiv.appendChild(playerNameDiv);
// Div container for player's cards
let cardsDivContainer = document.createElement('div');
cardsDivContainer.classList.add('flex', 'items-center', 'gap-2', 'border');
boardDiv.appendChild(cardsDivContainer);
// Each div for player's card
cardsForPlayer.forEach(card => {
let cardImg = document.createElement('div');
cardImg.classList.add('card', 'card-'+card.type);
cardImg.setAttribute('data-card-id', card.id);
cardImg.classList.add('card-state-'+card.state);
cardsDivContainer.appendChild(cardImg);
});
}
document.querySelectorAll('.card').forEach(square => square.addEventListener('click', e => this.onCardClick(e)));
document.querySelectorAll('.announceButton').forEach(div => div.addEventListener('click', e => this.announce(e)));
},
// onUpdateActionButtons: in this method you can manage "action buttons" that are displayed in the
// action status bar (ie: the HTML links in the status bar).
//
onUpdateActionButtons: function( stateName, args )
{
console.log( 'onUpdateActionButtons: '+stateName );
if( this.isCurrentPlayerActive() )
{
switch( stateName )
{
/*
Example:
case 'myGameState':
// Add 3 action buttons in the action status bar:
this.addActionButton( 'button_1_id', _('Button 1 label'), 'onMyMethodToCall1' );
this.addActionButton( 'button_2_id', _('Button 2 label'), 'onMyMethodToCall2' );
this.addActionButton( 'button_3_id', _('Button 3 label'), 'onMyMethodToCall3' );
break;
*/
}
}
},
///////////////////////////////////////////////////
//// Utility methods
/*
Here, you can defines some utility methods that you can use everywhere in your javascript
script.
*/
ucfirst: function(str) {
if (str.length === 0) {
return str;
}
return str.charAt(0).toUpperCase() + str.slice(1);
},
///////////////////////////////////////////////////
//// Player's action
/*
Here, you are defining methods to handle player's action (ex: results of mouse click on
game objects).
Most of the time, these methods:
_ check the action is possible at this game state.
_ make a call to the game server
*/
onCardClick: function(e) {
e.preventDefault();
e.stopPropagation();
let card = e.target;
if (!card.classList.contains('card-clickable')) return;
let card_id = card.getAttribute('data-card-id');
this.bgaPerformAction("cut", {
card_id: card_id
});
},
announce: function(e) {
e.preventDefault();
e.stopPropagation();
let button = e.target;
let qty = button.getAttribute('data-qty');
let type = button.getAttribute('data-type');
this.bgaPerformAction("announce", {
type: type,
qty: qty
});
},
///////////////////////////////////////////////////
//// Reaction to cometD notifications
/*
setupNotifications:
In this method, you associate each of your game notifications with your local method to handle it.
Note: game notification names correspond to "notifyAllPlayers" and "notifyPlayer" calls in
your timebombbga.game.php file.
*/
setupNotifications: function()
{
console.log( 'notifications subscriptions setup' );
const notifs = [
['cut', 500],
['nextround', 2000],
['goodteam', 100],
['badteam', 100],
['beforegameend', 5000],
];
notifs.forEach((notif) => {
dojo.subscribe(notif[0], this, `notif_${notif[0]}`);
this.notifqueue.setSynchronous(notif[0], notif[1]);
});
},
notif_cut: function(notif) {
let card_id = notif.args.card_id;
let card_type = notif.args.card_type;
let card = document.querySelector(`.card[data-card-id="${card_id}"]`);
card.classList.remove('card-unknown');
card.classList.add(`card-${card_type}`);
card.classList.remove('card-state-hidden');
card.classList.add('card-state-revealed');
},
notif_nextround: function(notif) {
let gamedatas = notif.args.gamedatas;
this.updateBoard(gamedatas);
},
notif_beforegameend: function(notif) {
let gamedatas = notif.args.gamedatas;
this.updateBoard(gamedatas);
},
notif_goodteam: function(notif) {
},
notif_badteam: function(notif) {
},
});
});
Do you see where I made a mistake in it?
Once again, thanks!