00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
00078 ImageHandle map = ImageFactory::loadImageHandle(S3D::getDataFile("data/windows/white.bmp"));
00079 colorTexture_.create(map);
00080
00081
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
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
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
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
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
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
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
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
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
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
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
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
00417 TankModel *model =
00418 ScorchedClient::instance()->getTankModels().
00419 getModelByName(viewer_->getModelName(),
00420 getCurrentTeam(), false);
00421
00422
00423 const char *playerType = typeDropDown_->getCurrentDataText();
00424
00425
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
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 }