Пример #1
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CTeamplayRules::Think ( void )
{
	BaseClass::Think();

	///// Check game rules /////

	if ( g_fGameOver )   // someone else quit the game already
	{
		BaseClass::Think();
		return;
	}

	float flTimeLimit = mp_timelimit.GetFloat() * 60;
	
	if ( flTimeLimit != 0 && gpGlobals->curtime >= flTimeLimit )
	{
		ChangeLevel();
		return;
	}

	float flFragLimit = fraglimit.GetFloat();
	if ( flFragLimit )
	{
		// check if any team is over the frag limit
		for ( int i = 0; i < num_teams; i++ )
		{
			if ( team_scores[i] >= flFragLimit )
			{
				ChangeLevel();
				return;
			}
		}
	}
}
Пример #2
0
//************************************************************************
void CNutDropScene::OnCommand (HWND hWnd, int id, HWND hControl, UINT codeNotify)
//************************************************************************
{
	switch (id)
	{
		case IDC_LEVEL1:
		case IDC_LEVEL2:
		case IDC_LEVEL3:
		{
			int iLevel = id-IDC_LEVEL1;
		 	if (iLevel >= NUM_LEVELS)
		 		iLevel = NUM_LEVELS-1;
			PlayClickWave();
			ChangeLevel (iLevel);
			break;
		}

		case IDC_HELP:
		{
			PlayIntro(NULL);
			break;
		}

		default:
			CGBScene::OnCommand (hWnd, id, hControl, codeNotify);
			break;
	}
}
Пример #3
0
void Game_Actor::ChangeExp(int exp, bool level_up_message) {
	int new_level = GetLevel();
	int new_exp = min(max(exp, 0), max_exp_value());

	if (new_exp > GetExp()) {
		for (int i = GetLevel() + 1; i <= GetMaxLevel(); ++i) {
			if (GetNextExp(new_level) != -1 && GetNextExp(new_level) > new_exp) {
				break;
			}
			new_level++;
		}
	} else if (new_exp < GetExp()) {
		for (int i = GetLevel(); i > 1; --i) {
			if (new_exp >= GetNextExp(i - 1)) {
				break;
			}
			new_level--;
		}
	}

	SetExp(new_exp);

	if (new_level != GetLevel()) {
		ChangeLevel(new_level, level_up_message);
	}
}
Пример #4
0
bool LevelManager::Update()
{

    GameLevel* nextLevel = LevelManager::currentLevel->OnUpdate();
    if(nextLevel == NULL)
        return false;
    if(nextLevel != currentLevel)
        ChangeLevel(nextLevel);
    return true;
}
Пример #5
0
int UserInput(Game * game) {
	int key = get_char();
	if (key == 'l') {
		ChangeLevel(game);
	} else if (key == 'r') {
		Megamaniac();
	} else if (key == 'p') {
		// Pause Game.
	} else if (key == 'q') {
		exit(0);
	}
	return key;
}
Пример #6
0
bool CHL2MPRules::CheckGameOver()
{
#ifndef CLIENT_DLL
    if ( g_fGameOver )   // someone else quit the game already
    {
        // check to see if we should change levels now
        if ( m_flIntermissionEndTime < gpGlobals->curtime )
        {
            ChangeLevel(); // intermission is over
        }

        return true;
    }
#endif

    return false;
}
Пример #7
0
// This is my primary Event Loop. This is where most of the fun stuff happens ;)
void Megamaniac() {
    // WTF does this do? Something to do with my Data Structure I assume...
    Game game;

	while (true) {
	    // Let's run our initial setup to get everything for the game ready.
	    SetupGame(&game);

	    // Do we need to change the level? Not really but we should probably start at Level 1.
	    ChangeLevel(&game);

		// This is where the Event Loop actually starts. This will run repeatedly until our game is over.
	    while (!game.game_over) {
		    clear_screen();
		    GameStats(&game);
			int userInput = UserInput(&game);
		    MovementPlayer(&game, userInput);
			MovementMissiles(&game, userInput);
		    MovementAliens(&game);
			MovementBombs(&game);
			MovementBonuses(&game);

			CollisionMissiles(&game);
			CollisionAliens(&game);
		    CollisionBombs(&game);
			CollisionBonuses(&game);

			UpdateScreen(&game);
		    show_screen();
		    timer_pause(25);
	    }

		GameOver(&game);

		int userInput = wait_char();
		while (userInput != 'r' && userInput >= 0) {
			if (userInput == 'q') {
				exit(0);
			}
			if (userInput == 'r') {
				Megamaniac();
			}
			userInput = wait_char();
		}
	}
}
Пример #8
0
int GameSetupScreen::Update(float p_dt,std::vector<UserCMD>* userCMD )
{
	MenuScreen::Update(p_dt, userCMD);
	if (timeSinceLastChange[0]>0.5)
	{
		if (userCMD->at(0).aButtonPressed || userCMD->at(0).startButtonPressed)
		{
			SaveInfo();
			return JOIN_GAME_SCREEN;
		}
		if (userCMD->at(0).backButtonPressed)
		{
			timeSinceLastChange[0] = 0;
			return MAIN_MENU_SCREEN;
		} 
	}
	if (timeSinceLastChange[0]>0.1)
	{
		ChangeLevel(userCMD);
		ChangeNumberOfLaps(userCMD);
	}
	return GAME_SETUP_SCREEN;
}
Пример #9
0
	//=========================================================
	//=========================================================
	void CMultiplayRules::Think ( void )
	{
		BaseClass::Think();
		
		///// Check game rules /////

		if ( g_fGameOver )   // someone else quit the game already
		{
			ChangeLevel(); // intermission is over
			return;
		}

		float flTimeLimit = mp_timelimit.GetFloat() * 60;
		float flFragLimit = fraglimit.GetFloat();
		
		if ( flTimeLimit != 0 && gpGlobals->curtime >= flTimeLimit )
		{
			GoToIntermission();
			return;
		}

		if ( flFragLimit )
		{
			// check if any player is over the frag limit
			for ( int i = 1; i <= gpGlobals->maxClients; i++ )
			{
				CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );

				if ( pPlayer && pPlayer->FragCount() >= flFragLimit )
				{
					GoToIntermission();
					return;
				}
			}
		}
	}
