int Game::ScenarioInfo(void)
{
    Settings & conf = Settings::Get();

    AGG::PlayMusic(MUS::MAINMENU);

    MapsFileInfoList lists;
    if(!PrepareMapsFileInfoList(lists, (conf.GameType(Game::TYPE_MULTI))))
    {
	Dialog::Message(_("Warning"), _("No maps available!"), Font::BIG, Dialog::OK);
        return MAINMENU;
    }

    int result = QUITGAME;
    LocalEvent & le = LocalEvent::Get();

    // cursor
    Cursor & cursor = Cursor::Get();
    cursor.Hide();
    cursor.SetThemes(cursor.POINTER);

    Display & display = Display::Get();

    Point top, pointDifficultyInfo, pointOpponentInfo, pointClassInfo;
    Rect rectPanel;
    Button* buttonSelectMaps = NULL;
    Button* buttonOk = NULL;
    Button* buttonCancel = NULL;

    // vector coord difficulty
    Rects coordDifficulty;
    coordDifficulty.reserve(5);

    const Sprite & ngextra = AGG::GetICN(ICN::NGEXTRA, 62);
    Dialog::FrameBorder* frameborder = NULL;

    // image background
    if(conf.QVGA())
    {
	frameborder = new Dialog::FrameBorder(Size(380, 224));
	rectPanel = frameborder->GetArea();

	pointDifficultyInfo = Point(rectPanel.x + 4, rectPanel.y + 24);
	pointOpponentInfo = Point(rectPanel.x + 4, rectPanel.y + 94);
	pointClassInfo = Point(rectPanel.x + 4, rectPanel.y + 148);

	coordDifficulty.push_back(Rect(rectPanel.x + 1, rectPanel.y + 21,   ngextra.w(), ngextra.h()));
	coordDifficulty.push_back(Rect(rectPanel.x + 78, rectPanel.y + 21,  ngextra.w(), ngextra.h()));
	coordDifficulty.push_back(Rect(rectPanel.x + 154, rectPanel.y + 21, ngextra.w(), ngextra.h()));
	coordDifficulty.push_back(Rect(rectPanel.x + 231, rectPanel.y + 21, ngextra.w(), ngextra.h()));
        coordDifficulty.push_back(Rect(rectPanel.x + 308, rectPanel.y + 21, ngextra.w(), ngextra.h()));

	buttonOk = new Button(rectPanel.x + rectPanel.w / 2 - 160, rectPanel.y + rectPanel.h - 30, ICN::NGEXTRA, 66, 67);
	buttonCancel = new Button(rectPanel.x + rectPanel.w / 2 + 60, rectPanel.y + rectPanel.h - 30, ICN::NGEXTRA, 68, 69);

	Text text;
	text.Set(conf.CurrentFileInfo().name, Font::BIG);
	text.Blit(rectPanel.x + (rectPanel.w - text.w()) / 2, rectPanel.y + 5);
    }
    else
    {
	const Sprite &panel = AGG::GetICN(ICN::NGHSBKG, 0);
	const Sprite &back = AGG::GetICN(ICN::HEROES, 0);
	const Point top((display.w() - back.w()) / 2, (display.h() - back.h()) / 2);

	rectPanel = Rect(top.x + 204, top.y + 32, panel.w(), panel.h());
	pointDifficultyInfo = Point(rectPanel.x + 24, rectPanel.y + 93);
	pointOpponentInfo = Point(rectPanel.x + 24, rectPanel.y + 202);
	pointClassInfo = Point(rectPanel.x + 24, rectPanel.y + 282);

	coordDifficulty.push_back(Rect(rectPanel.x + 21, rectPanel.y + 91,  ngextra.w(), ngextra.h()));
	coordDifficulty.push_back(Rect(rectPanel.x + 98, rectPanel.y + 91,  ngextra.w(), ngextra.h()));
	coordDifficulty.push_back(Rect(rectPanel.x + 174, rectPanel.y + 91, ngextra.w(), ngextra.h()));
	coordDifficulty.push_back(Rect(rectPanel.x + 251, rectPanel.y + 91, ngextra.w(), ngextra.h()));
	coordDifficulty.push_back(Rect(rectPanel.x + 328, rectPanel.y + 91, ngextra.w(), ngextra.h()));

	buttonSelectMaps = new Button(rectPanel.x + 309, rectPanel.y + 45, ICN::NGEXTRA, 64, 65);
	buttonOk = new Button(rectPanel.x + 31, rectPanel.y + 380, ICN::NGEXTRA, 66, 67);
	buttonCancel = new Button(rectPanel.x + 287, rectPanel.y + 380, ICN::NGEXTRA, 68, 69);

	back.Blit(top);
    }

    const bool reset_starting_settings = conf.MapsFile().empty() || ! System::IsFile(conf.MapsFile());
    Players & players = conf.GetPlayers();
    Interface::PlayersInfo playersInfo(true, !conf.QVGA(), !conf.QVGA());

    // set first maps settings
    if(reset_starting_settings)
	conf.SetCurrentFileInfo(lists.front());

    playersInfo.UpdateInfo(players, pointOpponentInfo, pointClassInfo);

    RedrawScenarioStaticInfo(rectPanel);
    RedrawDifficultyInfo(pointDifficultyInfo, !conf.QVGA());

    playersInfo.RedrawInfo();

    TextSprite* rating = conf.QVGA() ? NULL : new TextSprite();
    if(rating)
    {
	rating->SetFont(Font::BIG);
	rating->SetPos(rectPanel.x + 166, rectPanel.y + 383);
	RedrawRatingInfo(*rating);
    }

    SpriteMove levelCursor(ngextra);

    switch(conf.GameDifficulty())
    {
	case Difficulty::EASY:		levelCursor.Move(coordDifficulty[0]); break;
	case Difficulty::NORMAL:	levelCursor.Move(coordDifficulty[1]); break;
	case Difficulty::HARD:		levelCursor.Move(coordDifficulty[2]); break;
	case Difficulty::EXPERT:	levelCursor.Move(coordDifficulty[3]); break;
	case Difficulty::IMPOSSIBLE:	levelCursor.Move(coordDifficulty[4]); break;
    }

    if(buttonSelectMaps) buttonSelectMaps->Draw();
    buttonOk->Draw();
    buttonCancel->Draw();

    cursor.Show();
    display.Flip();

    while(le.HandleEvents())
    {
	// press button
	if(buttonSelectMaps)
	le.MousePressLeft(*buttonSelectMaps) ? buttonSelectMaps->PressDraw() : buttonSelectMaps->ReleaseDraw();
	le.MousePressLeft(*buttonOk) ? buttonOk->PressDraw() : buttonOk->ReleaseDraw();
	le.MousePressLeft(*buttonCancel) ? buttonCancel->PressDraw() : buttonCancel->ReleaseDraw();

	// click select
	if(buttonSelectMaps &&
	  (HotKeyPressEvent(Game::EVENT_BUTTON_SELECT) || le.MouseClickLeft(*buttonSelectMaps)))
	{
	    levelCursor.Hide();
	    const Maps::FileInfo* fi = Dialog::SelectScenario(lists);
	    if(fi)
	    {
		conf.SetCurrentFileInfo(*fi);
		playersInfo.UpdateInfo(players, pointOpponentInfo, pointClassInfo);

		cursor.Hide();
		RedrawScenarioStaticInfo(rectPanel);
		RedrawDifficultyInfo(pointDifficultyInfo, !conf.QVGA());
		playersInfo.RedrawInfo();
		if(rating) RedrawRatingInfo(*rating);
		// default difficulty normal
		levelCursor.Move(coordDifficulty[1]);
    		conf.SetGameDifficulty(Difficulty::NORMAL);
		buttonOk->Draw();
		buttonCancel->Draw();
	    }
	    cursor.Show();
	    display.Flip();
	}
	else
	// click cancel
	if(HotKeyPressEvent(EVENT_DEFAULT_EXIT) || le.MouseClickLeft(*buttonCancel))
	{
	    result = MAINMENU;
	    break;
	}
	else
	// click ok
	if(HotKeyPressEvent(EVENT_DEFAULT_READY) || le.MouseClickLeft(*buttonOk))
	{
	    DEBUG(DBG_GAME, DBG_INFO, "select maps: " << conf.MapsFile() << \
		    ", difficulty: " << Difficulty::String(conf.GameDifficulty()));
	    result = STARTGAME;
	    break;
	}
	else
	if(le.MouseClickLeft(rectPanel))
	{
	    const s32 index = coordDifficulty.GetIndex(le.GetMouseCursor());

	    // select difficulty
	    if(0 <= index)
	    {
		cursor.Hide();
		levelCursor.Move(coordDifficulty[index]);
		conf.SetGameDifficulty(index);
		if(rating) RedrawRatingInfo(*rating);
		cursor.Show();
		display.Flip();
	    }
	    else
	    // playersInfo
	    if(playersInfo.QueueEventProcessing())
	    {
		cursor.Hide();
		RedrawScenarioStaticInfo(rectPanel);
		levelCursor.Redraw();
		RedrawDifficultyInfo(pointDifficultyInfo, !conf.QVGA());

		playersInfo.RedrawInfo();
		if(rating) RedrawRatingInfo(*rating);
		buttonOk->Draw();
		buttonCancel->Draw();
		cursor.Show();
		display.Flip();
	    }
	}

	if(le.MousePressRight(rectPanel))
	{
	    if(buttonSelectMaps && le.MousePressRight(*buttonSelectMaps))
		Dialog::Message(_("Scenario"), _("Click here to select which scenario to play."), Font::BIG);
	    else
	    if(0 <= coordDifficulty.GetIndex(le.GetMouseCursor()))
		Dialog::Message(_("Game Difficulty"), _("This lets you change the starting difficulty at which you will play. Higher difficulty levels start you of with fewer resources, and at the higher settings, give extra resources to the computer."), Font::BIG);
	    else
	    if(rating && le.MousePressRight(rating->GetRect()))
		Dialog::Message(_("Difficulty Rating"), _("The difficulty rating reflects a combination of various settings for your game. This number will be applied to your final score."), Font::BIG);
	    else
	    if(le.MousePressRight(*buttonOk))
		Dialog::Message(_("OK"), _("Click to accept these settings and start a new game."), Font::BIG);
	    else
	    if(le.MousePressRight(*buttonCancel))
		Dialog::Message(_("Cancel"), _("Click to return to the main menu."), Font::BIG);
	    else
		playersInfo.QueueEventProcessing();
	}
    }

    cursor.Hide();

    if(result == STARTGAME)
    {
	players.SetStartGame();
	if(conf.ExtGameUseFade()) display.Fade();
	Game::ShowLoadMapsText();
	// Load maps
	std::string lower = StringLower(conf.MapsFile());

	if(lower.size() > 3)
	{
	    std::string ext = lower.substr(lower.size() - 3);

	    if(ext == "mp2" || ext == "mx2")
		result = world.LoadMapMP2(conf.MapsFile()) ? STARTGAME : MAINMENU;
	    else
	    if(ext == "map")
		result = world.LoadMapMAP(conf.MapsFile()) ? STARTGAME : MAINMENU;
	}
	else
	{
	    result = MAINMENU;
	    DEBUG(DBG_GAME, DBG_WARN, conf.MapsFile() << ", " << "unknown map format");
	}
    }

    if(frameborder) delete frameborder;
    if(rating) delete rating;
    if(buttonSelectMaps) delete buttonSelectMaps;
    delete buttonOk;
    delete buttonCancel;

    return result;
}
Beispiel #2
0
bool FH2LocalClient::ScenarioInfoDialog(void)
{
    Settings & conf = Settings::Get();
    Cursor & cursor = Cursor::Get();
    Display & display = Display::Get();
    LocalEvent & le = LocalEvent::Get();

    if(!GetCurrentMapInfo() ||
	!GetPlayersInfo()) return false;

    const Sprite & panel = AGG::GetICN(ICN::NGHSBKG, 0);
    const Rect  rectPanel(204, 32, panel.w(), panel.h());
    const Point pointOpponentInfo(rectPanel.x + 24, rectPanel.y + 202);
    const Point pointClassInfo(rectPanel.x + 24, rectPanel.y + 282);
    const Rect  box(pointOpponentInfo, 360, 180);

    Rects::const_iterator itr;

    Interface::PlayersInfo playersInfo(true, false, false);

    playersInfo.UpdateInfo(conf.GetPlayers(), pointOpponentInfo, pointClassInfo);

    RedrawScenarioStaticInfo(rectPanel);
    playersInfo.RedrawInfo();

    Button buttonSelectMaps(rectPanel.x + 309, rectPanel.y + 45, ICN::NGEXTRA, 64, 65);
    Button buttonOk(rectPanel.x + 31, rectPanel.y + 380, ICN::NGEXTRA, 66, 67);
    Button buttonCancel(rectPanel.x + 287, rectPanel.y + 380, ICN::NGEXTRA, 68, 69);

    SpriteCursor sp;
    sp.SetSprite(AGG::GetICN(ICN::NGEXTRA, 80));

    if(! Modes(ST_ADMIN))
    {
	buttonOk.SetDisable(true);
	buttonSelectMaps.SetDisable(true);
    }

    buttonSelectMaps.Draw();
    buttonOk.Draw();
    buttonCancel.Draw();
    cursor.Show();
    display.Flip();

    bool exit = false;
    bool update_info = false;
    u8 change_color = Color::NONE;
    DEBUG(DBG_NETWORK, DBG_INFO, "start queue");

    while(!exit && le.HandleEvents())
    {
        if(Ready())
	{
	    QueueMessage packet;

	    if(!Recv(packet)) return false;
	    DEBUG(DBG_NETWORK, DBG_INFO, "recv: " << Network::GetMsgString(packet.GetID()));

	    switch(packet.GetID())
    	    {
		case MSG_READY:
		    break;

		case MSG_CHANGE_RACE:
		    Network::UnpackRaceColors(packet);
		    update_info = true;
		    break;

		case MSG_UPDATE_PLAYERS:
		{
		    MsgUpdatePlayers(packet);
		    if(Modes(ST_ADMIN))
		    {
			buttonOk.Release();
			buttonOk.SetDisable(false);
			buttonSelectMaps.Release();
			buttonSelectMaps.SetDisable(false);
		    }
		    else
		    {
			buttonOk.Press();
			buttonOk.SetDisable(true);
			buttonSelectMaps.Press();
			buttonSelectMaps.SetDisable(true);
		    }
		    update_info = true;
		    break;
		}

		case MSG_SET_CURRENT_MAP:
		    Network::PacketPopMapsFileInfo(packet, conf.CurrentFileInfo());
		    playersInfo.UpdateInfo(conf.GetPlayers(), pointOpponentInfo, pointClassInfo);
		    update_info = true;
		    break;

		case MSG_MESSAGE:
		    break;

		case MSG_SHUTDOWN:
		    exit = true;
		    break;


		default: break;
	    }
	}

	if(update_info)
	{
	    cursor.Hide();
	    RedrawScenarioStaticInfo(rectPanel);
	    playersInfo.RedrawInfo();
	    buttonSelectMaps.Draw();
	    buttonOk.Draw();
	    buttonCancel.Draw();
	    cursor.Show();
	    display.Flip();
	    update_info = false;
	}

	// press button
        if(buttonSelectMaps.isEnable()) le.MousePressLeft(buttonSelectMaps) ? buttonSelectMaps.PressDraw() : buttonSelectMaps.ReleaseDraw();
        if(buttonOk.isEnable()) le.MousePressLeft(buttonOk) ? buttonOk.PressDraw() : buttonOk.ReleaseDraw();
        le.MousePressLeft(buttonCancel) ? buttonCancel.PressDraw() : buttonCancel.ReleaseDraw();

	// click select
	if(Game::HotKeyPress(Game::EVENT_BUTTON_SELECT) ||
	    (buttonSelectMaps.isEnable() && le.MouseClickLeft(buttonSelectMaps)))
	{
	    cursor.Hide();
	    sp.Hide();
	    cursor.Show();

	    // recv maps_info_list
	    QueueMessage packet(MSG_GET_MAPS_LIST);
	    if(SendWait(packet, MSG_GET_MAPS_LIST, "ScenarioInfoDialog: "))
	    {
		MapsFileInfoList lists;
		Network::PacketPopMapsFileInfoList(packet, lists);
		if(const Maps::FileInfo *fi = Dialog::SelectScenario(lists))
        	{
		    // send set_maps_info
	    	    packet.Reset();
		    packet.SetID(MSG_SET_CURRENT_MAP);
	    	    packet.Push(fi->file);
		    DEBUG(DBG_NETWORK, DBG_INFO, "send: " << Network::GetMsgString(packet.GetID()));
	    	    if(!Send(packet)) return false;
		}
		update_info = true;
	    }
	}
	else
	// click cancel
        if(le.MouseClickLeft(buttonCancel) || Game::HotKeyPress(Game::EVENT_DEFAULT_EXIT))
    	    return false;
        else
        // click ok
        if(Game::HotKeyPress(Game::EVENT_DEFAULT_READY) || (buttonOk.isEnable() && le.MouseClickLeft(buttonOk)))
    	{
/*
	    packet.Reset();
	    packet.SetID(MSG_START_GAME);
	    DEBUG(DBG_NETWORK, DBG_INFO, "send: " << Network::GetMsgString(packet.GetID()));
	    if(!Send(packet)) return false;
	    cursor.Hide();
	    return true;
*/
	}
	else
	if(Modes(ST_ADMIN) && le.MouseClickLeft(box))
	{
	    // click colors
	    if(Player* player = playersInfo.GetFromOpponentClick(le.GetMouseCursor()))
	    {
		u8 humans = conf.GetPlayers().GetColors(CONTROL_HUMAN);

		if((humans & player->color) && Color::NONE == change_color)
		{
		    cursor.Hide();
		    sp.Move((*itr).x - 3, (*itr).y - 3);
		    cursor.Show();
		    display.Flip();
		    change_color = player->color;
		}
		else
		if(conf.CurrentFileInfo().AllowHumanColors() & player->color)
		{
		    cursor.Hide();
		    sp.Hide();
		    cursor.Show();
		    display.Flip();
		    if(Color::NONE != change_color)
		    {
			QueueMessage packet(MSG_CHANGE_COLORS);
			packet.Push(change_color);
			packet.Push(player->color);
		        DEBUG(DBG_NETWORK, DBG_INFO, "send: " << Network::GetMsgString(packet.GetID()));
			if(!Send(packet)) return false;
			change_color = Color::NONE;
		    }
		}
	    }
	    else
	    // click races
	    if(Player* player = playersInfo.GetFromClassClick(le.GetMouseCursor()))
	    {
		if(conf.AllowChangeRace(player->color))
		{
                    switch(player->race)
                    {
                        case Race::KNGT: player->race = Race::BARB; break;
                        case Race::BARB: player->race = Race::SORC; break;
                        case Race::SORC: player->race = Race::WRLK; break;
                        case Race::WRLK: player->race = Race::WZRD; break;
                        case Race::WZRD: player->race = Race::NECR; break;
                        case Race::NECR: player->race = Race::RAND; break;
                        case Race::RAND: player->race = Race::KNGT; break;
                        default: break;
                    }
		    if(change_color)
		    {
			cursor.Hide();
			sp.Hide();
			cursor.Show();
			display.Flip();
			change_color = Color::NONE;
		    }
		    if((player->race & Race::ALL) || player->race == Race::RAND)
		    {
			QueueMessage packet(MSG_CHANGE_RACE);
			packet.Push(player->color);
			packet.Push(player->race);
		        DEBUG(DBG_NETWORK, DBG_INFO, "send: " << Network::GetMsgString(packet.GetID()));
			if(!Send(packet)) return false;
		    }
		}
	    }
	}

        DELAY(10);
    }

    return false;
}