00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <weapons/Weapon.h>
00022 #include <weapons/AccessoryStore.h>
00023 #include <engine/GameState.h>
00024 #include <engine/ActionController.h>
00025 #include <engine/MainLoop.h>
00026 #include <client/ClientState.h>
00027 #include <client/ScorchedClient.h>
00028 #include <server/ScorchedServer.h>
00029 #include <tank/TankContainer.h>
00030 #include <tank/TankAccessories.h>
00031 #include <tank/TankModelContainer.h>
00032 #include <tank/TankState.h>
00033 #include <tankai/TankAI.h>
00034 #include <target/TargetParachute.h>
00035 #include <target/TargetShield.h>
00036 #include <tankgraph/TankMenus.h>
00037 #include <GLW/GLWWindowManager.h>
00038 #include <client/ClientParams.h>
00039 #include <graph/OptionsDisplay.h>
00040 #include <common/FileLogger.h>
00041 #include <common/Defines.h>
00042 #include <common/Logger.h>
00043 #include <coms/ComsMessageSender.h>
00044 #include <coms/ComsMessageHandler.h>
00045 #include <landscape/Landscape.h>
00046 #include <landscapemap/LandscapeMaps.h>
00047 #include <tankgraph/RenderTracer.h>
00048 #include <tankgraph/TargetRendererImplTarget.h>
00049 #include <dialogs/MainMenuDialog.h>
00050 #include <dialogs/QuitDialog.h>
00051 #include <dialogs/SaveDialog.h>
00052 #include <dialogs/ResignDialog.h>
00053 #include <dialogs/SkipDialog.h>
00054 #include <sound/SoundUtils.h>
00055 #include <console/ConsoleRuleFnIAdapter.h>
00056 #include <console/ConsoleRuleMethodIAdapter.h>
00057 #include <image/ImageFactory.h>
00058 #include <GLEXT/GLTexture.h>
00059 #include <lua/LUAScriptFactory.h>
00060
00061 TankMenus::TankMenus() : logger_("ClientLog")
00062 {
00063 new ConsoleRuleMethodIAdapter<Landscape>(
00064 Landscape::instance(), &Landscape::updatePlanTexture, "ResetPlan");
00065 new ConsoleRuleMethodIAdapter<Landscape>(
00066 Landscape::instance(), &Landscape::updatePlanATexture, "ResetAPlan");
00067
00068 new ConsoleRuleMethodIAdapter<TankMenus>(
00069 this, &TankMenus::resetLandscape, "ResetLandscape");
00070 new ConsoleRuleMethodIAdapter<TankMenus>(
00071 this, &TankMenus::clearTracerLines, "ClearTracerLines");
00072 new ConsoleRuleMethodIAdapter<TankMenus>(
00073 this, &TankMenus::showTankDetails, "TankDetails");
00074 new ConsoleRuleMethodIAdapter<TankMenus>(
00075 this, &TankMenus::showTargetDetails, "TargetDetails");
00076 new ConsoleRuleMethodIAdapter<TankMenus>(
00077 this, &TankMenus::showTextureDetails, "TextureDetails");
00078 new ConsoleRuleMethodIAdapter<TankMenus>(
00079 this, &TankMenus::logToFile, "LogToFile");
00080 new ConsoleRuleMethodIAdapter<TankMenus>(
00081 this, &TankMenus::groupInfo, "GroupInfo");
00082
00083
00084 new ConsoleRuleFnIBooleanAdapter(
00085 "ComsMessageLogging",
00086 ScorchedClient::instance()->getComsMessageHandler().getMessageLogging());
00087 new ConsoleRuleFnIBooleanAdapter(
00088 "StateLogging",
00089 ScorchedClient::instance()->getGameState().getStateLogging());
00090 new ConsoleRuleFnIBooleanAdapter(
00091 "ActionLogging",
00092 ScorchedClient::instance()->getActionController().getActionLogging());
00093 new ConsoleRuleFnIBooleanAdapter(
00094 "ActionProfiling",
00095 ScorchedServer::instance()->getActionController().getActionProfiling());
00096 new ConsoleRuleFnINumberAdapter(
00097 "StateTimeLogging",
00098 ScorchedClient::instance()->getGameState().getStateTimeLogging());
00099 new ConsoleRuleFnINumberAdapter(
00100 "ServerStateTimeLogging",
00101 ScorchedServer::instance()->getGameState().getStateTimeLogging());
00102 new ConsoleRuleFnIBooleanAdapter(
00103 "MainLoopLogging",
00104 ScorchedClient::instance()->getMainLoop().getDrawLogging());
00105
00106 if (OptionsDisplay::instance()->getClientLogToFile())
00107 {
00108 logToFile();
00109 }
00110
00111 unsigned int logState = OptionsDisplay::instance()->getClientLogState();
00112 if (logState & 0x1)
00113 {
00114 ScorchedServer::instance()->getGameState().getStateLogging() = true;
00115 ScorchedClient::instance()->getGameState().getStateLogging() = true;
00116 }
00117 if (logState & 0x2)
00118 {
00119 ScorchedServer::instance()->getComsMessageHandler().getMessageLogging() = true;
00120 ScorchedClient::instance()->getComsMessageHandler().getMessageLogging() = true;
00121 }
00122 }
00123
00124 TankMenus::~TankMenus()
00125 {
00126
00127 }
00128
00129 void TankMenus::groupInfo()
00130 {
00131 std::map<std::string, TargetGroupsGroupEntry*> &groups =
00132 ScorchedClient::instance()->getLandscapeMaps().getGroundMaps().
00133 getGroups().getGroups();
00134 std::map<std::string, TargetGroupsGroupEntry*>::iterator itor;
00135 for (itor = groups.begin();
00136 itor != groups.end();
00137 itor++)
00138 {
00139 const std::string &name = itor->first;
00140 TargetGroupsGroupEntry *entry = itor->second;
00141 Logger::log(S3D::formatStringBuffer("Group %s count %i",
00142 name.c_str(),
00143 entry->getObjectCount()));
00144 }
00145 }
00146
00147 void TankMenus::logToFile()
00148 {
00149 Logger::addLogger(&logger_);
00150 }
00151
00152 void TankMenus::showTextureDetails()
00153 {
00154 Console::instance()->addLine(false,
00155 S3D::formatStringBuffer("%i bytes", GLTexture::getTextureSpace()));
00156 }
00157
00158 void TankMenus::resetLandscape()
00159 {
00160 Landscape::instance()->reset();
00161 }
00162
00163 void TankMenus::clearTracerLines()
00164 {
00165 RenderTracer::instance()->clearTracerLines();
00166 }
00167
00168 void TankMenus::showInventory()
00169 {
00170 std::map<unsigned int, Tank *> &tanks =
00171 ScorchedClient::instance()->getTankContainer().getAllTanks();
00172 std::map<unsigned int, Tank *>::iterator itor;
00173 for (itor = tanks.begin();
00174 itor != tanks.end();
00175 itor++)
00176 {
00177 Tank *tank = (*itor).second;
00178 Console::instance()->addLine(false,
00179 S3D::formatStringBuffer("--%s------------------------------------",
00180 tank->getCStrName().c_str()));
00181
00182 std::list<Accessory *> accessories;
00183 tank->getAccessories().getAllAccessories(accessories);
00184 ScorchedClient::instance()->getAccessoryStore().sortList(accessories, AccessoryStore::SortName);
00185
00186 std::list<Accessory *>::iterator aitor;
00187 for (aitor = accessories.begin();
00188 aitor != accessories.end();
00189 aitor++)
00190 {
00191 Accessory *accessory = (*aitor);
00192
00193 Console::instance()->addLine(false,
00194 S3D::formatStringBuffer("%s - %i", accessory->getName(),
00195 tank->getAccessories().getAccessoryCount(accessory)));
00196 }
00197
00198 Console::instance()->addLine(false,
00199 "----------------------------------------------------");
00200 }
00201 }
00202
00203 void TankMenus::showTargetDetails()
00204 {
00205 std::map<std::string, unsigned int> results;
00206 std::map<unsigned int, Target *> &targets =
00207 ScorchedClient::instance()->getTargetContainer().getTargets();
00208 std::map<unsigned int, Target *>::iterator itor;
00209 for (itor = targets.begin();
00210 itor != targets.end();
00211 itor++)
00212 {
00213 Target *target = (*itor).second;
00214
00215 std::string name = target->getCStrName();
00216 if (target->isTarget() &&
00217 target->getRenderer() &&
00218 name.empty())
00219 {
00220 TargetRendererImplTarget *renderer =
00221 (TargetRendererImplTarget *) target->getRenderer();
00222 name = renderer->getModelId().getMeshName();
00223 }
00224
00225 if (results.find(name) == results.end()) results[name] = 1;
00226 else results[name]++;
00227 }
00228
00229 char buffer[1024];
00230 Console::instance()->addLine(false,
00231 "--Target Dump-----------------------------------------");
00232 std::map<std::string, unsigned int>::iterator resultItor;
00233 for (resultItor = results.begin();
00234 resultItor != results.end();
00235 resultItor++)
00236 {
00237 snprintf(buffer, 1024, "\"%s\" - %u", resultItor->first.c_str(), resultItor->second);
00238 Console::instance()->addLine(false, buffer);
00239 }
00240 snprintf(buffer, 1024, "TOTAL - %u", targets.size());
00241 Console::instance()->addLine(false, buffer);
00242 Console::instance()->addLine(false,
00243 "----------------------------------------------------");
00244 }
00245
00246 void TankMenus::showTankDetails()
00247 {
00248 std::map<unsigned int, Tank *> &tanks =
00249 ScorchedClient::instance()->getTankContainer().getAllTanks();
00250 Tank *currentTank =
00251 ScorchedClient::instance()->getTankContainer().getCurrentTank();
00252
00253 Console::instance()->addLine(false,
00254 "--Tank Dump-----------------------------------------");
00255
00256 std::map<unsigned int, Tank *>::iterator itor;
00257 for (itor = tanks.begin();
00258 itor != tanks.end();
00259 itor++)
00260 {
00261 Tank *tank = (*itor).second;
00262
00263 const char *description = "Unknown";
00264 if (!ClientParams::instance()->getConnectedToServer())
00265 {
00266 Tank *otherTank = ScorchedServer::instance()->
00267 getTankContainer().getTankById(tank->getPlayerId());
00268 if (otherTank && !otherTank->getTankAI())
00269 {
00270 description = "Human";
00271 }
00272 else if (otherTank && otherTank->getTankAI())
00273 {
00274 description = otherTank->getTankAI()->getName();
00275 }
00276 }
00277
00278 char buffer[1024];
00279 snprintf(buffer, 1024, "%u %c %8s - \"%10s\" (%s)",
00280 tank->getPlayerId(),
00281 currentTank == tank?'>':' ',
00282 description,
00283 tank->getCStrName().c_str(),
00284 tank->getModelContainer().getTankModelName());
00285 Console::instance()->addLine(false, buffer);
00286 }
00287
00288 Console::instance()->addLine(false,
00289 "----------------------------------------------------");
00290 }
00291
00292
00293
00294 TankMenus::PlayerMenu::PlayerMenu()
00295 {
00296 Image *map = ImageFactory::loadImage(
00297 S3D::getDataFile("data/windows/setting.bmp"),
00298 S3D::getDataFile("data/windows/settinga.bmp"),
00299 false);
00300 DIALOG_ASSERT(map->getBits());
00301 MainMenuDialog::instance()->addMenu(LANG_RESOURCE("PLAYER", "Player"),
00302 "Player",
00303 LANG_RESOURCE("PLAYER_WINDOW", "Skip move, resign, and quit"),
00304 32,
00305 ClientState::StatePlaying, this, map);
00306
00307 MainMenuDialog::instance()->addMenuItem("Player",
00308 GLMenuItem(LANG_RESOURCE("SKIP_MOVE", "Skip Move"),
00309 new ToolTip(ToolTip::ToolTipHelp,
00310 LANG_RESOURCE("SKIP_MOVE", "Skip Move"),
00311 LANG_RESOURCE("SKIP_MOVE_TOOLTIP", "Player forfits this move."))));
00312 MainMenuDialog::instance()->addMenuItem("Player",
00313 GLMenuItem(LANG_RESOURCE("RESIGN_ROUND", "Resign Round"),
00314 new ToolTip(ToolTip::ToolTipHelp,
00315 LANG_RESOURCE("RESIGN_ROUND", "Resign Round"),
00316 LANG_RESOURCE("RESIGN_ROUND_TOOLTIP",
00317 "Player resigns from this round.\n"
00318 "Player takes no part in the rest of the round."))));
00319 MainMenuDialog::instance()->addMenuItem("Player",
00320 GLMenuItem(LANG_RESOURCE("EXIT_GAME", "Exit Game"),
00321 new ToolTip(ToolTip::ToolTipHelp,
00322 LANG_RESOURCE("EXIT_GAME", "Exit Game"),
00323 LANG_RESOURCE("EXIT_GAME_TOOLTIP", "Stop Playing Scorched."))));
00324 if (!ClientParams::instance()->getConnectedToServer())
00325 {
00326 MainMenuDialog::instance()->addMenuItem("Player",
00327 GLMenuItem(LANG_RESOURCE("MASS_TANK_KILL", "Mass Tank Kill"),
00328 new ToolTip(ToolTip::ToolTipHelp,
00329 LANG_RESOURCE("MASS_TANK_KILL", "Mass Tank Kill"),
00330 LANG_RESOURCE("MASS_TANK_KILL_TOOLTIP",
00331 "Kill all tanks.\nStarts the next round."))));
00332 MainMenuDialog::instance()->addMenuItem("Player",
00333 GLMenuItem(LANG_RESOURCE("SAVE", "Save"),
00334 new ToolTip(ToolTip::ToolTipHelp,
00335 LANG_RESOURCE("SAVE", "Save"),
00336 LANG_RESOURCE("SAVE_TOOLTIP", "Save this game."))));
00337 }
00338 }
00339
00340 void TankMenus::PlayerMenu::menuSelection(const char* menuName,
00341 const int position, GLMenuItem &item)
00342 {
00343 Tank *firstTank = ScorchedClient::instance()->getTankContainer().getCurrentTank();
00344 if (firstTank)
00345 {
00346 switch (position)
00347 {
00348 case 0:
00349 GLWWindowManager::instance()->showWindow(
00350 SkipDialog::instance()->getId());
00351 break;
00352 case 1:
00353 GLWWindowManager::instance()->showWindow(
00354 ResignDialog::instance()->getId());
00355 break;
00356 case 2:
00357 GLWWindowManager::instance()->showWindow(
00358 QuitDialog::instance()->getId());
00359 break;
00360 case 3:
00361 GLWWindowManager::instance()->showWindow(
00362 QuitDialog::instance()->getId());
00363 break;
00364 case 4:
00365 GLWWindowManager::instance()->showWindow(
00366 SaveDialog::instance()->getId());
00367 break;
00368 }
00369 }
00370 }
00371
00372 bool TankMenus::PlayerMenu::getEnabled(const char* menuName)
00373 {
00374 if (ScorchedClient::instance()->getGameState().getState()
00375 != ClientState::StatePlaying) return false;
00376
00377 Tank *firstTank = ScorchedClient::instance()->getTankContainer().getCurrentTank();
00378 if (firstTank)
00379 {
00380 return (firstTank->getState().getState() == TankState::sNormal);
00381 }
00382 return false;
00383 }
00384
00385
00386 TankMenus::AccessoryMenu::AccessoryMenu()
00387 {
00388 Image *map = ImageFactory::loadImage(
00389 S3D::getDataFile("data/windows/bomb.bmp"),
00390 S3D::getDataFile("data/windows/bomba.bmp"),
00391 false);
00392 DIALOG_ASSERT(map->getBits());
00393 MainMenuDialog::instance()->addMenu(LANG_RESOURCE("WEAPONS", "Weapons"),
00394 "Weapons",
00395 LANG_RESOURCE("WEAPONS_WINDOW", "Change the current weapon and enable defenses"),
00396 32,
00397 ClientState::StatePlaying, this, map);
00398 }
00399
00400 void TankMenus::AccessoryMenu::menuSelection(const char* menuName,
00401 const int position, GLMenuItem &item)
00402 {
00403 Accessory *accessory = (Accessory *) item.getUserData();
00404 Tank *firstTank = ScorchedClient::instance()->getTankContainer().getCurrentTank();
00405 if (firstTank && accessory)
00406 {
00407 firstTank->getAccessories().activate(accessory);
00408 }
00409 }
00410
00411 bool TankMenus::AccessoryMenu::getMenuItems(const char* menuName,
00412 std::list<GLMenuItem> &result)
00413 {
00414 Tank *firstTank = ScorchedClient::instance()->getTankContainer().getCurrentTank();
00415 if (!firstTank) return true;
00416
00417 std::string lastGroup;
00418 bool firstIteration = true;
00419 std::set<std::string> tabGroups = ScorchedClient::instance()->
00420 getAccessoryStore().getTabGroupNames();
00421 std::set<std::string>::iterator groupitor;
00422 for (groupitor = tabGroups.begin();
00423 groupitor != tabGroups.end();
00424 groupitor++)
00425 {
00426 const char *group = (*groupitor).c_str();
00427 std::list<Accessory *> weapons = ScorchedClient::instance()->
00428 getAccessoryStore().getAllAccessoriesByTabGroup(
00429 group,
00430 OptionsDisplay::instance()->getAccessorySortKey());
00431
00432 std::list<Accessory *>::iterator itor;
00433 for (itor = weapons.begin();
00434 itor != weapons.end();
00435 itor++)
00436 {
00437 Accessory *accessory = (*itor);
00438 int accessoryCount =
00439 firstTank->getAccessories().getAccessoryCount(accessory);
00440 if (!firstTank->getAccessories().canUse(accessory)) continue;
00441
00442 bool sel = false;
00443 switch (accessory->getType())
00444 {
00445 case AccessoryPart::AccessoryParachute:
00446 sel = (firstTank->getParachute().getCurrentParachute() == accessory);
00447 break;
00448 case AccessoryPart::AccessoryShield:
00449 sel = (firstTank->getShield().getCurrentShield() == accessory);
00450 break;
00451 case AccessoryPart::AccessoryWeapon:
00452 sel = (firstTank->getAccessories().getWeapons().getCurrent() == accessory);
00453 break;
00454 case AccessoryPart::AccessoryAutoDefense:
00455 sel = true;
00456 break;
00457 default:
00458 case AccessoryPart::AccessoryBattery:
00459 sel = false;
00460 break;
00461 }
00462
00463 if (!firstIteration &&
00464 0 != strcmp(lastGroup.c_str(), accessory->getTabGroupName()))
00465 {
00466 GLMenuItem bar(LANG_STRING("----------"));
00467 bar.setSeperator();
00468 result.push_back(bar);
00469 }
00470 lastGroup = accessory->getTabGroupName();
00471 firstIteration = false;
00472
00473 result.push_back(
00474 GLMenuItem(
00475 firstTank->getAccessories().getAccessoryAndCountString(accessory),
00476 &accessory->getToolTip(),
00477 sel,
00478 accessory->getTexture(),
00479 accessory));
00480 }
00481 }
00482 return true;
00483 }
00484
00485 bool TankMenus::AccessoryMenu::getEnabled(const char* menuName)
00486 {
00487 if (ScorchedClient::instance()->getGameState().getState() !=
00488 ClientState::StatePlaying) return false;
00489
00490 Tank *firstTank = ScorchedClient::instance()->getTankContainer().getCurrentTank();
00491 if (firstTank)
00492 {
00493 return (firstTank->getState().getState() == TankState::sNormal);
00494 }
00495 return false;
00496 }
00497
00498 void TankMenus::runScriptConsole(std::list<ConsoleRuleValue> list)
00499 {
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518 }
00519