Пример #10
0
LRESULT CALLBACK PopupProc(HWND hWnd, UINT uMsg,
			   WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CREATE:

	// Get the window and client dimensions

	GetClientRect(hWnd, &popup.rect);

	int width = popup.rect.right - popup.rect.left;
	int height = popup.rect.bottom - popup.rect.top;

	// Create level control

	level.hwnd =
	    CreateWindow(TRACKBAR_CLASS, NULL,
			 WS_VISIBLE | WS_CHILD |
			 TBS_VERT | TBS_NOTICKS,
			 0, 0,
			 width, height, hWnd,
			 (HMENU)LEVEL_ID, hInst, NULL);

	// Set the slider range

	SendMessage(level.hwnd, TBM_SETRANGE, TRUE,
		    MAKELONG(MIN_VOL, MAX_VOL));
	SendMessage(level.hwnd, TBM_SETPAGESIZE, 0, STEP_VOL);

	// Add level to tooltip

	tooltip.info.uId = (UINT_PTR)level.hwnd;
	tooltip.info.lpszText = "Input level";

	SendMessage(tooltip.hwnd, TTM_ADDTOOL, 0,
		    (LPARAM) &tooltip.info);

	if (mixer.pmxcd != NULL)
	{
	    // Get the value

	    mixerGetControlDetails((HMIXEROBJ)mixer.hmx, mixer.pmxcd,
				   MIXER_GETCONTROLDETAILSF_VALUE);

	    // Set the slider

	    int value = MAX_VOL - (mixer.pmxcdu->dwValue * (MAX_VOL - MIN_VOL) /
				   (mixer.pmxc->Bounds.dwMaximum -
				    mixer.pmxc->Bounds.dwMinimum));

	    SendMessage(level.hwnd, TBM_SETPOS, TRUE, value);
	}

	else
	    EnableWindow(level.hwnd, FALSE);

	break;

	// Level control

    case WM_VSCROLL:
	ChangeLevel(wParam, lParam);

	// Set the focus back to the window

	SetFocus(hWnd);
	break;

	// Focus lost

    case WM_KILLFOCUS:
	FocusLost(hWnd, wParam, lParam);
	break;

	// Everything else

    default:
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }

    return 0;
}
Пример #11
0
void CHL2MPRules::Think( void )
{

#ifndef CLIENT_DLL

    CGameRules::Think();

    if ( g_fGameOver )   // someone else quit the game already
    {
        // check to see if we should change levels now
        if ( m_flIntermissionEndTime < gpGlobals->curtime )
        {
            if ( !m_bChangelevelDone )
            {
                ChangeLevel(); // intermission is over
                m_bChangelevelDone = true;
            }
        }

        return;
    }

//	float flTimeLimit = mp_timelimit.GetFloat() * 60;
    float flFragLimit = fraglimit.GetFloat();

    if ( GetMapRemainingTime() < 0 )
    {
        GoToIntermission();
        return;
    }

    if ( flFragLimit )
    {
        if( IsTeamplay() == true )
        {
            CTeam *pCombine = g_Teams[TEAM_COMBINE];
            CTeam *pRebels = g_Teams[TEAM_REBELS];

            if ( pCombine->GetScore() >= flFragLimit || pRebels->GetScore() >= flFragLimit )
            {
                GoToIntermission();
                return;
            }
        }
        else
        {
            // check if any player is over the frag limit
            for ( int i = 1; i <= gpGlobals->maxClients; i++ )
            {
                CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );

                if ( pPlayer && pPlayer->FragCount() >= flFragLimit )
                {
                    GoToIntermission();
                    return;
                }
            }
        }
    }

    if ( gpGlobals->curtime > m_tmNextPeriodicThink )
    {
        CheckAllPlayersReady();
        CheckRestartGame();
        m_tmNextPeriodicThink = gpGlobals->curtime + 1.0;
    }

    if ( m_flRestartGameTime > 0.0f && m_flRestartGameTime <= gpGlobals->curtime )
    {
        RestartGame();
    }

    if( m_bAwaitingReadyRestart && m_bHeardAllPlayersReady )
    {
        UTIL_ClientPrintAll( HUD_PRINTCENTER, "All players ready. Game will restart in 5 seconds" );
        UTIL_ClientPrintAll( HUD_PRINTCONSOLE, "All players ready. Game will restart in 5 seconds" );

        m_flRestartGameTime = gpGlobals->curtime + 5;
        m_bAwaitingReadyRestart = false;
    }

    ManageObjectRelocation();

