Page 1 of 2

Help - checkAction not working properly

Posted: 19 October 2020, 08:05
by stefano
I've some issue with checkAction function. I want to test if the possible action is allowed, but even if the state machine seems to be configured properly, it replies with a popup saying... "This is not your turn"

This is my code:

State Machine:

Code: Select all

    1 => array(
        "name" => "gameSetup",
        "description" => clienttranslate("Game setup"),
        "type" => "manager",
        "action" => "stGameSetup",
        "transitions" => array( "" => 2 )
    ),
    
    2 => array(
        "name" => "PlaceFruit",
		"description" => clienttranslate("Rolling the dice"),
        "type" => "game",
        "action" => "stPlaceFruit",
		"args" => "argPlaceFruit",
		"possibleactions" => array( "PlaceFruitDone"),
        "updateGameProgression" => true,      
        "transitions" => array( "PlayersTurn" => 3 )
    ),
    3 => array(
        "name" => "Playacard",
		"description" => clienttranslate("Play one card"),
        "type" => "multipleactiveplayer",
        "action" => "stPlayacard",
        //"updateGameProgression" => true,      
		"possibleactions" => array( 'Playacard' ),		
        "transitions" => array( "Applyaction" => 4 )
    ),
Game PHP:

Code: Select all

	function gPlaceFruitDone()
	{
		$this->gamestate->nextState( 'PlayersTurn' );
	}
	
	function stPlaceFruit()
	{
		$result1 = bga_rand(1, 6);
		$result2 = bga_rand(1, 6);
		self::setGameStateValue('diceFace1', $result1 );
		self::setGameStateValue('diceFace2', $result2 );

		$sql = "UPDATE fruits SET numbers=numbers+1 WHERE treelevel = '$result1'";
		self::DbQuery( $sql );
		$sql = "UPDATE fruits SET numbers=numbers+1 WHERE treelevel = '$result2'";
		self::DbQuery( $sql );
	}
	function argPlaceFruit()
	{
		$result1 = self::getGameStateValue('diceFace1');
		$result2 = self::getGameStateValue('diceFace2');
        return array(
            'diceresult1' => $result1,
			'diceresult2' => $result2,
        );
	}
Javascript:

Code: Select all

        onEnteringState: function( stateName, args )
        {
           console.log( 'Entering state: '+stateName );
            
            switch( stateName )
            {
            case 'PlaceFruit':

				console.log( "Dice result: " + args.args.diceresult1 + " " + args.args.diceresult2);
         		//replace all of this kind with dojo.byId() at BGA Studio
				dice1=document.getElementById("dice1");
				dice2=document.getElementById("dice2");
				diceresult1=document.getElementById("diceresult1");
				diceresult2=document.getElementById("diceresult2");
				message=document.getElementById("message");   
				message.value="the result is "+args.args.diceresult1 + " " + args.args.diceresult2;
				dice1.className ="rolled1";
				dice2.className ="rolled2";
				diceresult1.className ="num1"+args.args.diceresult1;   
				diceresult2.className ="num2"+args.args.diceresult2;   
				//this.addFruitBoard( args.args.diceresult1, 1, 2337413 );
				//this.addFruitBoard( args.args.diceresult2, 2, 2337413 );
				this.onDiceCompleted();
                break;
            }
        },
        
                onDiceCompleted: function( evt )
        {
            console.log( 'PlaceFruitDone' );
            
            // Preventing default browser reaction
            //dojo.stopEvent( evt );

            // Check that this action is possible (see "possibleactions" in states.inc.php)
            if( ! this.checkAction( 'PlaceFruitDone' ) )
            {   
				console.log('Not PlaceFruitDone action!');
				//return; 
			}

            this.ajaxcall( "/snowtime/snowtime/PlaceFruitDone.html", {  }, 
                         this, function( result ) {
                            
                            // What to do after the server call if it succeeded
                            // (most of the time: nothing)
                            
                         }, function( is_error) {

                            // What to do after the server call in anyway (success or failure)
                            // (most of the time: nothing)

                         } );        
        },        

in Javascript, the this.checkAction( 'PlaceFruitDone' ) fails!!!

Re: Help - checkAction not working properly

