T_void ClientReceiveGameStartPacket(
           T_packetEitherShortOrLong *p_packet)
{
    T_gameStartPacket *p_start ;
    T_word16 i ;
    T_directTalkUniqueAddress ourAddress ;
    T_gameGroupID groupID ;
	T_word16 levelStatus = LEVEL_STATUS_STARTED;

    DebugRoutine("ClientReceiveGameStartPacket") ;

//puts("ClientReceiveGameStartPacket") ;
    p_start = (T_gameStartPacket *)(p_packet->data) ;

    /* Set up the time offset. */
    MapSetDayOffset(p_start->timeOfDay) ;

    /* Only consider the packet if we are in the same group. */
//printf("-- %d %d\n", ClientSyncGetGameGroupID(), p_start->groupID) ;
    groupID = ClientSyncGetGameGroupID() ;
    if (CompareGameGroupIDs(groupID, p_start->groupID))  {
        DirectTalkGetUniqueAddress(&ourAddress) ;

        /* See if we are in the list. */
        for (i=0; i<p_start->numPlayers; i++)  {
            if (memcmp(&ourAddress, &p_start->players[i], sizeof(ourAddress)) == 0)
                break ;
        }
		//Level complete packet
		if (p_start->firstLevel == LEVEL_STATUS_LEVEL_CODE_COMPLETE ||
			p_start->firstLevel == LEVEL_STATUS_LEVEL_CODE_SUCCESS)
		{
			G_CompletedPlayers++;
			if (p_start->firstLevel == LEVEL_STATUS_LEVEL_CODE_SUCCESS)
				G_SuccessPlayers++;

			//if we got complete packets from everyone
			if (G_CompletedPlayers == p_start->numPlayers)
			{
				levelStatus = LEVEL_STATUS_COMPLETE;
				if (G_SuccessPlayers > 0)
					levelStatus |= LEVEL_STATUS_SUCCESS;

				TownUIFinishedQuest(levelStatus, p_start->numPlayers, StatsGetCurrentQuestNumber());

				//once all players respond, quit the game
				ClientSyncSetGameGroupID(*DirectTalkGetNullBlankUniqueAddress());
				PeopleHereSetOurAdventure(0);
				PeopleHereSetOurState(PLAYER_ID_STATE_NONE);
			}
		}
		/* Did we find a match? */
		else if (i != p_start->numPlayers)  
		{
			//Reset number of players completed
			G_CompletedPlayers = 0;
			G_SuccessPlayers = 0;

			//puts("Matched") ;
			/* Yes, we are on the list in the ith position. */
			/* Set up the game setup and go. */
			ClientSyncSetNumberPlayers(p_start->numPlayers);
			ClientSetLoginId(i);

			/* Set up the next jump */
			ClientSetNextPlace(p_start->firstLevel, 0);
			ClientSetAdventureNumber(p_start->adventure);
			ClientSyncInitPlayersHere();

			/* Clear all the messages */
			MessageClear();

			/* Copy all the player address over to the peophere module. */
			for (i = 0; i < p_start->numPlayers; i++)
			{
				PeopleHereSetUniqueAddr(i, (&p_start->players[i]));
			}
		}
		else 
		{
			//puts("Not Matched") ;
			/* Make sure we are still in the guild and if so drop us. */
			if ((PeopleHereGetOurLocation() == PLAYER_ID_LOCATION_GUILD) &&
				(PeopleHereGetOurState() == PLAYER_ID_STATE_JOINING_GAME))  {
				/* Cancel that game we were joining, it left without us. */
				GuildUICancelJoinGame(NULL);

				/* Nope, we got excluded. */
				MessageAdd("Game started without you.");
			}
		}
    }

    DebugEnd() ;
}
void StateProcess(void)
{
	double d;

	// Check that robot is in a safe state.
	if (!ROBOT_Safe(ROBOT_ID))
	{
		printf("Robot not safe.\n");
		ProgramExit();
	}

	// Special processing while a trial is running.
	if (TrialRunning)
	{
		if (!RobotActive())
		{
			// If robot is not active, abort current trial.
			ErrorRobotInactive();
			TrialAbort();
			MissTrial();
		}
		else
			if (FrameData.Full())
			{
				// Abort current trail if frame data is full.
				ErrorFrameDataFull();
				TrialAbort();
				MissTrial();
			}
	}

	// Some states are processing in the LoopTask.
	if (StateLoopTask[State])
	{
		return;
	}

	// State processing.
	switch (State)
	{
	case STATE_INITIALIZE:
		// Initialization state.
		if (TargetTestFlag)
		{
			break;
		}

		ExperimentTimer.Reset();
		StateNext(STATE_SETUP);
		break;

	case STATE_SETUP:


		// Setup details of next trial, but only when robot stationary and active.


		if (RobotNotMoving() && RobotActive())
		{
			printf("Dynamic learning: before Trialsetup i am here=====!!!!\n");
			TrialSetup();
			StateNext(STATE_HOME);
		}
		break;

	case STATE_HOME:
		// Start trial when robot in home position (and stationary and active).
		if (RobotNotMoving() && RobotHome() && RobotActive())
		{
			StateNext(STATE_START);
			break;
		}
		break;

	case STATE_START:
		// Start trial.
		TrialStart();
		StateNext(STATE_DELAY);
		break;

	case STATE_DELAY:
		// Delay period before go signal.
		if (StateTimer.ExpiredSeconds(TrialDelay))
		{
			StateNext(STATE_GO);
			break;
		}

		if (MovementStarted())
		{
			ErrorMoveTooSoon();
			TrialAbort();
			MissTrial();
		}
		break;

	case STATE_GO:
		// Wait until graphics state matches.
		if (State != StateGraphics)
		{
			break;
		}

		StateNext(STATE_TARGETWAIT);
		break;

	case STATE_TARGETWAIT:
		// Wait for estimated target display delay.
		if (GraphicsTargetTimer.ExpiredSeconds(GRAPHICS_DisplayDelayTarget(TargetPosition)))
		{
			// Target should be displayed now (within a few milliseconds).
			TriggerOn();
			MovementReactionTimer.Reset();
			BeepGo();
			StateNext(STATE_MOVEWAIT);
		}
		break;

	case STATE_MOVEWAIT:
		// Process in the robot forces function (LoopTask)
		break;

	case STATE_MOVING:
		// Process in the robot forces function (LoopTask)
		break;

	case STATE_FINISH:
		// Trial has finished so stop trial.
		TrialStop();

		// Save the data for this trial.
		if (!TrialSave())
		{
			printf("Cannot save Trial %d.\n", Trial);
			StateNext(STATE_EXIT);
			break;
		}

		// Catch too-slow trials.
		if (MovementDurationTime >= MovementDurationTimeOut)
		{
			ErrorMoveTimeOut();
			BeepError();
			InterTrialDelayTimer.Reset();
		}

		// Go to next trial, if there is one.
		if (TrialNext())
		{
			StateNext(STATE_INTERTRIAL);
		}
		else
		{
			StateNext(STATE_EXIT);
		}
		break;

	case STATE_INTERTRIAL:
		// Wait for the intertrial delay to expire.
		if (!InterTrialDelayTimer.ExpiredSeconds(InterTrialDelay))
		{
			break;
		}

		MessageClear();

		// Optional rest between blocks of trials.
		if (RestTrials != 0)
		{
			// Rest every X number of trials.
			if ((Trial % RestTrials) == 0)
			{
				StateNext(STATE_REST);
				break;
			}
		}

		StateNext(STATE_SETUP);
		break;

	case STATE_EXIT:
		ProgramExit();
		break;

	case STATE_TIMEOUT:
		switch (StateLast) // Which state had the timeout?
		{
		case STATE_MOVEWAIT:
			ErrorMoveWaitTimeOut();
			break;

		case STATE_MOVING:
			ErrorMoveTimeOut();
			break;

		default:
			ErrorMessage(STR_stringf("%s TimeOut", StateText[StateLast]));
			break;
		}

		TrialAbort(); // Abort the current trial.
		MissTrial();  // Generate miss trial.
		break;

	case STATE_ERROR:
		if (StateTimer.ExpiredSeconds(ErrorWait))
		{
			ErrorResume();
		}
		break;

	case STATE_REST:
		if (StateTimer.ExpiredSeconds(RestWait))
		{
			StateNext(STATE_SETUP);
		}
		break;
	}
}