00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <dialogs/TutorialDialog.h>
00022 #include <dialogs/MainMenuDialog.h>
00023 #include <image/ImageFactory.h>
00024 #include <GLEXT/GLMenuEntry.h>
00025 #include <GLEXT/GLViewPort.h>
00026 #include <GLW/GLWTextButton.h>
00027 #include <GLW/GLWLabel.h>
00028 #include <GLW/GLWWindowManager.h>
00029 #include <GLW/GLWListView.h>
00030 #include <client/ScorchedClient.h>
00031 #include <tank/TankContainer.h>
00032 #include <target/TargetRenderer.h>
00033 #include <tankgraph/TargetRendererImpl.h>
00034 #include <common/Logger.h>
00035 #include <common/LoggerI.h>
00036 #include <common/Defines.h>
00037 #include <common/OptionsScorched.h>
00038 #include <time.h>
00039
00040 TutorialDialog *TutorialDialog::instance_ = 0;
00041
00042 TutorialDialog *TutorialDialog::instance()
00043 {
00044 if (!instance_)
00045 {
00046 instance_ = new TutorialDialog;
00047 }
00048 return instance_;
00049 }
00050
00051 TutorialDialog::TutorialDialog() :
00052 GLWWindow("", 155.0f, -125.0f,
00053 470.0f, 120.0f, eSemiTransparent | eNoTitle,
00054 "The ingame tutorial."),
00055 triangleDir_(30.0f), triangleDist_(0.0f),
00056 current_(0)
00057 {
00058 windowLevel_ = 75000;
00059
00060 Vector listColor(0.0f, 0.0f, 0.0f);
00061 float wid = float(GLViewPort::getWidth() - 330);
00062 listView_ = new GLWListView(0.0f, 0.0f, wid, 105.0f, -1, 12.0f, 24.0f);
00063 listView_->setColor(listColor);
00064 listView_->setHandler(this);
00065 addWidget(listView_, 0, SpaceAll, 10.0f);
00066 setLayout(GLWPanel::LayoutVerticle);
00067 layout();
00068
00069 if (file_.parseFile(S3D::getDataFile(
00070 ScorchedClient::instance()->getOptionsGame().getTutorial())))
00071 {
00072 showPage(file_.getStartEntry());
00073 }
00074 }
00075
00076 TutorialDialog::~TutorialDialog()
00077 {
00078
00079 }
00080
00081 void TutorialDialog::showPage(TutorialFileEntry *entry)
00082 {
00083 currentEvents_.clear();
00084 current_ = entry;
00085
00086 listView_->clear();
00087 listView_->addXML(entry->text_);
00088 }
00089
00090 void TutorialDialog::display()
00091 {
00092 GLWWindow::display();
00093 listView_->resetPosition();
00094 }
00095
00096 void TutorialDialog::draw()
00097 {
00098 GLWWindow::draw();
00099
00100 processEvents();
00101 }
00102
00103 static const char *getValue(const char *name,
00104 std::map<std::string, std::string> &event)
00105 {
00106 std::map<std::string, std::string>::iterator itor =
00107 event.find(name);
00108 if (itor == event.end()) return 0;
00109 return (*itor).second.c_str();
00110 }
00111
00112 void TutorialDialog::processEvents(bool log)
00113 {
00114 TargetRendererImpl::setHighlightType(TargetRendererImpl::eNoHighlight);
00115
00116 if (currentEvents_.empty()) return;
00117
00118 const char *action = getValue("action", currentEvents_);
00119 if (!action)
00120 {
00121 S3D::dialogExit("TutorialDialog", "No action in event");
00122 }
00123
00124 if (0 == strcmp(action, "highlight"))
00125 {
00126 processHighlight(log);
00127 }
00128 else if (0 == strcmp(action, "targets"))
00129 {
00130 TargetRendererImpl::setHighlightType(TargetRendererImpl::eOtherHighlight);
00131 }
00132 else if (0 == strcmp(action, "player"))
00133 {
00134 TargetRendererImpl::setHighlightType(TargetRendererImpl::ePlayerHighlight);
00135 }
00136 else if (0 == strcmp(action, "menu"))
00137 {
00138 processMenu(log);
00139 }
00140 else
00141 {
00142 S3D::dialogExit("TutorialDialog",
00143 S3D::formatStringBuffer("Unknown tutorial event type \"%s\"",
00144 action));
00145 }
00146 }
00147
00148 void TutorialDialog::processMenu(bool log)
00149 {
00150 const char *menuName = getValue("menu", currentEvents_);
00151 if (!menuName)
00152 {
00153 S3D::dialogExit("TutorialDialog", "No menu in event");
00154 }
00155
00156 GLMenuEntry *entry = MainMenuDialog::instance()->
00157 getMenu((char*) menuName);
00158 if (!entry) return;
00159
00160 drawHighlight(
00161 entry->getX(), entry->getY() - entry->getH(),
00162 entry->getW(), entry->getH());
00163 }
00164
00165 void TutorialDialog::processHighlight(bool log)
00166 {
00167 const char *windowName = getValue("window", currentEvents_);
00168 const char *controlName = getValue("control", currentEvents_);
00169 if (!windowName || !controlName)
00170 {
00171 S3D::dialogExit("TutorialDialog", "No window or control in event");
00172 }
00173
00174 GLWWindow *window = GLWWindowManager::instance()->getWindowByName(windowName);
00175 if (!window)
00176 {
00177 if (log)
00178 {
00179 Logger::log(S3D::formatStringBuffer("Tutorial cannot find window \"%s\"", windowName));
00180 }
00181 return;
00182 }
00183
00184 GLWidget *control = window->getWidgetByName(controlName);
00185 if (!control)
00186 {
00187 if (log)
00188 {
00189 Logger::log(S3D::formatStringBuffer("Tutorial cannot find control \"%s\" in window \"%s\"",
00190 controlName, windowName));
00191 }
00192 return;
00193 }
00194
00195 float x = control->getX();
00196 float y = control->getY();
00197 GLWPanel *parent = control->getParent();
00198 while (parent)
00199 {
00200 x += parent->getX();
00201 y += parent->getY();
00202 parent = parent->getParent();
00203 }
00204
00205 drawHighlight(
00206 x, y, control->getW(), control->getH());
00207 }
00208
00209 void TutorialDialog::simulate(float frameTime)
00210 {
00211 GLWWindow::simulate(frameTime);
00212
00213 triangleDist_ += frameTime * triangleDir_;
00214 if (triangleDist_ < 0.0f)
00215 {
00216 triangleDist_ = -triangleDist_;
00217 triangleDir_ = -triangleDir_;
00218 }
00219 if (triangleDist_ > 10.0f)
00220 {
00221 triangleDist_ = 10.0f;
00222 triangleDir_ = -triangleDir_;
00223 }
00224
00225 if (current_)
00226 {
00227 TutorialFileEntry *entry = current_->checkConditions();
00228 if (entry) showPage(entry);
00229 }
00230 }
00231
00232 void TutorialDialog::url(const char *url)
00233 {
00234 if (0 == strcmp(url, "exit"))
00235 {
00236 GLWWindowManager::instance()->hideWindow(getId());
00237 return;
00238 }
00239
00240 TutorialFileEntry *entry = file_.getEntry(url);
00241 if (entry)
00242 {
00243 showPage(entry);
00244 }
00245 else
00246 {
00247 S3D::dialogExit("TutorialDialog",
00248 S3D::formatStringBuffer("Unknown url \"%s\"", url));
00249 }
00250 }
00251
00252 void TutorialDialog::drawHighlight(float x, float y, float w, float h)
00253 {
00254 if (!triangleTex_.textureValid())
00255 {
00256 std::string file = S3D::getDataFile("data/windows/triangle.bmp");
00257 ImageHandle maps = ImageFactory::loadImageHandle(file.c_str(), file.c_str(), false);
00258 triangleTex_.create(maps, true);
00259 }
00260
00261 GLState state(GLState::TEXTURE_ON | GLState::BLEND_ON | GLState::DEPTH_OFF);
00262 glColor4f(1.0f, 0.0f, 0.0f, 0.7f);
00263
00264 triangleTex_.draw();
00265
00266 const float size = 20.0f;
00267 drawTriangle(x - size - triangleDist_, y + (h - size) / 2.0f, size, 1);
00268 drawTriangle(x + w + triangleDist_, y + (h - size) / 2.0f, size, 3);
00269 drawTriangle(x + (w - size) / 2.0f, y + h + triangleDist_, size, 2);
00270 drawTriangle(x + (w - size) / 2.0f, y - size - triangleDist_, size, 0);
00271 }
00272
00273 void TutorialDialog::drawTriangle(float x, float y, float size, int tex)
00274 {
00275 glBegin(GL_QUADS);
00276 switch (tex)
00277 {
00278 case 0: glTexCoord2f(0.0f, 0.0f); break;
00279 case 1: glTexCoord2f(1.0f, 0.0f); break;
00280 case 2: glTexCoord2f(1.0f, 1.0f); break;
00281 case 3: glTexCoord2f(0.0f, 1.0f); break;
00282 }
00283 glVertex2f(x, y);
00284 switch (tex)
00285 {
00286 case 0: glTexCoord2f(1.0f, 0.0f); break;
00287 case 1: glTexCoord2f(1.0f, 1.0f); break;
00288 case 2: glTexCoord2f(0.0f, 1.0f); break;
00289 case 3: glTexCoord2f(0.0f, 0.0f); break;
00290 }
00291 glVertex2f(x + size, y);
00292 switch (tex)
00293 {
00294 case 0: glTexCoord2f(1.0f, 1.0f); break;
00295 case 1: glTexCoord2f(0.0f, 1.0f); break;
00296 case 2: glTexCoord2f(0.0f, 0.0f); break;
00297 case 3: glTexCoord2f(1.0f, 0.0f); break;
00298 }
00299 glVertex2f(x + size, y + size);
00300 switch (tex)
00301 {
00302 case 0: glTexCoord2f(0.0f, 1.0f); break;
00303 case 1: glTexCoord2f(0.0f, 0.0f); break;
00304 case 2: glTexCoord2f(1.0f, 0.0f); break;
00305 case 3: glTexCoord2f(1.0f, 1.0f); break;
00306 }
00307 glVertex2f(x, y + size);
00308 glEnd();
00309 }
00310
00311 void TutorialDialog::event(std::map<std::string, std::string> &event)
00312 {
00313 currentEvents_ = event;
00314 }
00315