00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <dialogs/ScoreDialog.h>
00022 #include <tank/TankSort.h>
00023 #include <tank/TankContainer.h>
00024 #include <tank/TankTeamScore.h>
00025 #include <tank/TankColorGenerator.h>
00026 #include <tank/TankScore.h>
00027 #include <tank/TankState.h>
00028 #include <tank/TankAvatar.h>
00029 #include <tankgraph/TargetRendererImplTank.h>
00030 #include <tankai/TankAI.h>
00031 #include <GLW/GLWFont.h>
00032 #include <GLW/GLWWindowManager.h>
00033 #include <GLW/GLWColors.h>
00034 #include <client/ClientParams.h>
00035 #include <graph/OptionsDisplay.h>
00036 #include <common/OptionsTransient.h>
00037 #include <common/OptionsScorched.h>
00038 #include <common/Defines.h>
00039 #include <engine/GameState.h>
00040 #include <client/ClientState.h>
00041 #include <client/ScorchedClient.h>
00042 #include <client/ClientScoreHandler.h>
00043 #include <server/ScorchedServer.h>
00044 #include <lang/LangResource.h>
00045 #include <stdio.h>
00046
00047 static const float rankLeft = 15.0f;
00048 static const float iconLeft = 5.0f;
00049 static const float nameLeft = 35.0f;
00050 static const float livesLeft = 230.0f;
00051 static const float killsLeft = 255.0f;
00052 static const float assistsLeft = 280.0f;
00053 static const float winsLeft = 305.0f;
00054 static const float moneyLeft = 325.0f;
00055 static const float scoreLeft = 405.0f;
00056 static const float statsLeft = 475.0f;
00057 static const float readyLeft = 515.0f;
00058 static const float lineSpacer = 10.0f;
00059
00060 ScoreDialog *ScoreDialog::instance_ = 0;
00061 ScoreDialog *ScoreDialog::instance2_ = 0;
00062
00063 ScoreDialog *ScoreDialog::instance()
00064 {
00065 if (!instance_)
00066 {
00067 instance_ = new ScoreDialog;
00068 }
00069
00070 return instance_;
00071 }
00072
00073 ScoreDialog *ScoreDialog::instance2()
00074 {
00075 if (!instance2_)
00076 {
00077 instance2_ = new ScoreDialog;
00078 }
00079
00080 return instance2_;
00081 }
00082
00083 ScoreDialog::ScoreDialog() :
00084 GLWWindow("Score", 10.0f, 10.0f, 525.0f, 310.0f, eTransparent |eSmallTitle,
00085 "Shows the current score for all players."),
00086 lastScoreValue_(0), lastMoneyValue_(0), lastNoPlayers_(0)
00087 {
00088
00089 }
00090
00091 ScoreDialog::~ScoreDialog()
00092 {
00093
00094 }
00095
00096 void ScoreDialog::display()
00097 {
00098 GLWWindow::display();
00099 calculateScores();
00100
00101 if (OptionsDisplay::instance()->getHideFinalScore() &&
00102 ScorchedClient::instance()->getGameState().getState() ==
00103 ClientState::StateScore)
00104 {
00105 GLWWindowManager::instance()->hideWindow(getId());
00106 }
00107 }
00108
00109 void ScoreDialog::calculateScores()
00110 {
00111 lastScoreValue_ = lastMoneyValue_ = 0;
00112 std::map<unsigned int, Tank *> &tanks =
00113 ScorchedClient::instance()->getTankContainer().getPlayingTanks();
00114 std::map<unsigned int, Tank *>::iterator itor;
00115 for (itor = tanks.begin();
00116 itor != tanks.end();
00117 itor++)
00118 {
00119 Tank *tank = (*itor).second;
00120 lastMoneyValue_ += tank->getScore().getMoney();
00121 lastScoreValue_ += tank->getScore().getScore();
00122 }
00123
00124 lastNoPlayers_ = tanks.size();
00125 sortedTanks_.clear();
00126 TankSort::getSortedTanksIds(
00127 ScorchedClient::instance()->getContext(), sortedTanks_);
00128 }
00129
00130 void ScoreDialog::windowInit(const unsigned state)
00131 {
00132 needCentered_ = true;
00133 }
00134
00135 void ScoreDialog::draw()
00136 {
00137 float h = sortedTanks_.size() * lineSpacer + 80.0f;
00138 if (ScorchedClient::instance()->getOptionsGame().getTeams() > 1)
00139 {
00140 h += (lineSpacer * 2.0f) * (ScorchedClient::instance()->getOptionsGame().getTeams() - 1) +
00141 lineSpacer * 2.0f;
00142 }
00143 setH(h);
00144
00145 static size_t noTanks = 0;
00146 if (noTanks != sortedTanks_.size())
00147 {
00148 needCentered_ = true;
00149 noTanks = sortedTanks_.size();
00150 }
00151
00152 GLWWindow::draw();
00153 GLState newState(GLState::TEXTURE_OFF | GLState::DEPTH_OFF);
00154
00155 bool finished = false;
00156 if (ScorchedClient::instance()->getGameState().getState() ==
00157 ClientState::StateScore)
00158 {
00159 finished = ClientScoreHandler::instance()->getFinalScore();
00160 }
00161
00162 Vector white(0.9f, 0.9f, 1.0f);
00163 bool server = (ClientParams::instance()->getConnectedToServer());
00164 {
00165 LANG_RESOURCE_VAR(CURRENT_RANKINGS, "CURRENT_RANKINGS", "Current Rankings");
00166 LANG_RESOURCE_VAR(FINAL_RANKINGS, "FINAL_RANKINGS", "Final Rankings");
00167 LANG_RESOURCE_VAR(WAITING_FOR_PLAYERS, "WAITING_FOR_PLAYERS", "Waiting for more players");
00168 LANG_RESOURCE_VAR(WAITING_TO_JOIN, "WAITING_TO_JOIN", "Waiting to join game");
00169 LangString SERVER_NAME = LANG_STRING(ScorchedClient::instance()->getOptionsGame().getServerName());
00170
00171 LangString *text = &CURRENT_RANKINGS;
00172 if (finished)
00173 {
00174 text = &FINAL_RANKINGS;
00175 }
00176 else if (ScorchedClient::instance()->getGameState().getState() ==
00177 ClientState::StateGetPlayers)
00178 {
00179 finished = true;
00180 if (ScorchedClient::instance()->getTankContainer().getNoOfNonSpectatorTanks() <
00181 ScorchedClient::instance()->getOptionsGame().getNoMinPlayers())
00182 {
00183 text = &WAITING_FOR_PLAYERS;
00184 }
00185 else
00186 {
00187 text = &WAITING_TO_JOIN;
00188 }
00189 }
00190 else if (server)
00191 {
00192 text = &SERVER_NAME;
00193 }
00194
00195 GLWFont::instance()->getGameShadowFont()->draw(
00196 GLWColors::black,
00197 20,
00198 x_ + 8.0f - 2.0f, y_ + h_ - 22.0f + 2.0f, 0.0f,
00199 *text);
00200 GLWFont::instance()->getGameFont()->draw(
00201 white,
00202 20,
00203 x_ + 8.0f, y_ + h_ - 22.0f, 0.0f,
00204 *text);
00205 }
00206
00207 if (!finished)
00208 {
00209 LangString buffer;
00210
00211 LANG_RESOURCE_VAR_2(ROUND_OF, "ROUND_OF", "Round {0} of {1}",
00212 S3D::formatStringBuffer("%i", ScorchedClient::instance()->getOptionsTransient().getCurrentRoundNo()),
00213 S3D::formatStringBuffer("%i", ScorchedClient::instance()->getOptionsGame().getNoRounds()));
00214 buffer.append(ROUND_OF);
00215
00216 if (ScorchedClient::instance()->getOptionsGame().getNoMaxRoundTurns() > 0)
00217 {
00218 LANG_RESOURCE_VAR_2(MOVE_OF, "MOVE_OF", ",Move {0} of {1}",
00219 S3D::formatStringBuffer("%i", ScorchedClient::instance()->getOptionsTransient().getCurrentGameNo()),
00220 S3D::formatStringBuffer("%i", ScorchedClient::instance()->getOptionsGame().getNoMaxRoundTurns()));
00221 buffer.append(MOVE_OF);
00222 }
00223
00224 float roundsWidth = GLWFont::instance()->getGameFont()->getWidth(
00225 10, buffer);
00226 GLWFont::instance()->getGameFont()->draw(
00227 white,
00228 10,
00229 x_ + 470 - roundsWidth, y_ + h_ - 40.0f, 0.0f,
00230 buffer);
00231 }
00232
00233 LANG_RESOURCE_VAR(SCORE_NAME, "SCORE_NAME", "Name");
00234 LANG_RESOURCE_VAR(SCORE_K, "SCORE_K", "K");
00235 LANG_RESOURCE_VAR(SCORE_W, "SCORE_W", "W");
00236 LANG_RESOURCE_VAR(SCORE_A, "SCORE_A", "A");
00237 LANG_RESOURCE_VAR(SCORE_SCORE, "SCORE_SCORE", "Score");
00238 LANG_RESOURCE_VAR(SCORE_RANK, "SCORE_RANK", "Rank");
00239 LANG_RESOURCE_VAR(SCORE_L, "SCORE_L", "L");
00240
00241 float y = lineSpacer + 10.0f;
00242 GLWFont::instance()->getGameFont()->draw(
00243 white,
00244 12,
00245 x_ + nameLeft, y_ + h_ - y - lineSpacer - 26.0f, 0.0f,
00246 SCORE_NAME);
00247 GLWToolTip::instance()->addToolTip(ToolTip::ToolTipHelp,
00248 LANG_RESOURCE("NAME", "Name"),
00249 LANG_RESOURCE("NAME_TOOLTIP", "The name of the player"),
00250 x_ + nameLeft, y_ + h_ - y - lineSpacer - 26.0f, 100.0f, 16.0f);
00251
00252 GLWFont::instance()->getGameFont()->draw(
00253 white,
00254 12,
00255 x_ + killsLeft, y_ + h_ - y - lineSpacer - 26.0f, 0.0f,
00256 SCORE_K);
00257 GLWToolTip::instance()->addToolTip(ToolTip::ToolTipHelp,
00258 LANG_RESOURCE("KILLS", "Kills"),
00259 LANG_RESOURCE_1("KILL_TOOLTIP",
00260 "The number of players this player has killed.\n{0} score awarded per kill.",
00261 S3D::formatStringBuffer("%i", ScorchedClient::instance()->getOptionsGame().getScorePerKill())),
00262 x_ + killsLeft, y_ + h_ - y - lineSpacer - 26.0f, 20.0f, 16.0f);
00263
00264 GLWFont::instance()->getGameFont()->draw(
00265 white,
00266 12,
00267 x_ + winsLeft, y_ + h_ - y - lineSpacer - 26.0f, 0.0f,
00268 SCORE_W);
00269 GLWToolTip::instance()->addToolTip(ToolTip::ToolTipHelp,
00270 LANG_RESOURCE("WINS", "Wins"),
00271 LANG_RESOURCE_1("WINS_TOOLTIP",
00272 "The number of rounds this player has won.\n{0} score awarded per round won.",
00273 S3D::formatStringBuffer("%i", ScorchedClient::instance()->getOptionsGame().getScoreWonForRound())),
00274 x_ + winsLeft, y_ + h_ - y - lineSpacer - 26.0f, 20.0f, 16.0f);
00275
00276 GLWFont::instance()->getGameFont()->draw(
00277 white,
00278 12,
00279 x_ + assistsLeft, y_ + h_ - y - lineSpacer - 26.0f, 0.0f,
00280 SCORE_A);
00281 GLWToolTip::instance()->addToolTip(ToolTip::ToolTipHelp,
00282 LANG_RESOURCE("ASSISTS", "Assists"),
00283 LANG_RESOURCE_1("ASSISTS_TOOLTIP",
00284 "The number of kills this player has assisted in.\n{0} score awarded per assist.",
00285 S3D::formatStringBuffer("%i", ScorchedClient::instance()->getOptionsGame().getScorePerAssist())),
00286 x_ + assistsLeft, y_ + h_ - y - lineSpacer - 26.0f, 20.0f, 16.0f);
00287
00288 GLWFont::instance()->getGameFont()->draw(
00289 white,
00290 12,
00291 x_ + moneyLeft + 10, y_ + h_ - y - lineSpacer - 26.0f, 0.0f,
00292 "$");
00293 GLWToolTip::instance()->addToolTip(ToolTip::ToolTipHelp,
00294 LANG_RESOURCE("MONEY", "Money"),
00295 LANG_RESOURCE_1("MONEY_TOOLTIP", "The amount of money this player has.\n%{0} score awarded per dollar.",
00296 S3D::formatStringBuffer("%.1f", float(ScorchedClient::instance()->getOptionsGame().getScorePerMoney()) / 1000.0f)),
00297 x_ + moneyLeft, y_ + h_ - y - lineSpacer - 26.0f, 20.0f, 16.0f);
00298
00299 GLWFont::instance()->getGameFont()->draw(
00300 white,
00301 12,
00302 x_ + scoreLeft, y_ + h_ - y - lineSpacer - 26.0f, 0.0f,
00303 SCORE_SCORE);
00304 GLWToolTip::instance()->addToolTip(ToolTip::ToolTipHelp,
00305 LANG_RESOURCE("SCORE", "Score"),
00306 LANG_RESOURCE("SCORE_TOOLTIP", "The current score for this player.\nCalculated from the number of kills, wins, money and bonus score awards."),
00307 x_ + scoreLeft, y_ + h_ - y - lineSpacer - 26.0f, 80.0f, 16.0f);
00308
00309 GLWFont::instance()->getGameFont()->draw(
00310 white,
00311 12,
00312 x_ + statsLeft, y_ + h_ - y - lineSpacer - 26.0f, 0.0f,
00313 SCORE_RANK);
00314 GLWToolTip::instance()->addToolTip(ToolTip::ToolTipHelp,
00315 LANG_RESOURCE("RANK", "Rank"),
00316 LANG_RESOURCE("RANK_TOOLTIP", "The current online ranking for this player."),
00317 x_ + statsLeft, y_ + h_ - y - lineSpacer - 26.0f, 40.0f, 16.0f);
00318
00319 GLWFont::instance()->getGameFont()->draw(
00320 white,
00321 12,
00322 x_ + livesLeft, y_ + h_ - y - lineSpacer - 26.0f, 0.0f,
00323 SCORE_L);
00324 GLWToolTip::instance()->addToolTip(ToolTip::ToolTipHelp,
00325 LANG_RESOURCE("LIVES", "Lives"),
00326 LANG_RESOURCE_1("LIVES_TOOLTIP", "The current number of lives this player has left.\n{0} score awarded for each life remaining.",
00327 S3D::formatStringBuffer("%i", ScorchedClient::instance()->getOptionsGame().getScoreWonForLives())),
00328 x_ + livesLeft, y_ + h_ - y - lineSpacer - 26.0f, 20.0f, 16.0f);
00329 y+= lineSpacer + lineSpacer;
00330
00331 int tmpLastScoreValue = 0;
00332 int tmpLastMoneyValue = 0;
00333 if (ScorchedClient::instance()->getOptionsGame().getTeams() > 1)
00334 {
00335 int winningTeam = TankSort::getWinningTeam(
00336 ScorchedClient::instance()->getContext());
00337
00338 for (int i=0; i<ScorchedClient::instance()->getOptionsGame().getTeams(); i++)
00339 {
00340 bool someTeam = false;
00341 std::list<unsigned int>::iterator itor;
00342 for (itor = sortedTanks_.begin();
00343 itor != sortedTanks_.end();
00344 itor ++)
00345 {
00346 unsigned int playerId = (*itor);
00347 Tank *current = ScorchedClient::instance()->getTankContainer().getTankById(playerId);
00348 if (current && current->getTeam() == (i + 1) && !current->getState().getSpectator())
00349 {
00350 someTeam = true;
00351 addLine(current, y, (char *)((winningTeam==(i+1))?"1":"2"), finished);
00352
00353 tmpLastScoreValue += current->getScore().getScore();
00354 tmpLastMoneyValue += current->getScore().getMoney();
00355 y+= lineSpacer;
00356 }
00357 }
00358 if (someTeam)
00359 {
00360 addScoreLine(y,
00361 TankColorGenerator::getTeamColor(i + 1),
00362 ScorchedClient::instance()->getContext().getTankTeamScore().getScore(i+1));
00363 y+= lineSpacer;
00364 y+= lineSpacer;
00365 }
00366 }
00367 }
00368 else
00369 {
00370
00371 int rank = 1;
00372 char strrank[10];
00373 std::list<unsigned int>::iterator itor;
00374 for (itor = sortedTanks_.begin();
00375 itor != sortedTanks_.end();
00376 itor ++, rank++)
00377 {
00378 unsigned int playerId = (*itor);
00379 Tank *current = ScorchedClient::instance()->getTankContainer().getTankById(playerId);
00380 if (current && !current->getState().getSpectator())
00381 {
00382 snprintf(strrank, 10, "%i", rank);
00383
00384 addLine(current, y, strrank, finished);
00385 tmpLastScoreValue += current->getScore().getScore();
00386 tmpLastMoneyValue += current->getScore().getMoney();
00387 y+= lineSpacer;
00388 }
00389 }
00390 }
00391 y+= lineSpacer / 1.5f;
00392
00393 std::list<unsigned int>::iterator itor;
00394 for (itor = sortedTanks_.begin();
00395 itor != sortedTanks_.end();
00396 itor ++)
00397 {
00398 unsigned int playerId = (*itor);
00399 Tank *current = ScorchedClient::instance()->
00400 getTankContainer().getTankById(playerId);
00401 if (current && current->getState().getSpectator())
00402 {
00403 addLine(current, y, " ", false);
00404 y+= lineSpacer;
00405 }
00406 }
00407
00408 std::map<unsigned int, Tank *> &realTanks =
00409 ScorchedClient::instance()->getTankContainer().getPlayingTanks();
00410 if (tmpLastScoreValue != lastScoreValue_ ||
00411 tmpLastMoneyValue != lastMoneyValue_ ||
00412 realTanks.size() != lastNoPlayers_)
00413 {
00414 calculateScores();
00415 }
00416 }
00417
00418 void ScoreDialog::addScoreLine(float y, Vector &color, int score)
00419 {
00420 float textX = x_;
00421 float textY = y_ + h_ - y - lineSpacer - 30.0f;
00422
00423
00424 GLWFont::instance()->getGameFont()->draw(
00425 color,
00426 10,
00427 textX + scoreLeft, textY, 0.0f,
00428 S3D::formatStringBuffer("%i", score));
00429 }
00430
00431 void ScoreDialog::addLine(Tank *current, float y, char *rank, bool finished)
00432 {
00433 float textX = x_;
00434 float textY = y_ + h_ - y - lineSpacer - 25.0f;
00435 bool currentPlayer = false;
00436
00437 TargetRendererImplTank *renderer = (TargetRendererImplTank *)
00438 current->getRenderer();
00439 if (renderer)
00440 {
00441 GLWToolTip::instance()->addToolTip(&renderer->getTips()->tankTip,
00442 textX,
00443 textY,
00444 x_ + w_ - textX,
00445 10.0f);
00446 }
00447
00448
00449 if (!current->getState().getSpectator() &&
00450 current->getDestinationId() ==
00451 ScorchedClient::instance()->getTankContainer().getCurrentDestinationId())
00452 {
00453 GLState state(GLState::BLEND_ON);
00454
00455 glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
00456 glBegin(GL_QUADS);
00457 glVertex2f(x_ + w_ - 3.0f, textY + lineSpacer - 1.0f);
00458 glVertex2f(x_ + 3.0f, textY + lineSpacer - 1.0f);
00459 glVertex2f(x_ + 3.0f, textY - 1.0f);
00460 glVertex2f(x_ + w_ - 3.0f, textY - 1.0f);
00461 glEnd();
00462 }
00463
00464
00465 static LangString name;
00466
00467
00468 if (current->getTargetName().size() > 12)
00469 name = current->getTargetName().substr(0, 12);
00470 else
00471 name = current->getTargetName();
00472
00473 if (finished && ! ClientParams::instance()->getConnectedToServer())
00474 {
00475 name.append(LANG_STRING(" ("));
00476 Tank *serverTank =
00477 ScorchedServer::instance()->getTankContainer().getTankById(
00478 current->getPlayerId());
00479 TankAI *tankAI = serverTank->getTankAI();
00480 if (tankAI) name.append(LANG_STRING(tankAI->getName()));
00481 else name.append(LANG_RESOURCE("HUMAN", "Human"));
00482 name.append(LANG_STRING(")"));
00483 }
00484 else if (current->getState().getState() != TankState::sNormal)
00485 {
00486 name.append(LANG_STRING(" ("));
00487 name.append(current->getState().getSmallStateLangString());
00488 name.append(LANG_STRING(")"));
00489 }
00490
00491 if (current->getState().getSpectator())
00492 {
00493 if (name.size() > 50) name = name.substr(0, 50);
00494
00495
00496 GLWFont::instance()->getGameFont()->draw(
00497 current->getColor(),
00498 10,
00499 textX + nameLeft, textY, 0.0f,
00500 name);
00501 GLWFont::instance()->getGameFont()->draw(
00502 current->getColor(),
00503 10,
00504 textX + readyLeft, textY, 0.0f,
00505 S3D::formatStringBuffer("%2s",
00506 ((current->getState().getReadyState() == TankState::SNotReady)?"*":" ")));
00507 }
00508 else
00509 {
00510 if (name.size() > 25) name = name.substr(0, 25);
00511
00512 GLState state(GLState::TEXTURE_ON);
00513 glColor3f(1.0f, 1.0f, 1.0f);
00514 current->getAvatar().getTexture()->draw();
00515 glBegin(GL_QUADS);
00516 glTexCoord2f(0.0f, 0.0f);
00517 glVertex2f(textX + iconLeft,
00518 textY + 2.0f);
00519 glTexCoord2f(1.0f, 0.0f);
00520 glVertex2f(textX + iconLeft + 8.0f,
00521 textY + 2.0f);
00522 glTexCoord2f(1.0f, 1.0f);
00523 glVertex2f(textX + iconLeft + 8.0f,
00524 textY + 10.0f);
00525 glTexCoord2f(0.0f, 1.0f);
00526 glVertex2f(textX + iconLeft,
00527 textY + 10.0f);
00528 glEnd();
00529
00530
00531 GLWFont::instance()->getGameFont()->draw(
00532 current->getColor(),
00533 10,
00534 textX + rankLeft, textY, 0.0f,
00535 rank);
00536 GLWFont::instance()->getGameFont()->drawWidth(
00537 killsLeft - nameLeft,
00538 current->getColor(),
00539 10,
00540 textX + nameLeft, textY, 0.0f,
00541 name);
00542 GLWFont::instance()->getGameFont()->draw(
00543 current->getColor(),
00544 10,
00545 textX + killsLeft, textY, 0.0f,
00546 S3D::formatStringBuffer("%i", current->getScore().getKills()));
00547 GLWFont::instance()->getGameFont()->draw(
00548 current->getColor(),
00549 10,
00550 textX + moneyLeft, textY, 0.0f,
00551 S3D::formatStringBuffer("$%i", current->getScore().getMoney()));
00552 GLWFont::instance()->getGameFont()->draw(
00553 current->getColor(),
00554 10,
00555 textX + winsLeft, textY, 0.0f,
00556 S3D::formatStringBuffer("%i", current->getScore().getWins()));
00557 GLWFont::instance()->getGameFont()->draw(
00558 current->getColor(),
00559 10,
00560 textX + scoreLeft, textY, 0.0f,
00561 S3D::formatStringBuffer("%i", current->getScore().getScore()));
00562 GLWFont::instance()->getGameFont()->draw(
00563 current->getColor(),
00564 10,
00565 textX + assistsLeft, textY, 0.0f,
00566 S3D::formatStringBuffer("%i", current->getScore().getAssists()));
00567 GLWFont::instance()->getGameFont()->draw(
00568 current->getColor(),
00569 10,
00570 textX + readyLeft, textY, 0.0f,
00571 ((current->getState().getReadyState() == TankState::SNotReady)?"*":" "));
00572 if (current->getScore().getRank() >= 0)
00573 {
00574 GLWFont::instance()->getGameFont()->draw(
00575 current->getColor(),
00576 10,
00577 textX + statsLeft, textY, 0.0f,
00578 S3D::formatStringBuffer("%i", current->getScore().getRank()));
00579 }
00580 GLWFont::instance()->getGameFont()->draw(
00581 current->getColor(),
00582 10,
00583 textX + livesLeft, textY, 0.0f,
00584 S3D::formatStringBuffer("%i", current->getState().getLives()));
00585 }
00586 }