00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <client/ScorchedClient.h>
00022 #include <client/ClientNewGameHandler.h>
00023 #include <client/ClientState.h>
00024 #include <client/ClientWaitState.h>
00025 #include <client/ClientReloadAdaptor.h>
00026 #include <graph/SpeedChange.h>
00027 #include <graph/OptionsDisplayConsole.h>
00028 #include <graph/MainCamera.h>
00029 #include <tankgraph/RenderTracer.h>
00030 #include <weapons/AccessoryStore.h>
00031 #include <engine/ActionController.h>
00032 #include <engine/MainLoop.h>
00033 #include <GLW/GLWWindowManager.h>
00034 #include <client/ClientParams.h>
00035 #include <common/OptionsScorched.h>
00036 #include <common/ChannelManager.h>
00037 #include <common/Clock.h>
00038 #include <common/Logger.h>
00039 #include <coms/ComsNewGameMessage.h>
00040 #include <dialogs/PlayerDialog.h>
00041 #include <dialogs/ProgressDialog.h>
00042 #include <dialogs/RulesDialog.h>
00043 #include <landscapemap/LandscapeMaps.h>
00044 #include <landscapemap/DeformLandscape.h>
00045 #include <landscapedef/LandscapeDefinitions.h>
00046 #include <landscape/Landscape.h>
00047 #include <tank/TankContainer.h>
00048 #include <tank/TankCamera.h>
00049 #include <target/TargetRenderer.h>
00050 #include <tankai/TankAIAdder.h>
00051
00052 ClientNewGameHandler *ClientNewGameHandler::instance_ = 0;
00053
00054 ClientNewGameHandler *ClientNewGameHandler::instance()
00055 {
00056 if (!instance_)
00057 {
00058 instance_ = new ClientNewGameHandler();
00059 }
00060
00061 return instance_;
00062 }
00063
00064 ClientNewGameHandler::ClientNewGameHandler()
00065 {
00066 ScorchedClient::instance()->getComsMessageHandler().addHandler(
00067 "ComsNewGameMessage",
00068 this);
00069 }
00070
00071 ClientNewGameHandler::~ClientNewGameHandler()
00072 {
00073
00074 }
00075
00076 bool ClientNewGameHandler::processMessage(
00077 NetMessage &netMessage,
00078 const char *messageType,
00079 NetBufferReader &reader)
00080 {
00081 Clock generateClock;
00082 bool result = actualProcessMessage(netMessage, messageType, reader);
00083 float generateTime = generateClock.getTimeDifference();
00084 int idleTime = ScorchedClient::instance()->getOptionsGame().getIdleKickTime();
00085
00086 if (idleTime > 0 && int(generateTime) > idleTime - 5)
00087 {
00088 LangString message = LANG_RESOURCE("LEVEL_TIMEOUT_WARNING",
00089 "Warning: Your PC is taking a long time to generate levels.\n"
00090 "This may cause you to be kicked by some servers.\n"
00091 "You can fix this by lowering your display settings");
00092
00093 Logger::log(LangStringUtil::convertFromLang(message));
00094 ChannelText text("info", message);
00095 ChannelManager::showText(ScorchedClient::instance()->getContext(), text);
00096 }
00097
00098 return result;
00099 }
00100
00101 bool ClientNewGameHandler::actualProcessMessage(
00102 NetMessage &netMessage,
00103 const char *messageType,
00104 NetBufferReader &reader)
00105 {
00106 ComsNewGameMessage message;
00107 if (!message.readMessage(reader)) return false;
00108
00109
00110
00111
00112 if (!message.parsePlayerStateMessage())
00113 {
00114 Logger::log("ClientNewGameHandler: Failed to parse playerstate");
00115 return false;
00116 }
00117
00118
00119 OptionsDisplayConsole::instance()->addDisplayToConsole();
00120
00121
00122 ProgressDialog::instance()->changeTip();
00123 LandscapeDefinitionsEntry *landscapeDefinition =
00124 ScorchedClient::instance()->getLandscapes().getLandscapeByName(
00125 message.getLevelMessage().getGroundMapsDefn().getName());
00126 if (landscapeDefinition)
00127 {
00128 std::string fileName = S3D::getDataFile(
00129 S3D::formatStringBuffer("data/landscapes/%s",
00130 landscapeDefinition->picture.c_str()));
00131 ProgressDialog::instance()->setIcon(fileName.c_str());
00132 }
00133
00134
00135 removeTargets();
00136
00137
00138 ScorchedClient::instance()->getLandscapeMaps().generateMaps(
00139 ScorchedClient::instance()->getContext(),
00140 message.getLevelMessage().getGroundMapsDefn(),
00141 ProgressDialogSync::instance());
00142
00143 Clock generateClock;
00144 DeformLandscape::applyInfos(
00145 ScorchedClient::instance()->getContext(),
00146 message.getLevelMessage().getDeformInfos(),
00147 ProgressDialogSync::instance());
00148 float deformTime = generateClock.getTimeDifference();
00149 Logger::log(S3D::formatStringBuffer("Landscape deformation time %.2f seconds", deformTime));
00150
00151
00152 Landscape::instance()->generate(ProgressDialogSync::instance());
00153
00154
00155 std::map<unsigned int, Target *> targets =
00156 ScorchedClient::instance()->getTargetContainer().getTargets();
00157 std::map<unsigned int, Target *>::iterator targetItor;
00158 for (targetItor = targets.begin();
00159 targetItor != targets.end();
00160 targetItor++)
00161 {
00162 Target *target = targetItor->second;
00163 if (target->getPlayerId() >= TargetID::MIN_TARGET_ID &&
00164 target->getPlayerId() < TargetID::MIN_TARGET_TRANSIENT_ID)
00165 {
00166 if (message.getLevelMessage().getTargetIds().find(target->getPlayerId()) ==
00167 message.getLevelMessage().getTargetIds().end())
00168 {
00169 if (target->isTarget())
00170 {
00171 Target *removedTarget =
00172 ScorchedClient::instance()->getTargetContainer().removeTarget(target->getPlayerId());
00173 delete removedTarget;
00174 }
00175 else
00176 {
00177
00178
00179 Tank *removedTank =
00180 ScorchedClient::instance()->getTankContainer().removeTank(target->getPlayerId());
00181 delete removedTank;
00182 }
00183 }
00184 }
00185 }
00186
00187
00188 NetBufferReader newTargets(message.getLevelMessage().getNewTargets());
00189 unsigned int newTargetId = 0;
00190 while (newTargets.getFromBuffer(newTargetId))
00191 {
00192 Target *newTarget = new Target(
00193 newTargetId,
00194 LangString(),
00195 ScorchedClient::instance()->getContext());
00196 if (!newTarget->readMessage(newTargets))
00197 {
00198 Logger::log("ClientNewGameHandler: Failed to parse new target message");
00199 return false;
00200 }
00201
00202 ScorchedClient::instance()->getTargetContainer().addTarget(newTarget);
00203 }
00204
00205
00206 NetBufferReader oldTargets(message.getLevelMessage().getOldTargets());
00207 unsigned int oldTargetId = 0;
00208 while (oldTargets.getFromBuffer(oldTargetId))
00209 {
00210 Target *oldTarget = ScorchedClient::instance()->
00211 getTargetContainer().getTargetById(oldTargetId);
00212 if (!oldTarget)
00213 {
00214 Logger::log("ClientNewGameHandler: Failed to find old target");
00215 return false;
00216 }
00217
00218 if (!oldTarget->readMessage(oldTargets))
00219 {
00220 Logger::log("ClientNewGameHandler: Failed to parse old target message");
00221 return false;
00222 }
00223 }
00224
00225
00226 Landscape::instance()->reset(ProgressDialogSync::instance());
00227
00228 RenderTracer::instance()->newGame();
00229 SpeedChange::instance()->resetSpeed();
00230
00231
00232 ScorchedClient::instance()->getActionController().clear();
00233
00234
00235 ScorchedClient::instance()->getTankContainer().clientNewGame();
00236
00237
00238
00239
00240 ScorchedClient::instance()->getMainLoop().getTimer().getTimeDifference();
00241
00242
00243 std::map<unsigned int, Tank *>::iterator tankItor;
00244 for (tankItor = ScorchedClient::instance()->getTankContainer().getAllTanks().begin();
00245 tankItor != ScorchedClient::instance()->getTankContainer().getAllTanks().end();
00246 tankItor++)
00247 {
00248 Tank *current = (*tankItor).second;
00249 current->getRenderer()->moved();
00250 current->getCamera().setCameraType(1);
00251 }
00252 MainCamera::instance()->getTarget().setCameraType(TargetCamera::CamSpectator);
00253
00254
00255 ClientWaitState::instance()->sendClientReady();
00256 ClientReloadAdaptor::instance();
00257
00258
00259 ScorchedClient::instance()->getGameState().stimulate(ClientState::StimWait);
00260 ScorchedClient::instance()->getGameState().checkStimulate();
00261
00262 return true;
00263 }
00264
00265 void ClientNewGameHandler::removeTargets()
00266 {
00267 std::map<unsigned int, Target *> targets =
00268 ScorchedClient::instance()->getTargetContainer().getTargets();
00269 std::map<unsigned int, Target *>::iterator itor;
00270 for (itor = targets.begin();
00271 itor != targets.end();
00272 itor++)
00273 {
00274 unsigned int playerId = (*itor).first;
00275 Target *target = (*itor).second;
00276 if (target->isTemp())
00277 {
00278 if (target->isTarget())
00279 {
00280 Target *removedTarget =
00281 ScorchedClient::instance()->getTargetContainer().removeTarget(playerId);
00282 delete removedTarget;
00283 }
00284 else
00285 {
00286 Tank *removedTank =
00287 ScorchedClient::instance()->getTankContainer().removeTank(playerId);
00288 delete removedTank;
00289 }
00290 }
00291 }
00292 }