#endif
}
Пример #12
0
//=========================================================
//=========================================================
void CHalfLifeMultiplay :: Think ( void )
{
	g_VoiceGameMgr.Update(gpGlobals->frametime);

	///// Check game rules /////
	static int last_frags;
	static int last_time;

	int frags_remaining = 0;
	int time_remaining = 0;

	if ( g_fGameOver )   // someone else quit the game already
	{
		if ( m_flIntermissionEndTime < gpGlobals->time )
		{
			if ( m_iEndIntermissionButtonHit  // check that someone has pressed a key, or the max intermission time is over
				|| ((m_flIntermissionEndTime + MAX_INTERMISSION_TIME) < gpGlobals->time) ) 
				ChangeLevel(); // intermission is over
		}
		return;
	}

	float flTimeLimit = timelimit.value * 60;
	float flFragLimit = fraglimit.value;
	
	time_remaining = (int)(flTimeLimit ? ( flTimeLimit - gpGlobals->time ) : 0);

	if ( flTimeLimit != 0 && gpGlobals->time >= flTimeLimit )
	{
		GoToIntermission();
		return;
	}

	if ( flFragLimit )
	{
		int bestfrags = 9999;
		int remain;

		// check if any player is over the frag limit
		for ( int i = 1; i <= gpGlobals->maxClients; i++ )
		{
			CBaseEntity *pPlayer = UTIL_PlayerByIndex( i );

			if ( pPlayer && pPlayer->pev->frags >= flFragLimit )
			{
				GoToIntermission();
				return;
			}


			if ( pPlayer )
			{
				remain = static_cast<int>(flFragLimit - pPlayer->pev->frags);
				if ( remain < bestfrags )
				{
					bestfrags = remain;
				}
			}

		}
		frags_remaining = bestfrags;
	}

	// Updates when frags change
	if ( frags_remaining != last_frags )
	{
		g_engfuncs.pfnCvar_DirectSet( &fragsleft, UTIL_VarArgs( "%i", frags_remaining ) );
	}

	// Updates once per second
	if ( timeleft.value != last_time )
	{
		g_engfuncs.pfnCvar_DirectSet( &timeleft, UTIL_VarArgs( "%i", time_remaining ) );
	}

	last_frags = frags_remaining;
	last_time  = time_remaining;
}
//Process
bool cGame::Process()
{
	bool res=true;
	
	//Process Input
	if(keys[27])	res=false;	

	char attackSide = 0;
	//Game Logic
	if (Player.isBeingPushed())					Player.pushMove(Scene.GetMap());
	else if(keys['z'] && !Player.isAttacking())
	{
		Player.Attack(allSwords, &attackSide);
		DetectCollisionPlayerAttack(&attackSide, false);
	}
	else if(keys[GLUT_KEY_UP])					Player.MoveUp(Scene.GetMap());
	else if(keys[GLUT_KEY_DOWN])				Player.MoveDown(Scene.GetMap());
	else if(keys[GLUT_KEY_LEFT])				Player.MoveLeft(Scene.GetMap());
	else if(keys[GLUT_KEY_RIGHT])				Player.MoveRight(Scene.GetMap());
	else Player.Stop();

	if (allSwords.size() > 0) DetectCollisionPlayerAttack(&attackSide, true);

	std::vector<int> swordPositionsToErase;
	for (int i = 0; i < allSwords.size(); ++i) {
		allSwords[i].Move(Scene.GetMap());
		int state = allSwords[i].GetState();
		if (state != STATE_WALKRIGHT && state != STATE_WALKLEFT && state != STATE_WALKUP && state != STATE_WALKDOWN) {
			swordPositionsToErase.push_back(i);
		}
	}

	for (int j = 0; j < swordPositionsToErase.size(); ++j) {
		allSwords.erase(allSwords.begin()+swordPositionsToErase[j]);
	}

	//dogs behaviour
	for (int i = 0; i < allDogs.size(); ++i){
		if (allDogs[i].isBeingPushed()) allDogs[i].pushMove(Scene.GetMap());
		else allDogs[i].Move(Scene.GetMap(), Player.GetPositionX(), Player.GetPositionY());
	}

	//octopus behaviour
	int playerX, playerY;
	Player.GetPosition(&playerX,&playerY);
	for (int i = 0; i < allOctopus.size(); ++i) {
		if (allOctopus[i].isBeingPushed()) allOctopus[i].pushMove(Scene.GetMap());
		else allOctopus[i].Move(Scene.GetMap(), playerX, playerY);
		if (allOctopus[i].hasBall()) {
			allOctopus[i].getBall()->Move(Scene.GetMap());
			int state = allOctopus[i].getBall()->GetState();
			if (state != STATE_WALKRIGHT && state != STATE_WALKLEFT && state != STATE_WALKUP && state != STATE_WALKDOWN) {
				allOctopus[i].setHasBall(false);
				allOctopus[i].getBall()->SetPosition(-1,-1);
			}
		}
	}

	if (levelKind == LEVEL_BOSS) Isaac.Attack(playerX, playerY);

	std::vector<int> tearPositionsToErase;
	for (int i=0; i < Isaac.getAllTears()->size(); ++i) {
		Isaac.getTear(i)->Move(Scene.GetMap());
		int state = Isaac.getTear(i)->GetState();
		if (state == STATE_LOOKLEFT) {
			tearPositionsToErase.push_back(i);
		}
	}
	for (int j=0; j < tearPositionsToErase.size(); ++j) {
		Isaac.deleteTear(tearPositionsToErase[j]);
	}

	if (!Player.isInvincible()) DetectCollisionsPlayer();

	/*
	if (Player.isDead()) {
		music.stop();
		if (!music.openFromFile("resources/music/gameover.ogg")) {
		//error
		}
		music.play();
	}*/
	
	ChangeLevel();
	closeBossRoom();

	return res;
}
Пример #14
0
void MainWindow::SetLevel(float level) {
  CHECK_LE(level, 1.0);
  CHECK_GT(level, 0.0);
  ChangeLevel(level * max_slider_level_ + 0.5f);
}
Пример #15
0
void CHeadQuartersRules :: Think ( void )
{	
	if( gamemode.value != 4 )
		SERVER_COMMAND( "restart\n" );

	HeadQThink();

	g_VoiceGameMgr.Update(gpGlobals->frametime);

	///// Check game rules /////
	static int last_frags;
	static int last_time;

	int frags_remaining = 0;
	int time_remaining = 0;

	if ( g_fGameOver )   // someone else quit the game already
	{
		// bounds check
		int time = (int)CVAR_GET_FLOAT( "mp_chattime" );
		if ( time < 1 )
			CVAR_SET_STRING( "mp_chattime", "1" );
		else if ( time > MAX_INTERMISSION_TIME )
			CVAR_SET_STRING( "mp_chattime", UTIL_dtos1( MAX_INTERMISSION_TIME ) );

		m_flIntermissionEndTime = g_flIntermissionStartTime + mp_chattime.value;

		// check to see if we should change levels now
		if ( m_flIntermissionEndTime < gpGlobals->time )
		{
			if ( m_iEndIntermissionButtonHit  // check that someone has pressed a key, or the max intermission time is over
				|| ( ( g_flIntermissionStartTime + MAX_INTERMISSION_TIME ) < gpGlobals->time) ) 
				ChangeLevel(); // intermission is over
		}

		return;
	}

	float flTimeLimit = timelimit.value * 60;
	float flFragLimit = fraglimit.value;

	time_remaining = (int)(flTimeLimit ? ( flTimeLimit - gpGlobals->time ) : 0);

	if ( flTimeLimit != 0 && gpGlobals->time >= flTimeLimit )
	{
		GoToIntermission();
		return;
	}

	if ( flFragLimit )
	{
		int bestfrags = 9999;
		int remain;

		// check if any player is over the frag limit
		for ( int i = 1; i <= gpGlobals->maxClients; i++ )
		{
			CBaseEntity *pPlayer = UTIL_PlayerByIndex( i );

			if ( pPlayer && pPlayer->pev->frags >= flFragLimit )
			{
				GoToIntermission();
				return;
			}


			if ( pPlayer )
			{
				remain = flFragLimit - pPlayer->pev->frags;
				if ( remain < bestfrags )
				{
					bestfrags = remain;
				}
			}

		}
		frags_remaining = bestfrags;
	}

	// Updates when frags change
	if ( frags_remaining != last_frags )
	{
		g_engfuncs.pfnCvar_DirectSet( &fragsleft, UTIL_VarArgs( "%i", frags_remaining ) );
	}

	// Updates once per second
	if ( timeleft.value != last_time )
	{
		g_engfuncs.pfnCvar_DirectSet( &timeleft, UTIL_VarArgs( "%i", time_remaining ) );
	}

	last_frags = frags_remaining;
	last_time  = time_remaining;
}
Пример #16
0
void render_window()
{
    game_config = GetGameConfig();
    game_levels = GetGameLevels();
    game_levels_count = GetGameLevelsCount();

    arguments = GetArguments();
    user_set = GetUserSettings();
    int start_level = get_start_level();

    save_dir_full = GetSaveDir();
    cache_dir_full = GetCacheDir();
    can_cache = (save_dir_full && cache_dir_full);

//------------------------------------------------------------------------------
    ApplyArguments();

    const SDL_VideoInfo *video_info = SDL_GetVideoInfo();
    if (user_set->geom_x > 0 && user_set->geom_y > 0)
    {
        disp_x = user_set->geom_x;
        disp_y = user_set->geom_y;
    }
    else
    {
        disp_x = video_info->current_w;
        disp_y = video_info->current_h;
    }

    int probe_bpp = (user_set->bpp == 0 ? video_info->vfmt->BitsPerPixel : user_set->bpp);
    disp_bpp = (probe_bpp == 32 ? probe_bpp : 16);

    bool rot = TransformGeom();

//------------------------------------------------------------------------------
#define BTN_SPACE_KOEF 4.5
    int btn_side = disp_y / 7;
    int btn_space = btn_side / BTN_SPACE_KOEF;
    int btns_padded_width = btn_side * 4 + btn_space * 5;
    if (btns_padded_width > disp_x)
    {
        //btn_side = ( wnd_w - 5 * ( btn_side / BTN_SPACE_KOEF ) ) / 4
        btn_side = (int)(disp_x / (4 + 5 / BTN_SPACE_KOEF));
        btn_space = btn_side / BTN_SPACE_KOEF;
    }
    int btns_width = btn_side * 4 + btn_space * 3;
    int font_height = btn_side / 3;
    int font_padding = font_height / 2;

//-- font and labels -----------------------------------------------------------
    TTF_Font *font = TTF_OpenFont(DEFAULT_FONT_FILE, font_height);
    if (!font)
    {
        log_error("Can't load font '%s'. Exiting.", DEFAULT_FONT_FILE);
        return;
    }

    SDL_Surface *levelTextSurface = NULL;
    SDL_Rect levelTextLocation;
    levelTextLocation.y = font_padding;

    SDL_Color fontColor = {0};
#ifndef RGBSWAP
    fontColor.r = 231;
    fontColor.g = 190;
    fontColor.b = 114;
#else
    //--enable-rgb-swap
    fontColor.r = 114;
    fontColor.g = 190;
    fontColor.b = 231;
#endif

    /* Window initialization */
    ingame = true;
    Uint32 sdl_flags = SDL_SWSURFACE;
    if (user_set->fullscreen_mode != FULLSCREEN_NONE)
        sdl_flags |= SDL_FULLSCREEN;
    SDL_Surface *disp = SDL_SetVideoMode(disp_x, disp_y, disp_bpp, sdl_flags);
    if (disp == NULL)
    {
        log_error("Can't set video mode %dx%dx%dbpp. Exiting.", disp_x, disp_y, disp_bpp);
        return;
    }
    screen = disp;
    SDL_Surface *gui_surface = disp;
    SDL_WM_SetCaption("Mokomaze", "Mokomaze");

    /* Draw loading screen */
    SDL_Color whiteColor = {0};
    whiteColor.r = whiteColor.g = whiteColor.b = 255;
    SDL_Surface *titleSurface = TTF_RenderText_Blended(font, "Loading...", whiteColor);
    SDL_Rect title_rect;
    title_rect.x = (disp_x - titleSurface->w) / 2;
    title_rect.y = (disp_y - titleSurface->h) / 2;
    title_rect.w = titleSurface->w;
    title_rect.h = titleSurface->h;
    SDL_BlitSurface(titleSurface, NULL, screen, &title_rect);
    SDL_UpdateRect(screen, title_rect.x, title_rect.y, title_rect.w, title_rect.h);
    SDL_FreeSurface(titleSurface);

//-- load pictures -------------------------------------------------------------
    SDL_Surface *back_pic     = LoadSvg(MDIR "prev-main.svg", btn_side, btn_side, false, false);
    SDL_Surface *forward_pic  = LoadSvg(MDIR "next-main.svg", btn_side, btn_side, false, false);
    SDL_Surface *settings_pic = LoadSvg(MDIR "settings-main.svg", btn_side, btn_side, false, false);
    SDL_Surface *exit_pic     = LoadSvg(MDIR "close-main.svg", btn_side, btn_side, false, false);

    SDL_Surface *back_i_pic    = LoadSvg(MDIR "prev-grey.svg", btn_side, btn_side, false, false);
    SDL_Surface *forward_i_pic = LoadSvg(MDIR "next-grey.svg", btn_side, btn_side, false, false);

    SDL_Surface *back_p_pic    = LoadSvg(MDIR "prev-light.svg", btn_side, btn_side, false, false);
    SDL_Surface *forward_p_pic = LoadSvg(MDIR "next-light.svg", btn_side, btn_side, false, false);

    int tmpx = (rot ? game_config.wnd_h : game_config.wnd_w);
    int tmpy = (rot ? game_config.wnd_w : game_config.wnd_h);
    desk_pic = LoadSvg(MDIR "desk.svg", tmpx, tmpy, rot, true);
    wall_pic = LoadSvg(MDIR "wall.svg", tmpx, tmpy, rot, true);
    int hole_d = game_config.hole_r * 2;
    fin_pic = LoadSvg(MDIR "openmoko.svg", hole_d, hole_d, rot, false);

    if (LoadImgErrors > 0)
    {
        log_error("Some images were not loaded. Exiting.");
        return;
    }

//-- positions of buttons ------------------------------------------------------
    SDL_Rect gui_rect_1, gui_rect_2, gui_rect_3, gui_rect_4;
    gui_rect_1.y = gui_rect_2.y = gui_rect_3.y = gui_rect_4.y = levelTextLocation.y + font_height + font_padding;
    gui_rect_1.x = (disp_x - btns_width) / 2;
    gui_rect_2.x = gui_rect_1.x + btn_side + btn_space;
    gui_rect_3.x = gui_rect_2.x + btn_side + btn_space;
    gui_rect_4.x = gui_rect_3.x + btn_side + btn_space;
//-- for click detection -------------------------------------------------------
    Box gui_box_1, gui_box_2, gui_box_3, gui_box_4;
    gui_box_1.x1 = gui_rect_1.x;
    gui_box_1.y1 = gui_rect_1.y;
    gui_box_1.x2 = gui_rect_1.x + btn_side;
    gui_box_1.y2 = gui_rect_1.y + btn_side;
    gui_box_2.x1 = gui_rect_2.x;
    gui_box_2.y1 = gui_rect_2.y;
    gui_box_2.x2 = gui_rect_2.x + btn_side;
    gui_box_2.y2 = gui_rect_2.y + btn_side;
    gui_box_3.x1 = gui_rect_3.x;
    gui_box_3.y1 = gui_rect_3.y;
    gui_box_3.x2 = gui_rect_3.x + btn_side;
    gui_box_3.y2 = gui_rect_3.y + btn_side;
    gui_box_4.x1 = gui_rect_4.x;
    gui_box_4.y1 = gui_rect_4.y;
    gui_box_4.x2 = gui_rect_4.x + btn_side;
    gui_box_4.y2 = gui_rect_4.y + btn_side;

    //create surface for rendering the level
    render_pic = CreateSurface(SDL_SWSURFACE, game_config.wnd_w, game_config.wnd_h, disp);

    if (user_set->scrolling)
        screen = CreateSurface(SDL_SWSURFACE, game_config.wnd_w, game_config.wnd_h, disp);

    if (user_set->fullscreen_mode != FULLSCREEN_NONE)
        SDL_ShowCursor(!ingame);

    desk_rect.x = 0;
    desk_rect.y = 0;
    desk_rect.w = game_config.wnd_w;
    desk_rect.h = game_config.wnd_h;

    SDL_Rect ball_rect;

    int disp_scroll_border = min(disp_x, disp_y) * 0.27;
    SDL_Rect screen_rect;
    screen_rect.x = 0;
    screen_rect.y = 0;
    screen_rect.w = disp_x;
    screen_rect.h = disp_y;
    SDL_Rect disp_rect;
    disp_rect = screen_rect;

    SDL_Color ballColor = {0};
    ballColor.r = 255;
    ballColor.g = 127;
    ballColor.b = 0;

    User user_set_new = *user_set;
    bool video_set_modified = false;

    /* Settings window initialization */
    settings_init(disp, font_height, user_set, &user_set_new);

    /* Render initialization */
    InitRender();

    /* Input system initialization */
    input_get_dummy(&input);
    SetInput();

    /* Vibro system initialization */
    vibro_get_dummy(&vibro);
    SetVibro();

    /* MazeCore initialization */
    maze_init();
    maze_set_config(game_config);
    maze_set_vibro_callback(BumpVibrate);
    maze_set_levels_data(game_levels, game_levels_count);

    cur_level = start_level;
    RenderLevel();
    RedrawDesk();
    maze_set_level(cur_level);
    ResetPrevPos();

    SDL_Event event;
    bool done = false;
    bool redraw_all = true;
    bool ingame_changed = false;
    int prev_ticks = SDL_GetTicks();
    Point mouse = {0};

//== Game Loop =================================================================
    while (!done)
    {
        bool wasclick = false;
        bool show_settings = false;
        while (SDL_PollEvent(&event))
        {
            bool btndown = false;
            bool btnesc = false;
            if (event.type == SDL_QUIT)
            {
                done = true;
            }
            else if (event.type == SDL_ACTIVEEVENT)
            {
                int g = event.active.gain;
                int s = event.active.state;
                if (ingame && !g && ((s & SDL_APPINPUTFOCUS) || (s & SDL_APPACTIVE)))
                {
                    btndown = true;
                }
            }
            else if (event.type == SDL_MOUSEMOTION)
            {
                mouse.x = event.motion.x;
                mouse.y = event.motion.y;
            }
            else if (event.type == SDL_MOUSEBUTTONUP)
            {
                StopFastChange();
            }
            else if (event.type == SDL_MOUSEBUTTONDOWN)
            {
                btndown = true;
            }
            else if (event.type == SDL_KEYDOWN)
            {
                switch(event.key.keysym.sym)
                {
                case SDLK_q:
                case SDLK_ESCAPE:
                    btnesc = true;
                case SDLK_SPACE:
                case SDLK_p:
                case SDLK_PAUSE:
                    btndown = true;
                    break;
                default:
                    break;
                }
            }
            else if (event.type == SDL_KEYUP)
            {
                switch(event.key.keysym.sym)
                {
                case SDLK_q:
                case SDLK_ESCAPE:
                    if( !wasclick || ingame || show_settings )
                        StopFastChange();
                    else
                        done = true;
                    break;
                case SDLK_SPACE:
                case SDLK_p:
                case SDLK_PAUSE:
                    StopFastChange();
                    break;
                default:
                    break;
                }
            }

            if (btndown)
            {
                if (!ingame)
                {
                    if (inbox(mouse.x, mouse.y, gui_box_1) && !btnesc)
                    {
                        if (cur_level > 0)
                        {
                            SDL_BlitSurface(back_p_pic, NULL, gui_surface, &gui_rect_1);
                            SDL_UpdateRect(gui_surface, gui_rect_1.x, gui_rect_1.y, gui_rect_1.w, gui_rect_1.h);

                            ChangeLevel(cur_level-1, &redraw_all, &wasclick);

                            fastchange_step = -10;
                            StopFastChange();
                            fastchange_timer = SDL_AddTimer(FASTCHANGE_INTERVAL, fastchange_callback, NULL);
                        }
                        continue;
                    }
                    else if (inbox(mouse.x, mouse.y, gui_box_2) && !btnesc)
                    {
                        if (cur_level < game_levels_count - 1)
                        {
                            SDL_BlitSurface(forward_p_pic, NULL, gui_surface, &gui_rect_2);
                            SDL_UpdateRect(gui_surface, gui_rect_2.x, gui_rect_2.y, gui_rect_2.w, gui_rect_2.h);

                            ChangeLevel(cur_level+1, &redraw_all, &wasclick);

                            fastchange_step = +10;
                            StopFastChange();
                            fastchange_timer = SDL_AddTimer(FASTCHANGE_INTERVAL, fastchange_callback, NULL);
                        }
                        continue;
                    }
                    else if (inbox(mouse.x, mouse.y, gui_box_3) && !btnesc)
                    {
                        show_settings = true;
                        RedrawDesk();
                        redraw_all = true;
                        wasclick = true;
                        continue;
                    }
                    else if (inbox(mouse.x, mouse.y, gui_box_4) || btnesc)
                    {
                        done = true;
                        continue;
                    }
                }
                ingame_changed = true;
            } //if (btndown)
        }

        if (ingame_changed)
        {
            ingame = !ingame;
            if (!ingame)
            {
                wasclick = true;
            }
            else
            {
                RedrawDesk();
                redraw_all = true;
            }

            if (user_set->fullscreen_mode == FULLSCREEN_INGAME)
                SDL_WM_ToggleFullScreen(disp);
            if (user_set->fullscreen_mode != FULLSCREEN_NONE)
                SDL_ShowCursor(!ingame);

            prev_ticks = SDL_GetTicks();
            ingame_changed = false;
        }

        if ((!ingame) && (!wasclick) && (must_fastchange))
        {
            int new_cur_level = cur_level + fastchange_dostep;
            clamp_max(new_cur_level, game_levels_count - 1);
            clamp_min(new_cur_level, 0);

            if (new_cur_level != cur_level)
            {
                if (fastchange_dostep < 0)
                {
                    SDL_BlitSurface(back_p_pic, NULL, gui_surface, &gui_rect_1);
                    SDL_UpdateRect(gui_surface, gui_rect_1.x, gui_rect_1.y, gui_rect_1.w, gui_rect_1.h);
                }
                else
                {
                    SDL_BlitSurface(forward_p_pic, NULL, gui_surface, &gui_rect_2);
                    SDL_UpdateRect(gui_surface, gui_rect_2.x, gui_rect_2.y, gui_rect_2.w, gui_rect_2.h);
                }

                ChangeLevel(new_cur_level, &redraw_all, &wasclick);
            }
            must_fastchange = false;
        }

        if (!ingame && !wasclick)
        {
            SDL_Delay(user_set->frame_delay);
            continue;
        }

//-- physics step --------------------------------------------------------------
        int ticks = SDL_GetTicks();
        int delta_ticks = ticks - prev_ticks;
        prev_ticks = ticks;
        clamp_min(delta_ticks, 1);
        clamp_max(delta_ticks, 1000 / 15);

        float acx = 0, acy = 0;
        input.read(&acx, &acy, NULL);
        if (input_cal_cycle)
            input_cal_cycle = (input_calibration_sample(&user_set->input_calibration_data, &acx, &acy, NULL) < MAX_CALIBRATION_SAMPLES);
        input_calibration_adjust(&user_set->input_calibration_data, &acx, &acy, NULL);
        maze_set_speed(user_set->ball_speed);
        maze_set_tilt(acx, acy, 0);
        GameState game_state = maze_step(delta_ticks);

        const dReal *R;
        int tk_px, tk_py, tk_pz;
        maze_get_ball(&tk_px, &tk_py, &tk_pz, &R);
        maze_get_animations(&keys_anim, &final_anim);
//------------------------------------------------------------------------------

        //restore the background
        ball_rect.w = game_config.ball_r * 2;
        ball_rect.h = game_config.ball_r * 2; //
        ball_rect.x = prev_px - game_config.ball_r;
        ball_rect.y = prev_py - game_config.ball_r;
        SDL_BlitSurface(render_pic, &ball_rect, screen, &ball_rect);

        UpdateBufAnimation();
        DrawBall(tk_px, tk_py, tk_pz, R, ballColor);

        //update the screen
        if (!redraw_all && !user_set->scrolling)
        {
            int min_px, max_px;
            int min_py, max_py;
            if (prev_px <= tk_px)
            {
                min_px = prev_px;
                max_px = tk_px;
            }
            else
            {
                min_px = tk_px;
                max_px = prev_px;
            }

            if (prev_py <= tk_py)
            {
                min_py = prev_py;
                max_py = tk_py;
            }
            else
            {
                min_py = tk_py;
                max_py = prev_py;
            }
            min_px -= game_config.ball_r;
            max_px += game_config.ball_r;
            min_py -= game_config.ball_r;
            max_py += game_config.ball_r;
            clamp_min(min_px, 0);
            clamp_max(max_px, game_config.wnd_w - 1);
            clamp_min(min_py, 0);
            clamp_max(max_py, game_config.wnd_h - 1);
            SDL_UpdateRect(screen, min_px, min_py, max_px - min_px, max_py - min_py);
            UpdateScreenAnimation();
        }

        if (user_set->scrolling)
        {
            clamp_min(screen_rect.x, tk_px - disp_x + disp_scroll_border);
            clamp_max(screen_rect.x, tk_px - disp_scroll_border);
            clamp_min(screen_rect.y, tk_py - disp_y + disp_scroll_border);
            clamp_max(screen_rect.y, tk_py - disp_scroll_border);
            clamp(screen_rect.x, 0, game_config.wnd_w - disp_x);
            clamp(screen_rect.y, 0, game_config.wnd_h - disp_y);
            SDL_BlitSurface(screen, &screen_rect, disp, &disp_rect);
        }

        prev_px = tk_px;
        prev_py = tk_py;

//-- GUI -----------------------------------------------------------------------
        if (wasclick && !ingame && !show_settings)
        {
            char txt[32];
            sprintf(txt, "Level %d/%d", cur_level + 1, game_levels_count);
            SDL_FreeSurface(levelTextSurface);
            levelTextSurface = TTF_RenderText_Blended(font, txt, fontColor);
            levelTextLocation.x = (disp_x - levelTextSurface->w) / 2;
            SDL_BlitSurface(levelTextSurface, NULL, gui_surface, &levelTextLocation);

            if (cur_level > 0)
                SDL_BlitSurface(back_pic, NULL, gui_surface, &gui_rect_1);
            else
                SDL_BlitSurface(back_i_pic, NULL, gui_surface, &gui_rect_1);

            if (cur_level < game_levels_count - 1)
                SDL_BlitSurface(forward_pic, NULL, gui_surface, &gui_rect_2);
            else
                SDL_BlitSurface(forward_i_pic, NULL, gui_surface, &gui_rect_2);

            SDL_BlitSurface(settings_pic, NULL, gui_surface, &gui_rect_3);
            SDL_BlitSurface(exit_pic, NULL, gui_surface, &gui_rect_4);
            redraw_all = true;
        }
//------------------------------------------------------------------------------

        //update the whole screen if needed
        if (user_set->scrolling)
        {
            SDL_Flip(disp);
        }
        else if (redraw_all)
        {
            SDL_Flip(screen);
        }
        redraw_all = false;

        if (show_settings)
        {
            bool _video_set_modified = false;
            bool _input_set_modified = false;
            bool _vibro_set_modified = false;
            settings_show(&input_cal_cycle, &_video_set_modified, &_input_set_modified, &_vibro_set_modified);
            if (input_cal_cycle)
                input_calibration_reset();
            if (_video_set_modified)
                video_set_modified = true;
            if (_input_set_modified)
                SetInput();
            if (_vibro_set_modified)
                SetVibro();
            SDL_GetMouseState(&mouse.x, &mouse.y);
            ingame_changed = true;
        }

        switch (game_state)
        {
        case GAME_STATE_FAILED:
            RedrawDesk();
            maze_restart_level();
            ResetPrevPos();
            redraw_all = true;
            break;
        case GAME_STATE_SAVED:
            RedrawDesk();
            maze_reload_level();
            ResetPrevPos();
            redraw_all = true;
            break;
        case GAME_STATE_WIN:
            if (++cur_level >= game_levels_count) cur_level=0;
            RenderLevel();
            RedrawDesk();
            maze_set_level(cur_level);
            ResetPrevPos();
            redraw_all = true;
            break;
        default:
            break;
        }

        SDL_Delay(user_set->frame_delay);
    }
//==============================================================================

    if (video_set_modified)
    {
        user_set->scrolling = user_set_new.scrolling;
        user_set->geom_x = user_set_new.geom_x;
        user_set->geom_y = user_set_new.geom_y;
        user_set->bpp = user_set_new.bpp;
        user_set->fullscreen_mode = user_set_new.fullscreen_mode;
        user_set->frame_delay = user_set_new.frame_delay;
    }

    user_set->level = cur_level + 1;
    SaveUserSettings();

    settings_shutdown();

    SDL_FreeSurface(levelTextSurface);
    TTF_CloseFont(font);
    vibro.shutdown();
    input.shutdown();
}
eStateStatus CGameWorld::Update(float aTimeDelta)
{
	myTextFPS->myText = "FPS " + std::to_string(myTimerManager.GetMasterTimer().GetFPS());
	myTextFPS->myPosition = { 0.5f - myTextFPS->GetWidth() / 2, 0.05f };

	if (myInputManager.KeyPressed(DIK_F1) == true)
	{
		ResolutionManager::GetInstance()->ToggleFullscreen();
	}

#ifdef _DEBUG
	if (myInputManager.KeyPressed(DIK_F2) == true)
	{
		myShouldRenderDebug = !myShouldRenderDebug;
	}
#endif

	if (myInputManager.KeyPressed(DIK_F3) == true)
	{
		myShouldRenderFPS = !myShouldRenderFPS;
	}

	if (myInputManager.KeyPressed(DIK_F4) == true)
	{
		myShouldRenderNavPoints = !myShouldRenderNavPoints;
	}

#ifdef _DEBUG
	if (myInputManager.KeyPressed(DIK_SPACE) == true)
	{
		ChangeLevel("kitchen");
		ResetGame();

		std::cout << "Resetted game" << std::endl;
	}
#endif

	float fadeSpeed = 2.0f;
	if (myDoFadeIn == true)
	{
		myFadeIn -= aTimeDelta * fadeSpeed;
		if (myFadeIn <= 0.0f)
		{
			myFadeIn = 0.0f;
		}
	}
	else
	{
		myFadeIn += aTimeDelta * fadeSpeed;
		if (myFadeIn >= 1.0f)
		{
			myFadeIn = 1.0f;
		}
	}

	if (myResettedGame == true)
	{
		myResettedGame = false;
		return eStateStatus::eKeepState;
	}

	myPlayerIsPresent = false;
	myRenderPasses.RemoveAll();
	bool hasMoved = false;

	if (myCurrentRoom != nullptr)
	{
		for (unsigned int i = 0; i < myCurrentRoom->GetObjectList()->Size(); ++i)
		{
			UpdateObject((*myCurrentRoom->GetObjectList())[i], aTimeDelta);
		}
		if (myOptionsMenu.GetActive() == true)
		{
			PlayerMovement(false, false, false, aTimeDelta);
			hasMoved = true;
		}
	}
	if (myOptionsMenu.GetActive() == false)
	{
		bool myCachedTalkIsOn = myTalkIsOn;
		bool input = EventManager::GetInstance()->Update(aTimeDelta, myTalkIsOn);
		if (myResettedGame == true)
		{
			return eStateStatus::eKeepState;
		}
		if (myCurrentRoom != nullptr && hasMoved == false)
		{
			PlayerMovement(input, myCachedTalkIsOn, true, aTimeDelta);
		}
	}

	myOptionsMenu.Update(aTimeDelta);
	//std::cout << myRenderPasses.Size() << std::endl;

	if (myDoQuit == true)
	{
		return eStateStatus::ePopMainState;
	}

	return eStateStatus::eKeepState;
}
void CGameWorld::Init()
{
	Vector3f Vec1({ 1, 0, 0 });
	Vector3f Vec2({ -1, 0, 0 });
	//std::cout << "Angle in rad: " << Vec1.Angle(Vec2) << std::endl;
	//std::cout << "Angle in degrees: " << (Vec1.Angle(Vec2) * (180.0f / 3.14159265359f)) << std::endl;

	std::string name = "";
	unsigned char timer = myTimerManager.CreateTimer();
	myTimerManager.UpdateTimers();

	myJson.Load("root.json", myRooms, this, name);

	myTimerManager.UpdateTimers();
	double delta = myTimerManager.GetTimer(timer).GetTimeElapsed().GetMiliseconds();
	std::cout << "Loading root.json and levels took " << delta << " milliseconds" << std::endl;

	myTimerManager.UpdateTimers();
	myJson.LoadMusic("JSON/Music.json");
	myTimerManager.UpdateTimers();
	delta = myTimerManager.GetTimer(timer).GetTimeElapsed().GetMiliseconds();
	std::cout << "Loading music took " << delta << " milliseconds" << std::endl;
	//myJson.LoadItems("JSON/items.json", myPlayer.GetInventory());

	std::cout << "Level: " << CGame::myTestLevel << std::endl;
	if (CGame::myTestLevel.size() > 0)
	{
		DL_PRINT(CGame::myTestLevel.c_str());
		ChangeLevel(CGame::myTestLevel);
	}
	else
	{
		ChangeLevel(name);
	}


	myDoQuit = false;
	myTalkIsOn = false;
	myPlayerCanMove = true;

	myTextFPS = new DX2D::CText("Text/PassionOne-Regular.ttf_sdf");
	myTextFPS->myPosition = { 0.5f, 0.05f };
	myTextFPS->myText = "FPS: ";
	myTextFPS->mySize = 0.8f;

	myRenderPasses.Init(32);

	myPlayer.Init(DX2D::Vector2f(0.5f, 0.8f), this);

	myFadeIn = 1.0f;
	myDoFadeIn = false;

	myShouldRenderDebug = false;
	myShouldRenderFPS = false;
	myShouldRenderNavPoints = false;
#ifdef _DEBUG
	myShouldRenderFPS = true;
	myShouldRenderNavPoints = true;
#endif

	myCurrentWaypoint = 0;
	myHasPath = false;
	myHasNewTargetPosition = false;
	myTargetPosition = { 0.0f, 0.0f };
	myNewTargetPosition = myTargetPosition;
	
#ifdef _DEBUG
	myDotSprites.Init(12000);
	for (int i = 0; i < 12000; ++i)
	{
		DX2D::CSprite* sprite = new DX2D::CSprite("Sprites/Dot.dds");
		myDotSprites.Add(sprite);
	}
#endif
	
	myOptionsMenu.Initialize();
}