00001 /* 00002 SagaEngine library 00003 Copyright (c) 2002-2006 Skalden Studio AS 00004 00005 This software is provided 'as-is', without any express or implied 00006 warranty. In no event will the authors be held liable for any 00007 damages arising from the use of this software. 00008 00009 Permission is granted to distribute the library under the terms of the 00010 Q Public License version 1.0. Be sure to read and understand the license 00011 before using the library. It should be included here, or you may read it 00012 at http://www.trolltech.com/products/qt/licenses/licensing/qpl 00013 00014 The original version of this library can be located at: 00015 http://www.sagaengine.com/ 00016 00017 Rune Myrland 00018 rune@skalden.com 00019 */ 00020 00021 00022 #include "O3dPre.hpp" 00023 #include "SpeechBubble.hpp" 00024 #include "../schema/O3dSchema.hpp" 00025 #include "sim/message/MessageCentral.hpp" 00026 #include "client/lang/Phrase.hpp" 00027 #include "sim/thing/Actor.hpp" 00028 #include "sim/script/Script.hpp" 00029 #include <OgreRenderWindow.h> 00030 #include <OgreOverlayManager.h> 00031 00032 00033 using namespace se_client; 00034 using namespace se_core; 00035 00036 namespace se_ogre { 00037 SpeechBubble 00038 ::SpeechBubble() : InputHandler("SpeechBubble"), isMonologue_(false), shouldTrack_(false), speaker_(0), speakerCamera_(0), speechOverlay_(0), infoOverlay_(0), speechCaption_(0), infoCaption_(0) { 00039 } 00040 00041 00042 SpeechBubble 00043 ::~SpeechBubble() { 00044 } 00045 00046 00047 bool SpeechBubble 00048 ::init() { 00049 try { 00050 speechOverlay_ = Ogre::OverlayManager::getSingleton().getByName("Bubbins/SpeechBubble"); 00051 speechCaption_ = Ogre::OverlayManager::getSingleton().getOverlayElement("Bubbins/SpeechBubbleText"); 00052 } 00053 catch(...) { 00054 LogWarning("Failed setting upp speech bubble overlays."); 00055 } 00056 00057 try { 00058 infoOverlay_ = Ogre::OverlayManager::getSingleton().getByName("Bubbins/InfoBubble"); 00059 infoCaption_ = Ogre::OverlayManager::getSingleton().getOverlayElement("Bubbins/InfoBubbleText"); 00060 } 00061 catch(...) { 00062 LogWarning("Failed setting upp info bubble overlays."); 00063 } 00064 00065 speakerCamera_ = Physics::lookup("SpeakerCamera"); 00066 00067 SimSchema::messageCentral.addListener(*this); 00068 return true; 00069 } 00070 00071 00072 void SpeechBubble 00073 ::cleanup() { 00074 SimSchema::messageCentral.removeListener(*this); 00075 speaker_ = 0; 00076 isMonologue_ = false; 00077 if(hasFocus()) 00078 loseFocus(); 00079 } 00080 00081 00082 void SpeechBubble 00083 ::infoEvent(char* messageName) { 00084 if(!messageName) { 00085 try { 00086 infoOverlay_->hide(); 00087 } 00088 catch(...) { 00089 LogWarning("Couldn't hide info bubble"); 00090 } 00091 return; 00092 } 00093 00094 wchar_t buffer[512]; 00095 LogDetail("Info: " << messageName); 00096 bool hadTranslation = translate(messageName, buffer); 00097 try { 00098 if(hadTranslation) 00099 infoCaption_->setCaption(buffer); 00100 else 00101 infoCaption_->setCaption(messageName); 00102 infoOverlay_->show(); 00103 } 00104 catch(...) { 00105 LogWarning("Couldn't show info bubble"); 00106 } 00107 } 00108 00109 00110 bool SpeechBubble 00111 ::translate(const char* messageName, wchar_t* buffer) { 00112 const char* message = ClientSchema::phrases().getPhrase(Phrase::SPEECH, messageName); 00113 00114 if(!message) 00115 return false; 00116 const unsigned char* c = (const unsigned char*)message; 00117 int linePos = 0; 00118 int i = 0; 00119 for(; *c != 0 && i < 255; ++i, ++c) { 00120 buffer[i] = *c; 00121 ++linePos; 00122 if(*c == '_') { 00123 if(linePos < MAX_LINE_LENGTH) { 00124 buffer[i] = ' '; 00125 } 00126 else { 00127 buffer[i] = '\n'; 00128 linePos = 0; 00129 } 00130 } 00131 } 00132 buffer[i] = 0; 00133 return true; 00134 } 00135 00136 00137 void SpeechBubble 00138 ::startMonologueEvent(se_core::Actor& speaker) { 00139 if(isMonologue_) { 00140 StatComponent::Ptr(ClientSchema::floatingCamera)->setTarget(speaker_->owner()); 00141 speaker_ = &speaker; 00142 } 00143 else { 00144 isMonologue_ = true; 00145 speaker_ = &speaker; 00146 grabFocus(); 00147 } 00148 } 00149 00150 void SpeechBubble 00151 ::stopMonologueEvent(se_core::Actor& speaker) { 00152 if(speaker_ != &speaker) { 00153 return; 00154 } 00155 Assert(isMonologue_); 00156 isMonologue_ = false; 00157 speaker_ = 0; 00158 loseFocus(); 00159 } 00160 00161 void SpeechBubble 00162 ::speechEvent(se_core::Actor& speaker, const char* messageName) { 00163 LogDetail(speaker.name() << " says '" << messageName << "'"); 00164 if(isMonologue_) { 00165 StatComponent::Ptr(ClientSchema::floatingCamera)->setTarget(speaker_->owner()); 00166 } 00167 speaker_ = &speaker; 00168 wchar_t buffer[512]; 00169 bool hadTranslation = translate(messageName, buffer); 00170 try { 00171 if(hadTranslation) 00172 speechCaption_->setCaption(buffer); 00173 else 00174 speechCaption_->setCaption(messageName); 00175 speechOverlay_->show(); 00176 shouldTrack_ = true; 00177 } 00178 catch(...) { 00179 LogWarning("Couldn't show speech bubble"); 00180 } 00181 00182 if(!isMonologue_) 00183 grabFocus(); 00184 } 00185 00186 00187 void SpeechBubble 00188 ::trackUserFeedback() { 00189 if(!shouldTrack_) 00190 return; 00191 if(speaker_) { 00192 ActionComponent::Ptr(speaker_)->castFeedbackEvent(ActionComponent::fb_SPEECH_FINISHED); 00193 if(!isMonologue_) 00194 speaker_ = 0; 00195 } 00196 shouldTrack_ = false; 00197 speechOverlay_->hide(); 00198 00199 if(!isMonologue_) 00200 loseFocus(); 00201 } 00202 00203 void SpeechBubble 00204 ::grabbedFocusEvent() { 00205 if(speakerCamera_) { 00206 StatComponent::Ptr(ClientSchema::floatingCamera)->setTarget(speaker_->owner()); 00207 PhysicsComponent::Ptr(ClientSchema::floatingCamera)->pushPhysics( speakerCamera_ ); 00208 } 00209 } 00210 00211 void SpeechBubble 00212 ::lostFocusEvent() { 00213 if(speakerCamera_) { 00214 PhysicsComponent::Ptr(ClientSchema::floatingCamera)->popPhysics(); 00215 StatComponent::Ptr(ClientSchema::floatingCamera)->resetTarget(); 00216 } 00217 } 00218 } 00219
Home Page | SagaEngine trunk (updated nightly) reference generated Sun Dec 2 20:06:09 2007 by Doxygen version 1.3.9.1.