Entity.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551
  1. #include "Entity.h"
  2. #include <Globals.h>
  3. #include <math.h>
  4. #include "Game.h"
  5. #include "Globals.h"
  6. Entity::Entity(const EntityType* zType,
  7. Framework::Model3DData* model,
  8. Framework::Model3DTextur* texture,
  9. int id,
  10. Framework::Vec3<float> position,
  11. float maxMovementSpeed,
  12. float size)
  13. : FactoryCraftModel(),
  14. id(id),
  15. zType(zType),
  16. playerControlled(0),
  17. maxMovementSpeed(maxMovementSpeed),
  18. lastFlags(0),
  19. timeSinceSync(0),
  20. speed(0, 0, 0)
  21. {
  22. pos = position;
  23. setModelDaten(model);
  24. setModelTextur(texture);
  25. lastDirection = World::INSTANCE->zKamera()->getDirection();
  26. currentFrame.duration = 0;
  27. rend = 1;
  28. setSize(size);
  29. }
  30. Entity::~Entity() {}
  31. void Entity::api(char* message)
  32. {
  33. switch (message[0])
  34. {
  35. case 0:
  36. { // add movement frame
  37. MovementFrame frame;
  38. frame.direction.x = *(float*)(message += 1);
  39. frame.direction.y = *(float*)(message += 4);
  40. frame.direction.z = *(float*)(message += 4);
  41. frame.targetPosition.x = *(float*)(message += 4);
  42. frame.targetPosition.y = *(float*)(message += 4);
  43. frame.targetPosition.z = *(float*)(message += 4);
  44. frame.movementFlags = *(int*)(message += 4);
  45. frame.duration = *(double*)(message += 4);
  46. Vec2<float> norm = {0, -1};
  47. this->setDrehungZ((frame.direction.x < 0 ? -1 : 1)
  48. * norm.angle(Vec2<float>(
  49. frame.direction.x, frame.direction.y)));
  50. if (!playerControlled)
  51. {
  52. cs.lock();
  53. movements.add(frame);
  54. cs.unlock();
  55. }
  56. break;
  57. }
  58. case 1:
  59. { // position correction
  60. if (playerControlled)
  61. {
  62. timeSinceSync = 0;
  63. pos.x = *(float*)(message += 1);
  64. pos.y = *(float*)(message += 4);
  65. pos.z = *(float*)(message += 4);
  66. lastDirection = World::INSTANCE->zKamera()->getDirection();
  67. lastFlags = 0;
  68. }
  69. break;
  70. }
  71. }
  72. }
  73. bool Entity::tick(double time)
  74. {
  75. if (!World::INSTANCE || !World::INSTANCE->zKamera()) return 0;
  76. if (playerControlled && GetForegroundWindow() == window->getFensterHandle())
  77. {
  78. Vec3<float> direction = World::INSTANCE->zKamera()->getDirection();
  79. Vec3<float> lastPos = pos;
  80. int flags = 0;
  81. speed = {0, 0, speed.z};
  82. if (GetKeyState('w') & 0x8000 || GetKeyState('W') & 0x8000)
  83. {
  84. flags |= 1;
  85. speed += {direction.x, direction.y, 0};
  86. }
  87. if (GetKeyState('a') & 0x8000 || GetKeyState('A') & 0x8000)
  88. {
  89. flags |= 2;
  90. Vec2<float> norm = {direction.x, direction.y};
  91. norm.CCW90().normalize();
  92. speed += {norm.x, norm.y, 0};
  93. }
  94. if (GetKeyState('s') & 0x8000 || GetKeyState('S') & 0x8000)
  95. {
  96. flags |= 4;
  97. speed += {-direction.x, -direction.y, 0};
  98. }
  99. if (GetKeyState('d') & 0x8000 || GetKeyState('D') & 0x8000)
  100. {
  101. flags |= 8;
  102. Vec2<float> norm = {direction.x, direction.y};
  103. norm.CW90().normalize();
  104. speed += {norm.x, norm.y, 0};
  105. }
  106. if (GetKeyState(T_Shift) & 0x8000)
  107. {
  108. flags |= 16;
  109. speed.z = -maxMovementSpeed;
  110. }
  111. else if (GetKeyState(T_Space) & 0x8000)
  112. {
  113. flags |= 32;
  114. speed.z = maxMovementSpeed;
  115. }
  116. else
  117. {
  118. speed.z = 0.f;
  119. }
  120. Vec2<float> norm = {speed.x, speed.y};
  121. if (norm.getLengthSq() != 0)
  122. {
  123. norm.normalize();
  124. speed.x = norm.x * maxMovementSpeed;
  125. speed.y = norm.y * maxMovementSpeed;
  126. }
  127. // collision checking
  128. Vec3<float> minP = model->getMinPos();
  129. Vec3<float> maxP = model->getMaxPos();
  130. Vec3<float> worldBoundingBox[8];
  131. worldBoundingBox[0] = applyWorldTransformation(minP);
  132. worldBoundingBox[1]
  133. = applyWorldTransformation({minP.x, minP.y, maxP.z});
  134. worldBoundingBox[2]
  135. = applyWorldTransformation({minP.x, maxP.y, minP.z});
  136. worldBoundingBox[3]
  137. = applyWorldTransformation({maxP.x, minP.y, minP.z});
  138. worldBoundingBox[4]
  139. = applyWorldTransformation({maxP.x, minP.y, maxP.z});
  140. worldBoundingBox[5]
  141. = applyWorldTransformation({maxP.x, maxP.y, minP.z});
  142. worldBoundingBox[6]
  143. = applyWorldTransformation({minP.x, maxP.y, maxP.z});
  144. worldBoundingBox[7] = applyWorldTransformation(maxP);
  145. Vec3<float> worldBoundingBoxFloor[8];
  146. for (int i = 0; i < 8; i++)
  147. {
  148. worldBoundingBoxFloor[i] = Vec3<float>(floor(worldBoundingBox[i].x),
  149. floor(worldBoundingBox[i].y),
  150. floor(worldBoundingBox[i].z));
  151. }
  152. Vec3<float> frameSpeed = speed * (float)time;
  153. bool hasCollided = 0;
  154. for (int m = 0; m < 20; m++)
  155. {
  156. float tf = 1.f;
  157. int collType = 0;
  158. int updateType = 0;
  159. int updateI = 0;
  160. if (frameSpeed.x > 0)
  161. {
  162. for (int i = 0; i < 8; i++)
  163. {
  164. if (abs(frameSpeed.x) >= abs(worldBoundingBoxFloor[i].x
  165. + 1.f - worldBoundingBox[i].x))
  166. {
  167. float xt = (worldBoundingBoxFloor[i].x + 1.f
  168. - worldBoundingBox[i].x)
  169. / frameSpeed.x;
  170. Vec3<float> tmp = worldBoundingBox[i] + frameSpeed * xt;
  171. if (tmp.y >= worldBoundingBoxFloor[i].y
  172. && tmp.y < worldBoundingBoxFloor[i].y + 1.f
  173. && tmp.z >= worldBoundingBoxFloor[i].z
  174. && tmp.z < worldBoundingBoxFloor[i].z + 1.f)
  175. {
  176. Block* b = World::INSTANCE->zBlockAt(
  177. Vec3<int>{(int)worldBoundingBoxFloor[i].x + 1,
  178. (int)worldBoundingBoxFloor[i].y,
  179. (int)worldBoundingBoxFloor[i].z});
  180. if (b) // TODO: ignore passable blocks
  181. {
  182. if (xt < tf)
  183. {
  184. tf = xt;
  185. collType = 1;
  186. updateType = 0;
  187. }
  188. hasCollided = 1;
  189. }
  190. else
  191. {
  192. if (xt < tf)
  193. {
  194. tf = xt;
  195. collType = 0;
  196. updateType = 1;
  197. updateI = i;
  198. }
  199. }
  200. }
  201. }
  202. }
  203. }
  204. if (frameSpeed.x < 0)
  205. {
  206. for (int i = 0; i < 8; i++)
  207. {
  208. if (abs(frameSpeed.x) >= abs(
  209. worldBoundingBoxFloor[i].x - worldBoundingBox[i].x))
  210. {
  211. float xt = (worldBoundingBoxFloor[i].x
  212. - worldBoundingBox[i].x)
  213. / frameSpeed.x;
  214. Vec3<float> tmp = worldBoundingBox[i] + frameSpeed * xt;
  215. if (tmp.y >= worldBoundingBoxFloor[i].y
  216. && tmp.y < worldBoundingBoxFloor[i].y + 1.f
  217. && tmp.z >= worldBoundingBoxFloor[i].z
  218. && tmp.z < worldBoundingBoxFloor[i].z + 1.f)
  219. {
  220. Block* b = World::INSTANCE->zBlockAt(
  221. Vec3<int>{(int)worldBoundingBoxFloor[i].x - 1,
  222. (int)worldBoundingBoxFloor[i].y,
  223. (int)worldBoundingBoxFloor[i].z});
  224. if (b) // TODO: ignore passable blocks
  225. {
  226. if (xt < tf)
  227. {
  228. tf = xt;
  229. collType = 1;
  230. updateType = 0;
  231. }
  232. hasCollided = 1;
  233. }
  234. else
  235. {
  236. if (xt < tf)
  237. {
  238. tf = xt;
  239. collType = 0;
  240. updateType = 1;
  241. updateI = i;
  242. }
  243. }
  244. }
  245. }
  246. }
  247. }
  248. if (frameSpeed.y > 0)
  249. {
  250. for (int i = 0; i < 8; i++)
  251. {
  252. if (abs(frameSpeed.y) >= abs(worldBoundingBoxFloor[i].y
  253. + 1.f - worldBoundingBox[i].y))
  254. {
  255. float yt = (worldBoundingBoxFloor[i].y + 1.f
  256. - worldBoundingBox[i].y)
  257. / frameSpeed.y;
  258. Vec3<float> tmp = worldBoundingBox[i] + frameSpeed * yt;
  259. if (tmp.x >= worldBoundingBoxFloor[i].x
  260. && tmp.x < worldBoundingBoxFloor[i].x + 1.f
  261. && tmp.z >= worldBoundingBoxFloor[i].z
  262. && tmp.z < worldBoundingBoxFloor[i].z + 1.f)
  263. {
  264. Block* b = World::INSTANCE->zBlockAt(
  265. Vec3<int>{(int)worldBoundingBoxFloor[i].x,
  266. (int)worldBoundingBoxFloor[i].y + 1,
  267. (int)worldBoundingBoxFloor[i].z});
  268. if (b) // TODO: ignore passable blocks
  269. {
  270. if (yt < tf)
  271. {
  272. tf = yt;
  273. collType = 2;
  274. updateType = 0;
  275. }
  276. hasCollided = 1;
  277. }
  278. else
  279. {
  280. if (yt < tf)
  281. {
  282. tf = yt;
  283. collType = 0;
  284. updateType = 2;
  285. updateI = i;
  286. }
  287. }
  288. }
  289. }
  290. }
  291. }
  292. if (frameSpeed.y < 0)
  293. {
  294. for (int i = 0; i < 8; i++)
  295. {
  296. if (abs(frameSpeed.y) >= abs(
  297. worldBoundingBoxFloor[i].y - worldBoundingBox[i].y))
  298. {
  299. float yt = (worldBoundingBoxFloor[i].y
  300. - worldBoundingBox[i].y)
  301. / frameSpeed.y;
  302. Vec3<float> tmp = worldBoundingBox[i] + frameSpeed * yt;
  303. if (tmp.x >= worldBoundingBoxFloor[i].x
  304. && tmp.x < worldBoundingBoxFloor[i].x + 1.f
  305. && tmp.z >= worldBoundingBoxFloor[i].z
  306. && tmp.z < worldBoundingBoxFloor[i].z + 1.f)
  307. {
  308. Block* b = World::INSTANCE->zBlockAt(
  309. Vec3<int>{(int)worldBoundingBoxFloor[i].x,
  310. (int)worldBoundingBoxFloor[i].y - 1,
  311. (int)worldBoundingBoxFloor[i].z});
  312. if (b) // TODO: ignore passable blocks
  313. {
  314. if (yt < tf)
  315. {
  316. tf = yt;
  317. collType = 2;
  318. updateType = 0;
  319. }
  320. hasCollided = 1;
  321. }
  322. else
  323. {
  324. if (yt < tf)
  325. {
  326. tf = yt;
  327. collType = 0;
  328. updateType = 2;
  329. updateI = i;
  330. }
  331. }
  332. }
  333. }
  334. }
  335. }
  336. if (frameSpeed.z > 0)
  337. {
  338. for (int i = 0; i < 8; i++)
  339. {
  340. if (abs(frameSpeed.z) >= abs(worldBoundingBoxFloor[i].z
  341. + 1.f - worldBoundingBox[i].z))
  342. {
  343. float zt = (worldBoundingBoxFloor[i].z + 1.f
  344. - worldBoundingBox[i].z)
  345. / frameSpeed.z;
  346. Vec3<float> tmp = worldBoundingBox[i] + frameSpeed * zt;
  347. if (zt <= 1.f && tmp.x >= worldBoundingBoxFloor[i].x
  348. && tmp.x < worldBoundingBoxFloor[i].x + 1.f
  349. && tmp.y >= worldBoundingBoxFloor[i].y
  350. && tmp.y < worldBoundingBoxFloor[i].y + 1.f)
  351. {
  352. Block* b = World::INSTANCE->zBlockAt(
  353. Vec3<int>{(int)worldBoundingBoxFloor[i].x,
  354. (int)worldBoundingBoxFloor[i].y,
  355. (int)worldBoundingBoxFloor[i].z + 1});
  356. if (b) // TODO: ignore passable blocks
  357. {
  358. if (zt < tf)
  359. {
  360. tf = zt;
  361. collType = 3;
  362. }
  363. hasCollided = 1;
  364. }
  365. else
  366. {
  367. if (zt < tf)
  368. {
  369. tf = zt;
  370. collType = 0;
  371. updateType = 3;
  372. updateI = i;
  373. }
  374. }
  375. }
  376. }
  377. }
  378. }
  379. if (frameSpeed.z < 0)
  380. {
  381. for (int i = 0; i < 8; i++)
  382. {
  383. if (abs(frameSpeed.z) >= abs(
  384. worldBoundingBoxFloor[i].z - worldBoundingBox[i].z))
  385. {
  386. float zt = (worldBoundingBoxFloor[i].z
  387. - worldBoundingBox[i].z)
  388. / frameSpeed.z;
  389. Vec3<float> tmp = worldBoundingBox[i] + frameSpeed * zt;
  390. if (tmp.x >= worldBoundingBoxFloor[i].x
  391. && tmp.x < worldBoundingBoxFloor[i].x + 1.f
  392. && tmp.y >= worldBoundingBoxFloor[i].y
  393. && tmp.y < worldBoundingBoxFloor[i].y + 1)
  394. {
  395. Block* b = World::INSTANCE->zBlockAt(
  396. Vec3<int>{(int)worldBoundingBoxFloor[i].x,
  397. (int)worldBoundingBoxFloor[i].y,
  398. (int)worldBoundingBoxFloor[i].z - 1});
  399. if (b) // TODO: ignore passable blocks
  400. {
  401. if (zt < tf)
  402. {
  403. tf = zt;
  404. collType = 3;
  405. updateType = 0;
  406. }
  407. hasCollided = 1;
  408. }
  409. else
  410. {
  411. if (zt < tf)
  412. {
  413. tf = zt;
  414. collType = 0;
  415. updateType = 3;
  416. updateI = i;
  417. }
  418. }
  419. }
  420. }
  421. }
  422. }
  423. if (collType == 1)
  424. frameSpeed.x = tf > 0.1f ? frameSpeed.x * (tf - 0.1f) : 0.f;
  425. if (collType == 2)
  426. frameSpeed.y = tf > 0.1f ? frameSpeed.y * (tf - 0.1f) : 0.f;
  427. if (collType == 3)
  428. frameSpeed.z = tf > 0.1f ? frameSpeed.z * (tf - 0.1f) : 0.f;
  429. if (updateType == 1)
  430. {
  431. if ((int)worldBoundingBoxFloor[updateI].x
  432. <= (int)floor(worldBoundingBox[updateI].x + frameSpeed.x))
  433. worldBoundingBoxFloor[updateI].x++;
  434. if ((int)worldBoundingBoxFloor[updateI].x
  435. > (int)floor(worldBoundingBox[updateI].x + frameSpeed.x))
  436. worldBoundingBoxFloor[updateI].x--;
  437. }
  438. if (updateType == 2)
  439. {
  440. if ((int)worldBoundingBoxFloor[updateI].y
  441. <= (int)floor(worldBoundingBox[updateI].y + frameSpeed.y))
  442. worldBoundingBoxFloor[updateI].y++;
  443. if ((int)worldBoundingBoxFloor[updateI].y
  444. > (int)floor(worldBoundingBox[updateI].y + frameSpeed.y))
  445. worldBoundingBoxFloor[updateI].y--;
  446. }
  447. if (updateType == 3)
  448. {
  449. if ((int)worldBoundingBoxFloor[updateI].z
  450. <= (int)floor(worldBoundingBox[updateI].z + frameSpeed.z))
  451. worldBoundingBoxFloor[updateI].z++;
  452. if ((int)worldBoundingBoxFloor[updateI].z
  453. > (int)floor(worldBoundingBox[updateI].z + frameSpeed.z))
  454. worldBoundingBoxFloor[updateI].z--;
  455. }
  456. if (updateType || collType) continue;
  457. break;
  458. }
  459. pos += frameSpeed;
  460. World::INSTANCE->zKamera()->setPosition(
  461. pos + Vec3<float>(0.f, 0.f, 1.5f));
  462. Model3D* target = World::INSTANCE->getCurrentTarget();
  463. Block* b = target ? dynamic_cast<Block*>(target) : 0;
  464. ((Game*)(Menu*)menuRegister->get("game"))
  465. ->updatePosition(
  466. pos, b != 0, b ? b->getLocation() : Vec3<int>(0, 0, 0));
  467. if (target) target->release();
  468. if (flags != lastFlags || direction != lastDirection
  469. || timeSinceSync >= 1 || hasCollided)
  470. {
  471. if (timeSinceSync > 0)
  472. {
  473. MovementFrame frame;
  474. frame.direction = lastDirection;
  475. frame.targetPosition = lastPos;
  476. frame.movementFlags = lastFlags;
  477. frame.duration = timeSinceSync;
  478. World::INSTANCE->zClient()->sendPlayerMovement(frame);
  479. }
  480. lastFlags = flags;
  481. lastDirection = direction;
  482. timeSinceSync = 0;
  483. }
  484. timeSinceSync += time;
  485. rend = 1;
  486. }
  487. else
  488. {
  489. double totalTime = time;
  490. while (totalTime > 0)
  491. {
  492. if (currentFrame.duration <= 0)
  493. {
  494. if (movements.getEintragAnzahl() > 0)
  495. {
  496. currentFrame = movements.get(0);
  497. cs.lock();
  498. movements.remove(0);
  499. cs.unlock();
  500. }
  501. else
  502. {
  503. break;
  504. }
  505. }
  506. double t = min(currentFrame.duration, totalTime);
  507. pos += (currentFrame.targetPosition - pos)
  508. * (float)(t / currentFrame.duration);
  509. currentFrame.duration -= t;
  510. totalTime -= t;
  511. if (currentFrame.duration <= 0)
  512. {
  513. pos = currentFrame.targetPosition;
  514. }
  515. rend = 1;
  516. }
  517. }
  518. return Model3D::tick(time);
  519. }
  520. int Entity::getId() const
  521. {
  522. return id;
  523. }
  524. const EntityType* Entity::zEntityType() const
  525. {
  526. return zType;
  527. }
  528. void Entity::lock()
  529. {
  530. cs.lock();
  531. }
  532. void Entity::unlock()
  533. {
  534. cs.unlock();
  535. }
  536. void Entity::setPlayerControlled()
  537. {
  538. playerControlled = 1;
  539. World::INSTANCE->zKamera()->setPosition(pos + Vec3<float>(0.f, 0.f, 1.5f));
  540. }