Entity.cpp 22 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060
  1. #include <OgreSceneNode.h>
  2. #include "core/ConfigVar.h"
  3. #include "core/DebugDraw.h"
  4. #include "core/Entity.h"
  5. #include "core/Logger.h"
  6. ConfigVar cv_debug_entity("debug_entity", "Draw entity debug info", "0");
  7. Entity::Entity(const Ogre::String& name, Ogre::SceneNode* node):
  8. m_Name(name),
  9. m_SceneNode(node),
  10. m_Height(1.0f),
  11. m_SolidRadius(0.24f),
  12. m_Solid(false),
  13. m_TalkRadius(0.45f),
  14. m_Talkable(false),
  15. m_State(Entity::NONE),
  16. m_MoveAutoSpeed(0.7f),
  17. m_MoveWalkSpeed(0.7f),
  18. m_MoveRunSpeed(0.8f),
  19. m_MovePosition(Ogre::Vector3(0, 0, 0)),
  20. m_MoveEntity(nullptr),
  21. m_MoveStopDistance(0.0f),
  22. m_MoveTriangleId(-1),
  23. m_MoveAutoRotation(true),
  24. m_MoveAutoAnimation(true),
  25. m_MoveAnimationWalk("Walk"),
  26. m_MoveAnimationRun("Run"),
  27. m_LinearMovement(LM_UP_TO_DOWN),
  28. m_LinearStart(0.0f, 0.0f, 0.0f),
  29. m_LinearEnd(0.0f, 0.0f, 0.0f),
  30. m_JumpStart(0.0f, 0.0f, 0.0f),
  31. m_JumpEnd(0.0f, 0.0f, 0.0f),
  32. m_JumpSeconds(0.0f),
  33. m_JumpCurrentSeconds(0.0f),
  34. m_OffsetPositionStart(0.0f, 0.0f, 0.0f),
  35. m_OffsetPositionEnd(0.0f, 0.0f, 0.0f),
  36. m_OffsetType(AT_NONE),
  37. m_OffsetSeconds(0.0f),
  38. m_OffsetCurrentSeconds(0.0f),
  39. m_TurnDirection(TD_CLOSEST),
  40. m_TurnDirectionStart(0),
  41. m_TurnDirectionEnd(0),
  42. m_TurnEntity(nullptr),
  43. m_TurnType(AT_NONE),
  44. m_TurnSeconds(0.0f),
  45. m_TurnCurrentSeconds(0.0f),
  46. m_AnimationSpeed(1.0f),
  47. m_AnimationDefault("Idle"),
  48. m_AnimationCurrentName(""),
  49. m_AnimationAutoPlay(true)
  50. {
  51. m_model_root_node = m_SceneNode->createChildSceneNode();
  52. m_ModelNode = m_model_root_node->createChildSceneNode();
  53. m_Direction = new EntityDirection();
  54. m_Direction->setMaterial("entity/direction");
  55. m_DirectionNode = m_SceneNode->createChildSceneNode();
  56. m_DirectionNode->attachObject(m_Direction);
  57. m_SolidCollision = new EntityCollision();
  58. m_SolidCollision->setMaterial("entity/solid_collision");
  59. m_SolidCollisionNode = m_SceneNode->createChildSceneNode();
  60. m_SolidCollisionNode->setScale(m_SolidRadius, m_SolidRadius, m_Height);
  61. m_SolidCollisionNode->attachObject(m_SolidCollision);
  62. m_TalkCollision = new EntityCollision();
  63. m_TalkCollision->setMaterial("entity/talk_collision");
  64. m_TalkCollisionNode = m_SceneNode->createChildSceneNode();
  65. m_TalkCollisionNode->setScale(m_TalkRadius, m_TalkRadius, m_Height);
  66. m_TalkCollisionNode->attachObject(m_TalkCollision);
  67. m_model_root_node->setPosition(Ogre::Vector3::ZERO);
  68. m_ModelNode->setPosition(Ogre::Vector3::ZERO);
  69. m_SceneNode->setPosition(Ogre::Vector3::ZERO);
  70. LOG_TRIVIAL("Entity \"" + m_Name + "\" created.");
  71. }
  72. Entity::~Entity()
  73. {
  74. delete m_SolidCollision;
  75. delete m_TalkCollision;
  76. m_SceneNode->removeAndDestroyAllChildren();
  77. LOG_TRIVIAL("Entity \"" + m_Name + "\" destroyed.");
  78. }
  79. void
  80. Entity::Update()
  81. {
  82. if(m_MoveEntity != nullptr)
  83. {
  84. m_MovePosition = m_MoveEntity->GetPosition();
  85. m_MoveStopDistance = GetSolidRadius() + m_MoveEntity->GetSolidRadius();
  86. }
  87. if(m_TurnEntity != nullptr)
  88. {
  89. Ogre::Degree angle = GetDirectionToEntity(m_TurnEntity);
  90. angle = CalculateTurnAngle(m_TurnDirectionStart, angle);
  91. m_TurnDirectionEnd = angle;
  92. }
  93. }
  94. void
  95. Entity::UpdateDebug()
  96. {
  97. int debug = cv_debug_entity.GetI();
  98. m_DirectionNode->setVisible(debug > 0);
  99. m_SolidCollisionNode->setVisible(debug > 0 && m_Solid);
  100. m_TalkCollisionNode->setVisible(debug > 0 && m_Talkable);
  101. // debug output
  102. if(debug > 0)
  103. {
  104. DEBUG_DRAW.SetColour(Ogre::ColourValue::White);
  105. DEBUG_DRAW.SetScreenSpace(true);
  106. DEBUG_DRAW.SetTextAlignment(DEBUG_DRAW.CENTER);
  107. DEBUG_DRAW.SetFadeDistance(40, 50);
  108. Ogre::Vector3 entity_pos = GetPosition();
  109. DEBUG_DRAW.Text(entity_pos, 0, 0, m_Name);
  110. DEBUG_DRAW.Text(entity_pos, 0, 12, m_AnimationCurrentName);
  111. if(debug > 1)
  112. {
  113. static Ogre::String move_state_string[] = { "NONE", "WALKMESH", "LINEAR", "JUMP" };
  114. DEBUG_DRAW.Text(entity_pos, 0, 24, Ogre::StringConverter::toString(entity_pos));
  115. DEBUG_DRAW.Text(entity_pos, 0, 36, "Triangle: " + Ogre::StringConverter::toString(m_MoveTriangleId));
  116. DEBUG_DRAW.Text(entity_pos, 0, 48, "Move state: " + move_state_string[m_State]);
  117. switch(m_State)
  118. {
  119. case Entity::WALKMESH:
  120. {
  121. DEBUG_DRAW.Line3d(entity_pos, m_MovePosition);
  122. }
  123. break;
  124. case Entity::LINEAR:
  125. {
  126. DEBUG_DRAW.Text(m_LinearStart, 0, 0, "Start: " + Ogre::StringConverter::toString(m_LinearStart));
  127. DEBUG_DRAW.Text(m_LinearEnd, 0, 0, "End: " + Ogre::StringConverter::toString(m_LinearEnd));
  128. DEBUG_DRAW.Line3d(m_LinearStart, m_LinearEnd);
  129. }
  130. break;
  131. case Entity::JUMP:
  132. {
  133. DEBUG_DRAW.Text(m_JumpStart, 0, 0, "Start: " + Ogre::StringConverter::toString(m_JumpStart));
  134. DEBUG_DRAW.Text(m_JumpEnd, 0, 0, "End: " + Ogre::StringConverter::toString(m_JumpEnd));
  135. Ogre::Vector3 distance = m_JumpEnd - m_JumpStart;
  136. Ogre::Vector3 pos1, pos2, pos3;
  137. pos1.x = m_JumpStart.x + distance.x * 0.25f;
  138. pos1.y = m_JumpStart.y + distance.y * 0.25f;
  139. float current1 = m_JumpSeconds / 4;
  140. pos1.z = current1 * current1 * -13.08f + current1 * ((distance.z) / m_JumpSeconds + m_JumpSeconds * 13.08f) + m_JumpStart.z;
  141. pos2.x = m_JumpStart.x + distance.x * 0.5f;
  142. pos2.y = m_JumpStart.y + distance.y * 0.5f;
  143. float current2 = current1 * 2;
  144. pos2.z = current2 * current2 * -13.08f + current2 * ((distance.z) / m_JumpSeconds + m_JumpSeconds * 13.08f) + m_JumpStart.z;
  145. pos3.x = m_JumpStart.x + distance.x * 0.75f;
  146. pos3.y = m_JumpStart.y + distance.y * 0.75f;
  147. float current3 = current1 * 3;
  148. pos3.z = current3 * current3 * -13.08f + current3 * ((distance.z) / m_JumpSeconds + m_JumpSeconds * 13.08f) + m_JumpStart.z;
  149. DEBUG_DRAW.Line3d(m_JumpStart, pos1);
  150. DEBUG_DRAW.Line3d(pos1, pos2);
  151. DEBUG_DRAW.Line3d(pos2, pos3);
  152. DEBUG_DRAW.Line3d(pos3, m_JumpEnd);
  153. }
  154. break;
  155. }
  156. }
  157. }
  158. }
  159. const Ogre::String&
  160. Entity::GetName() const
  161. {
  162. return m_Name;
  163. }
  164. void
  165. Entity::SetPosition(const Ogre::Vector3& position)
  166. {
  167. m_SceneNode->setPosition(position);
  168. }
  169. void
  170. Entity::ScriptSetPosition(const float x, const float y, const float z)
  171. {
  172. SetPosition(Ogre::Vector3(x, y, z));
  173. // if we set it from script - reset walkmesh triangle to reattach entity to walkmesh again if needed
  174. m_MoveTriangleId = -1;
  175. }
  176. const Ogre::Vector3
  177. Entity::GetPosition() const
  178. {
  179. return m_SceneNode->getPosition();
  180. }
  181. void
  182. Entity::ScriptGetPosition() const
  183. {
  184. Ogre::Vector3 position = m_SceneNode->getPosition();
  185. ScriptManager::getSingleton().AddValueToStack(position.x);
  186. ScriptManager::getSingleton().AddValueToStack(position.y);
  187. ScriptManager::getSingleton().AddValueToStack(position.z);
  188. }
  189. void
  190. Entity::SetOffset(const Ogre::Vector3& position)
  191. {
  192. assert(m_model_root_node);
  193. m_model_root_node->setPosition(position);
  194. }
  195. const Ogre::Vector3
  196. Entity::GetOffset() const
  197. {
  198. assert(m_model_root_node);
  199. return m_model_root_node->getPosition();
  200. }
  201. void
  202. Entity::SetRotation(const Ogre::Degree& rotation)
  203. {
  204. assert(m_model_root_node);
  205. float angle = rotation.valueDegrees() - Ogre::Math::Floor(rotation.valueDegrees() / 360.0f) * 360.0f;
  206. if(angle < 0)
  207. {
  208. angle = 360 + angle;
  209. }
  210. Ogre::Quaternion q;
  211. Ogre::Vector3 vec = Ogre::Vector3::UNIT_Z;
  212. q.FromAngleAxis(Ogre::Radian(Ogre::Degree(angle)), vec);
  213. m_model_root_node->setOrientation(q);
  214. m_DirectionNode->setOrientation(q);
  215. }
  216. void
  217. Entity::ScriptSetRotation(const float rotation)
  218. {
  219. SetRotation(Ogre::Degree(rotation));
  220. }
  221. Ogre::Degree
  222. Entity::GetRotation() const
  223. {
  224. assert(m_model_root_node);
  225. Ogre::Quaternion q = m_model_root_node->getOrientation();
  226. Ogre::Degree temp;
  227. Ogre::Vector3 vec = Ogre::Vector3::UNIT_Z;
  228. q.ToAngleAxis(temp, vec);
  229. return temp;
  230. }
  231. float
  232. Entity::ScriptGetRotation() const
  233. {
  234. return GetRotation().valueDegrees();
  235. }
  236. void Entity::setScale(const Ogre::Vector3 &scale)
  237. {
  238. assert(m_model_root_node);
  239. m_model_root_node->setScale(scale);
  240. }
  241. void Entity::setRootOrientation(const Ogre::Quaternion &root_orientation)
  242. {
  243. assert(m_ModelNode);
  244. m_ModelNode->setOrientation(root_orientation);
  245. }
  246. float
  247. Entity::GetHeight() const
  248. {
  249. return m_Height;
  250. }
  251. void
  252. Entity::SetSolidRadius(const float radius)
  253. {
  254. m_SolidRadius = radius;
  255. m_SolidCollisionNode->setScale(m_SolidRadius, m_SolidRadius, m_Height);
  256. }
  257. float
  258. Entity::GetSolidRadius() const
  259. {
  260. return m_SolidRadius;
  261. }
  262. void
  263. Entity::SetSolid(const bool solid)
  264. {
  265. m_Solid = solid;
  266. }
  267. bool
  268. Entity::IsSolid() const
  269. {
  270. return m_Solid;
  271. }
  272. void
  273. Entity::SetTalkRadius(const float radius)
  274. {
  275. m_TalkRadius = radius;
  276. m_TalkCollisionNode->setScale(m_TalkRadius, m_TalkRadius, m_Height);
  277. }
  278. float
  279. Entity::GetTalkRadius() const
  280. {
  281. return m_TalkRadius;
  282. }
  283. void
  284. Entity::SetTalkable(const bool talkable)
  285. {
  286. m_Talkable = talkable;
  287. }
  288. bool
  289. Entity::IsTalkable() const
  290. {
  291. return m_Talkable;
  292. }
  293. void
  294. Entity::SetState(const Entity::State state)
  295. {
  296. m_State = state;
  297. }
  298. Entity::State
  299. Entity::GetState() const
  300. {
  301. return m_State;
  302. }
  303. void
  304. Entity::SetMoveAutoSpeed(const float speed)
  305. {
  306. m_MoveAutoSpeed = speed;
  307. }
  308. float
  309. Entity::GetMoveAutoSpeed() const
  310. {
  311. return m_MoveAutoSpeed;
  312. }
  313. void
  314. Entity::SetMoveWalkSpeed(const float speed)
  315. {
  316. m_MoveWalkSpeed = speed;
  317. }
  318. float
  319. Entity::GetMoveWalkSpeed() const
  320. {
  321. return m_MoveWalkSpeed;
  322. }
  323. void
  324. Entity::SetMoveRunSpeed(const float speed)
  325. {
  326. m_MoveRunSpeed = speed;
  327. }
  328. float
  329. Entity::GetMoveRunSpeed() const
  330. {
  331. return m_MoveRunSpeed;
  332. }
  333. void
  334. Entity::SetMovePosition(const Ogre::Vector3& target)
  335. {
  336. m_MovePosition = target;
  337. }
  338. const Ogre::Vector3&
  339. Entity::GetMovePosition() const
  340. {
  341. return m_MovePosition;
  342. }
  343. float
  344. Entity::GetMoveStopDistance() const
  345. {
  346. return m_MoveStopDistance;
  347. }
  348. void
  349. Entity::SetMoveTriangleId(const int triangle)
  350. {
  351. m_MoveTriangleId = triangle;
  352. }
  353. int
  354. Entity::GetMoveTriangleId() const
  355. {
  356. return m_MoveTriangleId;
  357. }
  358. void
  359. Entity::SetMoveAutoRotation(const bool rotate)
  360. {
  361. m_MoveAutoRotation = rotate;
  362. }
  363. bool
  364. Entity::GetMoveAutoRotation() const
  365. {
  366. return m_MoveAutoRotation;
  367. }
  368. void
  369. Entity::SetMoveAutoAnimation(const bool animate)
  370. {
  371. m_MoveAutoAnimation = animate;
  372. }
  373. bool
  374. Entity::GetMoveAutoAnimation() const
  375. {
  376. return m_MoveAutoAnimation;
  377. }
  378. const Ogre::String&
  379. Entity::GetMoveAnimationWalkName() const
  380. {
  381. return m_MoveAnimationWalk;
  382. }
  383. const Ogre::String&
  384. Entity::GetMoveAnimationRunName() const
  385. {
  386. return m_MoveAnimationRun;
  387. }
  388. void
  389. Entity::ScriptMoveToPosition(const float x, const float y)
  390. {
  391. m_State = Entity::WALKMESH;
  392. m_MovePosition = Ogre::Vector3(x, y, 0);
  393. m_MoveEntity = nullptr;
  394. m_MoveStopDistance = 0;
  395. LOG_TRIVIAL("[SCRIPT] Entity \"" + m_Name + "\" set move to walkmesh position \"" + Ogre::StringConverter::toString(m_MovePosition) + "\".");
  396. }
  397. void
  398. Entity::ScriptMoveToEntity(Entity* entity)
  399. {
  400. m_State = Entity::WALKMESH;
  401. m_MovePosition = entity->GetPosition();
  402. m_MoveEntity = entity;
  403. m_MoveStopDistance = GetSolidRadius() + entity->GetSolidRadius();
  404. LOG_TRIVIAL("[SCRIPT] Entity \"" + m_Name + "\" set move to entity \"" + entity->GetName() + "\".");
  405. }
  406. int
  407. Entity::ScriptMoveSync()
  408. {
  409. ScriptId script = ScriptManager::getSingleton().GetCurrentScriptId();
  410. m_Sync.push_back(script);
  411. LOG_TRIVIAL("[SCRIPT] Wait entity \"" + m_Name + "\" move for function \"" + script.function + "\" in script entity \"" + script.entity + "\".");
  412. return -1;
  413. }
  414. void
  415. Entity::UnsetMove()
  416. {
  417. m_State = Entity::NONE;
  418. m_MoveEntity = nullptr;
  419. m_MoveStopDistance = 0;
  420. for(const auto &script : m_Sync)
  421. {
  422. ScriptManager::getSingleton().ContinueScriptExecution(script);
  423. }
  424. m_Sync.clear();
  425. }
  426. void
  427. Entity::ScriptLinearToPosition(const float x, const float y, const float z, const LinearMovement movement, const char* animation)
  428. {
  429. Ogre::Vector3 pos = Ogre::Vector3(x, y, z);
  430. SetLinear(pos, movement, animation);
  431. LOG_TRIVIAL("[SCRIPT] Entity \"" + m_Name + "\" set linear move to position \"" + Ogre::StringConverter::toString(pos) + "\" with animation \"" + animation + "\".");
  432. }
  433. int
  434. Entity::ScriptLinearSync()
  435. {
  436. ScriptId script = ScriptManager::getSingleton().GetCurrentScriptId();
  437. LOG_TRIVIAL("[SCRIPT] Wait entity \"" + m_Name + "\" linear move for function \"" + script.function + "\" in script entity \"" + script.entity + "\".");
  438. m_Sync.push_back(script);
  439. return -1;
  440. }
  441. void
  442. Entity::SetLinear(const Ogre::Vector3& end, const LinearMovement movement, const Ogre::String& animation)
  443. {
  444. m_State = Entity::LINEAR;
  445. m_LinearMovement = movement;
  446. m_LinearStart = GetPosition();
  447. m_LinearEnd = end;
  448. // linear animation
  449. m_AnimationAutoPlay = false;
  450. PlayAnimation(animation, Entity::AUTO_ANIMATION, Entity::PLAY_LOOPED, 0, -1);
  451. // after move we need reattach entity to walkmesh
  452. m_MoveTriangleId = -1;
  453. }
  454. void
  455. Entity::UnsetLinear()
  456. {
  457. m_State = Entity::NONE;
  458. m_AnimationAutoPlay = true;
  459. PlayAnimation(m_AnimationDefault, Entity::AUTO_ANIMATION, Entity::PLAY_LOOPED, 0, -1);
  460. for(size_t i = 0; i < m_Sync.size(); ++i)
  461. {
  462. ScriptManager::getSingleton().ContinueScriptExecution(m_Sync[i]);
  463. }
  464. m_Sync.clear();
  465. }
  466. LinearMovement
  467. Entity::GetLinearMovement() const
  468. {
  469. return m_LinearMovement;
  470. }
  471. const Ogre::Vector3&
  472. Entity::GetLinearStart() const
  473. {
  474. return m_LinearStart;
  475. }
  476. const Ogre::Vector3&
  477. Entity::GetLinearEnd() const
  478. {
  479. return m_LinearEnd;
  480. }
  481. void
  482. Entity::ScriptJumpToPosition(const float x, const float y, const float z, const float seconds)
  483. {
  484. Ogre::Vector3 jump_to(x, y, z);
  485. SetJump(jump_to, seconds);
  486. LOG_TRIVIAL("[SCRIPT] Entity \"" + m_Name + "\" set jump to position \"" + Ogre::StringConverter::toString(jump_to) + "\" in " + Ogre::StringConverter::toString(seconds) + " seconds.");
  487. }
  488. int
  489. Entity::ScriptJumpSync()
  490. {
  491. ScriptId script = ScriptManager::getSingleton().GetCurrentScriptId();
  492. LOG_TRIVIAL("[SCRIPT] Wait entity \"" + m_Name + "\" jump for function \"" + script.function + "\" in script entity \"" + script.entity + "\".");
  493. m_Sync.push_back(script);
  494. return -1;
  495. }
  496. void
  497. Entity::SetJump(const Ogre::Vector3& jump_to, const float seconds)
  498. {
  499. m_State = Entity::JUMP;
  500. m_JumpStart = GetPosition();
  501. m_JumpEnd = jump_to;
  502. m_JumpSeconds = seconds;
  503. m_JumpCurrentSeconds = 0;
  504. // after move we need reattach entity to walkmesh
  505. m_MoveTriangleId = -1;
  506. }
  507. void
  508. Entity::UnsetJump()
  509. {
  510. m_State = Entity::NONE;
  511. for(size_t i = 0; i < m_Sync.size(); ++i)
  512. {
  513. ScriptManager::getSingleton().ContinueScriptExecution(m_Sync[i]);
  514. }
  515. m_Sync.clear();
  516. }
  517. const Ogre::Vector3&
  518. Entity::GetJumpStart() const
  519. {
  520. return m_JumpStart;
  521. }
  522. const Ogre::Vector3&
  523. Entity::GetJumpEnd() const
  524. {
  525. return m_JumpEnd;
  526. }
  527. float
  528. Entity::GetJumpSeconds() const
  529. {
  530. return m_JumpSeconds;
  531. }
  532. void
  533. Entity::SetJumpCurrentSeconds(const float seconds)
  534. {
  535. m_JumpCurrentSeconds = seconds;
  536. }
  537. float
  538. Entity::GetJumpCurrentSeconds() const
  539. {
  540. return m_JumpCurrentSeconds;
  541. }
  542. void
  543. Entity::ScriptOffsetToPosition(const float x, const float y, const float z, const ActionType type, const float seconds)
  544. {
  545. LOG_TRIVIAL("[SCRIPT] Entity \"" + m_Name + "\" set offset to position \"" + Ogre::StringConverter::toString(Ogre::Vector3(x, y, z)) + "'.");
  546. Ogre::Vector3 position = Ogre::Vector3(x, y, z);
  547. if(type == AT_NONE)
  548. {
  549. this->SetOffset(position);
  550. return;
  551. }
  552. m_OffsetPositionStart = GetOffset();
  553. m_OffsetPositionEnd = position;
  554. m_OffsetType = type;
  555. m_OffsetSeconds = seconds;
  556. m_OffsetCurrentSeconds = 0;
  557. }
  558. int
  559. Entity::ScriptOffsetSync()
  560. {
  561. ScriptId script = ScriptManager::getSingleton().GetCurrentScriptId();
  562. LOG_TRIVIAL("[SCRIPT] Wait entity \"" + m_Name + "\" offset for function \"" + script.function + "\" in script entity \"" + script.entity + "\".");
  563. m_OffsetSync.push_back(script);
  564. return -1;
  565. }
  566. void
  567. Entity::UnsetOffset()
  568. {
  569. m_OffsetType = AT_NONE;
  570. for(unsigned int i = 0; i < m_OffsetSync.size(); ++i)
  571. {
  572. ScriptManager::getSingleton().ContinueScriptExecution(m_OffsetSync[i]);
  573. }
  574. m_OffsetSync.clear();
  575. }
  576. const Ogre::Vector3&
  577. Entity::GetOffsetPositionStart() const
  578. {
  579. return m_OffsetPositionStart;
  580. }
  581. const Ogre::Vector3&
  582. Entity::GetOffsetPositionEnd() const
  583. {
  584. return m_OffsetPositionEnd;
  585. }
  586. ActionType
  587. Entity::GetOffsetType() const
  588. {
  589. return m_OffsetType;
  590. }
  591. float
  592. Entity::GetOffsetSeconds() const
  593. {
  594. return m_OffsetSeconds;
  595. }
  596. void
  597. Entity::SetOffsetCurrentSeconds(const float seconds)
  598. {
  599. m_OffsetCurrentSeconds = seconds;
  600. }
  601. float
  602. Entity::GetOffsetCurrentSeconds() const
  603. {
  604. return m_OffsetCurrentSeconds;
  605. }
  606. void
  607. Entity::ScriptTurnToDirection(const float direction, const TurnDirection turn_direction, const ActionType turn_type, const float seconds)
  608. {
  609. SetTurn(Ogre::Degree(direction), nullptr, turn_direction, turn_type, seconds);
  610. LOG_TRIVIAL("[SCRIPT] Entity \"" + m_Name + "\" turn to angle \"" + Ogre::StringConverter::toString(direction) + "\".");
  611. }
  612. void
  613. Entity::ScriptTurnToEntity(Entity* entity, const TurnDirection turn_direction, const float seconds)
  614. {
  615. if(entity == nullptr || entity == this)
  616. {
  617. LOG_ERROR("[SCRIPT] Turn to entity: Invalid entity pointer (NUUL or this).");
  618. return;
  619. }
  620. Ogre::Degree angle = GetDirectionToEntity(entity);
  621. SetTurn(angle, entity, turn_direction, AT_SMOOTH, seconds);
  622. LOG_TRIVIAL("[SCRIPT] Entity \"" + m_Name + "\" turn to entity \"" + entity->GetName() + ".");
  623. }
  624. int
  625. Entity::ScriptTurnSync()
  626. {
  627. ScriptId script = ScriptManager::getSingleton().GetCurrentScriptId();
  628. LOG_TRIVIAL("[SCRIPT] Wait entity \"" + m_Name + "\" turn for function \"" + script.function + "\" in script entity \"" + script.entity + "\".");
  629. m_TurnSync.push_back(script);
  630. return -1;
  631. }
  632. void
  633. Entity::SetTurn(const Ogre::Degree& direction_to, Entity* entity, const TurnDirection turn_direction, const ActionType turn_type, const float seconds)
  634. {
  635. if(turn_type == AT_NONE)
  636. {
  637. SetRotation(direction_to);
  638. return;
  639. }
  640. m_TurnDirection = turn_direction;
  641. Ogre::Degree angle_start = GetRotation();
  642. Ogre::Degree angle_end = CalculateTurnAngle(angle_start, direction_to);
  643. m_TurnEntity = entity;
  644. m_TurnDirectionStart = angle_start;
  645. m_TurnDirectionEnd = angle_end;
  646. m_TurnType = turn_type;
  647. m_TurnSeconds = seconds;
  648. m_TurnCurrentSeconds = 0;
  649. }
  650. void
  651. Entity::UnsetTurn()
  652. {
  653. m_TurnType = AT_NONE;
  654. for(unsigned int i = 0; i < m_TurnSync.size(); ++i)
  655. {
  656. ScriptManager::getSingleton().ContinueScriptExecution(m_TurnSync[i]);
  657. }
  658. m_TurnSync.clear();
  659. }
  660. Ogre::Degree
  661. Entity::CalculateTurnAngle(const Ogre::Degree& start, const Ogre::Degree& end) const
  662. {
  663. Ogre::Degree ret = end;
  664. switch(m_TurnDirection)
  665. {
  666. case TD_CLOCKWISE:
  667. {
  668. if(end <= start)
  669. {
  670. ret = end + Ogre::Degree(360);
  671. }
  672. }
  673. break;
  674. case TD_ANTICLOCKWISE:
  675. {
  676. if(end >= start)
  677. {
  678. ret = end - Ogre::Degree(360);
  679. }
  680. }
  681. break;
  682. case TD_CLOSEST:
  683. {
  684. Ogre::Degree delta = end - start;
  685. delta = (delta < Ogre::Degree(0)) ? -delta : delta;
  686. if(delta > Ogre::Degree(180))
  687. {
  688. if(start < end)
  689. {
  690. ret = end - Ogre::Degree(360);
  691. }
  692. else
  693. {
  694. ret = end + Ogre::Degree(360);
  695. }
  696. }
  697. }
  698. break;
  699. }
  700. return ret;
  701. }
  702. Ogre::Degree
  703. Entity::GetTurnDirectionStart() const
  704. {
  705. return m_TurnDirectionStart;
  706. }
  707. Ogre::Degree
  708. Entity::GetTurnDirectionEnd() const
  709. {
  710. return m_TurnDirectionEnd;
  711. }
  712. ActionType
  713. Entity::GetTurnType() const
  714. {
  715. return m_TurnType;
  716. }
  717. float
  718. Entity::GetTurnSeconds() const
  719. {
  720. return m_TurnSeconds;
  721. }
  722. void
  723. Entity::SetTurnCurrentSeconds(const float seconds)
  724. {
  725. m_TurnCurrentSeconds = seconds;
  726. }
  727. float
  728. Entity::GetTurnCurrentSeconds() const
  729. {
  730. return m_TurnCurrentSeconds;
  731. }
  732. void
  733. Entity::ScriptSetAnimationSpeed(const float speed)
  734. {
  735. m_AnimationSpeed = speed;
  736. }
  737. const Ogre::String&
  738. Entity::GetDefaultAnimationName() const
  739. {
  740. return m_AnimationDefault;
  741. }
  742. const Ogre::String&
  743. Entity::GetCurrentAnimationName() const
  744. {
  745. return m_AnimationCurrentName;
  746. }
  747. Entity::AnimationState
  748. Entity::GetAnimationState() const
  749. {
  750. return m_AnimationState;
  751. }
  752. void
  753. Entity::ScriptPlayAnimation(const char* name)
  754. {
  755. PlayAnimation(Ogre::String(name), Entity::REQUESTED_ANIMATION, Entity::PLAY_DEFAULT, 0, -1);
  756. }
  757. void
  758. Entity::ScriptPlayAnimationStop(const char* name)
  759. {
  760. PlayAnimation(Ogre::String(name), Entity::REQUESTED_ANIMATION, Entity::PLAY_ONCE, 0, -1);
  761. }
  762. void
  763. Entity::ScriptPlayAnimation(const char* name, const float start, const float end)
  764. {
  765. PlayAnimation(Ogre::String(name), Entity::REQUESTED_ANIMATION, Entity::PLAY_DEFAULT, start, end);
  766. }
  767. void
  768. Entity::ScriptPlayAnimationStop(const char* name, const float start, const float end)
  769. {
  770. PlayAnimation(Ogre::String(name), Entity::REQUESTED_ANIMATION, Entity::PLAY_ONCE, start, end);
  771. }
  772. void
  773. Entity::ScriptSetDefaultAnimation(const char* animation)
  774. {
  775. m_AnimationDefault = Ogre::String(animation);
  776. }
  777. int
  778. Entity::ScriptAnimationSync()
  779. {
  780. ScriptId script = ScriptManager::getSingleton().GetCurrentScriptId();
  781. LOG_TRIVIAL("[SCRIPT] Wait entity \"" + m_Name + "\" animation for function \"" + script.function + "\" in script entity \"" + script.entity + "\".");
  782. m_AnimationSync.push_back(script);
  783. return -1;
  784. }
  785. Ogre::Degree
  786. Entity::GetDirectionToEntity(Entity* entity) const
  787. {
  788. Ogre::Vector3 current_point = GetPosition();
  789. Ogre::Vector3 direction_point = entity->GetPosition();
  790. Ogre::Vector2 up(0.0f, -1.0f);
  791. Ogre::Vector2 dir(direction_point.x - current_point.x, direction_point.y - current_point.y);
  792. // angle between vectors
  793. Ogre::Degree angle(Ogre::Radian(acosf(dir.dotProduct(up) / (dir.length() * up.length()))));
  794. return (dir.x < 0) ? Ogre::Degree(360) - angle : angle;
  795. }