PlayerDialog.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 //    Scorched3D (c) 2000-2009
00003 //
00004 //    This file is part of Scorched3D.
00005 //
00006 //    Scorched3D is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    Scorched3D is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with Scorched3D; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 ////////////////////////////////////////////////////////////////////////////////
00020 
00021 #include <tank/TankModelStore.h>
00022 #include <dialogs/PlayerDialog.h>
00023 #include <client/ClientState.h>
00024 #include <client/ScorchedClient.h>
00025 #include <tankai/TankAIStore.h>
00026 #include <tankai/TankAIStrings.h>
00027 #include <tank/TankContainer.h>
00028 #include <tank/TankColorGenerator.h>
00029 #include <tank/TankState.h>
00030 #include <tank/TankAvatar.h>
00031 #include <client/ClientParams.h>
00032 #include <graph/OptionsDisplay.h>
00033 #include <common/OptionsTransient.h>
00034 #include <common/OptionsScorched.h>
00035 #include <common/ChannelText.h>
00036 #include <common/Logger.h>
00037 #include <common/Defines.h>
00038 #include <GLW/GLWWindowManager.h>
00039 #include <GLW/GLWTextButton.h>
00040 #include <image/ImageFactory.h>
00041 #include <coms/ComsAddPlayerMessage.h>
00042 #include <coms/ComsMessageSender.h>
00043 #include <stdio.h>
00044 
00045 PlayerDialog *PlayerDialog::instance_ = 0;
00046 
00047 PlayerDialog *PlayerDialog::instance()
00048 {
00049         if (!instance_)
00050         {
00051                 instance_ = new PlayerDialog;
00052         }
00053         return instance_;
00054 }
00055 
00056 PlayerDialog::PlayerDialog() : 
00057         GLWWindow("Team", 10.0f, 10.0f, 740.0f, 480.0f, eSmallTitle,
00058                 "Allows the player to make changes to their\n"
00059                 "name, their tank and to change teams."),
00060         allocatedTeam_(0), cancelId_(0), viewer_(0)
00061 {
00062         needCentered_ = true;
00063 
00064         // Add buttons
00065         okId_ = addWidget(new GLWTextButton(LANG_RESOURCE("OK", "Ok"), 675, 10, 55, this, 
00066                 GLWButton::ButtonFlagOk | GLWButton::ButtonFlagCenterX))->getId();
00067         if (ClientParams::instance()->getConnectedToServer())
00068         {
00069                 cancelId_ = addWidget(new GLWTextButton(LANG_RESOURCE("CANCEL", "Cancel"), 580, 10, 85, this, 
00070                         GLWButton::ButtonFlagCancel | GLWButton::ButtonFlagCenterX))->getId();
00071         }
00072 
00073         GLWPanel *infoPanel = new GLWPanel(10.0f, 390.0f, 720.0f, 75.0f,
00074                 false, true, true);
00075         addWidget(infoPanel);
00076 
00077         // Create a texture to display the player color selector
00078         ImageHandle map = ImageFactory::loadImageHandle(S3D::getDataFile("data/windows/white.bmp"));
00079         colorTexture_.create(map);
00080 
00081         // Create players avatar choice
00082         GLWLabel *avatarLabel = (GLWLabel *) 
00083                 infoPanel->addWidget(new GLWLabel(10, 25, LANG_RESOURCE("AVATAR_LABEL", "Avatar:")));
00084         avatarTip1_.setText(ToolTip::ToolTipHelp, 
00085                 LANG_RESOURCE("AVATAR", "Avatar"), 
00086                 LANG_RESOURCE("AVATAR_TOOLTIP_CHANGE",
00087                 "The current player's avatar.\n"
00088                 "Click to change.\n"));
00089         avatarTip2_.setText(ToolTip::ToolTipHelp, 
00090                 LANG_RESOURCE("AVATAR", "Avatar"), 
00091                 LANG_RESOURCE("AVATAR_TOOLTIP_NO_CHANGE",
00092                 "The current player's avatar.\n"
00093                 "CANNOT be changed while playing,\n"
00094                 "you must quit to change."));
00095         imageList_ = new GLWImageList(95.0f, 20.0f);
00096         imageList_->addDirectory(S3D::getSettingsFile("avatars"));
00097         imageList_->addDirectory(S3D::getDataFile("data/avatars"));
00098         imageList_->setCurrentShortPath("player.png");
00099         imageList_->setToolTip(&avatarTip1_);
00100         imageList_->setName("Avatar");
00101         infoPanel->addWidget(imageList_);
00102 
00103         // Create player name choice
00104         ToolTip *nameTip = new ToolTip(ToolTip::ToolTipHelp, 
00105                 LANG_RESOURCE("PLAYER_NAME", "Player Name"),
00106                 LANG_RESOURCE("PLAYER_NAME_TOOLTIP",
00107                 "The name of this player.\n"
00108                 "Use the backspace or delete key to remove this name.\n"
00109                 "Type in a new player name via the keyboad to change."));
00110         GLWLabel *nameLabel = (GLWLabel *) 
00111                 infoPanel->addWidget(new GLWLabel(145, 40, LANG_RESOURCE("NAME_LABEL", "Name:")));
00112         nameLabel->setToolTip(nameTip);
00113         playerName_ = (GLWTextBox *) 
00114                 infoPanel->addWidget(new GLWTextBox(215, 40, 495, LANG_RESOURCE("PLAYER", "Player")));
00115         playerName_->setMaxTextLen(22);
00116         playerName_->setToolTip(nameTip);
00117         playerName_->setName("Name");
00118         playerName_->setAllowUnicode(
00119                 ScorchedClient::instance()->getOptionsGame().getAllowMultiLingualNames());
00120         
00121         // Create team choice
00122         ToolTip *teamTip = new ToolTip(ToolTip::ToolTipHelp, 
00123                 LANG_RESOURCE("TEAM_SELECTION", "Team Selection"),
00124                 LANG_RESOURCE("TEAM_SELECTION_TOOLTIP", "Change the team this player will join.\n"
00125                 "This is only available when playing team games."));
00126         teamLabel_ = (GLWLabel *) 
00127                 infoPanel->addWidget(new GLWLabel(145, 8, LANG_RESOURCE("TEAM_LABEL", "Team:")));
00128         teamLabel_->setToolTip(teamTip);
00129         teamDropDown_ = (GLWDropDownText *) 
00130                 infoPanel->addWidget(new GLWDropDownText(215, 8, 120));
00131         teamDropDown_->setHandler(this);
00132         teamDropDown_->setToolTip(teamTip);
00133         teamDropDown_->setName("Team");
00134 
00135         // Create color choice
00136         ToolTip *colorTip = new ToolTip(ToolTip::ToolTipHelp, 
00137                 LANG_RESOURCE("COLOR_SELECTION", "Color Selection"),
00138                 LANG_RESOURCE("COLOR_SELECTION_TOOLTIP", "Change the color this player displayed as.\n"
00139                 "This is only available when playing non-team games."));
00140         colorLabel_ = (GLWLabel *) 
00141                 infoPanel->addWidget(new GLWLabel(145, 8, LANG_RESOURCE("COLOR_LABEL", "Color:")));
00142         colorLabel_->setToolTip(colorTip);
00143         colorDropDown_ = (GLWDropDownColor *) 
00144                 infoPanel->addWidget(new GLWDropDownColor(215, 8, 120));
00145         colorDropDown_->setHandler(this);
00146         colorDropDown_->setToolTip(colorTip);
00147         colorDropDown_->setName("Color");
00148 
00149         // Create computer type choice
00150         ToolTip *typeTip = new ToolTip(ToolTip::ToolTipHelp, 
00151                 LANG_RESOURCE("PLAYER_TYPE", "Player Type"),
00152                 LANG_RESOURCE("PLAYER_TYPE_TOOLTIP", "Change between human and computer controlled\n"
00153                 "players.  This is only available when playing\n"
00154                 "single player games."));
00155         GLWLabel *typeLabel = (GLWLabel *) 
00156                 infoPanel->addWidget(new GLWLabel(520, 8, LANG_RESOURCE("TYPE_LABEL", "Type:")));
00157         typeLabel->setToolTip(typeTip);
00158         typeDropDown_ = (GLWDropDownText *) 
00159                 infoPanel->addWidget(new GLWDropDownText(590, 8, 120));
00160         typeDropDown_->setHandler(this);
00161         typeDropDown_->setToolTip(typeTip);
00162         typeDropDown_->setName("Type");
00163 
00164         humanToolTip_.setText(ToolTip::ToolTipHelp, 
00165                 LANG_RESOURCE("HUMAN", "Human"), 
00166                 LANG_RESOURCE("HUMAN_TOOLTIP", "A human controlled player."));
00167 }
00168 
00169 PlayerDialog::~PlayerDialog()
00170 {
00171 }
00172 
00173 void PlayerDialog::draw()
00174 {
00175         if (ScorchedClient::instance()->getOptionsGame().getTeams() != 1)
00176         {
00177                 // Auto select the team with the least players
00178                 unsigned int newTeam = 
00179                         ScorchedClient::instance()->getOptionsTransient().getLeastUsedTeam(
00180                         ScorchedClient::instance()->getTankContainer());
00181                 if (newTeam != allocatedTeam_)
00182                 {
00183                         teamDropDown_->setCurrentPosition(newTeam - 1);
00184                         allocatedTeam_ = newTeam;
00185                         viewer_->setTeam(newTeam);
00186                 }
00187         }
00188         GLWWindow::draw();
00189 }
00190 
00191 void PlayerDialog::select(unsigned int id, const int pos, 
00192         GLWSelectorEntry value)
00193 {
00194         if (id == typeDropDown_->getId())
00195         {
00196                 if (value.getDataText() == "Human")
00197                 {
00198                         imageList_->setCurrentShortPath("player.png");
00199                 }
00200                 else
00201                 {
00202                         imageList_->setCurrentShortPath("computer.png");
00203                 }
00204         }
00205         else if (id == teamDropDown_->getId())
00206         {
00207                 viewer_->setTeam(getCurrentTeam());
00208         }
00209 }
00210 
00211 void PlayerDialog::keyDown(char *buffer, unsigned int keyState, 
00212                 KeyboardHistory::HistoryElement *history, int hisCount, 
00213                 bool &skipRest)
00214 {
00215         GLWWindow::keyDown(buffer, keyState, history, hisCount, skipRest);
00216         if (ClientParams::instance()->getConnectedToServer()) skipRest = true;
00217 }
00218 
00219 void PlayerDialog::display()
00220 {       
00221         GLWWindow::display();
00222 
00223         if (!viewer_)
00224         {
00225                 GLWPanel *infoPanel = new GLWPanel(10.0f, 40.0f, 720.0f, 330.0f,
00226                         false, true, true);
00227                 viewer_ = new GLWTankViewer(5.0f, 5.0f, 4, 3);
00228                 viewer_->setName("Tank");
00229                 infoPanel->addWidget(viewer_);
00230                 addWidget(infoPanel);
00231         }
00232 
00233         static TankAIStore tankAIStore;
00234         static bool init = false;
00235         if (!init)
00236         {
00237                 init = true;
00238                 tankAIStore.loadAIs(true);
00239         }
00240 
00241         // Add teams
00242         teamDropDown_->clear();
00243         if (ScorchedClient::instance()->getOptionsGame().getTeams() == 1)
00244         {
00245                 teamDropDown_->addText(LANG_RESOURCE("NONE", "None"), "None");
00246                 teamDropDown_->setVisible(false);
00247                 teamLabel_->setVisible(false);
00248         }
00249         else
00250         {
00251                 for (int i=1; i<=ScorchedClient::instance()->getOptionsGame().getTeams(); i++)
00252                 {
00253                         const char *name = TankColorGenerator::getTeamName(i);
00254                         GLWSelectorEntry entry(LANG_RESOURCE(name, name), 0, false, &colorTexture_, 0);
00255                         entry.getColor() = TankColorGenerator::getTeamColor(i);
00256                         teamDropDown_->addEntry(entry);
00257                 }       
00258                 colorDropDown_->setVisible(false);
00259                 colorLabel_->setVisible(false);
00260         }
00261 
00262         // Add player types
00263         typeDropDown_->clear();
00264         typeDropDown_->addEntry(GLWSelectorEntry(LANG_RESOURCE("HUMAN", "Human"), 
00265                 &humanToolTip_, false, 0, 0, "Human"));
00266         if (!ClientParams::instance()->getConnectedToServer() &&
00267                 !ScorchedClient::instance()->getOptionsGame().getTutorial()[0])
00268         {
00269                 std::list<TankAI *>::iterator aiitor;
00270                 for (aiitor = tankAIStore.getAis().begin();
00271                         aiitor != tankAIStore.getAis().end();
00272                         aiitor++)
00273                 {
00274                         TankAI *ai = (*aiitor);
00275                         if (ai->availableForPlayers())
00276                         {
00277                                 typeDropDown_->addEntry(
00278                                         GLWSelectorEntry(LANG_RESOURCE(ai->getName(), ai->getName()),
00279                                                 (*aiitor)->getToolTip(), false, 0, 0, ai->getName()));
00280                         }
00281                 }
00282         }
00283         currentPlayerId_ = 0;
00284         nextPlayer();
00285 }
00286 
00287 void PlayerDialog::nextPlayer()
00288 {
00289         allocatedTeam_ = 0;
00290         currentPlayerId_ = getNextPlayer(currentPlayerId_);
00291         if (currentPlayerId_ == 0)
00292         {
00293                 GLWWindowManager::instance()->hideWindow(getId());
00294                 return;
00295         }
00296 
00297         Tank *tank = 
00298                 ScorchedClient::instance()->getTankContainer().getTankById(currentPlayerId_);
00299         if (ClientParams::instance()->getConnectedToServer())
00300         {
00301                 // If we are connected online then use the online name
00302                 playerName_->setText(
00303                         LANG_STRING(OptionsDisplay::instance()->getOnlineUserName()));
00304                 viewer_->selectModelByName(
00305                         OptionsDisplay::instance()->getOnlineTankModel());
00306                 if (!imageList_->setCurrentShortPath(
00307                         OptionsDisplay::instance()->getOnlineUserIcon()))
00308                 {
00309                         imageList_->setCurrentShortPath("player.png");
00310                 }
00311         }
00312         else
00313         {
00314                 // Else use the default names
00315                 if (tank) playerName_->setText(tank->getTargetName());
00316         }
00317                 
00318         if (tank->getState().getSpectator())
00319         {
00320                 imageList_->setEnabled(true);
00321                 imageList_->setToolTip(&avatarTip1_);
00322         }
00323         else
00324         {
00325                 imageList_->setEnabled(false);
00326                 imageList_->setToolTip(&avatarTip2_);
00327         }
00328 
00329         // Add colors
00330         colorDropDown_->clear();
00331         if (ScorchedClient::instance()->getOptionsGame().getTeams() == 1)
00332         {
00333                 std::map<unsigned int, Tank *> tanks =
00334                         ScorchedClient::instance()->getTankContainer().getPlayingTanks();
00335                 std::vector<Vector *> availableColors =
00336                         TankColorGenerator::instance()->getAvailableColors(tanks, tank);
00337                 std::vector<Vector *>::iterator itor;
00338                 for (itor = availableColors.begin();
00339                         itor != availableColors.end();
00340                         itor++)
00341                 {
00342                         Vector &color = *(*itor);
00343                         colorDropDown_->addColor(color);
00344                 }
00345 
00346                 if (ClientParams::instance()->getConnectedToServer())
00347                 {
00348                         Vector onlineColor = 
00349                                 OptionsDisplay::instance()->getOnlineColor();
00350                         colorDropDown_->setCurrentColor(onlineColor);
00351                         if (colorDropDown_->getCurrentColor() != onlineColor)
00352                         {
00353                                 colorDropDown_->setCurrentColor(tank->getColor());      
00354                         }
00355                 }
00356                 else
00357                 {
00358                         colorDropDown_->setCurrentColor(tank->getColor());                      
00359                 }
00360         }
00361 }
00362 
00363 unsigned int PlayerDialog::getNextPlayer(unsigned int current)
00364 {
00365         std::map<unsigned int, Tank *> &tanks = 
00366                 ScorchedClient::instance()->getTankContainer().getPlayingTanks();
00367         std::map<unsigned int, Tank *>::iterator itor;
00368         for (itor = tanks.begin();
00369                 itor != tanks.end();
00370                 itor++)
00371         {
00372                 Tank *tank = (*itor).second;
00373                 if ((tank->getDestinationId() == 
00374                         ScorchedClient::instance()->getTankContainer().getCurrentDestinationId()) &&
00375                         (tank->getPlayerId() != TargetID::SPEC_TANK_ID) &&
00376                         (tank->getState().getState() != TankState::sNormal))
00377                 {
00378                         if (current == 0)
00379                         {
00380                                 return tank->getPlayerId();
00381                         }
00382                         else if (tank->getPlayerId() == current) current = 0;
00383                 }
00384         }
00385         return 0;
00386 }
00387 
00388 int PlayerDialog::getCurrentTeam()
00389 {
00390         return ((ScorchedClient::instance()->getOptionsGame().getTeams() > 1)?
00391                 teamDropDown_->getCurrentPosition() + 1:0);
00392 }
00393 
00394 void PlayerDialog::buttonDown(unsigned int id)
00395 {
00396         if (id == okId_)
00397         {
00398                 if (!playerName_->getText().empty())
00399                 {
00400                         // If we are connected online save this players name
00401                         if (ClientParams::instance()->getConnectedToServer())
00402                         {
00403                                 OptionsDisplay::instance()->getOnlineUserNameEntry().setValue(
00404                                         playerName_->getText().c_str());
00405                                 OptionsDisplay::instance()->getOnlineTankModelEntry().setValue(
00406                                         viewer_->getModelName());
00407                                 OptionsDisplay::instance()->getOnlineUserIconEntry().setValue(
00408                                         imageList_->getCurrentShortPath());
00409                                 if (ScorchedClient::instance()->getOptionsGame().getTeams() == 1)
00410                                 {
00411                                         OptionsDisplay::instance()->getOnlineColorEntry().setValue(
00412                                                 colorDropDown_->getCurrentColor());
00413                                 }
00414                         }
00415 
00416                         // Get the model type (turns a "Random" choice into a proper name)
00417                         TankModel *model = 
00418                                 ScorchedClient::instance()->getTankModels().
00419                                         getModelByName(viewer_->getModelName(), 
00420                                         getCurrentTeam(), false);
00421 
00422                         // Get the player type
00423                         const char *playerType = typeDropDown_->getCurrentDataText();
00424 
00425                         // Add this player
00426                         ComsAddPlayerMessage message(currentPlayerId_,
00427                                 playerName_->getLangString(),
00428                                 colorDropDown_->getCurrentColor(),
00429                                 model->getName(),
00430                                 model->getTypeName(),
00431                                 ScorchedClient::instance()->getTankContainer().getCurrentDestinationId(),
00432                                 getCurrentTeam(),
00433                                 playerType);
00434                         // Add avatar (if not one)
00435                         Tank *tank = ScorchedClient::instance()->getTankContainer().
00436                                 getTankById(currentPlayerId_);
00437                         if (tank && !tank->getAvatar().getName()[0])
00438                         {
00439                                 if (tank->getAvatar().loadFromFile(imageList_->getCurrentLongPath()))
00440                                 {
00441                                         if (tank->getAvatar().getFile().getBufferUsed() <=
00442                                                 (unsigned) ScorchedClient::instance()->getOptionsGame().getMaxAvatarSize())
00443                                         {
00444                                                 message.setPlayerIconName(imageList_->getCurrentShortPath());
00445                                                 message.getPlayerIcon().addDataToBuffer(
00446                                                         tank->getAvatar().getFile().getBuffer(),
00447                                                         tank->getAvatar().getFile().getBufferUsed());
00448                                         }
00449                                         else
00450                                         {
00451                                                 ChannelText text("general", 
00452                                                         LANG_RESOURCE_2("AVATAR_TOO_LARGE", 
00453                                                         "Warning: Avatar too large to send to server, is {0} should be < {1}",
00454                                                         tank->getAvatar().getFile().getBufferUsed(),
00455                                                         ScorchedClient::instance()->getOptionsGame().getMaxAvatarSize()));
00456                                                 Logger::log( "Warning: Avatar too large to send to server");
00457                                         }
00458                                 }
00459                         }
00460                         ComsMessageSender::sendToServer(message);
00461 
00462                         nextPlayer();
00463                 }
00464         }
00465         else if (id == cancelId_)
00466         {
00467                 GLWWindowManager::instance()->hideWindow(getId());
00468         }
00469 }

Generated on Mon Feb 16 15:14:37 2009 for Scorched3D by  doxygen 1.5.3