Entity.cpp 24 KB

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