playersdiagram.cpp
1 // playerdiagram.cpp
2 //------------------------------------------------------------------------------
3 //------------------------------------------------------------------------------
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 // 02110-1301, USA.
19 //
20 //------------------------------------------------------------------------------
21 // Copyright (C) 2010 "Blzut3" <admin@maniacsvault.net>
22 //------------------------------------------------------------------------------
23 #include "playersdiagram.h"
24 #include "serverapi/playerslist.h"
25 #include "serverapi/server.h"
26 #include "log.h"
27 #include <QPainter>
28 #include <cassert>
29 
30 const char* PlayersDiagram::slotStyles[NUM_SLOTSTYLES] = { "marines", "blocks" };
31 const QImage* PlayersDiagram::openImage = NULL;
32 const QImage* PlayersDiagram::openSpecImage = NULL;
33 const QImage* PlayersDiagram::botImage = NULL;
34 const QImage* PlayersDiagram::playerImage = NULL;
35 const QImage* PlayersDiagram::spectatorImage = NULL;
36 
37 PlayersDiagram::PlayersDiagram(ServerCPtr server)
38 : server(server), tmp(NULL)
39 {
40  if(openImage == NULL)
41  {
42  return;
43  }
44 
45  obtainPlayerNumbers();
46  draw();
47 }
48 
49 PlayersDiagram::~PlayersDiagram()
50 {
51  if(tmp != NULL)
52  delete tmp;
53 }
54 
55 const QImage* PlayersDiagram::colorizePlayer(const QImage *image, const QColor &color)
56 {
57  if(tmp != NULL)
58  {
59  delete tmp;
60  }
61  tmp = new QImage(*image);
62 
63  QVector<QRgb> colors = tmp->colorTable();
64  QColor destinationColor = color.toHsv();
65  for(int i = 0; i < colors.size(); ++i)
66  {
67  // Cyan has no red so move on if this color has red.
68  if(qRed(colors[i]) != 0 || qAlpha(colors[i]) == 0)
69  {
70  continue;
71  }
72 
73  int hue = 0;
74  int saturation = 0;
75  int value = 0;
76  destinationColor.getHsv(&hue, &saturation, &value);
77  destinationColor.setHsv(hue, saturation, QColor(colors[i]).toHsv().value());
78  colors[i] = destinationColor.rgb();
79  }
80  tmp->setColorTable(colors);
81 
82  return tmp;
83 }
84 
85 void PlayersDiagram::deleteImages()
86 {
87  if(openImage != NULL)
88  {
89  delete openImage;
90  delete openSpecImage;
91  delete botImage;
92  delete playerImage;
93  delete spectatorImage;
94  }
95 }
96 
97 void PlayersDiagram::draw()
98 {
99  // Don't bother trying to draw an empty image.
100  if(server->numTotalSlots() == 0)
101  return;
102 
103  diagram = QPixmap(server->numTotalSlots() * playerImage->width(), playerImage->height());
104  diagram.fill(Qt::transparent);
105 
106  slotSize = playerImage->width();
107  position = diagram.width() - slotSize;
108  painter = new QPainter(&diagram);
109 
110  for (int team = 0; team < MAX_TEAMS; ++team)
111  {
112  drawTeam(Human, team, numHumansOnTeam[team]);
113  drawTeam(Bot, team, numBotsOnTeam[team]);
114  }
115 
116  drawTeam(Human, Player::TEAM_NONE, numHumansWithoutTeam);
117  drawTeam(Bot, Player::TEAM_NONE, numBotsWithoutTeam);
118 
119  if (numSpectators > 0)
120  {
121  drawPictures(spectatorImage, numSpectators);
122  }
123 
124  if (numFreeJoinSlots > 0)
125  {
126  drawPictures(openImage, numFreeJoinSlots);
127  }
128 
129  if (numFreeSpectatorSlots > 0)
130  {
131  drawPictures(openSpecImage, numFreeSpectatorSlots);
132  }
133 
134  delete painter;
135 }
136 
137 void PlayersDiagram::drawTeam(PlayerType playerType, int team, int howMany)
138 {
139  if (howMany > 0)
140  {
141  const QImage* baseImage;
142 
143  switch(playerType)
144  {
145  case Bot:
146  baseImage = botImage;
147  break;
148 
149  case Human:
150  baseImage = playerImage;
151  break;
152 
153  default:
154  gLog << "Error inside PlayersDiagram::drawTeam(): unknown PlayerType";
155  return;
156  }
157 
158  const QImage* picture = colorizePlayer(baseImage, QColor(server->teamColor(team)));
159  drawPictures(picture, howMany);
160  }
161 }
162 
163 void PlayersDiagram::drawPictures(const QImage* image, int howMany)
164 {
165  assert(image != NULL);
166  for (; howMany > 0; --howMany)
167  {
168  painter->drawImage(position, 0, *image);
169  position -= slotSize;
170  }
171 }
172 
173 bool PlayersDiagram::isStyleNumberValid(int style)
174 {
175  return style >= NUM_SLOTSTYLES || style < 0;
176 }
177 
179 {
180  deleteImages();
181 
182  if(isStyleNumberValid(style))
183  {
184  style = 0;
185  }
186 
187  QString filepath(":/slots/");
188  filepath += slotStyles[style];
189  openImage = new QImage(filepath + "/open");
190  openSpecImage = new QImage(filepath + "/specopen");
191  botImage = new QImage(filepath + "/bot");
192  playerImage = new QImage(filepath + "/player");
193  spectatorImage = new QImage(filepath + "/spectator");
194 }
195 
196 void PlayersDiagram::obtainPlayerNumbers()
197 {
198  memset(numBotsOnTeam, 0, sizeof(int) * MAX_TEAMS);
199  memset(numHumansOnTeam, 0, sizeof(int) * MAX_TEAMS);
200 
201  const PlayersList &players = server->players();
202 
203  numBotsWithoutTeam = players.numBotsWithoutTeam();
204  numFreeJoinSlots = server->numFreeJoinSlots();
205  numFreeSpectatorSlots = server->numFreeSpectatorSlots();
206  numHumansWithoutTeam = players.numHumansWithoutTeam();
207  numSpectators = players.numSpectators();
208 
209  for(int i = 0; i < MAX_TEAMS; ++i)
210  {
211  numBotsOnTeam[i] = players.numBotsOnTeam(i);
212  numHumansOnTeam[i] = players.numHumansOnTeam(i);
213  }
214 }
static void loadImages(int style)
const QImage * colorizePlayer(const QImage *image, const QColor &color)