1 /*
2  * Copyright 2014, 2016 Peter Olsson
3  *
4  * This file is part of Brum Brum Rally.
5  *
6  * Brum Brum Rally is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Brum Brum Rally is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "NetworkMenu.h"
21 #include "ConnectToNetwork.h"
22 #include "CreateNetworkGame.h"
23 #include "JoinNetworkGame.h"
24 #include "StateManager.h"
25 #include "Network.h"
26 #include <sstream>
27 
NetworkMenu(Network * net)28 NetworkMenu::NetworkMenu(Network* net)
29 :	net(net),
30 	joinAction(false),
31 	hostAction(false),
32 	disconnectAction(false),
33 	gameList(net->getGameList()),
34 	numberOfPlayersWaiting(-1)
35 {
36 	net->lobby();
37 
38 	menu.setTitle(net->name() + " games");
39 
40 	menu.addItem("Join", &joinAction);
41 	menu.addItem("Create", &hostAction);
42 	menu.addItem("Disconnect", &disconnectAction);
43 
44 	menu.addRenderObjects(this, CENTER_X, 210);
45 	net->setGameState(this, true, true);
46 
47 	addRenderObject(playersWaitingRenderObject);
48 }
49 
update()50 void NetworkMenu::update()
51 {
52 	updatePlayersOnlineCounter();
53 
54 	net->step();
55 	menu.update();
56 }
57 
onEvent(const SDL_Event & event)58 void NetworkMenu::onEvent(const SDL_Event& event)
59 {
60 	IPaddress joinAddress = IPaddress();
61 	if (!net->onEvent(event))
62 	{
63 		StateManager& sm = StateManager::getInstance();
64 		MenuEvent me = sm.getMenuEvent(event);
65 		if (gameList.focus())
66 		{
67 			joinAddress = gameList.onEvent(event);
68 			if (me.type == MENU_MOUSE_MOVE ||
69 				(!gameList.focus() &&
70 			    (me.type == MENU_MOUSE_CLICK1 ||
71 			     me.type == MENU_MOUSE_CLICK2)) ||
72 				 me.type == MENU_MOUSE_RELEASE)
73 			{
74 				if (!gameList.focus() ||
75 				    menu.getItem(me.x, me.y) > 0)
76 				{
77 					gameList.focus(false);
78 					menu.makeActive(ITEM_UNSELECTED);
79 				}
80 				menu.onEvent(me);
81 
82 				if (!menu.isActive())
83 				{
84 					gameList.focus(false);
85 				}
86 			}
87 			else if (me.type == MENU_ESC)
88 			{
89 				gameList.focus(false);
90 				menu.makeActive(ITEM_SELECTED);
91 			}
92 		}
93 		else
94 		{
95 			menu.onEvent(me);
96 			if (me.type == MENU_MOUSE_MOVE ||
97 			    me.type == MENU_MOUSE_CLICK1 ||
98 			    me.type == MENU_MOUSE_CLICK2 ||
99 				me.type == MENU_MOUSE_RELEASE ||
100 				(event.type == SDL_MOUSEBUTTONDOWN && (event.button.button == SDL_BUTTON_WHEELUP || event.button.button == SDL_BUTTON_WHEELDOWN)))
101 			{
102 				joinAddress = gameList.onEvent(event);
103 				if (gameList.focus())
104 				{
105 					gameList.focus(true);
106 					menu.setItem(0);
107 					menu.makeActive();
108 				}
109 			}
110 
111 			if (disconnectAction || me.type == MENU_ESC)
112 			{
113 				sm.enter(new ConnectToNetwork(), -1);
114 			}
115 			else if (hostAction)
116 			{
117 				sm.enter(new CreateNetworkGame(net), +1);
118 			}
119 			else if (joinAction)
120 			{
121 				gameList.focus(true);
122 				joinAction = false;
123 				menu.makeActive();
124 			}
125 		}
126 
127 		if (joinAddress.host != 0)
128 		{
129 			sm.enter(new JoinNetworkGame(net, joinAddress), +1);
130 		}
131 	}
132 }
133 
updatePlayersOnlineCounter()134 void NetworkMenu::updatePlayersOnlineCounter()
135 {
136 	int newNumberOfplayersWaiting = net->numberOfPlayersWaiting();
137 	if (numberOfPlayersWaiting != newNumberOfplayersWaiting)
138 	{
139 		numberOfPlayersWaiting = newNumberOfplayersWaiting;
140 
141 		// Build text.
142 		std::ostringstream oss;
143 		if (numberOfPlayersWaiting == 0)
144 		{
145 			oss.str("You are the only player waiting here");
146 		}
147 		else if (numberOfPlayersWaiting == 1)
148 		{
149 			oss.str("There is one other player waiting here");
150 		}
151 		else
152 		{
153 			oss << "There are " << numberOfPlayersWaiting << " other players waiting here";
154 		}
155 
156 		// Update render object.
157 		Surface surface(oss.str(), SMALL_FONT, TEXT_COLOR, TEXT_BORDER_COLOR);
158 		playersWaitingRenderObject.setSurface(surface);
159 		playersWaitingRenderObject.moveTo((GAME_WIDTH - surface.width()) / 2, GAME_HEIGHT - 9);
160 	}
161 }
162