EntityManager.cpp 47 KB

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