CSimulationImpl.cpp
Go to the documentation of this file.00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "stdpch.h"
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <nel/misc/types_nl.h>
00039 #include <nel/net/message.h>
00040
00041
00042
00043
00044 #include "wwcommon/ISimulationObj.h"
00045 #include "wwcommon/CPerformer.h"
00046 #include "CActorProxy.h"
00047
00048 #include <wwcommon/CSobManager.h>
00049 #include <wwcommon/CSobFactory.h>
00050 #include <wwcommon/IBaseSimulation.h>
00051 #include <wwcommon/CGameEventServer.h>
00052 #include "CSimulationImpl.h"
00053 #include "controllers/CInteractiveSobController.h"
00054
00055
00056 #include "tasks/CNetworkTask.h"
00057 #include "tasks/CConfigTask.h"
00058 #include "tasks/CResourceTask.h"
00059 #include "views/CPerformer3DView.h"
00060 #include "views/CPerformerChatView.h"
00061
00062 #include <wwcommon/CSobHandlerFactory.h>
00063 #include <wwcommon/CMotionController.h>
00064 #include "tasks/CPacsTask.h"
00065
00066
00067
00068
00069
00070 namespace WWCLIENT {
00071
00072 CSimulationImpl *getClientSimulation() {
00073 return dynamic_cast<CSimulationImpl *>(getSimulation());
00074 }
00075
00076 bool CSimulationImpl::attachUser(uint32 uid, uint32 sobid) {
00077
00078 return true;
00079 }
00080
00081 void CSimulationImpl::detachUser(uint32 uid, uint32 sobid) {
00082
00083 }
00084
00085
00086 void CSimulationImpl::init() {
00087
00088 std::string retBankName, globRetBank;
00089 retBankName=CConfigTask::instance().configFile().getVar("RetrieverBankName").asString();
00090 globRetBank=CConfigTask::instance().configFile().getVar("GlobalRetrieverName").asString();
00091
00092 nlinfo("Create Retriever Bank: %s", NLMISC::CPath::lookup(retBankName).c_str());
00093 nlinfo("Create Global Retriever: %s", NLMISC::CPath::lookup(globRetBank).c_str());
00094
00095
00096 m_RetrieverBank = NLPACS::URetrieverBank::createRetrieverBank(retBankName.c_str());
00097 if(m_RetrieverBank == NULL)
00098 nlinfo("what the fuck bitch.");
00099 m_GlobalRetriever = NLPACS::UGlobalRetriever::createGlobalRetriever(globRetBank.c_str(), m_RetrieverBank);
00100
00101 nlinfo("Create Move Container.");
00102 m_MoveContainer = NLPACS::UMoveContainer::createMoveContainer(m_GlobalRetriever, 100, 100, 6.0);
00103
00104
00105 m_SelfSob=NULL;
00106
00107 WWCOMMON::IBaseSimulation::init();
00108
00109
00110 m_SimulationDelay=0.1;
00111 m_PingLatency=0;
00112 m_PingCount=0;
00113 m_PingLocalTimeStamp=0;
00114
00115 m_Epsilon=0.000001;
00116 m_NoPing=false;
00117 m_NextPingTime=0;
00118
00119 WWCOMMON::CGameEventServer::instance().setDeltaMultiplier(0.0f);
00120 }
00121
00122 void CSimulationImpl::update() {
00123
00124 updatePing();
00125
00126
00127 WWCOMMON::IBaseSimulation::update();
00128 }
00129
00130 void CSimulationImpl::spawnSelf(WWCOMMON::CSobSpawnEvent *event) {
00131
00132 CActorProxy *sob=dynamic_cast<CActorProxy *>(getNewSob("sobActor", event->SourceID));
00133
00134
00135 m_ActorManager->addSob(sob);
00136
00137 m_SelfSob=sob;
00138
00139
00140 if(event->Position == NLMISC::CVector::Null) {
00141 nlwarning("Entity spawned at an invalid position: %d", sob->getSobId());
00142 return;
00143 }
00144
00145 sob->setPosition(event->Position);
00146 sob->setGlobalPosition(event->Position);
00147
00148
00149 CEntityMedia emd = CResourceTask::instance().getEMD(event->EMD);
00150 WWCOMMON::IView* view = new CPerformer3DView(sob, emd);
00151 view->show();
00152 sob->addView(view);
00153
00154
00155 view = new CPerformerChatView(sob);
00156 view->show();
00157 sob->addView(view);
00158
00159 sob->addController(new CInteractiveSobController(sob));
00160
00161 sob->addHandler(WWCOMMON::CSobHandlerFactory::instance().getHandler(WWCOMMON::CSobHandlerFactory::H_CLIENT_MOTION));
00162 sob->addHandler(WWCOMMON::CSobHandlerFactory::instance().getHandler(WWCOMMON::CSobHandlerFactory::H_MOTION));
00163 sob->addHandler(WWCOMMON::CSobHandlerFactory::instance().getHandler(WWCOMMON::CSobHandlerFactory::H_MOTION_REQUEST));
00164 }
00165
00166 void CSimulationImpl::addSob(WWCOMMON::CSobAddEvent *event) {
00167
00168 CActorProxy *sob=dynamic_cast<CActorProxy *>(getNewSob("sobActor", event->SourceID));
00169
00170
00171 m_ActorManager->addSob(sob);
00172
00173
00174 if(event->Position == NLMISC::CVector::Null) {
00175 nlwarning("Entity spawned at an invalid position: %d", sob->getSobId());
00176 return;
00177 }
00178
00179 sob->setPosition(event->Position);
00180 sob->getCurrentKey()->setSpeed(event->Speed);
00181 sob->getCurrentKey()->setYaw(event->Yaw);
00182 sob->getCurrentKey()->setYawSpeed(event->YawVelocity);
00183 sob->setGlobalPosition(event->Position);
00184 sob->setActiveStateList(&event->ActiveStateList);
00185
00186 CEntityMedia emd = CResourceTask::instance().getEMD(event->EMD);
00187 WWCOMMON::IView* view = new CPerformer3DView(sob, emd);
00188 view->show();
00189 sob->addView(view);
00190
00191 sob->addHandler(WWCOMMON::CSobHandlerFactory::instance().getHandler(WWCOMMON::CSobHandlerFactory::H_CLIENT_MOTION));
00192
00193 WWCOMMON::CMotionController* controller = new WWCOMMON::CMotionController(sob);
00194 controller->setVisualCollisionEntity(&(CPacsTask::instance().getVisualCollisionManager()));
00195 sob->addController(controller);
00196 }
00197
00198 void CSimulationImpl::removeSob(uint32 id) {
00199 WWCOMMON::ISimulationObj *sob=m_ActorManager->find(id);
00200 if(sob==NULL) {
00201 nlwarning("Failed to locate sob %d to unspawn.", id);
00202 return;
00203 }
00204
00205 nlinfo("Removing sob %d from simulation.", id);
00206 m_ActorManager->removeSob(sob);
00207
00208 delete sob;
00209 }
00210
00211 void CSimulationImpl::recvPing(double serverTimeStamp, double localTimeStamp) {
00212
00213 if(m_PingLocalTimeStamp==0) {
00214 nlwarning("Received a ping response with no ping pending!");
00215 return;
00216 }
00217
00218
00219 if(m_PingLocalTimeStamp != localTimeStamp) {
00220 nlwarning("Received a ping response for a ping that's not current.");
00221 return;
00222 }
00223
00224
00225 double localRecvTimeStamp = time();
00226 double currentLatency = localRecvTimeStamp - localTimeStamp;
00227
00228
00229
00230 ++m_PingCount;
00231
00232 unsigned long pingWeight = std::min<unsigned long>(5, m_PingCount-1);
00233 m_PingLatency = (pingWeight*m_PingLatency + currentLatency)/(pingWeight+1);
00234
00235
00236
00237 double currentOffset = serverTimeStamp - localRecvTimeStamp + m_PingLatency;
00238 currentOffset /= m_PingCount;
00239 if(currentOffset > m_Epsilon) {
00240 unsigned long offsetWeight = m_PingCount-1;
00241
00242 if(m_PingCount < 50) {
00243 offsetWeight = std::min<unsigned long>(5, offsetWeight);
00244 currentOffset = serverTimeStamp - localRecvTimeStamp + m_PingLatency;
00245 currentOffset /= (offsetWeight+1);
00246 }
00247 m_OffsetTime = (m_OffsetTime*offsetWeight)/(offsetWeight+1) + currentOffset;
00248 } else {
00249
00250
00251
00252
00253 m_NoPing = true;
00254 nlinfo("Stopped pinging.");
00255 }
00256
00257
00258 }
00259
00260 void CSimulationImpl::sendPing() {
00261
00262 if(!CNetworkTask::instance().connected())
00263 return;
00264
00265 m_PingLocalTimeStamp = time();
00266
00267
00268
00269 if(m_PingCount < 25) {
00270 m_NextPingTime = time() + 0.4;
00271 } else {
00272 m_NextPingTime=time()+ 5.00;
00273 }
00274
00275
00276 NLNET::CMessage msgout("PINGREQ");
00277 msgout.serial(m_PingLocalTimeStamp);
00278 CNetworkTask::instance().send(msgout);
00279 }
00280
00281 void CSimulationImpl::updatePing() {
00282
00283 if(m_NoPing)
00284 return;
00285
00286
00287 if(m_SelfSob == NULL)
00288 return;
00289
00290
00291 if(m_NextPingTime <= time())
00292 sendPing();
00293 }
00294
00295 };