EntityManager.cpp 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415
  1. #include "core/EntityManager.h"
  2. #include <OgreEntity.h>
  3. #include <OgreRoot.h>
  4. #include "core/CameraManager.h"
  5. #include "core/ConfigVar.h"
  6. #include "core/DebugDraw.h"
  7. #include "core/EntityModel.h"
  8. #include "core/InputManager.h"
  9. #include "core/Logger.h"
  10. #include "core/ScriptManager.h"
  11. #include "core/Timer.h"
  12. template<>EntityManager *Ogre::Singleton< EntityManager >::msSingleton = NULL;
  13. ConfigVar cv_debug_grid( "debug_grid", "Draw debug grid", "false" );
  14. ConfigVar cv_debug_axis( "debug_axis", "Draw debug axis", "false" );
  15. float
  16. PointElevation( const Ogre::Vector2& point, const Ogre::Vector3& A, const Ogre::Vector3& B, const Ogre::Vector3& C )
  17. {
  18. float _A = A.z * ( B.y - C.y ) + B.z * ( C.y - A.y ) + C.z * ( A.y - B.y );
  19. float _B = A.y * ( B.x - C.x ) + B.y * ( C.x - A.x ) + C.y * ( A.x - B.x );
  20. float _C = A.x * ( B.z - C.z ) + B.x * ( C.z - A.z ) + C.x * ( A.z - B.z );
  21. float _D = A.x * ( B.z * C.y - C.z * B.y ) + B.x * ( C.z * A.y - A.z * C.y ) + C.x * ( A.z * B.y - B.z * A.y );
  22. return ( _D - _C * point.y - _A * point.x ) / _B;
  23. }
  24. float
  25. SideOfVector( const Ogre::Vector2& point, const Ogre::Vector2& p1, const Ogre::Vector2& p2 )
  26. {
  27. Ogre::Vector2 AB = p2 - p1;
  28. Ogre::Vector2 AP = point - p1;
  29. return AB.x * AP.y - AB.y * AP.x;
  30. }
  31. float
  32. SquareDistanceToLine( const Ogre::Vector3& p, const Ogre::Vector3& p1, const Ogre::Vector3& p2, Ogre::Vector3& proj )
  33. {
  34. float temp = -( ( p1.x - p.x ) * ( p2.x - p1.x ) + ( p1.y - p.y ) * ( p2.y - p1.y ) + ( p1.z - p.z ) * ( p2.z - p1.z ) ) / ( ( p2.x - p1.x ) * ( p2.x - p1.x ) + ( p2.y - p1.y ) * ( p2.y - p1.y ) + ( p2.z - p1.z ) * ( p2.z - p1.z ) );
  35. proj.x = temp * ( p2.x - p1.x ) + p1.x;
  36. proj.y = temp * ( p2.y - p1.y ) + p1.y;
  37. proj.z = temp * ( p2.z - p1.z ) + p1.z;
  38. if( ( ( p1.x >= proj.x && p2.x <= proj.x ) || ( p1.x < proj.x && p2.x >= proj.x ) ) &&
  39. ( ( p1.y >= proj.y && p2.y <= proj.y ) || ( p1.y < proj.y && p2.y >= proj.y ) ) )
  40. {
  41. return ( proj.x - p.x ) * ( proj.x - p.x ) + ( proj.y - p.y ) * ( proj.y - p.y ) + ( proj.z - p.z ) * ( proj.z - p.z );
  42. }
  43. return -1;
  44. }
  45. Ogre::Degree
  46. GetDirectionToPoint( const Ogre::Vector3& current_point, const Ogre::Vector3& direction_point )
  47. {
  48. Ogre::Vector2 up( 0.0f, -1.0f );
  49. Ogre::Vector2 dir( direction_point.x - current_point.x, direction_point.y - current_point.y );
  50. // angle between vectors
  51. Ogre::Degree angle( Ogre::Radian( acosf( dir.dotProduct( up ) / ( dir.length() * up.length() ) ) ) );
  52. return ( dir.x < 0 ) ? Ogre::Degree( 360 ) - angle : angle;
  53. }
  54. EntityManager::EntityManager():
  55. m_Paused( false ),
  56. m_PlayerEntity( NULL ),
  57. m_PlayerMove( Ogre::Vector3::ZERO ),
  58. m_PlayerMoveRotation( 0 ),
  59. m_PlayerLock( false )
  60. {
  61. LOG_TRIVIAL( "EntityManager created." );
  62. m_SceneNode = Ogre::Root::getSingleton().getSceneManager( "Scene" )->getRootSceneNode()->createChildSceneNode( "EntityManager" );
  63. m_Grid = Ogre::Root::getSingleton().getSceneManager( "Scene" )->createEntity( "Grid", "system/grid.mesh" );
  64. m_SceneNode->attachObject( m_Grid );
  65. m_Axis = Ogre::Root::getSingleton().getSceneManager( "Scene" )->createEntity( "Axis", "system/axis.mesh" );
  66. m_SceneNode->attachObject( m_Axis );
  67. }
  68. EntityManager::~EntityManager()
  69. {
  70. if( m_Grid != NULL )
  71. {
  72. Ogre::Root::getSingleton().getSceneManager( "Scene" )->destroyEntity( m_Grid );
  73. }
  74. if( m_Axis != NULL )
  75. {
  76. Ogre::Root::getSingleton().getSceneManager( "Scene" )->destroyEntity( m_Axis );
  77. }
  78. Clear();
  79. Ogre::Root::getSingleton().getSceneManager( "Scene" )->getRootSceneNode()->removeAndDestroyChild( "EntityManager" );
  80. LOG_TRIVIAL( "EntityManager destroyed." );
  81. }
  82. void
  83. EntityManager::Input( const Event& event )
  84. {
  85. m_Background2D.InputDebug( event );
  86. if( m_Paused == true )
  87. {
  88. return;
  89. }
  90. if( m_PlayerEntity != NULL && m_PlayerLock == false )
  91. {
  92. if( ( event.type == ET_KEY_IMPULSE ) && ( event.param1 == OIS::KC_LEFT ) )
  93. {
  94. m_PlayerMove.x = -1;
  95. }
  96. else if( ( event.type == ET_KEY_IMPULSE ) && ( event.param1 == OIS::KC_RIGHT ) )
  97. {
  98. m_PlayerMove.x = 1;
  99. }
  100. if( ( event.type == ET_KEY_IMPULSE ) && ( event.param1 == OIS::KC_DOWN ) )
  101. {
  102. m_PlayerMove.y = -1;
  103. }
  104. if( ( event.type == ET_KEY_IMPULSE ) && ( event.param1 == OIS::KC_UP ) )
  105. {
  106. m_PlayerMove.y = 1;
  107. }
  108. //rotate move vector to field move rotation
  109. Ogre::Quaternion q1;
  110. q1.FromAngleAxis( m_PlayerMoveRotation, Ogre::Vector3::UNIT_Z );
  111. m_PlayerMove = q1 * m_PlayerMove;
  112. }
  113. }
  114. void
  115. EntityManager::Update()
  116. {
  117. UpdateDebug();
  118. if( m_Paused == true )
  119. {
  120. return;
  121. }
  122. // update all entity scripts
  123. ScriptManager::getSingleton().Update( ScriptManager::ENTITY );
  124. // set move point for player entity
  125. if( m_PlayerEntity != NULL && m_PlayerMove != Ogre::Vector3::ZERO )
  126. {
  127. Entity::State state = m_PlayerEntity->GetState();
  128. if( state == Entity::WALKMESH || state == Entity::NONE )
  129. {
  130. m_PlayerMove *= m_PlayerEntity->GetMoveWalkSpeed() * Timer::getSingleton().GetGameTimeDelta();
  131. m_PlayerEntity->SetMovePosition( m_PlayerEntity->GetPosition() + m_PlayerMove );
  132. m_PlayerEntity->SetState( Entity::WALKMESH );
  133. }
  134. }
  135. for( unsigned int i = 0; i < m_Entity.size(); ++i )
  136. {
  137. m_Entity[ i ]->Update();
  138. // it's not needed to update movements it delta time == 0 (for example if we stop time)
  139. if( Timer::getSingleton().GetGameTimeDelta() == 0 )
  140. {
  141. continue;
  142. }
  143. // update screen scroll
  144. Entity* scroll_entity = m_Background2D.GetAutoScrollEntity();
  145. if( scroll_entity == m_Entity[ i ] )
  146. {
  147. CameraManager &camera_manager( CameraManager::getSingleton() );
  148. Ogre::Vector3 view = camera_manager.ProjectPointToScreen( scroll_entity->GetPosition() );
  149. Ogre::Vector2 pos = m_Background2D.GetScreenScroll();
  150. Ogre::Viewport *viewport( camera_manager.getViewport() );
  151. float width = float(viewport->getActualWidth());
  152. float height = float(viewport->getActualHeight());
  153. view.x = view.x - width / 2 - pos.x;
  154. view.y = view.y - height / 2 - pos.y;
  155. m_Background2D.SetScreenScroll( Ogre::Vector2( -view.x, -view.y ) );
  156. }
  157. // update offseting
  158. if( m_Entity[ i ]->GetOffsetType() != AT_NONE )
  159. {
  160. SetNextOffsetStep( m_Entity[ i ] );
  161. }
  162. // update turning
  163. if( m_Entity[ i ]->GetTurnType() != AT_NONE )
  164. {
  165. SetNextTurnStep( m_Entity[ i ] );
  166. }
  167. // update movement
  168. switch( m_Entity[ i ]->GetState() )
  169. {
  170. case Entity::WALKMESH:
  171. {
  172. bool is_move = false;
  173. // try set entity on walkmesh it it's still don't has triangle
  174. if( m_Entity[ i ]->GetMoveTriangleId() == -1 )
  175. {
  176. if( SetEntityOnWalkmesh( m_Entity[ i ] ) == false )
  177. {
  178. LOG_TRIVIAL( "Can't set entity \"" + m_Entity[ i ]->GetName() + "\" on walkmesh. Finish move." );
  179. m_Entity[ i ]->UnsetMove();
  180. }
  181. }
  182. // perform move
  183. if( m_Entity[ i ]->GetState() == Entity::WALKMESH )
  184. {
  185. float speed = 0;
  186. if( m_PlayerLock == false && m_PlayerEntity == m_Entity[ i ] )
  187. {
  188. speed = m_Entity[ i ]->GetMoveWalkSpeed();
  189. if( InputManager::getSingleton().IsButtonPressed( OIS::KC_LCONTROL ) == true )
  190. {
  191. speed *= 4;
  192. }
  193. }
  194. else
  195. {
  196. speed = m_Entity[ i ]->GetMoveAutoSpeed();
  197. }
  198. is_move = PerformWalkmeshMove( m_Entity[ i ], speed );
  199. if( m_Entity[ i ]->GetMoveAutoAnimation() == true )
  200. {
  201. if( is_move == true )
  202. {
  203. if( speed >= m_Entity[ i ]->GetMoveRunSpeed() )
  204. {
  205. m_Entity[ i ]->PlayAnimationContinue( m_Entity[ i ]->GetMoveAnimationRunName() );
  206. }
  207. else
  208. {
  209. m_Entity[ i ]->PlayAnimationContinue( m_Entity[ i ]->GetMoveAnimationWalkName() );
  210. }
  211. }
  212. else if ( m_Entity[ i ]->GetAnimationState() != Entity::REQUESTED_ANIMATION )
  213. {
  214. m_Entity[ i ]->PlayAnimationContinue( m_Entity[ i ]->GetDefaultAnimationName() );
  215. }
  216. }
  217. }
  218. }
  219. break;
  220. case Entity::LINEAR:
  221. {
  222. SetNextLinearStep( m_Entity[ i ] );
  223. }
  224. break;
  225. case Entity::JUMP:
  226. {
  227. SetNextJumpStep( m_Entity[ i ] );
  228. }
  229. break;
  230. case Entity::NONE:
  231. {
  232. if( m_Entity[ i ]->GetAnimationState() != Entity::REQUESTED_ANIMATION )
  233. {
  234. m_Entity[ i ]->PlayAnimationContinue( m_Entity[ i ]->GetDefaultAnimationName() );
  235. }
  236. }
  237. break;
  238. }
  239. }
  240. // reset player move. It already must be handled in update
  241. m_PlayerMove = Ogre::Vector3::ZERO;
  242. if( m_Background2D.GetScrollType() != Background2D::NONE )
  243. {
  244. SetNextScrollStep();
  245. }
  246. m_Background2D.Update();
  247. }
  248. void
  249. EntityManager::UpdateDebug()
  250. {
  251. m_Grid->setVisible( cv_debug_grid.GetB() );
  252. m_Axis->setVisible( cv_debug_axis.GetB() );
  253. for( unsigned int i = 0; i < m_Entity.size(); ++i )
  254. {
  255. m_Entity[ i ]->UpdateDebug();
  256. }
  257. for( unsigned int i = 0; i < m_EntityTriggers.size(); ++i )
  258. {
  259. m_EntityTriggers[ i ]->UpdateDebug();
  260. }
  261. for( unsigned int i = 0; i < m_EntityPoints.size(); ++i )
  262. {
  263. m_EntityPoints[ i ]->UpdateDebug();
  264. }
  265. m_Walkmesh.UpdateDebug();
  266. m_Background2D.UpdateDebug();
  267. }
  268. void
  269. EntityManager::OnResize()
  270. {
  271. m_Background2D.OnResize();
  272. }
  273. void
  274. EntityManager::Clear()
  275. {
  276. m_Walkmesh.Clear();
  277. m_Background2D.Clear();
  278. for( unsigned int i = 0; i < m_Entity.size(); ++i )
  279. {
  280. ScriptManager::getSingleton().RemoveEntity( ScriptManager::ENTITY, m_Entity[ i ]->GetName() );
  281. delete m_Entity[ i ];
  282. }
  283. m_Entity.clear();
  284. m_PlayerEntity = NULL;
  285. m_PlayerMove = Ogre::Vector3::ZERO;
  286. m_PlayerMoveRotation = 0;
  287. m_PlayerLock = false;
  288. for( unsigned int i = 0; i < m_EntityTriggers.size(); ++i )
  289. {
  290. ScriptManager::getSingleton().RemoveEntity( ScriptManager::ENTITY, m_EntityTriggers[ i ]->GetName() );
  291. delete m_EntityTriggers[ i ];
  292. }
  293. m_EntityTriggers.clear();
  294. for( unsigned int i = 0; i < m_EntityPoints.size(); ++i )
  295. {
  296. delete m_EntityPoints[ i ];
  297. }
  298. m_EntityPoints.clear();
  299. for( unsigned int i = 0; i < m_EntityScripts.size(); ++i )
  300. {
  301. ScriptManager::getSingleton().RemoveEntity( ScriptManager::ENTITY, m_EntityScripts[ i ] );
  302. }
  303. m_SceneNode->removeAndDestroyAllChildren();
  304. }
  305. void
  306. EntityManager::ScriptSetPaused( const bool paused )
  307. {
  308. m_Paused = paused;
  309. }
  310. Walkmesh*
  311. EntityManager::GetWalkmesh()
  312. {
  313. return &m_Walkmesh;
  314. }
  315. Background2D*
  316. EntityManager::GetBackground2D()
  317. {
  318. return &m_Background2D;
  319. }
  320. //--------------------------------------------------------------------------
  321. void
  322. EntityManager::AddEntity( const Ogre::String& name, const Ogre::String& file_name, const Ogre::Vector3& position, const Ogre::Degree& rotation )
  323. {
  324. AddEntity( name, file_name, position, rotation, Ogre::Vector3::UNIT_SCALE, Ogre::Quaternion::IDENTITY );
  325. }
  326. //--------------------------------------------------------------------------
  327. void
  328. EntityManager::AddEntity( const Ogre::String& name, const Ogre::String& file_name, const Ogre::Vector3& position, const Ogre::Degree& rotation, const Ogre::Vector3& scale, const Ogre::Quaternion& root_orientation )
  329. {
  330. Ogre::SceneNode* node = m_SceneNode->createChildSceneNode( "Model_" + name );
  331. EntityModel* entity = new EntityModel( name, file_name, node );
  332. entity->SetPosition( position );
  333. entity->SetRotation( rotation );
  334. entity->setScale( scale );
  335. entity->setRootOrientation( root_orientation );
  336. m_Entity.push_back( entity );
  337. ScriptManager::getSingleton().AddEntity( ScriptManager::ENTITY, entity->GetName(), entity );
  338. }
  339. //--------------------------------------------------------------------------
  340. void
  341. EntityManager::ScriptAddEntity( const char* name, const char* file_name, const float x, const float y, const float z, const float rotation )
  342. {
  343. AddEntity( name, file_name, Ogre::Vector3( x, y, z ), Ogre::Degree( rotation ) );
  344. }
  345. void
  346. EntityManager::AddEntityTrigger( const Ogre::String& name, const Ogre::Vector3& point1, const Ogre::Vector3& point2, const bool enabled )
  347. {
  348. EntityTrigger* trigger = new EntityTrigger( name );
  349. trigger->SetPoints( point1, point2 );
  350. trigger->SetEnabled( enabled );
  351. m_EntityTriggers.push_back( trigger );
  352. ScriptManager::getSingleton().AddEntity( ScriptManager::ENTITY, trigger->GetName(), NULL );
  353. }
  354. void
  355. EntityManager::AddEntityPoint( const Ogre::String& name, const Ogre::Vector3& position, const float rotation )
  356. {
  357. EntityPoint* entity_point = new EntityPoint( name );
  358. entity_point->SetPosition( position );
  359. entity_point->SetRotation( rotation );
  360. m_EntityPoints.push_back( entity_point );
  361. }
  362. void
  363. EntityManager::AddEntityScript( const Ogre::String& name )
  364. {
  365. m_EntityScripts.push_back( name );
  366. ScriptManager::getSingleton().AddEntity( ScriptManager::ENTITY, name, NULL );
  367. }
  368. void
  369. EntityManager::ScriptAddEntityScript( const char* name )
  370. {
  371. AddEntityScript( name );
  372. }
  373. Entity*
  374. EntityManager::GetEntity( const Ogre::String& name ) const
  375. {
  376. for( unsigned int i = 0; i < m_Entity.size(); ++i )
  377. {
  378. if( m_Entity[ i ]->GetName() == name )
  379. {
  380. return m_Entity[ i ];
  381. }
  382. }
  383. return NULL;
  384. }
  385. Entity*
  386. EntityManager::ScriptGetEntity( const char* name ) const
  387. {
  388. return GetEntity( Ogre::String( name ) );
  389. }
  390. EntityPoint*
  391. EntityManager::ScriptGetEntityPoint( const char* name ) const
  392. {
  393. for( unsigned int i = 0; i < m_EntityPoints.size(); ++i )
  394. {
  395. if( m_EntityPoints[ i ]->GetName() == name )
  396. {
  397. return m_EntityPoints[ i ];
  398. }
  399. }
  400. return NULL;
  401. }
  402. void
  403. EntityManager::ScriptSetPlayerEntity( const char* name )
  404. {
  405. for( unsigned int i = 0; i < m_Entity.size(); ++i )
  406. {
  407. if( m_Entity[ i ]->GetName() == name )
  408. {
  409. m_PlayerEntity = m_Entity[ i ];
  410. }
  411. }
  412. }
  413. void
  414. EntityManager::ScriptUnsetPlayerEntity()
  415. {
  416. m_PlayerEntity = NULL;
  417. }
  418. void
  419. EntityManager::ScriptPlayerLock( const bool lock )
  420. {
  421. m_PlayerLock = lock;
  422. if( lock == true )
  423. {
  424. m_PlayerMove = Ogre::Vector3::ZERO;
  425. }
  426. }
  427. void
  428. EntityManager::SetPlayerMoveRotation( const Ogre::Radian rotation )
  429. {
  430. m_PlayerMoveRotation = rotation;
  431. }
  432. bool
  433. EntityManager::SetEntityOnWalkmesh( Entity* entity )
  434. {
  435. Ogre::Vector3 position3 = entity->GetPosition();
  436. Ogre::Vector2 position2;
  437. position2.x = position3.x;
  438. position2.y = position3.y;
  439. std::vector< std::pair< int, float > > triangles;
  440. // we search for posible triangles
  441. for( int i = 0; i < m_Walkmesh.GetNumberOfTriangles(); ++i )
  442. {
  443. Ogre::Vector3 A3 = m_Walkmesh.GetA( i );
  444. Ogre::Vector3 B3 = m_Walkmesh.GetB( i );
  445. Ogre::Vector3 C3 = m_Walkmesh.GetC( i );
  446. Ogre::Vector2 A2( A3.x, A3.y );
  447. Ogre::Vector2 B2( B3.x, B3.y );
  448. Ogre::Vector2 C2( C3.x, C3.y );
  449. if( Ogre::Math::pointInTri2D( position2, A2, B2, C2 ) == true )
  450. {
  451. triangles.push_back( std::make_pair( i, PointElevation( position2, m_Walkmesh.GetA( i ), m_Walkmesh.GetB( i ), m_Walkmesh.GetC( i ) ) ) );
  452. }
  453. }
  454. // if our coords doesn't match any triangle
  455. if( triangles.size() == 0 )
  456. {
  457. LOG_ERROR( "Can't find any triangle to place entity \"" + entity->GetName() + "\" on walkmesh." );
  458. return false;
  459. }
  460. /*
  461. int triangle = m_Models[entity_id]->GetTriangle();
  462. if (triangle != -1)
  463. {
  464. for (int i = 0; i < triangles.size(); ++i)
  465. {
  466. if (triangles[i].first == triangle)
  467. {
  468. m_Models[entity_id]->SetPosition(Ogre::Vector3(position2.x, position2.y, triangles[i].second));
  469. return;
  470. }
  471. }
  472. }
  473. */
  474. // place entity on fount triangles
  475. // first try to set on top triangle less than current pos of entity
  476. float pos_z = position3.z;
  477. int triangle_id = -1;
  478. for( size_t i = 0; i < triangles.size(); ++i )
  479. {
  480. if( triangles[ i ].second <= pos_z )
  481. {
  482. pos_z = triangles[ i ].second;
  483. triangle_id = triangles[ i ].first;
  484. break;
  485. }
  486. }
  487. // if every triangle are higher than entity
  488. if( triangle_id == -1 )
  489. {
  490. for( size_t i = 0; i < triangles.size(); ++i )
  491. {
  492. if( triangles[ i ].second >= pos_z )
  493. {
  494. pos_z = triangles[ i ].second;
  495. triangle_id = triangles[ i ].first;
  496. }
  497. }
  498. }
  499. entity->SetPosition( Ogre::Vector3( position2.x, position2.y, pos_z ) );
  500. entity->SetMoveTriangleId( triangle_id );
  501. return true;
  502. }
  503. bool
  504. EntityManager::PerformWalkmeshMove( Entity* entity, const float speed )
  505. {
  506. Ogre::Vector3 start_point = entity->GetPosition();
  507. Ogre::Vector3 move_vector = entity->GetMovePosition() - start_point;
  508. Ogre::Vector2 direction( move_vector.x, move_vector.y );
  509. direction.normalise();
  510. direction *= Timer::getSingleton().GetGameTimeDelta();
  511. direction *= speed;
  512. // if we still need to move but speed ot time don't allow us to do this just return for now
  513. if( direction.isZeroLength() == true )
  514. {
  515. return false;
  516. }
  517. int current_triangle = entity->GetMoveTriangleId();
  518. if( current_triangle == -1 )
  519. {
  520. LOG_ERROR( "Entity \"" + entity->GetName() + "\" not placed on walkmesh and can't move.");
  521. return false;
  522. }
  523. //LOG_TRIVIAL( "Start position calculation." );
  524. //LOG_TRIVIAL( "Start point: " + Ogre::StringConverter::toString( start_point ) + "." );
  525. //LOG_TRIVIAL( "Move vector: " + Ogre::StringConverter::toString( direction ) + "." );
  526. Ogre::Vector3 rotation( 0.0f, 0.0f, 0.0f );
  527. Ogre::Quaternion q1( 0.0f, 0.0f, 0.0f, 1.0f );
  528. Ogre::Vector3 end_point( 0.0f, 0.0f, 0.0f );
  529. Ogre::Vector3 end_point2( 0.0f, 0.0f, 0.0f );
  530. bool first_triangle_check = false;
  531. bool second_triangle_check = false;
  532. bool third_triangle_check = false;
  533. bool last_triangle_check = false;
  534. bool first_entity_check = false;
  535. bool second_entity_check = false;
  536. bool third_entity_check = false;
  537. // shorten move vector by triangle angle
  538. end_point.x = start_point.x + direction.x;
  539. end_point.y = start_point.y + direction.y;
  540. Ogre::Vector3 A3 = m_Walkmesh.GetA( current_triangle );
  541. Ogre::Vector3 B3 = m_Walkmesh.GetB( current_triangle );
  542. Ogre::Vector3 C3 = m_Walkmesh.GetC( current_triangle );
  543. end_point.z = PointElevation( Ogre::Vector2( end_point.x, end_point.y ), A3, B3, C3 );
  544. Ogre::Vector3 temp = end_point - start_point;
  545. temp.normalise();
  546. temp = temp * direction.length();
  547. direction.x = temp.x;
  548. direction.y = temp.y;
  549. //LOG_TRIVIAL( "Shortened Direction:(" + Ogre::StringConverter::toString( direction ) + ")." );
  550. // set direction for entity if we want to move
  551. if( entity->GetMoveAutoRotation() == true )
  552. {
  553. Ogre::Vector2 up( 0.0f, -1.0f );
  554. // angle between vectors
  555. Ogre::Degree angle( Ogre::Radian( acosf( direction.dotProduct( up ) / ( direction.length() * up.length() ) ) ) );
  556. angle = ( direction.x < 0 ) ? Ogre::Degree( 360 ) - angle : angle;
  557. entity->SetRotation( Ogre::Degree( angle ) );
  558. }
  559. float solid = ( entity->IsSolid() == true ) ? entity->GetSolidRadius() : 0.01f;
  560. // get ending point
  561. end_point.z = start_point.z;
  562. //LOG_TRIVIAL( "End point: (" + Ogre::StringConverter::toString( end_point ) + ")." );
  563. //LOG_TRIVIAL( "Start cycle." );
  564. for( int i = 0; ( entity == m_PlayerEntity && /*m_PlayerModelSlip == true &&*/ i < 16 ) ||
  565. ( entity == m_PlayerEntity && /*m_PlayerModelSlip == false &&*/ i < 3 ) ||
  566. ( entity != m_PlayerEntity && i <= 16 ); ++i )
  567. {
  568. //LOG_TRIVIAL( "Cycle " + Ogre::StringConverter::toString( i ) + "." );
  569. end_point = Ogre::Vector3( start_point.x + direction.x, start_point.y + direction.y, start_point.z );
  570. // 1st check
  571. // rotate move_vector +45
  572. q1.FromAngleAxis( Ogre::Radian( Ogre::Degree( 45 ) ), Ogre::Vector3::UNIT_Z );
  573. rotation.x = direction.x;
  574. rotation.y = direction.y;
  575. rotation.z = 0;
  576. rotation.normalise();
  577. rotation = q1 * rotation;
  578. //LOG_TRIVIAL( "Move vector length: " + Ogre::StringConverter::toString( rotation.length() ) + "." );
  579. // multiply move_vector by solid range
  580. rotation = rotation * solid;
  581. end_point2.x = end_point.x + rotation.x;
  582. end_point2.y = end_point.y + rotation.y;
  583. //LOG_TRIVIAL( "Left sector part end point:(" + Ogre::StringConverter::toString( end_point2 ) + ")." );
  584. // check_triangle
  585. first_triangle_check = WalkmeshBorderCross( entity, end_point2, direction );
  586. entity->SetMoveTriangleId( current_triangle );
  587. // model_check
  588. first_entity_check = CheckSolidCollisions( entity, end_point2 );
  589. //LOG_TRIVIAL( "Entity \"" + entity->GetName() + "\" check1: " + Ogre::StringConverter::toString( first_triangle_check ) + " " + Ogre::StringConverter::toString( first_entity_check ) + "." );
  590. // 2nd check
  591. // rotate move_vector +45
  592. q1.FromAngleAxis( Ogre::Radian( Ogre::Degree( -45 ) ), Ogre::Vector3::UNIT_Z );
  593. rotation.x = direction.x;
  594. rotation.y = direction.y;
  595. rotation.z = 0;
  596. rotation.normalise();
  597. rotation = q1 * rotation;
  598. // multiply move_vector by solid range
  599. rotation = rotation * solid;
  600. end_point2.x = end_point.x + rotation.x;
  601. end_point2.y = end_point.y + rotation.y;
  602. // check triangle
  603. second_triangle_check = WalkmeshBorderCross( entity, end_point2, direction );
  604. entity->SetMoveTriangleId( current_triangle );
  605. // model_check
  606. second_entity_check = CheckSolidCollisions( entity, end_point2 );
  607. //LOG_TRIVIAL( "Entity \"" + entity->GetName() + "\" check2: " + Ogre::StringConverter::toString( second_triangle_check ) + " " + Ogre::StringConverter::toString( second_entity_check ) + "." );
  608. // 3rd check
  609. rotation.x = direction.x;
  610. rotation.y = direction.y;
  611. rotation.z = 0;
  612. rotation.normalise();
  613. rotation = rotation * solid;
  614. end_point2.x = end_point.x + rotation.x;
  615. end_point2.y = end_point.y + rotation.y;
  616. // check triangle
  617. third_triangle_check = WalkmeshBorderCross( entity, end_point2, direction );
  618. entity->SetMoveTriangleId( current_triangle );
  619. // model_check
  620. third_entity_check = CheckSolidCollisions( entity, end_point2 );
  621. //LOG_TRIVIAL( "Entity \"" + entity->GetName() + "\" check3: " + Ogre::StringConverter::toString( third_triangle_check ) + " " + Ogre::StringConverter::toString( third_entity_check ) + "." );
  622. // check condition and modify move_vector
  623. if( first_triangle_check != false || second_triangle_check != false || third_triangle_check != false ||
  624. first_entity_check != false || second_entity_check != false || third_entity_check != false )
  625. {
  626. // only for NPC
  627. if( entity != m_PlayerEntity )
  628. {
  629. // if we collide only directly into triangle border
  630. if( first_triangle_check == false && second_triangle_check == false && third_triangle_check != false )
  631. {
  632. q1.FromAngleAxis( Ogre::Radian( Ogre::Degree( -7 ) ), Ogre::Vector3::UNIT_Z );
  633. rotation.x = direction.x;
  634. rotation.y = direction.y;
  635. rotation = q1 * rotation;
  636. direction.x = rotation.x;
  637. direction.y = rotation.y;
  638. }
  639. // or if we only collide into others entity directly
  640. else if( first_entity_check == false && second_entity_check == false && third_entity_check != false )
  641. {
  642. //LOG_TRIVIAL( "Entity \"" + entity->GetName() + "\" try to rotate." );
  643. q1.FromAngleAxis( Ogre::Radian( Ogre::Degree( -11.25f ) ), Ogre::Vector3::UNIT_Z );
  644. rotation.x = direction.x;
  645. rotation.y = direction.y;
  646. rotation = q1 * rotation;
  647. direction.x = rotation.x;
  648. direction.y = rotation.y;
  649. }
  650. // if not both left and right check was fail
  651. if( first_triangle_check == false || second_triangle_check == false )
  652. {
  653. if( ( first_triangle_check == false && first_entity_check != false ) || ( first_triangle_check != false && second_triangle_check == false ) )
  654. {
  655. q1.FromAngleAxis( Ogre::Radian( Ogre::Degree( -11.25f ) ), Ogre::Vector3::UNIT_Z );
  656. rotation.x = direction.x;
  657. rotation.y = direction.y;
  658. rotation = q1 * rotation;
  659. direction.x = rotation.x;
  660. direction.y = rotation.y;
  661. //LOGGER->Log(LOGGER_WARNING, "New move vector: %f %f.", direction.x, direction.y);
  662. }
  663. if( first_triangle_check == false && first_entity_check == false && ( second_triangle_check != false || second_entity_check != false ) )
  664. {
  665. q1.FromAngleAxis( Ogre::Radian( Ogre::Degree( 11.25f ) ), Ogre::Vector3::UNIT_Z );
  666. rotation.x = direction.x;
  667. rotation.y = direction.y;
  668. rotation = q1 * rotation;
  669. direction.x = rotation.x;
  670. direction.y = rotation.y;
  671. //LOGGER->Log(LOGGER_WARNING, "New move vector: %f %f.", direction.x, direction.y);
  672. }
  673. continue;
  674. }
  675. break;
  676. }
  677. // only for PC
  678. else
  679. {
  680. if( first_entity_check == false && second_entity_check == false && third_entity_check == false )
  681. {
  682. // if not both left and right check was fail
  683. if( first_triangle_check == false || second_triangle_check == false )
  684. {
  685. if( ( first_triangle_check == false && first_entity_check != false ) ||
  686. ( first_triangle_check != false && second_triangle_check == false ) )
  687. {
  688. q1.FromAngleAxis( Ogre::Radian( Ogre::Degree( -11.25f ) ), Ogre::Vector3::UNIT_Z );
  689. rotation.x = direction.x;
  690. rotation.y = direction.y;
  691. rotation = q1 * rotation;
  692. direction.x = rotation.x;
  693. direction.y = rotation.y;
  694. //LOG_TRIVIAL( "Entity \"" + entity->GetName() + "\" new move vector: " + Ogre::StringConverter::toString( direction.x ) + " " + Ogre::StringConverter::toString( direction.y ) + "." );
  695. }
  696. if( first_triangle_check == false && first_entity_check == false && ( second_triangle_check != false || second_entity_check != false ) )
  697. {
  698. q1.FromAngleAxis( Ogre::Radian( Ogre::Degree( 11.25f ) ), Ogre::Vector3::UNIT_Z );
  699. rotation.x = direction.x;
  700. rotation.y = direction.y;
  701. rotation = q1 * rotation;
  702. direction.x = rotation.x;
  703. direction.y = rotation.y;
  704. //LOG_TRIVIAL( "Entity \"" + entity->GetName() + "\" new move vector: " + Ogre::StringConverter::toString( direction.x ) + " " + Ogre::StringConverter::toString( direction.y ) + "." );
  705. }
  706. continue;
  707. }
  708. break;
  709. }
  710. }
  711. }
  712. }
  713. //LOG_TRIVIAL( "Stop cycle." );
  714. // set new X, Y and Z
  715. last_triangle_check = WalkmeshBorderCross( entity, end_point, direction );
  716. if( first_triangle_check != false || second_triangle_check != false || third_triangle_check != false || last_triangle_check != false ||
  717. first_entity_check != false || second_entity_check != false || third_entity_check != false )
  718. {
  719. LOG_TRIVIAL( "Entity \"" + entity->GetName() + "\" can't move to specified position." );
  720. return false;
  721. }
  722. // check triggers before set entity position because we check move line
  723. CheckTriggers( entity, end_point );
  724. entity->SetPosition( end_point );
  725. // if we come to destination point - finish movement
  726. Ogre::Vector3 final = entity->GetMovePosition() - end_point;
  727. if( Ogre::Vector2( final.x, final.y ).length() <= entity->GetMoveStopDistance() + speed / 10 )
  728. {
  729. entity->UnsetMove();
  730. }
  731. return true;
  732. }
  733. bool
  734. EntityManager::WalkmeshBorderCross( Entity* entity, Ogre::Vector3& position, const Ogre::Vector2& move_vector)
  735. {
  736. int current_triangle = entity->GetMoveTriangleId();
  737. if (current_triangle == -1)
  738. {
  739. return true;
  740. }
  741. Ogre::Vector2 pos = Ogre::Vector2( position.x, position.y );
  742. for( ;; )
  743. {
  744. Ogre::Vector3 A3 = m_Walkmesh.GetA( current_triangle );
  745. Ogre::Vector3 B3 = m_Walkmesh.GetB( current_triangle );
  746. Ogre::Vector3 C3 = m_Walkmesh.GetC( current_triangle );
  747. /*LOG_ERROR( "Triangle:A(" + Ogre::StringConverter::toString( A3.x ) +
  748. " " + Ogre::StringConverter::toString( A3.y ) +
  749. " " + Ogre::StringConverter::toString( A3.z ) +
  750. ") B(" + Ogre::StringConverter::toString( B3.x ) +
  751. " " + Ogre::StringConverter::toString( B3.y ) +
  752. " " + Ogre::StringConverter::toString( B3.z ) +
  753. ") C(" + Ogre::StringConverter::toString( C3.x ) +
  754. " " + Ogre::StringConverter::toString( C3.y ) +
  755. " " + Ogre::StringConverter::toString( C3.z ) + ")." );*/
  756. Ogre::Vector2 A( A3.x, A3.y );
  757. Ogre::Vector2 B( B3.x, B3.y );
  758. Ogre::Vector2 C( C3.x, C3.y );
  759. float sign1 = SideOfVector( pos, B, A );
  760. float sign2 = SideOfVector( pos, C, B );
  761. float sign3 = SideOfVector( pos, A, C );
  762. int next_triangle = -1;
  763. if( sign1 < 0 )
  764. {
  765. next_triangle = m_Walkmesh.GetAccessSide( current_triangle, 0 );
  766. }
  767. else if( sign2 < 0 )
  768. {
  769. next_triangle = m_Walkmesh.GetAccessSide( current_triangle, 1 );
  770. }
  771. else if( sign3 < 0 )
  772. {
  773. next_triangle = m_Walkmesh.GetAccessSide( current_triangle, 2 );
  774. }
  775. else
  776. {
  777. position.z = PointElevation( pos, A3, B3, C3 );
  778. //LOG_ERROR( "In triangle." );
  779. //LOG_ERROR( "Stop CheckTriangles with false and triangle " + Ogre::StringConverter::toString( current_triangle ) + "." );
  780. entity->SetMoveTriangleId( current_triangle );
  781. return false;
  782. }
  783. if( next_triangle >= 0 )
  784. {
  785. bool lock = m_Walkmesh.IsLocked( next_triangle );
  786. if( lock == false )
  787. {
  788. current_triangle = next_triangle;
  789. continue;
  790. }
  791. }
  792. position.z = PointElevation( pos, A3, B3, C3 );
  793. entity->SetMoveTriangleId( current_triangle );
  794. return true;
  795. }
  796. }
  797. bool
  798. EntityManager::CheckSolidCollisions( Entity* entity, Ogre::Vector3& position )
  799. {
  800. if( entity->IsSolid() == false )
  801. {
  802. return false;
  803. }
  804. for( size_t i = 0; i < m_Entity.size(); ++i )
  805. {
  806. if( m_Entity[ i ]->IsSolid() == false )
  807. {
  808. continue;
  809. }
  810. if( m_Entity[ i ] == entity )
  811. {
  812. continue;
  813. }
  814. Ogre::Vector3 pos1 = m_Entity[ i ]->GetPosition();
  815. float solid_range = m_Entity[ i ]->GetSolidRadius();
  816. solid_range *= solid_range;
  817. float height = ( pos1.z < position.z ) ? m_Entity[ i ]->GetHeight() : entity->GetHeight();
  818. //log->logMessage("Height collision(" + Ogre::StringConverter::toString(pos1.z) + " " + Ogre::StringConverter::toString(position.z) + " " + Ogre::StringConverter::toString(height) + ").");
  819. if( ( ( pos1.z - position.z + height ) < ( height * 2 ) ) && ( ( pos1.z - position.z + height ) >= 0 ) )
  820. {
  821. float distance = ( pos1.x - position.x ) * ( pos1.x - position.x ) + ( pos1.y - position.y ) * ( pos1.y - position.y );
  822. //log->logMessage("Dist collision(" + Ogre::StringConverter::toString(solid_range) + " " + Ogre::StringConverter::toString(distance) + ").");
  823. if( distance < solid_range )
  824. {
  825. //log->logMessage("Collide with entity.");
  826. // if this is player and we move by ourself (in ffvii only player model checked)
  827. /*
  828. if (model_id == m_PlayerModelId && m_PlayerModelLock == false)
  829. {
  830. m_FieldScriptManager->AddScript(m_Models[i]->GetName(), "on_collide", 1);
  831. }
  832. */
  833. return true;
  834. }
  835. }
  836. }
  837. //LOGGER->Log(LOGGER_INFO, "Not collide with entity");
  838. return false;
  839. }
  840. void
  841. EntityManager::CheckTriggers( Entity* entity, Ogre::Vector3& position )
  842. {
  843. if( entity->IsSolid() == false )
  844. {
  845. return;
  846. }
  847. for( unsigned int i = 0; i < m_EntityTriggers.size(); ++i )
  848. {
  849. ScriptEntity* scr_entity = ScriptManager::getSingleton().GetScriptEntityByName( ScriptManager::ENTITY, m_EntityTriggers[ i ]->GetName() );
  850. if( scr_entity != NULL && m_EntityTriggers[ i ]->IsEnabled() == true )
  851. {
  852. Ogre::Vector3 lp1 = m_EntityTriggers[ i ]->GetPoint1();
  853. Ogre::Vector3 lp2 = m_EntityTriggers[ i ]->GetPoint2();
  854. Ogre::Vector3 mp1 = entity->GetPosition();
  855. Ogre::Vector3 proj;
  856. // calculate distance
  857. float square_dist = SquareDistanceToLine( mp1, lp1, lp2, proj );
  858. float solid = entity->GetSolidRadius();
  859. if( square_dist != -1 && square_dist < solid * solid )
  860. {
  861. if( m_EntityTriggers[ i ]->IsActivator( entity ) == false )
  862. {
  863. bool added = ScriptManager::getSingleton().ScriptRequest( scr_entity, "on_enter_line", 1, entity->GetName(), "", false, false );
  864. if( added == false )
  865. {
  866. LOG_WARNING( "Script \"on_enter_line\" for entity \"" + m_EntityTriggers[ i ]->GetName() + "\" doesn't exist." );
  867. }
  868. m_EntityTriggers[ i ]->AddActivator( entity );
  869. }
  870. // check that 1st and 2nd points are on different side of line
  871. float cond1 = ( ( lp2.x - lp1.x ) * ( mp1.y - lp1.y ) ) - ( ( mp1.x - lp1.x ) * ( lp2.y - lp1.y ) );
  872. float cond2 = ( ( lp2.x - lp1.x ) * ( position.y - lp1.y ) ) - ( ( position.x - lp1.x ) * ( lp2.y - lp1.y ) );
  873. // if we cross the line
  874. if( ( cond1 > 0 && cond2 <= 0 ) || ( cond2 > 0 && cond1 <= 0 ) || ( cond1 >= 0 && cond2 < 0 ) || ( cond2 >= 0 && cond1 < 0 ) )
  875. {
  876. bool added = ScriptManager::getSingleton().ScriptRequest( scr_entity, "on_cross_line", 1, entity->GetName(), "", false, false );
  877. if( added == false )
  878. {
  879. LOG_WARNING( "Script \"on_cross_line\" for entity \"" + m_EntityTriggers[ i ]->GetName() + "\" doesn't exist." );
  880. }
  881. }
  882. // if we not move in line
  883. if( mp1 == position )
  884. {
  885. bool added = ScriptManager::getSingleton().ScriptRequest( scr_entity, "on_move_to_line", 1, entity->GetName(), "", false, false );
  886. if( added == false )
  887. {
  888. LOG_WARNING( "Script \"on_move_to_line\" for entity \"" + m_EntityTriggers[ i ]->GetName() + "\" doesn't exist." );
  889. }
  890. }
  891. else
  892. {
  893. const Ogre::Degree direction_to_line = GetDirectionToPoint( mp1, proj );
  894. const Ogre::Degree movement_direction = GetDirectionToPoint( mp1, position );
  895. // if we move to line
  896. Ogre::Degree angle = direction_to_line - movement_direction + Ogre::Degree( 90 );
  897. angle = ( angle > Ogre::Degree( 360 ) ) ? angle - Ogre::Degree( 360 ) : angle;
  898. if( angle < Ogre::Degree( 180 ) && angle > Ogre::Degree( 0 ) )
  899. {
  900. bool added = ScriptManager::getSingleton().ScriptRequest( scr_entity, "on_move_to_line", 1, entity->GetName(), "", false, false );
  901. if( added == false )
  902. {
  903. LOG_WARNING( "Script \"on_move_to_line\" for entity \"" + m_EntityTriggers[ i ]->GetName() + "\" doesn't exist." );
  904. }
  905. }
  906. }
  907. }
  908. else
  909. {
  910. if( m_EntityTriggers[ i ]->IsActivator( entity ) == true )
  911. {
  912. bool added = ScriptManager::getSingleton().ScriptRequest( scr_entity, "on_leave_line", 1, entity->GetName(), "", false, false );
  913. if( added == false )
  914. {
  915. LOG_WARNING( "Script \"on_leave_line\" for entity \"" + m_EntityTriggers[ i ]->GetName() + "\" doesn't exist." );
  916. }
  917. m_EntityTriggers[ i ]->RemoveActivator( entity );
  918. }
  919. }
  920. }
  921. }
  922. }
  923. void
  924. EntityManager::SetNextOffsetStep( Entity* entity )
  925. {
  926. ActionType type = entity->GetOffsetType();
  927. float total = entity->GetOffsetSeconds();
  928. float current = entity->GetOffsetCurrentSeconds();
  929. current += Timer::getSingleton().GetGameTimeDelta();
  930. current = ( current > total ) ? total : current;
  931. Ogre::Vector3 start = entity->GetOffsetPositionStart();
  932. Ogre::Vector3 end = entity->GetOffsetPositionEnd();
  933. float x = current / total;
  934. float smooth_modifier = ( type == AT_SMOOTH ) ? -2 * x * x * x + 3 * x * x : x;
  935. Ogre::Vector3 offset = start + ( end - start ) * smooth_modifier;
  936. entity->SetOffset( offset );
  937. if( current == total )
  938. {
  939. entity->UnsetOffset();
  940. }
  941. else
  942. {
  943. entity->SetOffsetCurrentSeconds( current );
  944. }
  945. }
  946. void
  947. EntityManager::SetNextTurnStep( Entity* entity )
  948. {
  949. ActionType type = entity->GetTurnType();
  950. float total = entity->GetTurnSeconds();
  951. float current = entity->GetTurnCurrentSeconds();
  952. current += Timer::getSingleton().GetGameTimeDelta();
  953. current = ( current > total ) ? total : current;
  954. Ogre::Degree start = entity->GetTurnDirectionStart();
  955. Ogre::Degree end = entity->GetTurnDirectionEnd();
  956. float x = current / total;
  957. float smooth_modifier = ( type == AT_SMOOTH ) ? -2 * x * x * x + 3 * x * x : x;
  958. Ogre::Degree rotation = start + ( end - start ) * smooth_modifier;
  959. entity->SetRotation( rotation );
  960. if( current == total )
  961. {
  962. entity->UnsetTurn();
  963. }
  964. else
  965. {
  966. entity->SetTurnCurrentSeconds( current );
  967. }
  968. }
  969. void
  970. EntityManager::SetNextLinearStep( Entity* entity )
  971. {
  972. bool to_end = true;
  973. bool is_move = false;
  974. Ogre::Vector3 start = entity->GetLinearStart();
  975. Ogre::Vector3 end = entity->GetLinearEnd();
  976. Ogre::Vector3 current = entity->GetPosition();
  977. float delta = Timer::getSingleton().GetGameTimeDelta();
  978. if( entity == m_PlayerEntity )
  979. {
  980. LinearMovement move = entity->GetLinearMovement();
  981. if( move == LM_DOWN_TO_UP || move == LM_UP_TO_DOWN )
  982. {
  983. if( m_PlayerMove.y > 0 ) // move up
  984. {
  985. to_end = ( move == LM_DOWN_TO_UP ) ? true : false;
  986. is_move = true;
  987. }
  988. else if( m_PlayerMove.y < 0 ) // move down
  989. {
  990. to_end = ( move == LM_DOWN_TO_UP ) ? false : true;
  991. is_move = true;
  992. }
  993. }
  994. else if( move == LM_LEFT_TO_RIGHT || move == LM_RIGHT_TO_LEFT )
  995. {
  996. if( m_PlayerMove.x > 0 ) // move right
  997. {
  998. to_end = ( move == LM_LEFT_TO_RIGHT ) ? true : false;
  999. is_move = true;
  1000. }
  1001. else if( m_PlayerMove.x < 0 ) // move left
  1002. {
  1003. to_end = ( move == LM_LEFT_TO_RIGHT ) ? false : true;
  1004. is_move = true;
  1005. }
  1006. }
  1007. }
  1008. else
  1009. {
  1010. is_move = true;
  1011. }
  1012. if( is_move == true )
  1013. {
  1014. Ogre::Vector3 position;
  1015. if( to_end == true )
  1016. {
  1017. Ogre::Vector3 end_start = end - start;
  1018. float time = end_start.length() / 1.2f; // move whole line by this number of seconds
  1019. position.x = current.x + ( end_start.x / time ) * delta;
  1020. position.y = current.y + ( end_start.y / time ) * delta;
  1021. position.z = current.z + ( end_start.z / time ) * delta;
  1022. position.x = ( end_start.x < 0 ) ? std::max( position.x, end.x ) : std::min( position.x, end.x );
  1023. position.y = ( end_start.y < 0 ) ? std::max( position.y, end.y ) : std::min( position.y, end.y );
  1024. position.z = ( end_start.z < 0 ) ? std::max( position.z, end.z ) : std::min( position.z, end.z );
  1025. if( position == end )
  1026. {
  1027. entity->UnsetLinear();
  1028. }
  1029. }
  1030. else
  1031. {
  1032. Ogre::Vector3 end_start = start - end;
  1033. float time = end_start.length() / 1.2f; // move whole line by this number of seconds
  1034. position.x = current.x + ( end_start.x / time ) * delta;
  1035. position.y = current.y + ( end_start.y / time ) * delta;
  1036. position.z = current.z + ( end_start.z / time ) * delta;
  1037. position.x = ( end_start.x < 0 ) ? std::max( position.x, start.x ) : std::min( position.x, start.x );
  1038. position.y = ( end_start.y < 0 ) ? std::max( position.y, start.y ) : std::min( position.y, start.y );
  1039. position.z = ( end_start.z < 0 ) ? std::max( position.z, start.z ) : std::min( position.z, start.z );
  1040. if( position == start )
  1041. {
  1042. entity->UnsetLinear();
  1043. }
  1044. }
  1045. entity->SetPosition( position );
  1046. entity->UpdateAnimation( ( to_end == true ) ? delta : -delta );
  1047. }
  1048. }
  1049. void
  1050. EntityManager::SetNextJumpStep( Entity* entity )
  1051. {
  1052. float total = entity->GetJumpSeconds();
  1053. float current = entity->GetJumpCurrentSeconds();
  1054. current += Timer::getSingleton().GetGameTimeDelta();
  1055. current = ( current > total ) ? total : current;
  1056. Ogre::Vector3 start_position = entity->GetJumpStart();
  1057. Ogre::Vector3 end_position = entity->GetJumpEnd();
  1058. Ogre::Vector3 position;
  1059. position.x = start_position.x + ( ( end_position.x - start_position.x) / total ) * current;
  1060. position.y = start_position.y + ( ( end_position.y - start_position.y ) / total ) * current;
  1061. position.z = current * current * -13.08f + current * ( ( end_position.z - start_position.z ) / total + total * 13.08f ) + start_position.z;
  1062. entity->SetPosition( position );
  1063. if( total == current )
  1064. {
  1065. entity->UnsetJump();
  1066. }
  1067. else
  1068. {
  1069. entity->SetJumpCurrentSeconds( current );
  1070. }
  1071. }
  1072. void
  1073. EntityManager::SetNextScrollStep()
  1074. {
  1075. Background2D::ScrollType type = m_Background2D.GetScrollType();
  1076. float total = m_Background2D.GetScrollSeconds();
  1077. float current = m_Background2D.GetScrollCurrentSeconds();
  1078. current += Timer::getSingleton().GetGameTimeDelta();
  1079. current = ( current > total ) ? total : current;
  1080. Ogre::Vector2 start = m_Background2D.GetScrollPositionStart();
  1081. Ogre::Vector2 end = m_Background2D.GetScrollPositionEnd();
  1082. float x = current / total;
  1083. float smooth_modifier = ( type == Background2D::SMOOTH ) ? -2 * x * x * x + 3 * x * x : x;
  1084. Ogre::Vector2 scroll = start + ( end - start ) * smooth_modifier;
  1085. m_Background2D.SetScroll( scroll );
  1086. if( current == total )
  1087. {
  1088. m_Background2D.UnsetScroll();
  1089. }
  1090. else
  1091. {
  1092. m_Background2D.SetScrollCurrentSeconds( current );
  1093. }
  1094. }