Posted: 19 October 2020, 10:14
by Tisaac
Well, if this is the same statemachin as in previous post, the error probably come from the same thing : you need to make players active to let them play (you can see if a player is active by looking at the player board on top right), so you need to fix your other issue to solve this one also.

Re: Help - checkAction not working properly

Posted: 19 October 2020, 10:33
by stefano
Step 2 is a game state, so I guess no player should be active, right?

How can I check if the action is possible then?

I want to prevent that the javascript function is called twice, cause sometimes, randomly, I get invalid state transition "PlayersTurn"... it seems that the function is called one more time even after the transition...

Re: Help - checkAction not working properly

Posted: 19 October 2020, 10:39
by Tisaac
Wait, why are you doing this ?
Why would you need a hook to detect when animation is over ??

Re: Help - checkAction not working properly

Posted: 19 October 2020, 10:55
by stefano
Are you referring to onDiceCompleted ?

I am running an animation that displays two dice rolling (it's a common state of type "game"). When animation is over (but I'm not yet there... there is no wait function so far)... I want to move to step 3.

If I don't put the control of the actionpossibles, I sometimes get the invalid transition "PlayersTurn" like the onDiceCompleted is called twice...

Re: Help - checkAction not working properly

Posted: 19 October 2020, 11:15
by Tisaac
That's not the way you should do it. The server should not wait for an animation to end before going on.
You have to move to next state in state 2 directly (which will solv your "final state" error) and instead of running the animation in the onEnteringState, use a synchronous notification that will precisely do what you are looking for : waiting for the end of animation before updating the state.

Re: Help - checkAction not working properly

Posted: 19 October 2020, 12:12
by stefano
Could you help me with some code snippets?

Re: Help - checkAction not working properly

Posted: 19 October 2020, 13:01
by Victoria_La
Its documented here https://en.doc.boardgamearena.com/Game_ ... ifications
stefano wrote: 19 October 2020, 12:12 Could you help me with some code snippets?

Re: Help - checkAction not working properly

Posted: 19 October 2020, 13:23
by stefano
I don't understand how it applies to my case...

Re: Help - checkAction not working properly

Posted: 19 October 2020, 18:19
by stefano
I tried this:

Game PHP

Code: Select all

	function stPlaceFruit()
	{
		//$this->gamestate->setAllPlayersMultiactive();
		$result1 = bga_rand(1, 6);
		$result2 = bga_rand(1, 6);
		self::setGameStateValue('diceFace1', $result1 );
		self::setGameStateValue('diceFace2', $result2 );

		$sql = "UPDATE fruits SET numbers=numbers+1 WHERE treelevel = '$result1'";
		self::DbQuery( $sql );
		$sql = "UPDATE fruits SET numbers=numbers+1 WHERE treelevel = '$result2'";
		self::DbQuery( $sql );

		self::notifyAllPlayers( "DiceResult", clienttranslate( 'Dice rolled... result ' . $result1 . ' and ' . $result2 . '!' ),
					array('result1' => $result1,
						  'result2' => $result2));
		$this->gamestate->nextState( 'PlayersTurn' );						  

	}
JS:

Code: Select all

			
	   dojo.subscribe( 'DiceResult', this, "notif_DiceResult" );
            this.notifqueue.setSynchronous( 'DiceResult', 5500 );	
            
            
            		notif_DiceResult: function( notif )
        {
			console.log("AAA");
			console.log( "Dice result: " + notif.args.diceresult1 + " " + notif.args.diceresult2);
			//replace all of this kind with dojo.byId() at BGA Studio
			dice1=document.getElementById("dice1");
			dice2=document.getElementById("dice2");
			diceresult1=document.getElementById("diceresult1");
			diceresult2=document.getElementById("diceresult2");
			message=document.getElementById("message");   
			message.value="the result is "+notif.args.diceresult1 + " " + notif.args.diceresult2;
			dice1.className ="rolled1";
			dice2.className ="rolled2";
			diceresult1.className ="num1"+notif.args.diceresult1;   
			diceresult2.className ="num2"+notif.args.diceresult2;   
        },
		
I see the notification popping up, but The code inside the notif_DiceResult is not triggered... why?